]> rtime.felk.cvut.cz Git - fpga/lx-cpu1/tumbl.git/blob - hw/decode.vhd
Remove FSL from Tumbl completely
[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 := FALSE;
29         USE_BARREL_g : BOOLEAN := FALSE
30         );
31     PORT (
32         IF2ID_i     :  IN IF2ID_Type;
33         imem_data_i :  IN STD_LOGIC_VECTOR (31 DOWNTO 0);
34         --
35         ID2GPRF_o   : OUT ID2GPRF_Type;
36         ID2EX_o     : OUT ID2EX_Type;
37         --
38         INT_CTRL_i  :  IN INT_CTRL_Type;
39         ID2CTRL_o   : OUT ID2CTRL_Type;
40                                 --
41                                 noLiteOpc_o : OUT STD_LOGIC
42         );
43 END ENTITY decode;
44
45
46 --------------------------------------------------------------------------------
47 ARCHITECTURE rtl OF decode IS
48 --------------------------------------------------------------------------------
49
50 BEGIN
51
52 p_decode:
53     PROCESS (IF2ID_i, imem_data_i, INT_CTRL_i) IS
54
55         VARIABLE prog_counter_v  : STD_LOGIC_VECTOR (31 DOWNTO 0);
56         VARIABLE opcIx_v         : STD_LOGIC_VECTOR ( 5 DOWNTO 0);
57         VARIABLE instruction_v   : STD_LOGIC_VECTOR (31 DOWNTO 0);
58         VARIABLE rD_v            : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
59         VARIABLE rA_v            : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
60         VARIABLE rB_v            : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
61         VARIABLE IMM16_v         : STD_LOGIC_VECTOR (15 DOWNTO 0);
62         VARIABLE code_x26_v      : STD_LOGIC_VECTOR ( 2 DOWNTO 0);
63         VARIABLE IMM_Lock_v      : STD_LOGIC;
64         VARIABLE alu_Action_v    : ALU_ACTION_Type;
65         VARIABLE alu_Op1_v       : ALU_IN1_Type;
66         VARIABLE alu_Op2_v       : ALU_IN2_Type;
67         VARIABLE alu_Cin_v       : ALU_CIN_Type;
68         VARIABLE msr_Action_v    : MSR_ACTION_Type;
69         VARIABLE branch_Action_v : BRANCH_ACTION_Type;
70         VARIABLE delayBit_v      : STD_LOGIC;
71         VARIABLE mem_Action_v    : MEM_ACTION_Type;
72         VARIABLE transfer_Size_v : TRANSFER_SIZE_Type;
73         VARIABLE wrb_Action_v    : WRB_ACTION_Type;
74         VARIABLE int_busy_v      : STD_LOGIC;
75
76     BEGIN
77         prog_counter_v  := IF2ID_i.program_counter;
78         instruction_v   := imem_data_i;
79         opcIx_v         := instruction_v (31 DOWNTO 26);
80         rD_v            := instruction_v (25 DOWNTO 21);
81         rA_v            := instruction_v (20 DOWNTO 16);
82         rB_v            := instruction_v (15 DOWNTO 11);
83         IMM16_v         := instruction_v (15 DOWNTO  0);
84         IMM_Lock_v      := '0';
85         delayBit_v      := '0';
86         alu_Cin_v       := CIN_ZERO;
87         alu_Action_v    := A_NOP;
88         msr_Action_v    := KEEP_CARRY;
89         branch_Action_v := NO_BR;
90         mem_Action_v    := NO_MEM;
91         transfer_Size_v := WORD;
92         wrb_Action_v    := WRB_EX;
93         -- for decoding SEXT16, SEXT8, SRC, SRC or SRL
94         code_x26_v      := instruction_v(6) & instruction_v(5) & instruction_v(0);
95         int_busy_v      := INT_CTRL_i.int_busy;
96         -- for debugging purposes
97         noLiteOpc_o     <= '0';
98
99         IF (INT_CTRL_i.setup_int = '1') THEN
100
101             alu_Op1_v       := ALU_IN_ZERO;
102             alu_Op2_v       := ALU_IN_IMM;
103             IMM16_v         := X"0010";                 -- address of _interrupt_handler vector
104             prog_counter_v  := INT_CTRL_i.rti_target;   -- delayed program counter
105             alu_Action_v    := A_ADD;
106             rD_v            := "01110";                 -- r14 reserved for storing program_counter
107             rA_v            := (OTHERS => '0');         -- also set rA and rB to avoid possible ...
108             rB_v            := (OTHERS => '0');         -- ... erronuous hazard detection in exeq module
109             int_busy_v      := '1';
110             branch_Action_v := BRL;
111
112         ELSE
113
114             alu_Op1_v := ALU_IN_REGA;
115             IF (opcIx_v(3) = '0') THEN
116                 alu_Op2_v := ALU_IN_REGB;
117             ELSE
118                 alu_Op2_v := ALU_IN_IMM;
119             END IF;
120
121             CASE opcIx_v (5 DOWNTO 4) IS
122
123                 WHEN "00" =>                                            -- ADD / RSUB / CMP
124                     IF (opcIx_v(0) = '1') THEN                          -- RSUB / CMP
125                         alu_Op1_v := ALU_IN_NOT_REGA;
126                     END IF;
127                     IF (opcIx_v(1) = '0') THEN                          -- xxx
128                         IF (opcIx_v(0) = '0') THEN
129                             alu_Cin_v := CIN_ZERO;
130                         ELSE
131                             alu_Cin_v := CIN_ONE;
132                         END IF;
133                     ELSE                                                -- xxxC
134                         alu_Cin_v := FROM_MSR;
135                     END IF;
136                     IF ((opcIx_v(3 DOWNTO 0) = "0101") AND (IMM16_v(0)= '1')) THEN
137                     -- special CMP(U) and not RSUB(I)K
138                         IF (IMM16_v(1) = '1') THEN                        -- U-bit set, CMPU
139                             alu_Action_v := A_CMPU;
140                         ELSE
141                             alu_Action_v := A_CMP;
142                         END IF;
143                     ELSE
144                         alu_Action_v := A_ADD;
145                         IF (opcIx_v(2) = '0') THEN
146                             msr_Action_v := UPDATE_CARRY;
147                         END IF;
148                     END IF;
149
150                 WHEN "01" =>                                            -- MUL / BS
151                     CASE opcIx_v (2 DOWNTO 0) IS
152                         WHEN "000" =>                                   -- MUL
153                             IF (USE_HW_MUL_g = TRUE) THEN
154                                 alu_Action_v := A_MUL;
155                             ELSE
156                                 noLiteOpc_o <= '1';
157                             END IF;
158                         WHEN "001" =>                                   -- BS
159                             IF (USE_BARREL_g = TRUE) THEN
160                                 IF (instruction_v(10) = '1') THEN
161                                     alu_Action_v := A_BSLL;
162                                 ELSE
163                                     IF (instruction_v(9) = '1') THEN
164                                         alu_Action_v := A_BSRA;
165                                     ELSE
166                                         alu_Action_v := A_BSRL;
167                                     END IF;
168                                 END IF;
169                             ELSE
170                                 noLiteOpc_o <= '1';
171                             END IF;
172                         WHEN OTHERS =>
173                             noLiteOpc_o <= '1';
174                     END CASE;
175
176                 WHEN "10" =>
177                     IF (opcIx_v (3 DOWNTO 0) = "0100") THEN
178                         CASE code_x26_v IS
179                             WHEN "001" | "011" | "101" =>
180                                 CASE code_x26_v(2 DOWNTO 1) IS
181                                     WHEN "00" =>                        -- SRA
182                                         alu_Cin_v := FROM_IN1;
183                                     WHEN "01" =>                        -- SRC
184                                         alu_Cin_v := FROM_MSR;
185                                     WHEN "10" =>                        -- SRL
186                                         alu_Cin_v := CIN_ZERO;
187                                     WHEN OTHERS =>
188                                         noLiteOpc_o <= '1';
189                                 END CASE;
190                                 alu_Action_v := A_SHIFT;
191                                 msr_Action_v := UPDATE_CARRY;
192                             WHEN "110" =>                               -- SEXT8
193                                 alu_Action_v := A_SEXT8;
194                             WHEN "111" =>                               -- SEXT16
195                                 alu_Action_v := A_SEXT16;
196                             WHEN OTHERS  =>
197                                 noLiteOpc_o  <= '1';
198                         END CASE;
199                     ELSIF (opcIx_v (3 DOWNTO 0) = "1100") THEN          -- IMM
200                         IMM_Lock_v   := '1';
201                         -- always: IMM_LOCK_o.IMM16 <= IMM16_v;
202                         alu_Action_v := A_NOP;
203                         wrb_Action_v := NO_WRB;
204                     ELSIF (opcIx_v (3 DOWNTO 0) = "1101") THEN
205                         CASE rD_v IS
206                             WHEN "10001" =>                             -- RTID
207                                 int_busy_v := '0';
208                             WHEN "10000" =>                             -- RTSD
209 --                          WHEN "10010" =>                             -- RTBD
210 --                          WHEN "10100" =>                             -- RTED
211                             WHEN OTHERS  =>
212                                 noLiteOpc_o <= '1';
213                         END CASE;
214                         alu_Action_v    := A_ADD;
215                         branch_Action_v := BR;
216                         wrb_Action_v    := NO_WRB;
217                         delayBit_v      := '1';
218                     ELSIF (opcIx_v (3 DOWNTO 0) = "0101") THEN
219                         CASE IMM16_v IS
220                             WHEN X"8001" =>                             -- MFS (MSR only)
221                                 alu_Action_v := A_MFS;
222                             WHEN X"C001" =>                             -- MTS (MSR only)
223                                 alu_Action_v := A_MTS;
224                                 wrb_Action_v := NO_WRB;
225                             WHEN OTHERS  =>
226                                 noLiteOpc_o  <= '1';
227                         END CASE;
228                         rB_v := (OTHERS => '0');    -- in order to prevent occasional hazards (r16, r24)
229                     ELSE
230                         CASE opcIx_v (2 DOWNTO 0) IS
231                             WHEN "000" =>
232                                 alu_Action_v := A_OR;
233                             WHEN "001" =>
234                                 alu_Action_v := A_AND;
235                             WHEN "010" =>
236                                 alu_Action_v := A_XOR;
237                             WHEN "011" =>
238                                 alu_Action_v := A_AND;
239                                 IF (opcIx_v(3) = '0') THEN
240                                     alu_Op2_v := ALU_IN_NOT_REGB;
241                                 ELSE
242                                     alu_Op2_v := ALU_IN_NOT_IMM;
243                                 END IF;
244                             WHEN "110" =>                               -- BR(I)
245                                 IF (rA_v(2) = '1') THEN
246                                     branch_Action_v := BRL;
247                                 ELSE
248                                     branch_Action_v := BR;
249                                     wrb_Action_v    := NO_WRB;
250                                 END IF;
251                                 IF (rA_v(3) = '1') THEN
252                                     alu_Op1_v := ALU_IN_ZERO;
253                                 ELSE
254                                     alu_Op1_v := ALU_IN_PC;
255                                 END IF;
256                                 IF (rA_v(4) = '1') THEN
257                                     delayBit_v  := '1';
258                                 END IF;
259                                 alu_Action_v    := A_ADD;
260                             WHEN "111" =>
261                                 CASE rD_v(3 DOWNTO 0) IS
262                                     WHEN "0000" =>                      -- BEQ
263                                         branch_Action_v := BEQ;
264                                     WHEN "0001" =>                      -- BNE
265                                         branch_Action_v := BNE;
266                                     WHEN "0010" =>                      -- BLT
267                                         branch_Action_v := BLT;
268                                     WHEN "0011" =>                      -- BLE
269                                         branch_Action_v := BLE;
270                                     WHEN "0100" =>                      -- BGT
271                                         branch_Action_v := BGT;
272                                     WHEN "0101" =>                      -- BGE
273                                         branch_Action_v := BGE;
274                                     WHEN OTHERS =>
275                                         noLiteOpc_o <= '1';
276                                 END CASE;
277                                 alu_Action_v := A_ADD;
278                                 alu_Op1_v    := ALU_IN_PC;
279                                 delayBit_v   := rD_v(4);
280                             wrb_Action_v := NO_WRB;     -- evaluate and update/overwrite in exeq
281                             WHEN OTHERS =>
282                                 noLiteOpc_o  <= '1';
283                         END CASE;
284                     END IF;
285
286                 WHEN "11" =>
287                     alu_Action_v :=  A_ADD;
288                     CASE opcIx_v (1 DOWNTO 0) IS
289                         WHEN "00"   => transfer_Size_v := BYTE;
290                         WHEN "01"   => transfer_Size_v := HALFWORD;
291                         WHEN "10"   => transfer_Size_v := WORD;
292                         WHEN OTHERS =>
293                             noLiteOpc_o <= '1';
294                     END CASE;
295                     IF (opcIx_v(2) = '0') THEN
296                         mem_Action_v := RD_MEM;
297                         wrb_Action_v := WRB_MEM;
298                     ELSE
299                         mem_Action_v := WR_MEM;
300                         wrb_Action_v := NO_WRB;
301                     END IF;
302
303                 WHEN OTHERS =>
304                     noLiteOpc_o  <= '1';
305
306             END CASE;
307
308         END IF;         -- interrupt test
309
310         ID2GPRF_o.rdix_rA  <= rA_v;
311         ID2GPRF_o.rdix_rB  <= rB_v;
312         ID2GPRF_o.rdix_rD  <= rD_v;
313
314         ID2EX_o.program_counter  <= prog_counter_v;
315         ID2EX_o.rdix_rA          <= rA_v;
316         ID2EX_o.rdix_rB          <= rB_v;
317         ID2EX_o.curr_rD          <= rD_v;
318         ID2EX_o.alu_Action       <= alu_Action_v;
319         ID2EX_o.alu_Op1          <= alu_Op1_v;
320         ID2EX_o.alu_Op2          <= alu_Op2_v;
321         ID2EX_o.alu_Cin          <= alu_Cin_v;
322         ID2EX_o.IMM16            <= IMM16_v;
323         ID2EX_o.IMM_Lock         <= IMM_Lock_v;
324         ID2EX_o.msr_Action       <= msr_Action_v;
325         ID2EX_o.branch_Action    <= branch_Action_v;
326         ID2EX_o.mem_Action       <= mem_Action_v;
327         ID2EX_o.transfer_Size    <= transfer_Size_v;
328         ID2EX_o.wrb_Action       <= wrb_Action_v;
329         --
330         ID2CTRL_o.delayBit      <= delayBit_v;
331         ID2CTRL_o.int_busy      <= int_busy_v;
332
333
334
335     END PROCESS;
336
337 END ARCHITECTURE rtl;
338