]> rtime.felk.cvut.cz Git - fpga/lx-cpu1/tumbl.git/blob - hw/decode.vhd
17c6781f4ab5a9e3c441ee7409cc8f3f18dcec00
[fpga/lx-cpu1/tumbl.git] / hw / decode.vhd
1 ---------------------------------------------------------------------------------
2 --
3 --  Entity:       decode
4 --  Filename:     decode.vhd
5 --  Description:  the Instruction Decode (ID) unit for
6 --                the TUD MB-Lite implementation
7 --
8 --  Author:       Huib Lincklaen Arriens
9 --                Delft University of Technology
10 --                Faculty EEMCS, Department ME&CE, Circuits and Systems
11 --  Date:         September, 2010
12 --                     June, 2011: added code for MUL and BARREL (Huib)
13 --  Modified:
14 --  Remarks:
15 --
16 --------------------------------------------------------------------------------
17
18 LIBRARY IEEE;
19
20 USE IEEE.std_logic_1164.all;
21 USE WORK.mbl_Pkg.all;
22
23
24 --------------------------------------------------------------------------------
25 ENTITY decode IS
26 --------------------------------------------------------------------------------
27     GENERIC (
28         USE_HW_MUL_g : BOOLEAN := TRUE;
29         USE_BARREL_g : BOOLEAN := TRUE;
30         COMPATIBILITY_MODE_g : BOOLEAN := FALSE
31         );
32     PORT (
33         IF2ID_i     :  IN IF2ID_Type;
34         imem_data_i :  IN STD_LOGIC_VECTOR (31 DOWNTO 0);
35         --
36         ID2GPRF_o   : OUT ID2GPRF_Type;
37         ID2EX_o     : OUT ID2EX_Type;
38         --
39         INT_CTRL_i  :  IN INT_CTRL_Type;
40         ID2CTRL_o   : OUT ID2CTRL_Type;
41         --
42         noLiteOpc_o : OUT STD_LOGIC
43         );
44 END ENTITY decode;
45
46
47 --------------------------------------------------------------------------------
48 ARCHITECTURE rtl OF decode IS
49 --------------------------------------------------------------------------------
50
51 BEGIN
52
53 p_decode:
54     PROCESS (IF2ID_i, imem_data_i, INT_CTRL_i) IS
55
56         VARIABLE prog_counter_v  : STD_LOGIC_VECTOR (31 DOWNTO 0);
57         VARIABLE opcIx_v         : STD_LOGIC_VECTOR ( 5 DOWNTO 0);
58         VARIABLE instruction_v   : STD_LOGIC_VECTOR (31 DOWNTO 0);
59         VARIABLE rD_v            : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
60         VARIABLE rA_v            : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
61         VARIABLE rB_v            : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
62         VARIABLE IMM16_v         : STD_LOGIC_VECTOR (15 DOWNTO 0);
63         VARIABLE code_x26_v      : STD_LOGIC_VECTOR ( 2 DOWNTO 0);
64         VARIABLE IMM_Lock_v      : STD_LOGIC;
65         VARIABLE alu_Action_v    : ALU_ACTION_Type;
66         VARIABLE alu_Op1_v       : ALU_IN1_Type;
67         VARIABLE alu_Op2_v       : ALU_IN2_Type;
68         VARIABLE alu_Cin_v       : ALU_CIN_Type;
69         VARIABLE msr_Action_v    : MSR_ACTION_Type;
70         VARIABLE branch_Action_v : BRANCH_ACTION_Type;
71         VARIABLE delayBit_v      : STD_LOGIC;
72         VARIABLE mem_Action_v    : MEM_ACTION_Type;
73         VARIABLE transfer_Size_v : TRANSFER_SIZE_Type;
74         VARIABLE wrb_Action_v    : WRB_ACTION_Type;
75         VARIABLE int_busy_v      : STD_LOGIC;
76         VARIABLE cmp_Cond_v      : CMP_COND_Type;
77         VARIABLE cmp_Cond_Type_v : CMP_COND_TYPE_Type;
78
79     BEGIN
80         prog_counter_v  := IF2ID_i.program_counter;
81         instruction_v   := imem_data_i;
82         opcIx_v         := instruction_v (31 DOWNTO 26);
83         rD_v            := instruction_v (25 DOWNTO 21);
84         rA_v            := instruction_v (20 DOWNTO 16);
85         rB_v            := instruction_v (15 DOWNTO 11);
86         IMM16_v         := instruction_v (15 DOWNTO  0);
87         IMM_Lock_v      := '0';
88         IF (COMPATIBILITY_MODE_g = TRUE) THEN
89             delayBit_v      := '0';
90         ELSE
91             cmp_cond_v      := COND_ALL;
92             cmp_cond_type_v := COND_TYPE_ALL;
93         END IF;
94         alu_Cin_v       := CIN_ZERO;
95         alu_Action_v    := A_NOP;
96         msr_Action_v    := KEEP_CARRY;
97         branch_Action_v := NO_BR;
98         mem_Action_v    := NO_MEM;
99         transfer_Size_v := WORD;
100         wrb_Action_v    := WRB_EX;
101         -- for decoding SEXT16, SEXT8, SRC, SRC or SRL
102         code_x26_v      := instruction_v(6) & instruction_v(5) & instruction_v(0);
103         int_busy_v      := INT_CTRL_i.int_busy;
104         -- for debugging purposes
105         noLiteOpc_o     <= '0';
106
107         IF (INT_CTRL_i.setup_int = '1') THEN
108
109             alu_Op1_v       := ALU_IN_ZERO;
110             alu_Op2_v       := ALU_IN_IMM;
111             IMM16_v         := X"0010";                 -- address of _interrupt_handler vector
112             prog_counter_v  := INT_CTRL_i.rti_target;   -- delayed program counter
113             alu_Action_v    := A_ADD;
114             rD_v            := "01110";                 -- r14 reserved for storing program_counter
115             rA_v            := (OTHERS => '0');         -- also set rA and rB to avoid possible ...
116             rB_v            := (OTHERS => '0');         -- ... erronuous hazard detection in exeq module
117             int_busy_v      := '1';
118             branch_Action_v := BRL;
119
120         ELSE
121
122             alu_Op1_v := ALU_IN_REGA;
123             IF (opcIx_v(3) = '0') THEN
124                 alu_Op2_v := ALU_IN_REGB;
125             ELSE
126                 alu_Op2_v := ALU_IN_IMM;
127             END IF;
128
129             CASE opcIx_v (5 DOWNTO 4) IS
130
131                 WHEN "00" =>                                            -- ADD / RSUB
132                     IF (opcIx_v(0) = '1') THEN                          -- RSUB
133                         alu_Op1_v := ALU_IN_NOT_REGA;
134                     END IF;
135                     IF (opcIx_v(1) = '0') THEN                          -- xxx
136                         IF (opcIx_v(0) = '0') THEN
137                             alu_Cin_v := CIN_ZERO;
138                         ELSE
139                             alu_Cin_v := CIN_ONE;
140                         END IF;
141                     ELSE                                                -- xxxC
142                         alu_Cin_v := FROM_MSR;
143                     END IF;
144                     IF ((COMPATIBILITY_MODE_g = TRUE) AND (opcIx_v(3 DOWNTO 0) = "0101") AND (IMM16_v(0)= '1')) THEN
145                     -- special CMP(U) and not RSUB(I)K, supported only in compatibility mode
146                         IF (IMM16_v(1) = '1') THEN                        -- U-bit set, CMPU
147                             alu_Action_v := A_CMPU;
148                         ELSE
149                             alu_Action_v := A_CMP;
150                         END IF;
151                     ELSE
152                         alu_Action_v := A_ADD;
153                         IF (opcIx_v(2) = '0') THEN
154                             msr_Action_v := UPDATE_CARRY;
155                         END IF;
156                     END IF;
157
158                 WHEN "01" =>                                            -- MUL / BS
159                     CASE opcIx_v (2 DOWNTO 0) IS
160                         WHEN "000" =>                                   -- MUL
161                             IF (USE_HW_MUL_g = TRUE) THEN
162                                 alu_Action_v := A_MUL;
163                             ELSE
164                                 noLiteOpc_o <= '1';
165                             END IF;
166                         WHEN "001" =>                                   -- BS
167                             IF (USE_BARREL_g = TRUE) THEN
168                                 IF (instruction_v(10) = '1') THEN
169                                     alu_Action_v := A_BSLL;
170                                 ELSE
171                                     IF (instruction_v(9) = '1') THEN
172                                         alu_Action_v := A_BSRA;
173                                     ELSE
174                                         alu_Action_v := A_BSRL;
175                                     END IF;
176                                 END IF;
177                             ELSE
178                                 noLiteOpc_o <= '1';
179                             END IF;
180                         WHEN "010" =>                                             -- CMP / CMPU / CMPI (new format)
181                             IF (COMPATIBILITY_MODE_g = FALSE) THEN
182                                 IF (IMM16_v(5) = '1') THEN   -- U-bit set, CMPU
183                                     alu_Action_v := A_CMPU;
184                                 ELSE
185                                     alu_Action_v := A_CMP;
186                                 END IF;
187
188                                 IF (opcIx_v(3) = '0') THEN   -- IT, ITT, ITE is not available to CMPI
189                                     CASE IMM16_v(4 downto 3) IS
190                                         WHEN "00"   =>
191                                             cmp_Cond_Type_v := COND_TYPE_ALL;
192                                         WHEN "01"   =>
193                                             cmp_Cond_Type_v := COND_TYPE_IF_THEN;
194                                         WHEN "10"   =>
195                                             cmp_Cond_Type_v := COND_TYPE_IF_THEN_THEN;
196                                         WHEN "11"   =>
197                                             cmp_Cond_Type_v := COND_TYPE_IF_THEN_ELSE;
198                                         WHEN OTHERS =>
199                                             NULL;
200                                     END CASE;
201
202                                     CASE IMM16_v(2 downto 0) IS
203                                         WHEN "001"  =>
204                                             cmp_Cond_v := COND_EQ;
205                                         WHEN "010"  =>
206                                             cmp_Cond_v := COND_NE;
207                                         WHEN "011"  =>
208                                             cmp_Cond_v := COND_LT;
209                                         WHEN "100"  =>
210                                             cmp_Cond_v := COND_LE;
211                                         WHEN "101"  =>
212                                             cmp_Cond_v := COND_GT;
213                                         WHEN "110"  =>
214                                             cmp_Cond_v := COND_GE;
215                                         WHEN OTHERS =>
216                                             NULL;
217                                     END CASE;
218                                 END IF;
219                             ELSE
220                                 noLiteOpc_o <= '1';
221                             END IF;
222                         WHEN OTHERS =>
223                             noLiteOpc_o <= '1';
224                     END CASE;
225
226                 WHEN "10" =>
227                     IF (opcIx_v (3 DOWNTO 0) = "0100") THEN
228                         CASE code_x26_v IS
229                             WHEN "001" | "011" | "101" =>
230                                 CASE code_x26_v(2 DOWNTO 1) IS
231                                     WHEN "00" =>                        -- SRA
232                                         alu_Cin_v := FROM_IN1;
233                                     WHEN "01" =>                        -- SRC
234                                         alu_Cin_v := FROM_MSR;
235                                     WHEN "10" =>                        -- SRL
236                                         alu_Cin_v := CIN_ZERO;
237                                     WHEN OTHERS =>
238                                         noLiteOpc_o <= '1';
239                                 END CASE;
240                                 alu_Action_v := A_SHIFT;
241                                 msr_Action_v := UPDATE_CARRY;
242                             WHEN "110" =>                               -- SEXT8
243                                 alu_Action_v := A_SEXT8;
244                             WHEN "111" =>                               -- SEXT16
245                                 alu_Action_v := A_SEXT16;
246                             WHEN OTHERS  =>
247                                 noLiteOpc_o  <= '1';
248                         END CASE;
249                     ELSIF (opcIx_v (3 DOWNTO 0) = "1100") THEN          -- IMM
250                         IMM_Lock_v   := '1';
251                         -- always: IMM_LOCK_o.IMM16 <= IMM16_v;
252                         alu_Action_v := A_NOP;
253                         wrb_Action_v := NO_WRB;
254                     ELSIF (opcIx_v (3 DOWNTO 0) = "1101") THEN
255                         CASE rD_v (3 DOWNTO 0) IS
256                             WHEN "0001" =>                              -- RTI(D)
257                                 int_busy_v := '0';
258                             WHEN "0000" =>                              -- RTS(D)
259                             WHEN OTHERS  =>
260                                 noLiteOpc_o <= '1';
261                         END CASE;
262                         alu_Action_v    := A_ADD;
263                         branch_Action_v := BR;
264                         wrb_Action_v    := NO_WRB;
265                         IF (COMPATIBILITY_MODE_g = TRUE) THEN
266                             delayBit_v  := rD_v(4);
267                         END IF;
268                     ELSIF (opcIx_v (3 DOWNTO 0) = "0101") THEN
269                         CASE IMM16_v IS
270                             WHEN X"8001" =>                             -- MFS (MSR only)
271                                 alu_Action_v := A_MFS;
272                             WHEN X"C001" =>                             -- MTS (MSR only)
273                                 alu_Action_v := A_MTS;
274                                 wrb_Action_v := NO_WRB;
275                             WHEN OTHERS  =>
276                                 noLiteOpc_o  <= '1';
277                         END CASE;
278                         rB_v := (OTHERS => '0');    -- in order to prevent occasional hazards (r16, r24)
279                     ELSE
280                         CASE opcIx_v (2 DOWNTO 0) IS
281                             WHEN "000" =>
282                                 alu_Action_v := A_OR;
283                             WHEN "001" =>
284                                 alu_Action_v := A_AND;
285                             WHEN "010" =>
286                                 alu_Action_v := A_XOR;
287                             WHEN "011" =>
288                                 alu_Action_v := A_AND;
289                                 IF (opcIx_v(3) = '0') THEN
290                                     alu_Op2_v := ALU_IN_NOT_REGB;
291                                 ELSE
292                                     alu_Op2_v := ALU_IN_NOT_IMM;
293                                 END IF;
294                             WHEN "110" =>                               -- BR(I)(D)
295                                 IF (rA_v(2) = '1') THEN
296                                     branch_Action_v := BRL;
297                                 ELSE
298                                     branch_Action_v := BR;
299                                     wrb_Action_v    := NO_WRB;
300                                 END IF;
301                                 IF (rA_v(3) = '1') THEN
302                                     alu_Op1_v := ALU_IN_ZERO;
303                                 ELSE
304                                     alu_Op1_v := ALU_IN_PC;
305                                 END IF;
306                                 alu_Action_v    := A_ADD;
307                                 IF (COMPATIBILITY_MODE_g = TRUE) THEN
308                                     delayBit_v  := rA_v(4);
309                                 END IF;
310                             WHEN "111" =>
311                                 CASE rD_v(3 DOWNTO 0) IS
312                                     WHEN "0000" =>                      -- BEQ
313                                         branch_Action_v := BEQ;
314                                     WHEN "0001" =>                      -- BNE
315                                         branch_Action_v := BNE;
316                                     WHEN "0010" =>                      -- BLT
317                                         branch_Action_v := BLT;
318                                     WHEN "0011" =>                      -- BLE
319                                         branch_Action_v := BLE;
320                                     WHEN "0100" =>                      -- BGT
321                                         branch_Action_v := BGT;
322                                     WHEN "0101" =>                      -- BGE
323                                         branch_Action_v := BGE;
324                                     WHEN OTHERS =>
325                                         noLiteOpc_o <= '1';
326                                 END CASE;
327                                 alu_Action_v := A_ADD;
328                                 alu_Op1_v    := ALU_IN_PC;
329                                 IF (COMPATIBILITY_MODE_g = TRUE) THEN
330                                     delayBit_v := rD_v(4);
331                                 END IF;
332                                 wrb_Action_v := NO_WRB;     -- evaluate and update/overwrite in exeq
333                             WHEN OTHERS =>
334                                 noLiteOpc_o  <= '1';
335                         END CASE;
336                     END IF;
337
338                 WHEN "11" =>
339                     IF (opcIx_v (3 DOWNTO 0) = "1111") THEN             -- HALT
340                         alu_Action_v :=  A_HALT;
341                         wrb_Action_v := NO_WRB;
342                     ELSE
343                         alu_Action_v :=  A_ADD;
344                         CASE opcIx_v (1 DOWNTO 0) IS
345                             WHEN "00"   => transfer_Size_v := BYTE;
346                             WHEN "01"   => transfer_Size_v := HALFWORD;
347                             WHEN "10"   => transfer_Size_v := WORD;
348                             WHEN OTHERS =>
349                                 noLiteOpc_o <= '1';
350                         END CASE;
351                         IF (opcIx_v(2) = '0') THEN
352                             mem_Action_v := RD_MEM;
353                             wrb_Action_v := WRB_MEM;
354                         ELSE
355                             mem_Action_v := WR_MEM;
356                             wrb_Action_v := NO_WRB;
357                         END IF;
358                     END IF;
359
360                 WHEN OTHERS =>
361                     noLiteOpc_o  <= '1';
362
363             END CASE;
364
365         END IF;         -- interrupt test
366
367         ID2GPRF_o.rdix_rA  <= rA_v;
368         ID2GPRF_o.rdix_rB  <= rB_v;
369         ID2GPRF_o.rdix_rD  <= rD_v;
370
371         ID2EX_o.program_counter  <= prog_counter_v;
372         ID2EX_o.rdix_rA          <= rA_v;
373         ID2EX_o.rdix_rB          <= rB_v;
374         ID2EX_o.curr_rD          <= rD_v;
375         ID2EX_o.alu_Action       <= alu_Action_v;
376         ID2EX_o.alu_Op1          <= alu_Op1_v;
377         ID2EX_o.alu_Op2          <= alu_Op2_v;
378         ID2EX_o.alu_Cin          <= alu_Cin_v;
379         ID2EX_o.IMM16            <= IMM16_v;
380         ID2EX_o.IMM_Lock         <= IMM_Lock_v;
381         ID2EX_o.msr_Action       <= msr_Action_v;
382         ID2EX_o.branch_Action    <= branch_Action_v;
383         ID2EX_o.mem_Action       <= mem_Action_v;
384         ID2EX_o.transfer_Size    <= transfer_Size_v;
385         ID2EX_o.wrb_Action       <= wrb_Action_v;
386         --
387         IF (COMPATIBILITY_MODE_g = TRUE) THEN
388             ID2CTRL_o.delayBit    <= delayBit_v;
389         ELSE
390             ID2EX_o.cmp_Cond      <= cmp_Cond_v;
391             ID2EX_o.cmp_Cond_Type <= cmp_Cond_Type_v;
392         END IF;
393         ID2CTRL_o.int_busy        <= int_busy_v;
394
395     END PROCESS;
396
397 END ARCHITECTURE rtl;
398