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

Subversion Repositories raptor64

[/] [raptor64/] [trunk/] [rtl/] [verilog/] [Raptor64sc.v] - Blame information for rev 21

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

Line No. Rev Author Line
1 13 robfinch
// ============================================================================
2
// (C) 2012 Robert Finch
3
// All Rights Reserved.
4
// robfinch<remove>@opencores.org
5
//
6
// Raptor64.v
7
//  - 64 bit CPU
8
//
9
// This source file is free software: you can redistribute it and/or modify 
10
// it under the terms of the GNU Lesser General Public License as published 
11
// by the Free Software Foundation, either version 3 of the License, or     
12
// (at your option) any later version.                                      
13
//                                                                          
14
// This source file is distributed in the hope that it will be useful,      
15
// but WITHOUT ANY WARRANTY; without even the implied warranty of           
16
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            
17
// GNU General Public License for more details.                             
18
//                                                                          
19
// You should have received a copy of the GNU General Public License        
20
// along with this program.  If not, see <http://www.gnu.org/licenses/>.    
21
//                                                                          
22
// ============================================================================
23
//
24 21 robfinch
`define ADDRESS_RESERVATION     1
25
`define RAS_PREDICTION          1
26 19 robfinch
//`define BTB                                   1
27
//`define TLB           1
28
//`define BRANCH_PREDICTION_SIMPLE      1
29
 
30 13 robfinch
`define RESET_VECTOR    64'hFFFF_FFFF_FFFF_FFF0
31
`define NMI_VECTOR              64'hFFFF_FFFF_FFFF_FFE0
32
`define IRQ_VECTOR              64'hFFFF_FFFF_FFFF_FFD0
33
`define TRAP_VECTOR             64'h0000_0000_0000_0000
34
 
35
`define TLBMissPage             52'hFFFF_FFFF_FFFF_F
36
`define ITLB_MissHandler        64'hFFFF_FFFF_FFFF_FFC0
37
`define DTLB_MissHandler        64'hFFFF_FFFF_FFFF_FFB0
38
 
39
`define GEN_TRAP_OFFSET         13'h0200
40
`define DBZ_TRAP_OFFSET         13'h0050
41
`define OFL_TRAP_OFFSET         13'h0070
42 14 robfinch
`define PRIV_OFFSET                     13'h0080
43 13 robfinch
 
44
`define EX_NON          8'd0
45
`define EX_RST          8'd1
46
`define EX_NMI          8'd2
47
`define EX_IRQ          8'd3
48
`define EX_TRAP         8'd4
49 14 robfinch
`define EX_PRIV         8'd5    // priviledge violation
50 13 robfinch
`define EX_OFL          8'd16   // overflow
51
`define EX_DBZ          8'd17   // divide by zero
52
`define EX_TLBI         8'd19   // TLB exception - ifetch
53
`define EX_TLBD         8'd20   // TLB exception - data
54
 
55
`define EXCEPT_Int              5'd00
56
`define EXCEPT_Mod              5'd01   // TLB modification
57
`define EXCEPT_TLBL             5'd02   // TLB exception - load or ifetch
58
`define EXCEPT_TLBS             5'd03   // TLB exception - store
59
`define EXCEPT_AdEL             5'd04   // Address error - load or ifetch
60
`define EXCEPT_AdES             5'd05   // Address error - store
61
`define EXCEPT_IBE              5'd06   // Bus Error - instruction fetch
62
`define EXCEPT_DBE              5'd07   // Bus Error - load or store
63
`define EXCEPT_Sys              5'd08
64
`define EXCEPT_Bp               5'd09
65
`define EXCEPT_RI               5'd10   // reserved instruction
66
`define EXCEPT_CpU              5'd11   // Coprocessor unusable
67
`define EXCEPT_Ov               5'd12   // Integer Overflow
68
`define EXCEPT_Tr               5'd13   // Trap exception
69
// 14-22 Reserved
70
`define EXCEPT_WATCH    5'd23
71
`define EXCEPT_MCheck   5'd24   // Machine check
72
// 25-31 Reserved
73
 
74
 
75
`define MISC    7'd0
76
`define         BRK             7'd0
77
`define         IRQ             7'd1
78 19 robfinch
`define         ICACHE_ON       7'd10
79
`define         ICACHE_OFF      7'd11
80 21 robfinch
`define         DCACHE_ON       7'd12
81
`define         DCACHE_OFF      7'd13
82 13 robfinch
`define     FIP         7'd20
83
`define         IRET    7'd32
84
`define         ERET    7'd33
85
`define         WAIT    7'd40
86 14 robfinch
`define         TLBP    7'd49
87 13 robfinch
`define     TLBR        7'd50
88
`define     TLBWI       7'd51
89
`define     TLBWR       7'd52
90
`define         CLI             7'd64
91
`define         SEI             7'd65
92
`define R               7'd1
93
`define         COM             7'd4
94
`define         NOT             7'd5
95
`define         NEG             7'd6
96
`define         ABS             7'd7
97 21 robfinch
`define         MOV             7'd9
98 13 robfinch
`define         SWAP    7'd13
99
`define         CTLZ    7'd16
100
`define         CTLO    7'd17
101
`define         CTPOP   7'd18
102
`define         SEXT8   7'd19
103
`define         SEXT16  7'd20
104
`define         SEXT32  7'd21
105
`define         SQRT    7'd24
106
`define         REDOR   7'd30
107
`define         REDAND  7'd31
108
`define     MFSPR       7'd40
109
`define     MTSPR       7'd41
110
`define         TLBIndex        6'd01
111
`define         TLBRandom               6'd02
112
`define         PageTableAddr   6'd04
113
`define         BadVAddr        6'd08
114 14 robfinch
`define         TLBPhysPage0    6'd10
115
`define         TLBPhysPage1    6'd11
116
`define         TLBVirtPage             6'd12
117
`define                 TLBPageMask             6'd13
118
`define                 TLBASID                 6'd14
119
`define         ASID                    6'd15
120
`define                 Wired                   6'd16
121
`define         EP0             6'd17
122
`define         EP1             6'd18
123
`define         EP2             6'd19
124
`define         EP3             6'd20
125
`define         AXC             6'd21
126
`define                 Tick                    6'd22
127
`define                 EPC                             6'd23
128
`define                 CauseCode               6'd24
129
`define                 TBA                             6'd25
130 19 robfinch
`define                 NON_ICACHE_SEG  6'd26
131 21 robfinch
`define                 FPCR                    6'd32
132
`define                 IPC                             6'd33
133 13 robfinch
`define         OMG             7'd50
134
`define         CMG             7'd51
135
`define         OMGI    7'd52
136
`define         CMGI    7'd53
137 19 robfinch
`define         EXEC    7'd58
138 21 robfinch
`define         MYST    7'd59
139 13 robfinch
`define RR      7'd2
140
`define         ADD             7'd2
141
`define         ADDU    7'd3
142
`define         SUB             7'd4
143
`define         SUBU    7'd5
144
`define         CMP             7'd6
145
`define         CMPU    7'd7
146
`define         AND             7'd8
147
`define         OR              7'd9
148
`define         XOR             7'd10
149
`define         ANDC    7'd11
150
`define         NAND    7'd12
151
`define         NOR             7'd13
152
`define         XNOR    7'd14
153
`define         ORC             7'd15
154
`define         MIN             7'd20
155
`define         MAX             7'd21
156
`define         MULU    7'd24
157
`define         MULS    7'd25
158
`define         DIVU    7'd26
159
`define         DIVS    7'd27
160
`define         MOD             7'd28
161
`define         MOVZ    7'd30
162
`define         MOVNZ   7'd31
163
 
164
`define         SHL             7'd40
165
`define         SHRU    7'd41
166
`define         ROL             7'd42
167
`define         ROR             7'd43
168
`define         SHR             7'd44
169
`define         ROLAM   7'd45
170
 
171
`define         NOP             7'd60
172
 
173
`define         SLT             7'd96
174
`define         SLE             7'd97
175
`define         SGT             7'd98
176
`define         SGE             7'd99
177
`define         SLTU    7'd100
178
`define         SLEU    7'd101
179
`define         SGTU    7'd102
180
`define         SGEU    7'd103
181
`define         SEQ             7'd104
182
`define         SNE             7'd105
183
 
184
`define     BCD_ADD     7'd110
185
`define     BCD_SUB 7'd111
186
 
187
`define SHFTI   7'd3
188
`define SHLI            7'd0
189
`define SHRUI           7'd1
190
`define ROLI            7'd2
191
`define SHRI            7'd3
192
`define RORI            7'd4
193
`define ROLAMI          7'd5
194
`define BFINS           7'd8
195
`define BFSET           7'd9
196
`define BFCLR           7'd10
197
`define BFCHG           7'd11
198
`define ADDI    7'd4
199
`define ADDUI   7'd5
200
`define SUBI    7'd6
201 14 robfinch
`define SUBUI   7'd7
202
`define CMPI    7'd8
203
`define CMPUI   7'd9
204
`define ANDI    7'd10
205
`define ORI             7'd11
206
`define XORI    7'd12
207 13 robfinch
 
208 14 robfinch
`define MULUI   7'd13
209
`define MULSI   7'd14
210
`define DIVUI   7'd15
211
`define DIVSI   7'd16
212 13 robfinch
 
213
`define TRAPcc  7'd17
214
`define         TEQ             7'd0
215
`define         TNE             7'd1
216
`define         TLT             7'd2
217 14 robfinch
`define         TGE             7'd3
218
`define         TLE             7'd4
219
`define         TGT             7'd5
220
`define         TLTU    7'd6
221
`define         TGEU    7'd7
222
`define         TLEU    7'd8
223
`define         TGTU    7'd9
224 13 robfinch
`define         TRAP    7'd10
225
`define         TRN             7'd11
226
`define TRAPcci 7'd18
227
`define         TEQI    5'd0
228
`define         TNEI    5'd1
229
`define         TLTI    5'd2
230 14 robfinch
`define         TGEI    5'd3
231
`define         TLEI    5'd4
232
`define         TGTI    5'd5
233
`define         TLTUI   5'd6
234
`define         TGEUI   5'd7
235
`define         TLEUI   5'd8
236
`define         TGTUI   5'd9
237 13 robfinch
`define         TRAI    5'd10
238
`define         TRNI    5'd11
239 14 robfinch
// SETLO=20 to 23
240
`define SETLO   7'b00101xx
241 13 robfinch
`define CALL    7'd24
242
`define JMP             7'd25
243
`define JAL             7'd26
244
`define RET             7'd27
245 14 robfinch
// SETLO=28 to 31
246
`define SETHI   7'b00111xx
247 13 robfinch
`define LB              7'd32
248
`define LC              7'd33
249
`define LH              7'd34
250
`define LW              7'd35
251
`define LP              7'd36
252
`define LBU             7'd37
253
`define LCU             7'd38
254
`define LHU             7'd39
255
`define LSH             7'd40
256
`define LSW             7'd41
257
`define LF              7'd42
258
`define LFD             7'd43
259
`define LFP             7'd44
260
`define LFDP    7'd45
261
`define LWR             7'd46
262
`define LDONE   7'd47
263
 
264
`define SB              7'd48
265
`define SC              7'd49
266
`define SH              7'd50
267
`define SW              7'd51
268
`define SP              7'd52
269
`define MEMNDX  7'd53
270
`define SSH             7'd56
271
`define SSW             7'd57
272
`define SF              7'd58
273
`define SFD             7'd59
274
`define SFP             7'd60
275
`define SFDP    7'd61
276
`define SWC             7'd62
277
 
278
`define INB             7'd64
279
`define INCH    7'd65
280
`define INH             7'd66
281
`define INW             7'd67
282 14 robfinch
`define INBU    7'd68
283
`define INCU    7'd69
284
`define INHU    7'd70
285 13 robfinch
`define OUTB    7'd72
286
`define OUTC    7'd73
287
`define OUTH    7'd74
288
`define OUTW    7'd75
289
 
290 21 robfinch
`define LM              7'd78
291
`define SM              7'd79
292
 
293 13 robfinch
`define BLTI    7'd80
294
`define BGEI    7'd81
295
`define BLEI    7'd82
296
`define BGTI    7'd83
297
`define BLTUI   7'd84
298
`define BGEUI   7'd85
299
`define BLEUI   7'd86
300
`define BGTUI   7'd87
301
`define BEQI    7'd88
302
`define BNEI    7'd89
303
 
304
`define BTRI    7'd94
305
`define         BLTRI   5'd0
306
`define         BGERI   5'd1
307
`define         BLERI   5'd2
308
`define         BGTRI   5'd3
309
`define         BLTURI  5'd4
310
`define         BGEURI  5'd5
311
`define         BLEURI  5'd6
312
`define         BGTURI  5'd7
313
`define         BEQRI   5'd8
314
`define         BNERI   5'd9
315
`define         BRARI   5'd10
316
`define         BRNRI   5'd11
317
`define         BANDRI  5'd12
318
`define         BORRI   5'd13
319
`define BTRR    7'd95
320
`define         BLT             5'd0
321
`define         BGE             5'd1
322
`define         BLE             5'd2
323
`define         BGT             5'd3
324
`define         BLTU    5'd4
325
`define         BGEU    5'd5
326
`define         BLEU    5'd6
327
`define         BGTU    5'd7
328
`define         BEQ             5'd8
329
`define         BNE             5'd9
330
`define         BRA             5'd10
331
`define         BRN             5'd11
332
`define         BAND    5'd12
333
`define         BOR             5'd13
334
`define         BNR             5'd14
335 21 robfinch
`define         LOOP    5'd15
336 13 robfinch
`define         BLTR    5'd16
337
`define         BGER    5'd17
338
`define         BLER    5'd18
339
`define         BGTR    5'd19
340
`define         BLTUR   5'd20
341
`define         BGEUR   5'd21
342
`define         BLEUR   5'd22
343
`define         BGTUR   5'd23
344
`define         BEQR    5'd24
345
`define         BNER    5'd25
346
`define         BRAR    5'd26
347
`define         BRNR    5'd27
348
 
349
 
350
`define SLTI    7'd96
351
`define SLEI    7'd97
352
`define SGTI    7'd98
353
`define SGEI    7'd99
354
`define SLTUI   7'd100
355
`define SLEUI   7'd101
356
`define SGTUI   7'd102
357
`define SGEUI   7'd103
358
`define SEQI    7'd104
359
`define SNEI    7'd105
360
 
361
`define FPLOO   7'd109
362
`define FPZL    7'd110
363
`define NOPI    7'd111
364
 
365
`define IMM             3'd7
366
 
367
`define NOP_INSN        42'b1101111_000_00000000_00000000_00000000_00000000
368
 
369 14 robfinch
module Raptor64sc(rst_i, clk_i, nmi_i, irq_i, bte_o, cti_o, bl_o,
370
        cyc_o, stb_o, ack_i, we_o, sel_o, rsv_o, adr_o, dat_i, dat_o, sys_adv, sys_adr
371 13 robfinch
);
372
parameter IDLE = 5'd1;
373
parameter ICACT = 5'd2;
374
parameter ICACT0 = 5'd3;
375
parameter ICACT1 = 5'd4;
376
parameter ICACT2 = 5'd5;
377
parameter ICACT3 = 5'd6;
378
parameter ICACT4 = 5'd7;
379
parameter ICACT5 = 5'd8;
380
parameter ICACT6 = 5'd9;
381
parameter ICACT7 = 5'd10;
382
parameter ICDLY = 5'd11;
383
parameter DCIDLE = 5'd20;
384
parameter DCACT = 5'd21;
385
parameter DCACT0 = 5'd22;
386
parameter DCACT1 = 5'd23;
387
parameter DCACT2 = 5'd24;
388
parameter DCACT3 = 5'd25;
389
parameter DCACT4 = 5'd26;
390
parameter DCACT5 = 5'd27;
391
parameter DCACT6 = 5'd28;
392
parameter DCACT7 = 5'd29;
393
parameter DCDLY = 5'd30;
394
 
395
input rst_i;
396
input clk_i;
397
input nmi_i;
398
input irq_i;
399
 
400
output [1:0] bte_o;
401
reg [1:0] bte_o;
402
output [2:0] cti_o;
403
reg [2:0] cti_o;
404 14 robfinch
output [4:0] bl_o;
405
reg [4:0] bl_o;
406 13 robfinch
output cyc_o;
407
reg cyc_o;
408
output stb_o;
409
reg stb_o;
410
input ack_i;
411
output we_o;
412
reg we_o;
413 14 robfinch
output [7:0] sel_o;
414
reg [7:0] sel_o;
415 13 robfinch
output rsv_o;
416
reg rsv_o;
417 14 robfinch
output [63:0] adr_o;
418
reg [63:0] adr_o;
419
input [63:0] dat_i;
420
output [63:0] dat_o;
421
reg [63:0] dat_o;
422 13 robfinch
 
423
input sys_adv;
424
input [63:5] sys_adr;
425
 
426
reg resetA;
427 14 robfinch
reg im,bu_im;                   // interrupt mask
428 21 robfinch
reg im1;                        // temporary interrupt mask for LM/SM
429 13 robfinch
reg [1:0] rm;            // fp rounding mode
430
reg [41:0] dIR;
431 21 robfinch
reg [41:0] ndIR;
432
wire [6:0] dOpcode = dIR[41:35];
433 13 robfinch
reg [41:0] xIR;
434
reg [63:0] pc;
435 14 robfinch
reg [63:0] ErrorEPC,EPC,IPC;
436 19 robfinch
reg [63:0] dpc,m1pc,m2pc,wpc;
437
reg dpcv,xpcv,m1pcv,m2pcv,wpcv; // PC valid indicators
438 13 robfinch
reg [63:0] xpc;
439
reg [63:0] tlbra;                // return address for a TLB exception
440
reg [8:0] dRa,dRb,dRc;
441 19 robfinch
reg [8:0] wRt,mRt,m1Rt,m2Rt,tRt,dRt;
442 13 robfinch
reg [8:0] xRt;
443
reg [63:0] dImm;
444
reg [63:0] ea;
445
reg [63:0] iadr_o;
446
reg [31:0] idat;
447
reg [4:0] cstate;
448
reg dbranch_taken,xbranch_taken;
449
reg [63:0] mutex_gate;
450
reg [63:0] TBA;
451 19 robfinch
reg [1:0] dhwxtype,xhwxtype,m1hwxtype,m2hwxtype,whwxtype;
452 14 robfinch
reg [3:0] AXC,dAXC,xAXC;
453
reg dtinit;
454 21 robfinch
reg dcache_on;
455 19 robfinch
reg [63:32] nonICacheSeg;
456 13 robfinch
 
457
reg dccyc;
458
wire [63:0] cdat;
459
reg [63:0] wr_addr;
460 14 robfinch
reg [41:0] insn;
461 13 robfinch
wire [63:0] rfoa,rfob;
462
reg clk_en;
463
reg cpu_clk_en;
464
reg StatusERL;          // 1= in error processing
465
reg StatusEXL;          // 1= in exception processing
466 14 robfinch
reg StatusHWI;          // 1= in interrupt processing
467
reg StatusUM;           // 1= user mode
468 13 robfinch
reg [7:0] CauseCode;
469
reg [7:0] ASID;          // address space identifier (process ID)
470
integer n;
471
reg [63:13] BadVAddr;
472
reg [63:13] PageTableAddr;
473
 
474
function [63:0] fnIncPC;
475
input [63:0] fpc;
476
begin
477
case(fpc[3:2])
478
2'd0:   fnIncPC = {fpc[63:4],4'b0100};
479
2'd1:   fnIncPC = {fpc[63:4],4'b1000};
480
2'd2:   fnIncPC = {fpc[63:4]+60'd1,4'b0000};
481
2'd3:   fnIncPC = {fpc[63:4]+60'd1,4'b0000};
482
endcase
483
end
484
endfunction
485
 
486 14 robfinch
wire KernelMode = StatusEXL;
487
 
488 13 robfinch
//-----------------------------------------------------------------------------
489 14 robfinch
// TLB
490 19 robfinch
// The TLB contains 64 entries, that are 8 way set associative.
491
// The TLB is dual ported and shared between the instruction and data streams.
492 13 robfinch
//-----------------------------------------------------------------------------
493
 
494 19 robfinch
wire unmappedArea = pc[63:52]==12'hFFD || pc[63:52]==12'hFFE || pc[63:52]==12'hFFF;
495
wire unmappedDataArea = ea[63:52]==12'hFFD || ea[63:52]==12'hFFE || ea[63:52]==12'hFFF;
496
wire [63:0] ppc;
497
wire [63:0] pea;
498
 
499
`ifdef TLB
500 14 robfinch
reg [24:13] TLBPageMask;
501
reg [63:13] TLBVirtPage;
502
reg [63:13] TLBPhysPage0;
503
reg [63:13] TLBPhysPage1;
504
reg [7:0] TLBASID;
505
reg TLBG;
506
reg TLBD;
507
reg TLBValid;
508
reg [63:0] Index;
509 19 robfinch
reg [2:0] Random;
510
reg [2:0] Wired;
511 14 robfinch
reg [15:0] IMatch,DMatch;
512
 
513 19 robfinch
reg [3:0] m;
514
reg [5:0] i;
515
reg [24:13] ITLBPageMask [63:0];
516
reg [63:13] ITLBVirtPage [63:0];
517
reg [63:13] ITLBPhysPage0 [63:0];
518
reg [63:13] ITLBPhysPage1 [63:0];
519
reg [63:0] ITLBG;
520
reg [63:0] ITLBD;
521
reg [7:0] ITLBASID [63:0];
522 13 robfinch
reg [15:0] ITLBValid;
523
initial begin
524 19 robfinch
        for (n = 0; n < 64; n = n + 1)
525 13 robfinch
        begin
526
                ITLBPageMask[n] = 0;
527
                ITLBVirtPage[n] = 0;
528 14 robfinch
                ITLBPhysPage0[n] = 0;
529
                ITLBPhysPage1[n] = 0;
530 13 robfinch
                ITLBG[n] = 0;
531
                ITLBASID[n] = 0;
532
                ITLBValid[n] = 0;
533
        end
534
end
535
always @*
536 19 robfinch
for (n = 0; n < 8; n = n + 1)
537
        IMatch[n] = ((pc[63:13]|ITLBPageMask[{n[2:0],pc[15:13]}])==(ITLBVirtPage[{n[2:0],pc[15:13]}]|ITLBPageMask[{n[2:0],pc[15:13]}])) &&
538
                                ((ITLBASID[{n,pc[15:13]}]==ASID) || ITLBG[{n,pc[15:13]}]) &&
539
                                ITLBValid[{n,pc[15:13]}];
540 13 robfinch
always @(IMatch)
541 19 robfinch
if (IMatch[0]) m <= 4'd0;
542
else if (IMatch[1]) m <= 4'd1;
543
else if (IMatch[2]) m <= 4'd2;
544
else if (IMatch[3]) m <= 4'd3;
545
else if (IMatch[4]) m <= 4'd4;
546
else if (IMatch[5]) m <= 4'd5;
547
else if (IMatch[6]) m <= 4'd6;
548
else if (IMatch[7]) m <= 4'd7;
549
else m <= 4'd15;
550 13 robfinch
 
551 19 robfinch
wire ioddpage = |({ITLBPageMask[{m[2:0],pc[15:13]}]+19'd1,13'd0}&pc);
552
wire [63:13] IPFN = ioddpage ? ITLBPhysPage1[{m[2:0],pc[15:13]}] : ITLBPhysPage0[{m[2:0],pc[15:13]}];
553 14 robfinch
 
554 19 robfinch
wire ITLBMiss = !unmappedArea & m[3];
555 13 robfinch
 
556 19 robfinch
assign ppc[63:13] = unmappedArea ? pc[63:13] : m[3] ? `TLBMissPage: IPFN;
557 13 robfinch
assign ppc[12:0] = pc[12:0];
558
 
559 19 robfinch
reg [3:0] q;
560 13 robfinch
always @(ea)
561 19 robfinch
for (n = 0; n < 7; n = n + 1)
562
        DMatch[n] = ((ea[63:13]|ITLBPageMask[{n,ea[15:13]}])==(ITLBVirtPage[{n,ea[15:13]}]|ITLBPageMask[{n,ea[15:13]}])) &&
563
                                ((ITLBASID[{n,ea[15:13]}]==ASID) || ITLBG[{n,ea[15:13]}]) &&
564
                                ITLBValid[{n,ea[15:13]}];
565 13 robfinch
always @(DMatch)
566 19 robfinch
if (DMatch[0]) q <= 4'd0;
567
else if (DMatch[1]) q <= 4'd1;
568
else if (DMatch[2]) q <= 4'd2;
569
else if (DMatch[3]) q <= 4'd3;
570
else if (DMatch[4]) q <= 4'd4;
571
else if (DMatch[5]) q <= 4'd5;
572
else if (DMatch[6]) q <= 4'd6;
573
else if (DMatch[7]) q <= 4'd7;
574
else q <= 4'd15;
575 13 robfinch
 
576 19 robfinch
wire doddpage = |({ITLBPageMask[{q[2:0],ea[15:13]}]+19'd1,13'd0}&ea);
577
wire [63:13] DPFN = doddpage ? ITLBPhysPage1[{q[2:0],ea[15:13]}] : ITLBPhysPage0[{q[2:0],ea[15:13]}];
578 14 robfinch
 
579 19 robfinch
wire DTLBMiss = !unmappedDataArea & q[3];
580
 
581
assign pea[63:13] = unmappedDataArea ? ea[63:13] : q[3] ? `TLBMissPage: DPFN;
582
assign pea[12:0] = ea[12:0];
583
`else
584
assign ppc = pc;
585
assign pea = ea;
586
`endif
587 14 robfinch
wire m1UnmappedDataArea = pea[63:13]>=12'hFFD;
588 13 robfinch
 
589 14 robfinch
wire dram_bus = !pea[63];
590
wire m2_dram_bus = !m2Addr[63];
591 13 robfinch
 
592
//-----------------------------------------------------------------------------
593
// Clock control
594
// - reset or NMI reenables the clock
595
// - this circuit must be under the clk_i domain
596
//-----------------------------------------------------------------------------
597
//
598
BUFGCE u20 (.CE(cpu_clk_en), .I(clk_i), .O(clk) );
599
 
600
always @(posedge clk_i)
601
if (rst_i) begin
602
        cpu_clk_en <= 1'b1;
603
end
604
else begin
605
        if (nmi_i)
606
                cpu_clk_en <= 1'b1;
607
        else
608
                cpu_clk_en <= clk_en;
609
end
610
 
611
//-----------------------------------------------------------------------------
612
// Instruction Cache
613
// 8kB
614
// 
615
//-----------------------------------------------------------------------------
616 21 robfinch
//reg lfdir;
617
wire lfdir = ((dOpcode==`LM || dOpcode==`SM) && dIR[31:0]!=32'd0) &&     ndIR[31:0]!=32'd0;
618
wire ldnop = ((dOpcode==`LM || dOpcode==`SM) && (dIR[31:0]==32'd0 || ndIR[31:0]==32'd0));
619 14 robfinch
reg icaccess;
620 19 robfinch
reg ICacheOn;
621
wire ibufrdy;
622
reg [63:0] tmpbuf;
623 14 robfinch
wire [127:0] insnbundle;
624 21 robfinch
reg [127:0] insnbuf0,insnbuf1;
625
reg [63:4] ibuftag0,ibuftag1;
626 19 robfinch
wire isICached = ppc[63:32]!=nonICacheSeg;
627
wire ICacheAct = ICacheOn & isICached;
628 14 robfinch
 
629
Raptor64_icache_ram u1
630 13 robfinch
(
631 14 robfinch
        .clka(clk), // input clka
632
        .wea(icaccess & ack_i), // input [0 : 0] wea
633
        .addra(adr_o[12:3]), // input [9 : 0] addra
634
        .dina(dat_i), // input [63 : 0] dina
635
        .clkb(~clk), // input clkb
636 21 robfinch
        .addrb(pc[12:4]), // input [8 : 0] addrb
637
        .doutb(insnbundle) // output [127 : 0] doutb
638 13 robfinch
);
639
 
640 21 robfinch
always @(ppc or insnbundle or ICacheAct or insnbuf0 or insnbuf1 or ndIR or lfdir or ldnop)
641 14 robfinch
begin
642 21 robfinch
        casex({ldnop,lfdir,ICacheAct,ibuftag1==ppc[63:4],pc[3:2]})
643
        6'b1xxxxx:      insn <= 42'h37800000000;
644
        6'b01xxxx:      insn <= ndIR;
645
        6'b001x00:      insn <= insnbundle[ 41: 0];
646
        6'b001x01:      insn <= insnbundle[ 83:42];
647
        6'b001x10:      insn <= insnbundle[125:84];
648
        6'b001x11:      insn <= 42'h37800000000;        // NOP instruction
649
        6'b000000:      insn <= insnbuf0[ 41: 0];
650
        6'b000001:      insn <= insnbuf0[ 83:42];
651
        6'b000010:      insn <= insnbuf0[125:84];
652
        6'b000011:      insn <= 42'h37800000000;
653
        6'b000100:      insn <= insnbuf1[ 41: 0];
654
        6'b000101:      insn <= insnbuf1[ 83:42];
655
        6'b000110:      insn <= insnbuf1[125:84];
656
        6'b000111:      insn <= 42'h37800000000;
657 14 robfinch
        endcase
658
end
659
 
660
 
661 13 robfinch
reg [63:13] tmem [127:0];
662
reg [127:0] tvalid;
663
 
664
initial begin
665
        for (n=0; n < 128; n = n + 1)
666
                tmem[n] = 0;
667
        for (n=0; n < 128; n = n + 1)
668
                tvalid[n] = 0;
669
end
670
 
671
wire [64:13] tgout;
672
assign tgout = {tvalid[pc[12:6]],tmem[pc[12:6]]};
673
assign ihit = (tgout=={1'b1,ppc[63:13]});
674 21 robfinch
assign ibufrdy = ibuftag0==ppc[63:4] || ibuftag1==ppc[63:4];
675 13 robfinch
 
676
//-----------------------------------------------------------------------------
677
// Data Cache
678
// No-allocate on write
679
//-----------------------------------------------------------------------------
680
reg dcaccess;
681
wire dhit;
682 14 robfinch
wire [64:15] dtgout;
683 13 robfinch
reg wrhit;
684
reg [7:0] dsel_o;
685
reg [63:0] dadr_o;
686
reg [31:0] ddat;
687
reg wr_dcache;
688
 
689 21 robfinch
// cache RAM 32Kb
690 14 robfinch
Raptor64_dcache_ram u10
691
(
692
        .clka(clk), // input clka
693
        .ena(1'b1),
694
        .wea(dcaccess ? {8{ack_i}} : wrhit ? sel_o : 8'h00), // input [7 : 0] wea
695
        .addra(adr_o[14:3]), // input [11 : 0] addra
696
        .dina(dcaccess ? dat_i : dat_o), // input [63 : 0] dina
697 13 robfinch
 
698 14 robfinch
        .clkb(~clk), // input clkb
699 21 robfinch
        .addrb(pea[14:3]), // input [11 : 0] addrb
700 14 robfinch
        .doutb(cdat) // output [63 : 0] doutb
701
);
702
 
703
 
704
Raptor64_dcache_tagram u11
705 13 robfinch
(
706 14 robfinch
        .clka(clk), // input clka
707
        .ena(dtinit | (adr_o[5:3]==3'b111)), // input ena
708
        .wea(dtinit | (dcaccess & ack_i)), // input [0 : 0] wea
709
        .addra({1'b0,adr_o[14:6]}), // input [9 : 0] addra
710
        .dina(dtinit ? {1'b0,adr_o[63:15]} : {1'b1,adr_o[63:15]}), // input [48 : 0] dina
711 13 robfinch
 
712 14 robfinch
        .clkb(~clk), // input clkb
713
        .addrb({1'b0,pea[14:6]}), // input [9 : 0] addrb
714
        .doutb(dtgout) // output [48 : 0] doutb
715 13 robfinch
);
716
 
717 14 robfinch
assign dhit = (dtgout=={1'b1,pea[63:15]});
718 13 robfinch
 
719
//-----------------------------------------------------------------------------
720
//-----------------------------------------------------------------------------
721
 
722
reg [64:0] xData;
723 21 robfinch
wire xisCacheElement = (xData[63:52] != 12'hFFD && xData[63:52]!=12'hFFF) && dcache_on;
724 13 robfinch
reg m1IsCacheElement;
725
 
726
reg nopI;
727
wire [6:0] iFunc = insn[6:0];
728
wire [6:0] dFunc = dIR[6:0];
729
wire [6:0] xFunc = xIR[6:0];
730
wire [6:0] iOpcode = insn[41:35];
731
wire [6:0] xOpcode = xIR[41:35];
732 19 robfinch
reg [6:0] m1Opcode,m2Opcode;
733
reg [6:0] m1Func,m2Func;
734
reg [63:0] m1Data,m2Data,wData,tData;
735
reg [63:0] m2Addr;
736 13 robfinch
reg [63:0] tick;
737
reg [63:0] tba;
738
reg [63:0] exception_address,ipc;
739
reg [63:0] a,b,c,imm,m1b;
740
reg prev_ihit;
741
reg rsf;
742
reg [63:5] resv_address;
743 19 robfinch
reg dirqf,rirqf,m1irqf,m2irqf,wirqf,tirqf;
744 13 robfinch
reg xirqf;
745 19 robfinch
reg [7:0] dextype,m1extype,m2extype,wextype,textype,exception_type;
746 13 robfinch
reg [7:0] xextype;
747
wire advanceX_edge;
748
reg takb;
749
 
750
wire [127:0] mult_out;
751
wire [63:0] sqrt_out;
752
wire [63:0] div_q;
753
wire [63:0] div_r;
754
wire sqrt_done,mult_done,div_done;
755
wire isSqrt = xOpcode==`R && xFunc==`SQRT;
756
wire [7:0] bcdaddo,bcdsubo;
757
 
758
BCDAdd u40(.ci(1'b0),.a(a[7:0]),.b(b[7:0]),.o(bcdaddo),.c());
759
BCDSub u41(.ci(1'b0),.a(a[7:0]),.b(b[7:0]),.o(bcdsubo),.c());
760
 
761
isqrt #(64) u14
762
(
763
        .rst(rst_i),
764
        .clk(clk),
765
        .ce(1'b1),
766
        .ld(isSqrt),
767
        .a(a),
768
        .o(sqrt_out),
769
        .done(sqrt_done)
770
);
771
 
772
wire isMulu = xOpcode==`RR && xFunc==`MULU;
773
wire isMuls = (xOpcode==`RR && xFunc==`MULS) || xOpcode==`MULSI;
774
wire isMuli = xOpcode==`MULSI || xOpcode==`MULUI;
775
wire isMult = xOpcode==`MULSI || xOpcode==`MULUI || (xOpcode==`RR && (xFunc==`MULS || xFunc==`MULU));
776
wire isDivu = xOpcode==`RR && xFunc==`DIVU;
777
wire isDivs = (xOpcode==`RR && xFunc==`DIVS) || xOpcode==`DIVSI;
778
wire isDivi = xOpcode==`DIVSI || xOpcode==`DIVUI;
779
wire isDiv = xOpcode==`DIVSI || xOpcode==`DIVUI || (xOpcode==`RR && (xFunc==`DIVS || xFunc==`DIVU));
780
 
781
wire disRRShift = dOpcode==`RR && (
782
        dFunc==`SHL || dFunc==`ROL || dFunc==`SHR ||
783
        dFunc==`SHRU || dFunc==`ROR || dFunc==`ROLAM
784
        );
785
wire disRightShift = dOpcode==`RR && (
786
        dFunc==`SHR || dFunc==`SHRU || dFunc==`ROR
787
        );
788
 
789
Raptor64Mult u18
790
(
791
        .rst(rst_i),
792
        .clk(clk),
793
        .ld(isMult),
794
        .sgn(isMuls),
795
        .isMuli(isMuli),
796
        .a(a),
797
        .b(b),
798
        .imm(imm),
799
        .o(mult_out),
800
        .done(mult_done)
801
);
802
 
803
Raptor64Div u19
804
(
805
        .rst(rst_i),
806
        .clk(clk),
807
        .ld(isDiv),
808
        .sgn(isDivs),
809
        .isDivi(isDivi),
810
        .a(a),
811
        .b(b),
812
        .imm(imm),
813
        .qo(div_q),
814
        .ro(div_r),
815
        .dvByZr(),
816
        .done(div_done)
817
);
818
 
819
wire [63:0] fpZLOut;
820
wire [63:0] fpLooOut;
821
wire fpLooDone;
822
 
823
fpZLUnit #(64) u30
824
(
825
        .op(xFunc[5:0]),
826
        .a(a),
827
        .b(b),  // for fcmp
828
        .o(fpZLOut),
829
        .nanx()
830
);
831
 
832
fpLOOUnit #(64) u31
833
(
834
        .clk(clk),
835
        .ce(1'b1),
836
        .rm(rm),
837
        .op(xFunc[5:0]),
838
        .a(a),
839
        .o(fpLooOut),
840
        .done(fpLooDone)
841
);
842
 
843
function [2:0] popcnt6;
844
input [5:0] a;
845
begin
846
case(a)
847
6'b000000:      popcnt6 = 3'd0;
848
6'b000001:      popcnt6 = 3'd1;
849
6'b000010:      popcnt6 = 3'd1;
850
6'b000011:      popcnt6 = 3'd2;
851
6'b000100:      popcnt6 = 3'd1;
852
6'b000101:      popcnt6 = 3'd2;
853
6'b000110:      popcnt6 = 3'd2;
854
6'b000111:      popcnt6 = 3'd3;
855
6'b001000:      popcnt6 = 3'd1;
856
6'b001001:      popcnt6 = 3'd2;
857
6'b001010:      popcnt6 = 3'd2;
858
6'b001011:      popcnt6 = 3'd3;
859
6'b001100:      popcnt6 = 3'd2;
860
6'b001101:      popcnt6 = 3'd3;
861
6'b001110:      popcnt6 = 3'd3;
862
6'b001111:  popcnt6 = 3'd4;
863
6'b010000:      popcnt6 = 3'd1;
864
6'b010001:      popcnt6 = 3'd2;
865
6'b010010:  popcnt6 = 3'd2;
866
6'b010011:      popcnt6 = 3'd3;
867
6'b010100:  popcnt6 = 3'd2;
868
6'b010101:  popcnt6 = 3'd3;
869
6'b010110:  popcnt6 = 3'd3;
870
6'b010111:      popcnt6 = 3'd4;
871
6'b011000:      popcnt6 = 3'd2;
872
6'b011001:      popcnt6 = 3'd3;
873
6'b011010:      popcnt6 = 3'd3;
874
6'b011011:      popcnt6 = 3'd4;
875
6'b011100:      popcnt6 = 3'd3;
876
6'b011101:      popcnt6 = 3'd4;
877
6'b011110:      popcnt6 = 3'd4;
878
6'b011111:      popcnt6 = 3'd5;
879
6'b100000:      popcnt6 = 3'd1;
880
6'b100001:      popcnt6 = 3'd2;
881
6'b100010:      popcnt6 = 3'd2;
882
6'b100011:      popcnt6 = 3'd3;
883
6'b100100:      popcnt6 = 3'd2;
884
6'b100101:      popcnt6 = 3'd3;
885
6'b100110:      popcnt6 = 3'd3;
886
6'b100111:      popcnt6 = 3'd4;
887
6'b101000:      popcnt6 = 3'd2;
888
6'b101001:      popcnt6 = 3'd3;
889
6'b101010:      popcnt6 = 3'd3;
890
6'b101011:      popcnt6 = 3'd4;
891
6'b101100:      popcnt6 = 3'd3;
892
6'b101101:      popcnt6 = 3'd4;
893
6'b101110:      popcnt6 = 3'd4;
894
6'b101111:      popcnt6 = 3'd5;
895
6'b110000:      popcnt6 = 3'd2;
896
6'b110001:      popcnt6 = 3'd3;
897
6'b110010:      popcnt6 = 3'd3;
898
6'b110011:      popcnt6 = 3'd4;
899
6'b110100:      popcnt6 = 3'd3;
900
6'b110101:      popcnt6 = 3'd4;
901
6'b110110:      popcnt6 = 3'd4;
902
6'b110111:      popcnt6 = 3'd5;
903
6'b111000:      popcnt6 = 3'd3;
904
6'b111001:      popcnt6 = 3'd4;
905
6'b111010:      popcnt6 = 3'd4;
906
6'b111011:      popcnt6 = 3'd5;
907
6'b111100:      popcnt6 = 3'd4;
908
6'b111101:      popcnt6 = 3'd5;
909
6'b111110:      popcnt6 = 3'd5;
910
6'b111111:      popcnt6 = 3'd6;
911
endcase
912
end
913
endfunction
914
 
915 21 robfinch
function [5:0] popcnt36;
916
input [35:0] a;
917
begin
918
popcnt36 = popcnt6(a[5:0]) +
919
                        popcnt6(a[11:6]) +
920
                        popcnt6(a[17:12]) +
921
                        popcnt6(a[23:18]) +
922
                        popcnt6(a[29:24]) +
923
                        popcnt6(a[35:30]);
924
end
925
endfunction
926
 
927 13 robfinch
wire [63:0] jmp_tgt = dOpcode[6:4]==`IMM ? {dIR[26:0],insn[34:0],2'b00} : {pc[63:37],insn[34:0],2'b00};
928
 
929
//-----------------------------------------------------------------------------
930 21 robfinch
// Stack for return address predictor
931 19 robfinch
//-----------------------------------------------------------------------------
932
`ifdef RAS_PREDICTION
933
reg [63:0] ras [63:0];    // return address stack, return predictions
934 21 robfinch
reg [5:0] ras_sp;                // stack pointer
935 19 robfinch
`endif
936
`ifdef BTB
937
reg [63:0] btb [63:0];    // branch target buffer
938
`endif
939
 
940
`ifdef BRANCH_PREDICTION_SIMPLE
941
//-----------------------------------------------------------------------------
942
// Simple predictor:
943
// - backwards branches are predicted taken, others predicted not taken.
944
//-----------------------------------------------------------------------------
945
reg predict_taken;
946
 
947
always @(iOpcode or insn)
948
case(iOpcode)
949
`BTRR:
950
        case(insn[4:0])
951
        `BEQ,`BNE,`BLT,`BLE,`BGT,`BGE,`BLTU,`BLEU,`BGTU,`BGEU,`BAND,`BOR,`BNR:
952
                predict_taken = insn[24];
953
        default:        predict_taken = 1'd0;
954
        endcase
955
`BEQI,`BNEI,`BLTI,`BLEI,`BGTI,`BGEI,`BLTUI,`BLEUI,`BGTUI,`BGEUI:
956
        predict_taken = insn[29];
957
default:
958
        predict_taken = 1'd0;
959
endcase
960
`else
961
//-----------------------------------------------------------------------------
962 13 robfinch
// Branch history table.
963
// The history table is updated by the EX stage and read in
964
// both the EX and IF stages.
965
//-----------------------------------------------------------------------------
966
reg [2:0] gbl_branch_hist;
967
reg [1:0] branch_history_table [255:0];
968
wire [7:0] bht_wa = {xpc[5:0],gbl_branch_hist[2:1]};              // write address
969
wire [7:0] bht_ra1 = {xpc[5:0],gbl_branch_hist[2:1]};             // read address (EX stage)
970
wire [7:0] bht_ra2 = {pc[5:0],gbl_branch_hist[2:1]};      // read address (IF stage)
971
wire [1:0] bht_xbits = branch_history_table[bht_ra1];
972
wire [1:0] bht_ibits = branch_history_table[bht_ra2];
973
wire predict_taken = bht_ibits==2'd0 || bht_ibits==2'd1;
974
 
975 21 robfinch
wire isxBranchI = (xOpcode==`BEQI || xOpcode==`BNEI ||
976 13 robfinch
                                        xOpcode==`BLTI || xOpcode==`BLEI || xOpcode==`BGTI || xOpcode==`BGEI ||
977
                                        xOpcode==`BLTUI || xOpcode==`BLEUI || xOpcode==`BGTUI || xOpcode==`BGEUI)
978
                                ;
979
wire isxBranch = isxBranchI || xOpcode==`TRAPcc || xOpcode==`TRAPcci || xOpcode==`BTRI || xOpcode==`BTRR;
980
 
981
reg [1:0] xbits_new;
982
 
983
always @(takb or bht_xbits)
984
if (takb) begin
985
        if (bht_xbits != 2'd1)
986
                xbits_new <= bht_xbits + 2'd1;
987
        else
988
                xbits_new <= bht_xbits;
989
end
990
else begin
991
        if (bht_xbits != 2'd2)
992
                xbits_new <= bht_xbits - 2'd1;
993
        else
994
                xbits_new <= bht_xbits;
995
end
996
 
997
// For simulation only, initialize the history table to zeros.
998
// In the real world we don't care.
999
initial begin
1000
        for (n = 0; n < 256; n = n + 1)
1001
                branch_history_table[n] = 0;
1002
end
1003 19 robfinch
`endif
1004 13 robfinch
 
1005
//-----------------------------------------------------------------------------
1006
// Evaluate branch conditions.
1007
//-----------------------------------------------------------------------------
1008
wire signed [63:0] as = a;
1009
wire signed [63:0] bs = b;
1010
wire signed [63:0] imms = imm;
1011
wire aeqz = a==64'd0;
1012
wire beqz = b==64'd0;
1013
wire immeqz = imm==64'd0;
1014
wire eq = a==b;
1015
wire eqi = a==imm;
1016 19 robfinch
wire lt = $signed(a) < $signed(b);
1017 13 robfinch
wire lti = as < imms;
1018
wire ltu = a < b;
1019
wire ltui = a < imm;
1020
 
1021
always @(xOpcode or xFunc or a or eq or eqi or lt or lti or ltu or ltui or aeqz or beqz or rsf or xIR)
1022
case (xOpcode)
1023
`BTRR:
1024 14 robfinch
        case(xIR[4:0])
1025 13 robfinch
        `BRA:   takb = 1'b1;
1026
        `BRN:   takb = 1'b0;
1027
        `BEQ:   takb = eq;
1028
        `BNE:   takb = !eq;
1029
        `BLT:   takb = lt;
1030
        `BLE:   takb = lt|eq;
1031
        `BGT:   takb = !(lt|eq);
1032
        `BGE:   takb = !lt;
1033
        `BLTU:  takb = ltu;
1034
        `BLEU:  takb = ltu|eq;
1035
        `BGTU:  takb = !(ltu|eq);
1036
        `BGEU:  takb = !ltu;
1037
        `BOR:   takb = !aeqz || !beqz;
1038
        `BAND:  takb = !aeqz && !beqz;
1039
        `BNR:   takb = !rsf;
1040 21 robfinch
        `LOOP:  takb = !beqz;
1041 13 robfinch
        `BEQR:  takb = eq;
1042
        `BNER:  takb = !eq;
1043
        `BLTR:  takb = lt;
1044
        `BLER:  takb = lt|eq;
1045
        `BGTR:  takb = !(lt|eq);
1046
        `BGER:  takb = !lt;
1047
        `BLTUR: takb = ltu;
1048
        `BLEUR: takb = ltu|eq;
1049
        `BGTUR: takb = !(ltu|eq);
1050
        `BGEUR: takb = !ltu;
1051
        default:        takb = 1'b0;
1052
        endcase
1053
`BEQI:  takb = eqi;
1054
`BNEI:  takb = !eqi;
1055
`BLTI:  takb = lti;
1056
`BLEI:  takb = lti|eqi;
1057
`BGTI:  takb = !(lti|eqi);
1058
`BGEI:  takb = !lti;
1059
`BLTUI: takb = ltui;
1060
`BLEUI: takb = ltui|eqi;
1061
`BGTUI: takb = !(ltui|eqi);
1062
`BGEUI: takb = !ltui;
1063
`BTRI:
1064
        case(xIR[24:18])
1065
        `BRA:   takb = 1'b1;
1066
        `BRN:   takb = 1'b0;
1067
        `BEQ:   takb = eqi;
1068
        `BNE:   takb = !eqi;
1069
        `BLT:   takb = lti;
1070
        `BLE:   takb = lti|eqi;
1071
        `BGT:   takb = !(lti|eqi);
1072
        `BGE:   takb = !lti;
1073
        `BLTU:  takb = ltui;
1074
        `BLEU:  takb = ltui|eqi;
1075
        `BGTU:  takb = !(ltui|eqi);
1076
        `BGEU:  takb = !ltui;
1077
        default:        takb = 1'b0;
1078
        endcase
1079
`TRAPcc:
1080
        case(xFunc)
1081
        `TEQ:   takb = eq;
1082
        `TNE:   takb = !eq;
1083
        `TLT:   takb = lt;
1084
        `TLE:   takb = lt|eq;
1085
        `TGT:   takb = !(lt|eq);
1086
        `TGE:   takb = !lt;
1087 14 robfinch
        `TLTU:  takb = ltu;
1088
        `TLEU:  takb = ltu|eq;
1089
        `TGTU:  takb = !(ltu|eq);
1090
        `TGEU:  takb = !ltu;
1091 13 robfinch
        default:        takb = 1'b0;
1092
        endcase
1093
`TRAPcci:
1094
        case(xIR[29:25])
1095
        `TEQI:  takb = eqi;
1096
        `TNEI:  takb = !eqi;
1097
        `TLTI:  takb = lti;
1098
        `TLEI:  takb = lti|eqi;
1099
        `TGTI:  takb = !(lti|eqi);
1100
        `TGEI:  takb = !lti;
1101 14 robfinch
        `TLTUI: takb = ltui;
1102
        `TLEUI: takb = ltui|eqi;
1103
        `TGTUI: takb = !(ltui|eqi);
1104
        `TGEUI: takb = !ltui;
1105 13 robfinch
        default:        takb = 1'b0;
1106
        endcase
1107
default:
1108
        takb = 1'b0;
1109
endcase
1110
 
1111
 
1112
//-----------------------------------------------------------------------------
1113
// Datapath (ALU) operations.
1114
//-----------------------------------------------------------------------------
1115
wire [6:0] cntlzo,cntloo;
1116
cntlz64 u12 ( .i(a),  .o(cntlzo) );
1117
cntlo64 u13 ( .i(a),  .o(cntloo) );
1118
 
1119
reg [1:0] shftop;
1120
wire [63:0] shfto;
1121
always @(xFunc)
1122
        if (xFunc==`SHL)
1123
                shftop = 2'b00;
1124
        else if (xFunc==`ROL || xFunc==`ROR)
1125
                shftop = 2'b01;
1126
        else if (xFunc==`SHRU)
1127
                shftop = 2'b10;
1128
        else if (xFunc==`SHR)
1129
                shftop = 2'b11;
1130
        else
1131
                shftop = 2'b01;
1132
 
1133
wire [63:0] masko;
1134
shiftAndMask u15
1135
(
1136
        .op(shftop),
1137
        .oz(1'b0),              // zero the output
1138
        .a(a),
1139
        .b(b[5:0]),
1140
        .mb(xIR[12:7]),
1141
        .me(xIR[18:13]),
1142
        .o(shfto),
1143
        .mo(masko)
1144
);
1145
 
1146
always @(xOpcode or xFunc or a or b or imm or as or bs or imms or xpc or
1147 14 robfinch
        sqrt_out or cntlzo or cntloo or tick or ipc or tba or AXC or
1148 13 robfinch
        lt or eq or ltu or mult_out or lti or eqi or ltui or xIR or div_q or div_r or
1149 19 robfinch
        shfto or masko or bcdaddo or bcdsubo or fpLooOut or fpZLOut
1150
`ifdef TLB
1151
        or Wired or Index or Random or TLBPhysPage0 or TLBPhysPage1 or TLBVirtPage or TLBASID or
1152 21 robfinch
        PageTableAddr or BadVAddr or ASID or TLBPageMask
1153 19 robfinch
`endif
1154 21 robfinch
        or ASID or EPC or mutex_gate or IPC or CauseCode or TBA or xAXC or nonICacheSeg or rm
1155 13 robfinch
)
1156 16 robfinch
casex(xOpcode)
1157 13 robfinch
`R:
1158
        casex(xFunc)
1159
        `COM:   xData = ~a;
1160
        `NOT:   xData = ~|a;
1161
        `NEG:   xData = -a;
1162
        `ABS:   xData = a[63] ? -a : a;
1163 21 robfinch
        `MOV:   xData = a;
1164 13 robfinch
        `SQRT:  xData = sqrt_out;
1165
        `SWAP:  xData = {a[31:0],a[63:32]};
1166
 
1167
        `REDOR:         xData = |a;
1168
        `REDAND:        xData = &a;
1169
 
1170
        `CTLZ:  xData = cntlzo;
1171
        `CTLO:  xData = cntloo;
1172
        `CTPOP: xData = {4'd0,popcnt6(a[5:0])} +
1173
                                        {4'd0,popcnt6(a[11:6])} +
1174
                                        {4'd0,popcnt6(a[17:12])} +
1175
                                        {4'd0,popcnt6(a[23:18])} +
1176
                                        {4'd0,popcnt6(a[29:24])} +
1177
                                        {4'd0,popcnt6(a[35:30])} +
1178
                                        {4'd0,popcnt6(a[41:36])} +
1179
                                        {4'd0,popcnt6(a[47:42])} +
1180
                                        {4'd0,popcnt6(a[53:48])} +
1181
                                        {4'd0,popcnt6(a[59:54])} +
1182
                                        {4'd0,popcnt6(a[63:60])}
1183
                                        ;
1184
        `SEXT8:         xData = {{56{a[7]}},a[7:0]};
1185
        `SEXT16:        xData = {{48{a[15]}},a[15:0]};
1186
        `SEXT32:        xData = {{32{a[31]}},a[31:0]};
1187
 
1188
        `MFSPR:
1189
                case(xIR[12:7])
1190 19 robfinch
`ifdef TLB
1191 13 robfinch
                `Wired:                 xData = Wired;
1192
                `TLBIndex:              xData = Index;
1193
                `TLBRandom:             xData = Random;
1194 14 robfinch
                `TLBPhysPage0:  xData = {TLBPhysPage0,13'd0};
1195
                `TLBPhysPage1:  xData = {TLBPhysPage1,13'd0};
1196 13 robfinch
                `TLBVirtPage:   xData = {TLBVirtPage,13'd0};
1197
                `TLBPageMask:   xData = {TLBPageMask,13'd0};
1198 14 robfinch
                `TLBASID:       begin
1199
                                        xData = 65'd0;
1200
                                        xData[0] = TLBValid;
1201
                                        xData[1] = TLBD;
1202
                                        xData[2] = TLBG;
1203
                                        xData[15:8] = TLBASID;
1204
                                        end
1205 13 robfinch
                `PageTableAddr: xData = {PageTableAddr,13'd0};
1206
                `BadVAddr:              xData = {BadVAddr,13'd0};
1207 19 robfinch
`endif
1208 13 robfinch
                `ASID:                  xData = ASID;
1209
                `Tick:                  xData = tick;
1210
                `EPC:                   xData = EPC;
1211 21 robfinch
                `IPC:                   xData = IPC;
1212 13 robfinch
                `CauseCode:             xData = CauseCode;
1213
                `TBA:                   xData = TBA;
1214 14 robfinch
                `AXC:                   xData = xAXC;
1215 19 robfinch
                `NON_ICACHE_SEG:        xData = nonICacheSeg;
1216 21 robfinch
                `FPCR:                  xData = {rm,30'd0};
1217 13 robfinch
                default:        xData = 65'd0;
1218
                endcase
1219
        `OMG:           xData = mutex_gate[a[5:0]];
1220
        `CMG:           xData = mutex_gate[a[5:0]];
1221 14 robfinch
        `OMGI:          begin
1222
                                xData = mutex_gate[xIR[12:7]];
1223
                                $display("mutex_gate[%d]=%d",xIR[12:7],mutex_gate[xIR[12:7]]);
1224
                                end
1225 13 robfinch
        `CMGI:          xData = mutex_gate[xIR[12:7]];
1226
        default:        xData = 65'd0;
1227
        endcase
1228
`RR:
1229
        case(xFunc)
1230
        `ADD:   xData = a + b;
1231
        `ADDU:  xData = a + b;
1232
        `SUB:   xData = a - b;
1233
        `SUBU:  xData = a - b;
1234
        `CMP:   xData = lt ? 64'hFFFFFFFFFFFFF : eq ? 64'd0 : 64'd1;
1235
        `CMPU:  xData = ltu ? 64'hFFFFFFFFFFFFF : eq ? 64'd0 : 64'd1;
1236
        `SEQ:   xData = eq;
1237
        `SNE:   xData = !eq;
1238
        `SLT:   xData = lt;
1239
        `SLE:   xData = lt|eq;
1240
        `SGT:   xData = !(lt|eq);
1241
        `SGE:   xData = !lt;
1242
        `SLTU:  xData = ltu;
1243
        `SLEU:  xData = ltu|eq;
1244
        `SGTU:  xData = !(ltu|eq);
1245
        `SGEU:  xData = !ltu;
1246
        `AND:   xData = a & b;
1247
        `OR:    xData = a | b;
1248
        `XOR:   xData = a ^ b;
1249
        `ANDC:  xData = a & ~b;
1250
        `NAND:  xData = ~(a & b);
1251
        `NOR:   xData = ~(a | b);
1252
        `XNOR:  xData = ~(a ^ b);
1253
        `ORC:   xData = a | ~b;
1254
        `MIN:   xData = lt ? a : b;
1255
        `MAX:   xData = lt ? b : a;
1256
        `MOVZ:  xData = b;
1257
        `MOVNZ: xData = b;
1258
        `MULS:  xData = mult_out[63:0];
1259
        `MULU:  xData = mult_out[63:0];
1260
        `DIVS:  xData = div_q;
1261
        `DIVU:  xData = div_q;
1262
        `MOD:   xData = div_r;
1263
 
1264
        `SHL:   xData = shfto;
1265
        `SHRU:  xData = shfto;
1266
        `ROL:   xData = shfto;
1267
        `ROR:   xData = {a[0],a[63:1]};
1268
        `SHR:   xData = shfto;
1269
        `ROLAM: xData = shfto & masko;
1270
 
1271
        `BCD_ADD:       xData = bcdaddo;
1272
        `BCD_SUB:       xData = bcdsubo;
1273
 
1274
        default:        xData = 65'd0;
1275
        endcase
1276
`SHFTI:
1277
        case(xFunc)
1278
        `SHLI:  xData = shfto;
1279
        `SHRUI: xData = shfto;
1280
        `ROLI:  xData = shfto;
1281
        `RORI:  xData = {a[0],a[63:1]};
1282
        `SHRI:  xData = shfto;
1283
        `ROLAMI:        xData = shfto & masko;
1284
        `BFINS:         begin for (n = 0; n < 64; n = n + 1) xData[n] = masko[n] ? shfto[n] : b[n]; xData[64] = 1'b0; end
1285
        `BFSET:         begin for (n = 0; n < 64; n = n + 1) xData[n] = masko[n] ? 1'b1 : b[n]; xData[64] = 1'b0; end
1286
        `BFCLR:         begin for (n = 0; n < 64; n = n + 1) xData[n] = masko[n] ? 1'b0 : b[n]; xData[64] = 1'b0; end
1287
        `BFCHG:         begin for (n = 0; n < 64; n = n + 1) xData[n] = masko[n] ? ~b[n] : b[n]; xData[64] = 1'b0; end
1288
        default:        xData = 65'd0;
1289
        endcase
1290 21 robfinch
`BTRR:
1291
        case(xIR[4:0])
1292
        `LOOP:  xData = b - 64'd1;
1293
        default:        xData = 64'd0;
1294
        endcase
1295 14 robfinch
`SETLO: xData = {{32{xIR[31]}},xIR[31:0]};
1296
`SETHI: xData = {xIR[31:0],a[31:0]};
1297 13 robfinch
`ADDI:  xData = a + imm;
1298
`ADDUI: xData = a + imm;
1299
`SUBI:  xData = a - imm;
1300 14 robfinch
`SUBUI: xData = a - imm;
1301 13 robfinch
`CMPI:  xData = lti ? 64'hFFFFFFFFFFFFF : eqi ? 64'd0 : 64'd1;
1302
`CMPUI: xData = ltui ? 64'hFFFFFFFFFFFFF : eqi ? 64'd0 : 64'd1;
1303
`MULSI: xData = mult_out[63:0];
1304
`MULUI: xData = mult_out[63:0];
1305
`DIVSI: xData = div_q;
1306
`DIVUI: xData = div_q;
1307
`ANDI:  xData = a & imm;
1308
`ORI:   xData = a | imm;
1309
`XORI:  xData = a ^ imm;
1310
`SEQI:  xData = eqi;
1311
`SNEI:  xData = !eqi;
1312
`SLTI:  xData = lti;
1313
`SLEI:  xData = lti|eqi;
1314
`SGTI:  xData = !(lti|eqi);
1315
`SGEI:  xData = !lti;
1316
`SLTUI: xData = ltui;
1317
`SLEUI: xData = ltui|eqi;
1318
`SGTUI: xData = !(ltui|eqi);
1319
`SGEUI: xData = !ltui;
1320
`INB,`INCH,`INH,`INW:
1321
                xData = a + imm;
1322
`OUTB,`OUTC,`OUTH,`OUTW:
1323
                xData = a + imm;
1324 21 robfinch
`LW,`LH,`LC,`LB,`LHU,`LCU,`LBU,`LWR,`LF,`LFD:
1325 13 robfinch
                xData = a + imm;
1326 21 robfinch
`SW,`SH,`SC,`SB,`SWC,`SF,`SFD:
1327 13 robfinch
                xData = a + imm;
1328
`MEMNDX:
1329
                xData = a + b + imm;
1330 21 robfinch
`SM:    xData = a + {popcnt36(xIR[31:0]),3'b000};
1331
`LM:    xData = a + {popcnt36(xIR[31:0]),3'b000};
1332 13 robfinch
`TRAPcc:        xData = fnIncPC(xpc);
1333
`TRAPcci:       xData = fnIncPC(xpc);
1334
`CALL:          xData = fnIncPC(xpc);
1335
`JAL:           xData = xpc + {xIR[29:25],2'b00};
1336 21 robfinch
`RET:   xData = a + imm;
1337 13 robfinch
`FPLOO: xData = fpLooOut;
1338
`FPZL:  xData = fpZLOut;
1339
default:        xData = 65'd0;
1340
endcase
1341
 
1342 14 robfinch
wire v_ri,v_rr;
1343
overflow u2 (.op(xOpcode==`SUBI), .a(a[63]), .b(imm[63]), .s(xData[63]), .v(v_ri));
1344
overflow u3 (.op(xOpcode==`RR && xFunc==`SUB), .a(a[63]), .b(b[63]), .s(xData[63]), .v(v_rr));
1345
 
1346 13 robfinch
wire dbz_error = (xOpcode==`DIVSI||xOpcode==`DIVUI) && b==64'd0;
1347 19 robfinch
wire ovr_error = ((xOpcode==`ADDI || xOpcode==`SUBI) && v_ri) || ((xOpcode==`RR && (xFunc==`SUB || xFunc==`ADD)) && v_rr);
1348 14 robfinch
wire priv_violation = !KernelMode && (xOpcode==`MISC &&
1349
        (xFunc==`IRET || xFunc==`ERET || xFunc==`CLI || xFunc==`SEI ||
1350
         xFunc==`TLBP || xFunc==`TLBR || xFunc==`TLBWR || xFunc==`TLBWI
1351
        ));
1352 13 robfinch
wire xIsSqrt = xOpcode==`R && xFunc==`SQRT;
1353
wire xIsMult = (xOpcode==`RR && (xFunc==`MULU || xFunc==`MULS)) ||
1354
        xOpcode==`MULSI || xOpcode==`MULUI;
1355
wire xIsDiv = (xOpcode==`RR && (xFunc==`DIVU || xFunc==`DIVS)) ||
1356
        xOpcode==`DIVSI || xOpcode==`DIVUI;
1357
 
1358
wire xIsLoad =
1359
        xOpcode==`LW || xOpcode==`LH || xOpcode==`LB || xOpcode==`LWR ||
1360
        xOpcode==`LHU || xOpcode==`LBU ||
1361 21 robfinch
        xOpcode==`LC || xOpcode==`LCU || xOpcode==`LM ||
1362
        xOpcode==`LF || xOpcode==`LFD
1363 13 robfinch
        ;
1364
wire xIsStore =
1365 21 robfinch
        xOpcode==`SW || xOpcode==`SH || xOpcode==`SB || xOpcode==`SC || xOpcode==`SWC || xOpcode==`SM ||
1366
        xOpcode==`SF || xOpcode==`SFD ||
1367 13 robfinch
        xOpcode==`OUTW || xOpcode==`OUTH || xOpcode==`OUTB || xOpcode==`OUTC
1368
        ;
1369
wire xIsSWC = xOpcode==`SWC;
1370
wire xIsIn =
1371
        xOpcode==`INW || xOpcode==`INH || xOpcode==`INCH || xOpcode==`INB
1372
        ;
1373
//wire mIsSWC = mOpcode==`SWC;
1374
 
1375
//wire mIsLoad =
1376
//      mOpcode==`LW || mOpcode==`LH || mOpcode==`LB || mOpcode==`LC || mOpcode==`LWR ||
1377
//      mOpcode==`LHU || mOpcode==`LBU || mOpcode==`LCU ||
1378
//      mOpcode==`INW || mOpcode==`INB || mOpcode==`INH
1379
//      ;
1380
wire m1IsLoad =
1381
        m1Opcode==`LW || m1Opcode==`LH || m1Opcode==`LB || m1Opcode==`LC || m1Opcode==`LWR ||
1382 21 robfinch
        m1Opcode==`LHU || m1Opcode==`LBU || m1Opcode==`LCU || m1Opcode==`LM ||
1383
        m1Opcode==`LF || m1Opcode==`LFD
1384 13 robfinch
        ;
1385
wire m1IsIn =
1386
        m1Opcode==`INW || m1Opcode==`INH || m1Opcode==`INCH || m1Opcode==`INB
1387
        ;
1388 14 robfinch
wire m2IsInW = m2Opcode==`INW;
1389 21 robfinch
wire m1IsStore = m1Opcode==`SW || m1Opcode==`SH || m1Opcode==`SB || m1Opcode==`SC || m1Opcode==`SWC || m1Opcode==`SM ||
1390
                                m1Opcode==`SF || m1Opcode==`SFD;
1391
wire m2IsStore = m2Opcode==`SW || m2Opcode==`SWC || m2Opcode==`SH || m2Opcode==`SC || m2Opcode==`SB || m2Opcode==`SM ||
1392
                                m2Opcode==`SF || m2Opcode==`SFD;
1393 14 robfinch
wire xIsIO =
1394
        xIsIn ||
1395
        xOpcode==`OUTW || xOpcode==`OUTH || xOpcode==`OUTC || xOpcode==`OUTB
1396
        ;
1397 13 robfinch
wire m1IsIO =
1398
        m1IsIn ||
1399
        m1Opcode==`OUTW || m1Opcode==`OUTH || m1Opcode==`OUTC || m1Opcode==`OUTB
1400
        ;
1401
wire m2IsLoad =
1402
        m2Opcode==`LW || m2Opcode==`LH || m2Opcode==`LB || m2Opcode==`LC || m2Opcode==`LWR ||
1403 21 robfinch
        m2Opcode==`LHU || m2Opcode==`LBU || m2Opcode==`LCU || m2Opcode==`LM ||
1404
        m2Opcode==`LF || m2Opcode==`LFD
1405 13 robfinch
        ;
1406
 
1407
wire xIsFPLoo = xOpcode==`FPLOO;
1408
 
1409 14 robfinch
wire xneedBus = xIsIO;
1410 19 robfinch
wire m1needBus = (m1IsLoad & !m1IsCacheElement) || m1IsStore || m1IsIO;
1411 14 robfinch
wire m2needBus = (m2IsLoad | m2IsStore);
1412
 
1413 13 robfinch
// Stall on SWC allows rsf flag to be loaded for the next instruction
1414
// Currently stalls on load of R0, but doesn't need to.
1415 14 robfinch
wire StallR =   (((xIsLoad||xIsIn) && ((xRt==dRa)||(xRt==dRb)||(xRt==dRt))) || xIsSWC) ||
1416
                                (((m1IsLoad||m1IsIn) && ((m1Rt==dRa)||(m1Rt==dRb)||(m1Rt==dRt)))) ||
1417 19 robfinch
                                (((m2IsLoad) && ((m2Rt==dRa)||(m2Rt==dRb)||(m2Rt==dRt))))
1418 14 robfinch
                                ;
1419
wire StallX = xneedBus & (m1needBus|m2needBus|icaccess|dcaccess);
1420 21 robfinch
wire StallM1 = (m1needBus & (m2needBus|icaccess|dcaccess)) ||
1421
                                ( m1IsLoad & m1IsCacheElement & m2IsStore)      // wait for a preceding store to complete
1422
                                ;
1423 14 robfinch
wire StallM2 =  icaccess|dcaccess;
1424 13 robfinch
 
1425
wire advanceT = !resetA;
1426
wire advanceW = advanceT;
1427 14 robfinch
wire advanceM2 = advanceW &&
1428
                                        ((m2IsLoad || m2IsStore) ? ack_i : 1'b1) &&
1429
                                        !StallM2
1430 13 robfinch
                                        ;
1431 14 robfinch
wire advanceM1 = advanceM2 &
1432 13 robfinch
                                        (m1IsIO ? ack_i : 1'b1) &
1433
                                        ((m1IsLoad & m1IsCacheElement) ? dhit : 1'b1) &
1434
                                        !StallM1
1435
                                        ;
1436 14 robfinch
wire advanceX = advanceM1 & (
1437 13 robfinch
                                        xIsSqrt ? sqrt_done :
1438
                                        xIsMult ? mult_done :
1439
                                        xIsDiv ? div_done :
1440
                                        xIsFPLoo ? fpLooDone :
1441 14 robfinch
                                        1'b1) &
1442
                                        !StallX;
1443
wire advanceR = advanceX & !StallR;
1444 19 robfinch
wire advanceI = advanceR & (ICacheOn ? ihit : ibufrdy);
1445 13 robfinch
 
1446
wire triggerDCacheLoad = (m1IsLoad & m1IsCacheElement & !dhit) &&       // there is a miss
1447 14 robfinch
                                                !(icaccess | dcaccess) &&       // caches are not active
1448
                                                m2Opcode==`NOPI                         // and the pipeline is free of memory-ops
1449 13 robfinch
                                                ;
1450
// Since IMM is "sticky" we have to check for it.
1451 21 robfinch
wire triggerICacheLoad1 = ICacheAct && !ihit && !triggerDCacheLoad &&   // There is a miss
1452 19 robfinch
                                                !(icaccess | dcaccess) &&       // caches are not active
1453 13 robfinch
                                                (dOpcode==`NOPI || dOpcode[6:4]==`IMM) &&                       // and the pipeline is flushed
1454
                                                (xOpcode==`NOPI || xOpcode[6:4]==`IMM) &&
1455
                                                m1Opcode==`NOPI &&
1456 14 robfinch
                                                m2Opcode==`NOPI
1457 13 robfinch
                                                ;
1458 21 robfinch
wire triggerICacheLoad2 = (!ICacheAct && !ibufrdy) && !triggerDCacheLoad &&     // There is a miss
1459
                                                !(icaccess | dcaccess)  // caches are not active
1460
                                                ;
1461
wire triggerICacheLoad = triggerICacheLoad1 | triggerICacheLoad2;
1462
 
1463 14 robfinch
wire EXexception_pending = ovr_error || dbz_error || priv_violation || xOpcode==`TRAPcci || xOpcode==`TRAPcc;
1464 19 robfinch
`ifdef TLB
1465 14 robfinch
wire M1exception_pending = advanceM1 & (m1IsLoad|m1IsStore) & DTLBMiss;
1466 19 robfinch
`else
1467
wire M1exception_pending = 1'b0;
1468
`endif
1469 14 robfinch
wire exception_pending = EXexception_pending | M1exception_pending;
1470 13 robfinch
 
1471
reg prev_nmi,nmi_edge;
1472
 
1473 21 robfinch
always @(dOpcode or dIR)
1474
begin
1475
        ndIR <= dIR;
1476
        if ((dOpcode==`LM || dOpcode==`SM) && dIR[31:0]!=32'd0) begin
1477
                $display("LM/SM %h",dIR[31:0]);
1478
                if (dIR[0])
1479
                        ndIR[0] <= 1'b0;
1480
                else if (dIR[1])
1481
                        ndIR[1] <= 1'b0;
1482
                else if (dIR[2])
1483
                        ndIR[2] <= 1'b0;
1484
                else if (dIR[3])
1485
                        ndIR[3] <= 1'b0;
1486
                else if (dIR[4])
1487
                        ndIR[4] <= 1'b0;
1488
                else if (dIR[5])
1489
                        ndIR[5] <= 1'b0;
1490
                else if (dIR[6])
1491
                        ndIR[6] <= 1'b0;
1492
                else if (dIR[7])
1493
                        ndIR[7] <= 1'b0;
1494
                else if (dIR[8])
1495
                        ndIR[8] <= 1'b0;
1496
                else if (dIR[9])
1497
                        ndIR[9] <= 1'b0;
1498
                else if (dIR[10])
1499
                        ndIR[10] <= 1'b0;
1500
                else if (dIR[11])
1501
                        ndIR[11] <= 1'b0;
1502
                else if (dIR[12])
1503
                        ndIR[12] <= 1'b0;
1504
                else if (dIR[13])
1505
                        ndIR[13] <= 1'b0;
1506
                else if (dIR[14])
1507
                        ndIR[14] <= 1'b0;
1508
                else if (dIR[15])
1509
                        ndIR[15] <= 1'b0;
1510
                else if (dIR[16])
1511
                        ndIR[16] <= 1'b0;
1512
                else if (dIR[17])
1513
                        ndIR[17] <= 1'b0;
1514
                else if (dIR[18])
1515
                        ndIR[18] <= 1'b0;
1516
                else if (dIR[19])
1517
                        ndIR[19] <= 1'b0;
1518
                else if (dIR[20])
1519
                        ndIR[20] <= 1'b0;
1520
                else if (dIR[21])
1521
                        ndIR[21] <= 1'b0;
1522
                else if (dIR[22])
1523
                        ndIR[22] <= 1'b0;
1524
                else if (dIR[23])
1525
                        ndIR[23] <= 1'b0;
1526
                else if (dIR[24])
1527
                        ndIR[24] <= 1'b0;
1528
                else if (dIR[25])
1529
                        ndIR[25] <= 1'b0;
1530
                else if (dIR[26])
1531
                        ndIR[26] <= 1'b0;
1532
                else if (dIR[27])
1533
                        ndIR[27] <= 1'b0;
1534
                else if (dIR[28])
1535
                        ndIR[28] <= 1'b0;
1536
                else if (dIR[29])
1537
                        ndIR[29] <= 1'b0;
1538
                else if (dIR[30])
1539
                        ndIR[30] <= 1'b0;
1540
                else
1541
                        ndIR[31] <= 1'b0;
1542
        end
1543
end
1544 13 robfinch
 
1545
//---------------------------------------------------------
1546
// Register file.
1547
//---------------------------------------------------------
1548
 
1549
syncRam512x64_1rw3r u5
1550
(
1551
        .wrst(1'b0),
1552
        .wclk(clk),
1553
        .wce(advanceW),
1554
        .we(1'b1),
1555
        .wadr(wRt),
1556
        .i(wData),
1557
        .wo(),
1558
 
1559
        .rrsta(1'b0),
1560
        .rclka(~clk),
1561
        .rcea(advanceR),
1562
        .radra(dRa),
1563
        .roa(rfoa),
1564
 
1565
        .rrstb(1'b0),
1566
        .rclkb(~clk),
1567
        .rceb(advanceR),
1568
        .radrb(dRb),
1569
        .rob(rfob),
1570
 
1571
        .rrstc(1'b0),
1572
        .rclkc(~clk),
1573
        .rcec(advanceR),
1574
        .radrc(dRc),
1575
        .roc(rfoc)
1576
);
1577
 
1578
 
1579
reg m1clkoff,m2clkoff,m3clkoff,m4clkoff,wclkoff;
1580
reg dFip,xFip,m1Fip,m2Fip,m3Fip,m4Fip,wFip;
1581 21 robfinch
reg cyc1;
1582 13 robfinch
 
1583 21 robfinch
reg [63:0] nxt_c;
1584
always @(dRc or xData or m1Data or m2Data or wData or tData or rfoc)
1585
        casex(dRc)
1586
        9'bxxxx00000:   nxt_c <= 64'd0;
1587
        xRt:    nxt_c <= xData;
1588
        m1Rt:   nxt_c <= m1Data;
1589
        m2Rt:   nxt_c <= m2Data;
1590
        wRt:    nxt_c <= wData;
1591
        tRt:    nxt_c <= tData;
1592
        default:        nxt_c <= rfoc;
1593
        endcase
1594
 
1595 13 robfinch
always @(posedge clk)
1596
if (rst_i) begin
1597
        bte_o <= 2'b00;
1598
        cti_o <= 3'b000;
1599
        cyc_o <= 1'b0;
1600
        stb_o <= 1'b0;
1601
        we_o <= 1'b0;
1602
        sel_o <= 8'h00;
1603
        adr_o <= 64'd0;
1604
        dat_o <= 64'd0;
1605
        dccyc <= 1'b0;
1606
 
1607 19 robfinch
        nonICacheSeg <= 32'hFFFF_FFFD;
1608 14 robfinch
        TBA <= 64'd0;
1609
        pc <= `RESET_VECTOR;
1610 13 robfinch
        m1Opcode <= `NOPI;
1611
        m2Opcode <= `NOPI;
1612
        dIR <= `NOP_INSN;
1613
        dRt <= 9'd0;
1614
        tRt <= 9'd0;
1615
        wRt <= 9'd0;
1616
        m1Rt <= 9'd0;
1617
        m2Rt <= 9'd0;
1618
        tData <= 64'd0;
1619
        wData <= 64'd0;
1620
        m1Data <= 64'd0;
1621
        m2Data <= 64'd0;
1622
        icaccess <= 1'b0;
1623
        dcaccess <= 1'b0;
1624
        nopI <= 1'b0;
1625
        prev_ihit <= 1'b0;
1626 14 robfinch
        dhwxtype <= 2'b00;
1627
        xhwxtype <= 2'b00;
1628
        m1hwxtype <= 2'b00;
1629
        m2hwxtype <= 2'b00;
1630
        whwxtype <= 2'b00;
1631 13 robfinch
        wFip <= 1'b0;
1632
        m2Fip <= 1'b0;
1633
        m1Fip <= 1'b0;
1634
        xFip <= 1'b0;
1635
        dFip <= 1'b0;
1636
        dirqf <= 1'b0;
1637 16 robfinch
        dpcv <= 1'b0;
1638
        xpcv <= 1'b0;
1639
        m1pcv <= 1'b0;
1640
        m2pcv <= 1'b0;
1641
        wpcv <= 1'b0;
1642 13 robfinch
        tick <= 32'd0;
1643
        cstate <= IDLE;
1644
        dImm <= 64'd0;
1645 14 robfinch
        AXC <= 4'd0;
1646
        dAXC <= 4'd0;
1647 13 robfinch
        xirqf <= 1'b0;
1648
        xextype <= 8'h00;
1649
        xIR <= `NOP_INSN;
1650
        xpc <= 64'd0;
1651
        a <= 64'd0;
1652
        b <= 64'd0;
1653
        imm <= 64'd0;
1654
        xRt <= 9'd0;
1655
        clk_en <= 1'b1;
1656 19 robfinch
`ifdef TLB
1657 13 robfinch
        Random <= 4'hF;
1658
        Wired <= 4'd0;
1659 19 robfinch
`endif
1660 14 robfinch
        StatusEXL <= 1'b1;
1661
        StatusHWI <= 1'b0;
1662 13 robfinch
        resetA <= 1'b1;
1663 14 robfinch
        mutex_gate <= 64'h0;
1664 19 robfinch
`ifndef BRANCH_PREDICTION_SIMPLE
1665 13 robfinch
        gbl_branch_hist <= 3'b000;
1666 19 robfinch
`endif
1667 21 robfinch
        dcache_on <= 1'b0;
1668 19 robfinch
        ICacheOn <= 1'b0;
1669 21 robfinch
        ibuftag0 <= 64'h0;
1670
        ibuftag1 <= 64'h0;
1671 14 robfinch
        m1IsCacheElement <= 1'b0;
1672
        dtinit <= 1'b1;
1673 19 robfinch
`ifdef RAS_PREDICTION
1674
        ras_sp <= 6'd63;
1675
`endif
1676 21 robfinch
        im <= 1'b1;
1677
        im1 <= 1'b1;
1678 13 robfinch
end
1679
else begin
1680
 
1681
//---------------------------------------------------------
1682
// Initialize program counters
1683 14 robfinch
// Initialize data tags to zero.
1684 13 robfinch
//---------------------------------------------------------
1685
if (resetA) begin
1686
        pc <= `RESET_VECTOR;
1687 14 robfinch
        adr_o[14:6] <= adr_o[14:6]+9'd1;
1688
        if (adr_o[14:6]==9'h1FF) begin
1689
                dtinit <= 1'b0;
1690
                resetA <= 1'b0;
1691
        end
1692 13 robfinch
end
1693
 
1694 19 robfinch
`ifdef TLB
1695 13 robfinch
if (Random==Wired)
1696 19 robfinch
        Random <= 3'd7;
1697 13 robfinch
else
1698 19 robfinch
        Random <= Random - 3'd1;
1699
`endif
1700 13 robfinch
 
1701
tick <= tick + 64'd1;
1702
 
1703
prev_nmi <= nmi_i;
1704
if (!prev_nmi & nmi_i)
1705
        nmi_edge <= 1'b1;
1706
 
1707
 
1708 21 robfinch
`ifdef ADDRESS_RESERVATION
1709 13 robfinch
// A store by any device in the system to a reserved address blcok
1710
// clears the reservation.
1711
 
1712
if (sys_adv && sys_adr[63:5]==resv_address)
1713
        resv_address <= 59'd0;
1714 21 robfinch
`endif
1715 13 robfinch
 
1716
//---------------------------------------------------------
1717
// TRAILER:
1718
// - placeholder to allow the use of synchronous register
1719
//   memory
1720
//---------------------------------------------------------
1721
if (advanceT) begin
1722
        tRt <= 9'd0;
1723
        tData <= 64'd0;
1724
end
1725
 
1726
//---------------------------------------------------------
1727
// WRITEBACK:
1728
// - update the register file with results
1729
// - record exception address and type
1730
// - jump to exception handler routine (below)
1731
//---------------------------------------------------------
1732
if (advanceW) begin
1733
        textype <= wextype;
1734
        wextype <= `EX_NON;
1735
        tRt <= wRt;
1736
        tData <= wData;
1737 16 robfinch
        if (wRt!=5'd0)
1738
                $display("Writing regfile[%d:%d] with %h", wRt[8:5],wRt[4:0], wData);
1739 13 robfinch
        wRt <= 9'd0;
1740
        wData <= 64'd0;
1741 14 robfinch
        if (|whwxtype) begin
1742
                dhwxtype <= 2'b00;
1743
                xhwxtype <= 2'b00;
1744
                m1hwxtype <= 2'b00;
1745
                m2hwxtype <= 2'b00;
1746
                whwxtype <= 2'b00;
1747 13 robfinch
        end
1748
        clk_en <= 1'b1;
1749
        if (wclkoff)
1750
                clk_en <= 1'b0;
1751
        wclkoff <= 1'b0;
1752
        m1clkoff <= 1'b0;
1753
        m2clkoff <= 1'b0;
1754
        if (wFip) begin
1755
                wFip <= 1'b0;
1756
                m2Fip <= 1'b0;
1757
                m1Fip <= 1'b0;
1758
                xFip <= 1'b0;
1759
                dFip <= 1'b0;
1760
        end
1761
end
1762
 
1763
//---------------------------------------------------------
1764
// MEMORY:
1765
//---------------------------------------------------------
1766 14 robfinch
if (advanceM2) begin
1767
        wData <= m2Data;
1768
        whwxtype <= m2hwxtype;
1769
        wextype <= m2extype;
1770
        wRt <= m2Rt;
1771
        wpc <= m2pc;
1772 16 robfinch
        wpcv <= m2pcv;
1773 14 robfinch
        wclkoff <= m2clkoff;
1774
        wFip <= m2Fip;
1775 13 robfinch
 
1776 14 robfinch
        m2Rt <= 9'd0;
1777
        m2Opcode <= `NOPI;
1778
        m2Func <= 7'd0;
1779
        m2Addr <= 64'd0;
1780
        m2Data <= 64'd0;
1781
        m2clkoff <= 1'b0;
1782
        m2pc <= 64'd0;
1783
        m2extype <= `EX_NON;
1784
        if (m2extype==`EX_NON) begin
1785
                case(m2Opcode)
1786 21 robfinch
                `SH,`SC,`SB,`SW,`SWC,`SM,`SF,`SFD:
1787 13 robfinch
                        begin
1788
                                cyc_o <= 1'b0;
1789
                                stb_o <= 1'b0;
1790 14 robfinch
                                we_o <= 1'b0;
1791 13 robfinch
                                sel_o <= 4'h0;
1792
                        end
1793 21 robfinch
                `LH,`LF:
1794 13 robfinch
                        begin
1795
                                cyc_o <= 1'b0;
1796
                                stb_o <= 1'b0;
1797 14 robfinch
                                sel_o <= 8'h00;
1798 19 robfinch
                                wData <= sel_o[7] ? {{32{dat_i[63]}},dat_i[63:32]}:{{32{dat_i[31]}},dat_i[31: 0]};
1799 13 robfinch
                        end
1800 21 robfinch
                `LW,`LWR,`LM,`LFD:
1801 13 robfinch
                        begin
1802 14 robfinch
                                cyc_o <= 1'b0;
1803
                                stb_o <= 1'b0;
1804
                                sel_o <= 8'h00;
1805 19 robfinch
                                wData <= dat_i;
1806 13 robfinch
                        end
1807
                `LHU:
1808
                        begin
1809 14 robfinch
                                cyc_o <= 1'b0;
1810
                                stb_o <= 1'b0;
1811
                                sel_o <= 8'h00;
1812 19 robfinch
                                wData <= sel_o[7] ? dat_i[63:32] : dat_i[31: 0];
1813 13 robfinch
                        end
1814
                `LC:
1815
                        begin
1816 14 robfinch
                                cyc_o <= 1'b0;
1817
                                stb_o <= 1'b0;
1818
                                sel_o <= 8'h00;
1819
                                case(sel_o)
1820 19 robfinch
                                8'b00000011:    wData <= {{48{dat_i[15]}},dat_i[15: 0]};
1821
                                8'b00001100:    wData <= {{48{dat_i[31]}},dat_i[31:16]};
1822
                                8'b00110000:    wData <= {{48{dat_i[47]}},dat_i[47:32]};
1823
                                8'b11000000:    wData <= {{48{dat_i[63]}},dat_i[63:48]};
1824
                                default:        wData <= 64'hDEADDEADDEADDEAD;
1825 14 robfinch
                                endcase
1826 13 robfinch
                        end
1827
                `LCU:
1828
                        begin
1829 14 robfinch
                                cyc_o <= 1'b0;
1830
                                stb_o <= 1'b0;
1831
                                sel_o <= 8'h00;
1832
                                case(sel_o)
1833 19 robfinch
                                8'b00000011:    wData <= dat_i[15: 0];
1834
                                8'b00001100:    wData <= dat_i[31:16];
1835
                                8'b00110000:    wData <= dat_i[47:32];
1836
                                8'b11000000:    wData <= dat_i[63:48];
1837
                                default:        wData <= 64'hDEADDEADDEADDEAD;
1838 14 robfinch
                                endcase
1839 13 robfinch
                        end
1840
                `LB:
1841
                        begin
1842 14 robfinch
                                cyc_o <= 1'b0;
1843
                                stb_o <= 1'b0;
1844
                                sel_o <= 8'h00;
1845
                                case(sel_o)
1846 19 robfinch
                                8'b00000001:    wData <= {{56{dat_i[ 7]}},dat_i[ 7: 0]};
1847
                                8'b00000010:    wData <= {{56{dat_i[15]}},dat_i[15: 8]};
1848
                                8'b00000100:    wData <= {{56{dat_i[23]}},dat_i[23:16]};
1849
                                8'b00001000:    wData <= {{56{dat_i[31]}},dat_i[31:24]};
1850
                                8'b00010000:    wData <= {{56{dat_i[39]}},dat_i[39:32]};
1851
                                8'b00100000:    wData <= {{56{dat_i[47]}},dat_i[47:40]};
1852
                                8'b01000000:    wData <= {{56{dat_i[55]}},dat_i[55:48]};
1853
                                8'b10000000:    wData <= {{56{dat_i[63]}},dat_i[63:56]};
1854
                                default:        wData <= 64'hDEADDEADDEADDEAD;
1855 14 robfinch
                                endcase
1856 13 robfinch
                        end
1857
                `LBU:
1858
                        begin
1859 14 robfinch
                                cyc_o <= 1'b0;
1860
                                stb_o <= 1'b0;
1861
                                sel_o <= 8'h00;
1862
                                case(sel_o)
1863 19 robfinch
                                8'b00000001:    wData <= dat_i[ 7: 0];
1864
                                8'b00000010:    wData <= dat_i[15: 8];
1865
                                8'b00000100:    wData <= dat_i[23:16];
1866
                                8'b00001000:    wData <= dat_i[31:24];
1867
                                8'b00010000:    wData <= dat_i[39:32];
1868
                                8'b00100000:    wData <= dat_i[47:40];
1869
                                8'b01000000:    wData <= dat_i[55:48];
1870
                                8'b10000000:    wData <= dat_i[63:56];
1871
                                default:        wData <= 64'hDEADDEADDEADDEAD;
1872 14 robfinch
                                endcase
1873 13 robfinch
                        end
1874
                default:        ;
1875
                endcase
1876
        end
1877
end
1878
 
1879
wrhit <= 1'b0;
1880
//---------------------------------------------------------
1881
// MEMORY:
1882 14 robfinch
// - I/O instructions are finished
1883
// - store instructions are started
1884
// - missed loads are started
1885 13 robfinch
// On a data cache hit for a load, the load is essentially
1886 14 robfinch
// finished in this stage. We switch the opcode to 'NOPI'
1887 13 robfinch
// to cause the pipeline to advance as if a NOPs were
1888
// present.
1889
//---------------------------------------------------------
1890
if (advanceM1) begin
1891
        m2Opcode <= m1Opcode;
1892
        m2Func <= m1Func;
1893
        m2Addr <= pea;
1894
        m2Data <= m1Data;
1895 14 robfinch
        m2hwxtype <= m1hwxtype;
1896 13 robfinch
        m2extype <= m1extype;
1897
        m2Rt <= m1Rt;
1898
        m2pc <= m1pc;
1899 16 robfinch
        m2pcv <= m1pcv;
1900 13 robfinch
        m2clkoff <= m1clkoff;
1901
        m2Fip <= m1Fip;
1902
 
1903
        m1Rt <= 9'd0;
1904
        m1Opcode <= `NOPI;
1905
        m1Func <= 7'd0;
1906
        m1Data <= 64'd0;
1907
        m1clkoff <= 1'b0;
1908
        m1pc <= 64'd0;
1909
        m1IsCacheElement <= 1'b0;
1910
        m1extype <= `EX_NON;
1911
 
1912
        if (m1extype == `EX_NON) begin
1913
                case(m1Opcode)
1914
                `MISC:
1915
                        case(m1Func)
1916 19 robfinch
`ifdef TLB
1917 14 robfinch
                        `TLBP:
1918
                                begin
1919
                                        Index[63] <= ~|DMatch;
1920
                                end
1921 13 robfinch
                        `TLBR:
1922
                                begin
1923
                                        TLBPageMask <= ITLBPageMask[i];
1924
                                        TLBVirtPage <= ITLBVirtPage[i];
1925 14 robfinch
                                        TLBPhysPage0 <= ITLBPhysPage0[i];
1926
                                        TLBPhysPage1 <= ITLBPhysPage1[i];
1927 13 robfinch
                                        TLBASID <= ITLBASID[i];
1928
                                        TLBG <= ITLBG[i];
1929 14 robfinch
                                        TLBD <= ITLBD[i];
1930
                                        TLBValid <= ITLBValid[i];
1931 13 robfinch
                                end
1932
                        `TLBWI,`TLBWR:
1933
                                begin
1934 14 robfinch
                                        ITLBValid[i] <= TLBValid;
1935 13 robfinch
                                        ITLBVirtPage[i] <= TLBVirtPage;
1936 14 robfinch
                                        ITLBPhysPage0[i] <= TLBPhysPage0;
1937
                                        ITLBPhysPage1[i] <= TLBPhysPage1;
1938 13 robfinch
                                        ITLBPageMask[i] <= TLBPageMask;
1939
                                        ITLBASID[i] <= TLBASID;
1940 14 robfinch
                                        ITLBD[i] <= TLBD;
1941
                                        ITLBG[i] <= TLBG;
1942 13 robfinch
                                end
1943 19 robfinch
`endif
1944 13 robfinch
                        endcase
1945
                `INW:
1946
                        begin
1947 14 robfinch
                                cyc_o <= 1'b0;
1948 13 robfinch
                                stb_o <= 1'b0;
1949 14 robfinch
                                sel_o <= 8'h00;
1950
                                m2Data <= dat_i;
1951
                                m2Opcode <= `NOPI;
1952 13 robfinch
                        end
1953
                `INH:
1954
                        begin
1955
                                cyc_o <= 1'b0;
1956
                                stb_o <= 1'b0;
1957 14 robfinch
                                sel_o <= 8'h00;
1958
                                m2Data <= sel_o[7] ? {{32{dat_i[63]}},dat_i[63:32]}:{{32{dat_i[31]}},dat_i[31: 0]};
1959
                                m2Opcode <= `NOPI;
1960 13 robfinch
                        end
1961 14 robfinch
                `INHU:
1962
                        begin
1963
                                cyc_o <= 1'b0;
1964
                                stb_o <= 1'b0;
1965
                                sel_o <= 8'h00;
1966
                                m2Data <= sel_o[7] ? dat_i[63:32] : dat_i[31: 0];
1967
                                m2Opcode <= `NOPI;
1968
                        end
1969 13 robfinch
                `INCH:
1970
                        begin
1971
                                cyc_o <= 1'b0;
1972
                                stb_o <= 1'b0;
1973 14 robfinch
                                sel_o <= 8'h00;
1974 13 robfinch
                                case(sel_o)
1975 14 robfinch
                                8'b00000011:    m2Data <= {{48{dat_i[15]}},dat_i[15: 0]};
1976
                                8'b00001100:    m2Data <= {{48{dat_i[31]}},dat_i[31:16]};
1977
                                8'b00110000:    m2Data <= {{48{dat_i[47]}},dat_i[47:32]};
1978
                                8'b11000000:    m2Data <= {{48{dat_i[63]}},dat_i[63:48]};
1979 13 robfinch
                                default:        m2Data <= 64'hDEADDEADDEADDEAD;
1980
                                endcase
1981 14 robfinch
                                m2Opcode <= `NOPI;
1982 13 robfinch
                        end
1983 14 robfinch
                `INCU:
1984
                        begin
1985
                                cyc_o <= 1'b0;
1986
                                stb_o <= 1'b0;
1987
                                sel_o <= 8'h00;
1988
                                case(sel_o)
1989
                                8'b00000011:    m2Data <= dat_i[15: 0];
1990
                                8'b00001100:    m2Data <= dat_i[31:16];
1991
                                8'b00110000:    m2Data <= dat_i[47:32];
1992
                                8'b11000000:    m2Data <= dat_i[63:48];
1993
                                default:        m2Data <= 64'hDEADDEADDEADDEAD;
1994
                                endcase
1995
                                m2Opcode <= `NOPI;
1996
                        end
1997 13 robfinch
                `INB:
1998
                        begin
1999
                                cyc_o <= 1'b0;
2000
                                stb_o <= 1'b0;
2001 14 robfinch
                                sel_o <= 8'h00;
2002 13 robfinch
                                case(sel_o)
2003 14 robfinch
                                8'b00000001:    m2Data <= {{56{dat_i[ 7]}},dat_i[ 7: 0]};
2004
                                8'b00000010:    m2Data <= {{56{dat_i[15]}},dat_i[15: 8]};
2005
                                8'b00000100:    m2Data <= {{56{dat_i[23]}},dat_i[23:16]};
2006
                                8'b00001000:    m2Data <= {{56{dat_i[31]}},dat_i[31:24]};
2007
                                8'b00010000:    m2Data <= {{56{dat_i[39]}},dat_i[39:32]};
2008
                                8'b00100000:    m2Data <= {{56{dat_i[47]}},dat_i[47:40]};
2009
                                8'b01000000:    m2Data <= {{56{dat_i[55]}},dat_i[55:48]};
2010
                                8'b10000000:    m2Data <= {{56{dat_i[63]}},dat_i[63:56]};
2011 13 robfinch
                                default:        m2Data <= 64'hDEADDEADDEADDEAD;
2012
                                endcase
2013 14 robfinch
                                m2Opcode <= `NOPI;
2014 13 robfinch
                        end
2015 14 robfinch
                `INBU:
2016 13 robfinch
                        begin
2017 14 robfinch
                                cyc_o <= 1'b0;
2018 13 robfinch
                                stb_o <= 1'b0;
2019 14 robfinch
                                sel_o <= 8'h00;
2020
                                case(sel_o)
2021
                                8'b00000001:    m2Data <= dat_i[ 7: 0];
2022
                                8'b00000010:    m2Data <= dat_i[15: 8];
2023
                                8'b00000100:    m2Data <= dat_i[23:16];
2024
                                8'b00001000:    m2Data <= dat_i[31:24];
2025
                                8'b00010000:    m2Data <= dat_i[39:32];
2026
                                8'b00100000:    m2Data <= dat_i[47:40];
2027
                                8'b01000000:    m2Data <= dat_i[55:48];
2028
                                8'b10000000:    m2Data <= dat_i[63:56];
2029
                                default:        m2Data <= 64'hDEADDEADDEADDEAD;
2030
                                endcase
2031
                                m2Opcode <= `NOPI;
2032 13 robfinch
                        end
2033 14 robfinch
                `OUTW,`OUTH,`OUTC,`OUTB:
2034 13 robfinch
                        begin
2035
                                cyc_o <= 1'b0;
2036
                                stb_o <= 1'b0;
2037
                                we_o <= 1'b0;
2038 14 robfinch
                                sel_o <= 8'h00;
2039
                                m2Opcode <= `NOPI;
2040 13 robfinch
                        end
2041 14 robfinch
 
2042 21 robfinch
                `LW,`LM,`LFD:
2043 13 robfinch
                        if (!m1IsCacheElement) begin
2044 14 robfinch
                                cyc_o <= 1'b1;
2045
                                stb_o <= 1'b1;
2046
                                sel_o <= 8'hFF;
2047
                                adr_o <= {pea[63:3],3'b000};
2048
                                m2Addr <= {pea[63:3],3'b000};
2049 13 robfinch
                        end
2050
                        else if (dhit) begin
2051 14 robfinch
                                m2Opcode <= `NOPI;
2052 13 robfinch
                                m2Data <= cdat;
2053
                        end
2054 21 robfinch
`ifdef ADDRESS_RESERVATION
2055 13 robfinch
                `LWR:
2056
                        if (!m1IsCacheElement) begin
2057
                                rsv_o <= 1'b1;
2058
                                resv_address <= pea[63:5];
2059 14 robfinch
                                cyc_o <= 1'b1;
2060
                                stb_o <= 1'b1;
2061
                                sel_o <= 8'hFF;
2062
                                adr_o <= {pea[63:3],3'b000};
2063
                                m2Addr <= {pea[63:3],3'b000};
2064 13 robfinch
                        end
2065
                        else if (dhit) begin
2066 14 robfinch
                                m2Opcode <= `NOPI;
2067 13 robfinch
                                m2Data <= cdat;
2068
                                rsv_o <= 1'b1;
2069
                                resv_address <= pea[63:5];
2070
                        end
2071 21 robfinch
`endif
2072
                `LH,`LF:
2073 13 robfinch
                        if (!m1IsCacheElement) begin
2074 14 robfinch
                                cyc_o <= 1'b1;
2075
                                stb_o <= 1'b1;
2076
                                sel_o <= pea[2] ? 8'b11110000 : 8'b00001111;
2077
                                adr_o <= {pea[63:2],2'b00};
2078
                                m2Addr <= {pea[63:2],2'b00};
2079 13 robfinch
                        end
2080
                        else if (dhit) begin
2081 14 robfinch
                                m2Opcode <= `NOPI;
2082 13 robfinch
                                if (pea[1])
2083
                                        m2Data <= {{32{cdat[31]}},cdat[31:0]};
2084
                                else
2085
                                        m2Data <= {{32{cdat[63]}},cdat[63:32]};
2086
                        end
2087 14 robfinch
 
2088 13 robfinch
                `LHU:
2089
                        if (!m1IsCacheElement) begin
2090 14 robfinch
                                cyc_o <= 1'b1;
2091
                                stb_o <= 1'b1;
2092
                                sel_o <= pea[2] ? 8'b11110000 : 8'b00001111;
2093
                                adr_o <= {pea[63:2],2'b00};
2094
                                m2Addr <= {pea[63:2],2'b00};
2095 13 robfinch
                        end
2096
                        else if (dhit) begin
2097 14 robfinch
                                m2Opcode <= `NOPI;
2098 13 robfinch
                                if (pea[1])
2099
                                        m2Data <= {32'd0,cdat};
2100
                                else
2101
                                        m2Data <= {32'd0,cdat[63:32]};
2102
                        end
2103 14 robfinch
 
2104 13 robfinch
                `LC:
2105
                        if (!m1IsCacheElement) begin
2106 14 robfinch
                                cyc_o <= 1'b1;
2107
                                stb_o <= 1'b1;
2108
                                case(pea[2:1])
2109
                                2'b00:  sel_o <= 8'b00000011;
2110
                                2'b01:  sel_o <= 8'b00001100;
2111
                                2'b10:  sel_o <= 8'b00110000;
2112
                                2'b11:  sel_o <= 8'b11000000;
2113
                                endcase
2114
                                adr_o <= {pea[63:1],1'b0};
2115
                                m2Addr <= {pea[63:1],1'b0};
2116 13 robfinch
                        end
2117
                        else if (dhit) begin
2118 21 robfinch
                                $display("dhit=1, cdat=%h",cdat);
2119 14 robfinch
                                m2Opcode <= `NOPI;
2120 13 robfinch
                                case(pea[2:1])
2121
                                2'd0:   m2Data <= {{48{cdat[15]}},cdat[15:0]};
2122
                                2'd1:   m2Data <= {{48{cdat[31]}},cdat[31:16]};
2123
                                2'd2:   m2Data <= {{48{cdat[47]}},cdat[47:32]};
2124
                                2'd3:   m2Data <= {{48{cdat[63]}},cdat[63:48]};
2125
                                endcase
2126
                        end
2127 14 robfinch
 
2128 13 robfinch
                `LCU:
2129
                        if (!m1IsCacheElement) begin
2130 14 robfinch
                                cyc_o <= 1'b1;
2131
                                stb_o <= 1'b1;
2132
                                case(pea[2:1])
2133
                                2'b00:  sel_o <= 8'b00000011;
2134
                                2'b01:  sel_o <= 8'b00001100;
2135
                                2'b10:  sel_o <= 8'b00110000;
2136
                                2'b11:  sel_o <= 8'b11000000;
2137
                                endcase
2138
                                adr_o <= {pea[63:1],1'b0};
2139
                                m2Addr <= {pea[63:1],1'b0};
2140 13 robfinch
                        end
2141
                        else if (dhit) begin
2142 14 robfinch
                                m2Opcode <= `NOPI;
2143 13 robfinch
                                case(pea[2:1])
2144
                                2'd0:   m2Data <= {48'd0,cdat[15: 0]};
2145
                                2'd1:   m2Data <= {48'd0,cdat[31:16]};
2146
                                2'd2:   m2Data <= {48'd0,cdat[47:32]};
2147
                                2'd3:   m2Data <= {48'd0,cdat[63:48]};
2148
                                endcase
2149
                        end
2150 14 robfinch
 
2151 13 robfinch
                `LB:
2152
                        if (!m1IsCacheElement) begin
2153 14 robfinch
                                $display("Load byte:");
2154
                                cyc_o <= 1'b1;
2155
                                stb_o <= 1'b1;
2156
                                case(pea[2:0])
2157
                                3'b000: sel_o <= 8'b00000001;
2158
                                3'b001: sel_o <= 8'b00000010;
2159
                                3'b010: sel_o <= 8'b00000100;
2160
                                3'b011: sel_o <= 8'b00001000;
2161
                                3'b100: sel_o <= 8'b00010000;
2162
                                3'b101: sel_o <= 8'b00100000;
2163
                                3'b110: sel_o <= 8'b01000000;
2164
                                3'b111: sel_o <= 8'b10000000;
2165
                                endcase
2166
                                adr_o <= pea;
2167
                                m2Addr <= pea;
2168 13 robfinch
                        end
2169
                        else if (dhit) begin
2170 14 robfinch
                                m2Opcode <= `NOPI;
2171 13 robfinch
                                case(pea[2:0])
2172
                                3'b000: m2Data <= {{56{cdat[ 7]}},cdat[ 7: 0]};
2173
                                3'b001: m2Data <= {{56{cdat[15]}},cdat[15: 8]};
2174
                                3'b010: m2Data <= {{56{cdat[23]}},cdat[23:16]};
2175
                                3'b011: m2Data <= {{56{cdat[31]}},cdat[31:24]};
2176
                                3'b100: m2Data <= {{56{cdat[39]}},cdat[39:32]};
2177
                                3'b101: m2Data <= {{56{cdat[47]}},cdat[47:40]};
2178
                                3'b110: m2Data <= {{56{cdat[55]}},cdat[55:48]};
2179
                                3'b111: m2Data <= {{56{cdat[63]}},cdat[63:56]};
2180
                                endcase
2181
                        end
2182 14 robfinch
 
2183 13 robfinch
                `LBU:
2184
                        if (!m1IsCacheElement) begin
2185 14 robfinch
                                cyc_o <= 1'b1;
2186
                                stb_o <= 1'b1;
2187
                                case(pea[2:0])
2188
                                3'b000: sel_o <= 8'b00000001;
2189
                                3'b001: sel_o <= 8'b00000010;
2190
                                3'b010: sel_o <= 8'b00000100;
2191
                                3'b011: sel_o <= 8'b00001000;
2192
                                3'b100: sel_o <= 8'b00010000;
2193
                                3'b101: sel_o <= 8'b00100000;
2194
                                3'b110: sel_o <= 8'b01000000;
2195
                                3'b111: sel_o <= 8'b10000000;
2196
                                endcase
2197
                                adr_o <= pea;
2198
                                m2Addr <= pea;
2199 13 robfinch
                        end
2200
                        else if (dhit) begin
2201 14 robfinch
                                m2Opcode <= `NOPI;
2202 13 robfinch
                                case(pea[2:0])
2203
                                3'b000: m2Data <= {56'd0,cdat[ 7: 0]};
2204
                                3'b001: m2Data <= {56'd0,cdat[15: 8]};
2205
                                3'b010: m2Data <= {56'd0,cdat[23:16]};
2206
                                3'b011: m2Data <= {56'd0,cdat[31:23]};
2207
                                3'b100: m2Data <= {56'd0,cdat[39:32]};
2208
                                3'b101: m2Data <= {56'd0,cdat[47:40]};
2209
                                3'b110: m2Data <= {56'd0,cdat[55:48]};
2210
                                3'b111: m2Data <= {56'd0,cdat[63:56]};
2211
                                endcase
2212
                        end
2213 14 robfinch
 
2214 21 robfinch
                `SW,`SM,`SFD:
2215 13 robfinch
                        begin
2216 21 robfinch
                                $display("SW/SM");
2217 14 robfinch
                                m2Addr <= {pea[63:3],3'b000};
2218 13 robfinch
                                wrhit <= dhit;
2219 19 robfinch
`ifdef TLB
2220
                                if (!m1UnmappedDataArea & !q[3])
2221
                                        ITLBD[{q[2:0],pea[15:13]}] <= 1'b1;
2222
`endif
2223 21 robfinch
`ifdef ADDRESS_RESERVATION
2224 13 robfinch
                                if (resv_address==pea[63:5])
2225
                                        resv_address <= 59'd0;
2226 21 robfinch
`endif
2227 14 robfinch
                                cyc_o <= 1'b1;
2228
                                stb_o <= 1'b1;
2229
                                we_o <= 1'b1;
2230
                                sel_o <= 8'hFF;
2231
                                adr_o <= {pea[63:3],3'b000};
2232 19 robfinch
                                dat_o <= m1Data;
2233 13 robfinch
                        end
2234 14 robfinch
 
2235 21 robfinch
                `SH,`SF:
2236 14 robfinch
                        begin
2237
                                wrhit <= dhit;
2238
                                m2Addr <= {pea[63:2],2'b00};
2239 19 robfinch
`ifdef TLB
2240
                                if (!m1UnmappedDataArea & !q[3])
2241
                                        ITLBD[{q[2:0],pea[15:13]}] <= 1'b1;
2242
`endif
2243 21 robfinch
`ifdef ADDRESS_RESERVATION
2244 14 robfinch
                                if (resv_address==pea[63:5])
2245
                                        resv_address <= 59'd0;
2246 21 robfinch
`endif
2247 14 robfinch
                                cyc_o <= 1'b1;
2248
                                stb_o <= 1'b1;
2249
                                we_o <= 1'b1;
2250
                                sel_o <= pea[2] ? 8'b11110000 : 8'b00001111;
2251
                                adr_o <= {pea[63:2],2'b00};
2252 19 robfinch
                                dat_o <= {2{m1Data[31:0]}};
2253 14 robfinch
                        end
2254
 
2255 13 robfinch
                `SC:
2256
                        begin
2257
                                $display("Storing char to %h, ea=%h",pea,ea);
2258
                                wrhit <= dhit;
2259
                                m2Addr <= {pea[63:2],2'b00};
2260 19 robfinch
`ifdef TLB
2261
                                if (!m1UnmappedDataArea & !q[3])
2262
                                        ITLBD[{q[2:0],pea[15:13]}] <= 1'b1;
2263
`endif
2264 21 robfinch
`ifdef ADDRESS_RESERVATION
2265 13 robfinch
                                if (resv_address==pea[63:5])
2266
                                        resv_address <= 59'd0;
2267 21 robfinch
`endif
2268 14 robfinch
                                cyc_o <= 1'b1;
2269
                                stb_o <= 1'b1;
2270
                                we_o <= 1'b1;
2271
                                case(pea[2:1])
2272
                                2'b00:  sel_o <= 8'b00000011;
2273
                                2'b01:  sel_o <= 8'b00001100;
2274
                                2'b10:  sel_o <= 8'b00110000;
2275
                                2'b11:  sel_o <= 8'b11000000;
2276
                                endcase
2277
                                adr_o <= {pea[63:1],1'b0};
2278 19 robfinch
                                dat_o <= {4{m1Data[15:0]}};
2279 13 robfinch
                        end
2280 14 robfinch
 
2281 13 robfinch
                `SB:
2282
                        begin
2283
                                wrhit <= dhit;
2284
                                m2Addr <= {pea[63:2],2'b00};
2285 21 robfinch
`ifdef ADDRESS_RESERVATION
2286 13 robfinch
                                if (resv_address==pea[63:5])
2287
                                        resv_address <= 59'd0;
2288 21 robfinch
`endif
2289 19 robfinch
`ifdef TLB
2290
                                if (!m1UnmappedDataArea & !q[3])
2291
                                        ITLBD[{q[2:0],pea[15:13]}] <= 1'b1;
2292
`endif
2293 14 robfinch
                                cyc_o <= 1'b1;
2294
                                stb_o <= 1'b1;
2295
                                we_o <= 1'b1;
2296
                                case(pea[2:0])
2297
                                3'b000: sel_o <= 8'b00000001;
2298
                                3'b001: sel_o <= 8'b00000010;
2299
                                3'b010: sel_o <= 8'b00000100;
2300
                                3'b011: sel_o <= 8'b00001000;
2301
                                3'b100: sel_o <= 8'b00010000;
2302
                                3'b101: sel_o <= 8'b00100000;
2303
                                3'b110: sel_o <= 8'b01000000;
2304
                                3'b111: sel_o <= 8'b10000000;
2305
                                endcase
2306
                                adr_o <= {pea[63:2],2'b00};
2307 19 robfinch
                                dat_o <= {8{m1Data[7:0]}};
2308 13 robfinch
                        end
2309 14 robfinch
 
2310 21 robfinch
`ifdef ADDRESS_RESERVATION
2311 13 robfinch
                `SWC:
2312
                        begin
2313
                                rsf <= 1'b0;
2314
                                if (resv_address==pea[63:5]) begin
2315 19 robfinch
`ifdef TLB
2316
                                        if (!m1UnmappedDataArea & !q[3])
2317
                                                ITLBD[{q[2:0],pea[15:13]}] <= 1'b1;
2318
`endif
2319 13 robfinch
                                        wrhit <= dhit;
2320 14 robfinch
                                        m2Addr <= {pea[63:3],3'b00};
2321
                                        cyc_o <= 1'b1;
2322
                                        stb_o <= 1'b1;
2323
                                        we_o <= 1'b1;
2324
                                        sel_o <= 8'hFF;
2325
                                        adr_o <= {pea[63:3],3'b000};
2326 19 robfinch
                                        dat_o <= m1Data;
2327 13 robfinch
                                        resv_address <= 59'd0;
2328
                                        rsf <= 1'b1;
2329
                                end
2330
                                else
2331
                                        m2Opcode <= `NOPI;
2332
                        end
2333 21 robfinch
`endif
2334 13 robfinch
                endcase
2335
        end
2336
end
2337
 
2338
//---------------------------------------------------------
2339
// EXECUTE:
2340
// - perform datapath operation
2341 14 robfinch
// - perform virtual to physical address translation.
2342 13 robfinch
//---------------------------------------------------------
2343
if (advanceX) begin
2344 14 robfinch
        m1hwxtype <= xhwxtype;
2345 13 robfinch
        m1Fip <= xFip;
2346
        m1extype <= xextype;
2347
        m1Opcode <= xOpcode;
2348
        m1Func <= xFunc;
2349
        m1Rt <= xRt;
2350
        m1Data <= xData;
2351
        m1IsCacheElement <= xisCacheElement;
2352
        if (xOpcode==`MOVZ && !aeqz) begin
2353
                m1Rt <= 9'd0;
2354
                m1Data <= 64'd0;
2355
        end
2356
        if (xOpcode==`MOVNZ && aeqz) begin
2357
                m1Rt <= 9'd0;
2358
                m1Data <= 64'd0;
2359
        end
2360
        m1pc <= xpc;
2361 16 robfinch
        m1pcv <= xpcv;
2362 13 robfinch
        xRt <= 9'd0;
2363
        a <= 64'd0;
2364
        b <= 64'd0;
2365
        imm <= 64'd0;
2366
        xextype <= `EX_NON;
2367
        if (xOpcode[6:4]!=`IMM) begin
2368
                xIR <= `NOP_INSN;
2369
        end
2370
//      xpc <= 64'd0;
2371
        case(xOpcode)
2372
        `MISC:
2373
                case(xFunc)
2374
                `WAIT:  m1clkoff <= 1'b1;
2375 19 robfinch
                `ICACHE_ON:             ICacheOn <= 1'b1;
2376
                `ICACHE_OFF:    ICacheOn <= 1'b0;
2377 21 robfinch
                `DCACHE_ON:             dcache_on <= 1'b1;
2378
                `DCACHE_OFF:    dcache_on <= 1'b0;
2379 19 robfinch
`ifdef TLB
2380 14 robfinch
                `TLBP:  ea <= TLBVirtPage;
2381 13 robfinch
                `TLBR,`TLBWI:
2382
                        begin
2383 19 robfinch
                                i <= {Index[2:0],TLBVirtPage[15:13]};
2384 13 robfinch
                        end
2385
                `TLBWR:
2386
                        begin
2387 19 robfinch
                                i <= {Random,TLBVirtPage[15:13]};
2388 13 robfinch
                        end
2389 19 robfinch
`endif
2390 13 robfinch
                default:        ;
2391
                endcase
2392
        `R:
2393
                case(xFunc)
2394
                `MTSPR:
2395
                        case(xIR[12:7])
2396 19 robfinch
`ifdef TLB
2397
                        `Wired:                 Wired <= a[2:0];
2398
                        `TLBIndex:              Index <= a[2:0];
2399
                        `TLBVirtPage:   TLBVirtPage <= a[63:13];
2400
                        `TLBPhysPage0:  TLBPhysPage0 <= a[63:13];
2401
                        `TLBPhysPage1:  TLBPhysPage1 <= a[63:13];
2402
                        `TLBPageMask:   TLBPageMask <= a[24:13];
2403 14 robfinch
                        `TLBASID:               begin
2404 19 robfinch
                                                        TLBValid <= a[0];
2405
                                                        TLBD <= a[1];
2406
                                                        TLBG <= a[2];
2407
                                                        TLBASID <= a[15:8];
2408 14 robfinch
                                                        end
2409 19 robfinch
                        `PageTableAddr: PageTableAddr <= a[63:13];
2410
                        `BadVAddr:              BadVAddr <= a[63:13];
2411
`endif
2412
                        `ASID:                  ASID <= a[7:0];
2413
                        `EPC:                   EPC <= a;
2414
                        `TBA:                   TBA <= {a[63:12],12'h000};
2415
                        `AXC:                   AXC <= a[3:0];
2416
                        `NON_ICACHE_SEG:        nonICacheSeg <= a[63:32];
2417 21 robfinch
                        `FPCR:                  rm <= a[31:30];
2418
                        `IPC:                   IPC <= a;
2419 13 robfinch
                        default:        ;
2420
                        endcase
2421
                `OMG:   mutex_gate[a[5:0]] <= 1'b1;
2422
                `CMG:   mutex_gate[a[5:0]] <= 1'b0;
2423
                `OMGI:  mutex_gate[xIR[12:7]] <= 1'b1;
2424
                `CMGI:  mutex_gate[xIR[12:7]] <= 1'b0;
2425
                default:        ;
2426
                endcase
2427
        `CALL:  m1Data <= fnIncPC(xpc);
2428
        `INW:
2429
                        begin
2430
                        cyc_o <= 1'b1;
2431
                        stb_o <= 1'b1;
2432 14 robfinch
                        sel_o <= 8'hFF;
2433 13 robfinch
                        adr_o <= {xData[63:3],3'b000};
2434
                        end
2435 14 robfinch
        `INH,`INHU:
2436 13 robfinch
                        begin
2437
                        cyc_o <= 1'b1;
2438
                        stb_o <= 1'b1;
2439 14 robfinch
                        sel_o <= xData[2] ? 8'b11110000 : 8'b00001111;
2440 13 robfinch
                        adr_o <= {xData[63:2],2'b00};
2441
                        end
2442 14 robfinch
        `INCH,`INCU:
2443 13 robfinch
                        begin
2444
                        cyc_o <= 1'b1;
2445
                        stb_o <= 1'b1;
2446 14 robfinch
                        case(xData[2:1])
2447
                        2'b00:  sel_o <= 8'b00000011;
2448
                        2'b01:  sel_o <= 8'b00001100;
2449
                        2'b10:  sel_o <= 8'b00110000;
2450
                        2'b11:  sel_o <= 8'b11000000;
2451 13 robfinch
                        endcase
2452
                        adr_o <= {xData[63:1],1'b0};
2453
                        end
2454 14 robfinch
        `INB,`INBU:
2455 13 robfinch
                        begin
2456
                        cyc_o <= 1'b1;
2457
                        stb_o <= 1'b1;
2458 14 robfinch
                        case(xData[2:0])
2459
                        3'b000: sel_o <= 8'b00000001;
2460
                        3'b001: sel_o <= 8'b00000010;
2461
                        3'b010: sel_o <= 8'b00000100;
2462
                        3'b011: sel_o <= 8'b00001000;
2463
                        3'b100: sel_o <= 8'b00010000;
2464
                        3'b101: sel_o <= 8'b00100000;
2465
                        3'b110: sel_o <= 8'b01000000;
2466
                        3'b111: sel_o <= 8'b10000000;
2467 13 robfinch
                        endcase
2468
                        adr_o <= xData;
2469
                        end
2470
        `OUTW:
2471
                        begin
2472
                        cyc_o <= 1'b1;
2473
                        stb_o <= 1'b1;
2474
                        we_o <= 1'b1;
2475 14 robfinch
                        sel_o <= 8'hFF;
2476 13 robfinch
                        adr_o <= {xData[63:3],3'b000};
2477 14 robfinch
                        dat_o <= b;
2478 13 robfinch
                        end
2479
        `OUTH:
2480
                        begin
2481
                        cyc_o <= 1'b1;
2482
                        stb_o <= 1'b1;
2483
                        we_o <= 1'b1;
2484 14 robfinch
                        sel_o <= xData[2] ? 8'b11110000 : 8'b00001111;
2485 13 robfinch
                        adr_o <= {xData[63:2],2'b00};
2486 14 robfinch
                        dat_o <= {2{b[31:0]}};
2487 13 robfinch
                        end
2488
        `OUTC:
2489
                        begin
2490
                        cyc_o <= 1'b1;
2491
                        stb_o <= 1'b1;
2492
                        we_o <= 1'b1;
2493 14 robfinch
                        case(xData[2:1])
2494
                        2'b00:  sel_o <= 8'b00000011;
2495
                        2'b01:  sel_o <= 8'b00001100;
2496
                        2'b10:  sel_o <= 8'b00110000;
2497
                        2'b11:  sel_o <= 8'b11000000;
2498 13 robfinch
                        endcase
2499
                        adr_o <= {xData[63:1],1'b0};
2500 14 robfinch
                        dat_o <= {4{b[15:0]}};
2501 13 robfinch
                        end
2502
        `OUTB:
2503
                        begin
2504
                        cyc_o <= 1'b1;
2505
                        stb_o <= 1'b1;
2506
                        we_o <= 1'b1;
2507 14 robfinch
                        case(xData[2:0])
2508
                        3'b000: sel_o <= 8'b00000001;
2509
                        3'b001: sel_o <= 8'b00000010;
2510
                        3'b010: sel_o <= 8'b00000100;
2511
                        3'b011: sel_o <= 8'b00001000;
2512
                        3'b100: sel_o <= 8'b00010000;
2513
                        3'b101: sel_o <= 8'b00100000;
2514
                        3'b110: sel_o <= 8'b01000000;
2515
                        3'b111: sel_o <= 8'b10000000;
2516 13 robfinch
                        endcase
2517
                        adr_o <= xData;
2518 14 robfinch
                        dat_o <= {8{b[7:0]}};
2519 13 robfinch
                        end
2520 21 robfinch
        `LB,`LBU,`LC,`LCU,`LH,`LHU,`LW,`LWR,`LF,`LFD,`LM,
2521
        `SW,`SH,`SC,`SB,`SWC,`SF,`SFD,`SM:
2522 13 robfinch
                        begin
2523 19 robfinch
                        m1Data <= b;
2524 13 robfinch
                        ea <= xData;
2525
                        end
2526
        `MEMNDX:
2527
                        begin
2528
                        m1Opcode <= xFunc;
2529 19 robfinch
                        m1Data <= c;
2530 13 robfinch
                        ea <= xData;
2531
                        end
2532
        `DIVSI,`DIVUI:
2533
                if (b==64'd0) begin
2534
                        xextype <= `EX_DBZ;
2535
                end
2536
        default:        ;
2537
        endcase
2538 19 robfinch
`ifndef BRANCH_PREDICTION_SIMPLE
2539 13 robfinch
        // Update the branch history
2540
        if (isxBranch) begin
2541
                gbl_branch_hist <= {gbl_branch_hist,takb};
2542
                branch_history_table[bht_wa] <= xbits_new;
2543
        end
2544 19 robfinch
`endif
2545 13 robfinch
end
2546
 
2547
//---------------------------------------------------------
2548
// RFETCH:
2549
// Register fetch stage
2550
//---------------------------------------------------------
2551
if (advanceR) begin
2552 14 robfinch
        xAXC <= dAXC;
2553
        xhwxtype <= dhwxtype;
2554 13 robfinch
        xFip <= dFip;
2555
        xextype <= dextype;
2556 21 robfinch
        if (dOpcode==`R && dFunc==`MYST)
2557
                xIR <= nxt_c;
2558
        else
2559
                xIR <= dIR;
2560 13 robfinch
        xpc <= dpc;
2561 16 robfinch
        xpcv <= dpcv;
2562 13 robfinch
        xbranch_taken <= dbranch_taken;
2563
        dbranch_taken <= 1'b0;
2564
        dextype <= `EX_NON;
2565 21 robfinch
        if (dOpcode[6:4]!=`IMM && dOpcode!=`LM && dOpcode!=`SM) // IMM is "sticky"
2566 13 robfinch
                dIR <= `NOP_INSN;
2567
        dRa <= 9'd0;
2568
        dRb <= 9'd0;
2569
 
2570
        // Result forward muxes
2571
        casex(dRa)
2572
        9'bxxxx00000:   a <= 64'd0;
2573
        xRt:    a <= xData;
2574
        m1Rt:   a <= m1Data;
2575
        m2Rt:   a <= m2Data;
2576
        wRt:    a <= wData;
2577
        tRt:    a <= tData;
2578
        default:        a <= rfoa;
2579
        endcase
2580
        casex(dRb)
2581
        9'bxxxx00000:   b <= 64'd0;
2582
        xRt:    b <= disRightShift ? -xData[5:0] : xData;
2583
        m1Rt:   b <= disRightShift ? -m1Data[5:0] : m1Data;
2584
        m2Rt:   b <= disRightShift ? -m2Data[5:0] : m2Data;
2585
        wRt:    b <= disRightShift ? -wData[5:0] : wData;
2586
        tRt:    b <= disRightShift ? -tData[5:0] : tData;
2587
        default:        b <= disRightShift ? -rfob[5:0] : rfob;
2588
        endcase
2589
        if (dOpcode==`SHFTI)
2590
                case(dFunc)
2591
                `RORI:          b <= {58'd0,~dIR[24:19]+6'd1};
2592
                default:        b <= {58'd0,dIR[24:19]};
2593
                endcase
2594 21 robfinch
        c <= nxt_c;
2595 13 robfinch
 
2596
        // Set the target register
2597 14 robfinch
        casex(dOpcode)
2598 21 robfinch
        `R:
2599
                case(dFunc)
2600
                `MYST:          xRt <= {dAXC,dIR[19:15]};
2601
                default:        xRt <= {dAXC,dIR[29:25]};
2602
                endcase
2603 14 robfinch
        `SETLO:         xRt <= {dAXC,dIR[36:32]};
2604
        `SETHI:         xRt <= {dAXC,dIR[36:32]};
2605
        `RR:            xRt <= {dAXC,dIR[24:20]};
2606 13 robfinch
        `BTRI:          xRt <= 9'd0;
2607 21 robfinch
        `BTRR:
2608
                case(dIR[4:0])
2609
                `LOOP:  xRt <= {AXC,dIR[29:25]};
2610
                default: xRt <= 9'd0;
2611
                endcase
2612 13 robfinch
        `TRAPcc:        xRt <= 9'd0;
2613
        `TRAPcci:       xRt <= 9'd0;
2614
        `JMP:           xRt <= 9'd00;
2615 14 robfinch
        `CALL:          xRt <= {dAXC,5'd31};
2616
        `RET:           xRt <= {dAXC,dIR[24:20]};
2617 13 robfinch
        `MEMNDX:
2618
                case(dFunc)
2619 21 robfinch
                `SW,`SH,`SC,`SB,`SF,`SFD,
2620
                `OUTW,`OUTH,`OUTC,`OUTB:
2621 13 robfinch
                                xRt <= 9'd0;
2622 14 robfinch
                default:        xRt <= {dAXC,dIR[24:20]};
2623 13 robfinch
                endcase
2624 21 robfinch
        `SW,`SH,`SC,`SB,`SF,`SFD,       // but not SWC!
2625
        `OUTW,`OUTH,`OUTC,`OUTB:
2626 13 robfinch
                                xRt <= 9'd0;
2627
        `NOPI:          xRt <= 9'd0;
2628
        `BEQI,`BNEI,`BLTI,`BLEI,`BGTI,`BGEI,`BLTUI,`BLEUI,`BGTUI,`BGEUI:
2629
                                xRt <= 9'd0;
2630 21 robfinch
        `SM:            xRt <= 9'd0;
2631
        `LM:
2632
                casex(dIR[30:0])
2633
                31'bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx1:    xRt <= {AXC,5'd1};
2634
                31'bxxxxxxxxxxxxxxxxxxxxxxxxxxxxx10:    xRt <= {AXC,5'd2};
2635
                31'bxxxxxxxxxxxxxxxxxxxxxxxxxxxx100:    xRt <= {AXC,5'd3};
2636
                31'bxxxxxxxxxxxxxxxxxxxxxxxxxxx1000:    xRt <= {AXC,5'd4};
2637
                31'bxxxxxxxxxxxxxxxxxxxxxxxxxx10000:    xRt <= {AXC,5'd5};
2638
                31'bxxxxxxxxxxxxxxxxxxxxxxxxx100000:    xRt <= {AXC,5'd6};
2639
                31'bxxxxxxxxxxxxxxxxxxxxxxxx1000000:    xRt <= {AXC,5'd7};
2640
                31'bxxxxxxxxxxxxxxxxxxxxxxx10000000:    xRt <= {AXC,5'd8};
2641
                31'bxxxxxxxxxxxxxxxxxxxxxx100000000:    xRt <= {AXC,5'd9};
2642
                31'bxxxxxxxxxxxxxxxxxxxxx1000000000:    xRt <= {AXC,5'd10};
2643
                31'bxxxxxxxxxxxxxxxxxxxx10000000000:    xRt <= {AXC,5'd11};
2644
                31'bxxxxxxxxxxxxxxxxxxx100000000000:    xRt <= {AXC,5'd12};
2645
                31'bxxxxxxxxxxxxxxxxxx1000000000000:    xRt <= {AXC,5'd13};
2646
                31'bxxxxxxxxxxxxxxxxx10000000000000:    xRt <= {AXC,5'd14};
2647
                31'bxxxxxxxxxxxxxxxx100000000000000:    xRt <= {AXC,5'd15};
2648
                31'bxxxxxxxxxxxxxxx1000000000000000:    xRt <= {AXC,5'd16};
2649
                31'bxxxxxxxxxxxxxx10000000000000000:    xRt <= {AXC,5'd17};
2650
                31'bxxxxxxxxxxxxx100000000000000000:    xRt <= {AXC,5'd18};
2651
                31'bxxxxxxxxxxxx1000000000000000000:    xRt <= {AXC,5'd19};
2652
                31'bxxxxxxxxxxx10000000000000000000:    xRt <= {AXC,5'd20};
2653
                31'bxxxxxxxxxx100000000000000000000:    xRt <= {AXC,5'd21};
2654
                31'bxxxxxxxxx1000000000000000000000:    xRt <= {AXC,5'd22};
2655
                31'bxxxxxxxx10000000000000000000000:    xRt <= {AXC,5'd23};
2656
                31'bxxxxxxx100000000000000000000000:    xRt <= {AXC,5'd24};
2657
                31'bxxxxxx1000000000000000000000000:    xRt <= {AXC,5'd25};
2658
                31'bxxxxx10000000000000000000000000:    xRt <= {AXC,5'd26};
2659
                31'bxxxx100000000000000000000000000:    xRt <= {AXC,5'd27};
2660
                31'bxxx1000000000000000000000000000:    xRt <= {AXC,5'd28};
2661
                31'bxx10000000000000000000000000000:    xRt <= {AXC,5'd29};
2662
                31'bx100000000000000000000000000000:    xRt <= {AXC,5'd30};
2663
                31'b1000000000000000000000000000000:    xRt <= {AXC,5'd31};
2664
                default:        xRt <= 9'h000;
2665
                endcase
2666
 
2667 14 robfinch
        default:        xRt <= {dAXC,dIR[29:25]};
2668 13 robfinch
        endcase
2669
        if (dOpcode[6:4]==`IMM)
2670
                xRt <= 9'd0;
2671
 
2672
        // Set immediate value
2673
        if (xOpcode[6:4]==`IMM) begin
2674
                imm <= {xIR[38:0],dIR[24:0]};
2675
        end
2676
        else
2677
                case(dOpcode)
2678
                `BTRI:  imm <= {{44{dIR[19]}},dIR[19:0]};
2679
                `BEQI,`BNEI,`BLTI,`BLEI,`BGTI,`BGEI,`BLTUI,`BLEUI,`BGTUI,`BGEUI:
2680
                        imm <= {{46{dIR[17]}},dIR[17:0]};
2681
                `ANDI:  imm <= {39'h7FFFFFFFFF,dIR[24:0]};
2682
                `ORI:   imm <= {39'h0000000000,dIR[24:0]};
2683
                `XORI:  imm <= {39'h0000000000,dIR[24:0]};
2684 21 robfinch
                `RET:   imm <= {41'h00000000,dIR[19:0],3'b000};
2685 13 robfinch
                `MEMNDX:        imm <= {{51{dIR[19]}},dIR[19:7]};
2686
                default:        imm <= {{39{dIR[24]}},dIR[24:0]};
2687
                endcase
2688
        case(dOpcode)
2689
 
2690
        `MISC:
2691
                case(dFunc)
2692
                `SEI:   im <= 1'b1;
2693
                `CLI:   im <= 1'b0;
2694
                endcase
2695
        endcase
2696 21 robfinch
 
2697
        if ((dOpcode==`SM || dOpcode==`LM) && dIR[31:0]!=32'd0)
2698
                dIR <= ndIR;
2699 13 robfinch
end
2700
 
2701
//---------------------------------------------------------
2702
// IFETCH:
2703
// - check for external hardware interrupt
2704
// - fetch instruction
2705
// - increment PC
2706
// - set special register defaults for some instructions
2707
//---------------------------------------------------------
2708
if (advanceI) begin
2709 14 robfinch
        dAXC <= AXC;
2710 13 robfinch
        dextype <= `EX_NON;
2711 21 robfinch
        if (nmi_edge & !StatusHWI & !im1) begin
2712 14 robfinch
                $display("*****************");
2713
                $display("NMI edge detected");
2714
                $display("*****************");
2715
                StatusHWI <= 1'b1;
2716 13 robfinch
                nmi_edge <= 1'b0;
2717 14 robfinch
                dhwxtype <= 2'b01;
2718 13 robfinch
                dIR <= `NOP_INSN;
2719
                dextype <= `EX_NMI;
2720
        end
2721 21 robfinch
        else if (irq_i & !im & !StatusHWI & !im1) begin
2722 16 robfinch
                im <= 1'b1;
2723 14 robfinch
                StatusHWI <= 1'b1;
2724
                dhwxtype <= 2'b10;
2725 13 robfinch
                dIR <= `NOP_INSN;
2726
                dextype <= `EX_IRQ;
2727
        end
2728
        // Are we filling the pipeline with NOP's as a result of a previous
2729
        // hardware interrupt ?
2730 14 robfinch
        else if (|dhwxtype|dFip) begin
2731 13 robfinch
                dIR <= `NOP_INSN;
2732
        end
2733 19 robfinch
`ifdef TLB
2734 14 robfinch
        else if (ITLBMiss)
2735
                dIR <= `NOP_INSN;
2736 19 robfinch
`endif
2737 13 robfinch
        else begin
2738 21 robfinch
                if ((iOpcode==`SM || iOpcode==`LM) && insn[31:0]!=32'd0)
2739
                        im1 <= 1'b1;
2740
                else
2741
                        im1 <= 1'b0;
2742
                if ((iOpcode==`SM || iOpcode==`LM) && insn[31:0]==32'd0) begin
2743
                        dIR <= `NOP_INSN;
2744
                        pc <= fnIncPC(pc);
2745
                end
2746
                else
2747
                        dIR <= insn;
2748 14 robfinch
`include "insn_dumpsc.v"
2749 13 robfinch
        end
2750
        nopI <= 1'b0;
2751
        if (dOpcode[6:4]!=`IMM) begin
2752
                dpc <= pc;
2753 16 robfinch
                dpcv <= 1'b1;
2754 13 robfinch
        end
2755 21 robfinch
        dRb <= {AXC,insn[29:25]};
2756
        dRc <= {AXC,insn[24:20]};
2757 14 robfinch
        casex(iOpcode)
2758
        `SETLO:         dRa <= {AXC,insn[36:32]};
2759
        `SETHI:         dRa <= {AXC,insn[36:32]};
2760 21 robfinch
        `SM,`LM:
2761
                begin
2762
                dRa <= {AXC,1'b1,insn[34:31]};
2763
                casex(insn[30:0])
2764
                31'bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx1:    dRb <= {AXC,5'd1};
2765
                31'bxxxxxxxxxxxxxxxxxxxxxxxxxxxxx10:    dRb <= {AXC,5'd2};
2766
                31'bxxxxxxxxxxxxxxxxxxxxxxxxxxxx100:    dRb <= {AXC,5'd3};
2767
                31'bxxxxxxxxxxxxxxxxxxxxxxxxxxx1000:    dRb <= {AXC,5'd4};
2768
                31'bxxxxxxxxxxxxxxxxxxxxxxxxxx10000:    dRb <= {AXC,5'd5};
2769
                31'bxxxxxxxxxxxxxxxxxxxxxxxxx100000:    dRb <= {AXC,5'd6};
2770
                31'bxxxxxxxxxxxxxxxxxxxxxxxx1000000:    dRb <= {AXC,5'd7};
2771
                31'bxxxxxxxxxxxxxxxxxxxxxxx10000000:    dRb <= {AXC,5'd8};
2772
                31'bxxxxxxxxxxxxxxxxxxxxxx100000000:    dRb <= {AXC,5'd9};
2773
                31'bxxxxxxxxxxxxxxxxxxxxx1000000000:    dRb <= {AXC,5'd10};
2774
                31'bxxxxxxxxxxxxxxxxxxxx10000000000:    dRb <= {AXC,5'd11};
2775
                31'bxxxxxxxxxxxxxxxxxxx100000000000:    dRb <= {AXC,5'd12};
2776
                31'bxxxxxxxxxxxxxxxxxx1000000000000:    dRb <= {AXC,5'd13};
2777
                31'bxxxxxxxxxxxxxxxxx10000000000000:    dRb <= {AXC,5'd14};
2778
                31'bxxxxxxxxxxxxxxxx100000000000000:    dRb <= {AXC,5'd15};
2779
                31'bxxxxxxxxxxxxxxx1000000000000000:    dRb <= {AXC,5'd16};
2780
                31'bxxxxxxxxxxxxxx10000000000000000:    dRb <= {AXC,5'd17};
2781
                31'bxxxxxxxxxxxxx100000000000000000:    dRb <= {AXC,5'd18};
2782
                31'bxxxxxxxxxxxx1000000000000000000:    dRb <= {AXC,5'd19};
2783
                31'bxxxxxxxxxxx10000000000000000000:    dRb <= {AXC,5'd20};
2784
                31'bxxxxxxxxxx100000000000000000000:    dRb <= {AXC,5'd21};
2785
                31'bxxxxxxxxx1000000000000000000000:    dRb <= {AXC,5'd22};
2786
                31'bxxxxxxxx10000000000000000000000:    dRb <= {AXC,5'd23};
2787
                31'bxxxxxxx100000000000000000000000:    dRb <= {AXC,5'd24};
2788
                31'bxxxxxx1000000000000000000000000:    dRb <= {AXC,5'd25};
2789
                31'bxxxxx10000000000000000000000000:    dRb <= {AXC,5'd26};
2790
                31'bxxxx100000000000000000000000000:    dRb <= {AXC,5'd27};
2791
                31'bxxx1000000000000000000000000000:    dRb <= {AXC,5'd28};
2792
                31'bxx10000000000000000000000000000:    dRb <= {AXC,5'd29};
2793
                31'bx100000000000000000000000000000:    dRb <= {AXC,5'd30};
2794
                31'b1000000000000000000000000000000:    dRb <= {AXC,5'd31};
2795
                default:        dRb <= {AXC,5'd0};
2796
                endcase
2797
                end
2798 14 robfinch
        default:        dRa <= {AXC,insn[34:30]};
2799
        endcase
2800 19 robfinch
`ifdef TLB
2801 13 robfinch
        if (ITLBMiss) begin
2802 14 robfinch
                $display("TLB miss on instruction fetch.");
2803 13 robfinch
                CauseCode <= `EX_TLBI;
2804
                StatusEXL <= 1'b1;
2805
                BadVAddr <= pc[63:13];
2806
                pc <= `ITLB_MissHandler;
2807
                EPC <= pc;
2808
        end
2809 19 robfinch
        else
2810
`endif
2811
        begin
2812 13 robfinch
                dbranch_taken <= 1'b0;
2813 21 robfinch
                if ((iOpcode==`LM || iOpcode==`SM) && insn[31:0]!=32'd0)
2814
                        ;
2815
                else begin
2816
                        pc <= fnIncPC(pc);
2817
                end
2818 13 robfinch
                case(iOpcode)
2819
                `MISC:
2820
                        case(iFunc)
2821
                        `FIP:   dFip <= 1'b1;
2822
                        default:        ;
2823
                        endcase
2824 19 robfinch
                // We predict the return address by storing it in a return address stack
2825
                // during a call instruction, then popping it off the stack in a return
2826
                // instruction. The prediction will not always be correct, if it's wrong
2827
                // it's corrected by the EX stage branching to the right address.
2828
                `CALL:
2829 13 robfinch
                        begin
2830 19 robfinch
`ifdef RAS_PREDICTION
2831
                                ras[ras_sp] <= fnIncPC(pc);
2832
                                ras_sp <= ras_sp - 6'd1;
2833
`endif
2834 13 robfinch
                                dbranch_taken <= 1'b1;
2835
                                pc <= jmp_tgt;
2836
                        end
2837 19 robfinch
                `RET:
2838
                        begin
2839
`ifdef RAS_PREDICTION
2840
//                              $display("predicted return address=%h.%h",{ras[ras_sp + 6'd1][63:4],4'b0000},ras[ras_sp + 6'd1][3:2]);
2841
                                pc <= ras[ras_sp + 6'd1];
2842
                                ras_sp <= ras_sp + 6'd1;
2843
`endif
2844
                        end
2845
                `JMP:
2846
                        begin
2847
                                dbranch_taken <= 1'b1;
2848
                                pc <= jmp_tgt;
2849
                        end
2850 13 robfinch
                `BTRR:
2851
                        case(insn[4:0])
2852 21 robfinch
                        `BEQ,`BNE,`BLT,`BLE,`BGT,`BGE,`BLTU,`BLEU,`BGTU,`BGEU,`BAND,`BOR,`BRA,`BNR,`BRN,`LOOP:
2853 13 robfinch
                                if (predict_taken) begin
2854 19 robfinch
//                                      $display("Taking predicted branch: %h",{pc[63:4] + {{42{insn[24]}},insn[24:7]},insn[6:5],2'b00});
2855 13 robfinch
                                        dbranch_taken <= 1'b1;
2856
                                        pc <= {pc[63:4] + {{42{insn[24]}},insn[24:7]},insn[6:5],2'b00};
2857
                                end
2858
                        default:        ;
2859
                        endcase
2860 19 robfinch
`ifdef BTB
2861
                `BTRI:
2862
                        if (predict_taken) begin
2863
                                dbranch_taken <= 1'b1;
2864
                                pc <= btb[pc[7:2]];
2865
                        end
2866
`endif
2867 13 robfinch
                `BEQI,`BNEI,`BLTI,`BLEI,`BGTI,`BGEI,`BLTUI,`BLEUI,`BGTUI,`BGEUI:
2868
                        begin
2869
                                if (predict_taken) begin
2870
                                        dbranch_taken <= 1'b1;
2871
                                        pc <= {pc[63:4] + {{50{insn[29]}},insn[29:20]},insn[19:18],2'b00};
2872
                                end
2873
                        end
2874
                `TRAPcc:        if (predict_taken) begin pc <= {TBA[63:13],`GEN_TRAP_OFFSET}; dbranch_taken <= 1'b1; end
2875
                `TRAPcci:       if (predict_taken) begin pc <= {TBA[63:13],`GEN_TRAP_OFFSET}; dbranch_taken <= 1'b1; end
2876
                default:        ;
2877
                endcase
2878
        end
2879
end
2880
 
2881
//`include "RPSTAGE.v"
2882
//---------------------------------------------------------
2883
// EXECUTE - part two:
2884
// - override the default program counter increment for
2885
//   control flow instructions
2886
// - NOP out the instructions following a branch in the
2887
//   pipeline
2888
//---------------------------------------------------------
2889
if (advanceX) begin
2890
        case(xOpcode)
2891
        `MISC:
2892
                case(xFunc)
2893 14 robfinch
                `IRET:
2894
                        if (StatusHWI) begin
2895
                                StatusHWI <= 1'b0;
2896 16 robfinch
                                im <= 1'b0;
2897 14 robfinch
                                pc <= IPC;
2898
                                dIR <= `NOP_INSN;
2899
                                xIR <= `NOP_INSN;
2900
                                xRt <= 9'd0;
2901 16 robfinch
                                xpcv <= 1'b0;
2902
                                dpcv <= 1'b0;
2903 14 robfinch
                        end
2904
                `ERET:
2905
                        if (StatusEXL) begin
2906
                                StatusEXL <= 1'b0;
2907
                                pc <= EPC;
2908
                                dIR <= `NOP_INSN;
2909
                                xIR <= `NOP_INSN;
2910
                                xRt <= 9'd0;
2911 16 robfinch
                                xpcv <= 1'b0;
2912
                                dpcv <= 1'b0;
2913 14 robfinch
                        end
2914 13 robfinch
                default:        ;
2915
                endcase
2916 19 robfinch
        `R:
2917
                case(xFunc)
2918
                `EXEC:
2919
                        begin
2920
                                pc <= fnIncPC(xpc);
2921 21 robfinch
                                dRa <= b[34:30];
2922
                                dRb <= b[29:25];
2923
                                dRc <= b[24:20];
2924 19 robfinch
                                dIR <= b;
2925
                                xIR <= `NOP_INSN;
2926
                                xRt <= 9'd0;
2927
                                xpcv <= 1'b0;
2928
                                dpcv <= 1'b0;
2929
                        end
2930
                default:        ;
2931
                endcase
2932 13 robfinch
        `BTRR:
2933
                case(xIR[4:0])
2934
        // BEQ r1,r2,label
2935 21 robfinch
                `BEQ,`BNE,`BLT,`BLE,`BGT,`BGE,`BLTU,`BLEU,`BGTU,`BGEU,`BAND,`BOR,`BNR,`LOOP,`BRA,`BRN:
2936 14 robfinch
                        if (!takb & xbranch_taken) begin
2937
                                $display("Taking mispredicted branch %h",fnIncPC(xpc));
2938
                                pc <= fnIncPC(xpc);
2939
                                dIR <= `NOP_INSN;
2940
                                xIR <= `NOP_INSN;
2941
                                xRt <= 9'd0;
2942 16 robfinch
                                xpcv <= 1'b0;
2943
                                dpcv <= 1'b0;
2944 14 robfinch
                        end
2945
                        else if (takb & !xbranch_taken) begin
2946
                                $display("Taking branch %h.%h",{xpc[63:4] + {{42{xIR[24]}},xIR[24:7]},4'b0000},xIR[6:5]);
2947 13 robfinch
                                pc[63:4] <= xpc[63:4] + {{42{xIR[24]}},xIR[24:7]};
2948
                                pc[3:2] <= xIR[6:5];
2949
                                dIR <= `NOP_INSN;
2950
                                xIR <= `NOP_INSN;
2951
                                xRt <= 9'd0;
2952 16 robfinch
                                xpcv <= 1'b0;
2953
                                dpcv <= 1'b0;
2954 13 robfinch
                        end
2955
        // BEQ r1,r2,r10
2956
                `BEQR,`BNER,`BLTR,`BLER,`BGTR,`BGER,`BLTUR,`BLEUR,`BGTUR,`BGEUR://,`BANDR,`BORR,`BNRR:
2957
                        if (takb) begin
2958
                                pc[63:2] <= c[63:2];
2959
                                pc[1:0] <= 2'b00;
2960 19 robfinch
`ifdef BTB
2961
                                btb[xpc[7:2]] <= c;
2962
`endif
2963 13 robfinch
                                dIR <= `NOP_INSN;
2964
                                xIR <= `NOP_INSN;
2965
                                xRt <= 9'd0;
2966 16 robfinch
                                xpcv <= 1'b0;
2967
                                dpcv <= 1'b0;
2968 13 robfinch
                        end
2969
                default:        ;
2970
                endcase
2971
        // JMP and CALL change the program counter immediately in the IF stage.
2972
        // There's no work to do here. The pipeline does not need to be cleared.
2973
        `JMP:   ;
2974
        `CALL:  ;
2975 14 robfinch
        `JAL:
2976
                begin
2977
                        pc[63:2] <= a[63:2] + imm[63:2];
2978
                        dIR <= `NOP_INSN;
2979
                        xIR <= `NOP_INSN;
2980
                        xRt <= 9'd0;
2981 16 robfinch
                        xpcv <= 1'b0;
2982
                        dpcv <= 1'b0;
2983 14 robfinch
                end
2984 19 robfinch
 
2985
        // Check the pc of the instruction after the RET instruction (the dpc), to
2986
        // see if it's equal to the RET target. If it's the same as the target then
2987
        // we predicted the RET return correctly, so there's nothing to do. Otherwise
2988
        // we need to branch to the RET location.
2989 14 robfinch
        `RET:
2990 19 robfinch
`ifdef RAS_PREDICTION
2991
                if (dpc[63:2]!=b[63:2]) begin
2992
`else
2993 14 robfinch
                begin
2994 19 robfinch
`endif
2995
//                      $display("returning to: %h.%h", {b[63:4],4'b0},b[3:2]);
2996 14 robfinch
                        pc[63:2] <= b[63:2];
2997
                        dIR <= `NOP_INSN;
2998
                        xIR <= `NOP_INSN;
2999
                        xRt <= 9'd0;
3000 16 robfinch
                        xpcv <= 1'b0;
3001
                        dpcv <= 1'b0;
3002 14 robfinch
                end
3003 19 robfinch
//              else
3004
//                      $display("RET address %h predicted correctly.", {b[63:4],4'b0},b[3:2]);
3005 13 robfinch
        // BEQ r1,#3,r10
3006
        `BTRI:
3007 19 robfinch
`ifdef BTB
3008 13 robfinch
                if (takb) begin
3009 19 robfinch
                        if ((xbranch_taken && b!=btb[xpc[7:2]]) ||      // took branch, but not to right target
3010
                                !xbranch_taken) begin                                   // didn't take branch, and were supposed to
3011
                                pc[63:2] <= b[63:2];
3012
                                pc[1:0] <= 2'b00;
3013
                                btb[xpc[7:2]] <= b;
3014
                                dIR <= `NOP_INSN;
3015
                                xIR <= `NOP_INSN;
3016
                                xRt <= 9'd0;
3017
                                xpcv <= 1'b0;
3018
                                dpcv <= 1'b0;
3019
                        end
3020
                end
3021
                else if (xbranch_taken) begin   // took the branch, and weren't supposed to
3022
                        pc <= fnIncPC(xpc);
3023
                        dIR <= `NOP_INSN;
3024
                        xIR <= `NOP_INSN;
3025
                        xRt <= 9'd0;
3026
                        xpcv <= 1'b0;
3027
                        dpcv <= 1'b0;
3028
                end
3029
`else
3030
                if (takb) begin
3031 13 robfinch
                        pc[63:2] <= b[63:2];
3032
                        pc[1:0] <= 2'b00;
3033
                        dIR <= `NOP_INSN;
3034
                        xIR <= `NOP_INSN;
3035
                        xRt <= 9'd0;
3036 16 robfinch
                        xpcv <= 1'b0;
3037
                        dpcv <= 1'b0;
3038 13 robfinch
                end
3039 19 robfinch
`endif
3040 13 robfinch
        // BEQI r1,#3,label
3041
        `BEQI,`BNEI,`BLTI,`BLEI,`BGTI,`BGEI,`BLTUI,`BLEUI,`BGTUI,`BGEUI:
3042
                if (takb) begin
3043
                        if (!xbranch_taken) begin
3044
                                pc[63:4] <= xpc[63:4] + {{50{xIR[29]}},xIR[29:20]};
3045
                                pc[3:2] <= xIR[19:18];
3046
                                dIR <= `NOP_INSN;
3047
                                xIR <= `NOP_INSN;
3048
                                xRt <= 9'd0;
3049 16 robfinch
                                xpcv <= 1'b0;
3050
                                dpcv <= 1'b0;
3051 13 robfinch
                        end
3052
                end
3053 14 robfinch
                else begin
3054
                        if (xbranch_taken) begin
3055 19 robfinch
//                              $display("Taking mispredicted branch %h",fnIncPC(xpc));
3056 14 robfinch
                                pc <= fnIncPC(xpc);
3057
                                dIR <= `NOP_INSN;
3058
                                xIR <= `NOP_INSN;
3059
                                xRt <= 9'd0;
3060 16 robfinch
                                xpcv <= 1'b0;
3061
                                dpcv <= 1'b0;
3062 14 robfinch
                        end
3063
                end
3064
        `TRAPcc,`TRAPcci:
3065 13 robfinch
                if (takb) begin
3066
                        StatusEXL <= 1'b1;
3067
                        CauseCode <= `EX_TRAP;
3068
                        EPC <= xpc;
3069
                        if (!xbranch_taken) begin
3070
                                pc <= {TBA[63:13],`GEN_TRAP_OFFSET};
3071
                                dIR <= `NOP_INSN;
3072
                                xIR <= `NOP_INSN;
3073
                                xRt <= 9'd0;
3074 16 robfinch
                                xpcv <= 1'b0;
3075
                                dpcv <= 1'b0;
3076 13 robfinch
                        end
3077
                end
3078 14 robfinch
                else begin
3079
                        if (xbranch_taken) begin
3080 19 robfinch
//                              $display("Taking mispredicted branch %h",fnIncPC(xpc));
3081 14 robfinch
                                pc <= fnIncPC(xpc);
3082 13 robfinch
                                dIR <= `NOP_INSN;
3083
                                xIR <= `NOP_INSN;
3084
                                xRt <= 9'd0;
3085 16 robfinch
                                xpcv <= 1'b0;
3086
                                dpcv <= 1'b0;
3087 13 robfinch
                        end
3088
                end
3089
        default:        ;
3090
        endcase
3091 14 robfinch
 
3092 13 robfinch
        if (dbz_error) begin
3093
                $display("Divide by zero error");
3094
                CauseCode <= `EX_DBZ;
3095
                StatusEXL <= 1'b1;
3096
                EPC <= xpc;
3097
                pc <= {TBA[63:13],`DBZ_TRAP_OFFSET};
3098
                dIR <= `NOP_INSN;
3099
                xIR <= `NOP_INSN;
3100
                xRt <= 9'd0;
3101 16 robfinch
                xpcv <= 1'b0;
3102
                dpcv <= 1'b0;
3103 13 robfinch
        end
3104 14 robfinch
        else if (ovr_error) begin
3105 13 robfinch
                $display("Overflow error");
3106
                CauseCode <= `EX_OFL;
3107
                StatusEXL <= 1'b1;
3108
                EPC <= xpc;
3109
                pc <= {TBA[63:13],`OFL_TRAP_OFFSET};
3110
                dIR <= `NOP_INSN;
3111
                xIR <= `NOP_INSN;
3112
                xRt <= 9'd0;
3113 16 robfinch
                xpcv <= 1'b0;
3114
                dpcv <= 1'b0;
3115 13 robfinch
        end
3116 14 robfinch
        else if (priv_violation) begin
3117
                $display("Priviledge violation");
3118
                CauseCode <= `EX_PRIV;
3119
                StatusEXL <= 1'b1;
3120
                EPC <= xpc;
3121
                pc <= {TBA[63:13],`PRIV_OFFSET};
3122
                dIR <= `NOP_INSN;
3123
                xIR <= `NOP_INSN;
3124
                xRt <= 9'd0;
3125 16 robfinch
                xpcv <= 1'b0;
3126
                dpcv <= 1'b0;
3127 14 robfinch
        end
3128 13 robfinch
end
3129
 
3130
//---------------------------------------------------------
3131
// MEMORY1 (M1') - part two:
3132
// Check for a TLB miss.
3133
//---------------------------------------------------------
3134 19 robfinch
`ifdef TLB
3135 13 robfinch
if (advanceM1) begin
3136
        if (m1IsLoad|m1IsStore) begin
3137
                if (DTLBMiss) begin
3138
                        $display("DTLB miss on address: %h",ea);
3139
                        m1extype <= `EX_TLBD;
3140
                        CauseCode <= `EX_TLBD;
3141
                        StatusEXL <= 1'b1;
3142
                        BadVAddr <= ea[63:13];
3143
                        EPC <= m1pc;
3144
                        pc <= `DTLB_MissHandler;
3145
                        m1Opcode <= `NOPI;
3146
                        m1Rt <= 9'd0;
3147
                        xIR <= `NOP_INSN;
3148
                        xRt <= 9'd0;
3149
                        dIR <= `NOP_INSN;
3150 16 robfinch
                        m1pcv <= 1'b0;
3151
                        xpcv <= 1'b0;
3152
                        dpcv <= 1'b0;
3153 13 robfinch
                end
3154
        end
3155
end
3156 19 robfinch
`endif
3157 13 robfinch
 
3158
//---------------------------------------------------------
3159
// MEMORY2 (M2')
3160
//---------------------------------------------------------
3161
if (advanceM2) begin
3162
end
3163
 
3164
//---------------------------------------------------------
3165
// WRITEBACK (WB') - part two:
3166
// - vector to exception handler address
3167
// In the case of a hardware interrupt (NMI/IRQ) we know
3168
// the pipeline following the interrupt is filled with
3169
// NOP instructions. This means there is no need to 
3170
// invalidate the pipeline.
3171 14 robfinch
//              Also, we have to wait until the WB stage before
3172
// vectoring so that the pc setting doesn't get trashed
3173
// by a branch or other exception.
3174 16 robfinch
//              Tricky because we have to find the first valid
3175
// PC to record in the IPC register. The interrupt might
3176
// have occurred in a branch shadow, in which case the
3177
// current PC isn't valid.
3178 13 robfinch
//---------------------------------------------------------
3179
if (advanceW) begin
3180 14 robfinch
        case(wextype)
3181 16 robfinch
        `EX_RST:        begin
3182
                                pc <= `RESET_VECTOR;
3183
                                case(1'b1)
3184
                                wpcv:   IPC <= wpc;
3185
                                m2pcv:  IPC <= m2pc;
3186
                                m1pcv:  IPC <= m1pc;
3187
                                xpcv:   IPC <= xpc;
3188
                                dpcv:   IPC <= dpc;
3189
                                default:        IPC <= pc;
3190
                                endcase
3191
                                end
3192
        `EX_NMI:        begin
3193
                                pc <= `NMI_VECTOR;
3194
                                case(1'b1)
3195
                                wpcv:   IPC <= wpc;
3196
                                m2pcv:  IPC <= m2pc;
3197
                                m1pcv:  IPC <= m1pc;
3198
                                xpcv:   IPC <= xpc;
3199
                                dpcv:   IPC <= dpc;
3200
                                default:        IPC <= pc;
3201
                                endcase
3202
                                end
3203
        `EX_IRQ:        begin
3204
                                pc <= `IRQ_VECTOR;
3205
                                case(1'b1)
3206
                                wpcv:   IPC <= wpc;
3207
                                m2pcv:  IPC <= m2pc;
3208
                                m1pcv:  IPC <= m1pc;
3209
                                xpcv:   IPC <= xpc;
3210
                                dpcv:   IPC <= dpc;
3211
                                default:        IPC <= pc;
3212
                                endcase
3213
                                end
3214 14 robfinch
        default:        ;
3215
        endcase
3216 13 robfinch
end
3217
 
3218
 
3219
//---------------------------------------------------------
3220
// Trailer (TR')
3221
// - no exceptions
3222
//---------------------------------------------------------
3223
if (advanceT) begin
3224
end
3225
 
3226
 
3227
//---------------------------------------------------------
3228
// Cache loader
3229
//---------------------------------------------------------
3230
if (rst_i) begin
3231
        cstate <= IDLE;
3232
end
3233
else begin
3234
case(cstate)
3235
IDLE:
3236 14 robfinch
        if (triggerDCacheLoad) begin
3237
                dcaccess <= 1'b1;
3238
                bte_o <= 2'b00;                 // linear burst
3239
                cti_o <= 3'b010;                // burst access
3240
                bl_o <= 5'd8;
3241
                cyc_o <= 1'b1;
3242
                stb_o <= 1'b1;
3243
                adr_o <= {pea[63:6],6'h00};
3244
                cstate <= DCACT;
3245 13 robfinch
        end
3246 14 robfinch
        else if (triggerICacheLoad) begin
3247
                icaccess <= 1'b1;
3248
                bte_o <= 2'b00;                 // linear burst
3249
                cti_o <= 3'b010;                // burst access
3250
                cyc_o <= 1'b1;
3251
                stb_o <= 1'b1;
3252 19 robfinch
                if (ICacheAct) begin
3253
                        bl_o <= 5'd8;
3254
                        adr_o <= {ppc[63:6],6'h00};
3255
                        cstate <= ICACT1;
3256
                end
3257
                else begin
3258
                        bl_o <= 5'd2;
3259
                        adr_o <= {ppc[63:4],4'b0000};
3260
                        cstate <= ICACT2;
3261
                end
3262 13 robfinch
        end
3263
// WISHBONE burst accesses
3264
//
3265
ICACT1:
3266
        if (ack_i) begin
3267 14 robfinch
                adr_o[5:3] <= adr_o[5:3] + 3'd1;
3268 19 robfinch
                if (adr_o[5:3]==3'd6)
3269 13 robfinch
                        cti_o <= 3'b111;        // Last cycle ahead
3270 19 robfinch
                else if (adr_o[5:3]==3'd7) begin
3271 13 robfinch
                        cti_o <= 3'b000;        // back to non-burst mode
3272
                        cyc_o <= 1'b0;
3273
                        stb_o <= 1'b0;
3274 14 robfinch
                        tmem[adr_o[12:6]] <= {1'b1,adr_o[63:13]};       // This will cause ihit to go high
3275
                        tvalid[adr_o[12:6]] <= 1'b1;
3276
                        icaccess <= 1'b0;
3277 13 robfinch
                        cstate <= IDLE;
3278
                end
3279
        end
3280 19 robfinch
ICACT2:
3281
        if (ack_i) begin
3282
                adr_o <= adr_o + 64'd8;
3283
                if (adr_o[3]==1'b0) begin
3284
                        cti_o <= 3'b111;        // Last cycle ahead
3285
                        tmpbuf <= dat_i;
3286
                end
3287
                else begin
3288 21 robfinch
                        if (tick[0]) begin
3289
                                insnbuf0 <= {dat_i,tmpbuf};
3290
                                ibuftag0 <= adr_o[63:4];
3291
                        end
3292
                        else begin
3293
                                insnbuf1 <= {dat_i,tmpbuf};
3294
                                ibuftag1 <= adr_o[63:4];
3295
                        end
3296 19 robfinch
                        cti_o <= 3'b000;        // back to non-burst mode
3297
                        cyc_o <= 1'b0;
3298
                        stb_o <= 1'b0;
3299
                        icaccess <= 1'b0;
3300
                        cstate <= IDLE;
3301
                end
3302
        end
3303
 
3304 13 robfinch
DCACT:
3305 14 robfinch
        if (ack_i) begin
3306
                adr_o[5:3] <= adr_o[5:3] + 3'd1;
3307
                if (adr_o[5:3]==3'h6)
3308
                        cti_o <= 3'b111;        // Last cycle ahead
3309
                if (adr_o[5:3]==3'h7) begin
3310
                        cti_o <= 3'b000;        // back to non-burst mode
3311
                        cyc_o <= 1'b0;
3312
                        stb_o <= 1'b0;
3313
                        dcaccess <= 1'b0;
3314
                        cstate <= IDLE;
3315 13 robfinch
                end
3316
        end
3317 14 robfinch
 
3318 13 robfinch
endcase
3319
end
3320
 
3321
end
3322
 
3323
endmodule

powered by: WebSVN 2.1.0

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