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.displacement := (others => '0');
29 instr_s.jmptype := (others => '0');
31 instr_s.sreg_update := '0';
32 instr_s.high_low := '0';
34 instr_s.signext := '0';
37 instr_s.op_detail := (others => '0');
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);
48 instr_s.carry := instruction(1);
49 instr_s.sreg_update := instruction(0);
51 instr_s.op_detail(NO_PSW_OPT) := instruction(0); --instr_s.sreg_update;
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 -- 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);
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);
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);
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);
91 --=================================================================
92 if (instr_s.opcode = "00010" or instr_s.opcode = "00011") then
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);
102 if (instr_s.signext = '1' and instr_s.immediate(11) = '1') then
103 instr_s.immediate(31 downto 12) := (others => '1');
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);
110 if (instr_s.opcode = "00011") then
111 instr_s.op_detail(SUB_OPT) := '1';
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);
126 --=================================================================
127 if (instr_s.opcode = "00101" or instr_s.opcode = "00111" or instr_s.opcode = "01001") then
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);
137 if (instr_s.fill = '1') then
138 instr_s.immediate(31 downto 16) := (others => '1');
141 instr_s.op_detail(IMM_OPT) := '1';
142 instr_s.op_detail(NO_PSW_OPT) := instruction(0);
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);
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);
161 --=================================================================
162 if (instr_s.opcode = "01010" or instr_s.opcode = "01011") then
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);
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);
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);
188 --=================================================================
189 if (instr_s.opcode = "01110" or instr_s.opcode = "10000" or instr_s.opcode = "10010" or instr_s.opcode = "11010") then
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);
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');
203 instr_s.op_detail(IMM_OPT) := '1';
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);
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);
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);
231 --=================================================================
232 if (instr_s.opcode = "01111" or instr_s.opcode = "10001" or instr_s.opcode = "10011" or instr_s.opcode = "10101") then
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);
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);
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);
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);
255 --=================================================================
256 if (instr_s.opcode = "10110" or instr_s.opcode = "10111") then
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);
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
273 --=================================================================
274 if (instr_s.opcode = "11000" or instr_s.opcode = "11001") then
276 -- when "11000" => --cmp
277 instr_s.reg_src1_addr := instruction(22 downto 19);
278 instr_s.reg_src2_addr := instruction(18 downto 15);
280 if (instr_s.opcode = "11001") then
281 instr_s.immediate(15 downto 0) := instruction(18 downto 3);
282 instr_s.signext := instruction(2);
284 if (instr_s.signext = '1' and instr_s.immediate(15) = '1') then
285 instr_s.immediate(31 downto 16) := (others => '1');
288 instr_s.op_detail(IMM_OPT) := '1';
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);
298 -- when others => null;
304 instr_spl <= instr_s;
311 --===========================================================================