mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Merge branch 'main' of https://github.com/openhwgroup/cvw
This commit is contained in:
commit
0d8c251fa4
2
src/cache/cache.sv
vendored
2
src/cache/cache.sv
vendored
@ -176,7 +176,7 @@ module cache import cvw::*; #(parameter cvw_t P,
|
||||
|
||||
logic [LINELEN/8-1:0] BlankByteMask;
|
||||
assign BlankByteMask[WORDLEN/8-1:0] = ByteMask;
|
||||
assign BlankByteMask[LINELEN/8-1:WORDLEN/8] = '0;
|
||||
assign BlankByteMask[LINELEN/8-1:WORDLEN/8] = 0;
|
||||
|
||||
assign DemuxedByteMask = BlankByteMask << ((MUXINTERVAL/8) * WordOffsetAddr);
|
||||
|
||||
|
2
src/cache/cacheLRU.sv
vendored
2
src/cache/cacheLRU.sv
vendored
@ -143,7 +143,7 @@ module cacheLRU
|
||||
// Every cycle must read from CacheSetData and each load/store must write the new LRU.
|
||||
always_ff @(posedge clk) begin
|
||||
if (reset | (InvalidateCache & ~FlushStage))
|
||||
for (int set = 0; set < NUMLINES; set++) LRUMemory[set] <= '0; // exclusion-tag: initialize
|
||||
for (int set = 0; set < NUMLINES; set++) LRUMemory[set] <= 0; // exclusion-tag: initialize
|
||||
if(CacheEn) begin
|
||||
if(LRUWriteEn)
|
||||
LRUMemory[PAdr] <= NextLRU;
|
||||
|
10
src/cache/cacheway.sv
vendored
10
src/cache/cacheway.sv
vendored
@ -117,7 +117,7 @@ module cacheway import cvw::*; #(parameter cvw_t P,
|
||||
.din(PAdr[PA_BITS-1:OFFSETLEN+INDEXLEN]), .we(SetValidEN));
|
||||
|
||||
// AND portion of distributed tag multiplexer
|
||||
assign TagWay = SelectedWay ? ReadTag : '0; // AND part of AOMux
|
||||
assign TagWay = SelectedWay ? ReadTag : 0; // AND part of AOMux
|
||||
assign HitDirtyWay = Dirty & ValidWay;
|
||||
assign DirtyWay = SelecteDirty & HitDirtyWay; // exclusion-tag: icache DirtyWay
|
||||
assign HitWay = ValidWay & (ReadTag == PAdr[PA_BITS-1:OFFSETLEN+INDEXLEN]) & ~InvalidateCacheDelay; // exclusion-tag: dcache HitWay
|
||||
@ -149,19 +149,19 @@ module cacheway import cvw::*; #(parameter cvw_t P,
|
||||
end
|
||||
|
||||
// AND portion of distributed read multiplexers
|
||||
assign ReadDataLineWay = SelectedWay ? ReadDataLine : '0; // AND part of AO mux.
|
||||
assign ReadDataLineWay = SelectedWay ? ReadDataLine : 0; // AND part of AO mux.
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Valid Bits
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
always_ff @(posedge clk) begin // Valid bit array,
|
||||
if (reset) ValidBits <= #1 '0;
|
||||
if (reset) ValidBits <= #1 0;
|
||||
if(CacheEn) begin
|
||||
ValidWay <= #1 ValidBits[CacheSetTag];
|
||||
if(InvalidateCache) ValidBits <= #1 '0; // exclusion-tag: dcache invalidateway
|
||||
if(InvalidateCache) ValidBits <= #1 0; // exclusion-tag: dcache invalidateway
|
||||
else if (SetValidEN) ValidBits[CacheSetData] <= #1 SetValidWay;
|
||||
else if (ClearValidEN) ValidBits[CacheSetData] <= #1 '0; // exclusion-tag: icache ClearValidBits
|
||||
else if (ClearValidEN) ValidBits[CacheSetData] <= #1 0; // exclusion-tag: icache ClearValidBits
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -62,8 +62,8 @@ module ahbinterface #(
|
||||
flop #(XLEN) wdreg(HCLK, WriteData, HWDATA);
|
||||
flop #(XLEN/8) HWSTRBReg(HCLK, ByteMask, HWSTRB);
|
||||
end else begin
|
||||
assign HWDATA = '0;
|
||||
assign HWSTRB = '0;
|
||||
assign HWDATA = 0;
|
||||
assign HWSTRB = 0;
|
||||
end
|
||||
|
||||
busfsm #(~LSU) busfsm(.HCLK, .HRESETn, .Flush, .BusRW, .BusAtomic,
|
||||
|
@ -111,11 +111,11 @@ module ebu import cvw::*; #(parameter cvw_t P) (
|
||||
.HTRANSOut(LSUHTRANSOut), .HADDROut(LSUHADDROut), .HREADYIn(HREADY));
|
||||
|
||||
// output mux //*** switch to structural implementation
|
||||
assign HADDR = LSUSelect ? LSUHADDROut : IFUSelect ? IFUHADDROut : '0;
|
||||
assign HSIZE = LSUSelect ? LSUHSIZEOut : IFUSelect ? IFUHSIZEOut: '0;
|
||||
assign HBURST = LSUSelect ? LSUHBURSTOut : IFUSelect ? IFUHBURSTOut : '0; // If doing memory accesses, use LSUburst, else use Instruction burst.
|
||||
assign HTRANS = LSUSelect ? LSUHTRANSOut : IFUSelect ? IFUHTRANSOut: '0; // SEQ if not first read or write, NONSEQ if first read or write, IDLE otherwise
|
||||
assign HWRITE = LSUSelect ? LSUHWRITEOut : IFUSelect ? 1'b0 : '0;
|
||||
assign HADDR = LSUSelect ? LSUHADDROut : IFUSelect ? IFUHADDROut : 0;
|
||||
assign HSIZE = LSUSelect ? LSUHSIZEOut : IFUSelect ? IFUHSIZEOut: 0;
|
||||
assign HBURST = LSUSelect ? LSUHBURSTOut : IFUSelect ? IFUHBURSTOut : 0; // If doing memory accesses, use LSUburst, else use Instruction burst.
|
||||
assign HTRANS = LSUSelect ? LSUHTRANSOut : IFUSelect ? IFUHTRANSOut: 0; // SEQ if not first read or write, NONSEQ if first read or write, IDLE otherwise
|
||||
assign HWRITE = LSUSelect ? LSUHWRITEOut : 0;
|
||||
assign HPROT = 4'b0011; // not used; see Section 3.7
|
||||
assign HMASTLOCK = 0; // no locking supported
|
||||
|
||||
|
@ -37,7 +37,7 @@ module fdivsqrtfgen2 import cvw::*; #(parameter cvw_t P) (
|
||||
// Generate for both positive and negative quotient digits
|
||||
assign FP = ~(U << 1) & C;
|
||||
assign FN = (UM << 1) | (C & ~(C << 2));
|
||||
assign FZ = '0;
|
||||
assign FZ = 0;
|
||||
|
||||
always_comb // Choose which adder input will be used
|
||||
if (up) F = FP;
|
||||
|
@ -37,7 +37,7 @@ module fdivsqrtfgen4 import cvw::*; #(parameter cvw_t P) (
|
||||
// Generate for both positive and negative digits
|
||||
assign F2 = (~U << 2) & (C << 2); //
|
||||
assign F1 = ~(U << 1) & C;
|
||||
assign F0 = '0;
|
||||
assign F0 = 0;
|
||||
assign FN1 = (UM << 1) | (C & ~(C << 3));
|
||||
assign FN2 = (UM << 2) | ((C << 2) & ~(C << 4));
|
||||
|
||||
|
@ -81,7 +81,7 @@ module fdivsqrtiter import cvw::*; #(parameter cvw_t P) (
|
||||
|
||||
// C register/initialization mux: C = -R:
|
||||
// C = -4 = 00.000000... (in Q2.DIVb) for radix 4, C = -2 = 10.000000... for radix2
|
||||
if(P.RADIX == 4) assign initC = '0;
|
||||
if(P.RADIX == 4) assign initC = 0;
|
||||
else assign initC = {2'b10, {{P.DIVb{1'b0}}}};
|
||||
mux2 #(P.DIVb+2) cmux(C[P.DIVCOPIES], initC, IFDivStartE, NextC);
|
||||
flopen #(P.DIVb+2) creg(clk, FDivBusyE, NextC, C[0]);
|
||||
|
@ -121,7 +121,7 @@ module fdivsqrtpostproc import cvw::*; #(parameter cvw_t P) (
|
||||
else IntDivResultM = {(P.XLEN){1'b1}};
|
||||
end else if (ALTBM) begin // Numerator is small
|
||||
if (RemOpM) IntDivResultM = AM;
|
||||
else IntDivResultM = '0;
|
||||
else IntDivResultM = 0;
|
||||
end else IntDivResultM = PreIntResultM[P.XLEN-1:0];
|
||||
|
||||
// sign extend result for W64
|
||||
|
@ -58,7 +58,7 @@ module fdivsqrtstage2 import cvw::*; #(parameter cvw_t P) (
|
||||
// Divisor multiple
|
||||
always_comb
|
||||
if (up) Dsel = DBar;
|
||||
else if (uz) Dsel = '0;
|
||||
else if (uz) Dsel = 0;
|
||||
else Dsel = D; // un
|
||||
|
||||
// Residual Update
|
||||
|
@ -68,7 +68,7 @@ module fdivsqrtstage4 import cvw::*; #(parameter cvw_t P) (
|
||||
case (udigit)
|
||||
4'b1000: Dsel = DBar2;
|
||||
4'b0100: Dsel = DBar;
|
||||
4'b0000: Dsel = '0;
|
||||
4'b0000: Dsel = 0;
|
||||
4'b0010: Dsel = D;
|
||||
4'b0001: Dsel = D2;
|
||||
default: Dsel = 'x;
|
||||
|
@ -80,7 +80,7 @@ module fli import cvw::*; #(parameter cvw_t P) (
|
||||
endcase
|
||||
end
|
||||
assign HImmBox = {{(P.FLEN-16){1'b1}}, HImm}; // NaN-box HImm
|
||||
end else assign HImmBox = '0;
|
||||
end else assign HImmBox = 0;
|
||||
|
||||
////////////////////////////
|
||||
// single
|
||||
@ -168,7 +168,7 @@ module fli import cvw::*; #(parameter cvw_t P) (
|
||||
endcase
|
||||
end
|
||||
assign DImmBox = {{(P.FLEN-64){1'b1}}, DImm}; // NaN-box DImm
|
||||
end else assign DImmBox = '0;
|
||||
end else assign DImmBox = 0;
|
||||
|
||||
////////////////////////////
|
||||
// double
|
||||
@ -213,7 +213,7 @@ module fli import cvw::*; #(parameter cvw_t P) (
|
||||
endcase
|
||||
end
|
||||
assign QImmBox = QImm; // NaN-box QImm trivial because Q is longest format
|
||||
end else assign QImmBox = '0;
|
||||
end else assign QImmBox = 0;
|
||||
|
||||
mux4 #(P.FLEN) flimux(SImmBox, DImmBox, HImmBox, QImmBox, Fmt, Imm); // select immediate based on format
|
||||
|
||||
|
@ -51,9 +51,9 @@ module fmaadd import cvw::*; #(parameter cvw_t P) (
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Choose an inverted or non-inverted addend. Put carry into adder/LZA for addition
|
||||
assign AmInv = {3*P.NF+4{InvA}}^Am;
|
||||
assign AmInv = InvA ? ~Am : Am;
|
||||
// Kill the product if the product is too small to effect the addition (determined in fma1.sv)
|
||||
assign PmKilled = {2*P.NF+2{~KillProd}}&Pm;
|
||||
assign PmKilled = KillProd ? 0 : Pm;
|
||||
// Do the addition
|
||||
// - calculate a positive and negative sum in parallel
|
||||
// if there was a small negative number killed in the alignment stage one needs to be subtracted from the sum
|
||||
|
@ -37,6 +37,6 @@ module fmaexpadd import cvw::*; #(parameter cvw_t P) (
|
||||
|
||||
// kill the exponent if the product is zero - either X or Y is 0
|
||||
assign PZero = XZero | YZero;
|
||||
assign Pe = PZero ? '0 : ({2'b0, Xe} + {2'b0, Ye} - {2'b0, (P.NE)'(P.BIAS)});
|
||||
assign Pe = PZero ? 0 : ({2'b0, Xe} + {2'b0, Ye} - {2'b0, (P.NE)'(P.BIAS)});
|
||||
|
||||
endmodule
|
||||
|
@ -275,7 +275,7 @@ module fpu import cvw::*; #(parameter cvw_t P) (
|
||||
flopenrc #(5) Rs1EReg(clk, reset, FlushE, ~StallE, InstrD[19:15], Rs1E);
|
||||
flopenrc #(2) Fmt2EReg(clk, reset, FlushE, ~StallE, InstrD[26:25], Fmt2E);
|
||||
fli #(P) fli(.Rs1(Rs1E), .Fmt(Fmt2E), .Imm(FliResE));
|
||||
end else assign FliResE = '0;
|
||||
end else assign FliResE = 0;
|
||||
|
||||
// fmv.*.x: NaN Box SrcA to extend integer to requested FP size
|
||||
if(P.FPSIZES == 1)
|
||||
|
@ -65,7 +65,7 @@ module divshiftcalc import cvw::*; #(parameter cvw_t P) (
|
||||
|
||||
// if the shift amount is negative then don't shift (keep sticky bit)
|
||||
// need to multiply the early termination shift by LOGR*DIVCOPIES = left shift of log2(LOGR*DIVCOPIES)
|
||||
assign DivSubnormShiftAmt = DivSubnormShiftPos ? DivSubnormShift[P.LOGNORMSHIFTSZ-1:0] : '0;
|
||||
assign DivSubnormShiftAmt = DivSubnormShiftPos ? DivSubnormShift[P.LOGNORMSHIFTSZ-1:0] : 0;
|
||||
assign DivShiftAmt = DivResSubnorm ? DivSubnormShiftAmt : NormShift;
|
||||
|
||||
// pre-shift the divider result for normalization
|
||||
|
@ -60,7 +60,7 @@ module fmashiftcalc import cvw::*; #(parameter cvw_t P) (
|
||||
end else if (P.FPSIZES == 3) begin
|
||||
always_comb begin
|
||||
case (Fmt)
|
||||
P.FMT: BiasCorr = '0;
|
||||
P.FMT: BiasCorr = 0;
|
||||
P.FMT1: BiasCorr = (P.NE+2)'(P.BIAS1-P.BIAS);
|
||||
P.FMT2: BiasCorr = (P.NE+2)'(P.BIAS2-P.BIAS);
|
||||
default: BiasCorr = 'x;
|
||||
@ -70,7 +70,7 @@ module fmashiftcalc import cvw::*; #(parameter cvw_t P) (
|
||||
end else if (P.FPSIZES == 4) begin
|
||||
always_comb begin
|
||||
case (Fmt)
|
||||
2'h3: BiasCorr = '0;
|
||||
2'h3: BiasCorr = 0;
|
||||
2'h1: BiasCorr = (P.NE+2)'(P.D_BIAS-P.Q_BIAS);
|
||||
2'h0: BiasCorr = (P.NE+2)'(P.S_BIAS-P.Q_BIAS);
|
||||
2'h2: BiasCorr = (P.NE+2)'(P.H_BIAS-P.Q_BIAS);
|
||||
|
@ -303,9 +303,9 @@ module round import cvw::*; #(parameter cvw_t P) (
|
||||
case(PostProcSel)
|
||||
2'b10: Me = FmaMe; // fma
|
||||
2'b00: Me = {CvtCe[P.NE], CvtCe}&{P.NE+2{~CvtResSubnormUf|CvtResUf}}; // cvt
|
||||
// 2'b01: Me = DivDone ? Ue : '0; // divide
|
||||
// 2'b01: Me = DivDone ? Ue : 0; // divide
|
||||
2'b01: Me = Ue; // divide
|
||||
default: Me = '0;
|
||||
default: Me = 0;
|
||||
endcase
|
||||
|
||||
|
||||
|
@ -88,5 +88,5 @@ module shiftcorrection import cvw::*; #(parameter cvw_t P) (
|
||||
|
||||
// the quotent is in the range [.5,2) if there is no early termination
|
||||
// if the quotent < 1 and not Subnormal then subtract 1 to account for the normalization shift
|
||||
assign Ue = (DivResSubnorm & DivSubnormShiftPos) ? '0 : DivUe - {(P.NE+1)'(0), ~LZAPlus1};
|
||||
assign Ue = (DivResSubnorm & DivSubnormShiftPos) ? 0 : DivUe - {(P.NE+1)'(0), ~LZAPlus1};
|
||||
endmodule
|
||||
|
@ -339,7 +339,7 @@ module specialcase import cvw::*; #(parameter cvw_t P) (
|
||||
|
||||
if (P.ZFA_SUPPORTED & P.D_SUPPORTED) // fcvtmod.w.d support
|
||||
always_comb begin
|
||||
if (Zfa) OfIntRes2 = '0; // fcvtmod.w.d produces 0 on overflow
|
||||
if (Zfa) OfIntRes2 = 0; // fcvtmod.w.d produces 0 on overflow
|
||||
else OfIntRes2 = OfIntRes;
|
||||
if (Zfa) Int64Res = {{(P.XLEN-32){CvtNegRes[P.XLEN-1]}}, CvtNegRes[31:0]};
|
||||
else Int64Res = CvtNegRes[P.XLEN-1:0];
|
||||
|
@ -49,19 +49,19 @@ module ram1p1rwe import cvw::* ; #(parameter USE_SRAM=0, DEPTH=64, WIDTH=44) (
|
||||
// 64 x 128-bit SRAM
|
||||
ram1p1rwbe_64x128 sram1A (.CLK(clk), .CEB(~ce), .WEB(~we),
|
||||
.A(addr), .D(din),
|
||||
.BWEB('0), .Q(dout));
|
||||
.BWEB(0), .Q(dout));
|
||||
|
||||
end else if ((USE_SRAM == 1) & (WIDTH == 44) & (DEPTH == 64)) begin // RV64 cache tag
|
||||
// 64 x 44-bit SRAM
|
||||
ram1p1rwbe_64x44 sram1B (.CLK(clk), .CEB(~ce), .WEB(~we),
|
||||
.A(addr), .D(din),
|
||||
.BWEB('0), .Q(dout));
|
||||
.BWEB(0), .Q(dout));
|
||||
|
||||
end else if ((USE_SRAM == 1) & (WIDTH == 22) & (DEPTH == 64)) begin // RV32 cache tag
|
||||
// 64 x 22-bit SRAM
|
||||
ram1p1rwbe_64x22 sram1 (.CLK(clk), .CEB(~ce), .WEB(~we),
|
||||
.A(addr), .D(din),
|
||||
.BWEB('0), .Q(dout));
|
||||
.BWEB(0), .Q(dout));
|
||||
|
||||
// ***************************************************************************
|
||||
// READ first SRAM model
|
||||
|
@ -43,7 +43,7 @@ module ram2p1r1wbe import cvw::*; #(parameter USE_SRAM=0, DEPTH=1024, WIDTH=68)
|
||||
output logic [WIDTH-1:0] rd1
|
||||
);
|
||||
|
||||
logic [WIDTH-1:0] mem[DEPTH-1:0];
|
||||
bit [WIDTH-1:0] mem[DEPTH-1:0];
|
||||
localparam SRAMWIDTH = 32;
|
||||
localparam SRAMNUMSETS = SRAMWIDTH/WIDTH;
|
||||
|
||||
@ -55,11 +55,11 @@ module ram2p1r1wbe import cvw::*; #(parameter USE_SRAM=0, DEPTH=1024, WIDTH=68)
|
||||
|
||||
ram2p1r1wbe_1024x68 memory1(.CLKA(clk), .CLKB(clk),
|
||||
.CEBA(~ce1), .CEBB(~ce2),
|
||||
.WEBA('0), .WEBB(~we2),
|
||||
.WEBA(0), .WEBB(~we2),
|
||||
.AA(ra1), .AB(wa2),
|
||||
.DA('0),
|
||||
.DA(0),
|
||||
.DB(wd2),
|
||||
.BWEBA('0), .BWEBB('1),
|
||||
.BWEBA(0), .BWEBB('1),
|
||||
.QA(rd1),
|
||||
.QB());
|
||||
|
||||
@ -67,11 +67,11 @@ module ram2p1r1wbe import cvw::*; #(parameter USE_SRAM=0, DEPTH=1024, WIDTH=68)
|
||||
|
||||
ram2p1r1wbe_1024x36 memory1(.CLKA(clk), .CLKB(clk),
|
||||
.CEBA(~ce1), .CEBB(~ce2),
|
||||
.WEBA('0), .WEBB(~we2),
|
||||
.WEBA(0), .WEBB(~we2),
|
||||
.AA(ra1), .AB(wa2),
|
||||
.DA('0),
|
||||
.DA(0),
|
||||
.DB(wd2),
|
||||
.BWEBA('0), .BWEBB('1),
|
||||
.BWEBA(0), .BWEBB('1),
|
||||
.QA(rd1),
|
||||
.QB());
|
||||
|
||||
@ -95,12 +95,12 @@ module ram2p1r1wbe import cvw::*; #(parameter USE_SRAM=0, DEPTH=1024, WIDTH=68)
|
||||
assign rd1 = RD1Sets[RA1Q[$clog2(SRAMWIDTH)-1:0]];
|
||||
ram2p1r1wbe_64x32 memory2(.CLKA(clk), .CLKB(clk),
|
||||
.CEBA(~ce1), .CEBB(~ce2),
|
||||
.WEBA('0), .WEBB(~we2),
|
||||
.WEBA(0), .WEBB(~we2),
|
||||
.AA(ra1[$clog2(DEPTH)-1:$clog2(SRAMNUMSETS)]),
|
||||
.AB(wa2[$clog2(DEPTH)-1:$clog2(SRAMNUMSETS)]),
|
||||
.DA('0),
|
||||
.DA(0),
|
||||
.DB(SRAMWriteData),
|
||||
.BWEBA('0), .BWEBB(SRAMBitMask),
|
||||
.BWEBA(0), .BWEBB(SRAMBitMask),
|
||||
.QA(SRAMReadData),
|
||||
.QB());
|
||||
|
||||
@ -110,13 +110,14 @@ module ram2p1r1wbe import cvw::*; #(parameter USE_SRAM=0, DEPTH=1024, WIDTH=68)
|
||||
// READ first SRAM model
|
||||
// ***************************************************************************
|
||||
integer i;
|
||||
|
||||
/*
|
||||
initial begin // initialize memory for simulation only; not needed because done in the testbench now
|
||||
integer j;
|
||||
for (j=0; j < DEPTH; j++)
|
||||
mem[j] = '0;
|
||||
mem[j] = 0;
|
||||
end
|
||||
|
||||
*/
|
||||
|
||||
// Read
|
||||
logic [$clog2(DEPTH)-1:0] ra1d;
|
||||
flopen #($clog2(DEPTH)) adrreg(clk, ce1, ra1, ra1d);
|
||||
|
@ -34,7 +34,7 @@ module rom1p1r #(parameter ADDR_WIDTH = 8, DATA_WIDTH = 32, PRELOAD_ENABLED = 0)
|
||||
);
|
||||
|
||||
// Core Memory
|
||||
logic [DATA_WIDTH-1:0] ROM [(2**ADDR_WIDTH)-1:0];
|
||||
bit [DATA_WIDTH-1:0] ROM [(2**ADDR_WIDTH)-1:0];
|
||||
|
||||
// dh 10/30/23 ROM macros are presently commented out
|
||||
// because they don't point to a generated ROM
|
||||
@ -52,7 +52,7 @@ module rom1p1r #(parameter ADDR_WIDTH = 8, DATA_WIDTH = 32, PRELOAD_ENABLED = 0)
|
||||
end
|
||||
end
|
||||
|
||||
always @ (posedge clk) begin
|
||||
always_ff @ (posedge clk) begin
|
||||
if(ce) dout <= ROM[addr];
|
||||
end
|
||||
|
||||
|
@ -31,7 +31,7 @@ module onehotdecoder #(parameter WIDTH = 2) (
|
||||
);
|
||||
|
||||
always_comb begin
|
||||
decoded = '0;
|
||||
decoded = 0;
|
||||
decoded[bin] = 1'b1;
|
||||
end
|
||||
|
||||
|
@ -82,7 +82,7 @@ module hazard import cvw::*; #(parameter cvw_t P) (
|
||||
// The IFU and LSU stall the entire pipeline on a cache miss, bus access, or other long operation.
|
||||
// The IFU stalls the entire pipeline rather than just Fetch to avoid complications with instructions later in the pipeline causing Exceptions
|
||||
// A trap could be asserted at the start of a IFU/LSU stall, and should flush the memory operation
|
||||
assign StallFCause = '0;
|
||||
assign StallFCause = 0;
|
||||
assign StallDCause = (StructuralStallD | FPUStallD) & ~FlushDCause;
|
||||
assign StallECause = (DivBusyE | FDivBusyE) & ~FlushECause;
|
||||
assign StallMCause = WFIStallM & ~FlushMCause;
|
||||
|
@ -57,8 +57,8 @@ module cnt #(parameter WIDTH = 32) (
|
||||
lzc #(WIDTH) lzc(.num(lzcA), .ZeroCnt(czResult[$clog2(WIDTH):0]));
|
||||
popcnt #(WIDTH) popcntw(.num(popcntA), .PopCnt(cpopResult[$clog2(WIDTH):0]));
|
||||
// zero extend these results to fit into width
|
||||
assign czResult[WIDTH-1:$clog2(WIDTH)+1] = '0;
|
||||
assign cpopResult[WIDTH-1:$clog2(WIDTH)+1] = '0;
|
||||
assign czResult[WIDTH-1:$clog2(WIDTH)+1] = 0;
|
||||
assign cpopResult[WIDTH-1:$clog2(WIDTH)+1] = 0;
|
||||
|
||||
mux2 #(WIDTH) cntresultmux(czResult, cpopResult, B[1], CntResult);
|
||||
endmodule
|
||||
|
@ -224,7 +224,7 @@ module bpred import cvw::*; #(parameter cvw_t P) (
|
||||
assign BTAWrongM = BPBTAWrongM & PCSrcM;
|
||||
|
||||
end else begin
|
||||
assign {BTAWrongM, RASPredPCWrongM} = '0;
|
||||
assign {BTAWrongM, RASPredPCWrongM} = 0;
|
||||
end
|
||||
|
||||
// **** Fix me
|
||||
|
@ -65,7 +65,7 @@ module icpred import cvw::*; #(parameter cvw_t P,
|
||||
assign CJumpF = cjal | cj | cjr | cjalr;
|
||||
assign CBranchF = CompressedOpcF[4:1] == 4'h7;
|
||||
end else begin
|
||||
assign {cjal, cj, cjr, cjalr, CJumpF, CBranchF} = '0;
|
||||
assign {cjal, cj, cjr, cjalr, CJumpF, CBranchF} = 0;
|
||||
end
|
||||
|
||||
assign NCJumpF = PostSpillInstrRawF[6:0] == 7'h67 | PostSpillInstrRawF[6:0] == 7'h6F;
|
||||
|
@ -116,7 +116,7 @@ module localrepairbp import cvw::*; #(parameter cvw_t P,
|
||||
SpeculativeFlushedF <= #1 FlushedBits[IndexLHRNextF];
|
||||
if (reset | FlushD) FlushedBits <= #1 '1;
|
||||
if(BranchD & ~StallE & ~FlushE) begin
|
||||
FlushedBits[IndexLHRD] <= #1 '0;
|
||||
FlushedBits[IndexLHRD] <= #1 0;
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -194,10 +194,10 @@ module ifu import cvw::*; #(parameter cvw_t P) (
|
||||
.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW);
|
||||
|
||||
end else begin
|
||||
assign {ITLBMissF, InstrAccessFaultF, InstrPageFaultF, InstrUpdateDAF} = '0;
|
||||
assign {ITLBMissF, InstrAccessFaultF, InstrPageFaultF, InstrUpdateDAF} = 0;
|
||||
assign PCPF = PCFExt[P.PA_BITS-1:0];
|
||||
assign CacheableF = '1;
|
||||
assign SelIROM = '0;
|
||||
assign CacheableF = 1;
|
||||
assign SelIROM = 0;
|
||||
end
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -234,8 +234,8 @@ module ifu import cvw::*; #(parameter cvw_t P) (
|
||||
logic ICacheBusAck;
|
||||
logic [1:0] CacheBusRW, BusRW, CacheRWF;
|
||||
|
||||
assign BusRW = ~ITLBMissF & ~CacheableF & ~SelIROM ? IFURWF : '0;
|
||||
assign CacheRWF = ~ITLBMissF & CacheableF & ~SelIROM ? IFURWF : '0;
|
||||
assign BusRW = ~ITLBMissF & ~CacheableF & ~SelIROM ? IFURWF : 0;
|
||||
assign CacheRWF = ~ITLBMissF & CacheableF & ~SelIROM ? IFURWF : 0;
|
||||
// *** RT: PAdr and NextSet are replaced with mux between PCPF/IEUAdrM and PCSpillNextF/IEUAdrE.
|
||||
cache #(.P(P), .PA_BITS(P.PA_BITS), .XLEN(P.XLEN), .LINELEN(P.ICACHE_LINELENINBITS),
|
||||
.NUMLINES(P.ICACHE_WAYSIZEINBYTES*8/P.ICACHE_LINELENINBITS),
|
||||
@ -271,7 +271,7 @@ module ifu import cvw::*; #(parameter cvw_t P) (
|
||||
end else begin : passthrough
|
||||
assign IFUHADDR = PCPF;
|
||||
logic [1:0] BusRW;
|
||||
assign BusRW = ~ITLBMissF & ~SelIROM ? IFURWF : '0;
|
||||
assign BusRW = ~ITLBMissF & ~SelIROM ? IFURWF : 0;
|
||||
assign IFUHSIZE = 3'b010;
|
||||
|
||||
ahbinterface #(P.XLEN, 1'b0) ahbinterface(.HCLK(clk), .Flush(FlushD), .HRESETn(~reset), .HREADY(IFUHREADY),
|
||||
@ -279,15 +279,15 @@ module ifu import cvw::*; #(parameter cvw_t P) (
|
||||
.HWSTRB(), .BusRW, .BusAtomic('0), .ByteMask(), .WriteData('0),
|
||||
.Stall(GatedStallD), .BusStall, .BusCommitted(BusCommittedF), .FetchBuffer(FetchBuffer));
|
||||
|
||||
assign CacheCommittedF = '0;
|
||||
assign CacheCommittedF = 0;
|
||||
if(P.IROM_SUPPORTED) mux2 #(32) UnCachedDataMux2(ShiftUncachedInstr, IROMInstrF, SelIROM, InstrRawF);
|
||||
else assign InstrRawF = ShiftUncachedInstr;
|
||||
assign IFUHBURST = 3'b0;
|
||||
assign {ICacheMiss, ICacheAccess, ICacheStallF} = '0;
|
||||
assign {ICacheMiss, ICacheAccess, ICacheStallF} = 0;
|
||||
end
|
||||
end else begin : nobus // block: bus
|
||||
assign {BusStall, CacheCommittedF} = '0;
|
||||
assign {ICacheStallF, ICacheMiss, ICacheAccess} = '0;
|
||||
assign {BusStall, CacheCommittedF} = 0;
|
||||
assign {ICacheStallF, ICacheMiss, ICacheAccess} = 0;
|
||||
assign InstrRawF = IROMInstrF;
|
||||
end
|
||||
|
||||
@ -355,7 +355,7 @@ module ifu import cvw::*; #(parameter cvw_t P) (
|
||||
.BTBBranchF(1'b0), .BPCallF(), .BPReturnF(), .BPJumpF(), .BPBranchF(), .IClassWrongM,
|
||||
.IClassWrongE(), .BPReturnWrongD());
|
||||
flopenrc #(1) PCSrcMReg(clk, reset, FlushM, ~StallM, PCSrcE, BPWrongM);
|
||||
assign RASPredPCWrongM = '0;
|
||||
assign RASPredPCWrongM = 0;
|
||||
assign BPDirPredWrongM = BPWrongM;
|
||||
assign BTAWrongM = BPWrongM;
|
||||
assign InstrClassM = {CallM, ReturnM, JumpM, BranchM};
|
||||
|
@ -95,23 +95,23 @@ module align import cvw::*; #(parameter cvw_t P) (
|
||||
// compute misalignement
|
||||
always_comb begin
|
||||
case (Funct3M & {FpLoadStoreM, 2'b11})
|
||||
3'b000: AccessByteOffsetM = '0; // byte access
|
||||
3'b000: AccessByteOffsetM = 0; // byte access
|
||||
3'b001: AccessByteOffsetM = {{OFFSET_LEN-1{1'b0}}, IEUAdrM[0]}; // half access
|
||||
3'b010: AccessByteOffsetM = {{OFFSET_LEN-2{1'b0}}, IEUAdrM[1:0]}; // word access
|
||||
3'b011: AccessByteOffsetM = {{OFFSET_LEN-3{1'b0}}, IEUAdrM[2:0]}; // double access
|
||||
3'b100: if(P.LLEN == 128) AccessByteOffsetM = IEUAdrM[OFFSET_LEN-1:0]; // quad access
|
||||
else AccessByteOffsetM = '0; // invalid
|
||||
else AccessByteOffsetM = 0; // invalid
|
||||
default: AccessByteOffsetM = IEUAdrM[OFFSET_LEN-1:0];
|
||||
endcase
|
||||
case (Funct3M[1:0])
|
||||
2'b00: PotentialSpillM = '0; // byte access
|
||||
2'b00: PotentialSpillM = 0; // byte access
|
||||
2'b01: PotentialSpillM = IEUAdrM[OFFSET_BIT_POS-1:1] == '1; // half access
|
||||
2'b10: PotentialSpillM = IEUAdrM[OFFSET_BIT_POS-1:2] == '1; // word access
|
||||
2'b11: PotentialSpillM = IEUAdrM[OFFSET_BIT_POS-1:3] == '1; // double access
|
||||
default: PotentialSpillM = '0;
|
||||
default: PotentialSpillM = 0;
|
||||
endcase
|
||||
end
|
||||
assign MisalignedM = (|MemRWM) & (AccessByteOffsetM != '0);
|
||||
assign MisalignedM = (|MemRWM) & (AccessByteOffsetM != 0);
|
||||
|
||||
assign ValidSpillM = MisalignedM & PotentialSpillM & ~CacheBusHPWTStall; // Don't take the spill if there is a stall
|
||||
|
||||
@ -147,7 +147,7 @@ module align import cvw::*; #(parameter cvw_t P) (
|
||||
|
||||
// shifter (4:1 mux for 32 bit, 8:1 mux for 64 bit)
|
||||
// 8 * is for shifting by bytes not bits
|
||||
assign ShiftAmount = SelHPTW ? '0 : {AccessByteOffsetM, 3'b0}; // AND gate
|
||||
assign ShiftAmount = SelHPTW ? 0 : {AccessByteOffsetM, 3'b0}; // AND gate
|
||||
assign ReadDataWordSpillShiftedM = ReadDataWordSpillAllM >> ShiftAmount;
|
||||
assign DCacheReadDataWordSpillM = ReadDataWordSpillShiftedM[P.LLEN-1:0];
|
||||
|
||||
|
@ -173,17 +173,17 @@ module lsu import cvw::*; #(parameter cvw_t P) (
|
||||
end else begin : no_ziccslm_align
|
||||
assign IEUAdrExtM = {2'b00, IEUAdrM};
|
||||
assign IEUAdrExtE = {2'b00, IEUAdrE};
|
||||
assign SelSpillE = '0;
|
||||
assign SelSpillE = 0;
|
||||
assign DCacheReadDataWordSpillM = DCacheReadDataWordM;
|
||||
assign ByteMaskSpillM = ByteMaskM;
|
||||
assign LSUWriteDataSpillM = LSUWriteDataM;
|
||||
assign MemRWSpillM = MemRWM;
|
||||
assign {SpillStallM} = '0;
|
||||
assign {SpillStallM} = 0;
|
||||
end
|
||||
|
||||
if(P.ZICBOZ_SUPPORTED) begin : cboz
|
||||
mux2 #(P.XLEN) writedatacbozmux(WriteDataM, '0, CMOpM[3], WriteDataZM);
|
||||
end else begin : cboz
|
||||
assign WriteDataZM = CMOpM[3] ? 0 : WriteDataM;
|
||||
end else begin : cboz
|
||||
assign WriteDataZM = WriteDataM;
|
||||
end
|
||||
|
||||
@ -216,8 +216,8 @@ module lsu import cvw::*; #(parameter cvw_t P) (
|
||||
assign StoreAmoAccessFaultM = LSUStoreAmoAccessFaultM;
|
||||
assign LoadPageFaultM = LSULoadPageFaultM;
|
||||
assign StoreAmoPageFaultM = LSUStoreAmoPageFaultM;
|
||||
assign {HPTWStall, SelHPTW, PTE, PageType, DTLBWriteM, ITLBWriteF, IgnoreRequestTLB} = '0;
|
||||
assign {HPTWInstrAccessFaultF, HPTWInstrPageFaultF} = '0;
|
||||
assign {HPTWStall, SelHPTW, PTE, PageType, DTLBWriteM, ITLBWriteF, IgnoreRequestTLB} = 0;
|
||||
assign {HPTWInstrAccessFaultF, HPTWInstrPageFaultF} = 0;
|
||||
end
|
||||
|
||||
// CommittedM indicates the cache, bus, or HPTW are busy with a multiple cycle operation.
|
||||
@ -253,8 +253,8 @@ module lsu import cvw::*; #(parameter cvw_t P) (
|
||||
.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW);
|
||||
|
||||
end else begin // No MMU, so no PMA/page faults and no address translation
|
||||
assign {DTLBMissM, LSULoadAccessFaultM, LSUStoreAmoAccessFaultM, LoadMisalignedFaultM, StoreAmoMisalignedFaultM} = '0;
|
||||
assign {LSULoadPageFaultM, LSUStoreAmoPageFaultM} = '0;
|
||||
assign {DTLBMissM, LSULoadAccessFaultM, LSUStoreAmoAccessFaultM, LoadMisalignedFaultM, StoreAmoMisalignedFaultM} = 0;
|
||||
assign {LSULoadPageFaultM, LSUStoreAmoPageFaultM} = 0;
|
||||
assign PAdrM = IHAdrM[P.PA_BITS-1:0];
|
||||
assign CacheableM = 1'b1;
|
||||
assign SelDTIM = P.DTIM_SUPPORTED & ~P.BUS_SUPPORTED; // if no PMA then select dtim if there is a DTIM. If there is
|
||||
@ -279,7 +279,7 @@ module lsu import cvw::*; #(parameter cvw_t P) (
|
||||
|
||||
// The DTIM uses untranslated addresses, so it is not compatible with virtual memory.
|
||||
mux2 #(P.PA_BITS) DTIMAdrMux(IEUAdrExtE[P.PA_BITS-1:0], IEUAdrExtM[P.PA_BITS-1:0], MemRWM[0], DTIMAdr);
|
||||
assign DTIMMemRWM = SelDTIM & ~IgnoreRequestTLB ? LSURWM : '0;
|
||||
assign DTIMMemRWM = SelDTIM & ~IgnoreRequestTLB ? LSURWM : 0;
|
||||
// **** fix ReadDataWordM to be LLEN. ByteMask is wrong length.
|
||||
// **** create config to support DTIM with floating point.
|
||||
// Add support for cboz
|
||||
@ -316,16 +316,16 @@ module lsu import cvw::*; #(parameter cvw_t P) (
|
||||
|
||||
if(P.ZICBOZ_SUPPORTED) begin
|
||||
assign BusCMOZero = CMOpM[3] & ~CacheableM;
|
||||
assign CacheCMOpM = (CacheableM & ~SelHPTW) ? CMOpM : '0;
|
||||
assign CacheCMOpM = (CacheableM & ~SelHPTW) ? CMOpM : 0;
|
||||
assign BusAtomic = AtomicM[1] & ~CacheableM;
|
||||
end else begin
|
||||
assign BusCMOZero = '0;
|
||||
assign CacheCMOpM = '0;
|
||||
assign BusAtomic = '0;
|
||||
assign BusCMOZero = 0;
|
||||
assign CacheCMOpM = 0;
|
||||
assign BusAtomic = 0;
|
||||
end
|
||||
assign BusRW = ~CacheableM & ~SelDTIM ? LSURWM : '0;
|
||||
assign BusRW = (~CacheableM & ~SelDTIM )? LSURWM : 0;
|
||||
assign CacheableOrFlushCacheM = CacheableM | FlushDCacheM;
|
||||
assign CacheRWM = CacheableM & ~SelDTIM ? LSURWM : '0;
|
||||
assign CacheRWM = (CacheableM & ~SelDTIM) ? LSURWM : 0;
|
||||
assign FlushDCache = FlushDCacheM & ~(SelHPTW);
|
||||
|
||||
cache #(.P(P), .PA_BITS(P.PA_BITS), .XLEN(P.XLEN), .LINELEN(P.DCACHE_LINELENINBITS), .NUMLINES(P.DCACHE_WAYSIZEINBYTES*8/LINELEN),
|
||||
@ -365,7 +365,7 @@ module lsu import cvw::*; #(parameter cvw_t P) (
|
||||
end else begin : passthrough // No Cache, use simple ahbinterface instad of ahbcacheinterface
|
||||
logic [1:0] BusRW; // Non-DTIM memory access, ignore cacheableM
|
||||
logic [P.XLEN-1:0] FetchBuffer;
|
||||
assign BusRW = ~IgnoreRequestTLB & ~SelDTIM ? LSURWM : '0;
|
||||
assign BusRW = (~IgnoreRequestTLB & ~SelDTIM) ? LSURWM : 0;
|
||||
|
||||
assign LSUHADDR = PAdrM;
|
||||
assign LSUHSIZE = LSUFunct3M;
|
||||
@ -379,14 +379,14 @@ module lsu import cvw::*; #(parameter cvw_t P) (
|
||||
if(P.DTIM_SUPPORTED) mux2 #(P.XLEN) ReadDataMux2(FetchBuffer, DTIMReadDataWordM[P.XLEN-1:0], SelDTIM, ReadDataWordMuxM[P.XLEN-1:0]);
|
||||
else assign ReadDataWordMuxM[P.XLEN-1:0] = FetchBuffer[P.XLEN-1:0]; // *** bus only does not support double wide floats.
|
||||
assign LSUHBURST = 3'b0;
|
||||
assign {DCacheStallM, DCacheCommittedM, DCacheMiss, DCacheAccess} = '0;
|
||||
assign {DCacheStallM, DCacheCommittedM, DCacheMiss, DCacheAccess} = 0;
|
||||
end
|
||||
end else begin: nobus // block: bus, only DTIM
|
||||
assign LSUHWDATA = '0;
|
||||
assign LSUHWDATA = 0;
|
||||
assign ReadDataWordMuxM = DTIMReadDataWordM;
|
||||
assign {BusStall, BusCommittedM} = '0;
|
||||
assign {DCacheMiss, DCacheAccess} = '0;
|
||||
assign {DCacheStallM, DCacheCommittedM} = '0;
|
||||
assign {BusStall, BusCommittedM} = 0;
|
||||
assign {DCacheMiss, DCacheAccess} = 0;
|
||||
assign {DCacheStallM, DCacheCommittedM} = 0;
|
||||
end
|
||||
|
||||
assign LSUBusStallM = BusStall & ~IgnoreRequestTLB;
|
||||
@ -415,7 +415,7 @@ module lsu import cvw::*; #(parameter cvw_t P) (
|
||||
// Subword Accesses
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
subwordread #(P.LLEN) subwordread(.ReadDataWordMuxM(LittleEndianReadDataWordM), .PAdrM(PAdrM[2:0]), .BigEndianM,
|
||||
subwordread #(P) subwordread(.ReadDataWordMuxM(LittleEndianReadDataWordM), .PAdrM(PAdrM[3:0]), .BigEndianM,
|
||||
.FpLoadStoreM, .Funct3M(LSUFunct3M), .ReadDataM);
|
||||
subwordwrite #(P.LLEN) subwordwrite(.LSUFunct3M, .IMAFWriteDataM, .LittleEndianWriteDataM);
|
||||
|
||||
|
@ -28,98 +28,47 @@
|
||||
// and limitations under the License.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module subwordread #(parameter LLEN)
|
||||
(
|
||||
input logic [LLEN-1:0] ReadDataWordMuxM,
|
||||
input logic [2:0] PAdrM,
|
||||
input logic [2:0] Funct3M,
|
||||
input logic FpLoadStoreM,
|
||||
input logic BigEndianM,
|
||||
output logic [LLEN-1:0] ReadDataM
|
||||
module subwordread import cvw::*; #(parameter cvw_t P) (
|
||||
input logic [P.LLEN-1:0] ReadDataWordMuxM,
|
||||
input logic [3:0] PAdrM,
|
||||
input logic [2:0] Funct3M,
|
||||
input logic FpLoadStoreM,
|
||||
input logic BigEndianM,
|
||||
output logic [P.LLEN-1:0] ReadDataM
|
||||
);
|
||||
|
||||
localparam ADRBITS = $clog2(P.LLEN)-3;
|
||||
|
||||
logic [ADRBITS-1:0] PAdrSwapM;
|
||||
logic [7:0] ByteM;
|
||||
logic [15:0] HalfwordM;
|
||||
logic [2:0] PAdrSwap;
|
||||
// Funct3M[2] is the unsigned bit. mask upper bits.
|
||||
// Funct3M[1:0] is the size of the memory access.
|
||||
assign PAdrSwap = PAdrM ^ {3{BigEndianM}};
|
||||
logic [31:0] WordM;
|
||||
logic [63:0] DblWordM;
|
||||
|
||||
if (LLEN == 64) begin:swrmux
|
||||
// ByteMe mux
|
||||
always_comb
|
||||
case(PAdrSwap[2:0])
|
||||
3'b000: ByteM = ReadDataWordMuxM[7:0];
|
||||
3'b001: ByteM = ReadDataWordMuxM[15:8];
|
||||
3'b010: ByteM = ReadDataWordMuxM[23:16];
|
||||
3'b011: ByteM = ReadDataWordMuxM[31:24];
|
||||
3'b100: ByteM = ReadDataWordMuxM[39:32];
|
||||
3'b101: ByteM = ReadDataWordMuxM[47:40];
|
||||
3'b110: ByteM = ReadDataWordMuxM[55:48];
|
||||
3'b111: ByteM = ReadDataWordMuxM[63:56];
|
||||
endcase
|
||||
|
||||
// halfword mux
|
||||
always_comb
|
||||
case(PAdrSwap[2:1])
|
||||
2'b00: HalfwordM = ReadDataWordMuxM[15:0];
|
||||
2'b01: HalfwordM = ReadDataWordMuxM[31:16];
|
||||
2'b10: HalfwordM = ReadDataWordMuxM[47:32];
|
||||
2'b11: HalfwordM = ReadDataWordMuxM[63:48];
|
||||
endcase
|
||||
|
||||
logic [31:0] WordM;
|
||||
|
||||
always_comb
|
||||
case(PAdrSwap[2])
|
||||
1'b0: WordM = ReadDataWordMuxM[31:0];
|
||||
1'b1: WordM = ReadDataWordMuxM[63:32];
|
||||
endcase
|
||||
// invert lsbs of address to select appropriate subword for big endian
|
||||
if (P.BIGENDIAN_SUPPORTED) assign PAdrSwapM = PAdrM[ADRBITS-1:0] ^ {ADRBITS{BigEndianM}};
|
||||
else assign PAdrSwapM = PAdrM[ADRBITS-1:0];
|
||||
|
||||
logic [63:0] DblWordM;
|
||||
assign DblWordM = ReadDataWordMuxM[63:0];
|
||||
// Use indexed part select to imply muxes to select each size of subword
|
||||
if (P.LLEN == 128) mux2 #(64) dblmux(ReadDataWordMuxM[63:0], ReadDataWordMuxM[127:64], PAdrSwapM[3], DblWordM);
|
||||
else if (P.LLEN == 64) assign DblWordM = ReadDataWordMuxM;
|
||||
if (P.LLEN >= 64) mux2 #(32) wordmux(DblWordM[31:0], DblWordM[63:32], PAdrSwapM[2], WordM);
|
||||
else assign WordM = ReadDataWordMuxM;
|
||||
mux2 #(16) halfwordmux(WordM[15:0], WordM[31:16], PAdrSwapM[1], HalfwordM);
|
||||
mux2 #(8) bytemux(HalfwordM[7:0], HalfwordM[15:8], PAdrSwapM[0], ByteM);
|
||||
|
||||
// sign extension/ NaN boxing
|
||||
always_comb
|
||||
// sign extension/ NaN boxing
|
||||
always_comb
|
||||
case(Funct3M)
|
||||
3'b000: ReadDataM = {{LLEN-8{ByteM[7]}}, ByteM}; // lb
|
||||
3'b001: ReadDataM = {{LLEN-16{HalfwordM[15]|FpLoadStoreM}}, HalfwordM[15:0]}; // lh/flh
|
||||
3'b010: ReadDataM = {{LLEN-32{WordM[31]|FpLoadStoreM}}, WordM[31:0]}; // lw/flw
|
||||
3'b011: ReadDataM = {{LLEN-64{DblWordM[63]|FpLoadStoreM}}, DblWordM[63:0]}; // ld/fld
|
||||
3'b100: ReadDataM = {{LLEN-8{1'b0}}, ByteM[7:0]}; // lbu
|
||||
//3'b100: ReadDataM = FpLoadStoreM ? ReadDataWordMuxM : {{LLEN-8{1'b0}}, ByteM[7:0]}; // lbu/flq - only needed when LLEN=128
|
||||
3'b101: ReadDataM = {{LLEN-16{1'b0}}, HalfwordM[15:0]}; // lhu
|
||||
3'b110: ReadDataM = {{LLEN-32{1'b0}}, WordM[31:0]}; // lwu
|
||||
default: ReadDataM = ReadDataWordMuxM; // Shouldn't happen
|
||||
3'b000: ReadDataM = {{(P.LLEN-8){ByteM[7]}}, ByteM}; // lb
|
||||
3'b001: ReadDataM = {{P.LLEN-16{HalfwordM[15]|FpLoadStoreM}}, HalfwordM[15:0]}; // lh/flh
|
||||
3'b010: ReadDataM = {{P.LLEN-32{WordM[31]|FpLoadStoreM}}, WordM[31:0]}; // lw/flw
|
||||
3'b011: if (P.LLEN >= 64) ReadDataM = {{P.LLEN-64{DblWordM[63]|FpLoadStoreM}}, DblWordM[63:0]}; // ld/fld
|
||||
else ReadDataM = ReadDataWordMuxM; // shouldn't happen
|
||||
3'b100: if (P.LLEN == 128) ReadDataM = FpLoadStoreM ? ReadDataWordMuxM : {{P.LLEN-8{1'b0}}, ByteM[7:0]}; // lbu/flq
|
||||
else ReadDataM = {{P.LLEN-8{1'b0}}, ByteM[7:0]}; // lbu
|
||||
3'b101: ReadDataM = {{P.LLEN-16{1'b0}}, HalfwordM[15:0]}; // lhu
|
||||
3'b110: ReadDataM = {{P.LLEN-32{1'b0}}, WordM[31:0]}; // lwu
|
||||
default: ReadDataM = ReadDataWordMuxM; // Shouldn't happen
|
||||
endcase
|
||||
|
||||
end else begin:swrmux // 32-bit
|
||||
// byte mux
|
||||
always_comb
|
||||
case(PAdrSwap[1:0])
|
||||
2'b00: ByteM = ReadDataWordMuxM[7:0];
|
||||
2'b01: ByteM = ReadDataWordMuxM[15:8];
|
||||
2'b10: ByteM = ReadDataWordMuxM[23:16];
|
||||
2'b11: ByteM = ReadDataWordMuxM[31:24];
|
||||
endcase
|
||||
|
||||
// halfword mux
|
||||
always_comb
|
||||
case(PAdrSwap[1])
|
||||
1'b0: HalfwordM = ReadDataWordMuxM[15:0];
|
||||
1'b1: HalfwordM = ReadDataWordMuxM[31:16];
|
||||
endcase
|
||||
|
||||
// sign extension
|
||||
always_comb
|
||||
case(Funct3M)
|
||||
3'b000: ReadDataM = {{LLEN-8{ByteM[7]}}, ByteM}; // lb
|
||||
3'b001: ReadDataM = {{LLEN-16{HalfwordM[15]|FpLoadStoreM}}, HalfwordM[15:0]}; // lh/flh
|
||||
3'b010: ReadDataM = {{LLEN-32{ReadDataWordMuxM[31]|FpLoadStoreM}}, ReadDataWordMuxM[31:0]}; // lw/flw
|
||||
3'b011: ReadDataM = ReadDataWordMuxM; // fld
|
||||
3'b100: ReadDataM = {{LLEN-8{1'b0}}, ByteM[7:0]}; // lbu
|
||||
3'b101: ReadDataM = {{LLEN-16{1'b0}}, HalfwordM[15:0]}; // lhu
|
||||
default: ReadDataM = ReadDataWordMuxM; // Shouldn't happen
|
||||
endcase
|
||||
end
|
||||
endmodule
|
||||
|
@ -55,9 +55,9 @@ module subwordwrite #(parameter LLEN) (
|
||||
end else begin:sww // 32-bit
|
||||
always_comb
|
||||
case(LSUFunct3M[1:0])
|
||||
2'b00: LittleEndianWriteDataM = {4{IMAFWriteDataM[7:0]}}; // sb
|
||||
2'b01: LittleEndianWriteDataM = {2{IMAFWriteDataM[15:0]}}; // sh
|
||||
2'b10: LittleEndianWriteDataM = IMAFWriteDataM; // sw
|
||||
2'b00: LittleEndianWriteDataM = {4{IMAFWriteDataM[7:0]}}; // sb
|
||||
2'b01: LittleEndianWriteDataM = {2{IMAFWriteDataM[15:0]}}; // sh
|
||||
2'b10: LittleEndianWriteDataM = IMAFWriteDataM; // sw
|
||||
default: LittleEndianWriteDataM = IMAFWriteDataM; // shouldn't happen
|
||||
endcase
|
||||
end
|
||||
|
@ -42,7 +42,7 @@ module swbytemask #(parameter WORDLEN, EXTEND = 0)(
|
||||
assign ByteMaskExtended = ExtendedByteMask[WORDLEN*2/8-1:WORDLEN/8];
|
||||
end else begin
|
||||
assign ByteMask = (('d2**('d2**Size))-'d1) << Adr;
|
||||
assign ByteMaskExtended = '0;
|
||||
assign ByteMaskExtended = 0;
|
||||
end
|
||||
|
||||
/* Equivalent to the following
|
||||
|
@ -148,7 +148,6 @@ module hptw import cvw::*; #(parameter cvw_t P) (
|
||||
flopenr #(1) TLBMissMReg(clk, reset, StartWalk, DTLBMissOrUpdateDAM, DTLBWalk); // when walk begins, record whether it was for DTLB (or record 0 for ITLB)
|
||||
assign PRegEn = HPTWRW[1] & ~DCacheBusStallM | UpdatePTE;
|
||||
flopenr #(P.XLEN) PTEReg(clk, reset, PRegEn, NextPTE, PTE); // Capture page table entry from data cache
|
||||
assert property(@(posedge clk) ~PRegEn | reset | NextPTE[0] !== 1'bx); // report writing an x PTE from an uninitialized page table
|
||||
|
||||
// Assign PTE descriptors common across all XLEN values
|
||||
// For non-leaf PTEs, D, A, U bits are reserved and ignored. They do not cause faults while walking the page table
|
||||
@ -174,7 +173,7 @@ module hptw import cvw::*; #(parameter cvw_t P) (
|
||||
logic [P.XLEN-1:0] AccessedPTE;
|
||||
|
||||
assign AccessedPTE = {PTE[P.XLEN-1:8], (SetDirty | PTE[7]), 1'b1, PTE[5:0]}; // set accessed bit, conditionally set dirty bit
|
||||
//assign ReadDataNoXM = (ReadDataM[0] === 'x) ? '0 : ReadDataM; // If the PTE.V bit is x because it was read from uninitialized memory set to 0 to avoid x propagation and hanging the simulation.
|
||||
//assign ReadDataNoXM = (ReadDataM[0] === 'x) ? 0 : ReadDataM; // If the PTE.V bit is x because it was read from uninitialized memory set to 0 to avoid x propagation and hanging the simulation.
|
||||
assign ReadDataNoXM = ReadDataM; // *** temporary fix for synthesis; === and x in line above are not synthesizable.
|
||||
mux2 #(P.XLEN) NextPTEMux(ReadDataNoXM, AccessedPTE, UpdatePTE, NextPTE); // NextPTE = ReadDataNoXM when ADUE = 0 because UpdatePTE = 0
|
||||
flopenr #(P.PA_BITS) HPTWAdrWriteReg(clk, reset, SaveHPTWAdr, HPTWReadAdr, HPTWWriteAdr);
|
||||
@ -214,9 +213,9 @@ module hptw import cvw::*; #(parameter cvw_t P) (
|
||||
end else begin // block: hptwwrites
|
||||
assign NextPTE = ReadDataNoXM;
|
||||
assign HPTWAdr = HPTWReadAdr;
|
||||
assign HPTWUpdateDA = '0;
|
||||
assign UpdatePTE = '0;
|
||||
assign HPTWRW[0] = '0;
|
||||
assign HPTWUpdateDA = 0;
|
||||
assign UpdatePTE = 0;
|
||||
assign HPTWRW[0] = 0;
|
||||
end
|
||||
|
||||
// Enable and select signals based on states
|
||||
|
@ -98,6 +98,6 @@ module tlbmixer import cvw::*; #(parameter cvw_t P) (
|
||||
|
||||
// Output the hit physical address if translation is currently on.
|
||||
// Provide physical address of zero if not TLBHits, to cause segmentation error if miss somehow percolated through signal
|
||||
mux2 #(P.PA_BITS) hitmux('0, {PPNMixed2, Offset}, TLBHit, TLBPAdr); // set PA to 0 if TLB misses, to cause segementation error if this miss somehow passes through system
|
||||
assign TLBPAdr = TLBHit ? {PPNMixed2, Offset} : 0;
|
||||
|
||||
endmodule
|
||||
|
@ -74,11 +74,11 @@ module csri import cvw::*; #(parameter cvw_t P) (
|
||||
assign SIP_WRITE_MASK = 12'h000;
|
||||
assign MIE_WRITE_MASK = 12'h888;
|
||||
end
|
||||
always @(posedge clk)
|
||||
always_ff @(posedge clk)
|
||||
if (reset) MIP_REGW_writeable <= 12'b0;
|
||||
else if (WriteMIPM) MIP_REGW_writeable <= (CSRWriteValM[11:0] & MIP_WRITE_MASK);
|
||||
else if (WriteSIPM) MIP_REGW_writeable <= (CSRWriteValM[11:0] & SIP_WRITE_MASK) | (MIP_REGW_writeable & ~SIP_WRITE_MASK);
|
||||
always @(posedge clk)
|
||||
always_ff @(posedge clk)
|
||||
if (reset) MIE_REGW <= 12'b0;
|
||||
else if (WriteMIEM) MIE_REGW <= (CSRWriteValM[11:0] & MIE_WRITE_MASK); // MIE controls M and S fields
|
||||
else if (WriteSIEM) MIE_REGW <= (CSRWriteValM[11:0] & 12'h222 & MIDELEG_REGW) | (MIE_REGW & 12'h888); // only S fields
|
||||
|
@ -163,7 +163,7 @@ module csrm import cvw::*; #(parameter cvw_t P) (
|
||||
flopenr #(32) MCOUNTINHIBITreg(clk, reset, WriteMCOUNTINHIBITM, CSRWriteValM[31:0], MCOUNTINHIBIT_REGW);
|
||||
if (P.U_SUPPORTED) begin: mcounteren // MCOUNTEREN only exists when user mode is supported
|
||||
flopenr #(32) MCOUNTERENreg(clk, reset, WriteMCOUNTERENM, CSRWriteValM[31:0], MCOUNTEREN_REGW);
|
||||
end else assign MCOUNTEREN_REGW = '0;
|
||||
end else assign MCOUNTEREN_REGW = 0;
|
||||
|
||||
// MENVCFG register
|
||||
if (P.U_SUPPORTED) begin // menvcfg only exists if there is a lower privilege to control
|
||||
@ -199,7 +199,7 @@ module csrm import cvw::*; #(parameter cvw_t P) (
|
||||
// verilator lint_off WIDTH
|
||||
logic [5:0] entry;
|
||||
always_comb begin
|
||||
entry = '0;
|
||||
entry = 0;
|
||||
CSRMReadValM = 0;
|
||||
IllegalCSRMAccessM = !(P.S_SUPPORTED) & (CSRAdrM == MEDELEG | CSRAdrM == MIDELEG); // trap on DELEG register access when no S or N-mode
|
||||
if (CSRAdrM >= PMPADDR0 & CSRAdrM < PMPADDR0 + P.PMP_ENTRIES) // reading a PMP entry
|
||||
|
@ -66,7 +66,7 @@ module csrsr import cvw::*; #(parameter cvw_t P) (
|
||||
STATUS_XS, STATUS_FS, /*STATUS_MPP, 2'b0*/ 4'b0,
|
||||
STATUS_SPP, /*STATUS_MPIE*/ 1'b0, STATUS_UBE, STATUS_SPIE,
|
||||
/*1'b0, STATUS_MIE, 1'b0*/ 3'b0, STATUS_SIE, 1'b0};
|
||||
assign MSTATUSH_REGW = '0; // *** does not exist when XLEN=64, but don't want it to have an undefined value. Spec is not clear what it should be.
|
||||
assign MSTATUSH_REGW = 0; // *** does not exist when XLEN=64, but don't want it to have an undefined value. Spec is not clear what it should be.
|
||||
end else begin: csrsr32 // RV32
|
||||
assign MSTATUS_REGW = {STATUS_SD, 8'b0,
|
||||
STATUS_TSR, STATUS_TW, STATUS_TVM, STATUS_MXR, STATUS_SUM, STATUS_MPRV,
|
||||
|
@ -65,8 +65,8 @@ module trap import cvw::*; #(parameter cvw_t P) (
|
||||
assign PendingIntsM = MIP_REGW & MIE_REGW;
|
||||
assign IntPendingM = |PendingIntsM;
|
||||
assign Committed = CommittedM | CommittedF;
|
||||
assign EnabledIntsM = ({12{MIntGlobalEnM}} & PendingIntsM & ~MIDELEG_REGW | {12{SIntGlobalEnM}} & PendingIntsM & MIDELEG_REGW);
|
||||
assign ValidIntsM = {12{~Committed}} & EnabledIntsM;
|
||||
assign EnabledIntsM = (MIntGlobalEnM ? PendingIntsM & ~MIDELEG_REGW : 0) | (SIntGlobalEnM ? PendingIntsM & MIDELEG_REGW : 0);
|
||||
assign ValidIntsM = Committed ? 0 : EnabledIntsM;
|
||||
assign InterruptM = (|ValidIntsM) & InstrValidM & (~wfiM | wfiW); // suppress interrupt if the memory system has partially processed a request. Delay interrupt until wfi is in the W stage.
|
||||
// wfiW is to support possible but unlikely back to back wfi instructions. wfiM would be high in the M stage, while also in the W stage.
|
||||
assign DelegateM = P.S_SUPPORTED & (InterruptM ? MIDELEG_REGW[CauseM] : MEDELEG_REGW[CauseM]) &
|
||||
|
@ -63,7 +63,7 @@ module clint_apb import cvw::*; #(parameter cvw_t P) (
|
||||
|
||||
// register access
|
||||
if (P.XLEN==64) begin:clint // 64-bit
|
||||
always @(posedge PCLK) begin
|
||||
always_ff @(posedge PCLK) begin
|
||||
case(entry)
|
||||
16'h0000: PRDATA <= {63'b0, MSIP};
|
||||
16'h4000: PRDATA <= MTIMECMP;
|
||||
@ -97,7 +97,7 @@ module clint_apb import cvw::*; #(parameter cvw_t P) (
|
||||
MTIME[j*8 +: 8] <= PWDATA[j*8 +: 8];
|
||||
end else MTIME <= MTIME + 1;
|
||||
end else begin:clint // 32-bit
|
||||
always @(posedge PCLK) begin
|
||||
always_ff @(posedge PCLK) begin
|
||||
case(entry)
|
||||
16'h0000: PRDATA <= {31'b0, MSIP};
|
||||
16'h4000: PRDATA <= MTIMECMP[31:0];
|
||||
|
@ -91,7 +91,7 @@ module plic_apb import cvw::*; #(parameter cvw_t P) (
|
||||
assign memread = ~PWRITE & PSEL; // read at start of access phase. PENABLE hasn't set up before this
|
||||
assign PREADY = 1'b1; // PLIC never takes >1 cycle to respond
|
||||
assign entry = {PADDR[23:2],2'b0};
|
||||
assign One[P.PLIC_NUM_SRC-1:1] = '0; assign One[0] = 1'b1; // Vivado does not like this as a single assignment.
|
||||
assign One[P.PLIC_NUM_SRC-1:1] = 0; assign One[0] = 1'b1; // Vivado does not like this as a single assignment.
|
||||
|
||||
// account for subword read/write circuitry
|
||||
// -- Note PLIC registers are 32 bits no matter what; access them with LW SW.
|
||||
@ -104,13 +104,13 @@ module plic_apb import cvw::*; #(parameter cvw_t P) (
|
||||
// ==================
|
||||
localparam PLIC_NUM_SRC_MIN_32 = P.PLIC_NUM_SRC < 32 ? P.PLIC_NUM_SRC : 31;
|
||||
|
||||
always @(posedge PCLK) begin
|
||||
always_ff @(posedge PCLK) begin
|
||||
// resetting
|
||||
if (~PRESETn) begin
|
||||
intPriority <= #1 '0;
|
||||
intEn <= #1 '0;
|
||||
intThreshold <= #1 '0;
|
||||
intInProgress <= #1 '0;
|
||||
intPriority <= #1 0;
|
||||
intEn <= #1 0;
|
||||
intThreshold <= #1 0;
|
||||
intInProgress <= #1 0;
|
||||
// writing
|
||||
end else begin
|
||||
if (memwrite)
|
||||
|
@ -520,7 +520,7 @@ module uartPC16550D #(parameter UART_PRESCALE) (
|
||||
intrpending = 0;
|
||||
end
|
||||
end
|
||||
always @(posedge PCLK) INTR <= #1 intrpending; // prevent glitches on interrupt pin
|
||||
always_ff @(posedge PCLK) INTR <= #1 intrpending; // prevent glitches on interrupt pin
|
||||
|
||||
// Side effect of reading LSR is lowering overrun, parity, framing, break intr's
|
||||
assign setSquashRXerrIP = ~MEMRb & (A==3'b101);
|
||||
|
@ -136,7 +136,7 @@ module FunctionName import cvw::*; #(parameter cvw_t P) (
|
||||
ProgramAddrMapFP = $fopen(ProgramAddrMapFile, "r");
|
||||
|
||||
// read line by line to count lines
|
||||
if (ProgramAddrMapFP != '0) begin
|
||||
if (ProgramAddrMapFP != 0) begin
|
||||
while (! $feof(ProgramAddrMapFP)) begin
|
||||
status = $fscanf(ProgramAddrMapFP, "%h\n", ProgramAddrMapLine);
|
||||
ProgramAddrMapMemory[ProgramAddrMapLineCount] = ProgramAddrMapLine;
|
||||
@ -154,7 +154,7 @@ module FunctionName import cvw::*; #(parameter cvw_t P) (
|
||||
ProgramLabelMapLineCount = 0;
|
||||
ProgramLabelMapFP = $fopen(ProgramLabelMapFile, "r");
|
||||
|
||||
if (ProgramLabelMapFP != '0) begin
|
||||
if (ProgramLabelMapFP != 0) begin
|
||||
while (! $feof(ProgramLabelMapFP)) begin
|
||||
status = $fscanf(ProgramLabelMapFP, "%s\n", ProgramLabelMapLine);
|
||||
ProgramLabelMapMemory[ProgramLabelMapLineCount] = ProgramLabelMapLine;
|
||||
@ -174,7 +174,7 @@ module FunctionName import cvw::*; #(parameter cvw_t P) (
|
||||
logic OrReducedAdr, AnyUnknown;
|
||||
assign OrReducedAdr = |ProgramAddrIndex;
|
||||
assign AnyUnknown = (OrReducedAdr === 1'bx) ? 1'b1 : 1'b0;
|
||||
initial ProgramAddrIndex = '0;
|
||||
initial ProgramAddrIndex = 0;
|
||||
|
||||
always @(*) FunctionName = AnyUnknown ? "Unknown!" : ProgramLabelMapMemory[ProgramAddrIndex];
|
||||
|
||||
|
@ -231,7 +231,7 @@ module wallyTracer import cvw::*; #(parameter cvw_t P) (rvviTrace rvvi);
|
||||
end
|
||||
|
||||
genvar index;
|
||||
assign rf[0] = '0;
|
||||
assign rf[0] = 0;
|
||||
for(index = 1; index < NUMREGS; index += 1)
|
||||
assign rf[index] = testbench.dut.core.ieu.dp.regf.rf[index];
|
||||
|
||||
@ -239,7 +239,7 @@ module wallyTracer import cvw::*; #(parameter cvw_t P) (rvviTrace rvvi);
|
||||
assign rf_we3 = testbench.dut.core.ieu.dp.regf.we3;
|
||||
|
||||
always_comb begin
|
||||
rf_wb <= '0;
|
||||
rf_wb <= 0;
|
||||
if(rf_we3)
|
||||
rf_wb[rf_a3] <= 1'b1;
|
||||
end
|
||||
@ -251,7 +251,7 @@ module wallyTracer import cvw::*; #(parameter cvw_t P) (rvviTrace rvvi);
|
||||
assign frf_we4 = testbench.dut.core.fpu.fpu.fregfile.we4;
|
||||
|
||||
always_comb begin
|
||||
frf_wb <= '0;
|
||||
frf_wb <= 0;
|
||||
if(frf_we4)
|
||||
frf_wb[frf_a4] <= 1'b1;
|
||||
end
|
||||
@ -492,7 +492,7 @@ module wallyTracer import cvw::*; #(parameter cvw_t P) (rvviTrace rvvi);
|
||||
end
|
||||
|
||||
// *** implementation only cancel? so sc does not clear?
|
||||
assign rvvi.lrsc_cancel[0][0] = '0;
|
||||
assign rvvi.lrsc_cancel[0][0] = 0;
|
||||
|
||||
integer index2;
|
||||
|
||||
|
@ -40,7 +40,7 @@ module watchdog #(parameter XLEN, WatchDogTimerThreshold)
|
||||
always_ff @(posedge clk) begin
|
||||
OldPCW <= PCW;
|
||||
if(OldPCW == PCW) WatchDogTimerCount = WatchDogTimerCount + 1'b1;
|
||||
else WatchDogTimerCount = '0;
|
||||
else WatchDogTimerCount = 0;
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
|
@ -252,9 +252,9 @@ module testbench;
|
||||
assign SDCCmdIn = SDCCmd;
|
||||
assign SDCDatIn = SDCDat;
|
||||
-----/\----- EXCLUDED -----/\----- */
|
||||
assign SDCIntr = '0;
|
||||
assign SDCIntr = 0;
|
||||
end else begin
|
||||
assign SDCIntr = '0;
|
||||
assign SDCIntr = 0;
|
||||
end
|
||||
|
||||
wallypipelinedsoc #(P) dut(.clk, .reset_ext, .reset, .HRDATAEXT, .HREADYEXT, .HRESPEXT, .HSELEXT, .HSELEXTSDC,
|
||||
|
@ -335,7 +335,7 @@ module testbench;
|
||||
if (P.UNCORE_RAM_SUPPORTED) begin
|
||||
`ifdef TB_UNCORE_RAM_SUPPORTED
|
||||
for (adrindex=0; adrindex<(P.UNCORE_RAM_RANGE>>1+(P.XLEN/32)); adrindex = adrindex+1)
|
||||
dut.uncore.uncore.ram.ram.memory.RAM[adrindex] = '0;
|
||||
dut.uncore.uncore.ram.ram.memory.RAM[adrindex] = 0;
|
||||
`endif
|
||||
end
|
||||
if(reset) begin // branch predictor must always be reset
|
||||
@ -411,7 +411,7 @@ module testbench;
|
||||
.HREADRam(HRDATAEXT), .HREADYRam(HREADYEXT), .HRESPRam(HRESPEXT), .HREADY, .HWSTRB);
|
||||
end else begin
|
||||
assign HREADYEXT = 1;
|
||||
assign {HRESPEXT, HRDATAEXT} = '0;
|
||||
assign {HRESPEXT, HRDATAEXT} = 0;
|
||||
end
|
||||
|
||||
if(P.FPGA) begin : sdcard
|
||||
@ -424,8 +424,8 @@ module testbench;
|
||||
assign SDCCmdIn = SDCCmd;
|
||||
assign SDCDatIn = SDCDat;
|
||||
end else begin
|
||||
assign SDCCmd = '0;
|
||||
assign SDCDat = '0;
|
||||
assign SDCCmd = 0;
|
||||
assign SDCDat = 0;
|
||||
end
|
||||
|
||||
wallypipelinedsoc #(P) dut(.clk, .reset_ext, .reset, .HRDATAEXT, .HREADYEXT, .HRESPEXT, .HSELEXT, .HSELEXTSDC,
|
||||
|
@ -440,7 +440,7 @@ module testbench;
|
||||
always @(posedge clk)
|
||||
if (ResetMem) // program memory is sometimes reset (e.g. for CoreMark, which needs zeroed memory)
|
||||
for (adrindex=0; adrindex<(P.UNCORE_RAM_RANGE>>1+(P.XLEN/32)); adrindex = adrindex+1)
|
||||
dut.uncore.uncore.ram.ram.memory.RAM[adrindex] = '0;
|
||||
dut.uncore.uncore.ram.ram.memory.RAM[adrindex] = 0;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Actual hardware
|
||||
@ -457,7 +457,7 @@ module testbench;
|
||||
.HREADRam(HRDATAEXT), .HREADYRam(HREADYEXT), .HRESPRam(HRESPEXT), .HREADY, .HWSTRB);
|
||||
end else begin
|
||||
assign HREADYEXT = 1;
|
||||
assign {HRESPEXT, HRDATAEXT} = '0;
|
||||
assign {HRESPEXT, HRDATAEXT} = 0;
|
||||
end
|
||||
|
||||
if(P.SDC_SUPPORTED) begin : sdcard
|
||||
@ -473,9 +473,9 @@ module testbench;
|
||||
assign SDCDat = sd_dat_reg_t ? sd_dat_reg_o : sd_dat_i;
|
||||
assign SDCDatIn = SDCDat;
|
||||
-----/\----- EXCLUDED -----/\----- */
|
||||
assign SDCIntr = '0;
|
||||
assign SDCIntr = 0;
|
||||
end else begin
|
||||
assign SDCIntr = '0;
|
||||
assign SDCIntr = 0;
|
||||
end
|
||||
|
||||
wallypipelinedsoc #(P) dut(.clk, .reset_ext, .reset, .HRDATAEXT, .HREADYEXT, .HRESPEXT, .HSELEXT, .HSELEXTSDC,
|
||||
|
Loading…
Reference in New Issue
Block a user