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

Subversion Repositories raptor64

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

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

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

powered by: WebSVN 2.1.0

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