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

Subversion Repositories eco32

[/] [eco32/] [trunk/] [fpga/] [mc-vl/] [src/] [cpu/] [cpu_core.v] - Blame information for rev 308

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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