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');
37 instr_s.op_group := ADDSUB_OP;
39 -- type op_info_t is (ADDSUB_OP,AND_OP,OR_OP, XOR_OP,SHIFT_OP);
41 -- special function register operations missing
44 --=================================================================
45 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
46 -- when "00000" => --add
47 instr_s.reg_dest_addr := instruction(22 downto 19);
48 instr_s.reg_src1_addr := instruction(18 downto 15);
49 instr_s.reg_src2_addr := instruction(14 downto 11);
51 instr_s.op_detail(NO_PSW_OPT) := instruction(0); --instr_s.sreg_update;
53 instr_s.op_group := ADDSUB_OP;
55 if (instr_s.opcode = "00000") then
56 instr_s.op_detail(CARRY_OPT) := instruction(1); --instr_s.carry;
59 if (instr_s.opcode = "00001") then
60 instr_s.op_detail(SUB_OPT) := '1';
61 instr_s.op_detail(CARRY_OPT) := instruction(1); --instr_s.carry;
64 if (instr_s.opcode = "00100") then
65 instr_s.op_group := AND_OP;
68 if (instr_s.opcode = "00110") then
69 instr_s.op_group := OR_OP;
72 if (instr_s.opcode = "01000") then
73 instr_s.op_group := XOR_OP;
77 -- when "00001" => --sub
78 -- instr_s.reg_dest_addr := instruction(22 downto 19);
79 -- instr_s.reg_src1_addr := instruction(18 downto 15);
80 -- instr_s.reg_src2_addr := instruction(14 downto 11);
81 -- instr_s.carry := instruction(1);
82 -- instr_s.sreg_update := instruction(0);
85 -- when "00100" => --and
86 -- instr_s.reg_dest_addr := instruction(22 downto 19);
87 -- instr_s.reg_src1_addr := instruction(18 downto 15);
88 -- instr_s.reg_src2_addr := instruction(14 downto 11);
89 -- instr_s.carry := instruction(1); --negligible
90 -- instr_s.sreg_update := instruction(0);
92 -- when "00110" => --or
93 -- instr_s.reg_dest_addr := instruction(22 downto 19);
94 -- instr_s.reg_src1_addr := instruction(18 downto 15);
95 -- instr_s.reg_src2_addr := instruction(14 downto 11);
96 -- instr_s.carry := instruction(1); --negligible
97 -- instr_s.sreg_update := instruction(0);
99 -- when "01000" => --xor
100 -- instr_s.reg_dest_addr := instruction(22 downto 19);
101 -- instr_s.reg_src1_addr := instruction(18 downto 15);
102 -- instr_s.reg_src2_addr := instruction(14 downto 11);
103 -- instr_s.carry := instruction(1); --negligible
104 -- instr_s.sreg_update := instruction(0);
106 --=================================================================
107 if (instr_s.opcode = "00010" or instr_s.opcode = "00011") then
109 -- when "00010" => --addi
110 instr_s.reg_dest_addr := instruction(22 downto 19);
111 instr_s.reg_src1_addr := instruction(18 downto 15);
112 instr_s.immediate(11 downto 0) := instruction(14 downto 3);
113 instr_s.signext := instruction(2);
115 if (instr_s.signext = '1' and instr_s.immediate(11) = '1') then
116 instr_s.immediate(31 downto 12) := (others => '1');
119 instr_s.op_detail(IMM_OPT) := '1';
120 instr_s.op_detail(CARRY_OPT) := instruction(1);
121 instr_s.op_detail(NO_PSW_OPT) := instruction(0);
123 instr_s.op_group := ADDSUB_OP;
125 if (instr_s.opcode = "00011") then
126 instr_s.op_detail(SUB_OPT) := '1';
130 -- when "00011" => --subi
131 -- instr_s.reg_dest_addr := instruction(22 downto 19);
132 -- instr_s.reg_src1_addr := instruction(18 downto 15);
133 -- instr_s.immediate(11 downto 0) := instruction(14 downto 3);
134 -- instr_s.signext := instruction(2);
135 -- instr_s.carry := instruction(1);
136 -- instr_s.sreg_update := instruction(0);
141 --=================================================================
142 if (instr_s.opcode = "00101" or instr_s.opcode = "00111" or instr_s.opcode = "01001") then
144 -- when "00101" => --andx
145 instr_s.reg_dest_addr := instruction(22 downto 19);
146 instr_s.reg_src1_addr := instruction(22 downto 19);
147 instr_s.immediate(15 downto 0) := instruction(18 downto 3);
148 instr_s.high_low := instruction(2);
149 instr_s.fill := instruction(1);
151 if (instr_s.fill = '1') then
152 instr_s.immediate(31 downto 16) := (others => '1');
155 instr_s.op_detail(IMM_OPT) := '1';
156 instr_s.op_detail(NO_PSW_OPT) := instruction(0);
158 if (instr_s.opcode = "00101") then
159 instr_s.op_group := AND_OP;
162 if (instr_s.opcode = "00111") then
163 instr_s.op_group := OR_OP;
166 if (instr_s.opcode = "01001") then
167 instr_s.op_group := XOR_OP;
171 -- when "00111" => --orx
172 -- instr_s.reg_dest_addr := instruction(22 downto 19);
173 -- instr_s.reg_src1_addr := instruction(22 downto 19);
174 -- instr_s.immediate(15 downto 0) := instruction(18 downto 3);
175 -- instr_s.high_low := instruction(2);
176 -- instr_s.fill := instruction(1);
177 -- instr_s.sreg_update := instruction(0);
179 -- when "01001" => --xorx
180 -- instr_s.reg_dest_addr := instruction(22 downto 19);
181 -- instr_s.reg_src1_addr := instruction(22 downto 19);
182 -- instr_s.immediate(15 downto 0) := instruction(18 downto 3);
183 -- instr_s.high_low := instruction(2);
184 -- instr_s.fill := instruction(1);
185 -- instr_s.sreg_update := instruction(0);
187 --=================================================================
188 if (instr_s.opcode = "01010") then
190 -- when "01010" => --shift
191 instr_s.reg_dest_addr := instruction(22 downto 19);
192 instr_s.reg_src1_addr := instruction(18 downto 15);
193 instr_s.immediate(4 downto 0) := instruction(14 downto 10);
195 instr_s.op_detail(RIGHT_OPT) := instruction(3);
196 instr_s.op_detail(NO_PSW_OPT) := instruction(0);
197 instr_s.op_detail(CARRY_OPT) := instruction(1);
198 instr_s.op_detail(ARITH_OPT) := instruction(2);
199 instr_s.op_detail(IMM_OPT) := '1';
201 instr_s.op_group := SHIFT_OP;
204 -- when "01011" => --stackop
205 -- instr_s.reg_dest_addr := instruction(22 downto 19);
206 -- instr_s.reg_src1_addr := instruction(22 downto 19);
207 -- instr_s.immediate(1 downto 0) := instruction(18 downto 17);
208 -- instr_s.left_right := instruction(3);
209 -- instr_s.arith := instruction(2);
210 -- instr_s.carry := instruction(1);
211 -- instr_s.sreg_update := instruction(0);
213 --=================================================================
214 if (instr_s.opcode = "01110" or instr_s.opcode = "10000" or instr_s.opcode = "10010" or instr_s.opcode = "11010") then
216 -- when "01110" => --ldw
217 instr_s.reg_dest_addr := instruction(22 downto 19);
218 instr_s.reg_src1_addr := instruction(18 downto 15);
219 instr_s.signext := instruction(2);
220 instr_s.high_low := instruction(1);
221 instr_s.displacement(14 downto 0) := instruction(14 downto 0);
223 instr_s.op_group := LDST_OP;
224 instr_s.op_detail(NO_PSW_OPT) := '1';
226 if (instr_s.displacement(14) = '1') then
227 instr_s.displacement(31 downto 15) := (others => '1');
230 if (instr_s.opcode = "11010") then --ldi
231 instr_s.reg_src1_addr := instr_s.reg_dest_addr;
232 instr_s.op_detail(LOW_HIGH_OPT) := instr_s.high_low;
233 instr_s.op_detail(LDI_REPLACE_OPT) := instr_s.signext;
235 if (instr_s.high_low = '1') then
236 instr_s.immediate(31 downto 16) := instruction(18 downto 3);
237 instr_s.immediate(15 downto 0) := (others => '0');
239 instr_s.immediate(15 downto 0) := instruction(18 downto 3);
240 instr_s.immediate(31 downto 16) := (others => '0');
243 if (instr_s.signext = '1' and instr_s.immediate(11) = '1') then
244 instr_s.immediate(31 downto 16) := (others => '1');
247 instr_s.op_detail(IMM_OPT) := '1';
250 if (instr_s.opcode = "10000") then
251 instr_s.op_detail(HWORD_OPT) := '1';
254 if (instr_s.opcode = "10010") then
255 instr_s.op_detail(BYTE_OPT) := '1';
259 -- when "10000" => --ldh
260 -- instr_s.reg_dest_addr := instruction(22 downto 19);
261 -- instr_s.reg_src1_addr := instruction(18 downto 15);
262 -- instr_s.displacement(14 downto 0) := instruction(14 downto 0);
263 -- instr_s.immediate(15 downto 0) := instruction(18 downto 3);
264 -- instr_s.signext := instruction(2);
265 -- instr_s.high_low := instruction(1);
267 -- when "10010" => --ldb
268 -- instr_s.reg_dest_addr := instruction(22 downto 19);
269 -- instr_s.reg_src1_addr := instruction(18 downto 15);
270 -- instr_s.displacement(14 downto 0) := instruction(14 downto 0);
271 -- instr_s.immediate(15 downto 0) := instruction(18 downto 3);
272 -- instr_s.signext := instruction(2);
273 -- instr_s.high_low := instruction(1);
275 -- when "11010" => --ldi
276 -- instr_s.reg_dest_addr := instruction(22 downto 19);
277 -- instr_s.reg_src1_addr := instruction(18 downto 15);
278 -- instr_s.displacement(14 downto 0) := instruction(14 downto 0);
279 -- instr_s.immediate(15 downto 0) := instruction(18 downto 3);
280 -- instr_s.signext := instruction(2);
281 -- instr_s.high_low := instruction(1);
283 --=================================================================
284 if (instr_s.opcode = "01111" or instr_s.opcode = "10001" or instr_s.opcode = "10011" or instr_s.opcode = "10101") then
286 --when "01111" => --stw
287 instr_s.reg_src2_addr := instruction(22 downto 19); -- register value
288 instr_s.reg_src1_addr := instruction(18 downto 15); -- mem addr
289 instr_s.displacement(14 downto 0) := instruction(14 downto 0);
290 instr_s.op_detail(NO_PSW_OPT) := '1';
291 instr_s.op_detail(ST_OPT) := '1';
292 instr_s.op_group := LDST_OP;
294 if (instr_s.displacement(14) = '1') then
295 instr_s.displacement(31 downto 15) := (others => '1');
298 if (instr_s.opcode = "10001") then
299 instr_s.op_detail(HWORD_OPT) := '1';
302 if (instr_s.opcode = "10011") then
303 instr_s.op_detail(BYTE_OPT) := '1';
308 -- ===============================================================
310 if (instr_s.opcode = "01011") then -- stack op
311 instr_s.reg_src1_addr := instruction(22 downto 19);
312 instr_s.reg_dest_addr := instruction(22 downto 19);
313 instr_s.op_group := STACK_OP;
314 instr_s.op_detail(NO_PSW_OPT) := '1';
315 instr_s.op_detail(PWREN_OPT) := '1';
317 case instruction(18 downto 17) is
319 instr_s.op_detail(PUSH_OPT) := '0';
322 instr_s.op_detail(PUSH_OPT) := '0';
323 instr_s.op_detail(NO_DST_OPT) := '1';
326 instr_s.op_detail(PUSH_OPT) := '0';
327 instr_s.op_detail(PWREN_OPT) := '0';
330 instr_s.op_detail(PUSH_OPT) := '1';
337 -- when "10001" => --sth
338 -- instr_s.reg_src1_addr := instruction(22 downto 19);
339 -- instr_s.reg_src2_addr := instruction(18 downto 15);
340 -- instr_s.displacement(14 downto 0) := instruction(14 downto 0);
342 -- when "10011" => --stb
343 -- instr_s.reg_src1_addr := instruction(22 downto 19);
344 -- instr_s.reg_src2_addr := instruction(18 downto 15);
345 -- instr_s.displacement(14 downto 0) := instruction(14 downto 0);
347 -- when "10101" => --stx
348 -- instr_s.reg_src1_addr := instruction(22 downto 19);
349 -- instr_s.reg_src2_addr := instruction(18 downto 15);
350 -- instr_s.displacement(14 downto 0) := instruction(14 downto 0);
352 --=================================================================
353 if (instr_s.opcode = "10110" or instr_s.opcode = "10111") then
355 -- when "10110" => --jumpop
356 instr_s.reg_src1_addr := instruction(22 downto 19); -- register value
357 instr_s.immediate(15 downto 0) := instruction(22 downto 7);
358 instr_s.bp := instruction(1);
359 instr_s.jmptype := instruction(3 downto 2);
360 instr_s.signext := instruction(0);
361 instr_s.op_detail(NO_PSW_OPT) := '1';
362 instr_s.op_detail(DIRECT_JUMP_OPT) := instruction(4);
363 instr_s.int := instruction(4);
365 if (instr_s.opcode = "10110") then
366 instr_s.op_detail(IMM_OPT) := '1';
368 instr_s.immediate(31 downto 0) := (others => '0');
369 instr_s.op_detail(JMP_REG_OPT) := '1';
370 instr_s.op_detail(IMM_OPT) := '1';
373 if (instr_s.signext = '1' and instr_s.immediate(15) = '1') then
374 instr_s.immediate(31 downto 16) := (others => '1');
377 case instr_s.jmptype is
379 instr_s.op_group := JMP_OP;
382 instr_s.op_group := JMP_ST_OP;
385 instr_s.op_group := JMP_ST_OP;
386 instr_s.op_detail(RET_OPT) := '1';
389 instr_s.op_group := JMP_OP;
390 instr_s.op_detail(JMP_REG_OPT) := '1';
391 instr_s.op_detail(IMM_OPT) := '1';
392 instr_s.immediate := (others => '0');
397 -- if (instr_s.jmptype = "00") then
398 ---- instr_s.op_detail(SUB_OPT) := not instr_s.opcode(0);
399 -- instr_s.op_group := JMP_OP;
402 -- if (instr_s.jmptype = "01") then
403 -- instr_s.op_group := JMP_ST_OP;
404 -- -- instr_s.op_detail(RET_OPT) := '0';
407 -- if (instr_s.jmptype = "10") then
408 -- instr_s.op_group := JMP_ST_OP;
409 -- instr_s.op_detail(RET_OPT) := '1';
412 -- if (instr_s.jmptype = "11") then
413 -- instr_s.op_group := JMP_OP;
414 -- instr_s.op_detail(JMP_REG_OPT) := '1';
415 -- instr_s.op_detail(IMM_OPT) := '1';
416 -- instr_s.immediate := (others => '0');
419 if (instr_s.predicates = "1111" or instr_s.jmptype = "10") then
424 -- when "10111" => --brreg
425 -- instr_s.reg_src1_addr := instruction(22 downto 19); -- register value
426 -- instr_s.immediate(15 downto 0) := instruction(22 downto 7); -- negligible
427 -- instr_s.bp := instruction(1); -- negligible
428 -- instr_s.jmptype := instruction(3 downto 2); -- only lsb
429 -- instr_s.signext := instruction(0); -- negligible
431 --=================================================================
432 if (instr_s.opcode = "11000" or instr_s.opcode = "11001") then
434 -- when "11000" => --cmp
435 instr_s.reg_src1_addr := instruction(22 downto 19);
436 instr_s.reg_src2_addr := instruction(18 downto 15);
438 if (instr_s.opcode = "11001") then
439 instr_s.immediate(15 downto 0) := instruction(18 downto 3);
440 instr_s.signext := instruction(2);
442 if (instr_s.signext = '1' and instr_s.immediate(15) = '1') then
443 instr_s.immediate(31 downto 16) := (others => '1');
446 instr_s.op_detail(IMM_OPT) := '1';
448 instr_s.op_detail(NO_DST_OPT) := '1';
449 instr_s.op_group := ADDSUB_OP;
450 instr_s.op_detail(SUB_OPT) := '1';
454 -- when "11001" => --cmpi
455 -- instr_s.reg_src1_addr := instruction(22 downto 19);
456 -- instr_s.reg_src2_addr := instruction(18 downto 15);
457 -- instr_s.immediate(15 downto 0) := instruction(18 downto 3);
459 -- when others => null;
465 instr_spl <= instr_s;
472 --===========================================================================