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