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

Subversion Repositories raptor64

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

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

powered by: WebSVN 2.1.0

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