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

Subversion Repositories raptor64

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

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

powered by: WebSVN 2.1.0

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