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

Subversion Repositories raptor64

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

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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