📄 armiu_exstg.vhd
字号:
-- $(lic)-- $(help_generic)-- $(help_local)library ieee;use ieee.std_logic_1164.all;use work.int.all;use work.memdef.all;use work.armpmodel.all;use work.armpctrl.all;use work.armdecode.all;use work.armdebug.all;use work.arm_comp.all;entity armiu_exstg is port ( rst : in std_logic; clk : in std_logic; i : in armiu_exstg_typ_in; o : out armiu_exstg_typ_out );end armiu_exstg;architecture rtl of armiu_exstg is type exstg_tmp_resultsrc is (exstg_src_log, exstg_src_add); type armiu_exstg_tmp_type is record o : armiu_exstg_typ_out; commit : std_logic; op1, op2: std_logic_vector(31 downto 0); -- adder inputs log_AND, log_EOR, log_ORR : std_logic_vector(31 downto 0); -- logic cmds log_MOV, log_BIC, log_MVN : std_logic_vector(31 downto 0); -- move cmds add_carry, add_issub, add_usecarry, add_use : std_logic; -- adder param src : exstg_tmp_resultsrc; src_log_data : std_logic_vector(31 downto 0); src_add_data : std_logic_vector(31 downto 0); result : std_logic_vector(31 downto 0); cpsr, newcpsr, spsr : apm_cpsr; -- pragma translate_off dbgaluop : adg_dbgaluop; -- pragma translate_on end record; type armiu_exstg_reg_type is record pctrl : apc_pctrl; cpsr : apm_cpsr; buf : std_logic_vector(31 downto 0); end record; type armiu_exstg_dbg_type is record dummy : std_logic; -- pragma translate_off dbg : armiu_exstg_tmp_type; -- pragma translate_on end record; signal r, c : armiu_exstg_reg_type; signal rdbg, cdbg : armiu_exstg_dbg_type;begin p0: process (clk, rst, r, i ) variable v : armiu_exstg_reg_type; variable t : armiu_exstg_tmp_type; variable vdbg : armiu_exstg_dbg_type; begin -- $(init(t:armiu_exstg_tmp_type)) v := r; t.commit := not i.flush_v; t.spsr := r.cpsr; t.spsr := apm_bankspsr(r.cpsr.wr.mode, i.fromWR_spsr_r); t.add_carry := r.cpsr.ex.c; t.add_issub := '0'; t.add_usecarry := '0'; t.add_use := '0'; t.op1 := (others => '0'); t.op2 := (others => '0'); t.log_AND := r.pctrl.data1 and r.pctrl.data2; t.log_EOR := r.pctrl.data1 xor r.pctrl.data2; t.log_ORR := r.pctrl.data1 or r.pctrl.data2; t.log_MOV := r.pctrl.data2; t.log_BIC := r.pctrl.data1 and not r.pctrl.data2; t.log_MVN := not r.pctrl.data2; t.src_log_data := t.log_AND; case r.pctrl.ex.exop_aluop is when ADE_OP_AND => t.src := exstg_src_log; t.src_log_data := t.log_AND; when ADE_OP_EOR => t.src := exstg_src_log; t.src_log_data := t.log_EOR; when ADE_OP_SUB => t.src := exstg_src_add; t.add_issub := '1'; t.add_use := '1'; t.op1 := r.pctrl.data1; t.op2 := r.pctrl.data2; when ADE_OP_RSB => t.src := exstg_src_add; t.add_issub := '1'; t.add_use := '1'; t.op1 := r.pctrl.data2; t.op2 := r.pctrl.data1; when ADE_OP_ADD => t.src := exstg_src_add; t.add_use := '1'; t.op1 := r.pctrl.data1; t.op2 := r.pctrl.data2; when ADE_OP_ADC => t.src := exstg_src_add; t.add_usecarry := '1'; t.add_use := '1'; t.op1 := r.pctrl.data1; t.op2 := r.pctrl.data2; when ADE_OP_SBC => t.src := exstg_src_add; t.add_usecarry := '1'; t.add_issub := '1'; t.add_carry := not t.add_carry; t.add_use := '1'; t.op1 := r.pctrl.data1; t.op2 := r.pctrl.data2; when ADE_OP_RSC => t.src := exstg_src_add; t.add_usecarry := '1'; t.add_issub := '1'; t.add_carry := not t.add_carry; t.add_use := '1'; t.op2 := r.pctrl.data1; t.op1 := r.pctrl.data2; when ADE_OP_TST => t.src := exstg_src_log; t.src_log_data := t.log_AND; when ADE_OP_TEQ => t.src := exstg_src_log; t.src_log_data := t.log_EOR; when ADE_OP_CMP => t.src := exstg_src_add; t.add_issub := '1'; t.add_use := '1'; t.op1 := r.pctrl.data1; t.op2 := r.pctrl.data2; when ADE_OP_CMN => t.src := exstg_src_add; t.add_use := '1'; t.op1 := r.pctrl.data1; t.op2 := r.pctrl.data2; when ADE_OP_ORR => t.src := exstg_src_log; t.src_log_data := t.log_ORR; when ADE_OP_MOV => t.src := exstg_src_log; t.src_log_data := t.log_MOV; when ADE_OP_BIC => t.src := exstg_src_log; t.src_log_data := t.log_BIC; when ADE_OP_MVN => t.src := exstg_src_log; t.src_log_data := t.log_MVN; when others => null; end case; if t.add_usecarry = '0' then t.add_carry := '0'; end if; if t.add_issub = '1' then t.op2 := not t.op2; t.add_carry := not t.add_carry; end if; -- the adder lin_adder( t.op1, t.op2, t.add_carry, '0', t.src_add_data ); t.result := t.src_add_data; case t.src is when exstg_src_log => t.result := t.src_log_data; -- logic cmd when exstg_src_add => t.result := t.src_add_data; -- adder cmd when others => end case; -- calc cpsr t.cpsr := r.cpsr; if t.add_issub = '1' then t.cpsr.ex.c := ((not t.op1(31)) and t.op2(31)) or -- Carry (t.src_add_data(31) and ((not t.op1(31)) or t.op2(31))); t.cpsr.ex.v := ( t.op1(31) and (not t.op2(31)) and not t.src_add_data(31)) or -- Overflow ((not t.op1(31)) and t.op2(31) and t.src_add_data(31)); else t.cpsr.ex.c := (t.op1(31) and t.op2(31)) or -- Carry ((not t.src_add_data(31)) and (t.op1(31) or t.op2(31))); t.cpsr.ex.v := ( t.op1(31) and t.op2(31) and not t.src_add_data(31)) or -- Overflow ((not t.op1(31)) and (not t.op2(31)) and t.src_add_data(31)); end if; if t.result = LIN_ZERO then t.cpsr.ex.z := '1'; else t.cpsr.ex.z := '0'; end if; t.cpsr.ex.n := t.result(31); -- calc new cpsr t.newcpsr := r.cpsr; case r.pctrl.insn.decinsn is when type_arm_invalid => null; when type_arm_nop => null; when type_arm_mrs => null; if r.pctrl.insn.insn(ADE_MRS_R) = '0' then t.result := apm_cpsrtostd (r.cpsr); else t.result := apm_cpsrtostd (t.spsr); end if; when type_arm_msr => if r.pctrl.insn.insn(ADE_MSR_R) = '0' then if apm_is_privmode(r.cpsr.wr.mode) then t.newcpsr := apm_msr ( r.pctrl.insn.insn, apm_stdtocpsr(r.pctrl.insn.insn) , r.cpsr); end if; end if; when type_arm_bx => null; when type_arm_mul => null; when type_arm_mla => null; when type_arm_swp => null; when type_arm_sumull => null; when type_arm_sumlal => null; when type_arm_teq => -- Test Equivalence -- $(del) -- arm@4.1.53: -- if ConditionPassed(cond) then -- alu_out = Rn EOR shifter_operand -- N Flag = alu_out[31] -- Z Flag = if alu_out == 0 then 1 else 0 -- C Flag = shifter_carry_out -- V Flag = unaffected -- $(/del) t.newcpsr.ex.n := t.cpsr.ex.n; t.newcpsr.ex.z := t.cpsr.ex.z; t.newcpsr.ex.c := r.pctrl.rs.rs_shieftcarryout; when type_arm_tst => -- Test -- $(del) -- arm@4.1.54: --if ConditionPassed(cond) then -- alu_out = Rn AND shifter_operand -- N Flag = alu_out[31] -- Z Flag = if alu_out == 0 then 1 else 0 -- C Flag = shifter_carry_out -- V Flag = unaffected -- $(/del) t.newcpsr.ex.n := t.cpsr.ex.n; t.newcpsr.ex.z := t.cpsr.ex.z; t.newcpsr.ex.c := r.pctrl.rs.rs_shieftcarryout; when type_arm_cmn => -- Compare Negative -- $(del) -- arm@4.1.13: -- if ConditionPassed(cond) then -- alu_out = Rn + shifter_operand -- N Flag = alu_out[31] -- Z Flag = if alu_out == 0 then 1 else 0 -- C Flag = CarryFrom(Rn + shifter_operand) -- V Flag = OverflowFrom(Rn + shifter_operand) -- $(/del) t.newcpsr.ex.n := t.cpsr.ex.n; t.newcpsr.ex.z := t.cpsr.ex.z; t.newcpsr.ex.c := t.cpsr.ex.c; t.newcpsr.ex.v := t.cpsr.ex.v; when type_arm_cmp => -- Compare -- $(del) -- arm@4.1.14: --if ConditionPassed(cond) then -- alu_out = Rn - shifter_operand -- N Flag = alu_out[31] -- Z Flag = if alu_out == 0 then 1 else 0 -- C Flag = NOT BorrowFrom(Rn - shifter_operand) -- V Flag = OverflowFrom(Rn - shifter_operand) -- $(/del) t.newcpsr.ex.n := t.cpsr.ex.n; t.newcpsr.ex.z := t.cpsr.ex.z; t.newcpsr.ex.c := not t.cpsr.ex.c; t.newcpsr.ex.v := t.cpsr.ex.v; when type_arm_and => -- Logical And -- $(del) -- arm@4.1.4: --if ConditionPassed(cond) then -- Rd = Rn AND shifter_operand -- if S == 1 and Rd == R15 then -- CPSR = SPSR -- else if S == 1 then -- N Flag = Rd[31] -- Z Flag = if Rd == 0 then 1 else 0 -- C Flag = shifter_carry_out -- V Flag = unaffected -- $(/del) t.newcpsr.ex.n := t.cpsr.ex.n; t.newcpsr.ex.z := t.cpsr.ex.z; t.newcpsr.ex.c := r.pctrl.rs.rs_shieftcarryout; when type_arm_eor => -- Logical Exclusive Or -- $(del) -- arm@4.1.15: --if ConditionPassed(cond) then -- Rd = Rn EOR shifter_operand -- if S == 1 and Rd == R15 then -- CPSR = SPSR -- else if S == 1 then -- N Flag = Rd[31] -- Z Flag = if Rd == 0 then 1 else 0 -- C Flag = shifter_carry_out -- V Flag = unaffected -- $(/del) t.newcpsr.ex.n := t.cpsr.ex.n; t.newcpsr.ex.z := t.cpsr.ex.z; t.newcpsr.ex.c := r.pctrl.rs.rs_shieftcarryout; when type_arm_orr => -- Logical Or -- $(del) -- arm@4.1.35: --if ConditionPassed(cond) then -- Rd = Rn OR shifter_operand -- if S == 1 and Rd == R15 then -- CPSR = SPSR -- else if S == 1 then -- N Flag = Rd[31] -- Z Flag = if Rd == 0 then 1 else 0 -- C Flag = shifter_carry_out -- V Flag = unaffected -- $(/del) t.newcpsr.ex.n := t.cpsr.ex.n; t.newcpsr.ex.z := t.cpsr.ex.z; t.newcpsr.ex.c := r.pctrl.rs.rs_shieftcarryout; when type_arm_bic => -- Bit Clear -- $(del) -- arm@4.1.6: --if ConditionPassed(cond) then -- Rd = Rn AND NOT shifter_operand -- if S == 1 and Rd == R15 then -- CPSR = SPSR -- else if S == 1 then -- N Flag = Rd[31] -- Z Flag = if Rd == 0 then 1 else 0 -- C Flag = shifter_carry_out -- V Flag = unaffected -- $(/del) t.newcpsr.ex.n := t.cpsr.ex.n; t.newcpsr.ex.z := t.cpsr.ex.z; t.newcpsr.ex.c := r.pctrl.rs.rs_shieftcarryout; when type_arm_mov => -- -- $(del) -- arm@4.1.29: --if ConditionPassed(cond) then -- Rd = shifter_operand -- if S == 1 and Rd == R15 then -- CPSR = SPSR -- else if S == 1 then -- N Flag = Rd[31] -- Z Flag = if Rd == 0 then 1 else 0 -- C Flag = shifter_carry_out -- V Flag = unaffected -- $(/del) t.newcpsr.ex.n := t.cpsr.ex.n; t.newcpsr.ex.z := t.cpsr.ex.z; t.newcpsr.ex.c := r.pctrl.rs.rs_shieftcarryout; when type_arm_mvn => -- Move Negative -- $(del) -- arm@4.1.34: --if ConditionPassed(cond) then -- Rd = NOT shifter_operand -- if S == 1 and Rd == R15 then -- CPSR = SPSR -- else if S == 1 then -- N Flag = Rd[31] -- Z Flag = if Rd == 0 then 1 else 0 -- C Flag = shifter_carry_out -- V Flag = unaffected
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -