-- exeq to fetch feedback registers
EX2IF_REG_i : IN EX2IF_Type;
EX2IF_REG_o : OUT EX2IF_Type;
+ EX2CTRL_REG_i : IN EX2CTRL_Type;
-- exeq to core (halting)
exeq_halt_i : IN STD_LOGIC;
-- exeq to mem pipeline registers
SIGNAL rst_r : STD_LOGIC;
SIGNAL reset_s : STD_LOGIC;
- SIGNAL core_clken_s : STD_LOGIC;
+ SIGNAL core_clken_s : STD_LOGIC;
SIGNAL ID2EX_REG_r : ID2EX_Type;
SIGNAL EX2IF_REG_r : EX2IF_Type;
SIGNAL IMM_LOCK_r : IMM_LOCK_Type;
SIGNAL HAZARD_WRB_r : HAZARD_WRB_Type;
+ SIGNAL flush_second_r : STD_LOGIC;
SIGNAL delayBit_r : STD_LOGIC;
SIGNAL clken_s : STD_LOGIC;
SIGNAL clken_pipe_s : STD_LOGIC;
gprf_clken_o <= clken_s;
-- signals for clearing the ID2EX and EX2MEM registers during branches
flush_ID2EX_s <= ((EX2IF_REG_i.take_branch AND (NOT delayBit_r)) OR EX2IF_REG_r.take_branch) WHEN COMPATIBILITY_MODE_g = TRUE
- ELSE (EX2IF_REG_i.take_branch OR EX2IF_REG_r.take_branch);
+ ELSE (EX2IF_REG_i.take_branch OR EX2IF_REG_r.take_branch OR EX2CTRL_REG_i.flush_first OR flush_second_r);
flush_EX2MEM_s <= HAZARD_WRB_i.hazard;
-- outputs that need to be readable too, so needing shadowing signals
ID2EX_REG_o <= ID2EX_REG_r;
flush_ID2EX_s, flush_EX2MEM_s, HAZARD_WRB_i,
MEM_REG_i, ID2CTRL_i, int_i, MSR_i,
int_busy_r, IMM_LOCK_i, ID2EX_REG_i, ID2EX_REG_r,
- EX2IF_REG_i, EX_WRB_i, EX2MEM_REG_i )
+ EX2IF_REG_i, EX2CTRL_REG_i, EX_WRB_i, EX2MEM_REG_i )
-- some local procedures
PROCEDURE lp_rst_IF2ID_REG IS
lp_rst_MEM_REG;
IF (COMPATIBILITY_MODE_g = TRUE) THEN
- delayBit_r <= '0';
+ delayBit_r <= '0';
+ ELSE
+ flush_second_r <= '0';
END IF;
flush_ID2EX_r <= '0';
IF2ID_REG_o <= IF2ID_REG_i;
END IF;
flush_ID2EX_r <= flush_ID2EX_s;
+ IF (COMPATIBILITY_MODE_g = FALSE) THEN
+ flush_second_r <= EX2CTRL_REG_i.flush_second;
+ END IF;
HAZARD_WRB_r <= HAZARD_WRB_i;
MEM_REG_o <= MEM_REG_i;
int_busy_r <= ID2CTRL_i.int_busy;
lp_rst_IMM_LOCK;
ELSE
IF (clken_pipe_s = '1') THEN
- EX2IF_REG_r <= EX2IF_REG_i;
- EX_WRB_o <= EX_WRB_i;
+ EX2IF_REG_r <= EX2IF_REG_i;
+ EX_WRB_o <= EX_WRB_i;
END IF;
IF (clken_s = '1') THEN
-- next test to prevent a flush from disrupting
VARIABLE transfer_Size_v : TRANSFER_SIZE_Type;
VARIABLE wrb_Action_v : WRB_ACTION_Type;
VARIABLE int_busy_v : STD_LOGIC;
+ VARIABLE cmp_Cond_v : CMP_COND_Type;
+ VARIABLE cmp_Cond_Type_v : CMP_COND_TYPE_Type;
BEGIN
prog_counter_v := IF2ID_i.program_counter;
IMM_Lock_v := '0';
IF (COMPATIBILITY_MODE_g = TRUE) THEN
delayBit_v := '0';
+ ELSE
+ cmp_cond_v := COND_ALL;
+ cmp_cond_type_v := COND_TYPE_ALL;
END IF;
alu_Cin_v := CIN_ZERO;
alu_Action_v := A_NOP;
ELSE
alu_Action_v := A_CMP;
END IF;
+
+ IF (opcIx_v(3) = '0') THEN -- IT, ITT, ITE is not available to CMPI
+ CASE IMM16_v(4 downto 3) IS
+ WHEN "00" =>
+ cmp_Cond_Type_v := COND_TYPE_ALL;
+ WHEN "01" =>
+ cmp_Cond_Type_v := COND_TYPE_IF_THEN;
+ WHEN "10" =>
+ cmp_Cond_Type_v := COND_TYPE_IF_THEN_THEN;
+ WHEN "11" =>
+ cmp_Cond_Type_v := COND_TYPE_IF_THEN_ELSE;
+ WHEN OTHERS =>
+ NULL;
+ END CASE;
+
+ CASE IMM16_v(2 downto 0) IS
+ WHEN "001" =>
+ cmp_Cond_v := COND_EQ;
+ WHEN "010" =>
+ cmp_Cond_v := COND_NE;
+ WHEN "011" =>
+ cmp_Cond_v := COND_LT;
+ WHEN "100" =>
+ cmp_Cond_v := COND_LE;
+ WHEN "101" =>
+ cmp_Cond_v := COND_GT;
+ WHEN "110" =>
+ cmp_Cond_v := COND_GE;
+ WHEN OTHERS =>
+ NULL;
+ END CASE;
+ END IF;
ELSE
noLiteOpc_o <= '1';
END IF;
ID2EX_o.wrb_Action <= wrb_Action_v;
--
IF (COMPATIBILITY_MODE_g = TRUE) THEN
- ID2CTRL_o.delayBit <= delayBit_v;
+ ID2CTRL_o.delayBit <= delayBit_v;
+ ELSE
+ ID2EX_o.cmp_Cond <= cmp_Cond_v;
+ ID2EX_o.cmp_Cond_Type <= cmp_Cond_Type_v;
END IF;
- ID2CTRL_o.int_busy <= int_busy_v;
+ ID2CTRL_o.int_busy <= int_busy_v;
END PROCESS;
----------------------------------------------------------
GENERIC (
USE_HW_MUL_g : BOOLEAN := TRUE;
- USE_BARREL_g : BOOLEAN := TRUE
+ USE_BARREL_g : BOOLEAN := TRUE;
+ COMPATIBILITY_MODE_g : BOOLEAN := FALSE
);
PORT (
ID2EX_i : IN ID2EX_Type;
GPRF2EX_i : IN GPRF2EX_Type;
EX2IF_o : OUT EX2IF_Type;
+ EX2CTRL_o : OUT EX2CTRL_Type;
HALT_o : OUT HALT_Type;
--
EX_WRB_i : IN WRB_Type;
RETURN reversed_v;
END;
- VARIABLE data_rA_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
- VARIABLE data_rB_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
- VARIABLE data_rD_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
- VARIABLE in1_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
- VARIABLE in2_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
- VARIABLE hi16_v : STD_LOGIC_VECTOR (15 DOWNTO 0);
- VARIABLE IMM32_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
- VARIABLE carry_i_v : STD_LOGIC;
- VARIABLE result_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
- VARIABLE carry_o_v : STD_LOGIC;
- VARIABLE isZero_v : STD_LOGIC;
- VARIABLE signBit_in1_v : STD_LOGIC;
- VARIABLE signBit_in2_v : STD_LOGIC;
- VARIABLE signBit_rA_v : STD_LOGIC;
- VARIABLE rA_eq_ex_rD_v : STD_LOGIC;
- VARIABLE rB_eq_ex_rD_v : STD_LOGIC;
- VARIABLE hazard_v : STD_LOGIC;
- VARIABLE save_rX_v : SAVE_REG_Type;
- VARIABLE data_rX_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
- VARIABLE do_branch_v : STD_LOGIC;
- VARIABLE byte_Enable_v : STD_LOGIC_VECTOR ( 3 DOWNTO 0);
- VARIABLE tmp64_v : STD_LOGIC_VECTOR (63 DOWNTO 0);
- VARIABLE padVec_v : STD_LOGIC_VECTOR (15 DOWNTO 0);
- VARIABLE halt_v : STD_LOGIC;
- VARIABLE halt_code_v : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
+ VARIABLE data_rA_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
+ VARIABLE data_rB_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
+ VARIABLE data_rD_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
+ VARIABLE in1_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
+ VARIABLE in2_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
+ VARIABLE hi16_v : STD_LOGIC_VECTOR (15 DOWNTO 0);
+ VARIABLE IMM32_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
+ VARIABLE carry_i_v : STD_LOGIC;
+ VARIABLE result_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
+ VARIABLE carry_o_v : STD_LOGIC;
+ VARIABLE isZero_v : STD_LOGIC;
+ VARIABLE cmpResZero_v : STD_LOGIC;
+ VARIABLE signBit_in1_v : STD_LOGIC;
+ VARIABLE signBit_in2_v : STD_LOGIC;
+ VARIABLE signBit_rA_v : STD_LOGIC;
+ VARIABLE signBit_rD_v : STD_LOGIC;
+ VARIABLE rA_eq_ex_rD_v : STD_LOGIC;
+ VARIABLE rB_eq_ex_rD_v : STD_LOGIC;
+ VARIABLE hazard_v : STD_LOGIC;
+ VARIABLE save_rX_v : SAVE_REG_Type;
+ VARIABLE data_rX_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
+ VARIABLE do_branch_v : STD_LOGIC;
+ VARIABLE byte_Enable_v : STD_LOGIC_VECTOR ( 3 DOWNTO 0);
+ VARIABLE tmp64_v : STD_LOGIC_VECTOR (63 DOWNTO 0);
+ VARIABLE padVec_v : STD_LOGIC_VECTOR (15 DOWNTO 0);
+ VARIABLE halt_v : STD_LOGIC;
+ VARIABLE halt_code_v : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
+ VARIABLE do_cmp_cond_v : STD_LOGIC;
+ VARIABLE cmp_cond_type_v : CMP_COND_TYPE_Type;
BEGIN
- rA_eq_ex_rD_v := '0';
- rB_eq_ex_rD_v := '0';
- hazard_v := '0';
- save_rX_v := NO_SAVE;
- data_rX_v := data_rB_v; -- default value for data_rX_v
- result_v := (OTHERS => '0');
- carry_o_v := '0';
- do_branch_v := '0';
- byte_Enable_v := "0000";
- halt_v := '0';
- halt_code_v := "00000";
+ rA_eq_ex_rD_v := '0';
+ rB_eq_ex_rD_v := '0';
+ hazard_v := '0';
+ save_rX_v := NO_SAVE;
+ data_rX_v := data_rB_v; -- default value for data_rX_v
+ result_v := (OTHERS => '0');
+ carry_o_v := '0';
+ do_branch_v := '0';
+ byte_Enable_v := "0000";
+ halt_v := '0';
+ halt_code_v := "00000";
+ do_cmp_cond_v := '0';
+ cmp_cond_type_v := COND_TYPE_ALL;
+ signBit_rD_v := '0';
-- create some helper variables
IF (ID2EX_i.rdix_rA = EX_WRB_i.wrix_rD) THEN
WHEN OTHERS => carry_i_v := '0';
END CASE;
+ IF (data_rA_v = C_32_ZEROS) THEN
+ isZero_v := '1';
+ ELSE
+ isZero_v := '0';
+ END IF;
+
CASE ID2EX_i.alu_Action IS
WHEN A_ADD | A_CMP | A_CMPU =>
ep_add32 ( in1_v, in2_v, carry_i_v, result_v, carry_o_v);
IF (id2ex_i.alu_Action = A_CMPU) THEN
IF (signBit_in1_v = signBit_in2_v) THEN
- result_v(31) := NOT signBit_in1_v;
+ signBit_rD_v := NOT signBit_in1_v;
END IF;
ELSIF (id2ex_i.alu_Action = A_CMP) THEN
IF (signBit_in1_v = signBit_in2_v) THEN
- result_v(31) := signBit_in1_v;
+ signBit_rD_v := signBit_in1_v;
END IF;
END IF;
+
+ result_v(31) := signBit_rD_v;
+
+ IF (COMPATIBILITY_MODE_g = FALSE) THEN
+ IF (ID2EX_i.cmp_Cond /= COND_ALL) THEN
+ IF (result_v = C_32_ZEROS) THEN
+ cmpResZero_v := '1';
+ ELSE
+ cmpResZero_v := '0';
+ END IF;
+
+ CASE ID2EX_i.cmp_Cond IS
+ WHEN COND_EQ => do_cmp_cond_v := cmpResZero_v;
+ WHEN COND_NE => do_cmp_cond_v := NOT cmpResZero_v;
+ WHEN COND_LT => do_cmp_cond_v := signBit_rD_v;
+ WHEN COND_LE => do_cmp_cond_v := signBit_rD_v OR cmpResZero_v;
+ WHEN COND_GT => do_cmp_cond_v := NOT (signBit_rD_v OR cmpResZero_v);
+ WHEN COND_GE => do_cmp_cond_v := NOT signBit_rD_v;
+ WHEN OTHERS => NULL;
+ END CASE;
+
+ cmp_cond_type_v := ID2EX_i.cmp_Cond_Type;
+ END IF;
+ END IF;
+
WHEN A_OR =>
result_v := in1_v OR in2_v;
WHEN A_AND =>
NULL;
END CASE;
- IF (data_rA_v = C_32_ZEROS) THEN
- isZero_v := '1';
- ELSE
- isZero_v := '0';
- END IF;
CASE ID2EX_i.branch_Action IS
WHEN BR => do_branch_v := '1';
WHEN BRL => do_branch_v := '1';
EX2IF_o.branch_target <= C_32_ZEROS;
END IF;
+ -- CMP conditioning
+ IF (COMPATIBILITY_MODE_g = FALSE) THEN
+ CASE cmp_cond_type_v IS
+ WHEN COND_TYPE_ALL =>
+ EX2CTRL_o.flush_first <= '0';
+ EX2CTRL_o.flush_second <= '0';
+ WHEN COND_TYPE_IF_THEN =>
+ EX2CTRL_o.flush_first <= not do_cmp_cond_v;
+ EX2CTRL_o.flush_second <= '0';
+ WHEN COND_TYPE_IF_THEN_THEN =>
+ EX2CTRL_o.flush_first <= not do_cmp_cond_v;
+ EX2CTRL_o.flush_second <= not do_cmp_cond_v;
+ WHEN COND_TYPE_IF_THEN_ELSE =>
+ EX2CTRL_o.flush_first <= not do_cmp_cond_v;
+ EX2CTRL_o.flush_second <= do_cmp_cond_v;
+ WHEN OTHERS =>
+ NULL;
+ END CASE;
+ END IF;
+
-- Halting
HALT_o.halt <= halt_v;
HALT_o.halt_code <= halt_code_v;
TYPE MEM_ACTION_Type IS (NO_MEM, WR_MEM, RD_MEM);
TYPE TRANSFER_SIZE_Type IS (WORD, HALFWORD, BYTE);
TYPE SAVE_REG_Type IS (NO_SAVE, SAVE_RA, SAVE_RB);
+ TYPE CMP_COND_Type IS (COND_ALL, COND_EQ, COND_NE, COND_LT, COND_LE, COND_GT, COND_GE);
+ TYPE CMP_COND_TYPE_Type IS (COND_TYPE_ALL, COND_TYPE_IF_THEN, COND_TYPE_IF_THEN_THEN, COND_TYPE_IF_THEN_ELSE);
--
TYPE IF2ID_Type IS RECORD
program_counter : STD_LOGIC_VECTOR (31 DOWNTO 0);
mem_Action : MEM_ACTION_Type; -- rd_mem implies writeback
transfer_Size : TRANSFER_SIZE_Type;
wrb_Action : WRB_ACTION_Type;
+ cmp_Cond : CMP_COND_Type;
+ cmp_Cond_Type : CMP_COND_TYPE_Type;
END RECORD;
TYPE ID2GPRF_Type IS RECORD
branch_target : STD_LOGIC_VECTOR (31 DOWNTO 0);
END RECORD;
+ TYPE EX2CTRL_Type IS RECORD
+ flush_first : STD_LOGIC;
+ flush_second : STD_LOGIC;
+ END RECORD;
+
TYPE HALT_Type IS RECORD
halt : STD_LOGIC;
halt_code : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
COMPONENT exeq IS
GENERIC (
USE_HW_MUL_g : BOOLEAN := FALSE;
- USE_BARREL_g : BOOLEAN := FALSE
+ USE_BARREL_g : BOOLEAN := FALSE;
+ COMPATIBILITY_MODE_g : BOOLEAN := FALSE
);
PORT (
ID2EX_i : IN ID2EX_Type;
GPRF2EX_i : IN GPRF2EX_Type;
EX2IF_o : OUT EX2IF_Type;
+ EX2CTRL_o : OUT EX2CTRL_Type;
HALT_o : OUT HALT_Type;
--
EX_WRB_i : IN WRB_Type;
-- exeq to fetch feedback registers
EX2IF_REG_i : IN EX2IF_Type;
EX2IF_REG_o : OUT EX2IF_Type;
+ EX2CTRL_REG_i : IN EX2CTRL_Type;
-- exeq to core (halting)
exeq_halt_i : IN STD_LOGIC;
-- exeq to mem pipeline registers