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

Subversion Repositories raptor64

[/] [raptor64/] [trunk/] [rtl/] [verilog/] [Raptor64.v] - Blame information for rev 11

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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