1 -- `Deep Thought', a softcore CPU implemented on a FPGA
3 -- Copyright (C) 2010 Markus Hofstaetter <markus.manrow@gmx.at>
4 -- Copyright (C) 2010 Martin Perner <e0725782@student.tuwien.ac.at>
5 -- Copyright (C) 2010 Stefan Rebernig <stefan.rebernig@gmail.com>
6 -- Copyright (C) 2010 Manfred Schwarz <e0725898@student.tuwien.ac.at>
7 -- Copyright (C) 2010 Bernhard Urban <lewurm@gmail.com>
9 -- This program is free software: you can redistribute it and/or modify
10 -- it under the terms of the GNU General Public License as published by
11 -- the Free Software Foundation, either version 3 of the License, or
12 -- (at your option) any later version.
14 -- This program is distributed in the hope that it will be useful,
15 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
16 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 -- GNU General Public License for more details.
19 -- You should have received a copy of the GNU General Public License
20 -- along with this program. If not, see <http://www.gnu.org/licenses/>.
23 use IEEE.std_logic_1164.all;
24 use IEEE.numeric_std.all;
27 use work.core_pkg.all;
28 use work.common_pkg.all;
31 architecture behav_d of decoder is
35 split_instr: process(instruction)
37 variable instr_s : instruction_rec;
41 instr_s.predicates := instruction(31 downto 28);
42 instr_s.opcode := instruction(27 downto 27-OPCODE_WIDTH+1);
44 instr_s.reg_dest_addr := (others => '0');
45 instr_s.reg_src1_addr := (others => '0');
46 instr_s.reg_src2_addr := (others => '0');
48 instr_s.immediate := (others => '0');
49 instr_s.jmptype := (others => '0');
50 instr_s.high_low := '0';
52 instr_s.signext := '0';
54 instr_s.op_detail := (others => '0');
55 instr_s.displacement := (others => '0');
58 instr_s.op_group := ADDSUB_OP;
60 -- type op_info_t is (ADDSUB_OP,AND_OP,OR_OP, XOR_OP,SHIFT_OP);
62 -- special function register operations missing
65 --=================================================================
66 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
67 -- when "00000" => --add
68 instr_s.reg_dest_addr := instruction(22 downto 19);
69 instr_s.reg_src1_addr := instruction(18 downto 15);
70 instr_s.reg_src2_addr := instruction(14 downto 11);
72 instr_s.op_detail(NO_PSW_OPT) := instruction(0); --instr_s.sreg_update;
74 instr_s.op_group := ADDSUB_OP;
76 if (instr_s.opcode = "00000") then
77 instr_s.op_detail(CARRY_OPT) := instruction(1); --instr_s.carry;
80 if (instr_s.opcode = "00001") then
81 instr_s.op_detail(SUB_OPT) := '1';
82 instr_s.op_detail(CARRY_OPT) := instruction(1); --instr_s.carry;
85 if (instr_s.opcode = "00100") then
86 instr_s.op_group := AND_OP;
89 if (instr_s.opcode = "00110") then
90 instr_s.op_group := OR_OP;
93 if (instr_s.opcode = "01000") then
94 instr_s.op_group := XOR_OP;
98 -- when "00001" => --sub
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);
103 -- instr_s.sreg_update := instruction(0);
106 -- when "00100" => --and
107 -- instr_s.reg_dest_addr := instruction(22 downto 19);
108 -- instr_s.reg_src1_addr := instruction(18 downto 15);
109 -- instr_s.reg_src2_addr := instruction(14 downto 11);
110 -- instr_s.carry := instruction(1); --negligible
111 -- instr_s.sreg_update := instruction(0);
113 -- when "00110" => --or
114 -- instr_s.reg_dest_addr := instruction(22 downto 19);
115 -- instr_s.reg_src1_addr := instruction(18 downto 15);
116 -- instr_s.reg_src2_addr := instruction(14 downto 11);
117 -- instr_s.carry := instruction(1); --negligible
118 -- instr_s.sreg_update := instruction(0);
120 -- when "01000" => --xor
121 -- instr_s.reg_dest_addr := instruction(22 downto 19);
122 -- instr_s.reg_src1_addr := instruction(18 downto 15);
123 -- instr_s.reg_src2_addr := instruction(14 downto 11);
124 -- instr_s.carry := instruction(1); --negligible
125 -- instr_s.sreg_update := instruction(0);
127 --=================================================================
128 if (instr_s.opcode = "00010" or instr_s.opcode = "00011") then
130 -- when "00010" => --addi
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);
136 if (instr_s.signext = '1' and instr_s.immediate(11) = '1') then
137 instr_s.immediate(31 downto 12) := (others => '1');
140 instr_s.op_detail(IMM_OPT) := '1';
141 instr_s.op_detail(CARRY_OPT) := instruction(1);
142 instr_s.op_detail(NO_PSW_OPT) := instruction(0);
144 instr_s.op_group := ADDSUB_OP;
146 if (instr_s.opcode = "00011") then
147 instr_s.op_detail(SUB_OPT) := '1';
151 -- when "00011" => --subi
152 -- instr_s.reg_dest_addr := instruction(22 downto 19);
153 -- instr_s.reg_src1_addr := instruction(18 downto 15);
154 -- instr_s.immediate(11 downto 0) := instruction(14 downto 3);
155 -- instr_s.signext := instruction(2);
156 -- instr_s.carry := instruction(1);
157 -- instr_s.sreg_update := instruction(0);
162 --=================================================================
163 if (instr_s.opcode = "00101" or instr_s.opcode = "00111" or instr_s.opcode = "01001") then
165 -- when "00101" => --andx
166 instr_s.reg_dest_addr := instruction(22 downto 19);
167 instr_s.reg_src1_addr := instruction(22 downto 19);
168 instr_s.immediate(15 downto 0) := instruction(18 downto 3);
169 instr_s.high_low := instruction(2);
170 instr_s.fill := instruction(1);
172 if (instr_s.fill = '1') then
173 instr_s.immediate(31 downto 16) := (others => '1');
176 instr_s.op_detail(IMM_OPT) := '1';
177 instr_s.op_detail(NO_PSW_OPT) := instruction(0);
179 if (instr_s.opcode = "00101") then
180 instr_s.op_group := AND_OP;
183 if (instr_s.opcode = "00111") then
184 instr_s.op_group := OR_OP;
187 if (instr_s.opcode = "01001") then
188 instr_s.op_group := XOR_OP;
192 -- when "00111" => --orx
193 -- instr_s.reg_dest_addr := instruction(22 downto 19);
194 -- instr_s.reg_src1_addr := instruction(22 downto 19);
195 -- instr_s.immediate(15 downto 0) := instruction(18 downto 3);
196 -- instr_s.high_low := instruction(2);
197 -- instr_s.fill := instruction(1);
198 -- instr_s.sreg_update := instruction(0);
200 -- when "01001" => --xorx
201 -- instr_s.reg_dest_addr := instruction(22 downto 19);
202 -- instr_s.reg_src1_addr := instruction(22 downto 19);
203 -- instr_s.immediate(15 downto 0) := instruction(18 downto 3);
204 -- instr_s.high_low := instruction(2);
205 -- instr_s.fill := instruction(1);
206 -- instr_s.sreg_update := instruction(0);
208 --=================================================================
209 if (instr_s.opcode = "01010") then
211 -- when "01010" => --shift
212 instr_s.reg_dest_addr := instruction(22 downto 19);
213 instr_s.reg_src1_addr := instruction(18 downto 15);
214 instr_s.immediate(4 downto 0) := instruction(14 downto 10);
216 instr_s.op_detail(RIGHT_OPT) := instruction(3);
217 instr_s.op_detail(NO_PSW_OPT) := instruction(0);
218 instr_s.op_detail(CARRY_OPT) := instruction(1);
219 instr_s.op_detail(ARITH_OPT) := instruction(2);
220 instr_s.op_detail(IMM_OPT) := '1';
222 instr_s.op_group := SHIFT_OP;
225 -- when "01011" => --stackop
226 -- instr_s.reg_dest_addr := instruction(22 downto 19);
227 -- instr_s.reg_src1_addr := instruction(22 downto 19);
228 -- instr_s.immediate(1 downto 0) := instruction(18 downto 17);
229 -- instr_s.left_right := instruction(3);
230 -- instr_s.arith := instruction(2);
231 -- instr_s.carry := instruction(1);
232 -- instr_s.sreg_update := instruction(0);
234 --=================================================================
235 if (instr_s.opcode = "01110" or instr_s.opcode = "10000" or instr_s.opcode = "10010" or instr_s.opcode = "11010") then
237 -- when "01110" => --ldw
238 instr_s.reg_dest_addr := instruction(22 downto 19);
239 instr_s.reg_src1_addr := instruction(18 downto 15);
240 instr_s.signext := instruction(2);
241 instr_s.high_low := instruction(1);
242 instr_s.displacement(14 downto 0) := instruction(14 downto 0);
244 instr_s.op_group := LDST_OP;
245 instr_s.op_detail(NO_PSW_OPT) := '1';
247 if (instr_s.displacement(14) = '1') then
248 instr_s.displacement(31 downto 15) := (others => '1');
251 if (instr_s.opcode = "11010") then --ldi
252 instr_s.reg_src1_addr := instr_s.reg_dest_addr;
253 instr_s.op_detail(LOW_HIGH_OPT) := instr_s.high_low;
254 instr_s.op_detail(LDI_REPLACE_OPT) := instr_s.signext;
256 if (instr_s.high_low = '1') then
257 instr_s.immediate(31 downto 16) := instruction(18 downto 3);
258 instr_s.immediate(15 downto 0) := (others => '0');
260 instr_s.immediate(15 downto 0) := instruction(18 downto 3);
261 instr_s.immediate(31 downto 16) := (others => '0');
264 if (instr_s.signext = '1' and instr_s.immediate(11) = '1') then
265 instr_s.immediate(31 downto 16) := (others => '1');
268 instr_s.op_detail(IMM_OPT) := '1';
271 if (instr_s.opcode = "10000") then
272 instr_s.op_detail(HWORD_OPT) := '1';
275 if (instr_s.opcode = "10010") then
276 instr_s.op_detail(BYTE_OPT) := '1';
280 -- when "10000" => --ldh
281 -- instr_s.reg_dest_addr := instruction(22 downto 19);
282 -- instr_s.reg_src1_addr := instruction(18 downto 15);
283 -- instr_s.displacement(14 downto 0) := instruction(14 downto 0);
284 -- instr_s.immediate(15 downto 0) := instruction(18 downto 3);
285 -- instr_s.signext := instruction(2);
286 -- instr_s.high_low := instruction(1);
288 -- when "10010" => --ldb
289 -- instr_s.reg_dest_addr := instruction(22 downto 19);
290 -- instr_s.reg_src1_addr := instruction(18 downto 15);
291 -- instr_s.displacement(14 downto 0) := instruction(14 downto 0);
292 -- instr_s.immediate(15 downto 0) := instruction(18 downto 3);
293 -- instr_s.signext := instruction(2);
294 -- instr_s.high_low := instruction(1);
296 -- when "11010" => --ldi
297 -- instr_s.reg_dest_addr := instruction(22 downto 19);
298 -- instr_s.reg_src1_addr := instruction(18 downto 15);
299 -- instr_s.displacement(14 downto 0) := instruction(14 downto 0);
300 -- instr_s.immediate(15 downto 0) := instruction(18 downto 3);
301 -- instr_s.signext := instruction(2);
302 -- instr_s.high_low := instruction(1);
304 --=================================================================
305 if (instr_s.opcode = "01111" or instr_s.opcode = "10001" or instr_s.opcode = "10011" or instr_s.opcode = "10101") then
307 --when "01111" => --stw
308 instr_s.reg_src2_addr := instruction(22 downto 19); -- register value
309 instr_s.reg_src1_addr := instruction(18 downto 15); -- mem addr
310 instr_s.displacement(14 downto 0) := instruction(14 downto 0);
311 instr_s.op_detail(NO_PSW_OPT) := '1';
312 instr_s.op_detail(ST_OPT) := '1';
313 instr_s.op_group := LDST_OP;
315 if (instr_s.displacement(14) = '1') then
316 instr_s.displacement(31 downto 15) := (others => '1');
319 if (instr_s.opcode = "10001") then
320 instr_s.op_detail(HWORD_OPT) := '1';
323 if (instr_s.opcode = "10011") then
324 instr_s.op_detail(BYTE_OPT) := '1';
329 -- ===============================================================
331 if (instr_s.opcode = "01011") then -- stack op
332 instr_s.reg_src1_addr := instruction(22 downto 19);
333 instr_s.reg_dest_addr := instruction(22 downto 19);
334 instr_s.op_group := STACK_OP;
335 instr_s.op_detail(NO_PSW_OPT) := '1';
336 instr_s.op_detail(PWREN_OPT) := '1';
338 case instruction(18 downto 17) is
340 instr_s.op_detail(PUSH_OPT) := '0';
343 instr_s.op_detail(PUSH_OPT) := '0';
344 instr_s.op_detail(NO_DST_OPT) := '1';
347 instr_s.op_detail(PUSH_OPT) := '0';
348 instr_s.op_detail(PWREN_OPT) := '0';
351 instr_s.op_detail(PUSH_OPT) := '1';
358 -- when "10001" => --sth
359 -- instr_s.reg_src1_addr := instruction(22 downto 19);
360 -- instr_s.reg_src2_addr := instruction(18 downto 15);
361 -- instr_s.displacement(14 downto 0) := instruction(14 downto 0);
363 -- when "10011" => --stb
364 -- instr_s.reg_src1_addr := instruction(22 downto 19);
365 -- instr_s.reg_src2_addr := instruction(18 downto 15);
366 -- instr_s.displacement(14 downto 0) := instruction(14 downto 0);
368 -- when "10101" => --stx
369 -- instr_s.reg_src1_addr := instruction(22 downto 19);
370 -- instr_s.reg_src2_addr := instruction(18 downto 15);
371 -- instr_s.displacement(14 downto 0) := instruction(14 downto 0);
373 --=================================================================
374 if (instr_s.opcode = "10110" or instr_s.opcode = "10111") then
376 -- when "10110" => --jumpop
377 instr_s.reg_src1_addr := instruction(22 downto 19); -- register value
378 instr_s.immediate(15 downto 0) := instruction(22 downto 7);
379 instr_s.bp := instruction(1);
380 instr_s.jmptype := instruction(3 downto 2);
381 instr_s.signext := instruction(0);
382 instr_s.op_detail(NO_PSW_OPT) := '1';
383 instr_s.op_detail(DIRECT_JUMP_OPT) := instruction(4);
384 instr_s.int := instruction(4);
386 if (instr_s.opcode = "10110") then
387 instr_s.op_detail(IMM_OPT) := '1';
389 instr_s.immediate(31 downto 0) := (others => '0');
390 instr_s.op_detail(JMP_REG_OPT) := '1';
391 instr_s.op_detail(IMM_OPT) := '1';
394 if (instr_s.signext = '1' and instr_s.immediate(15) = '1') then
395 instr_s.immediate(31 downto 16) := (others => '1');
398 case instr_s.jmptype is
400 instr_s.op_group := JMP_OP;
403 instr_s.op_group := JMP_ST_OP;
406 instr_s.op_group := JMP_ST_OP;
407 instr_s.op_detail(RET_OPT) := '1';
410 instr_s.op_group := JMP_OP;
411 instr_s.op_detail(JMP_REG_OPT) := '1';
412 instr_s.op_detail(IMM_OPT) := '1';
413 instr_s.immediate := (others => '0');
418 -- if (instr_s.jmptype = "00") then
419 ---- instr_s.op_detail(SUB_OPT) := not instr_s.opcode(0);
420 -- instr_s.op_group := JMP_OP;
423 -- if (instr_s.jmptype = "01") then
424 -- instr_s.op_group := JMP_ST_OP;
425 -- -- instr_s.op_detail(RET_OPT) := '0';
428 -- if (instr_s.jmptype = "10") then
429 -- instr_s.op_group := JMP_ST_OP;
430 -- instr_s.op_detail(RET_OPT) := '1';
433 -- if (instr_s.jmptype = "11") then
434 -- instr_s.op_group := JMP_OP;
435 -- instr_s.op_detail(JMP_REG_OPT) := '1';
436 -- instr_s.op_detail(IMM_OPT) := '1';
437 -- instr_s.immediate := (others => '0');
440 if (instr_s.predicates = "1111" or instr_s.jmptype = "10") then
445 -- when "10111" => --brreg
446 -- instr_s.reg_src1_addr := instruction(22 downto 19); -- register value
447 -- instr_s.immediate(15 downto 0) := instruction(22 downto 7); -- negligible
448 -- instr_s.bp := instruction(1); -- negligible
449 -- instr_s.jmptype := instruction(3 downto 2); -- only lsb
450 -- instr_s.signext := instruction(0); -- negligible
452 --=================================================================
453 if (instr_s.opcode = "11000" or instr_s.opcode = "11001") then
455 -- when "11000" => --cmp
456 instr_s.reg_src1_addr := instruction(22 downto 19);
457 instr_s.reg_src2_addr := instruction(18 downto 15);
459 if (instr_s.opcode = "11001") then
460 instr_s.immediate(15 downto 0) := instruction(18 downto 3);
461 instr_s.signext := instruction(2);
463 if (instr_s.signext = '1' and instr_s.immediate(15) = '1') then
464 instr_s.immediate(31 downto 16) := (others => '1');
467 instr_s.op_detail(IMM_OPT) := '1';
469 instr_s.op_detail(NO_DST_OPT) := '1';
470 instr_s.op_group := ADDSUB_OP;
471 instr_s.op_detail(SUB_OPT) := '1';
475 -- when "11001" => --cmpi
476 -- instr_s.reg_src1_addr := instruction(22 downto 19);
477 -- instr_s.reg_src2_addr := instruction(18 downto 15);
478 -- instr_s.immediate(15 downto 0) := instruction(18 downto 3);
480 -- when others => null;
486 instr_spl <= instr_s;
493 --===========================================================================