Merge pull request #836 from davidharrishmc/dev

Code Cleanup: Lint Improvements
This commit is contained in:
Rose Thompson 2024-06-18 08:56:17 -07:00 committed by GitHub
commit d2933edee4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
61 changed files with 266 additions and 339 deletions

View File

@ -26,7 +26,10 @@ fi
for config in ${configs[@]}; do
# echo "$config linting..."
if !($verilator --lint-only --quiet --top-module wallywrapper "-I$basepath/config/shared" "-I$basepath/config/$config" "-I$basepath/config/deriv/$config" $basepath/src/cvw.sv $basepath/testbench/wallywrapper.sv $basepath/src/*/*.sv $basepath/src/*/*/*.sv --relative-includes ); then
if !($verilator --lint-only --quiet --top-module wallywrapper \
"-I$basepath/config/shared" "-I$basepath/config/$config" "-I$basepath/config/deriv/$config" \
$basepath/src/cvw.sv $basepath/testbench/wallywrapper.sv $basepath/src/*/*.sv $basepath/src/*/*/*.sv \
-Wall -Wno-UNUSEDSIGNAL -Wno-UNUSEDPARAM -Wno-VARHIDDEN -Wno-GENUNNAMED -Wno-PINCONNECTEMPTY); then
if [ "$1" == "-nightly" ]; then
echo -e "${RED}$config failed lint${NC}"
fails=$((fails+1))
@ -48,4 +51,5 @@ echo -e "${GREEN}All ${#configs[@]} lints run with no errors or warnings"
# -I points to the include directory where files such as `include config.vh are found
# For more exhaustive (and sometimes spurious) warnings, add --Wall to the Verilator command
# verilator --lint-only -Wall --quiet --top-module wallywrapper -Iconfig/shared -Iconfig/rv64gc src/cvw.sv testbench/wallywrapper.sv src/*/*.sv src/*/*/*.sv -Wno-UNUSEDPARAM -Wno-VARHIDDEN -Wno-GENUNNAMED -Wno-PINCONNECTEMPTY
# Unfortunately, this produces a bunch of UNUSED and UNDRIVEN signal warnings in blocks that are configured to not exist.

8
src/cache/cache.sv vendored
View File

@ -87,14 +87,13 @@ module cache import cvw::*; #(parameter cvw_t P,
logic LineDirty, HitLineDirty;
logic [TAGLEN-1:0] TagWay [NUMWAYS-1:0];
logic [TAGLEN-1:0] Tag;
logic [SETLEN-1:0] FlushAdr, NextFlushAdr, FlushAdrP1;
logic [SETLEN-1:0] FlushAdr;
logic FlushAdrCntEn, FlushCntRst;
logic FlushAdrFlag, FlushWayFlag;
logic [NUMWAYS-1:0] FlushWay, NextFlushWay;
logic FlushWayCntEn;
logic SelWriteback;
logic LRUWriteEn;
logic ResetOrFlushCntRst;
logic [LINELEN-1:0] ReadDataLine, ReadDataLineCache;
logic SelFetchBuffer;
logic CacheEn;
@ -128,7 +127,7 @@ module cache import cvw::*; #(parameter cvw_t P,
if(NUMWAYS > 1) begin:vict
cacheLRU #(NUMWAYS, SETLEN, OFFSETLEN, NUMSETS) cacheLRU(
.clk, .reset, .FlushStage, .CacheEn, .HitWay, .ValidWay, .VictimWay, .CacheSetTag, .LRUWriteEn,
.SetValid, .ClearValid, .PAdr(PAdr[SETTOP-1:OFFSETLEN]), .InvalidateCache);
.SetValid, .PAdr(PAdr[SETTOP-1:OFFSETLEN]), .InvalidateCache);
end else
assign VictimWay = 1'b1; // one hot.
@ -201,6 +200,9 @@ module cache import cvw::*; #(parameter cvw_t P,
/////////////////////////////////////////////////////////////////////////////////////////////
if (!READ_ONLY_CACHE) begin:flushlogic // D$ can be flushed
logic ResetOrFlushCntRst;
logic [SETLEN-1:0] NextFlushAdr, FlushAdrP1;
// Flush address (line number)
assign ResetOrFlushCntRst = reset | FlushCntRst;
flopenr #(SETLEN) FlushAdrReg(clk, ResetOrFlushCntRst, FlushAdrCntEn, FlushAdrP1, NextFlushAdr);

View File

@ -40,7 +40,6 @@ module cacheLRU
input logic [SETLEN-1:0] PAdr, // Physical address
input logic LRUWriteEn, // Update the LRU state
input logic SetValid, // Set the dirty bit in the selected way and set
input logic ClearValid, // Clear the dirty bit in the selected way and set
input logic InvalidateCache, // Clear all valid bits
output logic [NUMWAYS-1:0] VictimWay // LRU selects a victim to evict
);
@ -145,7 +144,7 @@ module cacheLRU
// LRU read path with write forwarding
assign ReadLRU = LRUMemory[CacheSetTag];
assign ForwardLRU = LRUWriteEn & (PAdr == CacheSetTag);
mux2 #(NUMWAYS-1) ReadLRUmux(LRUMemory[CacheSetTag], NextLRU, ForwardLRU, BypassedLRU);
mux2 #(NUMWAYS-1) ReadLRUmux(ReadLRU, NextLRU, ForwardLRU, BypassedLRU);
flop #(NUMWAYS-1) CurrLRUReg(clk, BypassedLRU, CurrLRU);
endmodule

View File

@ -76,7 +76,6 @@ module cacheway import cvw::*; #(parameter cvw_t P,
logic ClearValidWay;
logic SetDirtyWay;
logic ClearDirtyWay;
logic SelNonHit;
logic SelectedWay;
logic InvalidateCacheDelay;

View File

@ -79,8 +79,7 @@ module ahbcacheinterface import cvw::*; #(
logic [P.PA_BITS-1:0] LocalHADDR; // Address after selecting between cached and uncached operation
logic [AHBWLOGBWPL-1:0] BeatCountDelayed; // Beat within the cache line in the second (Data) cache stage
logic CaptureEn; // Enable updating the Fetch buffer with valid data from HRDATA
logic [P.AHBW/8-1:0] BusByteMaskM; // Byte enables within a word. For cache request all 1s
logic [P.AHBW-1:0] PreHWDATA; // AHB Address phase write data
logic [P.AHBW-1:0] PreHWDATA; // AHB Address phase write data
logic [P.PA_BITS-1:0] PAdrZero;
genvar index;
@ -117,6 +116,8 @@ module ahbcacheinterface import cvw::*; #(
if (READ_ONLY_CACHE) begin
assign HWSTRB = '0;
end else begin // compute byte mask for AHB transaction based on size and address. AHBW may be different than LLEN
logic [P.AHBW/8-1:0] BusByteMaskM; // Byte enables within a word. For cache request all 1s
swbytemask #(P.AHBW) busswbytemask(.Size(HSIZE), .Adr(HADDR[$clog2(P.AHBW/8)-1:0]), .ByteMask(BusByteMaskM), .ByteMaskExtended());
flopen #(P.AHBW/8) HWSTRBReg(HCLK, HREADY, BusByteMaskM[P.AHBW/8-1:0], HWSTRB);
end

View File

@ -65,11 +65,9 @@ module fdivsqrt import cvw::*; #(parameter cvw_t P) (
logic WZeroE; // Early termination flag
logic [P.DURLEN-1:0] CyclesE; // FSM cycles
logic SpecialCaseM; // Divide by zero, square root of negative, etc.
logic DivStartE; // Enable signal for flops during stall
// Integer div/rem signals
logic BZeroM; // Denominator is zero
logic IntDivM; // Integer operation
logic [P.DIVBLEN-1:0] IntNormShiftM; // Integer normalizatoin shift amount
logic ALTBM, AsM, BsM, W64M; // Special handling for postprocessor
logic [P.XLEN-1:0] AM; // Original Numerator for postprocessor
@ -80,8 +78,7 @@ module fdivsqrt import cvw::*; #(parameter cvw_t P) (
.FmtE, .Bias(BiasE), .Nf(NfE), .SqrtE, .XZeroE, .Funct3E, .UeM, .X, .D, .CyclesE,
// Int-specific
.ForwardedSrcAE, .ForwardedSrcBE, .IntDivE, .W64E, .ISpecialCaseE,
.BZeroM, .IntNormShiftM, .AM,
.IntDivM, .W64M, .ALTBM, .AsM, .BsM);
.BZeroM, .IntNormShiftM, .AM, .W64M, .ALTBM, .AsM, .BsM);
fdivsqrtfsm #(P) fdivsqrtfsm( // FSM
.clk, .reset, .XInfE, .YInfE, .XZeroE, .YZeroE, .XNaNE, .YNaNE,

View File

@ -28,9 +28,7 @@
////////////////////////////////////////////////////////////////////////////////////////////////
module fdivsqrtcycles import cvw::*; #(parameter cvw_t P) (
input logic [P.FMTBITS-1:0] FmtE,
input logic [P.LOGFLEN-1:0] Nf, // Number of fractional bits in selected format
input logic SqrtE,
input logic IntDivE,
input logic [P.DIVBLEN-1:0] IntResultBitsE,
output logic [P.DURLEN-1:0] CyclesE

View File

@ -131,5 +131,6 @@ module fdivsqrtpostproc import cvw::*; #(parameter cvw_t P) (
W64M, FIntDivResultM);
end else
assign FIntDivResultM = IntDivResultM[P.XLEN-1:0];
end
end else
assign FIntDivResultM = '0;
endmodule

View File

@ -47,7 +47,7 @@ module fdivsqrtpreproc import cvw::*; #(parameter cvw_t P) (
output logic ISpecialCaseE,
output logic [P.DURLEN-1:0] CyclesE,
output logic [P.DIVBLEN-1:0] IntNormShiftM,
output logic ALTBM, IntDivM, W64M,
output logic ALTBM, W64M,
output logic AsM, BsM, BZeroM,
output logic [P.XLEN-1:0] AM
);
@ -58,7 +58,6 @@ module fdivsqrtpreproc import cvw::*; #(parameter cvw_t P) (
logic [P.DIVb:0] IFX, IFD; // Correctly-sized inputs for iterator, selected from int or fp input
logic [P.DIVBLEN-1:0] mE, ell; // Leading zeros of inputs
logic [P.DIVBLEN-1:0] IntResultBitsE; // bits in integer result
logic NumerZeroE; // Numerator is zero (X or A)
logic AZeroE, BZeroE; // A or B is Zero for integer division
logic SignedDivE; // signed division
logic AsE, BsE; // Signs of integer inputs
@ -96,11 +95,9 @@ module fdivsqrtpreproc import cvw::*; #(parameter cvw_t P) (
// Select integer or floating point inputs
mux2 #(P.DIVb+1) ifxmux({Xm, {(P.DIVb-P.NF){1'b0}}}, {PosA, {(P.DIVb-P.XLEN+1){1'b0}}}, IntDivE, IFX);
mux2 #(P.DIVb+1) ifdmux({Ym, {(P.DIVb-P.NF){1'b0}}}, {PosB, {(P.DIVb-P.XLEN+1){1'b0}}}, IntDivE, IFD);
mux2 #(1) numzmux(XZeroE, AZeroE, IntDivE, NumerZeroE);
end else begin // Int not supported
assign IFX = {Xm, {(P.DIVb-P.NF){1'b0}}};
assign IFD = {Ym, {(P.DIVb-P.NF){1'b0}}};
assign NumerZeroE = XZeroE;
end
//////////////////////////////////////////////////////
@ -147,7 +144,7 @@ module fdivsqrtpreproc import cvw::*; #(parameter cvw_t P) (
assign DivXShifted = DivX;
end
end else begin
assign ISpecialCaseE = 1'b0;
assign {ISpecialCaseE, IntResultBitsE} = '0;
end
//////////////////////////////////////////////////////
@ -174,7 +171,6 @@ module fdivsqrtpreproc import cvw::*; #(parameter cvw_t P) (
// 4 2(x)-4 = 4(x/2 - 1)) 2(x/2)-4 = 4(x/4 - 1)
// Summary: PreSqrtX = r(x/2or4 - 1)
logic [P.DIVb:0] PreSqrtX;
assign EvenExp = Xe[0] ^ ell[0]; // effective unbiased exponent after normalization is even
mux2 #(P.DIVb+4) sqrtxmux({4'b0,Xnorm[P.DIVb:1]}, {5'b00, Xnorm[P.DIVb:2]}, EvenExp, SqrtX); // X/2 if exponent odd, X/4 if exponent even
@ -215,7 +211,7 @@ module fdivsqrtpreproc import cvw::*; #(parameter cvw_t P) (
flopen #(P.NE+2) expreg(clk, IFDivStartE, UeE, UeM);
// Number of FSM cycles (to FSM)
fdivsqrtcycles #(P) cyclecalc(.FmtE, .Nf, .SqrtE, .IntDivE, .IntResultBitsE, .CyclesE);
fdivsqrtcycles #(P) cyclecalc(.Nf, .IntDivE, .IntResultBitsE, .CyclesE);
if (P.IDIV_ON_FPU) begin:intpipelineregs
logic [P.DIVBLEN-1:0] IntDivNormShiftE, IntRemNormShiftE, IntNormShiftE;
@ -229,7 +225,6 @@ module fdivsqrtpreproc import cvw::*; #(parameter cvw_t P) (
mux2 #(P.DIVBLEN) normshiftmux(IntDivNormShiftE, IntRemNormShiftE, RemOpE, IntNormShiftE);
// pipeline registers
flopen #(1) mdureg(clk, IFDivStartE, IntDivE, IntDivM);
flopen #(1) altbreg(clk, IFDivStartE, ALTBE, ALTBM);
flopen #(1) bzeroreg(clk, IFDivStartE, BZeroE, BZeroM);
flopen #(1) asignreg(clk, IFDivStartE, AsE, AsM);
@ -238,7 +233,8 @@ module fdivsqrtpreproc import cvw::*; #(parameter cvw_t P) (
flopen #(P.XLEN) srcareg(clk, IFDivStartE, AE, AM);
if (P.XLEN==64)
flopen #(1) w64reg(clk, IFDivStartE, W64E, W64M);
end
end else
assign {ALTBM, W64M, AsM, BsM, BZeroM, AM, IntNormShiftM} = 0;
endmodule

View File

@ -47,7 +47,7 @@ module fdivsqrtuslc4cmp (
// Wmsbs = | |
logic [6:0] mk2, mk1, mk0, mkm1;
logic [6:0] mkj2, mkj1, mkj0, mkjm1;
logic [6:0] mkj2, mkj1;
logic [6:0] mks2[7:0], mks1[7:0], mks0[7:0], mksm1[7:0];
logic sqrtspecial;

View File

@ -279,7 +279,7 @@ module fpu import cvw::*; #(parameter cvw_t P) (
logic [P.FLEN-1:0] FliResE; // Zfa Floating-point load immediate value
// fround
fround #(P) fround(.X(XE), .Xs(XsE), .Xe(XeE), .Xm(XmE),
fround #(P) fround(.Xs(XsE), .Xe(XeE), .Xm(XmE),
.XNaN(XNaNE), .XSNaN(XSNaNE), .Fmt(FmtE), .Frm(FrmE), .Nf(NfE),
.ZfaFRoundNX(ZfaFRoundNXE),
.FRound(FRoundE), .FRoundNV(FRoundNVE), .FRoundNX(FRoundNXE));

View File

@ -28,7 +28,6 @@
////////////////////////////////////////////////////////////////////////////////////////////////
module fround import cvw::*; #(parameter cvw_t P) (
input logic [P.FLEN-1:0] X, // input before unpacking
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 with leading integer bit (U1.NF)
@ -45,7 +44,7 @@ module fround import cvw::*; #(parameter cvw_t P) (
logic [P.NE-1:0] E, Xep1;
logic [P.NF:0] IMask, Tmasknonneg, Tmaskneg, Tmask, HotE, HotEP1, Trunc, Rnd;
logic [P.FLEN-1:0] W, PackedW;
logic [P.FLEN-1:0] W;
logic Elt0, Eeqm1, Lnonneg, Lp, Rnonneg, Rp, Tp, RoundUp, Two, EgeNf;
// Unbiased exponent

View File

@ -100,4 +100,4 @@ module packoutput import cvw::*; #(parameter cvw_t P) (
endcase
end
end
endmodule
endmodule

View File

@ -45,7 +45,6 @@ module shiftcorrection import cvw::*; #(parameter cvw_t P) (
output logic [P.NE+1:0] Ue // corrected exponent for divider
);
logic [P.NORMSHIFTSZ-1:0] CorrShifted; // the shifted sum after LZA correction
logic ResSubnorm; // is the result Subnormal
logic LZAPlus1; // add one or two to the sum's exponent due to LZA correction
logic LeftShiftQm; // should the divsqrt result be shifted one to the left

View File

@ -46,23 +46,21 @@ module unpack import cvw::*; #(parameter cvw_t P) (
output logic [P.LOGFLEN-1:0] Nf // Number of fractional bits
);
logic XExpNonZero, YExpNonZero, ZExpNonZero; // is the exponent of XYZ non-zero
logic XFracZero, YFracZero, ZFracZero; // is the fraction zero
logic YExpMax, ZExpMax; // is the exponent all 1s
unpackinput #(P) unpackinputX (.A(X), .Fmt, .Sgn(Xs), .Exp(Xe), .Man(Xm), .En(XEn), .FPUActive,
.NaN(XNaN), .SNaN(XSNaN), .ExpNonZero(XExpNonZero),
.Zero(XZero), .Inf(XInf), .ExpMax(XExpMax), .FracZero(XFracZero),
.NaN(XNaN), .SNaN(XSNaN),
.Zero(XZero), .Inf(XInf), .ExpMax(XExpMax),
.Subnorm(XSubnorm), .PostBox(XPostBox));
unpackinput #(P) unpackinputY (.A(Y), .Fmt, .Sgn(Ys), .Exp(Ye), .Man(Ym), .En(YEn), .FPUActive,
.NaN(YNaN), .SNaN(YSNaN), .ExpNonZero(YExpNonZero),
.Zero(YZero), .Inf(YInf), .ExpMax(YExpMax), .FracZero(YFracZero),
.NaN(YNaN), .SNaN(YSNaN),
.Zero(YZero), .Inf(YInf), .ExpMax(YExpMax),
.Subnorm(), .PostBox());
unpackinput #(P) unpackinputZ (.A(Z), .Fmt, .Sgn(Zs), .Exp(Ze), .Man(Zm), .En(ZEn), .FPUActive,
.NaN(ZNaN), .SNaN(ZSNaN), .ExpNonZero(ZExpNonZero),
.Zero(ZZero), .Inf(ZInf), .ExpMax(ZExpMax), .FracZero(ZFracZero),
.NaN(ZNaN), .SNaN(ZSNaN),
.Zero(ZZero), .Inf(ZInf), .ExpMax(ZExpMax),
.Subnorm(), .PostBox());
// look up bias and fractional bits for the given format

View File

@ -39,8 +39,6 @@ module unpackinput import cvw::*; #(parameter cvw_t P) (
output logic SNaN, // is the number a signaling NaN
output logic Zero, // is the number zero
output logic Inf, // is the number infinity
output logic ExpNonZero, // is the exponent not zero
output logic FracZero, // is the fraction zero
output logic ExpMax, // does In have the maximum exponent (NaN or Inf)
output logic Subnorm, // is the number subnormal
output logic [P.FLEN-1:0] PostBox // Number reboxed correctly as a NaN
@ -48,6 +46,8 @@ module unpackinput import cvw::*; #(parameter cvw_t P) (
logic [P.NF-1:0] Frac; // Fraction of XYZ
logic BadNaNBox; // incorrectly NaN Boxed
logic FracZero; // is the fraction zero
logic ExpNonZero; // is the exponent non-zero
logic [P.FLEN-1:0] In;
// Gate input when FPU is not active to save power and simulation

View File

@ -82,7 +82,6 @@ module ram1p1rwbe import cvw::*; #(parameter USE_SRAM=0, DEPTH=64, WIDTH=44, PRE
///////////////////////////////////////////////////////////////////////////////
end else begin: ram
bit [WIDTH-1:0] RAM[DEPTH-1:0];
integer i;
if (PRELOAD_ENABLED) begin
initial begin
@ -102,11 +101,13 @@ module ram1p1rwbe import cvw::*; #(parameter USE_SRAM=0, DEPTH=64, WIDTH=44, PRE
// Write divided into part for bytes and part for extra msbs
// Questa sim version 2022.3_2 does not allow multiple drivers for RAM when using always_ff.
// Therefore these always blocks use the older always @(posedge clk)
if(WIDTH >= 8)
if(WIDTH >= 8) begin
integer i;
always @(posedge clk)
if (ce & we)
for(i = 0; i < WIDTH/8; i++)
if(bwe[i]) RAM[addr][i*8 +: 8] <= din[i*8 +: 8];
end
if (WIDTH%8 != 0) // handle msbs if width not a multiple of 8
always @(posedge clk)

View File

@ -71,8 +71,6 @@ module ram1p1rwe import cvw::* ; #(parameter USE_SRAM=0, DEPTH=64, WIDTH=44) (
bit [WIDTH-1:0] RAM[DEPTH-1:0];
integer i;
// Combinational read: register address and read after clock edge
logic [$clog2(DEPTH)-1:0] addrd;
flopen #($clog2(DEPTH)) adrreg(clk, ce, addr, addrd);

View File

@ -111,14 +111,6 @@ module ram2p1r1wbe import cvw::*; #(parameter USE_SRAM=0, DEPTH=1024, WIDTH=68)
///////////////////////////////////////////////////////////////////////////////
bit [WIDTH-1:0] RAM[DEPTH-1:0];
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++)
RAM[j] = '0;
end
*/
// Read
logic [$clog2(DEPTH)-1:0] ra1d;
@ -128,11 +120,13 @@ module ram2p1r1wbe import cvw::*; #(parameter USE_SRAM=0, DEPTH=1024, WIDTH=68)
// Write divided into part for bytes and part for extra msbs
// coverage off
// when byte write enables are tied high, the last IF is always taken
if(WIDTH >= 8)
if(WIDTH >= 8) begin
integer i;
always @(posedge clk)
if (ce2 & we2)
for(i = 0; i < WIDTH/8; i++)
if(bwe2[i]) RAM[wa2][i*8 +: 8] <= wd2[i*8 +: 8];
end
// coverage on
if (WIDTH%8 != 0) // handle msbs if width not a multiple of 8

View File

@ -26,11 +26,11 @@
////////////////////////////////////////////////////////////////////////////////////////////////
module aes64ks1i(
input logic [3:0] round,
input logic [63:0] rs1,
input logic [31:0] Sbox0Out,
output logic [31:0] SboxKIn,
output logic [63:0] result
input logic [3:0] round,
input logic [63:32] rs1,
input logic [31:0] Sbox0Out,
output logic [31:0] SboxKIn,
output logic [63:0] result
);
logic finalround;

View File

@ -26,9 +26,9 @@
////////////////////////////////////////////////////////////////////////////////////////////////
module aes64ks2(
input logic [63:0] rs2,
input logic [63:0] rs1,
output logic [63:0] result
input logic [63:0] rs2,
input logic [63:32] rs1,
output logic [63:0] result
);
logic [31:0] w0, w1;

View File

@ -26,7 +26,9 @@
////////////////////////////////////////////////////////////////////////////////////////////////
module aesinvshiftrows64(
input logic [127:0] a,
/* verilator lint_off UNUSEDSIGNAL */
input logic [127:0] a,
/* verilator lint_on UNUSEDSIGNAL */
output logic [63:0] y
);

View File

@ -26,7 +26,9 @@
////////////////////////////////////////////////////////////////////////////////////////////////
module aesshiftrows64(
/* verilator lint_off UNUSEDSIGNAL */
input logic [127:0] a,
/* verilator lint_on UNUSEDSIGNAL */
output logic [63:0] y
);

View File

@ -1,35 +0,0 @@
///////////////////////////////////////////
// aesshiftrows64.sv
//
// Written: ryan.swann@okstate.edu, james.stine@okstate.edu
// Created: 20 February 2024
//
// Purpose: aesshiftrow for taking in first Data line
//
// 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 aesshiftrows64(
input logic [127:0] a,
output logic [63:0] y
);
assign y = {a[31:24], a[119:112], a[79:72], a[39:32],
a[127:120], a[87:80], a[47:40], a[7:0]};
endmodule

View File

@ -49,7 +49,6 @@ module bitmanipalu import cvw::*; #(parameter cvw_t P) (
logic [P.XLEN-1:0] ZBBResult; // ZBB Result
logic [P.XLEN-1:0] ZBCResult; // ZBC Result
logic [P.XLEN-1:0] ZBKBResult; // ZBKB Result
logic [P.XLEN-1:0] ZBKCResult; // ZBKC Result
logic [P.XLEN-1:0] ZBKXResult; // ZBKX Result
logic [P.XLEN-1:0] ZKNHResult; // ZKNH Result
logic [P.XLEN-1:0] ZKNDEResult; // ZKNE or ZKND Result
@ -93,7 +92,7 @@ module bitmanipalu import cvw::*; #(parameter cvw_t P) (
// ZBC and ZBKCUnit
if (P.ZBC_SUPPORTED | P.ZBKC_SUPPORTED) begin: zbc
zbc #(P) ZBC(.A(ABMU), .RevA, .B(BBMU), .Funct3, .ZBCResult);
zbc #(P) ZBC(.A(ABMU), .RevA, .B(BBMU), .Funct3(Funct3[1:0]), .ZBCResult);
end else assign ZBCResult = '0;
// ZBB Unit
@ -108,7 +107,7 @@ module bitmanipalu import cvw::*; #(parameter cvw_t P) (
// ZBKB Unit
if (P.ZBKB_SUPPORTED) begin: zbkb
zbkb #(P.XLEN) ZBKB(.A(ABMU), .B(BBMU), .Funct3, .ZBKBSelect(ZBBSelect[2:0]), .ZBKBResult);
zbkb #(P.XLEN) ZBKB(.A(ABMU), .B(BBMU[P.XLEN/2-1:0]), .Funct3, .ZBKBSelect(ZBBSelect[2:0]), .ZBKBResult);
end else assign ZBKBResult = '0;
// ZBKX Unit
@ -125,7 +124,7 @@ module bitmanipalu import cvw::*; #(parameter cvw_t P) (
// ZKNH Unit
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));
else zknh64 ZKNH64(.A(ABMU), .ZKNHSelect(ZBBSelect), .ZKNHResult(ZKNHResult));
end else assign ZKNHResult = '0;
// Result Select Mux

View File

@ -31,11 +31,8 @@
module bmuctrl import cvw::*; #(parameter cvw_t P) (
input logic clk, reset,
// Decode stage control signals
input logic StallD, FlushD, // Stall, flush Decode stage
input logic [31:0] InstrD, // Instruction in Decode stage
input logic ALUOpD, // Regular ALU Operation
output logic [3:0] BSelectD, // Indicates if ZBA_ZBB_ZBC_ZBS instruction in one-hot encoding in Decode stage
output logic [3:0] ZBBSelectD, // ZBB mux select signal in Decode stage NOTE: do we need this in decode?
output logic BRegWriteD, // Indicates if it is a R type B instruction in Decode Stage
output logic BALUSrcBD, // Indicates if it is an I/IW (non auipc) type B instruction in Decode Stage
output logic BW64D, // Indiciates if it is a W type B instruction in Decode Stage
@ -46,7 +43,6 @@ module bmuctrl import cvw::*; #(parameter cvw_t P) (
output logic [2:0] ALUSelectD, // ALU select
output logic [3:0] BSelectE, // Indicates if ZBA_ZBB_ZBC_ZBS instruction in one-hot encoding
output logic [3:0] ZBBSelectE, // ZBB mux select signal
output logic BRegWriteE, // Indicates if it is a R type B instruction in Execute
output logic [2:0] BALUControlE, // ALU Control signals for B instructions in Execute Stage
output logic BMUActiveE // Bit manipulation instruction being executed
);
@ -61,6 +57,8 @@ module bmuctrl import cvw::*; #(parameter cvw_t P) (
logic [2:0] BALUControlD; // ALU Control signals for B instructions
logic [2:0] BALUSelectD; // ALU Mux select signal in Decode Stage for BMU operations
logic BALUOpD; // Indicates if it is an ALU B instruction in Decode Stage
logic [3:0] BSelectD; // Indicates if ZBA_ZBB_ZBC_ZBS instruction in one-hot encoding in Decode stage
logic [3:0] ZBBSelectD; // ZBB mux select signal in Decode stage
`define BMUCTRLW 20
@ -285,5 +283,5 @@ module bmuctrl import cvw::*; #(parameter cvw_t P) (
assign ALUSelectD = BALUOpD ? BALUSelectD : (ALUOpD ? Funct3D : 3'b000);
// BMU Execute stage pipieline control register
flopenrc #(13) controlregBMU(clk, reset, FlushE, ~StallE, {BSelectD, ZBBSelectD, BRegWriteD, BALUControlD, ~IllegalBitmanipInstrD}, {BSelectE, ZBBSelectE, BRegWriteE, BALUControlE, BMUActiveE});
flopenrc #(12) controlregBMU(clk, reset, FlushE, ~StallE, {BSelectD, ZBBSelectD, BALUControlD, ~IllegalBitmanipInstrD}, {BSelectE, ZBBSelectE, BALUControlE, BMUActiveE});
endmodule

View File

@ -29,7 +29,7 @@
////////////////////////////////////////////////////////////////////////////////////////////////
module ext #(parameter WIDTH = 32) (
input logic [WIDTH-1:0] A, // Operands
input logic [15:0] A, // Operand to extend
input logic [1:0] ExtSelect, // B[2], B[0] of immediate
output logic [WIDTH-1:0] ExtResult); // Extend Result

View File

@ -46,7 +46,7 @@ module zbb #(parameter WIDTH=32) (
mux2 #(1) ltmux(LT, LTU, BUnsigned , lt);
cnt #(WIDTH) cnt(.A, .RevA, .B(B[1:0]), .W64, .CntResult);
byteop #(WIDTH) bu(.A, .ByteSelect(B[0]), .ByteResult);
ext #(WIDTH) ext(.A, .ExtSelect({~B[2], {B[2] & B[0]}}), .ExtResult);
ext #(WIDTH) ext(.A(A[15:0]), .ExtSelect({~B[2], {B[2] & B[0]}}), .ExtResult);
// ZBBSelect[2] differentiates between min(u) vs max(u) instruction
mux2 #(WIDTH) minmaxmux(B, A, ZBBSelect[2]^lt, MinMaxResult);

View File

@ -30,7 +30,7 @@
module zbc import cvw::*; #(parameter cvw_t P) (
input logic [P.XLEN-1:0] A, RevA, B, // Operands
input logic [2:0] Funct3, // Indicates operation to perform
input logic [1:0] Funct3, // Indicates operation to perform
output logic [P.XLEN-1:0] ZBCResult); // ZBC result
logic [P.XLEN-1:0] ClmulResult, RevClmulResult;

View File

@ -53,16 +53,13 @@ module controller import cvw::*; #(parameter cvw_t P) (
output logic ALUSrcAE, ALUSrcBE, // ALU operands
output logic ALUResultSrcE, // Selects result to pass on to Memory stage
output logic [2:0] ALUSelectE, // ALU mux select signal
output logic MemReadE, CSRReadE, // Instruction reads memory, reads a CSR (needed for Hazard unit)
output logic [2:0] Funct3E, // Instruction's funct3 field
output logic [6:0] Funct7E, // Instruction's funct7 field
output logic IntDivE, // Integer divide
output logic MDUE, // MDU (multiply/divide) operatio
output logic W64E, // RV64 W-type operation
output logic SubArithE, // Subtraction or arithmetic shift
output logic JumpE, // jump instruction
output logic BranchE, // Branch instruction
output logic SCE, // Store Conditional instruction
output logic BranchSignedE, // Branch comparison operands are signed (if it's a branch)
output logic [3:0] BSelectE, // One-Hot encoding of if it's ZBA_ZBB_ZBC_ZBS instruction
output logic [3:0] ZBBSelectE, // ZBB mux select signal in Execute stage
@ -81,7 +78,6 @@ module controller import cvw::*; #(parameter cvw_t P) (
output logic CSRReadM, CSRWriteM, PrivilegedM, // CSR read, write, or privileged instruction
output logic [1:0] AtomicM, // Atomic (AMO) instruction
output logic [2:0] Funct3M, // Instruction's funct3 field
output logic RegWriteM, // Instruction writes a register (needed for Hazard unit)
output logic InvalidateICacheM, FlushDCacheM, // Invalidate I$, flush D$
output logic InstrValidD, InstrValidE, InstrValidM, // Instruction is valid
output logic FWriteIntM, // FPU controller writes integer register file
@ -122,6 +118,9 @@ module controller import cvw::*; #(parameter cvw_t P) (
logic FenceXD; // Fence instruction
logic CMOD; // Cache management instruction
logic InvalidateICacheD, FlushDCacheD;// Invalidate I$, flush D$
logic MemReadE, CSRReadE; // Instruction reads memory, reads a CSR (needed for Hazard unit)
logic MDUE; // MDU (multiply/divide) operatio
logic SCE; // Store Conditional instruction
logic CSRWriteD, CSRWriteE; // CSR write
logic PrivilegedD, PrivilegedE; // Privileged instruction
logic InvalidateICacheE, FlushDCacheE;// Invalidate I$, flush D$
@ -133,14 +132,12 @@ module controller import cvw::*; #(parameter cvw_t P) (
logic unused;
logic BranchFlagE; // Branch flag to use (chosen between eq or lt)
logic IEURegWriteE; // Register write
logic BRegWriteE; // Register write from BMU controller in Execute Stage
logic IllegalERegAdrD; // RV32E attempts to write upper 16 registers
logic [1:0] AtomicE; // Atomic instruction
logic FenceD, FenceE; // Fence instruction
logic SFenceVmaD; // sfence.vma instruction
logic IntDivM; // Integer divide instruction
logic [3:0] BSelectD; // One-Hot encoding if it's ZBA_ZBB_ZBC_ZBS instruction in decode stage
logic [3:0] ZBBSelectD; // ZBB Mux Select Signal
logic RegWriteM; // Instruction writes a register (needed for Hazard unit)
logic [1:0] CZeroD;
logic IFunctD, RFunctD, MFunctD; // Detect I, R, and M-type RV32IM/Rv64IM instructions
logic LFunctD, SFunctD, BFunctD; // Detect load, store, branch instructions
@ -158,7 +155,6 @@ module controller import cvw::*; #(parameter cvw_t P) (
logic [3:0] CMOpD, CMOpE; // which CMO instruction 1: cbo.inval; 2: cbo.flush; 4: cbo.clean; 8: cbo.zero
logic IFUPrefetchD; // instruction prefetch
logic LSUPrefetchD, LSUPrefetchE; // data prefetch
logic CMOStallD; // Structural hazards from cache management ops
logic MatchDE; // Match between a source register in Decode stage and destination register in Execute stage
logic FCvtIntStallD, MDUStallD, CSRRdStallD; // Stall due to conversion, load, multiply/divide, CSR read
logic FunctCZeroD; // Funct7 and Funct3 indicate czero.* (not including Op check)
@ -329,9 +325,9 @@ module controller import cvw::*; #(parameter cvw_t P) (
logic BSubArithD; // TRUE for BMU ext, clr, andn, orn, xnor
logic BALUSrcBD; // BMU alu src select signal
bmuctrl #(P) bmuctrl(.clk, .reset, .StallD, .FlushD, .InstrD, .ALUOpD, .BSelectD, .ZBBSelectD,
bmuctrl #(P) bmuctrl(.clk, .reset, .InstrD, .ALUOpD,
.BRegWriteD, .BALUSrcBD, .BW64D, .BSubArithD, .IllegalBitmanipInstrD, .StallE, .FlushE,
.ALUSelectD(PreALUSelectD), .BSelectE, .ZBBSelectE, .BRegWriteE, .BALUControlE, .BMUActiveE);
.ALUSelectD(PreALUSelectD), .BSelectE, .ZBBSelectE, .BALUControlE, .BMUActiveE);
if (P.ZBA_SUPPORTED) begin
// ALU Decoding is more comprehensive when ZBA is supported. slt and slti conflicts with sh1add, sh1add.uw
assign sltD = (Funct3D == 3'b010 & (~(Funct7D[4]) | ~OpD[5])) ;
@ -357,7 +353,6 @@ module controller import cvw::*; #(parameter cvw_t P) (
// tie off unused bit manipulation signals
assign BSelectE = 4'b0000;
assign BSelectD = 4'b0000;
assign ZBBSelectE = 4'b0000;
assign BALUControlE = 3'b0;
assign BMUActiveE = 1'b0;

View File

@ -80,7 +80,6 @@ module datapath import cvw::*; #(parameter cvw_t P) (
// Decode stage signals
logic [P.XLEN-1:0] R1D, R2D; // Read data from Rs1 (RD1), Rs2 (RD2)
logic [P.XLEN-1:0] ImmExtD; // Extended immediate in Decode stage
logic [4:0] RdD; // Destination register in Decode stage
// Execute stage signals
logic [P.XLEN-1:0] R1E, R2E; // Source operands read from register file
logic [P.XLEN-1:0] ImmExtE; // Extended immediate in Execute stage

View File

@ -87,7 +87,6 @@ module ieu import cvw::*; #(parameter cvw_t P) (
logic [2:0] ResultSrcW; // Selects result in Writeback stage
logic ALUResultSrcE; // Selects ALU result to pass on to Memory stage
logic [2:0] ALUSelectE; // ALU select mux signal
logic SCE; // Store Conditional instruction
logic FWriteIntM; // FPU writing to integer register file
logic IntDivW; // Integer divide instruction
logic [3:0] BSelectE; // Indicates if ZBA_ZBB_ZBC_ZBS instruction in one-hot encoding
@ -99,12 +98,10 @@ module ieu import cvw::*; #(parameter cvw_t P) (
// Forwarding signals
logic [4:0] Rs1D, Rs2D;
logic [4:0] Rs2E; // Source registers
logic [4:0] Rs2E; // Source registers
logic [1:0] ForwardAE, ForwardBE; // Select signals for forwarding multiplexers
logic RegWriteM, RegWriteW; // Register will be written in Memory, Writeback stages
logic MemReadE, CSRReadE; // Load, CSRRead instruction
logic RegWriteW; // Register will be written in Writeback stage
logic BranchSignedE; // Branch does signed comparison on operands
logic MDUE; // Multiply/divide instruction
logic BMUActiveE; // Bit manipulation instruction being executed
logic [1:0] CZeroE; // {czero.nez, czero.eqz} instructions active
@ -113,12 +110,12 @@ module ieu import cvw::*; #(parameter cvw_t P) (
.IllegalIEUFPUInstrD, .IllegalBaseInstrD,
.StructuralStallD, .LoadStallD, .StoreStallD, .Rs1D, .Rs2D, .Rs2E,
.StallE, .FlushE, .FlagsE, .FWriteIntE,
.PCSrcE, .ALUSrcAE, .ALUSrcBE, .ALUResultSrcE, .ALUSelectE, .MemReadE, .CSRReadE,
.Funct3E, .Funct7E, .IntDivE, .MDUE, .W64E, .SubArithE, .BranchD, .BranchE, .JumpD, .JumpE, .SCE,
.PCSrcE, .ALUSrcAE, .ALUSrcBE, .ALUResultSrcE, .ALUSelectE,
.Funct3E, .Funct7E, .IntDivE, .W64E, .SubArithE, .BranchD, .BranchE, .JumpD, .JumpE,
.BranchSignedE, .BSelectE, .ZBBSelectE, .BALUControlE, .BMUActiveE, .CZeroE, .MDUActiveE,
.FCvtIntE, .ForwardAE, .ForwardBE, .CMOpM, .IFUPrefetchE, .LSUPrefetchM,
.StallM, .FlushM, .MemRWE, .MemRWM, .CSRReadM, .CSRWriteM, .PrivilegedM, .AtomicM, .Funct3M,
.RegWriteM, .FlushDCacheM, .InstrValidM, .InstrValidE, .InstrValidD, .FWriteIntM,
.FlushDCacheM, .InstrValidM, .InstrValidE, .InstrValidD, .FWriteIntM,
.StallW, .FlushW, .RegWriteW, .IntDivW, .ResultSrcW, .CSRWriteFenceM, .InvalidateICacheM,
.RdW, .RdE, .RdM);

View File

@ -26,7 +26,7 @@
////////////////////////////////////////////////////////////////////////////////////////////////
module packer #(parameter WIDTH=32) (
input logic [WIDTH-1:0] A, B,
input logic [WIDTH/2-1:0] A, B,
input logic [2:0] PackSelect,
output logic [WIDTH-1:0] PackResult
);

View File

@ -26,10 +26,11 @@
////////////////////////////////////////////////////////////////////////////////////////////////
module zbkb #(parameter WIDTH=32) (
input logic [WIDTH-1:0] A, B,
input logic [2:0] Funct3,
input logic [2:0] ZBKBSelect,
output logic [WIDTH-1:0] ZBKBResult
input logic [WIDTH-1:0] A,
input logic [WIDTH/2-1:0] B,
input logic [2:0] Funct3,
input logic [2:0] ZBKBSelect,
output logic [WIDTH-1:0] ZBKBResult
);
logic [WIDTH-1:0] Brev8Result; // rev8, brev8
@ -42,8 +43,8 @@ module zbkb #(parameter WIDTH=32) (
for (j=0; j<8; j=j+1)
assign Brev8Result[i*8+j] = A[i*8+7-j];
packer #(WIDTH) pack(.A, .B, .PackSelect({ZBKBSelect[2], Funct3[1:0]}), .PackResult);
zipper #(WIDTH) zip(.A, .ZipSelect(Funct3[2]), .ZipResult);
packer #(WIDTH) pack(.A(A[WIDTH/2-1:0]), .B(B[WIDTH/2-1:0]), .PackSelect({ZBKBSelect[2], Funct3[1:0]}), .PackResult);
zipper #(WIDTH) zipper(.A, .ZipSelect(Funct3[2]), .ZipResult);
// ZBKB Result Select Mux
mux3 #(WIDTH) zbkbresultmux(Brev8Result, PackResult, ZipResult, ZBKBSelect[1:0], ZBKBResult);

View File

@ -31,8 +31,10 @@ module zbkx #(parameter WIDTH=32) (
output logic [WIDTH-1:0] ZBKXResult
);
logic [WIDTH-1:0] xperm4, xperm4lookup;
logic [WIDTH-1:0] xperm8, xperm8lookup;
logic [WIDTH-1:0] xperm4, xperm8;
/* verilator lint_off UNUSEDSIGNAL */
logic [WIDTH-1:0] xperm4lookup, xperm8lookup; // not all bits are used
/* verilator lint_on UNUSEDSIGNAL */
int i;
always_comb begin

View File

@ -48,8 +48,8 @@ module zknde64 import cvw::*; #(parameter cvw_t P) (
aessbox32 sbox(Sbox0In, Sbox0Out); // Substitute bytes of value obtained for tmp2 using Rijndael sbox
// Both ZKND and ZKNE support aes64ks1i and aes64ks2 instructions
aes64ks1i aes64ks1i(.round, .rs1(A), .Sbox0Out, .SboxKIn, .result(aes64ks1iRes));
aes64ks2 aes64ks2(.rs2(B), .rs1(A), .result(aes64ks2Res));
aes64ks1i aes64ks1i(.round, .rs1(A[63:32]), .Sbox0Out, .SboxKIn, .result(aes64ks1iRes));
aes64ks2 aes64ks2(.rs2(B), .rs1(A[63:32]), .result(aes64ks2Res));
// Choose among decrypt, encrypt, key schedule 1, key schedule 2 results
mux4 #(64) zkndmux(aes64dRes, aes64eRes, aes64ks1iRes, aes64ks2Res, ZKNSelect[1:0], ZKNDEResult);

View File

@ -26,7 +26,7 @@
////////////////////////////////////////////////////////////////////////////////////////////////
module zknh64 (
input logic [63:0] A, B,
input logic [63:0] A,
input logic [3:0] ZKNHSelect,
output logic [63:0] ZKNHResult
);

View File

@ -31,7 +31,7 @@
module RASPredictor import cvw::*; #(parameter cvw_t P)(
input logic clk,
input logic reset,
input logic StallF, StallD, StallE, StallM, FlushD, FlushE, FlushM,
input logic StallD, StallE, StallM, FlushD, FlushE, FlushM,
input logic BPReturnWrongD, // Prediction class is wrong
input logic ReturnD,
input logic ReturnE, CallE, // Instr class

View File

@ -72,33 +72,26 @@ module bpred import cvw::*; #(parameter cvw_t P) (
logic [1:0] BPDirPredF;
logic [P.XLEN-1:0] BPBTAF, RASPCF;
logic BPPCWrongE;
logic IClassWrongE;
logic [P.XLEN-1:0] BPBTAF, RASPCF;
logic BPDirPredWrongE;
logic BPPCSrcF;
logic [P.XLEN-1:0] BPPCF;
logic [P.XLEN-1:0] PC0NextF;
logic [P.XLEN-1:0] PCCorrectE;
logic [3:0] WrongPredInstrClassD;
logic [P.XLEN-1:0] BPPCF;
logic [P.XLEN-1:0] PC0NextF;
logic [P.XLEN-1:0] PCCorrectE;
logic BTBTargetWrongE;
logic RASTargetWrongE;
logic [P.XLEN-1:0] BPBTAD;
logic BTBCallF, BTBReturnF, BTBJumpF, BTBBranchF;
logic BPBranchF, BPJumpF, BPReturnF, BPCallF;
logic BPBranchD, BPJumpD, BPReturnD, BPCallD;
logic ReturnD, CallD;
logic ReturnE, CallE;
logic BranchM, JumpM, ReturnM, CallM;
logic BranchW, JumpW, ReturnW, CallW;
logic BPReturnWrongD;
logic [P.XLEN-1:0] BPBTAE;
logic BPBTAWrongM;
logic PCSrcM;
logic BTBCallF, BTBReturnF, BTBJumpF, BTBBranchF;
logic BPBranchF, BPJumpF, BPReturnF, BPCallF;
logic BPBranchD, BPJumpD, BPReturnD, BPCallD;
logic ReturnD, CallD;
logic ReturnE, CallE;
logic BranchM, JumpM, ReturnM, CallM;
logic BranchW, JumpW, ReturnW, CallW;
logic BPReturnWrongD;
logic BPBTAWrongM;
logic PCSrcM;
// Part 1 branch direction prediction
if (P.BPRED_TYPE == `BP_TWOBIT) begin:Predictor
@ -154,7 +147,7 @@ module bpred import cvw::*; #(parameter cvw_t P) (
btb #(P, P.BTB_SIZE)
TargetPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW,
.PCNextF, .PCF, .PCD, .PCE, .PCM,
.BPBTAF, .BPBTAD, .BPBTAE,
.BPBTAF,
.BTBIClassF({BTBCallF, BTBReturnF, BTBJumpF, BTBBranchF}),
.BPBTAWrongM,
.IClassWrongM,
@ -170,7 +163,7 @@ module bpred import cvw::*; #(parameter cvw_t P) (
.BTBBranchF, .BPCallF, .BPReturnF, .BPJumpF, .BPBranchF, .IClassWrongM, .BPReturnWrongD);
// Part 3 RAS
RASPredictor #(P) RASPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .FlushD, .FlushE, .FlushM,
RASPredictor #(P) RASPredictor(.clk, .reset, .StallD, .StallE, .StallM, .FlushD, .FlushE, .FlushM,
.BPReturnF, .ReturnD, .ReturnE, .CallE,
.BPReturnWrongD, .RASPCF, .PCLinkE);

View File

@ -36,8 +36,6 @@ module btb import cvw::*; #(parameter cvw_t P,
input logic StallF, StallD, StallE, StallM, StallW, FlushD, FlushE, FlushM, FlushW,
input logic [P.XLEN-1:0] PCNextF, PCF, PCD, PCE, PCM, // PC at various stages
output logic [P.XLEN-1:0] BPBTAF, // BTB's guess at PC
output logic [P.XLEN-1:0] BPBTAD,
output logic [P.XLEN-1:0] BPBTAE,
output logic [3:0] BTBIClassF, // BTB's guess at instruction class
output logic BPBTAWrongM,
// update
@ -52,11 +50,12 @@ module btb import cvw::*; #(parameter cvw_t P,
logic [Depth-1:0] PCNextFIndex, PCFIndex, PCDIndex, PCEIndex, PCMIndex, PCWIndex;
logic MatchD, MatchE, MatchM, MatchW, MatchX;
logic [P.XLEN+3:0] ForwardBTBPredF;
logic [P.XLEN+3:0] TableBTBPredF;
logic [P.XLEN-1:0] IEUAdrW;
logic [P.XLEN-1:0] PCW;
logic BTBWrongE, BPBTAWrongE;
logic [P.XLEN+3:0] ForwardBTBPredF;
logic [P.XLEN+3:0] TableBTBPredF;
logic [P.XLEN-1:0] IEUAdrW;
logic [P.XLEN-1:0] PCW;
logic [P.XLEN-1:0] BPBTAD, BPBTAE;
logic BPBTAWrongE;
logic BTBWrongM;

View File

@ -44,7 +44,7 @@ module gshare import cvw::*; #(parameter cvw_t P,
input logic BPBranchF, BranchD, BranchE, BranchM, BranchW, PCSrcE
);
logic MatchF, MatchD, MatchE, MatchM, MatchW;
logic MatchD, MatchE, MatchM, MatchW;
logic MatchX;
logic [1:0] PHTBPDirPredF, BPDirPredD, BPDirPredE, FwdNewDirPredF;

View File

@ -211,7 +211,7 @@ module ifu import cvw::*; #(parameter cvw_t P) (
// delay the interrupt until the LSU is in a clean state.
assign CommittedF = CacheCommittedF | BusCommittedF;
logic IgnoreRequest;
logic IgnoreRequest; // *** unused; RT: is this a bug or delete?
assign IgnoreRequest = ITLBMissF | FlushD;
// The IROM uses untranslated addresses, so it is not compatible with virtual memory.

View File

@ -131,7 +131,6 @@ module lsu import cvw::*; #(parameter cvw_t P) (
logic [P.LLEN-1:0] DCacheReadDataWordSpillM; // D$ read data
logic [P.LLEN-1:0] ReadDataWordMuxM; // DTIM or D$ read data
logic [P.LLEN-1:0] LittleEndianReadDataWordM; // Endian-swapped read data
logic [P.LLEN-1:0] ReadDataWordM; // Read data before subword selection
logic [P.LLEN-1:0] ReadDataM; // Final read data
logic [P.XLEN-1:0] IHWriteDataM; // IEU or HPTW write data
@ -380,7 +379,7 @@ 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, DCacheReadDataWordM} = '0;
end
end else begin: nobus // block: bus, only DTIM
assign {LSUHWDATA, LSUHADDR, LSUHWRITE, LSUHSIZE, LSUHBURST, LSUHTRANS, LSUHWSTRB} = '0;

View File

@ -45,12 +45,6 @@ module mdu import cvw::*; #(parameter cvw_t P) (
logic [P.XLEN-1:0] MDUResultM; // result after W truncation
logic W64M; // W-type instruction
logic [P.XLEN-1:0] AMDU, BMDU; // Gated inputs to MDU
// gate data inputs to MDU to only operate when MDU is active.
assign AMDU = ForwardedSrcAE & {P.XLEN{MDUActiveE}};
assign BMDU = ForwardedSrcBE & {P.XLEN{MDUActiveE}};
// Multiplier
mul #(P.XLEN) mul(.clk, .reset, .StallM, .FlushM, .ForwardedSrcAE, .ForwardedSrcBE, .Funct3E, .ProdM);

View File

@ -49,7 +49,7 @@ module hptw import cvw::*; #(parameter cvw_t P) (
input logic ITLBMissF,
input logic DTLBMissM,
input logic FlushW,
input logic InstrUpdateDAF,
input logic InstrUpdateDAF, // *** unused; RT, can we delete or is this a bug?
input logic DataUpdateDAM,
output logic [P.XLEN-1:0] PTE, // page table entry to TLBs
output logic [1:0] PageType, // page type to TLBs
@ -105,7 +105,7 @@ module hptw import cvw::*; #(parameter cvw_t P) (
logic HPTWLoadPageFault, HPTWStoreAmoPageFault, HPTWInstrPageFault;
logic HPTWLoadPageFaultDelay, HPTWStoreAmoPageFaultDelay, HPTWInstrPageFaultDelay;
logic HPTWAccessFaultDelay;
logic TakeHPTWFault, TakeHPTWFaultDelay;
logic TakeHPTWFault;
logic [P.XLEN-1:0] ReadDataNoXM;
logic PBMTFaultM;
logic HPTWFaultM;
@ -120,9 +120,9 @@ module hptw import cvw::*; #(parameter cvw_t P) (
assign HPTWStoreAmoPageFault = PBMTFaultM & DTLBWalk & MemRWM[0];
assign HPTWInstrPageFault = PBMTFaultM & ~DTLBWalk;
flopr #(7) HPTWAccesFaultReg(clk, reset, {TakeHPTWFault, HPTWLoadAccessFault, HPTWStoreAmoAccessFault, HPTWInstrAccessFault,
flopr #(6) HPTWAccesFaultReg(clk, reset, {HPTWLoadAccessFault, HPTWStoreAmoAccessFault, HPTWInstrAccessFault,
HPTWLoadPageFault, HPTWStoreAmoPageFault, HPTWInstrPageFault},
{TakeHPTWFaultDelay, HPTWLoadAccessFaultDelay, HPTWStoreAmoAccessFaultDelay, HPTWInstrAccessFaultDelay,
{HPTWLoadAccessFaultDelay, HPTWStoreAmoAccessFaultDelay, HPTWInstrAccessFaultDelay,
HPTWLoadPageFaultDelay, HPTWStoreAmoPageFaultDelay, HPTWInstrPageFaultDelay});
assign TakeHPTWFault = WalkerState != IDLE;
@ -320,7 +320,7 @@ module hptw import cvw::*; #(parameter cvw_t P) (
// stall and asserts one of HPTWLoadAccessFault, HPTWStoreAmoAccessFault or HPTWInstrAccessFaultDelay.
// The FSM directly transistions to IDLE to ready for the next operation when the delayed version will not be high.
assign HPTWAccessFaultDelay = HPTWLoadAccessFaultDelay | HPTWStoreAmoAccessFaultDelay | HPTWInstrAccessFaultDelay;
assign HPTWAccessFaultDelay = HPTWLoadAccessFaultDelay | HPTWStoreAmoAccessFaultDelay | HPTWInstrAccessFaultDelay; // *** unused - RT, can we delete?
assign HPTWStall = (WalkerState != IDLE & WalkerState != FAULT) | (WalkerState == IDLE & TLBMiss);
assign DTLBMissOrUpdateDAM = DTLBMissM | (P.SVADU_SUPPORTED & DataUpdateDAM);

View File

@ -71,7 +71,6 @@ module mmu import cvw::*; #(parameter cvw_t P,
logic PMPStoreAmoAccessFaultM; // Store or AMO access fault from PMP
logic DataMisalignedM; // load or store misaligned
logic Translate; // Translation occurs when virtual memory is active and DisableTranslation is off
logic TLBHit; // Hit in TLB
logic TLBPageFault; // Page fault from TLB
logic ReadNoAmoAccessM; // Read that is not part of atomic operation causes Load faults. Otherwise StoreAmo faults
logic [1:0] PBMemoryType; // PBMT field of PTE during TLB hit, or 00 otherwise
@ -90,14 +89,15 @@ module mmu import cvw::*; #(parameter cvw_t P,
.VAdr(VAdr[P.XLEN-1:0]), .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .ENVCFG_PBMTE, .ENVCFG_ADUE,
.PrivilegeModeW, .ReadAccess, .WriteAccess, .CMOpM,
.DisableTranslation, .PTE, .PageTypeWriteVal,
.TLBWrite, .TLBFlush, .TLBPAdr, .TLBMiss, .TLBHit,
.TLBWrite, .TLBFlush, .TLBPAdr, .TLBMiss,
.Translate, .TLBPageFault, .UpdateDA, .PBMemoryType);
end else begin:tlb // just pass address through as physical
assign Translate = 1'b0;
assign TLBMiss = 1'b0;
assign TLBHit = 1'b0;
assign TLBPageFault = 1'b0;
assign PBMemoryType = 2'b00;
assign UpdateDA = 1'b0;
assign TLBPAdr = '0;
end
// If translation is occuring, select translated physical address from TLB

View File

@ -72,7 +72,6 @@ module tlb import cvw::*; #(parameter cvw_t P,
input logic TLBFlush,
output logic [P.PA_BITS-1:0] TLBPAdr,
output logic TLBMiss,
output logic TLBHit,
output logic Translate,
output logic TLBPageFault,
output logic UpdateDA,
@ -87,6 +86,7 @@ module tlb import cvw::*; #(parameter cvw_t P,
logic [11:0] PTEAccessBits;
logic [1:0] HitPageType;
logic CAMHit;
logic TLBHit;
logic SV39Mode;
logic Misaligned;
logic MegapageMisaligned;
@ -110,12 +110,12 @@ module tlb import cvw::*; #(parameter cvw_t P,
assign NAPOT4 = (PPN[3:0] == 4'b1000); // 64 KiB contiguous region with pte.napot_bits = 4
tlbcontrol #(P, ITLB) tlbcontrol(.SATP_MODE, .VAdr, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .ENVCFG_PBMTE, .ENVCFG_ADUE,
.PrivilegeModeW, .ReadAccess, .WriteAccess, .CMOpM, .DisableTranslation, .TLBFlush,
.PrivilegeModeW, .ReadAccess, .WriteAccess, .CMOpM, .DisableTranslation,
.PTEAccessBits, .CAMHit, .Misaligned, .NAPOT4,
.TLBMiss, .TLBHit, .TLBPageFault,
.UpdateDA, .SV39Mode, .Translate, .PTE_N, .PBMemoryType);
tlblru #(TLB_ENTRIES) lru(.clk, .reset, .TLBWrite, .TLBFlush, .Matches, .TLBHit, .WriteEnables);
tlblru #(TLB_ENTRIES) lru(.clk, .reset, .TLBWrite, .Matches, .TLBHit, .WriteEnables);
tlbcam #(P, TLB_ENTRIES, P.VPN_BITS + P.ASID_BITS, P.VPN_SEGMENT_BITS)
tlbcam(.clk, .reset, .VPN, .PageTypeWriteVal, .SV39Mode, .TLBFlush, .WriteEnables, .PTE_Gs, .PTE_NAPOTs,
.SATP_ASID, .Matches, .HitPageType, .CAMHit);

View File

@ -38,7 +38,6 @@ module tlbcontrol import cvw::*; #(parameter cvw_t P, ITLB = 0) (
input logic ReadAccess, WriteAccess,
input logic [3:0] CMOpM,
input logic DisableTranslation,
input logic TLBFlush, // Invalidate all TLB entries
input logic [11:0] PTEAccessBits,
input logic CAMHit,
input logic Misaligned,

View File

@ -31,7 +31,6 @@
module tlblru #(parameter TLB_ENTRIES = 8) (
input logic clk, reset,
input logic TLBWrite,
input logic TLBFlush,
input logic [TLB_ENTRIES-1:0] Matches,
input logic TLBHit,
output logic [TLB_ENTRIES-1:0] WriteEnables

View File

@ -28,10 +28,10 @@
////////////////////////////////////////////////////////////////////////////////////////////////
module vm64check import cvw::*; #(parameter cvw_t P) (
input logic [P.SVMODE_BITS-1:0] SATP_MODE,
input logic [P.XLEN-1:0] VAdr,
output logic SV39Mode,
output logic UpperBitsUnequal
input logic [P.SVMODE_BITS-1:0] SATP_MODE,
input logic [P.XLEN-1:0] VAdr,
output logic SV39Mode,
output logic UpperBitsUnequal
);
if (P.XLEN == 64) begin

View File

@ -271,6 +271,8 @@ module csr import cvw::*; #(parameter cvw_t P) (
assign FRM_REGW = '0;
assign CSRUReadValM = '0;
assign IllegalCSRUAccessM = 1'b1;
assign WriteFRMM = 1'b0;
assign WriteFFLAGSM = 1'b0;
end
if (P.ZICNTR_SUPPORTED) begin:counters

View File

@ -45,8 +45,10 @@ module csrm import cvw::*; #(parameter cvw_t P) (
output logic [31:0] MCOUNTEREN_REGW, MCOUNTINHIBIT_REGW,
output logic [15:0] MEDELEG_REGW,
output logic [11:0] MIDELEG_REGW,
/* verilator lint_off UNDRIVEN */ // PMP registers are only used when PMP_ENTRIES > 0
output var logic [7:0] PMPCFG_ARRAY_REGW[P.PMP_ENTRIES-1:0],
output var logic [P.PA_BITS-3:0] PMPADDR_ARRAY_REGW [P.PMP_ENTRIES-1:0],
/* verilator lint_on UNDRIVEN */
output logic WriteMSTATUSM, WriteMSTATUSHM,
output logic IllegalCSRMAccessM, IllegalCSRMWriteReadonlyM,
output logic [63:0] MENVCFG_REGW

View File

@ -76,7 +76,7 @@ module clint_apb import cvw::*; #(parameter cvw_t P) (
default: PRDATA <= '0;
endcase
end
always_ff @(posedge PCLK or negedge PRESETn)
always_ff @(posedge PCLK)
if (~PRESETn) begin
MSIP <= 1'b0;
MTIMECMP <= 64'hFFFFFFFFFFFFFFFF; // Spec says MTIMECMP is not reset, but we reset to maximum value to prevent spurious timer interrupts
@ -92,7 +92,7 @@ module clint_apb import cvw::*; #(parameter cvw_t P) (
// eventually replace MTIME logic below with timereg
// timereg tr(PCLK, PRESETn, TIMECLK, memwrite & (entry==16'hBFF8), 1'b0, PWDATA, MTIME, done);
always_ff @(posedge PCLK or negedge PRESETn)
always_ff @(posedge PCLK)
if (~PRESETn) begin
MTIME <= '0;
end else if (memwrite & entry == 16'hBFF8) begin
@ -112,7 +112,7 @@ module clint_apb import cvw::*; #(parameter cvw_t P) (
default: PRDATA <= '0;
endcase
end
always_ff @(posedge PCLK or negedge PRESETn)
always_ff @(posedge PCLK)
if (~PRESETn) begin
MSIP <= 1'b0;
MTIMECMP <= '0;
@ -131,7 +131,7 @@ module clint_apb import cvw::*; #(parameter cvw_t P) (
// eventually replace MTIME logic below with timereg
// timereg tr(PCLK, PRESETn, TIMECLK, memwrite & (entry==16'hBFF8), memwrite & (entry == 16'hBFFC), PWDATA, MTIME, done);
always_ff @(posedge PCLK or negedge PRESETn)
always_ff @(posedge PCLK)
if (~PRESETn) begin
MTIME <= '0;
// MTIMECMP is not reset
@ -251,4 +251,4 @@ module graytobinary #(parameter N) (
assign b[i] = g[i] ^ b[i+1];
end
endmodule
*/
*/

View File

@ -82,8 +82,8 @@ module gpio_apb import cvw::*; #(parameter cvw_t P) (
else assign PRDATA = Dout;
// register access
always_ff @(posedge PCLK, negedge PRESETn)
if (~PRESETn) begin // asynch reset
always_ff @(posedge PCLK)
if (~PRESETn) begin
input_en <= '0;
output_en <= '0;
output_val <= '0;

View File

@ -61,6 +61,10 @@ module spi_apb import cvw::*; #(parameter cvw_t P) (
localparam SPI_IE = 8'h70;
localparam SPI_IP = 8'h74;
// receive shift register states
typedef enum logic [1:0] {ReceiveShiftFullState, ReceiveShiftNotFullState, ReceiveShiftDelayState} rsrstatetype;
// SPI control registers. Refer to SiFive FU540-C000 manual
logic [11:0] SckDiv;
logic [1:0] SckMode;
@ -88,8 +92,11 @@ module spi_apb import cvw::*; #(parameter cvw_t P) (
logic ReceiveFIFOReadIncrement;
logic ReceiveFIFOWriteFull, ReceiveFIFOReadEmpty;
logic [7:0] TransmitFIFOReadData;
logic [2:0] TransmitWriteWatermarkLevel, ReceiveReadWatermarkLevel;
/* verilator lint_off UNDRIVEN */
logic [2:0] TransmitWriteWatermarkLevel, ReceiveReadWatermarkLevel; // unused generic FIFO outputs
/* verilator lint_off UNDRIVEN */
logic [7:0] ReceiveShiftRegEndian; // Reverses ReceiveShiftReg if Format[2] set (little endian transmission)
rsrstatetype ReceiveState;
// Transmission signals
logic sck;
@ -150,7 +157,7 @@ module spi_apb import cvw::*; #(parameter cvw_t P) (
else assign PRDATA = Dout;
// Register access
always_ff@(posedge PCLK, negedge PRESETn)
always_ff@(posedge PCLK)
if (~PRESETn) begin
SckDiv <= 12'd3;
SckMode <= 2'b0;
@ -215,7 +222,7 @@ module spi_apb import cvw::*; #(parameter cvw_t P) (
// Active at 2x SCLK frequency to account for implicit half cycle delays and actions on both clock edges depending on phase
assign SCLKenable = (DivCounter == SckDiv);
assign SCLKenableEarly = ((DivCounter + 12'b1) == SckDiv);
always_ff @(posedge PCLK, negedge PRESETn)
always_ff @(posedge PCLK)
if (~PRESETn) DivCounter <= '0;
else if (SCLKenable) DivCounter <= 12'b0;
else DivCounter <= DivCounter + 12'b1;
@ -229,33 +236,56 @@ module spi_apb import cvw::*; #(parameter cvw_t P) (
assign ImplicitDelay2 = SckMode[0] ? 9'b1 : 9'b0;
// Calculate when tx/rx shift registers are full/empty
TransmitShiftFSM TransmitShiftFSM(PCLK, PRESETn, TransmitFIFOReadEmpty, ReceivePenultimateFrame, Active0, TransmitShiftEmpty);
ReceiveShiftFSM ReceiveShiftFSM(PCLK, PRESETn, SCLKenable, ReceivePenultimateFrame, SampleEdge, SckMode[0], ReceiveShiftFull);
// Transmit Shift FSM
always_ff @(posedge PCLK)
if (~PRESETn) TransmitShiftEmpty <= 1'b1;
else if (TransmitShiftEmpty) begin
if (TransmitFIFOReadEmpty | (~TransmitFIFOReadEmpty & (ReceivePenultimateFrame & Active0))) TransmitShiftEmpty <= 1'b1;
else if (~TransmitFIFOReadEmpty) TransmitShiftEmpty <= 1'b0;
end else begin
if (ReceivePenultimateFrame & Active0) TransmitShiftEmpty <= 1'b1;
else TransmitShiftEmpty <= 1'b0;
end
// Receive Shift FSM
always_ff @(posedge PCLK)
if (~PRESETn) ReceiveState <= ReceiveShiftNotFullState;
else if (SCLKenable) begin
case (ReceiveState)
ReceiveShiftFullState: ReceiveState <= ReceiveShiftNotFullState;
ReceiveShiftNotFullState: if (ReceivePenultimateFrame & (SampleEdge)) ReceiveState <= ReceiveShiftDelayState;
else ReceiveState <= ReceiveShiftNotFullState;
ReceiveShiftDelayState: ReceiveState <= ReceiveShiftFullState;
endcase
end
assign ReceiveShiftFull = SckMode[0] ? (ReceiveState == ReceiveShiftFullState) : (ReceiveState == ReceiveShiftDelayState);
// Calculate tx/rx fifo write and recieve increment signals
always_ff @(posedge PCLK, negedge PRESETn)
always_ff @(posedge PCLK)
if (~PRESETn) TransmitFIFOWriteIncrement <= 1'b0;
else TransmitFIFOWriteIncrement <= (Memwrite & (Entry == 8'h48) & ~TransmitFIFOWriteFull & TransmitInactive);
always_ff @(posedge PCLK, negedge PRESETn)
always_ff @(posedge PCLK)
if (~PRESETn) ReceiveFIFOReadIncrement <= 1'b0;
else ReceiveFIFOReadIncrement <= ((Entry == 8'h4C) & ~ReceiveFIFOReadEmpty & PSEL & ~ReceiveFIFOReadIncrement);
// Tx/Rx FIFOs
SynchFIFO #(3,8) txFIFO(PCLK, 1'b1, SCLKenable, PRESETn, TransmitFIFOWriteIncrement, TransmitShiftEmpty, TransmitData[7:0], TransmitWriteWatermarkLevel, TransmitWatermark[2:0],
spi_fifo #(3,8) txFIFO(PCLK, 1'b1, SCLKenable, PRESETn, TransmitFIFOWriteIncrement, TransmitShiftEmpty, TransmitData[7:0], TransmitWriteWatermarkLevel, TransmitWatermark[2:0],
TransmitFIFOReadData[7:0], TransmitFIFOWriteFull, TransmitFIFOReadEmpty, TransmitWriteMark, TransmitReadMark);
SynchFIFO #(3,8) rxFIFO(PCLK, SCLKenable, 1'b1, PRESETn, ReceiveShiftFullDelay, ReceiveFIFOReadIncrement, ReceiveShiftRegEndian, ReceiveWatermark[2:0], ReceiveReadWatermarkLevel,
spi_fifo #(3,8) rxFIFO(PCLK, SCLKenable, 1'b1, PRESETn, ReceiveShiftFullDelay, ReceiveFIFOReadIncrement, ReceiveShiftRegEndian, ReceiveWatermark[2:0], ReceiveReadWatermarkLevel,
ReceiveData[7:0], ReceiveFIFOWriteFull, ReceiveFIFOReadEmpty, RecieveWriteMark, RecieveReadMark);
always_ff @(posedge PCLK, negedge PRESETn)
always_ff @(posedge PCLK)
if (~PRESETn) TransmitFIFOReadEmptyDelay <= 1'b1;
else if (SCLKenable) TransmitFIFOReadEmptyDelay <= TransmitFIFOReadEmpty;
always_ff @(posedge PCLK, negedge PRESETn)
always_ff @(posedge PCLK)
if (~PRESETn) ReceiveShiftFullDelay <= 1'b0;
else if (SCLKenable) ReceiveShiftFullDelay <= ReceiveShiftFull;
always_ff @(posedge PCLK, negedge PRESETn)
always_ff @(posedge PCLK)
if (~PRESETn) ReceiveShiftFullDelayPCLK <= 1'b0;
else if (SCLKenableEarly) ReceiveShiftFullDelayPCLK <= ReceiveShiftFull;
@ -265,7 +295,7 @@ module spi_apb import cvw::*; #(parameter cvw_t P) (
typedef enum logic [2:0] {CS_INACTIVE, DELAY_0, ACTIVE_0, ACTIVE_1, DELAY_1,INTER_CS, INTER_XFR} statetype;
statetype state;
always_ff @(posedge PCLK, negedge PRESETn)
always_ff @(posedge PCLK)
if (~PRESETn) begin
state <= CS_INACTIVE;
FrameCount <= 4'b0;
@ -347,7 +377,7 @@ module spi_apb import cvw::*; #(parameter cvw_t P) (
// Transmit shift register
assign TransmitDataEndian = Format[0] ? {TransmitFIFOReadData[0], TransmitFIFOReadData[1], TransmitFIFOReadData[2], TransmitFIFOReadData[3], TransmitFIFOReadData[4], TransmitFIFOReadData[5], TransmitFIFOReadData[6], TransmitFIFOReadData[7]} : TransmitFIFOReadData[7:0];
always_ff @(posedge PCLK, negedge PRESETn)
always_ff @(posedge PCLK)
if(~PRESETn) TransmitShiftReg <= 8'b0;
else if (TransmitShiftRegLoad) TransmitShiftReg <= TransmitDataEndian;
else if (ShiftEdge & Active) TransmitShiftReg <= {TransmitShiftReg[6:0], 1'b0};
@ -359,7 +389,7 @@ module spi_apb import cvw::*; #(parameter cvw_t P) (
assign ShiftIn = P.SPI_LOOPBACK_TEST ? SPIOut : SPIIn;
// Receive shift register
always_ff @(posedge PCLK, negedge PRESETn)
always_ff @(posedge PCLK)
if(~PRESETn) ReceiveShiftReg <= 8'b0;
else if (SampleEdge & SCLKenable) begin
if (~Active) ReceiveShiftReg <= 8'b0;
@ -385,94 +415,3 @@ module spi_apb import cvw::*; #(parameter cvw_t P) (
assign SPICS = ChipSelectMode[0] ? ChipSelectDef : ChipSelectAuto;
endmodule
module SynchFIFO #(parameter M=3, N=8)( // 2^M entries of N bits each
input logic PCLK, wen, ren, PRESETn,
input logic winc, rinc,
input logic [N-1:0] wdata,
input logic [M-1:0] wwatermarklevel, rwatermarklevel,
output logic [N-1:0] rdata,
output logic wfull, rempty,
output logic wwatermark, rwatermark);
/* Pointer FIFO using design elements from "Simulation and Synthesis Techniques
for Asynchronous FIFO Design" by Clifford E. Cummings. Namely, M bit read and write pointers
are an extra bit larger than address size to determine full/empty conditions.
Watermark comparisons use 2's complement subtraction between the M-1 bit pointers,
which are also used to address memory
*/
logic [N-1:0] mem[2**M];
logic [M:0] rptr, wptr;
logic [M:0] rptrnext, wptrnext;
logic [M-1:0] raddr;
logic [M-1:0] waddr;
assign rdata = mem[raddr];
always_ff @(posedge PCLK)
if (winc & ~wfull) mem[waddr] <= wdata;
// write and read are enabled
always_ff @(posedge PCLK, negedge PRESETn)
if (~PRESETn) begin
rptr <= '0;
wptr <= '0;
wfull <= 1'b0;
rempty <= 1'b1;
end else begin
if (wen) begin
wfull <= ({~wptrnext[M], wptrnext[M-1:0]} == rptr);
wptr <= wptrnext;
end
if (ren) begin
rptr <= rptrnext;
rempty <= (wptr == rptrnext);
end
end
assign raddr = rptr[M-1:0];
assign rptrnext = rptr + {{(M){1'b0}}, (rinc & ~rempty)};
assign rwatermark = ((waddr - raddr) < rwatermarklevel) & ~wfull;
assign waddr = wptr[M-1:0];
assign wwatermark = ((waddr - raddr) > wwatermarklevel) | wfull;
assign wptrnext = wptr + {{(M){1'b0}}, (winc & ~wfull)};
endmodule
module TransmitShiftFSM(
input logic PCLK, PRESETn,
input logic TransmitFIFOReadEmpty, ReceivePenultimateFrame, Active0,
output logic TransmitShiftEmpty);
always_ff @(posedge PCLK, negedge PRESETn)
if (~PRESETn) TransmitShiftEmpty <= 1'b1;
else if (TransmitShiftEmpty) begin
if (TransmitFIFOReadEmpty | (~TransmitFIFOReadEmpty & (ReceivePenultimateFrame & Active0))) TransmitShiftEmpty <= 1'b1;
else if (~TransmitFIFOReadEmpty) TransmitShiftEmpty <= 1'b0;
end else begin
if (ReceivePenultimateFrame & Active0) TransmitShiftEmpty <= 1'b1;
else TransmitShiftEmpty <= 1'b0;
end
endmodule
module ReceiveShiftFSM(
input logic PCLK, PRESETn, SCLKenable,
input logic ReceivePenultimateFrame, SampleEdge, SckMode,
output logic ReceiveShiftFull
);
typedef enum logic [1:0] {ReceiveShiftFullState, ReceiveShiftNotFullState, ReceiveShiftDelayState} statetype;
statetype ReceiveState, ReceiveNextState;
always_ff @(posedge PCLK, negedge PRESETn)
if (~PRESETn) ReceiveState <= ReceiveShiftNotFullState;
else if (SCLKenable) begin
case (ReceiveState)
ReceiveShiftFullState: ReceiveState <= ReceiveShiftNotFullState;
ReceiveShiftNotFullState: if (ReceivePenultimateFrame & (SampleEdge)) ReceiveState <= ReceiveShiftDelayState;
else ReceiveState <= ReceiveShiftNotFullState;
ReceiveShiftDelayState: ReceiveState <= ReceiveShiftFullState;
endcase
end
assign ReceiveShiftFull = SckMode ? (ReceiveState == ReceiveShiftFullState) : (ReceiveState == ReceiveShiftDelayState);
endmodule

51
src/uncore/spi_fifo.sv Normal file
View File

@ -0,0 +1,51 @@
module spi_fifo #(parameter M=3, N=8)( // 2^M entries of N bits each
input logic PCLK, wen, ren, PRESETn,
input logic winc, rinc,
input logic [N-1:0] wdata,
input logic [M-1:0] wwatermarklevel, rwatermarklevel,
output logic [N-1:0] rdata,
output logic wfull, rempty,
output logic wwatermark, rwatermark);
/* Pointer FIFO using design elements from "Simulation and Synthesis Techniques
for Asynchronous FIFO Design" by Clifford E. Cummings. Namely, M bit read and write pointers
are an extra bit larger than address size to determine full/empty conditions.
Watermark comparisons use 2's complement subtraction between the M-1 bit pointers,
which are also used to address memory
*/
logic [N-1:0] mem[2**M];
logic [M:0] rptr, wptr;
logic [M:0] rptrnext, wptrnext;
logic [M-1:0] raddr;
logic [M-1:0] waddr;
assign rdata = mem[raddr];
always_ff @(posedge PCLK)
if (winc & ~wfull) mem[waddr] <= wdata;
// write and read are enabled
always_ff @(posedge PCLK)
if (~PRESETn) begin
rptr <= '0;
wptr <= '0;
wfull <= 1'b0;
rempty <= 1'b1;
end else begin
if (wen) begin
wfull <= ({~wptrnext[M], wptrnext[M-1:0]} == rptr);
wptr <= wptrnext;
end
if (ren) begin
rptr <= rptrnext;
rempty <= (wptr == rptrnext);
end
end
assign raddr = rptr[M-1:0];
assign rptrnext = rptr + {{(M){1'b0}}, (rinc & ~rempty)};
assign rwatermark = ((waddr - raddr) < rwatermarklevel) & ~wfull;
assign waddr = wptr[M-1:0];
assign wwatermark = ((waddr - raddr) > wwatermarklevel) | wfull;
assign wptrnext = wptr + {{(M){1'b0}}, (winc & ~wfull)};
endmodule

View File

@ -94,7 +94,7 @@ module uartPC16550D #(parameter UART_PRESCALE) (
logic [7:0] txfifo[15:0];
logic [4:0] rxfifotailunwrapped;
logic [3:0] rxfifohead, rxfifotail, txfifohead, txfifotail, rxfifotriggerlevel;
logic [3:0] rxfifoentries, txfifoentries;
logic [3:0] rxfifoentries;
logic [3:0] rxbitsexpected, txbitsexpected;
// receive data
@ -145,7 +145,7 @@ module uartPC16550D #(parameter UART_PRESCALE) (
// Register interface (Table 1, note some are read only and some write only)
///////////////////////////////////////////
always_ff @(posedge PCLK, negedge PRESETn)
always_ff @(posedge PCLK)
if (~PRESETn) begin // Table 3 Reset Configuration
IER <= 4'b0;
FCR <= 8'b0;
@ -222,7 +222,7 @@ module uartPC16550D #(parameter UART_PRESCALE) (
// the data, so the baud rate is 320x10^6 / (65 x 2^5 x 16) = 9615 Hz, which is
// close enough to 9600 baud to stay synchronized over the duration of one character.
///////////////////////////////////////////
always_ff @(posedge PCLK, negedge PRESETn)
always_ff @(posedge PCLK)
if (~PRESETn) begin
baudcount <= 1;
baudpulse <= 1'b0;
@ -248,7 +248,7 @@ module uartPC16550D #(parameter UART_PRESCALE) (
// receive timing and control
///////////////////////////////////////////
always_ff @(posedge PCLK, negedge PRESETn)
always_ff @(posedge PCLK)
if (~PRESETn) begin
rxoversampledcnt <= '0;
rxstate <= UART_IDLE;
@ -281,7 +281,7 @@ module uartPC16550D #(parameter UART_PRESCALE) (
// receive shift register, buffer register, FIFO
///////////////////////////////////////////
always_ff @(posedge PCLK, negedge PRESETn)
always_ff @(posedge PCLK)
if (~PRESETn) rxshiftreg <= 10'b0000000001; // initialize so that there is a valid stop bit
else if (rxcentered) rxshiftreg <= {rxshiftreg[8:0], SINsync}; // capture bit
assign rxparitybit = rxshiftreg[1]; // parity, if it exists, in bit 1 when all done
@ -363,7 +363,7 @@ module uartPC16550D #(parameter UART_PRESCALE) (
assign rxfifohaserr = |(RXerrbit & rxfullbit);
// receive buffer register and ready bit
always_ff @(posedge PCLK, negedge PRESETn) // track rxrdy for DMA mode (FCR3 = FCR0 = 1)
always_ff @(posedge PCLK) // track rxrdy for DMA mode (FCR3 = FCR0 = 1)
if (~PRESETn) rxfifodmaready <= 1'b0;
else if (rxfifotriggered | rxfifotimeout) rxfifodmaready <= 1'b1;
else if (rxfifoempty) rxfifodmaready <= 1'b0;
@ -383,7 +383,7 @@ module uartPC16550D #(parameter UART_PRESCALE) (
// transmit timing and control
///////////////////////////////////////////
always_ff @(posedge PCLK, negedge PRESETn)
always_ff @(posedge PCLK)
if (~PRESETn) begin
txoversampledcnt <= '0;
txstate <= UART_IDLE;
@ -431,7 +431,7 @@ module uartPC16550D #(parameter UART_PRESCALE) (
end
// registers & FIFO
always_ff @(posedge PCLK, negedge PRESETn)
always_ff @(posedge PCLK)
if (~PRESETn) begin
txfifohead <= '0; txfifotail <= '0; txhrfull <= 1'b0; txsrfull <= 1'b0; TXHR <= '0; txsr <= 12'hfff;
end else if (~MEMWb & (A == 3'b010) & Din[2]) begin
@ -467,7 +467,7 @@ module uartPC16550D #(parameter UART_PRESCALE) (
end
end
always_ff @(posedge PCLK, negedge PRESETn) begin
always_ff @(posedge PCLK) begin
// special condition to check if the fifo is empty or full. Because the head
// pointer indicates where the next write goes and not the location of the
// current head, the head and tail pointer being equal imply two different
@ -484,15 +484,11 @@ module uartPC16550D #(parameter UART_PRESCALE) (
HeadPointerLastMove <= 1'b0;
end
assign txfifoempty = (txfifohead == txfifotail) & ~HeadPointerLastMove;
// verilator lint_off WIDTH
assign txfifoentries = (txfifohead >= txfifotail) ? (txfifohead-txfifotail) :
(txfifohead + 16 - txfifotail);
// verilator lint_on WIDTH
assign txfifofull = (txfifohead == txfifotail) & HeadPointerLastMove;
assign txfifoempty = (txfifohead == txfifotail) & ~HeadPointerLastMove;
assign txfifofull = (txfifohead == txfifotail) & HeadPointerLastMove;
// transmit buffer ready bit
always_ff @(posedge PCLK, negedge PRESETn) // track txrdy for DMA mode (FCR3 = FCR0 = 1)
always_ff @(posedge PCLK) // track txrdy for DMA mode (FCR3 = FCR0 = 1)
if (~PRESETn) txfifodmaready <= 1'b0;
else if (txfifoempty) txfifodmaready <= 1'b1;
else if (txfifofull) txfifodmaready <= 1'b0;

View File

@ -75,11 +75,14 @@ module uncore import cvw::*; #(parameter cvw_t P)(
logic SDCIntM;
logic PCLK, PRESETn, PWRITE, PENABLE;
logic [4:0] PSEL, PREADY;
logic [4:0] PSEL;
logic [31:0] PADDR;
logic [P.XLEN-1:0] PWDATA;
logic [P.XLEN/8-1:0] PSTRB;
/* verilator lint_off UNDRIVEN */ // undriven in rv32e configuration
logic [4:0] PREADY;
logic [4:0][P.XLEN-1:0] PRDATA;
/* verilator lint_on UNDRIVEN */
logic [P.XLEN-1:0] HREADBRIDGE;
logic HRESPBRIDGE, HREADYBRIDGE, HSELBRIDGE, HSELBRIDGED;
@ -106,13 +109,13 @@ module uncore import cvw::*; #(parameter cvw_t P)(
ram_ahb #(.P(P), .BASE(P.UNCORE_RAM_BASE), .RANGE(P.UNCORE_RAM_RANGE), .PRELOAD(P.UNCORE_RAM_PRELOAD)) ram (
.HCLK, .HRESETn, .HSELRam, .HADDR, .HWRITE, .HREADY,
.HTRANS, .HWDATA, .HWSTRB, .HREADRam, .HRESPRam, .HREADYRam);
end
end else assign {HREADRam, HRESPRam, HREADYRam} = '0;
if (P.BOOTROM_SUPPORTED) begin : bootrom
rom_ahb #(.P(P), .BASE(P.BOOTROM_BASE), .RANGE(P.BOOTROM_RANGE), .PRELOAD(P.BOOTROM_PRELOAD))
bootrom(.HCLK, .HRESETn, .HSELRom(HSELBootRom), .HADDR, .HREADY, .HTRANS,
.HREADRom(HREADBootRom), .HRESPRom(HRESPBootRom), .HREADYRom(HREADYBootRom));
end
end else assign {HREADBootRom, HRESPBootRom, HREADYBootRom} = '0;
// memory-mapped I/O peripherals
if (P.CLINT_SUPPORTED == 1) begin : clint

View File

@ -115,8 +115,10 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
logic SelHPTW;
// PMA checker signals
/* verilator lint_off UNDRIVEN */ // these signals are undriven in configurations without a privileged unit
var logic [P.PA_BITS-3:0] PMPADDR_ARRAY_REGW[P.PMP_ENTRIES-1:0];
var logic [7:0] PMPCFG_ARRAY_REGW[P.PMP_ENTRIES-1:0];
/* verilator lint_on UNDRIVEN */
// IMem stalls
logic IFUStallF;
@ -351,7 +353,7 @@ 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, FWriteIntE, FCvtIntE, FIntResM, FCvtIntW,
assign {FPUStallD, FWriteIntE, FCvtIntE, FIntResM, FCvtIntW, FRegWriteM,
IllegalFPUInstrD, SetFflagsM, FpLoadStoreM,
FWriteDataM, FCvtIntResW, FIntDivResultW, FDivBusyE} = '0;
end

View File

@ -26,14 +26,18 @@
`include "config.vh"
import cvw::*;
module wallywrapper;
module wallywrapper import cvw::*;(
input logic clk,
input logic reset_ext,
input logic SPIIn,
input logic SDCIntr
);
`include "parameter-defs.vh"
logic clk;
logic reset_ext, reset;
logic reset;
logic [P.AHBW-1:0] HRDATAEXT;
logic HREADYEXT, HRESPEXT;
@ -50,9 +54,8 @@ module wallywrapper;
logic [31:0] GPIOIN, GPIOOUT, GPIOEN;
logic UARTSin, UARTSout;
logic SPIIn, SPIOut;
logic SPIOut;
logic [3:0] SPICS;
logic SDCIntr;
logic HREADY;
logic HSELEXT;