decode stage die erste
[calu.git] / cpu / src / decode_stage_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 architecture behav of decode_stage is
10
11 signal instr_spl : instruction_rec;
12
13 signal rtw_rec, rtw_rec_nxt : read_through_write_rec;
14 signal reg1_mem_data, reg2_mem_data : gp_register_t;
15
16 begin
17
18         -- register file
19         register_ram : r2_w_ram
20                 generic map (
21                         REG_ADDR_WIDTH,
22                         WORD_WIDTH
23                 )
24                 
25                 port map (
26                         sys_clk,
27                         reg_w_addr,
28                         instr_spl.reg_src1_addr,
29                         instr_spl.reg_src2_addr,
30                         reg_we,
31                         reg_wr_data,
32                         reg1_mem_data,
33                         reg2_mem_data
34                 );
35
36
37
38 -- sync process for read through write registers
39 syn: process(sys_clk, reset)
40
41 begin
42
43         if (reset = RESET_VALUE) then
44                 rtw_rec.rtw_reg <= (others => '0');
45                 rtw_rec.rtw_reg1 <= '0';
46                 rtw_rec.rtw_reg2 <= '0';
47         elsif rising_edge(sys_clk) then
48                 rtw_rec <= rtw_rec_nxt;
49         end if;
50         
51 end process; 
52
53
54 -- async process: decides between memory and read-through-write buffer on output
55 output: process(rtw_rec)
56
57 begin
58         if (rtw_rec.rtw_reg1 = '1') then
59                 reg1_rd_data <= rtw_rec.rtw_reg;
60         else
61                 reg1_rd_data <= reg1_mem_data;
62         end if;
63
64         if (rtw_rec.rtw_reg2 = '1') then
65                 reg2_rd_data <= rtw_rec.rtw_reg;
66         else
67                 reg2_rd_data <= reg2_mem_data;
68         end if;
69 end process;
70
71
72 -- async process: checks forward condition
73 forward: process(instr_spl, reg_w_addr, reg_wr_data)
74
75 begin
76
77         rtw_rec_nxt.rtw_reg <= reg_wr_data;
78         rtw_rec_nxt.rtw_reg1 <= '0';
79         rtw_rec_nxt.rtw_reg2 <= '0';
80
81         if (reg_w_addr = instr_spl.reg_src_1_addr) then
82                 rtw_rec_nxt.rtw_reg1 <= '1';
83         end if;
84
85         if (reg_w_addr = instr_spl.reg_src_2_addr) then
86                 rtw_rec_nxt.rtw_reg2 <= '1';
87         end if;
88
89 end process;
90
91
92 -- async process: calculates branch prediction
93 br_pred: process(instr_spl)
94
95 begin
96
97         branch_prediction_res <= (others => '0');
98         branch_prediction_bit <= '0';
99
100         if ((instr_spl.opcode = "10110" or instr_spl.opcode = "10111") and instr_spl.bp = '1') then
101                 branch_prediction_res <= instr_spl.immediate;   --both 32 bit
102                 branch_prediction_bit <= '1';
103         end if;
104
105 end process;
106
107
108 -- async process: sign extension
109 sign_ext: process(instr_spl)
110
111 variable instr_s : instruction_rec;
112
113 begin
114
115         instr_s := instr_spl;
116
117         -- currently no sign extension in jump implemented
118
119         if (instr_s.signext = '1' and instr_s.immediate(11) = '1') then
120                 if (instr_s.opcode = "00010" or instr_s.opcode = "00011") then
121                         instr_s.immediate(31 downto 12) <= (others => '1');
122                 end if;
123                 if (instr_s.opcode = "11010") then
124                         instr_s.immediate(31 downto 16) <= (others => '1');
125                 end if;
126         end if;
127
128         instr_spl <= instr_s;
129
130 end process;
131
132
133 -- async process: decodes instruction
134 split_instr: process(instruction)
135
136 variable instr_s : instruction_rec;
137
138 begin
139
140         instr_s.predicates := instruction(31 downto 28);
141         instr_s.opcode := instruction(27 downto 27-OPCODE_WIDTH+1);
142
143         instr_s.reg_dest_addr := (others => '0');
144         instr_s.reg_src1_addr := (others => '0');
145         instr_s.reg_src2_addr := (others => '0');
146
147         instr_s.immediate := (others => '0');
148         instr_s.displacement := (others => '0');
149         instr_s.jmptype := (others => '0');
150         instr_s.carry := '0';
151         instr_s.sreg_update := '0';
152         instr_s.high_low := '0';
153         instr_s.fill := '0';
154         instr_s.signext := '0';
155         instr_s.bp := '0';
156         instr_s.arith := '0';
157
158 --  special function register operations missing
159
160 --      case opcode is
161 --=================================================================
162         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
163 --      when "00000" =>         --add
164                 instr_s.reg_dest_addr := instruction(22 downto 19);
165                 instr_s.reg_src1_addr := instruction(18 downto 15);
166                 instr_s.reg_src2_addr := instruction(14 downto 11);
167                 instr_s.carry := instruction(1);
168                 instr_s.sreg_update := instruction(0);
169         end if;
170 --      when "00001" =>         --sub
171 --              instr_s.reg_dest_addr := instruction(22 downto 19);
172 --              instr_s.reg_src1_addr := instruction(18 downto 15);
173 --              instr_s.reg_src2_addr := instruction(14 downto 11);
174 --              instr_s.carry := instruction(1);
175 --              instr_s.sreg_update := instruction(0);
176
177
178 --      when "00100" =>         --and
179 --              instr_s.reg_dest_addr := instruction(22 downto 19);
180 --              instr_s.reg_src1_addr := instruction(18 downto 15);
181 --              instr_s.reg_src2_addr := instruction(14 downto 11);
182 --              instr_s.carry := instruction(1);                        --negligible
183 --              instr_s.sreg_update := instruction(0);
184
185 --      when "00110" =>         --or
186 --              instr_s.reg_dest_addr := instruction(22 downto 19);
187 --              instr_s.reg_src1_addr := instruction(18 downto 15);
188 --              instr_s.reg_src2_addr := instruction(14 downto 11);
189 --              instr_s.carry := instruction(1);                        --negligible
190 --              instr_s.sreg_update := instruction(0);
191
192 --      when "01000" =>         --xor
193 --              instr_s.reg_dest_addr := instruction(22 downto 19);
194 --              instr_s.reg_src1_addr := instruction(18 downto 15);
195 --              instr_s.reg_src2_addr := instruction(14 downto 11);
196 --              instr_s.carry := instruction(1);                        --negligible
197 --              instr_s.sreg_update := instruction(0);
198
199 --=================================================================
200         if (instr_s.opcode = "00010" or instr_s.opcode = "00011") then
201
202 --      when "00010" =>         --addi
203                 instr_s.reg_dest_addr := instruction(22 downto 19);
204                 instr_s.reg_src1_addr := instruction(18 downto 15);
205                 instr_s.immediate(11 downto 0) := instruction(14 downto 3);
206                 instr_s.signext := instruction(2);              
207                 instr_s.carry := instruction(1);
208                 instr_s.sreg_update := instruction(0);
209         end if;
210
211 --      when "00011" =>         --subi
212 --              instr_s.reg_dest_addr := instruction(22 downto 19);
213 --              instr_s.reg_src1_addr := instruction(18 downto 15);
214 --              instr_s.immediate(11 downto 0) := instruction(14 downto 3);
215 --              instr_s.signext := instruction(2);              
216 --              instr_s.carry := instruction(1);
217 --              instr_s.sreg_update := instruction(0);
218
219 --=================================================================
220         if (instr_s.opcode = "00101" or instr_s.opcode = "00111" or instr_s.opcode = "01001") then
221
222 --      when "00101" =>         --andx
223                 instr_s.reg_dest_addr := instruction(22 downto 19);
224                 instr_s.reg_src1_addr := instruction(22 downto 19);
225                 instr_s.immediate(15 downto 0) := instruction(18 downto 3);
226                 instr_s.high_low := instruction(2);             
227                 instr_s.fill := instruction(1);
228                 instr_s.sreg_update := instruction(0);
229         end if;
230
231 --      when "00111" =>         --orx
232 --              instr_s.reg_dest_addr := instruction(22 downto 19);
233 --              instr_s.reg_src1_addr := instruction(22 downto 19);
234 --              instr_s.immediate(15 downto 0) := instruction(18 downto 3);
235 --              instr_s.high_low := instruction(2);             
236 --              instr_s.fill := instruction(1);
237 --              instr_s.sreg_update := instruction(0);
238 --
239 --      when "01001" =>         --xorx
240 --              instr_s.reg_dest_addr := instruction(22 downto 19);
241 --              instr_s.reg_src1_addr := instruction(22 downto 19);
242 --              instr_s.immediate(15 downto 0) := instruction(18 downto 3);
243 --              instr_s.high_low := instruction(2);             
244 --              instr_s.fill := instruction(1);
245 --              instr_s.sreg_update := instruction(0);
246 --
247 --=================================================================
248         if (instr_s.opcode = "01010" or instr_s.opcode = "01011") then
249
250 --      when "01010" =>         --shift
251                 instr_s.reg_dest_addr := instruction(22 downto 19);
252                 instr_s.reg_src1_addr := instruction(18 downto 15);
253                 instr_s.immediate(4 downto 0) := instruction(14 downto 10);
254                 instr_s.left_right := instruction(3);           
255                 instr_s.arith := instruction(2);                
256                 instr_s.carry := instruction(1);
257                 instr_s.sreg_update := instruction(0);
258         end if;
259
260 --      when "01011" =>         --stackop
261 --              instr_s.reg_dest_addr := instruction(22 downto 19);
262 --              instr_s.reg_src1_addr := instruction(22 downto 19);
263 --              instr_s.immediate(1 downto 0) := instruction(18 downto 17);
264 --              instr_s.left_right := instruction(3);           
265 --              instr_s.arith := instruction(2);                
266 --              instr_s.carry := instruction(1);
267 --              instr_s.sreg_update := instruction(0);
268
269 --=================================================================
270         if (instr_s.opcode = "01110" or instr_s.opcode = "10000" or instr_s.opcode = "10010" or instr_s.opcode = "11010") then
271
272 --      when "01110" =>         --ldw
273                 instr_s.reg_dest_addr := instruction(22 downto 19);
274                 instr_s.reg_src1_addr := instruction(18 downto 15);
275                 instr_s.displacement(14 downto 0) := instruction(14 downto 0);
276                 instr_s.immediate(15 downto 0) := instruction(18 downto 3);
277                 instr_s.signext := instruction(2);
278                 instr_s.high_low := instruction(1);
279         end if;
280
281 --      when "10000" =>         --ldh
282 --              instr_s.reg_dest_addr := instruction(22 downto 19);
283 --              instr_s.reg_src1_addr := instruction(18 downto 15);
284 --              instr_s.displacement(14 downto 0) := instruction(14 downto 0);
285 --              instr_s.immediate(15 downto 0) := instruction(18 downto 3);
286 --              instr_s.signext := instruction(2);
287 --              instr_s.high_low := instruction(1);
288
289 --      when "10010" =>         --ldb
290 --              instr_s.reg_dest_addr := instruction(22 downto 19);
291 --              instr_s.reg_src1_addr := instruction(18 downto 15);
292 --              instr_s.displacement(14 downto 0) := instruction(14 downto 0);
293 --              instr_s.immediate(15 downto 0) := instruction(18 downto 3);
294 --              instr_s.signext := instruction(2);
295 --              instr_s.high_low := instruction(1);
296
297 --      when "11010" =>         --ldi
298 --              instr_s.reg_dest_addr := instruction(22 downto 19);
299 --              instr_s.reg_src1_addr := instruction(18 downto 15);
300 --              instr_s.displacement(14 downto 0) := instruction(14 downto 0);
301 --              instr_s.immediate(15 downto 0) := instruction(18 downto 3);
302 --              instr_s.signext := instruction(2);
303 --              instr_s.high_low := instruction(1);
304
305 --=================================================================
306         if (instr_s.opcode = "01111" or instr_s.opcode = "10001" or instr_s.opcode = "10011" or instr_s.opcode = "10101") then
307
308         --when "01111" =>               --stw
309                 instr_s.reg_src1_addr := instruction(22 downto 19);     -- register value
310                 instr_s.reg_src2_addr := instruction(18 downto 15);     -- mem addr
311                 instr_s.displacement(14 downto 0) := instruction(14 downto 0);
312         end if;
313
314 --      when "10001" =>         --sth
315 --              instr_s.reg_src1_addr := instruction(22 downto 19);
316 --              instr_s.reg_src2_addr := instruction(18 downto 15);
317 --              instr_s.displacement(14 downto 0) := instruction(14 downto 0);
318
319 --      when "10011" =>         --stb
320 --              instr_s.reg_src1_addr := instruction(22 downto 19);
321 --              instr_s.reg_src2_addr := instruction(18 downto 15);
322 --              instr_s.displacement(14 downto 0) := instruction(14 downto 0);
323
324 --      when "10101" =>         --stx
325 --              instr_s.reg_src1_addr := instruction(22 downto 19);
326 --              instr_s.reg_src2_addr := instruction(18 downto 15);
327 --              instr_s.displacement(14 downto 0) := instruction(14 downto 0);
328
329 --=================================================================
330         if (instr_s.opcode = "10110" or instr_s.opcode = "10111") then
331
332 --      when "10110" =>         --jumpop
333                 instr_s.reg_src1_addr := instruction(22 downto 19);     -- register value
334                 instr_s.immediate(15 downto 0) := instruction(22 downto 7);
335                 instr_s.bp := instruction(1);
336                 instr_s.jmptype := instruction(3 downto 2);
337                 instr_s.signext := instruction(0);
338         end if;
339
340 --      when "10111" =>         --brreg
341 --              instr_s.reg_src1_addr := instruction(22 downto 19);     -- register value
342 --              instr_s.immediate(15 downto 0) := instruction(22 downto 7);     -- negligible
343 --              instr_s.bp := instruction(1);                           -- negligible
344 --              instr_s.jmptype := instruction(3 downto 2);             -- only lsb
345 --              instr_s.signext := instruction(0);                      -- negligible
346
347 --=================================================================
348         if (instr_s.opcode = "11000" or instr_s.opcode = "11001") then
349
350 --      when "11000" =>         --cmp
351                 instr_s.reg_src1_addr := instruction(22 downto 19);
352                 instr_s.reg_src2_addr := instruction(18 downto 15);
353                 instr_s.immediate(15 downto 0) := instruction(18 downto 3);
354         end if;
355
356 --      when "11001" =>         --cmpi
357 --              instr_s.reg_src1_addr := instruction(22 downto 19);
358 --              instr_s.reg_src2_addr := instruction(18 downto 15);
359 --              instr_s.immediate(15 downto 0) := instruction(18 downto 3);
360
361 --      when others => null;
362
363 --      end case;
364
365         instr_spl <= instr_s;
366
367 end process;
368
369 end behav;
370