From 1c20bb9313d39ae3e955d2786cd57544baedc44f Mon Sep 17 00:00:00 2001 From: David Harris Date: Tue, 14 May 2024 11:32:21 -0700 Subject: [PATCH 01/51] Added riscv-isac for test vector generation --- bin/wally-tool-chain-install.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bin/wally-tool-chain-install.sh b/bin/wally-tool-chain-install.sh index 3b08aea54..44ff08aee 100755 --- a/bin/wally-tool-chain-install.sh +++ b/bin/wally-tool-chain-install.sh @@ -48,7 +48,8 @@ sudo apt update -y sudo apt upgrade -y sudo apt install -y git gawk make texinfo bison flex build-essential python3 libz-dev libexpat-dev autoconf device-tree-compiler ninja-build libpixman-1-dev ncurses-base ncurses-bin libncurses5-dev dialog curl wget ftp libgmp-dev libglib2.0-dev python3-pip pkg-config opam z3 zlib1g-dev automake autotools-dev libmpc-dev libmpfr-dev gperf libtool patchutils bc mutt ssmtp # Other python libraries used through the book. -sudo -H pip3 install sphinx sphinx_rtd_theme matplotlib scipy scikit-learn adjustText lief markdown pyyaml +sudo -H pip3 install sphinx sphinx_rtd_theme matplotlib scipy scikit-learn adjustText lief markdown pyyaml +sudo -H pip3 install riscv_isac # to generate new tests, such as quads with fp_dataset.py # needed for Ubuntu 22.04, gcc cross compiler expects python not python2 or python3. if ! command -v python &> /dev/null From 506973c27a9d8cfde3ea7a88bf2f03a3a12c2c83 Mon Sep 17 00:00:00 2001 From: David Harris Date: Wed, 15 May 2024 19:29:42 -0700 Subject: [PATCH 02/51] Added gfmul example --- .gitignore | 1 + examples/crypto/gfmul/Makefile | 16 ++++++++ examples/crypto/gfmul/gfmul.c | 72 ++++++++++++++++++++++++++++++++++ 3 files changed, 89 insertions(+) create mode 100644 examples/crypto/gfmul/Makefile create mode 100644 examples/crypto/gfmul/gfmul.c diff --git a/.gitignore b/.gitignore index 3a7513d12..e085dcb33 100644 --- a/.gitignore +++ b/.gitignore @@ -231,6 +231,7 @@ examples/verilog/fulladder/simprofile_dir/ examples/verilog/fulladder/simv.daidir/ examples/verilog/fulladder/ucli.key examples/verilog/fulladder/verdi_config_file +examples/crypto/gfmul/gfmul tests/functcov tests/functcov/* tests/functcov/*/* diff --git a/examples/crypto/gfmul/Makefile b/examples/crypto/gfmul/Makefile new file mode 100644 index 000000000..a501c3775 --- /dev/null +++ b/examples/crypto/gfmul/Makefile @@ -0,0 +1,16 @@ +# Makefile + +CC = gcc +CFLAGS = -O3 +LIBS = +SRCS = $(wildcard *.c) + +PROGS = $(patsubst %.c,%,$(SRCS)) + +all: $(PROGS) + +%: %.c + $(CC) $(CFLAGS) $(IFLAGS) -o $@ $< $(LIBS) + +clean: + rm -f $(PROGS) diff --git a/examples/crypto/gfmul/gfmul.c b/examples/crypto/gfmul/gfmul.c new file mode 100644 index 000000000..3c4f585f1 --- /dev/null +++ b/examples/crypto/gfmul/gfmul.c @@ -0,0 +1,72 @@ +// gfmul.c - Galois Field multiplication +// James Stine and David Harris 16 May 2024 + +#include + +/* return ab mod m(x) - long multiplication in GF(2^n) with polynomial m */ +int gfmul(int a, int b, int n, int m) { + int result = 0; + while (b) { + if (b & 1) result = result ^ a; /* if bit of b is set add a */ + a = a << 1; /* multiply a by x */ + if (a & 1 << n) + a = a ^ m; /* reduce/sub modulo AES m(x) = 100011011 */ + //printf("a = %x, b = %x, result = %x\n", a, b, result); + b = b >> 1; /* get next bit of b */ + } + return result; +} + +void inverses(void) { + int i, j, k, num; + + printf("\nTable of inverses in GF(2^8) with polynomial m(x) = 100011011\n"); + for (i=0; i<16; i++) { + for (j=0; j<16; j++) { + num = i*16+j; + if (num ==0) printf ("00 "); + else for (k=1; k<256; k++) { + if (gfmul(num, k, 8, 0b100011011) == 1) { + printf("%02x ", k); + break; + } + } + } + printf("\n"); + } +} + +void inverses3(void) { + int k, num; + + printf("\nTable of inverses in GF(2^8) with polynomial m(x) = 100011011\n"); + for (num=0; num<8; num++) { + if (num == 0) printf ("0 "); + else for (k=1; k<8; k++) { + if (gfmul(num, k, 3, 0b1011) == 1) { + printf("%d ", k); + break; + } + } + } + printf("\n"); +} + + +int main() { + int a = 0xC5; + int b = 0xA1; + + printf("The GF(2^8) result is %x\n", gfmul(a,b, 8, 0b100011011)); + printf("The GF(2^8) result is %x\n", gfmul(0xC1, 0x28, 8, 0b100011011)); + inverses(); + + // tabulate inverses for GF(2^3) + inverses3(); + // check worked examples + printf("The GF(2^3) result is %d\n", gfmul(0b101,0b011, 3, 0b1011)); + printf("The GF(2^3) result is %d\n", gfmul(0b101,0b010, 3, 0b1011)); + printf("The GF(2^3) result is %d\n", gfmul(0b101,0b100, 3, 0b1011)); + printf("The GF(2^3) result is %d\n", gfmul(0b101,0b011, 3, 0b1011)); + +} From 08601d727006171a3e0211c9e49465fe4118c6da Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Thu, 16 May 2024 13:59:15 -0500 Subject: [PATCH 03/51] Added functionallity to testbench.sv for single elf files. --- testbench/testbench.sv | 41 ++++++++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/testbench/testbench.sv b/testbench/testbench.sv index ef1809e9e..c1ff01599 100644 --- a/testbench/testbench.sv +++ b/testbench/testbench.sv @@ -68,7 +68,7 @@ module testbench; logic ResetMem; // Variables that can be overwritten with $value$plusargs at start of simulation - string TEST; + string TEST, ElfFile; integer INSTR_LIMIT; // DUT signals @@ -115,6 +115,10 @@ module testbench; // look for arguments passed to simulation, or use defaults if (!$value$plusargs("TEST=%s", TEST)) TEST = "none"; + if (!$value$plusargs("ElfFile=%s", ElfFile)) + ElfFile = "none"; + else begin + end if (!$value$plusargs("INSTR_LIMIT=%d", INSTR_LIMIT)) INSTR_LIMIT = 0; @@ -221,8 +225,12 @@ module testbench; "arch32zknh": if (P.ZKNH_SUPPORTED) tests = arch32zknh; endcase end - if (tests.size() == 0) begin - $display("TEST %s not supported in this configuration", TEST); + if (tests.size() == 0 & ElfFile == "none") begin + if (tests.size() == 0) begin + $display("TEST %s not supported in this configuration", TEST); + end else if(ElfFile == "none") begin + $display("ElfFile %s not found", ElfFile); + end $finish; end `ifdef MAKEVCD @@ -356,21 +364,23 @@ module testbench; //end // added //always @(posedge SelectTest) // added if(SelectTest) begin - if (riscofTest) memfilename = {pathname, tests[test], "/ref/ref.elf.memfile"}; - else if(TEST == "buildroot") begin + if (riscofTest) begin + memfilename = {pathname, tests[test], "/ref/ref.elf.memfile"}; + ProgramAddrMapFile = {pathname, tests[test], "/ref/ref.elf.objdump.addr"}; + ProgramLabelMapFile = {pathname, tests[test], "/ref/ref.elf.objdump.lab"}; + end else if(TEST == "buildroot") begin memfilename = {RISCV_DIR, "/linux-testvectors/ram.bin"}; bootmemfilename = {RISCV_DIR, "/linux-testvectors/bootmem.bin"}; uartoutfilename = {"logs/", TEST, "_uart.out"}; uartoutfile = $fopen(uartoutfilename, "w"); // delete UART output file - end - else memfilename = {pathname, tests[test], ".elf.memfile"}; - if (riscofTest) begin - ProgramAddrMapFile = {pathname, tests[test], "/ref/ref.elf.objdump.addr"}; - ProgramLabelMapFile = {pathname, tests[test], "/ref/ref.elf.objdump.lab"}; - end else if (TEST == "buildroot") begin ProgramAddrMapFile = {RISCV_DIR, "/buildroot/output/images/disassembly/vmlinux.objdump.addr"}; ProgramLabelMapFile = {RISCV_DIR, "/buildroot/output/images/disassembly/vmlinux.objdump.lab"}; + end else if(ElfFile != "none") begin + memfilename = {ElfFile, ".memfile"}; + ProgramAddrMapFile = {ElfFile, ".objdump.addr"}; + ProgramLabelMapFile = {ElfFile, ".objdump.lab"}; end else begin + memfilename = {pathname, tests[test], ".elf.memfile"}; ProgramAddrMapFile = {pathname, tests[test], ".elf.objdump.addr"}; ProgramLabelMapFile = {pathname, tests[test], ".elf.objdump.lab"}; end @@ -410,6 +420,15 @@ module testbench; $display("Embench Benchmark: created output file: %s", outputfile); end else if (TEST == "coverage64gc") begin $display("Coverage tests don't get checked"); + end else if (ElfFile != "none") begin + $display("Single Elf file tests don't get signatured checked."); +`ifdef VERILATOR // this macro is defined when verilator is used + $finish; // Simulator Verilator needs $finish to terminate simulation. +`elsif SIM_VCS // this macro is defined when vcs is used + $finish; // Simulator VCS needs $finish to terminate simulation. +`else + $stop; // if this is changed to $finish for Questa, wally-batch.do does not go to the next step to run coverage, and wally.do terminates without allowing GUI debug +`endif end else begin // for tests with no self checking mechanism, read .signature.output file and compare to check for errors // clear signature to prevent contamination from previous tests From 3fdfa0f70589b78967211edf1e8427db2fe67120 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Thu, 16 May 2024 15:14:49 -0500 Subject: [PATCH 04/51] wsim now simulates a single elffile. --- bin/wsim | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/bin/wsim b/bin/wsim index 9c4cce68f..531c6825c 100755 --- a/bin/wsim +++ b/bin/wsim @@ -18,6 +18,7 @@ import os parser = argparse.ArgumentParser() parser.add_argument("config", help="Configuration file") parser.add_argument("testsuite", help="Test suite or ELF file") +parser.add_argument("--elf", "-e", help="Elf file", action="store_true") parser.add_argument("--sim", "-s", help="Simulator", choices=["questa", "verilator", "vcs"], default="questa") parser.add_argument("--tb", "-t", help="Testbench", choices=["testbench", "testbench_fp"], default="testbench") parser.add_argument("--gui", "-g", help="Simulate with GUI", action="store_true") @@ -26,6 +27,10 @@ parser.add_argument("--args", "-a", help="Optional arguments passed to simulator parser.add_argument("--vcd", "-v", help="Generate testbench.vcd", action="store_true") args = parser.parse_args() print("Config=" + args.config + " tests=" + args.testsuite + " sim=" + args.sim + " gui=" + str(args.gui) + " args='" + args.args + "'") +ElfFile="" +if(args.elf): + ElfFile = "+ElfFile=" + args.testsuite + args.testsuite = "none" # Validate arguments if (args.gui): @@ -55,7 +60,7 @@ cd = "cd $WALLY/sim/" +args.sim if (args.sim == "questa"): if (args.tb == "testbench_fp"): args.args = " -GTEST=\"" + args.testsuite + "\" " + args.args - cmd = "do wally.do " + args.config + " " + args.testsuite + " " + args.tb + " " + args.args + cmd = "do wally.do " + args.config + " " + args.testsuite + " " + args.tb + " " + args.args + " " + ElfFile if (args.coverage): cmd += " --coverage" if (args.gui): # launch Questa with GUI; add +acc to keep variables accessible From 8391b8b821c09c33b28f4adcdabd662b0b6c2c90 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Thu, 16 May 2024 15:29:12 -0500 Subject: [PATCH 05/51] Progress towards unified regression. --- testbench/testbench.sv | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/testbench/testbench.sv b/testbench/testbench.sv index c1ff01599..846ef9e6a 100644 --- a/testbench/testbench.sv +++ b/testbench/testbench.sv @@ -265,7 +265,7 @@ module testbench; logic ResetCntRst; logic CopyRAM; - string signame, memfilename, bootmemfilename, uartoutfilename, pathname; + string signame, elffilename, memfilename, bootmemfilename, uartoutfilename, pathname; integer begin_signature_addr, end_signature_addr, signature_size; integer uartoutfile; @@ -366,20 +366,24 @@ module testbench; if(SelectTest) begin if (riscofTest) begin memfilename = {pathname, tests[test], "/ref/ref.elf.memfile"}; + elffilename = {pathname, tests[test], "ref/ref.elf"}; ProgramAddrMapFile = {pathname, tests[test], "/ref/ref.elf.objdump.addr"}; ProgramLabelMapFile = {pathname, tests[test], "/ref/ref.elf.objdump.lab"}; end else if(TEST == "buildroot") begin memfilename = {RISCV_DIR, "/linux-testvectors/ram.bin"}; + elffilename = "buildroot"; bootmemfilename = {RISCV_DIR, "/linux-testvectors/bootmem.bin"}; uartoutfilename = {"logs/", TEST, "_uart.out"}; uartoutfile = $fopen(uartoutfilename, "w"); // delete UART output file ProgramAddrMapFile = {RISCV_DIR, "/buildroot/output/images/disassembly/vmlinux.objdump.addr"}; ProgramLabelMapFile = {RISCV_DIR, "/buildroot/output/images/disassembly/vmlinux.objdump.lab"}; end else if(ElfFile != "none") begin + elffilename = ElfFile; memfilename = {ElfFile, ".memfile"}; ProgramAddrMapFile = {ElfFile, ".objdump.addr"}; ProgramLabelMapFile = {ElfFile, ".objdump.lab"}; end else begin + elffilename = {pathname, tests[test], ".elf"}; memfilename = {pathname, tests[test], ".elf.memfile"}; ProgramAddrMapFile = {pathname, tests[test], ".elf.objdump.addr"}; ProgramLabelMapFile = {pathname, tests[test], ".elf.objdump.lab"}; @@ -421,7 +425,7 @@ module testbench; end else if (TEST == "coverage64gc") begin $display("Coverage tests don't get checked"); end else if (ElfFile != "none") begin - $display("Single Elf file tests don't get signatured checked."); + $display("Single Elf file tests are not signatured verified."); `ifdef VERILATOR // this macro is defined when verilator is used $finish; // Simulator Verilator needs $finish to terminate simulation. `elsif SIM_VCS // this macro is defined when vcs is used @@ -688,6 +692,7 @@ end .CMP_CSR (1) ) idv_trace2api(rvvi); + string filename; initial begin int iter; #1; @@ -705,7 +710,10 @@ end void'(rvviRefConfigSetInt(IDV_CONFIG_MODEL_ADDRESS_BUS_WIDTH, 56)); void'(rvviRefConfigSetInt(IDV_CONFIG_MAX_NET_LATENCY_RETIREMENTS, 6)); - if (!rvviRefInit("")) begin + if(elffilename == "buildroot") filename = ""; + else filename = elffilename; + + if (!rvviRefInit(filename)) begin $display($sformatf("%m @ t=%0t: rvviRefInit failed", $time)); $fatal; end From 62eaca0e6ec72e9d39dd1eb9f8825bb4eb4f4a47 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Thu, 16 May 2024 17:01:25 -0500 Subject: [PATCH 06/51] Almost working ImperasDV with testbench.sv and wally.do. For some reason IDV is saying the instructions are mismatching. --- testbench/testbench.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testbench/testbench.sv b/testbench/testbench.sv index 846ef9e6a..63bbf7d00 100644 --- a/testbench/testbench.sv +++ b/testbench/testbench.sv @@ -775,7 +775,7 @@ end // *** RT: This section can probably be moved into the same chunk of code which // loads the memories. However I'm not sure that ImperasDV supports reloading // the memories without relaunching the simulator. - begin + if(elffilename == "buildroot") begin longint x64; int x32[2]; longint index; From bd8450734bf403785c537204cee6cd77cfde78cb Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Fri, 17 May 2024 10:39:00 -0500 Subject: [PATCH 07/51] Fixed more bugs with wally.do. --- sim/questa/wally.do | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sim/questa/wally.do b/sim/questa/wally.do index 0e717f730..4f626851e 100644 --- a/sim/questa/wally.do +++ b/sim/questa/wally.do @@ -143,7 +143,7 @@ vlog -lint -work ${WKDIR} +incdir+${CONFIG}/${CFG} +incdir+${CONFIG}/deriv/${CF # start and run simulation # remove +acc flag for faster sim during regressions if there is no need to access internal signals -vopt $accFlag wkdir/${CFG}_${TESTSUITE}.${TESTBENCH} -work ${WKDIR} ${lst} -o testbenchopt ${CoverageVoptArg} +vopt $accFlag wkdir/${CFG}_${TESTSUITE}.${TESTBENCH} -work ${WKDIR} ${ParamArgs} -o testbenchopt ${CoverageVoptArg} vsim -lib ${WKDIR} testbenchopt +TEST=${TESTSUITE} ${PlusArgs} -fatal 7 ${SVLib} ${SVLibPath} ${OtherFlags} -suppress 3829 ${CoverageVsimArg} From a885240fbde05e345145f084a252ae20e7472079 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Fri, 17 May 2024 12:36:00 -0500 Subject: [PATCH 08/51] temporary commit to help debug merging testbench.sv with testbench-imperas.sv --- sim/questa/run-imperas-linux.sh | 2 +- testbench/testbench-imperas.sv | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sim/questa/run-imperas-linux.sh b/sim/questa/run-imperas-linux.sh index d0f3981c4..aebf6b9d0 100755 --- a/sim/questa/run-imperas-linux.sh +++ b/sim/questa/run-imperas-linux.sh @@ -7,4 +7,4 @@ export OTHERFLAGS="+TRACE2LOG_ENABLE=1 +TRACE2LOG_AFTER=100" #export OTHERFLAGS="+TRACE2LOG_ENABLE=1 +TRACE2LOG_AFTER=10500000" #export OTHERFLAGS="" -vsim -c -do "do wally.do buildroot buildroot testbench --lockstep" +vsim -do "do wally.do buildroot buildroot testbench --lockstep +acc -GDEBUG=1" diff --git a/testbench/testbench-imperas.sv b/testbench/testbench-imperas.sv index c315272a6..877422fc5 100644 --- a/testbench/testbench-imperas.sv +++ b/testbench/testbench-imperas.sv @@ -97,7 +97,7 @@ module testbench; initial begin ResetCount = 0; - ResetThreshold = 2; + ResetThreshold = 21; InReset = 1; testadr = 0; testadrNoBase = 0; From d9807bb9094e2e8ea12d8c192ba5497df9b62c47 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Fri, 17 May 2024 14:45:37 -0500 Subject: [PATCH 09/51] This is crazy. I'm merging testbench.sv into testbench-imperas.sv to find the point when it stops working. But each logical point where it would stop working it keeps working. For example moving readmemh from initial to always block. --- testbench/testbench-imperas.sv | 633 +++++++++++++++++++++++++++------ 1 file changed, 515 insertions(+), 118 deletions(-) diff --git a/testbench/testbench-imperas.sv b/testbench/testbench-imperas.sv index 877422fc5..478474749 100644 --- a/testbench/testbench-imperas.sv +++ b/testbench/testbench-imperas.sv @@ -26,59 +26,66 @@ //////////////////////////////////////////////////////////////////////////////////////////////// `include "config.vh" - - -// This is set from the command line script -// `define USE_IMPERAS_DV +`include "tests.vh" +`include "BranchPredictorType.vh" `ifdef USE_IMPERAS_DV `include "idv/idv.svh" `endif + import cvw::*; module testbench; + /* verilator lint_off WIDTHTRUNC */ + /* verilator lint_off WIDTHEXPAND */ parameter DEBUG=0; + parameter PrintHPMCounters=0; + parameter BPRED_LOGGER=0; + parameter I_CACHE_ADDR_LOGGER=0; + parameter D_CACHE_ADDR_LOGGER=0; -`ifdef USE_IMPERAS_DV - import idvPkg::*; - import rvviApiPkg::*; - import idvApiPkg::*; -`endif + `ifdef USE_IMPERAS_DV + import idvPkg::*; + import rvviApiPkg::*; + import idvApiPkg::*; + `endif + + `ifdef VERILATOR + import "DPI-C" function string getenvval(input string env_name); + string RISCV_DIR = getenvval("RISCV"); // "/opt/riscv"; + `elsif SIM_VCS + import "DPI-C" function string getenv(input string env_name); + string RISCV_DIR = getenv("RISCV"); // "/opt/riscv"; + `else + string RISCV_DIR = "$RISCV"; // "/opt/riscv"; + `endif `include "parameter-defs.vh" logic clk; logic reset_ext, reset; + logic ResetMem; + // Variables that can be overwritten with $value$plusargs at start of simulation + string TEST; + string ElfFile; + integer INSTR_LIMIT; - logic [P.XLEN-1:0] testadr, testadrNoBase; - string InstrFName, InstrDName, InstrEName, InstrMName, InstrWName; - logic [31:0] InstrW; - - logic [3:0] dummy; - - logic [P.AHBW-1:0] HRDATAEXT; - logic HREADYEXT, HRESPEXT; - logic HSELEXTSDC; + // DUT signals + logic [P.AHBW-1:0] HRDATAEXT; + logic HREADYEXT, HRESPEXT; + logic HSELEXTSDC; logic [P.PA_BITS-1:0] HADDR; - logic [P.AHBW-1:0] HWDATA; - logic [P.XLEN/8-1:0] HWSTRB; - logic HWRITE; - logic [2:0] HSIZE; - logic [2:0] HBURST; - logic [3:0] HPROT; - logic [1:0] HTRANS; - 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 }; - logic DCacheFlushDone, DCacheFlushStart; - string testName; - string memfilename, testDir, adrstr, elffilename; + logic [P.AHBW-1:0] HWDATA; + logic [P.XLEN/8-1:0] HWSTRB; + logic HWRITE; + logic [2:0] HSIZE; + logic [2:0] HBURST; + logic [3:0] HPROT; + logic [1:0] HTRANS; + logic HMASTLOCK; + logic HCLK, HRESETn; logic [31:0] GPIOIN, GPIOOUT, GPIOEN; logic UARTSin, UARTSout; @@ -88,10 +95,275 @@ module testbench; logic HREADY; logic HSELEXT; + + string ProgramAddrMapFile, ProgramLabelMapFile; + integer ProgramAddrLabelArray [string]; + + int test, i, errors, totalerrors; + + string outputfile; + integer outputFilePointer; + + string tests[]; + logic DCacheFlushDone, DCacheFlushStart; + logic riscofTest; + logic Validate; + logic SelectTest; + logic TestComplete; + + initial begin + // look for arguments passed to simulation, or use defaults + if (!$value$plusargs("TEST=%s", TEST)) + TEST = "none"; + if (!$value$plusargs("ElfFile=%s", ElfFile)) + ElfFile = "none"; + else begin + end + if (!$value$plusargs("INSTR_LIMIT=%d", INSTR_LIMIT)) + INSTR_LIMIT = 0; + ElfFile = "/home/rose/repos/active/cvw2/cvw/tests/riscof/work/riscv-arch-test/rv64i_m/I/src/add-01.S/ref/ref.elf"; + + // pick tests based on modes supported + //tests = '{}; + if (P.XLEN == 64) begin // RV64 + case (TEST) + "arch64i": tests = arch64i; + "arch64priv": tests = arch64priv; + "arch64c": if (P.C_SUPPORTED) + if (P.ZICSR_SUPPORTED) tests = {arch64c, arch64cpriv}; + else tests = {arch64c}; + "arch64m": if (P.M_SUPPORTED) tests = arch64m; + "arch64a_amo": if (P.A_SUPPORTED | P.ZAAMO_SUPPORTED) tests = arch64a_amo; + "arch64f": if (P.F_SUPPORTED) tests = arch64f; + "arch64d": if (P.D_SUPPORTED) tests = arch64d; + "arch64f_fma": if (P.F_SUPPORTED) tests = arch64f_fma; + "arch64d_fma": if (P.D_SUPPORTED) tests = arch64d_fma; + "arch64f_divsqrt": if (P.F_SUPPORTED) tests = arch64f_divsqrt; + "arch64d_divsqrt": if (P.D_SUPPORTED) tests = arch64d_divsqrt; + "arch64zifencei": if (P.ZIFENCEI_SUPPORTED) tests = arch64zifencei; + "arch64zicond": if (P.ZICOND_SUPPORTED) tests = arch64zicond; + "imperas64i": tests = imperas64i; + "imperas64f": if (P.F_SUPPORTED) tests = imperas64f; + "imperas64d": if (P.D_SUPPORTED) tests = imperas64d; + "imperas64m": if (P.M_SUPPORTED) tests = imperas64m; + "wally64q": if (P.Q_SUPPORTED) tests = wally64q; + "wally64a_lrsc": if (P.A_SUPPORTED | P.ZALRSC_SUPPORTED) tests = wally64a_lrsc; + "imperas64c": if (P.C_SUPPORTED) tests = imperas64c; + else tests = imperas64iNOc; + "custom": tests = custom; + "wally64i": tests = wally64i; + "wally64priv": tests = wally64priv; + "wally64periph": tests = wally64periph; + "coremark": tests = coremark; + "fpga": tests = fpga; + "ahb64" : tests = ahb64; + "coverage64gc" : tests = coverage64gc; + "arch64zba": if (P.ZBA_SUPPORTED) tests = arch64zba; + "arch64zbb": if (P.ZBB_SUPPORTED) tests = arch64zbb; + "arch64zbc": if (P.ZBC_SUPPORTED) tests = arch64zbc; + "arch64zbs": if (P.ZBS_SUPPORTED) tests = arch64zbs; + "arch64zicboz": if (P.ZICBOZ_SUPPORTED) tests = arch64zicboz; + "arch64zcb": if (P.ZCB_SUPPORTED) tests = arch64zcb; + "arch64zfh": if (P.ZFH_SUPPORTED) tests = arch64zfh; + "arch64zfh_fma": if (P.ZFH_SUPPORTED) tests = arch64zfh_fma; + "arch64zfh_divsqrt": if (P.ZFH_SUPPORTED) tests = arch64zfh_divsqrt; + "arch64zfaf": if (P.ZFA_SUPPORTED) tests = arch64zfaf; + "arch64zfad": if (P.ZFA_SUPPORTED & P.D_SUPPORTED) tests = arch64zfad; + "buildroot": tests = buildroot; + "arch64zbkb": if (P.ZBKB_SUPPORTED) tests = arch64zbkb; + "arch64zbkc": if (P.ZBKC_SUPPORTED) tests = arch64zbkc; + "arch64zbkx": if (P.ZBKX_SUPPORTED) tests = arch64zbkx; + "arch64zknd": if (P.ZKND_SUPPORTED) tests = arch64zknd; + "arch64zkne": if (P.ZKNE_SUPPORTED) tests = arch64zkne; + "arch64zknh": if (P.ZKNH_SUPPORTED) tests = arch64zknh; + endcase + end else begin // RV32 + case (TEST) + "arch32e": tests = arch32e; + "arch32i": tests = arch32i; + "arch32priv": tests = arch32priv; + "arch32c": if (P.C_SUPPORTED) + if (P.ZICSR_SUPPORTED) tests = {arch32c, arch32cpriv}; + else tests = {arch32c}; + "arch32m": if (P.M_SUPPORTED) tests = arch32m; + "arch32a_amo": if (P.A_SUPPORTED | P.ZAAMO_SUPPORTED) tests = arch32a_amo; + "arch32f": if (P.F_SUPPORTED) tests = arch32f; + "arch32d": if (P.D_SUPPORTED) tests = arch32d; + "arch32f_fma": if (P.F_SUPPORTED) tests = arch32f_fma; + "arch32d_fma": if (P.D_SUPPORTED) tests = arch32d_fma; + "arch32f_divsqrt": if (P.F_SUPPORTED) tests = arch32f_divsqrt; + "arch32d_divsqrt": if (P.D_SUPPORTED) tests = arch32d_divsqrt; + "arch32zifencei": if (P.ZIFENCEI_SUPPORTED) tests = arch32zifencei; + "arch32zicond": if (P.ZICOND_SUPPORTED) tests = arch32zicond; + "imperas32i": tests = imperas32i; + "imperas32f": if (P.F_SUPPORTED) tests = imperas32f; + "imperas32m": if (P.M_SUPPORTED) tests = imperas32m; + "wally32a_lrsc": if (P.A_SUPPORTED | P.ZALRSC_SUPPORTED) tests = wally32a_lrsc; + "imperas32c": if (P.C_SUPPORTED) tests = imperas32c; + else tests = imperas32iNOc; + "wally32i": tests = wally32i; + "wally32priv": tests = wally32priv; + "wally32periph": tests = wally32periph; + "ahb32" : tests = ahb32; + "embench": tests = embench; + "coremark": tests = coremark; + "arch32zba": if (P.ZBA_SUPPORTED) tests = arch32zba; + "arch32zbb": if (P.ZBB_SUPPORTED) tests = arch32zbb; + "arch32zbc": if (P.ZBC_SUPPORTED) tests = arch32zbc; + "arch32zbs": if (P.ZBS_SUPPORTED) tests = arch32zbs; + "arch32zicboz": if (P.ZICBOZ_SUPPORTED) tests = arch32zicboz; + "arch32zcb": if (P.ZCB_SUPPORTED) tests = arch32zcb; + "arch32zfh": if (P.ZFH_SUPPORTED) tests = arch32zfh; + "arch32zfh_fma": if (P.ZFH_SUPPORTED) tests = arch32zfh_fma; + "arch32zfh_divsqrt": if (P.ZFH_SUPPORTED) tests = arch32zfh_divsqrt; + "arch32zfaf": if (P.ZFA_SUPPORTED) tests = arch32zfaf; + "arch32zfad": if (P.ZFA_SUPPORTED & P.D_SUPPORTED) tests = arch32zfad; + "arch32zbkb": if (P.ZBKB_SUPPORTED) tests = arch32zbkb; + "arch32zbkc": if (P.ZBKC_SUPPORTED) tests = arch32zbkc; + "arch32zbkx": if (P.ZBKX_SUPPORTED) tests = arch32zbkx; + "arch32zknd": if (P.ZKND_SUPPORTED) tests = arch32zknd; + "arch32zkne": if (P.ZKNE_SUPPORTED) tests = arch32zkne; + "arch32zknh": if (P.ZKNH_SUPPORTED) tests = arch32zknh; + endcase + end + if (tests.size() == 0 & ElfFile == "none") begin + if (tests.size() == 0) begin + $display("TEST %s not supported in this configuration", TEST); + end else if(ElfFile == "none") begin + $display("ElfFile %s not found", ElfFile); + end + $finish; + end +`ifdef MAKEVCD + $dumpfile("testbench.vcd"); + $dumpvars; +`endif + end // initial begin + + typedef enum logic [3:0]{STATE_TESTBENCH_RESET, + STATE_INIT_TEST, + STATE_RESET_MEMORIES, + STATE_RESET_MEMORIES2, + STATE_LOAD_MEMORIES, + STATE_RESET_TEST, + STATE_RUN_TEST, + STATE_COPY_RAM, + STATE_CHECK_TEST, + STATE_CHECK_TEST_WAIT, + STATE_VALIDATE, + STATE_INCR_TEST} statetype; + statetype CurrState, NextState; + logic TestBenchReset; + logic [2:0] ResetCountNew, ResetThresholdNew; + logic LoadMem; + logic ResetCntEn; + logic ResetCntRst; + logic CopyRAM; + + string signame, bootmemfilename, uartoutfilename, pathname; + integer begin_signature_addr, end_signature_addr, signature_size; + integer uartoutfile; + logic reset_extNew; + logic DCacheFlushStartNew; + + logic [P.XLEN-1:0] testadr, testadrNoBase; + string InstrFName, InstrDName, InstrEName, InstrMName, InstrWName; + logic [31:0] InstrW; + + + + logic [P.XLEN-1:0] PCW; + logic [31:0] NextInstrE, InstrM; + + string testName; + string memfilename, testDir, adrstr, elffilename; + + logic InitializingMemories; integer ResetCount, ResetThreshold; logic InReset; + integer memFile; + integer readResult; + + + + //////////////////////////////////////////////////////////////////////////////// + // load memories with program image + //////////////////////////////////////////////////////////////////////////////// + + integer ShadowIndex; + integer LogXLEN; + integer StartIndex; + integer EndIndex; + integer BaseIndex; + if (P.SDC_SUPPORTED) begin + always @(posedge clk) begin + if (LoadMem) begin + string romfilename, sdcfilename; + romfilename = {"../tests/custom/fpga-test-sdc/bin/fpga-test-sdc.memfile"}; + sdcfilename = {"../testbench/sdc/ramdisk2.hex"}; + //$readmemh(romfilename, dut.uncoregen.uncore.bootrom.bootrom.memory.ROM); + //$readmemh(sdcfilename, sdcard.sdcard.FLASHmem); + // shorten sdc timers for simulation + //dut.uncoregen.uncore.sdc.SDC.LimitTimers = 1; + end + end + end else if (P.IROM_SUPPORTED) begin + always @(posedge clk) begin + if (LoadMem) begin + $readmemh(memfilename, dut.core.ifu.irom.irom.rom.ROM); + end + end + end else if (P.BUS_SUPPORTED) begin : bus_supported + always @(posedge clk) begin + if (LoadMem) begin + if (TEST == "buildroot") begin + memFile = $fopen(bootmemfilename, "rb"); + readResult = $fread(dut.uncoregen.uncore.bootrom.bootrom.memory.ROM, memFile); + $fclose(memFile); + memFile = $fopen(memfilename, "rb"); + readResult = $fread(dut.uncoregen.uncore.ram.ram.memory.RAM, memFile); + $fclose(memFile); + end else + $readmemh(memfilename, dut.uncoregen.uncore.ram.ram.memory.RAM); + if (TEST == "embench") $display("Read memfile %s", memfilename); + end + if (CopyRAM) begin + LogXLEN = (1 + P.XLEN/32); // 2 for rv32 and 3 for rv64 + StartIndex = begin_signature_addr >> LogXLEN; + EndIndex = (end_signature_addr >> LogXLEN) + 8; + BaseIndex = P.UNCORE_RAM_BASE >> LogXLEN; + for(ShadowIndex = StartIndex; ShadowIndex <= EndIndex; ShadowIndex++) begin + testbench.DCacheFlushFSM.ShadowRAM[ShadowIndex] = dut.uncoregen.uncore.ram.ram.memory.RAM[ShadowIndex - BaseIndex]; + end + end + end + end + if (P.DTIM_SUPPORTED) begin + always @(posedge clk) begin + if (LoadMem) begin + $readmemh(memfilename, dut.core.lsu.dtim.dtim.ram.RAM); + $display("Read memfile %s", memfilename); + end + if (CopyRAM) begin + LogXLEN = (1 + P.XLEN/32); // 2 for rv32 and 3 for rv64 + StartIndex = begin_signature_addr >> LogXLEN; + EndIndex = (end_signature_addr >> LogXLEN) + 8; + BaseIndex = P.UNCORE_RAM_BASE >> LogXLEN; + for(ShadowIndex = StartIndex; ShadowIndex <= EndIndex; ShadowIndex++) begin + testbench.DCacheFlushFSM.ShadowRAM[ShadowIndex] = dut.core.lsu.dtim.dtim.ram.RAM[ShadowIndex - BaseIndex]; + end + end + end + end + + integer adrindex; + if (P.UNCORE_RAM_SUPPORTED) + always @(posedge clk) + if (ResetMem) // program memory is sometimes reset (e.g. for CoreMark, which needs zeroed memory) + for (adrindex=0; adrindex<(P.UNCORE_RAM_RANGE>>1+(P.XLEN/32)); adrindex = adrindex+1) + dut.uncoregen.uncore.ram.ram.memory.RAM[adrindex] = '0; // Imperas look here. initial @@ -110,8 +382,7 @@ module testbench; $error("Must specify test directory using plusarg testDir"); end - if (P.BUS_SUPPORTED) $readmemh(memfilename, dut.uncoregen.uncore.ram.ram.memory.RAM); - else $error("Imperas test bench requires BUS."); + #130; ProgramAddrMapFile = {testDir, "/ref/ref.elf.objdump.addr"}; ProgramLabelMapFile = {testDir, "/ref/ref.elf.objdump.lab"}; @@ -123,98 +394,224 @@ module testbench; end + // Model the testbench as an fsm. + // Do this in parts so it easier to verify + // part 1: build a version which echos the same behavior as the below code, but does not drive anything + // part 2: drive some of the controls + // part 3: drive all logic and remove old inital and always @ negedge clk block + + + assign ResetThresholdNew = 3'd5; + + initial begin + TestBenchReset = 1'b1; + # 100; + TestBenchReset = 1'b0; + end + + always_ff @(posedge clk) + if (TestBenchReset) CurrState <= STATE_TESTBENCH_RESET; + else CurrState <= NextState; + + // fsm next state logic + always_comb begin + // riscof tests have a different signature, tests[0] == "1" refers to RiscvArchTests + // and tests[0] == "2" refers to WallyRiscvArchTests + //pathname = tvpaths[tests[0].atoi()]; + + case(CurrState) + STATE_TESTBENCH_RESET: NextState = STATE_INIT_TEST; + STATE_INIT_TEST: NextState = STATE_RESET_MEMORIES; + STATE_RESET_MEMORIES: NextState = STATE_RESET_MEMORIES2; + STATE_RESET_MEMORIES2: NextState = STATE_LOAD_MEMORIES; // Give the reset enough time to ensure the bus is reset before loading the memories. + STATE_LOAD_MEMORIES: NextState = STATE_RESET_TEST; + STATE_RESET_TEST: if(ResetCountNew < ResetThresholdNew) NextState = STATE_RESET_TEST; + else NextState = STATE_RUN_TEST; + STATE_RUN_TEST: if(TestComplete) NextState = STATE_COPY_RAM; + else NextState = STATE_RUN_TEST; + STATE_COPY_RAM: NextState = STATE_CHECK_TEST; + STATE_CHECK_TEST: if (DCacheFlushDone) NextState = STATE_VALIDATE; + else NextState = STATE_CHECK_TEST_WAIT; + STATE_CHECK_TEST_WAIT: if(DCacheFlushDone) NextState = STATE_VALIDATE; + else NextState = STATE_CHECK_TEST_WAIT; + STATE_VALIDATE: NextState = STATE_INIT_TEST; + STATE_INCR_TEST: NextState = STATE_INIT_TEST; + default: NextState = STATE_TESTBENCH_RESET; + endcase + end // always_comb + // fsm output control logic + assign reset_extNew = CurrState == STATE_TESTBENCH_RESET | CurrState == STATE_INIT_TEST | + CurrState == STATE_RESET_MEMORIES | CurrState == STATE_RESET_MEMORIES2 | + CurrState == STATE_LOAD_MEMORIES | CurrState ==STATE_RESET_TEST; + // this initialization is very expensive, only do it for coremark. + assign ResetMem = (CurrState == STATE_RESET_MEMORIES | CurrState == STATE_RESET_MEMORIES2); + assign LoadMem = CurrState == STATE_LOAD_MEMORIES; + assign ResetCntRst = CurrState == STATE_INIT_TEST; + assign ResetCntEn = CurrState == STATE_RESET_TEST; + assign Validate = CurrState == STATE_VALIDATE; + assign SelectTest = CurrState == STATE_INIT_TEST; + assign CopyRAM = TestComplete & CurrState == STATE_RUN_TEST; + assign DCacheFlushStartNew = CurrState == STATE_COPY_RAM; + + // fsm reset counter + counter #(3) RstCounter(clk, ResetCntRst, ResetCntEn, ResetCountNew); + + `ifdef USE_IMPERAS_DV - rvviTrace #(.XLEN(P.XLEN), .FLEN(P.FLEN)) rvvi(); - wallyTracer #(P) wallyTracer(rvvi); + rvviTrace #(.XLEN(P.XLEN), .FLEN(P.FLEN)) rvvi(); + wallyTracer #(P) wallyTracer(rvvi); - trace2log idv_trace2log(rvvi); - trace2cov idv_trace2cov(rvvi); + trace2log idv_trace2log(rvvi); + // trace2cov idv_trace2cov(rvvi); - // enabling of comparison types - trace2api #(.CMP_PC (1), - .CMP_INS (1), - .CMP_GPR (1), - .CMP_FPR (1), - .CMP_VR (0), - .CMP_CSR (1) - ) idv_trace2api(rvvi); + // enabling of comparison types + trace2api #(.CMP_PC (1), + .CMP_INS (1), + .CMP_GPR (1), + .CMP_FPR (1), + .CMP_VR (0), + .CMP_CSR (1) + ) idv_trace2api(rvvi); - initial begin - - IDV_MAX_ERRORS = 3; + string filename; + initial begin + int iter; + #1; + IDV_MAX_ERRORS = 3; - // Initialize REF (do this before initializing the DUT) - if (!rvviVersionCheck(RVVI_API_VERSION)) begin - $display($sformatf("%m @ t=%0t: Expecting RVVI API version %0d.", $time, RVVI_API_VERSION)); - $fatal; - end - void'(rvviRefConfigSetString(IDV_CONFIG_MODEL_VENDOR, "riscv.ovpworld.org")); - void'(rvviRefConfigSetString(IDV_CONFIG_MODEL_NAME, "riscv")); - void'(rvviRefConfigSetString(IDV_CONFIG_MODEL_VARIANT, "RV64GC")); - void'(rvviRefConfigSetInt(IDV_CONFIG_MODEL_ADDRESS_BUS_WIDTH, 39)); - void'(rvviRefConfigSetInt(IDV_CONFIG_MAX_NET_LATENCY_RETIREMENTS, 6)); + // Initialize REF (do this before initializing the DUT) + if (!rvviVersionCheck(RVVI_API_VERSION)) begin + $display($sformatf("%m @ t=%0t: Expecting RVVI API version %0d.", $time, RVVI_API_VERSION)); + $fatal; + end + + void'(rvviRefConfigSetString(IDV_CONFIG_MODEL_VENDOR, "riscv.ovpworld.org")); + void'(rvviRefConfigSetString(IDV_CONFIG_MODEL_NAME, "riscv")); + void'(rvviRefConfigSetString(IDV_CONFIG_MODEL_VARIANT, "RV64GC")); + void'(rvviRefConfigSetInt(IDV_CONFIG_MODEL_ADDRESS_BUS_WIDTH, 56)); + void'(rvviRefConfigSetInt(IDV_CONFIG_MAX_NET_LATENCY_RETIREMENTS, 6)); - if (!rvviRefInit(elffilename)) begin - $display($sformatf("%m @ t=%0t: rvviRefInit failed", $time)); - $fatal; - end - - // Volatile CSRs - void'(rvviRefCsrSetVolatile(0, 32'hC00)); // CYCLE - void'(rvviRefCsrSetVolatile(0, 32'hB00)); // MCYCLE - void'(rvviRefCsrSetVolatile(0, 32'hC02)); // INSTRET - void'(rvviRefCsrSetVolatile(0, 32'hB02)); // MINSTRET - void'(rvviRefCsrSetVolatile(0, 32'hC01)); // TIME - - // cannot predict this register due to latency between - // pending and taken - void'(rvviRefCsrSetVolatile(0, 32'h344)); // MIP - void'(rvviRefCsrSetVolatile(0, 32'h144)); // SIP - - // Privileges for PMA are set in the imperas.ic - // volatile (IO) regions are defined here - // only real ROM/RAM areas are BOOTROM and UNCORE_RAM - if (P.CLINT_SUPPORTED) begin - void'(rvviRefMemorySetVolatile(P.CLINT_BASE, (P.CLINT_BASE + P.CLINT_RANGE))); - end - if (P.GPIO_SUPPORTED) begin - void'(rvviRefMemorySetVolatile(P.GPIO_BASE, (P.GPIO_BASE + P.GPIO_RANGE))); - end - if (P.UART_SUPPORTED) begin - void'(rvviRefMemorySetVolatile(P.UART_BASE, (P.UART_BASE + P.UART_RANGE))); - end - if (P.PLIC_SUPPORTED) begin - void'(rvviRefMemorySetVolatile(P.PLIC_BASE, (P.PLIC_BASE + P.PLIC_RANGE))); - end - if (P.SDC_SUPPORTED) begin - void'(rvviRefMemorySetVolatile(P.SDC_BASE, (P.SDC_BASE + P.SDC_RANGE))); - end - if (P.SPI_SUPPORTED) begin - void'(rvviRefMemorySetVolatile(P.SPI_BASE, (P.SPI_BASE + P.SPI_RANGE))); - end - - if(P.XLEN==32) begin - void'(rvviRefCsrSetVolatile(0, 32'hC80)); // CYCLEH - void'(rvviRefCsrSetVolatile(0, 32'hB80)); // MCYCLEH - void'(rvviRefCsrSetVolatile(0, 32'hC82)); // INSTRETH - void'(rvviRefCsrSetVolatile(0, 32'hB82)); // MINSTRETH - end - - void'(rvviRefCsrSetVolatile(0, 32'h104)); // SIE - Temporary!!!! - + if(elffilename == "buildroot") filename = ""; + else filename = elffilename; + + if (!rvviRefInit(filename)) begin + $display($sformatf("%m @ t=%0t: rvviRefInit failed", $time)); + $fatal; end - always @(dut.core.priv.priv.csr.csri.MIP_REGW[7]) void'(rvvi.net_push("MTimerInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[7])); - always @(dut.core.priv.priv.csr.csri.MIP_REGW[11]) void'(rvvi.net_push("MExternalInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[11])); - always @(dut.core.priv.priv.csr.csri.MIP_REGW[9]) void'(rvvi.net_push("SExternalInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[9])); - always @(dut.core.priv.priv.csr.csri.MIP_REGW[3]) void'(rvvi.net_push("MSWInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[3])); - always @(dut.core.priv.priv.csr.csri.MIP_REGW[1]) void'(rvvi.net_push("SSWInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[1])); - always @(dut.core.priv.priv.csr.csri.MIP_REGW[5]) void'(rvvi.net_push("STimerInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[5])); + // Volatile CSRs + void'(rvviRefCsrSetVolatile(0, 32'hC00)); // CYCLE + void'(rvviRefCsrSetVolatile(0, 32'hB00)); // MCYCLE + void'(rvviRefCsrSetVolatile(0, 32'hC02)); // INSTRET + void'(rvviRefCsrSetVolatile(0, 32'hB02)); // MINSTRET + void'(rvviRefCsrSetVolatile(0, 32'hC01)); // TIME + + // User HPMCOUNTER3 - HPMCOUNTER31 + for (iter='hC03; iter<='hC1F; iter++) begin + void'(rvviRefCsrSetVolatile(0, iter)); // HPMCOUNTERx + end + + // Machine MHPMCOUNTER3 - MHPMCOUNTER31 + for (iter='hB03; iter<='hB1F; iter++) begin + void'(rvviRefCsrSetVolatile(0, iter)); // MHPMCOUNTERx + end + + // cannot predict this register due to latency between + // pending and taken + void'(rvviRefCsrSetVolatile(0, 32'h344)); // MIP + void'(rvviRefCsrSetVolatile(0, 32'h144)); // SIP - final begin - void'(rvviRefShutdown()); + // Privileges for PMA are set in the imperas.ic + // volatile (IO) regions are defined here + // only real ROM/RAM areas are BOOTROM and UNCORE_RAM + if (P.CLINT_SUPPORTED) begin + void'(rvviRefMemorySetVolatile(P.CLINT_BASE, (P.CLINT_BASE + P.CLINT_RANGE))); end + if (P.GPIO_SUPPORTED) begin + void'(rvviRefMemorySetVolatile(P.GPIO_BASE, (P.GPIO_BASE + P.GPIO_RANGE))); + end + if (P.UART_SUPPORTED) begin + void'(rvviRefMemorySetVolatile(P.UART_BASE, (P.UART_BASE + P.UART_RANGE))); + end + if (P.PLIC_SUPPORTED) begin + void'(rvviRefMemorySetVolatile(P.PLIC_BASE, (P.PLIC_BASE + P.PLIC_RANGE))); + end + if (P.SDC_SUPPORTED) begin + void'(rvviRefMemorySetVolatile(P.SDC_BASE, (P.SDC_BASE + P.SDC_RANGE))); + end + if (P.SPI_SUPPORTED) begin + void'(rvviRefMemorySetVolatile(P.SPI_BASE, (P.SPI_BASE + P.SPI_RANGE))); + end + + if(P.XLEN==32) begin + void'(rvviRefCsrSetVolatile(0, 32'hC80)); // CYCLEH + void'(rvviRefCsrSetVolatile(0, 32'hB80)); // MCYCLEH + void'(rvviRefCsrSetVolatile(0, 32'hC82)); // INSTRETH + void'(rvviRefCsrSetVolatile(0, 32'hB82)); // MINSTRETH + end + + void'(rvviRefCsrSetVolatile(0, 32'h104)); // SIE - Temporary!!!! + + // Load memory + // *** RT: This section can probably be moved into the same chunk of code which + // loads the memories. However I'm not sure that ImperasDV supports reloading + // the memories without relaunching the simulator. + if(elffilename == "buildroot") begin + longint x64; + int x32[2]; + longint index; + string memfilenameImperasDV, bootmemfilenameImperasDV; + + memfilenameImperasDV = {RISCV_DIR, "/linux-testvectors/ram.bin"}; + bootmemfilenameImperasDV = {RISCV_DIR, "/linux-testvectors/bootmem.bin"}; + + $display("RVVI Loading bootmem.bin"); + memFile = $fopen(bootmemfilenameImperasDV, "rb"); + index = 'h1000 - 8; + while(!$feof(memFile)) begin + index+=8; + readResult = $fread(x64, memFile); + if (x64 == 0) continue; + x32[0] = x64 & 'hffffffff; + x32[1] = x64 >> 32; + rvviRefMemoryWrite(0, index+0, x32[0], 4); + rvviRefMemoryWrite(0, index+4, x32[1], 4); + //$display("boot %08X x32[0]=%08X x32[1]=%08X", index, x32[0], x32[1]); + end + $fclose(memFile); + + $display("RVVI Loading ram.bin"); + memFile = $fopen(memfilenameImperasDV, "rb"); + index = 'h80000000 - 8; + while(!$feof(memFile)) begin + index+=8; + readResult = $fread(x64, memFile); + if (x64 == 0) continue; + x32[0] = x64 & 'hffffffff; + x32[1] = x64 >> 32; + rvviRefMemoryWrite(0, index+0, x32[0], 4); + rvviRefMemoryWrite(0, index+4, x32[1], 4); + //$display("ram %08X x32[0]=%08X x32[1]=%08X", index, x32[0], x32[1]); + end + $fclose(memFile); + + $display("RVVI Loading Complete"); + + void'(rvviRefPcSet(0, P.RESET_VECTOR)); // set BOOTROM address + end + end + + always @(dut.core.priv.priv.csr.csri.MIP_REGW[7]) void'(rvvi.net_push("MTimerInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[7])); + always @(dut.core.priv.priv.csr.csri.MIP_REGW[11]) void'(rvvi.net_push("MExternalInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[11])); + always @(dut.core.priv.priv.csr.csri.MIP_REGW[9]) void'(rvvi.net_push("SExternalInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[9])); + always @(dut.core.priv.priv.csr.csri.MIP_REGW[3]) void'(rvvi.net_push("MSWInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[3])); + always @(dut.core.priv.priv.csr.csri.MIP_REGW[1]) void'(rvvi.net_push("SSWInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[1])); + always @(dut.core.priv.priv.csr.csri.MIP_REGW[5]) void'(rvvi.net_push("STimerInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[5])); + + final begin + void'(rvviRefShutdown()); + end `endif From e6902eb4d29f4e4eab28c783ce109a695e0ca232 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Fri, 17 May 2024 16:08:14 -0500 Subject: [PATCH 10/51] Ok. How does it still work? testbench-imperas.sv the same as testbench.sv now. --- testbench/testbench-imperas.sv | 619 ++++++++++++++++++++++----------- 1 file changed, 421 insertions(+), 198 deletions(-) diff --git a/testbench/testbench-imperas.sv b/testbench/testbench-imperas.sv index 478474749..c8ff90893 100644 --- a/testbench/testbench-imperas.sv +++ b/testbench/testbench-imperas.sv @@ -240,6 +240,12 @@ module testbench; `endif end // initial begin + // Model the testbench as an fsm. + // Do this in parts so it easier to verify + // part 1: build a version which echos the same behavior as the below code, but does not drive anything + // part 2: drive some of the controls + // part 3: drive all logic and remove old inital and always @ negedge clk block + typedef enum logic [3:0]{STATE_TESTBENCH_RESET, STATE_INIT_TEST, STATE_RESET_MEMORIES, @@ -260,33 +266,204 @@ module testbench; logic ResetCntRst; logic CopyRAM; - string signame, bootmemfilename, uartoutfilename, pathname; + string signame, elffilename, memfilename, bootmemfilename, uartoutfilename, pathname; integer begin_signature_addr, end_signature_addr, signature_size; integer uartoutfile; + logic reset_extNew; logic DCacheFlushStartNew; + assign ResetThresholdNew = 3'd5; + + initial begin + TestBenchReset = 1'b1; + # 100; + TestBenchReset = 1'b0; + end + + always_ff @(posedge clk) + if (TestBenchReset) CurrState <= STATE_TESTBENCH_RESET; + else CurrState <= NextState; + + // fsm next state logic + always_comb begin + // riscof tests have a different signature, tests[0] == "1" refers to RiscvArchTests + // and tests[0] == "2" refers to WallyRiscvArchTests + //pathname = tvpaths[tests[0].atoi()]; + + case(CurrState) + STATE_TESTBENCH_RESET: NextState = STATE_INIT_TEST; + STATE_INIT_TEST: NextState = STATE_RESET_MEMORIES; + STATE_RESET_MEMORIES: NextState = STATE_RESET_MEMORIES2; + STATE_RESET_MEMORIES2: NextState = STATE_LOAD_MEMORIES; // Give the reset enough time to ensure the bus is reset before loading the memories. + STATE_LOAD_MEMORIES: NextState = STATE_RESET_TEST; + STATE_RESET_TEST: if(ResetCountNew < ResetThresholdNew) NextState = STATE_RESET_TEST; + else NextState = STATE_RUN_TEST; + STATE_RUN_TEST: if(TestComplete) NextState = STATE_COPY_RAM; + else NextState = STATE_RUN_TEST; + STATE_COPY_RAM: NextState = STATE_CHECK_TEST; + STATE_CHECK_TEST: if (DCacheFlushDone) NextState = STATE_VALIDATE; + else NextState = STATE_CHECK_TEST_WAIT; + STATE_CHECK_TEST_WAIT: if(DCacheFlushDone) NextState = STATE_VALIDATE; + else NextState = STATE_CHECK_TEST_WAIT; + STATE_VALIDATE: NextState = STATE_INIT_TEST; + STATE_INCR_TEST: NextState = STATE_INIT_TEST; + default: NextState = STATE_TESTBENCH_RESET; + endcase + end // always_comb + // fsm output control logic + assign reset_ext = CurrState == STATE_TESTBENCH_RESET | CurrState == STATE_INIT_TEST | + CurrState == STATE_RESET_MEMORIES | CurrState == STATE_RESET_MEMORIES2 | + CurrState == STATE_LOAD_MEMORIES | CurrState ==STATE_RESET_TEST; + // this initialization is very expensive, only do it for coremark. + assign ResetMem = (CurrState == STATE_RESET_MEMORIES | CurrState == STATE_RESET_MEMORIES2); + assign LoadMem = CurrState == STATE_LOAD_MEMORIES; + assign ResetCntRst = CurrState == STATE_INIT_TEST; + assign ResetCntEn = CurrState == STATE_RESET_TEST; + assign Validate = CurrState == STATE_VALIDATE; + assign SelectTest = CurrState == STATE_INIT_TEST; + assign CopyRAM = TestComplete & CurrState == STATE_RUN_TEST; + assign DCacheFlushStartNew = CurrState == STATE_COPY_RAM; + + // fsm reset counter + counter #(3) RstCounter(clk, ResetCntRst, ResetCntEn, ResetCountNew); - logic [P.XLEN-1:0] testadr, testadrNoBase; - string InstrFName, InstrDName, InstrEName, InstrMName, InstrWName; - logic [31:0] InstrW; - - - - logic [P.XLEN-1:0] PCW; - logic [31:0] NextInstrE, InstrM; - - string testName; - string memfilename, testDir, adrstr, elffilename; - - - logic InitializingMemories; - integer ResetCount, ResetThreshold; - logic InReset; - integer memFile; - integer readResult; + //////////////////////////////////////////////////////////////////////////////// + // Find the test vector files and populate the PC to function label converter + //////////////////////////////////////////////////////////////////////////////// + logic [P.XLEN-1:0] testadr; + //VCS ignores the dynamic types while processing the implicit sensitivity lists of always @*, always_comb, and always_latch + //procedural blocks. VCS supports the dynamic types in the implicit sensitivity list of always @* block as specified in the Section 9.2 of the IEEE Standard SystemVerilog Specification 1800-2012. + //To support memory load and dump task verbosity: flag : -diag sys_task_mem + always @(*) begin + begin_signature_addr = ProgramAddrLabelArray["begin_signature"]; + end_signature_addr = ProgramAddrLabelArray["sig_end_canary"]; + signature_size = end_signature_addr - begin_signature_addr; + end + logic EcallFaultM; + if (P.ZICSR_SUPPORTED) + assign EcallFaultM = dut.core.priv.priv.EcallFaultM; + else + assign EcallFaultM = 0; + always @(posedge clk) begin + //////////////////////////////////////////////////////////////////////////////// + // Verify the test ran correctly by checking the memory against a known signature. + //////////////////////////////////////////////////////////////////////////////// + if(TestBenchReset) test = 1; + if (P.ZICSR_SUPPORTED & TEST == "coremark") + if (EcallFaultM) begin + $display("Benchmark: coremark is done."); + $stop; + end + if (P.ZICSR_SUPPORTED & dut.core.ifu.PCM == 0 & dut.core.ifu.InstrM == 0 & dut.core.ieu.InstrValidM) begin + $display("Program fetched illegal instruction 0x00000000 from address 0x00000000. Might be fault with no fault handler."); + //$stop; // presently wally32/64priv tests trigger this for reasons not yet understood. + end + // modifications 4/3/24 kunlin & harris to speed up Verilator + // For some reason, Verilator runs ~100x slower when these SelectTest and Validate codes are in the posedge clk block + //end // added + //always @(posedge SelectTest) // added + if(SelectTest) begin + if (riscofTest) begin + memfilename = {pathname, tests[test], "/ref/ref.elf.memfile"}; + elffilename = {pathname, tests[test], "ref/ref.elf"}; + ProgramAddrMapFile = {pathname, tests[test], "/ref/ref.elf.objdump.addr"}; + ProgramLabelMapFile = {pathname, tests[test], "/ref/ref.elf.objdump.lab"}; + end else if(TEST == "buildroot") begin + memfilename = {RISCV_DIR, "/linux-testvectors/ram.bin"}; + elffilename = "buildroot"; + bootmemfilename = {RISCV_DIR, "/linux-testvectors/bootmem.bin"}; + uartoutfilename = {"logs/", TEST, "_uart.out"}; + uartoutfile = $fopen(uartoutfilename, "w"); // delete UART output file + ProgramAddrMapFile = {RISCV_DIR, "/buildroot/output/images/disassembly/vmlinux.objdump.addr"}; + ProgramLabelMapFile = {RISCV_DIR, "/buildroot/output/images/disassembly/vmlinux.objdump.lab"}; + end else if(ElfFile != "none") begin + elffilename = ElfFile; + memfilename = {ElfFile, ".memfile"}; + ProgramAddrMapFile = {ElfFile, ".objdump.addr"}; + ProgramLabelMapFile = {ElfFile, ".objdump.lab"}; + end else begin + elffilename = {pathname, tests[test], ".elf"}; + memfilename = {pathname, tests[test], ".elf.memfile"}; + ProgramAddrMapFile = {pathname, tests[test], ".elf.objdump.addr"}; + ProgramLabelMapFile = {pathname, tests[test], ".elf.objdump.lab"}; + end + // declare memory labels that interest us, the updateProgramAddrLabelArray task will find + // the addr of each label and fill the array. To expand, add more elements to this array + // and initialize them to zero (also initilaize them to zero at the start of the next test) + updateProgramAddrLabelArray(ProgramAddrMapFile, ProgramLabelMapFile, ProgramAddrLabelArray); + end +`ifdef VERILATOR // this macro is defined when verilator is used + // Simulator Verilator has an issue that the validate logic below slows runtime 110x if it is + // in the posedge clk block rather than a separate posedge Validate block. + // Until it is fixed, provide a silly posedge Validate block to keep Verilator happy. + // https://github.com/verilator/verilator/issues/4967 + end // restored + always @(posedge Validate) // added +`endif + if(Validate) begin + if (TEST == "buildroot") + $fclose(uartoutfile); + if (TEST == "embench") begin + // Writes contents of begin_signature to .sim.output file + // this contains instret and cycles for start and end of test run, used by embench + // python speed script to calculate embench speed score. + // also, begin_signature contains the results of the self checking mechanism, + // which will be read by the python script for error checking + $display("Embench Benchmark: %s is done.", tests[test]); + if (riscofTest) outputfile = {pathname, tests[test], "/ref/ref.sim.output"}; + else outputfile = {pathname, tests[test], ".sim.output"}; + outputFilePointer = $fopen(outputfile, "w"); + i = 0; + testadr = ($unsigned(begin_signature_addr))/(P.XLEN/8); + while ($unsigned(i) < $unsigned(5'd5)) begin + $fdisplayh(outputFilePointer, DCacheFlushFSM.ShadowRAM[testadr+i]); + i = i + 1; + end + $fclose(outputFilePointer); + $display("Embench Benchmark: created output file: %s", outputfile); + end else if (TEST == "coverage64gc") begin + $display("Coverage tests don't get checked"); + end else if (ElfFile != "none") begin + $display("Single Elf file tests are not signatured verified."); +`ifdef VERILATOR // this macro is defined when verilator is used + $finish; // Simulator Verilator needs $finish to terminate simulation. +`elsif SIM_VCS // this macro is defined when vcs is used + $finish; // Simulator VCS needs $finish to terminate simulation. +`else + $stop; // if this is changed to $finish for Questa, wally-batch.do does not go to the next step to run coverage, and wally.do terminates without allowing GUI debug +`endif + end else begin + // for tests with no self checking mechanism, read .signature.output file and compare to check for errors + // clear signature to prevent contamination from previous tests + if (!begin_signature_addr) + $display("begin_signature addr not found in %s", ProgramLabelMapFile); + else if (TEST != "embench") begin // *** quick hack for embench. need a better long term solution + CheckSignature(pathname, tests[test], riscofTest, begin_signature_addr, errors); + if(errors > 0) totalerrors = totalerrors + 1; + end + end + test = test + 1; // *** this probably needs to be moved. + if (test == tests.size()) begin + if (totalerrors == 0) $display("SUCCESS! All tests ran without failures."); + else $display("FAIL: %d test programs had errors", totalerrors); +`ifdef VERILATOR // this macro is defined when verilator is used + $finish; // Simulator Verilator needs $finish to terminate simulation. +`elsif SIM_VCS // this macro is defined when vcs is used + $finish; // Simulator VCS needs $finish to terminate simulation. +`else + $stop; // if this is changed to $finish for Questa, wally-batch.do does not go to the next step to run coverage, and wally.do terminates without allowing GUI debug +`endif + end + end +`ifndef VERILATOR + // Remove this when issue 4967 is resolved and the posedge Validate logic above is removed + end +`endif + + //////////////////////////////////////////////////////////////////////////////// // load memories with program image @@ -297,6 +474,8 @@ module testbench; integer StartIndex; integer EndIndex; integer BaseIndex; + integer memFile; + integer readResult; if (P.SDC_SUPPORTED) begin always @(posedge clk) begin if (LoadMem) begin @@ -365,6 +544,155 @@ module testbench; for (adrindex=0; adrindex<(P.UNCORE_RAM_RANGE>>1+(P.XLEN/32)); adrindex = adrindex+1) dut.uncoregen.uncore.ram.ram.memory.RAM[adrindex] = '0; + //////////////////////////////////////////////////////////////////////////////// + // Actual hardware + //////////////////////////////////////////////////////////////////////////////// + + // instantiate device to be tested + assign GPIOIN = '0; + assign UARTSin = 1'b1; + assign SPIIn = 1'b0; + + if(P.EXT_MEM_SUPPORTED) begin + ram_ahb #(.P(P), .BASE(P.EXT_MEM_BASE), .RANGE(P.EXT_MEM_RANGE)) + ram (.HCLK, .HRESETn, .HADDR, .HWRITE, .HTRANS, .HWDATA, .HSELRam(HSELEXT), + .HREADRam(HRDATAEXT), .HREADYRam(HREADYEXT), .HRESPRam(HRESPEXT), .HREADY, .HWSTRB); + end else begin + assign HREADYEXT = 1'b1; + assign {HRESPEXT, HRDATAEXT} = '0; + end + + if(P.SDC_SUPPORTED) begin : sdcard + // *** fix later +/* -----\/----- EXCLUDED -----\/----- + sdModel sdcard + (.sdClk(SDCCLK), + .cmd(SDCCmd), + .dat(SDCDat)); + + assign SDCCmd = SDCCmdOE ? SDCCmdOut : 1'bz; + assign SDCCmdIn = SDCCmd; + assign SDCDat = sd_dat_reg_t ? sd_dat_reg_o : sd_dat_i; + assign SDCDatIn = SDCDat; + -----/\----- EXCLUDED -----/\----- */ + assign SDCIntr = 1'b0; + end else begin + assign SDCIntr = 1'b0; + end + + 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, .SPIIn, .SPIOut, .SPICS); + + // generate clock to sequence tests + always begin + clk = 1'b1; # 5; clk = 1'b0; # 5; + end + + /* + // Print key info each cycle for debugging + always @(posedge clk) begin + #2; + $display("PCM: %x InstrM: %x (%5s) WriteDataM: %x IEUResultM: %x", + dut.core.PCM, dut.core.InstrM, InstrMName, dut.core.WriteDataM, dut.core.ieu.dp.IEUResultM); + end + */ + + //////////////////////////////////////////////////////////////////////////////// + // 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, 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, + 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, InstrM, dut.core.lsu.IEUAdrM, InstrMName); + riscvassertions #(P) riscvassertions(); // check assertions for a legal configuration + loggers #(P, PrintHPMCounters, I_CACHE_ADDR_LOGGER, D_CACHE_ADDR_LOGGER, BPRED_LOGGER) + loggers (clk, reset, DCacheFlushStart, DCacheFlushDone, memfilename, TEST); + + // track the current function or global label + if (DEBUG > 0 | ((PrintHPMCounters | BPRED_LOGGER) & P.ZICNTR_SUPPORTED)) begin : FunctionName + FunctionName #(P) FunctionName(.reset(reset_ext | TestBenchReset), + .clk(clk), .ProgramAddrMapFile(ProgramAddrMapFile), .ProgramLabelMapFile(ProgramLabelMapFile)); + end + + // Append UART output to file for tests + if (P.UART_SUPPORTED) begin: uart_logger + always @(posedge clk) begin + if (TEST == "buildroot") begin + if (~dut.uncoregen.uncore.uartgen.uart.MEMWb & dut.uncoregen.uncore.uartgen.uart.uartPC.A == 3'b000 & ~dut.uncoregen.uncore.uartgen.uart.uartPC.DLAB) begin + $fwrite(uartoutfile, "%c", dut.uncoregen.uncore.uartgen.uart.uartPC.Din); // append characters one at a time so we see a consistent log appearing during the run + $fflush(uartoutfile); + end + end + end + end + + // 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 + // or sd gp, -56(t0) + // or on a jump to self infinite loop (6f) for RISC-V Arch tests + logic ecf; // remove this once we don't rely on old Imperas tests with Ecalls + if (P.ZICSR_SUPPORTED) assign ecf = dut.core.priv.priv.EcallFaultM; + else assign ecf = 0; + always_comb begin + TestComplete = ecf & + (dut.core.ieu.dp.regf.rf[3] == 1 | + (dut.core.ieu.dp.regf.we3 & + dut.core.ieu.dp.regf.a3 == 3 & + dut.core.ieu.dp.regf.wd3 == 1)) | + ((InstrM == 32'h6f | InstrM == 32'hfc32a423 | InstrM == 32'hfc32a823) & dut.core.ieu.c.InstrValidM ) | + ((dut.core.lsu.IEUAdrM == ProgramAddrLabelArray["tohost"] & dut.core.lsu.IEUAdrM != 0) & InstrMName == "SW" ); + end + + DCacheFlushFSM #(P) DCacheFlushFSM(.clk, .start(DCacheFlushStart), .done(DCacheFlushDone)); + + if(P.ZICSR_SUPPORTED) begin + logic [P.XLEN-1:0] Minstret; + assign Minstret = testbench.dut.core.priv.priv.csr.counters.counters.HPMCOUNTER_REGW[2]; + always @(negedge clk) begin + if (INSTR_LIMIT > 0) begin + if((Minstret != 0) && (Minstret % 'd100000 == 0)) $display("Reached %d instructions", Minstret); + if((Minstret == INSTR_LIMIT) & (INSTR_LIMIT!=0)) begin $finish; end + end + end +end + + + + + + + + + logic [P.XLEN-1:0] testadrNoBase; + + + string testName; + string testDir, adrstr; + + + logic InitializingMemories; + integer ResetCount, ResetThreshold; + logic InReset; + // Imperas look here. initial begin @@ -394,67 +722,8 @@ module testbench; end - // Model the testbench as an fsm. - // Do this in parts so it easier to verify - // part 1: build a version which echos the same behavior as the below code, but does not drive anything - // part 2: drive some of the controls - // part 3: drive all logic and remove old inital and always @ negedge clk block - assign ResetThresholdNew = 3'd5; - - initial begin - TestBenchReset = 1'b1; - # 100; - TestBenchReset = 1'b0; - end - - always_ff @(posedge clk) - if (TestBenchReset) CurrState <= STATE_TESTBENCH_RESET; - else CurrState <= NextState; - - // fsm next state logic - always_comb begin - // riscof tests have a different signature, tests[0] == "1" refers to RiscvArchTests - // and tests[0] == "2" refers to WallyRiscvArchTests - //pathname = tvpaths[tests[0].atoi()]; - - case(CurrState) - STATE_TESTBENCH_RESET: NextState = STATE_INIT_TEST; - STATE_INIT_TEST: NextState = STATE_RESET_MEMORIES; - STATE_RESET_MEMORIES: NextState = STATE_RESET_MEMORIES2; - STATE_RESET_MEMORIES2: NextState = STATE_LOAD_MEMORIES; // Give the reset enough time to ensure the bus is reset before loading the memories. - STATE_LOAD_MEMORIES: NextState = STATE_RESET_TEST; - STATE_RESET_TEST: if(ResetCountNew < ResetThresholdNew) NextState = STATE_RESET_TEST; - else NextState = STATE_RUN_TEST; - STATE_RUN_TEST: if(TestComplete) NextState = STATE_COPY_RAM; - else NextState = STATE_RUN_TEST; - STATE_COPY_RAM: NextState = STATE_CHECK_TEST; - STATE_CHECK_TEST: if (DCacheFlushDone) NextState = STATE_VALIDATE; - else NextState = STATE_CHECK_TEST_WAIT; - STATE_CHECK_TEST_WAIT: if(DCacheFlushDone) NextState = STATE_VALIDATE; - else NextState = STATE_CHECK_TEST_WAIT; - STATE_VALIDATE: NextState = STATE_INIT_TEST; - STATE_INCR_TEST: NextState = STATE_INIT_TEST; - default: NextState = STATE_TESTBENCH_RESET; - endcase - end // always_comb - // fsm output control logic - assign reset_extNew = CurrState == STATE_TESTBENCH_RESET | CurrState == STATE_INIT_TEST | - CurrState == STATE_RESET_MEMORIES | CurrState == STATE_RESET_MEMORIES2 | - CurrState == STATE_LOAD_MEMORIES | CurrState ==STATE_RESET_TEST; - // this initialization is very expensive, only do it for coremark. - assign ResetMem = (CurrState == STATE_RESET_MEMORIES | CurrState == STATE_RESET_MEMORIES2); - assign LoadMem = CurrState == STATE_LOAD_MEMORIES; - assign ResetCntRst = CurrState == STATE_INIT_TEST; - assign ResetCntEn = CurrState == STATE_RESET_TEST; - assign Validate = CurrState == STATE_VALIDATE; - assign SelectTest = CurrState == STATE_INIT_TEST; - assign CopyRAM = TestComplete & CurrState == STATE_RUN_TEST; - assign DCacheFlushStartNew = CurrState == STATE_COPY_RAM; - - // fsm reset counter - counter #(3) RstCounter(clk, ResetCntRst, ResetCntEn, ResetCountNew); `ifdef USE_IMPERAS_DV @@ -615,134 +884,88 @@ 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, InstrM, InstrW); + task automatic CheckSignature; + // This task must be declared inside this module as it needs access to parameter P. There is + // no way to pass P to the task unless we convert it to a module. + + input string pathname; + input string TestName; + input logic riscofTest; + input integer begin_signature_addr; + output integer errors; + int fd, code; + string line; + int siglines, sigentries; - // check assertions for a legal configuration - riscvassertions #(P) riscvassertions(); + localparam SIGNATURESIZE = 5000000; + integer i; + logic [31:0] sig32[0:SIGNATURESIZE]; + logic [31:0] parsed; + logic [P.XLEN-1:0] signature[0:SIGNATURESIZE]; + string signame; + logic [P.XLEN-1:0] testadr, testadrNoBase; + //$display("Invoking CheckSignature %s %s %0t", pathname, TestName, $time); + + // read .signature.output file and compare to check for errors + if (riscofTest) signame = {pathname, TestName, "/ref/Reference-sail_c_simulator.signature"}; + else signame = {pathname, TestName, ".signature.output"}; - // instantiate device to be tested - assign GPIOIN = 0; - assign UARTSin = 1; - - if(P.EXT_MEM_SUPPORTED) begin - ram_ahb #(.BASE(P.EXT_MEM_BASE), .RANGE(P.EXT_MEM_RANGE)) - ram (.HCLK, .HRESETn, .HADDR, .HWRITE, .HTRANS, .HWDATA, .HSELRam(HSELEXT), - .HREADRam(HRDATAEXT), .HREADYRam(HREADYEXT), .HRESPRam(HRESPEXT), .HREADY, - .HWSTRB); - end else begin - assign HREADYEXT = 1; - assign HRESPEXT = 0; - assign HRDATAEXT = 0; - end - - if(P.SDC_SUPPORTED) begin : sdcard - // *** fix later -/* -----\/----- EXCLUDED -----\/----- - sdModel sdcard - (.sdClk(SDCCLK), - .cmd(SDCCmd), - .dat(SDCDat)); - - assign SDCCmd = SDCCmdOE ? SDCCmdOut : 1'bz; - assign SDCCmdIn = SDCCmd; - assign SDCDatIn = SDCDat; - -----/\----- EXCLUDED -----/\----- */ - assign SDCIntr = 0; - end else begin - assign SDCIntr = 0; - end - - 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); - - // 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, - InstrM, InstrW, - InstrFName, InstrDName, InstrEName, InstrMName, InstrWName); - - // initialize tests - - // generate clock to sequence tests - always - begin - clk = 1; # 5; clk = 0; # 5; - // if ($time % 100000 == 0) $display("Time is %0t", $time); - end - - // check results - assign reset_ext = InReset; - - always @(negedge clk) - begin - InitializingMemories = 0; - if(InReset == 1) begin - // once the test inidicates it's done we need to immediately hold reset for a number of cycles. - if(ResetCount < ResetThreshold) ResetCount = ResetCount + 1; - else begin // hit reset threshold so we remove reset. - InReset = 0; - ResetCount = 0; - end - end - end // always @ (negedge clk) - - - // track the current function or global label - if (DEBUG == 1) begin : FunctionName - FunctionName #(P) FunctionName(.reset(reset), - .clk(clk), - .ProgramAddrMapFile(ProgramAddrMapFile), - .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 - // or sd gp, -56(t0) - // or on a jump to self infinite loop (6f) for RISC-V Arch tests - logic ecf; // remove this once we don't rely on old Imperas tests with Ecalls - if (P.ZICSR_SUPPORTED) assign ecf = dut.core.priv.priv.EcallFaultM; - else assign ecf = 0; - assign DCacheFlushStart = ecf & - (dut.core.ieu.dp.regf.rf[3] == 1 | - (dut.core.ieu.dp.regf.we3 & - dut.core.ieu.dp.regf.a3 == 3 & - dut.core.ieu.dp.regf.wd3 == 1)) | - ((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), - .start(DCacheFlushStart), - .done(DCacheFlushDone)); - - // initialize the branch predictor - if (P.BPRED_SUPPORTED == 1) - begin - genvar adrindex; - - // Initializing all zeroes into the branch predictor memory. - for(adrindex = 0; adrindex < 1024; adrindex++) begin - initial begin - force dut.core.ifu.bpred.bpred.Predictor.DirPredictor.PHT.mem[adrindex] = 0; - force dut.core.ifu.bpred.bpred.TargetPredictor.memory.mem[adrindex] = 0; - #1; - release dut.core.ifu.bpred.bpred.Predictor.DirPredictor.PHT.mem[adrindex]; - release dut.core.ifu.bpred.bpred.TargetPredictor.memory.mem[adrindex]; + // read signature file from memory and count lines. Can't use readmemh because we need the line count + // $readmemh(signame, sig32); + fd = $fopen(signame, "r"); + siglines = 0; + if (fd == 0) $display("Unable to read %s", signame); + else begin + while (!$feof(fd)) begin + code = $fgets(line, fd); + if (code != 0) begin + int errno; + string errstr; + errno = $ferror(fd, errstr); + if (errno != 0) $display("Error %d (code %d) reading line %d of %s: %s", errno, code, siglines, signame, errstr); + if (line.len() > 1) begin // skip blank lines + if ($sscanf(line, "%x", parsed) != 0) begin + sig32[siglines] = parsed; + siglines = siglines + 1; // increment if line is not blank + end + end end end + $fclose(fd); end - watchdog #(P.XLEN, 1000000) watchdog(.clk, .reset); // check if PCW is stuck + // Check valid number of lines were read + if (siglines == 0) begin + errors = 1; + $display("Error: empty test file %s", signame); + end else if (P.XLEN == 64 & (siglines % 2)) begin + errors = 1; + $display("Error: RV64 signature has odd number of lines %s", signame); + end else errors = 0; + // copy lines into signature, converting to XLEN if necessary + sigentries = (P.XLEN == 32) ? siglines : siglines/2; // number of signature entries + for (i=0; i Date: Fri, 17 May 2024 16:45:01 -0500 Subject: [PATCH 11/51] Yay. Finally found the issue with the integrated testbench.sv and imperasDV. The function which loads the elf file rvviRefInit must be called during an initial block using a valid file name. Because of how the testbench was organized the elffile was not defined until several cycles later so the call to rvviRefInit did not have a valid elf. Waiting several cycles does not work. rvviRefInit requires being called in an initial block so it is not possible to run back to back imperasDV simulations in the same run. --- testbench/testbench.sv | 2 ++ 1 file changed, 2 insertions(+) diff --git a/testbench/testbench.sv b/testbench/testbench.sv index 63bbf7d00..1bd41627a 100644 --- a/testbench/testbench.sv +++ b/testbench/testbench.sv @@ -694,9 +694,11 @@ end string filename; initial begin + // imperasDV requires the elffile be defined at the begining of the simulation. int iter; #1; IDV_MAX_ERRORS = 3; + elffilename = ElfFile; // Initialize REF (do this before initializing the DUT) if (!rvviVersionCheck(RVVI_API_VERSION)) begin From 0ed75a3ff511212ec92a764eb1f4f7d2d8816277 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Fri, 17 May 2024 16:48:29 -0500 Subject: [PATCH 12/51] Reverted testbench-imperas.sv incase someone wants this. --- testbench/testbench-imperas.sv | 1088 +++++++------------------------- 1 file changed, 234 insertions(+), 854 deletions(-) diff --git a/testbench/testbench-imperas.sv b/testbench/testbench-imperas.sv index c8ff90893..c315272a6 100644 --- a/testbench/testbench-imperas.sv +++ b/testbench/testbench-imperas.sv @@ -26,66 +26,59 @@ //////////////////////////////////////////////////////////////////////////////////////////////// `include "config.vh" -`include "tests.vh" -`include "BranchPredictorType.vh" + + +// This is set from the command line script +// `define USE_IMPERAS_DV `ifdef USE_IMPERAS_DV `include "idv/idv.svh" `endif - import cvw::*; module testbench; - /* verilator lint_off WIDTHTRUNC */ - /* verilator lint_off WIDTHEXPAND */ parameter DEBUG=0; - parameter PrintHPMCounters=0; - parameter BPRED_LOGGER=0; - parameter I_CACHE_ADDR_LOGGER=0; - parameter D_CACHE_ADDR_LOGGER=0; - `ifdef USE_IMPERAS_DV - import idvPkg::*; - import rvviApiPkg::*; - import idvApiPkg::*; - `endif - - `ifdef VERILATOR - import "DPI-C" function string getenvval(input string env_name); - string RISCV_DIR = getenvval("RISCV"); // "/opt/riscv"; - `elsif SIM_VCS - import "DPI-C" function string getenv(input string env_name); - string RISCV_DIR = getenv("RISCV"); // "/opt/riscv"; - `else - string RISCV_DIR = "$RISCV"; // "/opt/riscv"; - `endif +`ifdef USE_IMPERAS_DV + import idvPkg::*; + import rvviApiPkg::*; + import idvApiPkg::*; +`endif `include "parameter-defs.vh" logic clk; logic reset_ext, reset; - logic ResetMem; - // Variables that can be overwritten with $value$plusargs at start of simulation - string TEST; - string ElfFile; - integer INSTR_LIMIT; - // DUT signals - logic [P.AHBW-1:0] HRDATAEXT; - logic HREADYEXT, HRESPEXT; - logic HSELEXTSDC; + logic [P.XLEN-1:0] testadr, testadrNoBase; + string InstrFName, InstrDName, InstrEName, InstrMName, InstrWName; + logic [31:0] InstrW; + + logic [3:0] dummy; + + logic [P.AHBW-1:0] HRDATAEXT; + logic HREADYEXT, HRESPEXT; + logic HSELEXTSDC; logic [P.PA_BITS-1:0] HADDR; - logic [P.AHBW-1:0] HWDATA; - logic [P.XLEN/8-1:0] HWSTRB; - logic HWRITE; - logic [2:0] HSIZE; - logic [2:0] HBURST; - logic [3:0] HPROT; - logic [1:0] HTRANS; - logic HMASTLOCK; - logic HCLK, HRESETn; + logic [P.AHBW-1:0] HWDATA; + logic [P.XLEN/8-1:0] HWSTRB; + logic HWRITE; + logic [2:0] HSIZE; + logic [2:0] HBURST; + logic [3:0] HPROT; + logic [1:0] HTRANS; + 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 }; + logic DCacheFlushDone, DCacheFlushStart; + string testName; + string memfilename, testDir, adrstr, elffilename; logic [31:0] GPIOIN, GPIOOUT, GPIOEN; logic UARTSin, UARTSout; @@ -95,600 +88,7 @@ module testbench; logic HREADY; logic HSELEXT; - - string ProgramAddrMapFile, ProgramLabelMapFile; - integer ProgramAddrLabelArray [string]; - - int test, i, errors, totalerrors; - - string outputfile; - integer outputFilePointer; - - string tests[]; - logic DCacheFlushDone, DCacheFlushStart; - logic riscofTest; - logic Validate; - logic SelectTest; - logic TestComplete; - - initial begin - // look for arguments passed to simulation, or use defaults - if (!$value$plusargs("TEST=%s", TEST)) - TEST = "none"; - if (!$value$plusargs("ElfFile=%s", ElfFile)) - ElfFile = "none"; - else begin - end - if (!$value$plusargs("INSTR_LIMIT=%d", INSTR_LIMIT)) - INSTR_LIMIT = 0; - ElfFile = "/home/rose/repos/active/cvw2/cvw/tests/riscof/work/riscv-arch-test/rv64i_m/I/src/add-01.S/ref/ref.elf"; - - // pick tests based on modes supported - //tests = '{}; - if (P.XLEN == 64) begin // RV64 - case (TEST) - "arch64i": tests = arch64i; - "arch64priv": tests = arch64priv; - "arch64c": if (P.C_SUPPORTED) - if (P.ZICSR_SUPPORTED) tests = {arch64c, arch64cpriv}; - else tests = {arch64c}; - "arch64m": if (P.M_SUPPORTED) tests = arch64m; - "arch64a_amo": if (P.A_SUPPORTED | P.ZAAMO_SUPPORTED) tests = arch64a_amo; - "arch64f": if (P.F_SUPPORTED) tests = arch64f; - "arch64d": if (P.D_SUPPORTED) tests = arch64d; - "arch64f_fma": if (P.F_SUPPORTED) tests = arch64f_fma; - "arch64d_fma": if (P.D_SUPPORTED) tests = arch64d_fma; - "arch64f_divsqrt": if (P.F_SUPPORTED) tests = arch64f_divsqrt; - "arch64d_divsqrt": if (P.D_SUPPORTED) tests = arch64d_divsqrt; - "arch64zifencei": if (P.ZIFENCEI_SUPPORTED) tests = arch64zifencei; - "arch64zicond": if (P.ZICOND_SUPPORTED) tests = arch64zicond; - "imperas64i": tests = imperas64i; - "imperas64f": if (P.F_SUPPORTED) tests = imperas64f; - "imperas64d": if (P.D_SUPPORTED) tests = imperas64d; - "imperas64m": if (P.M_SUPPORTED) tests = imperas64m; - "wally64q": if (P.Q_SUPPORTED) tests = wally64q; - "wally64a_lrsc": if (P.A_SUPPORTED | P.ZALRSC_SUPPORTED) tests = wally64a_lrsc; - "imperas64c": if (P.C_SUPPORTED) tests = imperas64c; - else tests = imperas64iNOc; - "custom": tests = custom; - "wally64i": tests = wally64i; - "wally64priv": tests = wally64priv; - "wally64periph": tests = wally64periph; - "coremark": tests = coremark; - "fpga": tests = fpga; - "ahb64" : tests = ahb64; - "coverage64gc" : tests = coverage64gc; - "arch64zba": if (P.ZBA_SUPPORTED) tests = arch64zba; - "arch64zbb": if (P.ZBB_SUPPORTED) tests = arch64zbb; - "arch64zbc": if (P.ZBC_SUPPORTED) tests = arch64zbc; - "arch64zbs": if (P.ZBS_SUPPORTED) tests = arch64zbs; - "arch64zicboz": if (P.ZICBOZ_SUPPORTED) tests = arch64zicboz; - "arch64zcb": if (P.ZCB_SUPPORTED) tests = arch64zcb; - "arch64zfh": if (P.ZFH_SUPPORTED) tests = arch64zfh; - "arch64zfh_fma": if (P.ZFH_SUPPORTED) tests = arch64zfh_fma; - "arch64zfh_divsqrt": if (P.ZFH_SUPPORTED) tests = arch64zfh_divsqrt; - "arch64zfaf": if (P.ZFA_SUPPORTED) tests = arch64zfaf; - "arch64zfad": if (P.ZFA_SUPPORTED & P.D_SUPPORTED) tests = arch64zfad; - "buildroot": tests = buildroot; - "arch64zbkb": if (P.ZBKB_SUPPORTED) tests = arch64zbkb; - "arch64zbkc": if (P.ZBKC_SUPPORTED) tests = arch64zbkc; - "arch64zbkx": if (P.ZBKX_SUPPORTED) tests = arch64zbkx; - "arch64zknd": if (P.ZKND_SUPPORTED) tests = arch64zknd; - "arch64zkne": if (P.ZKNE_SUPPORTED) tests = arch64zkne; - "arch64zknh": if (P.ZKNH_SUPPORTED) tests = arch64zknh; - endcase - end else begin // RV32 - case (TEST) - "arch32e": tests = arch32e; - "arch32i": tests = arch32i; - "arch32priv": tests = arch32priv; - "arch32c": if (P.C_SUPPORTED) - if (P.ZICSR_SUPPORTED) tests = {arch32c, arch32cpriv}; - else tests = {arch32c}; - "arch32m": if (P.M_SUPPORTED) tests = arch32m; - "arch32a_amo": if (P.A_SUPPORTED | P.ZAAMO_SUPPORTED) tests = arch32a_amo; - "arch32f": if (P.F_SUPPORTED) tests = arch32f; - "arch32d": if (P.D_SUPPORTED) tests = arch32d; - "arch32f_fma": if (P.F_SUPPORTED) tests = arch32f_fma; - "arch32d_fma": if (P.D_SUPPORTED) tests = arch32d_fma; - "arch32f_divsqrt": if (P.F_SUPPORTED) tests = arch32f_divsqrt; - "arch32d_divsqrt": if (P.D_SUPPORTED) tests = arch32d_divsqrt; - "arch32zifencei": if (P.ZIFENCEI_SUPPORTED) tests = arch32zifencei; - "arch32zicond": if (P.ZICOND_SUPPORTED) tests = arch32zicond; - "imperas32i": tests = imperas32i; - "imperas32f": if (P.F_SUPPORTED) tests = imperas32f; - "imperas32m": if (P.M_SUPPORTED) tests = imperas32m; - "wally32a_lrsc": if (P.A_SUPPORTED | P.ZALRSC_SUPPORTED) tests = wally32a_lrsc; - "imperas32c": if (P.C_SUPPORTED) tests = imperas32c; - else tests = imperas32iNOc; - "wally32i": tests = wally32i; - "wally32priv": tests = wally32priv; - "wally32periph": tests = wally32periph; - "ahb32" : tests = ahb32; - "embench": tests = embench; - "coremark": tests = coremark; - "arch32zba": if (P.ZBA_SUPPORTED) tests = arch32zba; - "arch32zbb": if (P.ZBB_SUPPORTED) tests = arch32zbb; - "arch32zbc": if (P.ZBC_SUPPORTED) tests = arch32zbc; - "arch32zbs": if (P.ZBS_SUPPORTED) tests = arch32zbs; - "arch32zicboz": if (P.ZICBOZ_SUPPORTED) tests = arch32zicboz; - "arch32zcb": if (P.ZCB_SUPPORTED) tests = arch32zcb; - "arch32zfh": if (P.ZFH_SUPPORTED) tests = arch32zfh; - "arch32zfh_fma": if (P.ZFH_SUPPORTED) tests = arch32zfh_fma; - "arch32zfh_divsqrt": if (P.ZFH_SUPPORTED) tests = arch32zfh_divsqrt; - "arch32zfaf": if (P.ZFA_SUPPORTED) tests = arch32zfaf; - "arch32zfad": if (P.ZFA_SUPPORTED & P.D_SUPPORTED) tests = arch32zfad; - "arch32zbkb": if (P.ZBKB_SUPPORTED) tests = arch32zbkb; - "arch32zbkc": if (P.ZBKC_SUPPORTED) tests = arch32zbkc; - "arch32zbkx": if (P.ZBKX_SUPPORTED) tests = arch32zbkx; - "arch32zknd": if (P.ZKND_SUPPORTED) tests = arch32zknd; - "arch32zkne": if (P.ZKNE_SUPPORTED) tests = arch32zkne; - "arch32zknh": if (P.ZKNH_SUPPORTED) tests = arch32zknh; - endcase - end - if (tests.size() == 0 & ElfFile == "none") begin - if (tests.size() == 0) begin - $display("TEST %s not supported in this configuration", TEST); - end else if(ElfFile == "none") begin - $display("ElfFile %s not found", ElfFile); - end - $finish; - end -`ifdef MAKEVCD - $dumpfile("testbench.vcd"); - $dumpvars; -`endif - end // initial begin - - // Model the testbench as an fsm. - // Do this in parts so it easier to verify - // part 1: build a version which echos the same behavior as the below code, but does not drive anything - // part 2: drive some of the controls - // part 3: drive all logic and remove old inital and always @ negedge clk block - - typedef enum logic [3:0]{STATE_TESTBENCH_RESET, - STATE_INIT_TEST, - STATE_RESET_MEMORIES, - STATE_RESET_MEMORIES2, - STATE_LOAD_MEMORIES, - STATE_RESET_TEST, - STATE_RUN_TEST, - STATE_COPY_RAM, - STATE_CHECK_TEST, - STATE_CHECK_TEST_WAIT, - STATE_VALIDATE, - STATE_INCR_TEST} statetype; - statetype CurrState, NextState; - logic TestBenchReset; - logic [2:0] ResetCountNew, ResetThresholdNew; - logic LoadMem; - logic ResetCntEn; - logic ResetCntRst; - logic CopyRAM; - - string signame, elffilename, memfilename, bootmemfilename, uartoutfilename, pathname; - integer begin_signature_addr, end_signature_addr, signature_size; - integer uartoutfile; - - logic reset_extNew; - logic DCacheFlushStartNew; - - assign ResetThresholdNew = 3'd5; - - initial begin - TestBenchReset = 1'b1; - # 100; - TestBenchReset = 1'b0; - end - - always_ff @(posedge clk) - if (TestBenchReset) CurrState <= STATE_TESTBENCH_RESET; - else CurrState <= NextState; - - // fsm next state logic - always_comb begin - // riscof tests have a different signature, tests[0] == "1" refers to RiscvArchTests - // and tests[0] == "2" refers to WallyRiscvArchTests - //pathname = tvpaths[tests[0].atoi()]; - - case(CurrState) - STATE_TESTBENCH_RESET: NextState = STATE_INIT_TEST; - STATE_INIT_TEST: NextState = STATE_RESET_MEMORIES; - STATE_RESET_MEMORIES: NextState = STATE_RESET_MEMORIES2; - STATE_RESET_MEMORIES2: NextState = STATE_LOAD_MEMORIES; // Give the reset enough time to ensure the bus is reset before loading the memories. - STATE_LOAD_MEMORIES: NextState = STATE_RESET_TEST; - STATE_RESET_TEST: if(ResetCountNew < ResetThresholdNew) NextState = STATE_RESET_TEST; - else NextState = STATE_RUN_TEST; - STATE_RUN_TEST: if(TestComplete) NextState = STATE_COPY_RAM; - else NextState = STATE_RUN_TEST; - STATE_COPY_RAM: NextState = STATE_CHECK_TEST; - STATE_CHECK_TEST: if (DCacheFlushDone) NextState = STATE_VALIDATE; - else NextState = STATE_CHECK_TEST_WAIT; - STATE_CHECK_TEST_WAIT: if(DCacheFlushDone) NextState = STATE_VALIDATE; - else NextState = STATE_CHECK_TEST_WAIT; - STATE_VALIDATE: NextState = STATE_INIT_TEST; - STATE_INCR_TEST: NextState = STATE_INIT_TEST; - default: NextState = STATE_TESTBENCH_RESET; - endcase - end // always_comb - // fsm output control logic - assign reset_ext = CurrState == STATE_TESTBENCH_RESET | CurrState == STATE_INIT_TEST | - CurrState == STATE_RESET_MEMORIES | CurrState == STATE_RESET_MEMORIES2 | - CurrState == STATE_LOAD_MEMORIES | CurrState ==STATE_RESET_TEST; - // this initialization is very expensive, only do it for coremark. - assign ResetMem = (CurrState == STATE_RESET_MEMORIES | CurrState == STATE_RESET_MEMORIES2); - assign LoadMem = CurrState == STATE_LOAD_MEMORIES; - assign ResetCntRst = CurrState == STATE_INIT_TEST; - assign ResetCntEn = CurrState == STATE_RESET_TEST; - assign Validate = CurrState == STATE_VALIDATE; - assign SelectTest = CurrState == STATE_INIT_TEST; - assign CopyRAM = TestComplete & CurrState == STATE_RUN_TEST; - assign DCacheFlushStartNew = CurrState == STATE_COPY_RAM; - - // fsm reset counter - counter #(3) RstCounter(clk, ResetCntRst, ResetCntEn, ResetCountNew); - //////////////////////////////////////////////////////////////////////////////// - // Find the test vector files and populate the PC to function label converter - //////////////////////////////////////////////////////////////////////////////// - logic [P.XLEN-1:0] testadr; - - //VCS ignores the dynamic types while processing the implicit sensitivity lists of always @*, always_comb, and always_latch - //procedural blocks. VCS supports the dynamic types in the implicit sensitivity list of always @* block as specified in the Section 9.2 of the IEEE Standard SystemVerilog Specification 1800-2012. - //To support memory load and dump task verbosity: flag : -diag sys_task_mem - always @(*) begin - begin_signature_addr = ProgramAddrLabelArray["begin_signature"]; - end_signature_addr = ProgramAddrLabelArray["sig_end_canary"]; - signature_size = end_signature_addr - begin_signature_addr; - end - logic EcallFaultM; - if (P.ZICSR_SUPPORTED) - assign EcallFaultM = dut.core.priv.priv.EcallFaultM; - else - assign EcallFaultM = 0; - - always @(posedge clk) begin - //////////////////////////////////////////////////////////////////////////////// - // Verify the test ran correctly by checking the memory against a known signature. - //////////////////////////////////////////////////////////////////////////////// - if(TestBenchReset) test = 1; - if (P.ZICSR_SUPPORTED & TEST == "coremark") - if (EcallFaultM) begin - $display("Benchmark: coremark is done."); - $stop; - end - if (P.ZICSR_SUPPORTED & dut.core.ifu.PCM == 0 & dut.core.ifu.InstrM == 0 & dut.core.ieu.InstrValidM) begin - $display("Program fetched illegal instruction 0x00000000 from address 0x00000000. Might be fault with no fault handler."); - //$stop; // presently wally32/64priv tests trigger this for reasons not yet understood. - end - // modifications 4/3/24 kunlin & harris to speed up Verilator - // For some reason, Verilator runs ~100x slower when these SelectTest and Validate codes are in the posedge clk block - //end // added - //always @(posedge SelectTest) // added - if(SelectTest) begin - if (riscofTest) begin - memfilename = {pathname, tests[test], "/ref/ref.elf.memfile"}; - elffilename = {pathname, tests[test], "ref/ref.elf"}; - ProgramAddrMapFile = {pathname, tests[test], "/ref/ref.elf.objdump.addr"}; - ProgramLabelMapFile = {pathname, tests[test], "/ref/ref.elf.objdump.lab"}; - end else if(TEST == "buildroot") begin - memfilename = {RISCV_DIR, "/linux-testvectors/ram.bin"}; - elffilename = "buildroot"; - bootmemfilename = {RISCV_DIR, "/linux-testvectors/bootmem.bin"}; - uartoutfilename = {"logs/", TEST, "_uart.out"}; - uartoutfile = $fopen(uartoutfilename, "w"); // delete UART output file - ProgramAddrMapFile = {RISCV_DIR, "/buildroot/output/images/disassembly/vmlinux.objdump.addr"}; - ProgramLabelMapFile = {RISCV_DIR, "/buildroot/output/images/disassembly/vmlinux.objdump.lab"}; - end else if(ElfFile != "none") begin - elffilename = ElfFile; - memfilename = {ElfFile, ".memfile"}; - ProgramAddrMapFile = {ElfFile, ".objdump.addr"}; - ProgramLabelMapFile = {ElfFile, ".objdump.lab"}; - end else begin - elffilename = {pathname, tests[test], ".elf"}; - memfilename = {pathname, tests[test], ".elf.memfile"}; - ProgramAddrMapFile = {pathname, tests[test], ".elf.objdump.addr"}; - ProgramLabelMapFile = {pathname, tests[test], ".elf.objdump.lab"}; - end - // declare memory labels that interest us, the updateProgramAddrLabelArray task will find - // the addr of each label and fill the array. To expand, add more elements to this array - // and initialize them to zero (also initilaize them to zero at the start of the next test) - updateProgramAddrLabelArray(ProgramAddrMapFile, ProgramLabelMapFile, ProgramAddrLabelArray); - end -`ifdef VERILATOR // this macro is defined when verilator is used - // Simulator Verilator has an issue that the validate logic below slows runtime 110x if it is - // in the posedge clk block rather than a separate posedge Validate block. - // Until it is fixed, provide a silly posedge Validate block to keep Verilator happy. - // https://github.com/verilator/verilator/issues/4967 - end // restored - always @(posedge Validate) // added -`endif - if(Validate) begin - if (TEST == "buildroot") - $fclose(uartoutfile); - if (TEST == "embench") begin - // Writes contents of begin_signature to .sim.output file - // this contains instret and cycles for start and end of test run, used by embench - // python speed script to calculate embench speed score. - // also, begin_signature contains the results of the self checking mechanism, - // which will be read by the python script for error checking - $display("Embench Benchmark: %s is done.", tests[test]); - if (riscofTest) outputfile = {pathname, tests[test], "/ref/ref.sim.output"}; - else outputfile = {pathname, tests[test], ".sim.output"}; - outputFilePointer = $fopen(outputfile, "w"); - i = 0; - testadr = ($unsigned(begin_signature_addr))/(P.XLEN/8); - while ($unsigned(i) < $unsigned(5'd5)) begin - $fdisplayh(outputFilePointer, DCacheFlushFSM.ShadowRAM[testadr+i]); - i = i + 1; - end - $fclose(outputFilePointer); - $display("Embench Benchmark: created output file: %s", outputfile); - end else if (TEST == "coverage64gc") begin - $display("Coverage tests don't get checked"); - end else if (ElfFile != "none") begin - $display("Single Elf file tests are not signatured verified."); -`ifdef VERILATOR // this macro is defined when verilator is used - $finish; // Simulator Verilator needs $finish to terminate simulation. -`elsif SIM_VCS // this macro is defined when vcs is used - $finish; // Simulator VCS needs $finish to terminate simulation. -`else - $stop; // if this is changed to $finish for Questa, wally-batch.do does not go to the next step to run coverage, and wally.do terminates without allowing GUI debug -`endif - end else begin - // for tests with no self checking mechanism, read .signature.output file and compare to check for errors - // clear signature to prevent contamination from previous tests - if (!begin_signature_addr) - $display("begin_signature addr not found in %s", ProgramLabelMapFile); - else if (TEST != "embench") begin // *** quick hack for embench. need a better long term solution - CheckSignature(pathname, tests[test], riscofTest, begin_signature_addr, errors); - if(errors > 0) totalerrors = totalerrors + 1; - end - end - test = test + 1; // *** this probably needs to be moved. - if (test == tests.size()) begin - if (totalerrors == 0) $display("SUCCESS! All tests ran without failures."); - else $display("FAIL: %d test programs had errors", totalerrors); -`ifdef VERILATOR // this macro is defined when verilator is used - $finish; // Simulator Verilator needs $finish to terminate simulation. -`elsif SIM_VCS // this macro is defined when vcs is used - $finish; // Simulator VCS needs $finish to terminate simulation. -`else - $stop; // if this is changed to $finish for Questa, wally-batch.do does not go to the next step to run coverage, and wally.do terminates without allowing GUI debug -`endif - end - end -`ifndef VERILATOR - // Remove this when issue 4967 is resolved and the posedge Validate logic above is removed - end -`endif - - - - //////////////////////////////////////////////////////////////////////////////// - // load memories with program image - //////////////////////////////////////////////////////////////////////////////// - - integer ShadowIndex; - integer LogXLEN; - integer StartIndex; - integer EndIndex; - integer BaseIndex; - integer memFile; - integer readResult; - if (P.SDC_SUPPORTED) begin - always @(posedge clk) begin - if (LoadMem) begin - string romfilename, sdcfilename; - romfilename = {"../tests/custom/fpga-test-sdc/bin/fpga-test-sdc.memfile"}; - sdcfilename = {"../testbench/sdc/ramdisk2.hex"}; - //$readmemh(romfilename, dut.uncoregen.uncore.bootrom.bootrom.memory.ROM); - //$readmemh(sdcfilename, sdcard.sdcard.FLASHmem); - // shorten sdc timers for simulation - //dut.uncoregen.uncore.sdc.SDC.LimitTimers = 1; - end - end - end else if (P.IROM_SUPPORTED) begin - always @(posedge clk) begin - if (LoadMem) begin - $readmemh(memfilename, dut.core.ifu.irom.irom.rom.ROM); - end - end - end else if (P.BUS_SUPPORTED) begin : bus_supported - always @(posedge clk) begin - if (LoadMem) begin - if (TEST == "buildroot") begin - memFile = $fopen(bootmemfilename, "rb"); - readResult = $fread(dut.uncoregen.uncore.bootrom.bootrom.memory.ROM, memFile); - $fclose(memFile); - memFile = $fopen(memfilename, "rb"); - readResult = $fread(dut.uncoregen.uncore.ram.ram.memory.RAM, memFile); - $fclose(memFile); - end else - $readmemh(memfilename, dut.uncoregen.uncore.ram.ram.memory.RAM); - if (TEST == "embench") $display("Read memfile %s", memfilename); - end - if (CopyRAM) begin - LogXLEN = (1 + P.XLEN/32); // 2 for rv32 and 3 for rv64 - StartIndex = begin_signature_addr >> LogXLEN; - EndIndex = (end_signature_addr >> LogXLEN) + 8; - BaseIndex = P.UNCORE_RAM_BASE >> LogXLEN; - for(ShadowIndex = StartIndex; ShadowIndex <= EndIndex; ShadowIndex++) begin - testbench.DCacheFlushFSM.ShadowRAM[ShadowIndex] = dut.uncoregen.uncore.ram.ram.memory.RAM[ShadowIndex - BaseIndex]; - end - end - end - end - if (P.DTIM_SUPPORTED) begin - always @(posedge clk) begin - if (LoadMem) begin - $readmemh(memfilename, dut.core.lsu.dtim.dtim.ram.RAM); - $display("Read memfile %s", memfilename); - end - if (CopyRAM) begin - LogXLEN = (1 + P.XLEN/32); // 2 for rv32 and 3 for rv64 - StartIndex = begin_signature_addr >> LogXLEN; - EndIndex = (end_signature_addr >> LogXLEN) + 8; - BaseIndex = P.UNCORE_RAM_BASE >> LogXLEN; - for(ShadowIndex = StartIndex; ShadowIndex <= EndIndex; ShadowIndex++) begin - testbench.DCacheFlushFSM.ShadowRAM[ShadowIndex] = dut.core.lsu.dtim.dtim.ram.RAM[ShadowIndex - BaseIndex]; - end - end - end - end - - integer adrindex; - if (P.UNCORE_RAM_SUPPORTED) - always @(posedge clk) - if (ResetMem) // program memory is sometimes reset (e.g. for CoreMark, which needs zeroed memory) - for (adrindex=0; adrindex<(P.UNCORE_RAM_RANGE>>1+(P.XLEN/32)); adrindex = adrindex+1) - dut.uncoregen.uncore.ram.ram.memory.RAM[adrindex] = '0; - - //////////////////////////////////////////////////////////////////////////////// - // Actual hardware - //////////////////////////////////////////////////////////////////////////////// - - // instantiate device to be tested - assign GPIOIN = '0; - assign UARTSin = 1'b1; - assign SPIIn = 1'b0; - - if(P.EXT_MEM_SUPPORTED) begin - ram_ahb #(.P(P), .BASE(P.EXT_MEM_BASE), .RANGE(P.EXT_MEM_RANGE)) - ram (.HCLK, .HRESETn, .HADDR, .HWRITE, .HTRANS, .HWDATA, .HSELRam(HSELEXT), - .HREADRam(HRDATAEXT), .HREADYRam(HREADYEXT), .HRESPRam(HRESPEXT), .HREADY, .HWSTRB); - end else begin - assign HREADYEXT = 1'b1; - assign {HRESPEXT, HRDATAEXT} = '0; - end - - if(P.SDC_SUPPORTED) begin : sdcard - // *** fix later -/* -----\/----- EXCLUDED -----\/----- - sdModel sdcard - (.sdClk(SDCCLK), - .cmd(SDCCmd), - .dat(SDCDat)); - - assign SDCCmd = SDCCmdOE ? SDCCmdOut : 1'bz; - assign SDCCmdIn = SDCCmd; - assign SDCDat = sd_dat_reg_t ? sd_dat_reg_o : sd_dat_i; - assign SDCDatIn = SDCDat; - -----/\----- EXCLUDED -----/\----- */ - assign SDCIntr = 1'b0; - end else begin - assign SDCIntr = 1'b0; - end - - 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, .SPIIn, .SPIOut, .SPICS); - - // generate clock to sequence tests - always begin - clk = 1'b1; # 5; clk = 1'b0; # 5; - end - - /* - // Print key info each cycle for debugging - always @(posedge clk) begin - #2; - $display("PCM: %x InstrM: %x (%5s) WriteDataM: %x IEUResultM: %x", - dut.core.PCM, dut.core.InstrM, InstrMName, dut.core.WriteDataM, dut.core.ieu.dp.IEUResultM); - end - */ - - //////////////////////////////////////////////////////////////////////////////// - // 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, 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, - 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, InstrM, dut.core.lsu.IEUAdrM, InstrMName); - riscvassertions #(P) riscvassertions(); // check assertions for a legal configuration - loggers #(P, PrintHPMCounters, I_CACHE_ADDR_LOGGER, D_CACHE_ADDR_LOGGER, BPRED_LOGGER) - loggers (clk, reset, DCacheFlushStart, DCacheFlushDone, memfilename, TEST); - - // track the current function or global label - if (DEBUG > 0 | ((PrintHPMCounters | BPRED_LOGGER) & P.ZICNTR_SUPPORTED)) begin : FunctionName - FunctionName #(P) FunctionName(.reset(reset_ext | TestBenchReset), - .clk(clk), .ProgramAddrMapFile(ProgramAddrMapFile), .ProgramLabelMapFile(ProgramLabelMapFile)); - end - - // Append UART output to file for tests - if (P.UART_SUPPORTED) begin: uart_logger - always @(posedge clk) begin - if (TEST == "buildroot") begin - if (~dut.uncoregen.uncore.uartgen.uart.MEMWb & dut.uncoregen.uncore.uartgen.uart.uartPC.A == 3'b000 & ~dut.uncoregen.uncore.uartgen.uart.uartPC.DLAB) begin - $fwrite(uartoutfile, "%c", dut.uncoregen.uncore.uartgen.uart.uartPC.Din); // append characters one at a time so we see a consistent log appearing during the run - $fflush(uartoutfile); - end - end - end - end - - // 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 - // or sd gp, -56(t0) - // or on a jump to self infinite loop (6f) for RISC-V Arch tests - logic ecf; // remove this once we don't rely on old Imperas tests with Ecalls - if (P.ZICSR_SUPPORTED) assign ecf = dut.core.priv.priv.EcallFaultM; - else assign ecf = 0; - always_comb begin - TestComplete = ecf & - (dut.core.ieu.dp.regf.rf[3] == 1 | - (dut.core.ieu.dp.regf.we3 & - dut.core.ieu.dp.regf.a3 == 3 & - dut.core.ieu.dp.regf.wd3 == 1)) | - ((InstrM == 32'h6f | InstrM == 32'hfc32a423 | InstrM == 32'hfc32a823) & dut.core.ieu.c.InstrValidM ) | - ((dut.core.lsu.IEUAdrM == ProgramAddrLabelArray["tohost"] & dut.core.lsu.IEUAdrM != 0) & InstrMName == "SW" ); - end - - DCacheFlushFSM #(P) DCacheFlushFSM(.clk, .start(DCacheFlushStart), .done(DCacheFlushDone)); - - if(P.ZICSR_SUPPORTED) begin - logic [P.XLEN-1:0] Minstret; - assign Minstret = testbench.dut.core.priv.priv.csr.counters.counters.HPMCOUNTER_REGW[2]; - always @(negedge clk) begin - if (INSTR_LIMIT > 0) begin - if((Minstret != 0) && (Minstret % 'd100000 == 0)) $display("Reached %d instructions", Minstret); - if((Minstret == INSTR_LIMIT) & (INSTR_LIMIT!=0)) begin $finish; end - end - end -end - - - - - - - - - logic [P.XLEN-1:0] testadrNoBase; - - - string testName; - string testDir, adrstr; - - logic InitializingMemories; integer ResetCount, ResetThreshold; logic InReset; @@ -697,7 +97,7 @@ end initial begin ResetCount = 0; - ResetThreshold = 21; + ResetThreshold = 2; InReset = 1; testadr = 0; testadrNoBase = 0; @@ -710,7 +110,8 @@ end $error("Must specify test directory using plusarg testDir"); end - #130; + if (P.BUS_SUPPORTED) $readmemh(memfilename, dut.uncoregen.uncore.ram.ram.memory.RAM); + else $error("Imperas test bench requires BUS."); ProgramAddrMapFile = {testDir, "/ref/ref.elf.objdump.addr"}; ProgramLabelMapFile = {testDir, "/ref/ref.elf.objdump.lab"}; @@ -722,250 +123,229 @@ end end - - - - `ifdef USE_IMPERAS_DV - rvviTrace #(.XLEN(P.XLEN), .FLEN(P.FLEN)) rvvi(); - wallyTracer #(P) wallyTracer(rvvi); + rvviTrace #(.XLEN(P.XLEN), .FLEN(P.FLEN)) rvvi(); + wallyTracer #(P) wallyTracer(rvvi); - trace2log idv_trace2log(rvvi); - // trace2cov idv_trace2cov(rvvi); + trace2log idv_trace2log(rvvi); + trace2cov idv_trace2cov(rvvi); - // enabling of comparison types - trace2api #(.CMP_PC (1), - .CMP_INS (1), - .CMP_GPR (1), - .CMP_FPR (1), - .CMP_VR (0), - .CMP_CSR (1) - ) idv_trace2api(rvvi); + // enabling of comparison types + trace2api #(.CMP_PC (1), + .CMP_INS (1), + .CMP_GPR (1), + .CMP_FPR (1), + .CMP_VR (0), + .CMP_CSR (1) + ) idv_trace2api(rvvi); - string filename; - initial begin - int iter; - #1; - IDV_MAX_ERRORS = 3; - - // Initialize REF (do this before initializing the DUT) - if (!rvviVersionCheck(RVVI_API_VERSION)) begin - $display($sformatf("%m @ t=%0t: Expecting RVVI API version %0d.", $time, RVVI_API_VERSION)); - $fatal; - end - - void'(rvviRefConfigSetString(IDV_CONFIG_MODEL_VENDOR, "riscv.ovpworld.org")); - void'(rvviRefConfigSetString(IDV_CONFIG_MODEL_NAME, "riscv")); - void'(rvviRefConfigSetString(IDV_CONFIG_MODEL_VARIANT, "RV64GC")); - void'(rvviRefConfigSetInt(IDV_CONFIG_MODEL_ADDRESS_BUS_WIDTH, 56)); - void'(rvviRefConfigSetInt(IDV_CONFIG_MAX_NET_LATENCY_RETIREMENTS, 6)); - - if(elffilename == "buildroot") filename = ""; - else filename = elffilename; - - if (!rvviRefInit(filename)) begin - $display($sformatf("%m @ t=%0t: rvviRefInit failed", $time)); - $fatal; - end - - // Volatile CSRs - void'(rvviRefCsrSetVolatile(0, 32'hC00)); // CYCLE - void'(rvviRefCsrSetVolatile(0, 32'hB00)); // MCYCLE - void'(rvviRefCsrSetVolatile(0, 32'hC02)); // INSTRET - void'(rvviRefCsrSetVolatile(0, 32'hB02)); // MINSTRET - void'(rvviRefCsrSetVolatile(0, 32'hC01)); // TIME - - // User HPMCOUNTER3 - HPMCOUNTER31 - for (iter='hC03; iter<='hC1F; iter++) begin - void'(rvviRefCsrSetVolatile(0, iter)); // HPMCOUNTERx - end - - // Machine MHPMCOUNTER3 - MHPMCOUNTER31 - for (iter='hB03; iter<='hB1F; iter++) begin - void'(rvviRefCsrSetVolatile(0, iter)); // MHPMCOUNTERx - end - - // cannot predict this register due to latency between - // pending and taken - void'(rvviRefCsrSetVolatile(0, 32'h344)); // MIP - void'(rvviRefCsrSetVolatile(0, 32'h144)); // SIP - - // Privileges for PMA are set in the imperas.ic - // volatile (IO) regions are defined here - // only real ROM/RAM areas are BOOTROM and UNCORE_RAM - if (P.CLINT_SUPPORTED) begin - void'(rvviRefMemorySetVolatile(P.CLINT_BASE, (P.CLINT_BASE + P.CLINT_RANGE))); - end - if (P.GPIO_SUPPORTED) begin - void'(rvviRefMemorySetVolatile(P.GPIO_BASE, (P.GPIO_BASE + P.GPIO_RANGE))); - end - if (P.UART_SUPPORTED) begin - void'(rvviRefMemorySetVolatile(P.UART_BASE, (P.UART_BASE + P.UART_RANGE))); - end - if (P.PLIC_SUPPORTED) begin - void'(rvviRefMemorySetVolatile(P.PLIC_BASE, (P.PLIC_BASE + P.PLIC_RANGE))); - end - if (P.SDC_SUPPORTED) begin - void'(rvviRefMemorySetVolatile(P.SDC_BASE, (P.SDC_BASE + P.SDC_RANGE))); - end - if (P.SPI_SUPPORTED) begin - void'(rvviRefMemorySetVolatile(P.SPI_BASE, (P.SPI_BASE + P.SPI_RANGE))); - end - - if(P.XLEN==32) begin - void'(rvviRefCsrSetVolatile(0, 32'hC80)); // CYCLEH - void'(rvviRefCsrSetVolatile(0, 32'hB80)); // MCYCLEH - void'(rvviRefCsrSetVolatile(0, 32'hC82)); // INSTRETH - void'(rvviRefCsrSetVolatile(0, 32'hB82)); // MINSTRETH - end - - void'(rvviRefCsrSetVolatile(0, 32'h104)); // SIE - Temporary!!!! - - // Load memory - // *** RT: This section can probably be moved into the same chunk of code which - // loads the memories. However I'm not sure that ImperasDV supports reloading - // the memories without relaunching the simulator. - if(elffilename == "buildroot") begin - longint x64; - int x32[2]; - longint index; - string memfilenameImperasDV, bootmemfilenameImperasDV; + initial begin - memfilenameImperasDV = {RISCV_DIR, "/linux-testvectors/ram.bin"}; - bootmemfilenameImperasDV = {RISCV_DIR, "/linux-testvectors/bootmem.bin"}; + IDV_MAX_ERRORS = 3; - $display("RVVI Loading bootmem.bin"); - memFile = $fopen(bootmemfilenameImperasDV, "rb"); - index = 'h1000 - 8; - while(!$feof(memFile)) begin - index+=8; - readResult = $fread(x64, memFile); - if (x64 == 0) continue; - x32[0] = x64 & 'hffffffff; - x32[1] = x64 >> 32; - rvviRefMemoryWrite(0, index+0, x32[0], 4); - rvviRefMemoryWrite(0, index+4, x32[1], 4); - //$display("boot %08X x32[0]=%08X x32[1]=%08X", index, x32[0], x32[1]); + // Initialize REF (do this before initializing the DUT) + if (!rvviVersionCheck(RVVI_API_VERSION)) begin + $display($sformatf("%m @ t=%0t: Expecting RVVI API version %0d.", $time, RVVI_API_VERSION)); + $fatal; end - $fclose(memFile); - - $display("RVVI Loading ram.bin"); - memFile = $fopen(memfilenameImperasDV, "rb"); - index = 'h80000000 - 8; - while(!$feof(memFile)) begin - index+=8; - readResult = $fread(x64, memFile); - if (x64 == 0) continue; - x32[0] = x64 & 'hffffffff; - x32[1] = x64 >> 32; - rvviRefMemoryWrite(0, index+0, x32[0], 4); - rvviRefMemoryWrite(0, index+4, x32[1], 4); - //$display("ram %08X x32[0]=%08X x32[1]=%08X", index, x32[0], x32[1]); + void'(rvviRefConfigSetString(IDV_CONFIG_MODEL_VENDOR, "riscv.ovpworld.org")); + void'(rvviRefConfigSetString(IDV_CONFIG_MODEL_NAME, "riscv")); + void'(rvviRefConfigSetString(IDV_CONFIG_MODEL_VARIANT, "RV64GC")); + void'(rvviRefConfigSetInt(IDV_CONFIG_MODEL_ADDRESS_BUS_WIDTH, 39)); + void'(rvviRefConfigSetInt(IDV_CONFIG_MAX_NET_LATENCY_RETIREMENTS, 6)); + + if (!rvviRefInit(elffilename)) begin + $display($sformatf("%m @ t=%0t: rvviRefInit failed", $time)); + $fatal; end - $fclose(memFile); + + // Volatile CSRs + void'(rvviRefCsrSetVolatile(0, 32'hC00)); // CYCLE + void'(rvviRefCsrSetVolatile(0, 32'hB00)); // MCYCLE + void'(rvviRefCsrSetVolatile(0, 32'hC02)); // INSTRET + void'(rvviRefCsrSetVolatile(0, 32'hB02)); // MINSTRET + void'(rvviRefCsrSetVolatile(0, 32'hC01)); // TIME - $display("RVVI Loading Complete"); + // cannot predict this register due to latency between + // pending and taken + void'(rvviRefCsrSetVolatile(0, 32'h344)); // MIP + void'(rvviRefCsrSetVolatile(0, 32'h144)); // SIP + + // Privileges for PMA are set in the imperas.ic + // volatile (IO) regions are defined here + // only real ROM/RAM areas are BOOTROM and UNCORE_RAM + if (P.CLINT_SUPPORTED) begin + void'(rvviRefMemorySetVolatile(P.CLINT_BASE, (P.CLINT_BASE + P.CLINT_RANGE))); + end + if (P.GPIO_SUPPORTED) begin + void'(rvviRefMemorySetVolatile(P.GPIO_BASE, (P.GPIO_BASE + P.GPIO_RANGE))); + end + if (P.UART_SUPPORTED) begin + void'(rvviRefMemorySetVolatile(P.UART_BASE, (P.UART_BASE + P.UART_RANGE))); + end + if (P.PLIC_SUPPORTED) begin + void'(rvviRefMemorySetVolatile(P.PLIC_BASE, (P.PLIC_BASE + P.PLIC_RANGE))); + end + if (P.SDC_SUPPORTED) begin + void'(rvviRefMemorySetVolatile(P.SDC_BASE, (P.SDC_BASE + P.SDC_RANGE))); + end + if (P.SPI_SUPPORTED) begin + void'(rvviRefMemorySetVolatile(P.SPI_BASE, (P.SPI_BASE + P.SPI_RANGE))); + end + + if(P.XLEN==32) begin + void'(rvviRefCsrSetVolatile(0, 32'hC80)); // CYCLEH + void'(rvviRefCsrSetVolatile(0, 32'hB80)); // MCYCLEH + void'(rvviRefCsrSetVolatile(0, 32'hC82)); // INSTRETH + void'(rvviRefCsrSetVolatile(0, 32'hB82)); // MINSTRETH + end + + void'(rvviRefCsrSetVolatile(0, 32'h104)); // SIE - Temporary!!!! - void'(rvviRefPcSet(0, P.RESET_VECTOR)); // set BOOTROM address end - end - always @(dut.core.priv.priv.csr.csri.MIP_REGW[7]) void'(rvvi.net_push("MTimerInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[7])); - always @(dut.core.priv.priv.csr.csri.MIP_REGW[11]) void'(rvvi.net_push("MExternalInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[11])); - always @(dut.core.priv.priv.csr.csri.MIP_REGW[9]) void'(rvvi.net_push("SExternalInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[9])); - always @(dut.core.priv.priv.csr.csri.MIP_REGW[3]) void'(rvvi.net_push("MSWInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[3])); - always @(dut.core.priv.priv.csr.csri.MIP_REGW[1]) void'(rvvi.net_push("SSWInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[1])); - always @(dut.core.priv.priv.csr.csri.MIP_REGW[5]) void'(rvvi.net_push("STimerInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[5])); + always @(dut.core.priv.priv.csr.csri.MIP_REGW[7]) void'(rvvi.net_push("MTimerInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[7])); + always @(dut.core.priv.priv.csr.csri.MIP_REGW[11]) void'(rvvi.net_push("MExternalInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[11])); + always @(dut.core.priv.priv.csr.csri.MIP_REGW[9]) void'(rvvi.net_push("SExternalInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[9])); + always @(dut.core.priv.priv.csr.csri.MIP_REGW[3]) void'(rvvi.net_push("MSWInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[3])); + always @(dut.core.priv.priv.csr.csri.MIP_REGW[1]) void'(rvvi.net_push("SSWInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[1])); + always @(dut.core.priv.priv.csr.csri.MIP_REGW[5]) void'(rvvi.net_push("STimerInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[5])); - final begin - void'(rvviRefShutdown()); - end + final begin + void'(rvviRefShutdown()); + end `endif - task automatic CheckSignature; - // This task must be declared inside this module as it needs access to parameter P. There is - // no way to pass P to the task unless we convert it to a module. - - input string pathname; - input string TestName; - input logic riscofTest; - input integer begin_signature_addr; - output integer errors; - int fd, code; - string line; - int siglines, sigentries; + 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, InstrM, InstrW); - localparam SIGNATURESIZE = 5000000; - integer i; - logic [31:0] sig32[0:SIGNATURESIZE]; - logic [31:0] parsed; - logic [P.XLEN-1:0] signature[0:SIGNATURESIZE]; - string signame; - logic [P.XLEN-1:0] testadr, testadrNoBase; + // check assertions for a legal configuration + riscvassertions #(P) riscvassertions(); - //$display("Invoking CheckSignature %s %s %0t", pathname, TestName, $time); - - // read .signature.output file and compare to check for errors - if (riscofTest) signame = {pathname, TestName, "/ref/Reference-sail_c_simulator.signature"}; - else signame = {pathname, TestName, ".signature.output"}; - // read signature file from memory and count lines. Can't use readmemh because we need the line count - // $readmemh(signame, sig32); - fd = $fopen(signame, "r"); - siglines = 0; - if (fd == 0) $display("Unable to read %s", signame); - else begin - while (!$feof(fd)) begin - code = $fgets(line, fd); - if (code != 0) begin - int errno; - string errstr; - errno = $ferror(fd, errstr); - if (errno != 0) $display("Error %d (code %d) reading line %d of %s: %s", errno, code, siglines, signame, errstr); - if (line.len() > 1) begin // skip blank lines - if ($sscanf(line, "%x", parsed) != 0) begin - sig32[siglines] = parsed; - siglines = siglines + 1; // increment if line is not blank - end - end + // instantiate device to be tested + assign GPIOIN = 0; + assign UARTSin = 1; + + if(P.EXT_MEM_SUPPORTED) begin + ram_ahb #(.BASE(P.EXT_MEM_BASE), .RANGE(P.EXT_MEM_RANGE)) + ram (.HCLK, .HRESETn, .HADDR, .HWRITE, .HTRANS, .HWDATA, .HSELRam(HSELEXT), + .HREADRam(HRDATAEXT), .HREADYRam(HREADYEXT), .HRESPRam(HRESPEXT), .HREADY, + .HWSTRB); + end else begin + assign HREADYEXT = 1; + assign HRESPEXT = 0; + assign HRDATAEXT = 0; + end + + if(P.SDC_SUPPORTED) begin : sdcard + // *** fix later +/* -----\/----- EXCLUDED -----\/----- + sdModel sdcard + (.sdClk(SDCCLK), + .cmd(SDCCmd), + .dat(SDCDat)); + + assign SDCCmd = SDCCmdOE ? SDCCmdOut : 1'bz; + assign SDCCmdIn = SDCCmd; + assign SDCDatIn = SDCDat; + -----/\----- EXCLUDED -----/\----- */ + assign SDCIntr = 0; + end else begin + assign SDCIntr = 0; + end + + 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); + + // 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, + InstrM, InstrW, + InstrFName, InstrDName, InstrEName, InstrMName, InstrWName); + + // initialize tests + + // generate clock to sequence tests + always + begin + clk = 1; # 5; clk = 0; # 5; + // if ($time % 100000 == 0) $display("Time is %0t", $time); + end + + // check results + assign reset_ext = InReset; + + always @(negedge clk) + begin + InitializingMemories = 0; + if(InReset == 1) begin + // once the test inidicates it's done we need to immediately hold reset for a number of cycles. + if(ResetCount < ResetThreshold) ResetCount = ResetCount + 1; + else begin // hit reset threshold so we remove reset. + InReset = 0; + ResetCount = 0; end end - $fclose(fd); - end + end // always @ (negedge clk) - // Check valid number of lines were read - if (siglines == 0) begin - errors = 1; - $display("Error: empty test file %s", signame); - end else if (P.XLEN == 64 & (siglines % 2)) begin - errors = 1; - $display("Error: RV64 signature has odd number of lines %s", signame); - end else errors = 0; - // copy lines into signature, converting to XLEN if necessary - sigentries = (P.XLEN == 32) ? siglines : siglines/2; // number of signature entries - for (i=0; i Date: Fri, 17 May 2024 17:10:15 -0500 Subject: [PATCH 13/51] wsim now supports lockstep and single elf example wsim rv64gc ../../tests/riscof/work/riscv-arch-test/rv64i_m/I/src/add-01.S/ref/ref.elf --elf --lockstep --- bin/wsim | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/bin/wsim b/bin/wsim index 531c6825c..4a4103242 100755 --- a/bin/wsim +++ b/bin/wsim @@ -25,9 +25,12 @@ parser.add_argument("--gui", "-g", help="Simulate with GUI", action="store_true" parser.add_argument("--coverage", "-c", help="Code & Functional Coverage", action="store_true") parser.add_argument("--args", "-a", help="Optional arguments passed to simulator via $value$plusargs", default="") parser.add_argument("--vcd", "-v", help="Generate testbench.vcd", action="store_true") +parser.add_argument("--lockstep", "-l", help="Run ImperasDV lock, step, and compare.", action="store_true") +parser.add_argument("--locksteplog", "-b", help="Retired instruction number to be begin logging.", default=0) args = parser.parse_args() print("Config=" + args.config + " tests=" + args.testsuite + " sim=" + args.sim + " gui=" + str(args.gui) + " args='" + args.args + "'") ElfFile="" + if(args.elf): ElfFile = "+ElfFile=" + args.testsuite args.testsuite = "none" @@ -55,21 +58,29 @@ for d in ["logs", "wkdir", "cov"]: except: pass + # Launch selected simulator cd = "cd $WALLY/sim/" +args.sim if (args.sim == "questa"): + if (args.lockstep): + Instret = str(args.locksteplog) + prefix ="IMPERAS_TOOLS=" + WALLY + "/sim/imperas.ic OTHERFLAGS=\"+IDV_TRACE2LOG=" + Instret + " +IDV_TRACE2COV=" + Instret + "\" "; + suffix = "--lockstep" + else: + prefix = "" + suffix = "" if (args.tb == "testbench_fp"): args.args = " -GTEST=\"" + args.testsuite + "\" " + args.args - cmd = "do wally.do " + args.config + " " + args.testsuite + " " + args.tb + " " + args.args + " " + ElfFile + cmd = "do wally.do " + args.config + " " + args.testsuite + " " + args.tb + " " + args.args + " " + ElfFile + " " + suffix if (args.coverage): cmd += " --coverage" if (args.gui): # launch Questa with GUI; add +acc to keep variables accessible if(args.tb == "testbench"): - cmd = cd + "; vsim -do \"" + cmd + " +acc -GDEBUG=1\"" + cmd = cd + "; " + prefix + " vsim -do \"" + cmd + " +acc -GDEBUG=1\"" elif(args.tb == "testbench_fp"): - cmd = cd + "; vsim -do \"" + cmd + " +acc\"" + cmd = cd + "; " + prefix + " vsim -do \"" + cmd + " +acc\"" else: # launch Questa in batch mode - cmd = cd + "; vsim -c -do \"" + cmd + "\"" + cmd = cd + "; " + prefix + " vsim -c -do \"" + cmd + "\"" print("Running Questa with command: " + cmd) os.system(cmd) elif (args.sim == "verilator"): From 6e3ccbb9c18a7961612713443aa64055e65f0119 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Fri, 17 May 2024 17:34:29 -0500 Subject: [PATCH 14/51] Almost have it working for both buildroot and single elfs. --- testbench/testbench.sv | 104 +++++++++++++++++++++-------------------- 1 file changed, 53 insertions(+), 51 deletions(-) diff --git a/testbench/testbench.sv b/testbench/testbench.sv index e32fdd9a8..71aaa8126 100644 --- a/testbench/testbench.sv +++ b/testbench/testbench.sv @@ -696,6 +696,10 @@ end initial begin // imperasDV requires the elffile be defined at the begining of the simulation. int iter; + longint x64; + int x32[2]; + longint index; + string memfilenameImperasDV, bootmemfilenameImperasDV; #1; IDV_MAX_ERRORS = 3; elffilename = ElfFile; @@ -714,10 +718,55 @@ end if(elffilename == "buildroot") filename = ""; else filename = elffilename; - - if (!rvviRefInit(filename)) begin - $display($sformatf("%m @ t=%0t: rvviRefInit failed", $time)); - $fatal; + + // use the ImperasDV rvviRefInit to load the reference model with an elf file + if(elffilename != "none") begin + if (!rvviRefInit(filename)) begin + $display($sformatf("%m @ t=%0t: rvviRefInit failed", $time)); + $fatal; + end + end else begin // for buildroot use the binary instead to load teh reference model. + if (!rvviRefInit("")) begin // still have to call with nothing + $display($sformatf("%m @ t=%0t: rvviRefInit failed", $time)); + $fatal; + end + + memfilenameImperasDV = {RISCV_DIR, "/linux-testvectors/ram.bin"}; + bootmemfilenameImperasDV = {RISCV_DIR, "/linux-testvectors/bootmem.bin"}; + + $display("RVVI Loading bootmem.bin"); + memFile = $fopen(bootmemfilenameImperasDV, "rb"); + index = 'h1000 - 8; + while(!$feof(memFile)) begin + index+=8; + readResult = $fread(x64, memFile); + if (x64 == 0) continue; + x32[0] = x64 & 'hffffffff; + x32[1] = x64 >> 32; + rvviRefMemoryWrite(0, index+0, x32[0], 4); + rvviRefMemoryWrite(0, index+4, x32[1], 4); + //$display("boot %08X x32[0]=%08X x32[1]=%08X", index, x32[0], x32[1]); + end + $fclose(memFile); + + $display("RVVI Loading ram.bin"); + memFile = $fopen(memfilenameImperasDV, "rb"); + index = 'h80000000 - 8; + while(!$feof(memFile)) begin + index+=8; + readResult = $fread(x64, memFile); + if (x64 == 0) continue; + x32[0] = x64 & 'hffffffff; + x32[1] = x64 >> 32; + rvviRefMemoryWrite(0, index+0, x32[0], 4); + rvviRefMemoryWrite(0, index+4, x32[1], 4); + //$display("ram %08X x32[0]=%08X x32[1]=%08X", index, x32[0], x32[1]); + end + $fclose(memFile); + + $display("RVVI Loading Complete"); + + void'(rvviRefPcSet(0, P.RESET_VECTOR)); // set BOOTROM address end // Volatile CSRs @@ -773,53 +822,6 @@ end void'(rvviRefCsrSetVolatile(0, 32'h104)); // SIE - Temporary!!!! - // Load memory - // *** RT: This section can probably be moved into the same chunk of code which - // loads the memories. However I'm not sure that ImperasDV supports reloading - // the memories without relaunching the simulator. - if(elffilename == "buildroot") begin - longint x64; - int x32[2]; - longint index; - string memfilenameImperasDV, bootmemfilenameImperasDV; - - memfilenameImperasDV = {RISCV_DIR, "/linux-testvectors/ram.bin"}; - bootmemfilenameImperasDV = {RISCV_DIR, "/linux-testvectors/bootmem.bin"}; - - $display("RVVI Loading bootmem.bin"); - memFile = $fopen(bootmemfilenameImperasDV, "rb"); - index = 'h1000 - 8; - while(!$feof(memFile)) begin - index+=8; - readResult = $fread(x64, memFile); - if (x64 == 0) continue; - x32[0] = x64 & 'hffffffff; - x32[1] = x64 >> 32; - rvviRefMemoryWrite(0, index+0, x32[0], 4); - rvviRefMemoryWrite(0, index+4, x32[1], 4); - //$display("boot %08X x32[0]=%08X x32[1]=%08X", index, x32[0], x32[1]); - end - $fclose(memFile); - - $display("RVVI Loading ram.bin"); - memFile = $fopen(memfilenameImperasDV, "rb"); - index = 'h80000000 - 8; - while(!$feof(memFile)) begin - index+=8; - readResult = $fread(x64, memFile); - if (x64 == 0) continue; - x32[0] = x64 & 'hffffffff; - x32[1] = x64 >> 32; - rvviRefMemoryWrite(0, index+0, x32[0], 4); - rvviRefMemoryWrite(0, index+4, x32[1], 4); - //$display("ram %08X x32[0]=%08X x32[1]=%08X", index, x32[0], x32[1]); - end - $fclose(memFile); - - $display("RVVI Loading Complete"); - - void'(rvviRefPcSet(0, P.RESET_VECTOR)); // set BOOTROM address - end end always @(dut.core.priv.priv.csr.csri.MIP_REGW[7]) void'(rvvi.net_push("MTimerInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[7])); From ad568e9d25081efc028ca39b25c74d3a043d1991 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Mon, 20 May 2024 15:46:26 -0500 Subject: [PATCH 15/51] Updated readme. --- README.md | 57 ++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 50 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 2444ff99a..89dc350f3 100644 --- a/README.md +++ b/README.md @@ -41,19 +41,14 @@ Clone your fork of the repo and run the setup script. Change to y $ git remote add upstream https://github.com/openhwgroup/cvw $ source ./setup.sh +If you are installing on a new system without any tools installed please jump to the next section, Toolchain Installation then come back here. + Add the following lines to your .bashrc or .bash_profile to run the setup script each time you log in. if [ -f ~/cvw/setup.sh ]; then source ~/cvw/setup.sh fi -Edit setup.sh and change the following lines to point to the path and license server for your Siemens Questa and Synopsys Design Compiler installation and license server. If you only have Questa, you can still simulate but cannot run logic synthesis. - - export MGLS_LICENSE_FILE=.. # Change this to your Siemens license server - export SNPSLMD_LICENSE_FILE=.. # Change this to your Synopsys license server - export QUESTAPATH=.. # Change this for your path to Questa - export SNPSPATH=.. # Change this for your path to Design Compiler - If the tools are not yet installed on your server, follow the Toolchain Installation instructions in the section below. Build the tests and run a regression simulation with Questa to prove everything is installed. Building tests will take a while. @@ -73,6 +68,17 @@ Ubuntu users can install the tools by running $ sudo $WALLY/bin/wally-tool-chain-install.sh +The default installation directory is /opt/riscv defined by the environment variable RISCV. You must copy and edit ~/cvw/site-setup.sh to $RISCV/ ~/cvw/setup.sh sources $RISCV/site-setup.sh. +This allows for customization of the site specific information such as commerical licenses and PATH variables. + +Change the following lines to point to the path and license server for your Siemens Questa and Synopsys Design Compiler installation and license server. If you only have Questa, you can still simulate but cannot run logic synthesis. If Questa or Design Compiler are already setup on this system then don't set these variables. + + export MGLS_LICENSE_FILE=.. # Change this to your Siemens license server + export SNPSLMD_LICENSE_FILE=.. # Change this to your Synopsys license server + export QUESTAPATH=.. # Change this for your path to Questa + export SNPSPATH=.. # Change this for your path to Design Compiler + + See wally-tool-chain-install.sh for a detailed description of each component, or to issue the commands one at a time to install on the command line. ## Installing EDA Tools @@ -138,3 +144,40 @@ If you want to add a cronjob you can do the following: 30 21 * * * bash -l -c "source ~/PATH/TO/CVW/setup.sh; PATH_TO_CVW/cvw/bin/wrapper_nightly_runs.sh --path {PATH_TO_TEST_LOCATION} --target all --tests nightly --send_email harris@hmc.edu,kaitlin.verilog@gmail.com" ``` +# Example wsim commands + +wsim runs one of multiple simulators, Questa, VCS, or Verilator using a specific configuration and either a suite of tests or a specific elf file. +The general syntax is +wsim [--options] + +Options: + -h, --help show this help message and exit + --elf, -e Elf file + --sim {questa,verilator,vcs}, -s {questa,verilator,vcs} + Simulator + --tb {testbench,testbench_fp}, -t {testbench,testbench_fp} + Testbench + --gui, -g Simulate with GUI + --coverage, -c Code & Functional Coverage + --args ARGS, -a ARGS Optional arguments passed to simulator via $value$plusargs + --vcd, -v Generate testbench.vcd + --lockstep, -l Run ImperasDV lock, step, and compare. + --locksteplog LOCKSTEPLOG, -b LOCKSTEPLOG + Retired instruction number to be begin logging. + +Run basic test with questa + +wsim rv64gc arch64i + +Run Questa with gui + +wsim rv64gc wally64priv --gui + +Run lockstep against ImperasDV with a single elf file in the --gui. Lockstep requires single elf. + +wsim rv64gc ../../tests/riscof/work/riscv-arch-test/rv64i_m/I/src/add-01.S/ref/ref.elf --elf --lockstep --gui + +Run lockstep against ImperasDV with a single elf file. Compute coverage. + +wsim rv64gc ../../tests/riscof/work/riscv-arch-test/rv64i_m/I/src/add-01.S/ref/ref.elf --elf --lockstep --coverage + From 55008e98c95f20c29fc2170fee1f6639533a2a51 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Mon, 20 May 2024 15:50:17 -0500 Subject: [PATCH 16/51] Formated readme. --- README.md | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 89dc350f3..ea6c04424 100644 --- a/README.md +++ b/README.md @@ -151,33 +151,32 @@ The general syntax is wsim [--options] Options: - -h, --help show this help message and exit - --elf, -e Elf file - --sim {questa,verilator,vcs}, -s {questa,verilator,vcs} - Simulator - --tb {testbench,testbench_fp}, -t {testbench,testbench_fp} - Testbench - --gui, -g Simulate with GUI - --coverage, -c Code & Functional Coverage - --args ARGS, -a ARGS Optional arguments passed to simulator via $value$plusargs - --vcd, -v Generate testbench.vcd - --lockstep, -l Run ImperasDV lock, step, and compare. - --locksteplog LOCKSTEPLOG, -b LOCKSTEPLOG + -h, --help show this help message and exit + --elf, -e Elf file + --sim {questa,verilator,vcs}, -s {questa,verilator,vcs} + Simulator + --tb {testbench,testbench_fp}, -t {testbench,testbench_fp} + Testbench + --gui, -g Simulate with GUI + --coverage, -c Code & Functional Coverage + --args ARGS, -a ARGS Optional arguments passed to simulator via $value$plusargs + --vcd, -v Generate testbench.vcd + --lockstep, -l Run ImperasDV lock, step, and compare. + --locksteplog LOCKSTEPLOG, -b LOCKSTEPLOG Retired instruction number to be begin logging. Run basic test with questa -wsim rv64gc arch64i + wsim rv64gc arch64i Run Questa with gui -wsim rv64gc wally64priv --gui + wsim rv64gc wally64priv --gui Run lockstep against ImperasDV with a single elf file in the --gui. Lockstep requires single elf. -wsim rv64gc ../../tests/riscof/work/riscv-arch-test/rv64i_m/I/src/add-01.S/ref/ref.elf --elf --lockstep --gui + wsim rv64gc ../../tests/riscof/work/riscv-arch-test/rv64i_m/I/src/add-01.S/ref/ref.elf --elf --lockstep --gui Run lockstep against ImperasDV with a single elf file. Compute coverage. -wsim rv64gc ../../tests/riscof/work/riscv-arch-test/rv64i_m/I/src/add-01.S/ref/ref.elf --elf --lockstep --coverage - + wsim rv64gc ../../tests/riscof/work/riscv-arch-test/rv64i_m/I/src/add-01.S/ref/ref.elf --elf --lockstep --coverage From 7cc1fcbd49579e1cf99f6d390676ef569c73910f Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Mon, 20 May 2024 15:52:36 -0500 Subject: [PATCH 17/51] More formating. --- README.md | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index ea6c04424..88bd2e5fa 100644 --- a/README.md +++ b/README.md @@ -151,19 +151,16 @@ The general syntax is wsim [--options] Options: - -h, --help show this help message and exit - --elf, -e Elf file - --sim {questa,verilator,vcs}, -s {questa,verilator,vcs} - Simulator - --tb {testbench,testbench_fp}, -t {testbench,testbench_fp} - Testbench - --gui, -g Simulate with GUI - --coverage, -c Code & Functional Coverage - --args ARGS, -a ARGS Optional arguments passed to simulator via $value$plusargs - --vcd, -v Generate testbench.vcd - --lockstep, -l Run ImperasDV lock, step, and compare. - --locksteplog LOCKSTEPLOG, -b LOCKSTEPLOG - Retired instruction number to be begin logging. + -h, --help show this help message and exit + --elf, -e Elf file + --sim {questa,verilator,vcs}, -s {questa,verilator,vcs} Simulator + --tb {testbench,testbench_fp}, -t {testbench,testbench_fp} Testbench + --gui, -g Simulate with GUI + --coverage, -c Code & Functional Coverage + --args ARGS, -a ARGS Optional arguments passed to simulator via $value$plusargs + --vcd, -v Generate testbench.vcd + --lockstep, -l Run ImperasDV lock, step, and compare. + --locksteplog LOCKSTEPLOG, -b LOCKSTEPLOG Retired instruction number to be begin logging. Run basic test with questa From 33eb5980e7c8660298dd366ce02b3e7baacf06f0 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Mon, 20 May 2024 15:57:45 -0500 Subject: [PATCH 18/51] More readme formating. --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 88bd2e5fa..89ec18424 100644 --- a/README.md +++ b/README.md @@ -150,7 +150,8 @@ wsim runs one of multiple simulators, Questa, VCS, or Verilator using a specific The general syntax is wsim [--options] -Options: +Parameters and options: + -h, --help show this help message and exit --elf, -e Elf file --sim {questa,verilator,vcs}, -s {questa,verilator,vcs} Simulator From d025bd0aff5265f9838aaa02b64599b33d4aba81 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Mon, 20 May 2024 16:23:25 -0500 Subject: [PATCH 19/51] More improvements to the readme. --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 89ec18424..c2e0f1d39 100644 --- a/README.md +++ b/README.md @@ -68,7 +68,9 @@ Ubuntu users can install the tools by running $ sudo $WALLY/bin/wally-tool-chain-install.sh -The default installation directory is /opt/riscv defined by the environment variable RISCV. You must copy and edit ~/cvw/site-setup.sh to $RISCV/ ~/cvw/setup.sh sources $RISCV/site-setup.sh. +The default installation directory is /opt/riscv defined by the environment variable RISCV. You must copy and edit ~/cvw/site-setup.sh to $RISCV/site-setup.sh. + +~/cvw/setup.sh sources $RISCV/site-setup.sh. This allows for customization of the site specific information such as commerical licenses and PATH variables. Change the following lines to point to the path and license server for your Siemens Questa and Synopsys Design Compiler installation and license server. If you only have Questa, you can still simulate but cannot run logic synthesis. If Questa or Design Compiler are already setup on this system then don't set these variables. From 88eb7bd04564ab49f29bf3653171e906b45def41 Mon Sep 17 00:00:00 2001 From: David Harris Date: Wed, 22 May 2024 00:22:53 -0700 Subject: [PATCH 20/51] Pulled brev8 out of byteop so redundant byteop logic is not needed in zbkb --- src/ieu/bmu/bitmanipalu.sv | 2 +- src/ieu/bmu/byteop.sv | 10 ++++------ src/ieu/bmu/zbb.sv | 2 +- src/ieu/kmu/zbkb.sv | 13 +++++++++---- 4 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/ieu/bmu/bitmanipalu.sv b/src/ieu/bmu/bitmanipalu.sv index fec96883e..7748b8627 100644 --- a/src/ieu/bmu/bitmanipalu.sv +++ b/src/ieu/bmu/bitmanipalu.sv @@ -103,7 +103,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), .RevA, .W64, .Funct3, .ZBKBSelect(ZBBSelect[2:0]), .ZBKBResult); + zbkb #(P.XLEN) ZBKB(.A(ABMU), .B(BBMU), .W64, .Funct3, .ZBKBSelect(ZBBSelect[2:0]), .ZBKBResult); end else assign ZBKBResult = '0; // ZBKX Unit diff --git a/src/ieu/bmu/byteop.sv b/src/ieu/bmu/byteop.sv index 980c6d586..913c852b1 100644 --- a/src/ieu/bmu/byteop.sv +++ b/src/ieu/bmu/byteop.sv @@ -30,24 +30,22 @@ module byteop #(parameter WIDTH=32) ( input logic [WIDTH-1:0] A, // Operands - input logic [WIDTH-1:0] RevA, // Reversed A input logic [1:0] ByteSelect, // LSB of Immediate output logic [WIDTH-1:0] ByteResult); // rev8, orcb result - logic [WIDTH-1:0] OrcBResult, Rev8Result, Brev8Result; + logic [WIDTH-1:0] OrcBResult, Rev8Result; genvar i; for (i=0;i Date: Wed, 22 May 2024 00:48:04 -0700 Subject: [PATCH 21/51] Continued bmu cleanup --- src/ieu/bmu/byteop.sv | 12 +++--------- src/ieu/bmu/zbb.sv | 2 +- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/src/ieu/bmu/byteop.sv b/src/ieu/bmu/byteop.sv index 913c852b1..263680aea 100644 --- a/src/ieu/bmu/byteop.sv +++ b/src/ieu/bmu/byteop.sv @@ -30,22 +30,16 @@ module byteop #(parameter WIDTH=32) ( input logic [WIDTH-1:0] A, // Operands - input logic [1:0] ByteSelect, // LSB of Immediate + input logic ByteSelect, // LSB of Immediate output logic [WIDTH-1:0] ByteResult); // rev8, orcb result logic [WIDTH-1:0] OrcBResult, Rev8Result; genvar i; - for (i=0;i Date: Wed, 22 May 2024 08:29:08 -0700 Subject: [PATCH 22/51] Reordered Zicond support in ALU --- src/ieu/alu.sv | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/src/ieu/alu.sv b/src/ieu/alu.sv index 783d39495..e1cae73a6 100644 --- a/src/ieu/alu.sv +++ b/src/ieu/alu.sv @@ -60,7 +60,22 @@ module alu import cvw::*; #(parameter cvw_t P) ( // CondShiftA is A for add/sub or a shifted version of A for shift-and-add BMU instructions assign CondMaskInvB = SubArith ? ~CondMaskB : CondMaskB; assign {Carry, Sum} = CondShiftA + CondMaskInvB + {{(P.XLEN-1){1'b0}}, SubArith}; - + + // Zicond block conditionally zeros B + if (P.ZICOND_SUPPORTED) begin: zicond + logic BZero; + + assign BZero = (B == 0); // check if rs2 = 0 + // Create a signal that is 0 when czero.* instruction should clear result + // If B = 0 for czero.eqz or if B != 0 for czero.nez + always_comb + case (CZero) + 2'b01: ZeroCondMaskInvB = {P.XLEN{~BZero}}; // czero.eqz: kill if B = 0 + 2'b10: ZeroCondMaskInvB = {P.XLEN{BZero}}; // czero.nez: kill if B != 0 + default: ZeroCondMaskInvB = CondMaskInvB; // otherwise normal behavior + endcase + end else assign ZeroCondMaskInvB = CondMaskInvB; // no masking if Zicond is not supported + // Shifts (configurable for rotation) shifter #(P) sh(.A, .Amt(B[P.LOG_XLEN-1:0]), .Right(Funct3[2]), .W64, .SubArith, .Y(Shift), .Rotate(BALUControl[2])); @@ -105,18 +120,4 @@ module alu import cvw::*; #(parameter cvw_t P) ( assign CondShiftA = A; end - // Zicond block - if (P.ZICOND_SUPPORTED) begin: zicond - logic BZero; - - assign BZero = (B == 0); // check if rs2 = 0 - // Create a signal that is 0 when czero.* instruction should clear result - // If B = 0 for czero.eqz or if B != 0 for czero.nez - always_comb - case (CZero) - 2'b01: ZeroCondMaskInvB = {P.XLEN{~BZero}}; // czero.eqz: kill if B = 0 - 2'b10: ZeroCondMaskInvB = {P.XLEN{BZero}}; // czero.nez: kill if B != 0 - default: ZeroCondMaskInvB = CondMaskInvB; // otherwise normal behavior - endcase - end else assign ZeroCondMaskInvB = CondMaskInvB; // no masking if Zicond is not supported endmodule From c160ced2d2257df95d3333bd48805f740501775a Mon Sep 17 00:00:00 2001 From: David Harris Date: Wed, 22 May 2024 15:01:20 -0700 Subject: [PATCH 23/51] Zk* cleanup --- src/ieu/bmu/bitmanipalu.sv | 4 ++-- src/ieu/kmu/zbkb.sv | 3 +-- src/ieu/kmu/zbkx.sv | 4 ++-- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/ieu/bmu/bitmanipalu.sv b/src/ieu/bmu/bitmanipalu.sv index 7748b8627..b0af3e347 100644 --- a/src/ieu/bmu/bitmanipalu.sv +++ b/src/ieu/bmu/bitmanipalu.sv @@ -103,12 +103,12 @@ module bitmanipalu import cvw::*; #(parameter cvw_t P) ( // ZBKB Unit if (P.ZBKB_SUPPORTED) begin: zbkb - zbkb #(P.XLEN) ZBKB(.A(ABMU), .B(BBMU), .W64, .Funct3, .ZBKBSelect(ZBBSelect[2:0]), .ZBKBResult); + zbkb #(P.XLEN) ZBKB(.A(ABMU), .B(BBMU), .Funct3, .ZBKBSelect(ZBBSelect[2:0]), .ZBKBResult); end else assign ZBKBResult = '0; // ZBKX Unit if (P.ZBKX_SUPPORTED) begin: zbkx - zbkx #(P.XLEN) ZBKX(.A(ABMU), .B(BBMU), .ZBKXSelect(ZBBSelect[2:0]), .ZBKXResult); + zbkx #(P.XLEN) ZBKX(.A(ABMU), .B(BBMU), .ZBKXSelect(ZBBSelect[0]), .ZBKXResult); end else assign ZBKXResult = '0; // ZKND and ZKNE AES decryption and encryption diff --git a/src/ieu/kmu/zbkb.sv b/src/ieu/kmu/zbkb.sv index 8d437f62f..61173e982 100644 --- a/src/ieu/kmu/zbkb.sv +++ b/src/ieu/kmu/zbkb.sv @@ -27,8 +27,7 @@ module zbkb #(parameter WIDTH=32) ( input logic [WIDTH-1:0] A, B, - input logic W64, - input logic [2:0] Funct3, + input logic [2:0] Funct3, input logic [2:0] ZBKBSelect, output logic [WIDTH-1:0] ZBKBResult ); diff --git a/src/ieu/kmu/zbkx.sv b/src/ieu/kmu/zbkx.sv index dbbaf3d2d..18fe9a657 100644 --- a/src/ieu/kmu/zbkx.sv +++ b/src/ieu/kmu/zbkx.sv @@ -27,7 +27,7 @@ module zbkx #(parameter WIDTH=32) ( input logic [WIDTH-1:0] A, B, - input logic [2:0] ZBKXSelect, + input logic ZBKXSelect, output logic [WIDTH-1:0] ZBKXResult ); @@ -46,5 +46,5 @@ module zbkx #(parameter WIDTH=32) ( end end - assign ZBKXResult = ZBKXSelect[0] ? xperm4 : xperm8; + assign ZBKXResult = ZBKXSelect ? xperm4 : xperm8; endmodule From d9a1691c8323f5ca0c8ec3a1e7086ad0f4f74efd Mon Sep 17 00:00:00 2001 From: David Harris Date: Thu, 23 May 2024 05:39:50 -0700 Subject: [PATCH 24/51] Simplified sha512_32 --- src/ieu/sha/sha512_32.sv | 65 ++++++++++++++-------------------------- 1 file changed, 22 insertions(+), 43 deletions(-) diff --git a/src/ieu/sha/sha512_32.sv b/src/ieu/sha/sha512_32.sv index 679d6d740..4ce8e31ef 100644 --- a/src/ieu/sha/sha512_32.sv +++ b/src/ieu/sha/sha512_32.sv @@ -31,67 +31,46 @@ module sha512_32 ( output logic [31:0] result ); - logic [31:0] x[6][6]; - logic [31:0] y[6]; + logic [31:0] x[6][3]; + logic [31:0] y[3]; // sha512{sig0h/sig0l/sig1h/sig1l/sum0r/sum1r} select shifted operands for 32-bit xor6 // sha512sig0h - assign x[0][0] = A >> 1; - assign x[0][1] = A >> 7; - assign x[0][2] = A >> 8; - assign x[0][3] = B << 31; - assign x[0][4] = B << 24; - assign x[0][5] = '0; + assign x[0][0] = {B[0], A[31:1]}; + assign x[0][1] = {B[7:0], A[31:8]}; + assign x[0][2] = {7'b0, A[31:7]}; // sha512sig0l - assign x[1][0] = A >> 1; - assign x[1][1] = A >> 7; - assign x[1][2] = A >> 8; - assign x[1][3] = B << 31; - assign x[1][4] = B << 25; - assign x[1][5] = B << 24; + assign x[1][0] = x[0][0]; + assign x[1][1] = x[0][1]; + assign x[1][2] = {B[6:0], A[31:7]}; // sha512sig1h - assign x[2][0] = A << 3; - assign x[2][1] = A >> 6; - assign x[2][2] = A >> 19; - assign x[2][3] = B >> 29; - assign x[2][4] = B << 13; - assign x[2][5] = '0; + assign x[2][0] = {A[28:0], B[31:29]}; + assign x[2][1] = {B[18:0], A[31:19]}; + assign x[2][2] = {6'b0, A[31:6]}; // sha512sig1l - assign x[3][0] = A << 3; - assign x[3][1] = A >> 6; - assign x[3][2] = A >> 19; - assign x[3][3] = B >> 29; - assign x[3][4] = B << 26; - assign x[3][5] = B << 13; + assign x[3][0] = x[2][0]; + assign x[3][1] = x[2][1]; + assign x[3][2] = {B[5:0], A[31:6]}; // sha512sum0r - assign x[4][0] = A << 25; - assign x[4][1] = A << 30; - assign x[4][2] = A >> 28; - assign x[4][3] = B >> 7; - assign x[4][4] = B >> 2; - assign x[4][5] = B << 4; + assign x[4][0] = {A[6:0], B[31:7]}; + assign x[4][1] = {A[1:0], B[31:2]}; + assign x[4][2] = {B[27:0], A[31:28]}; // sha512sum1r - assign x[5][0] = A << 23; - assign x[5][1] = A >> 14; - assign x[5][2] = A >> 18; - assign x[5][3] = B >> 9; - assign x[5][4] = B << 18; - assign x[5][5] = B << 14; + assign x[5][0] = {A[8:0], B[31:9]}; + assign x[5][1] = {B[13:0], A[31:14]}; + assign x[5][2] = {B[17:0], A[31:18]}; // 32-bit muxes to select inputs to xor6 for sha512 assign y[0] = x[ZKNHSelect[2:0]][0]; assign y[1] = x[ZKNHSelect[2:0]][1]; assign y[2] = x[ZKNHSelect[2:0]][2]; - assign y[3] = x[ZKNHSelect[2:0]][3]; - assign y[4] = x[ZKNHSelect[2:0]][4]; - assign y[5] = x[ZKNHSelect[2:0]][5]; - + // sha512 32-bit xor6 - assign result = y[0] ^ y[1] ^ y[2] ^ y[3] ^ y[4] ^ y[5]; + assign result = y[0] ^ y[1] ^ y[2]; endmodule From ac153bc4ed75c83983e5953fc763c6a09723e376 Mon Sep 17 00:00:00 2001 From: David Harris Date: Thu, 23 May 2024 05:46:56 -0700 Subject: [PATCH 25/51] More simplifying sha512_32 --- src/ieu/bmu/bmuctrl.sv | 2 +- src/ieu/sha/sha512_32.sv | 46 +++++++++++++++++----------------------- 2 files changed, 20 insertions(+), 28 deletions(-) diff --git a/src/ieu/bmu/bmuctrl.sv b/src/ieu/bmu/bmuctrl.sv index 62376865f..76e08aba8 100644 --- a/src/ieu/bmu/bmuctrl.sv +++ b/src/ieu/bmu/bmuctrl.sv @@ -264,7 +264,7 @@ module bmuctrl import cvw::*; #(parameter cvw_t P) ( 17'b0110011_0101111_000: BMUControlsD = `BMUCTRLW'b000_1000_1010_1_0_0_1_0_0_0_0_0; // sha512sig1h 17'b0110011_0101011_000: BMUControlsD = `BMUCTRLW'b000_1000_1011_1_0_0_1_0_0_0_0_0; // sha512sig1l 17'b0110011_0101000_000: BMUControlsD = `BMUCTRLW'b000_1000_1100_1_0_0_1_0_0_0_0_0; // sha512sum0r - 17'b0110011_0101001_000: BMUControlsD = `BMUCTRLW'b000_1000_1101_1_0_0_1_0_0_0_0_0; // sha512sum1r + 17'b0110011_0101001_000: BMUControlsD = `BMUCTRLW'b000_1000_1110_1_0_0_1_0_0_0_0_0; // sha512sum1r endcase else if (P.XLEN==64) diff --git a/src/ieu/sha/sha512_32.sv b/src/ieu/sha/sha512_32.sv index 4ce8e31ef..484ce3586 100644 --- a/src/ieu/sha/sha512_32.sv +++ b/src/ieu/sha/sha512_32.sv @@ -31,45 +31,37 @@ module sha512_32 ( output logic [31:0] result ); - logic [31:0] x[6][3]; + logic [31:0] x[4][3]; logic [31:0] y[3]; - // sha512{sig0h/sig0l/sig1h/sig1l/sum0r/sum1r} select shifted operands for 32-bit xor6 + // sha512{sig0h/sig0l/sig1h/sig1l/sum0r/sum1r} select shifted operands for 32-bit xor - // sha512sig0h + // The l flavors differ from h by using low bits of B instead of zeros in x[0/1][2] + + // sha512sig0h/l assign x[0][0] = {B[0], A[31:1]}; assign x[0][1] = {B[7:0], A[31:8]}; - assign x[0][2] = {7'b0, A[31:7]}; + assign x[0][2] = {B[6:0] & {7{ZKNHSelect[0]}}, A[31:7]}; - // sha512sig0l - assign x[1][0] = x[0][0]; - assign x[1][1] = x[0][1]; - assign x[1][2] = {B[6:0], A[31:7]}; - - // sha512sig1h - assign x[2][0] = {A[28:0], B[31:29]}; - assign x[2][1] = {B[18:0], A[31:19]}; - assign x[2][2] = {6'b0, A[31:6]}; - - // sha512sig1l - assign x[3][0] = x[2][0]; - assign x[3][1] = x[2][1]; - assign x[3][2] = {B[5:0], A[31:6]}; + // sha512sig1h/l + assign x[1][0] = {A[28:0], B[31:29]}; + assign x[1][1] = {B[18:0], A[31:19]}; + assign x[1][2] = {B[5:0] & {6{ZKNHSelect[0]}}, A[31:6]}; // sha512sum0r - assign x[4][0] = {A[6:0], B[31:7]}; - assign x[4][1] = {A[1:0], B[31:2]}; - assign x[4][2] = {B[27:0], A[31:28]}; + assign x[2][0] = {A[6:0], B[31:7]}; + assign x[2][1] = {A[1:0], B[31:2]}; + assign x[2][2] = {B[27:0], A[31:28]}; // sha512sum1r - assign x[5][0] = {A[8:0], B[31:9]}; - assign x[5][1] = {B[13:0], A[31:14]}; - assign x[5][2] = {B[17:0], A[31:18]}; + assign x[3][0] = {A[8:0], B[31:9]}; + assign x[3][1] = {B[13:0], A[31:14]}; + assign x[3][2] = {B[17:0], A[31:18]}; // 32-bit muxes to select inputs to xor6 for sha512 - assign y[0] = x[ZKNHSelect[2:0]][0]; - assign y[1] = x[ZKNHSelect[2:0]][1]; - assign y[2] = x[ZKNHSelect[2:0]][2]; + assign y[0] = x[ZKNHSelect[2:1]][0]; + assign y[1] = x[ZKNHSelect[2:1]][1]; + assign y[2] = x[ZKNHSelect[2:1]][2]; // sha512 32-bit xor6 assign result = y[0] ^ y[1] ^ y[2]; From fb8e97dd04eac8e981b0f48ec99f03ca520f99a5 Mon Sep 17 00:00:00 2001 From: Jordan Carlin Date: Thu, 23 May 2024 13:17:24 -0700 Subject: [PATCH 26/51] Remove existing derived configs before creating new ones --- sim/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/sim/Makefile b/sim/Makefile index 09d417124..79a3042e4 100644 --- a/sim/Makefile +++ b/sim/Makefile @@ -62,6 +62,7 @@ coveragetests: make -C ../tests/coverage/ --jobs deriv: + rm -rf ../config/deriv derivgen.pl benchmarks: From 6a2192db6e0201a521c33e91705814040a91ecee Mon Sep 17 00:00:00 2001 From: Jordan Carlin Date: Thu, 23 May 2024 13:56:38 -0700 Subject: [PATCH 27/51] Revert "Remove existing derived configs before creating new ones" --- sim/Makefile | 1 - 1 file changed, 1 deletion(-) diff --git a/sim/Makefile b/sim/Makefile index 79a3042e4..09d417124 100644 --- a/sim/Makefile +++ b/sim/Makefile @@ -62,7 +62,6 @@ coveragetests: make -C ../tests/coverage/ --jobs deriv: - rm -rf ../config/deriv derivgen.pl benchmarks: From a1e22adc1ed3f66ce0bf7a288a678922de9dbb20 Mon Sep 17 00:00:00 2001 From: Jordan Carlin Date: Thu, 23 May 2024 14:01:13 -0700 Subject: [PATCH 28/51] Delete deriv directory in derivgen.pl before remaking derived configs --- bin/derivgen.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/derivgen.pl b/bin/derivgen.pl index 630962ca8..442455c53 100755 --- a/bin/derivgen.pl +++ b/bin/derivgen.pl @@ -70,10 +70,10 @@ foreach my $line (<$fh>) { } &terminateDeriv(); close($fh); +system("rm -rf $ENV{WALLY}/config/deriv"); #foreach my $key (keys %derivs) { foreach my $key (@derivnames) { my $dir = "$ENV{WALLY}/config/deriv/$key"; - system("rm -rf $dir"); system("mkdir -p $dir"); my $configunmod = "$dir/config_unmod.vh"; my $config = "$dir/config.vh"; From b0d13441217c50ae744b03f9162ec5a46d599e92 Mon Sep 17 00:00:00 2001 From: David Harris Date: Thu, 23 May 2024 22:06:37 -0700 Subject: [PATCH 29/51] Commented sha instructions --- src/ieu/sha/sha256.sv | 30 +++++++++++++++--------------- src/ieu/sha/sha512_32.sv | 29 +++++++++++++++-------------- src/ieu/sha/sha512_64.sv | 34 +++++++++++++++++----------------- 3 files changed, 47 insertions(+), 46 deletions(-) diff --git a/src/ieu/sha/sha256.sv b/src/ieu/sha/sha256.sv index 118f9e24b..12d08f2ce 100644 --- a/src/ieu/sha/sha256.sv +++ b/src/ieu/sha/sha256.sv @@ -37,29 +37,29 @@ module sha256 ( // sha256{sig0/sig1/sum0/sum1} select shifted operands for 32-bit xor3 and then sign-extend // sha256sig0 - assign x[0][0] = {A[6:0], A[31:7]}; - assign x[0][1] = {A[17:0], A[31:18]}; - assign x[0][2] = {3'b0, A[31:3]}; + assign x[0][0] = {A[6:0], A[31:7]}; // ror 7 + assign x[0][1] = {A[17:0], A[31:18]}; // ror 18 + assign x[0][2] = {3'b0, A[31:3]}; // >> 3 // sha256sig1 - assign x[1][0] = {A[16:0], A[31:17]}; - assign x[1][1] = {A[18:0], A[31:19]}; - assign x[1][2] = {10'b0, A[31:10]}; + assign x[1][0] = {A[16:0], A[31:17]}; // ror 17 + assign x[1][1] = {A[18:0], A[31:19]}; // ror 19 + assign x[1][2] = {10'b0, A[31:10]}; // >> 10 // sha256sum0 - assign x[2][0] = {A[1:0], A[31:2]}; - assign x[2][1] = {A[12:0], A[31:13]}; - assign x[2][2] = {A[21:0], A[31:22]}; + assign x[2][0] = {A[1:0], A[31:2]}; // ror 2 + assign x[2][1] = {A[12:0], A[31:13]}; // ror 13 + assign x[2][2] = {A[21:0], A[31:22]}; // ror 22 // sha256sum1 - assign x[3][0] = {A[5:0], A[31:6]}; - assign x[3][1] ={A[10:0], A[31:11]}; - assign x[3][2] = {A[24:0], A[31:25]}; + assign x[3][0] = {A[5:0], A[31:6]}; // ror 6 + assign x[3][1] ={ A[10:0], A[31:11]}; // ror 11 + assign x[3][2] = {A[24:0], A[31:25]}; // ror 25 // 32-bit muxes to select inputs to xor3 for sha256 - assign y[0] = x[ZKNHSelect[1:0]][0]; - assign y[1] = x[ZKNHSelect[1:0]][1]; - assign y[2] = x[ZKNHSelect[1:0]][2]; + assign y[0] = x[ZKNHSelect[1:0]][0]; + assign y[1] = x[ZKNHSelect[1:0]][1]; + assign y[2] = x[ZKNHSelect[1:0]][2]; // sha256 32-bit xor3 assign result = y[0] ^ y[1] ^ y[2]; diff --git a/src/ieu/sha/sha512_32.sv b/src/ieu/sha/sha512_32.sv index 484ce3586..ce205172c 100644 --- a/src/ieu/sha/sha512_32.sv +++ b/src/ieu/sha/sha512_32.sv @@ -34,33 +34,34 @@ module sha512_32 ( logic [31:0] x[4][3]; logic [31:0] y[3]; + // rotate/shift a 64-bit value contained in {B, A} and select 32 bits // sha512{sig0h/sig0l/sig1h/sig1l/sum0r/sum1r} select shifted operands for 32-bit xor // The l flavors differ from h by using low bits of B instead of zeros in x[0/1][2] // sha512sig0h/l - assign x[0][0] = {B[0], A[31:1]}; - assign x[0][1] = {B[7:0], A[31:8]}; - assign x[0][2] = {B[6:0] & {7{ZKNHSelect[0]}}, A[31:7]}; + assign x[0][0] = {B[0], A[31:1]}; // ror 1 + assign x[0][1] = {B[7:0], A[31:8]}; // ror 8 + assign x[0][2] = {B[6:0] & {7{ZKNHSelect[0]}}, A[31:7]}; // ror/srl 7 // sha512sig1h/l - assign x[1][0] = {A[28:0], B[31:29]}; - assign x[1][1] = {B[18:0], A[31:19]}; - assign x[1][2] = {B[5:0] & {6{ZKNHSelect[0]}}, A[31:6]}; + assign x[1][0] = {A[28:0], B[31:29]}; // ror 61 + assign x[1][1] = {B[18:0], A[31:19]}; // ror 19 + assign x[1][2] = {B[5:0] & {6{ZKNHSelect[0]}}, A[31:6]}; // ror/srl 6 // sha512sum0r - assign x[2][0] = {A[6:0], B[31:7]}; - assign x[2][1] = {A[1:0], B[31:2]}; - assign x[2][2] = {B[27:0], A[31:28]}; + assign x[2][0] = {A[6:0], B[31:7]}; // ror 39 + assign x[2][1] = {A[1:0], B[31:2]}; // ror 34 + assign x[2][2] = {B[27:0], A[31:28]}; // ror 28 // sha512sum1r - assign x[3][0] = {A[8:0], B[31:9]}; - assign x[3][1] = {B[13:0], A[31:14]}; - assign x[3][2] = {B[17:0], A[31:18]}; + assign x[3][0] = {A[8:0], B[31:9]}; // ror 41 + assign x[3][1] = {B[13:0], A[31:14]}; // ror 14 + assign x[3][2] = {B[17:0], A[31:18]}; // ror 18 // 32-bit muxes to select inputs to xor6 for sha512 - assign y[0] = x[ZKNHSelect[2:1]][0]; - assign y[1] = x[ZKNHSelect[2:1]][1]; + assign y[0] = x[ZKNHSelect[2:1]][0]; + assign y[1] = x[ZKNHSelect[2:1]][1]; assign y[2] = x[ZKNHSelect[2:1]][2]; // sha512 32-bit xor6 diff --git a/src/ieu/sha/sha512_64.sv b/src/ieu/sha/sha512_64.sv index 8707311e8..47fefce04 100644 --- a/src/ieu/sha/sha512_64.sv +++ b/src/ieu/sha/sha512_64.sv @@ -33,33 +33,33 @@ module sha512_64 ( logic [63:0] x[4][3]; logic [63:0] y[3]; - - // sha512{sig0/sig1/sum0/sum1} select shifted operands for 64-bit xor3 + + // sha512{sig0/sig1/sum0/sum1} select rotated/shifted operands for 64-bit xor3 // sha512sig0 - assign x[0][0] = {A[0], A[63:1]}; - assign x[0][1] = {A[7:0], A[63:8]}; - assign x[0][2] = A >> 7; + assign x[0][0] = {A[0], A[63:1]}; // ror 1 + assign x[0][1] = {A[7:0], A[63:8]}; // ror 8 + assign x[0][2] = {7'b0, A[63:7]}; // >> 7 // sha512sig1 - assign x[1][0] = {A[18:0], A[63:19]}; - assign x[1][1] = {A[60:0], A[63:61]}; - assign x[1][2] = A >> 6; + assign x[1][0] = {A[18:0], A[63:19]}; // ror 19 + assign x[1][1] = {A[60:0], A[63:61]}; // ror 61 + assign x[1][2] = {6'b0, A[63:6]}; // >> 6 // sha512sum0 - assign x[2][0] = {A[27:0], A[63:28]}; - assign x[2][1] = {A[33:0], A[63:34]}; - assign x[2][2] = {A[38:0], A[63:39]}; + assign x[2][0] = {A[27:0], A[63:28]}; // ror 28 + assign x[2][1] = {A[33:0], A[63:34]}; // ror 34 + assign x[2][2] = {A[38:0], A[63:39]}; // ror 39 // sha512sum1 - assign x[3][0] = {A[13:0], A[63:14]}; - assign x[3][1] = {A[17:0], A[63:18]}; - assign x[3][2] = {A[40:0], A[63:41]}; + assign x[3][0] = {A[13:0], A[63:14]}; // ror 14 + assign x[3][1] = {A[17:0], A[63:18]}; // ror 18 + assign x[3][2] = {A[40:0], A[63:41]}; // ror 41 // 64-bit muxes to select inputs to xor3 for sha512 - assign y[0] = x[ZKNHSelect[1:0]][0]; - assign y[1] = x[ZKNHSelect[1:0]][1]; - assign y[2] = x[ZKNHSelect[1:0]][2]; + assign y[0] = x[ZKNHSelect[1:0]][0]; + assign y[1] = x[ZKNHSelect[1:0]][1]; + assign y[2] = x[ZKNHSelect[1:0]][2]; // sha512 64-bit xor3 assign result = y[0] ^ y[1] ^ y[2]; From e626052ec93c5a402d7109ce01538556b304cf53 Mon Sep 17 00:00:00 2001 From: David Harris Date: Thu, 23 May 2024 22:30:25 -0700 Subject: [PATCH 30/51] simplified AES32de mixcolumns because input is only one byte --- src/ieu/aes/aes32d.sv | 6 ++-- src/ieu/aes/aes32e.sv | 8 +++--- src/ieu/aes/aes64d.sv | 2 +- src/ieu/aes/aes64e.sv | 2 +- src/ieu/aes/aesinvmixcolumns8.sv | 47 ++++++++++++++++++++++++++++++++ src/ieu/aes/aesmixcolumns8.sv | 39 ++++++++++++++++++++++++++ 6 files changed, 95 insertions(+), 9 deletions(-) create mode 100644 src/ieu/aes/aesinvmixcolumns8.sv create mode 100644 src/ieu/aes/aesmixcolumns8.sv diff --git a/src/ieu/aes/aes32d.sv b/src/ieu/aes/aes32d.sv index e3eb61cec..f761b5060 100644 --- a/src/ieu/aes/aes32d.sv +++ b/src/ieu/aes/aes32d.sv @@ -34,8 +34,8 @@ module aes32d( logic [7:0] SboxOut; logic [31:0] so, mixed; - aesinvsbox8 inv_sbox(SboxIn, SboxOut); // Apply inverse sbox to si - assign so = {24'h0, SboxOut}; // Pad output of inverse substitution box - aesinvmixcolumns32 mix(so, mixed); // Run so through the mixword AES function + aesinvsbox8 inv_sbox(SboxIn, SboxOut); // Apply inverse sbox to si + aesinvmixcolumns8 mix(SboxOut, mixed); // Run so through the InvMixColumns AES function + assign so = {24'h0, SboxOut}; // Pad output of inverse substitution box mux2 #(32) rmux(mixed, so, finalround, result); // on final round, skip mixcolumns endmodule diff --git a/src/ieu/aes/aes32e.sv b/src/ieu/aes/aes32e.sv index ca00afdd3..ab28db196 100644 --- a/src/ieu/aes/aes32e.sv +++ b/src/ieu/aes/aes32e.sv @@ -34,8 +34,8 @@ module aes32e( logic [7:0] SboxOut; logic [31:0] so, mixed; - aessbox8 sbox(SboxIn, SboxOut); // Substitute - assign so = {24'h0, SboxOut}; // Pad sbox output - aesmixcolumns32 mwd(so, mixed); // Mix Word using aesmixword component - mux2 #(32) rmux(mixed, so, finalround, result); // on final round, skip mixcolumns + aessbox8 sbox(SboxIn, SboxOut); // Substitute + assign so = {24'h0, SboxOut}; // Pad sbox output + aesmixcolumns32 mb(so, mixed); // Mix using MixColumns component + mux2 #(32) rmux(mixed, so, finalround, result); // on final round, skip MixColumns endmodule diff --git a/src/ieu/aes/aes64d.sv b/src/ieu/aes/aes64d.sv index 96355a566..a9e6feb75 100644 --- a/src/ieu/aes/aes64d.sv +++ b/src/ieu/aes/aes64d.sv @@ -42,7 +42,7 @@ module aes64d( mux2 #(64) mixcolmux(SboxOut, rs1, aes64im, MixcolIn); - // Apply inverse mixword to sbox outputs + // Apply inverse MixColumns to sbox outputs aesinvmixcolumns32 invmw0(MixcolIn[31:0], MixcolOut[31:0]); aesinvmixcolumns32 invmw1(MixcolIn[63:32], MixcolOut[63:32]); diff --git a/src/ieu/aes/aes64e.sv b/src/ieu/aes/aes64e.sv index b37d8787c..7435f4327 100644 --- a/src/ieu/aes/aes64e.sv +++ b/src/ieu/aes/aes64e.sv @@ -46,7 +46,7 @@ module aes64e( aessbox32 sbox1(ShiftRowOut[63:32], SboxOut[63:32]); // instantiate second sbox - // Apply mix columns operations + // Apply MixColumns operations aesmixcolumns32 mw0(SboxOut[31:0], MixcolOut[31:0]); aesmixcolumns32 mw1(SboxOut[63:32], MixcolOut[63:32]); diff --git a/src/ieu/aes/aesinvmixcolumns8.sv b/src/ieu/aes/aesinvmixcolumns8.sv new file mode 100644 index 000000000..134ceeb11 --- /dev/null +++ b/src/ieu/aes/aesinvmixcolumns8.sv @@ -0,0 +1,47 @@ +/////////////////////////////////////////// +// aesinvmixcolumns8.sv +// +// Written: kelvin.tran@okstate.edu, james.stine@okstate.edu +// Created: 05 March 2024 +// +// Purpose: AES Inverted Mix Column Function for use with AES +// +// 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 aesinvmixcolumns8( + input logic [7:0] a, + output logic [31:0] y +); + + logic [10:0] t, x0, x1, x2, x3; + + // aes32d operates on shifted versions of the input + assign t = {a, 3'b0} ^ {3'b0, a}; + assign x0 = {a, 3'b0} ^ {1'b0, a, 2'b0} ^ {2'b0, a, 1'b0}; + assign x1 = t; + assign x2 = t ^ {1'b0, a, 2'b0}; + assign x3 = t ^ {2'b0, a, 1'b0}; + + galoismultinverse8 gm0 (x0, y[7:0]); + galoismultinverse8 gm1 (x1, y[15:8]); + galoismultinverse8 gm2 (x2, y[23:16]); + galoismultinverse8 gm3 (x3, y[31:24]); + + endmodule diff --git a/src/ieu/aes/aesmixcolumns8.sv b/src/ieu/aes/aesmixcolumns8.sv new file mode 100644 index 000000000..66ab6534f --- /dev/null +++ b/src/ieu/aes/aesmixcolumns8.sv @@ -0,0 +1,39 @@ +/////////////////////////////////////////// +// aesmixcolumns8.sv +// +// Written: ryan.swann@okstate.edu, james.stine@okstate.edu, David_Harris@hmc.edu +// Created: 20 February 2024 +// +// Purpose: Galois field operation to byte in an individual 32-bit word +// +// 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 aesmixcolumns8( + input logic [7:0] a, + output logic [31:0] y +); + + logic [7:0] xa, xapa; + + galoismultforward8 gm(a, xa); // xa + assign xapa = a ^ xa; // a ^ xa + assign y = {xapa, a, a, xa}; +endmodule From ec5c67a5c12b52435686c2c7df03fe42d467ec3b Mon Sep 17 00:00:00 2001 From: David Harris Date: Fri, 24 May 2024 13:48:53 -0700 Subject: [PATCH 31/51] AES cleanup --- src/ieu/aes/aes64e.sv | 2 +- src/ieu/aes/aesmixcolumns8.sv | 2 +- src/ieu/bmu/bitmanipalu.sv | 4 ++-- src/ieu/kmu/zknde32.sv | 7 ++++--- src/ieu/kmu/zknde64.sv | 7 ++++--- 5 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/ieu/aes/aes64e.sv b/src/ieu/aes/aes64e.sv index 7435f4327..c1ca9013e 100644 --- a/src/ieu/aes/aes64e.sv +++ b/src/ieu/aes/aes64e.sv @@ -48,7 +48,7 @@ module aes64e( // Apply MixColumns operations aesmixcolumns32 mw0(SboxOut[31:0], MixcolOut[31:0]); - aesmixcolumns32 mw1(SboxOut[63:32], MixcolOut[63:32]); + aesmixcolumns32 mw1(SboxOut[63:32], MixcolOut[63:32]); // Skip mixcolumns on last round mux2 #(64) resultmux(MixcolOut, SboxOut, finalround, result); diff --git a/src/ieu/aes/aesmixcolumns8.sv b/src/ieu/aes/aesmixcolumns8.sv index 66ab6534f..256f728d0 100644 --- a/src/ieu/aes/aesmixcolumns8.sv +++ b/src/ieu/aes/aesmixcolumns8.sv @@ -27,7 +27,7 @@ module aesmixcolumns8( - input logic [7:0] a, + input logic [7:0] a, output logic [31:0] y ); diff --git a/src/ieu/bmu/bitmanipalu.sv b/src/ieu/bmu/bitmanipalu.sv index b0af3e347..36feff63e 100644 --- a/src/ieu/bmu/bitmanipalu.sv +++ b/src/ieu/bmu/bitmanipalu.sv @@ -113,8 +113,8 @@ module bitmanipalu import cvw::*; #(parameter cvw_t P) ( // ZKND and ZKNE AES decryption and encryption if (P.ZKND_SUPPORTED | P.ZKNE_SUPPORTED) begin: zknde - if (P.XLEN == 32) zknde32 #(P) ZKN32(.A(ABMU), .B(BBMU), .Funct7, .round(Rs2E[3:0]), .ZKNSelect(ZBBSelect[3:0]), .ZKNDEResult); - else zknde64 #(P) ZKN64(.A(ABMU), .B(BBMU), .Funct7, .round(Rs2E[3:0]), .ZKNSelect(ZBBSelect[3:0]), .ZKNDEResult); + if (P.XLEN == 32) zknde32 #(P) ZKN32(.A(ABMU), .B(BBMU), .bs(Funct7[6:5]), .round(Rs2E[3:0]), .ZKNSelect(ZBBSelect[3:0]), .ZKNDEResult); + else zknde64 #(P) ZKN64(.A(ABMU), .B(BBMU), .round(Rs2E[3:0]), .ZKNSelect(ZBBSelect[3:0]), .ZKNDEResult); end else assign ZKNDEResult = '0; // ZKNH Unit diff --git a/src/ieu/kmu/zknde32.sv b/src/ieu/kmu/zknde32.sv index 4c845599c..7e482d757 100644 --- a/src/ieu/kmu/zknde32.sv +++ b/src/ieu/kmu/zknde32.sv @@ -28,7 +28,7 @@ module zknde32 import cvw::*; #(parameter cvw_t P) ( input logic [31:0] A, B, - input logic [6:0] Funct7, + input logic [1:0] bs, input logic [3:0] round, input logic [3:0] ZKNSelect, output logic [31:0] ZKNDEResult @@ -39,7 +39,7 @@ module zknde32 import cvw::*; #(parameter cvw_t P) ( logic [31:0] ZKNEResult, ZKNDResult, rotin, rotout; // Initial shamt and Sbox input selection steps shared between encrypt and decrypt - assign shamt = {Funct7[6:5], 3'b0}; // shamt = bs * 8 (convert bytes to bits) + assign shamt = {bs, 3'b0}; // shamt = bs * 8 (convert bytes to bits) assign SboxIn = B[shamt +: 8]; // select byte bs of rs2 // Handle logic specific to encrypt or decrypt @@ -55,6 +55,7 @@ module zknde32 import cvw::*; #(parameter cvw_t P) ( assign rotin = ZKNEResult; // final rotate and XOR steps shared between encrypt and decrypt - rotate #(32) mrot(rotin, shamt, rotout); // Rotate the mixcolumns output left by shamt (bs * 8) + mux4 #(32) mrotmux(rotin, {rotin[23:0], rotin[31:24]}, + {rotin[15:0], rotin[31:16]}, {rotin[7:0], rotin[31:8]}, bs, rotout); // Rotate the mixcolumns output left by shamt (bs * 8) assign ZKNDEResult = A ^ rotout; // xor with running value (A = rs1) endmodule diff --git a/src/ieu/kmu/zknde64.sv b/src/ieu/kmu/zknde64.sv index 2a2b6cc10..9c2566718 100644 --- a/src/ieu/kmu/zknde64.sv +++ b/src/ieu/kmu/zknde64.sv @@ -28,7 +28,6 @@ module zknde64 import cvw::*; #(parameter cvw_t P) ( input logic [63:0] A, B, - input logic [6:0] Funct7, input logic [3:0] round, input logic [3:0] ZKNSelect, output logic [63:0] ZKNDEResult @@ -39,11 +38,13 @@ module zknde64 import cvw::*; #(parameter cvw_t P) ( if (P.ZKND_SUPPORTED) // ZKND supports aes64ds, aes64dsm, aes64im aes64d aes64d(.rs1(A), .rs2(B), .finalround(ZKNSelect[2]), .aes64im(ZKNSelect[3]), .result(aes64dRes)); // decode AES - if (P.ZKNE_SUPPORTED) // ZKNE supports aes64es, aes64esm + if (P.ZKNE_SUPPORTED) begin // ZKNE supports aes64es, aes64esm aes64e aes64e(.rs1(A), .rs2(B), .finalround(ZKNSelect[2]), .Sbox0Out, .SboxEIn, .result(aes64eRes)); + mux2 #(32) sboxmux(SboxEIn, SboxKIn, ZKNSelect[1], Sbox0In); + end else + assign Sbox0In = SboxKIn; // One S Box is always needed for aes64ks1i and is also needed for aes64e if that is supported. Put it at the top level to allow sharing - mux2 #(32) sboxmux(SboxEIn, SboxKIn, ZKNSelect[1], Sbox0In); aessbox32 sbox(Sbox0In, Sbox0Out); // Substitute bytes of value obtained for tmp2 using Rijndael sbox // Both ZKND and ZKNE support aes64ks1i and aes64ks2 instructions From b2689b4f01620e8f4dfb22a2e9ae085a5cbfec26 Mon Sep 17 00:00:00 2001 From: David Harris Date: Fri, 24 May 2024 14:13:57 -0700 Subject: [PATCH 32/51] AES cleanup --- src/ieu/aes/aes64d.sv | 6 ++-- src/ieu/aes/aes64e.sv | 8 ++--- ...sinvshiftrow64.sv => aesinvshiftrows64.sv} | 6 ++-- .../{aesshiftrow64.sv => aesshiftrows64.sv} | 4 +-- src/ieu/aes/aesshiftrows64.xv | 35 +++++++++++++++++++ 5 files changed, 47 insertions(+), 12 deletions(-) rename src/ieu/aes/{aesinvshiftrow64.sv => aesinvshiftrows64.sv} (94%) rename src/ieu/aes/{aesshiftrow64.sv => aesshiftrows64.sv} (96%) create mode 100644 src/ieu/aes/aesshiftrows64.xv diff --git a/src/ieu/aes/aes64d.sv b/src/ieu/aes/aes64d.sv index a9e6feb75..8934f74c3 100644 --- a/src/ieu/aes/aes64d.sv +++ b/src/ieu/aes/aes64d.sv @@ -32,13 +32,13 @@ module aes64d( output logic [63:0] result ); - logic [63:0] ShiftRowOut, SboxOut, MixcolIn, MixcolOut; + logic [63:0] ShiftRowsOut, SboxOut, MixcolIn, MixcolOut; // Apply inverse shiftrows to rs2 and rs1 - aesinvshiftrow64 srow({rs2, rs1}, ShiftRowOut); + aesinvshiftrows64 srow({rs2, rs1}, ShiftRowsOut); // Apply full word inverse substitution to lower doubleord of shiftrow out - aesinvsbox64 invsbox(ShiftRowOut, SboxOut); + aesinvsbox64 invsbox(ShiftRowsOut, SboxOut); mux2 #(64) mixcolmux(SboxOut, rs1, aes64im, MixcolIn); diff --git a/src/ieu/aes/aes64e.sv b/src/ieu/aes/aes64e.sv index c1ca9013e..f40535d8d 100644 --- a/src/ieu/aes/aes64e.sv +++ b/src/ieu/aes/aes64e.sv @@ -34,17 +34,17 @@ module aes64e( output logic [63:0] result ); - logic [63:0] ShiftRowOut, SboxOut, MixcolOut; + logic [63:0] ShiftRowsOut, SboxOut, MixcolOut; // AES shiftrow unit - aesshiftrow64 srow({rs2,rs1}, ShiftRowOut); + aesshiftrows64 srow({rs2,rs1}, ShiftRowsOut); // Apply substitution box to 2 lower words // Use the shared sbox in zknde64.sv for the first sbox - assign SboxEIn = ShiftRowOut[31:0]; + assign SboxEIn = ShiftRowsOut[31:0]; assign SboxOut[31:0] = Sbox0Out; - aessbox32 sbox1(ShiftRowOut[63:32], SboxOut[63:32]); // instantiate second sbox + aessbox32 sbox1(ShiftRowsOut[63:32], SboxOut[63:32]); // instantiate second sbox // Apply MixColumns operations aesmixcolumns32 mw0(SboxOut[31:0], MixcolOut[31:0]); diff --git a/src/ieu/aes/aesinvshiftrow64.sv b/src/ieu/aes/aesinvshiftrows64.sv similarity index 94% rename from src/ieu/aes/aesinvshiftrow64.sv rename to src/ieu/aes/aesinvshiftrows64.sv index c6d355b63..c934116ac 100644 --- a/src/ieu/aes/aesinvshiftrow64.sv +++ b/src/ieu/aes/aesinvshiftrows64.sv @@ -1,5 +1,5 @@ /////////////////////////////////////////// -// aesinvshiftrow.sv +// aesinvshiftrows64.sv // // Written: ryan.swann@okstate.edu, james.stine@okstate.edu // Created: 20 February 2024 @@ -25,9 +25,9 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -module aesinvshiftrow64( +module aesinvshiftrows64( input logic [127:0] a, - output logic [63:0] y + output logic [63:0] y ); assign y = {a[95:88], a[119:112], a[15:8], a[39:32], diff --git a/src/ieu/aes/aesshiftrow64.sv b/src/ieu/aes/aesshiftrows64.sv similarity index 96% rename from src/ieu/aes/aesshiftrow64.sv rename to src/ieu/aes/aesshiftrows64.sv index 8691a9946..7c8a68120 100644 --- a/src/ieu/aes/aesshiftrow64.sv +++ b/src/ieu/aes/aesshiftrows64.sv @@ -1,5 +1,5 @@ /////////////////////////////////////////// -// aesshiftrow.sv +// aesshiftrows64.sv // // Written: ryan.swann@okstate.edu, james.stine@okstate.edu // Created: 20 February 2024 @@ -25,7 +25,7 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -module aesshiftrow64( +module aesshiftrows64( input logic [127:0] a, output logic [63:0] y ); diff --git a/src/ieu/aes/aesshiftrows64.xv b/src/ieu/aes/aesshiftrows64.xv new file mode 100644 index 000000000..58638cea5 --- /dev/null +++ b/src/ieu/aes/aesshiftrows64.xv @@ -0,0 +1,35 @@ +/////////////////////////////////////////// +// 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 From a95977590dceb76120dc2240b6810f421664f998 Mon Sep 17 00:00:00 2001 From: David Harris Date: Fri, 24 May 2024 14:28:30 -0700 Subject: [PATCH 33/51] AES cleanup --- src/ieu/aes/aes64d.sv | 10 +++++----- src/ieu/aes/aes64e.sv | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/ieu/aes/aes64d.sv b/src/ieu/aes/aes64d.sv index 8934f74c3..517dd4bf0 100644 --- a/src/ieu/aes/aes64d.sv +++ b/src/ieu/aes/aes64d.sv @@ -32,7 +32,7 @@ module aes64d( output logic [63:0] result ); - logic [63:0] ShiftRowsOut, SboxOut, MixcolIn, MixcolOut; + logic [63:0] ShiftRowsOut, SboxOut, MixcolsIn, MixcolsOut; // Apply inverse shiftrows to rs2 and rs1 aesinvshiftrows64 srow({rs2, rs1}, ShiftRowsOut); @@ -40,12 +40,12 @@ module aes64d( // Apply full word inverse substitution to lower doubleord of shiftrow out aesinvsbox64 invsbox(ShiftRowsOut, SboxOut); - mux2 #(64) mixcolmux(SboxOut, rs1, aes64im, MixcolIn); + mux2 #(64) mixcolmux(SboxOut, rs1, aes64im, MixcolsIn); // Apply inverse MixColumns to sbox outputs - aesinvmixcolumns32 invmw0(MixcolIn[31:0], MixcolOut[31:0]); - aesinvmixcolumns32 invmw1(MixcolIn[63:32], MixcolOut[63:32]); + aesinvmixcolumns32 invmw0(MixcolsIn[31:0], MixcolsOut[31:0]); + aesinvmixcolumns32 invmw1(MixcolsIn[63:32], MixcolsOut[63:32]); // Final round skips mixcolumns. - mux2 #(64) resultmux(MixcolOut, SboxOut, finalround, result); + mux2 #(64) resultmux(MixcolsOut, SboxOut, finalround, result); endmodule diff --git a/src/ieu/aes/aes64e.sv b/src/ieu/aes/aes64e.sv index f40535d8d..f4b59178a 100644 --- a/src/ieu/aes/aes64e.sv +++ b/src/ieu/aes/aes64e.sv @@ -34,7 +34,7 @@ module aes64e( output logic [63:0] result ); - logic [63:0] ShiftRowsOut, SboxOut, MixcolOut; + logic [63:0] ShiftRowsOut, SboxOut, MixcolsOut; // AES shiftrow unit aesshiftrows64 srow({rs2,rs1}, ShiftRowsOut); @@ -47,9 +47,9 @@ module aes64e( aessbox32 sbox1(ShiftRowsOut[63:32], SboxOut[63:32]); // instantiate second sbox // Apply MixColumns operations - aesmixcolumns32 mw0(SboxOut[31:0], MixcolOut[31:0]); - aesmixcolumns32 mw1(SboxOut[63:32], MixcolOut[63:32]); + aesmixcolumns32 mw0(SboxOut[31:0], MixcolsOut[31:0]); + aesmixcolumns32 mw1(SboxOut[63:32], MixcolsOut[63:32]); // Skip mixcolumns on last round - mux2 #(64) resultmux(MixcolOut, SboxOut, finalround, result); + mux2 #(64) resultmux(MixcolsOut, SboxOut, finalround, result); endmodule From dcafe4793ed6ec8cdf674eb6de3124e38c207ebd Mon Sep 17 00:00:00 2001 From: Jordan Carlin Date: Fri, 24 May 2024 15:16:35 -0700 Subject: [PATCH 34/51] Add froundnx and fround.d tests --- testbench/tests.vh | 10 +- .../rv32i_m/D_Zfa/src/froundnx.d_b1-01.S | 353 ++++++++++++++++++ .../rv32i_m/D_Zfa/src/froundnx_b1-01.S | 353 ++++++++++++++++++ .../rv32i_m/F_Zfa/src/froundnx_b1-01.S | 353 ++++++++++++++++++ .../rv64i_m/D_Zfa/src/froundnx.d_b1-01.S | 353 ++++++++++++++++++ .../rv64i_m/D_Zfa/src/froundnx_b1-01.S | 353 ++++++++++++++++++ .../rv64i_m/F_Zfa/src/froundnx_b1-01.S | 353 ++++++++++++++++++ 7 files changed, 2127 insertions(+), 1 deletion(-) create mode 100644 tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/D_Zfa/src/froundnx.d_b1-01.S create mode 100644 tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/D_Zfa/src/froundnx_b1-01.S create mode 100644 tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/F_Zfa/src/froundnx_b1-01.S create mode 100644 tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/D_Zfa/src/froundnx.d_b1-01.S create mode 100644 tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/D_Zfa/src/froundnx_b1-01.S create mode 100644 tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/F_Zfa/src/froundnx_b1-01.S diff --git a/testbench/tests.vh b/testbench/tests.vh index 0386dba6e..44e72d53d 100644 --- a/testbench/tests.vh +++ b/testbench/tests.vh @@ -2279,6 +2279,7 @@ string arch64zknh[] = '{ //`RISCVARCHTEST, `WALLYTEST, "rv32i_m/F_Zfa/src/fround_b1-01.S", + "rv32i_m/F_Zfa/src/froundnx_b1-01.S", "rv32i_m/F_Zfa/src/fleq_b1-01.S", "rv32i_m/F_Zfa/src/fleq_b19-01.S", "rv32i_m/F_Zfa/src/fli.s-01.S", @@ -2296,6 +2297,9 @@ string arch64zknh[] = '{ //`RISCVARCHTEST, `WALLYTEST, "rv32i_m/D_Zfa/src/fround_b1-01.S", + "rv32i_m/D_Zfa/src/froundnx_b1-01.S", + "rv32i_m/D_Zfa/src/fround.d_b1-01.S", + "rv32i_m/D_Zfa/src/froundnx.d_b1-01.S", "rv32i_m/D_Zfa/src/fcvtmod.w.d_b1-01.S", "rv32i_m/D_Zfa/src/fcvtmod.w.d_b22-01.S", "rv32i_m/D_Zfa/src/fcvtmod.w.d_b23-01.S", @@ -2333,6 +2337,7 @@ string arch64zknh[] = '{ //`RISCVARCHTEST, `WALLYTEST, "rv64i_m/F_Zfa/src/fround_b1-01.S", + "rv64i_m/F_Zfa/src/froundnx_b1-01.S", "rv64i_m/F_Zfa/src/fleq_b1-01.S", "rv64i_m/F_Zfa/src/fleq_b19-01.S", "rv64i_m/F_Zfa/src/fli.s-01.S", @@ -2347,7 +2352,10 @@ string arch64zknh[] = '{ string arch64zfad[] = '{ //`RISCVARCHTEST, `WALLYTEST, - "rv64i_m/D_Zfa/src/fround_b1-01.S", + "rv64i_m/D_Zfa/src/fround_b1-01.S", + "rv64i_m/D_Zfa/src/froundnx_b1-01.S", + "rv64i_m/D_Zfa/src/fround.d_b1-01.S", + "rv64i_m/D_Zfa/src/froundnx.d_b1-01.S", "rv64i_m/D_Zfa/src/fcvtmod.w.d_b1-01.S", "rv64i_m/D_Zfa/src/fcvtmod.w.d_b22-01.S", "rv64i_m/D_Zfa/src/fcvtmod.w.d_b23-01.S", diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/D_Zfa/src/froundnx.d_b1-01.S b/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/D_Zfa/src/froundnx.d_b1-01.S new file mode 100644 index 000000000..8e7afb48b --- /dev/null +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/D_Zfa/src/froundnx.d_b1-01.S @@ -0,0 +1,353 @@ + +// ----------- +// This file was generated by riscv_ctg (https://github.com/riscv-software-src/riscv-ctg) +// version : 0.12.1 +// timestamp : Mon Apr 1 19:41:20 2024 GMT +// usage : riscv_ctg \ +// -- cgf // --cgf /home/cm/src/riscv-ctg/zfa/sample_cgfs/dataset.cgf \ +// --cgf /home/cm/src/riscv-ctg/zfa/sample_cgfs/zfa/froundnx.d.cgf \ + \ +// -- xlen 32 \ +// ----------- +// +// ----------- +// Copyright (c) 2020. RISC-V International. All rights reserved. +// SPDX-License-Identifier: BSD-3-Clause +// ----------- +// +// This assembly file tests the froundnx.d instruction of the RISC-V RV32FD_Zicsr_Zfa,RV64FD_Zicsr_Zfa extension for the froundnx.d_b1 covergroup. +// +#include "model_test.h" +#include "arch_test.h" +RVTEST_ISA("RV32IFD_Zicsr_Zfa,RV64IFD_Zicsr_Zfa") + +.section .text.init +.globl rvtest_entry_point +rvtest_entry_point: +RVMODEL_BOOT +RVTEST_CODE_BEGIN + +#ifdef TEST_CASE_1 + +RVTEST_CASE(0,"//check ISA:=regex(.*I.*D.*Zfa.*);def TEST_CASE_1=True;",froundnx.d_b1) + +RVTEST_FP_ENABLE() +RVTEST_VALBASEUPD(x3,test_dataset_0) +RVTEST_SIGBASE(x1,signature_x1_1) + +inst_0: +// rs1 == rd, rs1==f31, rd==f31,fs1 == 0 and fe1 == 0x000 and fm1 == 0x0000000000000 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.d ; op1:f31; dest:f31; op1val:0x0; valaddr_reg:x3; +val_offset:0*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.d, f31, f31, dyn, 0, 0, x3, 0*FLEN/8, x4, x1, x2) + +inst_1: +// rs1 != rd, rs1==f29, rd==f30,fs1 == 1 and fe1 == 0x000 and fm1 == 0x0000000000000 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.d ; op1:f29; dest:f30; op1val:0x8000000000000000; valaddr_reg:x3; +val_offset:1*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.d, f30, f29, dyn, 0, 0, x3, 1*FLEN/8, x4, x1, x2) + +inst_2: +// rs1==f30, rd==f29,fs1 == 0 and fe1 == 0x000 and fm1 == 0x0000000000001 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.d ; op1:f30; dest:f29; op1val:0x1; valaddr_reg:x3; +val_offset:2*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.d, f29, f30, dyn, 0, 0, x3, 2*FLEN/8, x4, x1, x2) + +inst_3: +// rs1==f27, rd==f28,fs1 == 1 and fe1 == 0x000 and fm1 == 0x0000000000001 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.d ; op1:f27; dest:f28; op1val:0x8000000000000001; valaddr_reg:x3; +val_offset:3*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.d, f28, f27, dyn, 0, 0, x3, 3*FLEN/8, x4, x1, x2) + +inst_4: +// rs1==f28, rd==f27,fs1 == 0 and fe1 == 0x000 and fm1 == 0x0000000000002 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.d ; op1:f28; dest:f27; op1val:0x2; valaddr_reg:x3; +val_offset:4*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.d, f27, f28, dyn, 0, 0, x3, 4*FLEN/8, x4, x1, x2) + +inst_5: +// rs1==f25, rd==f26,fs1 == 1 and fe1 == 0x000 and fm1 == 0x0000000000002 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.d ; op1:f25; dest:f26; op1val:0x8000000000000002; valaddr_reg:x3; +val_offset:5*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.d, f26, f25, dyn, 0, 0, x3, 5*FLEN/8, x4, x1, x2) + +inst_6: +// rs1==f26, rd==f25,fs1 == 0 and fe1 == 0x000 and fm1 == 0xfffffffffffff and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.d ; op1:f26; dest:f25; op1val:0xfffffffffffff; valaddr_reg:x3; +val_offset:6*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.d, f25, f26, dyn, 0, 0, x3, 6*FLEN/8, x4, x1, x2) + +inst_7: +// rs1==f23, rd==f24,fs1 == 1 and fe1 == 0x000 and fm1 == 0xfffffffffffff and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.d ; op1:f23; dest:f24; op1val:0x800fffffffffffff; valaddr_reg:x3; +val_offset:7*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.d, f24, f23, dyn, 0, 0, x3, 7*FLEN/8, x4, x1, x2) + +inst_8: +// rs1==f24, rd==f23,fs1 == 0 and fe1 == 0x001 and fm1 == 0x0000000000000 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.d ; op1:f24; dest:f23; op1val:0x10000000000000; valaddr_reg:x3; +val_offset:8*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.d, f23, f24, dyn, 0, 0, x3, 8*FLEN/8, x4, x1, x2) + +inst_9: +// rs1==f21, rd==f22,fs1 == 1 and fe1 == 0x001 and fm1 == 0x0000000000000 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.d ; op1:f21; dest:f22; op1val:0x8010000000000000; valaddr_reg:x3; +val_offset:9*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.d, f22, f21, dyn, 0, 0, x3, 9*FLEN/8, x4, x1, x2) + +inst_10: +// rs1==f22, rd==f21,fs1 == 0 and fe1 == 0x001 and fm1 == 0x0000000000002 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.d ; op1:f22; dest:f21; op1val:0x10000000000002; valaddr_reg:x3; +val_offset:10*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.d, f21, f22, dyn, 0, 0, x3, 10*FLEN/8, x4, x1, x2) + +inst_11: +// rs1==f19, rd==f20,fs1 == 1 and fe1 == 0x001 and fm1 == 0x0000000000002 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.d ; op1:f19; dest:f20; op1val:0x8010000000000002; valaddr_reg:x3; +val_offset:11*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.d, f20, f19, dyn, 0, 0, x3, 11*FLEN/8, x4, x1, x2) + +inst_12: +// rs1==f20, rd==f19,fs1 == 0 and fe1 == 0x7fe and fm1 == 0xfffffffffffff and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.d ; op1:f20; dest:f19; op1val:0x7fefffffffffffff; valaddr_reg:x3; +val_offset:12*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.d, f19, f20, dyn, 0, 0, x3, 12*FLEN/8, x4, x1, x2) + +inst_13: +// rs1==f17, rd==f18,fs1 == 1 and fe1 == 0x7fe and fm1 == 0xfffffffffffff and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.d ; op1:f17; dest:f18; op1val:0xffefffffffffffff; valaddr_reg:x3; +val_offset:13*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.d, f18, f17, dyn, 0, 0, x3, 13*FLEN/8, x4, x1, x2) + +inst_14: +// rs1==f18, rd==f17,fs1 == 0 and fe1 == 0x7ff and fm1 == 0x0000000000000 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.d ; op1:f18; dest:f17; op1val:0x7ff0000000000000; valaddr_reg:x3; +val_offset:14*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.d, f17, f18, dyn, 0, 0, x3, 14*FLEN/8, x4, x1, x2) + +inst_15: +// rs1==f15, rd==f16,fs1 == 1 and fe1 == 0x7ff and fm1 == 0x0000000000000 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.d ; op1:f15; dest:f16; op1val:0xfff0000000000000; valaddr_reg:x3; +val_offset:15*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.d, f16, f15, dyn, 0, 0, x3, 15*FLEN/8, x4, x1, x2) + +inst_16: +// rs1==f16, rd==f15,fs1 == 0 and fe1 == 0x7ff and fm1 == 0x8000000000000 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.d ; op1:f16; dest:f15; op1val:0x7ff8000000000000; valaddr_reg:x3; +val_offset:16*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.d, f15, f16, dyn, 0, 0, x3, 16*FLEN/8, x4, x1, x2) + +inst_17: +// rs1==f13, rd==f14,fs1 == 1 and fe1 == 0x7ff and fm1 == 0x8000000000000 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.d ; op1:f13; dest:f14; op1val:0xfff8000000000000; valaddr_reg:x3; +val_offset:17*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.d, f14, f13, dyn, 0, 0, x3, 17*FLEN/8, x4, x1, x2) + +inst_18: +// rs1==f14, rd==f13,fs1 == 0 and fe1 == 0x7ff and fm1 == 0x8000000000001 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.d ; op1:f14; dest:f13; op1val:0x7ff8000000000001; valaddr_reg:x3; +val_offset:18*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.d, f13, f14, dyn, 0, 0, x3, 18*FLEN/8, x4, x1, x2) + +inst_19: +// rs1==f11, rd==f12,fs1 == 1 and fe1 == 0x7ff and fm1 == 0x8000000000001 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.d ; op1:f11; dest:f12; op1val:0xfff8000000000001; valaddr_reg:x3; +val_offset:19*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.d, f12, f11, dyn, 0, 0, x3, 19*FLEN/8, x4, x1, x2) + +inst_20: +// rs1==f12, rd==f11,fs1 == 0 and fe1 == 0x7ff and fm1 == 0x0000000000001 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.d ; op1:f12; dest:f11; op1val:0x7ff0000000000001; valaddr_reg:x3; +val_offset:20*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.d, f11, f12, dyn, 0, 0, x3, 20*FLEN/8, x4, x1, x2) + +inst_21: +// rs1==f9, rd==f10,fs1 == 1 and fe1 == 0x7ff and fm1 == 0x0000000000001 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.d ; op1:f9; dest:f10; op1val:0xfff0000000000001; valaddr_reg:x3; +val_offset:21*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.d, f10, f9, dyn, 0, 0, x3, 21*FLEN/8, x4, x1, x2) + +inst_22: +// rs1==f10, rd==f9,fs1 == 0 and fe1 == 0x3ff and fm1 == 0x0000000000000 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.d ; op1:f10; dest:f9; op1val:0x3ff0000000000000; valaddr_reg:x3; +val_offset:22*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.d, f9, f10, dyn, 0, 0, x3, 22*FLEN/8, x4, x1, x2) + +inst_23: +// rs1==f7, rd==f8,fs1 == 1 and fe1 == 0x3f8 and fm1 == 0x0000000000000 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.d ; op1:f7; dest:f8; op1val:0xbf80000000000000; valaddr_reg:x3; +val_offset:23*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.d, f8, f7, dyn, 0, 0, x3, 23*FLEN/8, x4, x1, x2) + +inst_24: +// rs1==f8, rd==f7, +/* opcode: froundnx.d ; op1:f8; dest:f7; op1val:0x0; valaddr_reg:x3; +val_offset:24*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.d, f7, f8, dyn, 0, 0, x3, 24*FLEN/8, x4, x1, x2) + +inst_25: +// rs1==f5, rd==f6, +/* opcode: froundnx.d ; op1:f5; dest:f6; op1val:0x0; valaddr_reg:x3; +val_offset:25*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.d, f6, f5, dyn, 0, 0, x3, 25*FLEN/8, x4, x1, x2) + +inst_26: +// rs1==f6, rd==f5, +/* opcode: froundnx.d ; op1:f6; dest:f5; op1val:0x0; valaddr_reg:x3; +val_offset:26*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.d, f5, f6, dyn, 0, 0, x3, 26*FLEN/8, x4, x1, x2) + +inst_27: +// rs1==f3, rd==f4, +/* opcode: froundnx.d ; op1:f3; dest:f4; op1val:0x0; valaddr_reg:x3; +val_offset:27*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.d, f4, f3, dyn, 0, 0, x3, 27*FLEN/8, x4, x1, x2) + +inst_28: +// rs1==f4, rd==f3, +/* opcode: froundnx.d ; op1:f4; dest:f3; op1val:0x0; valaddr_reg:x3; +val_offset:28*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.d, f3, f4, dyn, 0, 0, x3, 28*FLEN/8, x4, x1, x2) + +inst_29: +// rs1==f1, rd==f2, +/* opcode: froundnx.d ; op1:f1; dest:f2; op1val:0x0; valaddr_reg:x3; +val_offset:29*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.d, f2, f1, dyn, 0, 0, x3, 29*FLEN/8, x4, x1, x2) + +inst_30: +// rs1==f2, rd==f1, +/* opcode: froundnx.d ; op1:f2; dest:f1; op1val:0x0; valaddr_reg:x3; +val_offset:30*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.d, f1, f2, dyn, 0, 0, x3, 30*FLEN/8, x4, x1, x2) + +inst_31: +// rs1==f0, +/* opcode: froundnx.d ; op1:f0; dest:f31; op1val:0x0; valaddr_reg:x3; +val_offset:31*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.d, f31, f0, dyn, 0, 0, x3, 31*FLEN/8, x4, x1, x2) + +inst_32: +// rd==f0, +/* opcode: froundnx.d ; op1:f31; dest:f0; op1val:0x0; valaddr_reg:x3; +val_offset:32*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.d, f0, f31, dyn, 0, 0, x3, 32*FLEN/8, x4, x1, x2) +#endif + + +RVTEST_CODE_END +RVMODEL_HALT + +RVTEST_DATA_BEGIN +.align 4 +rvtest_data: +.word 0xbabecafe +.word 0xabecafeb +.word 0xbecafeba +.word 0xecafebab +test_dataset_0: +NAN_BOXED(0,64,FLEN) +NAN_BOXED(9223372036854775808,64,FLEN) +NAN_BOXED(1,64,FLEN) +NAN_BOXED(9223372036854775809,64,FLEN) +NAN_BOXED(2,64,FLEN) +NAN_BOXED(9223372036854775810,64,FLEN) +NAN_BOXED(4503599627370495,64,FLEN) +NAN_BOXED(9227875636482146303,64,FLEN) +NAN_BOXED(4503599627370496,64,FLEN) +NAN_BOXED(9227875636482146304,64,FLEN) +NAN_BOXED(4503599627370498,64,FLEN) +NAN_BOXED(9227875636482146306,64,FLEN) +NAN_BOXED(9218868437227405311,64,FLEN) +NAN_BOXED(18442240474082181119,64,FLEN) +NAN_BOXED(9218868437227405312,64,FLEN) +NAN_BOXED(18442240474082181120,64,FLEN) +NAN_BOXED(9221120237041090560,64,FLEN) +NAN_BOXED(18444492273895866368,64,FLEN) +NAN_BOXED(9221120237041090561,64,FLEN) +NAN_BOXED(18444492273895866369,64,FLEN) +NAN_BOXED(9218868437227405313,64,FLEN) +NAN_BOXED(18442240474082181121,64,FLEN) +NAN_BOXED(4607182418800017408,64,FLEN) +NAN_BOXED(13799029258263199744,64,FLEN) +NAN_BOXED(0,64,FLEN) +NAN_BOXED(0,64,FLEN) +NAN_BOXED(0,64,FLEN) +NAN_BOXED(0,64,FLEN) +NAN_BOXED(0,64,FLEN) +NAN_BOXED(0,64,FLEN) +NAN_BOXED(0,64,FLEN) +NAN_BOXED(0,64,FLEN) +NAN_BOXED(0,64,FLEN) +RVTEST_DATA_END + +RVMODEL_DATA_BEGIN +rvtest_sig_begin: +sig_begin_canary: +CANARY; + + + +signature_x1_0: + .fill 0*((SIGALIGN)/4),4,0xdeadbeef + + +signature_x1_1: + .fill 66*((SIGALIGN)/4),4,0xdeadbeef + +#ifdef rvtest_mtrap_routine +tsig_begin_canary: +CANARY; + +mtrap_sigptr: + .fill 64*XLEN/32,4,0xdeadbeef + +tsig_end_canary: +CANARY; +#endif + +#ifdef rvtest_gpr_save + +gpr_save: + .fill 32*XLEN/32,4,0xdeadbeef + +#endif + + +sig_end_canary: +CANARY; +rvtest_sig_end: +RVMODEL_DATA_END diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/D_Zfa/src/froundnx_b1-01.S b/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/D_Zfa/src/froundnx_b1-01.S new file mode 100644 index 000000000..6771814ea --- /dev/null +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/D_Zfa/src/froundnx_b1-01.S @@ -0,0 +1,353 @@ + +// ----------- +// This file was generated by riscv_ctg (https://github.com/riscv-software-src/riscv-ctg) +// version : 0.12.1 +// timestamp : Wed Mar 6 21:52:24 2024 GMT +// usage : riscv_ctg \ +// -- cgf // --cgf /home/cm/src/riscv-ctg/zfa/sample_cgfs/dataset.cgf \ +// --cgf /home/cm/src/riscv-ctg/zfa/sample_cgfs/zfa/froundnx.s.cgf \ + \ +// -- xlen 32 \ +// ----------- +// +// ----------- +// Copyright (c) 2020. RISC-V International. All rights reserved. +// SPDX-License-Identifier: BSD-3-Clause +// ----------- +// +// This assembly file tests the froundnx.s instruction of the RISC-V RV32F_Zicsr_Zfa,RV32FD_Zicsr_Zfa,RV64F_Zicsr_Zfa,RV64FD_Zicsr_Zfa extension for the froundnx_b1 covergroup. +// +#include "model_test.h" +#include "arch_test.h" +RVTEST_ISA("RV32IF_Zicsr_Zfa,RV32IFD_Zicsr_Zfa,RV64IF_Zicsr_Zfa,RV64IFD_Zicsr_Zfa") + +.section .text.init +.globl rvtest_entry_point +rvtest_entry_point: +RVMODEL_BOOT +RVTEST_CODE_BEGIN + +#ifdef TEST_CASE_1 + +RVTEST_CASE(0,"//check ISA:=regex(.*I.*F.*Zfa.*);def TEST_CASE_1=True;",froundnx_b1) + +RVTEST_FP_ENABLE() +RVTEST_VALBASEUPD(x3,test_dataset_0) +RVTEST_SIGBASE(x1,signature_x1_1) + +inst_0: +// rs1 == rd, rs1==f31, rd==f31,fs1 == 0 and fe1 == 0x00 and fm1 == 0x000000 and fcsr == 0x0 and rm_val == 7 and rs1_nan_prefix == 0xffffffff +/* opcode: froundnx.s ; op1:f31; dest:f31; op1val:0x0; valaddr_reg:x3; +val_offset:0*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f31, f31, dyn, 0, 0, x3, 0*FLEN/8, x4, x1, x2) + +inst_1: +// rs1 != rd, rs1==f29, rd==f30,fs1 == 1 and fe1 == 0x00 and fm1 == 0x000000 and fcsr == 0x0 and rm_val == 7 and rs1_nan_prefix == 0xffffffff +/* opcode: froundnx.s ; op1:f29; dest:f30; op1val:0x80000000; valaddr_reg:x3; +val_offset:2*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f30, f29, dyn, 0, 0, x3, 2*FLEN/8, x4, x1, x2) + +inst_2: +// rs1==f30, rd==f29,fs1 == 0 and fe1 == 0x00 and fm1 == 0x000001 and fcsr == 0x0 and rm_val == 7 and rs1_nan_prefix == 0xffffffff +/* opcode: froundnx.s ; op1:f30; dest:f29; op1val:0x1; valaddr_reg:x3; +val_offset:4*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f29, f30, dyn, 0, 0, x3, 4*FLEN/8, x4, x1, x2) + +inst_3: +// rs1==f27, rd==f28,fs1 == 1 and fe1 == 0x00 and fm1 == 0x000001 and fcsr == 0x0 and rm_val == 7 and rs1_nan_prefix == 0xffffffff +/* opcode: froundnx.s ; op1:f27; dest:f28; op1val:0x80000001; valaddr_reg:x3; +val_offset:6*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f28, f27, dyn, 0, 0, x3, 6*FLEN/8, x4, x1, x2) + +inst_4: +// rs1==f28, rd==f27,fs1 == 0 and fe1 == 0x00 and fm1 == 0x000002 and fcsr == 0x0 and rm_val == 7 and rs1_nan_prefix == 0xffffffff +/* opcode: froundnx.s ; op1:f28; dest:f27; op1val:0x2; valaddr_reg:x3; +val_offset:8*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f27, f28, dyn, 0, 0, x3, 8*FLEN/8, x4, x1, x2) + +inst_5: +// rs1==f25, rd==f26,fs1 == 1 and fe1 == 0x00 and fm1 == 0x7ffffe and fcsr == 0x0 and rm_val == 7 and rs1_nan_prefix == 0xffffffff +/* opcode: froundnx.s ; op1:f25; dest:f26; op1val:0x807ffffe; valaddr_reg:x3; +val_offset:10*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f26, f25, dyn, 0, 0, x3, 10*FLEN/8, x4, x1, x2) + +inst_6: +// rs1==f26, rd==f25,fs1 == 0 and fe1 == 0x00 and fm1 == 0x7fffff and fcsr == 0x0 and rm_val == 7 and rs1_nan_prefix == 0xffffffff +/* opcode: froundnx.s ; op1:f26; dest:f25; op1val:0x7fffff; valaddr_reg:x3; +val_offset:12*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f25, f26, dyn, 0, 0, x3, 12*FLEN/8, x4, x1, x2) + +inst_7: +// rs1==f23, rd==f24,fs1 == 1 and fe1 == 0x00 and fm1 == 0x7fffff and fcsr == 0x0 and rm_val == 7 and rs1_nan_prefix == 0xffffffff +/* opcode: froundnx.s ; op1:f23; dest:f24; op1val:0x807fffff; valaddr_reg:x3; +val_offset:14*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f24, f23, dyn, 0, 0, x3, 14*FLEN/8, x4, x1, x2) + +inst_8: +// rs1==f24, rd==f23,fs1 == 0 and fe1 == 0x01 and fm1 == 0x000000 and fcsr == 0x0 and rm_val == 7 and rs1_nan_prefix == 0xffffffff +/* opcode: froundnx.s ; op1:f24; dest:f23; op1val:0x800000; valaddr_reg:x3; +val_offset:16*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f23, f24, dyn, 0, 0, x3, 16*FLEN/8, x4, x1, x2) + +inst_9: +// rs1==f21, rd==f22,fs1 == 1 and fe1 == 0x01 and fm1 == 0x000000 and fcsr == 0x0 and rm_val == 7 and rs1_nan_prefix == 0xffffffff +/* opcode: froundnx.s ; op1:f21; dest:f22; op1val:0x80800000; valaddr_reg:x3; +val_offset:18*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f22, f21, dyn, 0, 0, x3, 18*FLEN/8, x4, x1, x2) + +inst_10: +// rs1==f22, rd==f21,fs1 == 0 and fe1 == 0x01 and fm1 == 0x000001 and fcsr == 0x0 and rm_val == 7 and rs1_nan_prefix == 0xffffffff +/* opcode: froundnx.s ; op1:f22; dest:f21; op1val:0x800001; valaddr_reg:x3; +val_offset:20*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f21, f22, dyn, 0, 0, x3, 20*FLEN/8, x4, x1, x2) + +inst_11: +// rs1==f19, rd==f20,fs1 == 1 and fe1 == 0x01 and fm1 == 0x055555 and fcsr == 0x0 and rm_val == 7 and rs1_nan_prefix == 0xffffffff +/* opcode: froundnx.s ; op1:f19; dest:f20; op1val:0x80855555; valaddr_reg:x3; +val_offset:22*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f20, f19, dyn, 0, 0, x3, 22*FLEN/8, x4, x1, x2) + +inst_12: +// rs1==f20, rd==f19,fs1 == 0 and fe1 == 0xfe and fm1 == 0x7fffff and fcsr == 0x0 and rm_val == 7 and rs1_nan_prefix == 0xffffffff +/* opcode: froundnx.s ; op1:f20; dest:f19; op1val:0x7f7fffff; valaddr_reg:x3; +val_offset:24*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f19, f20, dyn, 0, 0, x3, 24*FLEN/8, x4, x1, x2) + +inst_13: +// rs1==f17, rd==f18,fs1 == 1 and fe1 == 0xfe and fm1 == 0x7fffff and fcsr == 0x0 and rm_val == 7 and rs1_nan_prefix == 0xffffffff +/* opcode: froundnx.s ; op1:f17; dest:f18; op1val:0xff7fffff; valaddr_reg:x3; +val_offset:26*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f18, f17, dyn, 0, 0, x3, 26*FLEN/8, x4, x1, x2) + +inst_14: +// rs1==f18, rd==f17,fs1 == 0 and fe1 == 0xff and fm1 == 0x000000 and fcsr == 0x0 and rm_val == 7 and rs1_nan_prefix == 0xffffffff +/* opcode: froundnx.s ; op1:f18; dest:f17; op1val:0x7f800000; valaddr_reg:x3; +val_offset:28*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f17, f18, dyn, 0, 0, x3, 28*FLEN/8, x4, x1, x2) + +inst_15: +// rs1==f15, rd==f16,fs1 == 1 and fe1 == 0xff and fm1 == 0x000000 and fcsr == 0x0 and rm_val == 7 and rs1_nan_prefix == 0xffffffff +/* opcode: froundnx.s ; op1:f15; dest:f16; op1val:0xff800000; valaddr_reg:x3; +val_offset:30*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f16, f15, dyn, 0, 0, x3, 30*FLEN/8, x4, x1, x2) + +inst_16: +// rs1==f16, rd==f15,fs1 == 0 and fe1 == 0xff and fm1 == 0x400000 and fcsr == 0x0 and rm_val == 7 and rs1_nan_prefix == 0xffffffff +/* opcode: froundnx.s ; op1:f16; dest:f15; op1val:0x7fc00000; valaddr_reg:x3; +val_offset:32*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f15, f16, dyn, 0, 0, x3, 32*FLEN/8, x4, x1, x2) + +inst_17: +// rs1==f13, rd==f14,fs1 == 1 and fe1 == 0xff and fm1 == 0x400000 and fcsr == 0x0 and rm_val == 7 and rs1_nan_prefix == 0xffffffff +/* opcode: froundnx.s ; op1:f13; dest:f14; op1val:0xffc00000; valaddr_reg:x3; +val_offset:34*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f14, f13, dyn, 0, 0, x3, 34*FLEN/8, x4, x1, x2) + +inst_18: +// rs1==f14, rd==f13,fs1 == 0 and fe1 == 0xff and fm1 == 0x400001 and fcsr == 0x0 and rm_val == 7 and rs1_nan_prefix == 0xffffffff +/* opcode: froundnx.s ; op1:f14; dest:f13; op1val:0x7fc00001; valaddr_reg:x3; +val_offset:36*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f13, f14, dyn, 0, 0, x3, 36*FLEN/8, x4, x1, x2) + +inst_19: +// rs1==f11, rd==f12,fs1 == 1 and fe1 == 0xff and fm1 == 0x455555 and fcsr == 0x0 and rm_val == 7 and rs1_nan_prefix == 0xffffffff +/* opcode: froundnx.s ; op1:f11; dest:f12; op1val:0xffc55555; valaddr_reg:x3; +val_offset:38*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f12, f11, dyn, 0, 0, x3, 38*FLEN/8, x4, x1, x2) + +inst_20: +// rs1==f12, rd==f11,fs1 == 0 and fe1 == 0xff and fm1 == 0x000001 and fcsr == 0x0 and rm_val == 7 and rs1_nan_prefix == 0xffffffff +/* opcode: froundnx.s ; op1:f12; dest:f11; op1val:0x7f800001; valaddr_reg:x3; +val_offset:40*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f11, f12, dyn, 0, 0, x3, 40*FLEN/8, x4, x1, x2) + +inst_21: +// rs1==f9, rd==f10,fs1 == 1 and fe1 == 0xff and fm1 == 0x2aaaaa and fcsr == 0x0 and rm_val == 7 and rs1_nan_prefix == 0xffffffff +/* opcode: froundnx.s ; op1:f9; dest:f10; op1val:0xffaaaaaa; valaddr_reg:x3; +val_offset:42*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f10, f9, dyn, 0, 0, x3, 42*FLEN/8, x4, x1, x2) + +inst_22: +// rs1==f10, rd==f9,fs1 == 0 and fe1 == 0x7f and fm1 == 0x000000 and fcsr == 0x0 and rm_val == 7 and rs1_nan_prefix == 0xffffffff +/* opcode: froundnx.s ; op1:f10; dest:f9; op1val:0x3f800000; valaddr_reg:x3; +val_offset:44*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f9, f10, dyn, 0, 0, x3, 44*FLEN/8, x4, x1, x2) + +inst_23: +// rs1==f7, rd==f8,fs1 == 1 and fe1 == 0x7f and fm1 == 0x000000 and fcsr == 0x0 and rm_val == 7 and rs1_nan_prefix == 0xffffffff +/* opcode: froundnx.s ; op1:f7; dest:f8; op1val:0xbf800000; valaddr_reg:x3; +val_offset:46*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f8, f7, dyn, 0, 0, x3, 46*FLEN/8, x4, x1, x2) + +inst_24: +// rs1==f8, rd==f7, +/* opcode: froundnx.s ; op1:f8; dest:f7; op1val:0x0; valaddr_reg:x3; +val_offset:48*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f7, f8, dyn, 0, 0, x3, 48*FLEN/8, x4, x1, x2) + +inst_25: +// rs1==f5, rd==f6, +/* opcode: froundnx.s ; op1:f5; dest:f6; op1val:0x0; valaddr_reg:x3; +val_offset:50*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f6, f5, dyn, 0, 0, x3, 50*FLEN/8, x4, x1, x2) + +inst_26: +// rs1==f6, rd==f5, +/* opcode: froundnx.s ; op1:f6; dest:f5; op1val:0x0; valaddr_reg:x3; +val_offset:52*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f5, f6, dyn, 0, 0, x3, 52*FLEN/8, x4, x1, x2) + +inst_27: +// rs1==f3, rd==f4, +/* opcode: froundnx.s ; op1:f3; dest:f4; op1val:0x0; valaddr_reg:x3; +val_offset:54*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f4, f3, dyn, 0, 0, x3, 54*FLEN/8, x4, x1, x2) + +inst_28: +// rs1==f4, rd==f3, +/* opcode: froundnx.s ; op1:f4; dest:f3; op1val:0x0; valaddr_reg:x3; +val_offset:56*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f3, f4, dyn, 0, 0, x3, 56*FLEN/8, x4, x1, x2) + +inst_29: +// rs1==f1, rd==f2, +/* opcode: froundnx.s ; op1:f1; dest:f2; op1val:0x0; valaddr_reg:x3; +val_offset:58*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f2, f1, dyn, 0, 0, x3, 58*FLEN/8, x4, x1, x2) + +inst_30: +// rs1==f2, rd==f1, +/* opcode: froundnx.s ; op1:f2; dest:f1; op1val:0x0; valaddr_reg:x3; +val_offset:60*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f1, f2, dyn, 0, 0, x3, 60*FLEN/8, x4, x1, x2) + +inst_31: +// rs1==f0, +/* opcode: froundnx.s ; op1:f0; dest:f31; op1val:0x0; valaddr_reg:x3; +val_offset:62*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f31, f0, dyn, 0, 0, x3, 62*FLEN/8, x4, x1, x2) + +inst_32: +// rd==f0, +/* opcode: froundnx.s ; op1:f31; dest:f0; op1val:0x0; valaddr_reg:x3; +val_offset:64*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f0, f31, dyn, 0, 0, x3, 64*FLEN/8, x4, x1, x2) +#endif + + +RVTEST_CODE_END +RVMODEL_HALT + +RVTEST_DATA_BEGIN +.align 4 +rvtest_data: +.word 0xbabecafe +.word 0xabecafeb +.word 0xbecafeba +.word 0xecafebab +test_dataset_0: +NAN_BOXED(0,32,FLEN) +NAN_BOXED(2147483648,32,FLEN) +NAN_BOXED(1,32,FLEN) +NAN_BOXED(2147483649,32,FLEN) +NAN_BOXED(2,32,FLEN) +NAN_BOXED(2155872254,32,FLEN) +NAN_BOXED(8388607,32,FLEN) +NAN_BOXED(2155872255,32,FLEN) +NAN_BOXED(8388608,32,FLEN) +NAN_BOXED(2155872256,32,FLEN) +NAN_BOXED(8388609,32,FLEN) +NAN_BOXED(2156221781,32,FLEN) +NAN_BOXED(2139095039,32,FLEN) +NAN_BOXED(4286578687,32,FLEN) +NAN_BOXED(2139095040,32,FLEN) +NAN_BOXED(4286578688,32,FLEN) +NAN_BOXED(2143289344,32,FLEN) +NAN_BOXED(4290772992,32,FLEN) +NAN_BOXED(2143289345,32,FLEN) +NAN_BOXED(4291122517,32,FLEN) +NAN_BOXED(2139095041,32,FLEN) +NAN_BOXED(4289374890,32,FLEN) +NAN_BOXED(1065353216,32,FLEN) +NAN_BOXED(3212836864,32,FLEN) +NAN_BOXED(0,64,FLEN) +NAN_BOXED(0,64,FLEN) +NAN_BOXED(0,64,FLEN) +NAN_BOXED(0,64,FLEN) +NAN_BOXED(0,64,FLEN) +NAN_BOXED(0,64,FLEN) +NAN_BOXED(0,64,FLEN) +NAN_BOXED(0,64,FLEN) +NAN_BOXED(0,64,FLEN) +RVTEST_DATA_END + +RVMODEL_DATA_BEGIN +rvtest_sig_begin: +sig_begin_canary: +CANARY; + + + +signature_x1_0: + .fill 0*((SIGALIGN)/4),4,0xdeadbeef + + +signature_x1_1: + .fill 66*((SIGALIGN)/4),4,0xdeadbeef + +#ifdef rvtest_mtrap_routine +tsig_begin_canary: +CANARY; + +mtrap_sigptr: + .fill 64*XLEN/32,4,0xdeadbeef + +tsig_end_canary: +CANARY; +#endif + +#ifdef rvtest_gpr_save + +gpr_save: + .fill 32*XLEN/32,4,0xdeadbeef + +#endif + + +sig_end_canary: +CANARY; +rvtest_sig_end: +RVMODEL_DATA_END diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/F_Zfa/src/froundnx_b1-01.S b/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/F_Zfa/src/froundnx_b1-01.S new file mode 100644 index 000000000..bef26add0 --- /dev/null +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/F_Zfa/src/froundnx_b1-01.S @@ -0,0 +1,353 @@ + +// ----------- +// This file was generated by riscv_ctg (https://github.com/riscv-software-src/riscv-ctg) +// version : 0.12.1 +// timestamp : Mon Apr 1 19:36:23 2024 GMT +// usage : riscv_ctg \ +// -- cgf // --cgf /home/cm/src/riscv-ctg/zfa/sample_cgfs/dataset.cgf \ +// --cgf /home/cm/src/riscv-ctg/zfa/sample_cgfs/zfa/froundnx.s.cgf \ + \ +// -- xlen 32 \ +// ----------- +// +// ----------- +// Copyright (c) 2020. RISC-V International. All rights reserved. +// SPDX-License-Identifier: BSD-3-Clause +// ----------- +// +// This assembly file tests the froundnx.s instruction of the RISC-V RV32F_Zicsr_Zfa,RV32FD_Zicsr_Zfa,RV64F_Zicsr_Zfa,RV64FD_Zicsr_Zfa extension for the froundnx_b1 covergroup. +// +#include "model_test.h" +#include "arch_test.h" +RVTEST_ISA("RV32IF_Zicsr_Zfa,RV32IFD_Zicsr_Zfa,RV64IF_Zicsr_Zfa,RV64IFD_Zicsr_Zfa") + +.section .text.init +.globl rvtest_entry_point +rvtest_entry_point: +RVMODEL_BOOT +RVTEST_CODE_BEGIN + +#ifdef TEST_CASE_1 + +RVTEST_CASE(0,"//check ISA:=regex(.*I.*F.*Zfa.*);def TEST_CASE_1=True;",froundnx_b1) + +RVTEST_FP_ENABLE() +RVTEST_VALBASEUPD(x3,test_dataset_0) +RVTEST_SIGBASE(x1,signature_x1_1) + +inst_0: +// rs1 == rd, rs1==f31, rd==f31,fs1 == 0 and fe1 == 0x00 and fm1 == 0x000000 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.s ; op1:f31; dest:f31; op1val:0x0; valaddr_reg:x3; +val_offset:0*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f31, f31, dyn, 0, 0, x3, 0*FLEN/8, x4, x1, x2) + +inst_1: +// rs1 != rd, rs1==f29, rd==f30,fs1 == 1 and fe1 == 0x00 and fm1 == 0x000000 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.s ; op1:f29; dest:f30; op1val:0x80000000; valaddr_reg:x3; +val_offset:2*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f30, f29, dyn, 0, 0, x3, 2*FLEN/8, x4, x1, x2) + +inst_2: +// rs1==f30, rd==f29,fs1 == 0 and fe1 == 0x00 and fm1 == 0x000001 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.s ; op1:f30; dest:f29; op1val:0x1; valaddr_reg:x3; +val_offset:4*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f29, f30, dyn, 0, 0, x3, 4*FLEN/8, x4, x1, x2) + +inst_3: +// rs1==f27, rd==f28,fs1 == 1 and fe1 == 0x00 and fm1 == 0x000001 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.s ; op1:f27; dest:f28; op1val:0x80000001; valaddr_reg:x3; +val_offset:6*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f28, f27, dyn, 0, 0, x3, 6*FLEN/8, x4, x1, x2) + +inst_4: +// rs1==f28, rd==f27,fs1 == 0 and fe1 == 0x00 and fm1 == 0x000002 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.s ; op1:f28; dest:f27; op1val:0x2; valaddr_reg:x3; +val_offset:8*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f27, f28, dyn, 0, 0, x3, 8*FLEN/8, x4, x1, x2) + +inst_5: +// rs1==f25, rd==f26,fs1 == 1 and fe1 == 0x00 and fm1 == 0x7ffffe and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.s ; op1:f25; dest:f26; op1val:0x807ffffe; valaddr_reg:x3; +val_offset:10*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f26, f25, dyn, 0, 0, x3, 10*FLEN/8, x4, x1, x2) + +inst_6: +// rs1==f26, rd==f25,fs1 == 0 and fe1 == 0x00 and fm1 == 0x7fffff and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.s ; op1:f26; dest:f25; op1val:0x7fffff; valaddr_reg:x3; +val_offset:12*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f25, f26, dyn, 0, 0, x3, 12*FLEN/8, x4, x1, x2) + +inst_7: +// rs1==f23, rd==f24,fs1 == 1 and fe1 == 0x00 and fm1 == 0x7fffff and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.s ; op1:f23; dest:f24; op1val:0x807fffff; valaddr_reg:x3; +val_offset:14*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f24, f23, dyn, 0, 0, x3, 14*FLEN/8, x4, x1, x2) + +inst_8: +// rs1==f24, rd==f23,fs1 == 0 and fe1 == 0x01 and fm1 == 0x000000 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.s ; op1:f24; dest:f23; op1val:0x800000; valaddr_reg:x3; +val_offset:16*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f23, f24, dyn, 0, 0, x3, 16*FLEN/8, x4, x1, x2) + +inst_9: +// rs1==f21, rd==f22,fs1 == 1 and fe1 == 0x01 and fm1 == 0x000000 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.s ; op1:f21; dest:f22; op1val:0x80800000; valaddr_reg:x3; +val_offset:18*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f22, f21, dyn, 0, 0, x3, 18*FLEN/8, x4, x1, x2) + +inst_10: +// rs1==f22, rd==f21,fs1 == 0 and fe1 == 0x01 and fm1 == 0x000001 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.s ; op1:f22; dest:f21; op1val:0x800001; valaddr_reg:x3; +val_offset:20*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f21, f22, dyn, 0, 0, x3, 20*FLEN/8, x4, x1, x2) + +inst_11: +// rs1==f19, rd==f20,fs1 == 1 and fe1 == 0x01 and fm1 == 0x055555 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.s ; op1:f19; dest:f20; op1val:0x80855555; valaddr_reg:x3; +val_offset:22*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f20, f19, dyn, 0, 0, x3, 22*FLEN/8, x4, x1, x2) + +inst_12: +// rs1==f20, rd==f19,fs1 == 0 and fe1 == 0xfe and fm1 == 0x7fffff and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.s ; op1:f20; dest:f19; op1val:0x7f7fffff; valaddr_reg:x3; +val_offset:24*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f19, f20, dyn, 0, 0, x3, 24*FLEN/8, x4, x1, x2) + +inst_13: +// rs1==f17, rd==f18,fs1 == 1 and fe1 == 0xfe and fm1 == 0x7fffff and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.s ; op1:f17; dest:f18; op1val:0xff7fffff; valaddr_reg:x3; +val_offset:26*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f18, f17, dyn, 0, 0, x3, 26*FLEN/8, x4, x1, x2) + +inst_14: +// rs1==f18, rd==f17,fs1 == 0 and fe1 == 0xff and fm1 == 0x000000 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.s ; op1:f18; dest:f17; op1val:0x7f800000; valaddr_reg:x3; +val_offset:28*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f17, f18, dyn, 0, 0, x3, 28*FLEN/8, x4, x1, x2) + +inst_15: +// rs1==f15, rd==f16,fs1 == 1 and fe1 == 0xff and fm1 == 0x000000 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.s ; op1:f15; dest:f16; op1val:0xff800000; valaddr_reg:x3; +val_offset:30*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f16, f15, dyn, 0, 0, x3, 30*FLEN/8, x4, x1, x2) + +inst_16: +// rs1==f16, rd==f15,fs1 == 0 and fe1 == 0xff and fm1 == 0x400000 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.s ; op1:f16; dest:f15; op1val:0x7fc00000; valaddr_reg:x3; +val_offset:32*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f15, f16, dyn, 0, 0, x3, 32*FLEN/8, x4, x1, x2) + +inst_17: +// rs1==f13, rd==f14,fs1 == 1 and fe1 == 0xff and fm1 == 0x400000 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.s ; op1:f13; dest:f14; op1val:0xffc00000; valaddr_reg:x3; +val_offset:34*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f14, f13, dyn, 0, 0, x3, 34*FLEN/8, x4, x1, x2) + +inst_18: +// rs1==f14, rd==f13,fs1 == 0 and fe1 == 0xff and fm1 == 0x400001 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.s ; op1:f14; dest:f13; op1val:0x7fc00001; valaddr_reg:x3; +val_offset:36*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f13, f14, dyn, 0, 0, x3, 36*FLEN/8, x4, x1, x2) + +inst_19: +// rs1==f11, rd==f12,fs1 == 1 and fe1 == 0xff and fm1 == 0x455555 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.s ; op1:f11; dest:f12; op1val:0xffc55555; valaddr_reg:x3; +val_offset:38*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f12, f11, dyn, 0, 0, x3, 38*FLEN/8, x4, x1, x2) + +inst_20: +// rs1==f12, rd==f11,fs1 == 0 and fe1 == 0xff and fm1 == 0x000001 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.s ; op1:f12; dest:f11; op1val:0x7f800001; valaddr_reg:x3; +val_offset:40*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f11, f12, dyn, 0, 0, x3, 40*FLEN/8, x4, x1, x2) + +inst_21: +// rs1==f9, rd==f10,fs1 == 1 and fe1 == 0xff and fm1 == 0x2aaaaa and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.s ; op1:f9; dest:f10; op1val:0xffaaaaaa; valaddr_reg:x3; +val_offset:42*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f10, f9, dyn, 0, 0, x3, 42*FLEN/8, x4, x1, x2) + +inst_22: +// rs1==f10, rd==f9,fs1 == 0 and fe1 == 0x7f and fm1 == 0x000000 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.s ; op1:f10; dest:f9; op1val:0x3f800000; valaddr_reg:x3; +val_offset:44*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f9, f10, dyn, 0, 0, x3, 44*FLEN/8, x4, x1, x2) + +inst_23: +// rs1==f7, rd==f8,fs1 == 1 and fe1 == 0x7f and fm1 == 0x000000 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.s ; op1:f7; dest:f8; op1val:0xbf800000; valaddr_reg:x3; +val_offset:46*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f8, f7, dyn, 0, 0, x3, 46*FLEN/8, x4, x1, x2) + +inst_24: +// rs1==f8, rd==f7, +/* opcode: froundnx.s ; op1:f8; dest:f7; op1val:0x0; valaddr_reg:x3; +val_offset:48*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f7, f8, dyn, 0, 0, x3, 48*FLEN/8, x4, x1, x2) + +inst_25: +// rs1==f5, rd==f6, +/* opcode: froundnx.s ; op1:f5; dest:f6; op1val:0x0; valaddr_reg:x3; +val_offset:50*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f6, f5, dyn, 0, 0, x3, 50*FLEN/8, x4, x1, x2) + +inst_26: +// rs1==f6, rd==f5, +/* opcode: froundnx.s ; op1:f6; dest:f5; op1val:0x0; valaddr_reg:x3; +val_offset:52*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f5, f6, dyn, 0, 0, x3, 52*FLEN/8, x4, x1, x2) + +inst_27: +// rs1==f3, rd==f4, +/* opcode: froundnx.s ; op1:f3; dest:f4; op1val:0x0; valaddr_reg:x3; +val_offset:54*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f4, f3, dyn, 0, 0, x3, 54*FLEN/8, x4, x1, x2) + +inst_28: +// rs1==f4, rd==f3, +/* opcode: froundnx.s ; op1:f4; dest:f3; op1val:0x0; valaddr_reg:x3; +val_offset:56*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f3, f4, dyn, 0, 0, x3, 56*FLEN/8, x4, x1, x2) + +inst_29: +// rs1==f1, rd==f2, +/* opcode: froundnx.s ; op1:f1; dest:f2; op1val:0x0; valaddr_reg:x3; +val_offset:58*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f2, f1, dyn, 0, 0, x3, 58*FLEN/8, x4, x1, x2) + +inst_30: +// rs1==f2, rd==f1, +/* opcode: froundnx.s ; op1:f2; dest:f1; op1val:0x0; valaddr_reg:x3; +val_offset:60*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f1, f2, dyn, 0, 0, x3, 60*FLEN/8, x4, x1, x2) + +inst_31: +// rs1==f0, +/* opcode: froundnx.s ; op1:f0; dest:f31; op1val:0x0; valaddr_reg:x3; +val_offset:62*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f31, f0, dyn, 0, 0, x3, 62*FLEN/8, x4, x1, x2) + +inst_32: +// rd==f0, +/* opcode: froundnx.s ; op1:f31; dest:f0; op1val:0x0; valaddr_reg:x3; +val_offset:64*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f0, f31, dyn, 0, 0, x3, 64*FLEN/8, x4, x1, x2) +#endif + + +RVTEST_CODE_END +RVMODEL_HALT + +RVTEST_DATA_BEGIN +.align 4 +rvtest_data: +.word 0xbabecafe +.word 0xabecafeb +.word 0xbecafeba +.word 0xecafebab +test_dataset_0: +NAN_BOXED(0,32,FLEN) +NAN_BOXED(2147483648,32,FLEN) +NAN_BOXED(1,32,FLEN) +NAN_BOXED(2147483649,32,FLEN) +NAN_BOXED(2,32,FLEN) +NAN_BOXED(2155872254,32,FLEN) +NAN_BOXED(8388607,32,FLEN) +NAN_BOXED(2155872255,32,FLEN) +NAN_BOXED(8388608,32,FLEN) +NAN_BOXED(2155872256,32,FLEN) +NAN_BOXED(8388609,32,FLEN) +NAN_BOXED(2156221781,32,FLEN) +NAN_BOXED(2139095039,32,FLEN) +NAN_BOXED(4286578687,32,FLEN) +NAN_BOXED(2139095040,32,FLEN) +NAN_BOXED(4286578688,32,FLEN) +NAN_BOXED(2143289344,32,FLEN) +NAN_BOXED(4290772992,32,FLEN) +NAN_BOXED(2143289345,32,FLEN) +NAN_BOXED(4291122517,32,FLEN) +NAN_BOXED(2139095041,32,FLEN) +NAN_BOXED(4289374890,32,FLEN) +NAN_BOXED(1065353216,32,FLEN) +NAN_BOXED(3212836864,32,FLEN) +NAN_BOXED(0,32,FLEN) +NAN_BOXED(0,32,FLEN) +NAN_BOXED(0,32,FLEN) +NAN_BOXED(0,32,FLEN) +NAN_BOXED(0,32,FLEN) +NAN_BOXED(0,32,FLEN) +NAN_BOXED(0,32,FLEN) +NAN_BOXED(0,32,FLEN) +NAN_BOXED(0,32,FLEN) +RVTEST_DATA_END + +RVMODEL_DATA_BEGIN +rvtest_sig_begin: +sig_begin_canary: +CANARY; + + + +signature_x1_0: + .fill 0*((SIGALIGN)/4),4,0xdeadbeef + + +signature_x1_1: + .fill 66*((SIGALIGN)/4),4,0xdeadbeef + +#ifdef rvtest_mtrap_routine +tsig_begin_canary: +CANARY; + +mtrap_sigptr: + .fill 64*XLEN/32,4,0xdeadbeef + +tsig_end_canary: +CANARY; +#endif + +#ifdef rvtest_gpr_save + +gpr_save: + .fill 32*XLEN/32,4,0xdeadbeef + +#endif + + +sig_end_canary: +CANARY; +rvtest_sig_end: +RVMODEL_DATA_END diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/D_Zfa/src/froundnx.d_b1-01.S b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/D_Zfa/src/froundnx.d_b1-01.S new file mode 100644 index 000000000..16874bb6a --- /dev/null +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/D_Zfa/src/froundnx.d_b1-01.S @@ -0,0 +1,353 @@ + +// ----------- +// This file was generated by riscv_ctg (https://github.com/riscv-software-src/riscv-ctg) +// version : 0.12.1 +// timestamp : Mon Apr 1 19:41:22 2024 GMT +// usage : riscv_ctg \ +// -- cgf // --cgf /home/cm/src/riscv-ctg/zfa/sample_cgfs/dataset.cgf \ +// --cgf /home/cm/src/riscv-ctg/zfa/sample_cgfs/zfa/froundnx.d.cgf \ + \ +// -- xlen 64 \ +// ----------- +// +// ----------- +// Copyright (c) 2020. RISC-V International. All rights reserved. +// SPDX-License-Identifier: BSD-3-Clause +// ----------- +// +// This assembly file tests the froundnx.d instruction of the RISC-V RV64FD_Zicsr_Zfa extension for the froundnx.d_b1 covergroup. +// +#include "model_test.h" +#include "arch_test.h" +RVTEST_ISA("RV64IFD_Zicsr_Zfa") + +.section .text.init +.globl rvtest_entry_point +rvtest_entry_point: +RVMODEL_BOOT +RVTEST_CODE_BEGIN + +#ifdef TEST_CASE_1 + +RVTEST_CASE(0,"//check ISA:=regex(.*RV64.*I.*D.*Zfa.*);def TEST_CASE_1=True;",froundnx.d_b1) + +RVTEST_FP_ENABLE() +RVTEST_VALBASEUPD(x3,test_dataset_0) +RVTEST_SIGBASE(x1,signature_x1_1) + +inst_0: +// rs1 == rd, rs1==f31, rd==f31,fs1 == 0 and fe1 == 0x000 and fm1 == 0x0000000000000 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.d ; op1:f31; dest:f31; op1val:0x0; valaddr_reg:x3; +val_offset:0*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.d, f31, f31, dyn, 0, 0, x3, 0*FLEN/8, x4, x1, x2) + +inst_1: +// rs1 != rd, rs1==f29, rd==f30,fs1 == 1 and fe1 == 0x000 and fm1 == 0x0000000000000 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.d ; op1:f29; dest:f30; op1val:0x8000000000000000; valaddr_reg:x3; +val_offset:1*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.d, f30, f29, dyn, 0, 0, x3, 1*FLEN/8, x4, x1, x2) + +inst_2: +// rs1==f30, rd==f29,fs1 == 0 and fe1 == 0x000 and fm1 == 0x0000000000001 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.d ; op1:f30; dest:f29; op1val:0x1; valaddr_reg:x3; +val_offset:2*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.d, f29, f30, dyn, 0, 0, x3, 2*FLEN/8, x4, x1, x2) + +inst_3: +// rs1==f27, rd==f28,fs1 == 1 and fe1 == 0x000 and fm1 == 0x0000000000001 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.d ; op1:f27; dest:f28; op1val:0x8000000000000001; valaddr_reg:x3; +val_offset:3*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.d, f28, f27, dyn, 0, 0, x3, 3*FLEN/8, x4, x1, x2) + +inst_4: +// rs1==f28, rd==f27,fs1 == 0 and fe1 == 0x000 and fm1 == 0x0000000000002 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.d ; op1:f28; dest:f27; op1val:0x2; valaddr_reg:x3; +val_offset:4*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.d, f27, f28, dyn, 0, 0, x3, 4*FLEN/8, x4, x1, x2) + +inst_5: +// rs1==f25, rd==f26,fs1 == 1 and fe1 == 0x000 and fm1 == 0x0000000000002 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.d ; op1:f25; dest:f26; op1val:0x8000000000000002; valaddr_reg:x3; +val_offset:5*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.d, f26, f25, dyn, 0, 0, x3, 5*FLEN/8, x4, x1, x2) + +inst_6: +// rs1==f26, rd==f25,fs1 == 0 and fe1 == 0x000 and fm1 == 0xfffffffffffff and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.d ; op1:f26; dest:f25; op1val:0xfffffffffffff; valaddr_reg:x3; +val_offset:6*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.d, f25, f26, dyn, 0, 0, x3, 6*FLEN/8, x4, x1, x2) + +inst_7: +// rs1==f23, rd==f24,fs1 == 1 and fe1 == 0x000 and fm1 == 0xfffffffffffff and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.d ; op1:f23; dest:f24; op1val:0x800fffffffffffff; valaddr_reg:x3; +val_offset:7*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.d, f24, f23, dyn, 0, 0, x3, 7*FLEN/8, x4, x1, x2) + +inst_8: +// rs1==f24, rd==f23,fs1 == 0 and fe1 == 0x001 and fm1 == 0x0000000000000 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.d ; op1:f24; dest:f23; op1val:0x10000000000000; valaddr_reg:x3; +val_offset:8*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.d, f23, f24, dyn, 0, 0, x3, 8*FLEN/8, x4, x1, x2) + +inst_9: +// rs1==f21, rd==f22,fs1 == 1 and fe1 == 0x001 and fm1 == 0x0000000000000 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.d ; op1:f21; dest:f22; op1val:0x8010000000000000; valaddr_reg:x3; +val_offset:9*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.d, f22, f21, dyn, 0, 0, x3, 9*FLEN/8, x4, x1, x2) + +inst_10: +// rs1==f22, rd==f21,fs1 == 0 and fe1 == 0x001 and fm1 == 0x0000000000002 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.d ; op1:f22; dest:f21; op1val:0x10000000000002; valaddr_reg:x3; +val_offset:10*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.d, f21, f22, dyn, 0, 0, x3, 10*FLEN/8, x4, x1, x2) + +inst_11: +// rs1==f19, rd==f20,fs1 == 1 and fe1 == 0x001 and fm1 == 0x0000000000002 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.d ; op1:f19; dest:f20; op1val:0x8010000000000002; valaddr_reg:x3; +val_offset:11*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.d, f20, f19, dyn, 0, 0, x3, 11*FLEN/8, x4, x1, x2) + +inst_12: +// rs1==f20, rd==f19,fs1 == 0 and fe1 == 0x7fe and fm1 == 0xfffffffffffff and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.d ; op1:f20; dest:f19; op1val:0x7fefffffffffffff; valaddr_reg:x3; +val_offset:12*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.d, f19, f20, dyn, 0, 0, x3, 12*FLEN/8, x4, x1, x2) + +inst_13: +// rs1==f17, rd==f18,fs1 == 1 and fe1 == 0x7fe and fm1 == 0xfffffffffffff and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.d ; op1:f17; dest:f18; op1val:0xffefffffffffffff; valaddr_reg:x3; +val_offset:13*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.d, f18, f17, dyn, 0, 0, x3, 13*FLEN/8, x4, x1, x2) + +inst_14: +// rs1==f18, rd==f17,fs1 == 0 and fe1 == 0x7ff and fm1 == 0x0000000000000 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.d ; op1:f18; dest:f17; op1val:0x7ff0000000000000; valaddr_reg:x3; +val_offset:14*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.d, f17, f18, dyn, 0, 0, x3, 14*FLEN/8, x4, x1, x2) + +inst_15: +// rs1==f15, rd==f16,fs1 == 1 and fe1 == 0x7ff and fm1 == 0x0000000000000 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.d ; op1:f15; dest:f16; op1val:0xfff0000000000000; valaddr_reg:x3; +val_offset:15*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.d, f16, f15, dyn, 0, 0, x3, 15*FLEN/8, x4, x1, x2) + +inst_16: +// rs1==f16, rd==f15,fs1 == 0 and fe1 == 0x7ff and fm1 == 0x8000000000000 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.d ; op1:f16; dest:f15; op1val:0x7ff8000000000000; valaddr_reg:x3; +val_offset:16*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.d, f15, f16, dyn, 0, 0, x3, 16*FLEN/8, x4, x1, x2) + +inst_17: +// rs1==f13, rd==f14,fs1 == 1 and fe1 == 0x7ff and fm1 == 0x8000000000000 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.d ; op1:f13; dest:f14; op1val:0xfff8000000000000; valaddr_reg:x3; +val_offset:17*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.d, f14, f13, dyn, 0, 0, x3, 17*FLEN/8, x4, x1, x2) + +inst_18: +// rs1==f14, rd==f13,fs1 == 0 and fe1 == 0x7ff and fm1 == 0x8000000000001 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.d ; op1:f14; dest:f13; op1val:0x7ff8000000000001; valaddr_reg:x3; +val_offset:18*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.d, f13, f14, dyn, 0, 0, x3, 18*FLEN/8, x4, x1, x2) + +inst_19: +// rs1==f11, rd==f12,fs1 == 1 and fe1 == 0x7ff and fm1 == 0x8000000000001 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.d ; op1:f11; dest:f12; op1val:0xfff8000000000001; valaddr_reg:x3; +val_offset:19*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.d, f12, f11, dyn, 0, 0, x3, 19*FLEN/8, x4, x1, x2) + +inst_20: +// rs1==f12, rd==f11,fs1 == 0 and fe1 == 0x7ff and fm1 == 0x0000000000001 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.d ; op1:f12; dest:f11; op1val:0x7ff0000000000001; valaddr_reg:x3; +val_offset:20*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.d, f11, f12, dyn, 0, 0, x3, 20*FLEN/8, x4, x1, x2) + +inst_21: +// rs1==f9, rd==f10,fs1 == 1 and fe1 == 0x7ff and fm1 == 0x0000000000001 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.d ; op1:f9; dest:f10; op1val:0xfff0000000000001; valaddr_reg:x3; +val_offset:21*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.d, f10, f9, dyn, 0, 0, x3, 21*FLEN/8, x4, x1, x2) + +inst_22: +// rs1==f10, rd==f9,fs1 == 0 and fe1 == 0x3ff and fm1 == 0x0000000000000 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.d ; op1:f10; dest:f9; op1val:0x3ff0000000000000; valaddr_reg:x3; +val_offset:22*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.d, f9, f10, dyn, 0, 0, x3, 22*FLEN/8, x4, x1, x2) + +inst_23: +// rs1==f7, rd==f8,fs1 == 1 and fe1 == 0x3f8 and fm1 == 0x0000000000000 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.d ; op1:f7; dest:f8; op1val:0xbf80000000000000; valaddr_reg:x3; +val_offset:23*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.d, f8, f7, dyn, 0, 0, x3, 23*FLEN/8, x4, x1, x2) + +inst_24: +// rs1==f8, rd==f7, +/* opcode: froundnx.d ; op1:f8; dest:f7; op1val:0x0; valaddr_reg:x3; +val_offset:24*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.d, f7, f8, dyn, 0, 0, x3, 24*FLEN/8, x4, x1, x2) + +inst_25: +// rs1==f5, rd==f6, +/* opcode: froundnx.d ; op1:f5; dest:f6; op1val:0x0; valaddr_reg:x3; +val_offset:25*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.d, f6, f5, dyn, 0, 0, x3, 25*FLEN/8, x4, x1, x2) + +inst_26: +// rs1==f6, rd==f5, +/* opcode: froundnx.d ; op1:f6; dest:f5; op1val:0x0; valaddr_reg:x3; +val_offset:26*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.d, f5, f6, dyn, 0, 0, x3, 26*FLEN/8, x4, x1, x2) + +inst_27: +// rs1==f3, rd==f4, +/* opcode: froundnx.d ; op1:f3; dest:f4; op1val:0x0; valaddr_reg:x3; +val_offset:27*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.d, f4, f3, dyn, 0, 0, x3, 27*FLEN/8, x4, x1, x2) + +inst_28: +// rs1==f4, rd==f3, +/* opcode: froundnx.d ; op1:f4; dest:f3; op1val:0x0; valaddr_reg:x3; +val_offset:28*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.d, f3, f4, dyn, 0, 0, x3, 28*FLEN/8, x4, x1, x2) + +inst_29: +// rs1==f1, rd==f2, +/* opcode: froundnx.d ; op1:f1; dest:f2; op1val:0x0; valaddr_reg:x3; +val_offset:29*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.d, f2, f1, dyn, 0, 0, x3, 29*FLEN/8, x4, x1, x2) + +inst_30: +// rs1==f2, rd==f1, +/* opcode: froundnx.d ; op1:f2; dest:f1; op1val:0x0; valaddr_reg:x3; +val_offset:30*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.d, f1, f2, dyn, 0, 0, x3, 30*FLEN/8, x4, x1, x2) + +inst_31: +// rs1==f0, +/* opcode: froundnx.d ; op1:f0; dest:f31; op1val:0x0; valaddr_reg:x3; +val_offset:31*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.d, f31, f0, dyn, 0, 0, x3, 31*FLEN/8, x4, x1, x2) + +inst_32: +// rd==f0, +/* opcode: froundnx.d ; op1:f31; dest:f0; op1val:0x0; valaddr_reg:x3; +val_offset:32*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.d, f0, f31, dyn, 0, 0, x3, 32*FLEN/8, x4, x1, x2) +#endif + + +RVTEST_CODE_END +RVMODEL_HALT + +RVTEST_DATA_BEGIN +.align 4 +rvtest_data: +.word 0xbabecafe +.word 0xabecafeb +.word 0xbecafeba +.word 0xecafebab +test_dataset_0: +NAN_BOXED(0,64,FLEN) +NAN_BOXED(9223372036854775808,64,FLEN) +NAN_BOXED(1,64,FLEN) +NAN_BOXED(9223372036854775809,64,FLEN) +NAN_BOXED(2,64,FLEN) +NAN_BOXED(9223372036854775810,64,FLEN) +NAN_BOXED(4503599627370495,64,FLEN) +NAN_BOXED(9227875636482146303,64,FLEN) +NAN_BOXED(4503599627370496,64,FLEN) +NAN_BOXED(9227875636482146304,64,FLEN) +NAN_BOXED(4503599627370498,64,FLEN) +NAN_BOXED(9227875636482146306,64,FLEN) +NAN_BOXED(9218868437227405311,64,FLEN) +NAN_BOXED(18442240474082181119,64,FLEN) +NAN_BOXED(9218868437227405312,64,FLEN) +NAN_BOXED(18442240474082181120,64,FLEN) +NAN_BOXED(9221120237041090560,64,FLEN) +NAN_BOXED(18444492273895866368,64,FLEN) +NAN_BOXED(9221120237041090561,64,FLEN) +NAN_BOXED(18444492273895866369,64,FLEN) +NAN_BOXED(9218868437227405313,64,FLEN) +NAN_BOXED(18442240474082181121,64,FLEN) +NAN_BOXED(4607182418800017408,64,FLEN) +NAN_BOXED(13799029258263199744,64,FLEN) +NAN_BOXED(0,64,FLEN) +NAN_BOXED(0,64,FLEN) +NAN_BOXED(0,64,FLEN) +NAN_BOXED(0,64,FLEN) +NAN_BOXED(0,64,FLEN) +NAN_BOXED(0,64,FLEN) +NAN_BOXED(0,64,FLEN) +NAN_BOXED(0,64,FLEN) +NAN_BOXED(0,64,FLEN) +RVTEST_DATA_END + +RVMODEL_DATA_BEGIN +rvtest_sig_begin: +sig_begin_canary: +CANARY; + + + +signature_x1_0: + .fill 0*((SIGALIGN)/4),4,0xdeadbeef + + +signature_x1_1: + .fill 66*((SIGALIGN)/4),4,0xdeadbeef + +#ifdef rvtest_mtrap_routine +tsig_begin_canary: +CANARY; + +mtrap_sigptr: + .fill 64*XLEN/32,4,0xdeadbeef + +tsig_end_canary: +CANARY; +#endif + +#ifdef rvtest_gpr_save + +gpr_save: + .fill 32*XLEN/32,4,0xdeadbeef + +#endif + + +sig_end_canary: +CANARY; +rvtest_sig_end: +RVMODEL_DATA_END diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/D_Zfa/src/froundnx_b1-01.S b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/D_Zfa/src/froundnx_b1-01.S new file mode 100644 index 000000000..a275776bd --- /dev/null +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/D_Zfa/src/froundnx_b1-01.S @@ -0,0 +1,353 @@ + +// ----------- +// This file was generated by riscv_ctg (https://github.com/riscv-software-src/riscv-ctg) +// version : 0.12.1 +// timestamp : Wed Mar 6 21:52:28 2024 GMT +// usage : riscv_ctg \ +// -- cgf // --cgf /home/cm/src/riscv-ctg/zfa/sample_cgfs/dataset.cgf \ +// --cgf /home/cm/src/riscv-ctg/zfa/sample_cgfs/zfa/froundnx.s.cgf \ + \ +// -- xlen 64 \ +// ----------- +// +// ----------- +// Copyright (c) 2020. RISC-V International. All rights reserved. +// SPDX-License-Identifier: BSD-3-Clause +// ----------- +// +// This assembly file tests the froundnx.s instruction of the RISC-V RV64F_Zicsr_Zfa,RV64FD_Zicsr_Zfa extension for the froundnx_b1 covergroup. +// +#include "model_test.h" +#include "arch_test.h" +RVTEST_ISA("RV64IF_Zicsr_Zfa,RV64IFD_Zicsr_Zfa") + +.section .text.init +.globl rvtest_entry_point +rvtest_entry_point: +RVMODEL_BOOT +RVTEST_CODE_BEGIN + +#ifdef TEST_CASE_1 + +RVTEST_CASE(0,"//check ISA:=regex(.*RV64.*I.*F.*Zfa.*);def TEST_CASE_1=True;",froundnx_b1) + +RVTEST_FP_ENABLE() +RVTEST_VALBASEUPD(x3,test_dataset_0) +RVTEST_SIGBASE(x1,signature_x1_1) + +inst_0: +// rs1 == rd, rs1==f31, rd==f31,fs1 == 0 and fe1 == 0x00 and fm1 == 0x000000 and fcsr == 0x0 and rm_val == 7 and rs1_nan_prefix == 0xffffffff +/* opcode: froundnx.s ; op1:f31; dest:f31; op1val:0x0; valaddr_reg:x3; +val_offset:0*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f31, f31, dyn, 0, 0, x3, 0*FLEN/8, x4, x1, x2) + +inst_1: +// rs1 != rd, rs1==f29, rd==f30,fs1 == 1 and fe1 == 0x00 and fm1 == 0x000000 and fcsr == 0x0 and rm_val == 7 and rs1_nan_prefix == 0xffffffff +/* opcode: froundnx.s ; op1:f29; dest:f30; op1val:0x80000000; valaddr_reg:x3; +val_offset:2*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f30, f29, dyn, 0, 0, x3, 2*FLEN/8, x4, x1, x2) + +inst_2: +// rs1==f30, rd==f29,fs1 == 0 and fe1 == 0x00 and fm1 == 0x000001 and fcsr == 0x0 and rm_val == 7 and rs1_nan_prefix == 0xffffffff +/* opcode: froundnx.s ; op1:f30; dest:f29; op1val:0x1; valaddr_reg:x3; +val_offset:4*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f29, f30, dyn, 0, 0, x3, 4*FLEN/8, x4, x1, x2) + +inst_3: +// rs1==f27, rd==f28,fs1 == 1 and fe1 == 0x00 and fm1 == 0x000001 and fcsr == 0x0 and rm_val == 7 and rs1_nan_prefix == 0xffffffff +/* opcode: froundnx.s ; op1:f27; dest:f28; op1val:0x80000001; valaddr_reg:x3; +val_offset:6*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f28, f27, dyn, 0, 0, x3, 6*FLEN/8, x4, x1, x2) + +inst_4: +// rs1==f28, rd==f27,fs1 == 0 and fe1 == 0x00 and fm1 == 0x000002 and fcsr == 0x0 and rm_val == 7 and rs1_nan_prefix == 0xffffffff +/* opcode: froundnx.s ; op1:f28; dest:f27; op1val:0x2; valaddr_reg:x3; +val_offset:8*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f27, f28, dyn, 0, 0, x3, 8*FLEN/8, x4, x1, x2) + +inst_5: +// rs1==f25, rd==f26,fs1 == 1 and fe1 == 0x00 and fm1 == 0x7ffffe and fcsr == 0x0 and rm_val == 7 and rs1_nan_prefix == 0xffffffff +/* opcode: froundnx.s ; op1:f25; dest:f26; op1val:0x807ffffe; valaddr_reg:x3; +val_offset:10*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f26, f25, dyn, 0, 0, x3, 10*FLEN/8, x4, x1, x2) + +inst_6: +// rs1==f26, rd==f25,fs1 == 0 and fe1 == 0x00 and fm1 == 0x7fffff and fcsr == 0x0 and rm_val == 7 and rs1_nan_prefix == 0xffffffff +/* opcode: froundnx.s ; op1:f26; dest:f25; op1val:0x7fffff; valaddr_reg:x3; +val_offset:12*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f25, f26, dyn, 0, 0, x3, 12*FLEN/8, x4, x1, x2) + +inst_7: +// rs1==f23, rd==f24,fs1 == 1 and fe1 == 0x00 and fm1 == 0x7fffff and fcsr == 0x0 and rm_val == 7 and rs1_nan_prefix == 0xffffffff +/* opcode: froundnx.s ; op1:f23; dest:f24; op1val:0x807fffff; valaddr_reg:x3; +val_offset:14*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f24, f23, dyn, 0, 0, x3, 14*FLEN/8, x4, x1, x2) + +inst_8: +// rs1==f24, rd==f23,fs1 == 0 and fe1 == 0x01 and fm1 == 0x000000 and fcsr == 0x0 and rm_val == 7 and rs1_nan_prefix == 0xffffffff +/* opcode: froundnx.s ; op1:f24; dest:f23; op1val:0x800000; valaddr_reg:x3; +val_offset:16*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f23, f24, dyn, 0, 0, x3, 16*FLEN/8, x4, x1, x2) + +inst_9: +// rs1==f21, rd==f22,fs1 == 1 and fe1 == 0x01 and fm1 == 0x000000 and fcsr == 0x0 and rm_val == 7 and rs1_nan_prefix == 0xffffffff +/* opcode: froundnx.s ; op1:f21; dest:f22; op1val:0x80800000; valaddr_reg:x3; +val_offset:18*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f22, f21, dyn, 0, 0, x3, 18*FLEN/8, x4, x1, x2) + +inst_10: +// rs1==f22, rd==f21,fs1 == 0 and fe1 == 0x01 and fm1 == 0x000001 and fcsr == 0x0 and rm_val == 7 and rs1_nan_prefix == 0xffffffff +/* opcode: froundnx.s ; op1:f22; dest:f21; op1val:0x800001; valaddr_reg:x3; +val_offset:20*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f21, f22, dyn, 0, 0, x3, 20*FLEN/8, x4, x1, x2) + +inst_11: +// rs1==f19, rd==f20,fs1 == 1 and fe1 == 0x01 and fm1 == 0x055555 and fcsr == 0x0 and rm_val == 7 and rs1_nan_prefix == 0xffffffff +/* opcode: froundnx.s ; op1:f19; dest:f20; op1val:0x80855555; valaddr_reg:x3; +val_offset:22*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f20, f19, dyn, 0, 0, x3, 22*FLEN/8, x4, x1, x2) + +inst_12: +// rs1==f20, rd==f19,fs1 == 0 and fe1 == 0xfe and fm1 == 0x7fffff and fcsr == 0x0 and rm_val == 7 and rs1_nan_prefix == 0xffffffff +/* opcode: froundnx.s ; op1:f20; dest:f19; op1val:0x7f7fffff; valaddr_reg:x3; +val_offset:24*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f19, f20, dyn, 0, 0, x3, 24*FLEN/8, x4, x1, x2) + +inst_13: +// rs1==f17, rd==f18,fs1 == 1 and fe1 == 0xfe and fm1 == 0x7fffff and fcsr == 0x0 and rm_val == 7 and rs1_nan_prefix == 0xffffffff +/* opcode: froundnx.s ; op1:f17; dest:f18; op1val:0xff7fffff; valaddr_reg:x3; +val_offset:26*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f18, f17, dyn, 0, 0, x3, 26*FLEN/8, x4, x1, x2) + +inst_14: +// rs1==f18, rd==f17,fs1 == 0 and fe1 == 0xff and fm1 == 0x000000 and fcsr == 0x0 and rm_val == 7 and rs1_nan_prefix == 0xffffffff +/* opcode: froundnx.s ; op1:f18; dest:f17; op1val:0x7f800000; valaddr_reg:x3; +val_offset:28*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f17, f18, dyn, 0, 0, x3, 28*FLEN/8, x4, x1, x2) + +inst_15: +// rs1==f15, rd==f16,fs1 == 1 and fe1 == 0xff and fm1 == 0x000000 and fcsr == 0x0 and rm_val == 7 and rs1_nan_prefix == 0xffffffff +/* opcode: froundnx.s ; op1:f15; dest:f16; op1val:0xff800000; valaddr_reg:x3; +val_offset:30*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f16, f15, dyn, 0, 0, x3, 30*FLEN/8, x4, x1, x2) + +inst_16: +// rs1==f16, rd==f15,fs1 == 0 and fe1 == 0xff and fm1 == 0x400000 and fcsr == 0x0 and rm_val == 7 and rs1_nan_prefix == 0xffffffff +/* opcode: froundnx.s ; op1:f16; dest:f15; op1val:0x7fc00000; valaddr_reg:x3; +val_offset:32*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f15, f16, dyn, 0, 0, x3, 32*FLEN/8, x4, x1, x2) + +inst_17: +// rs1==f13, rd==f14,fs1 == 1 and fe1 == 0xff and fm1 == 0x400000 and fcsr == 0x0 and rm_val == 7 and rs1_nan_prefix == 0xffffffff +/* opcode: froundnx.s ; op1:f13; dest:f14; op1val:0xffc00000; valaddr_reg:x3; +val_offset:34*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f14, f13, dyn, 0, 0, x3, 34*FLEN/8, x4, x1, x2) + +inst_18: +// rs1==f14, rd==f13,fs1 == 0 and fe1 == 0xff and fm1 == 0x400001 and fcsr == 0x0 and rm_val == 7 and rs1_nan_prefix == 0xffffffff +/* opcode: froundnx.s ; op1:f14; dest:f13; op1val:0x7fc00001; valaddr_reg:x3; +val_offset:36*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f13, f14, dyn, 0, 0, x3, 36*FLEN/8, x4, x1, x2) + +inst_19: +// rs1==f11, rd==f12,fs1 == 1 and fe1 == 0xff and fm1 == 0x455555 and fcsr == 0x0 and rm_val == 7 and rs1_nan_prefix == 0xffffffff +/* opcode: froundnx.s ; op1:f11; dest:f12; op1val:0xffc55555; valaddr_reg:x3; +val_offset:38*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f12, f11, dyn, 0, 0, x3, 38*FLEN/8, x4, x1, x2) + +inst_20: +// rs1==f12, rd==f11,fs1 == 0 and fe1 == 0xff and fm1 == 0x000001 and fcsr == 0x0 and rm_val == 7 and rs1_nan_prefix == 0xffffffff +/* opcode: froundnx.s ; op1:f12; dest:f11; op1val:0x7f800001; valaddr_reg:x3; +val_offset:40*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f11, f12, dyn, 0, 0, x3, 40*FLEN/8, x4, x1, x2) + +inst_21: +// rs1==f9, rd==f10,fs1 == 1 and fe1 == 0xff and fm1 == 0x2aaaaa and fcsr == 0x0 and rm_val == 7 and rs1_nan_prefix == 0xffffffff +/* opcode: froundnx.s ; op1:f9; dest:f10; op1val:0xffaaaaaa; valaddr_reg:x3; +val_offset:42*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f10, f9, dyn, 0, 0, x3, 42*FLEN/8, x4, x1, x2) + +inst_22: +// rs1==f10, rd==f9,fs1 == 0 and fe1 == 0x7f and fm1 == 0x000000 and fcsr == 0x0 and rm_val == 7 and rs1_nan_prefix == 0xffffffff +/* opcode: froundnx.s ; op1:f10; dest:f9; op1val:0x3f800000; valaddr_reg:x3; +val_offset:44*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f9, f10, dyn, 0, 0, x3, 44*FLEN/8, x4, x1, x2) + +inst_23: +// rs1==f7, rd==f8,fs1 == 1 and fe1 == 0x7f and fm1 == 0x000000 and fcsr == 0x0 and rm_val == 7 and rs1_nan_prefix == 0xffffffff +/* opcode: froundnx.s ; op1:f7; dest:f8; op1val:0xbf800000; valaddr_reg:x3; +val_offset:46*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f8, f7, dyn, 0, 0, x3, 46*FLEN/8, x4, x1, x2) + +inst_24: +// rs1==f8, rd==f7, +/* opcode: froundnx.s ; op1:f8; dest:f7; op1val:0x0; valaddr_reg:x3; +val_offset:48*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f7, f8, dyn, 0, 0, x3, 48*FLEN/8, x4, x1, x2) + +inst_25: +// rs1==f5, rd==f6, +/* opcode: froundnx.s ; op1:f5; dest:f6; op1val:0x0; valaddr_reg:x3; +val_offset:50*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f6, f5, dyn, 0, 0, x3, 50*FLEN/8, x4, x1, x2) + +inst_26: +// rs1==f6, rd==f5, +/* opcode: froundnx.s ; op1:f6; dest:f5; op1val:0x0; valaddr_reg:x3; +val_offset:52*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f5, f6, dyn, 0, 0, x3, 52*FLEN/8, x4, x1, x2) + +inst_27: +// rs1==f3, rd==f4, +/* opcode: froundnx.s ; op1:f3; dest:f4; op1val:0x0; valaddr_reg:x3; +val_offset:54*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f4, f3, dyn, 0, 0, x3, 54*FLEN/8, x4, x1, x2) + +inst_28: +// rs1==f4, rd==f3, +/* opcode: froundnx.s ; op1:f4; dest:f3; op1val:0x0; valaddr_reg:x3; +val_offset:56*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f3, f4, dyn, 0, 0, x3, 56*FLEN/8, x4, x1, x2) + +inst_29: +// rs1==f1, rd==f2, +/* opcode: froundnx.s ; op1:f1; dest:f2; op1val:0x0; valaddr_reg:x3; +val_offset:58*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f2, f1, dyn, 0, 0, x3, 58*FLEN/8, x4, x1, x2) + +inst_30: +// rs1==f2, rd==f1, +/* opcode: froundnx.s ; op1:f2; dest:f1; op1val:0x0; valaddr_reg:x3; +val_offset:60*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f1, f2, dyn, 0, 0, x3, 60*FLEN/8, x4, x1, x2) + +inst_31: +// rs1==f0, +/* opcode: froundnx.s ; op1:f0; dest:f31; op1val:0x0; valaddr_reg:x3; +val_offset:62*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f31, f0, dyn, 0, 0, x3, 62*FLEN/8, x4, x1, x2) + +inst_32: +// rd==f0, +/* opcode: froundnx.s ; op1:f31; dest:f0; op1val:0x0; valaddr_reg:x3; +val_offset:64*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f0, f31, dyn, 0, 0, x3, 64*FLEN/8, x4, x1, x2) +#endif + + +RVTEST_CODE_END +RVMODEL_HALT + +RVTEST_DATA_BEGIN +.align 4 +rvtest_data: +.word 0xbabecafe +.word 0xabecafeb +.word 0xbecafeba +.word 0xecafebab +test_dataset_0: +NAN_BOXED(0,32,FLEN) +NAN_BOXED(2147483648,32,FLEN) +NAN_BOXED(1,32,FLEN) +NAN_BOXED(2147483649,32,FLEN) +NAN_BOXED(2,32,FLEN) +NAN_BOXED(2155872254,32,FLEN) +NAN_BOXED(8388607,32,FLEN) +NAN_BOXED(2155872255,32,FLEN) +NAN_BOXED(8388608,32,FLEN) +NAN_BOXED(2155872256,32,FLEN) +NAN_BOXED(8388609,32,FLEN) +NAN_BOXED(2156221781,32,FLEN) +NAN_BOXED(2139095039,32,FLEN) +NAN_BOXED(4286578687,32,FLEN) +NAN_BOXED(2139095040,32,FLEN) +NAN_BOXED(4286578688,32,FLEN) +NAN_BOXED(2143289344,32,FLEN) +NAN_BOXED(4290772992,32,FLEN) +NAN_BOXED(2143289345,32,FLEN) +NAN_BOXED(4291122517,32,FLEN) +NAN_BOXED(2139095041,32,FLEN) +NAN_BOXED(4289374890,32,FLEN) +NAN_BOXED(1065353216,32,FLEN) +NAN_BOXED(3212836864,32,FLEN) +NAN_BOXED(0,64,FLEN) +NAN_BOXED(0,64,FLEN) +NAN_BOXED(0,64,FLEN) +NAN_BOXED(0,64,FLEN) +NAN_BOXED(0,64,FLEN) +NAN_BOXED(0,64,FLEN) +NAN_BOXED(0,64,FLEN) +NAN_BOXED(0,64,FLEN) +NAN_BOXED(0,64,FLEN) +RVTEST_DATA_END + +RVMODEL_DATA_BEGIN +rvtest_sig_begin: +sig_begin_canary: +CANARY; + + + +signature_x1_0: + .fill 0*((SIGALIGN)/4),4,0xdeadbeef + + +signature_x1_1: + .fill 66*((SIGALIGN)/4),4,0xdeadbeef + +#ifdef rvtest_mtrap_routine +tsig_begin_canary: +CANARY; + +mtrap_sigptr: + .fill 64*XLEN/32,4,0xdeadbeef + +tsig_end_canary: +CANARY; +#endif + +#ifdef rvtest_gpr_save + +gpr_save: + .fill 32*XLEN/32,4,0xdeadbeef + +#endif + + +sig_end_canary: +CANARY; +rvtest_sig_end: +RVMODEL_DATA_END diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/F_Zfa/src/froundnx_b1-01.S b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/F_Zfa/src/froundnx_b1-01.S new file mode 100644 index 000000000..046749f85 --- /dev/null +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/F_Zfa/src/froundnx_b1-01.S @@ -0,0 +1,353 @@ + +// ----------- +// This file was generated by riscv_ctg (https://github.com/riscv-software-src/riscv-ctg) +// version : 0.12.1 +// timestamp : Mon Apr 1 19:36:25 2024 GMT +// usage : riscv_ctg \ +// -- cgf // --cgf /home/cm/src/riscv-ctg/zfa/sample_cgfs/dataset.cgf \ +// --cgf /home/cm/src/riscv-ctg/zfa/sample_cgfs/zfa/froundnx.s.cgf \ + \ +// -- xlen 64 \ +// ----------- +// +// ----------- +// Copyright (c) 2020. RISC-V International. All rights reserved. +// SPDX-License-Identifier: BSD-3-Clause +// ----------- +// +// This assembly file tests the froundnx.s instruction of the RISC-V RV64F_Zicsr_Zfa,RV64FD_Zicsr_Zfa extension for the froundnx_b1 covergroup. +// +#include "model_test.h" +#include "arch_test.h" +RVTEST_ISA("RV64IF_Zicsr_Zfa,RV64IFD_Zicsr_Zfa") + +.section .text.init +.globl rvtest_entry_point +rvtest_entry_point: +RVMODEL_BOOT +RVTEST_CODE_BEGIN + +#ifdef TEST_CASE_1 + +RVTEST_CASE(0,"//check ISA:=regex(.*RV64.*I.*F.*Zfa.*);def TEST_CASE_1=True;",froundnx_b1) + +RVTEST_FP_ENABLE() +RVTEST_VALBASEUPD(x3,test_dataset_0) +RVTEST_SIGBASE(x1,signature_x1_1) + +inst_0: +// rs1 != rd, rs1==f30, rd==f31,fs1 == 0 and fe1 == 0x00 and fm1 == 0x000000 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.s ; op1:f30; dest:f31; op1val:0x0; valaddr_reg:x3; +val_offset:0*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f31, f30, dyn, 0, 0, x3, 0*FLEN/8, x4, x1, x2) + +inst_1: +// rs1 == rd, rs1==f29, rd==f29,fs1 == 1 and fe1 == 0x00 and fm1 == 0x000000 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.s ; op1:f29; dest:f29; op1val:0x80000000; valaddr_reg:x3; +val_offset:2*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f29, f29, dyn, 0, 0, x3, 2*FLEN/8, x4, x1, x2) + +inst_2: +// rs1==f31, rd==f30,fs1 == 0 and fe1 == 0x00 and fm1 == 0x000001 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.s ; op1:f31; dest:f30; op1val:0x1; valaddr_reg:x3; +val_offset:4*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f30, f31, dyn, 0, 0, x3, 4*FLEN/8, x4, x1, x2) + +inst_3: +// rs1==f27, rd==f28,fs1 == 1 and fe1 == 0x00 and fm1 == 0x000001 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.s ; op1:f27; dest:f28; op1val:0x80000001; valaddr_reg:x3; +val_offset:6*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f28, f27, dyn, 0, 0, x3, 6*FLEN/8, x4, x1, x2) + +inst_4: +// rs1==f28, rd==f27,fs1 == 0 and fe1 == 0x00 and fm1 == 0x000002 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.s ; op1:f28; dest:f27; op1val:0x2; valaddr_reg:x3; +val_offset:8*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f27, f28, dyn, 0, 0, x3, 8*FLEN/8, x4, x1, x2) + +inst_5: +// rs1==f25, rd==f26,fs1 == 1 and fe1 == 0x00 and fm1 == 0x7ffffe and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.s ; op1:f25; dest:f26; op1val:0x807ffffe; valaddr_reg:x3; +val_offset:10*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f26, f25, dyn, 0, 0, x3, 10*FLEN/8, x4, x1, x2) + +inst_6: +// rs1==f26, rd==f25,fs1 == 0 and fe1 == 0x00 and fm1 == 0x7fffff and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.s ; op1:f26; dest:f25; op1val:0x7fffff; valaddr_reg:x3; +val_offset:12*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f25, f26, dyn, 0, 0, x3, 12*FLEN/8, x4, x1, x2) + +inst_7: +// rs1==f23, rd==f24,fs1 == 1 and fe1 == 0x00 and fm1 == 0x7fffff and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.s ; op1:f23; dest:f24; op1val:0x807fffff; valaddr_reg:x3; +val_offset:14*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f24, f23, dyn, 0, 0, x3, 14*FLEN/8, x4, x1, x2) + +inst_8: +// rs1==f24, rd==f23,fs1 == 0 and fe1 == 0x01 and fm1 == 0x000000 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.s ; op1:f24; dest:f23; op1val:0x800000; valaddr_reg:x3; +val_offset:16*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f23, f24, dyn, 0, 0, x3, 16*FLEN/8, x4, x1, x2) + +inst_9: +// rs1==f21, rd==f22,fs1 == 1 and fe1 == 0x01 and fm1 == 0x000000 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.s ; op1:f21; dest:f22; op1val:0x80800000; valaddr_reg:x3; +val_offset:18*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f22, f21, dyn, 0, 0, x3, 18*FLEN/8, x4, x1, x2) + +inst_10: +// rs1==f22, rd==f21,fs1 == 0 and fe1 == 0x01 and fm1 == 0x000001 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.s ; op1:f22; dest:f21; op1val:0x800001; valaddr_reg:x3; +val_offset:20*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f21, f22, dyn, 0, 0, x3, 20*FLEN/8, x4, x1, x2) + +inst_11: +// rs1==f19, rd==f20,fs1 == 1 and fe1 == 0x01 and fm1 == 0x055555 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.s ; op1:f19; dest:f20; op1val:0x80855555; valaddr_reg:x3; +val_offset:22*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f20, f19, dyn, 0, 0, x3, 22*FLEN/8, x4, x1, x2) + +inst_12: +// rs1==f20, rd==f19,fs1 == 0 and fe1 == 0xfe and fm1 == 0x7fffff and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.s ; op1:f20; dest:f19; op1val:0x7f7fffff; valaddr_reg:x3; +val_offset:24*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f19, f20, dyn, 0, 0, x3, 24*FLEN/8, x4, x1, x2) + +inst_13: +// rs1==f17, rd==f18,fs1 == 1 and fe1 == 0xfe and fm1 == 0x7fffff and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.s ; op1:f17; dest:f18; op1val:0xff7fffff; valaddr_reg:x3; +val_offset:26*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f18, f17, dyn, 0, 0, x3, 26*FLEN/8, x4, x1, x2) + +inst_14: +// rs1==f18, rd==f17,fs1 == 0 and fe1 == 0xff and fm1 == 0x000000 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.s ; op1:f18; dest:f17; op1val:0x7f800000; valaddr_reg:x3; +val_offset:28*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f17, f18, dyn, 0, 0, x3, 28*FLEN/8, x4, x1, x2) + +inst_15: +// rs1==f15, rd==f16,fs1 == 1 and fe1 == 0xff and fm1 == 0x000000 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.s ; op1:f15; dest:f16; op1val:0xff800000; valaddr_reg:x3; +val_offset:30*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f16, f15, dyn, 0, 0, x3, 30*FLEN/8, x4, x1, x2) + +inst_16: +// rs1==f16, rd==f15,fs1 == 0 and fe1 == 0xff and fm1 == 0x400000 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.s ; op1:f16; dest:f15; op1val:0x7fc00000; valaddr_reg:x3; +val_offset:32*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f15, f16, dyn, 0, 0, x3, 32*FLEN/8, x4, x1, x2) + +inst_17: +// rs1==f13, rd==f14,fs1 == 1 and fe1 == 0xff and fm1 == 0x400000 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.s ; op1:f13; dest:f14; op1val:0xffc00000; valaddr_reg:x3; +val_offset:34*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f14, f13, dyn, 0, 0, x3, 34*FLEN/8, x4, x1, x2) + +inst_18: +// rs1==f14, rd==f13,fs1 == 0 and fe1 == 0xff and fm1 == 0x400001 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.s ; op1:f14; dest:f13; op1val:0x7fc00001; valaddr_reg:x3; +val_offset:36*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f13, f14, dyn, 0, 0, x3, 36*FLEN/8, x4, x1, x2) + +inst_19: +// rs1==f11, rd==f12,fs1 == 1 and fe1 == 0xff and fm1 == 0x455555 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.s ; op1:f11; dest:f12; op1val:0xffc55555; valaddr_reg:x3; +val_offset:38*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f12, f11, dyn, 0, 0, x3, 38*FLEN/8, x4, x1, x2) + +inst_20: +// rs1==f12, rd==f11,fs1 == 0 and fe1 == 0xff and fm1 == 0x000001 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.s ; op1:f12; dest:f11; op1val:0x7f800001; valaddr_reg:x3; +val_offset:40*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f11, f12, dyn, 0, 0, x3, 40*FLEN/8, x4, x1, x2) + +inst_21: +// rs1==f9, rd==f10,fs1 == 1 and fe1 == 0xff and fm1 == 0x2aaaaa and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.s ; op1:f9; dest:f10; op1val:0xffaaaaaa; valaddr_reg:x3; +val_offset:42*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f10, f9, dyn, 0, 0, x3, 42*FLEN/8, x4, x1, x2) + +inst_22: +// rs1==f10, rd==f9,fs1 == 0 and fe1 == 0x7f and fm1 == 0x000000 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.s ; op1:f10; dest:f9; op1val:0x3f800000; valaddr_reg:x3; +val_offset:44*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f9, f10, dyn, 0, 0, x3, 44*FLEN/8, x4, x1, x2) + +inst_23: +// rs1==f7, rd==f8,fs1 == 1 and fe1 == 0x7f and fm1 == 0x000000 and fcsr == 0x0 and rm_val == 7 +/* opcode: froundnx.s ; op1:f7; dest:f8; op1val:0xbf800000; valaddr_reg:x3; +val_offset:46*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f8, f7, dyn, 0, 0, x3, 46*FLEN/8, x4, x1, x2) + +inst_24: +// rs1==f8, rd==f7, +/* opcode: froundnx.s ; op1:f8; dest:f7; op1val:0x0; valaddr_reg:x3; +val_offset:48*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f7, f8, dyn, 0, 0, x3, 48*FLEN/8, x4, x1, x2) + +inst_25: +// rs1==f5, rd==f6, +/* opcode: froundnx.s ; op1:f5; dest:f6; op1val:0x0; valaddr_reg:x3; +val_offset:50*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f6, f5, dyn, 0, 0, x3, 50*FLEN/8, x4, x1, x2) + +inst_26: +// rs1==f6, rd==f5, +/* opcode: froundnx.s ; op1:f6; dest:f5; op1val:0x0; valaddr_reg:x3; +val_offset:52*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f5, f6, dyn, 0, 0, x3, 52*FLEN/8, x4, x1, x2) + +inst_27: +// rs1==f3, rd==f4, +/* opcode: froundnx.s ; op1:f3; dest:f4; op1val:0x0; valaddr_reg:x3; +val_offset:54*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f4, f3, dyn, 0, 0, x3, 54*FLEN/8, x4, x1, x2) + +inst_28: +// rs1==f4, rd==f3, +/* opcode: froundnx.s ; op1:f4; dest:f3; op1val:0x0; valaddr_reg:x3; +val_offset:56*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f3, f4, dyn, 0, 0, x3, 56*FLEN/8, x4, x1, x2) + +inst_29: +// rs1==f1, rd==f2, +/* opcode: froundnx.s ; op1:f1; dest:f2; op1val:0x0; valaddr_reg:x3; +val_offset:58*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f2, f1, dyn, 0, 0, x3, 58*FLEN/8, x4, x1, x2) + +inst_30: +// rs1==f2, rd==f1, +/* opcode: froundnx.s ; op1:f2; dest:f1; op1val:0x0; valaddr_reg:x3; +val_offset:60*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f1, f2, dyn, 0, 0, x3, 60*FLEN/8, x4, x1, x2) + +inst_31: +// rs1==f0, +/* opcode: froundnx.s ; op1:f0; dest:f31; op1val:0x0; valaddr_reg:x3; +val_offset:62*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f31, f0, dyn, 0, 0, x3, 62*FLEN/8, x4, x1, x2) + +inst_32: +// rd==f0, +/* opcode: froundnx.s ; op1:f31; dest:f0; op1val:0x0; valaddr_reg:x3; +val_offset:64*FLEN/8; rmval:dyn; correctval:??; testreg:x2; +fcsr_val: 0 */ +TEST_FPSR_OP(froundnx.s, f0, f31, dyn, 0, 0, x3, 64*FLEN/8, x4, x1, x2) +#endif + + +RVTEST_CODE_END +RVMODEL_HALT + +RVTEST_DATA_BEGIN +.align 4 +rvtest_data: +.word 0xbabecafe +.word 0xabecafeb +.word 0xbecafeba +.word 0xecafebab +test_dataset_0: +NAN_BOXED(0,32,FLEN) +NAN_BOXED(2147483648,32,FLEN) +NAN_BOXED(1,32,FLEN) +NAN_BOXED(2147483649,32,FLEN) +NAN_BOXED(2,32,FLEN) +NAN_BOXED(2155872254,32,FLEN) +NAN_BOXED(8388607,32,FLEN) +NAN_BOXED(2155872255,32,FLEN) +NAN_BOXED(8388608,32,FLEN) +NAN_BOXED(2155872256,32,FLEN) +NAN_BOXED(8388609,32,FLEN) +NAN_BOXED(2156221781,32,FLEN) +NAN_BOXED(2139095039,32,FLEN) +NAN_BOXED(4286578687,32,FLEN) +NAN_BOXED(2139095040,32,FLEN) +NAN_BOXED(4286578688,32,FLEN) +NAN_BOXED(2143289344,32,FLEN) +NAN_BOXED(4290772992,32,FLEN) +NAN_BOXED(2143289345,32,FLEN) +NAN_BOXED(4291122517,32,FLEN) +NAN_BOXED(2139095041,32,FLEN) +NAN_BOXED(4289374890,32,FLEN) +NAN_BOXED(1065353216,32,FLEN) +NAN_BOXED(3212836864,32,FLEN) +NAN_BOXED(0,32,FLEN) +NAN_BOXED(0,32,FLEN) +NAN_BOXED(0,32,FLEN) +NAN_BOXED(0,32,FLEN) +NAN_BOXED(0,32,FLEN) +NAN_BOXED(0,32,FLEN) +NAN_BOXED(0,32,FLEN) +NAN_BOXED(0,32,FLEN) +NAN_BOXED(0,32,FLEN) +RVTEST_DATA_END + +RVMODEL_DATA_BEGIN +rvtest_sig_begin: +sig_begin_canary: +CANARY; + + + +signature_x1_0: + .fill 0*((SIGALIGN)/4),4,0xdeadbeef + + +signature_x1_1: + .fill 66*((SIGALIGN)/4),4,0xdeadbeef + +#ifdef rvtest_mtrap_routine +tsig_begin_canary: +CANARY; + +mtrap_sigptr: + .fill 64*XLEN/32,4,0xdeadbeef + +tsig_end_canary: +CANARY; +#endif + +#ifdef rvtest_gpr_save + +gpr_save: + .fill 32*XLEN/32,4,0xdeadbeef + +#endif + + +sig_end_canary: +CANARY; +rvtest_sig_end: +RVMODEL_DATA_END From cfe83f5b498667c669c29d1218010fb4813a3e27 Mon Sep 17 00:00:00 2001 From: David Harris Date: Fri, 24 May 2024 15:18:36 -0700 Subject: [PATCH 35/51] Added derived configs to test Zb* and Zk* individually --- config/derivlist.txt | 240 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 240 insertions(+) diff --git a/config/derivlist.txt b/config/derivlist.txt index 1ed046a6a..174ca5191 100644 --- a/config/derivlist.txt +++ b/config/derivlist.txt @@ -530,6 +530,246 @@ ZALRSC_SUPPORTED 0 deriv zalrsc_rv64gc rv64gc ZAAMO_SUPPORTED 0 +deriv zba_rv32gc rv32gc +ZBA_SUPPORTED 1 +ZBB_SUPPORTED 0 +ZBS_SUPPORTED 0 +ZBC_SUPPORTED 0 +ZBKB_SUPPORTED 0 +ZBKC_SUPPORTED 0 +ZBKX_SUPPORTED 0 +ZKND_SUPPORTED 0 +ZKNE_SUPPORTED 0 +ZKNH_SUPPORTED 0 + +deriv zbb_rv32gc rv32gc +ZBA_SUPPORTED 0 +ZBB_SUPPORTED 1 +ZBS_SUPPORTED 0 +ZBC_SUPPORTED 0 +ZBKB_SUPPORTED 0 +ZBKC_SUPPORTED 0 +ZBKX_SUPPORTED 0 +ZKND_SUPPORTED 0 +ZKNE_SUPPORTED 0 +ZKNH_SUPPORTED 0 + +deriv zbc_rv32gc rv32gc +ZBA_SUPPORTED 0 +ZBB_SUPPORTED 0 +ZBS_SUPPORTED 0 +ZBC_SUPPORTED 1 +ZBKB_SUPPORTED 0 +ZBKC_SUPPORTED 0 +ZBKX_SUPPORTED 0 +ZKND_SUPPORTED 0 +ZKNE_SUPPORTED 0 +ZKNH_SUPPORTED 0 + +deriv zbs_rv32gc rv32gc +ZBA_SUPPORTED 0 +ZBB_SUPPORTED 0 +ZBS_SUPPORTED 1 +ZBC_SUPPORTED 0 +ZBKB_SUPPORTED 0 +ZBKC_SUPPORTED 0 +ZBKX_SUPPORTED 0 +ZKND_SUPPORTED 0 +ZKNE_SUPPORTED 0 +ZKNH_SUPPORTED 0 + +deriv zbkb_rv32gc rv32gc +ZBA_SUPPORTED 0 +ZBB_SUPPORTED 0 +ZBS_SUPPORTED 0 +ZBC_SUPPORTED 0 +ZBKB_SUPPORTED 1 +ZBKC_SUPPORTED 0 +ZBKX_SUPPORTED 0 +ZKND_SUPPORTED 0 +ZKNE_SUPPORTED 0 +ZKNH_SUPPORTED 0 + +deriv zbkc_rv32gc rv32gc +ZBA_SUPPORTED 0 +ZBB_SUPPORTED 0 +ZBS_SUPPORTED 0 +ZBC_SUPPORTED 0 +ZBKB_SUPPORTED 0 +ZBKC_SUPPORTED 1 +ZBKX_SUPPORTED 0 +ZKND_SUPPORTED 0 +ZKNE_SUPPORTED 0 +ZKNH_SUPPORTED 0 + +deriv zbkx_rv32gc rv32gc +ZBA_SUPPORTED 0 +ZBB_SUPPORTED 0 +ZBS_SUPPORTED 0 +ZBC_SUPPORTED 0 +ZBKB_SUPPORTED 0 +ZBKC_SUPPORTED 0 +ZBKX_SUPPORTED 1 +ZKND_SUPPORTED 0 +ZKNE_SUPPORTED 0 +ZKNH_SUPPORTED 0 + +deriv zknd_rv32gc rv32gc +ZBA_SUPPORTED 0 +ZBB_SUPPORTED 0 +ZBS_SUPPORTED 0 +ZBC_SUPPORTED 0 +ZBKB_SUPPORTED 0 +ZBKC_SUPPORTED 0 +ZBKX_SUPPORTED 0 +ZKND_SUPPORTED 1 +ZKNE_SUPPORTED 0 +ZKNH_SUPPORTED 0 + +deriv zkne_rv32gc rv32gc +ZBA_SUPPORTED 0 +ZBB_SUPPORTED 0 +ZBS_SUPPORTED 0 +ZBC_SUPPORTED 0 +ZBKB_SUPPORTED 0 +ZBKC_SUPPORTED 0 +ZBKX_SUPPORTED 0 +ZKND_SUPPORTED 0 +ZKNE_SUPPORTED 1 +ZKNH_SUPPORTED 0 + +deriv zknh_rv32gc rv32gc +ZBA_SUPPORTED 0 +ZBB_SUPPORTED 0 +ZBS_SUPPORTED 0 +ZBC_SUPPORTED 0 +ZBKB_SUPPORTED 0 +ZBKC_SUPPORTED 0 +ZBKX_SUPPORTED 0 +ZKND_SUPPORTED 0 +ZKNE_SUPPORTED 0 +ZKNH_SUPPORTED 1 + +deriv zba_rv64gc rv64gc +ZBA_SUPPORTED 1 +ZBB_SUPPORTED 0 +ZBS_SUPPORTED 0 +ZBC_SUPPORTED 0 +ZBKB_SUPPORTED 0 +ZBKC_SUPPORTED 0 +ZBKX_SUPPORTED 0 +ZKND_SUPPORTED 0 +ZKNE_SUPPORTED 0 +ZKNH_SUPPORTED 0 + +deriv zbb_rv64gc rv64gc +ZBA_SUPPORTED 0 +ZBB_SUPPORTED 1 +ZBS_SUPPORTED 0 +ZBC_SUPPORTED 0 +ZBKB_SUPPORTED 0 +ZBKC_SUPPORTED 0 +ZBKX_SUPPORTED 0 +ZKND_SUPPORTED 0 +ZKNE_SUPPORTED 0 +ZKNH_SUPPORTED 0 + +deriv zbc_rv64gc rv64gc +ZBA_SUPPORTED 0 +ZBB_SUPPORTED 0 +ZBS_SUPPORTED 0 +ZBC_SUPPORTED 1 +ZBKB_SUPPORTED 0 +ZBKC_SUPPORTED 0 +ZBKX_SUPPORTED 0 +ZKND_SUPPORTED 0 +ZKNE_SUPPORTED 0 +ZKNH_SUPPORTED 0 + +deriv zbs_rv64gc rv64gc +ZBA_SUPPORTED 0 +ZBB_SUPPORTED 0 +ZBS_SUPPORTED 1 +ZBC_SUPPORTED 0 +ZBKB_SUPPORTED 0 +ZBKC_SUPPORTED 0 +ZBKX_SUPPORTED 0 +ZKND_SUPPORTED 0 +ZKNE_SUPPORTED 0 +ZKNH_SUPPORTED 0 + +deriv zbkb_rv64gc rv64gc +ZBA_SUPPORTED 0 +ZBB_SUPPORTED 0 +ZBS_SUPPORTED 0 +ZBC_SUPPORTED 0 +ZBKB_SUPPORTED 1 +ZBKC_SUPPORTED 0 +ZBKX_SUPPORTED 0 +ZKND_SUPPORTED 0 +ZKNE_SUPPORTED 0 +ZKNH_SUPPORTED 0 + +deriv zbkc_rv64gc rv64gc +ZBA_SUPPORTED 0 +ZBB_SUPPORTED 0 +ZBS_SUPPORTED 0 +ZBC_SUPPORTED 0 +ZBKB_SUPPORTED 0 +ZBKC_SUPPORTED 1 +ZBKX_SUPPORTED 0 +ZKND_SUPPORTED 0 +ZKNE_SUPPORTED 0 +ZKNH_SUPPORTED 0 + +deriv zbkx_rv64gc rv64gc +ZBA_SUPPORTED 0 +ZBB_SUPPORTED 0 +ZBS_SUPPORTED 0 +ZBC_SUPPORTED 0 +ZBKB_SUPPORTED 0 +ZBKC_SUPPORTED 0 +ZBKX_SUPPORTED 1 +ZKND_SUPPORTED 0 +ZKNE_SUPPORTED 0 +ZKNH_SUPPORTED 0 + +deriv zknd_rv64gc rv64gc +ZBA_SUPPORTED 0 +ZBB_SUPPORTED 0 +ZBS_SUPPORTED 0 +ZBC_SUPPORTED 0 +ZBKB_SUPPORTED 0 +ZBKC_SUPPORTED 0 +ZBKX_SUPPORTED 0 +ZKND_SUPPORTED 1 +ZKNE_SUPPORTED 0 +ZKNH_SUPPORTED 0 + +deriv zkne_rv64gc rv64gc +ZBA_SUPPORTED 0 +ZBB_SUPPORTED 0 +ZBS_SUPPORTED 0 +ZBC_SUPPORTED 0 +ZBKB_SUPPORTED 0 +ZBKC_SUPPORTED 0 +ZBKX_SUPPORTED 0 +ZKND_SUPPORTED 0 +ZKNE_SUPPORTED 1 +ZKNH_SUPPORTED 0 + +deriv zknh_rv64gc rv64gc +ZBA_SUPPORTED 0 +ZBB_SUPPORTED 0 +ZBS_SUPPORTED 0 +ZBC_SUPPORTED 0 +ZBKB_SUPPORTED 0 +ZBKC_SUPPORTED 0 +ZBKX_SUPPORTED 0 +ZKND_SUPPORTED 0 +ZKNE_SUPPORTED 0 +ZKNH_SUPPORTED 1 + # Floating-point modes supported deriv f_rv32gc rv32gc From ae29a9b8616e1ef124a3103b859cd41cafc648da Mon Sep 17 00:00:00 2001 From: Jordan Carlin Date: Fri, 24 May 2024 15:17:36 -0700 Subject: [PATCH 36/51] Update control bits for froundnx --- src/fpu/fctrl.sv | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/fpu/fctrl.sv b/src/fpu/fctrl.sv index 2d456aeee..bbe2955c3 100755 --- a/src/fpu/fctrl.sv +++ b/src/fpu/fctrl.sv @@ -165,19 +165,19 @@ module fctrl import cvw::*; #(parameter cvw_t P) ( else if (Rs2D == 5'b00100 & P.ZFA_SUPPORTED) ControlsD = `FCTRLW'b1_0_00_00_100_0_0_0_1_0; // fround.s (Zfa) else if (Rs2D == 5'b00101 & P.ZFA_SUPPORTED) - ControlsD = `FCTRLW'b1_0_00_00_100_0_0_0_1_0; // froundnx.s (Zfa) + ControlsD = `FCTRLW'b1_0_00_00_100_0_0_0_1_1; // froundnx.s (Zfa) 7'b0100001: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b01) ControlsD = `FCTRLW'b1_0_01_00_001_0_0_0_0_0; // fcvt.d.(s/h/q) else if (Rs2D == 5'b00100 & P.ZFA_SUPPORTED) ControlsD = `FCTRLW'b1_0_00_00_100_0_0_0_1_0; // fround.d (Zfa) else if (Rs2D == 5'b00101 & P.ZFA_SUPPORTED) - ControlsD = `FCTRLW'b1_0_00_00_100_0_0_0_1_0; // froundnx.d (Zfa) + ControlsD = `FCTRLW'b1_0_00_00_100_0_0_0_1_1; // froundnx.d (Zfa) 7'b0100010: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b10) ControlsD = `FCTRLW'b1_0_01_00_010_0_0_0_0_0; // fcvt.h.(s/d/q) else if (Rs2D == 5'b00100 & P.ZFA_SUPPORTED) ControlsD = `FCTRLW'b1_0_00_00_100_0_0_0_1_0; // fround.h (Zfa) else if (Rs2D == 5'b00101 & P.ZFA_SUPPORTED) - ControlsD = `FCTRLW'b1_0_00_00_100_0_0_0_1_0; // froundnx.h (Zfa) + ControlsD = `FCTRLW'b1_0_00_00_100_0_0_0_1_1; // froundnx.h (Zfa) // coverage off // Not covered in testing because rv64gc does not support quad precision 7'b0100011: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b11) @@ -185,7 +185,7 @@ module fctrl import cvw::*; #(parameter cvw_t P) ( else if (Rs2D == 5'b00100 & P.ZFA_SUPPORTED) ControlsD = `FCTRLW'b1_0_00_00_100_0_0_0_1_0; // fround.q (Zfa) else if (Rs2D == 5'b00101 & P.ZFA_SUPPORTED) - ControlsD = `FCTRLW'b1_0_00_00_100_0_0_0_1_0; // froundnx.q (Zfa) + ControlsD = `FCTRLW'b1_0_00_00_100_0_0_0_1_1; // froundnx.q (Zfa) // coverage on 7'b1101000: case(Rs2D) 5'b00000: ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0_0_0; // fcvt.s.w w->s From fb77440a6434a2ab06f80a5c26b00b39f51d5bff Mon Sep 17 00:00:00 2001 From: Jordan Carlin Date: Fri, 24 May 2024 15:33:45 -0700 Subject: [PATCH 37/51] Update fpctrl fmt to work for fround instructions --- src/fpu/fctrl.sv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/fpu/fctrl.sv b/src/fpu/fctrl.sv index bbe2955c3..d8c1fe1d7 100755 --- a/src/fpu/fctrl.sv +++ b/src/fpu/fctrl.sv @@ -273,10 +273,10 @@ module fctrl import cvw::*; #(parameter cvw_t P) ( assign FmtD = 1'b0; else if (P.FPSIZES == 2) begin logic [1:0] FmtTmp; - assign FmtTmp = ((Funct7D[6:3] == 4'b0100)&OpD[4]) ? Rs2D[1:0] : (~OpD[6]&(&OpD[2:0])) ? {~Funct3D[1], ~(Funct3D[1]^Funct3D[0])} : Funct7D[1:0]; + assign FmtTmp = ((Funct7D[6:3] == 4'b0100)&OpD[4]&~Rs2D[2]) ? Rs2D[1:0] : (~OpD[6]&(&OpD[2:0])) ? {~Funct3D[1], ~(Funct3D[1]^Funct3D[0])} : Funct7D[1:0]; assign FmtD = (P.FMT == FmtTmp); end else if (P.FPSIZES == 3|P.FPSIZES == 4) - assign FmtD = ((Funct7D[6:3] == 4'b0100)&OpD[4]) ? Rs2D[1:0] : Funct7D[1:0]; + assign FmtD = ((Funct7D[6:3] == 4'b0100)&OpD[4]&~Rs2D[2]) ? Rs2D[1:0] : Funct7D[1:0]; // Enables indicate that a source register is used and may need stalls. Also indicate special cases for infinity or NaN. // When disabled infinity and NaN on source registers are ignored by the unpacker and thus special case logic. From b830d20f2de7f591f2f16613a5bfe3510fef4d5e Mon Sep 17 00:00:00 2001 From: Jordan Carlin Date: Sat, 25 May 2024 12:56:02 -0700 Subject: [PATCH 38/51] Modify Fround Tmask to work for X=1 --- src/fpu/fround.sv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/fpu/fround.sv b/src/fpu/fround.sv index 085e25771..64700834a 100644 --- a/src/fpu/fround.sv +++ b/src/fpu/fround.sv @@ -79,7 +79,7 @@ module fround import cvw::*; #(parameter cvw_t P) ( // Logic for nonnegative mask and rounding bits assign IMask = {1'b1, {P.NF{1'b0}}} >>> E; - assign Tmasknonneg = ~(IMask >>> 1'b1); + assign Tmasknonneg = ~IMask >>> 1'b1; assign HotE = IMask & ~(IMask << 1'b1); assign HotEP1 = HotE >> 1'b1; assign Lnonneg = |(Xm & HotE); @@ -139,7 +139,7 @@ module fround import cvw::*; #(parameter cvw_t P) ( else if (Elt0) // 0 <= |X| < 1 rounds to 0 or 1 if (RoundUp) W = {Xs, P.BIAS[P.NE-1:0], {P.NF{1'b0}}}; // round to +/- 1 else W = {Xs, {(P.FLEN-1){1'b0}}}; // round to +/- 0 - else begin // |X| > 1 rounds to an integer + else begin // |X| >= 1 rounds to an integer if (RoundUp & Two) W = {Xs, Xep1, {(P.NF){1'b0}}}; // Round up to 2.0 else if (RoundUp) W = {Xs, Xe, Rnd[P.NF-1:0]}; // Round up to Rnd else W = {Xs, Xe, Trunc[P.NF-1:0]}; // Round down to Trunc From 8edc4057ed9cd5b6e740dd944650f59040c8d1c6 Mon Sep 17 00:00:00 2001 From: Quswar Abid Date: Sat, 25 May 2024 23:10:09 -0700 Subject: [PATCH 39/51] compilable tests generating for loaditypes[lb, lh, lw, ld, lbu, lhu, lwu] --- Makefile | 1 + tests/testgen/covergen.py | 38 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 24d531917..b78bb689d 100644 --- a/Makefile +++ b/Makefile @@ -89,6 +89,7 @@ riscvdv_functcov: combine_functcov: mkdir -p ${SIM}/questa/functcov + mkdir -p ${SIM}/questa/functcov_logs cd ${SIM}/questa/functcov && rm -rf * run-elf-cov.bash --seed ${SIM}/questa/seed0.txt --verbose --coverdb ${SIM}/questa/functcov/add.ucdb --elf ${WALLY}/tests/functcov/rv64/I/WALLY-COV-add.elf >> ${SIM}/questa/functcov_logs/add.log 2>&1 run-elf-cov.bash --seed ${SIM}/questa/seed0.txt --verbose --coverdb ${SIM}/questa/functcov/and.ucdb --elf ${WALLY}/tests/functcov/rv64/I/WALLY-COV-and.elf >> ${SIM}/questa/functcov_logs/add.log 2>&1 diff --git a/tests/testgen/covergen.py b/tests/testgen/covergen.py index 44a0eea4c..03edc2f90 100755 --- a/tests/testgen/covergen.py +++ b/tests/testgen/covergen.py @@ -31,6 +31,23 @@ def signedImm12(imm): imm = imm - 0x1000 return str(imm) +def signedImm20(imm): + imm = imm % pow(2, 20) + if (imm & 0x80000): + imm = imm - 0x100000 + return str(imm) + +''' +rtype = ["add", "sub", "sll", "slt", "sltu", "xor", "srl", "sra", "or", "and", + "addw", "subw", "sllw", "srlw", "sraw" + "mul", "mulh", "mulhsu", "mulhu", "div", "divu", "rem", "remu", + "mulw", "divw", "divuw", "remw", "remuw"] +loaditype = ["lb", "lh", "lw", "ld", "lbu", "lhu", "lwu"] +shiftitype = ["slli", "srli", "srai"] +itype = ["addi", "slti", "sltiu", "xori", "ori", "andi"] +stypes = ["sb", "sh", "sw", "sd"] +btypes = ["beq", "bne", "blt", "bge", "bltu", "bgeu"] +''' def writeCovVector(desc, rs1, rs2, rd, rs1val, rs2val, immval, rdval, test, storecmd, xlen): lines = "\n# Testcase " + str(desc) + "\n" if (rs1val < 0): @@ -48,6 +65,20 @@ def writeCovVector(desc, rs1, rs2, rd, rs1val, rs2val, immval, rdval, test, stor elif (test in itype): lines = lines + "li x" + str(rs1) + ", " + formatstr.format(rs1val) + " # initialize rs1 to a random value \n" lines = lines + test + " x" + str(rd) + ", x" + str(rs1) + ", " + signedImm12(immval) + " # perform operation\n" + elif (test in loaditype): + ''' + auipc s9,0x2 + addi s9,s9,-448 # 80002800 + lw a4,-2048(s9) + ''' + lines = lines + "auipc x" + str(rs1) + ", 0x20" + " # add upper immediate value to pc \n" + lines = lines + "addi x" + str(rs1) + ", x" + str(rs1) + ", " + signedImm12(immval) + " # add immediate to lower part of rs1 \n" + lines = lines + test + " x" + str(rd) + ", " + signedImm12(immval) + "(x" + str(rs1) + ") # perform operation \n" + #print("Error: %s type not implemented yet" % test) + elif (test in stypes): + print("Error: %s type not implemented yet" % test) + elif (test in btypes): + print("Error: %s type not implemented yet" % test) else: pass #print("Error: %s type not implemented yet" % test) @@ -130,12 +161,12 @@ def make_rd_maxvals(test, storecmd, xlen): def make_rd_rs1_eqval(test, storecmd, xlen): [rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize() desc = "cmp_rdm_rs1_eqval (Test rs1 = rd = " + hex(rs1val) + ")" - writeCovVector(desc, rs1, 0, rd, rs1val, rs2val, immval, rdval, test, storecmd, xlen) + writeCovVector(desc, rs1, 0, rd, rdval, rs2val, immval, rdval, test, storecmd, xlen) def make_rd_rs2_eqval(test, storecmd, xlen): [rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize() desc = "cmp_rd_rs2_eqval (Test rs2 = rd = " + hex(rs2val) + ")" - writeCovVector(desc, 0, rs2, rd, rs1val, rs2val, immval, rdval, test, storecmd, xlen) + writeCovVector(desc, 0, rs2, rd, rs1val, rdval, immval, rdval, test, storecmd, xlen) def make_rs1_rs2_eqval(test, storecmd, xlen): [rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize() @@ -238,6 +269,7 @@ def getcovergroups(coverdefdir, coverfiles): if (m): coverpoints[curinstr].append(m.group(1)) f.close() + print(coverpoints) return coverpoints ################################## @@ -258,6 +290,8 @@ shiftitype = ["slli", "srli", "srai"] itype = ["addi", "slti", "sltiu", "xori", "ori", "andi"] stypes = ["sb", "sh", "sw", "sd"] btypes = ["beq", "bne", "blt", "bge", "bltu", "bgeu"] +# TODO: auipc missing, check whatelse is missing in ^these^ types + coverpoints = getcovergroups(coverdefdir, coverfiles) author = "David_Harris@hmc.edu" From 29d7cd56634caab652490b2d85c8a95cccf23280 Mon Sep 17 00:00:00 2001 From: Quswar Abid Date: Sat, 25 May 2024 23:16:07 -0700 Subject: [PATCH 40/51] unwanted comments --- tests/testgen/covergen.py | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/tests/testgen/covergen.py b/tests/testgen/covergen.py index 03edc2f90..53313d9ab 100755 --- a/tests/testgen/covergen.py +++ b/tests/testgen/covergen.py @@ -37,17 +37,6 @@ def signedImm20(imm): imm = imm - 0x100000 return str(imm) -''' -rtype = ["add", "sub", "sll", "slt", "sltu", "xor", "srl", "sra", "or", "and", - "addw", "subw", "sllw", "srlw", "sraw" - "mul", "mulh", "mulhsu", "mulhu", "div", "divu", "rem", "remu", - "mulw", "divw", "divuw", "remw", "remuw"] -loaditype = ["lb", "lh", "lw", "ld", "lbu", "lhu", "lwu"] -shiftitype = ["slli", "srli", "srai"] -itype = ["addi", "slti", "sltiu", "xori", "ori", "andi"] -stypes = ["sb", "sh", "sw", "sd"] -btypes = ["beq", "bne", "blt", "bge", "bltu", "bgeu"] -''' def writeCovVector(desc, rs1, rs2, rd, rs1val, rs2val, immval, rdval, test, storecmd, xlen): lines = "\n# Testcase " + str(desc) + "\n" if (rs1val < 0): @@ -66,15 +55,9 @@ def writeCovVector(desc, rs1, rs2, rd, rs1val, rs2val, immval, rdval, test, stor lines = lines + "li x" + str(rs1) + ", " + formatstr.format(rs1val) + " # initialize rs1 to a random value \n" lines = lines + test + " x" + str(rd) + ", x" + str(rs1) + ", " + signedImm12(immval) + " # perform operation\n" elif (test in loaditype): - ''' - auipc s9,0x2 - addi s9,s9,-448 # 80002800 - lw a4,-2048(s9) - ''' lines = lines + "auipc x" + str(rs1) + ", 0x20" + " # add upper immediate value to pc \n" lines = lines + "addi x" + str(rs1) + ", x" + str(rs1) + ", " + signedImm12(immval) + " # add immediate to lower part of rs1 \n" lines = lines + test + " x" + str(rd) + ", " + signedImm12(immval) + "(x" + str(rs1) + ") # perform operation \n" - #print("Error: %s type not implemented yet" % test) elif (test in stypes): print("Error: %s type not implemented yet" % test) elif (test in btypes): From 1bf9b1395325e33cdaee850fd5ee2fb0d187eef3 Mon Sep 17 00:00:00 2001 From: Quswar Abid Date: Sun, 26 May 2024 03:47:08 -0700 Subject: [PATCH 41/51] added some sb types --- tests/testgen/covergen.py | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/tests/testgen/covergen.py b/tests/testgen/covergen.py index 53313d9ab..233fa3495 100755 --- a/tests/testgen/covergen.py +++ b/tests/testgen/covergen.py @@ -54,14 +54,25 @@ def writeCovVector(desc, rs1, rs2, rd, rs1val, rs2val, immval, rdval, test, stor elif (test in itype): lines = lines + "li x" + str(rs1) + ", " + formatstr.format(rs1val) + " # initialize rs1 to a random value \n" lines = lines + test + " x" + str(rd) + ", x" + str(rs1) + ", " + signedImm12(immval) + " # perform operation\n" - elif (test in loaditype): + elif (test in loaditype):#["lb", "lh", "lw", "ld", "lbu", "lhu", "lwu"] lines = lines + "auipc x" + str(rs1) + ", 0x20" + " # add upper immediate value to pc \n" lines = lines + "addi x" + str(rs1) + ", x" + str(rs1) + ", " + signedImm12(immval) + " # add immediate to lower part of rs1 \n" lines = lines + test + " x" + str(rd) + ", " + signedImm12(immval) + "(x" + str(rs1) + ") # perform operation \n" - elif (test in stypes): - print("Error: %s type not implemented yet" % test) - elif (test in btypes): - print("Error: %s type not implemented yet" % test) + elif (test in stypes):#["sb", "sh", "sw", "sd"] + #lines = lines + test + " x" + str(rs2) + ", " + signedImm12(immval) + "(x" + str(rs1) + ") # perform operation \n" + lines = lines + test + " x" + str(rs2) + ", " "0(x" + str(rs1) + ") # perform operation \n" + #print("Error: %s type not implemented yet" % test) + elif (test in btypes):#["beq", "bne", "blt", "bge", "bltu", "bgeu"] + if (randint(1,100) > 50): + rs1val = rs2val + lines = lines + "# same values in both registers\n" + lines = lines + "nop \n" + lines = lines + "li x" + str(rs1) + ", " + formatstr.format(rs1val) + " # initialize rs1 to a random value that should get changed\n" + lines = lines + "li x" + str(rs2) + ", " + formatstr.format(rs2val) + " # initialize rs2 to a random value that should get changed\n" + lines = lines + test + " x" + str(rs1) + ", x" + str(rs2) + ", some_label_for_sb_types_" + str(immval) + "+4" + " # perform operation \n" + lines = lines + "some_label_for_sb_types_" + str(immval) + ":\n" + lines = lines + "nop \nnop \nnop \nnop \nnop \n" + #print("Error: %s type not implemented yet" % test) else: pass #print("Error: %s type not implemented yet" % test) From 997b5901cc47f2a6237c7be6bef8d7c16ddc8e2a Mon Sep 17 00:00:00 2001 From: Quswar Abid Date: Mon, 27 May 2024 04:27:50 -0700 Subject: [PATCH 42/51] sb types are all passing, loaditypes are not! --- tests/testgen/covergen.py | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/tests/testgen/covergen.py b/tests/testgen/covergen.py index 233fa3495..5a01b7c62 100755 --- a/tests/testgen/covergen.py +++ b/tests/testgen/covergen.py @@ -66,13 +66,14 @@ def writeCovVector(desc, rs1, rs2, rd, rs1val, rs2val, immval, rdval, test, stor if (randint(1,100) > 50): rs1val = rs2val lines = lines + "# same values in both registers\n" - lines = lines + "nop \n" + lines = lines + "nop\n" lines = lines + "li x" + str(rs1) + ", " + formatstr.format(rs1val) + " # initialize rs1 to a random value that should get changed\n" lines = lines + "li x" + str(rs2) + ", " + formatstr.format(rs2val) + " # initialize rs2 to a random value that should get changed\n" lines = lines + test + " x" + str(rs1) + ", x" + str(rs2) + ", some_label_for_sb_types_" + str(immval) + "+4" + " # perform operation \n" + lines = lines + "addi x0, x1, 1\n" lines = lines + "some_label_for_sb_types_" + str(immval) + ":\n" - lines = lines + "nop \nnop \nnop \nnop \nnop \n" - #print("Error: %s type not implemented yet" % test) + lines = lines + "addi x0, x2, 2\n" + lines = lines + "nop\nnop\nnop\nnop\nnop\n" else: pass #print("Error: %s type not implemented yet" % test) @@ -232,17 +233,37 @@ def write_tests(coverpoints, test, storecmd, xlen): elif (coverpoint == "cp_rs2_sign"): make_rs2_sign(test, storecmd, xlen) elif (coverpoint == "cp_rd_sign"): - pass # hope already covered by rd_maxvals + pass #TODO hope already covered by rd_maxvals elif (coverpoint == "cr_rs1_rs2"): make_cr_rs1_rs2_sign(test, storecmd, xlen) elif (coverpoint == "cp_rs1_toggle"): - pass # toggle not needed and seems to be covered by other things + pass #TODO toggle not needed and seems to be covered by other things elif (coverpoint == "cp_rs2_toggle"): - pass # toggle not needed and seems to be covered by other things + pass #TODO toggle not needed and seems to be covered by other things elif (coverpoint == "cp_rd_toggle"): - pass # toggle not needed and seems to be covered by other things + pass #TODO toggle not needed and seems to be covered by other things elif (coverpoint == "cp_gpr_hazard"): - pass # not yet implemented + pass #TODO not yet implemented + elif (coverpoint == "cp_imm_sign"): + pass #TODO + elif (coverpoint == "cr_rs1_imm"): + pass #TODO (not if crosses are not needed) + elif (coverpoint == "cp_imm_ones_zeros"): + pass #TODO + elif (coverpoint == "cp_mem_hazard"): + pass #TODO + elif (coverpoint == "cp_imm_zero"): + pass #TODO + elif (coverpoint == "cp_mem_unaligned"): + pass #TODO + elif (coverpoint == "cp_offset"): + pass #TODO + elif (coverpoint == "cr_nord_rs1_rs2"): + pass #TODO (not if crosses are not needed) + elif (coverpoint == "cp_imm_shift"): + pass #TODO + elif (coverpoint == "cp_rd_boolean"): + pass #TODO else: print("Warning: " + coverpoint + " not implemented yet for " + test) From 2985cfb7ebb312ad5fbbb2c6143c255d3342e86c Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Mon, 27 May 2024 11:59:13 -0500 Subject: [PATCH 43/51] Preliminary work to merge functional coverage into wally.do. --- sim/questa/wally.do | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/sim/questa/wally.do b/sim/questa/wally.do index 4f626851e..ba1000754 100644 --- a/sim/questa/wally.do +++ b/sim/questa/wally.do @@ -44,6 +44,20 @@ set coverage 0 set CoverageVoptArg "" set CoverageVsimArg "" +set FunctCoverage 0 +set riscvISACOVsrc "" +set FCdefineINCLUDE_TRACE2COV "" +set FCdefineCOVER_BASE_RV64I "" +set FCdefineCOVER_LEVEL_DV_PR_EXT "" +set FCdefineCOVER_RV64I "" +set FCdefineCOVER_RV64M "" +set FCdefineCOVER_RV64A "" +set FCdefineCOVER_RV64F "" +set FCdefineCOVER_RV64D "" +set FCdefineCOVER_RV64ZICSR "" +set FCdefineCOVER_RV64C "" +set FCdefineIDV_INCLUDE_TRACE2COV "" + set lockstep 0 # ok this is annoying. vlog, vopt, and vsim are very picky about how arguments are passed. # unforunately it won't allow these to be grouped as one argument per command so they are broken @@ -98,6 +112,27 @@ if {$CoverageIndex >= 0} { set lst [lreplace $lst $CoverageIndex $CoverageIndex] } +# if +coverage found set flag and remove from list +set FunctCoverageIndex [lsearch -exact $lst "--fcov"] +if {$FunctCoverageIndex >= 0} { + set FunctCoverage 1 + set riscvISACOVsrc +incdir+$env(IMPERAS_HOME)/ImpProprietary/source/host/riscvISACOV/source + + set FCdefineINCLUDE_TRACE2COV "+define+INCLUDE_TRACE2COV" + set FCdefineCOVER_BASE_RV64I "+define+COVER_BASE_RV64I" + set FCdefineCOVER_LEVEL_DV_PR_EXT "+define+COVER_LEVEL_DV_PR_EXT" + set FCdefineCOVER_RV64I "+define+COVER_RV64I" + set FCdefineCOVER_RV64M "+define+COVER_RV64M" + set FCdefineCOVER_RV64A "+define+COVER_RV64A" + set FCdefineCOVER_RV64F "+define+COVER_RV64F" + set FCdefineCOVER_RV64D "+define+COVER_RV64D" + set FCdefineCOVER_RV64ZICSR "+define+COVER_RV64ZICSR" + set FCdefineCOVER_RV64C "+define+COVER_RV64C" + set FCdefineIDV_INCLUDE_TRACE2COV "+define+IDV_INCLUDE_TRACE2COV" + + set lst [lreplace $lst $FunctCoverageIndex $FunctCoverageIndex] +} + set LockStepIndex [lsearch -exact $lst "--lockstep"] if {$LockStepIndex >= 0} { set lockstep 1 @@ -139,7 +174,7 @@ if {$DEBUG > 0} { # "Extra checking for conflicts with always_comb done at vopt time" # because vsim will run vopt -vlog -lint -work ${WKDIR} +incdir+${CONFIG}/${CFG} +incdir+${CONFIG}/deriv/${CFG} ${lockstepvoptstring} ${ImperasPubInc} ${ImperasPrivInc} +incdir+${CONFIG}/shared ${rvviFiles} ${idvFiles} ${SRC}/cvw.sv ${TB}/${TESTBENCH}.sv ${TB}/common/*.sv ${SRC}/*/*.sv ${SRC}/*/*/*.sv -suppress 2583 -suppress 7063,2596,13286 +vlog -lint -work ${WKDIR} +incdir+${CONFIG}/${CFG} +incdir+${CONFIG}/deriv/${CFG} ${lockstepvoptstring} ${ImperasPubInc} ${ImperasPrivInc} ${riscvISACOVsrc} ${FCdefineINCLUDE_TRACE2COV} ${FCdefineCOVER_BASE_RV64I} ${FCdefineCOVER_LEVEL_DV_PR_EXT} ${FCdefineCOVER_RV64I} ${FCdefineCOVER_RV64M} ${FCdefineCOVER_RV64A} ${FCdefineCOVER_RV64F} ${FCdefineCOVER_RV64D} ${FCdefineCOVER_RV64ZICSR} ${FCdefineCOVER_RV64C} ${FCdefineIDV_INCLUDE_TRACE2COV} +incdir+${CONFIG}/shared ${rvviFiles} ${idvFiles} ${SRC}/cvw.sv ${TB}/${TESTBENCH}.sv ${TB}/common/*.sv ${SRC}/*/*.sv ${SRC}/*/*/*.sv -suppress 2583 -suppress 7063,2596,13286 # start and run simulation # remove +acc flag for faster sim during regressions if there is no need to access internal signals From 26c6eec832907fd122766ad969c8029af0270f4b Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Mon, 27 May 2024 13:20:18 -0500 Subject: [PATCH 44/51] Getting closer to functional coverage integration. --- bin/wsim | 3 +++ 1 file changed, 3 insertions(+) diff --git a/bin/wsim b/bin/wsim index 4a4103242..0d4430e20 100755 --- a/bin/wsim +++ b/bin/wsim @@ -23,6 +23,7 @@ parser.add_argument("--sim", "-s", help="Simulator", choices=["questa", "verilat parser.add_argument("--tb", "-t", help="Testbench", choices=["testbench", "testbench_fp"], default="testbench") parser.add_argument("--gui", "-g", help="Simulate with GUI", action="store_true") parser.add_argument("--coverage", "-c", help="Code & Functional Coverage", action="store_true") +parser.add_argument("--fcov", "-f", help="Code & Functional Coverage", action="store_true") parser.add_argument("--args", "-a", help="Optional arguments passed to simulator via $value$plusargs", default="") parser.add_argument("--vcd", "-v", help="Generate testbench.vcd", action="store_true") parser.add_argument("--lockstep", "-l", help="Run ImperasDV lock, step, and compare.", action="store_true") @@ -74,6 +75,8 @@ if (args.sim == "questa"): cmd = "do wally.do " + args.config + " " + args.testsuite + " " + args.tb + " " + args.args + " " + ElfFile + " " + suffix if (args.coverage): cmd += " --coverage" + if (args.fcov): + cmd += " --fcov" if (args.gui): # launch Questa with GUI; add +acc to keep variables accessible if(args.tb == "testbench"): cmd = cd + "; " + prefix + " vsim -do \"" + cmd + " +acc -GDEBUG=1\"" From ff611016c73e82ef24b82e2854d9cc4ecce18328 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Mon, 27 May 2024 14:11:02 -0500 Subject: [PATCH 45/51] Closer? --- sim/questa/wally.do | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sim/questa/wally.do b/sim/questa/wally.do index ba1000754..e72a5022a 100644 --- a/sim/questa/wally.do +++ b/sim/questa/wally.do @@ -197,7 +197,7 @@ if { ${GUI} } { run -all # power off -r /dut/core/* -if {$coverage} { +if {$coverage || $FunctCoverage} { set UCDB cov/${CFG}_${TESTSUITE}.ucdb echo "Saving coverage to ${UCDB}" do coverage-exclusions-rv64gc.do # beware: this assumes testing the rv64gc configuration From 4c0261fd2cadc0c4e06faf12173aea9132a32c54 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Mon, 27 May 2024 15:37:16 -0500 Subject: [PATCH 46/51] Closer. Needed to reorder includes and defines. --- sim/questa/wally.do | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sim/questa/wally.do b/sim/questa/wally.do index e72a5022a..2942e496c 100644 --- a/sim/questa/wally.do +++ b/sim/questa/wally.do @@ -174,7 +174,7 @@ if {$DEBUG > 0} { # "Extra checking for conflicts with always_comb done at vopt time" # because vsim will run vopt -vlog -lint -work ${WKDIR} +incdir+${CONFIG}/${CFG} +incdir+${CONFIG}/deriv/${CFG} ${lockstepvoptstring} ${ImperasPubInc} ${ImperasPrivInc} ${riscvISACOVsrc} ${FCdefineINCLUDE_TRACE2COV} ${FCdefineCOVER_BASE_RV64I} ${FCdefineCOVER_LEVEL_DV_PR_EXT} ${FCdefineCOVER_RV64I} ${FCdefineCOVER_RV64M} ${FCdefineCOVER_RV64A} ${FCdefineCOVER_RV64F} ${FCdefineCOVER_RV64D} ${FCdefineCOVER_RV64ZICSR} ${FCdefineCOVER_RV64C} ${FCdefineIDV_INCLUDE_TRACE2COV} +incdir+${CONFIG}/shared ${rvviFiles} ${idvFiles} ${SRC}/cvw.sv ${TB}/${TESTBENCH}.sv ${TB}/common/*.sv ${SRC}/*/*.sv ${SRC}/*/*/*.sv -suppress 2583 -suppress 7063,2596,13286 +vlog -lint -work ${WKDIR} +incdir+${CONFIG}/${CFG} +incdir+${CONFIG}/deriv/${CFG} ${lockstepvoptstring} ${FCdefineINCLUDE_TRACE2COV} ${FCdefineCOVER_BASE_RV64I} ${FCdefineCOVER_LEVEL_DV_PR_EXT} ${FCdefineCOVER_RV64I} ${FCdefineCOVER_RV64M} ${FCdefineCOVER_RV64A} ${FCdefineCOVER_RV64F} ${FCdefineCOVER_RV64D} ${FCdefineCOVER_RV64ZICSR} ${FCdefineCOVER_RV64C} ${FCdefineIDV_INCLUDE_TRACE2COV} ${ImperasPubInc} ${ImperasPrivInc} ${riscvISACOVsrc} +incdir+${CONFIG}/shared ${rvviFiles} ${idvFiles} ${SRC}/cvw.sv ${TB}/${TESTBENCH}.sv ${TB}/common/*.sv ${SRC}/*/*.sv ${SRC}/*/*/*.sv -suppress 2583 -suppress 7063,2596,13286 # start and run simulation # remove +acc flag for faster sim during regressions if there is no need to access internal signals From 92ee56c1a10424f7910db989bae5dc9a056db1a8 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Mon, 27 May 2024 17:25:20 -0500 Subject: [PATCH 47/51] Yay. Finally found the bug which prevented wally.do from having functional coverage using riscvISACOV. testbench.sv was missing the trace2cov instance. --- sim/questa/wally.do | 2 +- testbench/testbench.sv | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sim/questa/wally.do b/sim/questa/wally.do index 2942e496c..32a096702 100644 --- a/sim/questa/wally.do +++ b/sim/questa/wally.do @@ -174,7 +174,7 @@ if {$DEBUG > 0} { # "Extra checking for conflicts with always_comb done at vopt time" # because vsim will run vopt -vlog -lint -work ${WKDIR} +incdir+${CONFIG}/${CFG} +incdir+${CONFIG}/deriv/${CFG} ${lockstepvoptstring} ${FCdefineINCLUDE_TRACE2COV} ${FCdefineCOVER_BASE_RV64I} ${FCdefineCOVER_LEVEL_DV_PR_EXT} ${FCdefineCOVER_RV64I} ${FCdefineCOVER_RV64M} ${FCdefineCOVER_RV64A} ${FCdefineCOVER_RV64F} ${FCdefineCOVER_RV64D} ${FCdefineCOVER_RV64ZICSR} ${FCdefineCOVER_RV64C} ${FCdefineIDV_INCLUDE_TRACE2COV} ${ImperasPubInc} ${ImperasPrivInc} ${riscvISACOVsrc} +incdir+${CONFIG}/shared ${rvviFiles} ${idvFiles} ${SRC}/cvw.sv ${TB}/${TESTBENCH}.sv ${TB}/common/*.sv ${SRC}/*/*.sv ${SRC}/*/*/*.sv -suppress 2583 -suppress 7063,2596,13286 +vlog -lint -work ${WKDIR} +incdir+${CONFIG}/${CFG} +incdir+${CONFIG}/deriv/${CFG} +incdir+${CONFIG}/shared ${lockstepvoptstring} ${FCdefineIDV_INCLUDE_TRACE2COV} ${ImperasPubInc} ${ImperasPrivInc} ${rvviFiles} ${idvFiles} ${FCdefineINCLUDE_TRACE2COV} ${FCdefineCOVER_BASE_RV64I} ${FCdefineCOVER_LEVEL_DV_PR_EXT} ${FCdefineCOVER_RV64I} ${FCdefineCOVER_RV64M} ${FCdefineCOVER_RV64A} ${FCdefineCOVER_RV64F} ${FCdefineCOVER_RV64D} ${FCdefineCOVER_RV64ZICSR} ${FCdefineCOVER_RV64C} ${riscvISACOVsrc} ${SRC}/cvw.sv ${TB}/${TESTBENCH}.sv ${TB}/common/*.sv ${SRC}/*/*.sv ${SRC}/*/*/*.sv -suppress 2583 -suppress 7063,2596,13286 # start and run simulation # remove +acc flag for faster sim during regressions if there is no need to access internal signals diff --git a/testbench/testbench.sv b/testbench/testbench.sv index 71aaa8126..17def063c 100644 --- a/testbench/testbench.sv +++ b/testbench/testbench.sv @@ -681,7 +681,7 @@ end wallyTracer #(P) wallyTracer(rvvi); trace2log idv_trace2log(rvvi); - // trace2cov idv_trace2cov(rvvi); + trace2cov idv_trace2cov(rvvi); // enabling of comparison types trace2api #(.CMP_PC (1), From 4a1e856b18af994a3e217248dd32ba81ed6bf932 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Mon, 27 May 2024 18:15:04 -0500 Subject: [PATCH 48/51] Almost working functional coverage in wally.do riscvISACOV is now loading, but for some reason I still cannot get it to record anything. Instead it is just logging the instructions. --- bin/wsim | 4 +++- sim/questa/wally.do | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/bin/wsim b/bin/wsim index 0d4430e20..5631131f4 100755 --- a/bin/wsim +++ b/bin/wsim @@ -28,6 +28,7 @@ parser.add_argument("--args", "-a", help="Optional arguments passed to simulator parser.add_argument("--vcd", "-v", help="Generate testbench.vcd", action="store_true") parser.add_argument("--lockstep", "-l", help="Run ImperasDV lock, step, and compare.", action="store_true") parser.add_argument("--locksteplog", "-b", help="Retired instruction number to be begin logging.", default=0) +parser.add_argument("--covlog", "-d", help="Log coverage after n instructions.", default=0) args = parser.parse_args() print("Config=" + args.config + " tests=" + args.testsuite + " sim=" + args.sim + " gui=" + str(args.gui) + " args='" + args.args + "'") ElfFile="" @@ -65,7 +66,8 @@ cd = "cd $WALLY/sim/" +args.sim if (args.sim == "questa"): if (args.lockstep): Instret = str(args.locksteplog) - prefix ="IMPERAS_TOOLS=" + WALLY + "/sim/imperas.ic OTHERFLAGS=\"+IDV_TRACE2LOG=" + Instret + " +IDV_TRACE2COV=" + Instret + "\" "; + CovEnableStr = "1\"" if int(args.covlog) > 0 else "0\""; + prefix ="IMPERAS_TOOLS=" + WALLY + "/sim/imperas.ic OTHERFLAGS=\"+IDV_TRACE2LOG=" + Instret + " +IDV_TRACE2COV=" + str(args.covlog) + " +TRACE2COV_ENABLE=" + CovEnableStr; suffix = "--lockstep" else: prefix = "" diff --git a/sim/questa/wally.do b/sim/questa/wally.do index 32a096702..5c7700e37 100644 --- a/sim/questa/wally.do +++ b/sim/questa/wally.do @@ -174,7 +174,7 @@ if {$DEBUG > 0} { # "Extra checking for conflicts with always_comb done at vopt time" # because vsim will run vopt -vlog -lint -work ${WKDIR} +incdir+${CONFIG}/${CFG} +incdir+${CONFIG}/deriv/${CFG} +incdir+${CONFIG}/shared ${lockstepvoptstring} ${FCdefineIDV_INCLUDE_TRACE2COV} ${ImperasPubInc} ${ImperasPrivInc} ${rvviFiles} ${idvFiles} ${FCdefineINCLUDE_TRACE2COV} ${FCdefineCOVER_BASE_RV64I} ${FCdefineCOVER_LEVEL_DV_PR_EXT} ${FCdefineCOVER_RV64I} ${FCdefineCOVER_RV64M} ${FCdefineCOVER_RV64A} ${FCdefineCOVER_RV64F} ${FCdefineCOVER_RV64D} ${FCdefineCOVER_RV64ZICSR} ${FCdefineCOVER_RV64C} ${riscvISACOVsrc} ${SRC}/cvw.sv ${TB}/${TESTBENCH}.sv ${TB}/common/*.sv ${SRC}/*/*.sv ${SRC}/*/*/*.sv -suppress 2583 -suppress 7063,2596,13286 +vlog -lint -work ${WKDIR} +incdir+${CONFIG}/${CFG} +incdir+${CONFIG}/deriv/${CFG} +incdir+${CONFIG}/shared ${lockstepvoptstring} ${FCdefineIDV_INCLUDE_TRACE2COV} ${FCdefineINCLUDE_TRACE2COV} ${ImperasPubInc} ${ImperasPrivInc} ${rvviFiles} ${idvFiles} ${FCdefineCOVER_BASE_RV64I} ${FCdefineCOVER_LEVEL_DV_PR_EXT} ${FCdefineCOVER_RV64I} ${FCdefineCOVER_RV64M} ${FCdefineCOVER_RV64A} ${FCdefineCOVER_RV64F} ${FCdefineCOVER_RV64D} ${FCdefineCOVER_RV64ZICSR} ${FCdefineCOVER_RV64C} ${riscvISACOVsrc} ${SRC}/cvw.sv ${TB}/${TESTBENCH}.sv ${TB}/common/*.sv ${SRC}/*/*.sv ${SRC}/*/*/*.sv -suppress 2583 -suppress 7063,2596,13286 # start and run simulation # remove +acc flag for faster sim during regressions if there is no need to access internal signals From 48fd365b9d78879ff2db9c46be208ac2a28ab187 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Tue, 28 May 2024 13:00:17 -0500 Subject: [PATCH 49/51] Still don't understand why wally.do can't load testbench.sv with functional coverage. But wally-imperas-cov.do can load testbench.sv with functional coverage. --- bin/wsim | 4 ++-- sim/questa/wally-imperas-cov.do | 22 +++++++++++----------- testbench/testbench-imperas.sv | 5 +++-- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/bin/wsim b/bin/wsim index 5631131f4..6bedf3fe9 100755 --- a/bin/wsim +++ b/bin/wsim @@ -66,8 +66,8 @@ cd = "cd $WALLY/sim/" +args.sim if (args.sim == "questa"): if (args.lockstep): Instret = str(args.locksteplog) - CovEnableStr = "1\"" if int(args.covlog) > 0 else "0\""; - prefix ="IMPERAS_TOOLS=" + WALLY + "/sim/imperas.ic OTHERFLAGS=\"+IDV_TRACE2LOG=" + Instret + " +IDV_TRACE2COV=" + str(args.covlog) + " +TRACE2COV_ENABLE=" + CovEnableStr; + CovEnableStr = "1" if int(args.covlog) > 0 else "0"; + prefix ="IMPERAS_TOOLS=" + WALLY + "/sim/imperas.ic OTHERFLAGS=\"+IDV_TRACE2LOG=" + Instret + " +IDV_TRACE2COV=" + str(args.covlog) + " +TRACE2COV_ENABLE=" + CovEnableStr + "\""; suffix = "--lockstep" else: prefix = "" diff --git a/sim/questa/wally-imperas-cov.do b/sim/questa/wally-imperas-cov.do index d407cde0f..1b83950d0 100644 --- a/sim/questa/wally-imperas-cov.do +++ b/sim/questa/wally-imperas-cov.do @@ -29,6 +29,14 @@ vlog +incdir+$env(WALLY)/config/$1 \ +incdir+$env(WALLY)/config/shared \ +define+USE_IMPERAS_DV \ +define+IDV_INCLUDE_TRACE2COV \ + +define+INCLUDE_TRACE2COV +define+COVER_BASE_RV64I +define+COVER_LEVEL_DV_PR_EXT \ + +define+COVER_RV64I \ + +define+COVER_RV64M \ + +define+COVER_RV64A \ + +define+COVER_RV64F \ + +define+COVER_RV64D \ + +define+COVER_RV64ZICSR \ + +define+COVER_RV64C \ +incdir+$env(IMPERAS_HOME)/ImpPublic/include/host \ +incdir+$env(IMPERAS_HOME)/ImpProprietary/include/host \ $env(IMPERAS_HOME)/ImpPublic/source/host/rvvi/rvviApiPkg.sv \ @@ -39,19 +47,11 @@ vlog +incdir+$env(WALLY)/config/$1 \ $env(IMPERAS_HOME)/ImpProprietary/source/host/idv/trace2api.sv \ $env(IMPERAS_HOME)/ImpProprietary/source/host/idv/trace2log.sv \ \ - +define+INCLUDE_TRACE2COV +define+COVER_BASE_RV64I +define+COVER_LEVEL_DV_PR_EXT \ - +define+COVER_RV64I \ - +define+COVER_RV64M \ - +define+COVER_RV64A \ - +define+COVER_RV64F \ - +define+COVER_RV64D \ - +define+COVER_RV64ZICSR \ - +define+COVER_RV64C \ +incdir+$env(IMPERAS_HOME)/ImpProprietary/source/host/riscvISACOV/source \ $env(IMPERAS_HOME)/ImpProprietary/source/host/idv/trace2cov.sv \ \ $env(WALLY)/src/cvw.sv \ - $env(WALLY)/testbench/testbench-imperas.sv \ + $env(WALLY)/testbench/testbench.sv \ $env(WALLY)/testbench/common/*.sv \ $env(WALLY)/src/*/*.sv \ $env(WALLY)/src/*/*/*.sv \ @@ -61,7 +61,7 @@ vlog +incdir+$env(WALLY)/config/$1 \ vopt +acc work.testbench -G DEBUG=1 -o workopt eval vsim workopt +nowarn3829 -fatal 7 \ -sv_lib $env(IMPERAS_HOME)/lib/Linux64/ImperasLib/imperas.com/verification/riscv/1.0/model \ - +testDir=$env(TESTDIR) $env(OTHERFLAGS) +TRACE2COV_ENABLE=1 + +ElfFile=$env(TESTDIR)/ref/ref.elf $env(OTHERFLAGS) +TRACE2COV_ENABLE=1 coverage save -onexit $env(WALLY)/sim/questa/riscv.ucdb @@ -76,4 +76,4 @@ run -all noview $env(WALLY)/testbench/testbench-imperas.sv view wave -quit -f +#quit -f diff --git a/testbench/testbench-imperas.sv b/testbench/testbench-imperas.sv index c315272a6..c834483f2 100644 --- a/testbench/testbench-imperas.sv +++ b/testbench/testbench-imperas.sv @@ -149,10 +149,11 @@ module testbench; $display($sformatf("%m @ t=%0t: Expecting RVVI API version %0d.", $time, RVVI_API_VERSION)); $fatal; end + void'(rvviRefConfigSetString(IDV_CONFIG_MODEL_VENDOR, "riscv.ovpworld.org")); void'(rvviRefConfigSetString(IDV_CONFIG_MODEL_NAME, "riscv")); void'(rvviRefConfigSetString(IDV_CONFIG_MODEL_VARIANT, "RV64GC")); - void'(rvviRefConfigSetInt(IDV_CONFIG_MODEL_ADDRESS_BUS_WIDTH, 39)); + void'(rvviRefConfigSetInt(IDV_CONFIG_MODEL_ADDRESS_BUS_WIDTH, 56)); void'(rvviRefConfigSetInt(IDV_CONFIG_MAX_NET_LATENCY_RETIREMENTS, 6)); if (!rvviRefInit(elffilename)) begin @@ -189,7 +190,7 @@ module testbench; end if (P.SDC_SUPPORTED) begin void'(rvviRefMemorySetVolatile(P.SDC_BASE, (P.SDC_BASE + P.SDC_RANGE))); - end + end if (P.SPI_SUPPORTED) begin void'(rvviRefMemorySetVolatile(P.SPI_BASE, (P.SPI_BASE + P.SPI_RANGE))); end From 0c5b70c40a1d09291964e63cc7079fe743996b4e Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Tue, 28 May 2024 13:54:48 -0500 Subject: [PATCH 50/51] It's a bit hacky. But I've got functional coverage working with our wally.do script and testbench.sv. --- bin/wsim | 21 +++++++++++++++------ sim/questa/wally.do | 37 +++++++++++++++++++++++++++++-------- 2 files changed, 44 insertions(+), 14 deletions(-) diff --git a/bin/wsim b/bin/wsim index 6bedf3fe9..487647514 100755 --- a/bin/wsim +++ b/bin/wsim @@ -63,18 +63,27 @@ for d in ["logs", "wkdir", "cov"]: # Launch selected simulator cd = "cd $WALLY/sim/" +args.sim +# ugh. can't have more than 9 arguments passed to vsim. why? I'll have to remove --lockstep when running +# functional coverage and imply it. if (args.sim == "questa"): if (args.lockstep): - Instret = str(args.locksteplog) - CovEnableStr = "1" if int(args.covlog) > 0 else "0"; - prefix ="IMPERAS_TOOLS=" + WALLY + "/sim/imperas.ic OTHERFLAGS=\"+IDV_TRACE2LOG=" + Instret + " +IDV_TRACE2COV=" + str(args.covlog) + " +TRACE2COV_ENABLE=" + CovEnableStr + "\""; - suffix = "--lockstep" + prefix = "IMPERAS_TOOLS=" + WALLY + "/sim/imperas.ic" # OTHERFLAGS=\"+IDV_TRACE2LOG=" + str(args.locksteplog) + " +IDV_TRACE2COV=" + str(args.covlog) + "\""; + if(args.fcov): + CovEnableStr = "1" if int(args.covlog) > 0 else "0"; + #ImperasPlusArgs = "+IDV_TRACE2LOG=" + str(args.locksteplog) + " +IDV_TRACE2COV=" + str(args.covlog) + " +TRACE2COV_ENABLE=" + CovEnableStr; + ImperasPlusArgs = " +IDV_TRACE2COV=" + str(args.covlog) + " +TRACE2COV_ENABLE=" + CovEnableStr; + suffix = "" + else: + CovEnableStr = "" + ImperasPlusArgs = ""; + suffix = "--lockstep" else: prefix = "" + ImperasPlusArgs = "" suffix = "" if (args.tb == "testbench_fp"): - args.args = " -GTEST=\"" + args.testsuite + "\" " + args.args - cmd = "do wally.do " + args.config + " " + args.testsuite + " " + args.tb + " " + args.args + " " + ElfFile + " " + suffix + args.args = " -GTEST=\"" + args.testsuite + "\" " + args.args + cmd = "do wally.do " + args.config + " " + args.testsuite + " " + args.tb + " " + args.args + " " + ElfFile + " " + suffix + " " + ImperasPlusArgs if (args.coverage): cmd += " --coverage" if (args.fcov): diff --git a/sim/questa/wally.do b/sim/questa/wally.do index 5c7700e37..b69f45267 100644 --- a/sim/questa/wally.do +++ b/sim/questa/wally.do @@ -65,7 +65,7 @@ set lockstep 0 set lockstepvoptstring "" set SVLib "" set SVLibPath "" -set OtherFlags "" +#set OtherFlags "" set ImperasPubInc "" set ImperasPrivInc "" set rvviFiles "" @@ -134,7 +134,9 @@ if {$FunctCoverageIndex >= 0} { } set LockStepIndex [lsearch -exact $lst "--lockstep"] -if {$LockStepIndex >= 0} { +# ugh. can't have more than 9 arguments passed to vsim. why? I'll have to remove --lockstep when running +# functional coverage and imply it. +if {$LockStepIndex >= 0 || $FunctCoverageIndex >= 0} { set lockstep 1 # ideally this would all be one or two variables, but questa is having a real hard time @@ -146,9 +148,11 @@ if {$LockStepIndex >= 0} { set idvFiles $env(IMPERAS_HOME)/ImpProprietary/source/host/idv/*.sv set SVLib "-sv_lib" set SVLibPath $env(IMPERAS_HOME)/lib/Linux64/ImperasLib/imperas.com/verification/riscv/1.0/model - set OtherFlags $env(OTHERFLAGS) + #set OtherFlags $env(OTHERFLAGS) - set lst [lreplace $lst $LockStepIndex $LockStepIndex] + if {$LockStepIndex >= 0} { + set lst [lreplace $lst $LockStepIndex $LockStepIndex] + } } # separate the +args from the -G parameters @@ -164,11 +168,26 @@ if {$DEBUG > 0} { echo "GUI = $GUI" echo "coverage = $coverage" echo "lockstep = $lockstep" - echo "remaining list = \'$lst\'" - echo "Extra +args = \'$PlusArgs\'" - echo "Extra -args = \'$ParamArgs\'" + echo "FunctCoverage = $FunctCoverage" + echo "remaining list = $lst" + echo "Extra +args = $PlusArgs" + echo "Extra -args = $ParamArgs" } +foreach x $PlusArgs { + echo "Element is $x" +} + +# need a better solution this is really ugly +# Questa really don't like passing $PlusArgs on the command line to vsim. It treats the whole things +# as one string rather than mutliple separate +args. Is there an automated way to pass these? +set temp0 [lindex $PlusArgs 0] +set temp1 [lindex $PlusArgs 1] +set temp2 [lindex $PlusArgs 2] +set temp3 [lindex $PlusArgs 3] + +#quit + # compile source files # suppress spurious warnngs about # "Extra checking for conflicts with always_comb done at vopt time" @@ -180,7 +199,9 @@ vlog -lint -work ${WKDIR} +incdir+${CONFIG}/${CFG} +incdir+${CONFIG}/deriv/${CF # remove +acc flag for faster sim during regressions if there is no need to access internal signals vopt $accFlag wkdir/${CFG}_${TESTSUITE}.${TESTBENCH} -work ${WKDIR} ${ParamArgs} -o testbenchopt ${CoverageVoptArg} -vsim -lib ${WKDIR} testbenchopt +TEST=${TESTSUITE} ${PlusArgs} -fatal 7 ${SVLib} ${SVLibPath} ${OtherFlags} -suppress 3829 ${CoverageVsimArg} +#vsim -lib ${WKDIR} testbenchopt +TEST=${TESTSUITE} ${PlusArgs} -fatal 7 ${SVLib} ${SVLibPath} ${OtherFlags} +TRACE2COV_ENABLE=1 -suppress 3829 ${CoverageVsimArg} +#vsim -lib ${WKDIR} testbenchopt +TEST=${TESTSUITE} ${PlusArgs} -fatal 7 ${SVLib} ${SVLibPath} +IDV_TRACE2COV=1 +TRACE2COV_ENABLE=1 -suppress 3829 ${CoverageVsimArg} +vsim -lib ${WKDIR} testbenchopt +TEST=${TESTSUITE} $temp0 $temp1 $temp2 $temp3 -fatal 7 ${SVLib} ${SVLibPath} -suppress 3829 ${CoverageVsimArg} # vsim -lib wkdir/work_${1}_${2} testbenchopt -fatal 7 -suppress 3829 # power add generates the logging necessary for said generation. From a88d5f403b5c0dca34fc5408191ee5a32c3c2ba9 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Tue, 28 May 2024 14:02:54 -0500 Subject: [PATCH 51/51] Functional coverage works with wally.do --- sim/questa/wally.do | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sim/questa/wally.do b/sim/questa/wally.do index b69f45267..a0e6fdbb6 100644 --- a/sim/questa/wally.do +++ b/sim/questa/wally.do @@ -219,7 +219,7 @@ run -all # power off -r /dut/core/* if {$coverage || $FunctCoverage} { - set UCDB cov/${CFG}_${TESTSUITE}.ucdb + set UCDB ${WALLY}/sim/questa/cov/${CFG}_${TESTSUITE}.ucdb echo "Saving coverage to ${UCDB}" do coverage-exclusions-rv64gc.do # beware: this assumes testing the rv64gc configuration coverage save -instance /testbench/dut/core ${UCDB}