📄 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 + -