fetch und decode kompilierbar, generelle tb, änderung in pkgs, eigene decoder entity
[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
38 --  special function register operations missing
39
40 --      case opcode is
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);
49         end if;
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);
56
57
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);
64
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);
71
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);
78
79 --=================================================================
80         if (instr_s.opcode = "00010" or instr_s.opcode = "00011") then
81
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);
89
90                 if (instr_s.signext = '1' and instr_s.immediate(11) = '1') then
91                         instr_s.immediate(31 downto 12) := (others => '1');
92                 end if;
93         end if;
94
95
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);
103
104
105
106
107 --=================================================================
108         if (instr_s.opcode = "00101" or instr_s.opcode = "00111" or instr_s.opcode = "01001") then
109
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);
117         end if;
118
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);
126 --
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);
134 --
135 --=================================================================
136         if (instr_s.opcode = "01010" or instr_s.opcode = "01011") then
137
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);
146         end if;
147
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);
156
157 --=================================================================
158         if (instr_s.opcode = "01110" or instr_s.opcode = "10000" or instr_s.opcode = "10010" or instr_s.opcode = "11010") then
159
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);
167
168                 if (instr_s.signext = '1' and instr_s.immediate(11) = '1') then
169                         instr_s.immediate(31 downto 16) := (others => '1');
170                 end if;
171         end if;
172
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);
180
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);
188
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);
196
197 --=================================================================
198         if (instr_s.opcode = "01111" or instr_s.opcode = "10001" or instr_s.opcode = "10011" or instr_s.opcode = "10101") then
199
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);
204         end if;
205
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);
210
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);
215
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);
220
221 --=================================================================
222         if (instr_s.opcode = "10110" or instr_s.opcode = "10111") then
223
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);
230         end if;
231
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
238
239 --=================================================================
240         if (instr_s.opcode = "11000" or instr_s.opcode = "11001") then
241
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);
246         end if;
247
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);
252
253 --      when others => null;
254
255 --      end case;
256
257
258
259         instr_spl <= instr_s;
260
261 end process;
262
263 end behav_d;
264
265
266 --===========================================================================
267
268