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

Subversion Repositories raptor64

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

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

powered by: WebSVN 2.1.0

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