register branch (untested) + de1 top level fix
[calu.git] / cpu / src / decoder_b.vhd
1 library IEEE;
2 use IEEE.std_logic_1164.all;
3 use IEEE.numeric_std.all;
4
5 use work.mem_pkg.all;
6 use work.core_pkg.all;
7 use work.common_pkg.all;
8
9
10 architecture behav_d of decoder is
11
12 begin
13
14 split_instr: process(instruction)
15
16 variable instr_s : instruction_rec;
17
18 begin
19
20         instr_s.predicates := instruction(31 downto 28);
21         instr_s.opcode := instruction(27 downto 27-OPCODE_WIDTH+1);
22
23         instr_s.reg_dest_addr := (others => '0');
24         instr_s.reg_src1_addr := (others => '0');
25         instr_s.reg_src2_addr := (others => '0');
26
27         instr_s.immediate := (others => '0');
28         instr_s.jmptype := (others => '0');
29         instr_s.high_low := '0';
30         instr_s.fill := '0';
31         instr_s.signext := '0';
32         instr_s.bp := '0';
33         instr_s.op_detail := (others => '0');
34         instr_s.displacement := (others => '0');
35         instr_s.int := '0';
36
37         instr_s.op_group := ADDSUB_OP;
38
39 --      type op_info_t is (ADDSUB_OP,AND_OP,OR_OP, XOR_OP,SHIFT_OP);
40
41 --  special function register operations missing
42
43 --      case opcode is
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);
50
51                 instr_s.op_detail(NO_PSW_OPT) := instruction(0); --instr_s.sreg_update;
52                 
53                 instr_s.op_group := ADDSUB_OP;
54
55                 if (instr_s.opcode = "00000") then              
56                         instr_s.op_detail(CARRY_OPT) := instruction(1); --instr_s.carry;
57                 end if;
58
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;
62                 end if;
63
64                 if (instr_s.opcode = "00100") then
65                         instr_s.op_group := AND_OP;
66                 end if;
67                 
68                 if (instr_s.opcode = "00110") then
69                         instr_s.op_group := OR_OP;
70                 end if;
71                 
72                 if (instr_s.opcode = "01000") then
73                         instr_s.op_group := XOR_OP;
74                 end if;
75
76         end if;
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);
83
84
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);
91
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);
98
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);
105
106 --=================================================================
107         if (instr_s.opcode = "00010" or instr_s.opcode = "00011") then
108
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);              
114
115                 if (instr_s.signext = '1' and instr_s.immediate(11) = '1') then
116                         instr_s.immediate(31 downto 12) := (others => '1');
117                 end if;
118
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);
122
123                 instr_s.op_group := ADDSUB_OP;
124
125                 if (instr_s.opcode = "00011") then
126                         instr_s.op_detail(SUB_OPT) := '1';
127                 end if;
128         end if;
129
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);
137
138
139
140
141 --=================================================================
142         if (instr_s.opcode = "00101" or instr_s.opcode = "00111" or instr_s.opcode = "01001") then
143
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);
150
151                 if (instr_s.fill = '1') then
152                         instr_s.immediate(31 downto 16) := (others => '1');
153                 end if;
154
155                 instr_s.op_detail(IMM_OPT) := '1';
156                 instr_s.op_detail(NO_PSW_OPT) := instruction(0);
157
158                 if (instr_s.opcode = "00101") then
159                         instr_s.op_group := AND_OP;
160                 end if;
161
162                 if (instr_s.opcode = "00111") then
163                         instr_s.op_group := OR_OP;
164                 end if;
165
166                 if (instr_s.opcode = "01001") then
167                         instr_s.op_group := XOR_OP;
168                 end if;
169         end if;
170
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);
178 --
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);
186 --
187 --=================================================================
188         if (instr_s.opcode = "01010") then
189
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);
194
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';
200
201                 instr_s.op_group := SHIFT_OP;
202         end if;
203
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);
212
213 --=================================================================
214         if (instr_s.opcode = "01110" or instr_s.opcode = "10000" or instr_s.opcode = "10010" or instr_s.opcode = "11010") then
215
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);
222
223                 instr_s.op_group := LDST_OP;
224                 instr_s.op_detail(NO_PSW_OPT) := '1';
225
226                 if (instr_s.displacement(14) = '1') then
227                         instr_s.displacement(31 downto 15) := (others => '1');
228                 end if;
229
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;
234                         
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');
238                         else
239                                 instr_s.immediate(15 downto 0) := instruction(18 downto 3);
240                                 instr_s.immediate(31 downto 16) := (others => '0');
241                         end if;                 
242
243                         if (instr_s.signext = '1' and instr_s.immediate(11) = '1') then
244                                 instr_s.immediate(31 downto 16) := (others => '1');
245                         end if;
246
247                         instr_s.op_detail(IMM_OPT) := '1';
248                 end if;
249                 
250                 if (instr_s.opcode = "10000") then
251                         instr_s.op_detail(HWORD_OPT) := '1';
252                 end if;
253                 
254                 if (instr_s.opcode = "10010") then
255                         instr_s.op_detail(BYTE_OPT) := '1';
256                 end if;
257         end if;
258
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);
266
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);
274
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);
282
283 --=================================================================
284         if (instr_s.opcode = "01111" or instr_s.opcode = "10001" or instr_s.opcode = "10011" or instr_s.opcode = "10101") then
285
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;
293
294                 if (instr_s.displacement(14) = '1') then
295                         instr_s.displacement(31 downto 15) := (others => '1');
296                 end if;
297
298                 if (instr_s.opcode = "10001") then
299                         instr_s.op_detail(HWORD_OPT) := '1';
300                 end if;
301                 
302                 if (instr_s.opcode = "10011") then
303                         instr_s.op_detail(BYTE_OPT) := '1';
304                 end if;
305
306         end if;
307
308         -- ===============================================================
309         
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         
316                 case instruction(18 downto 17) is
317                         when "00" => 
318                                 instr_s.op_detail(PUSH_OPT) := '0';
319                         
320                         when "01" => null;
321                         
322                         when "10" => null;
323                         
324                         when "11" =>
325                                 instr_s.op_detail(PUSH_OPT) := '1';
326                                 
327                         when others => null;
328                 end case;
329         
330         end if;
331         
332 --      when "10001" =>         --sth
333 --              instr_s.reg_src1_addr := instruction(22 downto 19);
334 --              instr_s.reg_src2_addr := instruction(18 downto 15);
335 --              instr_s.displacement(14 downto 0) := instruction(14 downto 0);
336
337 --      when "10011" =>         --stb
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);
341
342 --      when "10101" =>         --stx
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);
346
347 --=================================================================
348         if (instr_s.opcode = "10110" or instr_s.opcode = "10111") then
349
350 --      when "10110" =>         --jumpop
351                 instr_s.reg_src1_addr := instruction(22 downto 19);     -- register value
352                 instr_s.immediate(15 downto 0) := instruction(22 downto 7);
353                 instr_s.bp := instruction(1);
354                 instr_s.jmptype := instruction(3 downto 2);
355                 instr_s.signext := instruction(0);
356                 instr_s.op_detail(NO_PSW_OPT) := '1';
357                 instr_s.op_detail(DIRECT_JUMP_OPT) := instruction(4);
358                 instr_s.int := instruction(4);
359
360                 if (instr_s.opcode = "10110") then
361                         instr_s.op_detail(IMM_OPT) := '1';      
362                 else
363                         instr_s.immediate(31 downto 0) := (others => '0');
364                         instr_s.op_detail(JMP_REG_OPT) := '1';
365                         instr_s.op_detail(IMM_OPT) := '1';      
366                 end if;
367
368                 if (instr_s.signext = '1' and instr_s.immediate(15) = '1') then
369                         instr_s.immediate(31 downto 16) := (others => '1');
370                 end if;
371
372                 case instr_s.jmptype is 
373                         when "00" =>
374                                 instr_s.op_group := JMP_OP;
375                         
376                         when "01" =>
377                                 instr_s.op_group := JMP_ST_OP;
378                         
379                         when "10" =>
380                                 instr_s.op_group := JMP_ST_OP;
381                                 instr_s.op_detail(RET_OPT) := '1';
382                         
383                         when "11" =>
384                                 instr_s.op_group := JMP_OP;
385                                 instr_s.op_detail(JMP_REG_OPT) := '1';
386                                 instr_s.op_detail(IMM_OPT) := '1';
387                                 instr_s.immediate := (others => '0');
388                         
389                         when others => null;
390                 end case;
391                 
392 --              if (instr_s.jmptype = "00") then
393 ----                    instr_s.op_detail(SUB_OPT) := not instr_s.opcode(0);
394 --                      instr_s.op_group := JMP_OP;
395 --              end if;
396 --              
397 --              if (instr_s.jmptype = "01") then
398 --                      instr_s.op_group := JMP_ST_OP;
399 --              --      instr_s.op_detail(RET_OPT) := '0';
400 --              end if;
401 --
402 --              if (instr_s.jmptype = "10") then
403 --                      instr_s.op_group := JMP_ST_OP;
404 --                      instr_s.op_detail(RET_OPT) := '1';
405 --              end if;
406 --              
407 --              if (instr_s.jmptype = "11") then
408 --                      instr_s.op_group := JMP_OP;
409 --                      instr_s.op_detail(JMP_REG_OPT) := '1';
410 --                      instr_s.op_detail(IMM_OPT) := '1';
411 --                      instr_s.immediate := (others => '0');
412 --              end if;
413
414                 if (instr_s.predicates = "1111" or instr_s.jmptype = "10") then
415                         instr_s.bp := '0';
416                 end if;
417         end if;
418
419 --      when "10111" =>         --brreg
420 --              instr_s.reg_src1_addr := instruction(22 downto 19);     -- register value
421 --              instr_s.immediate(15 downto 0) := instruction(22 downto 7);     -- negligible
422 --              instr_s.bp := instruction(1);                           -- negligible
423 --              instr_s.jmptype := instruction(3 downto 2);             -- only lsb
424 --              instr_s.signext := instruction(0);                      -- negligible
425
426 --=================================================================
427         if (instr_s.opcode = "11000" or instr_s.opcode = "11001") then
428
429 --      when "11000" =>         --cmp
430                 instr_s.reg_src1_addr := instruction(22 downto 19);
431                 instr_s.reg_src2_addr := instruction(18 downto 15);
432
433                 if (instr_s.opcode = "11001") then
434                         instr_s.immediate(15 downto 0) := instruction(18 downto 3);
435                         instr_s.signext := instruction(2);              
436
437                         if (instr_s.signext = '1' and instr_s.immediate(15) = '1') then
438                                 instr_s.immediate(31 downto 16) := (others => '1');
439                         end if;
440
441                         instr_s.op_detail(IMM_OPT) := '1';
442                 end if;
443                 instr_s.op_detail(NO_DST_OPT) := '1';
444                 instr_s.op_group := ADDSUB_OP;
445                 instr_s.op_detail(SUB_OPT) := '1';
446
447         end if;
448
449 --      when "11001" =>         --cmpi
450 --              instr_s.reg_src1_addr := instruction(22 downto 19);
451 --              instr_s.reg_src2_addr := instruction(18 downto 15);
452 --              instr_s.immediate(15 downto 0) := instruction(18 downto 3);
453
454 --      when others => null;
455
456 --      end case;
457
458
459
460         instr_spl <= instr_s;
461
462 end process;
463
464 end behav_d;
465
466
467 --===========================================================================
468
469