b0ae0dd787eba34a5effccd7011d6ec2684fafa0
[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
35         instr_s.op_group := ADDSUB_OP;
36
37 --      type op_info_t is (ADDSUB_OP,AND_OP,OR_OP, XOR_OP,SHIFT_OP);
38
39 --  special function register operations missing
40
41 --      case opcode is
42 --=================================================================
43         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
44 --      when "00000" =>         --add
45                 instr_s.reg_dest_addr := instruction(22 downto 19);
46                 instr_s.reg_src1_addr := instruction(18 downto 15);
47                 instr_s.reg_src2_addr := instruction(14 downto 11);
48
49                 instr_s.op_detail(NO_PSW_OPT) := instruction(0); --instr_s.sreg_update;
50                 
51                 instr_s.op_group := ADDSUB_OP;
52
53                 if (instr_s.opcode = "00000") then              
54                         instr_s.op_detail(CARRY_OPT) := instruction(1); --instr_s.carry;
55                 end if;
56
57                 if (instr_s.opcode = "00001") then
58                         instr_s.op_detail(SUB_OPT) := '1';
59                         instr_s.op_detail(CARRY_OPT) := instruction(1); --instr_s.carry;
60                 end if;
61
62                 if (instr_s.opcode = "00100") then
63                         instr_s.op_group := AND_OP;
64                 end if;
65                 
66                 if (instr_s.opcode = "00110") then
67                         instr_s.op_group := OR_OP;
68                 end if;
69                 
70                 if (instr_s.opcode = "01000") then
71                         instr_s.op_group := XOR_OP;
72                 end if;
73
74         end if;
75 --      when "00001" =>         --sub
76 --              instr_s.reg_dest_addr := instruction(22 downto 19);
77 --              instr_s.reg_src1_addr := instruction(18 downto 15);
78 --              instr_s.reg_src2_addr := instruction(14 downto 11);
79 --              instr_s.carry := instruction(1);
80 --              instr_s.sreg_update := instruction(0);
81
82
83 --      when "00100" =>         --and
84 --              instr_s.reg_dest_addr := instruction(22 downto 19);
85 --              instr_s.reg_src1_addr := instruction(18 downto 15);
86 --              instr_s.reg_src2_addr := instruction(14 downto 11);
87 --              instr_s.carry := instruction(1);                        --negligible
88 --              instr_s.sreg_update := instruction(0);
89
90 --      when "00110" =>         --or
91 --              instr_s.reg_dest_addr := instruction(22 downto 19);
92 --              instr_s.reg_src1_addr := instruction(18 downto 15);
93 --              instr_s.reg_src2_addr := instruction(14 downto 11);
94 --              instr_s.carry := instruction(1);                        --negligible
95 --              instr_s.sreg_update := instruction(0);
96
97 --      when "01000" =>         --xor
98 --              instr_s.reg_dest_addr := instruction(22 downto 19);
99 --              instr_s.reg_src1_addr := instruction(18 downto 15);
100 --              instr_s.reg_src2_addr := instruction(14 downto 11);
101 --              instr_s.carry := instruction(1);                        --negligible
102 --              instr_s.sreg_update := instruction(0);
103
104 --=================================================================
105         if (instr_s.opcode = "00010" or instr_s.opcode = "00011") then
106
107 --      when "00010" =>         --addi
108                 instr_s.reg_dest_addr := instruction(22 downto 19);
109                 instr_s.reg_src1_addr := instruction(18 downto 15);
110                 instr_s.immediate(11 downto 0) := instruction(14 downto 3);
111                 instr_s.signext := instruction(2);              
112
113                 if (instr_s.signext = '1' and instr_s.immediate(11) = '1') then
114                         instr_s.immediate(31 downto 12) := (others => '1');
115                 end if;
116
117                 instr_s.op_detail(IMM_OPT) := '1';
118                 instr_s.op_detail(CARRY_OPT) := instruction(1);
119                 instr_s.op_detail(NO_PSW_OPT) := instruction(0);
120
121                 instr_s.op_group := ADDSUB_OP;
122
123                 if (instr_s.opcode = "00011") then
124                         instr_s.op_detail(SUB_OPT) := '1';
125                 end if;
126         end if;
127
128 --      when "00011" =>         --subi
129 --              instr_s.reg_dest_addr := instruction(22 downto 19);
130 --              instr_s.reg_src1_addr := instruction(18 downto 15);
131 --              instr_s.immediate(11 downto 0) := instruction(14 downto 3);
132 --              instr_s.signext := instruction(2);              
133 --              instr_s.carry := instruction(1);
134 --              instr_s.sreg_update := instruction(0);
135
136
137
138
139 --=================================================================
140         if (instr_s.opcode = "00101" or instr_s.opcode = "00111" or instr_s.opcode = "01001") then
141
142 --      when "00101" =>         --andx
143                 instr_s.reg_dest_addr := instruction(22 downto 19);
144                 instr_s.reg_src1_addr := instruction(22 downto 19);
145                 instr_s.immediate(15 downto 0) := instruction(18 downto 3);
146                 instr_s.high_low := instruction(2);             
147                 instr_s.fill := instruction(1);
148
149                 if (instr_s.fill = '1') then
150                         instr_s.immediate(31 downto 16) := (others => '1');
151                 end if;
152
153                 instr_s.op_detail(IMM_OPT) := '1';
154                 instr_s.op_detail(NO_PSW_OPT) := instruction(0);
155
156                 if (instr_s.opcode = "00111") then
157                         instr_s.op_group := AND_OP;
158                 end if;
159
160                 if (instr_s.opcode = "00111") then
161                         instr_s.op_group := OR_OP;
162                 end if;
163
164                 if (instr_s.opcode = "01001") then
165                         instr_s.op_group := XOR_OP;
166                 end if;
167         end if;
168
169 --      when "00111" =>         --orx
170 --              instr_s.reg_dest_addr := instruction(22 downto 19);
171 --              instr_s.reg_src1_addr := instruction(22 downto 19);
172 --              instr_s.immediate(15 downto 0) := instruction(18 downto 3);
173 --              instr_s.high_low := instruction(2);             
174 --              instr_s.fill := instruction(1);
175 --              instr_s.sreg_update := instruction(0);
176 --
177 --      when "01001" =>         --xorx
178 --              instr_s.reg_dest_addr := instruction(22 downto 19);
179 --              instr_s.reg_src1_addr := instruction(22 downto 19);
180 --              instr_s.immediate(15 downto 0) := instruction(18 downto 3);
181 --              instr_s.high_low := instruction(2);             
182 --              instr_s.fill := instruction(1);
183 --              instr_s.sreg_update := instruction(0);
184 --
185 --=================================================================
186         if (instr_s.opcode = "01010" or instr_s.opcode = "01011") then
187
188 --      when "01010" =>         --shift
189                 instr_s.reg_dest_addr := instruction(22 downto 19);
190                 instr_s.reg_src1_addr := instruction(18 downto 15);
191                 instr_s.immediate(4 downto 0) := instruction(14 downto 10);
192
193                 instr_s.op_detail(RIGHT_OPT) := instruction(3);
194                 instr_s.op_detail(NO_PSW_OPT) := instruction(0);
195                 instr_s.op_detail(CARRY_OPT) := instruction(1);
196                 instr_s.op_detail(ARITH_OPT) := instruction(2);
197                 instr_s.op_detail(IMM_OPT) := '1';
198
199                 instr_s.op_group := SHIFT_OP;
200         end if;
201
202 --      when "01011" =>         --stackop
203 --              instr_s.reg_dest_addr := instruction(22 downto 19);
204 --              instr_s.reg_src1_addr := instruction(22 downto 19);
205 --              instr_s.immediate(1 downto 0) := instruction(18 downto 17);
206 --              instr_s.left_right := instruction(3);           
207 --              instr_s.arith := instruction(2);                
208 --              instr_s.carry := instruction(1);
209 --              instr_s.sreg_update := instruction(0);
210
211 --=================================================================
212         if (instr_s.opcode = "01110" or instr_s.opcode = "10000" or instr_s.opcode = "10010" or instr_s.opcode = "11010") then
213
214 --      when "01110" =>         --ldw
215                 instr_s.reg_dest_addr := instruction(22 downto 19);
216                 instr_s.reg_src1_addr := instruction(18 downto 15);
217                 instr_s.immediate(15 downto 0) := instruction(18 downto 3);
218                 instr_s.signext := instruction(2);
219                 instr_s.high_low := instruction(1);
220
221                 if (instr_s.opcode = "11010") then
222                         if (instr_s.signext = '1' and instr_s.immediate(11) = '1') then
223                                 instr_s.immediate(31 downto 16) := (others => '1');
224                         end if;
225                         instr_s.immediate(14 downto 0) := instruction(14 downto 0);
226                         instr_s.immediate(WORD_WIDTH-1 downto 15) := (others => '0');
227                         instr_s.op_detail(IMM_OPT) := '1';
228                 end if;
229         end if;
230
231 --      when "10000" =>         --ldh
232 --              instr_s.reg_dest_addr := instruction(22 downto 19);
233 --              instr_s.reg_src1_addr := instruction(18 downto 15);
234 --              instr_s.displacement(14 downto 0) := instruction(14 downto 0);
235 --              instr_s.immediate(15 downto 0) := instruction(18 downto 3);
236 --              instr_s.signext := instruction(2);
237 --              instr_s.high_low := instruction(1);
238
239 --      when "10010" =>         --ldb
240 --              instr_s.reg_dest_addr := instruction(22 downto 19);
241 --              instr_s.reg_src1_addr := instruction(18 downto 15);
242 --              instr_s.displacement(14 downto 0) := instruction(14 downto 0);
243 --              instr_s.immediate(15 downto 0) := instruction(18 downto 3);
244 --              instr_s.signext := instruction(2);
245 --              instr_s.high_low := instruction(1);
246
247 --      when "11010" =>         --ldi
248 --              instr_s.reg_dest_addr := instruction(22 downto 19);
249 --              instr_s.reg_src1_addr := instruction(18 downto 15);
250 --              instr_s.displacement(14 downto 0) := instruction(14 downto 0);
251 --              instr_s.immediate(15 downto 0) := instruction(18 downto 3);
252 --              instr_s.signext := instruction(2);
253 --              instr_s.high_low := instruction(1);
254
255 --=================================================================
256         if (instr_s.opcode = "01111" or instr_s.opcode = "10001" or instr_s.opcode = "10011" or instr_s.opcode = "10101") then
257
258         --when "01111" =>               --stw
259                 instr_s.reg_src1_addr := instruction(22 downto 19);     -- register value
260                 instr_s.reg_src2_addr := instruction(18 downto 15);     -- mem addr
261                 instr_s.immediate(14 downto 0) := instruction(14 downto 0);
262         end if;
263
264 --      when "10001" =>         --sth
265 --              instr_s.reg_src1_addr := instruction(22 downto 19);
266 --              instr_s.reg_src2_addr := instruction(18 downto 15);
267 --              instr_s.displacement(14 downto 0) := instruction(14 downto 0);
268
269 --      when "10011" =>         --stb
270 --              instr_s.reg_src1_addr := instruction(22 downto 19);
271 --              instr_s.reg_src2_addr := instruction(18 downto 15);
272 --              instr_s.displacement(14 downto 0) := instruction(14 downto 0);
273
274 --      when "10101" =>         --stx
275 --              instr_s.reg_src1_addr := instruction(22 downto 19);
276 --              instr_s.reg_src2_addr := instruction(18 downto 15);
277 --              instr_s.displacement(14 downto 0) := instruction(14 downto 0);
278
279 --=================================================================
280         if (instr_s.opcode = "10110" or instr_s.opcode = "10111") then
281
282 --      when "10110" =>         --jumpop
283                 instr_s.reg_src1_addr := instruction(22 downto 19);     -- register value
284                 instr_s.immediate(15 downto 0) := instruction(22 downto 7);
285                 instr_s.bp := instruction(1);
286                 instr_s.jmptype := instruction(3 downto 2);
287                 instr_s.signext := instruction(0);
288         end if;
289
290 --      when "10111" =>         --brreg
291 --              instr_s.reg_src1_addr := instruction(22 downto 19);     -- register value
292 --              instr_s.immediate(15 downto 0) := instruction(22 downto 7);     -- negligible
293 --              instr_s.bp := instruction(1);                           -- negligible
294 --              instr_s.jmptype := instruction(3 downto 2);             -- only lsb
295 --              instr_s.signext := instruction(0);                      -- negligible
296
297 --=================================================================
298         if (instr_s.opcode = "11000" or instr_s.opcode = "11001") then
299
300 --      when "11000" =>         --cmp
301                 instr_s.reg_src1_addr := instruction(22 downto 19);
302                 instr_s.reg_src2_addr := instruction(18 downto 15);
303
304                 if (instr_s.opcode = "11001") then
305                         instr_s.immediate(15 downto 0) := instruction(18 downto 3);
306                         instr_s.signext := instruction(2);              
307
308                         if (instr_s.signext = '1' and instr_s.immediate(15) = '1') then
309                                 instr_s.immediate(31 downto 16) := (others => '1');
310                         end if;
311
312                         instr_s.op_detail(IMM_OPT) := '1';
313                 end if;
314
315         end if;
316
317 --      when "11001" =>         --cmpi
318 --              instr_s.reg_src1_addr := instruction(22 downto 19);
319 --              instr_s.reg_src2_addr := instruction(18 downto 15);
320 --              instr_s.immediate(15 downto 0) := instruction(18 downto 3);
321
322 --      when others => null;
323
324 --      end case;
325
326
327
328         instr_spl <= instr_s;
329
330 end process;
331
332 end behav_d;
333
334
335 --===========================================================================
336
337