OpenCores
URL https://opencores.org/ocsvn/eco32/eco32/trunk

Subversion Repositories eco32

[/] [eco32/] [tags/] [eco32-0.23/] [fpga/] [src/] [cpu/] [cpu.v] - Blame information for rev 168

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 hellwig
//
2
// cpu.v -- the ECO32 CPU
3
//
4
 
5
 
6
module cpu(clk, reset,
7
           bus_en, bus_wr, bus_size, bus_addr,
8 75 hellwig
           bus_data_in, bus_data_out, bus_wt,
9 27 hellwig
           irq);
10
    input clk;                          // system clock
11
    input reset;                        // system reset
12
    output bus_en;                      // bus enable
13
    output bus_wr;                      // bus write
14
    output [1:0] bus_size;               // 00: byte, 01: halfword, 10: word
15
    output [31:0] bus_addr;              // bus address
16
    input [31:0] bus_data_in;            // bus data input, for reads
17
    output [31:0] bus_data_out;          // bus data output, for writes
18 75 hellwig
    input bus_wt;                       // bus wait
19 27 hellwig
    input [15:0] irq;                    // interrupt requests
20
 
21
  // program counter
22
  wire [31:0] pc;                // program counter
23
  wire pc_we;                   // pc write enable
24
  wire [2:0] pc_src;             // pc source selector
25
  wire [31:0] pc_next;           // value written into pc
26
 
27
  // bus & mmu
28
  wire [31:0] mar;               // memory address register
29
  wire mar_we;                  // mar write enable
30
  wire ma_src;                  // memory address source selector
31
  wire [2:0] mmu_fnc;            // mmu function
32
  wire [31:0] virt_addr; // virtual address
33
  wire [31:0] phys_addr; // physical address
34
  wire [31:0] mdor;              // memory data out register
35
  wire mdor_we;                 // mdor write enable
36
  wire [31:0] mdir;              // memory data in register
37
  wire mdir_we;                 // mdir write enable
38
  wire mdir_sx;                 // mdir sign-extend
39
 
40
  // instruction register & decoder
41
  wire ir_we;                   // ir write enable
42
  wire [5:0] opcode;             // opcode part of ir
43
  wire [4:0] reg1;               // register 1 part of ir
44
  wire [4:0] reg2;               // register 2 part of ir
45
  wire [4:0] reg3;               // register 3 part of ir
46
  wire [31:0] sx16;              // sign-extended 16-bit immediate
47
  wire [31:0] zx16;              // zero-extended 16-bit immediate
48
  wire [31:0] hi16;              // high 16-bit immediate
49
  wire [31:0] sx16s2;            // sign-extended 16-bit immediate << 2
50
  wire [31:0] sx26s2;            // sign-extended 26-bit immediate << 2
51
 
52
  // register file
53
  wire [4:0] reg_a1;             // register address 1
54
  wire [31:0] reg_do1;           // register data out 1
55
  wire [1:0] reg_src2;           // register source 2 selector
56
  wire [4:0] reg_a2;             // register address 2
57
  wire [31:0] reg_do2;           // register data out 2
58
  wire reg_we2;                 // register write enable 2
59
  wire reg_we2_prot;            // register write enable 2,
60
                                // protected against writes with a2 = 0
61
  wire [2:0] reg_di2_src;        // register data in 2 source selector
62
  wire [31:0] reg_di2;           // register data in 2
63
 
64
  // alu, shift, and muldiv units
65
  wire alu_src1;                // alu source 1 selector
66
  wire [31:0] alu_op1;           // alu operand 1
67
  wire [2:0] alu_src2;           // alu source 2 selector
68
  wire [31:0] alu_op2;           // alu operand 2
69
  wire [2:0] alu_fnc;            // alu function
70
  wire [31:0] alu_res;           // alu result
71
  wire alu_equ;                 // alu operand 1 = operand 2
72
  wire alu_ult;                 // alu operand 1 < operand 2 (unsigned)
73
  wire alu_slt;                 // alu operand 1 < operand 2 (signed)
74
  wire [1:0] shift_fnc;          // shift function
75
  wire [31:0] shift_res; // shift result
76
  wire [2:0] muldiv_fnc; // muldiv function
77
  wire muldiv_start;            // muldiv should start
78
  wire muldiv_done;             // muldiv has finished
79
  wire muldiv_error;            // muldiv detected division by zero
80
  wire [31:0] muldiv_res;        // muldiv result
81
 
82
  // special registers
83 81 hellwig
  wire [2:0] sreg_num;           // special register number
84 27 hellwig
  wire sreg_we;                 // special register write enable
85
  wire [31:0] sreg_di;           // special register data in
86
  wire [31:0] sreg_do;           // special register data out
87
  wire [31:0] psw;               // special register 0 (psw) contents
88
  wire psw_we;                  // psw write enable
89
  wire [31:0] psw_new;           // new psw contents
90
  wire [31:0] tlb_index; // special register 1 (tlb index) contents
91
  wire tlb_index_we;            // tlb index write enable
92
  wire [31:0] tlb_index_new;     // new tlb index contents
93
  wire [31:0] tlb_entry_hi;      // special register 2 (tlb entry hi) contents
94
  wire tlb_entry_hi_we;         // tlb entry hi write enable
95
  wire [31:0] tlb_entry_hi_new;  // new tlb entry hi contents
96
  wire [31:0] tlb_entry_lo;      // special register 3 (tlb entry lo) contents
97
  wire tlb_entry_lo_we;         // tlb entry lo write enable
98
  wire [31:0] tlb_entry_lo_new;  // new tlb entry lo contents
99 81 hellwig
  wire [31:0] mmu_bad_addr;      // special register 4 (mmu bad addr) contents
100
  wire mmu_bad_addr_we;         // mmu bad addr write enable
101
  wire [31:0] mmu_bad_addr_new;  // new mmu bad addr contents
102 27 hellwig
 
103
  // mmu & tlb
104
  wire tlb_kmissed;             // page not found in tlb, MSB of addr is 1
105
  wire tlb_umissed;             // page not found in tlb, MSB of addr is 0
106
  wire tlb_invalid;             // tlb entry is invalid
107
  wire tlb_wrtprot;             // frame is write-protected
108
 
109
  //------------------------------------------------------------
110
 
111
  // program counter
112
  assign pc_next = (pc_src == 3'b000) ? alu_res :
113
                   (pc_src == 3'b001) ? 32'hE0000000 :
114
                   (pc_src == 3'b010) ? 32'hE0000004 :
115
                   (pc_src == 3'b011) ? 32'hC0000004 :
116
                   (pc_src == 3'b100) ? 32'hE0000008 :
117
                   (pc_src == 3'b101) ? 32'hC0000008 :
118
                   32'hxxxxxxxx;
119
  pc pc1(clk, pc_we, pc_next, pc);
120
 
121
  // bus & mmu
122
  mar mar1(clk, mar_we, alu_res, mar);
123
  assign virt_addr = (ma_src == 0) ? pc : mar;
124
  mmu mmu1(clk, reset, mmu_fnc, virt_addr, phys_addr,
125
           tlb_index, tlb_index_new,
126
           tlb_entry_hi, tlb_entry_hi_new,
127
           tlb_entry_lo, tlb_entry_lo_new,
128
           tlb_kmissed, tlb_umissed,
129
           tlb_invalid, tlb_wrtprot);
130
  assign bus_addr = phys_addr;
131
  mdor mdor1(clk, mdor_we, reg_do2, mdor);
132
  assign bus_data_out = mdor;
133
  mdir mdir1(clk, mdir_we, bus_data_in, bus_size, mdir_sx, mdir);
134
 
135
  // instruction register & decoder
136
  ir ir1(clk,
137
         ir_we, bus_data_in,
138
         opcode, reg1, reg2, reg3,
139
         sx16, zx16, hi16, sx16s2, sx26s2);
140
 
141
  // register file
142
  assign reg_a1 = reg1;
143
  assign reg_a2 = (reg_src2 == 2'b00) ? reg2 :
144
                  (reg_src2 == 2'b01) ? reg3 :
145
                  (reg_src2 == 2'b10) ? 5'b11111 :
146
                  (reg_src2 == 2'b11) ? 5'b11110 :
147
                  5'bxxxxx;
148
  assign reg_we2_prot = reg_we2 & (| reg_a2[4:0]);
149
  assign reg_di2 = (reg_di2_src == 3'b000) ? alu_res :
150
                   (reg_di2_src == 3'b001) ? shift_res :
151
                   (reg_di2_src == 3'b010) ? muldiv_res :
152
                   (reg_di2_src == 3'b011) ? mdir :
153
                   (reg_di2_src == 3'b100) ? sreg_do :
154
                   32'hxxxxxxxx;
155
  regs regs1(clk,
156
             reg_a1, reg_do1,
157
             reg_a2, reg_do2, reg_we2_prot, reg_di2);
158
 
159
  // alu, shift, and muldiv units
160
  assign alu_op1 = (alu_src1 == 0) ? pc : reg_do1;
161
  assign alu_op2 = (alu_src2 == 3'b000) ? 32'h00000004 :
162
                   (alu_src2 == 3'b001) ? reg_do2 :
163
                   (alu_src2 == 3'b010) ? sx16 :
164
                   (alu_src2 == 3'b011) ? zx16 :
165
                   (alu_src2 == 3'b100) ? hi16 :
166
                   (alu_src2 == 3'b101) ? sx16s2 :
167
                   (alu_src2 == 3'b110) ? sx26s2 :
168
                   32'hxxxxxxxx;
169
  alu alu1(alu_op1, alu_op2, alu_fnc,
170
           alu_res, alu_equ, alu_ult, alu_slt);
171
  shift shift1(clk, alu_op1, alu_op2[4:0], shift_fnc, shift_res);
172
  muldiv muldiv1(clk, alu_op1, alu_op2, muldiv_fnc, muldiv_start,
173
                 muldiv_done, muldiv_error, muldiv_res);
174
 
175
  // special registers
176 81 hellwig
  assign sreg_num = zx16[2:0];
177 27 hellwig
  assign sreg_di = reg_do2;
178
  sregs sregs1(clk, reset,
179
               sreg_num, sreg_we, sreg_di, sreg_do,
180
               psw, psw_we, psw_new,
181
               tlb_index, tlb_index_we, tlb_index_new,
182
               tlb_entry_hi, tlb_entry_hi_we, tlb_entry_hi_new,
183 81 hellwig
               tlb_entry_lo, tlb_entry_lo_we, tlb_entry_lo_new,
184
               mmu_bad_addr, mmu_bad_addr_we, mmu_bad_addr_new);
185
  assign mmu_bad_addr_new = virt_addr;
186 27 hellwig
 
187
  // ctrl
188
  ctrl ctrl1(clk, reset,
189
             opcode, alu_equ, alu_ult, alu_slt,
190
             bus_wt, bus_en, bus_wr, bus_size,
191
             pc_src, pc_we,
192
             mar_we, ma_src, mmu_fnc,
193
             mdor_we, mdir_we, mdir_sx, ir_we,
194
             reg_src2, reg_di2_src, reg_we2,
195
             alu_src1, alu_src2, alu_fnc, shift_fnc,
196
             muldiv_fnc, muldiv_start,
197
             muldiv_done, muldiv_error,
198
             sreg_we, irq, psw, psw_we, psw_new,
199
             virt_addr[31], virt_addr[1], virt_addr[0],
200 81 hellwig
             tlb_kmissed, tlb_umissed,
201
             tlb_invalid, tlb_wrtprot,
202
             tlb_index_we, tlb_entry_hi_we,
203
             tlb_entry_lo_we, mmu_bad_addr_we);
204 27 hellwig
 
205
endmodule
206
 
207
 
208
//--------------------------------------------------------------
209
// ctrl -- the finite state machine within the CPU
210
//--------------------------------------------------------------
211
 
212
 
213
module ctrl(clk, reset,
214
            opcode, alu_equ, alu_ult, alu_slt,
215
            bus_wt, bus_en, bus_wr, bus_size,
216
            pc_src, pc_we,
217
            mar_we, ma_src, mmu_fnc,
218
            mdor_we, mdir_we, mdir_sx, ir_we,
219
            reg_src2, reg_di2_src, reg_we2,
220
            alu_src1, alu_src2, alu_fnc, shift_fnc,
221
            muldiv_fnc, muldiv_start,
222
            muldiv_done, muldiv_error,
223
            sreg_we, irq, psw, psw_we, psw_new,
224
            va_31, va_1, va_0,
225 81 hellwig
            tlb_kmissed, tlb_umissed,
226
            tlb_invalid, tlb_wrtprot,
227
            tlb_index_we, tlb_entry_hi_we,
228
            tlb_entry_lo_we, mmu_bad_addr_we);
229 27 hellwig
    input clk;
230
    input reset;
231
    input [5:0] opcode;
232
    input alu_equ;
233
    input alu_ult;
234
    input alu_slt;
235
    input bus_wt;
236
    output reg bus_en;
237
    output reg bus_wr;
238
    output reg [1:0] bus_size;
239
    output reg [2:0] pc_src;
240
    output reg pc_we;
241
    output reg mar_we;
242
    output reg ma_src;
243
    output reg [2:0] mmu_fnc;
244
    output reg mdor_we;
245
    output reg mdir_we;
246
    output reg mdir_sx;
247
    output reg ir_we;
248
    output reg [1:0] reg_src2;
249
    output reg [2:0] reg_di2_src;
250
    output reg reg_we2;
251
    output reg alu_src1;
252
    output reg [2:0] alu_src2;
253
    output reg [2:0] alu_fnc;
254
    output reg [1:0] shift_fnc;
255
    output reg [2:0] muldiv_fnc;
256
    output reg muldiv_start;
257
    input muldiv_done;
258
    input muldiv_error;
259
    output reg sreg_we;
260
    input [15:0] irq;
261
    input [31:0] psw;
262
    output reg psw_we;
263
    output reg [31:0] psw_new;
264
    input va_31, va_1, va_0;
265
    input tlb_kmissed;
266
    input tlb_umissed;
267
    input tlb_invalid;
268
    input tlb_wrtprot;
269
    output reg tlb_index_we;
270
    output reg tlb_entry_hi_we;
271
    output reg tlb_entry_lo_we;
272 81 hellwig
    output reg mmu_bad_addr_we;
273 27 hellwig
 
274
  wire type_rrr;                // instr type is RRR
275
  wire type_rrs;                // instr type is RRS
276
  wire type_rrh;                // instr type is RRH
277
  wire type_rhh;                // instr type is RHH
278
  wire type_rrb;                // instr type is RRB
279
  wire type_j;                  // instr type is J
280
  wire type_jr;                 // instr type is JR
281
  wire type_link;               // instr saves PC+4 in $31
282
  wire type_ld;                 // instr loads data
283
  wire type_st;                 // instr stores data
284
  wire type_ldst;               // instr loads or stores data
285
  wire [1:0] ldst_size;          // load/store transfer size
286
  wire type_shift;              // instr uses the shift unit
287
  wire type_muldiv;             // instr uses the muldiv unit
288
  wire type_fast;               // instr is not shift or muldiv
289
  wire type_mvfs;               // instr is mvfs
290
  wire type_mvts;               // instr is mvts
291
  wire type_rfx;                // instr is rfx
292
  wire type_trap;               // instr is trap
293
  wire type_tb;                 // instr is a TLB instr
294
  reg [4:0] state;               // cpu internal state
295
                                //  0: reset
296
                                //  1: fetch instr (addr xlat)
297
                                //  2: decode instr
298
                                //     increment pc by 4
299
                                //     possibly store pc+4 in $31
300
                                //  3: execute RRR-type instr
301
                                //  4: execute RRS-type instr
302
                                //  5: execute RRH-type instr
303
                                //  6: execute RHH-type instr
304
                                //  7: execute RRB-type instr (1)
305
                                //  8: execute RRB-type instr (2)
306
                                //  9: execute J-type instr
307
                                // 10: execute JR-type instr
308
                                // 11: execute LDST-type instr (1)
309
                                // 12: execute LD-type instr (addr xlat)
310
                                // 13: execute LD-type instr (3)
311
                                // 14: execute ST-type instr (addr xlat)
312
                                // 15: interrupt
313
                                // 16: extra state for RRR shift instr
314
                                // 17: extra state for RRH shift instr
315
                                // 18: extra state for RRR muldiv instr
316
                                // 19: extra state for RRS muldiv instr
317
                                // 20: extra state for RRH muldiv instr
318
                                // 21: execute mvfs instr
319
                                // 22: execute mvts instr
320
                                // 23: execute rfx instr
321
                                // 24: irq_trigger check for mvts and rfx
322
                                // 25: exception (locus is PC-4)
323
                                // 26: exception (locus is PC)
324
                                // 27: execute TLB instr
325
                                // 28: fetch instr (bus cycle)
326
                                // 29: execute LD-type instr (bus cycle)
327
                                // 30: execute ST-type instr (bus cycle)
328
                                // all other: unused
329
  reg branch;                   // take the branch iff true
330
  wire [15:0] irq_pending;       // the vector of pending unmasked irqs
331
  wire irq_trigger;             // true iff any pending irq is present
332
                                // and interrupts are globally enabled
333
  reg [3:0] irq_priority;        // highest priority of pending interrupts
334
  reg [3:0] exc_priority;        // exception, when entering state 25 or 26
335
  reg [7:0] bus_count;           // counter to detect bus timeout
336
  wire bus_timeout;             // bus timeout detected
337
  wire exc_prv_addr;            // privileged address exception detected
338
  wire exc_ill_addr;            // illegal address exception detected
339
  wire exc_tlb_but_wrtprot;     // any tlb exception but write protection
340
  wire exc_tlb_any;             // any tlb exception
341
 
342
  //------------------------------------------------------------
343
 
344
  // decode instr type
345
  assign type_rrr    = ((opcode == 6'h00) ||
346
                        (opcode == 6'h02) ||
347
                        (opcode == 6'h04) ||
348
                        (opcode == 6'h06) ||
349
                        (opcode == 6'h08) ||
350
                        (opcode == 6'h0A) ||
351
                        (opcode == 6'h0C) ||
352
                        (opcode == 6'h0E) ||
353
                        (opcode == 6'h10) ||
354
                        (opcode == 6'h12) ||
355
                        (opcode == 6'h14) ||
356
                        (opcode == 6'h16) ||
357
                        (opcode == 6'h18) ||
358
                        (opcode == 6'h1A) ||
359
                        (opcode == 6'h1C)) ? 1 : 0;
360
  assign type_rrs    = ((opcode == 6'h01) ||
361
                        (opcode == 6'h03) ||
362
                        (opcode == 6'h05) ||
363
                        (opcode == 6'h09) ||
364
                        (opcode == 6'h0D)) ? 1 : 0;
365
  assign type_rrh    = ((opcode == 6'h07) ||
366
                        (opcode == 6'h0B) ||
367
                        (opcode == 6'h0F) ||
368
                        (opcode == 6'h11) ||
369
                        (opcode == 6'h13) ||
370
                        (opcode == 6'h15) ||
371
                        (opcode == 6'h17) ||
372
                        (opcode == 6'h19) ||
373
                        (opcode == 6'h1B) ||
374
                        (opcode == 6'h1D)) ? 1 : 0;
375
  assign type_rhh    = (opcode == 6'h1F) ? 1 : 0;
376
  assign type_rrb    = ((opcode == 6'h20) ||
377
                        (opcode == 6'h21) ||
378
                        (opcode == 6'h22) ||
379
                        (opcode == 6'h23) ||
380
                        (opcode == 6'h24) ||
381
                        (opcode == 6'h25) ||
382
                        (opcode == 6'h26) ||
383
                        (opcode == 6'h27) ||
384
                        (opcode == 6'h28) ||
385
                        (opcode == 6'h29)) ? 1 : 0;
386
  assign type_j      = ((opcode == 6'h2A) ||
387
                        (opcode == 6'h2C)) ? 1 : 0;
388
  assign type_jr     = ((opcode == 6'h2B) ||
389
                        (opcode == 6'h2D)) ? 1 : 0;
390
  assign type_link   = ((opcode == 6'h2C) ||
391
                        (opcode == 6'h2D)) ? 1 : 0;
392
  assign type_ld     = ((opcode == 6'h30) ||
393
                        (opcode == 6'h31) ||
394
                        (opcode == 6'h32) ||
395
                        (opcode == 6'h33) ||
396
                        (opcode == 6'h34)) ? 1 : 0;
397
  assign type_st     = ((opcode == 6'h35) ||
398
                        (opcode == 6'h36) ||
399
                        (opcode == 6'h37)) ? 1 : 0;
400
  assign type_ldst   = type_ld | type_st;
401
  assign ldst_size   = ((opcode == 6'h30) ||
402
                        (opcode == 6'h35)) ? 2'b10 :
403
                       ((opcode == 6'h31) ||
404
                        (opcode == 6'h32) ||
405
                        (opcode == 6'h36)) ? 2'b01 :
406
                       ((opcode == 6'h33) ||
407
                        (opcode == 6'h34) ||
408
                        (opcode == 6'h37)) ? 2'b00 :
409
                       2'bxx;
410
  assign type_shift  = ((opcode == 6'h18) ||
411
                        (opcode == 6'h19) ||
412
                        (opcode == 6'h1A) ||
413
                        (opcode == 6'h1B) ||
414
                        (opcode == 6'h1C) ||
415
                        (opcode == 6'h1D)) ? 1 : 0;
416
  assign type_muldiv = ((opcode == 6'h04) ||
417
                        (opcode == 6'h05) ||
418
                        (opcode == 6'h06) ||
419
                        (opcode == 6'h07) ||
420
                        (opcode == 6'h08) ||
421
                        (opcode == 6'h09) ||
422
                        (opcode == 6'h0A) ||
423
                        (opcode == 6'h0B) ||
424
                        (opcode == 6'h0C) ||
425
                        (opcode == 6'h0D) ||
426
                        (opcode == 6'h0E) ||
427
                        (opcode == 6'h0F)) ? 1 : 0;
428
  assign type_fast   = ~(type_shift | type_muldiv);
429
  assign type_mvfs   = (opcode == 6'h38) ? 1 : 0;
430
  assign type_mvts   = (opcode == 6'h39) ? 1 : 0;
431
  assign type_rfx    = (opcode == 6'h2F) ? 1 : 0;
432
  assign type_trap   = (opcode == 6'h2E) ? 1 : 0;
433
  assign type_tb     = ((opcode == 6'h3A) ||
434
                        (opcode == 6'h3B) ||
435
                        (opcode == 6'h3C) ||
436
                        (opcode == 6'h3D)) ? 1 : 0;
437
 
438
  // state machine
439
  always @(posedge clk) begin
440
    if (reset == 1) begin
441
      state <= 0;
442
    end else begin
443
      case (state)
444
        5'd0:  // reset
445
          begin
446
            state <= 5'd1;
447
          end
448
        5'd1:  // fetch instr (addr xlat)
449
          begin
450
            if (exc_prv_addr) begin
451
              state <= 26;
452
              exc_priority <= 4'd9;
453
            end else
454
            if (exc_ill_addr) begin
455
              state <= 26;
456
              exc_priority <= 4'd8;
457
            end else begin
458
              state <= 5'd28;
459
            end
460
          end
461
        5'd2:  // decode instr
462
               // increment pc by 4
463
               // possibly store pc+4 in $31
464
          begin
465
            if (type_rrr) begin
466
              // RRR-type instruction
467
              state <= 5'd3;
468
            end else
469
            if (type_rrs) begin
470
              // RRS-type instruction
471
              state <= 5'd4;
472
            end else
473
            if (type_rrh) begin
474
              // RRH-type instruction
475
              state <= 5'd5;
476
            end else
477
            if (type_rhh) begin
478
              // RHH-type instruction
479
              state <= 5'd6;
480
            end else
481
            if (type_rrb) begin
482
              // RRB-type instr
483
              state <= 5'd7;
484
            end else
485
            if (type_j) begin
486
              // J-type instr
487
              state <= 5'd9;
488
            end else
489
            if (type_jr) begin
490
              // JR-type instr
491
              state <= 5'd10;
492
            end else
493
            if (type_ldst) begin
494
              // LDST-type instr
495
              state <= 5'd11;
496
            end else
497
            if (type_mvfs) begin
498
              // mvfs instr
499
              state <= 5'd21;
500
            end else
501
            if (type_mvts) begin
502
              // mvts instr
503
              if (psw[26] == 1) begin
504
                state <= 5'd25;
505
                exc_priority <= 4'd2;
506
              end else begin
507
                state <= 5'd22;
508
              end
509
            end else
510
            if (type_rfx) begin
511
              // rfx instr
512
              if (psw[26] == 1) begin
513
                state <= 5'd25;
514
                exc_priority <= 4'd2;
515
              end else begin
516
                state <= 5'd23;
517
              end
518
            end else
519
            if (type_trap) begin
520
              // trap instr
521
              state <= 5'd25;
522
              exc_priority <= 4'd4;
523
            end else
524
            if (type_tb) begin
525
              // TLB instr
526
              if (psw[26] == 1) begin
527
                state <= 5'd25;
528
                exc_priority <= 4'd2;
529
              end else begin
530
                state <= 5'd27;
531
              end
532
            end else begin
533
              // illegal instruction
534
              state <= 5'd25;
535
              exc_priority <= 4'd1;
536
            end
537
          end
538
        5'd3:  // execute RRR-type instr
539
          begin
540
            if (type_muldiv) begin
541
              state <= 5'd18;
542
            end else
543
            if (type_shift) begin
544
              state <= 5'd16;
545
            end else begin
546
              if (irq_trigger) begin
547
                state <= 5'd15;
548
              end else begin
549
                state <= 5'd1;
550
              end
551
            end
552
          end
553
        5'd4:  // execute RRS-type instr
554
          begin
555
            if (type_muldiv) begin
556
              state <= 5'd19;
557
            end else begin
558
              if (irq_trigger) begin
559
                state <= 5'd15;
560
              end else begin
561
                state <= 5'd1;
562
              end
563
            end
564
          end
565
        5'd5:  // execute RRH-type instr
566
          begin
567
            if (type_muldiv) begin
568
              state <= 5'd20;
569
            end else
570
            if (type_shift) begin
571
              state <= 5'd17;
572
            end else begin
573
              if (irq_trigger) begin
574
                state <= 5'd15;
575
              end else begin
576
                state <= 5'd1;
577
              end
578
            end
579
          end
580
        5'd6:  // execute RHH-type instr
581
          begin
582
            if (irq_trigger) begin
583
              state <= 5'd15;
584
            end else begin
585
              state <= 5'd1;
586
            end
587
          end
588
        5'd7:  // execute RRB-type instr (1)
589
          begin
590
            if (branch) begin
591
              state <= 5'd8;
592
            end else begin
593
              if (irq_trigger) begin
594
                state <= 5'd15;
595
              end else begin
596
                state <= 5'd1;
597
              end
598
            end
599
          end
600
        5'd8:  // execute RRB-type instr (2)
601
          begin
602
            if (irq_trigger) begin
603
              state <= 5'd15;
604
            end else begin
605
              state <= 5'd1;
606
            end
607
          end
608
        5'd9:  // execute J-type instr
609
          begin
610
            if (irq_trigger) begin
611
              state <= 5'd15;
612
            end else begin
613
              state <= 5'd1;
614
            end
615
          end
616
        5'd10:  // execute JR-type instr
617
          begin
618
            if (irq_trigger) begin
619
              state <= 5'd15;
620
            end else begin
621
              state <= 5'd1;
622
            end
623
          end
624
        5'd11:  // execute LDST-type instr (1)
625
          begin
626
            if (type_ld) begin
627
              state <= 5'd12;
628
            end else begin
629
              state <= 5'd14;
630
            end
631
          end
632
        5'd12:  // execute LD-type instr (addr xlat)
633
          begin
634
            if (exc_prv_addr) begin
635
              state <= 25;
636
              exc_priority <= 4'd9;
637
            end else
638
            if (exc_ill_addr) begin
639
              state <= 25;
640
              exc_priority <= 4'd8;
641
            end else begin
642
              state <= 5'd29;
643
            end
644
          end
645
        5'd13:  // execute LD-type instr (3)
646
          begin
647
            if (irq_trigger) begin
648
              state <= 5'd15;
649
            end else begin
650
              state <= 5'd1;
651
            end
652
          end
653
        5'd14:  // execute ST-type instr (addr xlat)
654
          begin
655
            if (exc_prv_addr) begin
656
              state <= 25;
657
              exc_priority <= 4'd9;
658
            end else
659
            if (exc_ill_addr) begin
660
              state <= 25;
661
              exc_priority <= 4'd8;
662
            end else begin
663
              state <= 5'd30;
664
            end
665
          end
666
        5'd15:  // interrupt
667
          begin
668
            state <= 5'd1;
669
          end
670
        5'd16:  // extra state for RRR shift instr
671
          begin
672
            if (irq_trigger) begin
673
              state <= 5'd15;
674
            end else begin
675
              state <= 5'd1;
676
            end
677
          end
678
        5'd17:  // extra state for RRH shift instr
679
          begin
680
            if (irq_trigger) begin
681
              state <= 5'd15;
682
            end else begin
683
              state <= 5'd1;
684
            end
685
          end
686
        5'd18:  // extra state for RRR muldiv instr
687
          begin
688
            if (muldiv_done) begin
689
              if (muldiv_error) begin
690
                state <= 5'd25;
691
                exc_priority <= 4'd3;
692
              end else
693
              if (irq_trigger) begin
694
                state <= 5'd15;
695
              end else begin
696
                state <= 5'd1;
697
              end
698
            end else begin
699
              state <= 5'd18;
700
            end
701
          end
702
        5'd19:  // extra state for RRS muldiv instr
703
          begin
704
            if (muldiv_done) begin
705
              if (muldiv_error) begin
706
                state <= 5'd25;
707
                exc_priority <= 4'd3;
708
              end else
709
              if (irq_trigger) begin
710
                state <= 5'd15;
711
              end else begin
712
                state <= 5'd1;
713
              end
714
            end else begin
715
              state <= 5'd19;
716
            end
717
          end
718
        5'd20:  // extra state for RRH muldiv instr
719
          begin
720
            if (muldiv_done) begin
721
              if (muldiv_error) begin
722
                state <= 5'd25;
723
                exc_priority <= 4'd3;
724
              end else
725
              if (irq_trigger) begin
726
                state <= 5'd15;
727
              end else begin
728
                state <= 5'd1;
729
              end
730
            end else begin
731
              state <= 5'd20;
732
            end
733
          end
734
        5'd21:  // execute mvfs instr
735
          begin
736
            if (irq_trigger) begin
737
              state <= 5'd15;
738
            end else begin
739
              state <= 5'd1;
740
            end
741
          end
742
        5'd22:  // execute mvts instr
743
          begin
744
            state <= 5'd24;
745
          end
746
        5'd23:  // execute rfx instr
747
          begin
748
            state <= 5'd24;
749
          end
750
        5'd24:  // irq_trigger check for mvts and rfx
751
          begin
752
            if (irq_trigger) begin
753
              state <= 5'd15;
754
            end else begin
755
              state <= 5'd1;
756
            end
757
          end
758
        5'd25:  // exception (locus is PC-4)
759
          begin
760
            state <= 5'd1;
761
          end
762
        5'd26:  // exception (locus is PC)
763
          begin
764
            state <= 5'd1;
765
          end
766
        5'd27:  // execute TLB instr
767
          begin
768
            if (irq_trigger) begin
769
              state <= 5'd15;
770
            end else begin
771
              state <= 5'd1;
772
            end
773
          end
774
        5'd28:  // fetch instr (bus cycle)
775
          begin
776
            if (tlb_kmissed == 1 || tlb_umissed == 1) begin
777
              state <= 5'd26;
778
              exc_priority <= 4'd5;
779
            end else
780
            if (tlb_invalid == 1) begin
781
              state <= 5'd26;
782
              exc_priority <= 4'd7;
783
            end else
784
            if (bus_wt == 1) begin
785
              if (bus_timeout == 1) begin
786
                state <= 5'd26;
787
                exc_priority <= 4'd0;
788
              end else begin
789
                state <= 5'd28;
790
              end
791
            end else begin
792
              state <= 5'd2;
793
            end
794
          end
795
        5'd29:  // execute LD-type instr (bus cycle)
796
          begin
797
            if (tlb_kmissed == 1 || tlb_umissed == 1) begin
798
              state <= 5'd25;
799
              exc_priority <= 4'd5;
800
            end else
801
            if (tlb_invalid == 1) begin
802
              state <= 5'd25;
803
              exc_priority <= 4'd7;
804
            end else
805
            if (bus_wt == 1) begin
806
              if (bus_timeout == 1) begin
807
                state <= 5'd25;
808
                exc_priority <= 4'd0;
809
              end else begin
810
                state <= 5'd29;
811
              end
812
            end else begin
813
              state <= 5'd13;
814
            end
815
          end
816
        5'd30:  // execute ST-type instr (bus cycle)
817
          begin
818
            if (tlb_kmissed == 1 || tlb_umissed == 1) begin
819
              state <= 5'd25;
820
              exc_priority <= 4'd5;
821
            end else
822
            if (tlb_invalid == 1) begin
823
              state <= 5'd25;
824
              exc_priority <= 4'd7;
825
            end else
826
            if (tlb_wrtprot == 1) begin
827
              state <= 5'd25;
828
              exc_priority <= 4'd6;
829
            end else
830
            if (bus_wt == 1) begin
831
              if (bus_timeout == 1) begin
832
                state <= 5'd25;
833
                exc_priority <= 4'd0;
834
              end else begin
835
                state <= 5'd30;
836
              end
837
            end else begin
838
              if (irq_trigger) begin
839
                state <= 5'd15;
840
              end else begin
841
                state <= 5'd1;
842
              end
843
            end
844
          end
845
        default:  // all other states: unused
846
          begin
847
            state <= 5'd0;
848
          end
849
      endcase
850
    end
851
  end
852
 
853
  // bus timeout detector
854
  assign bus_timeout = (bus_count == 8'h00) ? 1 : 0;
855
  always @(posedge clk) begin
856
    if (bus_en == 1 && bus_wt == 1) begin
857
      // bus is waiting
858
      bus_count <= bus_count - 1;
859
    end else begin
860
      // bus is not waiting
861
      bus_count <= 8'hFF;
862
    end
863
  end
864
 
865
  // output logic
866
  always @(*) begin
867
    case (state)
868
      5'd0:  // reset
869
        begin
870
          pc_src = 3'b001;
871
          pc_we = 1'b1;
872
          mar_we = 1'b0;
873
          ma_src = 1'bx;
874
          mmu_fnc = 3'b000;
875
          mdor_we = 1'b0;
876
          bus_en = 1'b0;
877
          bus_wr = 1'bx;
878
          bus_size = 2'bxx;
879
          mdir_we = 1'b0;
880
          mdir_sx = 1'bx;
881
          ir_we = 1'b0;
882
          reg_src2 = 2'bxx;
883
          reg_di2_src = 3'bxxx;
884
          reg_we2 = 1'b0;
885
          alu_src1 = 1'bx;
886
          alu_src2 = 3'bxxx;
887
          alu_fnc = 3'bxxx;
888
          shift_fnc = 2'bxx;
889
          muldiv_fnc = 3'bxxx;
890
          muldiv_start = 1'b0;
891
          sreg_we = 1'b0;
892
          psw_we = 1'b0;
893
          psw_new = 32'hxxxxxxxx;
894
          tlb_index_we = 1'b0;
895
          tlb_entry_hi_we = 1'b0;
896
          tlb_entry_lo_we = 1'b0;
897 81 hellwig
          mmu_bad_addr_we = 1'b0;
898 27 hellwig
        end
899
      5'd1:  // fetch instr (addr xlat)
900
        begin
901
          pc_src = 3'bxxx;
902
          pc_we = 1'b0;
903
          mar_we = 1'b0;
904
          ma_src = 1'b0;
905
          mmu_fnc = (exc_prv_addr | exc_ill_addr) ? 3'b000 : 3'b001;
906
          mdor_we = 1'b0;
907
          bus_en = 1'b0;
908
          bus_wr = 1'bx;
909
          bus_size = 2'b10;  // enable illegal address detection
910
          mdir_we = 1'b0;
911
          mdir_sx = 1'bx;
912
          ir_we = 1'b0;
913
          reg_src2 = 2'bxx;
914
          reg_di2_src = 3'bxxx;
915
          reg_we2 = 1'b0;
916
          alu_src1 = 1'bx;
917
          alu_src2 = 3'bxxx;
918
          alu_fnc = 3'bxxx;
919
          shift_fnc = 2'bxx;
920
          muldiv_fnc = 3'bxxx;
921
          muldiv_start = 1'b0;
922
          sreg_we = 1'b0;
923
          psw_we = 1'b0;
924
          psw_new = 32'hxxxxxxxx;
925
          tlb_index_we = 1'b0;
926
          tlb_entry_hi_we = 1'b0;
927
          tlb_entry_lo_we = 1'b0;
928 81 hellwig
          mmu_bad_addr_we = exc_prv_addr | exc_ill_addr;
929 27 hellwig
        end
930
      5'd2:  // decode instr
931
             // increment pc by 4
932
             // possibly store pc+4 in $31
933
        begin
934
          pc_src = 3'b000;
935
          pc_we = 1'b1;
936
          mar_we = 1'b0;
937
          ma_src = 1'bx;
938
          mmu_fnc = 3'b000;
939
          mdor_we = 1'b0;
940
          bus_en = 1'b0;
941
          bus_wr = 1'bx;
942
          bus_size = 2'bxx;
943
          mdir_we = 1'b0;
944
          mdir_sx = 1'bx;
945
          ir_we = 1'b0;
946
          reg_src2 = (type_link == 1) ? 2'b10 :
947
                     (type_rfx == 1) ? 2'b11 :
948
                     2'b00;
949
          reg_di2_src = (type_link == 1) ? 3'b000 : 3'bxxx;
950
          reg_we2 = (type_link == 1) ? 1'b1 : 1'b0;
951
          alu_src1 = 1'b0;
952
          alu_src2 = 3'b000;
953
          alu_fnc = 3'b000;
954
          shift_fnc = 2'bxx;
955
          muldiv_fnc = 3'bxxx;
956
          muldiv_start = 1'b0;
957
          sreg_we = 1'b0;
958
          psw_we = 1'b0;
959
          psw_new = 32'hxxxxxxxx;
960
          tlb_index_we = 1'b0;
961
          tlb_entry_hi_we = 1'b0;
962
          tlb_entry_lo_we = 1'b0;
963 81 hellwig
          mmu_bad_addr_we = 1'b0;
964 27 hellwig
        end
965
      5'd3:  // execute RRR-type instr
966
        begin
967
          pc_src = 3'bxxx;
968
          pc_we = 1'b0;
969
          mar_we = 1'b0;
970
          ma_src = 1'bx;
971
          mmu_fnc = 3'b000;
972
          mdor_we = 1'b0;
973
          bus_en = 1'b0;
974
          bus_wr = 1'bx;
975
          bus_size = 2'bxx;
976
          mdir_we = 1'b0;
977
          mdir_sx = 1'bx;
978
          ir_we = 1'b0;
979
          reg_src2 = 2'b01;
980
          reg_di2_src = 3'b000;
981
          reg_we2 = type_fast;
982
          alu_src1 = 1'b1;
983
          alu_src2 = 3'b001;
984
          alu_fnc = { opcode[4], opcode[2], opcode[1] };
985
          shift_fnc = { opcode[2], opcode[1] };
986
          muldiv_fnc = { opcode[3], opcode[2], opcode[1] };
987
          muldiv_start = type_muldiv;
988
          sreg_we = 1'b0;
989
          psw_we = 1'b0;
990
          psw_new = 32'hxxxxxxxx;
991
          tlb_index_we = 1'b0;
992
          tlb_entry_hi_we = 1'b0;
993
          tlb_entry_lo_we = 1'b0;
994 81 hellwig
          mmu_bad_addr_we = 1'b0;
995 27 hellwig
        end
996
      5'd4:  // execute RRS-type instr
997
        begin
998
          pc_src = 3'bxxx;
999
          pc_we = 1'b0;
1000
          mar_we = 1'b0;
1001
          ma_src = 1'bx;
1002
          mmu_fnc = 3'b000;
1003
          mdor_we = 1'b0;
1004
          bus_en = 1'b0;
1005
          bus_wr = 1'bx;
1006
          bus_size = 2'bxx;
1007
          mdir_we = 1'b0;
1008
          mdir_sx = 1'bx;
1009
          ir_we = 1'b0;
1010
          reg_src2 = 2'b00;
1011
          reg_di2_src = 3'b000;
1012
          reg_we2 = type_fast;
1013
          alu_src1 = 1'b1;
1014
          alu_src2 = 3'b010;
1015
          alu_fnc = { opcode[4], opcode[2], opcode[1] };
1016
          shift_fnc = 2'bxx;
1017
          muldiv_fnc = { opcode[3], opcode[2], opcode[1] };
1018
          muldiv_start = type_muldiv;
1019
          sreg_we = 1'b0;
1020
          psw_we = 1'b0;
1021
          psw_new = 32'hxxxxxxxx;
1022
          tlb_index_we = 1'b0;
1023
          tlb_entry_hi_we = 1'b0;
1024
          tlb_entry_lo_we = 1'b0;
1025 81 hellwig
          mmu_bad_addr_we = 1'b0;
1026 27 hellwig
        end
1027
      5'd5:  // execute RRH-type instr
1028
        begin
1029
          pc_src = 3'bxxx;
1030
          pc_we = 1'b0;
1031
          mar_we = 1'b0;
1032
          ma_src = 1'bx;
1033
          mmu_fnc = 3'b000;
1034
          mdor_we = 1'b0;
1035
          bus_en = 1'b0;
1036
          bus_wr = 1'bx;
1037
          bus_size = 2'bxx;
1038
          mdir_we = 1'b0;
1039
          mdir_sx = 1'bx;
1040
          ir_we = 1'b0;
1041
          reg_src2 = 2'b00;
1042
          reg_di2_src = 3'b000;
1043
          reg_we2 = type_fast;
1044
          alu_src1 = 1'b1;
1045
          alu_src2 = 3'b011;
1046
          alu_fnc = { opcode[4], opcode[2], opcode[1] };
1047
          shift_fnc = { opcode[2], opcode[1] };
1048
          muldiv_fnc = { opcode[3], opcode[2], opcode[1] };
1049
          muldiv_start = type_muldiv;
1050
          sreg_we = 1'b0;
1051
          psw_we = 1'b0;
1052
          psw_new = 32'hxxxxxxxx;
1053
          tlb_index_we = 1'b0;
1054
          tlb_entry_hi_we = 1'b0;
1055
          tlb_entry_lo_we = 1'b0;
1056 81 hellwig
          mmu_bad_addr_we = 1'b0;
1057 27 hellwig
        end
1058
      5'd6:  // execute RHH-type instr
1059
        begin
1060
          pc_src = 3'bxxx;
1061
          pc_we = 1'b0;
1062
          mar_we = 1'b0;
1063
          ma_src = 1'bx;
1064
          mmu_fnc = 3'b000;
1065
          mdor_we = 1'b0;
1066
          bus_en = 1'b0;
1067
          bus_wr = 1'bx;
1068
          bus_size = 2'bxx;
1069
          mdir_we = 1'b0;
1070
          mdir_sx = 1'bx;
1071
          ir_we = 1'b0;
1072
          reg_src2 = 2'b00;
1073
          reg_di2_src = 3'b000;
1074
          reg_we2 = 1'b1;
1075
          alu_src1 = 1'bx;
1076
          alu_src2 = 3'b100;
1077
          alu_fnc = 3'b011;
1078
          shift_fnc = 2'bxx;
1079
          muldiv_fnc = 3'bxxx;
1080
          muldiv_start = 1'b0;
1081
          sreg_we = 1'b0;
1082
          psw_we = 1'b0;
1083
          psw_new = 32'hxxxxxxxx;
1084
          tlb_index_we = 1'b0;
1085
          tlb_entry_hi_we = 1'b0;
1086
          tlb_entry_lo_we = 1'b0;
1087 81 hellwig
          mmu_bad_addr_we = 1'b0;
1088 27 hellwig
        end
1089
      5'd7:  // execute RRB-type instr (1)
1090
        begin
1091
          pc_src = 3'bxxx;
1092
          pc_we = 1'b0;
1093
          mar_we = 1'b0;
1094
          ma_src = 1'bx;
1095
          mmu_fnc = 3'b000;
1096
          mdor_we = 1'b0;
1097
          bus_en = 1'b0;
1098
          bus_wr = 1'bx;
1099
          bus_size = 2'bxx;
1100
          mdir_we = 1'b0;
1101
          mdir_sx = 1'bx;
1102
          ir_we = 1'b0;
1103
          reg_src2 = 2'bxx;
1104
          reg_di2_src = 3'bxxx;
1105
          reg_we2 = 1'b0;
1106
          alu_src1 = 1'b1;
1107
          alu_src2 = 3'b001;
1108
          alu_fnc = 3'b001;
1109
          shift_fnc = 2'bxx;
1110
          muldiv_fnc = 3'bxxx;
1111
          muldiv_start = 1'b0;
1112
          sreg_we = 1'b0;
1113
          psw_we = 1'b0;
1114
          psw_new = 32'hxxxxxxxx;
1115
          tlb_index_we = 1'b0;
1116
          tlb_entry_hi_we = 1'b0;
1117
          tlb_entry_lo_we = 1'b0;
1118 81 hellwig
          mmu_bad_addr_we = 1'b0;
1119 27 hellwig
        end
1120
      5'd8:  // execute RRB-type instr (2)
1121
        begin
1122
          pc_src = 3'b000;
1123
          pc_we = 1'b1;
1124
          mar_we = 1'b0;
1125
          ma_src = 1'bx;
1126
          mmu_fnc = 3'b000;
1127
          mdor_we = 1'b0;
1128
          bus_en = 1'b0;
1129
          bus_wr = 1'bx;
1130
          bus_size = 2'bxx;
1131
          mdir_we = 1'b0;
1132
          mdir_sx = 1'bx;
1133
          ir_we = 1'b0;
1134
          reg_src2 = 2'bxx;
1135
          reg_di2_src = 3'bxxx;
1136
          reg_we2 = 1'b0;
1137
          alu_src1 = 1'b0;
1138
          alu_src2 = 3'b101;
1139
          alu_fnc = 3'b000;
1140
          shift_fnc = 2'bxx;
1141
          muldiv_fnc = 3'bxxx;
1142
          muldiv_start = 1'b0;
1143
          sreg_we = 1'b0;
1144
          psw_we = 1'b0;
1145
          psw_new = 32'hxxxxxxxx;
1146
          tlb_index_we = 1'b0;
1147
          tlb_entry_hi_we = 1'b0;
1148
          tlb_entry_lo_we = 1'b0;
1149 81 hellwig
          mmu_bad_addr_we = 1'b0;
1150 27 hellwig
        end
1151
      5'd9:  // execute J-type instr
1152
        begin
1153
          pc_src = 3'b000;
1154
          pc_we = 1'b1;
1155
          mar_we = 1'b0;
1156
          ma_src = 1'bx;
1157
          mmu_fnc = 3'b000;
1158
          mdor_we = 1'b0;
1159
          bus_en = 1'b0;
1160
          bus_wr = 1'bx;
1161
          bus_size = 2'bxx;
1162
          mdir_we = 1'b0;
1163
          mdir_sx = 1'bx;
1164
          ir_we = 1'b0;
1165
          reg_src2 = 2'bxx;
1166
          reg_di2_src = 3'bxxx;
1167
          reg_we2 = 1'b0;
1168
          alu_src1 = 1'b0;
1169
          alu_src2 = 3'b110;
1170
          alu_fnc = 3'b000;
1171
          shift_fnc = 2'bxx;
1172
          muldiv_fnc = 3'bxxx;
1173
          muldiv_start = 1'b0;
1174
          sreg_we = 1'b0;
1175
          psw_we = 1'b0;
1176
          psw_new = 32'hxxxxxxxx;
1177
          tlb_index_we = 1'b0;
1178
          tlb_entry_hi_we = 1'b0;
1179
          tlb_entry_lo_we = 1'b0;
1180 81 hellwig
          mmu_bad_addr_we = 1'b0;
1181 27 hellwig
        end
1182
      5'd10:  // execute JR-type instr
1183
        begin
1184
          pc_src = 3'b000;
1185
          pc_we = 1'b1;
1186
          mar_we = 1'b0;
1187
          ma_src = 1'bx;
1188
          mmu_fnc = 3'b000;
1189
          mdor_we = 1'b0;
1190
          bus_en = 1'b0;
1191
          bus_wr = 1'bx;
1192
          bus_size = 2'bxx;
1193
          mdir_we = 1'b0;
1194
          mdir_sx = 1'bx;
1195
          ir_we = 1'b0;
1196
          reg_src2 = 2'bxx;
1197
          reg_di2_src = 3'bxxx;
1198
          reg_we2 = 1'b0;
1199
          alu_src1 = 1'b1;
1200
          alu_src2 = 3'bxxx;
1201
          alu_fnc = 3'b010;
1202
          shift_fnc = 2'bxx;
1203
          muldiv_fnc = 3'bxxx;
1204
          muldiv_start = 1'b0;
1205
          sreg_we = 1'b0;
1206
          psw_we = 1'b0;
1207
          psw_new = 32'hxxxxxxxx;
1208
          tlb_index_we = 1'b0;
1209
          tlb_entry_hi_we = 1'b0;
1210
          tlb_entry_lo_we = 1'b0;
1211 81 hellwig
          mmu_bad_addr_we = 1'b0;
1212 27 hellwig
        end
1213
      5'd11:  // execute LDST-type instr (1)
1214
        begin
1215
          pc_src = 3'bxxx;
1216
          pc_we = 1'b0;
1217
          mar_we = 1'b1;
1218
          ma_src = 1'bx;
1219
          mmu_fnc = 3'b000;
1220
          mdor_we = 1'b1;
1221
          bus_en = 1'b0;
1222
          bus_wr = 1'bx;
1223
          bus_size = 2'bxx;
1224
          mdir_we = 1'b0;
1225
          mdir_sx = 1'bx;
1226
          ir_we = 1'b0;
1227
          reg_src2 = 2'bxx;
1228
          reg_di2_src = 3'bxxx;
1229
          reg_we2 = 1'b0;
1230
          alu_src1 = 1'b1;
1231
          alu_src2 = 3'b010;
1232
          alu_fnc = 3'b000;
1233
          shift_fnc = 2'bxx;
1234
          muldiv_fnc = 3'bxxx;
1235
          muldiv_start = 1'b0;
1236
          sreg_we = 1'b0;
1237
          psw_we = 1'b0;
1238
          psw_new = 32'hxxxxxxxx;
1239
          tlb_index_we = 1'b0;
1240
          tlb_entry_hi_we = 1'b0;
1241
          tlb_entry_lo_we = 1'b0;
1242 81 hellwig
          mmu_bad_addr_we = 1'b0;
1243 27 hellwig
        end
1244
      5'd12:  // execute LD-type instr (addr xlat)
1245
        begin
1246
          pc_src = 3'bxxx;
1247
          pc_we = 1'b0;
1248
          mar_we = 1'b0;
1249
          ma_src = 1'b1;
1250
          mmu_fnc = (exc_prv_addr | exc_ill_addr) ? 3'b000 : 3'b001;
1251
          mdor_we = 1'b0;
1252
          bus_en = 1'b0;
1253
          bus_wr = 1'bx;
1254
          bus_size = ldst_size;  // enable illegal address detection
1255
          mdir_we = 1'b0;
1256
          mdir_sx = 1'bx;
1257
          ir_we = 1'b0;
1258
          reg_src2 = 2'bxx;
1259
          reg_di2_src = 3'bxxx;
1260
          reg_we2 = 1'b0;
1261
          alu_src1 = 1'bx;
1262
          alu_src2 = 3'bxxx;
1263
          alu_fnc = 3'bxxx;
1264
          shift_fnc = 2'bxx;
1265
          muldiv_fnc = 3'bxxx;
1266
          muldiv_start = 1'b0;
1267
          sreg_we = 1'b0;
1268
          psw_we = 1'b0;
1269
          psw_new = 32'hxxxxxxxx;
1270
          tlb_index_we = 1'b0;
1271
          tlb_entry_hi_we = 1'b0;
1272
          tlb_entry_lo_we = 1'b0;
1273 81 hellwig
          mmu_bad_addr_we = exc_prv_addr | exc_ill_addr;
1274 27 hellwig
        end
1275
      5'd13:  // execute LD-type instr (3)
1276
        begin
1277
          pc_src = 3'bxxx;
1278
          pc_we = 1'b0;
1279
          mar_we = 1'b0;
1280
          ma_src = 1'bx;
1281
          mmu_fnc = 3'b000;
1282
          mdor_we = 1'b0;
1283
          bus_en = 1'b0;
1284
          bus_wr = 1'bx;
1285
          bus_size = ldst_size;
1286
          mdir_we = 1'b0;
1287
          mdir_sx = opcode[0];
1288
          ir_we = 1'b0;
1289
          reg_src2 = 2'b00;
1290
          reg_di2_src = 3'b011;
1291
          reg_we2 = 1'b1;
1292
          alu_src1 = 1'bx;
1293
          alu_src2 = 3'bxxx;
1294
          alu_fnc = 3'bxxx;
1295
          shift_fnc = 2'bxx;
1296
          muldiv_fnc = 3'bxxx;
1297
          muldiv_start = 1'b0;
1298
          sreg_we = 1'b0;
1299
          psw_we = 1'b0;
1300
          psw_new = 32'hxxxxxxxx;
1301
          tlb_index_we = 1'b0;
1302
          tlb_entry_hi_we = 1'b0;
1303
          tlb_entry_lo_we = 1'b0;
1304 81 hellwig
          mmu_bad_addr_we = 1'b0;
1305 27 hellwig
        end
1306
      5'd14:  // execute ST-type instr (addr xlat)
1307
        begin
1308
          pc_src = 3'bxxx;
1309
          pc_we = 1'b0;
1310
          mar_we = 1'b0;
1311
          ma_src = 1'b1;
1312
          mmu_fnc = (exc_prv_addr | exc_ill_addr) ? 3'b000 : 3'b001;
1313
          mdor_we = 1'b0;
1314
          bus_en = 1'b0;
1315
          bus_wr = 1'bx;
1316
          bus_size = ldst_size;  // enable illegal address detection
1317
          mdir_we = 1'b0;
1318
          mdir_sx = 1'bx;
1319
          ir_we = 1'b0;
1320
          reg_src2 = 2'bxx;
1321
          reg_di2_src = 3'bxxx;
1322
          reg_we2 = 1'b0;
1323
          alu_src1 = 1'bx;
1324
          alu_src2 = 3'bxxx;
1325
          alu_fnc = 3'bxxx;
1326
          shift_fnc = 2'bxx;
1327
          muldiv_fnc = 3'bxxx;
1328
          muldiv_start = 1'b0;
1329
          sreg_we = 1'b0;
1330
          psw_we = 1'b0;
1331
          psw_new = 32'hxxxxxxxx;
1332
          tlb_index_we = 1'b0;
1333
          tlb_entry_hi_we = 1'b0;
1334
          tlb_entry_lo_we = 1'b0;
1335 81 hellwig
          mmu_bad_addr_we = exc_prv_addr | exc_ill_addr;
1336 27 hellwig
        end
1337
      5'd15:  // interrupt
1338
        begin
1339
          pc_src = (psw[27] == 0) ? 3'b010 : 3'b011;
1340
          pc_we = 1'b1;
1341
          mar_we = 1'b0;
1342
          ma_src = 1'bx;
1343
          mmu_fnc = 3'b000;
1344
          mdor_we = 1'b0;
1345
          bus_en = 1'b0;
1346
          bus_wr = 1'bx;
1347
          bus_size = 2'bxx;
1348
          mdir_we = 1'b0;
1349
          mdir_sx = 1'bx;
1350
          ir_we = 1'b0;
1351
          reg_src2 = 2'b11;
1352
          reg_di2_src = 3'b000;
1353
          reg_we2 = 1'b1;
1354
          alu_src1 = 1'b0;
1355
          alu_src2 = 3'bxxx;
1356
          alu_fnc = 3'b010;
1357
          shift_fnc = 2'bxx;
1358
          muldiv_fnc = 3'bxxx;
1359
          muldiv_start = 1'b0;
1360
          sreg_we = 1'b0;
1361
          psw_we = 1'b1;
1362
          psw_new = {
1363 75 hellwig
            psw[31:28],
1364 27 hellwig
            psw[27],
1365
            1'b0, psw[26], psw[25],
1366
            1'b0, psw[23], psw[22],
1367
            1'b0, irq_priority,
1368
            psw[15:0]
1369
          };
1370
          tlb_index_we = 1'b0;
1371
          tlb_entry_hi_we = 1'b0;
1372
          tlb_entry_lo_we = 1'b0;
1373 81 hellwig
          mmu_bad_addr_we = 1'b0;
1374 27 hellwig
        end
1375
      5'd16:  // extra state for RRR shift instr
1376
        begin
1377
          pc_src = 3'bxxx;
1378
          pc_we = 1'b0;
1379
          mar_we = 1'b0;
1380
          ma_src = 1'bx;
1381
          mmu_fnc = 3'b000;
1382
          mdor_we = 1'b0;
1383
          bus_en = 1'b0;
1384
          bus_wr = 1'bx;
1385
          bus_size = 2'bxx;
1386
          mdir_we = 1'b0;
1387
          mdir_sx = 1'bx;
1388
          ir_we = 1'b0;
1389
          reg_src2 = 2'b01;
1390
          reg_di2_src = 3'b001;
1391
          reg_we2 = 1'b1;
1392
          alu_src1 = 1'bx;
1393
          alu_src2 = 3'bxxx;
1394
          alu_fnc = 3'bxxx;
1395
          shift_fnc = 2'bxx;
1396
          muldiv_fnc = 3'bxxx;
1397
          muldiv_start = 1'b0;
1398
          sreg_we = 1'b0;
1399
          psw_we = 1'b0;
1400
          psw_new = 32'hxxxxxxxx;
1401
          tlb_index_we = 1'b0;
1402
          tlb_entry_hi_we = 1'b0;
1403
          tlb_entry_lo_we = 1'b0;
1404 81 hellwig
          mmu_bad_addr_we = 1'b0;
1405 27 hellwig
        end
1406
      5'd17:  // extra state for RRH shift instr
1407
        begin
1408
          pc_src = 3'bxxx;
1409
          pc_we = 1'b0;
1410
          mar_we = 1'b0;
1411
          ma_src = 1'bx;
1412
          mmu_fnc = 3'b000;
1413
          mdor_we = 1'b0;
1414
          bus_en = 1'b0;
1415
          bus_wr = 1'bx;
1416
          bus_size = 2'bxx;
1417
          mdir_we = 1'b0;
1418
          mdir_sx = 1'bx;
1419
          ir_we = 1'b0;
1420
          reg_src2 = 2'b00;
1421
          reg_di2_src = 3'b001;
1422
          reg_we2 = 1'b1;
1423
          alu_src1 = 1'bx;
1424
          alu_src2 = 3'bxxx;
1425
          alu_fnc = 3'bxxx;
1426
          shift_fnc = 2'bxx;
1427
          muldiv_fnc = 3'bxxx;
1428
          muldiv_start = 1'b0;
1429
          sreg_we = 1'b0;
1430
          psw_we = 1'b0;
1431
          psw_new = 32'hxxxxxxxx;
1432
          tlb_index_we = 1'b0;
1433
          tlb_entry_hi_we = 1'b0;
1434
          tlb_entry_lo_we = 1'b0;
1435 81 hellwig
          mmu_bad_addr_we = 1'b0;
1436 27 hellwig
        end
1437
      5'd18:  // extra state for RRR muldiv instr
1438
        begin
1439
          pc_src = 3'bxxx;
1440
          pc_we = 1'b0;
1441
          mar_we = 1'b0;
1442
          ma_src = 1'bx;
1443
          mmu_fnc = 3'b000;
1444
          mdor_we = 1'b0;
1445
          bus_en = 1'b0;
1446
          bus_wr = 1'bx;
1447
          bus_size = 2'bxx;
1448
          mdir_we = 1'b0;
1449
          mdir_sx = 1'bx;
1450
          ir_we = 1'b0;
1451
          reg_src2 = 2'b01;
1452
          reg_di2_src = 3'b010;
1453
          reg_we2 = muldiv_done & ~muldiv_error;
1454
          alu_src1 = 1'bx;
1455
          alu_src2 = 3'bxxx;
1456
          alu_fnc = 3'bxxx;
1457
          shift_fnc = 2'bxx;
1458
          muldiv_fnc = 3'bxxx;
1459
          muldiv_start = 1'b0;
1460
          sreg_we = 1'b0;
1461
          psw_we = 1'b0;
1462
          psw_new = 32'hxxxxxxxx;
1463
          tlb_index_we = 1'b0;
1464
          tlb_entry_hi_we = 1'b0;
1465
          tlb_entry_lo_we = 1'b0;
1466 81 hellwig
          mmu_bad_addr_we = 1'b0;
1467 27 hellwig
        end
1468
      5'd19:  // extra state for RRS muldiv instr
1469
        begin
1470
          pc_src = 3'bxxx;
1471
          pc_we = 1'b0;
1472
          mar_we = 1'b0;
1473
          ma_src = 1'bx;
1474
          mmu_fnc = 3'b000;
1475
          mdor_we = 1'b0;
1476
          bus_en = 1'b0;
1477
          bus_wr = 1'bx;
1478
          bus_size = 2'bxx;
1479
          mdir_we = 1'b0;
1480
          mdir_sx = 1'bx;
1481
          ir_we = 1'b0;
1482
          reg_src2 = 2'b00;
1483
          reg_di2_src = 3'b010;
1484
          reg_we2 = muldiv_done & ~muldiv_error;
1485
          alu_src1 = 1'bx;
1486
          alu_src2 = 3'bxxx;
1487
          alu_fnc = 3'bxxx;
1488
          shift_fnc = 2'bxx;
1489
          muldiv_fnc = 3'bxxx;
1490
          muldiv_start = 1'b0;
1491
          sreg_we = 1'b0;
1492
          psw_we = 1'b0;
1493
          psw_new = 32'hxxxxxxxx;
1494
          tlb_index_we = 1'b0;
1495
          tlb_entry_hi_we = 1'b0;
1496
          tlb_entry_lo_we = 1'b0;
1497 81 hellwig
          mmu_bad_addr_we = 1'b0;
1498 27 hellwig
        end
1499
      5'd20:  // extra state for RRH muldiv instr
1500
        begin
1501
          pc_src = 3'bxxx;
1502
          pc_we = 1'b0;
1503
          mar_we = 1'b0;
1504
          ma_src = 1'bx;
1505
          mmu_fnc = 3'b000;
1506
          mdor_we = 1'b0;
1507
          bus_en = 1'b0;
1508
          bus_wr = 1'bx;
1509
          bus_size = 2'bxx;
1510
          mdir_we = 1'b0;
1511
          mdir_sx = 1'bx;
1512
          ir_we = 1'b0;
1513
          reg_src2 = 2'b00;
1514
          reg_di2_src = 3'b010;
1515
          reg_we2 = muldiv_done & ~muldiv_error;
1516
          alu_src1 = 1'bx;
1517
          alu_src2 = 3'bxxx;
1518
          alu_fnc = 3'bxxx;
1519
          shift_fnc = 2'bxx;
1520
          muldiv_fnc = 3'bxxx;
1521
          muldiv_start = 1'b0;
1522
          sreg_we = 1'b0;
1523
          psw_we = 1'b0;
1524
          psw_new = 32'hxxxxxxxx;
1525
          tlb_index_we = 1'b0;
1526
          tlb_entry_hi_we = 1'b0;
1527
          tlb_entry_lo_we = 1'b0;
1528 81 hellwig
          mmu_bad_addr_we = 1'b0;
1529 27 hellwig
        end
1530
      5'd21:  // execute mvfs instr
1531
        begin
1532
          pc_src = 3'bxxx;
1533
          pc_we = 1'b0;
1534
          mar_we = 1'b0;
1535
          ma_src = 1'bx;
1536
          mmu_fnc = 3'b000;
1537
          mdor_we = 1'b0;
1538
          bus_en = 1'b0;
1539
          bus_wr = 1'bx;
1540
          bus_size = 2'bxx;
1541
          mdir_we = 1'b0;
1542
          mdir_sx = 1'bx;
1543
          ir_we = 1'b0;
1544
          reg_src2 = 2'b00;
1545
          reg_di2_src = 3'b100;
1546
          reg_we2 = 1'b1;
1547
          alu_src1 = 1'bx;
1548
          alu_src2 = 3'bxxx;
1549
          alu_fnc = 3'bxxx;
1550
          shift_fnc = 2'bxx;
1551
          muldiv_fnc = 3'bxxx;
1552
          muldiv_start = 1'b0;
1553
          sreg_we = 1'b0;
1554
          psw_we = 1'b0;
1555
          psw_new = 32'hxxxxxxxx;
1556
          tlb_index_we = 1'b0;
1557
          tlb_entry_hi_we = 1'b0;
1558
          tlb_entry_lo_we = 1'b0;
1559 81 hellwig
          mmu_bad_addr_we = 1'b0;
1560 27 hellwig
        end
1561
      5'd22:  // execute mvts instr
1562
        begin
1563
          pc_src = 3'bxxx;
1564
          pc_we = 1'b0;
1565
          mar_we = 1'b0;
1566
          ma_src = 1'bx;
1567
          mmu_fnc = 3'b000;
1568
          mdor_we = 1'b0;
1569
          bus_en = 1'b0;
1570
          bus_wr = 1'bx;
1571
          bus_size = 2'bxx;
1572
          mdir_we = 1'b0;
1573
          mdir_sx = 1'bx;
1574
          ir_we = 1'b0;
1575
          reg_src2 = 2'bxx;
1576
          reg_di2_src = 3'bxxx;
1577
          reg_we2 = 1'b0;
1578
          alu_src1 = 1'bx;
1579
          alu_src2 = 3'bxxx;
1580
          alu_fnc = 3'bxxx;
1581
          shift_fnc = 2'bxx;
1582
          muldiv_fnc = 3'bxxx;
1583
          muldiv_start = 1'b0;
1584
          sreg_we = 1'b1;
1585
          psw_we = 1'b0;
1586
          psw_new = 32'hxxxxxxxx;
1587
          tlb_index_we = 1'b0;
1588
          tlb_entry_hi_we = 1'b0;
1589
          tlb_entry_lo_we = 1'b0;
1590 81 hellwig
          mmu_bad_addr_we = 1'b0;
1591 27 hellwig
        end
1592
      5'd23:  // execute rfx instr
1593
        begin
1594
          pc_src = 3'b000;
1595
          pc_we = 1'b1;
1596
          mar_we = 1'b0;
1597
          ma_src = 1'bx;
1598
          mmu_fnc = 3'b000;
1599
          mdor_we = 1'b0;
1600
          bus_en = 1'b0;
1601
          bus_wr = 1'bx;
1602
          bus_size = 2'bxx;
1603
          mdir_we = 1'b0;
1604
          mdir_sx = 1'bx;
1605
          ir_we = 1'b0;
1606
          reg_src2 = 2'bxx;
1607
          reg_di2_src = 3'bxxx;
1608
          reg_we2 = 1'b0;
1609
          alu_src1 = 1'bx;
1610
          alu_src2 = 3'b001;
1611
          alu_fnc = 3'b011;
1612
          shift_fnc = 2'bxx;
1613
          muldiv_fnc = 3'bxxx;
1614
          muldiv_start = 1'b0;
1615
          sreg_we = 1'b0;
1616
          psw_we = 1'b1;
1617
          psw_new = {
1618 75 hellwig
            psw[31:28],
1619 27 hellwig
            psw[27],
1620
            psw[25], psw[24], psw[24],
1621
            psw[22], psw[21], psw[21],
1622
            psw[20:16],
1623
            psw[15:0]
1624
          };
1625
          tlb_index_we = 1'b0;
1626
          tlb_entry_hi_we = 1'b0;
1627
          tlb_entry_lo_we = 1'b0;
1628 81 hellwig
          mmu_bad_addr_we = 1'b0;
1629 27 hellwig
        end
1630
      5'd24:  // irq_trigger check for mvts and rfx
1631
        begin
1632
          pc_src = 3'bxxx;
1633
          pc_we = 1'b0;
1634
          mar_we = 1'b0;
1635
          ma_src = 1'bx;
1636
          mmu_fnc = 3'b000;
1637
          mdor_we = 1'b0;
1638
          bus_en = 1'b0;
1639
          bus_wr = 1'bx;
1640
          bus_size = 2'bxx;
1641
          mdir_we = 1'b0;
1642
          mdir_sx = 1'bx;
1643
          ir_we = 1'b0;
1644
          reg_src2 = 2'bxx;
1645
          reg_di2_src = 3'bxxx;
1646
          reg_we2 = 1'b0;
1647
          alu_src1 = 1'bx;
1648
          alu_src2 = 3'bxxx;
1649
          alu_fnc = 3'bxxx;
1650
          shift_fnc = 2'bxx;
1651
          muldiv_fnc = 3'bxxx;
1652
          muldiv_start = 1'b0;
1653
          sreg_we = 1'b0;
1654
          psw_we = 1'b0;
1655
          psw_new = 32'hxxxxxxxx;
1656
          tlb_index_we = 1'b0;
1657
          tlb_entry_hi_we = 1'b0;
1658
          tlb_entry_lo_we = 1'b0;
1659 81 hellwig
          mmu_bad_addr_we = 1'b0;
1660 27 hellwig
        end
1661
      5'd25:  // exception (locus is PC-4)
1662
        begin
1663
          pc_src = (psw[27] != 0) ?
1664
                     ((tlb_umissed != 0) ? 3'b101 : 3'b011) :
1665
                     ((tlb_umissed != 0) ? 3'b100 : 3'b010);
1666
          pc_we = 1'b1;
1667
          mar_we = 1'b0;
1668
          ma_src = 1'bx;
1669
          mmu_fnc = 3'b000;
1670
          mdor_we = 1'b0;
1671
          bus_en = 1'b0;
1672
          bus_wr = 1'bx;
1673
          bus_size = 2'bxx;
1674
          mdir_we = 1'b0;
1675
          mdir_sx = 1'bx;
1676
          ir_we = 1'b0;
1677
          reg_src2 = 2'b11;
1678
          reg_di2_src = 3'b000;
1679
          reg_we2 = 1'b1;
1680
          alu_src1 = 1'b0;
1681
          alu_src2 = 3'b000;
1682
          alu_fnc = 3'b001;
1683
          shift_fnc = 2'bxx;
1684
          muldiv_fnc = 3'bxxx;
1685
          muldiv_start = 1'b0;
1686
          sreg_we = 1'b0;
1687
          psw_we = 1'b1;
1688
          psw_new = {
1689 75 hellwig
            psw[31:28],
1690 27 hellwig
            psw[27],
1691
            1'b0, psw[26], psw[25],
1692
            1'b0, psw[23], psw[22],
1693
            1'b1, exc_priority,
1694
            psw[15:0]
1695
          };
1696
          tlb_index_we = 1'b0;
1697
          tlb_entry_hi_we = 1'b0;
1698
          tlb_entry_lo_we = 1'b0;
1699 81 hellwig
          mmu_bad_addr_we = 1'b0;
1700 27 hellwig
        end
1701
      5'd26:  // exception (locus is PC)
1702
        begin
1703
          pc_src = (psw[27] != 0) ?
1704
                     ((tlb_umissed != 0) ? 3'b101 : 3'b011) :
1705
                     ((tlb_umissed != 0) ? 3'b100 : 3'b010);
1706
          pc_we = 1'b1;
1707
          mar_we = 1'b0;
1708
          ma_src = 1'bx;
1709
          mmu_fnc = 3'b000;
1710
          mdor_we = 1'b0;
1711
          bus_en = 1'b0;
1712
          bus_wr = 1'bx;
1713
          bus_size = 2'bxx;
1714
          mdir_we = 1'b0;
1715
          mdir_sx = 1'bx;
1716
          ir_we = 1'b0;
1717
          reg_src2 = 2'b11;
1718
          reg_di2_src = 3'b000;
1719
          reg_we2 = 1'b1;
1720
          alu_src1 = 1'b0;
1721
          alu_src2 = 3'bxxx;
1722
          alu_fnc = 3'b010;
1723
          shift_fnc = 2'bxx;
1724
          muldiv_fnc = 3'bxxx;
1725
          muldiv_start = 1'b0;
1726
          sreg_we = 1'b0;
1727
          psw_we = 1'b1;
1728
          psw_new = {
1729 75 hellwig
            psw[31:28],
1730 27 hellwig
            psw[27],
1731
            1'b0, psw[26], psw[25],
1732
            1'b0, psw[23], psw[22],
1733
            1'b1, exc_priority,
1734
            psw[15:0]
1735
          };
1736
          tlb_index_we = 1'b0;
1737
          tlb_entry_hi_we = 1'b0;
1738
          tlb_entry_lo_we = 1'b0;
1739 81 hellwig
          mmu_bad_addr_we = 1'b0;
1740 27 hellwig
        end
1741
      5'd27:  // execute TLB instr
1742
        begin
1743
          pc_src = 3'bxxx;
1744
          pc_we = 1'b0;
1745
          mar_we = 1'b0;
1746
          ma_src = 1'bx;
1747
          mmu_fnc = opcode[2:0];
1748
          mdor_we = 1'b0;
1749
          bus_en = 1'b0;
1750
          bus_wr = 1'bx;
1751
          bus_size = 2'bxx;
1752
          mdir_we = 1'b0;
1753
          mdir_sx = 1'bx;
1754
          ir_we = 1'b0;
1755
          reg_src2 = 2'bxx;
1756
          reg_di2_src = 3'bxxx;
1757
          reg_we2 = 1'b0;
1758
          alu_src1 = 1'bx;
1759
          alu_src2 = 3'bxxx;
1760
          alu_fnc = 3'bxxx;
1761
          shift_fnc = 2'bxx;
1762
          muldiv_fnc = 3'bxxx;
1763
          muldiv_start = 1'b0;
1764
          sreg_we = 1'b0;
1765
          psw_we = 1'b0;
1766
          psw_new = 32'hxxxxxxxx;
1767
          tlb_index_we = (opcode[2:0] == 3'b010) ? 1 : 0;
1768
          tlb_entry_hi_we = (opcode[2:0] == 3'b100) ? 1 : 0;
1769
          tlb_entry_lo_we = (opcode[2:0] == 3'b100) ? 1 : 0;
1770 81 hellwig
          mmu_bad_addr_we = 1'b0;
1771 27 hellwig
        end
1772
      5'd28:  // fetch instr (bus cycle)
1773
        begin
1774
          pc_src = 3'bxxx;
1775
          pc_we = 1'b0;
1776
          mar_we = 1'b0;
1777 81 hellwig
          ma_src = 1'b0;        // hold vaddr for latching in bad addr reg
1778 27 hellwig
          mmu_fnc = 3'b000;
1779
          mdor_we = 1'b0;
1780
          bus_en = ~exc_tlb_but_wrtprot;
1781
          bus_wr = 1'b0;
1782
          bus_size = 2'b10;
1783
          mdir_we = 1'b0;
1784
          mdir_sx = 1'bx;
1785
          ir_we = 1'b1;
1786
          reg_src2 = 2'bxx;
1787
          reg_di2_src = 3'bxxx;
1788
          reg_we2 = 1'b0;
1789
          alu_src1 = 1'bx;
1790
          alu_src2 = 3'bxxx;
1791
          alu_fnc = 3'bxxx;
1792
          shift_fnc = 2'bxx;
1793
          muldiv_fnc = 3'bxxx;
1794
          muldiv_start = 1'b0;
1795
          sreg_we = 1'b0;
1796
          psw_we = 1'b0;
1797
          psw_new = 32'hxxxxxxxx;
1798
          tlb_index_we = 1'b0;
1799
          tlb_entry_hi_we = exc_tlb_but_wrtprot;
1800
          tlb_entry_lo_we = 1'b0;
1801 81 hellwig
          mmu_bad_addr_we = exc_tlb_but_wrtprot;
1802 27 hellwig
        end
1803
      5'd29:  // execute LD-type instr (bus cycle)
1804
        begin
1805
          pc_src = 3'bxxx;
1806
          pc_we = 1'b0;
1807
          mar_we = 1'b0;
1808 81 hellwig
          ma_src = 1'b1;        // hold vaddr for latching in bad addr reg
1809 27 hellwig
          mmu_fnc = 3'b000;
1810
          mdor_we = 1'b0;
1811
          bus_en = ~exc_tlb_but_wrtprot;
1812
          bus_wr = 1'b0;
1813
          bus_size = ldst_size;
1814
          mdir_we = 1'b1;
1815
          mdir_sx = 1'bx;
1816
          ir_we = 1'b0;
1817
          reg_src2 = 2'bxx;
1818
          reg_di2_src = 3'bxxx;
1819
          reg_we2 = 1'b0;
1820
          alu_src1 = 1'bx;
1821
          alu_src2 = 3'bxxx;
1822
          alu_fnc = 3'bxxx;
1823
          shift_fnc = 2'bxx;
1824
          muldiv_fnc = 3'bxxx;
1825
          muldiv_start = 1'b0;
1826
          sreg_we = 1'b0;
1827
          psw_we = 1'b0;
1828
          psw_new = 32'hxxxxxxxx;
1829
          tlb_index_we = 1'b0;
1830
          tlb_entry_hi_we = exc_tlb_but_wrtprot;
1831
          tlb_entry_lo_we = 1'b0;
1832 81 hellwig
          mmu_bad_addr_we = exc_tlb_but_wrtprot;
1833 27 hellwig
        end
1834
      5'd30:  // execute ST-type instr (bus cycle)
1835
        begin
1836
          pc_src = 3'bxxx;
1837
          pc_we = 1'b0;
1838
          mar_we = 1'b0;
1839 81 hellwig
          ma_src = 1'b1;        // hold vaddr for latching in bad addr reg
1840 27 hellwig
          mmu_fnc = 3'b000;
1841
          mdor_we = 1'b0;
1842
          bus_en = ~exc_tlb_any;
1843
          bus_wr = 1'b1;
1844
          bus_size = ldst_size;
1845
          mdir_we = 1'b0;
1846
          mdir_sx = 1'bx;
1847
          ir_we = 1'b0;
1848
          reg_src2 = 2'bxx;
1849
          reg_di2_src = 3'bxxx;
1850
          reg_we2 = 1'b0;
1851
          alu_src1 = 1'bx;
1852
          alu_src2 = 3'bxxx;
1853
          alu_fnc = 3'bxxx;
1854
          shift_fnc = 2'bxx;
1855
          muldiv_fnc = 3'bxxx;
1856
          muldiv_start = 1'b0;
1857
          sreg_we = 1'b0;
1858
          psw_we = 1'b0;
1859
          psw_new = 32'hxxxxxxxx;
1860
          tlb_index_we = 1'b0;
1861
          tlb_entry_hi_we = exc_tlb_any;
1862
          tlb_entry_lo_we = 1'b0;
1863 81 hellwig
          mmu_bad_addr_we = exc_tlb_any;
1864 27 hellwig
        end
1865
      default:  // all other states: unused
1866
        begin
1867
          pc_src = 3'bxxx;
1868
          pc_we = 1'bx;
1869
          mar_we = 1'bx;
1870
          ma_src = 1'bx;
1871
          mmu_fnc = 3'bxxx;
1872
          mdor_we = 1'bx;
1873
          bus_en = 1'bx;
1874
          bus_wr = 1'bx;
1875
          bus_size = 2'bxx;
1876
          mdir_we = 1'bx;
1877
          mdir_sx = 1'bx;
1878
          ir_we = 1'bx;
1879
          reg_src2 = 2'bxx;
1880
          reg_di2_src = 3'bxxx;
1881
          reg_we2 = 1'bx;
1882
          alu_src1 = 1'bx;
1883
          alu_src2 = 3'bxxx;
1884
          alu_fnc = 3'bxxx;
1885
          shift_fnc = 2'bxx;
1886
          muldiv_fnc = 3'bxxx;
1887
          muldiv_start = 1'bx;
1888
          sreg_we = 1'bx;
1889
          psw_we = 1'bx;
1890
          psw_new = 32'hxxxxxxxx;
1891
          tlb_index_we = 1'bx;
1892
          tlb_entry_hi_we = 1'bx;
1893
          tlb_entry_lo_we = 1'bx;
1894 81 hellwig
          mmu_bad_addr_we = 1'bx;
1895 27 hellwig
        end
1896
    endcase
1897
  end
1898
 
1899
  // branch logic
1900
  always @(*) begin
1901
    casex ( { opcode[3:0], alu_equ, alu_ult, alu_slt } )
1902
      // eq
1903
      7'b00000xx:  branch = 0;
1904
      7'b00001xx:  branch = 1;
1905
      // ne
1906
      7'b00010xx:  branch = 1;
1907
      7'b00011xx:  branch = 0;
1908
      // le
1909
      7'b00100x0:  branch = 0;
1910
      7'b00101xx:  branch = 1;
1911
      7'b0010xx1:  branch = 1;
1912
      // leu
1913
      7'b001100x:  branch = 0;
1914
      7'b00111xx:  branch = 1;
1915
      7'b0011x1x:  branch = 1;
1916
      // lt
1917
      7'b0100xx0:  branch = 0;
1918
      7'b0100xx1:  branch = 1;
1919
      // ltu
1920
      7'b0101x0x:  branch = 0;
1921
      7'b0101x1x:  branch = 1;
1922
      // ge
1923
      7'b0110xx0:  branch = 1;
1924
      7'b0110xx1:  branch = 0;
1925
      // geu
1926
      7'b0111x0x:  branch = 1;
1927
      7'b0111x1x:  branch = 0;
1928
      // gt
1929
      7'b10000x0:  branch = 1;
1930
      7'b10001xx:  branch = 0;
1931
      7'b1000xx1:  branch = 0;
1932
      // gtu
1933
      7'b100100x:  branch = 1;
1934
      7'b10011xx:  branch = 0;
1935
      7'b1001x1x:  branch = 0;
1936
      // other
1937
      default:     branch = 1'bx;
1938
    endcase
1939
  end
1940
 
1941
  // interrupts
1942
  assign irq_pending = irq[15:0] & psw[15:0];
1943
  assign irq_trigger = (| irq_pending) & psw[23];
1944
  always @(*) begin
1945
    if ((| irq_pending[15:8]) != 0) begin
1946
      if ((| irq_pending[15:12]) != 0) begin
1947
        if ((| irq_pending[15:14]) != 0) begin
1948
          if (irq_pending[15] != 0) begin
1949
            irq_priority = 4'd15;
1950
          end else begin
1951
            irq_priority = 4'd14;
1952
          end
1953
        end else begin
1954
          if (irq_pending[13] != 0) begin
1955
            irq_priority = 4'd13;
1956
          end else begin
1957
            irq_priority = 4'd12;
1958
          end
1959
        end
1960
      end else begin
1961
        if ((| irq_pending[11:10]) != 0) begin
1962
          if (irq_pending[11] != 0) begin
1963
            irq_priority = 4'd11;
1964
          end else begin
1965
            irq_priority = 4'd10;
1966
          end
1967
        end else begin
1968
          if (irq_pending[9] != 0) begin
1969
            irq_priority = 4'd9;
1970
          end else begin
1971
            irq_priority = 4'd8;
1972
          end
1973
        end
1974
      end
1975
    end else begin
1976
      if ((| irq_pending[7:4]) != 0) begin
1977
        if ((| irq_pending[7:6]) != 0) begin
1978
          if (irq_pending[7] != 0) begin
1979
            irq_priority = 4'd7;
1980
          end else begin
1981
            irq_priority = 4'd6;
1982
          end
1983
        end else begin
1984
          if (irq_pending[5] != 0) begin
1985
            irq_priority = 4'd5;
1986
          end else begin
1987
            irq_priority = 4'd4;
1988
          end
1989
        end
1990
      end else begin
1991
        if ((| irq_pending[3:2]) != 0) begin
1992
          if (irq_pending[3] != 0) begin
1993
            irq_priority = 4'd3;
1994
          end else begin
1995
            irq_priority = 4'd2;
1996
          end
1997
        end else begin
1998
          if (irq_pending[1] != 0) begin
1999
            irq_priority = 4'd1;
2000
          end else begin
2001
            irq_priority = 4'd0;
2002
          end
2003
        end
2004
      end
2005
    end
2006
  end
2007
 
2008
  // exceptions
2009
  assign exc_prv_addr = psw[26] & va_31;
2010
  assign exc_ill_addr = (bus_size[0] & va_0) |
2011
                        (bus_size[1] & va_0) |
2012
                        (bus_size[1] & va_1);
2013
  assign exc_tlb_but_wrtprot = tlb_kmissed | tlb_umissed | tlb_invalid;
2014
  assign exc_tlb_any = exc_tlb_but_wrtprot | tlb_wrtprot;
2015
 
2016
endmodule
2017
 
2018
 
2019
//--------------------------------------------------------------
2020
// pc -- the program counter
2021
//--------------------------------------------------------------
2022
 
2023
 
2024
module pc(clk, pc_we, pc_next, pc);
2025
    input clk;
2026
    input pc_we;
2027
    input [31:0] pc_next;
2028
    output reg [31:0] pc;
2029
 
2030
  always @(posedge clk) begin
2031
    if (pc_we == 1) begin
2032
      pc <= pc_next;
2033
    end
2034
  end
2035
 
2036
endmodule
2037
 
2038
 
2039
//--------------------------------------------------------------
2040
// mar -- the memory address register
2041
//--------------------------------------------------------------
2042
 
2043
 
2044
module mar(clk, mar_we, mar_next, mar);
2045
    input clk;
2046
    input mar_we;
2047
    input [31:0] mar_next;
2048
    output reg [31:0] mar;
2049
 
2050
  always @(posedge clk) begin
2051
    if (mar_we == 1) begin
2052
      mar <= mar_next;
2053
    end
2054
  end
2055
 
2056
endmodule
2057
 
2058
 
2059
//--------------------------------------------------------------
2060
// mdor -- the memory data out register
2061
//--------------------------------------------------------------
2062
 
2063
 
2064
module mdor(clk, mdor_we, mdor_next, mdor);
2065
    input clk;
2066
    input mdor_we;
2067
    input [31:0] mdor_next;
2068
    output reg [31:0] mdor;
2069
 
2070
  always @(posedge clk) begin
2071
    if (mdor_we == 1) begin
2072
      mdor <= mdor_next;
2073
    end
2074
  end
2075
 
2076
endmodule
2077
 
2078
 
2079
//--------------------------------------------------------------
2080
// mdir -- the memory data in register
2081
//--------------------------------------------------------------
2082
 
2083
 
2084
module mdir(clk, mdir_we, mdir_next, size, sx, mdir);
2085
    input clk;
2086
    input mdir_we;
2087
    input [31:0] mdir_next;
2088
    input [1:0] size;
2089
    input sx;
2090
    output reg [31:0] mdir;
2091
 
2092
  reg [31:0] data;
2093
 
2094
  always @(posedge clk) begin
2095
    if (mdir_we == 1) begin
2096
      data <= mdir_next;
2097
    end
2098
  end
2099
 
2100
  always @(*) begin
2101
    case ({ size, sx })
2102
      3'b000:
2103
        begin
2104
          mdir[31:0] = { 24'h000000, data[7:0] };
2105
        end
2106
      3'b001:
2107
        begin
2108
          if (data[7] == 1) begin
2109
            mdir[31:0] = { 24'hFFFFFF, data[7:0] };
2110
          end else begin
2111
            mdir[31:0] = { 24'h000000, data[7:0] };
2112
          end
2113
        end
2114
      3'b010:
2115
        begin
2116
          mdir[31:0] = { 16'h0000, data[15:0] };
2117
        end
2118
      3'b011:
2119
        begin
2120
          if (data[15] == 1) begin
2121
            mdir[31:0] = { 16'hFFFF, data[15:0] };
2122
          end else begin
2123
            mdir[31:0] = { 16'h0000, data[15:0] };
2124
          end
2125
        end
2126
      default:
2127
        begin
2128
          mdir[31:0] = data[31:0];
2129
        end
2130
    endcase
2131
  end
2132
 
2133
endmodule
2134
 
2135
 
2136
//--------------------------------------------------------------
2137
// ir -- the instruction register and decoder
2138
//--------------------------------------------------------------
2139
 
2140
 
2141
module ir(clk,
2142
          ir_we, instr,
2143
          opcode, reg1, reg2, reg3,
2144
          sx16, zx16, hi16, sx16s2, sx26s2);
2145
    input clk;
2146
    input ir_we;
2147
    input [31:0] instr;
2148
    output [5:0] opcode;
2149
    output [4:0] reg1;
2150
    output [4:0] reg2;
2151
    output [4:0] reg3;
2152
    output [31:0] sx16;
2153
    output [31:0] zx16;
2154
    output [31:0] hi16;
2155
    output [31:0] sx16s2;
2156
    output [31:0] sx26s2;
2157
 
2158
  reg [31:0] ir;
2159
  wire [15:0] copy_sign_16;      // 16-bit copy of a 16-bit immediate's sign
2160
  wire [3:0] copy_sign_26;       // 4-bit copy of a 26-bit immediate's sign
2161
 
2162
  always @(posedge clk) begin
2163
    if (ir_we) begin
2164
      ir <= instr;
2165
    end
2166
  end
2167
 
2168
  assign opcode[5:0] = ir[31:26];
2169
  assign reg1[4:0] = ir[25:21];
2170
  assign reg2[4:0] = ir[20:16];
2171
  assign reg3[4:0] = ir[15:11];
2172
  assign copy_sign_16[15:0] = (ir[15] == 1) ? 16'hFFFF : 16'h0000;
2173
  assign copy_sign_26[3:0] = (ir[25] == 1) ? 4'hF : 4'h0;
2174
  assign sx16[31:0] = { copy_sign_16[15:0], ir[15:0] };
2175
  assign zx16[31:0] = { 16'h0000, ir[15:0] };
2176
  assign hi16[31:0] = { ir[15:0], 16'h0000 };
2177
  assign sx16s2[31:0] = { copy_sign_16[13:0], ir[15:0], 2'b00 };
2178
  assign sx26s2[31:0] = { copy_sign_26[3:0], ir[25:0], 2'b00 };
2179
 
2180
endmodule
2181
 
2182
 
2183
//--------------------------------------------------------------
2184
// regs -- the register file
2185
//--------------------------------------------------------------
2186
 
2187
 
2188
module regs(clk,
2189
            rn1, do1,
2190
            rn2, do2, we2, di2);
2191
    input clk;
2192
    input [4:0] rn1;
2193
    output reg [31:0] do1;
2194
    input [4:0] rn2;
2195
    output reg [31:0] do2;
2196
    input we2;
2197
    input [31:0] di2;
2198
 
2199
  reg [31:0] r[0:31];
2200
 
2201
  always @(posedge clk) begin
2202
    do1 <= r[rn1];
2203
    if (we2 == 0) begin
2204
      do2 <= r[rn2];
2205
    end else begin
2206
      do2 <= di2;
2207
      r[rn2] <= di2;
2208
    end
2209
  end
2210
 
2211
endmodule
2212
 
2213
 
2214
//--------------------------------------------------------------
2215
// alu -- the arithmetic/logic unit
2216
//--------------------------------------------------------------
2217
 
2218
 
2219
module alu(a, b, fnc,
2220
           res, equ, ult, slt);
2221
    input [31:0] a;
2222
    input [31:0] b;
2223
    input [2:0] fnc;
2224
    output [31:0] res;
2225
    output equ;
2226
    output ult;
2227
    output slt;
2228
 
2229
  wire [32:0] a1;
2230
  wire [32:0] b1;
2231
  reg [32:0] res1;
2232
 
2233
  assign a1 = { 1'b0, a };
2234
  assign b1 = { 1'b0, b };
2235
 
2236
  always @(*) begin
2237
    case (fnc)
2238
      3'b000:  res1 = a1 + b1;
2239
      3'b001:  res1 = a1 - b1;
2240
      3'b010:  res1 = a1;
2241
      3'b011:  res1 = b1;
2242
      3'b100:  res1 = a1 & b1;
2243
      3'b101:  res1 = a1 | b1;
2244
      3'b110:  res1 = a1 ^ b1;
2245
      3'b111:  res1 = a1 ~^ b1;
2246
      default: res1 = 33'hxxxxxxxx;
2247
    endcase
2248
  end
2249
 
2250
  assign res = res1[31:0];
2251
  assign equ = ~| res1[31:0];
2252
  assign ult = res1[32];
2253
  assign slt = res1[32] ^ a[31] ^ b[31];
2254
 
2255
endmodule
2256
 
2257
 
2258
//--------------------------------------------------------------
2259
// shift -- the shift unit
2260
//--------------------------------------------------------------
2261
 
2262
 
2263
module shift(clk, data_in, shamt, fnc, data_out);
2264
    input clk;
2265
    input [31:0] data_in;
2266
    input [4:0] shamt;
2267
    input [1:0] fnc;
2268
    output reg [31:0] data_out;
2269
 
2270
  always @(posedge clk) begin
2271
    if (fnc == 2'b00) begin
2272
      // sll
2273
      data_out <= data_in << shamt;
2274
    end else
2275
    if (fnc == 2'b01) begin
2276
      // slr
2277
      data_out <= data_in >> shamt;
2278
    end else
2279
    if (fnc == 2'b10) begin
2280
      // sar
2281
      if (data_in[31] == 1) begin
2282
        data_out <= ~(32'hFFFFFFFF >> shamt) |
2283
                    (data_in >> shamt);
2284
      end else begin
2285
        data_out <= data_in >> shamt;
2286
      end
2287
    end else begin
2288
      data_out <= 32'hxxxxxxxx;
2289
    end
2290
  end
2291
 
2292
endmodule
2293
 
2294
 
2295
//--------------------------------------------------------------
2296
// muldiv -- the multiplier/divide unit
2297
//--------------------------------------------------------------
2298
 
2299
 
2300
module muldiv(clk, a, b, fnc, start, done, error, res);
2301
    input clk;
2302
    input [31:0] a;
2303
    input [31:0] b;
2304
    input [2:0] fnc;
2305
    input start;
2306
    output reg done;
2307
    output reg error;
2308
    output reg [31:0] res;
2309
 
2310
  // fnc = 000    op = undefined
2311
  //       001         undefined
2312
  //       010         mul
2313
  //       011         mulu
2314
  //       100         div
2315
  //       101         divu
2316
  //       110         rem
2317
  //       111         remu
2318
 
2319
  reg div;
2320
  reg rem;
2321
  reg [5:0] count;
2322
  reg a_neg;
2323
  reg b_neg;
2324
  reg [31:0] b_abs;
2325
  reg [64:0] q;
2326
  wire [64:1] s;
2327
  wire [64:0] d;
2328
 
2329
  assign s[64:32] = q[64:32] + { 1'b0, b_abs };
2330
  assign s[31: 1] = q[31: 1];
2331
  assign d[64:32] = q[64:32] - { 1'b0, b_abs };
2332
  assign d[31: 0] = q[31: 0];
2333
 
2334
  always @(posedge clk) begin
2335
    if (start == 1) begin
2336
      if (fnc[2] == 1 && (| b[31:0]) == 0) begin
2337
        // division by zero
2338
        done <= 1;
2339
        error <= 1;
2340
      end else begin
2341
        // operands are ok
2342
        done <= 0;
2343
        error <= 0;
2344
      end
2345
      div <= fnc[2];
2346
      rem <= fnc[1];
2347
      count <= 6'd0;
2348
      if (fnc[0] == 0 && a[31] == 1) begin
2349
        // negate first operand
2350
        a_neg <= 1;
2351
        if (fnc[2] == 0) begin
2352
          // initialize q for multiplication
2353
          q[64:32] <= 33'b0;
2354
          q[31: 0] <= ~a + 1;
2355
        end else begin
2356
          // initialize q for division and remainder
2357
          q[64:33] <= 32'b0;
2358
          q[32: 1] <= ~a + 1;
2359
          q[ 0: 0] <= 1'b0;
2360
        end
2361
      end else begin
2362
        // use first operand as is
2363
        a_neg <= 0;
2364
        if (fnc[2] == 0) begin
2365
          // initialize q for multiplication
2366
          q[64:32] <= 33'b0;
2367
          q[31: 0] <= a;
2368
        end else begin
2369
          // initialize q for division and remainder
2370
          q[64:33] <= 32'b0;
2371
          q[32: 1] <= a;
2372
          q[ 0: 0] <= 1'b0;
2373
        end
2374
      end
2375
      if (fnc[0] == 0 && b[31] == 1) begin
2376
        // negate second operand
2377
        b_neg <= 1;
2378
        b_abs <= ~b + 1;
2379
      end else begin
2380
        // use second operand as is
2381
        b_neg <= 0;
2382
        b_abs <= b;
2383
      end
2384
    end else begin
2385
      if (done == 0) begin
2386
        // algorithm not yet finished
2387
        if (div == 0) begin
2388
          //
2389
          // multiplication
2390
          //
2391
          if (count == 6'd32) begin
2392
            // last step
2393
            done <= 1;
2394
            if (a_neg == b_neg) begin
2395
              res <= q[31:0];
2396
            end else begin
2397
              res <= ~q[31:0] + 1;
2398
            end
2399
          end else begin
2400
            // all other steps
2401
            count <= count + 1;
2402
            if (q[0] == 1) begin
2403
              q <= { 1'b0, s[64:1] };
2404
            end else begin
2405
              q <= { 1'b0, q[64:1] };
2406
            end
2407
          end
2408
        end else begin
2409
          //
2410
          // division and remainder
2411
          //
2412
          if (count == 6'd32) begin
2413
            // last step
2414
            done <= 1;
2415
            if (rem == 0) begin
2416
              // result <= quotient
2417
              if (a_neg == b_neg) begin
2418
                res <= q[31:0];
2419
              end else begin
2420
                res <= ~q[31:0] + 1;
2421
              end
2422
            end else begin
2423
              // result <= remainder
2424
              if (a_neg == 0) begin
2425
                res <= q[64:33];
2426
              end else begin
2427
                res <= ~q[64:33] + 1;
2428
              end
2429
            end
2430
          end else begin
2431
            // all other steps
2432
            count <= count + 1;
2433
            if (d[64] == 0) begin
2434
              q <= { d[63:0], 1'b1 };
2435
            end else begin
2436
              q <= { q[63:0], 1'b0 };
2437
            end
2438
          end
2439
        end
2440
      end
2441
    end
2442
  end
2443
 
2444
endmodule
2445
 
2446
 
2447
//--------------------------------------------------------------
2448
// sregs -- the special registers
2449
//--------------------------------------------------------------
2450
 
2451
 
2452
module sregs(clk, reset,
2453 120 hellwig
             rn, we, din, dout,
2454 27 hellwig
             psw, psw_we, psw_new,
2455
             tlb_index, tlb_index_we, tlb_index_new,
2456
             tlb_entry_hi, tlb_entry_hi_we, tlb_entry_hi_new,
2457 81 hellwig
             tlb_entry_lo, tlb_entry_lo_we, tlb_entry_lo_new,
2458
             mmu_bad_addr, mmu_bad_addr_we, mmu_bad_addr_new);
2459 27 hellwig
    input clk;
2460
    input reset;
2461 81 hellwig
    input [2:0] rn;
2462 27 hellwig
    input we;
2463 120 hellwig
    input [31:0] din;
2464
    output [31:0] dout;
2465 27 hellwig
    output [31:0] psw;
2466
    input psw_we;
2467
    input [31:0] psw_new;
2468
    output [31:0] tlb_index;
2469
    input tlb_index_we;
2470
    input [31:0] tlb_index_new;
2471
    output [31:0] tlb_entry_hi;
2472
    input tlb_entry_hi_we;
2473
    input [31:0] tlb_entry_hi_new;
2474
    output [31:0] tlb_entry_lo;
2475
    input tlb_entry_lo_we;
2476
    input [31:0] tlb_entry_lo_new;
2477 81 hellwig
    output [31:0] mmu_bad_addr;
2478
    input mmu_bad_addr_we;
2479
    input [31:0] mmu_bad_addr_new;
2480 27 hellwig
 
2481 81 hellwig
  // rn = 000   register = PSW
2482
  //      001              TLB index
2483
  //      010              TLB entry high
2484
  //      011              TLB entry low
2485
  //      100              MMU bad address
2486
  //      101              - not used -
2487
  //      110              - not used -
2488
  //      111              - not used -
2489 27 hellwig
 
2490 81 hellwig
  reg [31:0] sr[0:7];
2491 27 hellwig
 
2492 120 hellwig
  assign dout = sr[rn];
2493 27 hellwig
  assign psw = sr[0];
2494
  assign tlb_index = sr[1];
2495
  assign tlb_entry_hi = sr[2];
2496
  assign tlb_entry_lo = sr[3];
2497 81 hellwig
  assign mmu_bad_addr = sr[4];
2498 27 hellwig
 
2499
  always @(posedge clk) begin
2500
    if (reset == 1) begin
2501
      sr[0] <= 32'h00000000;
2502
    end else begin
2503
      if (we == 1) begin
2504 120 hellwig
        sr[rn] <= din;
2505 27 hellwig
      end else begin
2506
        if (psw_we) begin
2507
          sr[0] <= psw_new;
2508
        end
2509
        if (tlb_index_we) begin
2510
          sr[1] <= tlb_index_new;
2511
        end
2512
        if (tlb_entry_hi_we) begin
2513
          sr[2] <= tlb_entry_hi_new;
2514
        end
2515
        if (tlb_entry_lo_we) begin
2516
          sr[3] <= tlb_entry_lo_new;
2517
        end
2518 81 hellwig
        if (mmu_bad_addr_we) begin
2519
          sr[4] <= mmu_bad_addr_new;
2520
        end
2521 27 hellwig
      end
2522
    end
2523
  end
2524
 
2525
endmodule
2526
 
2527
 
2528
//--------------------------------------------------------------
2529
// mmu -- the memory management unit
2530
//--------------------------------------------------------------
2531
 
2532
 
2533
module mmu(clk, reset, fnc, virt, phys,
2534
           tlb_index, tlb_index_new,
2535
           tlb_entry_hi, tlb_entry_hi_new,
2536
           tlb_entry_lo, tlb_entry_lo_new,
2537
           tlb_kmissed, tlb_umissed,
2538
           tlb_invalid, tlb_wrtprot);
2539
    input clk;
2540
    input reset;
2541
    input [2:0] fnc;
2542
    input [31:0] virt;
2543
    output [31:0] phys;
2544
    input [31:0] tlb_index;
2545
    output [31:0] tlb_index_new;
2546
    input [31:0] tlb_entry_hi;
2547
    output [31:0] tlb_entry_hi_new;
2548
    input [31:0] tlb_entry_lo;
2549
    output [31:0] tlb_entry_lo_new;
2550
    output tlb_kmissed;
2551
    output tlb_umissed;
2552
    output tlb_invalid;
2553
    output tlb_wrtprot;
2554
 
2555
  // fnc = 000    no operation, hold output
2556
  //       001    map virt to phys address
2557
  //       010    tbs
2558
  //       011    tbwr
2559
  //       100    tbri
2560
  //       101    tbwi
2561
  //       110    undefined
2562
  //       111    undefined
2563
 
2564
  wire map;
2565
  wire tbs;
2566
  wire tbwr;
2567
  wire tbri;
2568
  wire tbwi;
2569
  reg [19:0] page;
2570
  reg [11:0] offset;
2571
  wire [19:0] tlb_page;
2572
  wire tlb_miss;
2573
  wire [4:0] tlb_found;
2574
  wire tlb_enable;
2575
  wire [19:0] tlb_frame;
2576
  wire tlb_wbit;
2577
  wire tlb_vbit;
2578
  wire [4:0] rw_index;
2579
  wire [19:0] r_page;
2580
  wire [19:0] r_frame;
2581
  wire w_enable;
2582
  wire [19:0] w_page;
2583
  wire [19:0] w_frame;
2584
  wire direct;
2585
  wire [17:0] frame;
2586
  reg [4:0] random_index;
2587
  reg tlb_miss_delayed;
2588
 
2589
  // decode function
2590
  assign map = (fnc == 3'b001) ? 1 : 0;
2591
  assign tbs = (fnc == 3'b010) ? 1 : 0;
2592
  assign tbwr = (fnc == 3'b011) ? 1 : 0;
2593
  assign tbri = (fnc == 3'b100) ? 1 : 0;
2594
  assign tbwi = (fnc == 3'b101) ? 1 : 0;
2595
 
2596
  // latch virtual address
2597
  always @(posedge clk) begin
2598
    if (map == 1) begin
2599
      page <= virt[31:12];
2600
      offset <= virt[11:0];
2601
    end
2602
  end
2603
 
2604
  // create tlb instance
2605
  assign tlb_page = (tbs == 1) ? tlb_entry_hi[31:12] : virt[31:12];
2606
  assign tlb_enable = map;
2607
  assign tlb_wbit = tlb_frame[1];
2608
  assign tlb_vbit = tlb_frame[0];
2609
  assign rw_index = (tbwr == 1) ? random_index : tlb_index[4:0];
2610 75 hellwig
  assign tlb_index_new = { tlb_miss | tlb_index[31],
2611
                           tlb_index[30:5], tlb_found };
2612
  assign tlb_entry_hi_new = { ((tbri == 1) ? r_page : page),
2613
                              tlb_entry_hi[11:0] };
2614
  assign tlb_entry_lo_new = { tlb_entry_lo[31:30], r_frame[19:2],
2615
                              tlb_entry_lo[11:2], r_frame[1:0] };
2616 27 hellwig
  assign w_enable = tbwr | tbwi;
2617
  assign w_page = tlb_entry_hi[31:12];
2618
  assign w_frame = { tlb_entry_lo[29:12], tlb_entry_lo[1:0] };
2619
  tlb tlb1(tlb_page, tlb_miss, tlb_found,
2620
           clk, tlb_enable, tlb_frame,
2621
           rw_index, r_page, r_frame,
2622
           w_enable, w_page, w_frame);
2623
 
2624
  // construct physical address
2625
  assign direct = (page[19:18] == 2'b11) ? 1 : 0;
2626
  assign frame = (direct == 1) ? page[17:0] : tlb_frame[19:2];
2627
  assign phys = { 2'b00, frame, offset };
2628
 
2629
  // generate "random" index
2630
  always @(posedge clk) begin
2631
    if (reset == 1) begin
2632
      // the index register is counting down
2633
      // so we must start at topmost index
2634
      random_index <= 5'd31;
2635
    end else begin
2636
      // decrement index register "randomly"
2637
      // (whenever there is a mapping operation)
2638
      // skip "fixed" entries (0..3)
2639
      if (map == 1) begin
2640
        if (random_index == 5'd4) begin
2641
          random_index <= 5'd31;
2642
        end else begin
2643
          random_index <= random_index - 1;
2644
        end
2645
      end
2646
    end
2647
  end
2648
 
2649
  // generate TLB exceptions
2650
  always @(posedge clk) begin
2651
    if (map == 1) begin
2652
      tlb_miss_delayed <= tlb_miss;
2653
    end
2654
  end
2655
  assign tlb_kmissed = tlb_miss_delayed & ~direct & page[19];
2656
  assign tlb_umissed = tlb_miss_delayed & ~direct & ~page[19];
2657
  assign tlb_invalid = ~tlb_vbit & ~direct;
2658
  assign tlb_wrtprot = ~tlb_wbit & ~direct;
2659
 
2660
endmodule
2661
 
2662
 
2663
//--------------------------------------------------------------
2664
// tlb -- the translation lookaside buffer
2665
//--------------------------------------------------------------
2666
 
2667
 
2668
module tlb(page_in, miss, found,
2669
           clk, enable, frame_out,
2670
           rw_index, r_page, r_frame,
2671
           w_enable, w_page, w_frame);
2672
    input [19:0] page_in;
2673
    output miss;
2674 75 hellwig
    output [4:0] found;
2675 27 hellwig
    input clk;
2676
    input enable;
2677
    output reg [19:0] frame_out;
2678
    input [4:0] rw_index;
2679
    output reg [19:0] r_page;
2680
    output reg [19:0] r_frame;
2681
    input w_enable;
2682
    input [19:0] w_page;
2683
    input [19:0] w_frame;
2684
 
2685
  reg [19:0] page[0:31];
2686
  reg [19:0] frame[0:31];
2687
 
2688
  wire [19:0] p00, p01, p02, p03;
2689
  wire [19:0] p04, p05, p06, p07;
2690
  wire [19:0] p08, p09, p10, p11;
2691
  wire [19:0] p12, p13, p14, p15;
2692
  wire [19:0] p16, p17, p18, p19;
2693
  wire [19:0] p20, p21, p22, p23;
2694
  wire [19:0] p24, p25, p26, p27;
2695
  wire [19:0] p28, p29, p30, p31;
2696
  wire [31:0] match;
2697
 
2698
  assign p00 = page[ 0];
2699
  assign p01 = page[ 1];
2700
  assign p02 = page[ 2];
2701
  assign p03 = page[ 3];
2702
  assign p04 = page[ 4];
2703
  assign p05 = page[ 5];
2704
  assign p06 = page[ 6];
2705
  assign p07 = page[ 7];
2706
  assign p08 = page[ 8];
2707
  assign p09 = page[ 9];
2708
  assign p10 = page[10];
2709
  assign p11 = page[11];
2710
  assign p12 = page[12];
2711
  assign p13 = page[13];
2712
  assign p14 = page[14];
2713
  assign p15 = page[15];
2714
  assign p16 = page[16];
2715
  assign p17 = page[17];
2716
  assign p18 = page[18];
2717
  assign p19 = page[19];
2718
  assign p20 = page[20];
2719
  assign p21 = page[21];
2720
  assign p22 = page[22];
2721
  assign p23 = page[23];
2722
  assign p24 = page[24];
2723
  assign p25 = page[25];
2724
  assign p26 = page[26];
2725
  assign p27 = page[27];
2726
  assign p28 = page[28];
2727
  assign p29 = page[29];
2728
  assign p30 = page[30];
2729
  assign p31 = page[31];
2730
 
2731
  assign match[ 0] = (page_in == p00) ? 1 : 0;
2732
  assign match[ 1] = (page_in == p01) ? 1 : 0;
2733
  assign match[ 2] = (page_in == p02) ? 1 : 0;
2734
  assign match[ 3] = (page_in == p03) ? 1 : 0;
2735
  assign match[ 4] = (page_in == p04) ? 1 : 0;
2736
  assign match[ 5] = (page_in == p05) ? 1 : 0;
2737
  assign match[ 6] = (page_in == p06) ? 1 : 0;
2738
  assign match[ 7] = (page_in == p07) ? 1 : 0;
2739
  assign match[ 8] = (page_in == p08) ? 1 : 0;
2740
  assign match[ 9] = (page_in == p09) ? 1 : 0;
2741
  assign match[10] = (page_in == p10) ? 1 : 0;
2742
  assign match[11] = (page_in == p11) ? 1 : 0;
2743
  assign match[12] = (page_in == p12) ? 1 : 0;
2744
  assign match[13] = (page_in == p13) ? 1 : 0;
2745
  assign match[14] = (page_in == p14) ? 1 : 0;
2746
  assign match[15] = (page_in == p15) ? 1 : 0;
2747
  assign match[16] = (page_in == p16) ? 1 : 0;
2748
  assign match[17] = (page_in == p17) ? 1 : 0;
2749
  assign match[18] = (page_in == p18) ? 1 : 0;
2750
  assign match[19] = (page_in == p19) ? 1 : 0;
2751
  assign match[20] = (page_in == p20) ? 1 : 0;
2752
  assign match[21] = (page_in == p21) ? 1 : 0;
2753
  assign match[22] = (page_in == p22) ? 1 : 0;
2754
  assign match[23] = (page_in == p23) ? 1 : 0;
2755
  assign match[24] = (page_in == p24) ? 1 : 0;
2756
  assign match[25] = (page_in == p25) ? 1 : 0;
2757
  assign match[26] = (page_in == p26) ? 1 : 0;
2758
  assign match[27] = (page_in == p27) ? 1 : 0;
2759
  assign match[28] = (page_in == p28) ? 1 : 0;
2760
  assign match[29] = (page_in == p29) ? 1 : 0;
2761
  assign match[30] = (page_in == p30) ? 1 : 0;
2762
  assign match[31] = (page_in == p31) ? 1 : 0;
2763
 
2764
  assign miss = ~(| match[31:0]);
2765
 
2766 75 hellwig
  assign found[0] = match[ 1] | match[ 3] | match[ 5] | match[ 7] |
2767
                    match[ 9] | match[11] | match[13] | match[15] |
2768
                    match[17] | match[19] | match[21] | match[23] |
2769
                    match[25] | match[27] | match[29] | match[31];
2770
  assign found[1] = match[ 2] | match[ 3] | match[ 6] | match[ 7] |
2771
                    match[10] | match[11] | match[14] | match[15] |
2772
                    match[18] | match[19] | match[22] | match[23] |
2773
                    match[26] | match[27] | match[30] | match[31];
2774
  assign found[2] = match[ 4] | match[ 5] | match[ 6] | match[ 7] |
2775
                    match[12] | match[13] | match[14] | match[15] |
2776
                    match[20] | match[21] | match[22] | match[23] |
2777
                    match[28] | match[29] | match[30] | match[31];
2778
  assign found[3] = match[ 8] | match[ 9] | match[10] | match[11] |
2779
                    match[12] | match[13] | match[14] | match[15] |
2780
                    match[24] | match[25] | match[26] | match[27] |
2781
                    match[28] | match[29] | match[30] | match[31];
2782
  assign found[4] = match[16] | match[17] | match[18] | match[19] |
2783
                    match[20] | match[21] | match[22] | match[23] |
2784
                    match[24] | match[25] | match[26] | match[27] |
2785
                    match[28] | match[29] | match[30] | match[31];
2786 27 hellwig
 
2787
  always @(posedge clk) begin
2788
    if (enable == 1) begin
2789
      frame_out <= frame[found];
2790
    end
2791
  end
2792
 
2793
  always @(posedge clk) begin
2794
    if (w_enable == 1) begin
2795
      page[rw_index] <= w_page;
2796
      frame[rw_index] <= w_frame;
2797
    end else begin
2798
      r_page <= page[rw_index];
2799
      r_frame <= frame[rw_index];
2800
    end
2801
  end
2802
 
2803
endmodule

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.