fix merge conflict

This commit is contained in:
bbracker 2021-11-05 23:42:15 -07:00
commit bc6332a780
18 changed files with 2511 additions and 198 deletions

View File

@ -8,15 +8,15 @@ To use Wally on Linux:
```
git clone https://github.com/davidharrishmc/riscv-wally
cd riscv-wally
cd imperas-riscv-tests
make
cd ../addins
cd addins
*** can these clones be replaced with git submodule commands?
git clone https://github.com/riscv-non-isa/riscv-arch-test
git clone https://github.com/riscv-software-src/riscv-isa-sim
cd riscv-isa-sim
*** replace these with a copy from ../install/F and ../install/D containing the Makefile.includes already updated
cp -r arch_test_target/spike/device/rv32i_m/I arch_test_target/spike/device/rv32i_m/F
<edit arch_test_target/spike/device/rv32i_m/F/Makefile.include line 35 and change --isa=rv32i to --isa=rv32if>
cp -r arch_test_target/spike/device/rv32i_m/I arch_test_target/spike/device/rv64i_m/D
cp -r arch_test_target/spike/device/rv64i_m/I arch_test_target/spike/device/rv64i_m/D
<edit arch_test_target/spike/device/rv64i_m/D/Makefile.include line 35 and change --isa=rv64i to --isa=rv64id>
mkdir build
cd build
@ -32,6 +32,15 @@ edit Makefile.include
make
make XLEN=32
exe2memfile.pl work/*/*/*.elf # converts ELF files to a format that can be read by Modelsim
cd ../../tests
cd imperas-riscv-tests
make
cd ../wally-riscv-arch-test
make
make XLEN=32
exe2memfile.pl work/*/*/*.elf # converts ELF files to a format that can be read by Modelsim
cd ../../wally-pipelined/linux-testgen/linux-testvectors
./tvLinker.sh
```
Notes:

View File

@ -1,6 +1,6 @@
#!/usr/bin/python3
##################################
# wally-I.py
# PIPELINE.py
#
# David_Harris@hmc.edu 27 October 2021
#
@ -88,10 +88,10 @@ def writeVector(a, b, storecmd, xlen):
##################################
# change these to suite your tests
instrs = ["ADD", "SUB", "SLT", "SLTU", "XOR", "OR", "AND"]
instrs = ["ADD"] # "SUB", "XOR", "OR", "AND", "SLT", "SLTU", ]
author = "David_Harris@hmc.edu"
xlens = [32, 64]
numrand = 100
numrand = 1000
# setup
seed(0) # make tests reproducible
@ -108,7 +108,7 @@ for xlen in xlens:
storecmd = "sd"
wordsize = 8
pathname = "../wally-riscv-arch-test/riscv-test-suite/rv" + str(xlen) + "i_m/I/"
fname = pathname + "src/WALLY-PIPELINE.S"
fname = pathname + "src/PIPELINE.S"
testnum = 0
# print custom header part
@ -126,6 +126,19 @@ for xlen in xlens:
for line in h:
f.write(line)
maxreg = 5
for i in range(numrand):
instr = instrs[randint(0,len(instrs)-1)]
reg1 = randint(0,maxreg)
reg2 = randint(1,maxreg)
reg3 = randint(1,maxreg)
line = instr + " x" +str(reg3) + ", x" + str(reg1) + ", x" + str(reg2) + "\n"
f.write(line)
for i in range(1,maxreg+1):
line = storecmd + " x" + str(i) + ", " + str(wordsize*(i-1)) + "(x8)\n"
f.write(line)
# print directed and random test vectors
# for a in corners:
# for b in corners:

View File

@ -16,7 +16,6 @@
#include "model_test.h"
#include "arch_test.h"
RVTEST_ISA("RV64I")
.section .text.init
.globl rvtest_entry_point
@ -24,8 +23,4 @@ rvtest_entry_point:
RVMODEL_BOOT
RVTEST_CODE_BEGIN
#ifdef TEST_CASE_1
RVTEST_CASE(0,"//check ISA:=regex(.*64.*);check ISA:=regex(.*I.*);def TEST_CASE_1=True;",add)
RVTEST_SIGBASE( x8,signature_x8_1)

View File

@ -87,7 +87,7 @@ simulate:
run -C $(SUITEDIR)
verify: simulate
riscv-test-env/verify.sh
# riscv-test-env/verify.sh # dmh 1 November 2021 removed because these tests don't have expected values
postverify:
ifeq ($(wildcard $(TARGETDIR)/$(RISCV_TARGET)/postverify.sh),)

View File

@ -28,7 +28,7 @@
# Description: Makefrag for RV32I architectural tests
rv32i_sc_tests = \
WALLY-PIPELINE \
PIPELINE \
rv32i_tests = $(addsuffix .elf, $(rv32i_sc_tests))

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,3 @@
include ../../Makefile.include
$(eval $(call compile_template,-march=rv64id -mabi=lp64 -DXLEN=$(XLEN)))

View File

@ -0,0 +1,35 @@
# RISC-V Architecture Test RV64IM Makefrag
#
# Copyright (c) 2018, Imperas Software Ltd.
# Copyright (c) 2020, InCore Semiconductors. Pvt. Ltd.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of the Imperas Software Ltd. nor the
# names of its contributors may be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Imperas Software Ltd. BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Description: Makefrag for RV64IM architectural tests
rv64im_sc_tests = \
rv64im_tests = $(addsuffix .elf, $(rv64im_sc_tests))
target_tests += $(rv64im_tests)

View File

@ -29,6 +29,7 @@
rv64i_sc_tests = \
add-01 \
PIPELINE \

File diff suppressed because it is too large Load Diff

View File

@ -60,20 +60,26 @@ add wave -noupdate -group {Decode Stage} /testbench/dut/hart/ieu/c/RegWriteD
add wave -noupdate -group {Decode Stage} /testbench/dut/hart/ieu/dp/RdD
add wave -noupdate -group {Decode Stage} /testbench/dut/hart/ieu/dp/Rs1D
add wave -noupdate -group {Decode Stage} /testbench/dut/hart/ieu/dp/Rs2D
add wave -noupdate -group {Execution Stage} /testbench/dut/hart/ifu/PCE
add wave -noupdate -group {Execution Stage} /testbench/InstrEName
add wave -noupdate -group {Execution Stage} /testbench/dut/hart/ifu/InstrE
add wave -noupdate -group {Execution Stage} -color {Cornflower Blue} /testbench/FunctionName/FunctionName
add wave -noupdate -group {Memory Stage} /testbench/dut/hart/priv/trap/InstrValidM
add wave -noupdate -group {Memory Stage} /testbench/dut/hart/PCM
add wave -noupdate -group {Memory Stage} /testbench/InstrMName
add wave -noupdate -group {Memory Stage} /testbench/dut/hart/InstrM
add wave -noupdate -group {Memory Stage} /testbench/dut/hart/lsu/MemAdrM
add wave -noupdate -group {WriteBack stage} /testbench/PCW
add wave -noupdate -group {WriteBack stage} /testbench/InstrW
add wave -noupdate -group {WriteBack stage} /testbench/InstrWName
add wave -noupdate -group {WriteBack stage} /testbench/InstrValidW
add wave -noupdate -group {WriteBack stage} /testbench/checkInstrW
add wave -noupdate -expand -group {Execution Stage} /testbench/dut/hart/ifu/PCE
add wave -noupdate -expand -group {Execution Stage} /testbench/dut/hart/ifu/InstrE
add wave -noupdate -expand -group {Execution Stage} /testbench/InstrEName
add wave -noupdate -expand -group {Execution Stage} /testbench/textE
add wave -noupdate -expand -group {Execution Stage} -color {Cornflower Blue} /testbench/FunctionName/FunctionName
add wave -noupdate -expand -group {Memory Stage} /testbench/checkInstrM
add wave -noupdate -expand -group {Memory Stage} /testbench/dut/hart/priv/trap/InstrValidM
add wave -noupdate -expand -group {Memory Stage} /testbench/dut/hart/PCM
add wave -noupdate -expand -group {Memory Stage} /testbench/ExpectedPCM
add wave -noupdate -expand -group {Memory Stage} /testbench/dut/hart/InstrM
add wave -noupdate -expand -group {Memory Stage} /testbench/InstrMName
add wave -noupdate -expand -group {Memory Stage} /testbench/textM
add wave -noupdate -expand -group {Memory Stage} /testbench/dut/hart/lsu/MemAdrM
add wave -noupdate -expand -group {WriteBack stage} /testbench/checkInstrW
add wave -noupdate -expand -group {WriteBack stage} /testbench/InstrValidW
add wave -noupdate -expand -group {WriteBack stage} /testbench/PCW
add wave -noupdate -expand -group {WriteBack stage} /testbench/ExpectedPCW
add wave -noupdate -expand -group {WriteBack stage} /testbench/InstrW
add wave -noupdate -expand -group {WriteBack stage} /testbench/InstrWName
add wave -noupdate -expand -group {WriteBack stage} /testbench/textW
add wave -noupdate -group Bpred -color Orange /testbench/dut/hart/ifu/bpred/bpred/Predictor/DirPredictor/GHR
add wave -noupdate -group Bpred -expand -group {branch update selection inputs} /testbench/dut/hart/ifu/bpred/bpred/Predictor/DirPredictor/BPPredF
add wave -noupdate -group Bpred -expand -group {branch update selection inputs} {/testbench/dut/hart/ifu/bpred/bpred/Predictor/DirPredictor/InstrClassE[0]}
@ -484,7 +490,6 @@ add wave -noupdate -group {debug trace} -expand -group mem /testbench/dut/hart/p
add wave -noupdate -group {debug trace} -expand -group mem /testbench/checkInstrM
add wave -noupdate -group {debug trace} -expand -group mem /testbench/dut/hart/PCM
add wave -noupdate -group {debug trace} -expand -group mem /testbench/ExpectedPCM
add wave -noupdate -group {debug trace} -expand -group mem /testbench/line
add wave -noupdate -group {debug trace} -expand -group mem /testbench/textM
add wave -noupdate -group {debug trace} -expand -group mem -color Brown /testbench/dut/hart/hzu/TrapM
add wave -noupdate -group {debug trace} -expand -group wb /testbench/checkInstrW
@ -510,7 +515,7 @@ add wave -noupdate /testbench/dut/uncore/dtim/memwrite
add wave -noupdate /testbench/dut/uncore/dtim/HWDATA
add wave -noupdate /testbench/dut/uncore/dtim/risingHREADYTim
TreeUpdate [SetDefaultTree]
WaveRestoreCursors {{Cursor 23} {209183247 ns} 0} {{Cursor 5} {229 ns} 0}
WaveRestoreCursors {{Cursor 23} {209183247 ns} 0} {{Cursor 5} {5672440 ns} 0}
quietly wave cursor active 2
configure wave -namecolwidth 250
configure wave -valuecolwidth 314
@ -526,4 +531,4 @@ configure wave -griddelta 40
configure wave -timeline 0
configure wave -timelineunits ns
update
WaveRestoreZoom {182 ns} {330 ns}
WaveRestoreZoom {5672937 ns} {5673085 ns}

View File

@ -41,7 +41,7 @@ def getBuildrootTC(short):
BRgrepstr=str(MAX_EXPECTED)+" instructions"
return TestCase(name="buildroot",cmd=BRcmd,grepstr=BRgrepstr)
tests64 = ["arch64i", "arch64priv", "arch64c", "arch64m", "imperas64i", "imperas64p", "imperas64mmu", "imperas64f", "imperas64d", "imperas64m", "imperas64a", "imperas64c"] #, "testsBP64"]
tests64 = ["wally64i", "arch64i", "arch64priv", "arch64c", "arch64m", "imperas64i", "imperas64p", "imperas64mmu", "imperas64f", "imperas64d", "imperas64m", "imperas64a", "imperas64c"] #, "testsBP64"]
for test in tests64:
tc = TestCase(
name=test,
@ -49,7 +49,7 @@ for test in tests64:
grepstr="All tests ran without failures")
configs.append(tc)
#tests32 = ["arch32i", "arch32priv", "arch32c", "arch32m", "arch32f", "imperas32i", "imperas32p", "imperas32mmu", "imperas32f", "imperas32m", "imperas32a", "imperas32c"]
tests32 = ["arch32i", "arch32priv", "arch32c", "arch32m", "imperas32i", "imperas32p", "imperas32mmu", "imperas32f", "imperas32m", "imperas32a", "imperas32c"]
tests32 = ["wally32i", "arch32i", "arch32priv", "arch32c", "arch32m", "imperas32i", "imperas32p", "imperas32mmu", "imperas32f", "imperas32m", "imperas32a", "imperas32c"]
for test in tests32:
tc = TestCase(
name=test,

View File

@ -55,7 +55,7 @@ module fpudivsqrtrecur (
// Special Cases
// *** shift to handle denorms in hardware
assign FDivSqrtResSign = FDivE & (XSgnE ^ YSgnE); // Sign is negative for division if inputs have opposite signs
assign FDivSqrtResSgn = FDivE & (XSgnE ^ YSgnE); // Sign is negative for division if inputs have opposite signs
always_comb begin
if (FSqrtE & XSgnE | FDivE & XZeroE & YZeroE | XNaNE | FDivE & YNaNE) FDivSqrtResM = 0; // ***replace with NAN; // *** which one

View File

@ -87,12 +87,26 @@ def Mod_Space_at(Ln,loc,diff):
return NewString
def main_filehandler(overwrite=False):
'''def main_filehandler(overwrite=False):
for filename in os.listdir():
if ".py" not in filename:
if ".sv" in filename:
GiantString = read_input(filename)
SOV = ID_start(GiantString)
ModifiedGS = modified_logNew(GiantString,SOV)
Newname = write_to_output(filename,ModifiedGS,overwrite)
Newname = write_to_output(filename,ModifiedGS,overwrite)'''
def root_filehandler(path,overwrite=False):
for f in os.listdir(path):
if os.path.isdir(f):
root_filehandler(path+"/"+f)
else:
if ".sv" in f:
GiantString = read_input(f)
SOV = ID_start(GiantString)
ModifiedGS = modified_logNew(GiantString,SOV)
Newname = write_to_output(f,ModifiedGS,overwrite)
def driver(overwrite=False):
root_filehandler(os.getcwd())
main_filehandler(True)
driver(True)

View File

@ -64,7 +64,10 @@ module intdiv #(parameter WIDTH=64)
logic [WIDTH-1:0] QT, remT;
logic D_NegOne;
logic Max_N;
logic otfzerov;
logic tcQ;
logic tcR;
// Check if negative (two's complement)
// If so, convert to positive
@ -182,7 +185,9 @@ module divide4 #(parameter WIDTH=64)
logic CshiftQ, CshiftQM;
logic [WIDTH+3:0] rem1, rem2, rem3;
logic [WIDTH+3:0] SumR, CarryR;
logic [WIDTH:0] Qt;
logic [WIDTH:0] Qt;
logic ulp;
// Create one's complement values of Divisor (for q*D)
assign divi1 = {3'h0, op2, 1'b0};

View File

@ -103,30 +103,35 @@ module testbench();
string checkpointDir;
logic [1:0] initPriv;
// Signals used to parse the trace file
integer data_file_all;
string name;
integer matchCount;
string line;
logic [`XLEN-1:0] ExpectedPCM;
logic [31:0] ExpectedInstrM;
string textM;
string token;
string ExpectedTokens [31:0];
integer index;
integer StartIndex, EndIndex;
integer TokenIndex;
integer MarkerIndex;
integer NumCSRM;
`define DECLARE_TRACE_SCANNER_SIGNALS(STAGE) \
integer traceFile``STAGE; \
integer matchCount``STAGE; \
string line``STAGE; \
string token``STAGE; \
string ExpectedTokens``STAGE [31:0]; \
integer index``STAGE; \
integer StartIndex``STAGE, EndIndex``STAGE; \
integer TokenIndex``STAGE; \
integer MarkerIndex``STAGE; \
integer NumCSR``STAGE; \
logic [`XLEN-1:0] ExpectedPC``STAGE; \
logic [31:0] ExpectedInstr``STAGE; \
string text``STAGE; \
string MemOp``STAGE; \
string RegWrite``STAGE; \
integer ExpectedRegAdr``STAGE; \
logic [`XLEN-1:0] ExpectedRegValue``STAGE; \
logic [`XLEN-1:0] ExpectedMemAdr``STAGE, ExpectedMemReadData``STAGE, ExpectedMemWriteData``STAGE; \
string ExpectedCSRArray``STAGE[10:0]; \
logic [`XLEN-1:0] ExpectedCSRArrayValue``STAGE[10:0];
`DECLARE_TRACE_SCANNER_SIGNALS(E)
`DECLARE_TRACE_SCANNER_SIGNALS(M)
integer NextMIPexpected;
integer NextMepcExpected;
// Memory stage expected values from trace
logic checkInstrM;
integer MIPexpected;
string RegWriteM;
integer ExpectedRegAdrM;
logic [`XLEN-1:0] ExpectedRegValueM;
string MemOpM;
logic [`XLEN-1:0] ExpectedMemAdrM, ExpectedMemReadDataM, ExpectedMemWriteDataM;
string ExpectedCSRArrayM[10:0];
logic [`XLEN-1:0] ExpectedCSRArrayValueM[10:0];
string name;
logic [`AHBW-1:0] readDataExpected;
// Write back stage expected values from trace
logic checkInstrW;
@ -148,6 +153,11 @@ module testbench();
integer NumCSRPostWIndex;
logic [`XLEN-1:0] InstrCountW;
integer RequestDelayedMIP;
integer ForceMIPFuture;
integer CSRIndex;
longint MepcExpected;
integer CheckMIPFutureE;
integer CheckMIPFutureM;
// Useful Aliases
`define RF dut.hart.ieu.dp.regf.rf
`define PC dut.hart.ifu.pcreg.q
@ -294,7 +304,8 @@ module testbench();
ProgramLabelMapFile = {`LINUX_TEST_VECTORS,"vmlinux.objdump.lab"};
if (CHECKPOINT==0) begin // normal
$readmemh({`LINUX_TEST_VECTORS,"ram.txt"}, dut.uncore.dtim.RAM);
data_file_all = $fopen({`LINUX_TEST_VECTORS,"all.txt"}, "r");
traceFileM = $fopen({`LINUX_TEST_VECTORS,"all.txt"}, "r");
traceFileE = $fopen({`LINUX_TEST_VECTORS,"all.txt"}, "r");
InstrCountW = '0;
end else begin // checkpoint
$sformat(checkpointDir,"checkpoint%0d/",CHECKPOINT);
@ -303,7 +314,8 @@ module testbench();
ramFile = $fopen({checkpointDir,"ram.bin"}, "rb");
readResult = $fread(dut.uncore.dtim.RAM,ramFile);
$fclose(ramFile);
data_file_all = $fopen({checkpointDir,"all.txt"}, "r");
traceFileE = $fopen({checkpointDir,"all.txt"}, "r");
traceFileM = $fopen({checkpointDir,"all.txt"}, "r");
InstrCountW = CHECKPOINT;
// manual checkpoint initializations that don't neatly fit into MACRO
force {`STATUS_TSR,`STATUS_TW,`STATUS_TVM,`STATUS_MXR,`STATUS_SUM,`STATUS_MPRV} = initMSTATUS[0][22:17];
@ -324,8 +336,12 @@ module testbench();
release `INSTRET;
release `CURR_PRIV;
end
// Get the E-stage trace reader ahead of the M-stage trace reader
matchCountE = $fgets(lineE,traceFileE);
end
///////////////////////////////////////////////////////////////////////////////
//////////////////////////////////// CORE /////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
@ -337,94 +353,158 @@ module testbench();
// on the next falling edge the expected state is compared to the wally state.
// step 0: read the expected state
assign checkInstrM = dut.hart.ieu.InstrValidM & ~dut.hart.priv.trap.InstrPageFaultM & ~dut.hart.priv.trap.InterruptM & ~dut.hart.StallM;
assign checkInstrM = dut.hart.ieu.InstrValidM & ~dut.hart.priv.trap.InstrPageFaultM & ~dut.hart.priv.trap.InterruptM & ~dut.hart.StallM;
`define SCAN_NEW_INSTR_FROM_TRACE(STAGE) \
// always check PC, instruction bits \
if (checkInstrM) begin \
// read 1 line of the trace file \
matchCount``STAGE = $fgets(line``STAGE, traceFile``STAGE); \
if(`DEBUG_TRACE >= 5) $display("Time %t, line %x", $time, line``STAGE); \
// extract PC, Instr \
matchCount``STAGE = $sscanf(line``STAGE, "%x %x %s", ExpectedPC``STAGE, ExpectedInstr``STAGE, text``STAGE); \
\
// for the life of me I cannot get any build in C or C++ string parsing functions/methods to work. \
// strtok was the best idea but it cannot be used correctly as system verilog does not have null \
// terminated strings. \
\
// Just going to do this char by char. \
StartIndex``STAGE = 0; \
TokenIndex``STAGE = 0; \
//$display("len = %d", line``STAGE.len()); \
for(index``STAGE = 0; index``STAGE < line``STAGE.len(); index``STAGE++) begin \
//$display("char = %s", line``STAGE[index]); \
if (line``STAGE[index``STAGE] == " " || line``STAGE[index``STAGE] == "\n") begin \
EndIndex``STAGE = index``STAGE; \
ExpectedTokens``STAGE[TokenIndex``STAGE] = line``STAGE.substr(StartIndex``STAGE, EndIndex``STAGE-1); \
//$display("In Tokenizer %s", line``STAGE.substr(StartIndex, EndIndex-1)); \
StartIndex``STAGE = EndIndex``STAGE + 1; \
TokenIndex``STAGE++; \
end \
end \
\
MarkerIndex``STAGE = 3; \
NumCSR``STAGE = 0; \
MemOp``STAGE = ""; \
RegWrite``STAGE = ""; \
\
#2; \
\
while(TokenIndex``STAGE > MarkerIndex``STAGE) begin \
// parse the GPR \
if (ExpectedTokens``STAGE[MarkerIndex``STAGE] == "GPR") begin \
RegWrite``STAGE = ExpectedTokens``STAGE[MarkerIndex``STAGE]; \
matchCount``STAGE = $sscanf(ExpectedTokens``STAGE[MarkerIndex``STAGE+1], "%d", ExpectedRegAdr``STAGE); \
matchCount``STAGE = $sscanf(ExpectedTokens``STAGE[MarkerIndex``STAGE+2], "%x", ExpectedRegValue``STAGE); \
MarkerIndex``STAGE += 3; \
// parse memory address, read data, and/or write data \
end else if(ExpectedTokens``STAGE[MarkerIndex``STAGE].substr(0, 2) == "Mem") begin \
MemOp``STAGE = ExpectedTokens``STAGE[MarkerIndex``STAGE]; \
matchCount``STAGE = $sscanf(ExpectedTokens``STAGE[MarkerIndex``STAGE+1], "%x", ExpectedMemAdr``STAGE); \
matchCount``STAGE = $sscanf(ExpectedTokens``STAGE[MarkerIndex``STAGE+2], "%x", ExpectedMemWriteData``STAGE); \
matchCount``STAGE = $sscanf(ExpectedTokens``STAGE[MarkerIndex``STAGE+3], "%x", ExpectedMemReadData``STAGE); \
MarkerIndex``STAGE += 4; \
// parse CSRs, because there are 1 or more CSRs after the CSR token \
// we check if the CSR token or the number of CSRs is greater than 0. \
// if so then we want to parse for a CSR. \
end else if(ExpectedTokens``STAGE[MarkerIndex``STAGE] == "CSR" || NumCSR``STAGE > 0) begin \
if(ExpectedTokens``STAGE[MarkerIndex``STAGE] == "CSR") begin \
// all additional CSR's won't have this token. \
MarkerIndex``STAGE++; \
end \
matchCount``STAGE = $sscanf(ExpectedTokens``STAGE[MarkerIndex``STAGE], "%s", ExpectedCSRArray``STAGE[NumCSR``STAGE]); \
matchCount``STAGE = $sscanf(ExpectedTokens``STAGE[MarkerIndex``STAGE+1], "%x", ExpectedCSRArrayValue``STAGE[NumCSR``STAGE]); \
MarkerIndex``STAGE += 2; \
if(`"STAGE`"=="E") begin \
// match MIP to QEMU's because interrupts are imprecise \
if(ExpectedCSRArrayE[NumCSRE].substr(0, 2) == "mip") begin \
CheckMIPFutureE = 1; \
NextMIPexpected = ExpectedCSRArrayValueE[NumCSRE]; \
end \
// $display("%tn: ExpectedCSRArrayM[7] (MEPC) = %x",$time,ExpectedCSRArrayM[7]); \
// $display("%tn: ExpectedPCM = %x",$time,ExpectedPCM); \
// // if PC does not equal MEPC, request delayed MIP is True \
// if(ExpectedPCM != ExpectedCSRArrayM[7]) begin \
// RequestDelayedMIP = 1; \
// end else begin \
// $display("%tns: Updating MIP to %x",$time,ExpectedCSRArrayValueM[NumCSRM]); \
// MIPexpected = ExpectedCSRArrayValueM[NumCSRM]; \
// force dut.hart.priv.csr.genblk1.csri.MIP_REGW = MIPexpected; \
// end \
// end \
// $display("%tns: ExpectedCSRArrayM::: %p",$time,ExpectedCSRArrayM); \
if(ExpectedCSRArrayE[NumCSRE].substr(0,3) == "mepc") begin \
$display("hello! we are here."); \
MepcExpected = ExpectedCSRArrayValueE[NumCSRE]; \
$display("%tns: MepcExpected: %x",$time,MepcExpected); \
end \
end \
\
NumCSR``STAGE++; \
end \
end \
if(`"STAGE`"=="M") begin \
// override on special conditions \
if (ExpectedMemAdrM == 'h10000005) begin \
//$display("%tns, %d instrs: Overwriting read data from CLINT.", $time, InstrCountW); \
force dut.hart.ieu.dp.ReadDataM = ExpectedMemReadDataM; \
end \
if(textM.substr(0,5) == "rdtime") begin \
//$display("%tns, %d instrs: Overwrite MTIME_CLINT on read of MTIME in memory stage.", $time, InstrCountW); \
force dut.uncore.clint.clint.MTIME = ExpectedRegValueM; \
end \
end \
end \
always @(negedge clk) begin
// always check PC, instruction bits
if (checkInstrM) begin
// read 1 line of the trace file
matchCount = $fgets(line, data_file_all);
if(`DEBUG_TRACE >= 5) $display("Time %t, line %x", $time, line);
// extract PC, Instr
matchCount = $sscanf(line, "%x %x %s", ExpectedPCM, ExpectedInstrM, textM);
//$display("matchCount %d, PCM %x ExpectedInstrM %x textM %x", matchCount, ExpectedPCM, ExpectedInstrM, textM);
`SCAN_NEW_INSTR_FROM_TRACE(E)
end
// for the life of me I cannot get any build in C or C++ string parsing functions/methods to work.
// strtok was the best idea but it cannot be used correctly as system verilog does not have null
// terminated strings.
// Just going to do this char by char.
StartIndex = 0;
TokenIndex = 0;
//$display("len = %d", line.len());
for(index = 0; index < line.len(); index++) begin
//$display("char = %s", line[index]);
if (line[index] == " " || line[index] == "\n") begin
EndIndex = index;
ExpectedTokens[TokenIndex] = line.substr(StartIndex, EndIndex-1);
//$display("In Tokenizer %s", line.substr(StartIndex, EndIndex-1));
StartIndex = EndIndex + 1;
TokenIndex++;
end
always @(negedge clk) begin
`SCAN_NEW_INSTR_FROM_TRACE(M)
end
// MIP spoofing
always @(posedge clk) begin
#1;
if(CheckMIPFutureE) CheckMIPFutureE <= 0;
CheckMIPFutureM <= CheckMIPFutureE;
if(CheckMIPFutureM) begin
if((ExpectedPCM != MepcExpected) & ((MepcExpected - ExpectedPCM) * (MepcExpected - ExpectedPCM) <= 16)) begin
RequestDelayedMIP = 1;
$display("%tns: Requesting Delayed MIP. Current MEPC value is %x",$time,MepcExpected);
end else begin // update MIP immediately
$display("%tns: Updating MIP to %x",$time,NextMIPexpected);
MIPexpected = NextMIPexpected;
force dut.hart.priv.csr.genblk1.csri.MIP_REGW = MIPexpected;
end
MarkerIndex = 3;
NumCSRM = 0;
MemOpM = "";
RegWriteM = "";
#2;
while(TokenIndex > MarkerIndex) begin
// parse the GPR
if (ExpectedTokens[MarkerIndex] == "GPR") begin
RegWriteM = ExpectedTokens[MarkerIndex];
matchCount = $sscanf(ExpectedTokens[MarkerIndex+1], "%d", ExpectedRegAdrM);
matchCount = $sscanf(ExpectedTokens[MarkerIndex+2], "%x", ExpectedRegValueM);
MarkerIndex += 3;
// parse memory address, read data, and/or write data
end else if(ExpectedTokens[MarkerIndex].substr(0, 2) == "Mem") begin
MemOpM = ExpectedTokens[MarkerIndex];
matchCount = $sscanf(ExpectedTokens[MarkerIndex+1], "%x", ExpectedMemAdrM);
matchCount = $sscanf(ExpectedTokens[MarkerIndex+2], "%x", ExpectedMemWriteDataM);
matchCount = $sscanf(ExpectedTokens[MarkerIndex+3], "%x", ExpectedMemReadDataM);
MarkerIndex += 4;
// parse CSRs, because there are 1 or more CSRs after the CSR token
// we check if the CSR token or the number of CSRs is greater than 0.
// if so then we want to parse for a CSR.
end else if(ExpectedTokens[MarkerIndex] == "CSR" || NumCSRM > 0) begin
if(ExpectedTokens[MarkerIndex] == "CSR") begin
// all additional CSR's won't have this token.
MarkerIndex++;
end
matchCount = $sscanf(ExpectedTokens[MarkerIndex], "%s", ExpectedCSRArrayM[NumCSRM]);
matchCount = $sscanf(ExpectedTokens[MarkerIndex+1], "%x", ExpectedCSRArrayValueM[NumCSRM]);
MarkerIndex += 2;
// match MIP to QEMU's because interrupts are imprecise
if(ExpectedCSRArrayM[NumCSRM].substr(0, 2) == "mip") begin
$display("%tn: ExpectedCSRArrayM[7] (MEPC) = %x",$time,ExpectedCSRArrayM[7]);
$display("%tn: ExpectedPCM = %x",$time,ExpectedPCM);
// if PC does not equal MEPC, request delayed MIP is True
if(ExpectedPCM != ExpectedCSRArrayM[7]) begin
RequestDelayedMIP = 1;
end else begin
$display("%tns: Updating MIP to %x",$time,ExpectedCSRArrayValueM[NumCSRM]);
MIPexpected = ExpectedCSRArrayValueM[NumCSRM];
force dut.hart.priv.csr.genblk1.csri.MIP_REGW = MIPexpected;
end
end
NumCSRM++;
end
end
// override on special conditions
if (ExpectedMemAdrM == 'h10000005) begin
//$display("%tns, %d instrs: Overwriting read data from CLINT.", $time, InstrCountW);
force dut.hart.ieu.dp.ReadDataM = ExpectedMemReadDataM;
end
if(textM.substr(0,5) == "rdtime") begin
//$display("%tns, %d instrs: Overwrite MTIME_CLINT on read of MTIME in memory stage.", $time, InstrCountW);
force dut.uncore.clint.clint.MTIME = ExpectedRegValueM;
$display("%tn: ExpectedCSRArrayM = %p",$time,ExpectedCSRArrayM);
$display("%tn: ExpectedCSRArrayValueM = %p",$time,ExpectedCSRArrayValueM);
$display("%tn: ExpectedTokens = %p",$time,ExpectedTokensM);
$display("%tn: MepcExpected = %x",$time,MepcExpected);
$display("%tn: ExpectedPCM = %x",$time,ExpectedPCM);
// if PC does not equal MEPC, request delayed MIP is True
$display("%tns: Difference/multiplication thing: %x",$time,(MepcExpected - ExpectedPCM) * (MepcExpected - ExpectedPCM));
$display("%tn: ExpectedCSRArrayM[NumCSRM] %x",$time,ExpectedCSRArrayM[NumCSRM]);
$display("%tn: ExpectedCSRArrayValueM[NumCSRM] %x",$time,ExpectedCSRArrayValueM[NumCSRM]);
if((ExpectedPCM != MepcExpected) & ((MepcExpected - ExpectedPCM) * (MepcExpected - ExpectedPCM) <= 16)) begin
RequestDelayedMIP = 1;
$display("%tns: Requesting Delayed MIP. Current MEPC value is %x",$time,MepcExpected);
end else begin
$display("%tns: Updating MIP to %x",$time,NextMIPexpected);
MIPexpected = NextMIPexpected;
force dut.hart.priv.csr.genblk1.csri.MIP_REGW = MIPexpected;
end
end
if(RequestDelayedMIP) begin
$display("%tns: Executing Delayed MIP. Current MEPC value is %x",$time,dut.hart.priv.csr.genblk1.csrm.MEPC_REGW);
$display("%tns: Updating MIP to %x",$time,NextMIPexpected);
$display("%tns: MepcExpected %x",$time,MepcExpected);
MIPexpected = NextMIPexpected;
force dut.hart.priv.csr.genblk1.csri.MIP_REGW = MIPexpected;
$display("%tns: Finished Executing Delayed MIP. Current MEPC value is %x",$time,dut.hart.priv.csr.genblk1.csrm.MEPC_REGW);
RequestDelayedMIP = 0;
end
end
// step 1: register expected state into the write back stage.
@ -454,7 +534,7 @@ module testbench();
ExpectedMemWriteDataW <= '0;
ExpectedMemReadDataW <= '0;
NumCSRW <= '0;
end else begin
end else if (dut.hart.ieu.c.InstrValidM) begin
ExpectedPCW <= ExpectedPCM;
ExpectedInstrW <= ExpectedInstrM;
textW <= textM;
@ -489,12 +569,6 @@ module testbench();
// step2: make all checks in the write back stage.
assign checkInstrW = InstrValidW & ~dut.hart.StallW; // trapW will already be invalid in there was an InstrPageFault in the previous instruction.
always @(negedge clk) begin
if(RequestDelayedMIP) begin
$display("%tns: Updating MIP to %x",$time,ExpectedCSRArrayValueW[NumCSRM]);
MIPexpected = ExpectedCSRArrayValueW[NumCSRM];
force dut.hart.priv.csr.genblk1.csri.MIP_REGW = MIPexpected;
RequestDelayedMIP = 0;
end
// always check PC, instruction bits
if (checkInstrW) begin
InstrCountW += 1;
@ -526,7 +600,7 @@ module testbench();
if(MemOpW == "MemR" || MemOpW == "MemRW") begin
if(`DEBUG_TRACE >= 4) $display("\tReadDataW: %016x ? expected: %016x", dut.hart.ieu.dp.ReadDataW, ExpectedMemReadDataW);
`checkEQ("ReadDataW",dut.hart.ieu.dp.ReadDataW,ExpectedMemReadDataW)
end else if(ExpectedTokens[MarkerIndex] == "MemW" || ExpectedTokens[MarkerIndex] == "MemRW") begin
end else if(MemOpW == "MemW" || MemOpW == "MemRW") begin
if(`DEBUG_TRACE >= 4) $display("\tWriteDataW: %016x ? expected: %016x", WriteDataW, ExpectedMemWriteDataW);
`checkEQ("WriteDataW",ExpectedMemWriteDataW,ExpectedMemWriteDataW)
end

View File

@ -94,7 +94,9 @@ logic [3:0] dummy;
"imperas64c": if (`C_SUPPORTED) tests = imperas64c;
else tests = imperas64iNOc;
"testsBP64": tests = testsBP64;
// *** add arch f and d tests, peripheral tests
"wally64i": tests = wally64i;
"wally64priv": tests = wally64priv;
"wally64periph": tests = wally64periph;
endcase
end else begin // RV32
case (TEST)
@ -111,51 +113,15 @@ logic [3:0] dummy;
"imperas32a": if (`A_SUPPORTED) tests = imperas32a;
"imperas32c": if (`C_SUPPORTED) tests = imperas32c;
else tests = imperas32iNOc;
// ***add arch f and d tests
"wally32i": tests = wally32i;
"wally32priv": tests = wally32priv;
"wally32periph": tests = wally32periph;
endcase
end
if (tests.size() == 1) begin
$display("TEST %s not supported in this configuration", TEST);
$stop;
end
//if (TEST == "arch-64m") //tests = {archtests64m};
/* if (`XLEN == 64) begin // RV64
if (`TESTSBP) begin
tests = testsBP64;
// testsbp should not run the other tests. It starts at address 0 rather than
// 0x8000_0000, the next if must remain an else if.
end else if (TESTSPERIPH)
tests = imperastests64periph;
else if (TESTSPRIV)
tests = imperastests64p;
else begin
tests = {imperastests64p,imperastests64i, imperastests64periph};
if (`C_SUPPORTED) tests = {tests, imperastests64ic};
else tests = {tests, imperastests64iNOc};
if (`F_SUPPORTED) tests = {imperastests64f, tests};
if (`D_SUPPORTED) tests = {imperastests64d, tests};
if (`MEM_VIRTMEM) tests = {imperastests64mmu, tests};
if (`A_SUPPORTED) tests = {imperastests64a, tests};
if (`M_SUPPORTED) tests = {imperastests64m, tests};
end
//tests = {imperastests64a, tests};
end else begin // RV32
// *** add the 32 bit bp tests
if (TESTSPERIPH)
tests = imperastests32periph;
else if (TESTSPRIV)
tests = imperastests32p;
else begin
tests = {archtests32i, imperastests32i, imperastests32p};//,imperastests32periph}; *** broken at the moment
if (`C_SUPPORTED) tests = {tests, imperastests32ic};
else tests = {tests, imperastests32iNOc};
if (`F_SUPPORTED) tests = {imperastests32f, tests};
if (`MEM_VIRTMEM) tests = {imperastests32mmu, tests};
if (`A_SUPPORTED) tests = {imperastests32a, tests};
if (`M_SUPPORTED) tests = {imperastests32m, tests};
tests = {archtests32i};
end
end */
end
string signame, memfilename, pathname;
@ -203,9 +169,10 @@ logic [3:0] dummy;
end
end
// read test vectors into memory
if (tests[0] == `IMPERASTEST)
pathname = tvpaths[tests[0].atoi()];
/* if (tests[0] == `IMPERASTEST)
pathname = tvpaths[0];
else pathname = tvpaths[1];
else pathname = tvpaths[1]; */
memfilename = {pathname, tests[test], ".elf.memfile"};
$readmemh(memfilename, dut.uncore.dtim.RAM);
ProgramAddrMapFile = {pathname, tests[test], ".elf.objdump.addr"};

View File

@ -25,10 +25,12 @@
`define IMPERASTEST "0"
`define RISCVARCHTEST "1"
`define WALLYTEST "2"
string tvpaths[] = '{
"../../tests/imperas-riscv-tests/work/",
"../../addins/riscv-arch-test/work/"
"../../addins/riscv-arch-test/work/",
"../../tests/wally-riscv-arch-test/work/"
};
string imperas32mmu[] = '{
@ -1067,4 +1069,30 @@ string imperas32f[] = '{
"rv32i_m/I/xori-01", "4010"
};
string wally64i[] = '{
`WALLYTEST,
"rv64i_m/I/add-01", "9010",
"rv64i_m/I/PIPELINE", "3010"
};
string wally64priv[] = '{
`WALLYTEST
};
string wally64periph[] = '{
`WALLYTEST
};
string wally32i[] = '{
`WALLYTEST,
"rv32i_m/I/PIPELINE", "3010"
};
string wally32priv[] = '{
`WALLYTEST
};
string wally32periph[] = '{
`WALLYTEST
};