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

Subversion Repositories eco32

[/] [eco32/] [tags/] [eco32-0.24/] [fpga/] [src/] [cpu/] [cpu.v] - Blame information for rev 240

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

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

powered by: WebSVN 2.1.0

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