1 ---------------------------------------------------------------------------------
4 -- Filename: decode.vhd
5 -- Description: the Instruction Decode (ID) unit for
6 -- the TUD MB-Lite implementation
8 -- Author: Huib Lincklaen Arriens
9 -- Delft University of Technology
10 -- Faculty EEMCS, Department ME&CE, Circuits and Systems
11 -- Date: September, 2010
12 -- September, 2013: core customization,
13 -- new instructions (Meloun)
14 -- June, 2011: added code for MUL and BARREL (Huib)
18 --------------------------------------------------------------------------------
22 USE IEEE.std_logic_1164.all;
25 --------------------------------------------------------------------------------
27 --------------------------------------------------------------------------------
30 USE_HW_MUL_g : BOOLEAN := TRUE;
31 USE_BARREL_g : BOOLEAN := TRUE;
32 COMPATIBILITY_MODE_g : BOOLEAN := FALSE
36 IF2ID_i : IN IF2ID_Type;
37 imem_data_i : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
39 ID2GPRF_o : OUT ID2GPRF_Type;
40 ID2EX_o : OUT ID2EX_Type;
42 INT_CTRL_i : IN INT_CTRL_Type;
43 ID2CTRL_o : OUT ID2CTRL_Type
47 --------------------------------------------------------------------------------
48 ARCHITECTURE rtl OF decode IS
49 --------------------------------------------------------------------------------
54 PROCESS (IF2ID_i, imem_data_i, INT_CTRL_i) IS
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 it_Action_v : IT_ACTION_Type;
72 VARIABLE delayBit_v : STD_LOGIC;
73 VARIABLE mem_Action_v : MEM_ACTION_Type;
74 VARIABLE transfer_Size_v : TRANSFER_SIZE_Type;
75 VARIABLE wrb_Action_v : WRB_ACTION_Type;
76 VARIABLE int_busy_v : STD_LOGIC;
77 VARIABLE condition_raw_v : STD_LOGIC_VECTOR ( 2 DOWNTO 0);
78 VARIABLE halt_v : STD_LOGIC;
82 prog_counter_v := IF2ID_i.program_counter;
83 instruction_v := imem_data_i;
84 opcIx_v := instruction_v (31 DOWNTO 26);
85 rD_v := instruction_v (25 DOWNTO 21);
86 rA_v := instruction_v (20 DOWNTO 16);
87 rB_v := instruction_v (15 DOWNTO 11);
88 IMM16_v := instruction_v (15 DOWNTO 0);
91 IF (COMPATIBILITY_MODE_g = FALSE) THEN
94 condition_raw_v := (others => '1');
95 alu_Cin_v := CIN_ZERO;
96 alu_Action_v := A_NOP;
97 msr_Action_v := KEEP_CARRY;
98 branch_Action_v := NO_BR;
99 mem_Action_v := NO_MEM;
100 transfer_Size_v := WORD;
101 wrb_Action_v := WRB_EX;
103 -- for decoding SEXT16, SEXT8, SRC, SRC or SRL
104 code_x26_v := instruction_v(6) & instruction_v(5) & instruction_v(0);
105 int_busy_v := INT_CTRL_i.int_busy;
107 IF (INT_CTRL_i.setup_int = '1') THEN
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
118 branch_Action_v := BRL;
122 alu_Op1_v := ALU_IN_REGA;
123 IF (opcIx_v(3) = '0') THEN
124 alu_Op2_v := ALU_IN_REGB;
126 alu_Op2_v := ALU_IN_IMM;
129 CASE opcIx_v (5 DOWNTO 4) IS
131 WHEN "00" => -- ADD / RSUB
132 IF (opcIx_v(0) = '1') THEN -- RSUB
133 alu_Op1_v := ALU_IN_NOT_REGA;
135 IF (opcIx_v(1) = '0') THEN -- xxx
136 IF (opcIx_v(0) = '0') THEN
137 alu_Cin_v := CIN_ZERO;
139 alu_Cin_v := CIN_ONE;
142 alu_Cin_v := FROM_MSR;
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;
149 alu_Action_v := A_CMP;
152 alu_Action_v := A_ADD;
153 IF (opcIx_v(2) = '0') THEN
154 msr_Action_v := UPDATE_CARRY;
158 WHEN "01" => -- MUL / BS
160 CASE opcIx_v (2 DOWNTO 0) IS
162 IF (USE_HW_MUL_g = TRUE) THEN
163 alu_Action_v := A_MUL;
167 IF (USE_BARREL_g = TRUE) THEN
168 IF (instruction_v(10) = '1') THEN
169 alu_Action_v := A_BSLL;
170 ELSIF (instruction_v(9) = '1') THEN
171 alu_Action_v := A_BSRA;
173 alu_Action_v := A_BSRL;
177 WHEN "010" | "011" => -- CMP(U)
178 IF (COMPATIBILITY_MODE_g = FALSE) THEN
179 IF (opcIx_v(0) = '1') THEN
180 alu_Action_v := A_CMPU;
182 alu_Action_v := A_CMP;
184 alu_Op1_v := ALU_IN_NOT_REGA;
185 alu_Cin_v := CIN_ONE;
188 WHEN "100" | "101" => -- IT(U) / ITT(U) / ITE(U)
189 IF (COMPATIBILITY_MODE_g = FALSE) THEN
190 IF (opcIx_v(0) = '1') THEN
191 alu_Action_v := A_CMPU;
193 alu_Action_v := A_CMP;
196 CASE rD_v(4 downto 3) IS
197 WHEN "00" => it_Action_v := IT;
198 WHEN "01" => it_Action_v := ITT;
199 WHEN "10" => it_Action_v := ITE;
202 condition_raw_v := rD_v(2 downto 0);
203 -- IT instruction isn't writing to anything
204 wrb_Action_v := NO_WRB;
205 alu_Op1_v := ALU_IN_NOT_REGA;
206 alu_Cin_v := CIN_ONE;
214 IF (opcIx_v (3 DOWNTO 0) = "0100") THEN
218 alu_Action_v := A_CLZ;
219 WHEN "001" | "011" | "101" =>
220 CASE code_x26_v(2 DOWNTO 1) IS
222 alu_Cin_v := FROM_IN1;
224 alu_Cin_v := FROM_MSR;
226 alu_Cin_v := CIN_ZERO;
230 alu_Action_v := A_SHIFT;
231 msr_Action_v := UPDATE_CARRY;
233 WHEN "110" => -- SEXT8
234 alu_Action_v := A_SEXT8;
235 WHEN "111" => -- SEXT16
236 alu_Action_v := A_SEXT16;
241 ELSIF (opcIx_v (3 DOWNTO 0) = "1100") THEN -- IMM
243 -- always: IMM_LOCK_o.IMM16 <= IMM16_v;
244 alu_Action_v := A_NOP;
245 wrb_Action_v := NO_WRB;
246 ELSIF (opcIx_v (3 DOWNTO 0) = "1101") THEN
248 CASE rD_v (3 DOWNTO 0) IS
249 WHEN "0001" => -- RTI(D)
251 WHEN OTHERS => -- RTS(D)
255 alu_Action_v := A_ADD;
256 branch_Action_v := BR;
257 wrb_Action_v := NO_WRB;
258 delayBit_v := rD_v(4);
260 ELSIF (opcIx_v (3 DOWNTO 0) = "0101") THEN
263 WHEN X"8001" => -- MFS (MSR only)
264 alu_Action_v := A_MFS;
265 WHEN X"C001" => -- MTS (MSR only)
266 alu_Action_v := A_MTS;
267 wrb_Action_v := NO_WRB;
271 rB_v := (OTHERS => '0'); -- in order to prevent occasional hazards (r16, r24)
275 CASE opcIx_v (2 DOWNTO 0) IS
277 alu_Action_v := A_OR;
279 alu_Action_v := A_AND;
281 alu_Action_v := A_XOR;
283 alu_Action_v := A_AND;
284 IF (opcIx_v(3) = '0') THEN
285 alu_Op2_v := ALU_IN_NOT_REGB;
287 alu_Op2_v := ALU_IN_NOT_IMM;
290 WHEN "110" => -- BR(I)(D)
291 IF (rA_v(3) = '1') THEN
292 alu_Op1_v := ALU_IN_ZERO;
294 alu_Op1_v := ALU_IN_PC;
297 IF (rA_v(2) = '1') THEN
298 branch_Action_v := BRL;
300 branch_Action_v := BR;
301 wrb_Action_v := NO_WRB;
303 alu_Action_v := A_ADD;
304 delayBit_v := rA_v(4);
307 condition_raw_v := rD_v(2 downto 0); -- Conditional branching
308 branch_Action_v := BR;
309 alu_Action_v := A_ADD;
310 alu_Op1_v := ALU_IN_PC;
311 delayBit_v := rD_v(4);
312 wrb_Action_v := NO_WRB; -- evaluate and update/overwrite in exeq
320 IF (opcIx_v (3 DOWNTO 0) = "1111") THEN -- HALT
321 alu_Action_v := A_NOP;
322 wrb_Action_v := NO_WRB;
325 alu_Action_v := A_ADD;
326 CASE opcIx_v (1 DOWNTO 0) IS
327 WHEN "00" => transfer_Size_v := BYTE;
328 WHEN "01" => transfer_Size_v := HALFWORD;
329 WHEN "10" => transfer_Size_v := WORD;
332 IF (opcIx_v(2) = '0') THEN
333 mem_Action_v := RD_MEM;
334 wrb_Action_v := WRB_MEM;
336 mem_Action_v := WR_MEM;
337 wrb_Action_v := NO_WRB;
346 END IF; -- interrupt test
348 ID2GPRF_o.rdix_rA <= rA_v;
349 ID2GPRF_o.rdix_rB <= rB_v;
350 ID2GPRF_o.rdix_rD <= rD_v;
352 ID2EX_o.program_counter <= prog_counter_v;
353 ID2EX_o.rdix_rA <= rA_v;
354 ID2EX_o.rdix_rB <= rB_v;
355 ID2EX_o.curr_rD <= rD_v;
356 ID2EX_o.alu_Action <= alu_Action_v;
357 ID2EX_o.alu_Op1 <= alu_Op1_v;
358 ID2EX_o.alu_Op2 <= alu_Op2_v;
359 ID2EX_o.alu_Cin <= alu_Cin_v;
360 ID2EX_o.IMM16 <= IMM16_v;
361 ID2EX_o.IMM_Lock <= IMM_Lock_v;
362 ID2EX_o.msr_Action <= msr_Action_v;
363 ID2EX_o.branch_Action <= branch_Action_v;
364 ID2EX_o.it_Action <= it_Action_v;
365 ID2EX_o.mem_Action <= mem_Action_v;
366 ID2EX_o.transfer_Size <= transfer_Size_v;
367 ID2EX_o.wrb_Action <= wrb_Action_v;
368 ID2EX_o.halt <= halt_v;
370 CASE condition_raw_v IS
372 ID2EX_o.condition <= COND_EQ;
374 ID2EX_o.condition <= COND_NE;
376 ID2EX_o.condition <= COND_LT;
378 ID2EX_o.condition <= COND_LE;
380 ID2EX_o.condition <= COND_GT;
382 ID2EX_o.condition <= COND_GE;
384 ID2EX_o.condition <= COND_ALL;
386 ID2EX_o.condition <= COND_ALL;
389 ID2CTRL_o.delayBit <= delayBit_v;
390 ID2CTRL_o.int_busy <= int_busy_v;
394 END ARCHITECTURE rtl;