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';
38 -- special function register operations missing
41 --=================================================================
42 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
43 -- when "00000" => --add
44 instr_s.reg_dest_addr := instruction(22 downto 19);
45 instr_s.reg_src1_addr := instruction(18 downto 15);
46 instr_s.reg_src2_addr := instruction(14 downto 11);
47 instr_s.carry := instruction(1);
48 instr_s.sreg_update := instruction(0);
50 -- when "00001" => --sub
51 -- instr_s.reg_dest_addr := instruction(22 downto 19);
52 -- instr_s.reg_src1_addr := instruction(18 downto 15);
53 -- instr_s.reg_src2_addr := instruction(14 downto 11);
54 -- instr_s.carry := instruction(1);
55 -- instr_s.sreg_update := instruction(0);
58 -- when "00100" => --and
59 -- instr_s.reg_dest_addr := instruction(22 downto 19);
60 -- instr_s.reg_src1_addr := instruction(18 downto 15);
61 -- instr_s.reg_src2_addr := instruction(14 downto 11);
62 -- instr_s.carry := instruction(1); --negligible
63 -- instr_s.sreg_update := instruction(0);
65 -- when "00110" => --or
66 -- instr_s.reg_dest_addr := instruction(22 downto 19);
67 -- instr_s.reg_src1_addr := instruction(18 downto 15);
68 -- instr_s.reg_src2_addr := instruction(14 downto 11);
69 -- instr_s.carry := instruction(1); --negligible
70 -- instr_s.sreg_update := instruction(0);
72 -- when "01000" => --xor
73 -- instr_s.reg_dest_addr := instruction(22 downto 19);
74 -- instr_s.reg_src1_addr := instruction(18 downto 15);
75 -- instr_s.reg_src2_addr := instruction(14 downto 11);
76 -- instr_s.carry := instruction(1); --negligible
77 -- instr_s.sreg_update := instruction(0);
79 --=================================================================
80 if (instr_s.opcode = "00010" or instr_s.opcode = "00011") then
82 -- when "00010" => --addi
83 instr_s.reg_dest_addr := instruction(22 downto 19);
84 instr_s.reg_src1_addr := instruction(18 downto 15);
85 instr_s.immediate(11 downto 0) := instruction(14 downto 3);
86 instr_s.signext := instruction(2);
87 instr_s.carry := instruction(1);
88 instr_s.sreg_update := instruction(0);
90 if (instr_s.signext = '1' and instr_s.immediate(11) = '1') then
91 instr_s.immediate(31 downto 12) := (others => '1');
96 -- when "00011" => --subi
97 -- instr_s.reg_dest_addr := instruction(22 downto 19);
98 -- instr_s.reg_src1_addr := instruction(18 downto 15);
99 -- instr_s.immediate(11 downto 0) := instruction(14 downto 3);
100 -- instr_s.signext := instruction(2);
101 -- instr_s.carry := instruction(1);
102 -- instr_s.sreg_update := instruction(0);
107 --=================================================================
108 if (instr_s.opcode = "00101" or instr_s.opcode = "00111" or instr_s.opcode = "01001") then
110 -- when "00101" => --andx
111 instr_s.reg_dest_addr := instruction(22 downto 19);
112 instr_s.reg_src1_addr := instruction(22 downto 19);
113 instr_s.immediate(15 downto 0) := instruction(18 downto 3);
114 instr_s.high_low := instruction(2);
115 instr_s.fill := instruction(1);
116 instr_s.sreg_update := instruction(0);
119 -- when "00111" => --orx
120 -- instr_s.reg_dest_addr := instruction(22 downto 19);
121 -- instr_s.reg_src1_addr := instruction(22 downto 19);
122 -- instr_s.immediate(15 downto 0) := instruction(18 downto 3);
123 -- instr_s.high_low := instruction(2);
124 -- instr_s.fill := instruction(1);
125 -- instr_s.sreg_update := instruction(0);
127 -- when "01001" => --xorx
128 -- instr_s.reg_dest_addr := instruction(22 downto 19);
129 -- instr_s.reg_src1_addr := instruction(22 downto 19);
130 -- instr_s.immediate(15 downto 0) := instruction(18 downto 3);
131 -- instr_s.high_low := instruction(2);
132 -- instr_s.fill := instruction(1);
133 -- instr_s.sreg_update := instruction(0);
135 --=================================================================
136 if (instr_s.opcode = "01010" or instr_s.opcode = "01011") then
138 -- when "01010" => --shift
139 instr_s.reg_dest_addr := instruction(22 downto 19);
140 instr_s.reg_src1_addr := instruction(18 downto 15);
141 instr_s.immediate(4 downto 0) := instruction(14 downto 10);
142 instr_s.left_right := instruction(3);
143 instr_s.arith := instruction(2);
144 instr_s.carry := instruction(1);
145 instr_s.sreg_update := instruction(0);
148 -- when "01011" => --stackop
149 -- instr_s.reg_dest_addr := instruction(22 downto 19);
150 -- instr_s.reg_src1_addr := instruction(22 downto 19);
151 -- instr_s.immediate(1 downto 0) := instruction(18 downto 17);
152 -- instr_s.left_right := instruction(3);
153 -- instr_s.arith := instruction(2);
154 -- instr_s.carry := instruction(1);
155 -- instr_s.sreg_update := instruction(0);
157 --=================================================================
158 if (instr_s.opcode = "01110" or instr_s.opcode = "10000" or instr_s.opcode = "10010" or instr_s.opcode = "11010") then
160 -- when "01110" => --ldw
161 instr_s.reg_dest_addr := instruction(22 downto 19);
162 instr_s.reg_src1_addr := instruction(18 downto 15);
163 instr_s.displacement(14 downto 0) := instruction(14 downto 0);
164 instr_s.immediate(15 downto 0) := instruction(18 downto 3);
165 instr_s.signext := instruction(2);
166 instr_s.high_low := instruction(1);
168 if (instr_s.signext = '1' and instr_s.immediate(11) = '1') then
169 instr_s.immediate(31 downto 16) := (others => '1');
173 -- when "10000" => --ldh
174 -- instr_s.reg_dest_addr := instruction(22 downto 19);
175 -- instr_s.reg_src1_addr := instruction(18 downto 15);
176 -- instr_s.displacement(14 downto 0) := instruction(14 downto 0);
177 -- instr_s.immediate(15 downto 0) := instruction(18 downto 3);
178 -- instr_s.signext := instruction(2);
179 -- instr_s.high_low := instruction(1);
181 -- when "10010" => --ldb
182 -- instr_s.reg_dest_addr := instruction(22 downto 19);
183 -- instr_s.reg_src1_addr := instruction(18 downto 15);
184 -- instr_s.displacement(14 downto 0) := instruction(14 downto 0);
185 -- instr_s.immediate(15 downto 0) := instruction(18 downto 3);
186 -- instr_s.signext := instruction(2);
187 -- instr_s.high_low := instruction(1);
189 -- when "11010" => --ldi
190 -- instr_s.reg_dest_addr := instruction(22 downto 19);
191 -- instr_s.reg_src1_addr := instruction(18 downto 15);
192 -- instr_s.displacement(14 downto 0) := instruction(14 downto 0);
193 -- instr_s.immediate(15 downto 0) := instruction(18 downto 3);
194 -- instr_s.signext := instruction(2);
195 -- instr_s.high_low := instruction(1);
197 --=================================================================
198 if (instr_s.opcode = "01111" or instr_s.opcode = "10001" or instr_s.opcode = "10011" or instr_s.opcode = "10101") then
200 --when "01111" => --stw
201 instr_s.reg_src1_addr := instruction(22 downto 19); -- register value
202 instr_s.reg_src2_addr := instruction(18 downto 15); -- mem addr
203 instr_s.displacement(14 downto 0) := instruction(14 downto 0);
206 -- when "10001" => --sth
207 -- instr_s.reg_src1_addr := instruction(22 downto 19);
208 -- instr_s.reg_src2_addr := instruction(18 downto 15);
209 -- instr_s.displacement(14 downto 0) := instruction(14 downto 0);
211 -- when "10011" => --stb
212 -- instr_s.reg_src1_addr := instruction(22 downto 19);
213 -- instr_s.reg_src2_addr := instruction(18 downto 15);
214 -- instr_s.displacement(14 downto 0) := instruction(14 downto 0);
216 -- when "10101" => --stx
217 -- instr_s.reg_src1_addr := instruction(22 downto 19);
218 -- instr_s.reg_src2_addr := instruction(18 downto 15);
219 -- instr_s.displacement(14 downto 0) := instruction(14 downto 0);
221 --=================================================================
222 if (instr_s.opcode = "10110" or instr_s.opcode = "10111") then
224 -- when "10110" => --jumpop
225 instr_s.reg_src1_addr := instruction(22 downto 19); -- register value
226 instr_s.immediate(15 downto 0) := instruction(22 downto 7);
227 instr_s.bp := instruction(1);
228 instr_s.jmptype := instruction(3 downto 2);
229 instr_s.signext := instruction(0);
232 -- when "10111" => --brreg
233 -- instr_s.reg_src1_addr := instruction(22 downto 19); -- register value
234 -- instr_s.immediate(15 downto 0) := instruction(22 downto 7); -- negligible
235 -- instr_s.bp := instruction(1); -- negligible
236 -- instr_s.jmptype := instruction(3 downto 2); -- only lsb
237 -- instr_s.signext := instruction(0); -- negligible
239 --=================================================================
240 if (instr_s.opcode = "11000" or instr_s.opcode = "11001") then
242 -- when "11000" => --cmp
243 instr_s.reg_src1_addr := instruction(22 downto 19);
244 instr_s.reg_src2_addr := instruction(18 downto 15);
245 instr_s.immediate(15 downto 0) := instruction(18 downto 3);
248 -- when "11001" => --cmpi
249 -- instr_s.reg_src1_addr := instruction(22 downto 19);
250 -- instr_s.reg_src2_addr := instruction(18 downto 15);
251 -- instr_s.immediate(15 downto 0) := instruction(18 downto 3);
253 -- when others => null;
259 instr_spl <= instr_s;
266 --===========================================================================