mirror of
https://github.com/openhwgroup/cvw.git
synced 2025-04-22 12:57:23 -04:00
Defined bit sizes more precisely to help VCS lint and conform to coding style
This commit is contained in:
parent
1759c920bb
commit
3f195884e9
69 changed files with 429 additions and 316 deletions
7
src/cache/cache.sv
vendored
7
src/cache/cache.sv
vendored
|
@ -215,9 +215,10 @@ module cache import cvw::*; #(parameter cvw_t P,
|
|||
assign FlushWayFlag = FlushWay[NUMWAYS-1];
|
||||
end // block: flushlogic
|
||||
else begin:flushlogic // I$ is never flushed because it is never dirty
|
||||
assign FlushWay = 0;
|
||||
assign FlushWayFlag = 0;
|
||||
assign FlushAdrFlag = 0;
|
||||
assign FlushWay = '0;
|
||||
assign FlushWayFlag = 1'b0;
|
||||
assign FlushAdrFlag = 1'b0;
|
||||
assign FlushAdr = '0;
|
||||
end
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
2
src/cache/cacheLRU.sv
vendored
2
src/cache/cacheLRU.sv
vendored
|
@ -146,7 +146,7 @@ module cacheLRU
|
|||
// Move to = to keep Verilator happy and simulator running fast
|
||||
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
|
||||
else if(CacheEn) begin
|
||||
// Because we are using blocking assignments, change to LRUMemory must occur after LRUMemory is used so we get the proper value
|
||||
if(LRUWriteEn & (PAdr == CacheSetTag)) CurrLRU = NextLRU;
|
||||
|
|
8
src/cache/cacheway.sv
vendored
8
src/cache/cacheway.sv
vendored
|
@ -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 <= 0;
|
||||
if (reset) ValidBits <= '0;
|
||||
if(CacheEn) begin
|
||||
ValidWay <= ValidBits[CacheSetTag];
|
||||
if(InvalidateCache) ValidBits <= 0; // exclusion-tag: dcache invalidateway
|
||||
if(InvalidateCache) ValidBits <= '0; // exclusion-tag: dcache invalidateway
|
||||
else if (SetValidEN) ValidBits[CacheSetData] <= SetValidWay;
|
||||
else if (ClearValidEN) ValidBits[CacheSetData] <= 0; // exclusion-tag: icache ClearValidBits
|
||||
else if (ClearValidEN) ValidBits[CacheSetData] <= '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,13 +111,13 @@ 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 : 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
|
||||
assign HMASTLOCK = 1'b0; // no locking supported
|
||||
|
||||
// data phase muxing. This would be a mux if IFU wrote data.
|
||||
assign HWDATA = LSUHWDATA;
|
||||
|
|
|
@ -268,7 +268,7 @@ module fctrl import cvw::*; #(parameter cvw_t P) (
|
|||
// 11 - quad
|
||||
|
||||
if (P.FPSIZES == 1)
|
||||
assign FmtD = 0;
|
||||
assign FmtD = 1'b0;
|
||||
else if (P.FPSIZES == 2)begin
|
||||
logic [1:0] FmtTmp;
|
||||
assign FmtTmp = ((Funct7D[6:3] == 4'b0100)&OpD[4]) ? Rs2D[1:0] : (~OpD[6]&(&OpD[2:0])) ? {~Funct3D[1], ~(Funct3D[1]^Funct3D[0])} : Funct7D[1:0];
|
||||
|
@ -359,7 +359,7 @@ module fctrl import cvw::*; #(parameter cvw_t P) (
|
|||
|
||||
// Integer division on FPU divider
|
||||
if (P.M_SUPPORTED & P.IDIV_ON_FPU) assign IDivStartE = IntDivE;
|
||||
else assign IDivStartE = 0;
|
||||
else assign IDivStartE = 1'b0;
|
||||
|
||||
// E/M pipleine register
|
||||
flopenrc #(14+int'(P.FMTBITS)) EMCtrlReg (clk, reset, FlushM, ~StallM,
|
||||
|
|
|
@ -31,7 +31,7 @@ module fdivsqrtexpcalc import cvw::*; #(parameter cvw_t P) (
|
|||
input logic [P.FMTBITS-1:0] Fmt,
|
||||
input logic [P.NE-1:0] Xe, Ye, // input exponents
|
||||
input logic Sqrt,
|
||||
input logic [P.DIVBLEN-1:0] ell, m, // number of leading 0s in Xe and Ye
|
||||
input logic [P.DIVBLEN-1:0] ell, m, // number of leading 0s in Xe and Ye
|
||||
output logic [P.NE+1:0] Ue // result exponent
|
||||
);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -145,7 +145,7 @@ module fdivsqrtpreproc import cvw::*; #(parameter cvw_t P) (
|
|||
assign DivXShifted = DivX;
|
||||
end
|
||||
end else begin
|
||||
assign ISpecialCaseE = 0;
|
||||
assign ISpecialCaseE = 1'b0;
|
||||
end
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -74,7 +74,7 @@ module fmaalign import cvw::*; #(parameter cvw_t P) (
|
|||
// | 53'b0 | 106'b(product) | 1'b0 |
|
||||
// | addnend |
|
||||
end else if (KillZ) begin
|
||||
ZmShifted = 0;
|
||||
ZmShifted = '0;
|
||||
ASticky = ~ZZero;
|
||||
|
||||
// If the Addend is shifted right
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -218,7 +218,7 @@ module fpu import cvw::*; #(parameter cvw_t P) (
|
|||
|
||||
// Select NAN-boxed value of Z = 0.0 in proper format for FMA for multiply X*Y+Z
|
||||
// For add and subtract, Z comes from second source operand
|
||||
if(P.FPSIZES == 1) assign BoxedZeroE = 0;
|
||||
if(P.FPSIZES == 1) assign BoxedZeroE = '0;
|
||||
else if(P.FPSIZES == 2)
|
||||
mux2 #(P.FLEN) fmulzeromux ({{P.FLEN-P.LEN1{1'b1}}, {P.LEN1{1'b0}}}, (P.FLEN)'(0), FmtE, BoxedZeroE); // NaN boxing zeroes
|
||||
else if(P.FPSIZES == 3 | P.FPSIZES == 4)
|
||||
|
@ -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)
|
||||
|
|
|
@ -44,7 +44,7 @@ module fregfile #(parameter FLEN) (
|
|||
// write occurs on falling edge of clock
|
||||
|
||||
always_ff @(negedge clk) // or posedge reset)
|
||||
if (reset) for(i=0; i<32; i++) rf[i] <= 0;
|
||||
if (reset) for(i=0; i<32; i++) rf[i] <= '0;
|
||||
else if (we4) rf[a4] <= wd4;
|
||||
|
||||
assign rd1 = rf[a1];
|
||||
|
|
108
src/fpu/fround.sv
Normal file
108
src/fpu/fround.sv
Normal file
|
@ -0,0 +1,108 @@
|
|||
///////////////////////////////////////////
|
||||
// fround.sv
|
||||
//
|
||||
// Written: David_Harris@hmc.edu
|
||||
// Modified: 4/21/2024
|
||||
//
|
||||
// Purpose: Floating-point round to integer for Zfa
|
||||
//
|
||||
// Documentation: RISC-V System on Chip Design Chapter 16
|
||||
//
|
||||
// A component of the CORE-V-WALLY configurable RISC-V project.
|
||||
// https://github.com/openhwgroup/cvw
|
||||
//
|
||||
// Copyright (C) 2021-24 Harvey Mudd College & Oklahoma State University
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
||||
//
|
||||
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
|
||||
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
|
||||
// may obtain a copy of the License at
|
||||
//
|
||||
// https://solderpad.org/licenses/SHL-2.1/
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, any work distributed under the
|
||||
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
// either express or implied. See the License for the specific language governing permissions
|
||||
// and limitations under the License.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module fround import cvw::*; #(parameter cvw_t P) (
|
||||
input logic Xs, // input's sign
|
||||
input logic [P.NE-1:0] Xe, // input's exponent
|
||||
input logic [P.NF:0] Xm, // input's fraction
|
||||
input logic [P.FMTBITS-1:0] Fmt, // the input's precision (11=quad 01=double 00=single 10=half)
|
||||
);
|
||||
|
||||
logic [P.NE-2:0] Bias;
|
||||
logic [P.NE-1:0] E;
|
||||
|
||||
//////////////////////////////////////////
|
||||
// Determine exponent bias according to the format
|
||||
//////////////////////////////////////////
|
||||
// *** replicated from fdivsqrt; find a way to share
|
||||
|
||||
if (P.FPSIZES == 1) begin
|
||||
assign Bias = (P.NE-1)'(P.BIAS);
|
||||
|
||||
end else if (P.FPSIZES == 2) begin
|
||||
assign Bias = Fmt ? (P.NE-1)'(P.BIAS) : (P.NE-1)'(P.BIAS1);
|
||||
|
||||
end else if (P.FPSIZES == 3) begin
|
||||
always_comb
|
||||
case (Fmt)
|
||||
P.FMT: Bias = (P.NE-1)'(P.BIAS);
|
||||
P.FMT1: Bias = (P.NE-1)'(P.BIAS1);
|
||||
P.FMT2: Bias = (P.NE-1)'(P.BIAS2);
|
||||
default: Bias = 'x;
|
||||
endcase
|
||||
|
||||
end else if (P.FPSIZES == 4) begin
|
||||
always_comb
|
||||
case (Fmt)
|
||||
2'h3: Bias = (P.NE-1)'(P.Q_BIAS);
|
||||
2'h1: Bias = (P.NE-1)'(P.D_BIAS);
|
||||
2'h0: Bias = (P.NE-1)'(P.S_BIAS);
|
||||
2'h2: Bias = (P.NE-1)'(P.H_BIAS);
|
||||
endcase
|
||||
end
|
||||
|
||||
// Unbiased exponent
|
||||
assign E = Xe - Bias;
|
||||
|
||||
//////////////////////////////////////////
|
||||
// Compute LSB, rounding bit and Sticky bit mask (TMask)
|
||||
// if (E < 0) // negative exponents round to 0 or 1.
|
||||
// L' = 0 // LSB = 0
|
||||
// if (E = -1) R' = 1, TMask = 0.1111...111 // if (E = -1) 0.5 X < 1. Round bit is 1
|
||||
// else R' = 0; TMask = 1.1111...111 // if (E < -1), X < 0.5. Round bit is 0
|
||||
// else // positive exponents truncate fraction and may add 1
|
||||
// IMask = 1.0000…000 >>> E // (in U1.Nf form); implies thermometer code generator
|
||||
// TMask = ~(IMask >>> 1) // 0.01111…111 >> E
|
||||
// HotE = IMask & ~(IMask << 1) // a 1 in column E, where 0 is the integer bit,
|
||||
// // 1 is the most significant fractional bit, etc.
|
||||
// HotEP1 = HotE >> 1 // a 1 in column E+1
|
||||
// L' = OR(Xm & HotE) // Xm[E], where Xm[0] is the integer bit,
|
||||
// // Xm[1] is the most significant fractional bit, etc.
|
||||
// R' = OR(Xm & HotEP1) // Xm[E+1]
|
||||
// TRUNC = Xm & IMask // Truncated fraction, corresponds to truncated integer value
|
||||
// RND = TRUNC + HotE // TRUNC + (1 >> E), corresponds to next integer
|
||||
// T' = OR(Xm & TMask) // T’ = OR(Xm[E+2:Nf]) if E >= 0, OR(Xf) if E = -1, 1 if E < -1
|
||||
//////////////////////////////////////////
|
||||
|
||||
// Check if exponent is negative and -1
|
||||
assign Elt0 = (E < 0);
|
||||
assign Eeqm1 = (E == -1);
|
||||
|
||||
assign Rneg = Elt0;
|
||||
mux2
|
||||
|
||||
//
|
||||
// if (E = -1) R' = 1, TMask = 0.1111...111 // if (E = -1) 0.5 X < 1. Round bit is 1
|
||||
else R' = 0; TMask = 1.1111...111 // if (E < -1), X < 0.5. Round bit is 0
|
||||
|
||||
|
||||
mux
|
||||
|
||||
|
||||
endmodule
|
|
@ -83,7 +83,7 @@ module cvtshiftcalc import cvw::*; #(parameter cvw_t P) (
|
|||
P.FMT: ResNegNF = -($clog2(P.NF)+1)'(P.NF);
|
||||
P.FMT1: ResNegNF = -($clog2(P.NF)+1)'(P.NF1);
|
||||
P.FMT2: ResNegNF = -($clog2(P.NF)+1)'(P.NF2);
|
||||
default: ResNegNF = 0; // Not used for floating-point so don't care, but convert to unsigned long has OutFmt = 11.
|
||||
default: ResNegNF = '0; // Not used for floating-point so don't care, but convert to unsigned long has OutFmt = 11.
|
||||
endcase
|
||||
|
||||
end else if (P.FPSIZES == 4) begin
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -255,7 +255,7 @@ module round import cvw::*; #(parameter cvw_t P) (
|
|||
// Determine if you add 1
|
||||
case (Frm)
|
||||
3'b000: CalcPlus1 = Guard & (Round|Sticky|LsbRes);//round to nearest even
|
||||
3'b001: CalcPlus1 = 0;//round to zero
|
||||
3'b001: CalcPlus1 = 1'b0;//round to zero
|
||||
3'b010: CalcPlus1 = Ms;//round down
|
||||
3'b011: CalcPlus1 = ~Ms;//round up
|
||||
3'b100: CalcPlus1 = Guard;//round to nearest max magnitude
|
||||
|
@ -264,7 +264,7 @@ module round import cvw::*; #(parameter cvw_t P) (
|
|||
// Determine if you add 1 (for underflow flag)
|
||||
case (Frm)
|
||||
3'b000: UfCalcPlus1 = Round & (Sticky|Guard);//round to nearest even
|
||||
3'b001: UfCalcPlus1 = 0;//round to zero
|
||||
3'b001: UfCalcPlus1 = 1'b0;//round to zero
|
||||
3'b010: UfCalcPlus1 = Ms;//round down
|
||||
3'b011: UfCalcPlus1 = ~Ms;//round up
|
||||
3'b100: UfCalcPlus1 = Round;//round to nearest max magnitude
|
||||
|
@ -305,7 +305,7 @@ module round import cvw::*; #(parameter cvw_t P) (
|
|||
2'b00: Me = {CvtCe[P.NE], CvtCe}&{P.NE+2{~CvtResSubnormUf|CvtResUf}}; // cvt
|
||||
// 2'b01: Me = DivDone ? Ue : 0; // divide
|
||||
2'b01: Me = Ue; // divide
|
||||
default: Me = 0;
|
||||
default: Me = '0;
|
||||
endcase
|
||||
|
||||
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -54,7 +54,7 @@ module unpackinput import cvw::*; #(parameter cvw_t P) (
|
|||
assign In = A & {P.FLEN{FPUActive}};
|
||||
|
||||
if (P.FPSIZES == 1) begin // if there is only one floating point format supported
|
||||
assign BadNaNBox = 0;
|
||||
assign BadNaNBox = 1'b0;
|
||||
assign Sgn = In[P.FLEN-1]; // sign bit
|
||||
assign Frac = In[P.NF-1:0]; // fraction (no assumed 1)
|
||||
assign ExpNonZero = |In[P.FLEN-2:P.NF]; // is the exponent non-zero
|
||||
|
@ -133,7 +133,7 @@ module unpackinput import cvw::*; #(parameter cvw_t P) (
|
|||
// Check NaN boxing
|
||||
always_comb
|
||||
case (Fmt)
|
||||
P.FMT: BadNaNBox = 0;
|
||||
P.FMT: BadNaNBox = 1'b0;
|
||||
P.FMT1: BadNaNBox = ~&In[P.FLEN-1:P.LEN1];
|
||||
P.FMT2: BadNaNBox = ~&In[P.FLEN-1:P.LEN2];
|
||||
default: BadNaNBox = 1'bx;
|
||||
|
@ -149,30 +149,30 @@ module unpackinput import cvw::*; #(parameter cvw_t P) (
|
|||
|
||||
// extract the sign bit
|
||||
always_comb
|
||||
if (BadNaNBox) Sgn = 0; // improperly boxed NaNs are treated as positive
|
||||
if (BadNaNBox) Sgn = 1'b0; // improperly boxed NaNs are treated as positive
|
||||
else
|
||||
case (Fmt)
|
||||
P.FMT: Sgn = In[P.FLEN-1];
|
||||
P.FMT1: Sgn = In[P.LEN1-1];
|
||||
P.FMT2: Sgn = In[P.LEN2-1];
|
||||
P.FMT: Sgn = In[P.FLEN-1];
|
||||
P.FMT1: Sgn = In[P.LEN1-1];
|
||||
P.FMT2: Sgn = In[P.LEN2-1];
|
||||
default: Sgn = 1'bx;
|
||||
endcase
|
||||
|
||||
// extract the fraction
|
||||
always_comb
|
||||
case (Fmt)
|
||||
P.FMT: Frac = In[P.NF-1:0];
|
||||
P.FMT1: Frac = {In[P.NF1-1:0], (P.NF-P.NF1)'(0)};
|
||||
P.FMT2: Frac = {In[P.NF2-1:0], (P.NF-P.NF2)'(0)};
|
||||
P.FMT: Frac = In[P.NF-1:0];
|
||||
P.FMT1: Frac = {In[P.NF1-1:0], (P.NF-P.NF1)'(0)};
|
||||
P.FMT2: Frac = {In[P.NF2-1:0], (P.NF-P.NF2)'(0)};
|
||||
default: Frac = {P.NF{1'bx}};
|
||||
endcase
|
||||
|
||||
// is the exponent non-zero
|
||||
always_comb
|
||||
case (Fmt)
|
||||
P.FMT: ExpNonZero = |In[P.FLEN-2:P.NF]; // if input is largest precision (P.FLEN - ie quad or double)
|
||||
P.FMT1: ExpNonZero = |In[P.LEN1-2:P.NF1]; // if input is larger precsion (P.LEN1 - double or single)
|
||||
P.FMT2: ExpNonZero = |In[P.LEN2-2:P.NF2]; // if input is smallest precsion (P.LEN2 - single or half)
|
||||
P.FMT: ExpNonZero = |In[P.FLEN-2:P.NF]; // if input is largest precision (P.FLEN - ie quad or double)
|
||||
P.FMT1: ExpNonZero = |In[P.LEN1-2:P.NF1]; // if input is larger precsion (P.LEN1 - double or single)
|
||||
P.FMT2: ExpNonZero = |In[P.LEN2-2:P.NF2]; // if input is smallest precsion (P.LEN2 - single or half)
|
||||
default: ExpNonZero = 1'bx;
|
||||
endcase
|
||||
|
||||
|
@ -209,13 +209,13 @@ module unpackinput import cvw::*; #(parameter cvw_t P) (
|
|||
// P.Q_LEN | P.D_LEN | P.S_LEN | P.H_LEN length of floating point number
|
||||
// P.Q_NE | P.D_NE | P.S_NE | P.H_NE length of exponent
|
||||
// P.Q_NF | P.D_NF | P.S_NF | P.H_NF length of fraction
|
||||
// P.Q_BIAS | P.D_BIAS | P.S_BIAS | P.H_BIAS exponent's bias value
|
||||
// P.Q_BIAS | P.D_= 1'b1; | P.S_BIAS | P.H_BIAS exponent's bias value
|
||||
// P.Q_FMT | P.D_FMT | P.S_FMT | P.H_FMT precision's format value - Q=11 D=01 Sticky=00 H=10
|
||||
|
||||
// Check NaN boxing
|
||||
always_comb
|
||||
case (Fmt)
|
||||
2'b11: BadNaNBox = 0;
|
||||
2'b11: BadNaNBox = 1'b0;
|
||||
2'b01: BadNaNBox = ~&In[P.Q_LEN-1:P.D_LEN];
|
||||
2'b00: BadNaNBox = ~&In[P.Q_LEN-1:P.S_LEN];
|
||||
2'b10: BadNaNBox = ~&In[P.Q_LEN-1:P.H_LEN];
|
||||
|
@ -234,7 +234,7 @@ module unpackinput import cvw::*; #(parameter cvw_t P) (
|
|||
|
||||
// extract sign bit
|
||||
always_comb
|
||||
if (BadNaNBox) Sgn = 0; // improperly boxed NaNs are treated as positive
|
||||
if (BadNaNBox) Sgn = 1'b0; // improperly boxed NaNs are treated as positive
|
||||
else
|
||||
case (Fmt)
|
||||
2'b11: Sgn = In[P.Q_LEN-1];
|
||||
|
|
|
@ -34,7 +34,7 @@ module binencoder #(parameter N = 8) (
|
|||
// this is coded as a priority encoder
|
||||
// consider redesigning to take advanteage of one-hot nature of input
|
||||
always_comb begin
|
||||
Y = 0;
|
||||
Y = '0;
|
||||
for(index = 0; index < N; index++)
|
||||
if(A[index] == 1'b1) Y = index[$clog2(N)-1:0];
|
||||
end
|
||||
|
|
|
@ -31,7 +31,7 @@ module flopenr #(parameter WIDTH = 8) (
|
|||
output logic [WIDTH-1:0] q);
|
||||
|
||||
always_ff @(posedge clk)
|
||||
if (reset) q <= 0;
|
||||
if (reset) q <= '0;
|
||||
else if (en) q <= d;
|
||||
endmodule
|
||||
|
||||
|
|
|
@ -31,9 +31,9 @@ module flopenrc #(parameter WIDTH = 8) (
|
|||
output logic [WIDTH-1:0] q);
|
||||
|
||||
always_ff @(posedge clk)
|
||||
if (reset) q <= 0;
|
||||
if (reset) q <= '0;
|
||||
else if (en)
|
||||
if (clear) q <= 0;
|
||||
if (clear) q <= '0;
|
||||
else q <= d;
|
||||
endmodule
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ module flopr #(parameter WIDTH = 8) (
|
|||
output logic [WIDTH-1:0] q);
|
||||
|
||||
always_ff @(posedge clk)
|
||||
if (reset) q <= 0;
|
||||
if (reset) q <= '0;
|
||||
else q <= d;
|
||||
endmodule
|
||||
|
||||
|
|
|
@ -114,7 +114,7 @@ module ram2p1r1wbe import cvw::*; #(parameter USE_SRAM=0, DEPTH=1024, WIDTH=68)
|
|||
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
|
||||
*/
|
||||
|
||||
|
|
|
@ -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 = 1'b0;
|
||||
assign StallDCause = (StructuralStallD | FPUStallD) & ~FlushDCause;
|
||||
assign StallECause = (DivBusyE | FDivBusyE) & ~FlushECause;
|
||||
assign StallMCause = WFIStallM & ~FlushMCause;
|
||||
|
|
|
@ -94,22 +94,22 @@ module bitmanipalu import cvw::*; #(parameter cvw_t P) (
|
|||
// ZBC and ZBKCUnit
|
||||
if (P.ZBC_SUPPORTED | P.ZBKC_SUPPORTED) begin: zbc
|
||||
zbc #(P.XLEN) ZBC(.A(ABMU), .RevA, .B(BBMU), .Funct3, .ZBCResult);
|
||||
end else assign ZBCResult = 0;
|
||||
end else assign ZBCResult = '0;
|
||||
|
||||
// ZBB Unit
|
||||
if (P.ZBB_SUPPORTED) begin: zbb
|
||||
zbb #(P.XLEN) ZBB(.A(ABMU), .RevA, .B(BBMU), .W64, .LT, .LTU, .BUnsigned(Funct3[0]), .ZBBSelect(ZBBSelect[2:0]), .ZBBResult);
|
||||
end else assign ZBBResult = 0;
|
||||
end else assign ZBBResult = '0;
|
||||
|
||||
// ZBKB Unit
|
||||
if (P.ZBKB_SUPPORTED) begin: zbkb
|
||||
zbkb #(P.XLEN) ZBKB(.A(ABMU), .B(BBMU), .RevA, .W64, .Funct3, .ZBKBSelect(ZBBSelect[2:0]), .ZBKBResult);
|
||||
end else assign ZBKBResult = 0;
|
||||
end else assign ZBKBResult = '0;
|
||||
|
||||
// ZBKX Unit
|
||||
if (P.ZBKX_SUPPORTED) begin: zbkx
|
||||
zbkx #(P.XLEN) ZBKX(.A(ABMU), .B(BBMU), .ZBKXSelect(ZBBSelect[2:0]), .ZBKXResult);
|
||||
end else assign ZBKXResult = 0;
|
||||
end else assign ZBKXResult = '0;
|
||||
|
||||
// ZKND and ZKNE AES decryption and encryption
|
||||
if (P.ZKND_SUPPORTED | P.ZKNE_SUPPORTED)
|
||||
|
@ -120,7 +120,7 @@ module bitmanipalu import cvw::*; #(parameter cvw_t P) (
|
|||
if (P.ZKNH_SUPPORTED) begin: zknh
|
||||
if (P.XLEN == 32) zknh32 ZKNH32(.A(ABMU), .B(BBMU), .ZKNHSelect(ZBBSelect), .ZKNHResult(ZKNHResult));
|
||||
else zknh64 ZKNH64(.A(ABMU), .B(BBMU), .ZKNHSelect(ZBBSelect), .ZKNHResult(ZKNHResult));
|
||||
end else assign ZKNHResult = 0;
|
||||
end else assign ZKNHResult = '0;
|
||||
|
||||
// Result Select Mux
|
||||
always_comb
|
||||
|
|
|
@ -56,8 +56,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
|
||||
|
|
|
@ -34,7 +34,7 @@ module popcnt #(parameter WIDTH = 32) (
|
|||
logic [$clog2(WIDTH):0] sum;
|
||||
|
||||
always_comb begin
|
||||
sum = 0;
|
||||
sum = '0;
|
||||
for (int i=0;i<WIDTH;i++) begin:loop
|
||||
sum = (num[i]) ? sum + 1 : sum;
|
||||
end
|
||||
|
|
|
@ -219,23 +219,23 @@ module controller import cvw::*; #(parameter cvw_t P) (
|
|||
assign CSRFunctD = Funct3D[1:0] != 2'b00;
|
||||
assign IWValidFunct3D = Funct3D == 3'b000 | Funct3D == 3'b001 | Funct3D == 3'b101;
|
||||
end else begin:legalcheck2
|
||||
assign IFunctD = 1; // Don't bother to separate out shift decoding
|
||||
assign IFunctD = 1'b1; // Don't bother to separate out shift decoding
|
||||
assign RFunctD = ~Funct7D[0]; // Not a multiply
|
||||
assign MFunctD = Funct7D[0] & (P.M_SUPPORTED | (P.ZMMUL_SUPPORTED & ~Funct3D[2])); // muldiv
|
||||
assign LFunctD = 1; // don't bother to check Funct3 for loads
|
||||
assign FLSFunctD = 1; // don't bother to check Func3 for floating-point loads/stores
|
||||
assign FenceFunctD = 1; // don't bother to check fields for fences
|
||||
assign CMOFunctD = 1; // don't bother to check fields for CMO instructions
|
||||
assign AFunctD = 1; // don't bother to check fields for atomics
|
||||
assign AMOFunctD = 1; // don't bother to check Funct7 for AMO operations
|
||||
assign RWFunctD = 1; // don't bother to check fields for RW instructions
|
||||
assign MWFunctD = 1; // don't bother to check fields for MW instructions
|
||||
assign SFunctD = 1; // don't bother to check Funct3 for stores
|
||||
assign BFunctD = 1; // don't bother to check Funct3 for branches
|
||||
assign JRFunctD = 1; // don't bother to check Funct3 for jalrs
|
||||
assign PFunctD = 1; // don't bother to check fields for privileged instructions
|
||||
assign CSRFunctD = 1; // don't bother to check Funct3 for CSR operations
|
||||
assign IWValidFunct3D = 1;
|
||||
assign LFunctD = 1'b1; // don't bother to check Funct3 for loads
|
||||
assign FLSFunctD = 1'b1; // don't bother to check Func3 for floating-point loads/stores
|
||||
assign FenceFunctD = 1'b1; // don't bother to check fields for fences
|
||||
assign CMOFunctD = 1'b1; // don't bother to check fields for CMO instructions
|
||||
assign AFunctD = 1'b1; // don't bother to check fields for atomics
|
||||
assign AMOFunctD = 1'b1; // don't bother to check Funct7 for AMO operations
|
||||
assign RWFunctD = 1'b1; // don't bother to check fields for RW instructions
|
||||
assign MWFunctD = 1'b1; // don't bother to check fields for MW instructions
|
||||
assign SFunctD = 1'b1; // don't bother to check Funct3 for stores
|
||||
assign BFunctD = 1'b1; // don't bother to check Funct3 for branches
|
||||
assign JRFunctD = 1'b1; // don't bother to check Funct3 for jalrs
|
||||
assign PFunctD = 1'b1; // don't bother to check fields for privileged instructions
|
||||
assign CSRFunctD = 1'b1; // don't bother to check Funct3 for CSR operations
|
||||
assign IWValidFunct3D = 1'b1;
|
||||
end
|
||||
|
||||
// Main Instruction Decoder
|
||||
|
@ -378,8 +378,8 @@ module controller import cvw::*; #(parameter cvw_t P) (
|
|||
assign InvalidateICacheD = FenceID;
|
||||
assign FlushDCacheD = FenceID;
|
||||
end else begin:fencei
|
||||
assign InvalidateICacheD = 0;
|
||||
assign FlushDCacheD = 0;
|
||||
assign InvalidateICacheD = 1'b0;
|
||||
assign FlushDCacheD = 1'b0;
|
||||
end
|
||||
|
||||
// Cache Management instructions
|
||||
|
|
|
@ -140,5 +140,5 @@ module datapath import cvw::*; #(parameter cvw_t P) (
|
|||
|
||||
// handle Store Conditional result if atomic extension supported
|
||||
if (P.A_SUPPORTED) assign SCResultW = {{(P.XLEN-1){1'b0}}, SquashSCW};
|
||||
else assign SCResultW = 0;
|
||||
else assign SCResultW = '0;
|
||||
endmodule
|
||||
|
|
|
@ -48,7 +48,7 @@ module extend import cvw::*; #(parameter cvw_t P) (
|
|||
// U-type (lui, auipc)
|
||||
3'b100: ImmExtD = {{(P.XLEN-31){InstrD[31]}}, InstrD[30:12], 12'b0};
|
||||
// Store Conditional: zero offset
|
||||
3'b101: if (P.A_SUPPORTED | P.ZICBOM_SUPPORTED | P.ZICBOZ_SUPPORTED) ImmExtD = 0;
|
||||
3'b101: if (P.A_SUPPORTED | P.ZICBOM_SUPPORTED | P.ZICBOZ_SUPPORTED) ImmExtD = '0;
|
||||
else ImmExtD = undefined;
|
||||
default: ImmExtD = undefined; // undefined
|
||||
endcase
|
||||
|
|
|
@ -50,7 +50,7 @@ module regfile #(parameter XLEN, E_SUPPORTED) (
|
|||
// can logic be adjusted to not need resettable registers?
|
||||
|
||||
always_ff @(negedge clk)
|
||||
if (reset) for(i=1; i<NUMREGS; i++) rf[i] <= 0;
|
||||
if (reset) for(i=1; i<NUMREGS; i++) rf[i] <= '0;
|
||||
else if (we3) rf[a3] <= wd3;
|
||||
|
||||
assign rd1 = (a1 != 0) ? rf[a1] : 0;
|
||||
|
|
|
@ -42,7 +42,7 @@ module sha512_32 (
|
|||
assign x[0][2] = A >> 8;
|
||||
assign x[0][3] = B << 31;
|
||||
assign x[0][4] = B << 24;
|
||||
assign x[0][5] = 0;
|
||||
assign x[0][5] = '0;
|
||||
|
||||
// sha512sig0l
|
||||
assign x[1][0] = A >> 1;
|
||||
|
@ -58,7 +58,7 @@ module sha512_32 (
|
|||
assign x[2][2] = A >> 19;
|
||||
assign x[2][3] = B >> 29;
|
||||
assign x[2][4] = B << 13;
|
||||
assign x[2][5] = 0;
|
||||
assign x[2][5] = '0;
|
||||
|
||||
// sha512sig1l
|
||||
assign x[3][0] = A << 3;
|
||||
|
|
|
@ -164,7 +164,7 @@ module bpred import cvw::*; #(parameter cvw_t P) (
|
|||
.InstrClassM({CallM, ReturnM, JumpM, BranchM}),
|
||||
.InstrClassW({CallW, ReturnW, JumpW, BranchW}));
|
||||
|
||||
icpred #(P, `INSTR_CLASS_PRED) icpred(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW,
|
||||
icpred #(P, `INSTR_CLASS_PRED) icpred(.clk, .reset, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM,
|
||||
.PostSpillInstrRawF, .InstrD, .BranchD, .BranchE, .JumpD, .JumpE, .BranchM, .BranchW, .JumpM, .JumpW,
|
||||
.CallD, .CallE, .CallM, .CallW, .ReturnD, .ReturnE, .ReturnM, .ReturnW, .BTBCallF, .BTBReturnF, .BTBJumpF,
|
||||
.BTBBranchF, .BPCallF, .BPReturnF, .BPJumpF, .BPBranchF, .IClassWrongM, .IClassWrongE, .BPReturnWrongD);
|
||||
|
|
|
@ -30,8 +30,8 @@
|
|||
module icpred import cvw::*; #(parameter cvw_t P,
|
||||
parameter INSTR_CLASS_PRED = 1)(
|
||||
input logic clk, reset,
|
||||
input logic StallF, StallD, StallE, StallM, StallW,
|
||||
input logic FlushD, FlushE, FlushM, FlushW,
|
||||
input logic StallD, StallE, StallM, StallW,
|
||||
input logic FlushD, FlushE, FlushM,
|
||||
input logic [31:0] PostSpillInstrRawF, InstrD, // Instruction
|
||||
input logic BranchD, BranchE,
|
||||
input logic JumpD, JumpE,
|
||||
|
@ -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 <= FlushedBits[IndexLHRNextF];
|
||||
if (reset | FlushD) FlushedBits <= '1;
|
||||
if(BranchD & ~StallE & ~FlushE) begin
|
||||
FlushedBits[IndexLHRD] <= 0;
|
||||
FlushedBits[IndexLHRD] <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -80,19 +80,19 @@ module decompress import cvw::*; #(parameter cvw_t P) (
|
|||
always_comb
|
||||
if (op == 2'b11) begin // noncompressed instruction
|
||||
InstrD = InstrRawD;
|
||||
IllegalCompInstrD = 0;
|
||||
IllegalCompInstrD = '0;
|
||||
end else begin // convert compressed instruction into uncompressed
|
||||
IllegalCompInstrD = 0;
|
||||
IllegalCompInstrD = '0;
|
||||
case ({op, instr16[15:13]})
|
||||
5'b00000: if (immCIW != 0) InstrD = {immCIW, 5'b00010, 3'b000, rdp, 7'b0010011}; // c.addi4spn
|
||||
else begin // illegal instruction
|
||||
IllegalCompInstrD = 1;
|
||||
IllegalCompInstrD = 1'b1;
|
||||
InstrD = {16'b0, instr16}; // preserve instruction for mtval on trap
|
||||
end
|
||||
5'b00001: if (P.C_SUPPORTED & P.D_SUPPORTED | P.ZCD_SUPPORTED)
|
||||
InstrD = {immCLD, rs1p, 3'b011, rdp, 7'b0000111}; // c.fld
|
||||
else begin // unsupported instruction
|
||||
IllegalCompInstrD = 1;
|
||||
IllegalCompInstrD = 1'b1;
|
||||
InstrD = {16'b0, instr16}; // preserve instruction for mtval on trap
|
||||
end
|
||||
5'b00010: InstrD = {immCL, rs1p, 3'b010, rdp, 7'b0000011}; // c.lw
|
||||
|
@ -100,7 +100,7 @@ module decompress import cvw::*; #(parameter cvw_t P) (
|
|||
if (P.C_SUPPORTED & P.F_SUPPORTED | P.ZCF_SUPPORTED)
|
||||
InstrD = {immCL, rs1p, 3'b010, rdp, 7'b0000111}; // c.flw
|
||||
else begin
|
||||
IllegalCompInstrD = 1;
|
||||
IllegalCompInstrD = 1'b1;
|
||||
InstrD = {16'b0, instr16}; // preserve instruction for mtval on trap
|
||||
end
|
||||
else
|
||||
|
@ -118,17 +118,17 @@ module decompress import cvw::*; #(parameter cvw_t P) (
|
|||
else if (instr16[12:10] == 3'b011 & instr16[6] == 1'b0)
|
||||
InstrD = {7'b0, rs2p, rs1p, 3'b001, 3'b000, instr16[5], 1'b0, 7'b0100011}; // c.sh
|
||||
else begin
|
||||
IllegalCompInstrD = 1;
|
||||
IllegalCompInstrD = 1'b1;
|
||||
InstrD = {16'b0, instr16}; // preserve instruction for mtval on trap
|
||||
end
|
||||
else begin
|
||||
IllegalCompInstrD = 1;
|
||||
IllegalCompInstrD = 1'b1;
|
||||
InstrD = {16'b0, instr16}; // preserve instruction for mtval on trap
|
||||
end
|
||||
5'b00101: if (P.C_SUPPORTED & P.D_SUPPORTED | P.ZCD_SUPPORTED)
|
||||
InstrD = {immCSD[11:5], rs2p, rs1p, 3'b011, immCSD[4:0], 7'b0100111}; // c.fsd
|
||||
else begin // unsupported instruction
|
||||
IllegalCompInstrD = 1;
|
||||
IllegalCompInstrD = 1'b1;
|
||||
InstrD = {16'b0, instr16}; // preserve instruction for mtval on trap
|
||||
end
|
||||
5'b00110: InstrD = {immCS[11:5], rs2p, rs1p, 3'b010, immCS[4:0], 7'b0100011}; // c.sw
|
||||
|
@ -136,7 +136,7 @@ module decompress import cvw::*; #(parameter cvw_t P) (
|
|||
if (P.C_SUPPORTED & P.F_SUPPORTED | P.ZCF_SUPPORTED)
|
||||
InstrD = {immCS[11:5], rs2p, rs1p, 3'b010, immCS[4:0], 7'b0100111}; // c.fsw
|
||||
else begin
|
||||
IllegalCompInstrD = 1;
|
||||
IllegalCompInstrD = 1'b1;
|
||||
InstrD = {16'b0, instr16}; // preserve instruction for mtval on trap
|
||||
end
|
||||
else
|
||||
|
@ -186,11 +186,11 @@ module decompress import cvw::*; #(parameter cvw_t P) (
|
|||
else if (instr16[6:5] == 2'b10 & P.ZCB_SUPPORTED)
|
||||
InstrD = {7'b0000001, rs2p, rds1p, 3'b000, rds1p, 7'b0110011}; // c.mul
|
||||
else begin // reserved
|
||||
IllegalCompInstrD = 1;
|
||||
IllegalCompInstrD = 1'b1;
|
||||
InstrD = {16'b0, instr16}; // preserve instruction for mtval on trap
|
||||
end
|
||||
/** end else begin // illegal instruction
|
||||
IllegalCompInstrD = 1;
|
||||
IllegalCompInstrD = 1'b1;
|
||||
InstrD = {16'b0, instr16}; // preserve instruction for mtval on trap **/
|
||||
end
|
||||
5'b01101: InstrD = {immCJ, 5'b00000, 7'b1101111}; // c.j
|
||||
|
@ -200,7 +200,7 @@ module decompress import cvw::*; #(parameter cvw_t P) (
|
|||
5'b10001: if (P.C_SUPPORTED & P.D_SUPPORTED | P.ZCD_SUPPORTED)
|
||||
InstrD = {immCILSPD, 5'b00010, 3'b011, rds1, 7'b0000111}; // c.fldsp
|
||||
else begin // unsupported instruction
|
||||
IllegalCompInstrD = 1;
|
||||
IllegalCompInstrD = 1'b1;
|
||||
InstrD = {16'b0, instr16}; // preserve instruction for mtval on trap
|
||||
end
|
||||
5'b10010: InstrD = {immCILSP, 5'b00010, 3'b010, rds1, 7'b0000011}; // c.lwsp
|
||||
|
@ -208,7 +208,7 @@ module decompress import cvw::*; #(parameter cvw_t P) (
|
|||
if (P.C_SUPPORTED & P.F_SUPPORTED | P.ZCF_SUPPORTED)
|
||||
InstrD = {immCILSP, 5'b00010, 3'b010, rds1, 7'b0000111}; // c.flwsp
|
||||
else begin
|
||||
IllegalCompInstrD = 1;
|
||||
IllegalCompInstrD = 1'b1;
|
||||
InstrD = {16'b0, instr16}; // preserve instruction for mtval on trap
|
||||
end
|
||||
else
|
||||
|
@ -229,7 +229,7 @@ module decompress import cvw::*; #(parameter cvw_t P) (
|
|||
5'b10101: if (P.C_SUPPORTED & P.D_SUPPORTED | P.ZCD_SUPPORTED)
|
||||
InstrD = {immCSSD[11:5], rs2, 5'b00010, 3'b011, immCSSD[4:0], 7'b0100111}; // c.fsdsp
|
||||
else begin // unsupported instruction
|
||||
IllegalCompInstrD = 1;
|
||||
IllegalCompInstrD = 1'b1;
|
||||
InstrD = {16'b0, instr16}; // preserve instruction for mtval on trap
|
||||
end
|
||||
5'b10110: InstrD = {immCSS[11:5], rs2, 5'b00010, 3'b010, immCSS[4:0], 7'b0100011}; // c.swsp
|
||||
|
@ -237,13 +237,13 @@ module decompress import cvw::*; #(parameter cvw_t P) (
|
|||
if (P.C_SUPPORTED & P.F_SUPPORTED | P.ZCF_SUPPORTED)
|
||||
InstrD = {immCSS[11:5], rs2, 5'b00010, 3'b010, immCSS[4:0], 7'b0100111}; // c.fswsp
|
||||
else begin
|
||||
IllegalCompInstrD = 1;
|
||||
IllegalCompInstrD = 1'b1;
|
||||
InstrD = {16'b0, instr16}; // preserve instruction for mtval on trap
|
||||
end
|
||||
else
|
||||
InstrD = {immCSSD[11:5], rs2, 5'b00010, 3'b011, immCSSD[4:0], 7'b0100011}; // c.sdsp
|
||||
default: begin // illegal instruction
|
||||
IllegalCompInstrD = 1;
|
||||
IllegalCompInstrD = 1'b1;
|
||||
InstrD = {16'b0, instr16}; // preserve instruction for mtval on trap
|
||||
end
|
||||
endcase
|
||||
|
|
|
@ -154,7 +154,7 @@ module ifu import cvw::*; #(parameter cvw_t P) (
|
|||
assign PCSpillNextF = PCNextF;
|
||||
assign PCSpillF = PCF;
|
||||
assign PostSpillInstrRawF = InstrRawF;
|
||||
assign {SelSpillNextF, CompressedF} = 0;
|
||||
assign {SelSpillNextF, CompressedF} = '0;
|
||||
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'b1;
|
||||
assign SelIROM = '0;
|
||||
end
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -216,12 +216,13 @@ module ifu import cvw::*; #(parameter cvw_t P) (
|
|||
|
||||
// The IROM uses untranslated addresses, so it is not compatible with virtual memory.
|
||||
if (P.IROM_SUPPORTED) begin : irom
|
||||
logic IROMce;
|
||||
assign IROMce = ~GatedStallD | reset;
|
||||
logic IROMce;
|
||||
assign IROMce = ~GatedStallD | reset;
|
||||
assign IFURWF = 2'b10;
|
||||
irom #(P) irom(.clk, .ce(IROMce), .Adr(PCSpillNextF[P.XLEN-1:0]), .IROMInstrF);
|
||||
end else begin
|
||||
assign IFURWF = 2'b10;
|
||||
assign IROMInstrF = '0;
|
||||
end
|
||||
if (P.BUS_SUPPORTED) begin : bus
|
||||
// **** must fix words per line vs beats per line as in lsu.
|
||||
|
@ -234,8 +235,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),
|
||||
|
@ -279,15 +280,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
|
||||
|
||||
|
@ -348,14 +349,14 @@ module ifu import cvw::*; #(parameter cvw_t P) (
|
|||
logic CallD, CallE, CallM, CallW;
|
||||
logic ReturnD, ReturnE, ReturnM, ReturnW;
|
||||
assign BPWrongE = PCSrcE;
|
||||
icpred #(P, 0) icpred(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW,
|
||||
icpred #(P, 0) icpred(.clk, .reset, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM,
|
||||
.PostSpillInstrRawF, .InstrD, .BranchD, .BranchE, .JumpD, .JumpE, .BranchM, .BranchW, .JumpM, .JumpW,
|
||||
.CallD, .CallE, .CallM, .CallW, .ReturnD, .ReturnE, .ReturnM, .ReturnW,
|
||||
.BTBCallF(1'b0), .BTBReturnF(1'b0), .BTBJumpF(1'b0),
|
||||
.BTBBranchF(1'b0), .BPCallF(), .BPReturnF(), .BPJumpF(), .BPBranchF(), .IClassWrongM,
|
||||
.IClassWrongE(), .BPReturnWrongD());
|
||||
flopenrc #(1) PCSrcMReg(clk, reset, FlushM, ~StallM, PCSrcE, BPWrongM);
|
||||
assign RASPredPCWrongM = 0;
|
||||
assign RASPredPCWrongM = 1'b0;
|
||||
assign BPDirPredWrongM = BPWrongM;
|
||||
assign BTAWrongM = BPWrongM;
|
||||
assign InstrClassM = {CallM, ReturnM, JumpM, BranchM};
|
||||
|
@ -402,11 +403,11 @@ module ifu import cvw::*; #(parameter cvw_t P) (
|
|||
if (P.ZICSR_SUPPORTED | P.A_SUPPORTED) begin
|
||||
mux2 #(32) FlushInstrMMux(InstrE, nop, FlushM, NextInstrE);
|
||||
flopenr #(32) InstrMReg(clk, reset, ~StallM, NextInstrE, InstrM);
|
||||
end else assign InstrM = 0;
|
||||
end else assign InstrM = '0;
|
||||
// PCM is only needed with CSRs or branch prediction
|
||||
if (P.ZICSR_SUPPORTED | P.BPRED_SUPPORTED)
|
||||
flopenr #(P.XLEN) PCMReg(clk, reset, ~StallM, PCE, PCM);
|
||||
else assign PCM = 0;
|
||||
else assign PCM = '0;
|
||||
|
||||
// If compressed instructions are supported, increment PCLink by 2 or 4 for a jal. Otherwise, just by 4
|
||||
if (P.COMPRESSED_SUPPORTED) begin
|
||||
|
@ -415,7 +416,7 @@ module ifu import cvw::*; #(parameter cvw_t P) (
|
|||
flopenrc #(1) CompressedEReg(clk, reset, FlushE, ~StallE, CompressedD, CompressedE);
|
||||
assign PCLinkE = PCE + (CompressedE ? 'd2 : 'd4); // 'd4 means 4 but stops Design Compiler complaining about signed to unsigned conversion
|
||||
end else begin
|
||||
assign CompressedE = 0;
|
||||
assign CompressedE = 1'b0;
|
||||
assign PCLinkE = PCE + 'd4;
|
||||
end
|
||||
|
||||
|
|
|
@ -95,21 +95,21 @@ 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: if(P.LLEN >= 64) AccessByteOffsetM = {{OFFSET_LEN-3{1'b0}}, IEUAdrM[2:0]}; // double access
|
||||
else AccessByteOffsetM = 0; // shouldn't happen
|
||||
else AccessByteOffsetM = '0; // shouldn't happen
|
||||
3'b100: if(P.LLEN == 128) AccessByteOffsetM = IEUAdrM[OFFSET_LEN-1:0]; // quad access
|
||||
else AccessByteOffsetM = IEUAdrM[OFFSET_LEN-1:0];
|
||||
default: AccessByteOffsetM = 0; // shouldn't happen
|
||||
default: AccessByteOffsetM = '0; // shouldn't happen
|
||||
endcase
|
||||
case (Funct3M[1:0])
|
||||
2'b00: PotentialSpillM = 0; // byte access
|
||||
2'b00: PotentialSpillM = 1'b0; // 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 = 1'b0;
|
||||
endcase
|
||||
end
|
||||
assign MisalignedM = (|MemRWM) & (AccessByteOffsetM != 0);
|
||||
|
@ -148,7 +148,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];
|
||||
|
||||
|
|
|
@ -58,9 +58,9 @@ module lrsc import cvw::*; #(parameter cvw_t P) (
|
|||
assign SquashSCM = scM & ~WriteAdrMatchM;
|
||||
assign LSURWM = SquashSCM ? 2'b00 : PreLSURWM;
|
||||
always_comb begin // ReservationValidM (next value of valid reservation)
|
||||
if (lrM) ReservationValidM = 1; // set valid on load reserve
|
||||
if (lrM) ReservationValidM = 1'b1; // set valid on load reserve
|
||||
// if we implement multiple harts invalidate reservation if another hart stores to this reservation.
|
||||
else if (scM) ReservationValidM = 0; // clear valid on store to same address or any sc
|
||||
else if (scM) ReservationValidM = 1'b0; // clear valid on store to same address or any sc
|
||||
else ReservationValidM = ReservationValidW; // otherwise don't change valid
|
||||
end
|
||||
|
||||
|
|
|
@ -173,12 +173,12 @@ 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 = 1'b0;
|
||||
assign DCacheReadDataWordSpillM = DCacheReadDataWordM;
|
||||
assign ByteMaskSpillM = ByteMaskM;
|
||||
assign LSUWriteDataSpillM = LSUWriteDataM;
|
||||
assign MemRWSpillM = MemRWM;
|
||||
assign {SpillStallM} = 0;
|
||||
assign {SpillStallM} = 1'b0;
|
||||
end
|
||||
|
||||
if(P.ZICBOZ_SUPPORTED) begin : cboz
|
||||
|
@ -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
|
||||
|
@ -287,7 +287,8 @@ module lsu import cvw::*; #(parameter cvw_t P) (
|
|||
.MemRWM(DTIMMemRWM),
|
||||
.DTIMAdr, .FlushW, .WriteDataM(LSUWriteDataM),
|
||||
.ReadDataWordM(DTIMReadDataWordM[P.LLEN-1:0]), .ByteMaskM(ByteMaskM));
|
||||
end
|
||||
end else
|
||||
assign DTIMReadDataWordM = '0;
|
||||
if (P.BUS_SUPPORTED) begin : bus
|
||||
if(P.DCACHE_SUPPORTED) begin : dcache
|
||||
localparam LLENWORDSPERLINE = P.DCACHE_LINELENINBITS/P.LLEN; // Number of LLEN words in cacheline
|
||||
|
@ -316,16 +317,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 = 1'b0;
|
||||
assign CacheCMOpM = '0;
|
||||
assign BusAtomic = 1'b0;
|
||||
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),
|
||||
|
@ -379,14 +380,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;
|
||||
end
|
||||
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;
|
||||
|
@ -400,7 +401,9 @@ module lsu import cvw::*; #(parameter cvw_t P) (
|
|||
.LSUFunct7M, .LSUFunct3M, .LSUAtomicM, .PreLSURWM, .IgnoreRequest,
|
||||
.IMAWriteDataM, .SquashSCW, .LSURWM);
|
||||
end else begin:lrsc
|
||||
assign SquashSCW = 0; assign LSURWM = PreLSURWM; assign IMAWriteDataM = IHWriteDataM;
|
||||
assign SquashSCW = 1'b0;
|
||||
assign LSURWM = PreLSURWM;
|
||||
assign IMAWriteDataM = IHWriteDataM;
|
||||
end
|
||||
|
||||
if (P.F_SUPPORTED)
|
||||
|
|
|
@ -35,6 +35,7 @@ module subwordwrite #(parameter LLEN) (
|
|||
);
|
||||
|
||||
// Replicate data for subword writes
|
||||
|
||||
if (LLEN == 128) begin:sww
|
||||
always_comb
|
||||
case(LSUFunct3M[2:0])
|
||||
|
|
|
@ -34,6 +34,7 @@ module swbytemask #(parameter WORDLEN, EXTEND = 0)(
|
|||
output logic [WORDLEN/8-1:0] ByteMask,
|
||||
output logic [WORDLEN/8-1:0] ByteMaskExtended
|
||||
);
|
||||
|
||||
if(EXTEND) begin
|
||||
logic [WORDLEN*2/8-1:0] ExtendedByteMask;
|
||||
// 'd2 means 2, but stops Design Compiler from complaining about signed to unsigned conversion
|
||||
|
@ -42,7 +43,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
|
||||
|
@ -50,7 +51,7 @@ module swbytemask #(parameter WORDLEN, EXTEND = 0)(
|
|||
if(WORDLEN == 64) begin
|
||||
always_comb begin
|
||||
case(Size[1:0])
|
||||
2'b00: begin ByteMask = 8'b00000000; ByteMask[Adr[2:0]] = 1; end // sb
|
||||
2'b00: begin ByteMask = 8'b00000000; ByteMask[Adr[2:0]] = 1'b1; end // sb
|
||||
2'b01: case (Adr[2:1])
|
||||
2'b00: ByteMask = 8'b0000_0011;
|
||||
2'b01: ByteMask = 8'b0000_1100;
|
||||
|
@ -65,7 +66,7 @@ module swbytemask #(parameter WORDLEN, EXTEND = 0)(
|
|||
end else begin
|
||||
always_comb begin
|
||||
case(Size[1:0])
|
||||
2'b00: begin ByteMask = 4'b0000; ByteMask[Adr[1:0]] = 1; end // sb
|
||||
2'b00: begin ByteMask = 4'b0000; ByteMask[Adr[1:0]] = 1'b1; end // sb
|
||||
2'b01: if (Adr[1]) ByteMask = 4'b1100;
|
||||
else ByteMask = 4'b0011;
|
||||
2'b10: ByteMask = 4'b1111;
|
||||
|
|
|
@ -59,9 +59,9 @@ module mdu import cvw::*; #(parameter cvw_t P) (
|
|||
// When IDIV_ON_FPU is set, use the FPU divider instead
|
||||
// In ZMMUL, with M_SUPPORTED = 0, omit the divider
|
||||
if ((P.IDIV_ON_FPU & P.F_SUPPORTED) || (!P.M_SUPPORTED)) begin:nodiv
|
||||
assign QuotM = 0;
|
||||
assign RemM = 0;
|
||||
assign DivBusyE = 0;
|
||||
assign QuotM = '0;
|
||||
assign RemM = '0;
|
||||
assign DivBusyE = 1'b0;
|
||||
end else begin:div
|
||||
div #(P) div(.clk, .reset, .StallM, .FlushE, .DivSignedE(~Funct3E[0]), .W64E, .IntDivE,
|
||||
.ForwardedSrcAE, .ForwardedSrcBE, .DivBusyE, .QuotM, .RemM);
|
||||
|
|
|
@ -213,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 = 1'b0;
|
||||
assign UpdatePTE = 1'b0;
|
||||
assign HPTWRW[0] = 1'b0;
|
||||
end
|
||||
|
||||
// Enable and select signals based on states
|
||||
|
|
|
@ -93,10 +93,10 @@ module mmu import cvw::*; #(parameter cvw_t P,
|
|||
.TLBWrite, .TLBFlush, .TLBPAdr, .TLBMiss, .TLBHit,
|
||||
.Translate, .TLBPageFault, .UpdateDA, .PBMemoryType);
|
||||
end else begin:tlb // just pass address through as physical
|
||||
assign Translate = 0;
|
||||
assign TLBMiss = 0;
|
||||
assign TLBHit = 1; // *** is this necessary
|
||||
assign TLBPageFault = 0;
|
||||
assign Translate = 1'b0;
|
||||
assign TLBMiss = 1'b0;
|
||||
assign TLBHit = 1'b1; // *** is this necessary
|
||||
assign TLBPageFault = 1'b0;
|
||||
assign PBMemoryType = 2'b00;
|
||||
end
|
||||
|
||||
|
@ -121,9 +121,9 @@ module mmu import cvw::*; #(parameter cvw_t P,
|
|||
.ExecuteAccessF, .WriteAccessM, .ReadAccessM, .CMOpM,
|
||||
.PMPInstrAccessFaultF, .PMPLoadAccessFaultM, .PMPStoreAmoAccessFaultM);
|
||||
end else begin
|
||||
assign PMPInstrAccessFaultF = 0;
|
||||
assign PMPStoreAmoAccessFaultM = 0;
|
||||
assign PMPLoadAccessFaultM = 0;
|
||||
assign PMPInstrAccessFaultF = 1'b0;
|
||||
assign PMPStoreAmoAccessFaultM = 1'b0;
|
||||
assign PMPLoadAccessFaultM = 1'b0;
|
||||
end
|
||||
|
||||
assign ReadNoAmoAccessM = ReadAccessM & ~WriteAccessM;// AMO causes StoreAmo rather than Load fault
|
||||
|
@ -132,7 +132,7 @@ module mmu import cvw::*; #(parameter cvw_t P,
|
|||
// Misaligned faults
|
||||
always_comb // exclusion-tag: immu-wordaccess
|
||||
case(Size[1:0])
|
||||
2'b00: DataMisalignedM = 0; // lb, sb, lbu
|
||||
2'b00: DataMisalignedM = 1'b0; // lb, sb, lbu
|
||||
2'b01: DataMisalignedM = VAdr[0]; // lh, sh, lhu
|
||||
2'b10: DataMisalignedM = VAdr[1] | VAdr[0]; // lw, sw, flw, fsw, lwu
|
||||
2'b11: DataMisalignedM = |VAdr[2:0]; // ld, sd, fld, fsd
|
||||
|
|
|
@ -60,7 +60,7 @@ module pmachecker import cvw::*; #(parameter cvw_t P) (
|
|||
|
||||
// Only non-core RAM/ROM memory regions are cacheable. PBMT can override cachable; NC and IO are uncachable
|
||||
assign CacheableRegion = SelRegions[3] | SelRegions[4] | SelRegions[5]; // exclusion-tag: unused-cachable
|
||||
assign Cacheable = (PBMemoryType == 2'b00) ? CacheableRegion : 0;
|
||||
assign Cacheable = (PBMemoryType == 2'b00) ? CacheableRegion : 1'b0;
|
||||
|
||||
// Nonidemdempotent means access could have side effect and must not be done speculatively or redundantly
|
||||
// I/O is nonidempotent. PBMT can override PMA; NC is idempotent and IO is non-idempotent
|
||||
|
|
|
@ -77,7 +77,7 @@ module pmpadrdec import cvw::*; #(parameter cvw_t P) (
|
|||
|
||||
assign Match = (AdrMode == TOR) ? TORMatch :
|
||||
(AdrMode == NA4 | AdrMode == NAPOT) ? NAMatch :
|
||||
0;
|
||||
1'b0;
|
||||
|
||||
assign L = PMPCfg[7];
|
||||
assign X = PMPCfg[2];
|
||||
|
|
|
@ -43,7 +43,7 @@ module vm64check import cvw::*; #(parameter cvw_t P) (
|
|||
assign eq_63_47 = &(VAdr[63:47]) | ~|(VAdr[63:47]);
|
||||
assign UpperBitsUnequal = SV39Mode ? ~(eq_63_47 & eq_46_38) : ~eq_63_47;
|
||||
end else begin
|
||||
assign SV39Mode = 0;
|
||||
assign UpperBitsUnequal = 0;
|
||||
assign SV39Mode = 1'b0;
|
||||
assign UpperBitsUnequal = 1'b0;
|
||||
end
|
||||
endmodule
|
||||
|
|
|
@ -138,12 +138,12 @@ module csr import cvw::*; #(parameter cvw_t P) (
|
|||
///////////////////////////////////////////
|
||||
|
||||
always_comb
|
||||
if (InterruptM) NextFaultMtvalM = 0;
|
||||
if (InterruptM) NextFaultMtvalM = '0;
|
||||
else case (CauseM)
|
||||
12, 1, 3: NextFaultMtvalM = PCM; // Instruction page/access faults, breakpoint
|
||||
2: NextFaultMtvalM = {{(P.XLEN-32){1'b0}}, InstrOrigM}; // Illegal instruction fault
|
||||
0, 4, 6, 13, 15, 5, 7: NextFaultMtvalM = IEUAdrM; // Instruction misaligned, Load/Store Misaligned/page/access faults
|
||||
default: NextFaultMtvalM = 0; // Ecall, interrupts
|
||||
default: NextFaultMtvalM = '0; // Ecall, interrupts
|
||||
endcase
|
||||
|
||||
///////////////////////////////////////////
|
||||
|
@ -252,13 +252,13 @@ module csr import cvw::*; #(parameter cvw_t P) (
|
|||
.SATP_REGW, .MIP_REGW, .MIE_REGW, .MIDELEG_REGW, .MTIME_CLINT, .STCE,
|
||||
.WriteSSTATUSM, .IllegalCSRSAccessM, .STimerInt, .SENVCFG_REGW);
|
||||
end else begin
|
||||
assign WriteSSTATUSM = 0;
|
||||
assign CSRSReadValM = 0;
|
||||
assign SEPC_REGW = 0;
|
||||
assign STVEC_REGW = 0;
|
||||
assign SCOUNTEREN_REGW = 0;
|
||||
assign SATP_REGW = 0;
|
||||
assign IllegalCSRSAccessM = 1;
|
||||
assign WriteSSTATUSM = 1'b0;
|
||||
assign CSRSReadValM = '0;
|
||||
assign SEPC_REGW = '0;
|
||||
assign STVEC_REGW = '0;
|
||||
assign SCOUNTEREN_REGW = '0;
|
||||
assign SATP_REGW = '0;
|
||||
assign IllegalCSRSAccessM = 1'b1;
|
||||
end
|
||||
|
||||
// Floating Point CSRs in User Mode only needed if Floating Point is supported
|
||||
|
@ -268,9 +268,9 @@ module csr import cvw::*; #(parameter cvw_t P) (
|
|||
.SetFflagsM, .FRM_REGW, .WriteFRMM, .WriteFFLAGSM,
|
||||
.IllegalCSRUAccessM);
|
||||
end else begin
|
||||
assign FRM_REGW = 0;
|
||||
assign CSRUReadValM = 0;
|
||||
assign IllegalCSRUAccessM = 1;
|
||||
assign FRM_REGW = '0;
|
||||
assign CSRUReadValM = '0;
|
||||
assign IllegalCSRUAccessM = 1'b1;
|
||||
end
|
||||
|
||||
if (P.ZICNTR_SUPPORTED) begin:counters
|
||||
|
@ -283,8 +283,8 @@ module csr import cvw::*; #(parameter cvw_t P) (
|
|||
.MCOUNTINHIBIT_REGW, .MCOUNTEREN_REGW, .SCOUNTEREN_REGW,
|
||||
.MTIME_CLINT, .CSRCReadValM, .IllegalCSRCAccessM);
|
||||
end else begin
|
||||
assign CSRCReadValM = 0;
|
||||
assign IllegalCSRCAccessM = 1; // counters aren't enabled
|
||||
assign CSRCReadValM = '0;
|
||||
assign IllegalCSRCAccessM = 1'b1; // counters aren't enabled
|
||||
end
|
||||
|
||||
// Broadcast appropriate environment configuration based on privilege mode
|
||||
|
|
|
@ -120,9 +120,9 @@ module csrc import cvw::*; #(parameter cvw_t P) (
|
|||
// DivBusyE will never be assert high since this configuration uses the FPU to do integer division
|
||||
assign CounterEvent[24] = DivBusyE | FDivBusyE; // division cycles *** RT: might need to be delay until the next cycle
|
||||
// coverage on
|
||||
assign CounterEvent[P.COUNTERS-1:25] = 0; // eventually give these sources, including FP instructions, I$/D$ misses, branches and mispredictions
|
||||
assign CounterEvent[P.COUNTERS-1:25] = '0; // eventually give these sources, including FP instructions, I$/D$ misses, branches and mispredictions
|
||||
end else begin: cevent
|
||||
assign CounterEvent[P.COUNTERS-1:3] = 0;
|
||||
assign CounterEvent[P.COUNTERS-1:3] = '0;
|
||||
end
|
||||
|
||||
// Counter update and write logic
|
||||
|
@ -130,7 +130,7 @@ module csrc import cvw::*; #(parameter cvw_t P) (
|
|||
assign WriteHPMCOUNTERM[i] = CSRMWriteM & (CSRAdrM == MHPMCOUNTERBASE + i);
|
||||
assign NextHPMCOUNTERM[i][P.XLEN-1:0] = WriteHPMCOUNTERM[i] ? CSRWriteValM : HPMCOUNTERPlusM[i][P.XLEN-1:0];
|
||||
always_ff @(posedge clk) //, posedge reset) // ModelSim doesn't like syntax of passing array element to flop
|
||||
if (reset) HPMCOUNTER_REGW[i][P.XLEN-1:0] <= 0;
|
||||
if (reset) HPMCOUNTER_REGW[i][P.XLEN-1:0] <= '0;
|
||||
else HPMCOUNTER_REGW[i][P.XLEN-1:0] <= NextHPMCOUNTERM[i];
|
||||
|
||||
if (P.XLEN==32) begin // write high and low separately
|
||||
|
@ -140,10 +140,11 @@ module csrc import cvw::*; #(parameter cvw_t P) (
|
|||
assign WriteHPMCOUNTERHM[i] = CSRMWriteM & (CSRAdrM == MHPMCOUNTERHBASE + i);
|
||||
assign NextHPMCOUNTERHM[i] = WriteHPMCOUNTERHM[i] ? CSRWriteValM : HPMCOUNTERPlusM[i][63:32];
|
||||
always_ff @(posedge clk) //, posedge reset) // ModelSim doesn't like syntax of passing array element to flop
|
||||
if (reset) HPMCOUNTERH_REGW[i][P.XLEN-1:0] <= 0;
|
||||
if (reset) HPMCOUNTERH_REGW[i][P.XLEN-1:0] <= '0;
|
||||
else HPMCOUNTERH_REGW[i][P.XLEN-1:0] <= NextHPMCOUNTERHM[i];
|
||||
end else begin // XLEN=64; write entire register
|
||||
assign HPMCOUNTERPlusM[i] = HPMCOUNTER_REGW[i] + {63'b0, CounterEvent[i] & ~MCOUNTINHIBIT_REGW[i]};
|
||||
assign HPMCOUNTERH_REGW[i] = '0; // disregard for RV64
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -152,7 +153,7 @@ module csrc import cvw::*; #(parameter cvw_t P) (
|
|||
always_comb
|
||||
if (PrivilegeModeW == P.M_MODE |
|
||||
MCOUNTEREN_REGW[CounterNumM] & (!P.S_SUPPORTED | PrivilegeModeW == P.S_MODE | SCOUNTEREN_REGW[CounterNumM])) begin
|
||||
IllegalCSRCAccessM = 0;
|
||||
IllegalCSRCAccessM = 1'b0;
|
||||
if (P.XLEN==64) begin // 64-bit counter reads
|
||||
// Veri lator doesn't realize this only occurs for XLEN=64
|
||||
/* verilator lint_off WIDTH */
|
||||
|
@ -163,8 +164,8 @@ module csrc import cvw::*; #(parameter cvw_t P) (
|
|||
else if (CSRAdrM >= HPMCOUNTERBASE & CSRAdrM < HPMCOUNTERBASE+P.COUNTERS)
|
||||
CSRCReadValM = HPMCOUNTER_REGW[CounterNumM];
|
||||
else begin
|
||||
CSRCReadValM = 0;
|
||||
IllegalCSRCAccessM = 1; // requested CSR doesn't exist
|
||||
CSRCReadValM = '0;
|
||||
IllegalCSRCAccessM = 1'b1; // requested CSR doesn't exist
|
||||
end
|
||||
end else begin // 32-bit counter reads
|
||||
// Veril ator doesn't realize this only occurs for XLEN=32
|
||||
|
@ -181,13 +182,13 @@ module csrc import cvw::*; #(parameter cvw_t P) (
|
|||
else if (CSRAdrM >= HPMCOUNTERHBASE & CSRAdrM < HPMCOUNTERHBASE+P.COUNTERS)
|
||||
CSRCReadValM = HPMCOUNTERH_REGW[CounterNumM];
|
||||
else begin
|
||||
CSRCReadValM = 0;
|
||||
IllegalCSRCAccessM = 1; // requested CSR doesn't exist
|
||||
CSRCReadValM = '0;
|
||||
IllegalCSRCAccessM = 1'b1; // requested CSR doesn't exist
|
||||
end
|
||||
end
|
||||
end else begin
|
||||
CSRCReadValM = 0;
|
||||
IllegalCSRCAccessM = 1; // no privileges for this csr
|
||||
CSRCReadValM = '0;
|
||||
IllegalCSRCAccessM = 1'b1; // no privileges for this csr
|
||||
end
|
||||
endmodule
|
||||
|
||||
|
|
|
@ -132,7 +132,7 @@ module csrm import cvw::*; #(parameter cvw_t P) (
|
|||
assign MISA_REGW = {(P.XLEN == 32 ? 2'b01 : 2'b10), {(P.XLEN-28){1'b0}}, MISA_26[25:0]};
|
||||
|
||||
// MHARTID is hardwired. It only exists as a signal so that the testbench can easily see it.
|
||||
assign MHARTID_REGW = 0;
|
||||
assign MHARTID_REGW = '0;
|
||||
|
||||
// Write machine Mode CSRs
|
||||
assign WriteMSTATUSM = CSRMWriteM & (CSRAdrM == MSTATUS);
|
||||
|
@ -154,7 +154,7 @@ module csrm import cvw::*; #(parameter cvw_t P) (
|
|||
if (P.S_SUPPORTED) begin:deleg // DELEG registers should exist
|
||||
flopenr #(16) MEDELEGreg(clk, reset, WriteMEDELEGM, CSRWriteValM[15:0] & MEDELEG_MASK, MEDELEG_REGW);
|
||||
flopenr #(12) MIDELEGreg(clk, reset, WriteMIDELEGM, CSRWriteValM[11:0] & MIDELEG_MASK, MIDELEG_REGW);
|
||||
end else assign {MEDELEG_REGW, MIDELEG_REGW} = 0;
|
||||
end else assign {MEDELEG_REGW, MIDELEG_REGW} = '0;
|
||||
|
||||
flopenr #(P.XLEN) MSCRATCHreg(clk, reset, WriteMSCRATCHM, CSRWriteValM, MSCRATCH_REGW);
|
||||
flopenr #(P.XLEN) MEPCreg(clk, reset, WriteMEPCM, NextEPCM, MEPC_REGW);
|
||||
|
@ -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
|
||||
|
@ -184,7 +184,7 @@ module csrm import cvw::*; #(parameter cvw_t P) (
|
|||
if (P.XLEN == 64) begin
|
||||
assign MENVCFG_PreWriteValM = CSRWriteValM;
|
||||
flopenr #(P.XLEN) MENVCFGreg(clk, reset, WriteMENVCFGM, MENVCFG_WriteValM, MENVCFG_REGW);
|
||||
assign MENVCFGH_REGW = 0;
|
||||
assign MENVCFGH_REGW = '0;
|
||||
end else begin // RV32 has high and low halves
|
||||
logic WriteMENVCFGHM;
|
||||
assign MENVCFG_PreWriteValM = {CSRWriteValM, CSRWriteValM};
|
||||
|
@ -199,8 +199,8 @@ module csrm import cvw::*; #(parameter cvw_t P) (
|
|||
// verilator lint_off WIDTH
|
||||
logic [5:0] entry;
|
||||
always_comb begin
|
||||
entry = 0;
|
||||
CSRMReadValM = 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
|
||||
CSRMReadValM = {{(P.XLEN-(P.PA_BITS-2)){1'b0}}, PMPADDR_ARRAY_REGW[CSRAdrM - PMPADDR0]};
|
||||
|
@ -221,10 +221,10 @@ module csrm import cvw::*; #(parameter cvw_t P) (
|
|||
MARCHID: CSRMReadValM = {{(P.XLEN-32){1'b0}}, 32'h24}; // 36 for CV-Wally
|
||||
MIMPID: CSRMReadValM = {{P.XLEN-12{1'b0}}, 12'h100}; // pipelined implementation
|
||||
MHARTID: CSRMReadValM = MHARTID_REGW; // hardwired to 0
|
||||
MCONFIGPTR: CSRMReadValM = 0; // hardwired to 0
|
||||
MCONFIGPTR: CSRMReadValM = '0; // hardwired to 0
|
||||
MSTATUS: CSRMReadValM = MSTATUS_REGW;
|
||||
MSTATUSH: if (P.XLEN==32) CSRMReadValM = MSTATUSH_REGW;
|
||||
else IllegalCSRMAccessM = 1;
|
||||
else IllegalCSRMAccessM = 1'b1;
|
||||
MTVEC: CSRMReadValM = MTVEC_REGW;
|
||||
MEDELEG: CSRMReadValM = {{(P.XLEN-16){1'b0}}, MEDELEG_REGW};
|
||||
MIDELEG: CSRMReadValM = {{(P.XLEN-12){1'b0}}, MIDELEG_REGW};
|
||||
|
@ -236,11 +236,11 @@ module csrm import cvw::*; #(parameter cvw_t P) (
|
|||
MTVAL: CSRMReadValM = MTVAL_REGW;
|
||||
MCOUNTEREN: CSRMReadValM = {{(P.XLEN-32){1'b0}}, MCOUNTEREN_REGW};
|
||||
MENVCFG: if (P.U_SUPPORTED) CSRMReadValM = MENVCFG_REGW[P.XLEN-1:0];
|
||||
else IllegalCSRMAccessM = 1;
|
||||
else IllegalCSRMAccessM = 1'b1;
|
||||
MENVCFGH: if (P.U_SUPPORTED & P.XLEN==32) CSRMReadValM = MENVCFGH_REGW;
|
||||
else IllegalCSRMAccessM = 1;
|
||||
else IllegalCSRMAccessM = 1'b1;
|
||||
MCOUNTINHIBIT: CSRMReadValM = {{(P.XLEN-32){1'b0}}, MCOUNTINHIBIT_REGW};
|
||||
default: IllegalCSRMAccessM = 1;
|
||||
default: IllegalCSRMAccessM = 1'b1;
|
||||
endcase
|
||||
end
|
||||
// verilator lint_on WIDTH
|
||||
|
|
|
@ -108,7 +108,7 @@ module csrs import cvw::*; #(parameter cvw_t P) (
|
|||
if (P.VIRTMEM_SUPPORTED)
|
||||
flopenr #(P.XLEN) SATPreg(clk, reset, WriteSATPM, CSRWriteValM, SATP_REGW);
|
||||
else
|
||||
assign SATP_REGW = 0; // hardwire to zero if virtual memory not supported
|
||||
assign SATP_REGW = '0; // hardwire to zero if virtual memory not supported
|
||||
flopenr #(32) SCOUNTERENreg(clk, reset, WriteSCOUNTERENM, CSRWriteValM[31:0], SCOUNTEREN_REGW);
|
||||
if (P.SSTC_SUPPORTED) begin : sstc
|
||||
if (P.XLEN == 64) begin : sstc64
|
||||
|
@ -117,14 +117,14 @@ module csrs import cvw::*; #(parameter cvw_t P) (
|
|||
flopenr #(P.XLEN) STIMECMPreg(clk, reset, WriteSTIMECMPM, CSRWriteValM, STIMECMP_REGW[31:0]);
|
||||
flopenr #(P.XLEN) STIMECMPHreg(clk, reset, WriteSTIMECMPHM, CSRWriteValM, STIMECMP_REGW[63:32]);
|
||||
end
|
||||
end else assign STIMECMP_REGW = 0;
|
||||
end else assign STIMECMP_REGW = '0;
|
||||
|
||||
// Supervisor timer interrupt logic
|
||||
// Spec is a bit peculiar - Machine timer interrupts are produced in CLINT, while Supervisor timer interrupts are in CSRs
|
||||
if (P.SSTC_SUPPORTED)
|
||||
assign STimerInt = ({1'b0, MTIME_CLINT} >= {1'b0, STIMECMP_REGW}); // unsigned comparison
|
||||
else
|
||||
assign STimerInt = 0;
|
||||
assign STimerInt = 1'b0;
|
||||
|
||||
assign SENVCFG_WriteValM = {
|
||||
{(P.XLEN-8){1'b0}},
|
||||
|
@ -138,7 +138,7 @@ module csrs import cvw::*; #(parameter cvw_t P) (
|
|||
|
||||
// CSR Reads
|
||||
always_comb begin:csrr
|
||||
IllegalCSRSAccessM = 0;
|
||||
IllegalCSRSAccessM = 1'b0;
|
||||
case (CSRAdrM)
|
||||
SSTATUS: CSRSReadValM = SSTATUS_REGW;
|
||||
STVEC: CSRSReadValM = STVEC_REGW;
|
||||
|
@ -150,26 +150,26 @@ module csrs import cvw::*; #(parameter cvw_t P) (
|
|||
STVAL: CSRSReadValM = STVAL_REGW;
|
||||
SATP: if (P.VIRTMEM_SUPPORTED & (PrivilegeModeW == P.M_MODE | ~STATUS_TVM)) CSRSReadValM = SATP_REGW;
|
||||
else begin
|
||||
CSRSReadValM = 0;
|
||||
IllegalCSRSAccessM = 1;
|
||||
CSRSReadValM = '0;
|
||||
IllegalCSRSAccessM = 1'b1;
|
||||
end
|
||||
SCOUNTEREN:CSRSReadValM = {{(P.XLEN-32){1'b0}}, SCOUNTEREN_REGW};
|
||||
SENVCFG: CSRSReadValM = SENVCFG_REGW;
|
||||
STIMECMP: if (STCE)
|
||||
CSRSReadValM = STIMECMP_REGW[P.XLEN-1:0];
|
||||
else begin
|
||||
CSRSReadValM = 0;
|
||||
IllegalCSRSAccessM = 1;
|
||||
CSRSReadValM = '0;
|
||||
IllegalCSRSAccessM = 1'b1;
|
||||
end
|
||||
STIMECMPH: if (STCE & P.XLEN == 32) // not supported for RV64
|
||||
CSRSReadValM = {{(P.XLEN-32){1'b0}}, STIMECMP_REGW[63:32]};
|
||||
else begin
|
||||
CSRSReadValM = 0;
|
||||
IllegalCSRSAccessM = 1;
|
||||
CSRSReadValM = '0;
|
||||
IllegalCSRSAccessM = 1'b1;
|
||||
end
|
||||
default: begin
|
||||
CSRSReadValM = 0;
|
||||
IllegalCSRSAccessM = 1;
|
||||
CSRSReadValM = '0;
|
||||
IllegalCSRSAccessM = 1'b1;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
|
|
@ -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,
|
||||
|
@ -89,14 +89,11 @@ module csrsr import cvw::*; #(parameter cvw_t P) (
|
|||
assign nextSBE = STATUS_SBE;
|
||||
end
|
||||
|
||||
// harwired STATUS bits
|
||||
// hardwired STATUS bits
|
||||
assign STATUS_TSR = P.S_SUPPORTED & STATUS_TSR_INT; // override reigster with 0 if supervisor mode not supported
|
||||
assign STATUS_TW = (P.S_SUPPORTED | P.U_SUPPORTED) & STATUS_TW_INT; // override register with 0 if only machine mode supported
|
||||
assign STATUS_TVM = P.S_SUPPORTED & STATUS_TVM_INT; // override reigster with 0 if supervisor mode not supported
|
||||
assign STATUS_MXR = P.S_SUPPORTED & STATUS_MXR_INT; // override reigster with 0 if supervisor mode not supported
|
||||
/* assign STATUS_UBE = 0; // little-endian
|
||||
assign STATUS_SBE = 0; // little-endian
|
||||
assign STATUS_MBE = 0; // little-endian */
|
||||
// SXL and UXL bits only matter for RV64. Set to 10 for RV64 if mode is supported, or 0 if not
|
||||
assign STATUS_SXL = P.S_SUPPORTED ? 2'b10 : 2'b00; // 10 if supervisor mode supported
|
||||
assign STATUS_UXL = P.U_SUPPORTED ? 2'b10 : 2'b00; // 10 if user mode supported
|
||||
|
@ -133,29 +130,29 @@ module csrsr import cvw::*; #(parameter cvw_t P) (
|
|||
endcase
|
||||
end
|
||||
end else begin: endianmux
|
||||
assign BigEndianM = 0;
|
||||
assign BigEndianM = 1'b0;
|
||||
end
|
||||
|
||||
// registers for STATUS bits
|
||||
// complex register with reset, write enable, and the ability to update other bits in certain cases
|
||||
always_ff @(posedge clk) //, posedge reset)
|
||||
if (reset) begin
|
||||
STATUS_TSR_INT <= 0;
|
||||
STATUS_TW_INT <= 0;
|
||||
STATUS_TVM_INT <= 0;
|
||||
STATUS_MXR_INT <= 0;
|
||||
STATUS_SUM_INT <= 0;
|
||||
STATUS_MPRV_INT <= 0; // Per Priv 3.3
|
||||
STATUS_FS_INT <= P.F_SUPPORTED ? 2'b00 : 2'b00; // leave floating-point off until activated, even if F_SUPPORTED
|
||||
STATUS_MPP <= 0;
|
||||
STATUS_SPP <= 0;
|
||||
STATUS_MPIE <= 0;
|
||||
STATUS_SPIE <= 0;
|
||||
STATUS_MIE <= 0;
|
||||
STATUS_SIE <= 0;
|
||||
STATUS_MBE <= 0;
|
||||
STATUS_SBE <= 0;
|
||||
STATUS_UBE <= 0;
|
||||
STATUS_TSR_INT <= 1'b0;
|
||||
STATUS_TW_INT <= 1'b0;
|
||||
STATUS_TVM_INT <= 1'b0;
|
||||
STATUS_MXR_INT <= 1'b0;
|
||||
STATUS_SUM_INT <= 1'b0;
|
||||
STATUS_MPRV_INT <= 1'b0; // Per Priv 3.3
|
||||
STATUS_FS_INT <= 2'b00; // leave floating-point off until activated, even if F_SUPPORTED
|
||||
STATUS_MPP <= 2'b00;
|
||||
STATUS_SPP <= 1'b0;
|
||||
STATUS_MPIE <= 1'b0;
|
||||
STATUS_SPIE <= 1'b0;
|
||||
STATUS_MIE <= 1'b0;
|
||||
STATUS_SIE <= 1'b0;
|
||||
STATUS_MBE <=1'b 0;
|
||||
STATUS_SBE <= 1'b0;
|
||||
STATUS_UBE <= 1'b0;
|
||||
end else if (~StallW) begin
|
||||
if (TrapM) begin
|
||||
// Update interrupt enables per Privileged Spec p. 21
|
||||
|
@ -164,23 +161,23 @@ module csrsr import cvw::*; #(parameter cvw_t P) (
|
|||
// Modes: 11 = Machine, 01 = Supervisor, 00 = User
|
||||
if (NextPrivilegeModeM == P.M_MODE) begin
|
||||
STATUS_MPIE <= STATUS_MIE;
|
||||
STATUS_MIE <= 0;
|
||||
STATUS_MIE <= 1'b0;
|
||||
STATUS_MPP <= PrivilegeModeW;
|
||||
end else begin // supervisor mode
|
||||
STATUS_SPIE <= STATUS_SIE;
|
||||
STATUS_SIE <= 0;
|
||||
STATUS_SIE <= 1'b0;
|
||||
STATUS_SPP <= PrivilegeModeW[0];
|
||||
end
|
||||
end else if (mretM) begin // Privileged 3.1.6.1
|
||||
STATUS_MIE <= STATUS_MPIE; // restore global interrupt enable
|
||||
STATUS_MPIE <= 1; //
|
||||
STATUS_MPIE <= 1'b1; //
|
||||
STATUS_MPP <= P.U_SUPPORTED ? P.U_MODE : P.M_MODE; // set MPP to lowest supported privilege level
|
||||
STATUS_MPRV_INT <= STATUS_MPRV_INT & (STATUS_MPP == P.M_MODE); // page 21 of privileged spec.
|
||||
end else if (sretM) begin
|
||||
STATUS_SIE <= STATUS_SPIE; // restore global interrupt enable
|
||||
STATUS_SPIE <= P.S_SUPPORTED;
|
||||
STATUS_SPP <= 0; // set SPP to lowest supported privilege level to catch bugs
|
||||
STATUS_MPRV_INT <= 0; // always clear MPRV
|
||||
STATUS_SPP <= 1'b0; // set SPP to lowest supported privilege level to catch bugs
|
||||
STATUS_MPRV_INT <= 1'b0; // always clear MPRV
|
||||
end else if (WriteMSTATUSM) begin
|
||||
STATUS_TSR_INT <= CSRWriteValM[22];
|
||||
STATUS_TW_INT <= CSRWriteValM[21];
|
||||
|
|
|
@ -66,17 +66,17 @@ module csru import cvw::*; #(parameter cvw_t P) (
|
|||
// CSR Reads
|
||||
always_comb begin
|
||||
if (STATUS_FS == 2'b00) begin // fpu disabled, trap
|
||||
IllegalCSRUAccessM = 1;
|
||||
CSRUReadValM = 0;
|
||||
IllegalCSRUAccessM = 1'b1;
|
||||
CSRUReadValM = '0;
|
||||
end else begin
|
||||
IllegalCSRUAccessM = 0;
|
||||
IllegalCSRUAccessM = 1'b0;
|
||||
case (CSRAdrM)
|
||||
FFLAGS: CSRUReadValM = {{(P.XLEN-5){1'b0}}, FFLAGS_REGW};
|
||||
FRM: CSRUReadValM = {{(P.XLEN-3){1'b0}}, FRM_REGW};
|
||||
FCSR: CSRUReadValM = {{(P.XLEN-8){1'b0}}, FRM_REGW, FFLAGS_REGW};
|
||||
default: begin
|
||||
CSRUReadValM = 0;
|
||||
IllegalCSRUAccessM = 1;
|
||||
CSRUReadValM = '0;
|
||||
IllegalCSRUAccessM = 1'b1;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
|
|
@ -86,7 +86,7 @@ module privdec import cvw::*; #(parameter cvw_t P) (
|
|||
// WFI Timout trap will not occur when STATUS_TW is low while in supervisor mode, so the system gets stuck waiting for an interrupt and triggers a watchdog timeout.
|
||||
assign WFITimeoutM = ((STATUS_TW & PrivilegeModeW != P.M_MODE) | (P.S_SUPPORTED & PrivilegeModeW == P.U_MODE)) & WFICount[P.WFI_TIMEOUT_BIT];
|
||||
// coverage on
|
||||
end else assign WFITimeoutM = 0;
|
||||
end else assign WFITimeoutM = 1'b0;
|
||||
|
||||
flopenrc #(1) wfiWReg(clk, reset, FlushW, ~StallW, wfiM, wfiW);
|
||||
|
||||
|
|
|
@ -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 = (MIntGlobalEnM ? PendingIntsM & ~MIDELEG_REGW : 0) | (SIntGlobalEnM ? PendingIntsM & MIDELEG_REGW : 0);
|
||||
assign ValidIntsM = Committed ? 0 : 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]) &
|
||||
|
@ -95,29 +95,29 @@ module trap import cvw::*; #(parameter cvw_t P) (
|
|||
///////////////////////////////////////////
|
||||
|
||||
always_comb
|
||||
if (reset) CauseM = 0; // hard reset 3.3
|
||||
else if (ValidIntsM[11]) CauseM = 11; // Machine External Int
|
||||
else if (ValidIntsM[3]) CauseM = 3; // Machine Sw Int
|
||||
else if (ValidIntsM[7]) CauseM = 7; // Machine Timer Int
|
||||
else if (ValidIntsM[9]) CauseM = 9; // Supervisor External Int
|
||||
else if (ValidIntsM[1]) CauseM = 1; // Supervisor Sw Int
|
||||
else if (ValidIntsM[5]) CauseM = 5; // Supervisor Timer Int
|
||||
else if (BothInstrPageFaultM) CauseM = 12;
|
||||
else if (BothInstrAccessFaultM) CauseM = 1;
|
||||
else if (IllegalInstrFaultM) CauseM = 2;
|
||||
if (reset) CauseM = 4'd0; // hard reset 3.3
|
||||
else if (ValidIntsM[11]) CauseM = 4'd11; // Machine External Int
|
||||
else if (ValidIntsM[3]) CauseM = 4'd3; // Machine Sw Int
|
||||
else if (ValidIntsM[7]) CauseM = 4'd7; // Machine Timer Int
|
||||
else if (ValidIntsM[9]) CauseM = 4'd9; // Supervisor External Int
|
||||
else if (ValidIntsM[1]) CauseM = 4'd1; // Supervisor Sw Int
|
||||
else if (ValidIntsM[5]) CauseM = 4'd5; // Supervisor Timer Int
|
||||
else if (BothInstrPageFaultM) CauseM = 4'd12;
|
||||
else if (BothInstrAccessFaultM) CauseM = 4'd1;
|
||||
else if (IllegalInstrFaultM) CauseM = 4'd2;
|
||||
// coverage off
|
||||
// Misaligned instructions cannot occur in rv64gc
|
||||
else if (InstrMisalignedFaultM) CauseM = 0;
|
||||
else if (InstrMisalignedFaultM) CauseM = 4'd0;
|
||||
// coverage on
|
||||
else if (BreakpointFaultM) CauseM = 3;
|
||||
else if (BreakpointFaultM) CauseM = 4'd3;
|
||||
else if (EcallFaultM) CauseM = {2'b10, PrivilegeModeW};
|
||||
else if (StoreAmoMisalignedFaultM & ~P.ZICCLSM_SUPPORTED) CauseM = 6; // misaligned faults are higher priority if they always are taken
|
||||
else if (LoadMisalignedFaultM & ~P.ZICCLSM_SUPPORTED) CauseM = 4;
|
||||
else if (StoreAmoPageFaultM) CauseM = 15;
|
||||
else if (LoadPageFaultM) CauseM = 13;
|
||||
else if (StoreAmoAccessFaultM) CauseM = 7;
|
||||
else if (LoadAccessFaultM) CauseM = 5;
|
||||
else if (StoreAmoMisalignedFaultM & P.ZICCLSM_SUPPORTED) CauseM = 6; // See priority in Privileged Spec 3.1.15
|
||||
else if (LoadMisalignedFaultM & P.ZICCLSM_SUPPORTED) CauseM = 4;
|
||||
else CauseM = 0;
|
||||
else if (StoreAmoMisalignedFaultM & ~P.ZICCLSM_SUPPORTED) CauseM = 4'd6; // misaligned faults are higher priority if they always are taken
|
||||
else if (LoadMisalignedFaultM & ~P.ZICCLSM_SUPPORTED) CauseM = 4'd4;
|
||||
else if (StoreAmoPageFaultM) CauseM = 4'd15;
|
||||
else if (LoadPageFaultM) CauseM = 4'd13;
|
||||
else if (StoreAmoAccessFaultM) CauseM = 4'd7;
|
||||
else if (LoadAccessFaultM) CauseM = 4'd5;
|
||||
else if (StoreAmoMisalignedFaultM & P.ZICCLSM_SUPPORTED) CauseM = 4'd6; // See priority in Privileged Spec 3.1.15
|
||||
else if (LoadMisalignedFaultM & P.ZICCLSM_SUPPORTED) CauseM = 4'd4;
|
||||
else CauseM = 4'd0;
|
||||
endmodule
|
||||
|
|
|
@ -89,7 +89,7 @@ module ahbapbbridge import cvw::*; #(parameter cvw_t P,
|
|||
int i;
|
||||
always_comb begin
|
||||
// default: no peripheral selected: read 0, indicate ready during access phase so bus doesn't hang
|
||||
HRDATA = 0;
|
||||
HRDATA = '0;
|
||||
PREADYOUT = 1'b1;
|
||||
for (i=0; i<PERIPHS; i++) begin
|
||||
if (PSEL[i]) begin // highest numbered peripheral has priority, but multiple PSEL should never be asserted
|
||||
|
@ -101,5 +101,5 @@ module ahbapbbridge import cvw::*; #(parameter cvw_t P,
|
|||
assign HREADYOUT = PREADYOUT & ~initTransSelD; // don't raise HREADYOUT before access phase
|
||||
|
||||
// resp logic
|
||||
assign HRESP = 0; // bridge never indicates errors
|
||||
assign HRESP = 1'b0; // bridge never indicates errors
|
||||
endmodule
|
||||
|
|
|
@ -43,7 +43,7 @@ module rom_ahb import cvw::*; #(parameter cvw_t P,
|
|||
|
||||
// Never stalls
|
||||
assign HREADYRom = 1'b1;
|
||||
assign HRESPRom = 0; // OK
|
||||
assign HRESPRom = 1'b0; // OK
|
||||
|
||||
// single-ported ROM
|
||||
rom1p1r #(ADDR_WIDTH, P.XLEN, PRELOAD)
|
||||
|
|
|
@ -119,16 +119,16 @@ module uncore import cvw::*; #(parameter cvw_t P)(
|
|||
clint_apb #(P) clint(.PCLK, .PRESETn, .PSEL(PSEL[1]), .PADDR(PADDR[15:0]), .PWDATA, .PSTRB, .PWRITE, .PENABLE,
|
||||
.PRDATA(PRDATA[1]), .PREADY(PREADY[1]), .MTIME(MTIME_CLINT), .MTimerInt, .MSwInt);
|
||||
end else begin : clint
|
||||
assign MTIME_CLINT = 0;
|
||||
assign MTimerInt = 0; assign MSwInt = 0;
|
||||
assign MTIME_CLINT = '0;
|
||||
assign MTimerInt = 1'b0; assign MSwInt = 1'b0;
|
||||
end
|
||||
|
||||
if (P.PLIC_SUPPORTED == 1) begin : plic
|
||||
plic_apb #(P) plic(.PCLK, .PRESETn, .PSEL(PSEL[2]), .PADDR(PADDR[27:0]), .PWDATA, .PSTRB, .PWRITE, .PENABLE,
|
||||
.PRDATA(PRDATA[2]), .PREADY(PREADY[2]), .UARTIntr, .GPIOIntr, .SDCIntr, .SPIIntr, .MExtInt, .SExtInt);
|
||||
end else begin : plic
|
||||
assign MExtInt = 0;
|
||||
assign SExtInt = 0;
|
||||
assign MExtInt = 1'b0;
|
||||
assign SExtInt = 1'b0;
|
||||
end
|
||||
|
||||
if (P.GPIO_SUPPORTED == 1) begin : gpio
|
||||
|
@ -137,7 +137,7 @@ module uncore import cvw::*; #(parameter cvw_t P)(
|
|||
.PRDATA(PRDATA[0]), .PREADY(PREADY[0]),
|
||||
.iof0(), .iof1(), .GPIOIN, .GPIOOUT, .GPIOEN, .GPIOIntr);
|
||||
end else begin : gpio
|
||||
assign GPIOOUT = 0; assign GPIOEN = 0; assign GPIOIntr = 0;
|
||||
assign GPIOOUT = '0; assign GPIOEN = '0; assign GPIOIntr = 1'b0;
|
||||
end
|
||||
if (P.UART_SUPPORTED == 1) begin : uartgen // Hack to work around Verilator bug https://github.com/verilator/verilator/issues/4769
|
||||
uart_apb #(P) uart(
|
||||
|
@ -147,7 +147,7 @@ module uncore import cvw::*; #(parameter cvw_t P)(
|
|||
.SOUT(UARTSout), .RTSb(), .DTRb(), // to E1A driver to RS232 interface
|
||||
.OUT1b(), .OUT2b(), .INTR(UARTIntr), .TXRDYb(), .RXRDYb()); // to CPU
|
||||
end else begin : uart
|
||||
assign UARTSout = 0; assign UARTIntr = 0;
|
||||
assign UARTSout = 1'b0; assign UARTIntr = 1'b0;
|
||||
end
|
||||
if (P.SPI_SUPPORTED == 1) begin : spi
|
||||
spi_apb #(P) spi (
|
||||
|
@ -155,7 +155,7 @@ module uncore import cvw::*; #(parameter cvw_t P)(
|
|||
.PREADY(PREADY[4]), .PRDATA(PRDATA[4]),
|
||||
.SPIOut, .SPIIn, .SPICS, .SPIIntr);
|
||||
end else begin : spi
|
||||
assign SPIOut = 0; assign SPICS = 0; assign SPIIntr = 0;
|
||||
assign SPIOut = 1'b0; assign SPICS = '0; assign SPIIntr = 1'b0;
|
||||
end
|
||||
|
||||
// AHB Read Multiplexer
|
||||
|
|
|
@ -302,15 +302,15 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
|
|||
.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW,
|
||||
.FRM_REGW, .ENVCFG_CBE, .ENVCFG_PBMTE, .ENVCFG_ADUE, .wfiM, .IntPendingM, .BigEndianM);
|
||||
end else begin
|
||||
assign CSRReadValW = 0;
|
||||
assign EPCM = 0;
|
||||
assign TrapVectorM = 0;
|
||||
assign RetM = 0;
|
||||
assign TrapM = 0;
|
||||
assign wfiM = 0;
|
||||
assign IntPendingM = 0;
|
||||
assign sfencevmaM = 0;
|
||||
assign BigEndianM = 0;
|
||||
assign CSRReadValW = '0;
|
||||
assign EPCM = '0;
|
||||
assign TrapVectorM = '0;
|
||||
assign RetM = 1'b0;
|
||||
assign TrapM = 1'b0;
|
||||
assign wfiM = 1'b0;
|
||||
assign IntPendingM = 1'b0;
|
||||
assign sfencevmaM = 1'b0;
|
||||
assign BigEndianM = 1'b0;
|
||||
end
|
||||
|
||||
// multiply/divide unit
|
||||
|
@ -320,8 +320,8 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
|
|||
.Funct3E, .Funct3M, .IntDivE, .W64E, .MDUActiveE,
|
||||
.MDUResultW, .DivBusyE);
|
||||
end else begin // no M instructions supported
|
||||
assign MDUResultW = 0;
|
||||
assign DivBusyE = 0;
|
||||
assign MDUResultW = '0;
|
||||
assign DivBusyE = 1'b0;
|
||||
end
|
||||
|
||||
// floating point unit
|
||||
|
@ -351,15 +351,15 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
|
|||
.SetFflagsM, // FPU flags (to privileged unit)
|
||||
.FIntDivResultW);
|
||||
end else begin // no F_SUPPORTED or D_SUPPORTED; tie outputs low
|
||||
assign FPUStallD = 0;
|
||||
assign FWriteIntE = 0;
|
||||
assign FCvtIntE = 0;
|
||||
assign FIntResM = 0;
|
||||
assign FCvtIntW = 0;
|
||||
assign FDivBusyE = 0;
|
||||
assign IllegalFPUInstrD = 1;
|
||||
assign SetFflagsM = 0;
|
||||
assign FpLoadStoreM = 0;
|
||||
assign FPUStallD = 1'b0;
|
||||
assign FWriteIntE = 1'b0;
|
||||
assign FCvtIntE = 1'b0;
|
||||
assign FIntResM = '0;
|
||||
assign FCvtIntW = 1'b0;
|
||||
assign FDivBusyE = 1'b0;
|
||||
assign IllegalFPUInstrD = 1'b1;
|
||||
assign SetFflagsM = '0;
|
||||
assign FpLoadStoreM = 1'b0;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue