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 (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 ----------------------------------------------------------
33 USE_HW_MUL_g : BOOLEAN := TRUE;
34 USE_BARREL_g : BOOLEAN := TRUE
37 ID2EX_i : IN ID2EX_Type;
38 GPRF2EX_i : IN GPRF2EX_Type;
39 EX2IF_o : OUT EX2IF_Type;
40 HALT_o : OUT HALT_Type;
42 EX_WRB_i : IN WRB_Type;
43 EX_WRB_o : OUT WRB_Type;
44 MEM_WRB_i : IN WRB_Type;
46 HAZARD_WRB_i : IN HAZARD_WRB_Type;
47 HAZARD_WRB_o : OUT HAZARD_WRB_Type;
49 IMM_LOCK_i : IN IMM_LOCK_Type;
50 IMM_LOCK_o : OUT IMM_LOCK_Type;
55 EX2MEM_o : OUT EX2MEM_Type
60 ----------------------------------------------------------
61 ARCHITECTURE rtl OF exeq IS
62 ----------------------------------------------------------
67 PROCESS (ID2EX_i, GPRF2EX_i, EX_WRB_i, MEM_WRB_i,
68 IMM_LOCK_i, MSR_i, HAZARD_WRB_i)
70 -- function needed by BSLL (only if USE_BARREL_g = TRUE)
71 FUNCTION reverse_bits ( word32 : STD_LOGIC_VECTOR (31 DOWNTO 0) )
72 RETURN STD_LOGIC_VECTOR IS
73 VARIABLE reversed_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
77 reversed_v(31-i) := word32(i);
82 VARIABLE data_rA_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
83 VARIABLE data_rB_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
84 VARIABLE data_rD_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
85 VARIABLE in1_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
86 VARIABLE in2_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
87 VARIABLE hi16_v : STD_LOGIC_VECTOR (15 DOWNTO 0);
88 VARIABLE IMM32_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
89 VARIABLE carry_i_v : STD_LOGIC;
90 VARIABLE result_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
91 VARIABLE carry_o_v : STD_LOGIC;
92 VARIABLE isZero_v : STD_LOGIC;
93 VARIABLE signBit_in1_v : STD_LOGIC;
94 VARIABLE signBit_in2_v : STD_LOGIC;
95 VARIABLE signBit_rA_v : STD_LOGIC;
96 VARIABLE rA_eq_ex_rD_v : STD_LOGIC;
97 VARIABLE rB_eq_ex_rD_v : STD_LOGIC;
98 VARIABLE hazard_v : STD_LOGIC;
99 VARIABLE save_rX_v : SAVE_REG_Type;
100 VARIABLE data_rX_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
101 VARIABLE do_branch_v : STD_LOGIC;
102 VARIABLE byte_Enable_v : STD_LOGIC_VECTOR ( 3 DOWNTO 0);
103 VARIABLE tmp64_v : STD_LOGIC_VECTOR (63 DOWNTO 0);
104 VARIABLE padVec_v : STD_LOGIC_VECTOR (15 DOWNTO 0);
105 VARIABLE halt_v : STD_LOGIC;
106 VARIABLE halt_code_v : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
110 rA_eq_ex_rD_v := '0';
111 rB_eq_ex_rD_v := '0';
113 save_rX_v := NO_SAVE;
114 data_rX_v := data_rB_v; -- default value for data_rX_v
115 result_v := (OTHERS => '0');
118 byte_Enable_v := "0000";
120 halt_code_v := "00000";
122 -- create some helper variables
123 IF (ID2EX_i.rdix_rA = EX_WRB_i.wrix_rD) THEN
124 rA_eq_ex_rD_v := '1';
126 IF (ID2EX_i.rdix_rB = EX_WRB_i.wrix_rD) THEN
127 rB_eq_ex_rD_v := '1';
129 -- test where to obtain data_rA from
130 IF ((EX_WRB_i.wrb_Action = WRB_EX) AND (rA_eq_ex_rD_v = '1')) THEN
131 data_rA_v := EX_WRB_i.data_rD;
132 ELSIF ((MEM_WRB_i.wrb_Action /= NO_WRB) AND (ID2EX_i.rdix_rA = MEM_WRB_i.wrix_rD)) THEN
133 data_rA_v := MEM_WRB_i.data_rD;
134 ELSIF ((HAZARD_WRB_i.hazard = '1') AND (HAZARD_WRB_i.save_rX = SAVE_RA)) THEN
135 data_rA_v := HAZARD_WRB_i.data_rX;
137 data_rA_v := GPRF2EX_i.data_rA;
139 -- test where to obtain data_rB from
140 IF ((EX_WRB_i.wrb_Action = WRB_EX) AND (rB_eq_ex_rD_v = '1')) THEN
141 data_rB_v := EX_WRB_i.data_rD;
142 ELSIF ((MEM_WRB_i.wrb_Action /= NO_WRB) AND (ID2EX_i.rdix_rB = MEM_WRB_i.wrix_rD)) THEN
143 data_rB_v := MEM_WRB_i.data_rD;
144 ELSIF ((HAZARD_WRB_i.hazard = '1') AND (HAZARD_WRB_i.save_rX = SAVE_RB)) THEN
145 data_rB_v := HAZARD_WRB_i.data_rX;
147 data_rB_v := GPRF2EX_i.data_rB;
149 -- .... or, isn't all necessary data available yet being still in the pipeline ?
150 data_rX_v := data_rB_v; -- default value for data_rX_v
151 IF (EX_WRB_i.wrb_Action = WRB_MEM) THEN
152 IF ((rA_eq_ex_rD_v = '1') OR (rB_eq_ex_rD_v = '1')) THEN
154 -- always?? IF (MEM_WRB_i.wrb_Action = WRB_MEM) THEN
155 -- handle situations in which both rA and rB needed
156 IF (rA_eq_ex_rD_v = '1') THEN
157 save_rX_v := SAVE_RB; -- already by default data_rX_v = data_rB_v
159 save_rX_v := SAVE_RA;
160 data_rX_v := data_rA_v;
166 IF (IMM_LOCK_i.locked = '1') THEN
167 hi16_v := IMM_LOCK_i.IMM_hi16;
168 ELSIF (ID2EX_i.IMM16(15) = '0') THEN
169 hi16_v := C_16_ZEROS;
173 IMM32_v := hi16_v & ID2EX_i.IMM16;
175 CASE ID2EX_i.alu_Op1 IS
176 WHEN ALU_IN_REGA => in1_v := data_rA_v;
177 WHEN ALU_IN_NOT_REGA => in1_v := NOT data_rA_v;
178 WHEN ALU_IN_PC => in1_v := ID2EX_i.program_counter;
179 WHEN ALU_IN_ZERO => in1_v := C_32_ZEROS;
183 CASE ID2EX_i.alu_Op2 IS
184 WHEN ALU_IN_REGB => in2_v := data_rB_v;
185 WHEN ALU_IN_NOT_REGB => in2_v := NOT data_rB_v;
186 WHEN ALU_IN_IMM => in2_v := IMM32_v;
187 WHEN ALU_IN_NOT_IMM => in2_v := NOT IMM32_v;
191 signBit_in1_v := in1_v(31);
192 signBit_in2_v := in2_v(31);
193 signBit_rA_v := data_rA_v(31);
195 CASE ID2EX_i.alu_Cin IS
196 WHEN CIN_ZERO => carry_i_v := '0';
197 WHEN CIN_ONE => carry_i_v := '1';
198 WHEN FROM_MSR => carry_i_v := MSR_i.C;
199 WHEN FROM_IN1 => carry_i_v := in1_v(31);
200 WHEN OTHERS => carry_i_v := '0';
203 CASE ID2EX_i.alu_Action IS
204 WHEN A_ADD | A_CMP | A_CMPU =>
205 ep_add32 ( in1_v, in2_v, carry_i_v, result_v, carry_o_v);
206 IF (id2ex_i.alu_Action = A_CMPU) THEN
207 IF (signBit_in1_v = signBit_in2_v) THEN
208 result_v(31) := NOT signBit_in1_v;
210 ELSIF (id2ex_i.alu_Action = A_CMP) THEN
211 IF (signBit_in1_v = signBit_in2_v) THEN
212 result_v(31) := signBit_in1_v;
216 result_v := in1_v OR in2_v;
218 result_v := in1_v AND in2_v;
220 result_v := in1_v XOR in2_v;
222 result_v := carry_i_v & in1_v(31 DOWNTO 1);
223 carry_o_v := in1_v(0);
225 IF (in1_v(7) = '0') THEN
226 result_v := C_24_ZEROS & in1_v( 7 DOWNTO 0);
228 result_v := C_24_ONES & in1_v( 7 DOWNTO 0);
231 IF (in1_v(15) = '0') THEN
232 result_v := C_16_ZEROS & in1_v(15 DOWNTO 0);
234 result_v := C_16_ONES & in1_v(15 DOWNTO 0);
237 result_v := MSR_i.C & C_24_ZEROS & "0000" & MSR_i.C & MSR_i.IE & '0';
239 MSR_o.IE <= data_Ra_v(1);
240 MSR_o.C <= data_Ra_v(2);
242 IF (USE_HW_MUL_g = TRUE) THEN
243 tmp64_v := STD_LOGIC_VECTOR( UNSIGNED(in1_v) * UNSIGNED(in2_v) );
244 result_v := tmp64_v(31 DOWNTO 0);
246 WHEN A_BSLL | A_BSRL | A_BSRA =>
247 IF (USE_BARREL_g = TRUE) THEN
248 IF (ID2EX_i.alu_Action = A_BSLL) THEN
249 result_v := reverse_bits (in1_v);
253 IF (ID2EX_i.alu_Action = A_BSRA) THEN
254 padVec_v := (OTHERS => in1_v(31));
256 padVec_v := (OTHERS => '0');
258 IF (in2_v(4) = '1') THEN
259 result_v := padVec_v (15 DOWNTO 0) & result_v (31 DOWNTO 16);
261 IF (in2_v(3) = '1') THEN
262 result_v := padVec_v ( 7 DOWNTO 0) & result_v (31 DOWNTO 8);
264 IF (in2_v(2) = '1') THEN
265 result_v := padVec_v ( 3 DOWNTO 0) & result_v (31 DOWNTO 4);
267 IF (in2_v(1) = '1') THEN
268 result_v := padVec_v ( 1 DOWNTO 0) & result_v (31 DOWNTO 2);
270 IF (in2_v(0) = '1') THEN
271 result_v := padVec_v ( 0 DOWNTO 0) & result_v (31 DOWNTO 1);
273 IF (ID2EX_i.alu_Action = A_BSLL) THEN
274 result_v := reverse_bits (result_v);
276 END IF; -- (USE_BARREL_g = TRUE)
279 halt_code_v := ID2EX_i.IMM16(4 DOWNTO 0);
284 IF (data_rA_v = C_32_ZEROS) THEN
289 CASE ID2EX_i.branch_Action IS
290 WHEN BR => do_branch_v := '1';
291 WHEN BRL => do_branch_v := '1';
292 WHEN BEQ => do_branch_v := isZero_v;
293 WHEN BNE => do_branch_v := NOT isZero_v;
294 WHEN BLT => do_branch_v := signBit_rA_v;
295 WHEN BLE => do_branch_v := signBit_rA_v OR isZero_v;
296 WHEN BGT => do_branch_v := NOT (signBit_rA_v OR isZero_v);
297 WHEN BGE => do_branch_v := NOT signBit_rA_v;
300 IF (do_branch_v = '1') THEN
301 EX2IF_o.take_branch <= '1';
302 EX2IF_o.branch_target <= result_v;
304 EX2IF_o.take_branch <= '0';
305 EX2IF_o.branch_target <= C_32_ZEROS;
309 HALT_o.halt <= halt_v;
310 HALT_o.halt_code <= halt_code_v;
312 -- WR_MEM/RD_MEM: result_v --> exeq_result --> mem_address,
313 -- WR_MEM: data_rD --> data_out_to_mem
314 -- BRL: prog_counter --> exeq_result
315 -- else result_v --> exeq_result (data_rD not used)
316 EX2MEM_o.wrix_rD <= ID2EX_i.curr_rD;
317 IF (ID2EX_i.branch_Action = BRL) THEN
318 EX2MEM_o.wrb_Action <= WRB_EX;
319 EX2MEM_o.exeq_result <= ID2EX_i.program_counter;
320 EX2MEM_o.data_rD <= ID2EX_i.program_counter;
321 -- set data_rD_v, although unused, to prevent an inferred latch
322 data_rD_v := GPRF2EX_i.data_rD;
324 EX2MEM_o.wrb_Action <= ID2EX_i.wrb_Action;
325 EX2MEM_o.exeq_result <= result_v;
326 -- test where to obtain data_rD from
327 IF (HAZARD_WRB_i.hazard = '1') THEN
328 data_rD_v := HAZARD_WRB_i.data_rD;
329 ELSIF ((EX_WRB_i.wrb_Action = WRB_EX) AND (ID2EX_i.curr_rD = EX_WRB_i.wrix_rD)) THEN
330 -- forward rD_data just calculated, to handle e.g. addi rD,rA,Imm; sw rD,mem[y]; ...
331 data_rD_v := EX_WRB_i.data_rD;
332 ELSIF ((MEM_WRB_i.wrb_Action /= NO_WRB) AND (ID2EX_i.curr_rD = MEM_WRB_i.wrix_rD)) THEN
333 data_rD_v := MEM_WRB_i.data_rD;
335 data_rD_v := GPRF2EX_i.data_rD;
338 IF (ID2EX_i.mem_Action /= NO_MEM) THEN
339 CASE ID2EX_i.transfer_Size IS
341 CASE result_v( 1 DOWNTO 0) IS
342 WHEN "00" => byte_Enable_v := "1000";
343 WHEN "01" => byte_Enable_v := "0100";
344 WHEN "10" => byte_Enable_v := "0010";
345 WHEN "11" => byte_Enable_v := "0001";
349 CASE result_v( 1 DOWNTO 0) IS
350 WHEN "00" => byte_Enable_v := "1100";
351 WHEN "10" => byte_Enable_v := "0011";
354 WHEN OTHERS => byte_Enable_v := "1111";
358 -- update MSR[IE] and/or MSR[C] if needed
359 IF (ID2EX_i.alu_Action /= A_MTS) THEN
360 MSR_o.IE <= MSR_i.IE;
361 IF (ID2EX_i.msr_Action = UPDATE_CARRY) THEN
362 MSR_o.C <= carry_o_v;
368 -- pass remaining data to mem
369 EX2MEM_o.mem_Action <= ID2EX_i.mem_Action;
370 EX2MEM_o.data_rD <= data_rD_v;
371 EX2MEM_o.byte_Enable <= byte_Enable_v;
372 EX2MEM_o.wrix_rD <= ID2EX_i.curr_rD;
374 IMM_LOCK_o.locked <= ID2EX_i.IMM_Lock;
375 IMM_LOCK_o.IMM_hi16 <= ID2EX_i.IMM16;
377 EX_WRB_o.wrb_Action <= ID2EX_i.wrb_Action;
378 EX_WRB_o.wrix_rD <= ID2EX_i.curr_rD;
379 EX_WRB_o.data_rD <= result_v;
381 HAZARD_WRB_o.hazard <= hazard_v;
382 HAZARD_WRB_o.save_rX <= save_rX_v;
383 HAZARD_WRB_o.data_rX <= data_rX_v;
384 HAZARD_WRB_o.data_rD <= data_rD_v;
388 END ARCHITECTURE rtl;