- PROCESS (ID2EX_i, GPRF2EX_i, EX_WRB_i, MEM_WRB_i,
- IMM_LOCK_i, MSR_i, HAZARD_WRB_i)
-
- -- function needed by BSLL (only if USE_BARREL_g = TRUE)
- FUNCTION reverse_bits ( word32 : STD_LOGIC_VECTOR (31 DOWNTO 0) )
- RETURN STD_LOGIC_VECTOR IS
- VARIABLE reversed_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
- BEGIN
- f_rev:
- FOR i IN 0 TO 31 LOOP
- reversed_v(31-i) := word32(i);
- END LOOP;
- 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 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";
- 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
- rA_eq_ex_rD_v := '1';
- END IF;
- IF (ID2EX_i.rdix_rB = EX_WRB_i.wrix_rD) THEN
- rB_eq_ex_rD_v := '1';
- END IF;
- -- test where to obtain data_rA from
- IF ((EX_WRB_i.wrb_Action = WRB_EX) AND (rA_eq_ex_rD_v = '1')) THEN
- data_rA_v := EX_WRB_i.data_rD;
- ELSIF ((MEM_WRB_i.wrb_Action /= NO_WRB) AND (ID2EX_i.rdix_rA = MEM_WRB_i.wrix_rD)) THEN
- data_rA_v := MEM_WRB_i.data_rD;
- ELSIF ((HAZARD_WRB_i.hazard = '1') AND (HAZARD_WRB_i.save_rX = SAVE_RA)) THEN
- data_rA_v := HAZARD_WRB_i.data_rX;
- ELSE
- data_rA_v := GPRF2EX_i.data_rA;
- END IF;
- -- test where to obtain data_rB from
- IF ((EX_WRB_i.wrb_Action = WRB_EX) AND (rB_eq_ex_rD_v = '1')) THEN
- data_rB_v := EX_WRB_i.data_rD;
- ELSIF ((MEM_WRB_i.wrb_Action /= NO_WRB) AND (ID2EX_i.rdix_rB = MEM_WRB_i.wrix_rD)) THEN
- data_rB_v := MEM_WRB_i.data_rD;
- ELSIF ((HAZARD_WRB_i.hazard = '1') AND (HAZARD_WRB_i.save_rX = SAVE_RB)) THEN
- data_rB_v := HAZARD_WRB_i.data_rX;
- ELSE
- data_rB_v := GPRF2EX_i.data_rB;
- END IF;
- -- .... or, isn't all necessary data available yet being still in the pipeline ?
- data_rX_v := data_rB_v; -- default value for data_rX_v
- IF (EX_WRB_i.wrb_Action = WRB_MEM) THEN
- IF ((rA_eq_ex_rD_v = '1') OR (rB_eq_ex_rD_v = '1')) THEN
- hazard_v := '1';
--- always?? IF (MEM_WRB_i.wrb_Action = WRB_MEM) THEN
- -- handle situations in which both rA and rB needed
- IF (rA_eq_ex_rD_v = '1') THEN
- save_rX_v := SAVE_RB; -- already by default data_rX_v = data_rB_v
- ELSE
- save_rX_v := SAVE_RA;
- data_rX_v := data_rA_v;
- END IF;
--- END IF;
- END IF;
- END IF;
-
- IF (IMM_LOCK_i.locked = '1') THEN
- hi16_v := IMM_LOCK_i.IMM_hi16;
- ELSIF (ID2EX_i.IMM16(15) = '0') THEN
- hi16_v := C_16_ZEROS;
- ELSE
- hi16_v := C_16_ONES;
- END IF;
- IMM32_v := hi16_v & ID2EX_i.IMM16;
-
- CASE ID2EX_i.alu_Op1 IS
- WHEN ALU_IN_REGA => in1_v := data_rA_v;
- WHEN ALU_IN_NOT_REGA => in1_v := NOT data_rA_v;
- WHEN ALU_IN_PC => in1_v := ID2EX_i.program_counter;
- WHEN ALU_IN_ZERO => in1_v := C_32_ZEROS;
- WHEN OTHERS => NULL;
- END CASE;
-
- CASE ID2EX_i.alu_Op2 IS
- WHEN ALU_IN_REGB => in2_v := data_rB_v;
- WHEN ALU_IN_NOT_REGB => in2_v := NOT data_rB_v;
- WHEN ALU_IN_IMM => in2_v := IMM32_v;
- WHEN ALU_IN_NOT_IMM => in2_v := NOT IMM32_v;
- WHEN OTHERS => NULL;
- END CASE;
-
- signBit_in1_v := in1_v(31);
- signBit_in2_v := in2_v(31);
- signBit_rA_v := data_rA_v(31);
-
- CASE ID2EX_i.alu_Cin IS
- WHEN CIN_ZERO => carry_i_v := '0';
- WHEN CIN_ONE => carry_i_v := '1';
- WHEN FROM_MSR => carry_i_v := MSR_i.C;
- WHEN FROM_IN1 => carry_i_v := in1_v(31);
- 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
- 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
- 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 =>
- result_v := in1_v AND in2_v;
- WHEN A_XOR =>
- result_v := in1_v XOR in2_v;
- WHEN A_SHIFT =>
- result_v := carry_i_v & in1_v(31 DOWNTO 1);
- carry_o_v := in1_v(0);
- WHEN A_SEXT8 =>
- IF (in1_v(7) = '0') THEN
- result_v := C_24_ZEROS & in1_v( 7 DOWNTO 0);
- ELSE
- result_v := C_24_ONES & in1_v( 7 DOWNTO 0);
- END IF;
- WHEN A_SEXT16 =>
- IF (in1_v(15) = '0') THEN
- result_v := C_16_ZEROS & in1_v(15 DOWNTO 0);
- ELSE
- result_v := C_16_ONES & in1_v(15 DOWNTO 0);
- END IF;
- WHEN A_MFS =>
- result_v := MSR_i.C & C_24_ZEROS & "0000" & MSR_i.C & MSR_i.IE & '0';
- WHEN A_MTS =>
- MSR_o.IE <= data_Ra_v(1);
- MSR_o.C <= data_Ra_v(2);
- WHEN A_MUL =>
- IF (USE_HW_MUL_g = TRUE) THEN
- tmp64_v := STD_LOGIC_VECTOR( UNSIGNED(in1_v) * UNSIGNED(in2_v) );
- result_v := tmp64_v(31 DOWNTO 0);
- END IF;
- WHEN A_BSLL | A_BSRL | A_BSRA =>
- IF (USE_BARREL_g = TRUE) THEN
- IF (ID2EX_i.alu_Action = A_BSLL) THEN
- result_v := reverse_bits (in1_v);
- ELSE
- result_v := in1_v;
- END IF;
- IF (ID2EX_i.alu_Action = A_BSRA) THEN
- padVec_v := (OTHERS => in1_v(31));
- ELSE
- padVec_v := (OTHERS => '0');
- END IF;
- IF (in2_v(4) = '1') THEN
- result_v := padVec_v (15 DOWNTO 0) & result_v (31 DOWNTO 16);
- END IF;
- IF (in2_v(3) = '1') THEN
- result_v := padVec_v ( 7 DOWNTO 0) & result_v (31 DOWNTO 8);
- END IF;
- IF (in2_v(2) = '1') THEN
- result_v := padVec_v ( 3 DOWNTO 0) & result_v (31 DOWNTO 4);
- END IF;
- IF (in2_v(1) = '1') THEN
- result_v := padVec_v ( 1 DOWNTO 0) & result_v (31 DOWNTO 2);
- END IF;
- IF (in2_v(0) = '1') THEN
- result_v := padVec_v ( 0 DOWNTO 0) & result_v (31 DOWNTO 1);
- END IF;
- IF (ID2EX_i.alu_Action = A_BSLL) THEN
- result_v := reverse_bits (result_v);
- END IF;
- END IF; -- (USE_BARREL_g = TRUE)
- WHEN A_HALT =>
- halt_v := '1';
- halt_code_v := ID2EX_i.IMM16(4 DOWNTO 0);
- WHEN OTHERS =>
- NULL;
- END CASE;
-
- CASE ID2EX_i.branch_Action IS
- WHEN BR => do_branch_v := '1';
- WHEN BRL => do_branch_v := '1';
- WHEN BEQ => do_branch_v := isZero_v;
- WHEN BNE => do_branch_v := NOT isZero_v;
- WHEN BLT => do_branch_v := signBit_rA_v;
- WHEN BLE => do_branch_v := signBit_rA_v OR isZero_v;
- WHEN BGT => do_branch_v := NOT (signBit_rA_v OR isZero_v);
- WHEN BGE => do_branch_v := NOT signBit_rA_v;
- WHEN OTHERS => NULL;
- END CASE;
- IF (do_branch_v = '1') THEN
- EX2IF_o.take_branch <= '1';
- EX2IF_o.branch_target <= result_v;
- ELSE
- EX2IF_o.take_branch <= '0';
- 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;
-
- -- WR_MEM/RD_MEM: result_v --> exeq_result --> mem_address,
- -- WR_MEM: data_rD --> data_out_to_mem
- -- BRL: prog_counter --> exeq_result
- -- else result_v --> exeq_result (data_rD not used)
- EX2MEM_o.wrix_rD <= ID2EX_i.curr_rD;
- IF (ID2EX_i.branch_Action = BRL) THEN
- EX2MEM_o.wrb_Action <= WRB_EX;
- EX2MEM_o.exeq_result <= ID2EX_i.program_counter;
- EX2MEM_o.data_rD <= ID2EX_i.program_counter;
- -- set data_rD_v, although unused, to prevent an inferred latch
- data_rD_v := GPRF2EX_i.data_rD;
- ELSE
- EX2MEM_o.wrb_Action <= ID2EX_i.wrb_Action;
- EX2MEM_o.exeq_result <= result_v;
- -- test where to obtain data_rD from
- IF (HAZARD_WRB_i.hazard = '1') THEN
- data_rD_v := HAZARD_WRB_i.data_rD;
- ELSIF ((EX_WRB_i.wrb_Action = WRB_EX) AND (ID2EX_i.curr_rD = EX_WRB_i.wrix_rD)) THEN
- -- forward rD_data just calculated, to handle e.g. addi rD,rA,Imm; sw rD,mem[y]; ...
- data_rD_v := EX_WRB_i.data_rD;
- ELSIF ((MEM_WRB_i.wrb_Action /= NO_WRB) AND (ID2EX_i.curr_rD = MEM_WRB_i.wrix_rD)) THEN
- data_rD_v := MEM_WRB_i.data_rD;
- ELSE
- data_rD_v := GPRF2EX_i.data_rD;
- END IF;
- END IF;
- IF (ID2EX_i.mem_Action /= NO_MEM) THEN
- CASE ID2EX_i.transfer_Size IS
- WHEN BYTE =>
- CASE result_v( 1 DOWNTO 0) IS
- WHEN "00" => byte_Enable_v := "1000";
- WHEN "01" => byte_Enable_v := "0100";
- WHEN "10" => byte_Enable_v := "0010";
- WHEN "11" => byte_Enable_v := "0001";
- WHEN OTHERS => NULL;
- END CASE;
- WHEN HALFWORD =>
- CASE result_v( 1 DOWNTO 0) IS
- WHEN "00" => byte_Enable_v := "1100";
- WHEN "10" => byte_Enable_v := "0011";
- WHEN OTHERS => NULL;
- END CASE;
- WHEN OTHERS => byte_Enable_v := "1111";
- END CASE;
- END IF;
-
- -- update MSR[IE] and/or MSR[C] if needed
- IF (ID2EX_i.alu_Action /= A_MTS) THEN
- MSR_o.IE <= MSR_i.IE;
- IF (ID2EX_i.msr_Action = UPDATE_CARRY) THEN
- MSR_o.C <= carry_o_v;
- ELSE
- MSR_o.C <= MSR_i.C;
- END IF;
- END IF;
-
- -- pass remaining data to mem
- EX2MEM_o.mem_Action <= ID2EX_i.mem_Action;
- EX2MEM_o.data_rD <= data_rD_v;
- EX2MEM_o.byte_Enable <= byte_Enable_v;
- EX2MEM_o.wrix_rD <= ID2EX_i.curr_rD;
- --
- IMM_LOCK_o.locked <= ID2EX_i.IMM_Lock;
- IMM_LOCK_o.IMM_hi16 <= ID2EX_i.IMM16;
- --
- EX_WRB_o.wrb_Action <= ID2EX_i.wrb_Action;
- EX_WRB_o.wrix_rD <= ID2EX_i.curr_rD;
- EX_WRB_o.data_rD <= result_v;
- --
- HAZARD_WRB_o.hazard <= hazard_v;
- HAZARD_WRB_o.save_rX <= save_rX_v;
- HAZARD_WRB_o.data_rX <= data_rX_v;
- HAZARD_WRB_o.data_rD <= data_rD_v;
-
- END PROCESS;
+ PROCESS (ID2EX_i, GPRF2EX_i, EX_WRB_i, MEM_WRB_i,
+ IMM_LOCK_i, MSR_i, HAZARD_WRB_i)
+
+ -- function needed by BSLL (only if USE_BARREL_g = TRUE)
+ FUNCTION reverse_bits ( word32 : STD_LOGIC_VECTOR (31 DOWNTO 0) )
+ RETURN STD_LOGIC_VECTOR IS
+ VARIABLE reversed_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
+ BEGIN
+ f_rev:
+ FOR i IN 0 TO 31 LOOP
+ reversed_v(31-i) := word32(i);
+ END LOOP;
+ 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_r_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 do_cond_v : STD_LOGIC;
+
+ 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 := (OTHERS => '0');
+ do_cond_v := '0';
+ --
+ MSR_o <= MSR_i; -- pass MSR by default
+
+ -- create some helper variables
+ IF (ID2EX_i.rdix_rA = EX_WRB_i.wrix_rD) THEN
+ rA_eq_ex_rD_v := '1';
+ END IF;
+ IF (ID2EX_i.rdix_rB = EX_WRB_i.wrix_rD) THEN
+ rB_eq_ex_rD_v := '1';
+ END IF;
+ -- test where to obtain data_rA from
+ IF ((EX_WRB_i.wrb_Action = WRB_EX) AND (rA_eq_ex_rD_v = '1')) THEN
+ data_rA_v := EX_WRB_i.data_rD;
+ ELSIF ((MEM_WRB_i.wrb_Action /= NO_WRB) AND (ID2EX_i.rdix_rA = MEM_WRB_i.wrix_rD)) THEN
+ data_rA_v := MEM_WRB_i.data_rD;
+ ELSIF ((HAZARD_WRB_i.hazard = '1') AND (HAZARD_WRB_i.save_rX = SAVE_RA)) THEN
+ data_rA_v := HAZARD_WRB_i.data_rX;
+ ELSE
+ data_rA_v := GPRF2EX_i.data_rA;
+ END IF;
+ -- test where to obtain data_rB from
+ IF ((EX_WRB_i.wrb_Action = WRB_EX) AND (rB_eq_ex_rD_v = '1')) THEN
+ data_rB_v := EX_WRB_i.data_rD;
+ ELSIF ((MEM_WRB_i.wrb_Action /= NO_WRB) AND (ID2EX_i.rdix_rB = MEM_WRB_i.wrix_rD)) THEN
+ data_rB_v := MEM_WRB_i.data_rD;
+ ELSIF ((HAZARD_WRB_i.hazard = '1') AND (HAZARD_WRB_i.save_rX = SAVE_RB)) THEN
+ data_rB_v := HAZARD_WRB_i.data_rX;
+ ELSE
+ data_rB_v := GPRF2EX_i.data_rB;
+ END IF;
+ -- .... or, isn't all necessary data available yet being still in the pipeline ?
+ data_rX_v := data_rB_v; -- default value for data_rX_v
+ IF (EX_WRB_i.wrb_Action = WRB_MEM) THEN
+ IF ((rA_eq_ex_rD_v = '1') OR (rB_eq_ex_rD_v = '1')) THEN
+ hazard_v := '1';
+ IF (rA_eq_ex_rD_v = '1') THEN
+ save_rX_v := SAVE_RB; -- already by default data_rX_v = data_rB_v
+ ELSE
+ save_rX_v := SAVE_RA;
+ data_rX_v := data_rA_v;
+ END IF;
+ END IF;
+ END IF;
+
+ IF (IMM_LOCK_i.locked = '1') THEN
+ hi16_v := IMM_LOCK_i.IMM_hi16;
+ ELSIF (ID2EX_i.IMM16(15) = '0') THEN
+ hi16_v := C_16_ZEROS;
+ ELSE
+ hi16_v := C_16_ONES;
+ END IF;
+ IMM32_v := hi16_v & ID2EX_i.IMM16;
+
+ CASE ID2EX_i.alu_Op1 IS
+ WHEN ALU_IN_REGA => in1_v := data_rA_v;
+ WHEN ALU_IN_NOT_REGA => in1_v := NOT data_rA_v;
+ WHEN ALU_IN_PC => in1_v := ID2EX_i.program_counter;
+ WHEN ALU_IN_ZERO => in1_v := C_32_ZEROS;
+ WHEN OTHERS => NULL;
+ END CASE;
+
+ CASE ID2EX_i.alu_Op2 IS
+ WHEN ALU_IN_REGB => in2_v := data_rB_v;
+ WHEN ALU_IN_NOT_REGB => in2_v := NOT data_rB_v;
+ WHEN ALU_IN_IMM => in2_v := IMM32_v;
+ WHEN ALU_IN_NOT_IMM => in2_v := NOT IMM32_v;
+ WHEN OTHERS => NULL;
+ END CASE;
+
+ signBit_in1_v := in1_v(31);
+ signBit_in2_v := in2_v(31);
+ signBit_r_v := data_rA_v(31); -- Init with Op1, then possibly override
+
+ CASE ID2EX_i.alu_Cin IS
+ WHEN CIN_ZERO => carry_i_v := '0';
+ WHEN CIN_ONE => carry_i_v := '1';
+ WHEN FROM_MSR => carry_i_v := MSR_i.C;
+ WHEN FROM_IN1 => carry_i_v := in1_v(31);
+ 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);
+ CASE ID2EX_i.alu_Action IS
+
+ WHEN A_CMPU =>
+ IF (signBit_in1_v = signBit_in2_v) THEN
+ signBit_r_v := NOT signBit_in1_v;
+ END IF;
+ IF (COMPATIBILITY_MODE_g = FALSE) AND (ID2EX_i.it_Action /= NO_IT) THEN
+ -- have to update zero flag with current result
+ IF (result_v = C_32_ZEROS) THEN
+ isZero_v := '1';
+ ELSE
+ isZero_v := '0';
+ END IF;
+ END IF;
+
+ WHEN A_CMP =>
+ IF (signBit_in1_v = signBit_in2_v) THEN
+ signBit_r_v := signBit_in1_v;
+ END IF;
+ IF (COMPATIBILITY_MODE_g = FALSE) AND (ID2EX_i.it_Action /= NO_IT) THEN
+ -- have to update zero flag with current result
+ IF (result_v = C_32_ZEROS) THEN
+ isZero_v := '1';
+ ELSE
+ isZero_v := '0';
+ END IF;
+ END IF;
+
+ WHEN OTHERS =>
+ NULL;
+
+ END CASE;
+
+ WHEN A_OR =>
+ result_v := in1_v OR in2_v;
+
+ WHEN A_AND =>
+ result_v := in1_v AND in2_v;
+
+ WHEN A_XOR =>
+ result_v := in1_v XOR in2_v;
+
+ WHEN A_SHIFT =>
+ result_v := carry_i_v & in1_v(31 DOWNTO 1);
+ carry_o_v := in1_v(0);
+
+ WHEN A_SEXT8 =>
+ IF (in1_v(7) = '0') THEN
+ result_v := C_24_ZEROS & in1_v( 7 DOWNTO 0);
+ ELSE
+ result_v := C_24_ONES & in1_v( 7 DOWNTO 0);
+ END IF;
+
+ WHEN A_SEXT16 =>
+ IF (in1_v(15) = '0') THEN
+ result_v := C_16_ZEROS & in1_v(15 DOWNTO 0);
+ ELSE
+ result_v := C_16_ONES & in1_v(15 DOWNTO 0);
+ END IF;
+
+ WHEN A_MFS =>
+ result_v := MSR_i.C & C_24_ZEROS & "0000" & MSR_i.C & MSR_i.IE & '0';
+
+ WHEN A_MTS =>
+ MSR_o.IE <= data_Ra_v(1);
+ MSR_o.C <= data_Ra_v(2);
+
+ WHEN A_MUL =>
+ IF (USE_HW_MUL_g = TRUE) THEN
+ tmp64_v := STD_LOGIC_VECTOR( UNSIGNED(in1_v) * UNSIGNED(in2_v) );
+ result_v := tmp64_v(31 DOWNTO 0);
+ END IF;
+
+ WHEN A_BSLL | A_BSRL | A_BSRA =>
+ IF (USE_BARREL_g = TRUE) THEN
+ IF (ID2EX_i.alu_Action = A_BSLL) THEN
+ result_v := reverse_bits (in1_v);
+ ELSE
+ result_v := in1_v;
+ END IF;
+ IF (ID2EX_i.alu_Action = A_BSRA) THEN
+ padVec_v := (OTHERS => in1_v(31));
+ ELSE
+ padVec_v := (OTHERS => '0');
+ END IF;
+ IF (in2_v(4) = '1') THEN
+ result_v := padVec_v (15 DOWNTO 0) & result_v (31 DOWNTO 16);
+ END IF;
+ IF (in2_v(3) = '1') THEN
+ result_v := padVec_v ( 7 DOWNTO 0) & result_v (31 DOWNTO 8);
+ END IF;
+ IF (in2_v(2) = '1') THEN
+ result_v := padVec_v ( 3 DOWNTO 0) & result_v (31 DOWNTO 4);
+ END IF;
+ IF (in2_v(1) = '1') THEN
+ result_v := padVec_v ( 1 DOWNTO 0) & result_v (31 DOWNTO 2);
+ END IF;
+ IF (in2_v(0) = '1') THEN
+ result_v := padVec_v ( 0 DOWNTO 0) & result_v (31 DOWNTO 1);
+ END IF;
+ IF (ID2EX_i.alu_Action = A_BSLL) THEN
+ result_v := reverse_bits (result_v);
+ END IF;
+ END IF; -- (USE_BARREL_g = TRUE)
+
+ WHEN OTHERS =>
+ NULL;
+
+ END CASE;
+
+ CASE ID2EX_i.condition IS
+ WHEN COND_EQ => do_cond_v := isZero_v;
+ WHEN COND_NE => do_cond_v := NOT isZero_v;
+ WHEN COND_LT => do_cond_v := signBit_r_v;
+ WHEN COND_LE => do_cond_v := signBit_r_v OR isZero_v;
+ WHEN COND_GT => do_cond_v := NOT (signBit_r_v OR isZero_v);
+ WHEN COND_GE => do_cond_v := NOT signBit_r_v;
+ WHEN COND_ALL => do_cond_v := '1';
+ WHEN OTHERS => NULL;
+ END CASE;
+
+ CASE ID2EX_i.branch_Action IS
+ WHEN BR => do_branch_v := do_cond_v;
+ WHEN BRL => do_branch_v := '1';
+ WHEN OTHERS => NULL;
+ END CASE;
+
+ IF (do_branch_v = '1') THEN
+ EX2IF_o.take_branch <= '1';
+ EX2IF_o.branch_target <= result_v;
+ ELSE
+ EX2IF_o.take_branch <= '0';
+ EX2IF_o.branch_target <= C_32_ZEROS;
+ END IF;
+
+ -- IT / ITE / ITT conditioning
+ IF (COMPATIBILITY_MODE_g = FALSE) THEN
+ CASE ID2EX_i.it_Action IS
+ WHEN IT =>
+ EX2CTRL_o.flush_first <= not do_cond_v;
+ EX2CTRL_o.flush_second <= '0';
+ EX2CTRL_o.ignore_state <= '1';
+ WHEN ITT =>
+ EX2CTRL_o.flush_first <= not do_cond_v;
+ EX2CTRL_o.flush_second <= not do_cond_v;
+ EX2CTRL_o.ignore_state <= '1';
+ WHEN ITE =>
+ EX2CTRL_o.flush_first <= not do_cond_v;
+ EX2CTRL_o.flush_second <= do_cond_v;
+ EX2CTRL_o.ignore_state <= '1';
+ WHEN OTHERS =>
+ EX2CTRL_o.flush_first <= '0';
+ EX2CTRL_o.flush_second <= '0';
+ EX2CTRL_o.ignore_state <= '0';
+ END CASE;
+ END IF;
+
+ -- Halting, the instruction parsing is separate
+ HALT_o.halt <= ID2EX_i.halt;
+ IF (ID2EX_i.halt = '1') THEN
+ HALT_o.halt_code <= ID2EX_i.IMM16(4 DOWNTO 0);
+ ELSE
+ HALT_o.halt_code <= (others => '0');
+ END IF;
+
+ -- WR_MEM/RD_MEM: result_v --> exeq_result --> mem_address,
+ -- WR_MEM: data_rD --> data_out_to_mem
+ -- BRL: prog_counter --> exeq_result
+ -- else result_v --> exeq_result (data_rD not used)
+ EX2MEM_o.wrix_rD <= ID2EX_i.curr_rD;
+ IF (ID2EX_i.branch_Action = BRL) THEN
+ EX2MEM_o.wrb_Action <= WRB_EX;
+ EX2MEM_o.exeq_result <= ID2EX_i.program_counter;
+ EX2MEM_o.data_rD <= ID2EX_i.program_counter;
+ -- set data_rD_v, although unused, to prevent an inferred latch
+ data_rD_v := GPRF2EX_i.data_rD;
+ ELSE
+ EX2MEM_o.wrb_Action <= ID2EX_i.wrb_Action;
+ EX2MEM_o.exeq_result <= result_v;
+ -- test where to obtain data_rD from
+ IF (HAZARD_WRB_i.hazard = '1') THEN
+ data_rD_v := HAZARD_WRB_i.data_rD;
+ ELSIF ((EX_WRB_i.wrb_Action = WRB_EX) AND (ID2EX_i.curr_rD = EX_WRB_i.wrix_rD)) THEN
+ -- forward rD_data just calculated, to handle e.g. addi rD,rA,Imm; sw rD,mem[y]; ...
+ data_rD_v := EX_WRB_i.data_rD;
+ ELSIF ((MEM_WRB_i.wrb_Action /= NO_WRB) AND (ID2EX_i.curr_rD = MEM_WRB_i.wrix_rD)) THEN
+ data_rD_v := MEM_WRB_i.data_rD;
+ ELSE
+ data_rD_v := GPRF2EX_i.data_rD;
+ END IF;
+ END IF;
+
+ IF (ID2EX_i.mem_Action /= NO_MEM) THEN
+ CASE ID2EX_i.transfer_Size IS
+
+ WHEN BYTE =>
+ CASE result_v( 1 DOWNTO 0) IS
+ WHEN "00" => byte_Enable_v := "1000";
+ WHEN "01" => byte_Enable_v := "0100";
+ WHEN "10" => byte_Enable_v := "0010";
+ WHEN "11" => byte_Enable_v := "0001";
+ WHEN OTHERS => NULL;
+ END CASE;
+
+ WHEN HALFWORD =>
+ CASE result_v( 1 DOWNTO 0) IS
+ WHEN "00" => byte_Enable_v := "1100";
+ WHEN "10" => byte_Enable_v := "0011";
+ WHEN OTHERS => NULL;
+ END CASE;
+
+ WHEN OTHERS => byte_Enable_v := "1111";
+
+ END CASE;
+ END IF;
+
+ -- update MSR[C] if needed
+ IF (ID2EX_i.msr_Action = UPDATE_CARRY) THEN
+ MSR_o.C <= carry_o_v;
+ END IF;
+
+ -- pass remaining data to mem
+ EX2MEM_o.mem_Action <= ID2EX_i.mem_Action;
+ EX2MEM_o.data_rD <= data_rD_v;
+ EX2MEM_o.byte_Enable <= byte_Enable_v;
+ EX2MEM_o.wrix_rD <= ID2EX_i.curr_rD;
+ --
+ IMM_LOCK_o.locked <= ID2EX_i.IMM_Lock;
+ IMM_LOCK_o.IMM_hi16 <= ID2EX_i.IMM16;
+ --
+ EX_WRB_o.wrb_Action <= ID2EX_i.wrb_Action;
+ EX_WRB_o.wrix_rD <= ID2EX_i.curr_rD;
+ EX_WRB_o.data_rD <= result_v;
+ --
+ HAZARD_WRB_o.hazard <= hazard_v;
+ HAZARD_WRB_o.save_rX <= save_rX_v;
+ HAZARD_WRB_o.data_rX <= data_rX_v;
+ HAZARD_WRB_o.data_rD <= data_rD_v;
+
+ END PROCESS;