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: December, 2010: FSL added (Huib)
13 -- June, 2011: added code for MUL and BARREL (Huib)
14 -- Adapted to work with separate fsl_M-
15 -- and fsl_S selectors and automatic
16 -- tumbl<_jtag><_fsl>.vhd generation (Huib)
19 --------------------------------------------------------------------------------
23 USE IEEE.std_logic_1164.all;
24 USE IEEE.numeric_std.all;
28 ----------------------------------------------------------
30 ----------------------------------------------------------
32 USE_HW_MUL_g : BOOLEAN := FALSE;
33 USE_BARREL_g : BOOLEAN := FALSE
36 ID2EX_i : IN ID2EX_Type;
37 GPRF2EX_i : IN GPRF2EX_Type;
38 EX2IF_o : OUT EX2IF_Type;
40 EX_WRB_i : IN WRB_Type;
41 EX_WRB_o : OUT WRB_Type;
42 MEM_WRB_i : IN WRB_Type;
44 HAZARD_WRB_i : IN HAZARD_WRB_Type;
45 HAZARD_WRB_o : OUT HAZARD_WRB_Type;
47 IMM_LOCK_i : IN IMM_LOCK_Type;
48 IMM_LOCK_o : OUT IMM_LOCK_Type;
53 EX2MEM_o : OUT EX2MEM_Type;
55 exq_branch_i : IN STD_LOGIC;
57 FSL_M2EX_i : IN FSL_M2EX_Type;
58 EX2FSL_M_o : OUT EX2FSL_M_Type;
60 FSL_S2EX_i : IN FSL_S2EX_Type;
61 EX2FSL_S_o : OUT EX2FSL_S_Type;
63 FSL_nStall_o : OUT STD_LOGIC
68 ----------------------------------------------------------
69 ARCHITECTURE rtl OF exeq IS
70 ----------------------------------------------------------
75 PROCESS (ID2EX_i, GPRF2EX_i, EX_WRB_i, MEM_WRB_i,
76 IMM_LOCK_i, MSR_i, exq_branch_i, FSL_M2EX_i, FSL_S2EX_i, HAZARD_WRB_i)
78 -- function needed by BSLL (only if USE_BARREL_g = TRUE)
79 FUNCTION reverse_bits ( word32 : STD_LOGIC_VECTOR (31 DOWNTO 0) )
80 RETURN STD_LOGIC_VECTOR IS
81 VARIABLE reversed_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
85 reversed_v(31-i) := word32(i);
90 VARIABLE data_rA_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
91 VARIABLE data_rB_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
92 VARIABLE data_rD_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
93 VARIABLE in1_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
94 VARIABLE in2_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
95 VARIABLE hi16_v : STD_LOGIC_VECTOR (15 DOWNTO 0);
96 VARIABLE IMM32_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
97 VARIABLE carry_i_v : STD_LOGIC;
98 VARIABLE result_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
99 VARIABLE carry_o_v : STD_LOGIC;
100 VARIABLE isZero_v : STD_LOGIC;
101 VARIABLE signBit_in1_v : STD_LOGIC;
102 VARIABLE signBit_in2_v : STD_LOGIC;
103 VARIABLE signBit_rA_v : STD_LOGIC;
104 VARIABLE rA_eq_ex_rD_v : STD_LOGIC;
105 VARIABLE rB_eq_ex_rD_v : STD_LOGIC;
106 VARIABLE hazard_v : STD_LOGIC;
107 VARIABLE save_rX_v : SAVE_REG_Type;
108 VARIABLE data_rX_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
109 VARIABLE do_branch_v : STD_LOGIC;
110 VARIABLE byte_Enable_v : STD_LOGIC_VECTOR ( 3 DOWNTO 0);
111 VARIABLE FSLx_M_v : STD_LOGIC_VECTOR ( 3 DOWNTO 0);
112 VARIABLE FSLx_S_v : STD_LOGIC_VECTOR ( 3 DOWNTO 0);
113 VARIABLE FSL_Read_v : STD_LOGIC;
114 VARIABLE FSL_Write_v : STD_LOGIC;
115 VARIABLE FSL_nStall_v : STD_LOGIC;
116 VARIABLE FSL_Atomic_v : STD_LOGIC;
117 VARIABLE FSL_Error_v : STD_LOGIC;
118 VARIABLE tmp64_v : STD_LOGIC_VECTOR (63 DOWNTO 0);
119 VARIABLE padVec_v : STD_LOGIC_VECTOR (15 DOWNTO 0);
123 rA_eq_ex_rD_v := '0';
124 rB_eq_ex_rD_v := '0';
126 save_rX_v := NO_SAVE;
127 data_rX_v := data_rB_v; -- default value for data_rX_v
128 result_v := (OTHERS => '0');
131 byte_Enable_v := "0000";
132 FSLx_M_v := (OTHERS => '0');
133 FSLx_S_v := (OTHERS => '0');
138 FSL_Error_v := MSR_i.FSL;
140 -- create some helper variables
141 IF (ID2EX_i.rdix_rA = EX_WRB_i.wrix_rD) THEN
142 rA_eq_ex_rD_v := '1';
144 IF (ID2EX_i.rdix_rB = EX_WRB_i.wrix_rD) THEN
145 rB_eq_ex_rD_v := '1';
147 -- test where to obtain data_rA from
148 IF ((EX_WRB_i.wrb_Action = WRB_EX) AND (rA_eq_ex_rD_v = '1')) THEN
149 data_rA_v := EX_WRB_i.data_rD;
150 ELSIF ((MEM_WRB_i.wrb_Action /= NO_WRB) AND (ID2EX_i.rdix_rA = MEM_WRB_i.wrix_rD)) THEN
151 data_rA_v := MEM_WRB_i.data_rD;
152 ELSIF ((HAZARD_WRB_i.hazard = '1') AND (HAZARD_WRB_i.save_rX = SAVE_RA)) THEN
153 data_rA_v := HAZARD_WRB_i.data_rX;
155 data_rA_v := GPRF2EX_i.data_rA;
157 -- test where to obtain data_rB from
158 IF ((EX_WRB_i.wrb_Action = WRB_EX) AND (rB_eq_ex_rD_v = '1')) THEN
159 data_rB_v := EX_WRB_i.data_rD;
160 ELSIF ((MEM_WRB_i.wrb_Action /= NO_WRB) AND (ID2EX_i.rdix_rB = MEM_WRB_i.wrix_rD)) THEN
161 data_rB_v := MEM_WRB_i.data_rD;
162 ELSIF ((HAZARD_WRB_i.hazard = '1') AND (HAZARD_WRB_i.save_rX = SAVE_RB)) THEN
163 data_rB_v := HAZARD_WRB_i.data_rX;
165 data_rB_v := GPRF2EX_i.data_rB;
167 -- .... or, isn't all necessary data available yet being still in the pipeline ?
168 data_rX_v := data_rB_v; -- default value for data_rX_v
169 IF (EX_WRB_i.wrb_Action = WRB_MEM) THEN
170 IF ((rA_eq_ex_rD_v = '1') OR (rB_eq_ex_rD_v = '1')) THEN
172 -- always?? IF (MEM_WRB_i.wrb_Action = WRB_MEM) THEN
173 -- handle situations in which both rA and rB needed
174 IF (rA_eq_ex_rD_v = '1') THEN
175 save_rX_v := SAVE_RB; -- already by default data_rX_v = data_rB_v
177 save_rX_v := SAVE_RA;
178 data_rX_v := data_rA_v;
184 IF (IMM_LOCK_i.locked = '1') THEN
185 hi16_v := IMM_LOCK_i.IMM_hi16;
186 ELSIF (ID2EX_i.IMM16(15) = '0') THEN
187 hi16_v := C_16_ZEROS;
191 IMM32_v := hi16_v & ID2EX_i.IMM16;
193 CASE ID2EX_i.alu_Op1 IS
194 WHEN ALU_IN_REGA => in1_v := data_rA_v;
195 WHEN ALU_IN_NOT_REGA => in1_v := NOT data_rA_v;
196 WHEN ALU_IN_PC => in1_v := ID2EX_i.program_counter;
197 WHEN ALU_IN_ZERO => in1_v := C_32_ZEROS;
201 CASE ID2EX_i.alu_Op2 IS
202 WHEN ALU_IN_REGB => in2_v := data_rB_v;
203 WHEN ALU_IN_NOT_REGB => in2_v := NOT data_rB_v;
204 WHEN ALU_IN_IMM => in2_v := IMM32_v;
205 WHEN ALU_IN_NOT_IMM => in2_v := NOT IMM32_v;
209 signBit_in1_v := in1_v(31);
210 signBit_in2_v := in2_v(31);
211 signBit_rA_v := data_rA_v(31);
213 CASE ID2EX_i.alu_Cin IS
214 WHEN CIN_ZERO => carry_i_v := '0';
215 WHEN CIN_ONE => carry_i_v := '1';
216 WHEN FROM_MSR => carry_i_v := MSR_i.C;
217 WHEN FROM_IN1 => carry_i_v := in1_v(31);
218 WHEN OTHERS => carry_i_v := '0';
221 CASE ID2EX_i.alu_Action IS
222 WHEN A_ADD | A_CMP | A_CMPU =>
223 ep_add32 ( in1_v, in2_v, carry_i_v, result_v, carry_o_v);
224 IF (id2ex_i.alu_Action = A_CMPU) THEN
225 IF (signBit_in1_v = signBit_in2_v) THEN
226 result_v(31) := NOT signBit_in1_v;
228 ELSIF (id2ex_i.alu_Action = A_CMP) THEN
229 IF (signBit_in1_v = signBit_in2_v) THEN
230 result_v(31) := signBit_in1_v;
234 result_v := in1_v OR in2_v;
236 result_v := in1_v AND in2_v;
238 result_v := in1_v XOR in2_v;
240 result_v := carry_i_v & in1_v(31 DOWNTO 1);
241 carry_o_v := in1_v(0);
243 IF (in1_v(7) = '0') THEN
244 result_v := C_24_ZEROS & in1_v( 7 DOWNTO 0);
246 result_v := C_24_ONES & in1_v( 7 DOWNTO 0);
249 IF (in1_v(15) = '0') THEN
250 result_v := C_16_ZEROS & in1_v(15 DOWNTO 0);
252 result_v := C_16_ONES & in1_v(15 DOWNTO 0);
255 result_v := MSR_i.C & C_24_ZEROS & "00" & MSR_i.FSL & '0' & MSR_i.C & MSR_i.IE & '0';
257 MSR_o.IE <= data_Ra_v(1);
258 MSR_o.C <= data_Ra_v(2);
259 MSR_o.FSL <= data_Ra_v(4);
261 IF (USE_HW_MUL_g = TRUE) THEN
262 tmp64_v := STD_LOGIC_VECTOR( UNSIGNED(in1_v) * UNSIGNED(in2_v) );
263 result_v := tmp64_v(31 DOWNTO 0);
265 WHEN A_BSLL | A_BSRL | A_BSRA =>
266 IF (USE_BARREL_g = TRUE) THEN
267 IF (ID2EX_i.alu_Action = A_BSLL) THEN
268 result_v := reverse_bits (in1_v);
272 IF (ID2EX_i.alu_Action = A_BSRA) THEN
273 padVec_v := (OTHERS => in1_v(31));
275 padVec_v := (OTHERS => '0');
277 IF (in2_v(4) = '1') THEN
278 result_v := padVec_v (15 DOWNTO 0) & result_v (31 DOWNTO 16);
280 IF (in2_v(3) = '1') THEN
281 result_v := padVec_v ( 7 DOWNTO 0) & result_v (31 DOWNTO 8);
283 IF (in2_v(2) = '1') THEN
284 result_v := padVec_v ( 3 DOWNTO 0) & result_v (31 DOWNTO 4);
286 IF (in2_v(1) = '1') THEN
287 result_v := padVec_v ( 1 DOWNTO 0) & result_v (31 DOWNTO 2);
289 IF (in2_v(0) = '1') THEN
290 result_v := padVec_v ( 0 DOWNTO 0) & result_v (31 DOWNTO 1);
292 IF (ID2EX_i.alu_Action = A_BSLL) THEN
293 result_v := reverse_bits (result_v);
295 END IF; -- (USE_BARREL_g = TRUE)
297 -- to be examined here, since FSL instruction treated differently than
298 -- e.g. memory read/writes, i.e. MSR-C and -FSL_E bit have to be set
299 -- depending on input values (exq_branch_i equals EX2IF_r.take_branch, i.e.
300 -- a one clock cycle delayed EX2IF_o.take_branch).
301 IF (exq_branch_i = '0') THEN
302 FSLx_S_v := in2_v(3 DOWNTO 0);
303 FSL_Read_v := FSL_S2EX_i.S_Exists AND (NOT hazard_v);
304 FSL_Atomic_v := ID2EX_i.FSL_Atomic;
305 IF (ID2EX_i.FSL_Non_blocking = '0') THEN
306 FSL_nStall_v := FSL_Read_v;
308 carry_o_v := NOT FSL_Read_v;
309 IF ((FSL_Read_v = '1') AND
310 (ID2EX_i.FSL_Control /= FSL_S2EX_i.S_Control)) THEN
318 FSLx_M_v := in2_v(3 DOWNTO 0);
319 FSL_Write_v := NOT (FSL_M2EX_i.M_Full OR hazard_v);
320 FSL_Atomic_v := ID2EX_i.FSL_Atomic;
321 IF (ID2EX_i.FSL_Non_blocking = '0') THEN
322 FSL_nStall_v := FSL_Write_v;
324 carry_o_v := FSL_M2EX_i.M_Full;
330 IF (data_rA_v = C_32_ZEROS) THEN
335 CASE ID2EX_i.branch_Action IS
336 WHEN BR => do_branch_v := '1';
337 WHEN BRL => do_branch_v := '1';
338 WHEN BEQ => do_branch_v := isZero_v;
339 WHEN BNE => do_branch_v := NOT isZero_v;
340 WHEN BLT => do_branch_v := signBit_rA_v;
341 WHEN BLE => do_branch_v := signBit_rA_v OR isZero_v;
342 WHEN BGT => do_branch_v := NOT (signBit_rA_v OR isZero_v);
343 WHEN BGE => do_branch_v := NOT signBit_rA_v;
346 IF (do_branch_v = '1') THEN
347 EX2IF_o.take_branch <= '1';
348 EX2IF_o.branch_target <= result_v;
350 EX2IF_o.take_branch <= '0';
351 EX2IF_o.branch_target <= C_32_ZEROS;
354 -- WR_MEM/RD_MEM: result_v --> exeq_result --> mem_address,
355 -- WR_MEM: data_rD --> data_out_to_mem
356 -- BRL: prog_counter --> exeq_result
357 -- else result_v --> exeq_result (data_rD not used)
358 EX2MEM_o.wrix_rD <= ID2EX_i.curr_rD;
359 IF (ID2EX_i.branch_Action = BRL) THEN
360 EX2MEM_o.wrb_Action <= WRB_EX;
361 EX2MEM_o.exeq_result <= ID2EX_i.program_counter;
362 EX2MEM_o.data_rD <= ID2EX_i.program_counter;
363 -- set data_rD_v, although unused, to prevent an inferred latch
364 data_rD_v := GPRF2EX_i.data_rD;
366 EX2MEM_o.wrb_Action <= ID2EX_i.wrb_Action;
367 EX2MEM_o.exeq_result <= result_v;
368 -- test where to obtain data_rD from
369 IF (HAZARD_WRB_i.hazard = '1') THEN
370 data_rD_v := HAZARD_WRB_i.data_rD;
371 ELSIF ((EX_WRB_i.wrb_Action = WRB_EX) AND (ID2EX_i.curr_rD = EX_WRB_i.wrix_rD)) THEN
372 -- forward rD_data just calculated, to handle e.g. addi rD,rA,Imm; sw rD,mem[y]; ...
373 data_rD_v := EX_WRB_i.data_rD;
374 ELSIF ((MEM_WRB_i.wrb_Action /= NO_WRB) AND (ID2EX_i.curr_rD = MEM_WRB_i.wrix_rD)) THEN
375 data_rD_v := MEM_WRB_i.data_rD;
377 data_rD_v := GPRF2EX_i.data_rD;
380 IF (ID2EX_i.mem_Action /= NO_MEM) THEN
381 CASE ID2EX_i.transfer_Size IS
383 CASE result_v( 1 DOWNTO 0) IS
384 WHEN "00" => byte_Enable_v := "1000";
385 WHEN "01" => byte_Enable_v := "0100";
386 WHEN "10" => byte_Enable_v := "0010";
387 WHEN "11" => byte_Enable_v := "0001";
391 CASE result_v( 1 DOWNTO 0) IS
392 WHEN "00" => byte_Enable_v := "1100";
393 WHEN "10" => byte_Enable_v := "0011";
396 WHEN OTHERS => byte_Enable_v := "1111";
400 -- update MSR[IE], MSR[C] and/or MSR[FSL_Error] if needed
401 IF (ID2EX_i.alu_Action /= A_MTS) THEN
402 MSR_o.FSL <= FSL_Error_v;
403 MSR_o.IE <= MSR_i.IE AND (NOT FSL_Atomic_v);
404 IF (ID2EX_i.msr_Action = UPDATE_CARRY) THEN
405 MSR_o.C <= carry_o_v;
411 -- pass remaining data to mem
412 EX2MEM_o.mem_Action <= ID2EX_i.mem_Action;
413 EX2MEM_o.data_rD <= data_rD_v;
414 EX2MEM_o.byte_Enable <= byte_Enable_v;
415 EX2MEM_o.wrix_rD <= ID2EX_i.curr_rD;
417 IMM_LOCK_o.locked <= ID2EX_i.IMM_Lock;
418 IMM_LOCK_o.IMM_hi16 <= ID2EX_i.IMM16;
420 EX_WRB_o.wrb_Action <= ID2EX_i.wrb_Action;
421 EX_WRB_o.wrix_rD <= ID2EX_i.curr_rD;
422 EX_WRB_o.data_rD <= result_v;
424 EX2FSL_M_o.FSLx_M <= FSLx_M_v;
425 EX2FSL_M_o.M_Write <= FSL_Write_v;
426 EX2FSL_M_o.M_Data <= data_rA_v;
427 EX2FSL_M_o.M_Control <= ID2EX_i.FSL_Control;
429 EX2FSL_S_o.FSLx_S <= FSLx_S_v;
430 EX2FSL_S_o.S_Read <= FSL_Read_v;
432 FSL_nStall_o <= FSL_nStall_v;
434 HAZARD_WRB_o.hazard <= hazard_v;
435 HAZARD_WRB_o.save_rX <= save_rX_v;
436 HAZARD_WRB_o.data_rX <= data_rX_v;
437 HAZARD_WRB_o.data_rD <= data_rD_v;
441 END ARCHITECTURE rtl;