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');
35 instr_s.op_group := ADDSUB_OP;
37 -- type op_info_t is (ADDSUB_OP,AND_OP,OR_OP, XOR_OP,SHIFT_OP);
39 -- special function register operations missing
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);
49 instr_s.op_detail(NO_PSW_OPT) := instruction(0); --instr_s.sreg_update;
51 instr_s.op_group := ADDSUB_OP;
53 if (instr_s.opcode = "00000") then
54 instr_s.op_detail(CARRY_OPT) := instruction(1); --instr_s.carry;
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;
62 if (instr_s.opcode = "00100") then
63 instr_s.op_group := AND_OP;
66 if (instr_s.opcode = "00110") then
67 instr_s.op_group := OR_OP;
70 if (instr_s.opcode = "01000") then
71 instr_s.op_group := XOR_OP;
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);
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);
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);
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);
104 --=================================================================
105 if (instr_s.opcode = "00010" or instr_s.opcode = "00011") then
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);
113 if (instr_s.signext = '1' and instr_s.immediate(11) = '1') then
114 instr_s.immediate(31 downto 12) := (others => '1');
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);
121 instr_s.op_group := ADDSUB_OP;
123 if (instr_s.opcode = "00011") then
124 instr_s.op_detail(SUB_OPT) := '1';
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);
139 --=================================================================
140 if (instr_s.opcode = "00101" or instr_s.opcode = "00111" or instr_s.opcode = "01001") then
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);
149 if (instr_s.fill = '1') then
150 instr_s.immediate(31 downto 16) := (others => '1');
153 instr_s.op_detail(IMM_OPT) := '1';
154 instr_s.op_detail(NO_PSW_OPT) := instruction(0);
156 if (instr_s.opcode = "00111") then
157 instr_s.op_group := AND_OP;
160 if (instr_s.opcode = "00111") then
161 instr_s.op_group := OR_OP;
164 if (instr_s.opcode = "01001") then
165 instr_s.op_group := XOR_OP;
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);
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);
185 --=================================================================
186 if (instr_s.opcode = "01010" or instr_s.opcode = "01011") then
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);
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';
199 instr_s.op_group := SHIFT_OP;
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);
211 --=================================================================
212 if (instr_s.opcode = "01110" or instr_s.opcode = "10000" or instr_s.opcode = "10010" or instr_s.opcode = "11010") then
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);
221 instr_s.op_group := LDST_OP;
222 instr_s.op_detail(NO_PSW_OPT) := '1';
224 if (instr_s.opcode = "11010") then
225 if (instr_s.signext = '1' and instr_s.immediate(11) = '1') then
226 instr_s.immediate(31 downto 16) := (others => '1');
228 instr_s.immediate(11 downto 0) := instruction(14 downto 3);
229 instr_s.immediate(WORD_WIDTH-1 downto 12) := (others => '0');
230 instr_s.op_detail(IMM_OPT) := '1';
234 -- when "10000" => --ldh
235 -- instr_s.reg_dest_addr := instruction(22 downto 19);
236 -- instr_s.reg_src1_addr := instruction(18 downto 15);
237 -- instr_s.displacement(14 downto 0) := instruction(14 downto 0);
238 -- instr_s.immediate(15 downto 0) := instruction(18 downto 3);
239 -- instr_s.signext := instruction(2);
240 -- instr_s.high_low := instruction(1);
242 -- when "10010" => --ldb
243 -- instr_s.reg_dest_addr := instruction(22 downto 19);
244 -- instr_s.reg_src1_addr := instruction(18 downto 15);
245 -- instr_s.displacement(14 downto 0) := instruction(14 downto 0);
246 -- instr_s.immediate(15 downto 0) := instruction(18 downto 3);
247 -- instr_s.signext := instruction(2);
248 -- instr_s.high_low := instruction(1);
250 -- when "11010" => --ldi
251 -- instr_s.reg_dest_addr := instruction(22 downto 19);
252 -- instr_s.reg_src1_addr := instruction(18 downto 15);
253 -- instr_s.displacement(14 downto 0) := instruction(14 downto 0);
254 -- instr_s.immediate(15 downto 0) := instruction(18 downto 3);
255 -- instr_s.signext := instruction(2);
256 -- instr_s.high_low := instruction(1);
258 --=================================================================
259 if (instr_s.opcode = "01111" or instr_s.opcode = "10001" or instr_s.opcode = "10011" or instr_s.opcode = "10101") then
261 --when "01111" => --stw
262 instr_s.reg_src1_addr := instruction(22 downto 19); -- register value
263 instr_s.reg_src2_addr := instruction(18 downto 15); -- mem addr
264 instr_s.immediate(14 downto 0) := instruction(14 downto 0);
267 -- when "10001" => --sth
268 -- instr_s.reg_src1_addr := instruction(22 downto 19);
269 -- instr_s.reg_src2_addr := instruction(18 downto 15);
270 -- instr_s.displacement(14 downto 0) := instruction(14 downto 0);
272 -- when "10011" => --stb
273 -- instr_s.reg_src1_addr := instruction(22 downto 19);
274 -- instr_s.reg_src2_addr := instruction(18 downto 15);
275 -- instr_s.displacement(14 downto 0) := instruction(14 downto 0);
277 -- when "10101" => --stx
278 -- instr_s.reg_src1_addr := instruction(22 downto 19);
279 -- instr_s.reg_src2_addr := instruction(18 downto 15);
280 -- instr_s.displacement(14 downto 0) := instruction(14 downto 0);
282 --=================================================================
283 if (instr_s.opcode = "10110" or instr_s.opcode = "10111") then
285 -- when "10110" => --jumpop
286 instr_s.reg_src1_addr := instruction(22 downto 19); -- register value
287 instr_s.immediate(15 downto 0) := instruction(22 downto 7);
288 instr_s.bp := instruction(1);
289 instr_s.jmptype := instruction(3 downto 2);
290 instr_s.signext := instruction(0);
293 -- when "10111" => --brreg
294 -- instr_s.reg_src1_addr := instruction(22 downto 19); -- register value
295 -- instr_s.immediate(15 downto 0) := instruction(22 downto 7); -- negligible
296 -- instr_s.bp := instruction(1); -- negligible
297 -- instr_s.jmptype := instruction(3 downto 2); -- only lsb
298 -- instr_s.signext := instruction(0); -- negligible
300 --=================================================================
301 if (instr_s.opcode = "11000" or instr_s.opcode = "11001") then
303 -- when "11000" => --cmp
304 instr_s.reg_src1_addr := instruction(22 downto 19);
305 instr_s.reg_src2_addr := instruction(18 downto 15);
307 if (instr_s.opcode = "11001") then
308 instr_s.immediate(15 downto 0) := instruction(18 downto 3);
309 instr_s.signext := instruction(2);
311 if (instr_s.signext = '1' and instr_s.immediate(15) = '1') then
312 instr_s.immediate(31 downto 16) := (others => '1');
315 instr_s.op_detail(IMM_OPT) := '1';
317 instr_s.op_detail(NO_DST_OPT) := '1';
318 instr_s.op_group := ADDSUB_OP;
319 instr_s.op_detail(SUB_OPT) := '1';
323 -- when "11001" => --cmpi
324 -- instr_s.reg_src1_addr := instruction(22 downto 19);
325 -- instr_s.reg_src2_addr := instruction(18 downto 15);
326 -- instr_s.immediate(15 downto 0) := instruction(18 downto 3);
328 -- when others => null;
334 instr_spl <= instr_s;
341 --===========================================================================