1 --------------------------------------------------------------------------
2 --
3 -- Copyright (C) 1993, Peter J. Ashenden
4 -- Mail: Dept. Computer Science
5 -- University of Adelaide, SA 5005, Australia
6 -- e-mail: petera@cs.adelaide.edu.au
7 --
8 -- This program is free software; you can redistribute it and/or modify
9 -- it under the terms of the GNU General Public License as published by
10 -- the Free Software Foundation; either version 1, or (at your option)
11 -- any later version.
12 --
13 -- This program is distributed in the hope that it will be useful,
14 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
15 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 -- GNU General Public License for more details.
17 --
18 -- You should have received a copy of the GNU General Public License
19 -- along with this program; if not, write to the Free Software
20 -- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 --
22 --------------------------------------------------------------------------
23 --
24 -- $RCSfile: controller-behaviour.vhdl,v $ $Revision: 1.1 $ $Date: 2000/05/08 14:36:47 $
25 --
26 --------------------------------------------------------------------------
27 --
28 -- Behavioural architecture of DLX control section.
29 --
30
31
32 use work.bv_arithmetic.all, std.textio.all;
33
34 architecture behaviour of controller is
35
36 begin -- behaviour
37
38 sequencer : process
39
40 alias IR_opcode : dlx_opcode is current_instruction(0 to 5);
41 alias IR_sp_func : dlx_sp_func is current_instruction(26 to 31);
42 alias IR_fp_func : dlx_fp_func is current_instruction(27 to 31);
43 alias IR_rs1 : dlx_reg_addr is current_instruction(6 to 10);
44 alias IR_rs2 : dlx_reg_addr is current_instruction(11 to 15);
45 alias IR_Itype_rd : dlx_reg_addr is current_instruction(11 to 15);
46 alias IR_Rtype_rd : dlx_reg_addr is current_instruction(16 to 20);
47 alias IR_immed16 : dlx_immed16 is current_instruction(16 to 31);
48 alias IR_immed26 : dlx_immed26 is current_instruction(6 to 31);
49
50 variable IR_opcode_num : dlx_opcode_num;
51 variable IR_sp_func_num : dlx_sp_func_num;
52 variable IR_fp_func_num : dlx_fp_func_num;
53
54 variable result_of_set_is_1, branch_taken : boolean;
55
56 variable L : line;
57
58 procedure bus_instruction_fetch is
59 begin
60 -- use PC as address
61 mem_addr_mux_sel <= '0' after Tpd_clk_ctrl;
62 -- set up memory control signals
63 width <= width_word after Tpd_clk_ctrl;
64 ifetch <= '1' after Tpd_clk_ctrl;
65 mem_enable <= '1' after Tpd_clk_ctrl;
66 -- wait until phi2, then enable IR input
67 wait until phi2 = '1';
68 ir_latch_en <= '1' after Tpd_clk_ctrl;
69 -- wait until memory is ready at end of phi2
70 loop
71 wait until phi2 = '0';
72 if reset = '1' then
73 return;
74 end if;
75 exit when ready = '1';
76 end loop;
77 -- disable IR input and memory control signals
78 ir_latch_en <= '0' after Tpd_clk_ctrl;
79 mem_enable <= '0' after Tpd_clk_ctrl;
80 end bus_instruction_fetch;
81
82 procedure bus_data_read(read_width : in mem_width) is
83 begin
84 -- use MAR as address
85 mem_addr_mux_sel <= '1' after Tpd_clk_ctrl;
86 -- set up memory control signals
87 width <= read_width after Tpd_clk_ctrl;
88 ifetch <= '0' after Tpd_clk_ctrl;
89 mem_enable <= '1' after Tpd_clk_ctrl;
90 -- wait until phi2, then enable MDR input
91 wait until phi2 = '1';
92 mdr_mux_sel <= '1' after Tpd_clk_ctrl;
93 mdr_latch_en <= '1' after Tpd_clk_ctrl;
94 -- wait until memory is ready at end of phi2
95 loop
96 wait until phi2 = '0';
97 if reset = '1' then
98 return;
99 end if;
100 exit when ready = '1';
101 end loop;
102 -- disable MDR input and memory control signals
103 mdr_latch_en <= '0' after Tpd_clk_ctrl;
104 mem_enable <= '0' after Tpd_clk_ctrl;
105 end bus_data_read;
106
107 procedure bus_data_write(write_width : in mem_width) is
108 begin
109 -- use MAR as address
110 mem_addr_mux_sel <= '1' after Tpd_clk_ctrl;
111 -- enable MDR output
112 mdr_out_en3 <= '1' after Tpd_clk_ctrl;
113 -- set up memory control signals
114 width <= write_width after Tpd_clk_ctrl;
115 ifetch <= '0' after Tpd_clk_ctrl;
116 write_enable <= '1' after Tpd_clk_ctrl;
117 mem_enable <= '1' after Tpd_clk_ctrl;
118 -- wait until memory is ready at end of phi2
119 loop
120 wait until phi2 = '0';
121 if reset = '1' then
122 return;
123 end if;
124 exit when ready = '1';
125 end loop;
126 -- disable MDR output and memory control signals
127 write_enable <= '0' after Tpd_clk_ctrl;
128 mem_enable <= '0' after Tpd_clk_ctrl;
129 mdr_out_en3 <= '0' after Tpd_clk_ctrl;
130 end bus_data_write;
131
132 procedure do_set_result is
133 begin
134 wait until phi1 = '1';
135 if result_of_set_is_1 then
136 const2 <= X"0000_0001" after Tpd_clk_const;
137 else
138 const2 <= X"0000_0000" after Tpd_clk_const;
139 end if;
140 alu_latch_en <= '1' after Tpd_clk_ctrl;
141 alu_function <= alu_pass_s2 after Tpd_clk_ctrl;
142 --
143 wait until phi1 = '0';
144 alu_latch_en <= '0' after Tpd_clk_ctrl;
145 const2 <= null after Tpd_clk_const;
146 --
147 wait until phi2 = '1';
148 c_latch_en <= '1' after Tpd_clk_ctrl;
149 --
150 wait until phi2 = '0';
151 c_latch_en <= '0' after Tpd_clk_ctrl;
152 end do_set_result;
153
154 procedure do_EX_set_unsigned(immed : boolean) is
155 begin
156 wait until phi1 = '1';
157 a_out_en <= '1' after Tpd_clk_ctrl;
158 if immed then
159 ir_immed_sel2 <= immed_size_16 after Tpd_clk_ctrl;
160 ir_immed_unsigned2 <= '1' after Tpd_clk_ctrl;
161 ir_immed_en2 <= '1' after Tpd_clk_ctrl;
162 else
163 b_out_en <= '1' after Tpd_clk_ctrl;
164 end if;
165 alu_latch_en <= '1' after Tpd_clk_ctrl;
166 alu_function <= alu_subu after Tpd_clk_ctrl;
167 --
168 wait until phi1 = '0';
169 alu_latch_en <= '0' after Tpd_clk_ctrl;
170 a_out_en <= '0' after Tpd_clk_ctrl;
171 if immed then
172 ir_immed_en2 <= '0' after Tpd_clk_ctrl;
173 else
174 b_out_en <= '0' after Tpd_clk_ctrl;
175 end if;
176 --
177 wait until phi2 = '0';
178 if immed then
179 case IR_opcode is
180 when op_sequi =>
181 result_of_set_is_1 := alu_zero = '1';
182 when op_sneui =>
183 result_of_set_is_1 := alu_zero /= '1';
184 when op_sltui =>
185 result_of_set_is_1 := alu_overflow = '1';
186 when op_sgtui =>
187 result_of_set_is_1 := alu_overflow /= '1' and alu_zero /= '1';
188 when op_sleui =>
189 result_of_set_is_1 := alu_overflow = '1' or alu_zero = '1';
190 when op_sgeui =>
191 result_of_set_is_1 := alu_overflow /= '1';
192 when others =>
193 null;
194 end case;
195 else
196 case IR_sp_func is
197 when sp_func_sequ =>
198 result_of_set_is_1 := alu_zero = '1';
199 when sp_func_sneu =>
200 result_of_set_is_1 := alu_zero /= '1';
201 when sp_func_sltu =>
202 result_of_set_is_1 := alu_overflow = '1';
203 when sp_func_sgtu =>
204 result_of_set_is_1 := alu_overflow /= '1' and alu_zero /= '1';
205 when sp_func_sleu =>
206 result_of_set_is_1 := alu_overflow = '1' or alu_zero = '1';
207 when sp_func_sgeu =>
208 result_of_set_is_1 := alu_overflow /= '1';
209 when others =>
210 null;
211 end case;
212 end if;
213 --
214 do_set_result;
215 end do_EX_set_unsigned;
216
217 procedure do_EX_set_signed(immed : boolean) is
218 begin
219 wait until phi1 = '1';
220 a_out_en <= '1' after Tpd_clk_ctrl;
221 if immed then
222 ir_immed_sel2 <= immed_size_16 after Tpd_clk_ctrl;
223 ir_immed_unsigned2 <= '0' after Tpd_clk_ctrl;
224 ir_immed_en2 <= '1' after Tpd_clk_ctrl;
225 else
226 b_out_en <= '1' after Tpd_clk_ctrl;
227 end if;
228 alu_latch_en <= '1' after Tpd_clk_ctrl;
229 alu_function <= alu_sub after Tpd_clk_ctrl;
230 --
231 wait until phi1 = '0';
232 alu_latch_en <= '0' after Tpd_clk_ctrl;
233 a_out_en <= '0' after Tpd_clk_ctrl;
234 if immed then
235 ir_immed_en2 <= '0' after Tpd_clk_ctrl;
236 else
237 b_out_en <= '0' after Tpd_clk_ctrl;
238 end if;
239 --
240 wait until phi2 = '0';
241 if immed then
242 case IR_opcode is
243 when op_seqi =>
244 result_of_set_is_1 := alu_zero = '1';
245 when op_snei =>
246 result_of_set_is_1 := alu_zero /= '1';
247 when op_slti =>
248 result_of_set_is_1 := alu_negative = '1';
249 when op_sgti =>
250 result_of_set_is_1 := alu_negative /= '1' and alu_zero /= '1';
251 when op_slei =>
252 result_of_set_is_1 := alu_negative = '1' or alu_zero = '1';
253 when op_sgei =>
254 result_of_set_is_1 := alu_negative /= '1';
255 when others =>
256 null;
257 end case;
258 else
259 case IR_sp_func is
260 when sp_func_seq =>
261 result_of_set_is_1 := alu_zero = '1';
262 when sp_func_sne =>
263 result_of_set_is_1 := alu_zero /= '1';
264 when sp_func_slt =>
265 result_of_set_is_1 := alu_negative = '1';
266 when sp_func_sgt =>
267 result_of_set_is_1 := alu_negative /= '1' and alu_zero /= '1';
268 when sp_func_sle =>
269 result_of_set_is_1 := alu_negative = '1' or alu_zero = '1';
270 when sp_func_sge =>
271 result_of_set_is_1 := alu_negative /= '1';
272 when others =>
273 null;
274 end case;
275 end if;
276 --
277 do_set_result;
278 end do_EX_set_signed;
279
280 procedure do_EX_arith_logic is
281 begin
282 wait until phi1 = '1';
283 a_out_en <= '1' after Tpd_clk_ctrl;
284 b_out_en <= '1' after Tpd_clk_ctrl;
285 alu_latch_en <= '1' after Tpd_clk_ctrl;
286 case IR_sp_func is
287 when sp_func_add =>
288 alu_function <= alu_add after Tpd_clk_ctrl;
289 when sp_func_addu =>
290 alu_function <= alu_addu after Tpd_clk_ctrl;
291 when sp_func_sub =>
292 alu_function <= alu_sub after Tpd_clk_ctrl;
293 when sp_func_subu =>
294 alu_function <= alu_subu after Tpd_clk_ctrl;
295 when sp_func_and =>
296 alu_function <= alu_and after Tpd_clk_ctrl;
297 when sp_func_or =>
298 alu_function <= alu_or after Tpd_clk_ctrl;
299 when sp_func_xor =>
300 alu_function <= alu_xor after Tpd_clk_ctrl;
301 when sp_func_sll =>
302 alu_function <= alu_sll after Tpd_clk_ctrl;
303 when sp_func_srl =>
304 alu_function <= alu_srl after Tpd_clk_ctrl;
305 when sp_func_sra =>
306 alu_function <= alu_sra after Tpd_clk_ctrl;
307 when others =>
308 null;
309 end case; -- IR_sp_func
310 --
311 wait until phi1 = '0';
312 alu_latch_en <= '0' after Tpd_clk_ctrl;
313 a_out_en <= '0' after Tpd_clk_ctrl;
314 b_out_en <= '0' after Tpd_clk_ctrl;
315 --
316 wait until phi2 = '1';
317 c_latch_en <= '1' after Tpd_clk_ctrl;
318 --
319 wait until phi2 = '0';
320 c_latch_en <= '0' after Tpd_clk_ctrl;
321 end do_EX_arith_logic;
322
323 procedure do_EX_arith_logic_immed is
324 begin
325 wait until phi1 = '1';
326 a_out_en <= '1' after Tpd_clk_ctrl;
327 ir_immed_sel2 <= immed_size_16 after Tpd_clk_ctrl;
328 if IR_opcode = op_addi or IR_opcode = op_subi then
329 ir_immed_unsigned2 <= '0' after Tpd_clk_ctrl;
330 else
331 ir_immed_unsigned2 <= '1' after Tpd_clk_ctrl;
332 end if;
333 ir_immed_en2 <= '1' after Tpd_clk_ctrl;
334 alu_latch_en <= '1' after Tpd_clk_ctrl;
335 case IR_opcode is
336 when op_addi =>
337 alu_function <= alu_add after Tpd_clk_ctrl;
338 when op_subi =>
339 alu_function <= alu_sub after Tpd_clk_ctrl;
340 when op_addui =>
341 alu_function <= alu_addu after Tpd_clk_ctrl;
342 when op_subui =>
343 alu_function <= alu_subu after Tpd_clk_ctrl;
344 when op_andi =>
345 alu_function <= alu_and after Tpd_clk_ctrl;
346 when op_ori =>
347 alu_function <= alu_or after Tpd_clk_ctrl;
348 when op_xori =>
349 alu_function <= alu_xor after Tpd_clk_ctrl;
350 when op_slli =>
351 alu_function <= alu_sll after Tpd_clk_ctrl;
352 when op_srli =>
353 alu_function <= alu_srl after Tpd_clk_ctrl;
354 when op_srai =>
355 alu_function <= alu_sra after Tpd_clk_ctrl;
356 when others =>
357 null;
358 end case; -- IR_opcode
359 --
360 wait until phi1 = '0';
361 alu_latch_en <= '0' after Tpd_clk_ctrl;
362 a_out_en <= '0' after Tpd_clk_ctrl;
363 ir_immed_en2 <= '0' after Tpd_clk_ctrl;
364 --
365 wait until phi2 = '1';
366 c_latch_en <= '1' after Tpd_clk_ctrl;
367 --
368 wait until phi2 = '0';
369 c_latch_en <= '0' after Tpd_clk_ctrl;
370 end do_EX_arith_logic_immed;
371
372 procedure do_EX_link is
373 begin
374 wait until phi1 = '1';
375 pc_out_en1 <= '1' after Tpd_clk_ctrl;
376 alu_latch_en <= '1' after Tpd_clk_ctrl;
377 alu_function <= alu_pass_s1 after Tpd_clk_ctrl;
378 --
379 wait until phi1 = '0';
380 alu_latch_en <= '0' after Tpd_clk_ctrl;
381 pc_out_en1 <= '0' after Tpd_clk_ctrl;
382 --
383 wait until phi2 = '1';
384 c_latch_en <= '1' after Tpd_clk_ctrl;
385 --
386 wait until phi2 = '0';
387 c_latch_en <= '0' after Tpd_clk_ctrl;
388 end do_EX_link;
389
390 procedure do_EX_lhi is
391 begin
392 wait until phi1 = '1';
393 ir_immed_sel1 <= immed_size_16 after Tpd_clk_ctrl;
394 ir_immed_unsigned1 <= '1' after Tpd_clk_ctrl;
395 ir_immed_en1 <= '1' after Tpd_clk_ctrl;
396 const2 <= X"0000_0010" after Tpd_clk_const; -- shift by 16 bits
397 alu_latch_en <= '1' after Tpd_clk_ctrl;
398 alu_function <= alu_sll after Tpd_clk_ctrl;
399 --
400 wait until phi1 = '0';
401 alu_latch_en <= '0' after Tpd_clk_ctrl;
402 ir_immed_en1 <= '0' after Tpd_clk_ctrl;
403 const2 <= null after Tpd_clk_const;
404 --
405 wait until phi2 = '1';
406 c_latch_en <= '1' after Tpd_clk_ctrl;
407 --
408 wait until phi2 = '0';
409 c_latch_en <= '0' after Tpd_clk_ctrl;
410 end do_EX_lhi;
411
412 procedure do_EX_branch is
413 begin
414 wait until phi1 = '1';
415 a_out_en <= '1' after Tpd_clk_ctrl;
416 const2 <= X"0000_0000" after Tpd_clk_const;
417 alu_latch_en <= '1' after Tpd_clk_ctrl;
418 alu_function <= alu_sub after Tpd_clk_ctrl;
419 --
420 wait until phi1 = '0';
421 alu_latch_en <= '0' after Tpd_clk_ctrl;
422 a_out_en <= '0' after Tpd_clk_ctrl;
423 const2 <= null after Tpd_clk_const;
424 --
425 wait until phi2 = '0';
426 if IR_opcode = op_beqz then
427 branch_taken := alu_zero = '1';
428 else
429 branch_taken := alu_zero /= '1';
430 end if;
431 end do_EX_branch;
432
433 procedure do_EX_load_store is
434 begin
435 wait until phi1 = '1';
436 a_out_en <= '1' after Tpd_clk_ctrl;
437 ir_immed_sel2 <= immed_size_16 after Tpd_clk_ctrl;
438 ir_immed_unsigned2 <= '0' after Tpd_clk_ctrl;
439 ir_immed_en2 <= '1' after Tpd_clk_ctrl;
440 alu_function <= alu_add after Tpd_clk_ctrl;
441 alu_latch_en <= '1' after Tpd_clk_ctrl;
442 --
443 wait until phi1 = '0';
444 alu_latch_en <= '0' after Tpd_clk_ctrl;
445 a_out_en <= '0' after Tpd_clk_ctrl;
446 ir_immed_en2 <= '0' after Tpd_clk_ctrl;
447 --
448 wait until phi2 = '1';
449 mar_latch_en <= '1' after Tpd_clk_ctrl;
450 --
451 wait until phi2 = '0';
452 mar_latch_en <= '0' after Tpd_clk_ctrl;
453 end do_EX_load_store;
454
455 procedure do_MEM_jump is
456 begin
457 wait until phi1 = '1';
458 pc_out_en1 <= '1' after Tpd_clk_ctrl;
459 ir_immed_sel2 <= immed_size_26 after Tpd_clk_ctrl;
460 ir_immed_unsigned2 <= '0' after Tpd_clk_ctrl;
461 ir_immed_en2 <= '1' after Tpd_clk_ctrl;
462 alu_latch_en <= '1' after Tpd_clk_ctrl;
463 alu_function <= alu_add after Tpd_clk_ctrl;
464 --
465 wait until phi1 = '0';
466 alu_latch_en <= '0' after Tpd_clk_ctrl;
467 pc_out_en1 <= '0' after Tpd_clk_ctrl;
468 ir_immed_en2 <= '0' after Tpd_clk_ctrl;
469 --
470 wait until phi2 = '1';
471 pc_latch_en <= '1' after Tpd_clk_ctrl;
472 --
473 wait until phi2 = '0';
474 pc_latch_en <= '0' after Tpd_clk_ctrl;
475 end do_MEM_jump;
476
477 procedure do_MEM_jump_reg is
478 begin
479 wait until phi1 = '1';
480 a_out_en <= '1' after Tpd_clk_ctrl;
481 alu_latch_en <= '1' after Tpd_clk_ctrl;
482 alu_function <= alu_pass_s1 after Tpd_clk_ctrl;
483 --
484 wait until phi1 = '0';
485 alu_latch_en <= '0' after Tpd_clk_ctrl;
486 a_out_en <= '0' after Tpd_clk_ctrl;
487 --
488 wait until phi2 = '1';
489 pc_latch_en <= '1' after Tpd_clk_ctrl;
490 --
491 wait until phi2 = '0';
492 pc_latch_en <= '0' after Tpd_clk_ctrl;
493 end do_MEM_jump_reg;
494
495 procedure do_MEM_branch is
496 begin
497 wait until phi1 = '1';
498 pc_out_en1 <= '1' after Tpd_clk_ctrl;
499 ir_immed_sel2 <= immed_size_16 after Tpd_clk_ctrl;
500 ir_immed_unsigned2 <= '0' after Tpd_clk_ctrl;
501 ir_immed_en2 <= '1' after Tpd_clk_ctrl;
502 alu_latch_en <= '1' after Tpd_clk_ctrl;
503 alu_function <= alu_add after Tpd_clk_ctrl;
504 --
505 wait until phi1 = '0';
506 alu_latch_en <= '0' after Tpd_clk_ctrl;
507 pc_out_en1 <= '0' after Tpd_clk_ctrl;
508 ir_immed_en2 <= '0' after Tpd_clk_ctrl;
509 --
510 wait until phi2 = '1';
511 pc_latch_en <= '1' after Tpd_clk_ctrl;
512 --
513 wait until phi2 = '0';
514 pc_latch_en <= '0' after Tpd_clk_ctrl;
515 end do_MEM_branch;
516
517 procedure do_MEM_load is
518 begin
519 wait until phi1 = '1';
520 bus_data_read(width_word);
521 if reset = '1' then
522 return;
523 end if;
524 --
525 wait until phi1 = '1';
526 mdr_out_en1 <= '1' after Tpd_clk_ctrl;
527 alu_function <= alu_pass_s1 after Tpd_clk_ctrl;
528 alu_latch_en <= '1' after Tpd_clk_ctrl;
529 --
530 wait until phi1 = '0';
531 mdr_out_en1 <= '0' after Tpd_clk_ctrl;
532 alu_latch_en <= '0' after Tpd_clk_ctrl;
533 --
534 wait until phi2 = '1';
535 c_latch_en <= '1' after Tpd_clk_ctrl;
536 --
537 wait until phi2 = '0';
538 c_latch_en <= '0' after Tpd_clk_ctrl;
539 end do_MEM_load;
540
541 procedure do_MEM_store is
542 begin
543 wait until phi1 = '1';
544 b_out_en <= '1' after Tpd_clk_ctrl;
545 alu_function <= alu_pass_s2 after Tpd_clk_ctrl;
546 alu_latch_en <= '1' after Tpd_clk_ctrl;
547 --
548 wait until phi1 = '0';
549 b_out_en <= '0' after Tpd_clk_ctrl;
550 alu_latch_en <= '0' after Tpd_clk_ctrl;
551 --
552 wait until phi2 = '1';
553 mdr_mux_sel <= '0' after Tpd_clk_ctrl;
554 mdr_latch_en <= '1' after Tpd_clk_ctrl;
555 --
556 wait until phi2 = '0';
557 mdr_latch_en <= '0' after Tpd_clk_ctrl;
558 --
559 wait until phi1 = '1';
560 bus_data_write(width_word);
561 end do_MEM_store;
562
563 procedure do_WB(Rd : dlx_reg_addr) is
564 begin
565 wait until phi1 = '1';
566 reg_dest_addr <= Rd after Tpd_clk_ctrl;
567 reg_write <= '1' after Tpd_clk_ctrl;
568 --
569 wait until phi2 = '0';
570 reg_write <= '0' after Tpd_clk_ctrl;
571 end do_WB;
572
573
574 begin -- sequencer
575 --
576 ----------------------------------------------------------------
577 -- initialize all control signals
578 ----------------------------------------------------------------
579 if debug then
580 write(L, string'("controller: initializing"));
581 writeline(output, L);
582 end if;
583 --
584 halt <= '0' after Tpd_clk_ctrl;
585 width <= width_word after Tpd_clk_ctrl;
586 write_enable <= '0' after Tpd_clk_ctrl;
587 mem_enable <= '0' after Tpd_clk_ctrl;
588 ifetch <= '0' after Tpd_clk_ctrl;
589 alu_latch_en <= '0' after Tpd_clk_ctrl;
590 alu_function <= alu_add after Tpd_clk_ctrl;
591 reg_s1_addr <= B"00000" after Tpd_clk_ctrl;
592 reg_s2_addr <= B"00000" after Tpd_clk_ctrl;
593 reg_dest_addr <= B"00000" after Tpd_clk_ctrl;
594 reg_write <= '0' after Tpd_clk_ctrl;
595 c_latch_en <= '0' after Tpd_clk_ctrl;
596 a_latch_en <= '0' after Tpd_clk_ctrl;
597 a_out_en <= '0' after Tpd_clk_ctrl;
598 b_latch_en <= '0' after Tpd_clk_ctrl;
599 b_out_en <= '0' after Tpd_clk_ctrl;
600 temp_latch_en <= '0' after Tpd_clk_ctrl;
601 temp_out_en1 <= '0' after Tpd_clk_ctrl;
602 temp_out_en2 <= '0' after Tpd_clk_ctrl;
603 iar_latch_en <= '0' after Tpd_clk_ctrl;
604 iar_out_en1 <= '0' after Tpd_clk_ctrl;
605 iar_out_en2 <= '0' after Tpd_clk_ctrl;
606 pc_latch_en <= '0' after Tpd_clk_ctrl;
607 pc_out_en1 <= '0' after Tpd_clk_ctrl;
608 pc_out_en2 <= '0' after Tpd_clk_ctrl;
609 mar_latch_en <= '0' after Tpd_clk_ctrl;
610 mar_out_en1 <= '0' after Tpd_clk_ctrl;
611 mar_out_en2 <= '0' after Tpd_clk_ctrl;
612 mem_addr_mux_sel <= '0' after Tpd_clk_ctrl;
613 mdr_latch_en <= '0' after Tpd_clk_ctrl;
614 mdr_out_en1 <= '0' after Tpd_clk_ctrl;
615 mdr_out_en2 <= '0' after Tpd_clk_ctrl;
616 mdr_out_en3 <= '0' after Tpd_clk_ctrl;
617 mdr_mux_sel <= '0' after Tpd_clk_ctrl;
618 ir_latch_en <= '0' after Tpd_clk_ctrl;
619 ir_immed_sel1 <= immed_size_16 after Tpd_clk_ctrl;
620 ir_immed_sel2 <= immed_size_16 after Tpd_clk_ctrl;
621 ir_immed_unsigned1 <= '0' after Tpd_clk_ctrl;
622 ir_immed_unsigned2 <= '0' after Tpd_clk_ctrl;
623 ir_immed_en1 <= '0' after Tpd_clk_ctrl;
624 ir_immed_en2 <= '0' after Tpd_clk_ctrl;
625 const1 <= null after Tpd_clk_const;
626 const2 <= null after Tpd_clk_const;
627 --
628 wait until phi2 = '0' and reset = '0';
629 --
630 ----------------------------------------------------------------
631 -- control loop
632 ----------------------------------------------------------------
633 loop
634 --
635 ----------------------------------------------------------------
636 -- fetch next instruction (IF)
637 ----------------------------------------------------------------
638 wait until phi1 = '1';
639 if debug then
640 write(L, string'("controller: instruction fetch"));
641 writeline(output, L);
642 end if;
643 --
644 bus_instruction_fetch;
645 --
646 ----------------------------------------------------------------
647 -- instruction decode, source register read, and PC increment (ID)
648 ----------------------------------------------------------------
649 wait until phi1 = '1';
650 if debug then
651 write(L, string'("controller: decode, reg-read and PC incr"));
652 writeline(output, L);
653 end if;
654 --
655 IR_opcode_num := bv_to_natural(IR_opcode);
656 IR_sp_func_num := bv_to_natural(IR_sp_func);
657 IR_fp_func_num := bv_to_natural(IR_fp_func);
658 --
659 reg_s1_addr <= IR_rs1 after Tpd_clk_ctrl;
660 reg_s2_addr <= IR_rs2 after Tpd_clk_ctrl;
661 a_latch_en <= '1' after Tpd_clk_ctrl;
662 b_latch_en <= '1' after Tpd_clk_ctrl;
663 --
664 pc_out_en1 <= '1' after Tpd_clk_ctrl;
665 const2 <= X"0000_0004" after Tpd_clk_const;
666 alu_latch_en <= '1' after Tpd_clk_ctrl;
667 alu_function <= alu_addu after Tpd_clk_ctrl;
668 --
669 wait until phi1 = '0';
670 a_latch_en <= '0' after Tpd_clk_ctrl;
671 b_latch_en <= '0' after Tpd_clk_ctrl;
672 alu_latch_en <= '0' after Tpd_clk_ctrl;
673 pc_out_en1 <= '0' after Tpd_clk_ctrl;
674 const2 <= null after Tpd_clk_const;
675 --
676 wait until phi2 = '1';
677 pc_latch_en <= '1' after Tpd_clk_ctrl;
678 --
679 wait until phi2 = '0';
680 pc_latch_en <= '0' after Tpd_clk_ctrl;
681 --
682 ----------------------------------------------------------------
683 -- execute instruction, (EX, MEM, WB)
684 ----------------------------------------------------------------
685 if debug then
686 write(L, string'("controller: execute"));
687 writeline(output, L);
688 end if;
689 --
690 case IR_opcode is
691 when op_special =>
692 case IR_sp_func is
693 when sp_func_nop =>
694 null;
695 when sp_func_sequ | sp_func_sneu |
696 sp_func_sltu | sp_func_sgtu |
697 sp_func_sleu | sp_func_sgeu =>
698 do_EX_set_unsigned(immed => false);
699 do_WB(IR_Rtype_rd);
700 when sp_func_add | sp_func_addu |
701 sp_func_sub | sp_func_subu |
702 sp_func_and | sp_func_or | sp_func_xor |
703 sp_func_sll | sp_func_srl | sp_func_sra =>
704 do_EX_arith_logic;
705 do_WB(IR_Rtype_rd);
706 when sp_func_seq | sp_func_sne |
707 sp_func_slt | sp_func_sgt |
708 sp_func_sle | sp_func_sge =>
709 do_EX_set_signed(immed => false);
710 do_WB(IR_Rtype_rd);
711 when sp_func_movi2s =>
712 assert false
713 report "MOVI2S instruction not implemented" severity warning;
714 when sp_func_movs2i =>
715 assert false
716 report "MOVS2I instruction not implemented" severity warning;
717 when sp_func_movf =>
718 assert false
719 report "MOVF instruction not implemented" severity warning;
720 when sp_func_movd =>
721 assert false
722 report "MOVD instruction not implemented" severity warning;
723 when sp_func_movfp2i =>
724 assert false
725 report "MOVFP2I instruction not implemented" severity warning;
726 when sp_func_movi2fp =>
727 assert false
728 report "MOVI2FP instruction not implemented" severity warning;
729 when others =>
730 assert false
731 report "undefined special instruction function" severity error;
732 end case;
733 when op_fparith =>
734 case IR_fp_func is
735 when fp_func_addf | fp_func_subf | fp_func_multf | fp_func_divf |
736 fp_func_addd | fp_func_subd | fp_func_multd | fp_func_divd |
737 fp_func_mult | fp_func_multu | fp_func_div | fp_func_divu |
738 fp_func_cvtf2d | fp_func_cvtf2i | fp_func_cvtd2f |
739 fp_func_cvtd2i | fp_func_cvti2f | fp_func_cvti2d |
740 fp_func_eqf | fp_func_nef | fp_func_ltf | fp_func_gtf |
741 fp_func_lef | fp_func_gef | fp_func_eqd | fp_func_ned |
742 fp_func_ltd | fp_func_gtd | fp_func_led | fp_func_ged =>
743 assert false
744 report "floating point instructions not implemented" severity warning;
745 when others =>
746 assert false
747 report "undefined floating point instruction function" severity error;
748 end case;
749 when op_j =>
750 do_MEM_jump;
751 when op_jr =>
752 do_MEM_jump_reg;
753 when op_jal =>
754 do_EX_link;
755 do_MEM_jump;
756 do_WB(natural_to_bv(link_reg, 5));
757 when op_jalr =>
758 do_EX_link;
759 do_MEM_jump_reg;
760 do_WB(natural_to_bv(link_reg, 5));
761 when op_beqz | op_bnez =>
762 do_EX_branch;
763 if branch_taken then
764 do_MEM_branch;
765 end if;
766 when op_bfpt =>
767 assert false
768 report "BFPT instruction not implemented" severity warning;
769 when op_bfpf =>
770 assert false
771 report "BFPF instruction not implemented" severity warning;
772 when op_addi | op_subi |
773 op_addui | op_subui |
774 op_andi | op_ori | op_xori |
775 op_slli | op_srli | op_srai =>
776 do_EX_arith_logic_immed;
777 do_WB(IR_Itype_rd);
778 when op_lhi =>
779 do_EX_lhi;
780 do_WB(IR_Itype_rd);
781 when op_rfe =>
782 assert false
783 report "RFE instruction not implemented" severity warning;
784 when op_trap =>
785 assert false
786 report "TRAP instruction encountered, execution halted"
787 severity note;
788 wait until phi1 = '1';
789 halt <= '1' after Tpd_clk_ctrl;
790 wait until reset = '1';
791 exit;
792 when op_seqi | op_snei | op_slti |
793 op_sgti | op_slei | op_sgei =>
794 do_EX_set_signed(immed => true);
795 do_WB(IR_Itype_rd);
796 when op_lb =>
797 assert false
798 report "LB instruction not implemented" severity warning;
799 when op_lh =>
800 assert false
801 report "LH instruction not implemented" severity warning;
802 when op_lw =>
803 do_EX_load_store;
804 do_MEM_load;
805 exit when reset = '1';
806 do_WB(IR_Itype_rd);
807 when op_sw =>
808 do_EX_load_store;
809 do_MEM_store;
810 exit when reset = '1';
811 when op_lbu =>
812 assert false
813 report "LBU instruction not implemented" severity warning;
814 when op_lhu =>
815 assert false
816 report "LHU instruction not implemented" severity warning;
817 when op_sb =>
818 assert false
819 report "SB instruction not implemented" severity warning;
820 when op_sh =>
821 assert false
822 report "SH instruction not implemented" severity warning;
823 when op_lf =>
824 assert false
825 report "LF instruction not implemented" severity warning;
826 when op_ld =>
827 assert false
828 report "LD instruction not implemented" severity warning;
829 when op_sf =>
830 assert false
831 report "SF instruction not implemented" severity warning;
832 when op_sd =>
833 assert false
834 report "SD instruction not implemented" severity warning;
835 when op_sequi | op_sneui | op_sltui |
836 op_sgtui | op_sleui | op_sgeui =>
837 do_EX_set_unsigned(immed => true);
838 do_WB(IR_Itype_rd);
839 when others =>
840 assert false
841 report "undefined instruction" severity error;
842 end case;
843 --
844 end loop;
845 --
846 ----------------------------------------------------------------
847 -- loop exited on reset
848 ----------------------------------------------------------------
849 assert reset = '1'
850 report "Internal error: reset code reached with reset = '0'"
851 severity failure;
852 --
853 -- start again
854 --
855 end process sequencer;
856
857
858 end behaviour;
859
This page was generated using GHDL 0.14 (20040829) [Sokcho edition], a program written by Tristan Gingold