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 -- June, 2011: added code for MUL and BARREL (Huib)
16 --------------------------------------------------------------------------------
20 USE IEEE.std_logic_1164.all;
24 --------------------------------------------------------------------------------
26 --------------------------------------------------------------------------------
28 USE_HW_MUL_g : BOOLEAN := FALSE;
29 USE_BARREL_g : BOOLEAN := FALSE
32 IF2ID_i : IN IF2ID_Type;
33 imem_data_i : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
35 ID2GPRF_o : OUT ID2GPRF_Type;
36 ID2EX_o : OUT ID2EX_Type;
38 INT_CTRL_i : IN INT_CTRL_Type;
39 ID2CTRL_o : OUT ID2CTRL_Type;
41 noLiteOpc_s : OUT STD_LOGIC
46 --------------------------------------------------------------------------------
47 ARCHITECTURE rtl OF decode IS
48 --------------------------------------------------------------------------------
53 PROCESS (IF2ID_i, imem_data_i, INT_CTRL_i) IS
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;
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);
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
101 IF (INT_CTRL_i.setup_int = '1') THEN
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
112 branch_Action_v := BRL;
116 alu_Op1_v := ALU_IN_REGA;
117 IF (opcIx_v(3) = '0') THEN
118 alu_Op2_v := ALU_IN_REGB;
120 alu_Op2_v := ALU_IN_IMM;
123 CASE opcIx_v (5 DOWNTO 4) IS
125 WHEN "00" => -- ADD / RSUB / CMP
126 IF (opcIx_v(0) = '1') THEN -- RSUB / CMP
127 alu_Op1_v := ALU_IN_NOT_REGA;
129 IF (opcIx_v(1) = '0') THEN -- xxx
130 IF (opcIx_v(0) = '0') THEN
131 alu_Cin_v := CIN_ZERO;
133 alu_Cin_v := CIN_ONE;
136 alu_Cin_v := FROM_MSR;
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;
143 alu_Action_v := A_CMP;
146 alu_Action_v := A_ADD;
147 IF (opcIx_v(2) = '0') THEN
148 msr_Action_v := UPDATE_CARRY;
152 WHEN "01" => -- MUL / BS / FSL
153 CASE opcIx_v (2 DOWNTO 0) IS
155 IF (USE_HW_MUL_g = TRUE) THEN
156 alu_Action_v := A_MUL;
161 IF (USE_BARREL_g = TRUE) THEN
162 IF (instruction_v(10) = '1') THEN
163 alu_Action_v := A_BSLL;
165 IF (instruction_v(9) = '1') THEN
166 alu_Action_v := A_BSRA;
168 alu_Action_v := A_BSRL;
175 IF (opcIx_v(3) = '0') THEN
176 FSL_Mode_v := instruction_v(10 DOWNTO 6);
178 FSL_Mode_v := instruction_v(15 DOWNTO 11);
180 IF (FSL_Mode_v(4) = '0') THEN
181 alu_Action_v := A_FSL_GET;
182 wrb_Action_v := WRB_FSL;
184 alu_Action_v := A_FSL_PUT;
185 wrb_Action_v := NO_WRB;
187 msr_Action_v := UPDATE_CARRY;
193 IF (opcIx_v (3 DOWNTO 0) = "0100") THEN
195 WHEN "001" | "011" | "101" =>
196 CASE code_x26_v(2 DOWNTO 1) IS
198 alu_Cin_v := FROM_IN1;
200 alu_Cin_v := FROM_MSR;
202 alu_Cin_v := CIN_ZERO;
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;
215 ELSIF (opcIx_v (3 DOWNTO 0) = "1100") THEN -- IMM
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
222 WHEN "10001" => -- RTID
224 WHEN "10000" => -- RTSD
225 -- WHEN "10010" => -- RTBD
226 -- WHEN "10100" => -- RTED
230 alu_Action_v := A_ADD;
231 branch_Action_v := BR;
232 wrb_Action_v := NO_WRB;
234 ELSIF (opcIx_v (3 DOWNTO 0) = "0101") THEN
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;
244 rB_v := (OTHERS => '0'); -- in order to prevent occasional hazards (r16, r24)
246 CASE opcIx_v (2 DOWNTO 0) IS
248 alu_Action_v := A_OR;
250 alu_Action_v := A_AND;
252 alu_Action_v := A_XOR;
254 alu_Action_v := A_AND;
255 IF (opcIx_v(3) = '0') THEN
256 alu_Op2_v := ALU_IN_NOT_REGB;
258 alu_Op2_v := ALU_IN_NOT_IMM;
260 WHEN "110" => -- BR(I)
261 IF (rA_v(2) = '1') THEN
262 branch_Action_v := BRL;
264 branch_Action_v := BR;
265 wrb_Action_v := NO_WRB;
267 IF (rA_v(3) = '1') THEN
268 alu_Op1_v := ALU_IN_ZERO;
270 alu_Op1_v := ALU_IN_PC;
272 IF (rA_v(4) = '1') THEN
275 alu_Action_v := A_ADD;
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;
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
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;
311 IF (opcIx_v(2) = '0') THEN
312 mem_Action_v := RD_MEM;
313 wrb_Action_v := WRB_MEM;
315 mem_Action_v := WR_MEM;
316 wrb_Action_v := NO_WRB;
324 END IF; -- interrupt test
326 ID2GPRF_o.rdix_rA <= rA_v;
327 ID2GPRF_o.rdix_rB <= rB_v;
328 ID2GPRF_o.rdix_rD <= rD_v;
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);
350 ID2CTRL_o.delayBit <= delayBit_v;
351 ID2CTRL_o.int_busy <= int_busy_v;
357 END ARCHITECTURE rtl;