Project

General

Profile

Download (42.1 KB) Statistics
| Branch: | Tag: | Revision:
1

    
2
-- Copyright (C) 1996 Morgan Kaufmann Publishers, Inc
3

    
4
-- This file is part of VESTs (Vhdl tESTs).
5

    
6
-- VESTs is free software; you can redistribute it and/or modify it
7
-- under the terms of the GNU General Public License as published by the
8
-- Free Software Foundation; either version 2 of the License, or (at
9
-- your option) any later version. 
10

    
11
-- VESTs is distributed in the hope that it will be useful, but WITHOUT
12
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14
-- for more details. 
15

    
16
-- You should have received a copy of the GNU General Public License
17
-- along with VESTs; if not, write to the Free Software Foundation,
18
-- Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
19

    
20
-- ---------------------------------------------------------------------
21
--
22
-- $Id: ch_15_ctrl-b.vhd,v 1.3 2001-10-26 16:29:35 paw Exp $
23
-- $Revision: 1.3 $
24
--
25
-- ---------------------------------------------------------------------
26

    
27
library bv_utilities;
28
use bv_utilities.bv_arithmetic.all;
29

    
30
library work;
31
use work.dlx_instr.all;
32

    
33
architecture behavior of controller is
34

    
35
begin -- behavior
36

    
37
  sequencer : process is
38

    
39
                        variable current_instruction_bv : dlx_bv_word;
40

    
41
                      alias IR_opcode : dlx_opcode is current_instruction_bv(0 to 5);
42
                      alias IR_sp_func : dlx_sp_func is current_instruction_bv(26 to 31);
43
                      alias IR_fp_func : dlx_fp_func is current_instruction_bv(27 to 31);
44

    
45
                      alias IR_rs1 : reg_file_addr is current_instruction(6 to 10);
46
                      alias IR_rs2 : reg_file_addr is current_instruction(11 to 15);
47
                      alias IR_Itype_rd : reg_file_addr is current_instruction(11 to 15);
48
                      alias IR_Rtype_rd : reg_file_addr is current_instruction(16 to 20);
49

    
50
                      variable result_of_set_is_1, branch_taken : boolean;
51

    
52
                      variable disassembled_instr : string(1 to 40);
53
                      variable disassembled_instr_len : positive;
54

    
55
                      variable instr_count : natural := 0;
56

    
57
                      procedure bus_instruction_fetch is
58
                      begin
59
                        -- use PC as address
60
                        mem_addr_mux_sel <= '0' after Tpd_clk_ctrl;
61
                        -- set up memory control signals
62
                        width <= dlx_mem_width_word after Tpd_clk_ctrl;
63
                        ifetch <= '1' after Tpd_clk_ctrl;
64
                        write_enable <= '0' after Tpd_clk_ctrl;
65
                        mem_enable <= '1' after Tpd_clk_ctrl;
66
                        -- wait until phi2, then enable IR input
67
                        wait until rising_edge(phi2);
68
                        ir_latch_en <= '1' after Tpd_clk_ctrl;
69
                        -- wait until memory is ready at end of phi2
70
                        loop 
71
                          wait until falling_edge(phi2);
72
                          if To_bit(reset) = '1' then
73
                            return;
74
                          end if;
75
                          exit when To_bit(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 procedure bus_instruction_fetch;
81

    
82
                      procedure bus_data_read ( read_width : in dlx_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
                        write_enable <= '0' after Tpd_clk_ctrl;
90
                        mem_enable <= '1' after Tpd_clk_ctrl;
91
                        -- wait until phi2, then enable MDR input
92
                        wait until rising_edge(phi2);
93
                        mdr_mux_sel <= '1' after Tpd_clk_ctrl;
94
                        mdr_latch_en <= '1' after Tpd_clk_ctrl;
95
                        -- wait until memory is ready at end of phi2
96
                        loop 
97
                          wait until falling_edge(phi2);
98
                          if To_bit(reset) = '1' then
99
                            return;
100
                          end if;
101
                          exit when To_bit(ready) = '1';
102
                        end loop;
103
                        -- disable MDR input and memory control signals
104
                        mdr_latch_en <= '0' after Tpd_clk_ctrl;
105
                        mem_enable <= '0' after Tpd_clk_ctrl;
106
                      end procedure bus_data_read;
107

    
108
                      procedure bus_data_write ( write_width : in dlx_mem_width ) is
109
                      begin
110
                        -- use MAR as address
111
                        mem_addr_mux_sel <= '1' after Tpd_clk_ctrl;
112
                        -- enable MDR output
113
                        mdr_out_en3 <= '1' after Tpd_clk_ctrl;
114
                        -- set up memory control signals
115
                        width <= write_width after Tpd_clk_ctrl;
116
                        ifetch <= '0' after Tpd_clk_ctrl;
117
                        write_enable <= '1' after Tpd_clk_ctrl;
118
                        mem_enable <= '1' after Tpd_clk_ctrl;
119
                        -- wait until memory is ready at end of phi2
120
                        loop 
121
                          wait until falling_edge(phi2);
122
                          if To_bit(reset) = '1' then
123
                            return;
124
                          end if;
125
                          exit when To_bit(ready) = '1';
126
                        end loop;
127
                        -- disable MDR output and memory control signals
128
                        write_enable <= '0' after Tpd_clk_ctrl;
129
                        mem_enable <= '0' after Tpd_clk_ctrl;
130
                        mdr_out_en3 <= '0' after Tpd_clk_ctrl;
131
                      end procedure bus_data_write;
132

    
133
                      procedure do_set_result is
134
                      begin
135
                        wait until rising_edge(phi1);
136
                        if result_of_set_is_1 then
137
                          const2 <= X"0000_0001" after Tpd_clk_const;
138
                        else
139
                          const2 <= X"0000_0000" after Tpd_clk_const;
140
                        end if;
141
                        alu_in_latch_en <= '1' after Tpd_clk_ctrl;
142
                        alu_function <= alu_pass_s2 after Tpd_clk_ctrl;
143

    
144
                        wait until falling_edge(phi1);
145
                        alu_in_latch_en <= '0' after Tpd_clk_ctrl;
146
                        const2 <= disabled_dlx_word after Tpd_clk_const;
147

    
148
                        wait until rising_edge(phi2);
149
                        c_latch_en <= '1' after Tpd_clk_ctrl;
150

    
151
                        wait until falling_edge(phi2);
152
                        c_latch_en <= '0' after Tpd_clk_ctrl;
153
                      end procedure do_set_result;    
154

    
155
                      procedure do_EX_set_unsigned ( immed : boolean ) is
156
                      begin
157
                        wait until rising_edge(phi1);
158
                        a_out_en <= '1' after Tpd_clk_ctrl;
159
                        if immed then
160
                          ir_immed2_size_26 <= '0' after Tpd_clk_ctrl;
161
                          ir_immed2_unsigned <= '1' after Tpd_clk_ctrl;
162
                          ir_immed2_en <= '1' after Tpd_clk_ctrl;
163
                        else
164
                          b_out_en <= '1' after Tpd_clk_ctrl;
165
                        end if;
166
                        alu_in_latch_en <= '1' after Tpd_clk_ctrl;
167
                        alu_function <= alu_subu after Tpd_clk_ctrl;
168

    
169
                        wait until falling_edge(phi1);
170
                        alu_in_latch_en <= '0' after Tpd_clk_ctrl;
171
                        a_out_en <= '0' after Tpd_clk_ctrl;
172
                        if immed then
173
                          ir_immed2_en <= '0' after Tpd_clk_ctrl;
174
                        else
175
                          b_out_en <= '0' after Tpd_clk_ctrl;
176
                        end if;
177

    
178
                        wait until falling_edge(phi2);
179
                        if immed then
180
                          case IR_opcode is
181
                            when op_sequi => 
182
                              result_of_set_is_1 := To_bit(alu_zero) = '1';
183
                            when op_sneui =>
184
                              result_of_set_is_1 := To_bit(alu_zero) /= '1';
185
                            when op_sltui =>
186
                              result_of_set_is_1 := To_bit(alu_overflow) = '1';
187
                            when op_sgtui => 
188
                              result_of_set_is_1 := To_bit(alu_overflow) /= '1' and To_bit(alu_zero) /= '1';
189
                            when op_sleui => 
190
                              result_of_set_is_1 := To_bit(alu_overflow) = '1' or To_bit(alu_zero) = '1';
191
                            when op_sgeui => 
192
                              result_of_set_is_1 := To_bit(alu_overflow) /= '1';
193
                            when others =>
194
                              null;
195
                          end case;
196
                        else
197
                          case IR_sp_func is
198
                            when sp_func_sequ => 
199
                              result_of_set_is_1 := To_bit(alu_zero) = '1';
200
                            when sp_func_sneu =>
201
                              result_of_set_is_1 := To_bit(alu_zero) /= '1';
202
                            when sp_func_sltu =>
203
                              result_of_set_is_1 := To_bit(alu_overflow) = '1';
204
                            when sp_func_sgtu =>
205
                              result_of_set_is_1 := To_bit(alu_overflow) /= '1' and To_bit(alu_zero) /= '1';
206
                            when sp_func_sleu => 
207
                              result_of_set_is_1 := To_bit(alu_overflow) = '1' or To_bit(alu_zero) = '1';
208
                            when sp_func_sgeu => 
209
                              result_of_set_is_1 := To_bit(alu_overflow) /= '1';
210
                            when others =>
211
                              null;
212
                          end case;
213
                        end if;
214

    
215
                        do_set_result;
216
                      end procedure do_EX_set_unsigned;
217

    
218
                      procedure do_EX_set_signed ( immed : boolean ) is
219
                      begin
220
                        wait until rising_edge(phi1);
221
                        a_out_en <= '1' after Tpd_clk_ctrl;
222
                        if immed then
223
                          ir_immed2_size_26 <= '0' after Tpd_clk_ctrl;
224
                          ir_immed2_unsigned <= '0' after Tpd_clk_ctrl;
225
                          ir_immed2_en <= '1' after Tpd_clk_ctrl;
226
                        else
227
                          b_out_en <= '1' after Tpd_clk_ctrl;
228
                        end if;
229
                        alu_in_latch_en <= '1' after Tpd_clk_ctrl;
230
                        alu_function <= alu_sub after Tpd_clk_ctrl;
231

    
232
                        wait until falling_edge(phi1);
233
                        alu_in_latch_en <= '0' after Tpd_clk_ctrl;
234
                        a_out_en <= '0' after Tpd_clk_ctrl;
235
                        if immed then
236
                          ir_immed2_en <= '0' after Tpd_clk_ctrl;
237
                        else
238
                          b_out_en <= '0' after Tpd_clk_ctrl;
239
                        end if;
240

    
241
                        wait until falling_edge(phi2);
242
                        if immed then
243
                          case IR_opcode is
244
                            when op_seqi => 
245
                              result_of_set_is_1 := To_bit(alu_zero) = '1';
246
                            when op_snei =>
247
                              result_of_set_is_1 := To_bit(alu_zero) /= '1';
248
                            when op_slti =>
249
                              result_of_set_is_1 := To_bit(alu_negative) = '1';
250
                            when op_sgti => 
251
                              result_of_set_is_1 := To_bit(alu_negative) /= '1' and To_bit(alu_zero) /= '1';
252
                            when op_slei => 
253
                              result_of_set_is_1 := To_bit(alu_negative) = '1' or To_bit(alu_zero) = '1';
254
                            when op_sgei => 
255
                              result_of_set_is_1 := To_bit(alu_negative) /= '1';
256
                            when others =>
257
                              null;
258
                          end case;
259
                        else
260
                          case IR_sp_func is
261
                            when sp_func_seq => 
262
                              result_of_set_is_1 := To_bit(alu_zero) = '1';
263
                            when sp_func_sne =>
264
                              result_of_set_is_1 := To_bit(alu_zero) /= '1';
265
                            when sp_func_slt =>
266
                              result_of_set_is_1 := To_bit(alu_negative) = '1';
267
                            when sp_func_sgt => 
268
                              result_of_set_is_1 := To_bit(alu_negative) /= '1' and To_bit(alu_zero) /= '1';
269
                            when sp_func_sle => 
270
                              result_of_set_is_1 := To_bit(alu_negative) = '1' or To_bit(alu_zero) = '1';
271
                            when sp_func_sge => 
272
                              result_of_set_is_1 := To_bit(alu_negative) /= '1';
273
                            when others =>
274
                              null;
275
                          end case;
276
                        end if;
277

    
278
                        do_set_result;
279
                      end procedure do_EX_set_signed;
280

    
281
                      procedure do_EX_arith_logic is
282
                      begin
283
                        wait until rising_edge(phi1);
284
                        a_out_en <= '1' after Tpd_clk_ctrl;
285
                        b_out_en <= '1' after Tpd_clk_ctrl;
286
                        alu_in_latch_en <= '1' after Tpd_clk_ctrl;
287
                        case IR_sp_func is
288
                          when sp_func_add =>
289
                            alu_function <= alu_add after Tpd_clk_ctrl;
290
                          when sp_func_addu =>
291
                            alu_function <= alu_addu after Tpd_clk_ctrl;
292
                          when sp_func_sub =>
293
                            alu_function <= alu_sub after Tpd_clk_ctrl;
294
                          when sp_func_subu =>
295
                            alu_function <= alu_subu after Tpd_clk_ctrl;
296
                          when sp_func_and =>
297
                            alu_function <= alu_and after Tpd_clk_ctrl;
298
                          when sp_func_or =>
299
                            alu_function <= alu_or after Tpd_clk_ctrl;
300
                          when sp_func_xor =>
301
                            alu_function <= alu_xor after Tpd_clk_ctrl;
302
                          when sp_func_sll =>
303
                            alu_function <= alu_sll after Tpd_clk_ctrl;
304
                          when sp_func_srl =>
305
                            alu_function <= alu_srl after Tpd_clk_ctrl;
306
                          when sp_func_sra =>
307
                            alu_function <= alu_sra after Tpd_clk_ctrl;
308
                          when others =>
309
                            null;
310
                        end case;                  --  IR_sp_func
311

    
312
                        wait until falling_edge(phi1);
313
                        alu_in_latch_en <= '0' after Tpd_clk_ctrl;
314
                        a_out_en <= '0' after Tpd_clk_ctrl;
315
                        b_out_en <= '0' after Tpd_clk_ctrl;
316

    
317
                        wait until rising_edge(phi2);
318
                        c_latch_en <= '1' after Tpd_clk_ctrl;
319

    
320
                        wait until falling_edge(phi2);
321
                        c_latch_en <= '0' after Tpd_clk_ctrl;
322
                      end procedure do_EX_arith_logic;
323

    
324
                      procedure do_EX_arith_logic_immed is
325
                      begin
326
                        wait until rising_edge(phi1);
327
                        a_out_en <= '1' after Tpd_clk_ctrl;
328
                        ir_immed2_size_26 <= '0' after Tpd_clk_ctrl;
329
                        if IR_opcode = op_addi or IR_opcode = op_subi then
330
                          ir_immed2_unsigned <= '0' after Tpd_clk_ctrl;
331
                        else
332
                          ir_immed2_unsigned <= '1' after Tpd_clk_ctrl;
333
                        end if;
334
                        ir_immed2_en <= '1' after Tpd_clk_ctrl;
335
                        alu_in_latch_en <= '1' after Tpd_clk_ctrl;
336
                        case IR_opcode is
337
                          when op_addi =>
338
                            alu_function <= alu_add after Tpd_clk_ctrl;
339
                          when op_subi =>
340
                            alu_function <= alu_sub after Tpd_clk_ctrl;
341
                          when op_addui =>
342
                            alu_function <= alu_addu after Tpd_clk_ctrl;
343
                          when op_subui =>
344
                            alu_function <= alu_subu after Tpd_clk_ctrl;
345
                          when op_andi =>
346
                            alu_function <= alu_and after Tpd_clk_ctrl;
347
                          when op_ori =>
348
                            alu_function <= alu_or after Tpd_clk_ctrl;
349
                          when op_xori =>
350
                            alu_function <= alu_xor after Tpd_clk_ctrl;
351
                          when op_slli =>
352
                            alu_function <= alu_sll after Tpd_clk_ctrl;
353
                          when op_srli =>
354
                            alu_function <= alu_srl after Tpd_clk_ctrl;
355
                          when op_srai =>
356
                            alu_function <= alu_sra after Tpd_clk_ctrl;
357
                          when others =>
358
                            null;
359
                        end case;                      --  IR_opcode
360

    
361
                        wait until falling_edge(phi1);
362
                        alu_in_latch_en <= '0' after Tpd_clk_ctrl;
363
                        a_out_en <= '0' after Tpd_clk_ctrl;
364
                        ir_immed2_en <= '0' after Tpd_clk_ctrl;
365

    
366
                        wait until rising_edge(phi2);
367
                        c_latch_en <= '1' after Tpd_clk_ctrl;
368

    
369
                        wait until falling_edge(phi2);
370
                        c_latch_en <= '0' after Tpd_clk_ctrl;
371
                      end procedure do_EX_arith_logic_immed;
372

    
373
                      procedure do_EX_link is
374
                      begin
375
                        wait until rising_edge(phi1);
376
                        pc_out_en1 <= '1' after Tpd_clk_ctrl;
377
                        alu_in_latch_en <= '1' after Tpd_clk_ctrl;
378
                        alu_function <= alu_pass_s1 after Tpd_clk_ctrl;
379

    
380
                        wait until falling_edge(phi1);
381
                        alu_in_latch_en <= '0' after Tpd_clk_ctrl;
382
                        pc_out_en1 <= '0' after Tpd_clk_ctrl;
383

    
384
                        wait until rising_edge(phi2);
385
                        c_latch_en <= '1' after Tpd_clk_ctrl;
386

    
387
                        wait until falling_edge(phi2);
388
                        c_latch_en <= '0' after Tpd_clk_ctrl;
389
                      end procedure do_EX_link;
390

    
391
                      procedure do_EX_lhi is
392
                      begin
393
                        wait until rising_edge(phi1);
394
                        ir_immed1_size_26 <= '0' after Tpd_clk_ctrl;
395
                        ir_immed1_unsigned <= '1' after Tpd_clk_ctrl;
396
                        ir_immed1_en <= '1' after Tpd_clk_ctrl;
397
                        const2 <= X"0000_0010" after Tpd_clk_const;         -- shift by 16 bits
398
                        alu_in_latch_en <= '1' after Tpd_clk_ctrl;
399
                        alu_function <= alu_sll after Tpd_clk_ctrl;
400

    
401
                        wait until falling_edge(phi1);
402
                        alu_in_latch_en <= '0' after Tpd_clk_ctrl;
403
                        ir_immed1_en <= '0' after Tpd_clk_ctrl;
404
                        const2 <= disabled_dlx_word after Tpd_clk_const;
405

    
406
                        wait until rising_edge(phi2);
407
                        c_latch_en <= '1' after Tpd_clk_ctrl;
408

    
409
                        wait until falling_edge(phi2);
410
                        c_latch_en <= '0' after Tpd_clk_ctrl;
411
                      end procedure do_EX_lhi;    
412

    
413
                      procedure do_EX_branch is
414
                      begin
415
                        wait until rising_edge(phi1);
416
                        a_out_en <= '1' after Tpd_clk_ctrl;
417
                        alu_in_latch_en <= '1' after Tpd_clk_ctrl;
418
                        alu_function <= alu_pass_s1 after Tpd_clk_ctrl;
419

    
420
                        wait until falling_edge(phi1);
421
                        alu_in_latch_en <= '0' after Tpd_clk_ctrl;
422
                        a_out_en <= '0' after Tpd_clk_ctrl;
423

    
424
                        wait until falling_edge(phi2);
425
                        if IR_opcode = op_beqz then
426
                          branch_taken := To_bit(alu_zero) = '1';
427
                        else
428
                          branch_taken := To_bit(alu_zero) /= '1';
429
                        end if;
430
                      end procedure do_EX_branch;
431

    
432
                      procedure do_EX_load_store is
433
                      begin
434
                        wait until rising_edge(phi1);
435
                        a_out_en <= '1' after Tpd_clk_ctrl;
436
                        ir_immed2_size_26 <= '0' after Tpd_clk_ctrl;
437
                        ir_immed2_unsigned <= '0' after Tpd_clk_ctrl;
438
                        ir_immed2_en <= '1' after Tpd_clk_ctrl;
439
                        alu_function <= alu_add after Tpd_clk_ctrl;
440
                        alu_in_latch_en <= '1' after Tpd_clk_ctrl;
441

    
442
                        wait until falling_edge(phi1);
443
                        alu_in_latch_en <= '0' after Tpd_clk_ctrl;
444
                        a_out_en <= '0' after Tpd_clk_ctrl;
445
                        ir_immed2_en <= '0' after Tpd_clk_ctrl;
446

    
447
                        wait until rising_edge(phi2);
448
                        mar_latch_en <= '1' after Tpd_clk_ctrl;
449

    
450
                        wait until falling_edge(phi2);
451
                        mar_latch_en <= '0' after Tpd_clk_ctrl;
452
                      end procedure do_EX_load_store;
453

    
454
                      procedure do_MEM_jump is
455
                      begin
456
                        wait until rising_edge(phi1);
457
                        pc_out_en1 <= '1' after Tpd_clk_ctrl;
458
                        ir_immed2_size_26 <= '1' after Tpd_clk_ctrl;
459
                        ir_immed2_unsigned <= '0' after Tpd_clk_ctrl;
460
                        ir_immed2_en <= '1' after Tpd_clk_ctrl;
461
                        alu_in_latch_en <= '1' after Tpd_clk_ctrl;
462
                        alu_function <= alu_add after Tpd_clk_ctrl;
463

    
464
                        wait until falling_edge(phi1);
465
                        alu_in_latch_en <= '0' after Tpd_clk_ctrl;
466
                        pc_out_en1 <= '0' after Tpd_clk_ctrl;
467
                        ir_immed2_en <= '0' after Tpd_clk_ctrl;
468

    
469
                        wait until rising_edge(phi2);
470
                        pc_latch_en <= '1' after Tpd_clk_ctrl;
471

    
472
                        wait until falling_edge(phi2);
473
                        pc_latch_en <= '0' after Tpd_clk_ctrl;
474
                      end procedure do_MEM_jump;
475

    
476
                      procedure do_MEM_jump_reg is
477
                      begin
478
                        wait until rising_edge(phi1);
479
                        a_out_en <= '1' after Tpd_clk_ctrl;
480
                        alu_in_latch_en <= '1' after Tpd_clk_ctrl;
481
                        alu_function <= alu_pass_s1 after Tpd_clk_ctrl;
482

    
483
                        wait until falling_edge(phi1);
484
                        alu_in_latch_en <= '0' after Tpd_clk_ctrl;
485
                        a_out_en <= '0' after Tpd_clk_ctrl;
486

    
487
                        wait until rising_edge(phi2);
488
                        pc_latch_en <= '1' after Tpd_clk_ctrl;
489

    
490
                        wait until falling_edge(phi2);
491
                        pc_latch_en <= '0' after Tpd_clk_ctrl;
492
                      end procedure do_MEM_jump_reg;
493

    
494
                      procedure do_MEM_branch is
495
                      begin
496
                        wait until rising_edge(phi1);
497
                        pc_out_en1 <= '1' after Tpd_clk_ctrl;
498
                        ir_immed2_size_26 <= '0' after Tpd_clk_ctrl;
499
                        ir_immed2_unsigned <= '0' after Tpd_clk_ctrl;
500
                        ir_immed2_en <= '1' after Tpd_clk_ctrl;
501
                        alu_in_latch_en <= '1' after Tpd_clk_ctrl;
502
                        alu_function <= alu_add after Tpd_clk_ctrl;
503

    
504
                        wait until falling_edge(phi1);
505
                        alu_in_latch_en <= '0' after Tpd_clk_ctrl;
506
                        pc_out_en1 <= '0' after Tpd_clk_ctrl;
507
                        ir_immed2_en <= '0' after Tpd_clk_ctrl;
508

    
509
                        wait until rising_edge(phi2);
510
                        pc_latch_en <= '1' after Tpd_clk_ctrl;
511

    
512
                        wait until falling_edge(phi2);
513
                        pc_latch_en <= '0' after Tpd_clk_ctrl;
514
                      end procedure do_MEM_branch;
515

    
516
                      procedure do_MEM_load is
517
                        subtype ls_2_addr_bits is bit_vector(1 downto 0);
518
                      begin
519
                        wait until rising_edge(phi1);
520
                        if IR_opcode = op_lb or IR_opcode = op_lbu then
521
                          bus_data_read(dlx_mem_width_byte);
522
                        elsif IR_opcode = op_lh or IR_opcode = op_lhu then
523
                          bus_data_read(dlx_mem_width_halfword);
524
                        else
525
                          bus_data_read(dlx_mem_width_word);
526
                        end if;
527
                        if To_bit(reset) = '1' then
528
                          return;
529
                        end if;
530

    
531
                        if ( (IR_opcode = op_lb or IR_opcode = op_lbu) and To_bitvector(mem_addr) /= "00" )
532
                          or ( (IR_opcode = op_lh or IR_opcode = op_lhu) and To_bit(mem_addr(1)) /= '0' ) then
533
                          -- first step of extension: left-justify byte or halfword -> mdr
534
                          wait until rising_edge(phi1);
535
                          mdr_out_en1 <= '1' after Tpd_clk_ctrl;
536
                          if IR_opcode = op_lb or IR_opcode = op_lbu then
537
                            case ls_2_addr_bits'(To_bitvector(mem_addr)) is
538
                              when "00" => 
539
                                null;
540
                              when "01" => 
541
                                const2 <= X"0000_0008" after Tpd_clk_const;
542
                              when "10" => 
543
                                const2 <= X"0000_0010" after Tpd_clk_const;
544
                              when "11" => 
545
                                const2 <= X"0000_0018" after Tpd_clk_const;
546
                            end case;
547
                          else
548
                            const2 <= X"0000_0010" after Tpd_clk_const;
549
                          end if;
550
                          alu_function <= alu_sll after Tpd_clk_ctrl;
551
                          alu_in_latch_en <= '1' after Tpd_clk_ctrl;
552

    
553
                          wait until falling_edge(phi1);
554
                          mdr_out_en1 <= '0' after Tpd_clk_ctrl;
555
                          const2 <= disabled_dlx_word after Tpd_clk_const;
556
                          alu_in_latch_en <= '0' after Tpd_clk_ctrl;
557

    
558
                          wait until rising_edge(phi2);
559
                          mdr_mux_sel <= '0' after Tpd_clk_ctrl;
560
                          mdr_latch_en <= '1' after Tpd_clk_ctrl;
561

    
562
                          wait until falling_edge(phi2);
563
                          mdr_latch_en <= '0' after Tpd_clk_ctrl;
564
                        end if;
565

    
566
                        wait until rising_edge(phi1);
567
                        mdr_out_en1 <= '1' after Tpd_clk_ctrl;
568
                        if IR_opcode = op_lb or IR_opcode = op_lbu then
569
                          const2 <= X"0000_0018" after Tpd_clk_const;
570
                        elsif IR_opcode = op_lh or IR_opcode = op_lhu then
571
                          const2 <= X"0000_0010" after Tpd_clk_const;
572
                        else
573
                          const2 <= X"0000_0000" after Tpd_clk_const;
574
                        end if;
575
                        if IR_opcode = op_lbu or IR_opcode = op_lhu then
576
                          alu_function <= alu_srl after Tpd_clk_ctrl;
577
                        else
578
                          alu_function <= alu_sra after Tpd_clk_ctrl;
579
                        end if;
580
                        alu_in_latch_en <= '1' after Tpd_clk_ctrl;
581

    
582
                        wait until falling_edge(phi1);
583
                        mdr_out_en1 <= '0' after Tpd_clk_ctrl;
584
                        const2 <= disabled_dlx_word after Tpd_clk_const;
585
                        alu_in_latch_en <= '0' after Tpd_clk_ctrl;
586

    
587
                        wait until rising_edge(phi2);
588
                        c_latch_en <= '1' after Tpd_clk_ctrl;
589

    
590
                        wait until falling_edge(phi2);
591
                        c_latch_en <= '0' after Tpd_clk_ctrl;
592
                      end procedure do_MEM_load;    
593

    
594
                      procedure do_MEM_store is
595
                        subtype ls_2_addr_bits is bit_vector(1 downto 0);
596
                      begin
597
                        wait until rising_edge(phi1);
598
                        b_out_en <= '1' after Tpd_clk_ctrl;
599
                        alu_function <= alu_pass_s2 after Tpd_clk_ctrl;
600
                        alu_in_latch_en <= '1' after Tpd_clk_ctrl;
601

    
602
                        wait until falling_edge(phi1);
603
                        b_out_en <= '0' after Tpd_clk_ctrl;
604
                        alu_in_latch_en <= '0' after Tpd_clk_ctrl;
605

    
606
                        wait until rising_edge(phi2);
607
                        mdr_mux_sel <= '0' after Tpd_clk_ctrl;
608
                        mdr_latch_en <= '1' after Tpd_clk_ctrl;
609

    
610
                        wait until falling_edge(phi2);
611
                        mdr_latch_en <= '0' after Tpd_clk_ctrl;
612

    
613
                        if ( IR_opcode = op_sb and To_bitvector(mem_addr) /= "11" )
614
                          or ( IR_opcode = op_sh and To_bit(mem_addr(1)) /= '1' ) then
615
                          -- align byte or halfword -> mdr
616
                          wait until rising_edge(phi1);
617
                          mdr_out_en1 <= '1' after Tpd_clk_ctrl;
618
                          if IR_opcode = op_sb then
619
                            case ls_2_addr_bits'(To_bitvector(mem_addr)) is
620
                              when "00" => 
621
                                const2 <= X"0000_0018" after Tpd_clk_const;
622
                              when "01" => 
623
                                const2 <= X"0000_0010" after Tpd_clk_const;
624
                              when "10" => 
625
                                const2 <= X"0000_0008" after Tpd_clk_const;
626
                              when "11" => 
627
                                null;
628
                            end case;
629
                          else
630
                            const2 <= X"0000_0010" after Tpd_clk_const;
631
                          end if;
632
                          alu_function <= alu_sll after Tpd_clk_ctrl;
633
                          alu_in_latch_en <= '1' after Tpd_clk_ctrl;
634

    
635
                          wait until falling_edge(phi1);
636
                          mdr_out_en1 <= '0' after Tpd_clk_ctrl;
637
                          const2 <= disabled_dlx_word after Tpd_clk_const;
638
                          alu_in_latch_en <= '0' after Tpd_clk_ctrl;
639

    
640
                          wait until rising_edge(phi2);
641
                          mdr_mux_sel <= '0' after Tpd_clk_ctrl;
642
                          mdr_latch_en <= '1' after Tpd_clk_ctrl;
643

    
644
                          wait until falling_edge(phi2);
645
                          mdr_latch_en <= '0' after Tpd_clk_ctrl;
646
                        end if;
647

    
648
                        wait until rising_edge(phi1);
649
                        if IR_opcode = op_sb then
650
                          bus_data_write(dlx_mem_width_byte);
651
                        elsif IR_opcode = op_sh then
652
                          bus_data_write(dlx_mem_width_halfword);
653
                        else
654
                          bus_data_write(dlx_mem_width_word);
655
                        end if;
656
                      end procedure do_MEM_store;
657

    
658
                      procedure do_WB ( Rd : reg_file_addr ) is
659
                      begin
660
                        wait until rising_edge(phi1);
661
                        reg_dest_addr <= Rd after Tpd_clk_ctrl;
662
                        reg_write <= '1' after Tpd_clk_ctrl;
663

    
664
                        wait until falling_edge(phi2);
665
                        reg_write <= '0' after Tpd_clk_ctrl;
666
                      end procedure do_WB;
667

    
668
                      procedure execute_op_special is
669
                      begin
670
                        case IR_sp_func is
671
                          when sp_func_nop =>
672
                            null;
673
                          when sp_func_add | sp_func_addu | sp_func_sub | sp_func_subu
674
                            | sp_func_sll | sp_func_srl | sp_func_sra
675
                            | sp_func_and | sp_func_or | sp_func_xor =>
676
                            do_EX_arith_logic;
677
                            do_WB(IR_Rtype_rd);
678
                          when sp_func_sequ | sp_func_sneu | sp_func_sltu
679
                            | sp_func_sgtu | sp_func_sleu | sp_func_sgeu => 
680
                            do_EX_set_unsigned(immed => false);
681
                            do_WB(IR_Rtype_rd);
682
                          when sp_func_seq | sp_func_sne | sp_func_slt
683
                            | sp_func_sgt | sp_func_sle | sp_func_sge => 
684
                            do_EX_set_signed(immed => false);
685
                            do_WB(IR_Rtype_rd);
686
                          when sp_func_movi2s | sp_func_movs2i
687
                            | sp_func_movf | sp_func_movd
688
                            | sp_func_movfp2i | sp_func_movi2fp  => 
689
                            report sp_func_names(bv_to_natural(IR_sp_func))
690
                              & " instruction not implemented" severity warning;
691
                          when others =>
692
                            report "undefined special instruction function" severity error;
693
                        end case;  
694
                      end procedure execute_op_special;
695

    
696
                      procedure execute_op_fparith is
697
                      begin
698
                        case IR_fp_func is
699
                          when fp_func_mult | fp_func_multu | fp_func_div | fp_func_divu
700
                            | fp_func_addf | fp_func_subf | fp_func_multf | fp_func_divf
701
                            | fp_func_addd | fp_func_subd | fp_func_multd | fp_func_divd
702
                            | fp_func_cvtf2d | fp_func_cvtf2i | fp_func_cvtd2f
703
                            | fp_func_cvtd2i | fp_func_cvti2f | fp_func_cvti2d
704
                            | fp_func_eqf | fp_func_nef | fp_func_ltf | fp_func_gtf
705
                            | fp_func_lef | fp_func_gef | fp_func_eqd | fp_func_ned
706
                            | fp_func_ltd | fp_func_gtd | fp_func_led | fp_func_ged => 
707
                            report fp_func_names(bv_to_natural(IR_fp_func))
708
                              & " instruction not implemented" severity warning;
709
                          when others =>
710
                            report "undefined floating point instruction function" severity error;
711
                        end case;
712
                      end procedure execute_op_fparith;
713

    
714
  begin -- sequencer
715

    
716
    ----------------------------------------------------------------
717
    -- initialize all control signals
718
    ----------------------------------------------------------------
719
    if debug > none then
720
      report "initializing";
721
    end if;
722

    
723
    halt <= '0' after Tpd_clk_ctrl;
724
    width <= dlx_mem_width_word after Tpd_clk_ctrl;
725
    write_enable <= '0' after Tpd_clk_ctrl;
726
    mem_enable <= '0' after Tpd_clk_ctrl;
727
    ifetch <= '0' after Tpd_clk_ctrl;
728
    alu_in_latch_en <= '0' after Tpd_clk_ctrl;
729
    alu_function <= alu_add after Tpd_clk_ctrl;
730
    reg_s1_addr <= B"00000" after Tpd_clk_ctrl;
731
    reg_s2_addr <= B"00000" after Tpd_clk_ctrl;
732
    reg_dest_addr <= B"00000" after Tpd_clk_ctrl;
733
    reg_write <= '0' after Tpd_clk_ctrl;
734
    c_latch_en <= '0' after Tpd_clk_ctrl;
735
    a_latch_en <= '0' after Tpd_clk_ctrl;
736
    a_out_en <= '0' after Tpd_clk_ctrl;
737
    b_latch_en <= '0' after Tpd_clk_ctrl;
738
    b_out_en <= '0' after Tpd_clk_ctrl;
739
    temp_latch_en <= '0' after Tpd_clk_ctrl;
740
    temp_out_en1 <= '0' after Tpd_clk_ctrl;
741
    temp_out_en2 <= '0' after Tpd_clk_ctrl;
742
    iar_latch_en <= '0' after Tpd_clk_ctrl;
743
    iar_out_en1 <= '0' after Tpd_clk_ctrl;
744
    iar_out_en2 <= '0' after Tpd_clk_ctrl;
745
    pc_latch_en <= '0' after Tpd_clk_ctrl;
746
    pc_out_en1 <= '0' after Tpd_clk_ctrl;
747
    pc_out_en2 <= '0' after Tpd_clk_ctrl;
748
    mar_latch_en <= '0' after Tpd_clk_ctrl;
749
    mar_out_en1 <= '0' after Tpd_clk_ctrl;
750
    mar_out_en2 <= '0' after Tpd_clk_ctrl;
751
    mem_addr_mux_sel <= '0' after Tpd_clk_ctrl;
752
    mdr_latch_en <= '0' after Tpd_clk_ctrl;
753
    mdr_out_en1 <= '0' after Tpd_clk_ctrl;
754
    mdr_out_en2 <= '0' after Tpd_clk_ctrl;
755
    mdr_out_en3 <= '0' after Tpd_clk_ctrl;
756
    mdr_mux_sel <= '0' after Tpd_clk_ctrl;
757
    ir_latch_en <= '0' after Tpd_clk_ctrl;
758
    ir_immed1_size_26 <= '0' after Tpd_clk_ctrl;
759
    ir_immed2_size_26 <= '0' after Tpd_clk_ctrl;
760
    ir_immed2_unsigned <= '0' after Tpd_clk_ctrl;
761
    ir_immed2_unsigned <= '0' after Tpd_clk_ctrl;
762
    ir_immed1_en <= '0' after Tpd_clk_ctrl;
763
    ir_immed2_en <= '0' after Tpd_clk_ctrl;
764
    const1 <= disabled_dlx_word after Tpd_clk_const;
765
    const2 <= disabled_dlx_word after Tpd_clk_const;
766

    
767
    instr_count := 0;
768

    
769
    wait on phi2 until falling_edge(phi2) and To_bit(reset) = '0';
770

    
771
    ----------------------------------------------------------------
772
    -- control loop
773
    ----------------------------------------------------------------
774
    loop
775
      exit when To_bit(reset) = '1';
776

    
777
      ----------------------------------------------------------------
778
      -- fetch next instruction (IF)
779
      ----------------------------------------------------------------
780
      wait until rising_edge(phi1);
781

    
782
      instr_count := instr_count + 1;
783
      if debug = msg_every_100_instructions and instr_count mod 100 = 0 then
784
        report "instruction count = " & natural'image(instr_count);
785
      end if;
786

    
787
      if debug >= msg_each_instruction then
788
        report "fetching instruction";
789
      end if;
790

    
791
      bus_instruction_fetch;
792
      exit when To_bit(reset) = '1';
793
      current_instruction_bv := To_bitvector(current_instruction);
794

    
795
      if debug >= trace_each_instruction then
796
        disassemble(current_instruction_bv, disassembled_instr, disassembled_instr_len);
797
        report disassembled_instr(1 to disassembled_instr_len);
798
      end if;
799

    
800
      ----------------------------------------------------------------
801
      -- instruction decode, source register read and PC increment (ID)
802
      ----------------------------------------------------------------
803
      wait until rising_edge(phi1);
804

    
805
      if debug = trace_each_step then
806
        report "decode, source register read and PC increment";
807
      end if;
808

    
809
      reg_s1_addr <= IR_rs1 after Tpd_clk_ctrl;
810
      reg_s2_addr <= IR_rs2 after Tpd_clk_ctrl;
811
      a_latch_en <= '1' after Tpd_clk_ctrl;
812
      b_latch_en <= '1' after Tpd_clk_ctrl;
813

    
814
      pc_out_en1 <= '1' after Tpd_clk_ctrl;
815
      const2 <= X"0000_0004" after Tpd_clk_const;
816
      alu_in_latch_en <= '1' after Tpd_clk_ctrl;
817
      alu_function <= alu_addu after Tpd_clk_ctrl;
818

    
819
      wait until falling_edge(phi1);
820
      a_latch_en <= '0' after Tpd_clk_ctrl;
821
      b_latch_en <= '0' after Tpd_clk_ctrl;
822
      alu_in_latch_en <= '0' after Tpd_clk_ctrl;
823
      pc_out_en1 <= '0' after Tpd_clk_ctrl;
824
      const2 <= disabled_dlx_word after Tpd_clk_const;
825

    
826
      wait until rising_edge(phi2);
827
      pc_latch_en <= '1' after Tpd_clk_ctrl;
828

    
829
      wait until falling_edge(phi2);
830
      pc_latch_en <= '0' after Tpd_clk_ctrl;
831

    
832
      ----------------------------------------------------------------
833
      -- execute instruction, (EX, MEM, WB)
834
      ----------------------------------------------------------------
835
      if debug = trace_each_step then
836
        report "execute";
837
      end if;
838

    
839
      case IR_opcode is
840
        when op_special =>
841
          execute_op_special;
842
        when op_fparith => 
843
          execute_op_fparith;
844
        when op_j =>
845
          do_MEM_jump;
846
        when op_jal =>
847
          do_EX_link;
848
          do_MEM_jump;
849
          do_WB(To_X01(natural_to_bv(link_reg, 5)));
850
        when op_jr =>
851
          do_MEM_jump_reg;
852
        when op_jalr =>
853
          do_EX_link;
854
          do_MEM_jump_reg;
855
          do_WB(To_X01(natural_to_bv(link_reg, 5)));
856
        when op_beqz | op_bnez => 
857
          do_EX_branch;
858
          if branch_taken then
859
            do_MEM_branch;
860
          end if;
861
        when op_addi | op_subi | op_addui | op_subui 
862
          | op_slli | op_srli | op_srai
863
          | op_andi | op_ori | op_xori =>
864
          do_EX_arith_logic_immed;
865
          do_WB(IR_Itype_rd);
866
        when op_lhi =>
867
          do_EX_lhi;
868
          do_WB(IR_Itype_rd);
869
        when op_sequi | op_sneui | op_sltui
870
          | op_sgtui | op_sleui | op_sgeui => 
871
          do_EX_set_unsigned(immed => true);
872
          do_WB(IR_Itype_rd);
873
        when op_seqi | op_snei | op_slti
874
          | op_sgti | op_slei | op_sgei => 
875
          do_EX_set_signed(immed => true);
876
          do_WB(IR_Itype_rd);
877
        when op_trap =>
878
          report "TRAP instruction encountered, execution halted"
879
            severity note;
880
          wait until rising_edge(phi1);
881
          halt <= '1' after Tpd_clk_ctrl;
882
          wait until reset = '1';
883
          exit;
884
        when op_lb | op_lh | op_lw | op_lbu | op_lhu => 
885
          do_EX_load_store;
886
          do_MEM_load;
887
          exit when reset = '1';
888
          do_WB(IR_Itype_rd);
889
        when op_sb | op_sh | op_sw =>
890
          do_EX_load_store;
891
          do_MEM_store;
892
          exit when reset = '1';
893
        when op_rfe | op_bfpt | op_bfpf | op_lf | op_ld | op_sf | op_sd =>
894
          report opcode_names(bv_to_natural(IR_opcode))
895
            & " instruction not implemented" severity warning;
896
        when others =>
897
          report "undefined instruction" severity error;
898
      end case;
899

    
900
      -- overflow and divide-by-zero exception handing
901
      -- (not implemented)
902

    
903
      if debug = trace_each_step then
904
        report "end of execution";
905
      end if;
906

    
907
    end loop;
908
    -- loop is only exited when reset active:
909
    -- process interpreter starts again from beginning
910
  end process sequencer;
911

    
912

    
913
end architecture behavior;
(262-262/510)