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

Subversion Repositories raptor64

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

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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