]> rtime.felk.cvut.cz Git - fpga/lx-cpu1/tumbl.git/blob - hw/exeq.vhd
04ad287abbcc6b830ed69ad8f28ef8384037df61
[fpga/lx-cpu1/tumbl.git] / hw / exeq.vhd
1 ---------------------------------------------------------------------------------
2 --
3 --  Entity:       exeq
4 --  Filename:     exeq.vhd
5 --  Description:  the Execution (EX) unit for the TUD MB-Lite implementation
6 --
7 --  Author:       Huib Lincklaen Arriens
8 --                Delft University of Technology
9 --                Faculty EEMCS, Department ME&CE, Circuits and Systems
10 --  Date:         September, 2010
11 --
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)
18 --  Remarks:
19 --
20 --------------------------------------------------------------------------------
21
22 LIBRARY IEEE;
23
24 USE IEEE.std_logic_1164.all;
25 USE IEEE.numeric_std.all;
26 USE WORK.mbl_Pkg.all;
27
28
29 ----------------------------------------------------------
30 ENTITY exeq IS
31 ----------------------------------------------------------
32     GENERIC (
33         USE_HW_MUL_g : BOOLEAN := FALSE;
34         USE_BARREL_g : BOOLEAN := FALSE
35         );
36     PORT (
37         ID2EX_i      :  IN ID2EX_Type;
38         GPRF2EX_i    :  IN GPRF2EX_Type;
39         EX2IF_o      : OUT EX2IF_Type;
40         --
41         EX_WRB_i     :  IN WRB_Type;
42         EX_WRB_o     : OUT WRB_Type;
43         MEM_WRB_i    :  IN WRB_Type;
44         --
45         HAZARD_WRB_i :  IN HAZARD_WRB_Type;
46         HAZARD_WRB_o : OUT HAZARD_WRB_Type;
47         --
48         IMM_LOCK_i   :  IN IMM_LOCK_Type;
49         IMM_LOCK_o   : OUT IMM_LOCK_Type;
50         --
51         MSR_i        :  IN MSR_Type;
52         MSR_o        : OUT MSR_Type;
53         --
54         EX2MEM_o     : OUT EX2MEM_Type
55         );
56 END ENTITY exeq;
57
58
59 ----------------------------------------------------------
60 ARCHITECTURE rtl OF exeq IS
61 ----------------------------------------------------------
62
63 BEGIN
64
65 p_exeq:
66     PROCESS (ID2EX_i, GPRF2EX_i, EX_WRB_i, MEM_WRB_i,
67                         IMM_LOCK_i, MSR_i, HAZARD_WRB_i)
68
69         -- function needed by BSLL (only if USE_BARREL_g = TRUE)
70         FUNCTION reverse_bits ( word32 : STD_LOGIC_VECTOR (31 DOWNTO 0) )
71                                                         RETURN STD_LOGIC_VECTOR IS
72             VARIABLE reversed_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
73         BEGIN
74         f_rev:
75             FOR i IN 0 TO 31 LOOP
76                 reversed_v(31-i) := word32(i);
77             END LOOP;
78             RETURN reversed_v;
79         END;
80
81         VARIABLE data_rA_v     : STD_LOGIC_VECTOR (31 DOWNTO 0);
82         VARIABLE data_rB_v     : STD_LOGIC_VECTOR (31 DOWNTO 0);
83         VARIABLE data_rD_v     : STD_LOGIC_VECTOR (31 DOWNTO 0);
84         VARIABLE in1_v         : STD_LOGIC_VECTOR (31 DOWNTO 0);
85         VARIABLE in2_v         : STD_LOGIC_VECTOR (31 DOWNTO 0);
86         VARIABLE hi16_v        : STD_LOGIC_VECTOR (15 DOWNTO 0);
87         VARIABLE IMM32_v       : STD_LOGIC_VECTOR (31 DOWNTO 0);
88         VARIABLE carry_i_v     : STD_LOGIC;
89         VARIABLE result_v      : STD_LOGIC_VECTOR (31 DOWNTO 0);
90         VARIABLE carry_o_v     : STD_LOGIC;
91         VARIABLE isZero_v      : STD_LOGIC;
92         VARIABLE signBit_in1_v : STD_LOGIC;
93         VARIABLE signBit_in2_v : STD_LOGIC;
94         VARIABLE signBit_rA_v  : STD_LOGIC;
95         VARIABLE rA_eq_ex_rD_v : STD_LOGIC;
96         VARIABLE rB_eq_ex_rD_v : STD_LOGIC;
97         VARIABLE hazard_v      : STD_LOGIC;
98         VARIABLE save_rX_v     : SAVE_REG_Type;
99         VARIABLE data_rX_v     : STD_LOGIC_VECTOR (31 DOWNTO 0);
100         VARIABLE do_branch_v   : STD_LOGIC;
101         VARIABLE byte_Enable_v : STD_LOGIC_VECTOR ( 3 DOWNTO 0);
102         VARIABLE tmp64_v       : STD_LOGIC_VECTOR (63 DOWNTO 0);
103         VARIABLE padVec_v      : STD_LOGIC_VECTOR (15 DOWNTO 0);
104
105     BEGIN
106
107         rA_eq_ex_rD_v := '0';
108         rB_eq_ex_rD_v := '0';
109         hazard_v      := '0';
110         save_rX_v     := NO_SAVE;
111         data_rX_v     := data_rB_v;         -- default value for data_rX_v
112         result_v      := (OTHERS => '0');
113         carry_o_v     := '0';
114         do_branch_v   := '0';
115         byte_Enable_v := "0000";
116
117         -- create some helper variables
118         IF (ID2EX_i.rdix_rA = EX_WRB_i.wrix_rD) THEN
119             rA_eq_ex_rD_v := '1';
120         END IF;
121         IF (ID2EX_i.rdix_rB = EX_WRB_i.wrix_rD) THEN
122             rB_eq_ex_rD_v := '1';
123         END IF;
124         -- test where to obtain data_rA from
125         IF ((EX_WRB_i.wrb_Action = WRB_EX) AND (rA_eq_ex_rD_v = '1')) THEN
126             data_rA_v := EX_WRB_i.data_rD;
127         ELSIF ((MEM_WRB_i.wrb_Action /= NO_WRB) AND (ID2EX_i.rdix_rA = MEM_WRB_i.wrix_rD)) THEN
128             data_rA_v := MEM_WRB_i.data_rD;
129         ELSIF ((HAZARD_WRB_i.hazard = '1') AND (HAZARD_WRB_i.save_rX = SAVE_RA)) THEN
130             data_rA_v := HAZARD_WRB_i.data_rX;
131         ELSE
132             data_rA_v := GPRF2EX_i.data_rA;
133         END IF;
134         -- test where to obtain data_rB from
135         IF ((EX_WRB_i.wrb_Action = WRB_EX) AND (rB_eq_ex_rD_v = '1')) THEN
136             data_rB_v := EX_WRB_i.data_rD;
137         ELSIF ((MEM_WRB_i.wrb_Action /= NO_WRB) AND (ID2EX_i.rdix_rB = MEM_WRB_i.wrix_rD)) THEN
138             data_rB_v := MEM_WRB_i.data_rD;
139         ELSIF ((HAZARD_WRB_i.hazard = '1') AND (HAZARD_WRB_i.save_rX = SAVE_RB)) THEN
140             data_rB_v := HAZARD_WRB_i.data_rX;
141         ELSE
142             data_rB_v := GPRF2EX_i.data_rB;
143         END IF;
144         -- .... or, isn't all necessary data available yet being still in the pipeline ?
145         data_rX_v := data_rB_v;                 -- default value for data_rX_v
146         IF (EX_WRB_i.wrb_Action = WRB_MEM) THEN
147             IF ((rA_eq_ex_rD_v = '1') OR (rB_eq_ex_rD_v = '1')) THEN
148                 hazard_v  := '1';
149 -- always??     IF (MEM_WRB_i.wrb_Action = WRB_MEM) THEN
150                     -- handle situations in which both rA and rB needed
151                     IF (rA_eq_ex_rD_v = '1') THEN
152                         save_rX_v := SAVE_RB;   -- already by default data_rX_v = data_rB_v
153                     ELSE
154                         save_rX_v := SAVE_RA;
155                         data_rX_v := data_rA_v;
156                     END IF;
157 --              END IF;
158             END IF;
159         END IF;
160
161         IF (IMM_LOCK_i.locked = '1') THEN
162             hi16_v := IMM_LOCK_i.IMM_hi16;
163         ELSIF (ID2EX_i.IMM16(15) = '0') THEN
164             hi16_v := C_16_ZEROS;
165         ELSE
166             hi16_v :=  C_16_ONES;
167         END IF;
168         IMM32_v := hi16_v & ID2EX_i.IMM16;
169
170         CASE ID2EX_i.alu_Op1 IS
171             WHEN ALU_IN_REGA     =>  in1_v := data_rA_v;
172             WHEN ALU_IN_NOT_REGA =>  in1_v := NOT data_rA_v;
173             WHEN ALU_IN_PC       =>  in1_v := ID2EX_i.program_counter;
174             WHEN ALU_IN_ZERO     =>  in1_v := C_32_ZEROS;
175             WHEN OTHERS          =>  NULL;
176         END CASE;
177
178         CASE ID2EX_i.alu_Op2 IS
179             WHEN ALU_IN_REGB     =>  in2_v := data_rB_v;
180             WHEN ALU_IN_NOT_REGB =>  in2_v := NOT data_rB_v;
181             WHEN ALU_IN_IMM      =>  in2_v := IMM32_v;
182             WHEN ALU_IN_NOT_IMM  =>  in2_v := NOT IMM32_v;
183             WHEN OTHERS          =>  NULL;
184         END CASE;
185
186         signBit_in1_v := in1_v(31);
187         signBit_in2_v := in2_v(31);
188         signBit_rA_v  := data_rA_v(31);
189
190         CASE ID2EX_i.alu_Cin IS
191             WHEN CIN_ZERO  =>   carry_i_v := '0';
192             WHEN CIN_ONE   =>   carry_i_v := '1';
193             WHEN FROM_MSR  =>   carry_i_v := MSR_i.C;
194             WHEN FROM_IN1  =>   carry_i_v := in1_v(31);
195             WHEN OTHERS    =>   carry_i_v := '0';
196         END CASE;
197
198         CASE ID2EX_i.alu_Action IS
199             WHEN A_ADD | A_CMP | A_CMPU =>
200                 ep_add32 ( in1_v, in2_v, carry_i_v, result_v, carry_o_v);
201                 IF (id2ex_i.alu_Action = A_CMPU) THEN
202                     IF (signBit_in1_v = signBit_in2_v) THEN
203                         result_v(31) := NOT signBit_in1_v;
204                     END IF;
205                 ELSIF (id2ex_i.alu_Action = A_CMP) THEN
206                     IF (signBit_in1_v = signBit_in2_v) THEN
207                         result_v(31) := signBit_in1_v;
208                     END IF;
209                 END IF;
210             WHEN A_OR      =>
211                 result_v  := in1_v  OR in2_v;
212             WHEN A_AND    =>
213                 result_v  := in1_v AND in2_v;
214             WHEN A_XOR    =>
215                 result_v  := in1_v XOR in2_v;
216             WHEN A_SHIFT  =>
217                 result_v  := carry_i_v & in1_v(31 DOWNTO 1);
218                 carry_o_v := in1_v(0);
219             WHEN A_SEXT8   =>
220                 IF (in1_v(7) = '0') THEN
221                     result_v := C_24_ZEROS & in1_v( 7 DOWNTO 0);
222                 ELSE
223                     result_v :=  C_24_ONES & in1_v( 7 DOWNTO 0);
224                 END IF;
225             WHEN A_SEXT16  =>
226                 IF (in1_v(15) = '0') THEN
227                     result_v := C_16_ZEROS & in1_v(15 DOWNTO 0);
228                 ELSE
229                     result_v :=  C_16_ONES & in1_v(15 DOWNTO 0);
230                 END IF;
231             WHEN A_MFS     =>
232                 result_v := MSR_i.C & C_24_ZEROS & "0000" & MSR_i.C & MSR_i.IE & '0';
233             WHEN A_MTS     =>
234                 MSR_o.IE  <= data_Ra_v(1);
235                 MSR_o.C   <= data_Ra_v(2);
236             WHEN A_MUL     =>
237                 IF (USE_HW_MUL_g = TRUE) THEN
238                     tmp64_v  := STD_LOGIC_VECTOR( UNSIGNED(in1_v) * UNSIGNED(in2_v) );
239                     result_v := tmp64_v(31 DOWNTO 0);
240                 END IF;
241             WHEN A_BSLL | A_BSRL | A_BSRA  =>
242                 IF (USE_BARREL_g = TRUE) THEN
243                     IF (ID2EX_i.alu_Action = A_BSLL) THEN
244                         result_v := reverse_bits (in1_v);
245                     ELSE
246                         result_v := in1_v;
247                     END IF;
248                     IF (ID2EX_i.alu_Action = A_BSRA) THEN
249                         padVec_v := (OTHERS => in1_v(31));
250                     ELSE
251                         padVec_v := (OTHERS => '0');
252                     END IF;
253                     IF (in2_v(4) = '1') THEN
254                         result_v := padVec_v (15 DOWNTO 0) & result_v (31 DOWNTO 16);
255                     END IF;
256                     IF (in2_v(3) = '1') THEN
257                         result_v := padVec_v ( 7 DOWNTO 0) & result_v (31 DOWNTO  8);
258                     END IF;
259                     IF (in2_v(2) = '1') THEN
260                         result_v := padVec_v ( 3 DOWNTO 0) & result_v (31 DOWNTO  4);
261                     END IF;
262                     IF (in2_v(1) = '1') THEN
263                         result_v := padVec_v ( 1 DOWNTO 0) & result_v (31 DOWNTO  2);
264                     END IF;
265                     IF (in2_v(0) = '1') THEN
266                         result_v := padVec_v ( 0 DOWNTO 0) & result_v (31 DOWNTO  1);
267                     END IF;
268                     IF (ID2EX_i.alu_Action = A_BSLL) THEN
269                         result_v := reverse_bits (result_v);
270                     END IF;
271                 END IF;     -- (USE_BARREL_g = TRUE)
272             WHEN OTHERS    =>
273                 NULL;
274         END CASE;
275
276         IF (data_rA_v = C_32_ZEROS) THEN
277             isZero_v := '1';
278         ELSE
279             isZero_v := '0';
280         END IF;
281         CASE ID2EX_i.branch_Action IS
282             WHEN BR     => do_branch_v := '1';
283             WHEN BRL    => do_branch_v := '1';
284             WHEN BEQ    => do_branch_v := isZero_v;
285             WHEN BNE    => do_branch_v := NOT isZero_v;
286             WHEN BLT    => do_branch_v := signBit_rA_v;
287             WHEN BLE    => do_branch_v := signBit_rA_v OR isZero_v;
288             WHEN BGT    => do_branch_v := NOT (signBit_rA_v OR isZero_v);
289             WHEN BGE    => do_branch_v := NOT signBit_rA_v;
290             WHEN OTHERS => NULL;
291         END CASE;
292         IF (do_branch_v = '1') THEN
293             EX2IF_o.take_branch   <= '1';
294             EX2IF_o.branch_target <= result_v;
295         ELSE
296             EX2IF_o.take_branch   <= '0';
297             EX2IF_o.branch_target <= C_32_ZEROS;
298         END IF;
299
300         -- WR_MEM/RD_MEM:      result_v --> exeq_result --> mem_address,
301         --        WR_MEM:                       data_rD --> data_out_to_mem
302         --           BRL:  prog_counter --> exeq_result
303         --          else       result_v --> exeq_result (data_rD not used)
304         EX2MEM_o.wrix_rD <= ID2EX_i.curr_rD;
305         IF (ID2EX_i.branch_Action = BRL) THEN
306             EX2MEM_o.wrb_Action  <= WRB_EX;
307             EX2MEM_o.exeq_result <= ID2EX_i.program_counter;
308             EX2MEM_o.data_rD     <= ID2EX_i.program_counter;
309             -- set data_rD_v, although unused, to prevent an inferred latch
310             data_rD_v := GPRF2EX_i.data_rD;
311         ELSE
312             EX2MEM_o.wrb_Action  <= ID2EX_i.wrb_Action;
313             EX2MEM_o.exeq_result <= result_v;
314             -- test where to obtain data_rD from
315             IF (HAZARD_WRB_i.hazard = '1') THEN
316                 data_rD_v := HAZARD_WRB_i.data_rD;
317             ELSIF ((EX_WRB_i.wrb_Action = WRB_EX) AND (ID2EX_i.curr_rD = EX_WRB_i.wrix_rD)) THEN
318                 -- forward rD_data just calculated, to handle e.g. addi rD,rA,Imm; sw rD,mem[y]; ...
319                 data_rD_v := EX_WRB_i.data_rD;
320             ELSIF ((MEM_WRB_i.wrb_Action /= NO_WRB) AND (ID2EX_i.curr_rD = MEM_WRB_i.wrix_rD)) THEN
321                 data_rD_v := MEM_WRB_i.data_rD;
322             ELSE
323                 data_rD_v := GPRF2EX_i.data_rD;
324             END IF;
325         END IF;
326         IF (ID2EX_i.mem_Action /= NO_MEM) THEN
327             CASE ID2EX_i.transfer_Size IS
328                 WHEN BYTE     =>
329                     CASE result_v( 1 DOWNTO 0) IS
330                         WHEN "00"   => byte_Enable_v := "1000";
331                         WHEN "01"   => byte_Enable_v := "0100";
332                         WHEN "10"   => byte_Enable_v := "0010";
333                         WHEN "11"   => byte_Enable_v := "0001";
334                         WHEN OTHERS => NULL;
335                     END CASE;
336                 WHEN HALFWORD =>
337                     CASE result_v( 1 DOWNTO 0) IS
338                         WHEN "00"   => byte_Enable_v := "1100";
339                         WHEN "10"   => byte_Enable_v := "0011";
340                         WHEN OTHERS => NULL;
341                     END CASE;
342                 WHEN OTHERS   =>       byte_Enable_v := "1111";
343             END CASE;
344         END IF;
345
346         -- update MSR[IE], MSR[C] and/or MSR[FSL_Error] if needed
347         IF (ID2EX_i.alu_Action /= A_MTS) THEN
348             MSR_o.IE  <= MSR_i.IE;
349             IF (ID2EX_i.msr_Action = UPDATE_CARRY) THEN
350                 MSR_o.C <= carry_o_v;
351             ELSE
352                 MSR_o.C <= MSR_i.C;
353             END IF;
354         END IF;
355
356         -- pass remaining data to mem
357         EX2MEM_o.mem_Action  <= ID2EX_i.mem_Action;
358         EX2MEM_o.data_rD     <= data_rD_v;
359         EX2MEM_o.byte_Enable <= byte_Enable_v;
360         EX2MEM_o.wrix_rD     <= ID2EX_i.curr_rD;
361         --
362         IMM_LOCK_o.locked    <= ID2EX_i.IMM_Lock;
363         IMM_LOCK_o.IMM_hi16  <= ID2EX_i.IMM16;
364         --
365         EX_WRB_o.wrb_Action  <= ID2EX_i.wrb_Action;
366         EX_WRB_o.wrix_rD     <= ID2EX_i.curr_rD;
367         EX_WRB_o.data_rD     <= result_v;
368         --
369         HAZARD_WRB_o.hazard  <= hazard_v;
370         HAZARD_WRB_o.save_rX <= save_rX_v;
371         HAZARD_WRB_o.data_rX <= data_rX_v;
372         HAZARD_WRB_o.data_rD <= data_rD_v;
373
374     END PROCESS;
375
376 END ARCHITECTURE rtl;
377