1 ---------------------------------------------------------------------------------
5 -- Description: the Execution (EX) unit for the TUD MB-Lite implementation
7 -- Author: Huib Lincklaen Arriens
8 -- Delft University of Technology
9 -- Faculty EEMCS, Department ME&CE, Circuits and Systems
10 -- Date: September, 2010
12 -- Modified: Septemper, 2013: FSL scratched, core customized (Meloun)
13 -- December, 2010: FSL added (Huib)
14 -- June, 2011: added code for MUL and BARREL (Huib)
15 -- Adapted to work with separate fsl_M-
16 -- and fsl_S selectors and automatic
17 -- tumbl<_jtag><_fsl>.vhd generation (Huib)
20 --------------------------------------------------------------------------------
24 USE IEEE.std_logic_1164.all;
25 USE IEEE.numeric_std.all;
29 ----------------------------------------------------------
31 ----------------------------------------------------------
34 USE_HW_MUL_g : BOOLEAN := TRUE;
35 USE_BARREL_g : BOOLEAN := TRUE;
36 COMPATIBILITY_MODE_g : BOOLEAN := FALSE
40 IF2ID_i : IN IF2ID_Type;
42 ID2EX_i : IN ID2EX_Type;
43 delayBit_i : IN STD_LOGIC;
44 GPRF2EX_i : IN GPRF2EX_Type;
45 EX2IF_o : OUT EX2IF_Type;
46 EX2CTRL_o : OUT EX2CTRL_Type;
47 HALT_o : OUT HALT_Type;
49 EX_WRB_i : IN WRB_Type;
50 EX_WRB_o : OUT WRB_Type;
51 MEM_WRB_i : IN WRB_Type;
53 HAZARD_WRB_i : IN HAZARD_WRB_Type;
54 HAZARD_WRB_o : OUT HAZARD_WRB_Type;
56 IMM_LOCK_i : IN IMM_LOCK_Type;
57 IMM_LOCK_o : OUT IMM_LOCK_Type;
62 EX2MEM_o : OUT EX2MEM_Type
66 ----------------------------------------------------------
67 ARCHITECTURE rtl OF exeq IS
68 ----------------------------------------------------------
73 PROCESS (ID2EX_i, GPRF2EX_i, EX_WRB_i, MEM_WRB_i,
74 IF2ID_i, delayBit_i, IMM_LOCK_i, MSR_i, HAZARD_WRB_i)
76 -- function needed by BSLL (only if USE_BARREL_g = TRUE)
77 FUNCTION reverse_bits ( word32 : STD_LOGIC_VECTOR (31 DOWNTO 0) )
78 RETURN STD_LOGIC_VECTOR IS
79 VARIABLE reversed_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
83 reversed_v(31-i) := word32(i);
88 VARIABLE data_rA_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
89 VARIABLE data_rB_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
90 VARIABLE data_rD_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
91 VARIABLE in1_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
92 VARIABLE in2_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
93 VARIABLE hi16_v : STD_LOGIC_VECTOR (15 DOWNTO 0);
94 VARIABLE IMM32_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
95 VARIABLE carry_i_v : STD_LOGIC;
96 VARIABLE result_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
97 VARIABLE carry_o_v : STD_LOGIC;
98 VARIABLE isZero_v : STD_LOGIC;
99 VARIABLE signBit_in1_v : STD_LOGIC;
100 VARIABLE signBit_in2_v : STD_LOGIC;
101 VARIABLE signBit_r_v : STD_LOGIC;
102 VARIABLE rA_eq_ex_rD_v : STD_LOGIC;
103 VARIABLE rB_eq_ex_rD_v : STD_LOGIC;
104 VARIABLE hazard_v : STD_LOGIC;
105 VARIABLE save_rX_v : SAVE_REG_Type;
106 VARIABLE data_rX_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
107 VARIABLE do_branch_v : STD_LOGIC;
108 VARIABLE byte_Enable_v : STD_LOGIC_VECTOR ( 3 DOWNTO 0);
109 VARIABLE tmp64_v : STD_LOGIC_VECTOR (63 DOWNTO 0);
110 VARIABLE padVec_v : STD_LOGIC_VECTOR (15 DOWNTO 0);
111 VARIABLE do_cond_v : STD_LOGIC;
115 rA_eq_ex_rD_v := '0';
116 rB_eq_ex_rD_v := '0';
118 save_rX_v := NO_SAVE;
119 data_rX_v := data_rB_v; -- default value for data_rX_v
120 result_v := (OTHERS => '0');
123 byte_Enable_v := (OTHERS => '0');
126 MSR_o <= MSR_i; -- pass MSR by default
128 -- create some helper variables
129 IF (ID2EX_i.rdix_rA = EX_WRB_i.wrix_rD) THEN
130 rA_eq_ex_rD_v := '1';
132 IF (ID2EX_i.rdix_rB = EX_WRB_i.wrix_rD) THEN
133 rB_eq_ex_rD_v := '1';
135 -- test where to obtain data_rA from
136 IF ((EX_WRB_i.wrb_Action = WRB_EX) AND (rA_eq_ex_rD_v = '1')) THEN
137 data_rA_v := EX_WRB_i.data_rD;
138 ELSIF ((MEM_WRB_i.wrb_Action /= NO_WRB) AND (ID2EX_i.rdix_rA = MEM_WRB_i.wrix_rD)) THEN
139 data_rA_v := MEM_WRB_i.data_rD;
140 ELSIF ((HAZARD_WRB_i.hazard = '1') AND (HAZARD_WRB_i.save_rX = SAVE_RA)) THEN
141 data_rA_v := HAZARD_WRB_i.data_rX;
143 data_rA_v := GPRF2EX_i.data_rA;
145 -- test where to obtain data_rB from
146 IF ((EX_WRB_i.wrb_Action = WRB_EX) AND (rB_eq_ex_rD_v = '1')) THEN
147 data_rB_v := EX_WRB_i.data_rD;
148 ELSIF ((MEM_WRB_i.wrb_Action /= NO_WRB) AND (ID2EX_i.rdix_rB = MEM_WRB_i.wrix_rD)) THEN
149 data_rB_v := MEM_WRB_i.data_rD;
150 ELSIF ((HAZARD_WRB_i.hazard = '1') AND (HAZARD_WRB_i.save_rX = SAVE_RB)) THEN
151 data_rB_v := HAZARD_WRB_i.data_rX;
153 data_rB_v := GPRF2EX_i.data_rB;
155 -- .... or, isn't all necessary data available yet being still in the pipeline ?
156 data_rX_v := data_rB_v; -- default value for data_rX_v
157 IF (EX_WRB_i.wrb_Action = WRB_MEM) THEN
158 IF ((rA_eq_ex_rD_v = '1') OR (rB_eq_ex_rD_v = '1')) THEN
160 IF (rA_eq_ex_rD_v = '1') THEN
161 save_rX_v := SAVE_RB; -- already by default data_rX_v = data_rB_v
163 save_rX_v := SAVE_RA;
164 data_rX_v := data_rA_v;
169 IF (IMM_LOCK_i.locked = '1') THEN
170 hi16_v := IMM_LOCK_i.IMM_hi16;
171 ELSIF (ID2EX_i.IMM16(15) = '0') THEN
172 hi16_v := C_16_ZEROS;
176 IMM32_v := hi16_v & ID2EX_i.IMM16;
178 CASE ID2EX_i.alu_Op1 IS
179 WHEN ALU_IN_REGA => in1_v := data_rA_v;
180 WHEN ALU_IN_NOT_REGA => in1_v := NOT data_rA_v;
181 WHEN ALU_IN_PC => in1_v := ID2EX_i.program_counter;
182 WHEN ALU_IN_ZERO => in1_v := C_32_ZEROS;
186 CASE ID2EX_i.alu_Op2 IS
187 WHEN ALU_IN_REGB => in2_v := data_rB_v;
188 WHEN ALU_IN_NOT_REGB => in2_v := NOT data_rB_v;
189 WHEN ALU_IN_IMM => in2_v := IMM32_v;
190 WHEN ALU_IN_NOT_IMM => in2_v := NOT IMM32_v;
194 signBit_in1_v := in1_v(31);
195 signBit_in2_v := in2_v(31);
196 signBit_r_v := data_rA_v(31); -- Init with Op1, then possibly override
198 CASE ID2EX_i.alu_Cin IS
199 WHEN CIN_ZERO => carry_i_v := '0';
200 WHEN CIN_ONE => carry_i_v := '1';
201 WHEN FROM_MSR => carry_i_v := MSR_i.C;
202 WHEN FROM_IN1 => carry_i_v := in1_v(31);
203 WHEN OTHERS => carry_i_v := '0';
206 IF (data_rA_v = C_32_ZEROS) THEN
212 CASE ID2EX_i.alu_Action IS
214 WHEN A_ADD | A_CMP | A_CMPU =>
215 ep_add32 ( in1_v, in2_v, carry_i_v, result_v, carry_o_v);
216 CASE ID2EX_i.alu_Action IS
219 IF (signBit_in1_v = signBit_in2_v) THEN
220 signBit_r_v := NOT signBit_in1_v;
222 IF (COMPATIBILITY_MODE_g = FALSE) AND (ID2EX_i.it_Action /= NO_IT) THEN
223 -- have to update zero flag with current result
224 IF (result_v = C_32_ZEROS) THEN
232 IF (signBit_in1_v = signBit_in2_v) THEN
233 signBit_r_v := signBit_in1_v;
235 IF (COMPATIBILITY_MODE_g = FALSE) AND (ID2EX_i.it_Action /= NO_IT) THEN
236 -- have to update zero flag with current result
237 IF (result_v = C_32_ZEROS) THEN
250 result_v := in1_v OR in2_v;
253 result_v := in1_v AND in2_v;
256 result_v := in1_v XOR in2_v;
259 result_v := carry_i_v & in1_v(31 DOWNTO 1);
260 carry_o_v := in1_v(0);
263 IF (in1_v(7) = '0') THEN
264 result_v := C_24_ZEROS & in1_v( 7 DOWNTO 0);
266 result_v := C_24_ONES & in1_v( 7 DOWNTO 0);
270 IF (in1_v(15) = '0') THEN
271 result_v := C_16_ZEROS & in1_v(15 DOWNTO 0);
273 result_v := C_16_ONES & in1_v(15 DOWNTO 0);
277 result_v := MSR_i.C & C_24_ZEROS & "0000" & MSR_i.C & MSR_i.IE & '0';
280 MSR_o.IE <= data_Ra_v(1);
281 MSR_o.C <= data_Ra_v(2);
284 IF (USE_HW_MUL_g = TRUE) THEN
285 tmp64_v := STD_LOGIC_VECTOR( UNSIGNED(in1_v) * UNSIGNED(in2_v) );
286 result_v := tmp64_v(31 DOWNTO 0);
289 WHEN A_BSLL | A_BSRL | A_BSRA =>
290 IF (USE_BARREL_g = TRUE) THEN
291 IF (ID2EX_i.alu_Action = A_BSLL) THEN
292 result_v := reverse_bits (in1_v);
296 IF (ID2EX_i.alu_Action = A_BSRA) THEN
297 padVec_v := (OTHERS => in1_v(31));
299 padVec_v := (OTHERS => '0');
301 IF (in2_v(4) = '1') THEN
302 result_v := padVec_v (15 DOWNTO 0) & result_v (31 DOWNTO 16);
304 IF (in2_v(3) = '1') THEN
305 result_v := padVec_v ( 7 DOWNTO 0) & result_v (31 DOWNTO 8);
307 IF (in2_v(2) = '1') THEN
308 result_v := padVec_v ( 3 DOWNTO 0) & result_v (31 DOWNTO 4);
310 IF (in2_v(1) = '1') THEN
311 result_v := padVec_v ( 1 DOWNTO 0) & result_v (31 DOWNTO 2);
313 IF (in2_v(0) = '1') THEN
314 result_v := padVec_v ( 0 DOWNTO 0) & result_v (31 DOWNTO 1);
316 IF (ID2EX_i.alu_Action = A_BSLL) THEN
317 result_v := reverse_bits (result_v);
319 END IF; -- (USE_BARREL_g = TRUE)
326 CASE ID2EX_i.condition IS
327 WHEN COND_EQ => do_cond_v := isZero_v;
328 WHEN COND_NE => do_cond_v := NOT isZero_v;
329 WHEN COND_LT => do_cond_v := signBit_r_v;
330 WHEN COND_LE => do_cond_v := signBit_r_v OR isZero_v;
331 WHEN COND_GT => do_cond_v := NOT (signBit_r_v OR isZero_v);
332 WHEN COND_GE => do_cond_v := NOT signBit_r_v;
333 WHEN COND_ALL => do_cond_v := '1';
337 CASE ID2EX_i.branch_Action IS
338 WHEN BR => do_branch_v := do_cond_v;
339 WHEN BRL => do_branch_v := '1';
343 IF (do_branch_v = '1') THEN
344 EX2IF_o.take_branch <= '1';
345 EX2IF_o.branch_target <= result_v;
347 EX2IF_o.take_branch <= '0';
348 EX2IF_o.branch_target <= C_32_ZEROS;
351 -- IT / ITE / ITT conditioning
352 IF (COMPATIBILITY_MODE_g = FALSE) THEN
353 CASE ID2EX_i.it_Action IS
355 EX2CTRL_o.flush_first <= not do_cond_v;
356 EX2CTRL_o.flush_second <= '0';
357 EX2CTRL_o.ignore_state <= '1';
359 EX2CTRL_o.flush_first <= not do_cond_v;
360 EX2CTRL_o.flush_second <= not do_cond_v;
361 EX2CTRL_o.ignore_state <= '1';
363 EX2CTRL_o.flush_first <= not do_cond_v;
364 EX2CTRL_o.flush_second <= do_cond_v;
365 EX2CTRL_o.ignore_state <= '1';
367 EX2CTRL_o.flush_first <= '0';
368 EX2CTRL_o.flush_second <= '0';
369 EX2CTRL_o.ignore_state <= '0';
373 -- Halting, the instruction parsing is separate
374 HALT_o.halt <= ID2EX_i.halt;
375 IF (ID2EX_i.halt = '1') THEN
376 HALT_o.halt_code <= ID2EX_i.IMM16(4 DOWNTO 0);
378 HALT_o.halt_code <= (others => '0');
381 -- WR_MEM/RD_MEM: result_v --> exeq_result --> mem_address,
382 -- WR_MEM: data_rD --> data_out_to_mem
383 -- BRL: prog_counter --> exeq_result
384 -- else result_v --> exeq_result (data_rD not used)
385 EX2MEM_o.wrix_rD <= ID2EX_i.curr_rD;
386 IF (ID2EX_i.branch_Action = BRL) THEN
387 EX2MEM_o.wrb_Action <= WRB_EX;
388 IF (COMPATIBILITY_MODE_g = TRUE) OR (delayBit_i = '0') THEN
389 EX2MEM_o.exeq_result <= ID2EX_i.program_counter;
390 EX2MEM_o.data_rD <= ID2EX_i.program_counter;
392 EX2MEM_o.exeq_result <= IF2ID_i.program_counter;
393 EX2MEM_o.data_rD <= IF2ID_i.program_counter;
395 -- set data_rD_v, although unused, to prevent an inferred latch
396 data_rD_v := GPRF2EX_i.data_rD;
398 EX2MEM_o.wrb_Action <= ID2EX_i.wrb_Action;
399 EX2MEM_o.exeq_result <= result_v;
400 -- test where to obtain data_rD from
401 IF (HAZARD_WRB_i.hazard = '1') THEN
402 data_rD_v := HAZARD_WRB_i.data_rD;
403 ELSIF ((EX_WRB_i.wrb_Action = WRB_EX) AND (ID2EX_i.curr_rD = EX_WRB_i.wrix_rD)) THEN
404 -- forward rD_data just calculated, to handle e.g. addi rD,rA,Imm; sw rD,mem[y]; ...
405 data_rD_v := EX_WRB_i.data_rD;
406 ELSIF ((MEM_WRB_i.wrb_Action /= NO_WRB) AND (ID2EX_i.curr_rD = MEM_WRB_i.wrix_rD)) THEN
407 data_rD_v := MEM_WRB_i.data_rD;
409 data_rD_v := GPRF2EX_i.data_rD;
413 IF (ID2EX_i.mem_Action /= NO_MEM) THEN
414 CASE ID2EX_i.transfer_Size IS
417 CASE result_v( 1 DOWNTO 0) IS
418 WHEN "00" => byte_Enable_v := "1000";
419 WHEN "01" => byte_Enable_v := "0100";
420 WHEN "10" => byte_Enable_v := "0010";
421 WHEN "11" => byte_Enable_v := "0001";
426 CASE result_v( 1 DOWNTO 0) IS
427 WHEN "00" => byte_Enable_v := "1100";
428 WHEN "10" => byte_Enable_v := "0011";
432 WHEN OTHERS => byte_Enable_v := "1111";
437 -- update MSR[C] if needed
438 IF (ID2EX_i.msr_Action = UPDATE_CARRY) THEN
439 MSR_o.C <= carry_o_v;
442 -- pass remaining data to mem
443 EX2MEM_o.mem_Action <= ID2EX_i.mem_Action;
444 EX2MEM_o.data_rD <= data_rD_v;
445 EX2MEM_o.byte_Enable <= byte_Enable_v;
446 EX2MEM_o.wrix_rD <= ID2EX_i.curr_rD;
448 IMM_LOCK_o.locked <= ID2EX_i.IMM_Lock;
449 IMM_LOCK_o.IMM_hi16 <= ID2EX_i.IMM16;
451 EX_WRB_o.wrb_Action <= ID2EX_i.wrb_Action;
452 EX_WRB_o.wrix_rD <= ID2EX_i.curr_rD;
453 EX_WRB_o.data_rD <= result_v;
455 HAZARD_WRB_o.hazard <= hazard_v;
456 HAZARD_WRB_o.save_rX <= save_rX_v;
457 HAZARD_WRB_o.data_rX <= data_rX_v;
458 HAZARD_WRB_o.data_rD <= data_rD_v;
462 END ARCHITECTURE rtl;