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

Subversion Repositories raptor64

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

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

powered by: WebSVN 2.1.0

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