Line 1... |
Line 1... |
`timescale 1ns / 1ps
|
`timescale 1ns / 1ps
|
// ============================================================================
|
// ============================================================================
|
// (C) 2012 Robert Finch
|
// __
|
// All Rights Reserved.
|
// \\__/ o\ (C) 2011-2013 Robert Finch, Stratford
|
// robfinch<remove>@opencores.org
|
// \ __ / All rights reserved.
|
|
// \/_// robfinch<remove>@opencores.org
|
|
// ||
|
//
|
//
|
// Raptor64sc.v
|
// Raptor64sc.v
|
// - 64 bit CPU
|
// - 64 bit CPU
|
//
|
//
|
// This source file is free software: you can redistribute it and/or modify
|
// This source file is free software: you can redistribute it and/or modify
|
Line 18... |
Line 20... |
// GNU General Public License for more details.
|
// GNU General Public License for more details.
|
//
|
//
|
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
//
|
//
|
|
// 15848 LUT's / 3591 ff's / 48.215 MHz
|
|
// 29 Block RAMs
|
// ============================================================================
|
// ============================================================================
|
//
|
//
|
`define ADDRESS_RESERVATION 1
|
`define ADDRESS_RESERVATION 1
|
//`define FLOATING_POINT 1
|
//`define FLOATING_POINT 1
|
//`define BTB 1
|
//`define BTB 1
|
Line 56... |
Line 60... |
parameter ICACT1 = 5'd4;
|
parameter ICACT1 = 5'd4;
|
parameter ICACT2 = 5'd5;
|
parameter ICACT2 = 5'd5;
|
parameter DCIDLE = 5'd20;
|
parameter DCIDLE = 5'd20;
|
parameter DCACT = 5'd21;
|
parameter DCACT = 5'd21;
|
parameter AMSB = 31;
|
parameter AMSB = 31;
|
|
parameter RESET = 4'd0;
|
|
parameter RUN = 4'd1;
|
input rst_i;
|
input rst_i;
|
input clk_i;
|
input clk_i;
|
input nmi_i;
|
input nmi_i;
|
input irq_i;
|
input irq_i;
|
|
|
Line 91... |
Line 96... |
reg [63:0] dat_o;
|
reg [63:0] dat_o;
|
|
|
input sys_adv;
|
input sys_adv;
|
input [63:5] sys_adr;
|
input [63:5] sys_adr;
|
|
|
|
reg [3:0] state;
|
reg [5:0] fltctr;
|
reg [5:0] fltctr;
|
wire fltdone = fltctr==6'd0;
|
wire fltdone = fltctr==6'd0;
|
reg resetA;
|
reg resetA;
|
reg im,bu_im; // interrupt mask
|
reg im,bu_im; // interrupt mask
|
reg im1; // temporary interrupt mask for LM/SM
|
reg im1; // temporary interrupt mask for LM/SM
|
reg [1:0] rm; // fp rounding mode
|
reg [1:0] rm; // fp rounding mode
|
reg FXE; // fp exception enable
|
reg FXE; // fp exception enable
|
wire KernelMode;
|
wire KernelMode;
|
wire [31:0] sr = {bu_im,15'd0,im,1'b0,KernelMode,FXE,2'b00,10'b0};
|
wire [31:0] sr = {bu_im,15'd0,im,1'b0,KernelMode,FXE,2'b00,10'b0};
|
reg [41:0] dIR,xIR,m1IR,m2IR,wIR;
|
reg [31:0] dIR,xIR,m1IR,m2IR,wIR;
|
reg [41:0] ndIR; // next dIR
|
reg [31:0] ndIR; // next dIR
|
reg [63:0] pc;
|
reg [63:0] pc;
|
wire [63:0] pchistoric;
|
wire [63:0] pchistoric;
|
reg pccap;
|
reg pccap;
|
reg [63:0] ErrorEPC,EPC,IPC;
|
reg [63:0] ErrorEPC,EPC,IPC;
|
reg [63:0] dpc,xpc,m1pc,m2pc,wpc;
|
reg [63:0] dpc,xpc,m1pc,m2pc,wpc;
|
Line 120... |
Line 126... |
reg dbranch_taken,xbranch_taken;
|
reg dbranch_taken,xbranch_taken;
|
reg [63:0] mutex_gate;
|
reg [63:0] mutex_gate;
|
reg [63:0] TBA; // Trap Base Address
|
reg [63:0] TBA; // Trap Base Address
|
reg [1:0] dhwxtype,xhwxtype,m1hwxtype,m2hwxtype,whwxtype;
|
reg [1:0] dhwxtype,xhwxtype,m1hwxtype,m2hwxtype,whwxtype;
|
reg [8:0] dextype,xextype,m1extype,m2extype,wextype,textype;
|
reg [8:0] dextype,xextype,m1extype,m2extype,wextype,textype;
|
reg [3:0] AXC,dAXC,xAXC;
|
reg [3:0] epat [0:255];
|
|
reg [7:0] eptr;
|
|
reg [3:0] dAXC,xAXC,m1AXC,m2AXC;
|
|
wire [3:0] AXC = epat[eptr];
|
reg dtinit;
|
reg dtinit;
|
reg dcache_on;
|
reg dcache_on;
|
reg [63:32] nonICacheSeg;
|
reg [63:32] nonICacheSeg;
|
|
|
reg [1:0] FPC_rm;
|
reg [1:0] FPC_rm;
|
reg FPC_SL; // result is negative (and non-zero)
|
reg FPC_SL; // result is negative (and non-zero)
|
reg FPC_SE; // result is zero
|
reg FPC_SE; // result is zero
|
reg FPC_SG; // result is positive (and non-zero)
|
reg FPC_SG; // result is positive (and non-zero)
|
reg FPC_SI; // result is infinite or NaN
|
reg FPC_SI; // result is infinite or NaN
|
Line 144... |
Line 152... |
FPC_SI,
|
FPC_SI,
|
16'd0
|
16'd0
|
};
|
};
|
wire [63:0] cdat;
|
wire [63:0] cdat;
|
reg [63:0] wr_addr;
|
reg [63:0] wr_addr;
|
reg [41:0] insn;
|
reg [31:0] insn;
|
reg clk_en;
|
reg clk_en;
|
reg cpu_clk_en;
|
reg cpu_clk_en;
|
reg StatusERL; // 1= in error processing
|
reg StatusERL; // 1= in error processing
|
reg StatusEXL; // 1= in exception processing
|
reg StatusEXL; // 1= in exception processing
|
reg StatusHWI; // 1= in interrupt processing
|
reg StatusHWI; // 1= in interrupt processing
|
Line 157... |
Line 165... |
integer n;
|
integer n;
|
reg [63:13] BadVAddr;
|
reg [63:13] BadVAddr;
|
reg [63:13] PageTableAddr;
|
reg [63:13] PageTableAddr;
|
reg [63:0] errorAddress;
|
reg [63:0] errorAddress;
|
|
|
wire [6:0] iOpcode = insn[41:35];
|
wire [6:0] iOpcode = insn[31:25];
|
wire [6:0] iFunc = insn[6:0];
|
wire [6:0] iFunc = insn[6:0];
|
wire [6:0] dOpcode = dIR[41:35];
|
wire [6:0] dOpcode = dIR[31:25];
|
wire [6:0] dFunc = dIR[6:0];
|
wire [6:0] dFunc = dIR[6:0];
|
wire [5:0] dFunc6 = dIR[5:0];
|
wire [5:0] dFunc6 = dIR[5:0];
|
wire [6:0] xOpcode = xIR[41:35];
|
wire [6:0] xOpcode = xIR[31:25];
|
wire [6:0] xFunc = xIR[6:0];
|
wire [6:0] xFunc = xIR[6:0];
|
wire [5:0] xFunc6 = xIR[5:0];
|
wire [5:0] xFunc6 = xIR[5:0];
|
wire [4:0] xFunc5 = xIR[4:0];
|
wire [4:0] xFunc5 = xIR[4:0];
|
reg [6:0] m1Opcode,m2Opcode,wOpcode;
|
reg [6:0] m1Opcode,m2Opcode,wOpcode;
|
reg [6:0] m1Func,m2Func,wFunc;
|
reg [6:0] m1Func,m2Func,wFunc;
|
|
wire [5:0] m1Func6 = m1Func[5:0];
|
reg [63:0] m1Data,m2Data,wData,tData;
|
reg [63:0] m1Data,m2Data,wData,tData;
|
reg [63:0] m2Addr;
|
reg [63:0] m2Addr;
|
reg [63:0] tick;
|
reg [63:0] tick;
|
reg [63:0] a,b,c,imm,m1b;
|
reg [63:0] a,b,c,imm,m1b;
|
|
reg [1:0] scale;
|
reg prev_ihit;
|
reg prev_ihit;
|
reg rsf;
|
reg rsf;
|
reg [63:5] resv_address;
|
reg [63:5] resv_address;
|
reg dirqf,rirqf,m1irqf,m2irqf,wirqf,tirqf;
|
reg dirqf,rirqf,m1irqf,m2irqf,wirqf,tirqf;
|
reg xirqf;
|
reg xirqf;
|
reg wLdPC,m2LdPC;
|
|
wire advanceX_edge;
|
wire advanceX_edge;
|
wire takb;
|
wire takb;
|
wire advanceX,advanceM1,advanceW;
|
wire advanceX,advanceM1,advanceW;
|
reg m1IsLoad,m2IsLoad;
|
reg m1IsLoad,m2IsLoad;
|
reg m1IsIO;
|
reg m1IsIO;
|
reg m1IsStore,m2IsStore,wIsStore;
|
reg m1IsStore,m2IsStore,wIsStore;
|
reg m1clkoff,m2clkoff,m3clkoff,m4clkoff,wclkoff;
|
reg m1clkoff,m2clkoff,m3clkoff,m4clkoff,wclkoff;
|
reg dFip,xFip,m1Fip,m2Fip,m3Fip,m4Fip,wFip;
|
reg dFip,xFip,m1Fip,m2Fip,m3Fip,m4Fip,wFip;
|
reg cyc1;
|
reg cyc1;
|
|
reg LoadNOPs;
|
|
|
function [63:0] fnIncPC;
|
function [63:0] fnIncPC;
|
input [63:0] fpc;
|
input [63:0] fpc;
|
begin
|
begin
|
case(fpc[3:2])
|
fnIncPC = fpc + 64'd4;
|
2'd0: fnIncPC = {fpc[63:4],4'b0100};
|
|
2'd1: fnIncPC = {fpc[63:4],4'b1000};
|
|
2'd2: fnIncPC = {fpc[63:4]+60'd1,4'b0000};
|
|
2'd3: fnIncPC = {fpc[63:4]+60'd1,4'b0000};
|
|
endcase
|
|
end
|
end
|
endfunction
|
endfunction
|
|
|
assign KernelMode = StatusEXL|StatusHWI;
|
assign KernelMode = StatusEXL|StatusHWI;
|
|
|
Line 311... |
Line 315... |
// On a bus error, the instruction cache / buffer is loaded with a SYSCALL 509
|
// On a bus error, the instruction cache / buffer is loaded with a SYSCALL 509
|
// instruction, which is a call to the bus error handler.
|
// instruction, which is a call to the bus error handler.
|
//
|
//
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
//reg lfdir;
|
//reg lfdir;
|
wire lfdir = (((dOpcode==`LM || dOpcode==`SM) && dIR[31:0]!=32'd0) && ndIR[31:0]!=32'd0) || (dIsLSPair && dIR[25]!=1'b1);
|
|
wire ldnop = (((dOpcode==`LM || dOpcode==`SM) && (dIR[31:0]==32'd0 || ndIR[31:0]==32'd0)) || (dIsLSPair && dIR[25]==1'b1));
|
|
reg icaccess;
|
reg icaccess;
|
reg ICacheOn;
|
reg ICacheOn;
|
wire ibufrdy;
|
wire ibufrdy;
|
reg [63:0] tmpbuf;
|
reg [63:0] tmpbuf;
|
wire [127:0] insnbundle;
|
wire [127:0] insnbundle;
|
reg [127:0] insnbuf0,insnbuf1;
|
reg [127:0] insnbuf0,insnbuf1;
|
reg [63:4] ibuftag0,ibuftag1;
|
reg [63:4] ibuftag0,ibuftag1;
|
wire isICached = ppc[63:32]!=nonICacheSeg;
|
wire isICached = ppc[63:32]!=nonICacheSeg;
|
//wire isEncrypted = ppc[63:32]==encryptedArea;
|
//wire isEncrypted = ppc[63:32]==encryptedArea;
|
wire ICacheAct = ICacheOn & isICached;
|
wire ICacheAct = ICacheOn & isICached;
|
reg [41:0] insn1;
|
reg [31:0] insn1;
|
reg [41:0] insnkey;
|
reg [31:0] insnkey;
|
|
|
// SYSCALL 509
|
// SYSCALL 509
|
wire syscall509 = 42'b00_00000000_00000000_00000000_11111110_10010111;
|
wire syscall509 = 32'b0000000_11000_0000_11111110_10010111;
|
wire [127:0] bevect = {2'b00,syscall509,syscall509,syscall509};
|
wire [63:0] bevect = {syscall509,syscall509};
|
|
|
Raptor64_icache_ram u1
|
Raptor64_icache_ram u1
|
(
|
(
|
.clka(clk), // input clka
|
.clka(clk), // input clka
|
.wea(icaccess & (ack_i|err_i)), // input [0 : 0] wea
|
.wea(icaccess & (ack_i|err_i)), // input [0 : 0] wea
|
.addra(adr_o[12:3]), // input [9 : 0] addra
|
.addra(adr_o[12:3]), // input [9 : 0] addra
|
.dina(err_i ? (adr_o[3] ? bevect[127:64] : bevect[63:0]) : dat_i), // input [63 : 0] dina
|
.dina(err_i ? bevect : dat_i), // input [63 : 0] dina
|
.clkb(~clk), // input clkb
|
.clkb(~clk), // input clkb
|
.addrb(pc[12:4]), // input [8 : 0] addrb
|
.addrb(pc[12:4]), // input [8 : 0] addrb
|
.doutb(insnbundle) // output [127 : 0] doutb
|
.doutb(insnbundle) // output [127 : 0] doutb
|
);
|
);
|
|
|
always @(ppc or insnbundle or ICacheAct or insnbuf0 or insnbuf1 or ndIR or lfdir or ldnop)
|
always @(ppc or insnbundle or ICacheAct or insnbuf0 or insnbuf1)
|
begin
|
begin
|
casex({ldnop,lfdir,ICacheAct,ibuftag1==ppc[63:4],pc[3:2]})
|
casex({ICacheAct,ibuftag1==ppc[63:4],pc[3:2]})
|
6'b1xxxxx: insn1 <= `NOP_INSN;
|
4'b0000: insn1 <= insnbuf0[ 31: 0];
|
6'b01xxxx: insn1 <= ndIR;
|
4'b0001: insn1 <= insnbuf0[ 63:32];
|
6'b001x00: insn1 <= insnbundle[ 41: 0];
|
4'b0010: insn1 <= insnbuf0[ 95:64];
|
6'b001x01: insn1 <= insnbundle[ 83:42];
|
4'b0011: insn1 <= insnbuf0[127:96];
|
6'b001x10: insn1 <= insnbundle[125:84];
|
4'b0100: insn1 <= insnbuf1[ 31: 0];
|
6'b001x11: insn1 <= `NOP_INSN;
|
4'b0101: insn1 <= insnbuf1[ 63:32];
|
6'b000000: insn1 <= insnbuf0[ 41: 0];
|
4'b0110: insn1 <= insnbuf1[ 95:64];
|
6'b000001: insn1 <= insnbuf0[ 83:42];
|
4'b0111: insn1 <= insnbuf1[127:96];
|
6'b000010: insn1 <= insnbuf0[125:84];
|
4'b1x00: insn1 <= insnbundle[ 31: 0];
|
6'b000011: insn1 <= `NOP_INSN;
|
4'b1x01: insn1 <= insnbundle[ 63:32];
|
6'b000100: insn1 <= insnbuf1[ 41: 0];
|
4'b1x10: insn1 <= insnbundle[ 95:64];
|
6'b000101: insn1 <= insnbuf1[ 83:42];
|
4'b1x11: insn1 <= insnbundle[127:96];
|
6'b000110: insn1 <= insnbuf1[125:84];
|
|
6'b000111: insn1 <= `NOP_INSN;
|
|
endcase
|
endcase
|
end
|
end
|
|
|
// Decrypt the instruction set.
|
// Decrypt the instruction set.
|
always @(insn1,insnkey)
|
always @(insn1,insnkey)
|
Line 607... |
Line 607... |
if (fltdone) begin
|
if (fltdone) begin
|
FPC_overx <= fp_ovr;
|
FPC_overx <= fp_ovr;
|
end
|
end
|
if (advanceX) begin
|
if (advanceX) begin
|
if (xOpcode==`FP) begin
|
if (xOpcode==`FP) begin
|
if (xFunc[5:0]==6'b000000) // FDADD
|
if (xFunc6==6'b000000) // FDADD
|
fltctr <= 6'd12;
|
fltctr <= 6'd12;
|
else if (xFunc[5:0]==6'b000001) // FDSUB
|
else if (xFunc6==6'b000001) // FDSUB
|
fltctr <= 6'd12;
|
fltctr <= 6'd12;
|
else if (xFunc[5:0]==6'b000010) // FDMUL
|
else if (xFunc6==6'b000010) // FDMUL
|
fltctr <= 6'd12;
|
fltctr <= 6'd12;
|
else if (xFunc[5:0]==6'b000011) // FDDIV
|
else if (xFunc6==6'b000011) // FDDIV
|
fltctr <= 6'd12;
|
fltctr <= 6'd12;
|
else if (xFunc[5:0]==6'b000100) // unordered
|
else if (xFunc6==6'b000100) // unordered
|
fltctr <= 6'd2;
|
fltctr <= 6'd2;
|
else if (xFunc[5:0]==6'b001100) // less than
|
else if (xFunc6==6'b001100) // less than
|
fltctr <= 6'd2;
|
fltctr <= 6'd2;
|
else if (xFunc[5:0]==6'b010100) // equal
|
else if (xFunc6==6'b010100) // equal
|
fltctr <= 6'd2;
|
fltctr <= 6'd2;
|
else if (xFunc[5:0]==6'b011100) // less than or equal
|
else if (xFunc6==6'b011100) // less than or equal
|
fltctr <= 6'd2;
|
fltctr <= 6'd2;
|
else if (xFunc[5:0]==6'b100100) // greater than
|
else if (xFunc6==6'b100100) // greater than
|
fltctr <= 6'd2;
|
fltctr <= 6'd2;
|
else if (xFunc[5:0]==6'b101100) // not equal
|
else if (xFunc6==6'b101100) // not equal
|
fltctr <= 6'd2;
|
fltctr <= 6'd2;
|
else if (xFunc[5:0]==6'b110100) // greater than or equal
|
else if (xFunc6==6'b110100) // greater than or equal
|
fltctr <= 6'd2;
|
fltctr <= 6'd2;
|
else if (xFunc[5:0]==6'b000101) // ItoFD
|
else if (xFunc6==6'b000101) // ItoFD
|
fltctr <= 6'd7;
|
fltctr <= 6'd7;
|
else if (xFunc[5:0]==6'b000110) // FFtoI
|
else if (xFunc6==6'b000110) // FFtoI
|
fltctr <= 6'd6;
|
fltctr <= 6'd6;
|
else if (xFunc[5:0]==6'b000111) // FtoD
|
else if (xFunc6==6'b000111) // FtoD
|
fltctr <= 6'd2;
|
fltctr <= 6'd2;
|
else if (xFunc[5:0]==6'b001000) // DtoF
|
else if (xFunc6==6'b001000) // DtoF
|
fltctr <= 6'd2;
|
fltctr <= 6'd2;
|
else
|
else
|
fltctr <= 6'd0;
|
fltctr <= 6'd0;
|
end
|
end
|
end
|
end
|
Line 731... |
Line 731... |
popcnt6(a[29:24]) +
|
popcnt6(a[29:24]) +
|
popcnt6(a[35:30]);
|
popcnt6(a[35:30]);
|
end
|
end
|
endfunction
|
endfunction
|
|
|
wire [63:0] jmp_tgt = dOpcode[6:4]==`IMM ? {dIR[26:0],insn[34:0],2'b00} : {pc[63:37],insn[34:0],2'b00};
|
wire [63:0] jmp_tgt = {pc[63:27],insn[24:0],2'b00};
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
// Stack for return address predictor
|
// Stack for return address predictor
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
reg [63:0] ras [63:0]; // return address stack, return predictions
|
reg [63:0] ras [63:0]; // return address stack, return predictions
|
Line 798... |
Line 798... |
|
|
Raptor64_addsub u21 (xIR,a,b,imm,xAddsubo);
|
Raptor64_addsub u21 (xIR,a,b,imm,xAddsubo);
|
Raptor64_logic u9 (xIR,a,b,imm,xLogico);
|
Raptor64_logic u9 (xIR,a,b,imm,xLogico);
|
Raptor64_set u15 (xIR,a,b,imm,xSeto);
|
Raptor64_set u15 (xIR,a,b,imm,xSeto);
|
Raptor64_bitfield u16(xIR, rolo, b, xBitfieldo, masko);
|
Raptor64_bitfield u16(xIR, rolo, b, xBitfieldo, masko);
|
Raptor64_shift u17 (xIR, a, b, masko, xShifto);
|
Raptor64_shift u17 (xIR, a, b, masko, xShifto, rolo);
|
BCDMul2 u22 (a[7:0],b[7:0],bcdmulo);
|
BCDMul2 u22 (a[7:0],b[7:0],bcdmulo);
|
|
|
wire aeqz = a==64'd0;
|
wire aeqz = a==64'd0;
|
wire eq = a==b;
|
wire eq = a==b;
|
wire eqi = a==imm;
|
wire eqi = a==imm;
|
Line 821... |
Line 821... |
ASID or EPC or mutex_gate or IPC or TBA or xAXC or nonICacheSeg or rm or
|
ASID or EPC or mutex_gate or IPC or TBA or xAXC or nonICacheSeg or rm or
|
rando or errorAddress
|
rando or errorAddress
|
)
|
)
|
casex(xOpcode)
|
casex(xOpcode)
|
`R:
|
`R:
|
casex(xFunc)
|
casex(xFunc6)
|
`COM: xData1 = ~a;
|
`COM: xData1 = ~a;
|
`NOT: xData1 = ~|a;
|
`NOT: xData1 = ~|a;
|
`NEG: xData1 = -a;
|
`NEG: xData1 = -a;
|
`ABS: xData1 = a[63] ? -a : a;
|
`ABS: xData1 = a[63] ? -a : a;
|
`SGN: xData1 = a[63] ? 64'hFFFFFFFF_FFFFFFFF : aeqz ? 64'd0 : 64'd1;
|
`SGN: xData1 = a[63] ? 64'hFFFFFFFF_FFFFFFFF : aeqz ? 64'd0 : 64'd1;
|
Line 854... |
Line 854... |
`SEXT16: xData1 = {{48{a[15]}},a[15:0]};
|
`SEXT16: xData1 = {{48{a[15]}},a[15:0]};
|
`SEXT32: xData1 = {{32{a[31]}},a[31:0]};
|
`SEXT32: xData1 = {{32{a[31]}},a[31:0]};
|
|
|
`MTSPR: xData1 = a;
|
`MTSPR: xData1 = a;
|
`MFSPR:
|
`MFSPR:
|
case(xIR[12:7])
|
case(xIR[11:6])
|
`ifdef TLB
|
`ifdef TLB
|
`TLBWired: xData1 = tlbo;
|
`TLBWired: xData1 = tlbo;
|
`TLBIndex: xData1 = tlbo;
|
`TLBIndex: xData1 = tlbo;
|
`TLBRandom: xData1 = tlbo;
|
`TLBRandom: xData1 = tlbo;
|
`TLBPhysPage0: xData1 = tlbo;
|
`TLBPhysPage0: xData1 = tlbo;
|
Line 892... |
Line 892... |
default: xData1 = 64'd0;
|
default: xData1 = 64'd0;
|
endcase
|
endcase
|
`OMG: xData1 = mutex_gate[a[5:0]];
|
`OMG: xData1 = mutex_gate[a[5:0]];
|
`CMG: xData1 = mutex_gate[a[5:0]];
|
`CMG: xData1 = mutex_gate[a[5:0]];
|
`OMGI: begin
|
`OMGI: begin
|
xData1 = mutex_gate[xIR[12:7]];
|
xData1 = mutex_gate[xIR[11:6]];
|
$display("mutex_gate[%d]=%d",xIR[12:7],mutex_gate[xIR[12:7]]);
|
$display("mutex_gate[%d]=%d",xIR[11:6],mutex_gate[xIR[11:6]]);
|
end
|
end
|
`CMGI: xData1 = mutex_gate[xIR[12:7]];
|
`CMGI: xData1 = mutex_gate[xIR[11:6]];
|
default: xData1 = 64'd0;
|
default: xData1 = 64'd0;
|
endcase
|
endcase
|
`RR:
|
`RR:
|
case(xFunc)
|
case(xFunc6)
|
`CMP: xData1 = lt ? 64'hFFFFFFFFFFFFF : eq ? 64'd0 : 64'd1;
|
`CMP: xData1 = lt ? 64'hFFFFFFFFFFFFF : eq ? 64'd0 : 64'd1;
|
`CMPU: xData1 = ltu ? 64'hFFFFFFFFFFFFF : eq ? 64'd0 : 64'd1;
|
`CMPU: xData1 = ltu ? 64'hFFFFFFFFFFFFF : eq ? 64'd0 : 64'd1;
|
`MIN: xData1 = lt ? a : b;
|
`MIN: xData1 = lt ? a : b;
|
`MAX: xData1 = lt ? b : a;
|
`MAX: xData1 = lt ? b : a;
|
`MOVZ: xData1 = b;
|
`MOVZ: xData1 = b;
|
`MOVNZ: xData1 = b;
|
`MOVNZ: xData1 = b;
|
|
`MOVPL: xData1 = b;
|
|
`MOVMI: xData1 = b;
|
`MULS: xData1 = mult_out[63:0];
|
`MULS: xData1 = mult_out[63:0];
|
`MULU: xData1 = mult_out[63:0];
|
`MULU: xData1 = mult_out[63:0];
|
`DIVS: xData1 = div_q;
|
`DIVS: xData1 = div_q;
|
`DIVU: xData1 = div_q;
|
`DIVU: xData1 = div_q;
|
`MODU: xData1 = div_r;
|
`MODU: xData1 = div_r;
|
`MODS: xData1 = div_r;
|
`MODS: xData1 = div_r;
|
`BCD_MUL: xData1 = bcdmulo;
|
`BCD_MUL: xData1 = bcdmulo;
|
|
`MFEP: xData1 = epat[a[7:0]];
|
default: xData1 = 64'd0;
|
default: xData1 = 64'd0;
|
endcase
|
endcase
|
`BTRR:
|
`BTRR:
|
case(xFunc5)
|
case(xFunc5)
|
`LOOP: xData1 = b - 64'd1;
|
`LOOP: xData1 = b - 64'd1;
|
default: xData1 = 64'd0;
|
default: xData1 = 64'd0;
|
endcase
|
endcase
|
`SETLO: xData1 = {{32{xIR[31]}},xIR[31:0]};
|
`MUX:
|
`SETHI: xData1 = {xIR[31:0],a[31:0]};
|
begin
|
|
for (n = 0; n < 64; n = n + 1)
|
|
xData1[n] = c[n] ? b[n] : a[n];
|
|
end
|
|
`SETLO: xData1 = {{42{xIR[21]}},xIR[21:0]};
|
|
`SETMID: xData1 = {{20{xIR[21]}},xIR[21:0],a[21:0]};
|
|
`SETHI: xData1 = {xIR[19:0],a[43:0]};
|
`CMPI: xData1 = lti ? 64'hFFFFFFFFFFFFF : eqi ? 64'd0 : 64'd1;
|
`CMPI: xData1 = lti ? 64'hFFFFFFFFFFFFF : eqi ? 64'd0 : 64'd1;
|
`CMPUI: xData1 = ltui ? 64'hFFFFFFFFFFFFF : eqi ? 64'd0 : 64'd1;
|
`CMPUI: xData1 = ltui ? 64'hFFFFFFFFFFFFF : eqi ? 64'd0 : 64'd1;
|
`MULSI: xData1 = mult_out[63:0];
|
`MULSI: xData1 = mult_out[63:0];
|
`MULUI: xData1 = mult_out[63:0];
|
`MULUI: xData1 = mult_out[63:0];
|
`DIVSI: xData1 = div_q;
|
`DIVSI: xData1 = div_q;
|
Line 937... |
Line 946... |
`LW,`LH,`LC,`LB,`LHU,`LCU,`LBU,`LWR,`LF,`LFD,`LP,`LFP,`LFDP,`LEA:
|
`LW,`LH,`LC,`LB,`LHU,`LCU,`LBU,`LWR,`LF,`LFD,`LP,`LFP,`LFDP,`LEA:
|
xData1 = a + imm;
|
xData1 = a + imm;
|
`SW,`SH,`SC,`SB,`SWC,`SF,`SFD,`SP,`SFP,`SFDP:
|
`SW,`SH,`SC,`SB,`SWC,`SF,`SFD,`SP,`SFP,`SFDP:
|
xData1 = a + imm;
|
xData1 = a + imm;
|
`MEMNDX:
|
`MEMNDX:
|
xData1 = a + b + imm;
|
xData1 = a + (b << scale) + imm;
|
`SM: xData1 = a + {popcnt36(xIR[31:0]),3'b000}-64'd8;
|
|
`LM: xData1 = a + {popcnt36(xIR[31:0]),3'b000}-64'd8;
|
|
`TRAPcc: xData1 = fnIncPC(xpc);
|
`TRAPcc: xData1 = fnIncPC(xpc);
|
`TRAPcci: xData1 = fnIncPC(xpc);
|
`TRAPcci: xData1 = fnIncPC(xpc);
|
`CALL: xData1 = fnIncPC(xpc);
|
`CALL: xData1 = fnIncPC(xpc);
|
`JAL: xData1 = xpc + {xIR[29:25],2'b00};
|
`JAL: xData1 = fnIncPC(xpc);//???xpc + {xIR[19:15],2'b00};
|
`RET: xData1 = a + imm;
|
`RET: xData1 = a + imm;
|
`FPLOO: xData1 = fpLooOut;
|
`FPLOO: xData1 = fpLooOut;
|
`FPZL: xData1 = fpZLOut;
|
`FPZL: xData1 = fpZLOut;
|
`ifdef FLOATING_POINT
|
`ifdef FLOATING_POINT
|
`FP:
|
`FP:
|
Line 976... |
Line 983... |
|
|
wire v_ri,v_rr;
|
wire v_ri,v_rr;
|
overflow u2 (.op(xOpcode==`SUBI), .a(a[63]), .b(imm[63]), .s(xAddsubo[63]), .v(v_ri));
|
overflow u2 (.op(xOpcode==`SUBI), .a(a[63]), .b(imm[63]), .s(xAddsubo[63]), .v(v_ri));
|
overflow u3 (.op(xOpcode==`RR && xFunc==`SUB), .a(a[63]), .b(b[63]), .s(xAddsubo[63]), .v(v_rr));
|
overflow u3 (.op(xOpcode==`RR && xFunc==`SUB), .a(a[63]), .b(b[63]), .s(xAddsubo[63]), .v(v_rr));
|
|
|
wire dbz_error = ((xOpcode==`DIVSI||xOpcode==`DIVUI) && imm==64'd0) || (xOpcode==`RR && (xFunc==`DIVS || xFunc==`DIVU) && b==64'd0);
|
wire dbz_error = ((xOpcode==`DIVSI||xOpcode==`DIVUI) && imm==64'd0) || (xOpcode==`RR && (xFunc6==`DIVS || xFunc6==`DIVU) && b==64'd0);
|
wire ovr_error = ((xOpcode==`ADDI || xOpcode==`SUBI) && v_ri) || ((xOpcode==`RR && (xFunc==`SUB || xFunc==`ADD)) && v_rr);
|
wire ovr_error = ((xOpcode==`ADDI || xOpcode==`SUBI) && v_ri) || ((xOpcode==`RR && (xFunc6==`SUB || xFunc6==`ADD)) && v_rr);
|
wire priv_violation = !KernelMode && (xOpcode==`MISC &&
|
wire priv_violation = !KernelMode && (xOpcode==`MISC &&
|
(xFunc==`IRET || xFunc==`ERET || xFunc==`CLI || xFunc==`SEI ||
|
(xFunc==`IRET || xFunc==`ERET || xFunc==`CLI || xFunc==`SEI ||
|
xFunc==`TLBP || xFunc==`TLBR || xFunc==`TLBWR || xFunc==`TLBWI
|
xFunc==`TLBP || xFunc==`TLBR || xFunc==`TLBWR || xFunc==`TLBWI
|
));
|
));
|
wire illegal_insn = (xOpcode==7'd19 || xOpcode==7'd47 || xOpcode==7'd54 || xOpcode==7'd55 || xOpcode==7'd63 || xOpcode==7'd71 ||
|
wire illegal_insn = (xOpcode==7'd19 || xOpcode==7'd47 || xOpcode==7'd54 || xOpcode==7'd55 || xOpcode==7'd63 || xOpcode==7'd71 ||
|
xOpcode==7'd90 || xOpcode==7'd91 || xOpcode==7'd92 || xOpcode==7'd93 || xOpcode==7'd106 || xOpcode==7'd107)
|
xOpcode==7'd90 || xOpcode==7'd91 || xOpcode==7'd92 || xOpcode==7'd93 || xOpcode==7'd106 || xOpcode==7'd107)
|
;
|
;
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
|
//-----------------------------------------------------------------------------
|
|
//wire dIsLoad =
|
|
// dOpcode==`LW || dOpcode==`LH || dOpcode==`LB || dOpcode==`LWR ||
|
|
// dOpcode==`LHU || dOpcode==`LBU ||
|
|
// dOpcode==`LC || dOpcode==`LCU || dOpcode==`LM ||
|
|
// dOpcode==`LF || dOpcode==`LFD || dOpcode==`LP || dOpcode==`LFP || dOpcode==`LFDP ||
|
|
// dOpcode==`LSH || dOpcode==`LSW ||
|
|
// (dOpcode==`MEMNDX && (
|
|
// dFunc6==`LWX || dFunc6==`LHX || dFunc6==`LBX || dFunc6==`LWRX ||
|
|
// dFunc6==`LHUX || dFunc6==`LBUX ||
|
|
// dFunc6==`LCX || dFunc6==`LCUX ||
|
|
// dFunc6==`LFX || dFunc6==`LFDX || dFunc6==`LPX ||
|
|
// dFunc6==`LSHX || dFunc6==`LSWX
|
|
// )) ||
|
|
// (dOpcode==`MISC && (dFunc==`SYSJMP || dFunc==`SYSCALL || dFunc==`SYSINT))
|
|
// ;
|
|
//wire dIsStore =
|
|
// dOpcode==`SW || dOpcode==`SH || dOpcode==`SB || dOpcode==`SC || dOpcode==`SWC || dOpcode==`SM ||
|
|
// dOpcode==`SF || dOpcode==`SFD || dOpcode==`SP || dOpcode==`SFP || dOpcode==`SFDP ||
|
|
// dOpcode==`SSH || dOpcode==`SSW ||
|
|
// (dOpcode==`MEMNDX && (
|
|
// dFunc6==`SWX || dFunc6==`SHX || dFunc6==`SBX || dFunc6==`SCX || dFunc6==`SWCX ||
|
|
// dFunc6==`SFX || dFunc6==`SFDX || dFunc6==`SPX ||
|
|
// dFunc6==`SSHX || dFunc6==`SSWX
|
|
// ))
|
|
// ;
|
|
//wire dIsIn =
|
|
// dOpcode==`INW || dOpcode==`INH || dOpcode==`INCH || dOpcode==`INB ||
|
|
// dOpcode==`INHU || dOpcode==`INCU || dOpcode==`INBU ||
|
|
// (dOpcode==`MEMNDX && (
|
|
// dFunc6==`INWX || dFunc6==`INHX || dFunc6==`INCX || dFunc6==`INBX ||
|
|
// dFunc6==`INHUX || dFunc6==`INCUX || dFunc6==`INBUX
|
|
// ))
|
|
// ;
|
|
//wire dIsOut = dOpcode==`OUTW || dOpcode==`OUTH || dOpcode==`OUTC || dOpcode==`OUTB ||
|
|
// (dOpcode==`MEMNDX && (
|
|
// dFunc6==`OUTWX || dFunc6==`OUTHX || dFunc6==`OUTCX || dFunc6==`OUTBX
|
|
// ))
|
|
// ;
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
// Pipeline advance and stall logic
|
// Pipeline advance and stall logic
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
wire xIsSqrt = xOpcode==`R && xFunc==`SQRT;
|
wire xIsSqrt = xOpcode==`R && xFunc6==`SQRT;
|
wire xIsMult = (xOpcode==`RR && (xFunc==`MULU || xFunc==`MULS)) || xOpcode==`MULSI || xOpcode==`MULUI;
|
wire xIsMult = (xOpcode==`RR && (xFunc6==`MULU || xFunc6==`MULS)) || xOpcode==`MULSI || xOpcode==`MULUI;
|
wire xIsDiv = (xOpcode==`RR && (xFunc==`DIVU || xFunc==`DIVS || xFunc==`MODU || xFunc==`MODS)) || xOpcode==`DIVSI || xOpcode==`DIVUI;
|
wire xIsDiv = (xOpcode==`RR && (xFunc6==`DIVU || xFunc6==`DIVS || xFunc6==`MODU || xFunc6==`MODS)) || xOpcode==`DIVSI || xOpcode==`DIVUI;
|
wire xIsCnt = xOpcode==`R && (xFunc==`CTLZ || xFunc==`CTLO || xFunc==`CTPOP);
|
wire xIsCnt = xOpcode==`R && (xFunc6==`CTLZ || xFunc6==`CTLO || xFunc6==`CTPOP);
|
reg m1IsCnt,m2IsCnt;
|
reg m1IsCnt,m2IsCnt;
|
|
|
|
|
wire xIsLoad =
|
wire xIsLoad =
|
xOpcode==`LW || xOpcode==`LH || xOpcode==`LB || xOpcode==`LWR ||
|
xOpcode==`LW || xOpcode==`LH || xOpcode==`LB || xOpcode==`LWR ||
|
xOpcode==`LHU || xOpcode==`LBU ||
|
xOpcode==`LHU || xOpcode==`LBU ||
|
xOpcode==`LC || xOpcode==`LCU || xOpcode==`LM ||
|
xOpcode==`LC || xOpcode==`LCU || xOpcode==`LM ||
|
xOpcode==`LF || xOpcode==`LFD || xOpcode==`LP || xOpcode==`LFP || xOpcode==`LFDP ||
|
xOpcode==`LF || xOpcode==`LFD || xOpcode==`LP || xOpcode==`LFP || xOpcode==`LFDP ||
|
Line 1008... |
Line 1058... |
xFunc6==`LHUX || xFunc6==`LBUX ||
|
xFunc6==`LHUX || xFunc6==`LBUX ||
|
xFunc6==`LCX || xFunc6==`LCUX ||
|
xFunc6==`LCX || xFunc6==`LCUX ||
|
xFunc6==`LFX || xFunc6==`LFDX || xFunc6==`LPX ||
|
xFunc6==`LFX || xFunc6==`LFDX || xFunc6==`LPX ||
|
xFunc6==`LSHX || xFunc6==`LSWX
|
xFunc6==`LSHX || xFunc6==`LSWX
|
)) ||
|
)) ||
|
(xOpcode==`MISC && (xFunc==`SYSJMP || xFunc==`SYSCALL))
|
(xOpcode==`MISC && (xFunc==`SYSCALL))
|
;
|
;
|
|
|
wire xIsStore =
|
wire xIsStore =
|
xOpcode==`SW || xOpcode==`SH || xOpcode==`SB || xOpcode==`SC || xOpcode==`SWC || xOpcode==`SM ||
|
xOpcode==`SW || xOpcode==`SH || xOpcode==`SB || xOpcode==`SC || xOpcode==`SWC || xOpcode==`SM ||
|
xOpcode==`SF || xOpcode==`SFD || xOpcode==`SP || xOpcode==`SFP || xOpcode==`SFDP ||
|
xOpcode==`SF || xOpcode==`SFD || xOpcode==`SP || xOpcode==`SFP || xOpcode==`SFDP ||
|
Line 1024... |
Line 1074... |
))
|
))
|
;
|
;
|
wire xIsSWC = xOpcode==`SWC;
|
wire xIsSWC = xOpcode==`SWC;
|
wire xIsIn =
|
wire xIsIn =
|
xOpcode==`INW || xOpcode==`INH || xOpcode==`INCH || xOpcode==`INB ||
|
xOpcode==`INW || xOpcode==`INH || xOpcode==`INCH || xOpcode==`INB ||
|
xOpcode==`INHU || xOpcode==`INCU || xOpcode==`INBU
|
xOpcode==`INHU || xOpcode==`INCU || xOpcode==`INBU ||
|
|
(xOpcode==`MEMNDX && (
|
|
xFunc6==`INWX || xFunc6==`INHX || xFunc6==`INCX || xFunc6==`INBX ||
|
|
xFunc6==`INHUX || xFunc6==`INCUX || xFunc6==`INBUX
|
|
))
|
|
;
|
|
wire xIsOut = xOpcode==`OUTW || xOpcode==`OUTH || xOpcode==`OUTC || xOpcode==`OUTB ||
|
|
(xOpcode==`MEMNDX && (
|
|
xFunc6==`OUTWX || xFunc6==`OUTHX || xFunc6==`OUTCX || xFunc6==`OUTBX
|
|
))
|
;
|
;
|
|
|
//wire mIsSWC = mOpcode==`SWC;
|
//wire mIsSWC = mOpcode==`SWC;
|
|
//reg m1IsIn;
|
|
|
wire m1IsIn =
|
wire m1IsIn =
|
m1Opcode==`INW || m1Opcode==`INH || m1Opcode==`INCH || m1Opcode==`INB ||
|
m1Opcode==`INW || m1Opcode==`INH || m1Opcode==`INCH || m1Opcode==`INB ||
|
m1Opcode==`INHU || m1Opcode==`INCU || m1Opcode==`INBU
|
m1Opcode==`INHU || m1Opcode==`INCU || m1Opcode==`INBU ||
|
|
(m1Opcode==`MEMNDX && (
|
|
m1Func6==`INWX || m1Func6==`INHX || m1Func6==`INCX || m1Func6==`INBX ||
|
|
m1Func6==`INHUX || m1Func6==`INCUX || m1Func6==`INBUX
|
|
))
|
;
|
;
|
wire m2IsInW = m2Opcode==`INW;
|
wire m2IsInW = m2Opcode==`INW;
|
wire xIsIO =
|
wire xIsIO = xIsIn || xIsOut;
|
xIsIn ||
|
|
xOpcode==`OUTW || xOpcode==`OUTH || xOpcode==`OUTC || xOpcode==`OUTB
|
|
;
|
|
|
|
|
|
wire xIsFPLoo = xOpcode==`FPLOO;
|
wire xIsFPLoo = xOpcode==`FPLOO;
|
wire xIsFP = xOpcode==`FP;
|
wire xIsFP = xOpcode==`FP;
|
wire xneedBus = xIsIO;
|
wire xneedBus = xIsIO;
|
Line 1050... |
Line 1112... |
wire xRtz = xRt[4:0]==5'd0;
|
wire xRtz = xRt[4:0]==5'd0;
|
wire m1Rtz = m1Rt[4:0]==5'd0;
|
wire m1Rtz = m1Rt[4:0]==5'd0;
|
wire m2Rtz = m2Rt[4:0]==5'd0;
|
wire m2Rtz = m2Rt[4:0]==5'd0;
|
|
|
// Stall on SWC allows rsf flag to be loaded for the next instruction
|
// Stall on SWC allows rsf flag to be loaded for the next instruction
|
|
// Could check for dRa,dRb,dRc==0, for non-stalling
|
wire StallR = (((xIsLoad||xIsIn||xIsCnt) && ((xRt==dRa)||(xRt==dRb)||(xRt==dRc)) && !xRtz) || xIsSWC) ||
|
wire StallR = (((xIsLoad||xIsIn||xIsCnt) && ((xRt==dRa)||(xRt==dRb)||(xRt==dRc)) && !xRtz) || xIsSWC) ||
|
(((m1IsLoad||m1IsIn||m1IsCnt) && ((m1Rt==dRa)||(m1Rt==dRb)||(m1Rt==dRc)) && !m1Rtz)) ||
|
(((m1IsLoad||m1IsIn||m1IsCnt) && ((m1Rt==dRa)||(m1Rt==dRb)||(m1Rt==dRc)) && !m1Rtz)) ||
|
(((m2IsLoad||m2IsCnt) && ((m2Rt==dRa)||(m2Rt==dRb)||(m2Rt==dRc)) && !m2Rtz))
|
(((m2IsLoad||m2IsCnt) && ((m2Rt==dRa)||(m2Rt==dRb)||(m2Rt==dRc)) && !m2Rtz))
|
;
|
;
|
wire StallX = xneedBus & (m1needBus|m2needBus|icaccess|dcaccess);
|
wire StallX = xneedBus & (m1needBus|m2needBus|icaccess|dcaccess);
|
Line 1086... |
Line 1149... |
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
// Cache loading control
|
// Cache loading control
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
wire pipelineEmpty =
|
wire pipelineEmpty =
|
(dOpcode==`NOPI || dOpcode[6:4]==`IMM) && // and the pipeline is flushed
|
(dOpcode==`NOPI) && // and the pipeline is flushed
|
(xOpcode==`NOPI || xOpcode[6:4]==`IMM) &&
|
(xOpcode==`NOPI) &&
|
m1Opcode==`NOPI &&
|
m1Opcode==`NOPI &&
|
m2Opcode==`NOPI
|
m2Opcode==`NOPI
|
;
|
;
|
wire triggerDCacheLoad = (m1IsLoad & m1IsCacheElement & !dhit) && // there is a miss
|
wire triggerDCacheLoad = (m1IsLoad & m1IsCacheElement & !dhit) && // there is a miss
|
!(icaccess | dcaccess) && // caches are not active
|
!(icaccess | dcaccess) && // caches are not active
|
Line 1116... |
Line 1179... |
wire exception_pending = EXexception_pending | M1exception_pending;
|
wire exception_pending = EXexception_pending | M1exception_pending;
|
|
|
reg prev_nmi,nmi_edge;
|
reg prev_nmi,nmi_edge;
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
|
|
|
always @(dOpcode or dIR or dIsLSPair)
|
|
begin
|
|
ndIR <= dIR;
|
|
if (dIsLSPair) begin
|
|
ndIR[25] <= 1'b1;
|
|
ndIR[3] <= 1'b1;
|
|
end
|
|
else if ((dOpcode==`LM || dOpcode==`SM) && dIR[31:0]!=32'd0) begin
|
|
$display("LM/SM %h",dIR[31:0]);
|
|
if (dIR[0])
|
|
ndIR[0] <= 1'b0;
|
|
else if (dIR[1])
|
|
ndIR[1] <= 1'b0;
|
|
else if (dIR[2])
|
|
ndIR[2] <= 1'b0;
|
|
else if (dIR[3])
|
|
ndIR[3] <= 1'b0;
|
|
else if (dIR[4])
|
|
ndIR[4] <= 1'b0;
|
|
else if (dIR[5])
|
|
ndIR[5] <= 1'b0;
|
|
else if (dIR[6])
|
|
ndIR[6] <= 1'b0;
|
|
else if (dIR[7])
|
|
ndIR[7] <= 1'b0;
|
|
else if (dIR[8])
|
|
ndIR[8] <= 1'b0;
|
|
else if (dIR[9])
|
|
ndIR[9] <= 1'b0;
|
|
else if (dIR[10])
|
|
ndIR[10] <= 1'b0;
|
|
else if (dIR[11])
|
|
ndIR[11] <= 1'b0;
|
|
else if (dIR[12])
|
|
ndIR[12] <= 1'b0;
|
|
else if (dIR[13])
|
|
ndIR[13] <= 1'b0;
|
|
else if (dIR[14])
|
|
ndIR[14] <= 1'b0;
|
|
else if (dIR[15])
|
|
ndIR[15] <= 1'b0;
|
|
else if (dIR[16])
|
|
ndIR[16] <= 1'b0;
|
|
else if (dIR[17])
|
|
ndIR[17] <= 1'b0;
|
|
else if (dIR[18])
|
|
ndIR[18] <= 1'b0;
|
|
else if (dIR[19])
|
|
ndIR[19] <= 1'b0;
|
|
else if (dIR[20])
|
|
ndIR[20] <= 1'b0;
|
|
else if (dIR[21])
|
|
ndIR[21] <= 1'b0;
|
|
else if (dIR[22])
|
|
ndIR[22] <= 1'b0;
|
|
else if (dIR[23])
|
|
ndIR[23] <= 1'b0;
|
|
else if (dIR[24])
|
|
ndIR[24] <= 1'b0;
|
|
else if (dIR[25])
|
|
ndIR[25] <= 1'b0;
|
|
else if (dIR[26])
|
|
ndIR[26] <= 1'b0;
|
|
else if (dIR[27])
|
|
ndIR[27] <= 1'b0;
|
|
else if (dIR[28])
|
|
ndIR[28] <= 1'b0;
|
|
else if (dIR[29])
|
|
ndIR[29] <= 1'b0;
|
|
else if (dIR[30])
|
|
ndIR[30] <= 1'b0;
|
|
else
|
|
ndIR[31] <= 1'b0;
|
|
end
|
|
end
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Register file.
|
// Register file.
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
|
|
wire [63:0] nxt_a, nxt_b, nxt_c;
|
wire [63:0] nxt_a, nxt_b, nxt_c;
|
|
|
Line 1273... |
Line 1257... |
we_o <= 1'b0;
|
we_o <= 1'b0;
|
sel_o <= 8'h00;
|
sel_o <= 8'h00;
|
adr_o <= 64'd0;
|
adr_o <= 64'd0;
|
dat_o <= 64'd0;
|
dat_o <= 64'd0;
|
|
|
|
state <= RESET;
|
|
cstate <= IDLE;
|
pccap <= 1'b1;
|
pccap <= 1'b1;
|
nonICacheSeg <= 32'hFFFF_FFFD;
|
nonICacheSeg <= 32'hFFFF_FFFD;
|
TBA <= 64'd0;
|
TBA <= 64'd0;
|
pc <= `RESET_VECTOR;
|
pc <= `RESET_VECTOR;
|
m1Opcode <= `NOPI;
|
m1Opcode <= `NOPI;
|
Line 1290... |
Line 1276... |
m2Rt <= 9'd0;
|
m2Rt <= 9'd0;
|
tData <= 64'd0;
|
tData <= 64'd0;
|
wData <= 64'd0;
|
wData <= 64'd0;
|
m1Data <= 64'd0;
|
m1Data <= 64'd0;
|
m2Data <= 64'd0;
|
m2Data <= 64'd0;
|
m2LdPC <= 1'b0;
|
|
wLdPC <= 1'b0;
|
|
m1IsLoad <= 1'b0;
|
m1IsLoad <= 1'b0;
|
m2IsLoad <= 1'b0;
|
m2IsLoad <= 1'b0;
|
m1IsStore <= 1'b0;
|
m1IsStore <= 1'b0;
|
m2IsStore <= 1'b0;
|
m2IsStore <= 1'b0;
|
wIsStore <= 1'b0;
|
wIsStore <= 1'b0;
|
Line 1319... |
Line 1303... |
m1pcv <= 1'b0;
|
m1pcv <= 1'b0;
|
m2pcv <= 1'b0;
|
m2pcv <= 1'b0;
|
wpcv <= 1'b0;
|
wpcv <= 1'b0;
|
tick <= 64'd0;
|
tick <= 64'd0;
|
cstate <= IDLE;
|
cstate <= IDLE;
|
AXC <= 4'd0;
|
|
dAXC <= 4'd0;
|
dAXC <= 4'd0;
|
xirqf <= 1'b0;
|
xirqf <= 1'b0;
|
dextype <= 9'h00;
|
dextype <= 9'h00;
|
xextype <= 9'h00;
|
xextype <= 9'h00;
|
m1extype <= 9'h00;
|
m1extype <= 9'h00;
|
Line 1351... |
Line 1334... |
im1 <= 1'b1;
|
im1 <= 1'b1;
|
// These must be non-zero in order to produce random numbers
|
// These must be non-zero in order to produce random numbers
|
// We set them here in case the user doesn't bother to set them.
|
// We set them here in case the user doesn't bother to set them.
|
m_z <= 64'h0123456789ABCDEF;
|
m_z <= 64'h0123456789ABCDEF;
|
m_w <= 64'h8888888877777777;
|
m_w <= 64'h8888888877777777;
|
insnkey <= 42'd0;
|
insnkey <= 32'd0;
|
|
LoadNOPs <= 1'b0;
|
|
eptr <= 8'h00;
|
end
|
end
|
else begin
|
else begin
|
|
|
//---------------------------------------------------------
|
//---------------------------------------------------------
|
// Initialize program counters
|
// Initialize program counters
|
// Initialize data tags to zero.
|
// Initialize data tags to zero.
|
|
// Initialize execution pattern register to zero.
|
//---------------------------------------------------------
|
//---------------------------------------------------------
|
if (resetA) begin
|
case(state)
|
|
RESET:
|
|
begin
|
pc <= `RESET_VECTOR;
|
pc <= `RESET_VECTOR;
|
adr_o[14:6] <= adr_o[14:6]+9'd1;
|
adr_o[14:6] <= adr_o[14:6]+9'd1;
|
if (adr_o[14:6]==9'h1FF) begin
|
if (adr_o[14:6]==9'h1FF) begin
|
dtinit <= 1'b0;
|
dtinit <= 1'b0;
|
resetA <= 1'b0;
|
resetA <= 1'b0;
|
|
state <= RUN;
|
end
|
end
|
|
epat[a[7:0]] <= b[3:0]; /// b=0, to make this line the same as MTEP
|
|
a[7:0] <= a[7:0] + 8'h1;
|
end
|
end
|
|
RUN:
|
|
begin
|
|
|
tick <= tick + 64'd1;
|
tick <= tick + 64'd1;
|
|
|
prev_nmi <= nmi_i;
|
prev_nmi <= nmi_i;
|
if (!prev_nmi & nmi_i)
|
if (!prev_nmi & nmi_i)
|
Line 1398... |
Line 1391... |
//---------------------------------------------------------
|
//---------------------------------------------------------
|
if (advanceI) begin
|
if (advanceI) begin
|
dpcv <= 1'b1;
|
dpcv <= 1'b1;
|
dAXC <= AXC;
|
dAXC <= AXC;
|
dextype <= `EX_NON;
|
dextype <= `EX_NON;
|
if (nmi_edge & !StatusHWI & !im1) begin
|
if (nmi_edge & !StatusHWI) begin
|
$display("*****************");
|
$display("*****************");
|
$display("NMI edge detected");
|
$display("NMI edge detected");
|
$display("*****************");
|
$display("*****************");
|
StatusHWI <= 1'b1;
|
StatusHWI <= 1'b1;
|
nmi_edge <= 1'b0;
|
nmi_edge <= 1'b0;
|
dhwxtype <= 2'b01;
|
dhwxtype <= 2'b01;
|
dextype <= `EX_NMI;
|
dextype <= `EX_NMI;
|
dIR <= `NOP_INSN;
|
dIR <= `NOP_INSN;
|
|
LoadNOPs <= 1'b1;
|
end
|
end
|
else if (irq_i & !im & !StatusHWI & !im1) begin
|
else if (irq_i & !im & !StatusHWI) begin
|
$display("*****************");
|
$display("*****************");
|
$display("IRQ detected");
|
$display("IRQ detected");
|
$display("*****************");
|
$display("*****************");
|
bu_im <= 1'b0;
|
bu_im <= 1'b0;
|
im <= 1'b1;
|
im <= 1'b1;
|
StatusHWI <= 1'b1;
|
StatusHWI <= 1'b1;
|
dhwxtype <= 2'b10;
|
dhwxtype <= 2'b10;
|
dextype <= `EX_IRQ;
|
dextype <= `EX_IRQ;
|
dIR <= `NOP_INSN;
|
dIR <= `NOP_INSN;
|
|
LoadNOPs <= 1'b1;
|
end
|
end
|
// Are we filling the pipeline with NOP's as a result of a previous
|
// Are we filling the pipeline with NOP's as a result of a previous
|
// hardware interrupt ?
|
// hardware interrupt ?
|
else if (|dhwxtype|dFip)
|
else if (|dhwxtype|dFip|LoadNOPs)
|
dIR <= `NOP_INSN;
|
dIR <= `NOP_INSN;
|
`ifdef TLB
|
`ifdef TLB
|
else if (ITLBMiss)
|
else if (ITLBMiss)
|
dIR <= `NOP_INSN;
|
dIR <= `NOP_INSN;
|
`endif
|
`endif
|
else begin
|
else begin
|
if (((iOpcode==`SM || iOpcode==`LM) && insn[31:0]!=32'd0) || (iIsLSPair && !insn[25]))
|
|
im1 <= 1'b1;
|
|
else
|
|
im1 <= 1'b0;
|
|
if (iIsLSPair && insn[25]==1'b1) begin
|
|
dIR <= `NOP_INSN;
|
|
pc <= fnIncPC(pc);
|
|
end
|
|
else if ((iOpcode==`SM || iOpcode==`LM) && insn[31:0]==32'd0) begin
|
|
dIR <= `NOP_INSN;
|
|
pc <= fnIncPC(pc);
|
|
end
|
|
else
|
|
dIR <= insn;
|
dIR <= insn;
|
`include "insn_dumpsc.v"
|
`include "insn_dumpsc.v"
|
end
|
end
|
// Cause the prefixed instruction to inherit the address of the immediate
|
|
// prefix, by not resetting the address.
|
|
if (dOpcode[6:4]!=`IMM)
|
|
dpc <= pc;
|
dpc <= pc;
|
`ifdef TLB
|
`ifdef TLB
|
if (ITLBMiss) begin
|
if (ITLBMiss) begin
|
$display("TLB miss on instruction fetch.");
|
$display("TLB miss on instruction fetch.");
|
StatusEXL <= 1'b1;
|
StatusEXL <= 1'b1;
|
Line 1460... |
Line 1439... |
end
|
end
|
else
|
else
|
`endif
|
`endif
|
begin
|
begin
|
dbranch_taken <= 1'b0;
|
dbranch_taken <= 1'b0;
|
if (iIsLSPair && !insn[25])
|
// if (!LoadNOPs)
|
;
|
|
else if ((iOpcode==`LM || iOpcode==`SM) && insn[31:0]!=32'd0)
|
|
;
|
|
else begin
|
|
if (pc!=64'hC)
|
|
pc <= fnIncPC(pc);
|
pc <= fnIncPC(pc);
|
end
|
|
case(iOpcode)
|
case(iOpcode)
|
`MISC:
|
`MISC:
|
case(iFunc)
|
case(iFunc)
|
`FIP: dFip <= 1'b1;
|
`FIP: dFip <= 1'b1;
|
default: ;
|
default: ;
|
Line 1489... |
Line 1462... |
end
|
end
|
`RET:
|
`RET:
|
begin
|
begin
|
pc <= ras[ras_sp + 6'd1];
|
pc <= ras[ras_sp + 6'd1];
|
ras_sp <= ras_sp + 6'd1;
|
ras_sp <= ras_sp + 6'd1;
|
if (ras[ras_sp+6'd1]==64'hFFFF_FFFF_FFFF_C100)
|
|
$display("****** C100 reached *****");
|
|
end
|
end
|
`JMP:
|
`JMP:
|
begin
|
begin
|
dbranch_taken <= 1'b1;
|
dbranch_taken <= 1'b1;
|
pc <= jmp_tgt;
|
pc <= jmp_tgt;
|
Line 1503... |
Line 1474... |
case(insn[4:0])
|
case(insn[4:0])
|
`BEQ,`BNE,`BLT,`BLE,`BGT,`BGE,`BLTU,`BLEU,`BGTU,`BGEU,`BAND,`BOR,`BRA,`BNR,`BRN,`LOOP:
|
`BEQ,`BNE,`BLT,`BLE,`BGT,`BGE,`BLTU,`BLEU,`BGTU,`BGEU,`BAND,`BOR,`BRA,`BNR,`BRN,`LOOP:
|
if (predict_taken) begin
|
if (predict_taken) begin
|
// $display("Taking predicted branch: %h",{pc[63:4] + {{42{insn[24]}},insn[24:7]},insn[6:5],2'b00});
|
// $display("Taking predicted branch: %h",{pc[63:4] + {{42{insn[24]}},insn[24:7]},insn[6:5],2'b00});
|
dbranch_taken <= 1'b1;
|
dbranch_taken <= 1'b1;
|
pc <= {pc[63:4] + {{42{insn[24]}},insn[24:7]},insn[6:5],2'b00};
|
pc <= pc + {{52{insn[14]}},insn[14:5],2'b00};
|
end
|
end
|
default: ;
|
default: ;
|
endcase
|
endcase
|
|
|
|
// If doing a JAL that stores a return address in the link register, save off the return address
|
|
// in the return address predictor stack.
|
|
`JAL:
|
|
if (insn[19:15]==5'd31) begin
|
|
ras[ras_sp] <= fnIncPC(pc);
|
|
ras_sp <= ras_sp - 6'd1;
|
|
end
|
`ifdef BTB
|
`ifdef BTB
|
`JAL: pc <= btb[pc[7:2]];
|
`JAL: pc <= btb[pc[7:2]];
|
`BTRI:
|
`BTRI:
|
if (predict_taken) begin
|
if (predict_taken) begin
|
dbranch_taken <= 1'b1;
|
dbranch_taken <= 1'b1;
|
Line 1519... |
Line 1498... |
`endif
|
`endif
|
`BEQI,`BNEI,`BLTI,`BLEI,`BGTI,`BGEI,`BLTUI,`BLEUI,`BGTUI,`BGEUI:
|
`BEQI,`BNEI,`BLTI,`BLEI,`BGTI,`BGEI,`BLTUI,`BLEUI,`BGTUI,`BGEUI:
|
begin
|
begin
|
if (predict_taken) begin
|
if (predict_taken) begin
|
dbranch_taken <= 1'b1;
|
dbranch_taken <= 1'b1;
|
pc <= {pc[63:4] + {{50{insn[29]}},insn[29:20]},insn[19:18],2'b00};
|
pc <= pc + {{50{insn[19]}},insn[19:8],2'b00};
|
end
|
end
|
end
|
end
|
default: ;
|
default: ;
|
endcase
|
endcase
|
end
|
end
|
Line 1531... |
Line 1510... |
// Stage tail
|
// Stage tail
|
// Pipeline annul for when a bubble in the pipeline occurs.
|
// Pipeline annul for when a bubble in the pipeline occurs.
|
else if (advanceR) begin
|
else if (advanceR) begin
|
dbranch_taken <= 1'b0;
|
dbranch_taken <= 1'b0;
|
dextype <= `EX_NON;
|
dextype <= `EX_NON;
|
// IMM is "sticky"
|
|
if (dOpcode[6:4]!=`IMM && dOpcode!=`LM && dOpcode!=`SM && !dIsLSPair) begin
|
|
dIR <= `NOP_INSN;
|
dIR <= `NOP_INSN;
|
dpcv <= 1'b0;
|
dpcv <= 1'b0;
|
dpc <= `RESET_VECTOR;
|
dpc <= `RESET_VECTOR;
|
end
|
end
|
if ((((dOpcode==`SM || dOpcode==`LM) && dIR[31:0]!=32'd0)) || (dIsLSPair && !dIR[25]))
|
|
dIR <= ndIR;
|
|
end
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
// RFETCH:
|
// RFETCH:
|
// Register fetch stage
|
// Register fetch stage
|
Line 1568... |
Line 1542... |
else
|
else
|
xIR <= dIR;
|
xIR <= dIR;
|
a <= nxt_a;
|
a <= nxt_a;
|
b <= nxt_b;
|
b <= nxt_b;
|
if (dOpcode==`SHFTI)
|
if (dOpcode==`SHFTI)
|
b <= {58'd0,dIR[24:19]};
|
b <= {58'd0,dIR[14:9]};
|
c <= nxt_c;
|
c <= nxt_c;
|
|
|
// Set immediate value
|
|
if (xOpcode[6:4]==`IMM) begin
|
|
imm <= {xIR[38:0],dIR[24:0]};
|
|
end
|
|
else
|
|
case(dOpcode)
|
case(dOpcode)
|
`BTRI: imm <= {{44{dIR[19]}},dIR[19:0]};
|
`BTRI: imm <= {{53{dIR[10]}},dIR[10:0]};
|
`BEQI,`BNEI,`BLTI,`BLEI,`BGTI,`BGEI,`BLTUI,`BLEUI,`BGTUI,`BGEUI:
|
`BEQI,`BNEI,`BLTI,`BLEI,`BGTI,`BGEI,`BLTUI,`BLEUI,`BGTUI,`BGEUI:
|
imm <= {{46{dIR[17]}},dIR[17:0]};
|
imm <= {{56{dIR[7]}},dIR[7:0]};
|
`ORI: imm <= {39'h0000000000,dIR[24:0]};
|
`RET: imm <= {49'h00000000,dIR[14:3],3'b000};
|
`XORI: imm <= {39'h0000000000,dIR[24:0]};
|
`MEMNDX: imm <= dIR[7:6];
|
`RET: imm <= {39'h00000000,dIR[24:3],3'b000};
|
default: imm <= {{49{dIR[14]}},dIR[14:0]};
|
`MEMNDX: imm <= {{50{dIR[19]}},dIR[19:6]};
|
|
default: imm <= {{39{dIR[24]}},dIR[24:0]};
|
|
endcase
|
endcase
|
|
scale <= dIR[9:8];
|
end
|
end
|
// Stage tail
|
// Stage tail
|
// Pipeline annul for when a bubble in the pipeline occurs.
|
// Pipeline annul for when a bubble in the pipeline occurs.
|
else if (advanceX) begin
|
else if (advanceX) begin
|
xRtZero <= 1'b1;
|
xRtZero <= 1'b1;
|
xextype <= `EX_NON;
|
xextype <= `EX_NON;
|
xbranch_taken <= 1'b0;
|
xbranch_taken <= 1'b0;
|
if (xOpcode[6:4]!=`IMM) begin
|
|
xIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
xpcv <= 1'b0;
|
xpcv <= 1'b0;
|
xpc <= `RESET_VECTOR;
|
xpc <= `RESET_VECTOR;
|
end
|
end
|
end
|
|
|
|
//---------------------------------------------------------
|
//---------------------------------------------------------
|
// EXECUTE:
|
// EXECUTE:
|
// - perform datapath operation
|
// - perform datapath operation
|
// - perform virtual to physical address translation.
|
// - perform virtual to physical address translation.
|
Line 1623... |
Line 1589... |
m1IsIO <= xIsIO;
|
m1IsIO <= xIsIO;
|
m1Opcode <= xOpcode;
|
m1Opcode <= xOpcode;
|
m1Rt <= xRtZero ? 9'd0 : xRt;
|
m1Rt <= xRtZero ? 9'd0 : xRt;
|
m1Data <= xData;
|
m1Data <= xData;
|
m1IsCacheElement <= xisCacheElement;
|
m1IsCacheElement <= xisCacheElement;
|
if (xOpcode==`MOVZ && !aeqz) begin
|
m1AXC <= xAXC;
|
|
if (xOpcode==`RR) begin
|
|
if (xFunc6==`MOVZ && !aeqz) begin
|
m1Rt <= 9'd0;
|
m1Rt <= 9'd0;
|
m1Data <= 64'd0;
|
m1Data <= 64'd0;
|
end
|
end
|
if (xOpcode==`MOVNZ && aeqz) begin
|
if (xFunc6==`MOVNZ && aeqz) begin
|
m1Rt <= 9'd0;
|
m1Rt <= 9'd0;
|
m1Data <= 64'd0;
|
m1Data <= 64'd0;
|
end
|
end
|
|
if (xFunc6==`MOVPL && a[63]) begin
|
|
m1Rt <= 9'd0;
|
|
m1Data <= 64'd0;
|
|
end
|
|
if (xFunc6==`MOVMI && !a[63]) begin
|
|
m1Rt <= 9'd0;
|
|
m1Data <= 64'd0;
|
|
end
|
|
end
|
|
|
case(xOpcode)
|
case(xOpcode)
|
`MISC:
|
`MISC:
|
case(xFunc)
|
case(xFunc)
|
`SEI: im <= 1'b1;
|
`SEI: im <= 1'b1;
|
Line 1642... |
Line 1619... |
`WAIT: m1clkoff <= 1'b1;
|
`WAIT: m1clkoff <= 1'b1;
|
`ICACHE_ON: ICacheOn <= 1'b1;
|
`ICACHE_ON: ICacheOn <= 1'b1;
|
`ICACHE_OFF: ICacheOn <= 1'b0;
|
`ICACHE_OFF: ICacheOn <= 1'b0;
|
`DCACHE_ON: dcache_on <= 1'b1;
|
`DCACHE_ON: dcache_on <= 1'b1;
|
`DCACHE_OFF: dcache_on <= 1'b0;
|
`DCACHE_OFF: dcache_on <= 1'b0;
|
|
`IEPP: eptr <= eptr + 8'd1;
|
`GRAN: begin
|
`GRAN: begin
|
rando <= rand;
|
rando <= rand;
|
m_z <= next_m_z;
|
m_z <= next_m_z;
|
m_w <= next_m_w;
|
m_w <= next_m_w;
|
end
|
end
|
Line 1656... |
Line 1634... |
end
|
end
|
`IRET:
|
`IRET:
|
if (StatusHWI) begin
|
if (StatusHWI) begin
|
StatusHWI <= 1'b0;
|
StatusHWI <= 1'b0;
|
im <= 1'b0;
|
im <= 1'b0;
|
pc <= IPC;
|
pc <= a;
|
dIR <= `NOP_INSN;
|
dIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
xRtZero <= 1'b1;
|
xRtZero <= 1'b1;
|
xpcv <= 1'b0;
|
xpcv <= 1'b0;
|
dpcv <= 1'b0;
|
dpcv <= 1'b0;
|
end
|
end
|
`ERET:
|
`ERET:
|
if (StatusEXL) begin
|
if (StatusEXL) begin
|
StatusEXL <= 1'b0;
|
StatusEXL <= 1'b0;
|
pc <= EPC;
|
pc <= a;
|
dIR <= `NOP_INSN;
|
dIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
xRtZero <= 1'b1;
|
xRtZero <= 1'b1;
|
xpcv <= 1'b0;
|
xpcv <= 1'b0;
|
dpcv <= 1'b0;
|
dpcv <= 1'b0;
|
end
|
end
|
`SYSJMP:
|
`SYSCALL:
|
begin
|
begin
|
if (xIR[15:7]!=`EX_NMI && xIR[15:7]!=`EX_IRQ) begin
|
if (xIR[15:7]!=`EX_NMI && xIR[15:7]!=`EX_IRQ) begin
|
StatusEXL <= 1'b1;
|
StatusEXL <= 1'b1;
|
end
|
end
|
pc <= 64'hC;
|
if (xIR[15:7]==`EX_NMI || xIR[15:7]==`EX_IRQ)
|
dIR <= `NOP_INSN;
|
m1Data <= xpc;
|
xIR <= `NOP_INSN;
|
else
|
xRtZero <= 1'b1;
|
m1Data <= fnIncPC(xpc);
|
xpcv <= 1'b0;
|
|
dpcv <= 1'b0;
|
|
ea <= {TBA[63:12],xIR[15:7],3'b000};
|
|
end
|
|
// SYSCALL EX_IRQ won't work.
|
|
`SYSCALL:
|
|
begin
|
|
StatusEXL <= 1'b1;
|
|
EPC <= fnIncPC(xpc);
|
|
pc <= 64'hC;
|
|
dIR <= `NOP_INSN;
|
dIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
xRtZero <= 1'b1;
|
xRtZero <= 1'b1;
|
xpcv <= 1'b0;
|
xpcv <= 1'b0;
|
dpcv <= 1'b0;
|
dpcv <= 1'b0;
|
ea <= {TBA[63:12],xIR[15:7],3'b000};
|
ea <= {TBA[63:12],xIR[15:7],3'b000};
|
|
$display("EX SYSCALL thru %h",{TBA[63:12],xIR[15:7],3'b000});
|
end
|
end
|
`ifdef TLB
|
`ifdef TLB
|
`TLBP: ea <= TLBVirtPage;
|
`TLBP: ea <= TLBVirtPage;
|
`endif
|
`endif
|
default: ;
|
default: ;
|
endcase
|
endcase
|
`R:
|
`R:
|
case(xFunc)
|
case(xFunc6)
|
`EXEC:
|
`EXEC:
|
begin
|
begin
|
pc <= fnIncPC(xpc);
|
pc <= fnIncPC(xpc);
|
dIR <= b;
|
dIR <= b;
|
xIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
Line 1724... |
Line 1693... |
`BadVAddr: BadVAddr <= a[63:13];
|
`BadVAddr: BadVAddr <= a[63:13];
|
`endif
|
`endif
|
`ASID: ASID <= a[7:0];
|
`ASID: ASID <= a[7:0];
|
`EPC: EPC <= a;
|
`EPC: EPC <= a;
|
`TBA: TBA <= {a[63:12],12'h000};
|
`TBA: TBA <= {a[63:12],12'h000};
|
`AXC: AXC <= a[3:0];
|
// `AXC: AXC <= a[3:0];
|
`NON_ICACHE_SEG: nonICacheSeg <= a[63:32];
|
`NON_ICACHE_SEG: nonICacheSeg <= a[63:32];
|
`FPCR: rm <= a[31:30];
|
`FPCR: rm <= a[31:30];
|
`IPC: IPC <= a;
|
`IPC: IPC <= a;
|
`SRAND1: begin
|
`SRAND1: begin
|
m_z <= a;
|
m_z <= a;
|
Line 1744... |
Line 1713... |
`CMG: mutex_gate[a[5:0]] <= 1'b0;
|
`CMG: mutex_gate[a[5:0]] <= 1'b0;
|
`OMGI: mutex_gate[xIR[12:7]] <= 1'b1;
|
`OMGI: mutex_gate[xIR[12:7]] <= 1'b1;
|
`CMGI: mutex_gate[xIR[12:7]] <= 1'b0;
|
`CMGI: mutex_gate[xIR[12:7]] <= 1'b0;
|
default: ;
|
default: ;
|
endcase
|
endcase
|
|
`RR:
|
|
case(xFunc6)
|
|
`MTEP: epat[a[7:0]] <= b[3:0];
|
|
default: ;
|
|
endcase
|
// JMP and CALL change the program counter immediately in the IF stage.
|
// JMP and CALL change the program counter immediately in the IF stage.
|
// There's no work to do here. The pipeline does not need to be cleared.
|
// There's no work to do here. The pipeline does not need to be cleared.
|
`JMP: ;
|
`JMP: ;
|
`CALL: m1Data <= fnIncPC(xpc);
|
`CALL: m1Data <= fnIncPC(xpc);
|
|
|
`JAL:
|
`JAL:
|
`ifdef BTB
|
`ifdef BTB
|
if (dpc[63:2] != a[63:2] + imm[63:2]) begin
|
if (dpc[63:2] != a[63:2] + imm[63:2]) begin
|
pc[63:2] <= a[63:2] + imm[63:2];
|
pc[63:2] <= a[63:2] + imm[63:2];
|
btb[xpc[7:2]] <= {a[63:2] + imm[63:2],2'b00};
|
btb[xpc[7:2]] <= {a[63:2] + imm[63:2],2'b00};
|
Line 1775... |
Line 1750... |
// see if it's equal to the RET target. If it's the same as the target then
|
// see if it's equal to the RET target. If it's the same as the target then
|
// we predicted the RET return correctly, so there's nothing to do. Otherwise
|
// we predicted the RET return correctly, so there's nothing to do. Otherwise
|
// we need to branch to the RET location.
|
// we need to branch to the RET location.
|
`RET:
|
`RET:
|
if (dpc[63:2]!=b[63:2]) begin
|
if (dpc[63:2]!=b[63:2]) begin
|
// $display("returning to: %h.%h", {b[63:4],4'b0},b[3:2]);
|
|
pc[63:2] <= b[63:2];
|
pc[63:2] <= b[63:2];
|
dIR <= `NOP_INSN;
|
dIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
xRtZero <= 1'b1;
|
xRtZero <= 1'b1;
|
xpcv <= 1'b0;
|
xpcv <= 1'b0;
|
Line 1797... |
Line 1771... |
xRtZero <= 1'b1;
|
xRtZero <= 1'b1;
|
xpcv <= 1'b0;
|
xpcv <= 1'b0;
|
dpcv <= 1'b0;
|
dpcv <= 1'b0;
|
end
|
end
|
else if (takb & !xbranch_taken) begin
|
else if (takb & !xbranch_taken) begin
|
$display("Taking branch %h.%h",{xpc[63:4] + {{42{xIR[24]}},xIR[24:7]},4'b0000},xIR[6:5]);
|
$display("Taking branch %h",{xpc[63:2] + {{52{xIR[14]}},xIR[14:5]},2'b00});
|
pc[63:4] <= xpc[63:4] + {{42{xIR[24]}},xIR[24:7]};
|
pc[63:2] <= xpc[63:2] + {{52{xIR[14]}},xIR[14:5]};
|
pc[3:2] <= xIR[6:5];
|
|
dIR <= `NOP_INSN;
|
dIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
xRtZero <= 1'b1;
|
xRtZero <= 1'b1;
|
xpcv <= 1'b0;
|
xpcv <= 1'b0;
|
dpcv <= 1'b0;
|
dpcv <= 1'b0;
|
Line 1861... |
Line 1834... |
`endif
|
`endif
|
// BEQI r1,#3,label
|
// BEQI r1,#3,label
|
`BEQI,`BNEI,`BLTI,`BLEI,`BGTI,`BGEI,`BLTUI,`BLEUI,`BGTUI,`BGEUI:
|
`BEQI,`BNEI,`BLTI,`BLEI,`BGTI,`BGEI,`BLTUI,`BLEUI,`BGTUI,`BGEUI:
|
if (takb) begin
|
if (takb) begin
|
if (!xbranch_taken) begin
|
if (!xbranch_taken) begin
|
pc[63:4] <= xpc[63:4] + {{50{xIR[29]}},xIR[29:20]};
|
pc[63:2] <= xpc[63:2] + {{50{xIR[19]}},xIR[19:8]};
|
pc[3:2] <= xIR[19:18];
|
|
dIR <= `NOP_INSN;
|
dIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
xRtZero <= 1'b1;
|
xRtZero <= 1'b1;
|
xpcv <= 1'b0;
|
xpcv <= 1'b0;
|
dpcv <= 1'b0;
|
dpcv <= 1'b0;
|
Line 1885... |
Line 1857... |
end
|
end
|
`TRAPcc,`TRAPcci:
|
`TRAPcc,`TRAPcci:
|
if (takb) begin
|
if (takb) begin
|
StatusEXL <= 1'b1;
|
StatusEXL <= 1'b1;
|
xextype <= `EX_TRAP;
|
xextype <= `EX_TRAP;
|
pc <= 64'hC;
|
|
dIR <= `NOP_INSN;
|
dIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
xRtZero <= 1'b1;
|
xRtZero <= 1'b1;
|
xpcv <= 1'b0;
|
xpcv <= 1'b0;
|
dpcv <= 1'b0;
|
dpcv <= 1'b0;
|
Line 1898... |
Line 1869... |
`INW:
|
`INW:
|
begin
|
begin
|
iocyc_o <= 1'b1;
|
iocyc_o <= 1'b1;
|
stb_o <= 1'b1;
|
stb_o <= 1'b1;
|
sel_o <= 8'hFF;
|
sel_o <= 8'hFF;
|
adr_o <= {xData[63:3],3'b000};
|
adr_o <= xData1;
|
end
|
end
|
`INH,`INHU:
|
`INH,`INHU:
|
begin
|
begin
|
iocyc_o <= 1'b1;
|
iocyc_o <= 1'b1;
|
stb_o <= 1'b1;
|
stb_o <= 1'b1;
|
sel_o <= xData[2] ? 8'b11110000 : 8'b00001111;
|
sel_o <= xData1[2] ? 8'b11110000 : 8'b00001111;
|
adr_o <= {xData[63:2],2'b00};
|
adr_o <= xData1;
|
end
|
end
|
`INCH,`INCU:
|
`INCH,`INCU:
|
begin
|
begin
|
iocyc_o <= 1'b1;
|
iocyc_o <= 1'b1;
|
stb_o <= 1'b1;
|
stb_o <= 1'b1;
|
case(xData[2:1])
|
case(xData1[2:1])
|
2'b00: sel_o <= 8'b00000011;
|
2'b00: sel_o <= 8'b00000011;
|
2'b01: sel_o <= 8'b00001100;
|
2'b01: sel_o <= 8'b00001100;
|
2'b10: sel_o <= 8'b00110000;
|
2'b10: sel_o <= 8'b00110000;
|
2'b11: sel_o <= 8'b11000000;
|
2'b11: sel_o <= 8'b11000000;
|
endcase
|
endcase
|
adr_o <= {xData[63:1],1'b0};
|
adr_o <= xData1;
|
end
|
end
|
`INB,`INBU:
|
`INB,`INBU:
|
begin
|
begin
|
iocyc_o <= 1'b1;
|
iocyc_o <= 1'b1;
|
stb_o <= 1'b1;
|
stb_o <= 1'b1;
|
case(xData[2:0])
|
case(xData1[2:0])
|
3'b000: sel_o <= 8'b00000001;
|
3'b000: sel_o <= 8'b00000001;
|
3'b001: sel_o <= 8'b00000010;
|
3'b001: sel_o <= 8'b00000010;
|
3'b010: sel_o <= 8'b00000100;
|
3'b010: sel_o <= 8'b00000100;
|
3'b011: sel_o <= 8'b00001000;
|
3'b011: sel_o <= 8'b00001000;
|
3'b100: sel_o <= 8'b00010000;
|
3'b100: sel_o <= 8'b00010000;
|
Line 1941... |
Line 1912... |
begin
|
begin
|
iocyc_o <= 1'b1;
|
iocyc_o <= 1'b1;
|
stb_o <= 1'b1;
|
stb_o <= 1'b1;
|
we_o <= 1'b1;
|
we_o <= 1'b1;
|
sel_o <= 8'hFF;
|
sel_o <= 8'hFF;
|
adr_o <= {xData[63:3],3'b000};
|
adr_o <= xData1;
|
dat_o <= b;
|
dat_o <= b;
|
end
|
end
|
`OUTH:
|
`OUTH:
|
begin
|
begin
|
iocyc_o <= 1'b1;
|
iocyc_o <= 1'b1;
|
stb_o <= 1'b1;
|
stb_o <= 1'b1;
|
we_o <= 1'b1;
|
we_o <= 1'b1;
|
sel_o <= xData[2] ? 8'b11110000 : 8'b00001111;
|
sel_o <= xData1[2] ? 8'b11110000 : 8'b00001111;
|
adr_o <= {xData[63:2],2'b00};
|
adr_o <= xData1;
|
dat_o <= {2{b[31:0]}};
|
dat_o <= {2{b[31:0]}};
|
end
|
end
|
`OUTC:
|
`OUTC:
|
begin
|
begin
|
iocyc_o <= 1'b1;
|
iocyc_o <= 1'b1;
|
stb_o <= 1'b1;
|
stb_o <= 1'b1;
|
we_o <= 1'b1;
|
we_o <= 1'b1;
|
case(xData[2:1])
|
case(xData1[2:1])
|
2'b00: sel_o <= 8'b00000011;
|
2'b00: sel_o <= 8'b00000011;
|
2'b01: sel_o <= 8'b00001100;
|
2'b01: sel_o <= 8'b00001100;
|
2'b10: sel_o <= 8'b00110000;
|
2'b10: sel_o <= 8'b00110000;
|
2'b11: sel_o <= 8'b11000000;
|
2'b11: sel_o <= 8'b11000000;
|
endcase
|
endcase
|
adr_o <= {xData[63:1],1'b0};
|
adr_o <= xData1;
|
dat_o <= {4{b[15:0]}};
|
dat_o <= {4{b[15:0]}};
|
end
|
end
|
`OUTB:
|
`OUTB:
|
begin
|
begin
|
iocyc_o <= 1'b1;
|
iocyc_o <= 1'b1;
|
stb_o <= 1'b1;
|
stb_o <= 1'b1;
|
we_o <= 1'b1;
|
we_o <= 1'b1;
|
case(xData[2:0])
|
case(xData1[2:0])
|
3'b000: sel_o <= 8'b00000001;
|
3'b000: sel_o <= 8'b00000001;
|
3'b001: sel_o <= 8'b00000010;
|
3'b001: sel_o <= 8'b00000010;
|
3'b010: sel_o <= 8'b00000100;
|
3'b010: sel_o <= 8'b00000100;
|
3'b011: sel_o <= 8'b00001000;
|
3'b011: sel_o <= 8'b00001000;
|
3'b100: sel_o <= 8'b00010000;
|
3'b100: sel_o <= 8'b00010000;
|
3'b101: sel_o <= 8'b00100000;
|
3'b101: sel_o <= 8'b00100000;
|
3'b110: sel_o <= 8'b01000000;
|
3'b110: sel_o <= 8'b01000000;
|
3'b111: sel_o <= 8'b10000000;
|
3'b111: sel_o <= 8'b10000000;
|
endcase
|
endcase
|
adr_o <= xData;
|
adr_o <= xData1;
|
dat_o <= {8{b[7:0]}};
|
dat_o <= {8{b[7:0]}};
|
end
|
end
|
`LEA: m1Data <= xData;
|
`LEA: begin
|
|
$display("LEA %h", xData1);
|
|
m1Data <= xData1;
|
|
end
|
`LB,`LBU,`LC,`LCU,`LH,`LHU,`LW,`LWR,`LF,`LFD,`LM,`LSH,`LSW,`LP,`LFP,`LFDP,
|
`LB,`LBU,`LC,`LCU,`LH,`LHU,`LW,`LWR,`LF,`LFD,`LM,`LSH,`LSW,`LP,`LFP,`LFDP,
|
`SW,`SH,`SC,`SB,`SWC,`SF,`SFD,`SM,`SSH,`SSW,`SP,`SFP,`SFDP:
|
`SW,`SH,`SC,`SB,`SWC,`SF,`SFD,`SM,`SSW,`SP,`SFP,`SFDP:
|
begin
|
begin
|
m1Data <= b;
|
m1Data <= b;
|
ea <= xData;
|
ea <= xData1;
|
|
$display("EX MEMOP %h", xData1);
|
end
|
end
|
`SSH: begin
|
`SSH: begin
|
case(xRt)
|
case(xRt)
|
`SR: m1Data <= {2{sr}};
|
`SR: m1Data <= {2{sr}};
|
default: m1Data <= 64'd0;
|
default: m1Data <= 64'd0;
|
endcase
|
endcase
|
ea <= xData;
|
ea <= xData1;
|
end
|
end
|
`CACHE:
|
`CACHE:
|
begin
|
begin
|
m1Data <= b;
|
m1Data <= b;
|
ea <= xData;
|
ea <= xData1;
|
case(xIR[29:25])
|
case(xIR[19:15])
|
|
`INVIL: ; // handled in M1 stage
|
`INVIALL: tvalid <= 128'd0;
|
`INVIALL: tvalid <= 128'd0;
|
|
`ICACHEON: ICacheOn <= 1'b1;
|
|
`ICACHEOFF: ICacheOn <= 1'b0;
|
|
`DCACHEON: dcache_on <= 1'b1;
|
|
`DCACHEOFF: dcache_on <= 1'b0;
|
default: ;
|
default: ;
|
endcase
|
endcase
|
end
|
end
|
`MEMNDX:
|
`MEMNDX:
|
begin
|
begin
|
m1Opcode <= 7'd32+xFunc6;
|
m1Opcode <= 7'd32+xFunc6;
|
case(xFunc6)
|
case(xFunc6)
|
`LEAX:
|
`LEAX:
|
begin
|
begin
|
m1Data <= xData;
|
$display("LEAX %h", xData1);
|
|
m1Data <= xData1;
|
|
end
|
|
`INWX:
|
|
begin
|
|
iocyc_o <= 1'b1;
|
|
stb_o <= 1'b1;
|
|
sel_o <= 8'hFF;
|
|
adr_o <= xData1;
|
|
end
|
|
`INHX,`INHUX:
|
|
begin
|
|
iocyc_o <= 1'b1;
|
|
stb_o <= 1'b1;
|
|
sel_o <= xData1[2] ? 8'b11110000 : 8'b00001111;
|
|
adr_o <= xData1;
|
|
end
|
|
`INCX,`INCUX:
|
|
begin
|
|
iocyc_o <= 1'b1;
|
|
stb_o <= 1'b1;
|
|
case(xData1[2:1])
|
|
2'b00: sel_o <= 8'b00000011;
|
|
2'b01: sel_o <= 8'b00001100;
|
|
2'b10: sel_o <= 8'b00110000;
|
|
2'b11: sel_o <= 8'b11000000;
|
|
endcase
|
|
adr_o <= xData1;
|
|
end
|
|
`INBX,`INBUX:
|
|
begin
|
|
iocyc_o <= 1'b1;
|
|
stb_o <= 1'b1;
|
|
case(xData1[2:0])
|
|
3'b000: sel_o <= 8'b00000001;
|
|
3'b001: sel_o <= 8'b00000010;
|
|
3'b010: sel_o <= 8'b00000100;
|
|
3'b011: sel_o <= 8'b00001000;
|
|
3'b100: sel_o <= 8'b00010000;
|
|
3'b101: sel_o <= 8'b00100000;
|
|
3'b110: sel_o <= 8'b01000000;
|
|
3'b111: sel_o <= 8'b10000000;
|
|
endcase
|
|
adr_o <= xData1;
|
|
end
|
|
`OUTWX:
|
|
begin
|
|
iocyc_o <= 1'b1;
|
|
stb_o <= 1'b1;
|
|
we_o <= 1'b1;
|
|
sel_o <= 8'hFF;
|
|
adr_o <= xData1;
|
|
dat_o <= c;
|
|
end
|
|
`OUTHX:
|
|
begin
|
|
iocyc_o <= 1'b1;
|
|
stb_o <= 1'b1;
|
|
we_o <= 1'b1;
|
|
sel_o <= xData1[2] ? 8'b11110000 : 8'b00001111;
|
|
adr_o <= xData1;
|
|
dat_o <= {2{c[31:0]}};
|
|
end
|
|
`OUTCX:
|
|
begin
|
|
iocyc_o <= 1'b1;
|
|
stb_o <= 1'b1;
|
|
we_o <= 1'b1;
|
|
case(xData1[2:1])
|
|
2'b00: sel_o <= 8'b00000011;
|
|
2'b01: sel_o <= 8'b00001100;
|
|
2'b10: sel_o <= 8'b00110000;
|
|
2'b11: sel_o <= 8'b11000000;
|
|
endcase
|
|
adr_o <= xData1;
|
|
dat_o <= {4{c[15:0]}};
|
|
end
|
|
`OUTBX:
|
|
begin
|
|
iocyc_o <= 1'b1;
|
|
stb_o <= 1'b1;
|
|
we_o <= 1'b1;
|
|
case(xData1[2:0])
|
|
3'b000: sel_o <= 8'b00000001;
|
|
3'b001: sel_o <= 8'b00000010;
|
|
3'b010: sel_o <= 8'b00000100;
|
|
3'b011: sel_o <= 8'b00001000;
|
|
3'b100: sel_o <= 8'b00010000;
|
|
3'b101: sel_o <= 8'b00100000;
|
|
3'b110: sel_o <= 8'b01000000;
|
|
3'b111: sel_o <= 8'b10000000;
|
|
endcase
|
|
adr_o <= xData1;
|
|
dat_o <= {8{c[7:0]}};
|
end
|
end
|
default:
|
default:
|
begin
|
begin
|
m1Data <= c;
|
m1Data <= c;
|
ea <= xData;
|
ea <= xData1;
|
end
|
end
|
endcase
|
endcase
|
end
|
end
|
default: ;
|
default: ;
|
endcase
|
endcase
|
Line 2070... |
Line 2143... |
endcase
|
endcase
|
end
|
end
|
`endif
|
`endif
|
if (dbz_error) begin
|
if (dbz_error) begin
|
$display("Divide by zero error");
|
$display("Divide by zero error");
|
xIR <= {`MISC,19'd0,`EX_DBZ,`SYSJMP};
|
m1extype <= `EX_DBZ;
|
pc <= 64'hC;
|
LoadNOPs <= 1'b1;
|
EPC <= xpc;
|
|
dIR <= `NOP_INSN;
|
|
xRtZero <= 1'b1;
|
xRtZero <= 1'b1;
|
xpcv <= 1'b0;
|
xpcv <= 1'b0;
|
dpcv <= 1'b0;
|
dpcv <= 1'b0;
|
end
|
end
|
else if (ovr_error) begin
|
else if (ovr_error) begin
|
$display("Overflow error");
|
$display("Overflow error");
|
xIR <= {`MISC,19'd0,`EX_OFL,`SYSJMP};
|
m1extype <= `EX_OFL;
|
pc <= 64'hC;
|
LoadNOPs <= 1'b1;
|
EPC <= xpc;
|
|
dIR <= `NOP_INSN;
|
|
xRtZero <= 1'b1;
|
xRtZero <= 1'b1;
|
xpcv <= 1'b0;
|
xpcv <= 1'b0;
|
dpcv <= 1'b0;
|
dpcv <= 1'b0;
|
end
|
end
|
else if (priv_violation) begin
|
else if (priv_violation) begin
|
$display("Priviledge violation");
|
$display("Priviledge violation");
|
xIR <= {`MISC,19'd0,`EX_PRIV,`SYSJMP};
|
m1extype <= `EX_PRIV;
|
dIR <= `NOP_INSN;
|
LoadNOPs <= 1'b1;
|
xRtZero <= 1'b1;
|
xRtZero <= 1'b1;
|
xpcv <= 1'b0;
|
xpcv <= 1'b0;
|
dpcv <= 1'b0;
|
dpcv <= 1'b0;
|
pc <= 64'hC;
|
|
EPC <= xpc;
|
|
end
|
end
|
else if (illegal_insn) begin
|
else if (illegal_insn) begin
|
$display("Unimplemented Instruction");
|
$display("Unimplemented Instruction");
|
xIR <= {`MISC,19'd0,`EX_UNIMP_INSN,`SYSJMP};
|
m1extype <= `EX_UNIMP_INSN;
|
pc <= 64'hC;
|
LoadNOPs <= 1'b1;
|
EPC <= xpc;
|
|
dIR <= `NOP_INSN;
|
|
xRtZero <= 1'b1;
|
xRtZero <= 1'b1;
|
xpcv <= 1'b0;
|
xpcv <= 1'b0;
|
dpcv <= 1'b0;
|
dpcv <= 1'b0;
|
end
|
end
|
end
|
end
|
Line 2159... |
Line 2224... |
m2IsStore <= #1 m1IsStore;
|
m2IsStore <= #1 m1IsStore;
|
m2IsCnt <= m1IsCnt;
|
m2IsCnt <= m1IsCnt;
|
m2Func <= m1Func;
|
m2Func <= m1Func;
|
m2Rt <= m1Rt;
|
m2Rt <= m1Rt;
|
m2clkoff <= m1clkoff;
|
m2clkoff <= m1clkoff;
|
m2LdPC <= 1'b0;
|
m2AXC <= m1AXC;
|
if (m1IsIO & err_i) begin
|
if (m1IsIO & err_i) begin
|
m2extype <= `EX_DBERR;
|
m2extype <= `EX_DBERR;
|
errorAddress <= adr_o;
|
errorAddress <= adr_o;
|
end
|
end
|
|
|
if (m1extype == `EX_NON) begin
|
if (m1extype == `EX_NON) begin
|
case(m1Opcode)
|
case(m1Opcode)
|
`MISC:
|
`MISC:
|
case(m1Func)
|
case(m1Func)
|
`SYSJMP,`SYSCALL:
|
`SYSCALL:
|
begin
|
|
m2LdPC <= 1'b1;
|
|
if (!m1IsCacheElement) begin
|
if (!m1IsCacheElement) begin
|
cyc_o <= 1'b1;
|
cyc_o <= 1'b1;
|
stb_o <= 1'b1;
|
stb_o <= 1'b1;
|
sel_o <= 8'hFF;
|
sel_o <= 8'hFF;
|
adr_o <= {pea[63:3],3'b000};
|
adr_o <= pea;
|
m2Addr <= {pea[63:3],3'b000};
|
m2Addr <= pea;
|
end
|
end
|
else begin // dhit must be true
|
else begin // dhit must be true
|
|
$display("fetched vector: %h", {cdat[63:2],2'b00});
|
m2IsLoad <= 1'b0;
|
m2IsLoad <= 1'b0;
|
m2Opcode <= `NOPI;
|
m2Opcode <= `NOPI;
|
m2Data <= {cdat[63:2],2'b00};
|
pc <= {cdat[63:2],2'b00};
|
end
|
LoadNOPs <= 1'b0;
|
end
|
end
|
endcase
|
endcase
|
`INW:
|
`INW:
|
begin
|
begin
|
iocyc_o <= 1'b0;
|
iocyc_o <= 1'b0;
|
Line 2275... |
Line 2339... |
stb_o <= #1 1'b0;
|
stb_o <= #1 1'b0;
|
we_o <= #1 1'b0;
|
we_o <= #1 1'b0;
|
sel_o <= #1 8'h00;
|
sel_o <= #1 8'h00;
|
end
|
end
|
`CACHE:
|
`CACHE:
|
case(m1IR[29:25])
|
case(m1IR[19:15])
|
`INVIL: tvalid[ea[12:6]] <= 1'b0;
|
`INVIL: tvalid[pea[12:6]] <= 1'b0;
|
default: ;
|
default: ;
|
endcase
|
endcase
|
|
|
|
|
`LW,`LM,`LFD,`LSW,`LP,`LFDP:
|
`LW,`LM,`LFD,`LSW,`LP,`LFDP:
|
if (!m1IsCacheElement) begin
|
if (!m1IsCacheElement) begin
|
cyc_o <= 1'b1;
|
cyc_o <= 1'b1;
|
stb_o <= 1'b1;
|
stb_o <= 1'b1;
|
sel_o <= 8'hFF;
|
sel_o <= 8'hFF;
|
adr_o <= {pea[63:3],3'b000};
|
adr_o <= pea;
|
m2Addr <= {pea[63:3],3'b000};
|
m2Addr <= pea;
|
end
|
end
|
else begin
|
else begin
|
m2IsLoad <= 1'b0;
|
m2IsLoad <= 1'b0;
|
m2Opcode <= `NOPI;
|
m2Opcode <= `NOPI;
|
m2Data <= cdat;
|
m2Data <= cdat;
|
Line 2302... |
Line 2366... |
rsv_o <= 1'b1;
|
rsv_o <= 1'b1;
|
resv_address <= pea[63:5];
|
resv_address <= pea[63:5];
|
cyc_o <= 1'b1;
|
cyc_o <= 1'b1;
|
stb_o <= 1'b1;
|
stb_o <= 1'b1;
|
sel_o <= 8'hFF;
|
sel_o <= 8'hFF;
|
adr_o <= {pea[63:3],3'b000};
|
adr_o <= pea;
|
m2Addr <= {pea[63:3],3'b000};
|
m2Addr <= pea;
|
end
|
end
|
else begin
|
else begin
|
m2IsLoad <= 1'b0;
|
m2IsLoad <= 1'b0;
|
m2Opcode <= `NOPI;
|
m2Opcode <= `NOPI;
|
m2Data <= cdat;
|
m2Data <= cdat;
|
rsv_o <= 1'b1;
|
rsv_o <= 1'b1; // ???
|
resv_address <= pea[63:5];
|
resv_address <= pea[63:5];
|
end
|
end
|
`endif
|
`endif
|
`LH,`LF,`LFP:
|
`LH,`LF,`LFP:
|
if (!m1IsCacheElement) begin
|
if (!m1IsCacheElement) begin
|
cyc_o <= 1'b1;
|
cyc_o <= 1'b1;
|
stb_o <= 1'b1;
|
stb_o <= 1'b1;
|
sel_o <= pea[2] ? 8'b11110000 : 8'b00001111;
|
sel_o <= pea[2] ? 8'b11110000 : 8'b00001111;
|
adr_o <= {pea[63:2],2'b00};
|
adr_o <= pea;
|
m2Addr <= {pea[63:2],2'b00};
|
m2Addr <= pea;
|
end
|
end
|
else begin
|
else begin
|
m2IsLoad <= 1'b0;
|
m2IsLoad <= 1'b0;
|
m2Opcode <= `NOPI;
|
m2Opcode <= `NOPI;
|
if (pea[1])
|
if (pea[2])
|
m2Data <= {{32{cdat[31]}},cdat[31:0]};
|
m2Data <= {{32{cdat[31]}},cdat[31:0]};
|
else
|
else
|
m2Data <= {{32{cdat[63]}},cdat[63:32]};
|
m2Data <= {{32{cdat[63]}},cdat[63:32]};
|
end
|
end
|
|
|
`LHU,`LSH:
|
`LHU,`LSH:
|
if (!m1IsCacheElement) begin
|
if (!m1IsCacheElement) begin
|
cyc_o <= 1'b1;
|
cyc_o <= 1'b1;
|
stb_o <= 1'b1;
|
stb_o <= 1'b1;
|
sel_o <= pea[2] ? 8'b11110000 : 8'b00001111;
|
sel_o <= pea[2] ? 8'b11110000 : 8'b00001111;
|
adr_o <= {pea[63:2],2'b00};
|
adr_o <= pea;
|
m2Addr <= {pea[63:2],2'b00};
|
m2Addr <= pea;
|
end
|
end
|
else begin
|
else begin
|
m2IsLoad <= 1'b0;
|
m2IsLoad <= 1'b0;
|
m2Opcode <= `NOPI;
|
m2Opcode <= `NOPI;
|
if (pea[1])
|
if (pea[2])
|
m2Data <= {32'd0,cdat};
|
m2Data <= {32'd0,cdat};
|
else
|
else
|
m2Data <= {32'd0,cdat[63:32]};
|
m2Data <= {32'd0,cdat[63:32]};
|
end
|
end
|
|
|
Line 2357... |
Line 2421... |
2'b00: sel_o <= 8'b00000011;
|
2'b00: sel_o <= 8'b00000011;
|
2'b01: sel_o <= 8'b00001100;
|
2'b01: sel_o <= 8'b00001100;
|
2'b10: sel_o <= 8'b00110000;
|
2'b10: sel_o <= 8'b00110000;
|
2'b11: sel_o <= 8'b11000000;
|
2'b11: sel_o <= 8'b11000000;
|
endcase
|
endcase
|
adr_o <= {pea[63:1],1'b0};
|
adr_o <= pea;
|
m2Addr <= {pea[63:1],1'b0};
|
m2Addr <= pea;
|
end
|
end
|
else begin
|
else begin
|
$display("dhit=1, cdat=%h",cdat);
|
$display("dhit=1, cdat=%h",cdat);
|
m2IsLoad <= 1'b0;
|
m2IsLoad <= 1'b0;
|
m2Opcode <= `NOPI;
|
m2Opcode <= `NOPI;
|
Line 2382... |
Line 2446... |
2'b00: sel_o <= 8'b00000011;
|
2'b00: sel_o <= 8'b00000011;
|
2'b01: sel_o <= 8'b00001100;
|
2'b01: sel_o <= 8'b00001100;
|
2'b10: sel_o <= 8'b00110000;
|
2'b10: sel_o <= 8'b00110000;
|
2'b11: sel_o <= 8'b11000000;
|
2'b11: sel_o <= 8'b11000000;
|
endcase
|
endcase
|
adr_o <= {pea[63:1],1'b0};
|
adr_o <= pea;
|
m2Addr <= {pea[63:1],1'b0};
|
m2Addr <= pea;
|
end
|
end
|
else begin
|
else begin
|
m2IsLoad <= 1'b0;
|
m2IsLoad <= 1'b0;
|
m2Opcode <= `NOPI;
|
m2Opcode <= `NOPI;
|
case(pea[2:1])
|
case(pea[2:1])
|
Line 2453... |
Line 2517... |
m2Opcode <= `NOPI;
|
m2Opcode <= `NOPI;
|
case(pea[2:0])
|
case(pea[2:0])
|
3'b000: m2Data <= {56'd0,cdat[ 7: 0]};
|
3'b000: m2Data <= {56'd0,cdat[ 7: 0]};
|
3'b001: m2Data <= {56'd0,cdat[15: 8]};
|
3'b001: m2Data <= {56'd0,cdat[15: 8]};
|
3'b010: m2Data <= {56'd0,cdat[23:16]};
|
3'b010: m2Data <= {56'd0,cdat[23:16]};
|
3'b011: m2Data <= {56'd0,cdat[31:23]};
|
3'b011: m2Data <= {56'd0,cdat[31:24]};
|
3'b100: m2Data <= {56'd0,cdat[39:32]};
|
3'b100: m2Data <= {56'd0,cdat[39:32]};
|
3'b101: m2Data <= {56'd0,cdat[47:40]};
|
3'b101: m2Data <= {56'd0,cdat[47:40]};
|
3'b110: m2Data <= {56'd0,cdat[55:48]};
|
3'b110: m2Data <= {56'd0,cdat[55:48]};
|
3'b111: m2Data <= {56'd0,cdat[63:56]};
|
3'b111: m2Data <= {56'd0,cdat[63:56]};
|
endcase
|
endcase
|
end
|
end
|
|
|
`SW,`SM,`SFD,`SSW,`SP,`SFDP:
|
`SW,`SM,`SFD,`SSW,`SP,`SFDP:
|
begin
|
begin
|
$display("SW/SM");
|
$display("%d SW/SM %h",tick,{pea[63:3],3'b000});
|
m2Addr <= #1 {pea[63:3],3'b000};
|
m2Addr <= pea;
|
wrhit <= #1 dhit;
|
wrhit <= #1 dhit;
|
`ifdef ADDRESS_RESERVATION
|
`ifdef ADDRESS_RESERVATION
|
if (resv_address==pea[63:5])
|
if (resv_address==pea[63:5])
|
resv_address <= #1 59'd0;
|
resv_address <= #1 59'd0;
|
`endif
|
`endif
|
cyc_o <= #1 1'b1;
|
cyc_o <= #1 1'b1;
|
stb_o <= #1 1'b1;
|
stb_o <= #1 1'b1;
|
we_o <= #1 1'b1;
|
we_o <= #1 1'b1;
|
sel_o <= #1 8'hFF;
|
sel_o <= #1 8'hFF;
|
adr_o <= #1 {pea[63:3],3'b000};
|
adr_o <= pea;
|
dat_o <= #1 m1Data;
|
dat_o <= #1 m1Data;
|
end
|
end
|
|
|
`SH,`SF,`SSH,`SFP:
|
`SH,`SF,`SSH,`SFP:
|
begin
|
begin
|
wrhit <= #1 dhit;
|
wrhit <= #1 dhit;
|
m2Addr <= #1 {pea[63:2],2'b00};
|
m2Addr <= pea;
|
`ifdef ADDRESS_RESERVATION
|
`ifdef ADDRESS_RESERVATION
|
if (resv_address==pea[63:5])
|
if (resv_address==pea[63:5])
|
resv_address <= #1 59'd0;
|
resv_address <= #1 59'd0;
|
`endif
|
`endif
|
cyc_o <= #1 1'b1;
|
cyc_o <= #1 1'b1;
|
stb_o <= #1 1'b1;
|
stb_o <= #1 1'b1;
|
we_o <= #1 1'b1;
|
we_o <= #1 1'b1;
|
sel_o <= #1 pea[2] ? 8'b11110000 : 8'b00001111;
|
sel_o <= #1 pea[2] ? 8'b11110000 : 8'b00001111;
|
adr_o <= #1 {pea[63:2],2'b00};
|
adr_o <= pea;
|
dat_o <= #1 {2{m1Data[31:0]}};
|
dat_o <= #1 {2{m1Data[31:0]}};
|
end
|
end
|
|
|
`SC:
|
`SC:
|
begin
|
begin
|
$display("Storing char to %h, ea=%h",pea,ea);
|
$display("Storing char to %h, ea=%h",pea,ea);
|
wrhit <= #1 dhit;
|
wrhit <= #1 dhit;
|
m2Addr <= #1 {pea[63:2],2'b00};
|
m2Addr <= pea;
|
`ifdef ADDRESS_RESERVATION
|
`ifdef ADDRESS_RESERVATION
|
if (resv_address==pea[63:5])
|
if (resv_address==pea[63:5])
|
resv_address <= #1 59'd0;
|
resv_address <= #1 59'd0;
|
`endif
|
`endif
|
cyc_o <= #1 1'b1;
|
cyc_o <= #1 1'b1;
|
Line 2512... |
Line 2576... |
2'b00: sel_o <= #1 8'b00000011;
|
2'b00: sel_o <= #1 8'b00000011;
|
2'b01: sel_o <= #1 8'b00001100;
|
2'b01: sel_o <= #1 8'b00001100;
|
2'b10: sel_o <= #1 8'b00110000;
|
2'b10: sel_o <= #1 8'b00110000;
|
2'b11: sel_o <= #1 8'b11000000;
|
2'b11: sel_o <= #1 8'b11000000;
|
endcase
|
endcase
|
adr_o <= #1 {pea[63:1],1'b0};
|
adr_o <= pea;
|
dat_o <= #1 {4{m1Data[15:0]}};
|
dat_o <= #1 {4{m1Data[15:0]}};
|
end
|
end
|
|
|
`SB:
|
`SB:
|
begin
|
begin
|
wrhit <= #1 dhit;
|
wrhit <= #1 dhit;
|
m2Addr <= #1 {pea[63:2],2'b00};
|
m2Addr <= pea;
|
`ifdef ADDRESS_RESERVATION
|
`ifdef ADDRESS_RESERVATION
|
if (resv_address==pea[63:5])
|
if (resv_address==pea[63:5])
|
resv_address <= #1 59'd0;
|
resv_address <= #1 59'd0;
|
`endif
|
`endif
|
cyc_o <= #1 1'b1;
|
cyc_o <= #1 1'b1;
|
Line 2537... |
Line 2601... |
3'b100: sel_o <= #1 8'b00010000;
|
3'b100: sel_o <= #1 8'b00010000;
|
3'b101: sel_o <= #1 8'b00100000;
|
3'b101: sel_o <= #1 8'b00100000;
|
3'b110: sel_o <= #1 8'b01000000;
|
3'b110: sel_o <= #1 8'b01000000;
|
3'b111: sel_o <= #1 8'b10000000;
|
3'b111: sel_o <= #1 8'b10000000;
|
endcase
|
endcase
|
adr_o <= #1 {pea[63:2],2'b00};
|
adr_o <= pea;
|
dat_o <= #1 {8{m1Data[7:0]}};
|
dat_o <= #1 {8{m1Data[7:0]}};
|
end
|
end
|
|
|
`ifdef ADDRESS_RESERVATION
|
`ifdef ADDRESS_RESERVATION
|
`SWC:
|
`SWC:
|
begin
|
begin
|
rsf <= #1 1'b0;
|
rsf <= #1 1'b0;
|
if (resv_address==pea[63:5]) begin
|
if (resv_address==pea[63:5]) begin
|
wrhit <= #1 dhit;
|
wrhit <= #1 dhit;
|
m2Addr <= #1 {pea[63:3],3'b00};
|
m2Addr <= pea;
|
cyc_o <= #1 1'b1;
|
cyc_o <= #1 1'b1;
|
stb_o <= #1 1'b1;
|
stb_o <= #1 1'b1;
|
we_o <= #1 1'b1;
|
we_o <= #1 1'b1;
|
sel_o <= #1 8'hFF;
|
sel_o <= #1 8'hFF;
|
adr_o <= #1 {pea[63:3],3'b000};
|
adr_o <= pea;
|
dat_o <= #1 m1Data;
|
dat_o <= #1 m1Data;
|
resv_address <= #1 59'd0;
|
resv_address <= #1 59'd0;
|
rsf <= #1 1'b1;
|
rsf <= #1 1'b1;
|
end
|
end
|
else
|
else
|
Line 2603... |
Line 2667... |
m2Opcode <= #1 `NOPI;
|
m2Opcode <= #1 `NOPI;
|
m2IsLoad <= #1 1'b0;
|
m2IsLoad <= #1 1'b0;
|
m2IsStore <= #1 1'b0;
|
m2IsStore <= #1 1'b0;
|
m2IsCnt <= #1 1'b0;
|
m2IsCnt <= #1 1'b0;
|
m2Func <= #1 7'd0;
|
m2Func <= #1 7'd0;
|
m2Addr <= #1 64'd0;
|
m2Addr <= 64'd0;
|
m2Data <= #1 64'd0;
|
m2Data <= #1 64'd0;
|
m2clkoff <= #1 1'b0;
|
m2clkoff <= #1 1'b0;
|
m2pcv <= #1 1'b0;
|
m2pcv <= #1 1'b0;
|
m2pc <= #1 `RESET_VECTOR;
|
m2pc <= #1 `RESET_VECTOR;
|
m2extype <= #1 `EX_NON;
|
m2extype <= #1 `EX_NON;
|
m2LdPC <= #1 1'b0;
|
|
end
|
end
|
|
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
// MEMORY:
|
// MEMORY:
|
Line 2635... |
Line 2698... |
wOpcode <= #1 m2Opcode;
|
wOpcode <= #1 m2Opcode;
|
wFunc <= #1 m2Func;
|
wFunc <= #1 m2Func;
|
wData <= #1 m2Data;
|
wData <= #1 m2Data;
|
wRt <= #1 m2Rt;
|
wRt <= #1 m2Rt;
|
wclkoff <= #1 m2clkoff;
|
wclkoff <= #1 m2clkoff;
|
wLdPC <= #1 m2LdPC;
|
|
|
|
// There's not an error is a prefetch is taking place (m2Rt=0).
|
// There's not an error is a prefetch is taking place (m2Rt=0).
|
if (((m2IsLoad&&m2Rt[4:0]!=5'd0)|m2IsStore)&err_i) begin
|
if (((m2IsLoad&&m2Rt[4:0]!=5'd0)|m2IsStore)&err_i) begin
|
wextype <= #1 `EX_DBERR;
|
wextype <= #1 `EX_DBERR;
|
errorAddress <= #1 adr_o;
|
errorAddress <= #1 adr_o;
|
end
|
end
|
|
|
if (m2extype==`EX_NON) begin
|
if (m2extype==`EX_NON) begin
|
case(m2Opcode)
|
case(m2Opcode)
|
`MISC:
|
`MISC:
|
if (m2Func==`SYSJMP || m2Func==`SYSCALL)
|
if (m2Func==`SYSCALL)
|
begin
|
begin
|
cyc_o <= #1 1'b0;
|
cyc_o <= #1 1'b0;
|
stb_o <= #1 1'b0;
|
stb_o <= #1 1'b0;
|
sel_o <= #1 8'h00;
|
sel_o <= #1 8'h00;
|
wData <= #1 {dat_i[63:2],2'b00};
|
pc <= #1 {dat_i[63:2],2'b00};
|
|
LoadNOPs <= 1'b0;
|
|
$display("M2 Fetched vector: %h",{dat_i[63:2],2'b00});
|
end
|
end
|
`SH,`SC,`SB,`SW,`SWC,`SM,`SF,`SFD,`SSH,`SSW,`SP,`SFP,`SFDP:
|
`SH,`SC,`SB,`SW,`SWC,`SF,`SFD,`SSH,`SSW,`SP,`SFP,`SFDP:
|
begin
|
begin
|
$display("negating write signals");
|
|
cyc_o <= #1 1'b0;
|
cyc_o <= #1 1'b0;
|
stb_o <= #1 1'b0;
|
stb_o <= #1 1'b0;
|
we_o <= #1 1'b0;
|
we_o <= #1 1'b0;
|
sel_o <= #1 8'h00;
|
sel_o <= #1 8'h00;
|
end
|
end
|
Line 2668... |
Line 2731... |
cyc_o <= #1 1'b0;
|
cyc_o <= #1 1'b0;
|
stb_o <= #1 1'b0;
|
stb_o <= #1 1'b0;
|
sel_o <= #1 8'h00;
|
sel_o <= #1 8'h00;
|
wData <= #1 sel_o[7] ? {{32{dat_i[63]}},dat_i[63:32]}:{{32{dat_i[31]}},dat_i[31: 0]};
|
wData <= #1 sel_o[7] ? {{32{dat_i[63]}},dat_i[63:32]}:{{32{dat_i[31]}},dat_i[31: 0]};
|
end
|
end
|
`LW,`LWR,`LM,`LFD,`LSW,`LP,`LFDP:
|
`LW,`LWR,`LFD,`LSW,`LP,`LFDP:
|
begin
|
begin
|
cyc_o <= #1 1'b0;
|
cyc_o <= #1 1'b0;
|
stb_o <= #1 1'b0;
|
stb_o <= #1 1'b0;
|
sel_o <= #1 8'h00;
|
sel_o <= #1 8'h00;
|
wData <= #1 dat_i;
|
wData <= #1 dat_i;
|
Line 2744... |
Line 2807... |
default: wData <= 64'hDEADDEADDEADDEAD;
|
default: wData <= 64'hDEADDEADDEADDEAD;
|
endcase
|
endcase
|
end
|
end
|
default: ;
|
default: ;
|
endcase
|
endcase
|
|
// Force stack pointer to word alignment
|
|
if (m2Rt[4:0]==5'b11110)
|
|
wData[2:0] <= 3'b000;
|
end
|
end
|
end
|
end
|
// Stage tail
|
// Stage tail
|
// Pipeline annul for when a bubble in the pipeline occurs.
|
// Pipeline annul for when a bubble in the pipeline occurs.
|
else if (advanceW) begin
|
else if (advanceW) begin
|
Line 2755... |
Line 2821... |
wRt <= 9'd0;
|
wRt <= 9'd0;
|
wData <= 64'd0;
|
wData <= 64'd0;
|
wIR <= `NOP_INSN;
|
wIR <= `NOP_INSN;
|
wOpcode <= `NOPI;
|
wOpcode <= `NOPI;
|
wIsStore <= 1'b0;
|
wIsStore <= 1'b0;
|
wLdPC <= 1'b0;
|
|
wclkoff <= 1'b0;
|
wclkoff <= 1'b0;
|
wpcv <= 1'b0;
|
wpcv <= 1'b0;
|
wpc <= `RESET_VECTOR;
|
wpc <= `RESET_VECTOR;
|
end
|
end
|
|
|
Line 2832... |
Line 2897... |
pc <= `RESET_VECTOR;
|
pc <= `RESET_VECTOR;
|
end
|
end
|
// Hardware exceptions
|
// Hardware exceptions
|
`EX_NMI,`EX_IRQ:
|
`EX_NMI,`EX_IRQ:
|
begin
|
begin
|
$display("Stuffing SYSJMP");
|
$display("Stuffing SYSCALL %d",wextype);
|
xIR <= {`MISC,19'd0,wextype,`SYSJMP};
|
dIR <= {`MISC,5'd25,4'd0,wextype,`SYSCALL};
|
pc <= 64'hC;
|
|
// One of the following three pc's MUST be valid.
|
// One of the following three pc's MUST be valid.
|
// wpc will be valid if the interrupt occurred outside of a branch
|
// wpc will be valid if the interrupt occurred outside of a branch
|
// shadow. m1pc or m2pc (the branch target address) will be valid
|
// shadow. m1pc or m2pc (the branch target address) will be valid
|
// depending on where in the branch shadow the interrupt falls.
|
// depending on where in the branch shadow the interrupt falls.
|
case(1'b1)
|
case(1'b1)
|
wpcv: IPC <= wpc;
|
wpcv: dpc <= wpc;
|
m2pcv: IPC <= m2pc;
|
m2pcv: dpc <= m2pc;
|
default: IPC <= m1pc;
|
default: dpc <= m1pc;
|
// xpcv: IPC <= xpc;
|
|
// dpcv: IPC <= dpc;
|
|
// default: IPC <= pc;
|
|
endcase
|
endcase
|
end
|
end
|
// Software exceptions
|
// Software exceptions
|
// We probably want to return to the excepting instruction.
|
// We probably want to return to the excepting instruction.
|
`EX_TLBD,`EX_DBERR:
|
`EX_TLBD,`EX_DBERR:
|
begin
|
begin
|
pccap <= 1'b0;
|
pccap <= 1'b0;
|
xIR <= {`MISC,19'd0,wextype,`SYSJMP};
|
dIR <= {`MISC,5'd24,4'd0,wextype,`SYSCALL};
|
pc <= 64'hC;
|
dpc <= wpc;
|
EPC <= wpc;
|
|
end
|
end
|
default:
|
default:
|
begin
|
begin
|
xIR <= {`MISC,19'd0,wextype,`SYSJMP};
|
dIR <= {`MISC,5'd24,4'd0,wextype,`SYSCALL};
|
pc <= 64'hC;
|
dpc <= wpc;
|
EPC <= fnIncPC(wpc);
|
|
end
|
end
|
endcase
|
endcase
|
if (wLdPC) begin
|
|
$display("Loading PC");
|
|
pc <= wData;
|
|
end
|
|
end
|
end
|
// Stage tail
|
// Stage tail
|
// Pipeline annul for when a bubble in the pipeline occurs.
|
// Pipeline annul for when a bubble in the pipeline occurs.
|
// T and W advance together, meaning an else would never be executed.
|
// T and W advance together, meaning an else would never be executed.
|
|
|
Line 2884... |
Line 2939... |
|
|
|
|
//=============================================================================
|
//=============================================================================
|
// Cache loader
|
// Cache loader
|
//=============================================================================
|
//=============================================================================
|
if (rst_i) begin
|
|
cstate <= IDLE;
|
|
end
|
|
else begin
|
|
case(cstate)
|
case(cstate)
|
IDLE:
|
IDLE:
|
if (triggerDCacheLoad) begin
|
if (triggerDCacheLoad) begin
|
dcaccess <= 1'b1;
|
dcaccess <= 1'b1;
|
bte_o <= 2'b00; // linear burst
|
bte_o <= 2'b00; // linear burst
|
Line 2934... |
Line 2985... |
tvalid[adr_o[12:6]] <= 1'b1;
|
tvalid[adr_o[12:6]] <= 1'b1;
|
icaccess <= 1'b0;
|
icaccess <= 1'b0;
|
cstate <= IDLE;
|
cstate <= IDLE;
|
end
|
end
|
end
|
end
|
//SYSCALL 509: 00_00000000_00000000_00000000_11111110_10010111
|
//SYSCALL 509: 00000000_00000000_11111110_10010111
|
ICACT2:
|
ICACT2:
|
if (ack_i|err_i) begin
|
if (ack_i|err_i) begin
|
adr_o <= adr_o + 64'd8;
|
adr_o <= adr_o + 64'd8;
|
if (adr_o[3]==1'b0) begin
|
if (adr_o[3]==1'b0) begin
|
cti_o <= 3'b111; // Last cycle ahead
|
cti_o <= 3'b111; // Last cycle ahead
|
tmpbuf <= err_i ? bevect[63:0] : dat_i;
|
tmpbuf <= err_i ? bevect : dat_i;
|
end
|
end
|
else begin
|
else begin
|
if (tick[0]) begin
|
if (tick[0]) begin
|
insnbuf0 <= {err_i ? bevect[127:64] : dat_i,tmpbuf};
|
insnbuf0 <= {err_i ? bevect : dat_i,tmpbuf};
|
ibuftag0 <= adr_o[63:4];
|
ibuftag0 <= adr_o[63:4];
|
end
|
end
|
else begin
|
else begin
|
insnbuf1 <= {err_i ? bevect[127:64] : dat_i,tmpbuf};
|
insnbuf1 <= {err_i ? bevect : dat_i,tmpbuf};
|
ibuftag1 <= adr_o[63:4];
|
ibuftag1 <= adr_o[63:4];
|
end
|
end
|
cti_o <= 3'b000; // back to non-burst mode
|
cti_o <= 3'b000; // back to non-burst mode
|
cyc_o <= 1'b0;
|
cyc_o <= 1'b0;
|
stb_o <= 1'b0;
|
stb_o <= 1'b0;
|
Line 2973... |
Line 3024... |
dcaccess <= 1'b0;
|
dcaccess <= 1'b0;
|
cstate <= IDLE;
|
cstate <= IDLE;
|
end
|
end
|
end
|
end
|
|
|
|
endcase // cstate
|
|
end // RUN
|
endcase
|
endcase
|
end
|
end
|
|
|
end
|
|
|
|
endmodule
|
endmodule
|
|
|
No newline at end of file
|
No newline at end of file
|