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

Subversion Repositories raptor64

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

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

powered by: WebSVN 2.1.0

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