📄 controllogic.vhd
字号:
IDR_MOV <= IDC_MOV;
IDR_MVN <= IDC_MVN;
IDR_MUL <= IDC_MUL;
IDR_MLA <= IDC_MLA;
IDR_UMULL <= IDC_UMULL;
IDR_UMLAL <= IDC_UMLAL;
IDR_SMULL <= IDC_SMULL;
IDR_SMLAL <= IDC_SMLAL;
IDR_MSR_R <= IDC_MSR_R;
IDR_MSR_I <= IDC_MSR_I;
IDR_MRS <= IDC_MRS;
IDR_B <= IDC_B;
IDR_BL <= IDC_BL;
IDR_BX <= IDC_BX;
IDR_LDR <= IDC_LDR;
IDR_LDRT <= IDC_LDRT;
IDR_LDRB <= IDC_LDRB;
IDR_LDRBT <= IDC_LDRBT;
IDR_LDRSB <= IDC_LDRSB;
IDR_LDRH <= IDC_LDRH;
IDR_LDRSH <= IDC_LDRSH;
IDR_LDM <= IDC_LDM;
IDR_STR <= IDC_STR;
IDR_STRT <= IDC_STRT;
IDR_STRB <= IDC_STRB;
IDR_STRBT <= IDC_STRBT;
IDR_STRH <= IDC_STRH;
IDR_STM <= IDC_STM;
IDR_SWP <= IDC_SWP;
IDR_SWPB <= IDC_SWPB;
IDR_SWI <= IDC_SWI;
IDR_MRC <= IDC_MRC;
IDR_MCR <= IDC_MCR;
IDR_LDC <= IDC_LDC;
IDR_CDP <= IDC_CDP;
IDR_STC <= IDC_STC;
-- Thumb branch with link support
IDR_ThBLFP <= ThBLFP;
IDR_ThBLSP <= ThBLSP;
IDR_Undef <= IDC_Undef;
-- Instruction groops
IDR_DPIRegSh <= IDC_DPIRegSh;
IDR_DPIImmSh <= IDC_DPIImmSh;
IDR_DPIImmRot <= IDC_DPIImmRot;
IDR_LSRegOffset <= IDC_LSRegOffset;
IDR_LSImmOffset <= IDC_LSImmOffset;
IDR_LSHWImmOffset <= IDC_LSHWImmOffset;
IDR_LSHWRegOffset <= IDC_LSHWRegOffset;
IDR_LHWBSRegOffset <= IDC_LHWBSRegOffset;
IDR_LHWBSImmOffset <= IDC_LHWBSImmOffset;
IDR_LdStInst <= IDC_LdStInst;
IDR_SingleCycleDPI <= IDC_DPIImmSh or IDC_DPIImmRot;
IDR_Branch <= IDC_Branch;
IDR_Compare <= IDC_Compare;
IDR_DPIArith <= IDC_DPIArith;
-- Stored instruction and it's abort indicator
InstForDecodeLatched <= InstForDecode;
IFAbtStored <= InstFetchAbort;
-- External interrupt requests syncronization with instruction execution
FIQLatched <= not nFIQ;
IRQLatched <= not nIRQ;
end if;
end if;
end process;
-- +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-- Shifter control
-- +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ShifterCtrl:process(nRESET,CLK)
begin
if nRESET='0' then -- Reset
ShLenImm <= (others => '0');
ShType <= (others => '0');
ShRotImm <= '0';
ShEn <= '0';
ShCFlagEn <= '0';
elsif CLK='1' and CLK'event then -- Clock
if CLKEN='1' then -- Clock enable
case StagnatePipeline_Int is
-- Beginning of the new instruction
when '0' =>
if ExceptFC='1' then -- First cycle of exception
if CPSRTFlag='0' or -- CPU in ARM mode
DAbtExcStart ='1' then -- Data abort
-- Shifter is disabled
ShEn <= '0';
ShCFlagEn <= '0';
else
-- LSR by 1 (4>>1=2)
ShType <= "010";
ShRotImm <= '0';
ShEn <= '1';
ShCFlagEn <= '0';
ShLenImm <= "00001";
end if;
else -- No exception
if Branch_St1='1' then
-- LR=LR-4(ARM)/LR=LR-2(Thumb)
if CPSRTFlag='1' then -- Thumb mode
ShType <= "010"; -- LSR by immediate
ShRotImm <= '0';
ShEn <= '1';
ShCFlagEn <= '0';
ShLenImm <= "00001"; -- Shift right by one
else
-- ARM mode - disable shifter
ShEn <= '0';
ShCFlagEn <= '0';
end if;
elsif ThBLFP='1' and CPSRTFlag='1' then
-- Thumb BL the first part LR<=PC+(SignExtend(offset_11)<<12)
ShType <= "000"; -- LSL by immediate
ShRotImm <= '0';
ShEn <= '1';
ShCFlagEn <= '0';
ShLenImm <= "01100"; -- Shift amount=12
elsif ThBLSP='1' and CPSRTFlag='1' then
-- Thumb BL the second part PC<=LR+(SignExtend(offset_11)<<1)|1
ShType <= "000"; -- LSL by immediate
ShRotImm <= '0';
ShEn <= '1';
ShCFlagEn <= '0';
ShLenImm <= "00001"; -- Shift amount=1
elsif IDC_B = '1' or (IDC_BL = '1' and CPSRTFlag='0') then
-- Branch or branch with link (destination address calculation)
ShType <= "000"; -- LSL by immediate
ShRotImm <= '0';
ShEn <= '1';
ShCFlagEn <= '0';
-- Shift amount depends on mode(ARM/Thumb)
if CPSRTFlag='0' then ShLenImm <= "00010"; -- ARM mode
else ShLenImm <= "00001"; -- Thumb mode
end if;
elsif (IDC_SWP or IDC_SWPB)='1' then -- Swap/Swap byte
ShEn <= '0'; -- Disable shifter
ShCFlagEn <= '0';
else
-- All other cases: data processing instructions, address calculations
ShLenImm <= shift_amount;
ShType <= shift&InstForDecode(4);
ShRotImm <= IDC_DPIImmRot or IDC_MSR_I; -- Data processing immediate or move immediate to status register
ShEn <= IDC_DPIImmSh or IDC_DPIImmRot or IDC_DPIRegSh or
IDC_LSRegOffset or IDC_MSR_I;
ShCFlagEn <= IDC_MOV or IDC_MVN or IDC_TST or IDC_TEQ or IDC_ORR or IDC_EOR or
IDC_ORR or IDC_BIC or IDC_LSRegOffset; -- Instructions which produce shifter carry out
end if;
end if;
-- Changes of data path control within the instruction
when '1' =>
if LDR_St1='1' or LDM_St1='1' then -- The third cycle of load instruction
ShEn <= '0';
end if;
when others => null;
end case;
end if;
end if;
end process;
-- +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-- Multiplier control (combinatorial)
-- +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
LoadRsRm <= (IDR_MUL and ExecuteInst and not MUL_St)or -- Start for MUL
((IDR_SMULL or IDR_UMULL) and ExecuteInst and not nMULL_St0)or -- Start for SMULL/UMULL
MLA_St1 or MLAL_St1; -- Start for MLA/SMLAL/UMLAL
UnsignedMul <= IDR_UMULL or IDR_UMLAL;
ReadLH <= MULL_St2 or MLAL_St3; -- Read bits 63:32 of Partial Sum/Carry
LoadPS <= (IDR_MLA and ExecuteInst and not nMLA_St0)or -- Load Partial Sum (for accumulation)
((IDR_SMLAL or IDR_UMLAL) and ExecuteInst and not nMLAL_St0);
ClearPSC <= ((MUL_St or MLA_St2)and MulResRdy)or MULL_St2 or MLAL_St3; -- Clear Partial Sum/Carry after any multiplication
-- +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-- ALU control register (Only data processing instructions are implemented now)
-- +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ALUCtrl:process(nRESET,CLK)
begin
if nRESET='0' then -- Reset
InvA <= '0';
InvB <= '0';
PassA_Reg <= '0';
PassB_Reg <= '0';
AND_Op <= '0';
ORR_Op <= '0';
EOR_Op <= '0';
CFlagUse <= '0';
elsif CLK='1' and CLK'event then -- Clock
if CLKEN='1' then -- Clock enable
case StagnatePipeline_Int is
when '0' =>
if ExceptFC='1' then -- First cycle of exception
if CPSRTFlag='0' or -- Start of any exception when CPU is in ARM mode
(SWI_UndefExcStart='1' and -- Undefined instruction or SWI
CPSRTFlag='1') then -- CPU is in Thumb mode
-- LR<=LR-4 / LR<=LR-2
InvA <= '0';
InvB <= '1';
PassA_Reg <= '0';
PassB_Reg <= '0';
AND_Op <= '0';
ORR_Op <= '0';
EOR_Op <= '0';
CFlagUse <= '0';
elsif (PAbtExcStart='1' or -- Prefetch abort
FIQExcStart='1' or -- FIQ
IRQExcStart='1')and -- IRQ
CPSRTFlag='1' then -- CPU is in Thumb mode
-- LR <= LR
InvA <= '0';
InvB <= '0';
PassA_Reg <= '1';
PassB_Reg <= '0';
AND_Op <= '0';
ORR_Op <= '0';
EOR_Op <= '0';
CFlagUse <= '0';
elsif DAbtExcStart ='1' and -- Data abort
CPSRTFlag='1' then -- CPU is in Thumb mode
-- LR <= LR+2
InvA <= '0';
InvB <= '0';
PassA_Reg <= '0';
PassB_Reg <= '0';
AND_Op <= '0';
ORR_Op <= '0';
EOR_Op <= '0';
CFlagUse <= '0';
end if;
else -- No exception
if Branch_St1='1' then
-- LR=LR-4(ARM)/LR=LR-2(Thumb)
PassA_Reg <= '0';
InvB <= '1';
elsif ((IDR_B or IDR_BL or (IDR_ThBLFP and CPSRTFlag)) and ExecuteInst)='1' then
-- LR=PC
PassA_Reg <= '1';
elsif IDC_BX='1' then
-- Branch with exchange
InvA <= '0';
InvB <= '0';
PassA_Reg <= '0';
PassB_Reg <= '1'; -- Rm !!!
AND_Op <= '0';
ORR_Op <= '0';
EOR_Op <= '0';
CFlagUse <= '0';
-- Load/store memory address calculation (post-indexed mode : ADDR=Rm)
elsif (IDC_SWP or IDC_SWPB)='1' or -- Swap/Swap byte
(IDC_LDRT or IDC_LDRBT or IDC_STRT or IDC_STRBT)='1' or -- Instructions which are always post-index
((IDC_LDR or IDC_LDRB or IDC_LDRH or IDC_LDRSB or IDC_LDRSH or IDC_LDM or
IDC_STR or IDC_STRB or IDC_STRH or IDC_STM)='1' and P='0') then -- Post-indexed
InvA <= '0';
InvB <= '0';
PassA_Reg <= '1'; --
PassB_Reg <= '0';
AND_Op <= '0';
ORR_Op <= '0';
EOR_Op <= '0';
CFlagUse <= '0';
elsif
((IDC_LDR or IDC_LDRB or IDC_LDRH or IDC_LDRSB or IDC_LDRSH or IDC_LDM or
IDC_STR or IDC_STRB or IDC_STRH or IDC_STM)='1' and P='1') then -- Pre-indexed
-- Load/store memory address calculation (pre-indexed mode ADDR=Rm+/- offset)
InvA <= '0';
InvB <= not U; -- U=1 - add, U=0 subtract
PassA_Reg <= '0';
PassB_Reg <= '0';
AND_Op <= '0';
ORR_Op <= '0';
EOR_Op <= '0';
CFlagUse <= '0';
else
-- Data processing instructions with /multiplications and branches/ !!! Check
InvA <= IDC_RSB or IDC_RSC;
InvB <= IDC_SUB or IDC_SBC or IDC_MVN or IDC_BIC or IDC_CMP;
PassA_Reg <= '0'; -- !!!!
PassB_Reg <= IDC_MOV or IDC_MVN or IDC_MSR_I or IDC_MSR_R;
AND_Op <= IDC_TST or IDC_AND or IDC_BIC;
ORR_Op <= IDC_ORR ;
EOR_Op <= IDC_TEQ or IDC_EOR;
CFlagUse <= IDC_ADC or IDC_SBC or IDC_RSC;
end if;
end if;
when '1' =>
-- Changes of data path control within the instruction
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -