mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-03 10:15:19 +00:00
Merge pull request #453 from davidharrishmc/dev
Fixed regression error of watchdog timeout when PCM is optimized out of the IFU
This commit is contained in:
commit
380694293f
@ -20,7 +20,7 @@
|
||||
--override cpu/Zicboz=T
|
||||
--override cpu/Svpbmt=T
|
||||
# 64 KiB continuous huge pages supported
|
||||
--override cpu/Svnapot_page_mask=1<<16
|
||||
--override cpu/Svnapot_page_mask=65536
|
||||
|
||||
|
||||
# clarify
|
||||
|
10
sim/verilate
10
sim/verilate
@ -8,15 +8,9 @@ basepath=$(dirname $0)/..
|
||||
#for config in rv32e rv64gc rv32gc rv32imc rv32i rv64i rv64fpquad; do
|
||||
for config in rv64gc; do
|
||||
echo "$config simulating..."
|
||||
if !($verilator --timescale "1ns/1ns" --timing --cc "$@" --top-module testbench "-I$basepath/config/shared" "-I$basepath/config/$config" $basepath/src/wally/cvw.sv $basepath/testbench/common/*.sv $basepath/testbench/testbench.sv $basepath/src/*/*.sv $basepath/src/*/*/*.sv --relative-includes ); then
|
||||
if !($verilator --timescale "1ns/1ns" --timing --exe --cc "$@" --top-module testbench "-I$basepath/config/shared" "-I$basepath/config/$config" $basepath/src/cvw.sv $basepath/testbench/testbench.sv $basepath/testbench/common/*.sv $basepath/src/*/*.sv $basepath/src/*/*/*.sv --relative-includes ); then
|
||||
echo "Exiting after $config lint due to errors or warnings"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
echo "All lints run with no errors or warnings"
|
||||
|
||||
# --lint-only just runs lint rather than trying to compile and simulate
|
||||
# -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
|
||||
# Unfortunately, this produces a bunch of UNUSED and UNDRIVEN signal warnings in blocks that are configured to not exist.
|
||||
echo "Verilation complete"
|
||||
|
6
src/cache/cacheway.sv
vendored
6
src/cache/cacheway.sv
vendored
@ -126,7 +126,7 @@ module cacheway import cvw::*; #(parameter cvw_t P,
|
||||
// Tag Array
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ram1p1rwe #(.P(P), .DEPTH(NUMLINES), .WIDTH(TAGLEN)) CacheTagMem(.clk, .ce(CacheEn),
|
||||
ram1p1rwe #(.USE_SRAM(P.USE_SRAM), .DEPTH(NUMLINES), .WIDTH(TAGLEN)) CacheTagMem(.clk, .ce(CacheEn),
|
||||
.addr(CacheSet), .dout(ReadTag),
|
||||
.din(PAdr[PA_BITS-1:OFFSETLEN+INDEXLEN]), .we(SetValidEN));
|
||||
|
||||
@ -148,12 +148,12 @@ module cacheway import cvw::*; #(parameter cvw_t P,
|
||||
|
||||
for(words = 0; words < NUMSRAM; words++) begin: word
|
||||
if (!READ_ONLY_CACHE) begin:wordram
|
||||
ram1p1rwbe #(.P(P), .DEPTH(NUMLINES), .WIDTH(SRAMLEN)) CacheDataMem(.clk, .ce(CacheEn), .addr(CacheSet),
|
||||
ram1p1rwbe #(.USE_SRAM(P.USE_SRAM), .DEPTH(NUMLINES), .WIDTH(SRAMLEN)) CacheDataMem(.clk, .ce(CacheEn), .addr(CacheSet),
|
||||
.dout(ReadDataLine[SRAMLEN*(words+1)-1:SRAMLEN*words]),
|
||||
.din(LineWriteData[SRAMLEN*(words+1)-1:SRAMLEN*words]),
|
||||
.we(SelectedWriteWordEn), .bwe(FinalByteMask[SRAMLENINBYTES*(words+1)-1:SRAMLENINBYTES*words]));
|
||||
end else begin:wordram // no byte-enable needed for i$.
|
||||
ram1p1rwe #(.P(P), .DEPTH(NUMLINES), .WIDTH(SRAMLEN)) CacheDataMem(.clk, .ce(CacheEn), .addr(CacheSet),
|
||||
ram1p1rwe #(.USE_SRAM(P.USE_SRAM), .DEPTH(NUMLINES), .WIDTH(SRAMLEN)) CacheDataMem(.clk, .ce(CacheEn), .addr(CacheSet),
|
||||
.dout(ReadDataLine[SRAMLEN*(words+1)-1:SRAMLEN*words]),
|
||||
.din(LineWriteData[SRAMLEN*(words+1)-1:SRAMLEN*words]),
|
||||
.we(SelectedWriteWordEn));
|
||||
|
@ -65,7 +65,8 @@ module fdivsqrtcycles import cvw::*; #(parameter cvw_t P) (
|
||||
endcase
|
||||
|
||||
always_comb begin
|
||||
if (SqrtE) fbits = Nf + 2 + 2; // Nf + two fractional bits for round/guard + 2 for right shift by up to 2
|
||||
if (SqrtE) fbits = Nf + 2 + 1; // Nf + two fractional bits for round/guard + 2 for right shift by up to 2 *** unclear why it works with just +1; is it related to DIVCOPIES logic below?
|
||||
// if (SqrtE) fbits = Nf + 2 + 2; // Nf + two fractional bits for round/guard + 2 for right shift by up to 2
|
||||
else fbits = Nf + 2 + P.LOGR; // Nf + two fractional bits for round/guard + integer bits - try this when placing results in msbs
|
||||
if (P.IDIV_ON_FPU) CyclesE = IntDivE ? ((nE + 1)/P.DIVCOPIES) : (fbits + (P.LOGR*P.DIVCOPIES)-1)/(P.LOGR*P.DIVCOPIES);
|
||||
else CyclesE = (fbits + (P.LOGR*P.DIVCOPIES)-1)/(P.LOGR*P.DIVCOPIES);
|
||||
|
@ -32,8 +32,7 @@
|
||||
|
||||
// WIDTH is number of bits in one "word" of the memory, DEPTH is number of such words
|
||||
|
||||
module ram1p1rwbe import cvw::*; #(parameter cvw_t P, parameter DEPTH=64, WIDTH=44,
|
||||
parameter PRELOAD_ENABLED=0) (
|
||||
module ram1p1rwbe import cvw::*; #(parameter USE_SRAM=0, DEPTH=64, WIDTH=44, PRELOAD_ENABLED=0) (
|
||||
input logic clk,
|
||||
input logic ce,
|
||||
input logic [$clog2(DEPTH)-1:0] addr,
|
||||
@ -48,7 +47,7 @@ module ram1p1rwbe import cvw::*; #(parameter cvw_t P, parameter DEPTH=64, WIDTH=
|
||||
// ***************************************************************************
|
||||
// TRUE SRAM macro
|
||||
// ***************************************************************************
|
||||
if ((P.USE_SRAM == 1) & (WIDTH == 128) & (DEPTH == 64)) begin // Cache data subarray
|
||||
if ((USE_SRAM == 1) & (WIDTH == 128) & (DEPTH == 64)) begin // Cache data subarray
|
||||
genvar index;
|
||||
// 64 x 128-bit SRAM
|
||||
logic [WIDTH-1:0] BitWriteMask;
|
||||
@ -58,7 +57,7 @@ module ram1p1rwbe import cvw::*; #(parameter cvw_t P, parameter DEPTH=64, WIDTH=
|
||||
.A(addr), .D(din),
|
||||
.BWEB(~BitWriteMask), .Q(dout));
|
||||
|
||||
end else if ((P.USE_SRAM == 1) & (WIDTH == 44) & (DEPTH == 64)) begin // RV64 cache tag
|
||||
end else if ((USE_SRAM == 1) & (WIDTH == 44) & (DEPTH == 64)) begin // RV64 cache tag
|
||||
genvar index;
|
||||
// 64 x 44-bit SRAM
|
||||
logic [WIDTH-1:0] BitWriteMask;
|
||||
@ -68,7 +67,7 @@ module ram1p1rwbe import cvw::*; #(parameter cvw_t P, parameter DEPTH=64, WIDTH=
|
||||
.A(addr), .D(din),
|
||||
.BWEB(~BitWriteMask), .Q(dout));
|
||||
|
||||
end else if ((P.USE_SRAM == 1) & (WIDTH == 22) & (DEPTH == 64)) begin // RV32 cache tag
|
||||
end else if ((USE_SRAM == 1) & (WIDTH == 22) & (DEPTH == 64)) begin // RV32 cache tag
|
||||
genvar index;
|
||||
// 64 x 22-bit SRAM
|
||||
logic [WIDTH-1:0] BitWriteMask;
|
||||
|
@ -30,8 +30,7 @@
|
||||
|
||||
// WIDTH is number of bits in one "word" of the memory, DEPTH is number of such words
|
||||
|
||||
module ram1p1rwe import cvw::* ; #(parameter cvw_t P,
|
||||
parameter DEPTH=64, WIDTH=44) (
|
||||
module ram1p1rwe import cvw::* ; #(parameter USE_SRAM=0, DEPTH=64, WIDTH=44) (
|
||||
input logic clk,
|
||||
input logic ce,
|
||||
input logic [$clog2(DEPTH)-1:0] addr,
|
||||
@ -45,19 +44,19 @@ module ram1p1rwe import cvw::* ; #(parameter cvw_t P,
|
||||
// ***************************************************************************
|
||||
// TRUE SRAM macro
|
||||
// ***************************************************************************
|
||||
if ((P.USE_SRAM == 1) & (WIDTH == 128) & (DEPTH == 64)) begin // Cache data subarray
|
||||
if ((USE_SRAM == 1) & (WIDTH == 128) & (DEPTH == 64)) begin // Cache data subarray
|
||||
// 64 x 128-bit SRAM
|
||||
ram1p1rwbe_64x128 sram1A (.CLK(clk), .CEB(~ce), .WEB(~we),
|
||||
.A(addr), .D(din),
|
||||
.BWEB('0), .Q(dout));
|
||||
|
||||
end else if ((P.USE_SRAM == 1) & (WIDTH == 44) & (DEPTH == 64)) begin // RV64 cache tag
|
||||
end else if ((USE_SRAM == 1) & (WIDTH == 44) & (DEPTH == 64)) begin // RV64 cache tag
|
||||
// 64 x 44-bit SRAM
|
||||
ram1p1rwbe_64x44 sram1B (.CLK(clk), .CEB(~ce), .WEB(~we),
|
||||
.A(addr), .D(din),
|
||||
.BWEB('0), .Q(dout));
|
||||
|
||||
end else if ((P.USE_SRAM == 1) & (WIDTH == 22) & (DEPTH == 64)) begin // RV32 cache tag
|
||||
end else if ((USE_SRAM == 1) & (WIDTH == 22) & (DEPTH == 64)) begin // RV32 cache tag
|
||||
// 64 x 22-bit SRAM
|
||||
ram1p1rwbe_64x22 sram1 (.CLK(clk), .CEB(~ce), .WEB(~we),
|
||||
.A(addr), .D(din),
|
||||
|
@ -31,8 +31,7 @@
|
||||
|
||||
// WIDTH is number of bits in one "word" of the memory, DEPTH is number of such words
|
||||
|
||||
module ram2p1r1wbe import cvw::*; #(parameter cvw_t P,
|
||||
parameter DEPTH=1024, WIDTH=68) (
|
||||
module ram2p1r1wbe import cvw::*; #(parameter USE_SRAM=0, DEPTH=1024, WIDTH=68) (
|
||||
input logic clk,
|
||||
input logic ce1, ce2,
|
||||
input logic [$clog2(DEPTH)-1:0] ra1,
|
||||
@ -51,7 +50,7 @@ module ram2p1r1wbe import cvw::*; #(parameter cvw_t P,
|
||||
// TRUE Smem macro
|
||||
// ***************************************************************************
|
||||
|
||||
if ((P.USE_SRAM == 1) & (WIDTH == 68) & (DEPTH == 1024)) begin
|
||||
if ((USE_SRAM == 1) & (WIDTH == 68) & (DEPTH == 1024)) begin
|
||||
|
||||
ram2p1r1wbe_1024x68 memory1(.CLKA(clk), .CLKB(clk),
|
||||
.CEBA(~ce1), .CEBB(~ce2),
|
||||
@ -63,7 +62,7 @@ module ram2p1r1wbe import cvw::*; #(parameter cvw_t P,
|
||||
.QA(rd1),
|
||||
.QB());
|
||||
|
||||
end else if ((P.USE_SRAM == 1) & (WIDTH == 36) & (DEPTH == 1024)) begin
|
||||
end else if ((USE_SRAM == 1) & (WIDTH == 36) & (DEPTH == 1024)) begin
|
||||
|
||||
ram2p1r1wbe_1024x36 memory1(.CLKA(clk), .CLKB(clk),
|
||||
.CEBA(~ce1), .CEBB(~ce2),
|
||||
@ -75,7 +74,7 @@ module ram2p1r1wbe import cvw::*; #(parameter cvw_t P,
|
||||
.QA(rd1),
|
||||
.QB());
|
||||
|
||||
end else if ((P.USE_SRAM == 1) & (WIDTH == 2) & (DEPTH == 1024)) begin
|
||||
end else if ((USE_SRAM == 1) & (WIDTH == 2) & (DEPTH == 1024)) begin
|
||||
|
||||
logic [SRAMWIDTH-1:0] SRAMReadData;
|
||||
logic [SRAMWIDTH-1:0] SRAMWriteData;
|
||||
|
@ -25,9 +25,7 @@
|
||||
|
||||
// This model actually works correctly with vivado.
|
||||
|
||||
module rom1p1r #(parameter ADDR_WIDTH = 8,
|
||||
parameter DATA_WIDTH = 32,
|
||||
parameter PRELOAD_ENABLED = 0)
|
||||
module rom1p1r #(parameter ADDR_WIDTH = 8, DATA_WIDTH = 32, PRELOAD_ENABLED = 0)
|
||||
(input logic clk,
|
||||
input logic ce,
|
||||
input logic [ADDR_WIDTH-1:0] addr,
|
||||
|
@ -92,7 +92,7 @@ module btb import cvw::*; #(parameter cvw_t P,
|
||||
|
||||
|
||||
// An optimization may be using a PC relative address.
|
||||
ram2p1r1wbe #(P, 2**Depth, P.XLEN+4) memory(
|
||||
ram2p1r1wbe #(.USE_SRAM(P.USE_SRAM), .DEPTH(2**Depth), .WIDTH(P.XLEN+4)) memory(
|
||||
.clk, .ce1(~StallF | reset), .ra1(PCNextFIndex), .rd1(TableBTBPredF),
|
||||
.ce2(~StallW & ~FlushW), .wa2(PCMIndex), .wd2({InstrClassM, IEUAdrM}), .we2(BTBWrongM), .bwe2('1));
|
||||
|
||||
|
@ -84,7 +84,7 @@ module gshare import cvw::*; #(parameter cvw_t P,
|
||||
|
||||
assign BPDirPredF = MatchX ? FwdNewDirPredF : TableBPDirPredF;
|
||||
|
||||
ram2p1r1wbe #(P, 2**k, 2) PHT(.clk(clk),
|
||||
ram2p1r1wbe #(.USE_SRAM(P.USE_SRAM), .DEPTH(2**k), .WIDTH(2)) PHT(.clk(clk),
|
||||
.ce1(~StallF), .ce2(~StallW & ~FlushW),
|
||||
.ra1(IndexNextF),
|
||||
.rd1(TableBPDirPredF),
|
||||
|
@ -58,7 +58,7 @@ module gsharebasic import cvw::*; #(parameter cvw_t P,
|
||||
assign IndexM = GHRM;
|
||||
end
|
||||
|
||||
ram2p1r1wbe #(P, 2**k, 2) PHT(.clk(clk),
|
||||
ram2p1r1wbe #(.USE_SRAM(P.USE_SRAM), .DEPTH(2**k), .WIDTH(2)) PHT(.clk(clk),
|
||||
.ce1(~StallF), .ce2(~StallW & ~FlushW),
|
||||
.ra1(IndexNextF),
|
||||
.rd1(BPDirPredF),
|
||||
|
@ -59,7 +59,7 @@ module localaheadbp import cvw::*; #(parameter cvw_t P,
|
||||
//assign IndexNextF = LHR;
|
||||
assign IndexM = LHRW;
|
||||
|
||||
ram2p1r1wbe #(P, 2**k, 2) PHT(.clk(clk),
|
||||
ram2p1r1wbe #(.USE_SRAM(P.USE_SRAM), .DEPTH(2**k), .WIDTH(2)) PHT(.clk(clk),
|
||||
.ce1(~StallD), .ce2(~StallW & ~FlushW),
|
||||
.ra1(LHRF),
|
||||
.rd1(BPDirPredD),
|
||||
@ -92,7 +92,7 @@ module localaheadbp import cvw::*; #(parameter cvw_t P,
|
||||
assign IndexLHRM = {PCW[m+1] ^ PCW[1], PCW[m:2]};
|
||||
assign IndexLHRNextF = {PCNextF[m+1] ^ PCNextF[1], PCNextF[m:2]};
|
||||
|
||||
ram2p1r1wbe #(P, 2**m, k) BHT(.clk(clk),
|
||||
ram2p1r1wbe #(.USE_SRAM(P.USE_SRAM), .DEPTH(2**m), .WIDTH(k)) BHT(.clk(clk),
|
||||
.ce1(~StallF), .ce2(~StallW & ~FlushW),
|
||||
.ra1(IndexLHRNextF),
|
||||
.rd1(LHRF),
|
||||
|
@ -56,7 +56,7 @@ module localbpbasic import cvw::*; #(parameter cvw_t P,
|
||||
assign IndexNextF = LHR;
|
||||
assign IndexM = LHRM;
|
||||
|
||||
ram2p1r1wbe #(P, 2**k, 2) PHT(.clk(clk),
|
||||
ram2p1r1wbe #(.USE_SRAM(P.USE_SRAM), .DEPTH(2**k), .WIDTH(2)) PHT(.clk(clk),
|
||||
.ce1(~StallF), .ce2(~StallW & ~FlushW),
|
||||
.ra1(IndexNextF),
|
||||
.rd1(BPDirPredF),
|
||||
|
@ -58,7 +58,7 @@ module localrepairbp import cvw::*; #(parameter cvw_t P,
|
||||
logic SpeculativeFlushedF;
|
||||
|
||||
|
||||
ram2p1r1wbe #(P, 2**k, 2) PHT(.clk(clk),
|
||||
ram2p1r1wbe #(.USE_SRAM(P.USE_SRAM), .DEPTH(2**k), .WIDTH(2)) PHT(.clk(clk),
|
||||
.ce1(~StallD), .ce2(~StallW & ~FlushW),
|
||||
.ra1(LHRF),
|
||||
.rd1(BPDirPredD),
|
||||
@ -89,7 +89,7 @@ module localrepairbp import cvw::*; #(parameter cvw_t P,
|
||||
assign IndexLHRM = {PCW[m+1] ^ PCW[1], PCW[m:2]};
|
||||
assign IndexLHRNextF = {PCNextF[m+1] ^ PCNextF[1], PCNextF[m:2]};
|
||||
|
||||
ram2p1r1wbe #(P, 2**m, k) BHT(.clk(clk),
|
||||
ram2p1r1wbe #(.USE_SRAM(P.USE_SRAM), .DEPTH(2**m), .WIDTH(k)) BHT(.clk(clk),
|
||||
.ce1(~StallF), .ce2(~StallW & ~FlushW),
|
||||
.ra1(IndexLHRNextF),
|
||||
.rd1(LHRCommittedF),
|
||||
@ -101,7 +101,7 @@ module localrepairbp import cvw::*; #(parameter cvw_t P,
|
||||
assign IndexLHRD = {PCE[m+1] ^ PCE[1], PCE[m:2]};
|
||||
assign LHRNextE = BranchD ? {BPDirPredD[1], LHRE[k-1:1]} : LHRE;
|
||||
// *** replace with a small CAM
|
||||
ram2p1r1wbe #(P, 2**m, k) SHB(.clk(clk),
|
||||
ram2p1r1wbe #(.USE_SRAM(P.USE_SRAM), .DEPTH(2**m), .WIDTH(k)) SHB(.clk(clk),
|
||||
.ce1(~StallF), .ce2(~StallE & ~FlushE),
|
||||
.ra1(IndexLHRNextF),
|
||||
.rd1(LHRSpeculativeF),
|
||||
|
@ -53,7 +53,7 @@ module twoBitPredictor import cvw::*; #(parameter cvw_t P, parameter XLEN,
|
||||
assign IndexM = {PCM[k+1] ^ PCM[1], PCM[k:2]};
|
||||
|
||||
|
||||
ram2p1r1wbe #(P, 2**k, 2) PHT(.clk(clk),
|
||||
ram2p1r1wbe #(.USE_SRAM(P.USE_SRAM), .DEPTH(2**k), .WIDTH(2)) PHT(.clk(clk),
|
||||
.ce1(~StallF), .ce2(~StallW & ~FlushW),
|
||||
.ra1(IndexNextF),
|
||||
.rd1(BPDirPredF),
|
||||
|
@ -114,10 +114,7 @@ module ifu import cvw::*; #(parameter cvw_t P) (
|
||||
logic [31:0] IROMInstrF; // Instruction from the IROM
|
||||
logic [31:0] ICacheInstrF; // Instruction from the I$
|
||||
logic [31:0] InstrRawF; // Instruction from the IROM, I$, or bus
|
||||
logic CompressedF; // The fetched instruction is compressed
|
||||
logic CompressedD; // The decoded instruction is compressed
|
||||
logic CompressedE; // The execution instruction is compressed
|
||||
logic CompressedM; // The execution instruction is compressed
|
||||
logic CompressedF, CompressedE; // The fetched instruction is compressed
|
||||
logic [31:0] PostSpillInstrRawF; // Fetch instruction after merge two halves of spill
|
||||
logic [31:0] InstrRawD; // Non-decompressed instruction in the Decode stage
|
||||
logic IllegalIEUInstrD; // IEU Instruction (regular or compressed) is not good
|
||||
@ -389,31 +386,40 @@ module ifu import cvw::*; #(parameter cvw_t P) (
|
||||
assign BranchMisalignedFaultE = (IEUAdrE[1] & ~P.COMPRESSED_SUPPORTED) & PCSrcE;
|
||||
flopenr #(1) InstrMisalignedReg(clk, reset, ~StallM, BranchMisalignedFaultE, InstrMisalignedFaultM);
|
||||
|
||||
// Instruction and PC pipeline registers
|
||||
// Cannot use flopenrc for Instr(E/M) as it resets to NOP not 0.
|
||||
// Instruction and PC pipeline registers flush to NOP, not zero
|
||||
mux2 #(32) FlushInstrEMux(InstrD, nop, FlushE, NextInstrD);
|
||||
mux2 #(32) FlushInstrMMux(InstrE, nop, FlushM, NextInstrE);
|
||||
flopenr #(32) InstrEReg(clk, reset, ~StallE, NextInstrD, InstrE);
|
||||
flopenr #(P.XLEN) PCEReg(clk, reset, ~StallE, PCD, PCE);
|
||||
|
||||
// InstrM is only needed with CSRs or atomic operations
|
||||
if (P.ZICSR_SUPPORTED | P.A_SUPPORTED)
|
||||
if (P.ZICSR_SUPPORTED | P.A_SUPPORTED) begin
|
||||
mux2 #(32) FlushInstrMMux(InstrE, nop, FlushM, NextInstrE);
|
||||
flopenr #(32) InstrMReg(clk, reset, ~StallM, NextInstrE, InstrM);
|
||||
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;
|
||||
|
||||
flopenrc #(1) CompressedDReg(clk, reset, FlushD, ~StallD, CompressedF, CompressedD);
|
||||
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
|
||||
|
||||
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
|
||||
logic CompressedD; // instruction is compressed
|
||||
flopenrc #(1) CompressedDReg(clk, reset, FlushD, ~StallD, CompressedF, CompressedD);
|
||||
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 PCLinkE = PCE + 'd4;
|
||||
end
|
||||
|
||||
// pipeline original compressed instruction in case it is needed for MTVAL on an illegal instruction exception
|
||||
if (P.ZICSR_SUPPORTED) begin
|
||||
if (P.ZICSR_SUPPORTED & P.COMPRESSED_SUPPORTED | 1) begin
|
||||
logic CompressedM; // instruction is compressed
|
||||
flopenrc #(16) InstrRawEReg(clk, reset, FlushE, ~StallE, InstrRawD[15:0], InstrRawE);
|
||||
flopenrc #(16) InstrRawMReg(clk, reset, FlushM, ~StallM, InstrRawE, InstrRawM);
|
||||
flopenrc #(1) CompressedMReg(clk, reset, FlushM, ~StallM, CompressedE, CompressedM);
|
||||
mux2 #(32) InstrOrigMux(InstrM, {16'b0, InstrRawM}, CompressedM, InstrOrigM);
|
||||
end else assign InstrOrigM = 0;
|
||||
end else
|
||||
assign InstrOrigM = InstrM;
|
||||
|
||||
endmodule
|
||||
|
@ -49,6 +49,6 @@ module dtim import cvw::*; #(parameter cvw_t P) (
|
||||
|
||||
assign we = MemRWM[0] & ~FlushW; // have to ignore write if Trap.
|
||||
|
||||
ram1p1rwbe #(.P(P), .DEPTH(DEPTH), .WIDTH(P.LLEN))
|
||||
ram1p1rwbe #(.USE_SRAM(P.USE_SRAM), .DEPTH(DEPTH), .WIDTH(P.LLEN))
|
||||
ram(.clk, .ce, .we, .bwe(ByteMaskM), .addr(DTIMAdr[ADDR_WDITH+OFFSET-1:OFFSET]), .dout(ReadDataWordM), .din(WriteDataM));
|
||||
endmodule
|
||||
|
@ -71,7 +71,7 @@ module ram_ahb import cvw::*; #(parameter cvw_t P,
|
||||
mux2 #(P.PA_BITS) adrmux(HADDR, HADDRD, memwriteD | ~HREADY, RamAddr);
|
||||
|
||||
// single-ported RAM
|
||||
ram1p1rwbe #(.P(P), .DEPTH(RANGE/8), .WIDTH(P.XLEN), .PRELOAD_ENABLED(P.FPGA)) memory(.clk(HCLK), .ce(1'b1),
|
||||
ram1p1rwbe #(.USE_SRAM(P.USE_SRAM), .DEPTH(RANGE/8), .WIDTH(P.XLEN), .PRELOAD_ENABLED(P.FPGA)) memory(.clk(HCLK), .ce(1'b1),
|
||||
.addr(RamAddr[ADDR_WIDTH+OFFSET-1:OFFSET]), .we(memwriteD), .din(HWDATA), .bwe(HWSTRB), .dout(HREADRam));
|
||||
|
||||
// use this to add arbitrary latency to ram. Helps test AHB controller correctness
|
||||
|
@ -32,17 +32,15 @@ eval file copy -force [glob ${hdl_src}/cvw.sv] {$outputDir/hdl/}
|
||||
eval file copy -force [glob ${hdl_src}/*/*.sv] {$outputDir/hdl/}
|
||||
eval file copy -force [glob ${hdl_src}/*/*/*.sv] {$outputDir/hdl/}
|
||||
|
||||
# Check if a wrapper is needed (when cvw_t parameters are used)
|
||||
# Check if a wrapper is needed and create it (to pass parameters when cvw_t parameters are used)
|
||||
set wrapper 0
|
||||
if {[eval exec grep "cvw_t" {$outputDir/hdl/$::env(DESIGN).sv}] ne ""} {
|
||||
if {[catch {eval exec grep "cvw_t" $outputDir/hdl/$::env(DESIGN).sv}] == 0} {
|
||||
echo "Creating wrapper"
|
||||
set wrapper 1
|
||||
# make the wrapper
|
||||
exec python3 $::env(WALLY)/synthDC/scripts/wrapperGen.py $::env(DESIGN) $outputDir/hdl
|
||||
}
|
||||
|
||||
# Only for FMA class project; comment out when done
|
||||
# eval file copy -force [glob ${hdl_src}/fma/fma16.v] {hdl/}
|
||||
|
||||
# Enables name mapping
|
||||
if { $saifpower == 1 } {
|
||||
saif_map -start
|
||||
|
@ -1,5 +1,5 @@
|
||||
///////////////////////////////////////////
|
||||
// shadowmem.sv
|
||||
// DCacheFlushFSM.sv
|
||||
//
|
||||
// Written: David Harris David_Harris@hmc.edu and Ross Thompson ross1728@gmail.com
|
||||
// Modified: 14 June 2023
|
@ -217,7 +217,7 @@ module loggers import cvw::*; #(parameter cvw_t P,
|
||||
logic PCSrcM;
|
||||
string LogFile;
|
||||
logic resetD, resetEdge;
|
||||
flopenrc #(1) PCSrcMReg(clk, reset, dut.core.FlushM, ~dut.core.StallM, dut.core.ifu.bpred.bpred.Predictor.DirPredictor.PCSrcE, PCSrcM);
|
||||
flopenrc #(1) PCSrcMReg(clk, reset, dut.core.FlushM, ~dut.core.StallM, dut.core.ifu.PCSrcE, PCSrcM);
|
||||
flop #(1) ResetDReg(clk, reset, resetD);
|
||||
assign resetEdge = ~reset & resetD;
|
||||
initial begin
|
||||
|
@ -30,11 +30,13 @@ module watchdog #(parameter XLEN, WatchDogTimerThreshold)
|
||||
);
|
||||
|
||||
// check for hang up.
|
||||
logic [XLEN-1:0] PCW;
|
||||
flopenr #(XLEN) PCWReg(clk, reset, ~dut.core.ieu.dp.StallW, dut.core.ifu.PCM, PCW);
|
||||
logic [XLEN-1:0] OldPCW;
|
||||
logic [XLEN-1:0] PCM, PCW, OldPCW;
|
||||
integer WatchDogTimerCount;
|
||||
logic WatchDogTimeOut;
|
||||
|
||||
flopenr #(XLEN) PCMReg(clk, reset, ~dut.core.ifu.StallM, dut.core.ifu.PCE, PCM); // duplicate PCM register because it is not in ifu for all configurations
|
||||
flopenr #(XLEN) PCWReg(clk, reset, ~dut.core.ieu.dp.StallW, PCM, PCW);
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
OldPCW <= PCW;
|
||||
if(OldPCW == PCW) WatchDogTimerCount = WatchDogTimerCount + 1'b1;
|
||||
|
@ -644,11 +644,11 @@ module testbenchfp;
|
||||
// Read the first test
|
||||
initial begin
|
||||
//string testname = {`PATH, Tests[TestNum]};
|
||||
string p = `PATH;
|
||||
static string pp = `PATH;
|
||||
string testname;
|
||||
string tt0;
|
||||
tt0 = $psprintf("%s", Tests[TestNum]);
|
||||
testname = {p, tt0};
|
||||
testname = {pp, tt0};
|
||||
$display("Here you are %s", testname);
|
||||
$display("\n\nRunning %s vectors ", Tests[TestNum]);
|
||||
$readmemh(testname, TestVectors);
|
||||
|
@ -72,6 +72,7 @@ module testbench;
|
||||
logic HMASTLOCK;
|
||||
logic HCLK, HRESETn;
|
||||
logic [P.XLEN-1:0] PCW;
|
||||
logic [31:0] NextInstrE, InstrM;
|
||||
|
||||
string ProgramAddrMapFile, ProgramLabelMapFile;
|
||||
integer ProgramAddrLabelArray [string] = '{ "begin_signature" : 0, "tohost" : 0 };
|
||||
@ -81,7 +82,8 @@ module testbench;
|
||||
|
||||
logic [31:0] GPIOIN, GPIOOUT, GPIOEN;
|
||||
logic UARTSin, UARTSout;
|
||||
|
||||
logic SPIIn, SPIOut;
|
||||
logic [3:0] SPICS;
|
||||
logic SDCIntr;
|
||||
|
||||
logic HREADY;
|
||||
@ -214,7 +216,7 @@ module testbench;
|
||||
`endif
|
||||
|
||||
flopenr #(P.XLEN) PCWReg(clk, reset, ~dut.core.ieu.dp.StallW, dut.core.ifu.PCM, PCW);
|
||||
flopenr #(32) InstrWReg(clk, reset, ~dut.core.ieu.dp.StallW, dut.core.ifu.InstrM, InstrW);
|
||||
flopenr #(32) InstrWReg(clk, reset, ~dut.core.ieu.dp.StallW, InstrM, InstrW);
|
||||
|
||||
// check assertions for a legal configuration
|
||||
riscvassertions #(P) riscvassertions();
|
||||
@ -255,13 +257,13 @@ module testbench;
|
||||
wallypipelinedsoc #(P) dut(.clk, .reset_ext, .reset, .HRDATAEXT, .HREADYEXT, .HRESPEXT, .HSELEXT, .HSELEXTSDC,
|
||||
.HCLK, .HRESETn, .HADDR, .HWDATA, .HWSTRB, .HWRITE, .HSIZE, .HBURST, .HPROT,
|
||||
.HTRANS, .HMASTLOCK, .HREADY, .TIMECLK(1'b0), .GPIOIN, .GPIOOUT, .GPIOEN,
|
||||
.UARTSin, .UARTSout, .SDCIntr);
|
||||
.UARTSin, .UARTSout, .SDCIntr, .SPICS, .SPIOut, .SPIIn);
|
||||
|
||||
// Track names of instructions
|
||||
instrTrackerTB it(clk, reset, dut.core.ieu.dp.FlushE,
|
||||
dut.core.ifu.InstrRawF[31:0],
|
||||
dut.core.ifu.InstrD, dut.core.ifu.InstrE,
|
||||
dut.core.ifu.InstrM, InstrW,
|
||||
InstrM, InstrW,
|
||||
InstrFName, InstrDName, InstrEName, InstrMName, InstrWName);
|
||||
|
||||
// initialize tests
|
||||
@ -298,6 +300,10 @@ module testbench;
|
||||
.ProgramLabelMapFile(ProgramLabelMapFile));
|
||||
end
|
||||
|
||||
// Duplicate copy of pipeline registers that are optimized out of some configurations
|
||||
mux2 #(32) FlushInstrMMux(dut.core.ifu.InstrE, dut.core.ifu.nop, dut.core.ifu.FlushM, NextInstrE);
|
||||
flopenr #(32) InstrMReg(clk, reset, ~dut.core.ifu.StallM, NextInstrE, InstrM);
|
||||
|
||||
// Termination condition
|
||||
// terminate on a specific ECALL after li x3,1 for old Imperas tests, *** remove this when old imperas tests are removed
|
||||
// or sw gp,-56(t0) for new Imperas tests
|
||||
@ -311,7 +317,7 @@ module testbench;
|
||||
(dut.core.ieu.dp.regf.we3 &
|
||||
dut.core.ieu.dp.regf.a3 == 3 &
|
||||
dut.core.ieu.dp.regf.wd3 == 1)) |
|
||||
((dut.core.ifu.InstrM == 32'h6f | dut.core.ifu.InstrM == 32'hfc32a423 | dut.core.ifu.InstrM == 32'hfc32a823) & dut.core.ieu.c.InstrValidM ) |
|
||||
((InstrM == 32'h6f | InstrM == 32'hfc32a423 | InstrM == 32'hfc32a823) & dut.core.ieu.c.InstrValidM ) |
|
||||
((dut.core.lsu.IEUAdrM == ProgramAddrLabelArray["tohost"]) & InstrMName == "SW" );
|
||||
|
||||
DCacheFlushFSM #(P) DCacheFlushFSM(.clk(clk),
|
||||
|
@ -229,10 +229,16 @@ module testbench;
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////// Cache Issue ///////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Duplicate copy of pipeline registers that are optimized out of some configurations
|
||||
logic [31:0] NextInstrE, InstrM;
|
||||
mux2 #(32) FlushInstrMMux(dut.core.ifu.InstrE, dut.core.ifu.nop, dut.core.ifu.FlushM, NextInstrE);
|
||||
flopenr #(32) InstrMReg(clk, reset, ~dut.core.ifu.StallM, NextInstrE, InstrM);
|
||||
|
||||
logic probe;
|
||||
if (NO_SPOOFING)
|
||||
assign probe = testbench.dut.core.PCM == 64'hffffffff80200c8c
|
||||
& testbench.dut.core.InstrM != 32'h14021273
|
||||
& InstrM != 32'h14021273
|
||||
& testbench.dut.core.InstrValidM;
|
||||
|
||||
|
||||
@ -276,7 +282,9 @@ module testbench;
|
||||
logic SDCCmdOE;
|
||||
logic [3:0] SDCDatIn;
|
||||
logic SDCIntr;
|
||||
|
||||
logic SPIIn, SPIOut;
|
||||
logic [3:0] SPICS;
|
||||
|
||||
|
||||
// Hardwire UART, GPIO pins
|
||||
assign GPIOIN = 0;
|
||||
@ -434,13 +442,10 @@ module testbench;
|
||||
|
||||
|
||||
// Wally
|
||||
wallypipelinedsoc #(P) dut(.clk, .reset, .reset_ext,
|
||||
.HRDATAEXT, .HREADYEXT, .HREADY, .HSELEXT, .HRESPEXT, .HCLK,
|
||||
.HRESETn, .HADDR, .HWDATA, .HWRITE, .HWSTRB, .HSIZE, .HBURST, .HPROT,
|
||||
.HTRANS, .HMASTLOCK,
|
||||
.TIMECLK('0), .GPIOIN, .GPIOOUT, .GPIOEN,
|
||||
.UARTSin, .UARTSout,
|
||||
.SDCIntr);
|
||||
wallypipelinedsoc #(P) dut(.clk, .reset_ext, .reset, .HRDATAEXT, .HREADYEXT, .HRESPEXT, .HSELEXT, .HSELEXTSDC,
|
||||
.HCLK, .HRESETn, .HADDR, .HWDATA, .HWSTRB, .HWRITE, .HSIZE, .HBURST, .HPROT,
|
||||
.HTRANS, .HMASTLOCK, .HREADY, .TIMECLK(1'b0), .GPIOIN, .GPIOOUT, .GPIOEN,
|
||||
.UARTSin, .UARTSout, .SDCIntr, .SPICS, .SPIOut, .SPIIn);
|
||||
|
||||
// W-stage hardware not needed by Wally itself
|
||||
parameter nop = 'h13;
|
||||
@ -452,7 +457,7 @@ module testbench;
|
||||
`define FLUSHW dut.core.FlushW
|
||||
`define STALLW dut.core.StallW
|
||||
flopenrc #(P.XLEN) PCWReg(clk, reset, `FLUSHW, ~`STALLW, `PCM, PCW);
|
||||
flopenr #(32) InstrWReg(clk, reset, ~`STALLW, `FLUSHW ? nop : dut.core.ifu.InstrM, InstrW);
|
||||
flopenr #(32) InstrWReg(clk, reset, ~`STALLW, `FLUSHW ? nop : InstrM, InstrW);
|
||||
flopenrc #(1) controlregW(clk, reset, `FLUSHW, ~`STALLW, dut.core.ieu.c.InstrValidM, InstrValidW);
|
||||
flopenrc #(P.XLEN) IEUAdrWReg(clk, reset, `FLUSHW, ~`STALLW, dut.core.IEUAdrM, IEUAdrW);
|
||||
flopenrc #(P.XLEN) WriteDataWReg(clk, reset, `FLUSHW, ~`STALLW, dut.core.lsu.WriteDataM, WriteDataW);
|
||||
@ -969,7 +974,7 @@ module testbench;
|
||||
instrTrackerTB it(clk, reset, dut.core.ieu.dp.FlushE,
|
||||
dut.core.ifu.InstrRawF[31:0],
|
||||
dut.core.ifu.InstrD, dut.core.ifu.InstrE,
|
||||
dut.core.ifu.InstrM, InstrW,
|
||||
InstrM, InstrW,
|
||||
InstrFName, InstrDName, InstrEName, InstrMName, InstrWName);
|
||||
|
||||
// ------------------
|
||||
|
@ -212,10 +212,16 @@ module testbench;
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////// Cache Issue ///////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Duplicate copy of pipeline registers that are optimized out of some configurations
|
||||
logic [31:0] NextInstrE, InstrM;
|
||||
mux2 #(32) FlushInstrMMux(dut.core.ifu.InstrE, dut.core.ifu.nop, dut.core.ifu.FlushM, NextInstrE);
|
||||
flopenr #(32) InstrMReg(dut.core.clk, dut.core.reset, ~dut.core.ifu.StallM, NextInstrE, InstrM);
|
||||
|
||||
logic probe;
|
||||
if (NO_SPOOFING)
|
||||
assign probe = testbench.dut.core.PCM == 64'hffffffff80200c8c
|
||||
& testbench.dut.core.InstrM != 32'h14021273
|
||||
& InstrM != 32'h14021273
|
||||
& testbench.dut.core.InstrValidM;
|
||||
|
||||
|
||||
@ -252,6 +258,8 @@ module testbench;
|
||||
logic [31:0] GPIOIN;
|
||||
logic [31:0] GPIOOUT, GPIOEN;
|
||||
logic UARTSin, UARTSout;
|
||||
logic SPIIn, SPIOut;
|
||||
logic [3:0] SPICS;
|
||||
|
||||
// FPGA-specific Stuff
|
||||
logic SDCIntr;
|
||||
@ -262,13 +270,10 @@ module testbench;
|
||||
assign SDCIntr = 0;
|
||||
|
||||
// Wally
|
||||
wallypipelinedsoc #(P) dut(.clk, .reset, .reset_ext,
|
||||
.HRDATAEXT, .HREADYEXT, .HREADY, .HSELEXT, .HSELEXTSDC, .HRESPEXT, .HCLK,
|
||||
.HRESETn, .HADDR, .HWDATA, .HWRITE, .HWSTRB, .HSIZE, .HBURST, .HPROT,
|
||||
.HTRANS, .HMASTLOCK,
|
||||
.TIMECLK('0), .GPIOIN, .GPIOOUT, .GPIOEN,
|
||||
.UARTSin, .UARTSout,
|
||||
.SDCIntr);
|
||||
wallypipelinedsoc #(P) dut(.clk, .reset_ext, .reset, .HRDATAEXT, .HREADYEXT, .HRESPEXT, .HSELEXT, .HSELEXTSDC,
|
||||
.HCLK, .HRESETn, .HADDR, .HWDATA, .HWSTRB, .HWRITE, .HSIZE, .HBURST, .HPROT,
|
||||
.HTRANS, .HMASTLOCK, .HREADY, .TIMECLK(1'b0), .GPIOIN, .GPIOOUT, .GPIOEN,
|
||||
.UARTSin, .UARTSout, .SDCIntr, .SPICS, .SPIOut, .SPIIn);
|
||||
|
||||
// W-stage hardware not needed by Wally itself
|
||||
parameter nop = 'h13;
|
||||
@ -280,7 +285,7 @@ module testbench;
|
||||
`define FLUSHW dut.core.FlushW
|
||||
`define STALLW dut.core.StallW
|
||||
flopenrc #(P.XLEN) PCWReg(clk, reset, `FLUSHW, ~`STALLW, `PCM, PCW);
|
||||
flopenr #(32) InstrWReg(clk, reset, ~`STALLW, `FLUSHW ? nop : dut.core.ifu.InstrM, InstrW);
|
||||
flopenr #(32) InstrWReg(clk, reset, ~`STALLW, `FLUSHW ? nop : InstrM, InstrW);
|
||||
flopenrc #(1) controlregW(clk, reset, `FLUSHW, ~`STALLW, dut.core.ieu.c.InstrValidM, InstrValidW);
|
||||
flopenrc #(P.XLEN) IEUAdrWReg(clk, reset, `FLUSHW, ~`STALLW, dut.core.IEUAdrM, IEUAdrW);
|
||||
flopenrc #(P.XLEN) WriteDataWReg(clk, reset, `FLUSHW, ~`STALLW, dut.core.lsu.WriteDataM, WriteDataW);
|
||||
@ -794,7 +799,7 @@ module testbench;
|
||||
instrTrackerTB it(clk, reset, dut.core.ieu.dp.FlushE,
|
||||
dut.core.ifu.InstrRawF[31:0],
|
||||
dut.core.ifu.InstrD, dut.core.ifu.InstrE,
|
||||
dut.core.ifu.InstrM, InstrW,
|
||||
InstrM, InstrW,
|
||||
InstrFName, InstrDName, InstrEName, InstrMName, InstrWName);
|
||||
|
||||
// ------------------
|
||||
|
@ -70,6 +70,8 @@ module testbench;
|
||||
logic [3:0] SDCDatIn;
|
||||
tri1 [3:0] SDCDat;
|
||||
tri1 SDCCmd;
|
||||
logic SPIIn, SPIOut;
|
||||
logic [3:0] SPICS;
|
||||
|
||||
logic HREADY;
|
||||
logic HSELEXT;
|
||||
@ -426,10 +428,10 @@ module testbench;
|
||||
assign SDCDat = '0;
|
||||
end
|
||||
|
||||
wallypipelinedsoc #(P) dut(.clk, .reset_ext, .reset, .HRDATAEXT,.HREADYEXT, .HRESPEXT,.HSELEXT,
|
||||
.HCLK, .HRESETn, .HADDR, .HWDATA, .HWSTRB, .HWRITE, .HSIZE, .HBURST, .HPROT,
|
||||
.HTRANS, .HMASTLOCK, .HREADY, .TIMECLK(1'b0), .GPIOIN, .GPIOOUT, .GPIOEN,
|
||||
.UARTSin, .UARTSout, .SDCCmdIn, .SDCCmdOut, .SDCCmdOE, .SDCDatIn, .SDCCLK);
|
||||
wallypipelinedsoc #(P) dut(.clk, .reset_ext, .reset, .HRDATAEXT, .HREADYEXT, .HRESPEXT, .HSELEXT, .HSELEXTSDC,
|
||||
.HCLK, .HRESETn, .HADDR, .HWDATA, .HWSTRB, .HWRITE, .HSIZE, .HBURST, .HPROT,
|
||||
.HTRANS, .HMASTLOCK, .HREADY, .TIMECLK(1'b0), .GPIOIN, .GPIOOUT, .GPIOEN,
|
||||
.UARTSin, .UARTSout, .SDCIntr, .SPICS, .SPIOut, .SPIIn);
|
||||
|
||||
// generate clock to sequence tests
|
||||
always begin
|
||||
@ -440,20 +442,25 @@ module testbench;
|
||||
// Support logic
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Duplicate copy of pipeline registers that are optimized out of some configurations
|
||||
logic [31:0] NextInstrE, InstrM;
|
||||
mux2 #(32) FlushInstrMMux(dut.core.ifu.InstrE, dut.core.ifu.nop, dut.core.ifu.FlushM, NextInstrE);
|
||||
flopenr #(32) InstrMReg(clk, reset, ~dut.core.ifu.StallM, NextInstrE, InstrM);
|
||||
|
||||
// Track names of instructions
|
||||
string InstrFName, InstrDName, InstrEName, InstrMName, InstrWName;
|
||||
logic [31:0] InstrW;
|
||||
flopenr #(32) InstrWReg(clk, reset, ~dut.core.ieu.dp.StallW, dut.core.ifu.InstrM, InstrW);
|
||||
flopenr #(32) InstrWReg(clk, reset, ~dut.core.ieu.dp.StallW, InstrM, InstrW);
|
||||
instrTrackerTB it(clk, reset, dut.core.ieu.dp.FlushE,
|
||||
dut.core.ifu.InstrRawF[31:0],
|
||||
dut.core.ifu.InstrD, dut.core.ifu.InstrE,
|
||||
dut.core.ifu.InstrM, InstrW,
|
||||
InstrM, InstrW,
|
||||
InstrFName, InstrDName, InstrEName, InstrMName, InstrWName);
|
||||
|
||||
// watch for problems such as lockup, reading unitialized memory, bad configs
|
||||
watchdog #(P.XLEN, 1000000) watchdog(.clk, .reset); // check if PCW is stuck
|
||||
ramxdetector #(P.XLEN, P.LLEN) ramxdetector(clk, dut.core.lsu.MemRWM[1], dut.core.lsu.LSULoadAccessFaultM, dut.core.lsu.ReadDataM,
|
||||
dut.core.ifu.PCM, dut.core.ifu.InstrM, dut.core.lsu.IEUAdrM, InstrMName);
|
||||
dut.core.ifu.PCM, InstrM, dut.core.lsu.IEUAdrM, InstrMName);
|
||||
riscvassertions #(P) riscvassertions(); // check assertions for a legal configuration
|
||||
loggers #(P, TEST, PrintHPMCounters, I_CACHE_ADDR_LOGGER, D_CACHE_ADDR_LOGGER, BPRED_LOGGER)
|
||||
loggers (clk, reset, DCacheFlushStart, DCacheFlushDone, memfilename);
|
||||
@ -478,7 +485,7 @@ module testbench;
|
||||
(dut.core.ieu.dp.regf.we3 &
|
||||
dut.core.ieu.dp.regf.a3 == 3 &
|
||||
dut.core.ieu.dp.regf.wd3 == 1)) |
|
||||
((dut.core.ifu.InstrM == 32'h6f | dut.core.ifu.InstrM == 32'hfc32a423 | dut.core.ifu.InstrM == 32'hfc32a823) & dut.core.ieu.c.InstrValidM ) |
|
||||
((InstrM == 32'h6f | InstrM == 32'hfc32a423 | InstrM == 32'hfc32a823) & dut.core.ieu.c.InstrValidM ) |
|
||||
((dut.core.lsu.IEUAdrM == ProgramAddrLabelArray["tohost"]) & InstrMName == "SW" );
|
||||
|
||||
DCacheFlushFSM #(P) DCacheFlushFSM(.clk(clk), .reset(reset), .start(DCacheFlushStart), .done(DCacheFlushDone));
|
||||
|
@ -410,20 +410,25 @@ module testbench;
|
||||
// Support logic
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Duplicate copy of pipeline registers that are optimized out of some configurations
|
||||
logic [31:0] NextInstrE, InstrM;
|
||||
mux2 #(32) FlushInstrMMux(dut.core.ifu.InstrE, dut.core.ifu.nop, dut.core.ifu.FlushM, NextInstrE);
|
||||
flopenr #(32) InstrMReg(clk, reset, ~dut.core.ifu.StallM, NextInstrE, InstrM);
|
||||
|
||||
// Track names of instructions
|
||||
string InstrFName, InstrDName, InstrEName, InstrMName, InstrWName;
|
||||
logic [31:0] InstrW;
|
||||
flopenr #(32) InstrWReg(clk, reset, ~dut.core.ieu.dp.StallW, dut.core.ifu.InstrM, InstrW);
|
||||
flopenr #(32) InstrWReg(clk, reset, ~dut.core.ieu.dp.StallW, InstrM, InstrW);
|
||||
instrTrackerTB it(clk, reset, dut.core.ieu.dp.FlushE,
|
||||
dut.core.ifu.InstrRawF[31:0],
|
||||
dut.core.ifu.InstrD, dut.core.ifu.InstrE,
|
||||
dut.core.ifu.InstrM, InstrW,
|
||||
InstrM, InstrW,
|
||||
InstrFName, InstrDName, InstrEName, InstrMName, InstrWName);
|
||||
|
||||
// watch for problems such as lockup, reading unitialized memory, bad configs
|
||||
watchdog #(P.XLEN, 1000000) watchdog(.clk, .reset); // check if PCW is stuck
|
||||
ramxdetector #(P.XLEN, P.LLEN) ramxdetector(clk, dut.core.lsu.MemRWM[1], dut.core.lsu.LSULoadAccessFaultM, dut.core.lsu.ReadDataM,
|
||||
dut.core.ifu.PCM, dut.core.ifu.InstrM, dut.core.lsu.IEUAdrM, InstrMName);
|
||||
dut.core.ifu.PCM, InstrM, dut.core.lsu.IEUAdrM, InstrMName);
|
||||
riscvassertions #(P) riscvassertions(); // check assertions for a legal configuration
|
||||
loggers #(P, TEST, PrintHPMCounters, I_CACHE_ADDR_LOGGER, D_CACHE_ADDR_LOGGER, BPRED_LOGGER)
|
||||
loggers (clk, reset, DCacheFlushStart, DCacheFlushDone, memfilename);
|
||||
@ -448,7 +453,7 @@ module testbench;
|
||||
(dut.core.ieu.dp.regf.we3 &
|
||||
dut.core.ieu.dp.regf.a3 == 3 &
|
||||
dut.core.ieu.dp.regf.wd3 == 1)) |
|
||||
((dut.core.ifu.InstrM == 32'h6f | dut.core.ifu.InstrM == 32'hfc32a423 | dut.core.ifu.InstrM == 32'hfc32a823) & dut.core.ieu.c.InstrValidM ) |
|
||||
((InstrM == 32'h6f | InstrM == 32'hfc32a423 | InstrM == 32'hfc32a823) & dut.core.ieu.c.InstrValidM ) |
|
||||
((dut.core.lsu.IEUAdrM == ProgramAddrLabelArray["tohost"]) & InstrMName == "SW" );
|
||||
|
||||
DCacheFlushFSM #(P) DCacheFlushFSM(.clk(clk), .reset(reset), .start(DCacheFlushStart), .done(DCacheFlushDone));
|
||||
|
@ -1,11 +1,10 @@
|
||||
///////////////////////////////////////////
|
||||
// testbench.sv
|
||||
// wallywrapper.sv
|
||||
//
|
||||
// Written: David_Harris@hmc.edu 9 January 2021
|
||||
// Modified:
|
||||
//
|
||||
// Purpose: Wally Testbench and helper modules
|
||||
// Applies test programs from the riscv-arch-test and Imperas suites
|
||||
// Purpose: Wrapper module to define parameters for Wally Verilator linting
|
||||
//
|
||||
// A component of the Wally configurable RISC-V project.
|
||||
//
|
||||
|
Loading…
Reference in New Issue
Block a user