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