2 use IEEE.std_logic_1164.all;
3 use IEEE.numeric_std.all;
7 use work.common_pkg.all;
10 architecture behav_d of decoder is
14 split_instr: process(instruction)
16 variable instr_s : instruction_rec;
20 instr_s.predicates := instruction(31 downto 28);
21 instr_s.opcode := instruction(27 downto 27-OPCODE_WIDTH+1);
23 instr_s.reg_dest_addr := (others => '0');
24 instr_s.reg_src1_addr := (others => '0');
25 instr_s.reg_src2_addr := (others => '0');
27 instr_s.immediate := (others => '0');
28 instr_s.jmptype := (others => '0');
29 instr_s.high_low := '0';
31 instr_s.signext := '0';
33 instr_s.op_detail := (others => '0');
34 instr_s.displacement := (others => '0');
36 instr_s.op_group := ADDSUB_OP;
38 -- type op_info_t is (ADDSUB_OP,AND_OP,OR_OP, XOR_OP,SHIFT_OP);
40 -- special function register operations missing
43 --=================================================================
44 if (instr_s.opcode = "00000" or instr_s.opcode = "00001" or instr_s.opcode = "00100" or instr_s.opcode = "00110" or instr_s.opcode = "01000") then
45 -- when "00000" => --add
46 instr_s.reg_dest_addr := instruction(22 downto 19);
47 instr_s.reg_src1_addr := instruction(18 downto 15);
48 instr_s.reg_src2_addr := instruction(14 downto 11);
50 instr_s.op_detail(NO_PSW_OPT) := instruction(0); --instr_s.sreg_update;
52 instr_s.op_group := ADDSUB_OP;
54 if (instr_s.opcode = "00000") then
55 instr_s.op_detail(CARRY_OPT) := instruction(1); --instr_s.carry;
58 if (instr_s.opcode = "00001") then
59 instr_s.op_detail(SUB_OPT) := '1';
60 instr_s.op_detail(CARRY_OPT) := instruction(1); --instr_s.carry;
63 if (instr_s.opcode = "00100") then
64 instr_s.op_group := AND_OP;
67 if (instr_s.opcode = "00110") then
68 instr_s.op_group := OR_OP;
71 if (instr_s.opcode = "01000") then
72 instr_s.op_group := XOR_OP;
76 -- when "00001" => --sub
77 -- instr_s.reg_dest_addr := instruction(22 downto 19);
78 -- instr_s.reg_src1_addr := instruction(18 downto 15);
79 -- instr_s.reg_src2_addr := instruction(14 downto 11);
80 -- instr_s.carry := instruction(1);
81 -- instr_s.sreg_update := instruction(0);
84 -- when "00100" => --and
85 -- instr_s.reg_dest_addr := instruction(22 downto 19);
86 -- instr_s.reg_src1_addr := instruction(18 downto 15);
87 -- instr_s.reg_src2_addr := instruction(14 downto 11);
88 -- instr_s.carry := instruction(1); --negligible
89 -- instr_s.sreg_update := instruction(0);
91 -- when "00110" => --or
92 -- instr_s.reg_dest_addr := instruction(22 downto 19);
93 -- instr_s.reg_src1_addr := instruction(18 downto 15);
94 -- instr_s.reg_src2_addr := instruction(14 downto 11);
95 -- instr_s.carry := instruction(1); --negligible
96 -- instr_s.sreg_update := instruction(0);
98 -- when "01000" => --xor
99 -- instr_s.reg_dest_addr := instruction(22 downto 19);
100 -- instr_s.reg_src1_addr := instruction(18 downto 15);
101 -- instr_s.reg_src2_addr := instruction(14 downto 11);
102 -- instr_s.carry := instruction(1); --negligible
103 -- instr_s.sreg_update := instruction(0);
105 --=================================================================
106 if (instr_s.opcode = "00010" or instr_s.opcode = "00011") then
108 -- when "00010" => --addi
109 instr_s.reg_dest_addr := instruction(22 downto 19);
110 instr_s.reg_src1_addr := instruction(18 downto 15);
111 instr_s.immediate(11 downto 0) := instruction(14 downto 3);
112 instr_s.signext := instruction(2);
114 if (instr_s.signext = '1' and instr_s.immediate(11) = '1') then
115 instr_s.immediate(31 downto 12) := (others => '1');
118 instr_s.op_detail(IMM_OPT) := '1';
119 instr_s.op_detail(CARRY_OPT) := instruction(1);
120 instr_s.op_detail(NO_PSW_OPT) := instruction(0);
122 instr_s.op_group := ADDSUB_OP;
124 if (instr_s.opcode = "00011") then
125 instr_s.op_detail(SUB_OPT) := '1';
129 -- when "00011" => --subi
130 -- instr_s.reg_dest_addr := instruction(22 downto 19);
131 -- instr_s.reg_src1_addr := instruction(18 downto 15);
132 -- instr_s.immediate(11 downto 0) := instruction(14 downto 3);
133 -- instr_s.signext := instruction(2);
134 -- instr_s.carry := instruction(1);
135 -- instr_s.sreg_update := instruction(0);
140 --=================================================================
141 if (instr_s.opcode = "00101" or instr_s.opcode = "00111" or instr_s.opcode = "01001") then
143 -- when "00101" => --andx
144 instr_s.reg_dest_addr := instruction(22 downto 19);
145 instr_s.reg_src1_addr := instruction(22 downto 19);
146 instr_s.immediate(15 downto 0) := instruction(18 downto 3);
147 instr_s.high_low := instruction(2);
148 instr_s.fill := instruction(1);
150 if (instr_s.fill = '1') then
151 instr_s.immediate(31 downto 16) := (others => '1');
154 instr_s.op_detail(IMM_OPT) := '1';
155 instr_s.op_detail(NO_PSW_OPT) := instruction(0);
157 if (instr_s.opcode = "00101") then
158 instr_s.op_group := AND_OP;
161 if (instr_s.opcode = "00111") then
162 instr_s.op_group := OR_OP;
165 if (instr_s.opcode = "01001") then
166 instr_s.op_group := XOR_OP;
170 -- when "00111" => --orx
171 -- instr_s.reg_dest_addr := instruction(22 downto 19);
172 -- instr_s.reg_src1_addr := instruction(22 downto 19);
173 -- instr_s.immediate(15 downto 0) := instruction(18 downto 3);
174 -- instr_s.high_low := instruction(2);
175 -- instr_s.fill := instruction(1);
176 -- instr_s.sreg_update := instruction(0);
178 -- when "01001" => --xorx
179 -- instr_s.reg_dest_addr := instruction(22 downto 19);
180 -- instr_s.reg_src1_addr := instruction(22 downto 19);
181 -- instr_s.immediate(15 downto 0) := instruction(18 downto 3);
182 -- instr_s.high_low := instruction(2);
183 -- instr_s.fill := instruction(1);
184 -- instr_s.sreg_update := instruction(0);
186 --=================================================================
187 if (instr_s.opcode = "01010") then
189 -- when "01010" => --shift
190 instr_s.reg_dest_addr := instruction(22 downto 19);
191 instr_s.reg_src1_addr := instruction(18 downto 15);
192 instr_s.immediate(4 downto 0) := instruction(14 downto 10);
194 instr_s.op_detail(RIGHT_OPT) := instruction(3);
195 instr_s.op_detail(NO_PSW_OPT) := instruction(0);
196 instr_s.op_detail(CARRY_OPT) := instruction(1);
197 instr_s.op_detail(ARITH_OPT) := instruction(2);
198 instr_s.op_detail(IMM_OPT) := '1';
200 instr_s.op_group := SHIFT_OP;
203 -- when "01011" => --stackop
204 -- instr_s.reg_dest_addr := instruction(22 downto 19);
205 -- instr_s.reg_src1_addr := instruction(22 downto 19);
206 -- instr_s.immediate(1 downto 0) := instruction(18 downto 17);
207 -- instr_s.left_right := instruction(3);
208 -- instr_s.arith := instruction(2);
209 -- instr_s.carry := instruction(1);
210 -- instr_s.sreg_update := instruction(0);
212 --=================================================================
213 if (instr_s.opcode = "01110" or instr_s.opcode = "10000" or instr_s.opcode = "10010" or instr_s.opcode = "11010") then
215 -- when "01110" => --ldw
216 instr_s.reg_dest_addr := instruction(22 downto 19);
217 instr_s.reg_src1_addr := instruction(18 downto 15);
218 instr_s.signext := instruction(2);
219 instr_s.high_low := instruction(1);
220 instr_s.displacement(14 downto 0) := instruction(14 downto 0);
222 instr_s.op_group := LDST_OP;
223 instr_s.op_detail(NO_PSW_OPT) := '1';
225 if (instr_s.displacement(14) = '1') then
226 instr_s.displacement(31 downto 15) := (others => '1');
229 if (instr_s.opcode = "11010") then --ldi
230 instr_s.reg_src1_addr := instr_s.reg_dest_addr;
231 instr_s.op_detail(LOW_HIGH_OPT) := instr_s.high_low;
232 instr_s.op_detail(LDI_REPLACE_OPT) := instr_s.signext;
234 if (instr_s.high_low = '1') then
235 instr_s.immediate(31 downto 16) := instruction(18 downto 3);
236 instr_s.immediate(15 downto 0) := (others => '0');
238 instr_s.immediate(15 downto 0) := instruction(18 downto 3);
239 instr_s.immediate(31 downto 16) := (others => '0');
242 if (instr_s.signext = '1' and instr_s.immediate(11) = '1') then
243 instr_s.immediate(31 downto 16) := (others => '1');
246 instr_s.op_detail(IMM_OPT) := '1';
249 if (instr_s.opcode = "10000") then
250 instr_s.op_detail(HWORD_OPT) := '1';
253 if (instr_s.opcode = "10010") then
254 instr_s.op_detail(BYTE_OPT) := '1';
258 -- when "10000" => --ldh
259 -- instr_s.reg_dest_addr := instruction(22 downto 19);
260 -- instr_s.reg_src1_addr := instruction(18 downto 15);
261 -- instr_s.displacement(14 downto 0) := instruction(14 downto 0);
262 -- instr_s.immediate(15 downto 0) := instruction(18 downto 3);
263 -- instr_s.signext := instruction(2);
264 -- instr_s.high_low := instruction(1);
266 -- when "10010" => --ldb
267 -- instr_s.reg_dest_addr := instruction(22 downto 19);
268 -- instr_s.reg_src1_addr := instruction(18 downto 15);
269 -- instr_s.displacement(14 downto 0) := instruction(14 downto 0);
270 -- instr_s.immediate(15 downto 0) := instruction(18 downto 3);
271 -- instr_s.signext := instruction(2);
272 -- instr_s.high_low := instruction(1);
274 -- when "11010" => --ldi
275 -- instr_s.reg_dest_addr := instruction(22 downto 19);
276 -- instr_s.reg_src1_addr := instruction(18 downto 15);
277 -- instr_s.displacement(14 downto 0) := instruction(14 downto 0);
278 -- instr_s.immediate(15 downto 0) := instruction(18 downto 3);
279 -- instr_s.signext := instruction(2);
280 -- instr_s.high_low := instruction(1);
282 --=================================================================
283 if (instr_s.opcode = "01111" or instr_s.opcode = "10001" or instr_s.opcode = "10011" or instr_s.opcode = "10101") then
285 --when "01111" => --stw
286 instr_s.reg_src2_addr := instruction(22 downto 19); -- register value
287 instr_s.reg_src1_addr := instruction(18 downto 15); -- mem addr
288 instr_s.displacement(14 downto 0) := instruction(14 downto 0);
289 instr_s.op_detail(NO_PSW_OPT) := '1';
290 instr_s.op_detail(ST_OPT) := '1';
291 instr_s.op_group := LDST_OP;
293 if (instr_s.displacement(14) = '1') then
294 instr_s.displacement(31 downto 15) := (others => '1');
297 if (instr_s.opcode = "10001") then
298 instr_s.op_detail(HWORD_OPT) := '1';
301 if (instr_s.opcode = "10011") then
302 instr_s.op_detail(BYTE_OPT) := '1';
307 -- ===============================================================
309 if (instr_s.opcode = "01011") then -- stack op
310 instr_s.reg_src1_addr := instruction(22 downto 19);
311 instr_s.reg_dest_addr := instruction(22 downto 19);
312 instr_s.op_group := STACK_OP;
313 instr_s.op_detail(NO_PSW_OPT) := '1';
315 case instruction(18 downto 17) is
317 instr_s.op_detail(PUSH_OPT) := '0';
324 instr_s.op_detail(PUSH_OPT) := '1';
331 -- when "10001" => --sth
332 -- instr_s.reg_src1_addr := instruction(22 downto 19);
333 -- instr_s.reg_src2_addr := instruction(18 downto 15);
334 -- instr_s.displacement(14 downto 0) := instruction(14 downto 0);
336 -- when "10011" => --stb
337 -- instr_s.reg_src1_addr := instruction(22 downto 19);
338 -- instr_s.reg_src2_addr := instruction(18 downto 15);
339 -- instr_s.displacement(14 downto 0) := instruction(14 downto 0);
341 -- when "10101" => --stx
342 -- instr_s.reg_src1_addr := instruction(22 downto 19);
343 -- instr_s.reg_src2_addr := instruction(18 downto 15);
344 -- instr_s.displacement(14 downto 0) := instruction(14 downto 0);
346 --=================================================================
347 if (instr_s.opcode = "10110" or instr_s.opcode = "10111") then
349 -- when "10110" => --jumpop
350 instr_s.reg_src1_addr := instruction(22 downto 19); -- register value
351 instr_s.immediate(15 downto 0) := instruction(22 downto 7);
352 instr_s.bp := instruction(1);
353 instr_s.jmptype := instruction(3 downto 2);
354 instr_s.signext := instruction(0);
355 instr_s.op_detail(NO_PSW_OPT) := '1';
358 if (instr_s.opcode = "10110") then
359 instr_s.op_detail(IMM_OPT) := '1';
361 instr_s.immediate(31 downto 0) := (others => '0');
362 instr_s.op_detail(JMP_REG_OPT) := '1';
363 instr_s.op_detail(IMM_OPT) := '1';
366 if (instr_s.signext = '1' and instr_s.immediate(15) = '1') then
367 instr_s.immediate(31 downto 16) := (others => '1');
370 if (instr_s.jmptype = "00") then
371 -- instr_s.op_detail(SUB_OPT) := not instr_s.opcode(0);
372 instr_s.op_group := JMP_OP;
375 if (instr_s.jmptype = "01") then
376 instr_s.op_group := JMP_ST_OP;
377 -- instr_s.op_detail(RET_OPT) := '0';
380 if (instr_s.jmptype = "10") then
381 instr_s.op_group := JMP_ST_OP;
382 instr_s.op_detail(RET_OPT) := '1';
385 if (instr_s.predicates = "1111" or instr_s.jmptype = "10") then
390 -- when "10111" => --brreg
391 -- instr_s.reg_src1_addr := instruction(22 downto 19); -- register value
392 -- instr_s.immediate(15 downto 0) := instruction(22 downto 7); -- negligible
393 -- instr_s.bp := instruction(1); -- negligible
394 -- instr_s.jmptype := instruction(3 downto 2); -- only lsb
395 -- instr_s.signext := instruction(0); -- negligible
397 --=================================================================
398 if (instr_s.opcode = "11000" or instr_s.opcode = "11001") then
400 -- when "11000" => --cmp
401 instr_s.reg_src1_addr := instruction(22 downto 19);
402 instr_s.reg_src2_addr := instruction(18 downto 15);
404 if (instr_s.opcode = "11001") then
405 instr_s.immediate(15 downto 0) := instruction(18 downto 3);
406 instr_s.signext := instruction(2);
408 if (instr_s.signext = '1' and instr_s.immediate(15) = '1') then
409 instr_s.immediate(31 downto 16) := (others => '1');
412 instr_s.op_detail(IMM_OPT) := '1';
414 instr_s.op_detail(NO_DST_OPT) := '1';
415 instr_s.op_group := ADDSUB_OP;
416 instr_s.op_detail(SUB_OPT) := '1';
420 -- when "11001" => --cmpi
421 -- instr_s.reg_src1_addr := instruction(22 downto 19);
422 -- instr_s.reg_src2_addr := instruction(18 downto 15);
423 -- instr_s.immediate(15 downto 0) := instruction(18 downto 3);
425 -- when others => null;
431 instr_spl <= instr_s;
438 --===========================================================================