Line 24... |
Line 24... |
//
|
//
|
// 15848 LUT's / 3591 ff's / 48.215 MHz
|
// 15848 LUT's / 3591 ff's / 48.215 MHz
|
// 29 Block RAMs
|
// 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
|
//`define TLB 1
|
//`define TLB 1
|
|
|
`define RESET_VECTOR 64'hFFFF_FFFF_FFFF_FFF0
|
`define RESET_VECTOR 64'hFFFF_FFFF_FFFF_FFF0
|
Line 108... |
Line 108... |
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 [31:0] dIR,xIR,m1IR,m2IR,wIR;
|
reg [31:0] dIR,xIR,m1IR,m2IR,wIR;
|
reg [31:0] ndIR; // next dIR
|
reg [31:0] ndIR; // next dIR
|
reg [63:0] pc;
|
reg [63:0] pc; // ipc
|
wire [63:0] pchistoric;
|
wire [63:0] pchistoric;
|
reg pccap;
|
reg pccap;
|
reg [63:0] ErrorEPC;
|
reg [63:0] ErrorEPC;
|
reg [63:0] EPC [0:15];
|
reg [63:0] EPC [0:15];
|
reg [63:0] IPC [0:15];
|
reg [63:0] IPC [0:15];
|
|
reg [63:0] PCS [0:15];
|
|
reg [15:0] StatusEXL;
|
reg [63:0] dpc,xpc,m1pc,m2pc,wpc;
|
reg [63:0] dpc,xpc,m1pc,m2pc,wpc;
|
reg dpcv,xpcv,m1pcv,m2pcv,wpcv; // PC valid indicators
|
reg ipcv,dpcv,xpcv,m1pcv,m2pcv,wpcv; // PC valid indicators
|
wire [63:0] rfoa,rfob,rfoc;
|
wire [63:0] rfoa,rfob,rfoc;
|
wire [8:0] dRa,dRb,dRc;
|
wire [8:0] dRa,dRb,dRc;
|
reg [8:0] wRt,m1Rt,m2Rt,tRt;
|
reg [8:0] wRt,m1Rt,m2Rt,tRt;
|
wire [8:0] xRt;
|
wire [8:0] xRt;
|
reg xRtZero;
|
reg xRtZero;
|
Line 130... |
Line 132... |
reg [63:0] TBA; // Trap Base Address
|
reg [63:0] TBA; // Trap Base Address
|
reg [8:0] dextype,xextype,m1extype,m2extype,wextype,textype;
|
reg [8:0] dextype,xextype,m1extype,m2extype,wextype,textype;
|
reg [3:0] epat [0:255];
|
reg [3:0] epat [0:255];
|
reg [7:0] eptr;
|
reg [7:0] eptr;
|
reg [3:0] dAXC,xAXC,m1AXC,m2AXC,wAXC;
|
reg [3:0] dAXC,xAXC,m1AXC,m2AXC,wAXC;
|
wire [3:0] AXC = epat[eptr];
|
wire [3:0] AXC = (eptr==8'h00) ? 4'h0 : 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)
|
Line 157... |
Line 159... |
reg [63:0] wr_addr;
|
reg [63:0] wr_addr;
|
reg [31: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
|
reg StatusUM; // 1= user mode
|
reg StatusUM; // 1= user mode
|
reg [7:0] ASID; // address space identifier (process ID)
|
reg [7:0] ASID; // address space identifier (process ID)
|
integer n;
|
integer n;
|
reg [63:13] BadVAddr;
|
reg [63:13] BadVAddr;
|
Line 178... |
Line 180... |
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];
|
wire [5:0] m1Func6 = m1Func[5:0];
|
|
wire [5:0] m2Func6 = m2Func[5:0];
|
|
wire [5:0] wFunc6 = wIR[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 [1:0] scale;
|
Line 190... |
Line 194... |
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;
|
wire advanceX_edge;
|
wire advanceX_edge;
|
wire takb;
|
wire takb;
|
wire advanceX,advanceM1,advanceW;
|
wire advanceI,advanceR,advanceX,advanceM1,advanceW,advanceT;
|
reg m1IsLoad,m2IsLoad;
|
|
//reg m1IsIO;
|
|
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;
|
reg LoadNOPs;
|
|
reg dIRvalid,xIRvalid,m1IRvalid,m2IRvalid,wIRvalid,tIRvalid;
|
|
|
function [63:0] fnIncPC;
|
function [63:0] fnIncPC;
|
input [63:0] fpc;
|
input [63:0] fpc;
|
begin
|
begin
|
fnIncPC = fpc + 64'd4;
|
fnIncPC = fpc + 64'd4;
|
end
|
end
|
endfunction
|
endfunction
|
|
|
assign KernelMode = StatusEXL|StatusHWI;
|
assign KernelMode = StatusEXL[xAXC]|StatusHWI;
|
|
|
wire iIsLSPair = iOpcode==`SP || iOpcode==`LP || iOpcode==`SFP || iOpcode==`LFP || iOpcode==`SFDP || iOpcode==`LFDP;
|
wire iIsLSPair = iOpcode==`SP || iOpcode==`LP || iOpcode==`SFP || iOpcode==`LFP || iOpcode==`SFDP || iOpcode==`LFDP;
|
wire dIsLSPair = dOpcode==`SP || dOpcode==`LP || dOpcode==`SFP || dOpcode==`LFP || dOpcode==`SFDP || dOpcode==`LFDP;
|
wire dIsLSPair = dOpcode==`SP || dOpcode==`LP || dOpcode==`SFP || dOpcode==`LFP || dOpcode==`SFDP || dOpcode==`LFDP;
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
Line 221... |
Line 223... |
wire [63:0] ppc;
|
wire [63:0] ppc;
|
wire [63:0] pea;
|
wire [63:0] pea;
|
wire [63:0] tlbo;
|
wire [63:0] tlbo;
|
`ifdef TLB
|
`ifdef TLB
|
wire [63:0] TLBVirtPage;
|
wire [63:0] TLBVirtPage;
|
wire wTlbp = advanceW && wOpcode==`MISC && wFunc==`TLBP;
|
wire wTlbp = wIRvalid && advanceW && wOpcode==`MISC && wFunc==`TLBP;
|
wire wTlbrd = advanceW && wOpcode==`MISC && wFunc==`TLBR;
|
wire wTlbrd = wIRvalid && advanceW && wOpcode==`MISC && wFunc==`TLBR;
|
wire wTlbwr = advanceW && wOpcode==`MISC && wFunc==`TLBWR;
|
wire wTlbwr = wIRvalid && advanceW && wOpcode==`MISC && wFunc==`TLBWR;
|
wire wTlbwi = advanceW && wOpcode==`MISC && wFunc==`TLBWI;
|
wire wTlbwi = wIRvalid && advanceW && wOpcode==`MISC && wFunc==`TLBWI;
|
wire wMtspr = advanceW && wOpcode==`R && wFunc==`MTSPR;
|
wire wMtspr = wIRvalid && advanceW && wOpcode==`R && wFunc==`MTSPR;
|
wire xTlbrd = advanceX && xOpcode==`MISC && xFunc==`TLBR;
|
wire xTlbrd = xIRvalid && advanceX && xOpcode==`MISC && xFunc==`TLBR;
|
wire xTlbwr = advanceX && xOpcode==`MISC && xFunc==`TLBWR;
|
wire xTlbwr = xIRvalid && advanceX && xOpcode==`MISC && xFunc==`TLBWR;
|
wire xTlbwi = advanceX && xOpcode==`MISC && xFunc==`TLBWI;
|
wire xTlbwi = xIRvalid && advanceX && xOpcode==`MISC && xFunc==`TLBWI;
|
wire ITLBMiss,DTLBMiss;
|
wire ITLBMiss,DTLBMiss;
|
|
|
Raptor64_TLB u22
|
Raptor64_TLB u22
|
(
|
(
|
.rst(rst_i),
|
.rst(rst_i),
|
Line 319... |
Line 321... |
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
//reg lfdir;
|
//reg lfdir;
|
reg icaccess;
|
reg icaccess;
|
reg ICacheOn;
|
reg ICacheOn;
|
wire ibufrdy;
|
wire ibufrdy;
|
reg [63:0] tmpbuf;
|
wire [31:0] insnbundle;
|
wire [127:0] insnbundle;
|
reg [31:0] insnbuf;
|
reg [127:0] insnbuf0,insnbuf1;
|
reg [63:0] ibufadr;
|
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 [31:0] insn1;
|
reg [31:0] insn1;
|
reg [31:0] insnkey;
|
reg [31:0] insnkey;
|
|
reg [63:0] icadr;
|
|
|
// SYSCALL 509
|
// SYSCALL 509
|
wire syscall509 = 32'b0000000_11000_0000_11111110_10010111;
|
wire syscall509 = 32'b0000000_11000_0000_11111110_10010111;
|
wire [63:0] bevect = {syscall509,syscall509};
|
wire [63:0] bevect = {syscall509,syscall509};
|
|
|
// Xilinx Core Generator Component
|
// Xilinx Core Generator Component
|
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(icadr[12:3]), // input [9 : 0] addra
|
.dina(err_i ? bevect : 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:2]), // 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)
|
always @(insnbundle or ICacheAct or insnbuf)
|
begin
|
begin
|
casex({ICacheAct,ibuftag1==ppc[63:4],pc[3:2]})
|
case(ICacheAct)
|
4'b0000: insn1 <= insnbuf0[ 31: 0];
|
1'b0: insn1 <= insnbuf;
|
4'b0001: insn1 <= insnbuf0[ 63:32];
|
1'b1: insn1 <= insnbundle;
|
4'b0010: insn1 <= insnbuf0[ 95:64];
|
|
4'b0011: insn1 <= insnbuf0[127:96];
|
|
4'b0100: insn1 <= insnbuf1[ 31: 0];
|
|
4'b0101: insn1 <= insnbuf1[ 63:32];
|
|
4'b0110: insn1 <= insnbuf1[ 95:64];
|
|
4'b0111: insn1 <= insnbuf1[127:96];
|
|
4'b1x00: insn1 <= insnbundle[ 31: 0];
|
|
4'b1x01: insn1 <= insnbundle[ 63:32];
|
|
4'b1x10: insn1 <= insnbundle[ 95:64];
|
|
4'b1x11: insn1 <= insnbundle[127:96];
|
|
endcase
|
endcase
|
end
|
end
|
|
|
// Decrypt the instruction set.
|
// Decrypt the instruction set.
|
always @(insn1,insnkey)
|
always @(insn1,insnkey)
|
Line 380... |
Line 372... |
end
|
end
|
|
|
wire [64:13] tgout;
|
wire [64:13] tgout;
|
assign tgout = {tvalid[pc[12:6]],tmem[pc[12:6]]};
|
assign tgout = {tvalid[pc[12:6]],tmem[pc[12:6]]};
|
assign ihit = (tgout=={1'b1,ppc[63:13]});
|
assign ihit = (tgout=={1'b1,ppc[63:13]});
|
assign ibufrdy = ibuftag0==ppc[63:4] || ibuftag1==ppc[63:4];
|
assign ibufrdy = ibufadr[63:2]==ppc[63:2];
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
// Data Cache
|
// Data Cache
|
// No-allocate on write
|
// No-allocate on write
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
reg dcaccess;
|
reg dcaccess;
|
wire dhit;
|
wire dhit;
|
wire [64:15] dtgout;
|
wire [64:15] dtgout;
|
reg wrhit;
|
reg wrhit;
|
reg wr_dcache;
|
reg wr_dcache;
|
|
reg [14:0] dcadr;
|
|
|
// cache RAM 32Kb
|
// cache RAM 32Kb
|
// Xilinx Core Generator Component
|
// Xilinx Core Generator Component
|
Raptor64_dcache_ram u10
|
Raptor64_dcache_ram u10
|
(
|
(
|
.clka(clk), // input clka
|
.clka(clk), // input clka
|
.ena(1'b1),
|
.ena(1'b1),
|
.wea(dcaccess ? {8{ack_i}} : wrhit ? sel_o : 8'h00), // input [7 : 0] wea
|
.wea(dcaccess ? {8{ack_i}} : wrhit ? sel_o : 8'h00), // input [7 : 0] wea
|
.addra(adr_o[14:3]), // input [11 : 0] addra
|
.addra(dcaccess ? dcadr[14:3] : adr_o[14:3]), // input [11 : 0] addra
|
.dina(dcaccess ? dat_i : dat_o), // input [63 : 0] dina
|
.dina(dcaccess ? dat_i : dat_o), // input [63 : 0] dina
|
|
|
.clkb(~clk), // input clkb
|
.clkb(~clk), // input clkb
|
.addrb(pea[14:3]), // input [11 : 0] addrb
|
.addrb(pea[14:3]), // input [11 : 0] addrb
|
.doutb(cdat) // output [63 : 0] doutb
|
.doutb(cdat) // output [63 : 0] doutb
|
Line 413... |
Line 406... |
// Xilinx Core Generator Component
|
// Xilinx Core Generator Component
|
// tag RAM 512 b
|
// tag RAM 512 b
|
Raptor64_dcache_tagram u11
|
Raptor64_dcache_tagram u11
|
(
|
(
|
.clka(clk), // input clka
|
.clka(clk), // input clka
|
.ena(dtinit | (adr_o[5:3]==3'b111)), // input ena
|
.ena(dtinit | (dcadr[5:3]==3'b111)), // input ena
|
.wea(dtinit | (dcaccess & ack_i)), // input [0 : 0] wea
|
.wea(dtinit | (dcaccess & ack_i)), // input [0 : 0] wea
|
.addra(adr_o[14:6]), // input [8 : 0] addra
|
.addra(dcadr[14:6]), // input [8 : 0] addra
|
.dina({~dtinit,adr_o[63:15]}), // input [49 : 0] dina
|
.dina({~dtinit,adr_o[63:15]}), // input [49 : 0] dina
|
|
|
.clkb(~clk), // input clkb
|
.clkb(~clk), // input clkb
|
.addrb(pea[14:6]), // input [8 : 0] addrb
|
.addrb(pea[14:6]), // input [8 : 0] addrb
|
.doutb(dtgout) // output [49 : 0] doutb
|
.doutb(dtgout) // output [49 : 0] doutb
|
Line 438... |
Line 431... |
wire [127:0] mult_out;
|
wire [127:0] mult_out;
|
wire [63:0] sqrt_out;
|
wire [63:0] sqrt_out;
|
wire [63:0] div_q;
|
wire [63:0] div_q;
|
wire [63:0] div_r;
|
wire [63:0] div_r;
|
wire sqrt_done,mult_done,div_done;
|
wire sqrt_done,mult_done,div_done;
|
wire isSqrt = xOpcode==`R && xFunc==`SQRT;
|
wire isSqrt = xIRvalid && xOpcode==`R && xFunc==`SQRT;
|
|
|
isqrt #(64) u14
|
isqrt #(64) u14
|
(
|
(
|
.rst(rst_i),
|
.rst(rst_i),
|
.clk(clk),
|
.clk(clk),
|
Line 451... |
Line 444... |
.a(a),
|
.a(a),
|
.o(sqrt_out),
|
.o(sqrt_out),
|
.done(sqrt_done)
|
.done(sqrt_done)
|
);
|
);
|
|
|
wire isMulu = xOpcode==`RR && xFunc==`MULU;
|
wire isMulu = xIRvalid && xOpcode==`RR && xFunc==`MULU;
|
wire isMuls = (xOpcode==`RR && xFunc==`MULS) || xOpcode==`MULSI;
|
wire isMuls = xIRvalid && ((xOpcode==`RR && xFunc==`MULS) || xOpcode==`MULSI);
|
wire isMuli = xOpcode==`MULSI || xOpcode==`MULUI;
|
wire isMuli = xIRvalid && (xOpcode==`MULSI || xOpcode==`MULUI);
|
wire isMult = xOpcode==`MULSI || xOpcode==`MULUI || (xOpcode==`RR && (xFunc==`MULS || xFunc==`MULU));
|
wire isMult = xIRvalid && (xOpcode==`MULSI || xOpcode==`MULUI || (xOpcode==`RR && (xFunc==`MULS || xFunc==`MULU)));
|
wire isDivu = xOpcode==`RR && xFunc==`DIVU;
|
wire isDivu = xIRvalid && (xOpcode==`RR && xFunc==`DIVU);
|
wire isDivs = (xOpcode==`RR && xFunc==`DIVS) || xOpcode==`DIVSI;
|
wire isDivs = xIRvalid && ((xOpcode==`RR && xFunc==`DIVS) || xOpcode==`DIVSI);
|
wire isDivi = xOpcode==`DIVSI || xOpcode==`DIVUI;
|
wire isDivi = xIRvalid && (xOpcode==`DIVSI || xOpcode==`DIVUI);
|
wire isDiv = xOpcode==`DIVSI || xOpcode==`DIVUI || (xOpcode==`RR && (xFunc==`DIVS || xFunc==`DIVU));
|
wire isDiv = xIRvalid && (xOpcode==`DIVSI || xOpcode==`DIVUI || (xOpcode==`RR && (xFunc==`DIVS || xFunc==`DIVU)));
|
wire isModu = (xOpcode==`RR && xFunc==`MODU);
|
wire isModu = xIRvalid && (xOpcode==`RR && xFunc==`MODU);
|
wire isMods = (xOpcode==`RR && xFunc==`MODS);
|
wire isMods = xIRvalid && (xOpcode==`RR && xFunc==`MODS);
|
wire isMod = isModu|isMods;
|
wire isMod = isModu|isMods;
|
|
|
Raptor64Mult u18
|
Raptor64Mult u18
|
(
|
(
|
.rst(rst_i),
|
.rst(rst_i),
|
Line 612... |
Line 605... |
else begin
|
else begin
|
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 && xIRvalid) begin
|
if (xFunc6==`FDADD) // FDADD
|
if (xFunc6==`FDADD) // FDADD
|
fltctr <= 6'd12;
|
fltctr <= 6'd12;
|
else if (xFunc6==`FDSUB) // FDSUB
|
else if (xFunc6==`FDSUB) // FDSUB
|
fltctr <= 6'd12;
|
fltctr <= 6'd12;
|
else if (xFunc6==`FDMUL) // FDMUL
|
else if (xFunc6==`FDMUL) // FDMUL
|
Line 744... |
Line 737... |
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
// 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
|
reg [5:0] ras_sp; // stack pointer
|
reg [5:0] ras_sp; // stack pointer
|
|
initial begin
|
|
for (n = 0; n < 64; n = n + 1)
|
|
ras[n] = 0;
|
|
end
|
`ifdef BTB
|
`ifdef BTB
|
reg [63:0] btb [63:0]; // branch target buffer
|
reg [63:0] btb [63:0]; // branch target buffer
|
`endif
|
`endif
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
Line 760... |
Line 757... |
Raptor64_BranchHistory u6
|
Raptor64_BranchHistory u6
|
(
|
(
|
.rst(rst_i),
|
.rst(rst_i),
|
.clk(clk),
|
.clk(clk),
|
.advanceX(advanceX),
|
.advanceX(advanceX),
|
|
.xIRvalid(xIRvalid),
|
.xIR(xIR),
|
.xIR(xIR),
|
.pc(pc),
|
.pc(pc),
|
.xpc(xpc),
|
.xpc(xpc),
|
.takb(takb),
|
.takb(takb),
|
.predict_taken(predict_taken)
|
.predict_taken(predict_taken)
|
Line 826... |
Line 824... |
`endif
|
`endif
|
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)
|
|
`MISC:
|
|
case(xFunc)
|
|
`SYSCALL:
|
|
if (xIR[16])
|
|
xData1 = fnIncPC(xpc);
|
|
else
|
|
xData1 = xpc;
|
|
default: xData1 = 64'd0;
|
|
endcase
|
`R:
|
`R:
|
casex(xFunc6)
|
casex(xFunc6)
|
`COM: xData1 = ~a;
|
`COM: xData1 = ~a;
|
`NOT: xData1 = ~|a;
|
`NOT: xData1 = ~|a;
|
`NEG: xData1 = -a;
|
`NEG: xData1 = -a;
|
Line 893... |
Line 900... |
`FPCR: xData1 = FPC;
|
`FPCR: xData1 = FPC;
|
`RAND: xData1 = rando;
|
`RAND: xData1 = rando;
|
`SRAND1: xData1 = m_z;
|
`SRAND1: xData1 = m_z;
|
`SRAND2: xData1 = m_w;
|
`SRAND2: xData1 = m_w;
|
`INSNKEY: xData1 = insnkey;
|
`INSNKEY: xData1 = insnkey;
|
// `PCHISTORIC: xData1 = pchistoric;
|
`PCHISTORIC: xData1 = pchistoric;
|
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
|
Line 946... |
Line 953... |
`MULUI: xData1 = mult_out[63:0];
|
`MULUI: xData1 = mult_out[63:0];
|
`DIVSI: xData1 = div_q;
|
`DIVSI: xData1 = div_q;
|
`DIVUI: xData1 = div_q;
|
`DIVUI: xData1 = div_q;
|
`INB,`INCH,`INH,`INW,`INCU,`INHU,`INBU:
|
`INB,`INCH,`INH,`INW,`INCU,`INHU,`INBU:
|
xData1 = a + imm;
|
xData1 = a + imm;
|
`OUTB,`OUTC,`OUTH,`OUTW:
|
`OUTB,`OUTC,`OUTH,`OUTW,`OUTBC:
|
xData1 = a + imm;
|
xData1 = a + imm;
|
`LW,`LH,`LC,`LB,`LHU,`LCU,`LBU,`LWR,`LF,`LFD,`LP,`LFP,`LFDP,`LEA:
|
`LW,`LH,`LC,`LB,`LHU,`LCU,`LBU,`LEA:
|
xData1 = a + imm;
|
xData1 = a + imm;
|
`SW,`SH,`SC,`SB,`SWC,`SF,`SFD,`SP,`SFP,`SFDP,`STBC:
|
`SW,`SH,`SC,`SB:
|
xData1 = a + imm;
|
xData1 = a + imm;
|
|
`ifdef ADDRESS_RESERVATION
|
|
`LWR: xData1 = a + imm;
|
|
`SWC: xData1 = a + imm;
|
|
`endif
|
|
`ifdef FLOATING_POINT
|
|
`LF,`LFD: xData1 = a + imm;
|
|
`SF,`SFD: xData1 = a + imm;
|
|
`LFP,`LFDP: xData1 = a + imm + xIR[15];
|
|
`SFP,`SFDP: xData1 = a + imm + xIR[15];
|
|
`endif
|
|
//`LP: xData1 = a + imm + xIR[15];
|
|
//`SP: xData1 = a + imm + xIR[15];
|
`MEMNDX:
|
`MEMNDX:
|
|
case(xFunc6)
|
|
// `LPX,`LFPX,`LFDPX,`SPX,`SFPX,`SFDPX:
|
|
// xData1 = a + (b << scale) + imm + xIR[15];
|
|
default:
|
xData1 = a + (b << scale) + imm;
|
xData1 = a + (b << scale) + imm;
|
|
endcase
|
`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 = fnIncPC(xpc);//???xpc + {xIR[19:15],2'b00};
|
`JAL: xData1 = fnIncPC(xpc);//???xpc + {xIR[19:15],2'b00};
|
`RET: xData1 = a + imm;
|
`RET: xData1 = a + imm;
|
Line 990... |
Line 1014... |
|
|
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 && (xFunc6==`DIVS || xFunc6==`DIVU) && b==64'd0);
|
wire dbz_error = xIRvalid && (((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 && (xFunc6==`SUB || xFunc6==`ADD)) && v_rr);
|
wire ovr_error = xIRvalid && (((xOpcode==`ADDI || xOpcode==`SUBI) && v_ri) || ((xOpcode==`RR && (xFunc6==`SUB || xFunc6==`ADD)) && v_rr));
|
// ToDo: add more priv violations
|
// ToDo: add more priv violations
|
wire priv_violation = !KernelMode && (xOpcode==`MISC &&
|
wire priv_violation = xIRvalid && !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==`IEPP
|
xFunc==`TLBP || xFunc==`TLBR || xFunc==`TLBWR || xFunc==`TLBWI || xFunc==`IEPP
|
));
|
));
|
// ToDo: detect illegal instructions in the hives (sub-opcodes)
|
// ToDo: detect illegal instructions in the hives (sub-opcodes)
|
wire illegal_insn = (
|
wire illegal_insn = xIRvalid && (
|
xOpcode==7'd19 ||
|
xOpcode==7'd19 ||
|
xOpcode==7'd20 ||
|
xOpcode==7'd20 ||
|
xOpcode==7'd28 ||
|
xOpcode==7'd28 ||
|
xOpcode==7'd29 ||
|
xOpcode==7'd29 ||
|
xOpcode==7'd30 ||
|
xOpcode==7'd30 ||
|
xOpcode==7'd31 ||
|
xOpcode==7'd31 ||
|
xOpcode==7'd47 ||
|
xOpcode==7'd47 ||
|
xOpcode==7'd54 ||
|
|
xOpcode==7'd55 ||
|
xOpcode==7'd55 ||
|
xOpcode==7'd63 ||
|
xOpcode==7'd63 ||
|
xOpcode==7'd71 ||
|
|
xOpcode==7'd90 ||
|
xOpcode==7'd90 ||
|
xOpcode==7'd91 ||
|
xOpcode==7'd91 ||
|
xOpcode==7'd92 ||
|
xOpcode==7'd92 ||
|
xOpcode==7'd93 ||
|
xOpcode==7'd93 ||
|
xOpcode==7'd106 ||
|
xOpcode==7'd106 ||
|
Line 1029... |
Line 1051... |
// For performance and core size reasons, the following should really decode
|
// For performance and core size reasons, the following should really decode
|
// the opcodes in the decode stage, then pass the decoding information forward
|
// the opcodes in the decode stage, then pass the decoding information forward
|
// using regs. However the core is trickier to get working that way; decoding
|
// using regs. However the core is trickier to get working that way; decoding
|
// in multiple stages is simpler.
|
// in multiple stages is simpler.
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
//wire dIsLoad =
|
//wire dIsLoad = dIRvalid && (
|
// dOpcode==`LW || dOpcode==`LH || dOpcode==`LB || dOpcode==`LWR ||
|
// dOpcode==`LW || dOpcode==`LH || dOpcode==`LB || dOpcode==`LWR ||
|
// dOpcode==`LHU || dOpcode==`LBU ||
|
// dOpcode==`LHU || dOpcode==`LBU ||
|
// dOpcode==`LC || dOpcode==`LCU || dOpcode==`LM ||
|
// dOpcode==`LC || dOpcode==`LCU || dOpcode==`LM ||
|
// dOpcode==`LF || dOpcode==`LFD || dOpcode==`LP || dOpcode==`LFP || dOpcode==`LFDP ||
|
// dOpcode==`LF || dOpcode==`LFD || dOpcode==`LP || dOpcode==`LFP || dOpcode==`LFDP ||
|
// dOpcode==`LSH || dOpcode==`LSW ||
|
// dOpcode==`LSH || dOpcode==`LSW ||
|
Line 1042... |
Line 1064... |
// dFunc6==`LHUX || dFunc6==`LBUX ||
|
// dFunc6==`LHUX || dFunc6==`LBUX ||
|
// dFunc6==`LCX || dFunc6==`LCUX ||
|
// dFunc6==`LCX || dFunc6==`LCUX ||
|
// dFunc6==`LFX || dFunc6==`LFDX || dFunc6==`LPX ||
|
// dFunc6==`LFX || dFunc6==`LFDX || dFunc6==`LPX ||
|
// dFunc6==`LSHX || dFunc6==`LSWX
|
// dFunc6==`LSHX || dFunc6==`LSWX
|
// )) ||
|
// )) ||
|
// (dOpcode==`MISC && (dFunc==`SYSJMP || dFunc==`SYSCALL || dFunc==`SYSINT))
|
// (dOpcode==`MISC && (dFunc==`SYSJMP || dFunc==`SYSCALL || dFunc==`SYSINT)))
|
// ;
|
// ;
|
//wire dIsStore =
|
//wire dIsStore = dIRvalid && (
|
// dOpcode==`SW || dOpcode==`SH || dOpcode==`SB || dOpcode==`SC || dOpcode==`SWC || dOpcode==`SM ||
|
// dOpcode==`SW || dOpcode==`SH || dOpcode==`SB || dOpcode==`SC || dOpcode==`SWC || dOpcode==`SM ||
|
// dOpcode==`SF || dOpcode==`SFD || dOpcode==`SP || dOpcode==`SFP || dOpcode==`SFDP ||
|
// dOpcode==`SF || dOpcode==`SFD || dOpcode==`SP || dOpcode==`SFP || dOpcode==`SFDP ||
|
// dOpcode==`SSH || dOpcode==`SSW ||
|
// dOpcode==`SSH || dOpcode==`SSW ||
|
// (dOpcode==`MEMNDX && (
|
// (dOpcode==`MEMNDX && (
|
// dFunc6==`SWX || dFunc6==`SHX || dFunc6==`SBX || dFunc6==`SCX || dFunc6==`SWCX ||
|
// dFunc6==`SWX || dFunc6==`SHX || dFunc6==`SBX || dFunc6==`SCX || dFunc6==`SWCX ||
|
// dFunc6==`SFX || dFunc6==`SFDX || dFunc6==`SPX ||
|
// dFunc6==`SFX || dFunc6==`SFDX || dFunc6==`SPX ||
|
// dFunc6==`SSHX || dFunc6==`SSWX
|
// dFunc6==`SSHX || dFunc6==`SSWX
|
// ))
|
// )))
|
// ;
|
// ;
|
//wire dIsIn =
|
//wire dIsIn = dIRvalid && (
|
// dOpcode==`INW || dOpcode==`INH || dOpcode==`INCH || dOpcode==`INB ||
|
// dOpcode==`INW || dOpcode==`INH || dOpcode==`INCH || dOpcode==`INB ||
|
// dOpcode==`INHU || dOpcode==`INCU || dOpcode==`INBU ||
|
// dOpcode==`INHU || dOpcode==`INCU || dOpcode==`INBU ||
|
// (dOpcode==`MEMNDX && (
|
// (dOpcode==`MEMNDX && (
|
// dFunc6==`INWX || dFunc6==`INHX || dFunc6==`INCX || dFunc6==`INBX ||
|
// dFunc6==`INWX || dFunc6==`INHX || dFunc6==`INCX || dFunc6==`INBX ||
|
// dFunc6==`INHUX || dFunc6==`INCUX || dFunc6==`INBUX
|
// dFunc6==`INHUX || dFunc6==`INCUX || dFunc6==`INBUX
|
// ))
|
// )))
|
// ;
|
// ;
|
//wire dIsOut = dOpcode==`OUTW || dOpcode==`OUTH || dOpcode==`OUTC || dOpcode==`OUTB ||
|
//wire dIsOut = dIRvalid && (dOpcode==`OUTW || dOpcode==`OUTH || dOpcode==`OUTC || dOpcode==`OUTB ||
|
// (dOpcode==`MEMNDX && (
|
// (dOpcode==`MEMNDX && (
|
// dFunc6==`OUTWX || dFunc6==`OUTHX || dFunc6==`OUTCX || dFunc6==`OUTBX
|
// dFunc6==`OUTWX || dFunc6==`OUTHX || dFunc6==`OUTCX || dFunc6==`OUTBX
|
// ))
|
// )))
|
// ;
|
// ;
|
|
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
// Pipeline advance and stall logic
|
// Pipeline advance and stall logic
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
wire xIsSqrt = xOpcode==`R && xFunc6==`SQRT;
|
wire xIsSqrt = xIRvalid && xOpcode==`R && xFunc6==`SQRT;
|
wire xIsMult = (xOpcode==`RR && (xFunc6==`MULU || xFunc6==`MULS)) || xOpcode==`MULSI || xOpcode==`MULUI;
|
wire xIsMult = xIRvalid && ((xOpcode==`RR && (xFunc6==`MULU || xFunc6==`MULS)) || xOpcode==`MULSI || xOpcode==`MULUI);
|
wire xIsDiv = (xOpcode==`RR && (xFunc6==`DIVU || xFunc6==`DIVS || xFunc6==`MODU || xFunc6==`MODS)) || xOpcode==`DIVSI || xOpcode==`DIVUI;
|
wire xIsDiv = xIRvalid && ((xOpcode==`RR && (xFunc6==`DIVU || xFunc6==`DIVS || xFunc6==`MODU || xFunc6==`MODS)) || xOpcode==`DIVSI || xOpcode==`DIVUI);
|
wire xIsCnt = xOpcode==`R && (xFunc6==`CTLZ || xFunc6==`CTLO || xFunc6==`CTPOP);
|
wire xIsCnt = xIRvalid && (xOpcode==`R && (xFunc6==`CTLZ || xFunc6==`CTLO || xFunc6==`CTPOP));
|
reg m1IsCnt,m2IsCnt;
|
reg m1IsCnt,m2IsCnt;
|
|
reg m2IsCacheElement;
|
|
|
// Have to set the xIsLoad/xIsStore flag to false when xIR is nopped out
|
// Have to set the xIsLoad/xIsStore flag to false when xIR is nopped out
|
wire xIsLoad =
|
wire xIsLoad = xIRvalid && (
|
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 ||
|
xOpcode==`LSH || xOpcode==`LSW ||
|
xOpcode==`LSH || xOpcode==`LSW ||
|
Line 1093... |
Line 1116... |
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==`SYSCALL))
|
(xOpcode==`MISC && (xFunc==`SYSCALL))
|
|
)
|
;
|
;
|
wire xIsStore =
|
wire xIsStore = xIRvalid && (
|
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 ||
|
xOpcode==`SSH || xOpcode==`SSW || xOpcode==`STBC ||
|
xOpcode==`SSH || xOpcode==`SSW || xOpcode==`STBC ||
|
(xOpcode==`MEMNDX && (
|
(xOpcode==`MEMNDX && (
|
xFunc6==`SWX || xFunc6==`SHX || xFunc6==`SBX || xFunc6==`SCX || xFunc6==`SWCX ||
|
xFunc6==`SWX || xFunc6==`SHX || xFunc6==`SBX || xFunc6==`SCX || xFunc6==`SWCX ||
|
xFunc6==`SFX || xFunc6==`SFDX || xFunc6==`SPX ||
|
xFunc6==`SFX || xFunc6==`SFDX || xFunc6==`SPX ||
|
xFunc6==`SSHX || xFunc6==`SSWX
|
xFunc6==`SSHX || xFunc6==`SSWX
|
))
|
))
|
|
)
|
;
|
;
|
wire xIsSWC = xOpcode==`SWC;
|
wire xIsSWC = xOpcode==`SWC && xIRvalid;
|
wire xIsIn =
|
wire xIsIn = xIRvalid && (
|
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 && (
|
(xOpcode==`MEMNDX && (
|
xFunc6==`INWX || xFunc6==`INHX || xFunc6==`INCX || xFunc6==`INBX ||
|
xFunc6==`INWX || xFunc6==`INHX || xFunc6==`INCX || xFunc6==`INBX ||
|
xFunc6==`INHUX || xFunc6==`INCUX || xFunc6==`INBUX
|
xFunc6==`INHUX || xFunc6==`INCUX || xFunc6==`INBUX
|
))
|
))
|
|
)
|
;
|
;
|
wire xIsOut = xOpcode==`OUTW || xOpcode==`OUTH || xOpcode==`OUTC || xOpcode==`OUTB ||
|
wire xIsOut = xIRvalid && (
|
|
xOpcode==`OUTW || xOpcode==`OUTH || xOpcode==`OUTC || xOpcode==`OUTB ||
|
(xOpcode==`MEMNDX && (
|
(xOpcode==`MEMNDX && (
|
xFunc6==`OUTWX || xFunc6==`OUTHX || xFunc6==`OUTCX || xFunc6==`OUTBX
|
xFunc6==`OUTWX || xFunc6==`OUTHX || xFunc6==`OUTCX || xFunc6==`OUTBX
|
))
|
)))
|
;
|
;
|
|
reg m1IsLoad,m1IsStore;
|
|
reg m2IsLoad,m2IsStore;
|
|
reg wIsStore;
|
|
reg m1IsOut,m1IsIn;
|
|
|
//wire mIsSWC = mOpcode==`SWC;
|
//wire mIsSWC = mOpcode==`SWC;
|
//reg m1IsIn;
|
//reg m1IsIn;
|
|
|
wire m1IsIn =
|
|
m1Opcode==`INW || m1Opcode==`INH || m1Opcode==`INCH || m1Opcode==`INB ||
|
|
m1Opcode==`INHU || m1Opcode==`INCU || m1Opcode==`INBU ||
|
|
(m1Opcode==`MEMNDX && (
|
|
m1Func6==`INWX || m1Func6==`INHX || m1Func6==`INCX || m1Func6==`INBX ||
|
|
m1Func6==`INHUX || m1Func6==`INCUX || m1Func6==`INBUX
|
|
))
|
|
;
|
|
wire m1IsOut = m1Opcode==`OUTW || m1Opcode==`OUTH || m1Opcode==`OUTC || m1Opcode==`OUTB ||
|
|
(m1Opcode==`MEMNDX && (
|
|
m1Func6==`OUTWX || m1Func6==`OUTHX || m1Func6==`OUTCX || m1Func6==`OUTBX
|
|
))
|
|
;
|
|
|
|
wire m2IsInW = m2Opcode==`INW;
|
wire m2IsInW = m2Opcode==`INW;
|
wire xIsIO = xIsIn || xIsOut;
|
wire xIsIO = xIsIn || xIsOut;
|
wire m1IsIO = m1IsIn || m1IsOut;
|
wire m1IsIO = m1IsIn || m1IsOut;
|
|
|
wire xIsFPLoo = xOpcode==`FPLOO;
|
wire xIsFPLoo = xIRvalid && xOpcode==`FPLOO;
|
wire xIsFP = xOpcode==`FP;
|
wire xIsFP = xIRvalid && xOpcode==`FP;
|
wire xneedBus = xIsIO;
|
wire xneedBus = xIsIO;
|
wire m1needBus = (m1IsLoad & !m1IsCacheElement) || m1IsStore || m1IsIO;
|
//wire m1needBus = (m1IsLoad & !m1IsCacheElement) || m1IsStore || m1IsIO;
|
wire m2needBus = (m2IsLoad | m2IsStore);
|
wire m1needBus = m1IsLoad || m1IsStore || m1IsIO;
|
|
wire m2needBus = m2IsLoad || m2IsStore;
|
|
|
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;
|
|
|
|
//wire StallI = dIsLSPair & ~dIR[15];
|
|
wire StallI = 1'b0;
|
|
|
// 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
|
// 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||xIsLoad||xIsStore) & (m1needBus|m2needBus|icaccess|dcaccess);
|
wire StallM1 = (m1needBus & (m2needBus|icaccess|dcaccess)) ||
|
wire StallM1 = (m1needBus & (m2needBus|icaccess|dcaccess)) ||
|
( m1IsLoad & m1IsCacheElement & (m2IsStore|wIsStore)) // wait for a preceding store to complete
|
( m1IsLoad & m1IsCacheElement & (m2IsStore|wIsStore)) // wait for a preceding store to complete
|
;
|
;
|
wire StallM2 = m2needBus & (icaccess|dcaccess);
|
wire StallM2 = m2needBus & (icaccess|dcaccess);
|
|
|
wire advanceT = !resetA;
|
assign advanceT = !resetA;
|
assign advanceW = advanceT;
|
assign advanceW = advanceT;
|
wire advanceM2 = advanceW &&
|
assign advanceM2 = advanceW && (cyc_o ? (ack_i|err_i) : 1'b1) && !StallM2;
|
((m2IsLoad || m2IsStore) ? (ack_i|err_i) : 1'b1) &&
|
|
!StallM2
|
|
;
|
|
assign advanceM1 = advanceM2 &
|
assign advanceM1 = advanceM2 &
|
(m1IsIO ? (ack_i|err_i) : 1'b1) &
|
(iocyc_o ? (ack_i|err_i) : 1'b1) &
|
((m1IsLoad & m1IsCacheElement) ? dhit : 1'b1) &
|
((m1IsLoad & m1IsCacheElement) ? dhit : 1'b1) &
|
!StallM1
|
!StallM1
|
;
|
;
|
assign advanceX = advanceM1 & (
|
assign advanceX = advanceM1 & (
|
xIsSqrt ? sqrt_done :
|
xIsSqrt ? sqrt_done :
|
Line 1181... |
Line 1199... |
xIsDiv ? div_done :
|
xIsDiv ? div_done :
|
xIsFPLoo ? fpLooDone :
|
xIsFPLoo ? fpLooDone :
|
xIsFP ? fltdone :
|
xIsFP ? fltdone :
|
1'b1) &
|
1'b1) &
|
!StallX;
|
!StallX;
|
wire advanceR = advanceX & !StallR;
|
assign advanceR = advanceX & !StallR;
|
wire advanceI = advanceR & (ICacheOn ? ihit : ibufrdy);
|
assign advanceI = advanceR & (ICacheAct ? ihit : ibufrdy) & !StallI;
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
// Cache loading control
|
// Cache loading control
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
wire pipelineEmpty =
|
wire pipelineEmpty =
|
(dOpcode==`NOPI) && // and the pipeline is flushed
|
(dOpcode==`NOPI || !dIRvalid) && // and the pipeline is flushed
|
(xOpcode==`NOPI) &&
|
(xOpcode==`NOPI || !xIRvalid) &&
|
m1Opcode==`NOPI &&
|
(m1Opcode==`NOPI || !m1IRvalid) &&
|
m2Opcode==`NOPI
|
(m2Opcode==`NOPI || !m2IRvalid)
|
;
|
;
|
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
|
m2Opcode==`NOPI; // and the pipeline is free of memory-ops
|
(m2Opcode==`NOPI || !m2IRvalid); // and the pipeline is free of memory-ops
|
;
|
;
|
// Since IMM is "sticky" we have to check for it.
|
|
wire triggerICacheLoad1 = ICacheAct && !ihit && !triggerDCacheLoad && // There is a miss
|
wire triggerICacheLoad1 = ICacheAct && !ihit && !triggerDCacheLoad && // There is a miss
|
!(icaccess | dcaccess) && // caches are not active
|
!(icaccess | dcaccess) && // caches are not active
|
pipelineEmpty;
|
pipelineEmpty;
|
wire triggerICacheLoad2 = (!ICacheAct && !ibufrdy) && !triggerDCacheLoad && // There is a miss
|
wire triggerICacheLoad2 = (!ICacheAct && !ibufrdy) && !triggerDCacheLoad && // There is a miss
|
!(icaccess | dcaccess) && // caches are not active
|
!(icaccess | dcaccess) && // caches are not active
|
Line 1228... |
Line 1245... |
Raptor64_regfile u5
|
Raptor64_regfile u5
|
(
|
(
|
.clk(clk),
|
.clk(clk),
|
.advanceR(advanceR),
|
.advanceR(advanceR),
|
.advanceW(advanceW),
|
.advanceW(advanceW),
|
|
.wIRvalid(wIRvalid),
|
.dRa(dRa),
|
.dRa(dRa),
|
.dRb(dRb),
|
.dRb(dRb),
|
.dRc(dRc),
|
.dRc(dRc),
|
.dpc(dpc),
|
.dpc(dpc),
|
.xRt(xRt),
|
.xRt(xRt),
|
Line 1256... |
Line 1274... |
.advanceI(advanceI),
|
.advanceI(advanceI),
|
.advanceR(advanceR),
|
.advanceR(advanceR),
|
.advanceX(advanceX),
|
.advanceX(advanceX),
|
.b(b),
|
.b(b),
|
.AXC(AXC),
|
.AXC(AXC),
|
|
.xAXC(xAXC),
|
.insn(insn),
|
.insn(insn),
|
.xIR(xIR),
|
.xIR(xIR),
|
.dRa(dRa),
|
.dRa(dRa),
|
.dRb(dRb),
|
.dRb(dRb),
|
.dRc(dRc)
|
.dRc(dRc)
|
Line 1269... |
Line 1288... |
(
|
(
|
.rst(rst_i),
|
.rst(rst_i),
|
.clk(clk),
|
.clk(clk),
|
.advanceR(advanceR),
|
.advanceR(advanceR),
|
.advanceX(advanceX),
|
.advanceX(advanceX),
|
|
.dIRvalid(dIRvalid),
|
.dIR(dIR),
|
.dIR(dIR),
|
.dAXC(dAXC),
|
.dAXC(dAXC),
|
.xRt(xRt)
|
.xRt(xRt)
|
);
|
);
|
|
|
reg [5:0] pchi;
|
reg [5:0] pchi;
|
//vtdl #(64,64) u23
|
vtdl #(64,64) u23
|
//(
|
(
|
// .clk(clk),
|
.clk(clk),
|
// .ce(advanceI & pccap),
|
.ce(advanceI & pccap),
|
// .a(pchi),
|
.a(pchi),
|
// .d(pc),
|
.d(pc),
|
// .q(pchistoric)
|
.q(pchistoric)
|
//);
|
);
|
|
|
always @(posedge clk)
|
always @(posedge clk)
|
if (rst_i) begin
|
if (rst_i) begin
|
bte_o <= 2'b00;
|
bte_o <= 2'b00;
|
cti_o <= 3'b000;
|
cti_o <= 3'b000;
|
Line 1304... |
Line 1324... |
nonICacheSeg <= 32'hFFFF_FFFD;
|
nonICacheSeg <= 32'hFFFF_FFFD;
|
TBA <= 64'd0;
|
TBA <= 64'd0;
|
pc <= `RESET_VECTOR;
|
pc <= `RESET_VECTOR;
|
m1Opcode <= `NOPI;
|
m1Opcode <= `NOPI;
|
m2Opcode <= `NOPI;
|
m2Opcode <= `NOPI;
|
|
m1IR <= `NOP_INSN;
|
|
m2IR <= `NOP_INSN;
|
|
wIR <= `NOP_INSN;
|
wOpcode <= `NOPI;
|
wOpcode <= `NOPI;
|
dIR <= `NOP_INSN;
|
dIR <= `NOP_INSN;
|
|
m1IsLoad <= 1'b0;
|
|
m1IsStore <= 1'b0;
|
|
m2IsLoad <= 1'b0;
|
|
m2IsStore <= 1'b0;
|
|
wIsStore <= 1'b0;
|
|
m1IsOut <= 1'b0;
|
|
m1IsIn <= 1'b0;
|
xRtZero <= 1'b0;
|
xRtZero <= 1'b0;
|
tRt <= 9'd0;
|
tRt <= 9'd0;
|
wRt <= 9'd0;
|
wRt <= 9'd0;
|
m1Rt <= 9'd0;
|
m1Rt <= 9'd0;
|
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;
|
m1IsLoad <= 1'b0;
|
|
m2IsLoad <= 1'b0;
|
|
m1IsStore <= 1'b0;
|
|
m2IsStore <= 1'b0;
|
|
wIsStore <= 1'b0;
|
|
icaccess <= 1'b0;
|
icaccess <= 1'b0;
|
dcaccess <= 1'b0;
|
dcaccess <= 1'b0;
|
prev_ihit <= 1'b0;
|
prev_ihit <= 1'b0;
|
wFip <= 1'b0;
|
wFip <= 1'b0;
|
m2Fip <= 1'b0;
|
m2Fip <= 1'b0;
|
m1Fip <= 1'b0;
|
m1Fip <= 1'b0;
|
xFip <= 1'b0;
|
xFip <= 1'b0;
|
dFip <= 1'b0;
|
dFip <= 1'b0;
|
dirqf <= 1'b0;
|
dirqf <= 1'b0;
|
|
ipcv <= 1'b1;
|
dpcv <= 1'b0;
|
dpcv <= 1'b0;
|
xpcv <= 1'b0;
|
xpcv <= 1'b0;
|
m1pcv <= 1'b0;
|
m1pcv <= 1'b0;
|
m2pcv <= 1'b0;
|
m2pcv <= 1'b0;
|
wpcv <= 1'b0;
|
wpcv <= 1'b0;
|
Line 1354... |
Line 1380... |
xpc <= 64'd0;
|
xpc <= 64'd0;
|
a <= 64'd0;
|
a <= 64'd0;
|
b <= 64'd0;
|
b <= 64'd0;
|
imm <= 64'd0;
|
imm <= 64'd0;
|
clk_en <= 1'b1;
|
clk_en <= 1'b1;
|
StatusEXL <= 1'b1;
|
StatusEXL <= 16'hFFFF;
|
StatusHWI <= 1'b0;
|
StatusHWI <= 1'b0;
|
resetA <= 1'b1;
|
resetA <= 1'b1;
|
mutex_gate <= 64'h0;
|
mutex_gate <= 64'h0;
|
dcache_on <= 1'b0;
|
dcache_on <= 1'b0;
|
ICacheOn <= 1'b0;
|
ICacheOn <= 1'b0;
|
ibuftag0 <= 64'h0;
|
ibufadr <= 64'h0;
|
ibuftag1 <= 64'h0;
|
|
m1IsCacheElement <= 1'b0;
|
m1IsCacheElement <= 1'b0;
|
dtinit <= 1'b1;
|
dtinit <= 1'b1;
|
ras_sp <= 6'd63;
|
ras_sp <= 6'd63;
|
im <= 1'b1;
|
im <= 1'b1;
|
im1 <= 1'b1;
|
im1 <= 1'b1;
|
Line 1374... |
Line 1399... |
m_z <= 64'h0123456789ABCDEF;
|
m_z <= 64'h0123456789ABCDEF;
|
m_w <= 64'h8888888877777777;
|
m_w <= 64'h8888888877777777;
|
insnkey <= 32'd0;
|
insnkey <= 32'd0;
|
LoadNOPs <= 1'b0;
|
LoadNOPs <= 1'b0;
|
eptr <= 8'h00;
|
eptr <= 8'h00;
|
|
dIRvalid <= 1'b1;
|
|
xIRvalid <= 1'b1;
|
|
m1IRvalid <= 1'b0;
|
|
m2IRvalid <= 1'b0;
|
|
wIRvalid <= 1'b0;
|
end
|
end
|
else begin
|
else begin
|
|
|
//---------------------------------------------------------
|
//---------------------------------------------------------
|
// Initialize program counters
|
// Initialize program counters
|
Line 1386... |
Line 1416... |
//---------------------------------------------------------
|
//---------------------------------------------------------
|
case(state)
|
case(state)
|
RESET:
|
RESET:
|
begin
|
begin
|
pc <= `RESET_VECTOR;
|
pc <= `RESET_VECTOR;
|
|
ipcv <= 1'b1;
|
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;
|
state <= RUN;
|
Line 1425... |
Line 1456... |
// - set special register defaults for some instructions
|
// - set special register defaults for some instructions
|
// Outputs:
|
// Outputs:
|
// - d???? signals
|
// - d???? signals
|
//---------------------------------------------------------
|
//---------------------------------------------------------
|
if (advanceI) begin
|
if (advanceI) begin
|
dpcv <= 1'b1;
|
|
dAXC <= AXC;
|
dAXC <= AXC;
|
dextype <= `EX_NON;
|
dextype <= `EX_NON;
|
|
// record instruction and associated pc value
|
|
dIR <= insn;
|
|
dIRvalid <= 1'b1;
|
|
dpc <= pc;
|
|
dpcv <= ipcv;
|
if (nmi_edge & !StatusHWI) 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;
|
dextype <= `EX_NMI;
|
dextype <= `EX_NMI;
|
dIR <= `NOP_INSN;
|
dIRvalid <= 1'b0;
|
LoadNOPs <= 1'b1;
|
LoadNOPs <= 1'b1;
|
end
|
end
|
else if (irq_i & !im & !StatusHWI) 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;
|
dextype <= `EX_IRQ;
|
dextype <= `EX_IRQ;
|
dIR <= `NOP_INSN;
|
dIRvalid <= 1'b0;
|
LoadNOPs <= 1'b1;
|
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 (|dFip|LoadNOPs)
|
else if (|dFip|LoadNOPs)
|
dIR <= `NOP_INSN;
|
dIRvalid <= 1'b0;
|
`ifdef TLB
|
`ifdef TLB
|
else if (ITLBMiss)
|
else if (ITLBMiss)
|
dIR <= `NOP_INSN;
|
dIRvalid <= 1'b0;
|
`endif
|
`endif
|
else begin
|
else begin
|
dIR <= insn;
|
|
`include "insn_dumpsc.v"
|
`include "insn_dumpsc.v"
|
end
|
end
|
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;
|
BadVAddr <= pc[63:13];
|
BadVAddr <= pc[63:13];
|
Line 1474... |
Line 1507... |
end
|
end
|
else
|
else
|
`endif
|
`endif
|
begin
|
begin
|
dbranch_taken <= 1'b0;
|
dbranch_taken <= 1'b0;
|
// if (!LoadNOPs)
|
|
pc <= fnIncPC(pc);
|
pc <= fnIncPC(pc);
|
case(iOpcode)
|
case(iOpcode)
|
// We predict the return address by storing it in a return address stack
|
// We predict the return address by storing it in a return address stack
|
// during a call instruction, then popping it off the stack in a return
|
// during a call instruction, then popping it off the stack in a return
|
// instruction. The prediction will not always be correct, if it's wrong
|
// instruction. The prediction will not always be correct, if it's wrong
|
// it's corrected by the EX stage branching to the right address.
|
// it's corrected by the EX stage branching to the right address.
|
`CALL:
|
`CALL:
|
begin
|
begin
|
ras[ras_sp] <= fnIncPC(pc);
|
ras[ras_sp] <= fnIncPC(pc);
|
ras_sp <= ras_sp - 6'd1;
|
ras_sp <= ras_sp - 6'd1;
|
dbranch_taken <= 1'b1;
|
|
pc <= jmp_tgt;
|
pc <= jmp_tgt;
|
|
ipcv <= 1'b1;
|
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;
|
|
ipcv <= 1'b1;
|
end
|
end
|
`JMP:
|
`JMP:
|
begin
|
begin
|
dbranch_taken <= 1'b1;
|
|
pc <= jmp_tgt;
|
pc <= jmp_tgt;
|
|
ipcv <= 1'b1;
|
end
|
end
|
`BTRR:
|
`BTRR:
|
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 + {{52{insn[14]}},insn[14:5],2'b00};
|
pc <= pc + {{52{insn[14]}},insn[14:5],2'b00};
|
|
ipcv <= 1'b1;
|
end
|
end
|
default: ;
|
default: ;
|
endcase
|
endcase
|
|
|
// If doing a JAL that stores a return address in the link register, save off the return address
|
// If doing a JAL that stores a return address in the link register, save off the return address
|
Line 1522... |
Line 1556... |
`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;
|
pc <= btb[pc[7:2]];
|
pc <= btb[pc[7:2]];
|
|
ipcv <= 1'b1;
|
end
|
end
|
`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 + {{50{insn[19]}},insn[19:8],2'b00};
|
pc <= pc + {{50{insn[19]}},insn[19:8],2'b00};
|
|
ipcv <= 1'b1;
|
end
|
end
|
end
|
end
|
default: ;
|
default: ;
|
endcase
|
endcase
|
end
|
end
|
Line 1540... |
Line 1576... |
// 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;
|
dIR <= `NOP_INSN;
|
dIRvalid <= 1'b0;
|
dpcv <= 1'b0;
|
dpcv <= 1'b0;
|
dpc <= `RESET_VECTOR;
|
|
end
|
end
|
|
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
// RFETCH:
|
// RFETCH:
|
Line 1564... |
Line 1599... |
xextype <= dextype;
|
xextype <= dextype;
|
xpc <= dpc;
|
xpc <= dpc;
|
xpcv <= dpcv;
|
xpcv <= dpcv;
|
xbranch_taken <= dbranch_taken;
|
xbranch_taken <= dbranch_taken;
|
xRtZero <= 1'b0;
|
xRtZero <= 1'b0;
|
if (dOpcode==`R && dFunc==`MYST)
|
xIRvalid <= dIRvalid;
|
|
if (dOpcode==`R && dFunc==`MYST && dIRvalid)
|
xIR <= nxt_c;
|
xIR <= nxt_c;
|
else
|
else
|
xIR <= dIR;
|
xIR <= dIR;
|
a <= nxt_a;
|
a <= nxt_a;
|
b <= nxt_b;
|
b <= nxt_b;
|
Line 1580... |
Line 1616... |
`BTRI: imm <= {{53{dIR[10]}},dIR[10: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 <= {{56{dIR[7]}},dIR[7:0]};
|
imm <= {{56{dIR[7]}},dIR[7:0]};
|
`RET: imm <= {49'h00000000,dIR[14:3],3'b000};
|
`RET: imm <= {49'h00000000,dIR[14:3],3'b000};
|
`MEMNDX: imm <= dIR[7:6];
|
`MEMNDX: imm <= dIR[7:6];
|
`STBC: imm <= {{52{dIR[11]}},dIR[11:0]};
|
|
default: imm <= {{49{dIR[14]}},dIR[14:0]};
|
default: imm <= {{49{dIR[14]}},dIR[14:0]};
|
endcase
|
endcase
|
scale <= dIR[9:8];
|
scale <= dIR[9:8];
|
|
// if (dIsLSPair & ~dIR[15])
|
|
// dIR <= dIR|32'h8000;
|
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 1'b1;
|
xRtZero <= #1 1'b1;
|
xextype <= #1 `EX_NON;
|
xextype <= #1 `EX_NON;
|
xbranch_taken <= #1 1'b0;
|
xbranch_taken <= #1 1'b0;
|
xIR <= #1 `NOP_INSN;
|
xIRvalid <= #1 1'b0;
|
xpcv <= #1 1'b0;
|
xpcv <= #1 1'b0;
|
xpc <= #1 `RESET_VECTOR;
|
|
xFip <= #1 1'b0;
|
xFip <= #1 1'b0;
|
end
|
end
|
|
|
//---------------------------------------------------------
|
//---------------------------------------------------------
|
// EXECUTE:
|
// EXECUTE:
|
Line 1611... |
Line 1647... |
m1Fip <= xFip;
|
m1Fip <= xFip;
|
m1Func <= xFunc;
|
m1Func <= xFunc;
|
m1pcv <= xpcv;
|
m1pcv <= xpcv;
|
m1pc <= xpc;
|
m1pc <= xpc;
|
m1IR <= xIR;
|
m1IR <= xIR;
|
m1IsLoad <= xIsLoad;
|
|
m1IsStore <= xIsStore;
|
|
m1IsCnt <= xIsCnt;
|
m1IsCnt <= xIsCnt;
|
m1Opcode <= xOpcode;
|
m1Opcode <= xOpcode;
|
|
m1IsLoad <= xIsLoad & xIRvalid;
|
|
m1IsStore <= xIsStore & xIRvalid;
|
|
m1IsOut <= xIsOut & xIRvalid;
|
|
m1IsIn <= xIsIn & xIRvalid;
|
m1Rt <= xRtZero ? 9'd0 : xRt;
|
m1Rt <= xRtZero ? 9'd0 : xRt;
|
m1Data <= xData;
|
m1Data <= xData;
|
m1IsCacheElement <= xisCacheElement;
|
m1IsCacheElement <= xisCacheElement;
|
|
m1IRvalid <= xIRvalid;
|
m1AXC <= xAXC;
|
m1AXC <= xAXC;
|
if (xOpcode==`RR) begin
|
if (xOpcode==`RR && xIRvalid) begin
|
if (xFunc6==`MOVZ && !aeqz) begin
|
if (xFunc6==`MOVZ && !aeqz) begin
|
m1Rt <= 9'd0;
|
m1Rt <= 9'd0;
|
m1Data <= 64'd0;
|
m1Data <= 64'd0;
|
end
|
end
|
if (xFunc6==`MOVNZ && aeqz) begin
|
if (xFunc6==`MOVNZ && aeqz) begin
|
Line 1638... |
Line 1677... |
m1Rt <= 9'd0;
|
m1Rt <= 9'd0;
|
m1Data <= 64'd0;
|
m1Data <= 64'd0;
|
end
|
end
|
end
|
end
|
|
|
|
if (xIRvalid) begin
|
case(xOpcode)
|
case(xOpcode)
|
`MISC:
|
`MISC:
|
case(xFunc)
|
case(xFunc)
|
`SEI: im <= 1'b1;
|
`SEI: im <= 1'b1;
|
`CLI: im <= 1'b0;
|
`CLI: im <= 1'b0;
|
Line 1649... |
Line 1689... |
`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;
|
`FIP: begin
|
`FIP: begin
|
dIR <= `NOP_INSN;
|
dIRvalid <= 1'b0;
|
xIR <= `NOP_INSN;
|
xIRvalid <= 1'b0;
|
xRtZero <= 1'b1;
|
xRtZero <= 1'b1;
|
xpcv <= 1'b0;
|
xpcv <= 1'b0;
|
dpcv <= 1'b0;
|
dpcv <= 1'b0;
|
|
ipcv <= 1'b0;
|
dFip <= 1'b1;
|
dFip <= 1'b1;
|
xFip <= 1'b1;
|
xFip <= 1'b1;
|
m1Fip <= 1'b1;
|
m1Fip <= 1'b1;
|
end
|
end
|
`IEPP: begin
|
`IEPP: begin
|
eptr <= eptr + 8'd1;
|
eptr <= eptr + 8'd1;
|
dIR <= `NOP_INSN;
|
dIRvalid <= 1'b0;
|
xIR <= `NOP_INSN;
|
xIRvalid <= 1'b0;
|
xRtZero <= 1'b1;
|
xRtZero <= 1'b1;
|
xpcv <= 1'b0;
|
xpcv <= 1'b0;
|
dpcv <= 1'b0;
|
dpcv <= 1'b0;
|
|
ipcv <= 1'b0;
|
dFip <= 1'b1;
|
dFip <= 1'b1;
|
xFip <= 1'b1;
|
xFip <= 1'b1;
|
m1Fip <= 1'b1;
|
m1Fip <= 1'b1;
|
end
|
end
|
`GRAN: begin
|
`GRAN: begin
|
Line 1684... |
Line 1726... |
`IRET:
|
`IRET:
|
if (StatusHWI) begin
|
if (StatusHWI) begin
|
StatusHWI <= 1'b0;
|
StatusHWI <= 1'b0;
|
im <= 1'b0;
|
im <= 1'b0;
|
pc <= IPC[xAXC]; //a;
|
pc <= IPC[xAXC]; //a;
|
dIR <= `NOP_INSN;
|
dIRvalid <= 1'b0;
|
xIR <= `NOP_INSN;
|
xIRvalid <= 1'b0;
|
xRtZero <= 1'b1;
|
xRtZero <= 1'b1;
|
xpcv <= 1'b0;
|
xpcv <= 1'b0;
|
dpcv <= 1'b0;
|
dpcv <= 1'b0;
|
|
ipcv <= 1'b1;
|
end
|
end
|
`ERET:
|
`ERET:
|
if (StatusEXL) begin
|
if (StatusEXL[xAXC]) begin
|
StatusEXL <= 1'b0;
|
StatusEXL[xAXC] <= 1'b0;
|
pc <= EPC[xAXC];
|
pc <= EPC[xAXC];
|
dIR <= `NOP_INSN;
|
dIRvalid <= 1'b0;
|
xIR <= `NOP_INSN;
|
xIRvalid <= 1'b0;
|
xRtZero <= 1'b1;
|
xRtZero <= 1'b1;
|
xpcv <= 1'b0;
|
xpcv <= 1'b0;
|
dpcv <= 1'b0;
|
dpcv <= 1'b0;
|
|
ipcv <= 1'b1;
|
end
|
end
|
|
// Note: we can't mask off the interrupts in the I-stage because this
|
|
// instruction might not be valid. Eg. a branch could occur causing
|
|
// the instruction to not be executed. But we don't want to allow
|
|
// nested interrupts. We would need a stack of return addresses to
|
|
// implement nested interrupts. We don't want a real IRQ that's following this
|
|
// instruction in the pipeline to interfere with it's operation. So...
|
|
// we check the pipeline and if if the IRQ SYSCALL is being followed by
|
|
// a real IRQ, then we merge the two IRQ's into a single one by aborting
|
|
// the IRQ SYSCALL. If nested interrupts were happening, the IRET at the
|
|
// end of the real IRQ routine would re-enable interrupts too soon.
|
`SYSCALL:
|
`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) && // Is this a IRQ SYSCALL ?
|
StatusEXL <= 1'b1;
|
((dextype==`EX_NMI || dextype==`EX_IRQ) || // Is there an interrupt in the pipeline ?
|
|
(nmi_edge & !StatusHWI) || (irq_i & ~im & !StatusHWI))) begin // OR about to happen
|
|
m1Opcode <= `NOPI; // Then turn this into a NOP
|
|
m1IRvalid <= 1'b0;
|
end
|
end
|
if (xIR[15:7]==`EX_NMI || xIR[15:7]==`EX_IRQ)
|
else begin
|
m1Data <= xpc;
|
if (xIR[15:7]!=`EX_NMI && xIR[15:7]!=`EX_IRQ)
|
else
|
StatusEXL[xAXC] <= 1'b1;
|
m1Data <= fnIncPC(xpc);
|
else begin
|
dIR <= `NOP_INSN;
|
StatusHWI <= 1'b1;
|
xIR <= `NOP_INSN;
|
im <= 1'b1;
|
|
end
|
|
dIRvalid <= 1'b0;
|
|
xIRvalid <= 1'b0;
|
xRtZero <= 1'b1;
|
xRtZero <= 1'b1;
|
xpcv <= 1'b0;
|
xpcv <= 1'b0;
|
dpcv <= 1'b0;
|
dpcv <= 1'b0;
|
|
ipcv <= 1'b0;
|
ea <= {TBA[63:12],xIR[15:7],3'b000};
|
ea <= {TBA[63:12],xIR[15:7],3'b000};
|
LoadNOPs <= 1'b1;
|
LoadNOPs <= 1'b1;
|
$display("EX SYSCALL thru %h",{TBA[63:12],xIR[15:7],3'b000});
|
$display("EX SYSCALL thru %h",{TBA[63:12],xIR[15:7],3'b000});
|
end
|
end
|
|
end
|
`ifdef TLB
|
`ifdef TLB
|
`TLBP: ea <= TLBVirtPage;
|
`TLBP: ea <= TLBVirtPage;
|
`endif
|
`endif
|
default: ;
|
default: ;
|
endcase
|
endcase
|
Line 1729... |
Line 1791... |
case(xFunc6)
|
case(xFunc6)
|
`EXEC:
|
`EXEC:
|
begin
|
begin
|
pc <= fnIncPC(xpc);
|
pc <= fnIncPC(xpc);
|
dIR <= b;
|
dIR <= b;
|
xIR <= `NOP_INSN;
|
xIRvalid <= 1'b0;
|
xRtZero <= 1'b1;
|
xRtZero <= 1'b1;
|
xpcv <= 1'b0;
|
xpcv <= 1'b0;
|
dpcv <= 1'b0;
|
dpcv <= 1'b0;
|
|
ipcv <= 1'b1;
|
end
|
end
|
`MTSPR:
|
`MTSPR:
|
|
begin
|
case(xIR[11:6])
|
case(xIR[11:6])
|
`ifdef TLB
|
`ifdef TLB
|
`PageTableAddr: PageTableAddr <= a[63:13];
|
`PageTableAddr: PageTableAddr <= a[63:13];
|
`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;
|
|
`TBA: TBA <= {a[63:12],12'h000};
|
`TBA: TBA <= {a[63:12],12'h000};
|
// `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;
|
|
`SRAND1: begin
|
`SRAND1: begin
|
m_z <= a;
|
m_z <= a;
|
end
|
end
|
`SRAND2: begin
|
`SRAND2: begin
|
m_w <= a;
|
m_w <= a;
|
end
|
end
|
`INSNKEY: insnkey <= a[41:0];
|
`INSNKEY: insnkey <= a[41:0];
|
// `PCHI: pchi <= a[5:0];
|
`PCHI: pchi <= a[5:0];
|
default: ;
|
default: ;
|
endcase
|
endcase
|
|
end
|
`OMG: mutex_gate[a[5:0]] <= 1'b1;
|
`OMG: mutex_gate[a[5:0]] <= 1'b1;
|
`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[11:6]] <= 1'b1;
|
`CMGI: mutex_gate[xIR[12:7]] <= 1'b0;
|
`CMGI: mutex_gate[xIR[11:6]] <= 1'b0;
|
default: ;
|
default: ;
|
endcase
|
endcase
|
`RR:
|
`RR:
|
case(xFunc6)
|
case(xFunc6)
|
`MTEP: epat[a[7:0]] <= b[3:0];
|
`MTEP: epat[a[7:0]] <= b[3:0];
|
Line 1778... |
Line 1840... |
`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};
|
dIR <= `NOP_INSN;
|
dIRvalid <= 1'b0;
|
xIR <= `NOP_INSN;
|
xIRvalid <= 1'b0;
|
xRtzero <= 1'b1;
|
xRtzero <= 1'b1;
|
xpcv <= 1'b0;
|
xpcv <= 1'b0;
|
dpcv <= 1'b0;
|
dpcv <= 1'b0;
|
|
ipcv <= 1'b1;
|
end
|
end
|
`else
|
`else
|
begin
|
begin
|
pc[63:2] <= a[63:2] + imm[63:2];
|
pc[63:2] <= a[63:2] + imm[63:2];
|
dIR <= `NOP_INSN;
|
dIRvalid <= 1'b0;
|
xIR <= `NOP_INSN;
|
xIRvalid <= 1'b0;
|
xRtZero <= 1'b1;
|
xRtZero <= 1'b1;
|
xpcv <= 1'b0;
|
xpcv <= 1'b0;
|
dpcv <= 1'b0;
|
dpcv <= 1'b0;
|
|
ipcv <= 1'b1;
|
end
|
end
|
`endif
|
`endif
|
// Check the pc of the instruction after the RET instruction (the dpc), to
|
// Check the pc of the instruction after the RET instruction (the dpc), to
|
// 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
|
pc[63:2] <= b[63:2];
|
pc[63:2] <= b[63:2];
|
dIR <= `NOP_INSN;
|
dIRvalid <= 1'b0;
|
xIR <= `NOP_INSN;
|
xIRvalid <= 1'b0;
|
xRtZero <= 1'b1;
|
xRtZero <= 1'b1;
|
xpcv <= 1'b0;
|
xpcv <= 1'b0;
|
dpcv <= 1'b0;
|
dpcv <= 1'b0;
|
|
ipcv <= 1'b1;
|
end
|
end
|
`BTRR:
|
`BTRR:
|
case(xFunc5)
|
case(xFunc5)
|
// BEQ r1,r2,label
|
// BEQ r1,r2,label
|
`BEQ,`BNE,`BLT,`BLE,`BGT,`BGE,`BLTU,`BLEU,`BGTU,`BGEU,`BAND,`BOR,`BNR,`LOOP,`BRA,`BRN:
|
`BEQ,`BNE,`BLT,`BLE,`BGT,`BGE,`BLTU,`BLEU,`BGTU,`BGEU,`BAND,`BOR,`BNR,`LOOP,`BRA,`BRN:
|
if (!takb & xbranch_taken) begin
|
if (!takb & xbranch_taken) begin
|
$display("Taking mispredicted branch %h",fnIncPC(xpc));
|
$display("Taking mispredicted branch %h",fnIncPC(xpc));
|
pc <= fnIncPC(xpc);
|
pc <= fnIncPC(xpc);
|
dIR <= `NOP_INSN;
|
dIRvalid <= 1'b0;
|
xIR <= `NOP_INSN;
|
xIRvalid <= 1'b0;
|
xRtZero <= 1'b1;
|
xRtZero <= 1'b1;
|
xpcv <= 1'b0;
|
xpcv <= 1'b0;
|
dpcv <= 1'b0;
|
dpcv <= 1'b0;
|
|
ipcv <= 1'b1;
|
end
|
end
|
else if (takb & !xbranch_taken) begin
|
else if (takb & !xbranch_taken) begin
|
$display("Taking branch %h",{xpc[63:2] + {{52{xIR[14]}},xIR[14:5]},2'b00});
|
$display("Taking branch %h",{xpc[63:2] + {{52{xIR[14]}},xIR[14:5]},2'b00});
|
pc[63:2] <= xpc[63:2] + {{52{xIR[14]}},xIR[14:5]};
|
pc[63:2] <= xpc[63:2] + {{52{xIR[14]}},xIR[14:5]};
|
dIR <= `NOP_INSN;
|
dIRvalid <= 1'b0;
|
xIR <= `NOP_INSN;
|
xIRvalid <= 1'b0;
|
xRtZero <= 1'b1;
|
xRtZero <= 1'b1;
|
xpcv <= 1'b0;
|
xpcv <= 1'b0;
|
dpcv <= 1'b0;
|
dpcv <= 1'b0;
|
|
ipcv <= 1'b1;
|
end
|
end
|
// BEQ r1,r2,r10
|
// BEQ r1,r2,r10
|
`BEQR,`BNER,`BLTR,`BLER,`BGTR,`BGER,`BLTUR,`BLEUR,`BGTUR,`BGEUR://,`BANDR,`BORR,`BNRR:
|
`BEQR,`BNER,`BLTR,`BLER,`BGTR,`BGER,`BLTUR,`BLEUR,`BGTUR,`BGEUR://,`BANDR,`BORR,`BNRR:
|
if (takb) begin
|
if (takb) begin
|
pc[63:2] <= c[63:2];
|
pc[63:2] <= c[63:2];
|
pc[1:0] <= 2'b00;
|
pc[1:0] <= 2'b00;
|
`ifdef BTB
|
`ifdef BTB
|
btb[xpc[7:2]] <= c;
|
btb[xpc[7:2]] <= c;
|
`endif
|
`endif
|
dIR <= `NOP_INSN;
|
dIRvalid <= 1'b0;
|
xIR <= `NOP_INSN;
|
xIRvalid <= 1'b0;
|
xRtZero <= 1'b1;
|
xRtZero <= 1'b1;
|
xpcv <= 1'b0;
|
xpcv <= 1'b0;
|
dpcv <= 1'b0;
|
dpcv <= 1'b0;
|
|
ipcv <= 1'b1;
|
end
|
end
|
default: ;
|
default: ;
|
endcase
|
endcase
|
// BEQ r1,#3,r10
|
// BEQ r1,#3,r10
|
`BTRI:
|
`BTRI:
|
Line 1854... |
Line 1922... |
if ((xbranch_taken && b[63:2]!=dpc[63:2]) || // took branch, but not to right target
|
if ((xbranch_taken && b[63:2]!=dpc[63:2]) || // took branch, but not to right target
|
!xbranch_taken) begin // didn't take branch, and were supposed to
|
!xbranch_taken) begin // didn't take branch, and were supposed to
|
pc[63:2] <= b[63:2];
|
pc[63:2] <= b[63:2];
|
pc[1:0] <= 2'b00;
|
pc[1:0] <= 2'b00;
|
btb[xpc[7:2]] <= b;
|
btb[xpc[7:2]] <= b;
|
dIR <= `NOP_INSN;
|
dIRvalid <= 1'b0;
|
xIR <= `NOP_INSN;
|
xIRvalid <= 1'b0;
|
xRtzero <= 1'b1;
|
xRtzero <= 1'b1;
|
xpcv <= 1'b0;
|
xpcv <= 1'b0;
|
dpcv <= 1'b0;
|
dpcv <= 1'b0;
|
|
ipcv <= 1'b1;
|
end
|
end
|
end
|
end
|
else if (xbranch_taken) begin // took the branch, and weren't supposed to
|
else if (xbranch_taken) begin // took the branch, and weren't supposed to
|
pc <= fnIncPC(xpc);
|
pc <= fnIncPC(xpc);
|
dIR <= `NOP_INSN;
|
dIRvalid <= 1'b0;
|
xIR <= `NOP_INSN;
|
xIRvalid <= 1'b0;
|
xRtzero <= 1'b1;
|
xRtzero <= 1'b1;
|
xpcv <= 1'b0;
|
xpcv <= 1'b0;
|
dpcv <= 1'b0;
|
dpcv <= 1'b0;
|
|
ipcv <= 1'b1;
|
end
|
end
|
`else
|
`else
|
if (takb) begin
|
if (takb) begin
|
pc[63:2] <= b[63:2];
|
pc[63:2] <= b[63:2];
|
pc[1:0] <= 2'b00;
|
pc[1:0] <= 2'b00;
|
dIR <= `NOP_INSN;
|
dIRvalid <= 1'b0;
|
xIR <= `NOP_INSN;
|
xIRvalid <= 1'b0;
|
xRtZero <= 1'b1;
|
xRtZero <= 1'b1;
|
xpcv <= 1'b0;
|
xpcv <= 1'b0;
|
dpcv <= 1'b0;
|
dpcv <= 1'b0;
|
|
ipcv <= 1'b1;
|
end
|
end
|
`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:2] <= xpc[63:2] + {{50{xIR[19]}},xIR[19:8]};
|
pc[63:2] <= xpc[63:2] + {{50{xIR[19]}},xIR[19:8]};
|
dIR <= `NOP_INSN;
|
dIRvalid <= 1'b0;
|
xIR <= `NOP_INSN;
|
xIRvalid <= 1'b0;
|
xRtZero <= 1'b1;
|
xRtZero <= 1'b1;
|
xpcv <= 1'b0;
|
xpcv <= 1'b0;
|
dpcv <= 1'b0;
|
dpcv <= 1'b0;
|
|
ipcv <= 1'b1;
|
end
|
end
|
end
|
end
|
else begin
|
else begin
|
if (xbranch_taken) begin
|
if (xbranch_taken) begin
|
$display("Taking mispredicted branch %h",fnIncPC(xpc));
|
$display("Taking mispredicted branch %h",fnIncPC(xpc));
|
pc <= fnIncPC(xpc);
|
pc <= fnIncPC(xpc);
|
dIR <= `NOP_INSN;
|
dIRvalid <= 1'b0;
|
xIR <= `NOP_INSN;
|
xIRvalid <= 1'b0;
|
xRtZero <= 1'b1;
|
xRtZero <= 1'b1;
|
xpcv <= 1'b0;
|
xpcv <= 1'b0;
|
dpcv <= 1'b0;
|
dpcv <= 1'b0;
|
|
ipcv <= 1'b1;
|
end
|
end
|
end
|
end
|
`TRAPcc,`TRAPcci:
|
`TRAPcc,`TRAPcci:
|
if (takb) begin
|
if (takb) begin
|
StatusEXL <= 1'b1;
|
StatusEXL[xAXC] <= 1'b1;
|
xextype <= `EX_TRAP;
|
xextype <= `EX_TRAP;
|
dIR <= `NOP_INSN;
|
dIRvalid <= 1'b0;
|
xIR <= `NOP_INSN;
|
xIRvalid <= 1'b0;
|
xRtZero <= 1'b1;
|
xRtZero <= 1'b1;
|
xpcv <= 1'b0;
|
xpcv <= 1'b0;
|
dpcv <= 1'b0;
|
dpcv <= 1'b0;
|
|
ipcv <= 1'b0;
|
LoadNOPs <= 1'b1;
|
LoadNOPs <= 1'b1;
|
end
|
end
|
|
|
`INW:
|
`INW:
|
begin
|
begin
|
Line 2007... |
Line 2081... |
3'b111: sel_o <= 8'b10000000;
|
3'b111: sel_o <= 8'b10000000;
|
endcase
|
endcase
|
adr_o <= xData1;
|
adr_o <= xData1;
|
dat_o <= {8{b[7:0]}};
|
dat_o <= {8{b[7:0]}};
|
end
|
end
|
|
// `OUTBC:
|
|
// 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{xIR[19:12]}};
|
|
// end
|
`LEA: begin
|
`LEA: begin
|
$display("LEA %h", xData1);
|
$display("LEA %h", xData1);
|
m1Data <= xData1;
|
m1Data <= xData1;
|
end
|
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,
|
Line 2023... |
Line 2115... |
// `STBC:
|
// `STBC:
|
// begin
|
// begin
|
// m1Data <= {8{xIR[19:12]}};
|
// m1Data <= {8{xIR[19:12]}};
|
// ea <= xData1;
|
// ea <= 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 <= xData1;
|
// ea <= xData1;
|
end
|
// end
|
`CACHE:
|
`CACHE:
|
begin
|
begin
|
m1Data <= b;
|
m1Data <= b;
|
ea <= xData1;
|
ea <= xData1;
|
case(xIR[19:15])
|
case(xIR[19:15])
|
Line 2154... |
Line 2246... |
end
|
end
|
endcase
|
endcase
|
end
|
end
|
default: ;
|
default: ;
|
endcase
|
endcase
|
|
end
|
`ifdef FLOATING_POINT
|
`ifdef FLOATING_POINT
|
if (xOpcode==`FP) begin
|
if (xOpcode==`FP && xIRvalid) begin
|
case (xFunc6)
|
case (xFunc6)
|
`FDADD,`FDSUB:
|
`FDADD,`FDSUB:
|
begin
|
begin
|
fp_uf <= fpaddsub_uf;
|
fp_uf <= fpaddsub_uf;
|
fp_ovr <= fpaddsub_ovr;
|
fp_ovr <= fpaddsub_ovr;
|
Line 2199... |
Line 2292... |
endcase
|
endcase
|
end
|
end
|
`endif
|
`endif
|
if (dbz_error) begin
|
if (dbz_error) begin
|
$display("Divide by zero error");
|
$display("Divide by zero error");
|
m1extype <= `EX_DBZ;
|
m1extype <= #1 `EX_DBZ;
|
LoadNOPs <= 1'b1;
|
LoadNOPs <= #1 1'b1;
|
xRtZero <= 1'b1;
|
xRtZero <= #1 1'b1;
|
xpcv <= 1'b0;
|
xpcv <= #1 1'b0;
|
dpcv <= 1'b0;
|
dpcv <= #1 1'b0;
|
|
ipcv <= 1'b0;
|
end
|
end
|
else if (ovr_error) begin
|
else if (ovr_error) begin
|
$display("Overflow error");
|
$display("Overflow error");
|
m1extype <= `EX_OFL;
|
m1extype <= `EX_OFL;
|
LoadNOPs <= 1'b1;
|
LoadNOPs <= 1'b1;
|
xRtZero <= 1'b1;
|
xRtZero <= 1'b1;
|
xpcv <= 1'b0;
|
xpcv <= 1'b0;
|
dpcv <= 1'b0;
|
dpcv <= 1'b0;
|
|
ipcv <= 1'b0;
|
end
|
end
|
else if (priv_violation) begin
|
// else if (priv_violation) begin
|
$display("Priviledge violation");
|
// $display("Priviledge violation");
|
m1extype <= `EX_PRIV;
|
// m1extype <= `EX_PRIV;
|
LoadNOPs <= 1'b1;
|
// LoadNOPs <= 1'b1;
|
xRtZero <= 1'b1;
|
// xRtZero <= 1'b1;
|
xpcv <= 1'b0;
|
// xpcv <= 1'b0;
|
dpcv <= 1'b0;
|
// dpcv <= 1'b0;
|
end
|
// ipcv <= 1'b0;
|
|
// end
|
else if (illegal_insn) begin
|
else if (illegal_insn) begin
|
$display("Unimplemented Instruction");
|
$display("Unimplemented Instruction");
|
m1extype <= `EX_UNIMP_INSN;
|
m1extype <= `EX_UNIMP_INSN;
|
LoadNOPs <= 1'b1;
|
LoadNOPs <= 1'b1;
|
xRtZero <= 1'b1;
|
xRtZero <= 1'b1;
|
xpcv <= 1'b0;
|
xpcv <= 1'b0;
|
dpcv <= 1'b0;
|
dpcv <= 1'b0;
|
|
ipcv <= 1'b0;
|
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 (advanceM1) begin
|
else if (advanceM1) begin
|
m1IR <= #1 `NOP_INSN;
|
m1IRvalid <= #1 1'b0;
|
m1Opcode <= #1 `NOPI;
|
m1IsLoad <= #1 1'b0;
|
|
m1IsStore <= #1 1'b0;
|
|
m1IsOut <= #1 1'b0;
|
|
m1IsIn <= #1 1'b0;
|
m1Rt <= #1 9'd0;
|
m1Rt <= #1 9'd0;
|
m1clkoff <= #1 1'b0;
|
m1clkoff <= #1 1'b0;
|
m1Fip <= #1 1'b0;
|
m1Fip <= #1 1'b0;
|
m1pc <= #1 `RESET_VECTOR;
|
|
m1pcv <= #1 1'b0;
|
m1pcv <= #1 1'b0;
|
m1extype <= #1 `EX_NON;
|
m1extype <= #1 `EX_NON;
|
m1IsLoad <= #1 1'b0;
|
|
m1IsStore <= #1 1'b0;
|
|
m1IsCnt <= #1 1'b0;
|
m1IsCnt <= #1 1'b0;
|
m1IsCacheElement <= #1 1'b0;
|
m1IsCacheElement <= #1 1'b0;
|
end
|
end
|
|
|
|
|
Line 2273... |
Line 2370... |
m2pc <= m1pc;
|
m2pc <= m1pc;
|
m2pcv <= m1pcv;
|
m2pcv <= m1pcv;
|
m2IR <= m1IR;
|
m2IR <= m1IR;
|
m2Opcode <= m1Opcode;
|
m2Opcode <= m1Opcode;
|
m2Func <= m1Func;
|
m2Func <= m1Func;
|
m2IsLoad <= #1 m1IsLoad;
|
|
m2IsStore <= #1 m1IsStore;
|
|
m2IsCnt <= m1IsCnt;
|
m2IsCnt <= m1IsCnt;
|
m2Func <= m1Func;
|
m2Func <= m1Func;
|
m2Rt <= m1Rt;
|
m2Rt <= m1Rt;
|
m2clkoff <= m1clkoff;
|
m2clkoff <= m1clkoff;
|
m2AXC <= m1AXC;
|
m2AXC <= m1AXC;
|
if (m1IsIO & err_i) begin
|
m2IsCacheElement <= m1IsCacheElement;
|
|
m2IRvalid <= m1IRvalid;
|
|
m2IsLoad <= m1IsLoad & m1IRvalid;
|
|
m2IsStore <= m2IsStore & m1IRvalid;
|
|
|
|
if (m1IsIO & err_i & m1IRvalid) begin
|
m2extype <= `EX_DBERR;
|
m2extype <= `EX_DBERR;
|
errorAddress <= adr_o;
|
errorAddress <= adr_o;
|
end
|
end
|
|
|
if (m1extype == `EX_NON) begin
|
if (m1extype == `EX_NON && m1IRvalid) begin
|
case(m1Opcode)
|
case(m1Opcode)
|
`MISC:
|
`MISC:
|
case(m1Func)
|
case(m1Func)
|
`SYSCALL:
|
`SYSCALL:
|
if (!m1IsCacheElement) begin
|
if (!m1IsCacheElement) begin
|
Line 2299... |
Line 2399... |
adr_o <= pea;
|
adr_o <= pea;
|
m2Addr <= pea;
|
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});
|
$display("fetched vector: %h", {cdat[63:2],2'b00});
|
m2IsLoad <= 1'b0;
|
|
m2Opcode <= `NOPI;
|
m2Opcode <= `NOPI;
|
|
m2IsLoad <= 1'b0;
|
pc <= {cdat[63:2],2'b00};
|
pc <= {cdat[63:2],2'b00};
|
|
ipcv <= 1'b1;
|
LoadNOPs <= 1'b0;
|
LoadNOPs <= 1'b0;
|
end
|
end
|
endcase
|
endcase
|
`INW:
|
`INW:
|
begin
|
begin
|
Line 2386... |
Line 2487... |
8'b01000000: m2Data <= dat_i[55:48];
|
8'b01000000: m2Data <= dat_i[55:48];
|
8'b10000000: m2Data <= dat_i[63:56];
|
8'b10000000: m2Data <= dat_i[63:56];
|
default: m2Data <= 64'hDEADDEADDEADDEAD;
|
default: m2Data <= 64'hDEADDEADDEADDEAD;
|
endcase
|
endcase
|
end
|
end
|
`OUTW,`OUTH,`OUTC,`OUTB:
|
`OUTW,`OUTH,`OUTC,`OUTB,`OUTBC:
|
begin
|
begin
|
iocyc_o <= #1 1'b0;
|
iocyc_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;
|
Line 2550... |
Line 2651... |
endcase
|
endcase
|
end
|
end
|
|
|
`LBU:
|
`LBU:
|
if (!m1IsCacheElement) begin
|
if (!m1IsCacheElement) begin
|
|
$display("Load unsigned byte:");
|
cyc_o <= 1'b1;
|
cyc_o <= 1'b1;
|
stb_o <= 1'b1;
|
stb_o <= 1'b1;
|
case(pea[2:0])
|
case(pea[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;
|
Line 2566... |
Line 2668... |
endcase
|
endcase
|
adr_o <= pea;
|
adr_o <= pea;
|
m2Addr <= pea;
|
m2Addr <= pea;
|
end
|
end
|
else begin
|
else begin
|
|
$display("m2IsLoad <= 0");
|
m2IsLoad <= 1'b0;
|
m2IsLoad <= 1'b0;
|
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]};
|
Line 2635... |
Line 2738... |
endcase
|
endcase
|
adr_o <= pea;
|
adr_o <= pea;
|
dat_o <= #1 {4{m1Data[15:0]}};
|
dat_o <= #1 {4{m1Data[15:0]}};
|
end
|
end
|
|
|
`SB:
|
`SB,`STBC:
|
begin
|
begin
|
wrhit <= #1 dhit;
|
wrhit <= #1 dhit;
|
m2Addr <= pea;
|
m2Addr <= pea;
|
`ifdef ADDRESS_RESERVATION
|
`ifdef ADDRESS_RESERVATION
|
if (resv_address==pea[63:5])
|
if (resv_address==pea[63:5])
|
Line 2716... |
Line 2819... |
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 (advanceM2) begin
|
else if (advanceM2) begin
|
m2Rt <= #1 9'd0;
|
m2Rt <= #1 9'd0;
|
m2IR <= #1 `NOP_INSN;
|
m2IRvalid <= 1'b0;
|
m2Opcode <= #1 `NOPI;
|
m2IsCnt <= #1 1'b0;
|
m2IsLoad <= #1 1'b0;
|
m2IsLoad <= #1 1'b0;
|
m2IsStore <= #1 1'b0;
|
m2IsStore <= #1 1'b0;
|
m2IsCnt <= #1 1'b0;
|
|
m2Func <= #1 7'd0;
|
m2Func <= #1 7'd0;
|
m2Addr <= 64'd0;
|
m2Addr <= 64'd0;
|
m2Data <= #1 64'd0;
|
m2Data <= #1 64'd0;
|
m2clkoff <= #1 1'b0;
|
m2clkoff <= #1 1'b0;
|
m2Fip <= #1 1'b0;
|
m2Fip <= #1 1'b0;
|
m2pcv <= #1 1'b0;
|
m2pcv <= #1 1'b0;
|
m2pc <= #1 `RESET_VECTOR;
|
|
m2extype <= #1 `EX_NON;
|
m2extype <= #1 `EX_NON;
|
|
m2IsCacheElement <= 1'b0;
|
end
|
end
|
|
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
// MEMORY:
|
// MEMORY:
|
Line 2746... |
Line 2848... |
if (advanceM2) begin
|
if (advanceM2) begin
|
wextype <= #1 m2extype;
|
wextype <= #1 m2extype;
|
wpc <= #1 m2pc;
|
wpc <= #1 m2pc;
|
wpcv <= #1 m2pcv;
|
wpcv <= #1 m2pcv;
|
wFip <= #1 m2Fip;
|
wFip <= #1 m2Fip;
|
wIsStore <= #1 m2IsStore;
|
|
wIR <= #1 m2IR;
|
wIR <= #1 m2IR;
|
|
wIsStore <= #1 m2IsStore & m2IRvalid;
|
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;
|
wAXC <= #1 m2AXC;
|
wAXC <= #1 m2AXC;
|
|
wIRvalid <= m2IRvalid;
|
|
|
// 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 & m2IRvalid) 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 & m2IRvalid) begin
|
case(m2Opcode)
|
case(m2Opcode)
|
`MISC:
|
`MISC:
|
if (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;
|
pc <= #1 {dat_i[63:2],2'b00};
|
pc <= #1 {dat_i[63:2],2'b00};
|
|
ipcv <= 1'b1;
|
LoadNOPs <= 1'b0;
|
LoadNOPs <= 1'b0;
|
$display("M2 Fetched vector: %h",{dat_i[63:2],2'b00});
|
$display("M2 Fetched vector: %h",{dat_i[63:2],2'b00});
|
end
|
end
|
`SH,`SC,`SB,`SW,`SWC,`SF,`SFD,`SSH,`SSW,`SP,`SFP,`SFDP:
|
`SH,`SC,`SB,`SW,`SWC,`SF,`SFD,`SSH,`SSW,`SP,`SFP,`SFDP:
|
begin
|
begin
|
Line 2874... |
Line 2978... |
// 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
|
wextype <= `EX_NON;
|
wextype <= `EX_NON;
|
wRt <= 9'd0;
|
wRt <= 9'd0;
|
wData <= 64'd0;
|
wData <= 64'd0;
|
wIR <= `NOP_INSN;
|
|
wOpcode <= `NOPI;
|
|
wIsStore <= 1'b0;
|
wIsStore <= 1'b0;
|
|
wIRvalid <= 1'b0;
|
wclkoff <= 1'b0;
|
wclkoff <= 1'b0;
|
wFip <= 1'b0;
|
wFip <= 1'b0;
|
wpcv <= 1'b0;
|
wpcv <= 1'b0;
|
wpc <= `RESET_VECTOR;
|
|
end
|
end
|
|
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
// WRITEBACK:
|
// WRITEBACK:
|
Line 2899... |
Line 3001... |
//
|
//
|
if (advanceW) begin
|
if (advanceW) begin
|
textype <= wextype;
|
textype <= wextype;
|
tRt <= wRt;
|
tRt <= wRt;
|
tData <= wData;
|
tData <= wData;
|
if (wRt!=5'd0)
|
if (wRt!=5'd0) begin
|
$display("Writing regfile[%d:%d] with %h", wRt[8:5],wRt[4:0], wData);
|
$display("Writing regfile[%d:%d] with %h", wRt[8:5],wRt[4:0], wData);
|
|
end
|
|
if (wIRvalid) begin
|
case(wOpcode)
|
case(wOpcode)
|
`LSH:
|
`LSH:
|
case (wRt)
|
case (wRt)
|
`SR: begin
|
`SR: begin
|
bu_im <= wData[31];
|
bu_im <= wData[31];
|
Line 2914... |
Line 3018... |
default: ;
|
default: ;
|
endcase
|
endcase
|
`MISC:
|
`MISC:
|
case(wFunc)
|
case(wFunc)
|
`SYSCALL:
|
`SYSCALL:
|
begin
|
if (wIR[15:7]==`EX_NMI || wIR[15:7]==`EX_IRQ)
|
if (wIR[24:20]==5'd25)
|
|
IPC[wAXC] <= wData;
|
IPC[wAXC] <= wData;
|
else
|
else
|
EPC[wAXC] <= wData;
|
EPC[wAXC] <= wData;
|
end
|
default: ;
|
endcase
|
endcase
|
`R:
|
`R:
|
case(wIR[5:0])
|
case(wFunc6)
|
`MTSPR:
|
`MTSPR:
|
case(wIR[11:6])
|
case(wIR[11:6])
|
`IPC: IPC[wAXC] <= wData;
|
`IPC: begin
|
|
$display("mtspr IPC[%d]=%h",wAXC,wData);
|
|
IPC[wAXC] <= wData;
|
|
end
|
`EPC: EPC[wAXC] <= wData;
|
`EPC: EPC[wAXC] <= wData;
|
|
default: ;
|
endcase
|
endcase
|
endcase
|
endcase
|
endcase
|
endcase
|
|
end
|
if (wclkoff)
|
if (wclkoff)
|
clk_en <= 1'b0;
|
clk_en <= 1'b0;
|
else
|
else
|
clk_en <= 1'b1;
|
clk_en <= 1'b1;
|
// FIP/IEPP:
|
// FIP/IEPP:
|
Line 2943... |
Line 3051... |
m2Fip <= 1'b0;
|
m2Fip <= 1'b0;
|
m1Fip <= 1'b0;
|
m1Fip <= 1'b0;
|
xFip <= 1'b0;
|
xFip <= 1'b0;
|
dFip <= 1'b0;
|
dFip <= 1'b0;
|
pc <= fnIncPC(wpc);
|
pc <= fnIncPC(wpc);
|
|
ipcv <= 1'b1;
|
end
|
end
|
//---------------------------------------------------------
|
//---------------------------------------------------------
|
// WRITEBACK (WB') - part two:
|
// WRITEBACK (WB') - part two:
|
// - vector to exception handler address
|
// - vector to exception handler address
|
// In the case of a hardware interrupt (NMI/IRQ) we know
|
// In the case of a hardware interrupt (NMI/IRQ) we know
|
Line 2970... |
Line 3079... |
// Hardware exceptions
|
// Hardware exceptions
|
`EX_NMI,`EX_IRQ:
|
`EX_NMI,`EX_IRQ:
|
begin
|
begin
|
$display("Stuffing SYSCALL %d",wextype);
|
$display("Stuffing SYSCALL %d",wextype);
|
dIR <= {`MISC,5'd25,4'd0,wextype,`SYSCALL};
|
dIR <= {`MISC,5'd25,4'd0,wextype,`SYSCALL};
|
// One of the following three pc's MUST be valid.
|
dIRvalid <= 1'b1;
|
|
// One of the following 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.
|
|
// Syscall has a larger shadow than a branch because it loads the
|
|
// vector from memory. Eventually syscall flags the pc valid.
|
case(1'b1)
|
case(1'b1)
|
wpcv: dpc <= wpc;
|
wpcv: dpc <= wpc;
|
m2pcv: dpc <= m2pc;
|
m2pcv: dpc <= m2pc;
|
default: dpc <= m1pc;
|
m1pcv: dpc <= m1pc;
|
|
xpcv: dpc <= xpc;
|
|
dpcv: dpc <= dpc;
|
|
default: dpc <= pc;
|
endcase
|
endcase
|
|
dpcv <= 1'b1;
|
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;
|
dIR <= {`MISC,5'd24,4'd0,wextype,`SYSCALL};
|
dIR <= {`MISC,5'd24,4'd0,wextype,`SYSCALL};
|
|
dIRvalid <= 1'b1;
|
dpc <= wpc;
|
dpc <= wpc;
|
|
dpcv <= 1'b1;
|
end
|
end
|
default:
|
default:
|
begin
|
begin
|
dIR <= {`MISC,5'd24,4'd0,wextype,`SYSCALL};
|
dIR <= {`MISC,5'd24,4'd0,wextype,`SYSCALL};
|
|
dIRvalid <= 1'b1;
|
dpc <= wpc;
|
dpc <= wpc;
|
|
dpcv <= 1'b1;
|
end
|
end
|
endcase
|
endcase
|
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.
|
Line 3015... |
Line 3135... |
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
|
cti_o <= 3'b010; // burst access
|
cti_o <= 3'b001; // constant address burst access
|
bl_o <= 5'd7;
|
bl_o <= 5'd7;
|
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:6],6'h00};
|
adr_o <= {pea[63:6],6'h00};
|
|
dcadr <= {pea[14:6],6'h00};
|
cstate <= DCACT;
|
cstate <= DCACT;
|
end
|
end
|
else if (triggerICacheLoad) begin
|
else if (triggerICacheLoad) begin
|
icaccess <= 1'b1;
|
icaccess <= 1'b1;
|
bte_o <= 2'b00; // linear burst
|
bte_o <= 2'b00; // linear burst
|
cti_o <= 3'b010; // burst access
|
|
cyc_o <= 1'b1;
|
cyc_o <= 1'b1;
|
stb_o <= 1'b1;
|
stb_o <= 1'b1;
|
sel_o <= 8'hFF;
|
sel_o <= 8'hFF;
|
if (ICacheAct) begin
|
if (ICacheAct) begin
|
|
cti_o <= 3'b001; // constant address burst access
|
bl_o <= 5'd7;
|
bl_o <= 5'd7;
|
adr_o <= {ppc[63:6],6'h00};
|
adr_o <= {ppc[63:6],6'h00};
|
|
icadr <= {ppc[63:6],6'h00};
|
cstate <= ICACT1;
|
cstate <= ICACT1;
|
end
|
end
|
else begin
|
else begin
|
bl_o <= 5'd1;
|
cti_o <= 3'b000;
|
adr_o <= {ppc[63:4],4'b0000};
|
bl_o <= 5'd0;
|
|
adr_o <= {ppc[63:2],2'b00};
|
cstate <= ICACT2;
|
cstate <= ICACT2;
|
end
|
end
|
end
|
end
|
// WISHBONE burst accesses
|
// WISHBONE burst accesses
|
//
|
//
|
ICACT1:
|
ICACT1:
|
if (ack_i|err_i) begin
|
if (ack_i|err_i) begin
|
adr_o[5:3] <= adr_o[5:3] + 3'd1;
|
icadr[5:3] <= icadr[5:3] + 3'd1;
|
if (adr_o[5:3]==3'd6)
|
if (icadr[5:3]==3'd6)
|
cti_o <= 3'b111; // Last cycle ahead
|
cti_o <= 3'b111; // Last cycle ahead
|
else if (adr_o[5:3]==3'd7) begin
|
if (icadr[5:3]==3'd7) begin
|
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;
|
sel_o <= 8'h00;
|
sel_o <= 8'h00;
|
tmem[adr_o[12:6]] <= {1'b1,adr_o[63:13]}; // This will cause ihit to go high
|
tmem[adr_o[12:6]] <= {1'b1,adr_o[63:13]}; // This will cause ihit to go high
|
Line 3061... |
Line 3184... |
cstate <= IDLE;
|
cstate <= IDLE;
|
end
|
end
|
end
|
end
|
//SYSCALL 509: 00000000_00000000_11111110_10010111
|
//SYSCALL 509: 00000000_00000000_11111110_10010111
|
ICACT2:
|
ICACT2:
|
|
begin
|
if (ack_i|err_i) begin
|
if (ack_i|err_i) begin
|
adr_o <= adr_o + 64'd8;
|
ibufadr <= adr_o;
|
if (adr_o[3]==1'b0) begin
|
if (err_i)
|
cti_o <= 3'b111; // Last cycle ahead
|
insnbuf <= syscall509;
|
tmpbuf <= err_i ? bevect : dat_i;
|
else
|
end
|
insnbuf <= adr_o[2] ? dat_i[63:32] : dat_i[31:0];
|
else begin
|
|
if (tick[0]) begin
|
|
insnbuf0 <= {err_i ? bevect : dat_i,tmpbuf};
|
|
ibuftag0 <= adr_o[63:4];
|
|
end
|
|
else begin
|
|
insnbuf1 <= {err_i ? bevect : dat_i,tmpbuf};
|
|
ibuftag1 <= adr_o[63:4];
|
|
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;
|
sel_o <= 8'h00;
|
sel_o <= 8'h00;
|
icaccess <= 1'b0;
|
icaccess <= 1'b0;
|
Line 3087... |
Line 3202... |
end
|
end
|
end
|
end
|
|
|
DCACT:
|
DCACT:
|
if (ack_i|err_i) begin
|
if (ack_i|err_i) begin
|
adr_o[5:3] <= adr_o[5:3] + 3'd1;
|
dcadr[5:3] <= dcadr[5:3] + 3'd1;
|
if (adr_o[5:3]==3'h6)
|
if (dcadr[5:3]==3'd6)
|
cti_o <= 3'b111; // Last cycle ahead
|
cti_o <= 3'b111; // Last cycle ahead
|
if (adr_o[5:3]==3'h7) begin
|
if (dcadr[5:3]==3'h7) begin
|
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;
|
sel_o <= 8'h00;
|
sel_o <= 8'h00;
|
dcaccess <= 1'b0;
|
dcaccess <= 1'b0;
|