diff --git a/wally-pipelined/bin/exe2memfile0.pl b/wally-pipelined/bin/exe2memfile.pl.old similarity index 100% rename from wally-pipelined/bin/exe2memfile0.pl rename to wally-pipelined/bin/exe2memfile.pl.old diff --git a/wally-pipelined/linux-testgen/testvector-generation/fix_mem.py b/wally-pipelined/linux-testgen/testvector-generation/fix_mem.py index d9b900099..66ff9cf03 100755 --- a/wally-pipelined/linux-testgen/testvector-generation/fix_mem.py +++ b/wally-pipelined/linux-testgen/testvector-generation/fix_mem.py @@ -1,11 +1,14 @@ #! /usr/bin/python3 -test_dir = '../' -gdbMemfileDir = '../linux-testvectors/intermediate-outputs/' -fixedMemfileDir = '../linux-testvectors/' -infiles = ['bootmemGDB.txt', 'ramGDB.txt'] -outfiles = ['bootmem.txt', 'ram.txt'] -for i in range(len(infiles)): - with open(f'{gdbMemfileDir}{infiles[i]}', 'r') as f: - with open(f'{fixedMemfileDir}{outfiles[i]}', 'w') as w: - for l in f: - w.write(f'{"".join([x[2:] for x in l.split()[:0:-1]])}\n') +import sys,os + +if len(sys.argv) != 3: + sys.exit('Error fix_mem.py expects 2 args:\n fix_mem.py ') +inputFile = sys.argv[1] +outputFile = sys.argv[2] +if not os.path.exists(inputFile): + sys.exit('Error input file '+inputFile+'not found') +print('Translating '+os.path.basename(inputFile)+' to '+os.path.basename(outputFile)) +with open(inputFile, 'r') as f: + with open(outputFile, 'w') as w: + for l in f: + w.write(f'{"".join([x[2:] for x in l.split()[:0:-1]])}\n') diff --git a/wally-pipelined/linux-testgen/testvector-generation/logBuildrootMem.sh b/wally-pipelined/linux-testgen/testvector-generation/logBuildrootMem.sh index 978311d92..a1ff42544 100755 --- a/wally-pipelined/linux-testgen/testvector-generation/logBuildrootMem.sh +++ b/wally-pipelined/linux-testgen/testvector-generation/logBuildrootMem.sh @@ -16,7 +16,8 @@ then ($customQemu -M virt -nographic -bios $imageDir/fw_jump.elf -kernel $imageDir/Image -append "root=/dev/vda ro" -initrd $imageDir/rootfs.cpio -d nochain,cpu,in_asm -serial /dev/null -singlestep -gdb tcp::1235 -S 2>/dev/null >/dev/null) & riscv64-unknown-elf-gdb -x gdbinit_mem echo "Translating Mem from GDB to Questa format" - ./fix_mem.py + ./fix_mem.py "$testVecDir/intermediate-outputs/bootmemGDB.txt" "$testVecDir/bootmem.txt" + ./fix_mem.py "$testVecDir/intermediate-outputs/ramGDB.txt" "$testVecDir/ram.txt" echo "Done" echo "Creating debugging objdump of linux image" diff --git a/wally-pipelined/regression/regression-wally.py b/wally-pipelined/regression/regression-wally.py index 2cd2d77ec..4d7baf8e5 100755 --- a/wally-pipelined/regression/regression-wally.py +++ b/wally-pipelined/regression/regression-wally.py @@ -33,6 +33,11 @@ configs = [ cmd="vsim -do wally-buildroot-batch.do -c > {}", grepstr="loaded 6000 instructions" ), + TestCase( + name="arch64", + cmd="vsim > {} -c < {} -c <" prompt: +# do wally-arch.do +# or, to run from a shell, type the following at the shell prompt: +# vsim -do wally-arch.do -c +# (omit the "-c" to see the GUI while running from the shell) + +onbreak {resume} + +# create library +if [file exists work-arch] { + vdel -all +} +vlib work-arch + +# compile source files +# suppress spurious warnngs about +# "Extra checking for conflicts with always_comb done at vopt time" +# because vsim will run vopt + +# default to config/rv64ic, but allow this to be overridden at the command line. For example: +# do wally-pipelined.do ../config/rv32ic +switch $argc { + 0 {vlog +incdir+../config/rv64ic +incdir+../config/shared ../testbench/testbench-arch.sv ../testbench/common/*.sv ../src/*/*.sv -suppress 2583} + 1 {vlog +incdir+$1 +incdir+../config/shared ../testbench/testbench-arch.sv ../testbench/common/*.sv ../src/*/*.sv -suppress 2583} +} +# start and run simulation +# remove +acc flag for faster sim during regressions if there is no need to access internal signals +vopt +acc work-arch.testbench -o workopt +vsim workopt + +view wave +-- display input and output signals as hexidecimal values +do ./wave-dos/peripheral-waves.do + +-- Run the Simulation +#run 5000 +run -all +#quit +noview ../testbench/testbench-arch.sv +view wave diff --git a/wally-pipelined/src/cache/cachereplacementpolicy.sv b/wally-pipelined/src/cache/cachereplacementpolicy.sv index a0b37cec8..0e508ca11 100644 --- a/wally-pipelined/src/cache/cachereplacementpolicy.sv +++ b/wally-pipelined/src/cache/cachereplacementpolicy.sv @@ -46,11 +46,11 @@ module cachereplacementpolicy always_ff @(posedge clk, posedge reset) begin if (reset) begin for(int index = 0; index < NUMLINES; index++) - ReplacementBits[index] <= '0; + ReplacementBits[index] = '0; end else begin - BlockReplacementBits <= ReplacementBits[RAdr]; + BlockReplacementBits = ReplacementBits[RAdr]; if (LRUWriteEn) begin - ReplacementBits[MemPAdrM[INDEXLEN+OFFSETLEN-1:OFFSETLEN]] <= NewReplacement; + ReplacementBits[MemPAdrM[INDEXLEN+OFFSETLEN-1:OFFSETLEN]] = NewReplacement; end end end diff --git a/wally-pipelined/src/cache/cacheway.sv b/wally-pipelined/src/cache/cacheway.sv index cb596846e..dc1f4c9bc 100644 --- a/wally-pipelined/src/cache/cacheway.sv +++ b/wally-pipelined/src/cache/cacheway.sv @@ -41,7 +41,7 @@ module cacheway #(parameter NUMLINES=512, parameter BLOCKLEN = 256, TAGLEN = 26, input logic SetDirty, input logic ClearDirty, input logic SelEvict, - input logic VictimWay, + input logic VictimWay, output logic [BLOCKLEN-1:0] ReadDataBlockWayMasked, output logic WayHit, @@ -55,7 +55,7 @@ module cacheway #(parameter NUMLINES=512, parameter BLOCKLEN = 256, TAGLEN = 26, logic Valid; logic Dirty; logic SelectedWay; - + genvar words; generate diff --git a/wally-pipelined/src/generic/or_rows.sv b/wally-pipelined/src/generic/or_rows.sv index 4c74f62e9..c29528e48 100644 --- a/wally-pipelined/src/generic/or_rows.sv +++ b/wally-pipelined/src/generic/or_rows.sv @@ -33,23 +33,14 @@ module or_rows #(parameter ROWS = 8, COLS=2) ( input var logic [COLS-1:0] a[ROWS-1:0], output logic [COLS-1:0] y); - logic [COLS-1:0] mid[ROWS-1:0]; + logic [COLS-1:0] mid[ROWS-1:1]; genvar row, col; generate assign mid[1] = a[0] | a[1]; for (row=2; row < ROWS; row++) assign mid[row] = mid[row-1] | a[row]; - assign y = mid[ROWS-1]; - - /* - for (col = 0; col < COLS; col++) begin - assign mid[1][col] = a[0][col] | a[1][col]; - for (row=2; row < ROWS; row++) - assign mid[row][col] = mid[row-1][col] | a[row][col]; - assign y[col] = mid[ROWS-1][col]; - end - */ - endgenerate + assign y = mid[ROWS-1]; + endgenerate endmodule /* verilator lint_on UNOPTFLAT */ diff --git a/wally-pipelined/src/mmu/priorityonehot.sv b/wally-pipelined/src/mmu/priorityonehot.sv index 75825dc40..7a17f8d28 100644 --- a/wally-pipelined/src/mmu/priorityonehot.sv +++ b/wally-pipelined/src/mmu/priorityonehot.sv @@ -35,6 +35,8 @@ module priorityonehot #(parameter ENTRIES = 8) ( output logic [ENTRIES-1:0] y ); + /* verilator lint_off UNOPTFLAT */ + logic [ENTRIES-1:0] nolower; // generate thermometer code mask @@ -47,5 +49,7 @@ module priorityonehot #(parameter ENTRIES = 8) ( endgenerate assign y = a & nolower; - + + /* verilator lint_on UNOPTFLAT */ + endmodule diff --git a/wally-pipelined/src/mmu/prioritythermometer.sv b/wally-pipelined/src/mmu/prioritythermometer.sv index 132a489c1..a6374579c 100644 --- a/wally-pipelined/src/mmu/prioritythermometer.sv +++ b/wally-pipelined/src/mmu/prioritythermometer.sv @@ -30,11 +30,14 @@ `include "wally-config.vh" +/* verilator lint_off UNOPTFLAT */ + module prioritythemometer #(parameter N = 8) ( input logic [N-1:0] a, output logic [N-1:0] y ); + // generate thermometer code mask genvar i; generate @@ -47,4 +50,5 @@ module prioritythemometer #(parameter N = 8) ( endmodule +/* verilator lint_on UNOPTFLAT */ diff --git a/wally-pipelined/testbench/testbench-arch.sv b/wally-pipelined/testbench/testbench-arch.sv new file mode 100644 index 000000000..f200c7189 --- /dev/null +++ b/wally-pipelined/testbench/testbench-arch.sv @@ -0,0 +1,836 @@ +/////////////////////////////////////////// +// testbench-imperas.sv +// +// Written: David_Harris@hmc.edu 9 January 2021 +// Modified: +// +// Purpose: Wally Testbench and helper modules +// Applies test programs from the Imperas suite +// +// A component of the Wally configurable RISC-V project. +// +// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, +// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software +// is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +/////////////////////////////////////////// + +`include "wally-config.vh" + +module testbench(); + parameter DEBUG = 0; + parameter TESTSPERIPH = 0; // set to 0 for regression + parameter TESTSPRIV = 0; // set to 0 for regression + + logic clk; + logic reset; + + parameter SIGNATURESIZE = 5000000; + + int test, i, errors, totalerrors; + logic [31:0] sig32[0:SIGNATURESIZE]; + logic [`XLEN-1:0] signature[0:SIGNATURESIZE]; + logic [`XLEN-1:0] testadr; + string InstrFName, InstrDName, InstrEName, InstrMName, InstrWName; + logic [31:0] InstrW; + logic [`XLEN-1:0] meminit; + + string tests32mmu[] = '{ + "rv32mmu/WALLY-MMU-SV32", "3000" + //"rv32mmu/WALLY-PMA", "3000", + //"rv32mmu/WALLY-PMA", "3000" + }; + + string tests64mmu[] = '{ + "rv64mmu/WALLY-MMU-SV48", "3000", + "rv64mmu/WALLY-MMU-SV39", "3000" + //"rv64mmu/WALLY-PMA", "3000", + //"rv64mmu/WALLY-PMA", "3000" + }; + + +string tests32f[] = '{ + "rv32f/I-FADD-S-01", "2000", + "rv32f/I-FCLASS-S-01", "2000", + "rv32f/I-FCVT-S-W-01", "2000", + "rv32f/I-FCVT-S-WU-01", "2000", + "rv32f/I-FCVT-W-S-01", "2000", + "rv32f/I-FCVT-WU-S-01", "2000", + "rv32f/I-FDIV-S-01", "2000", + "rv32f/I-FEQ-S-01", "2000", + "rv32f/I-FLE-S-01", "2000", + "rv32f/I-FLT-S-01", "2000", + "rv32f/I-FMADD-S-01", "2000", + "rv32f/I-FMAX-S-01", "2000", + "rv32f/I-FMIN-S-01", "2000", + "rv32f/I-FMSUB-S-01", "2000", + "rv32f/I-FMUL-S-01", "2000", + "rv32f/I-FMV-W-X-01", "2000", + "rv32f/I-FMV-X-W-01", "2000", + "rv32f/I-FNMADD-S-01", "2000", + "rv32f/I-FNMSUB-S-01", "2000", + "rv32f/I-FSGNJ-S-01", "2000", + "rv32f/I-FSGNJN-S-01", "2000", + "rv32f/I-FSGNJX-S-01", "2000", + "rv32f/I-FSQRT-S-01", "2000", + "rv32f/I-FSW-01", "2000", + "rv32f/I-FLW-01", "2110", + "rv32f/I-FSUB-S-01", "2000" + }; + + string tests64f[] = '{ + "rv64f/I-FLW-01", "2110", + "rv64f/I-FMV-W-X-01", "2000", + "rv64f/I-FMV-X-W-01", "2000", + "rv64f/I-FSW-01", "2000", + "rv64f/I-FCLASS-S-01", "2000", + "rv64f/I-FADD-S-01", "2000", +// "rv64f/I-FCVT-S-L-01", "2000", +// "rv64f/I-FCVT-S-LU-01", "2000", +// "rv64f/I-FCVT-S-W-01", "2000", +// "rv64f/I-FCVT-S-WU-01", "2000", + "rv64f/I-FCVT-L-S-01", "2000", + "rv64f/I-FCVT-LU-S-01", "2000", + "rv64f/I-FCVT-W-S-01", "2000", + "rv64f/I-FCVT-WU-S-01", "2000", + "rv64f/I-FDIV-S-01", "2000", + "rv64f/I-FEQ-S-01", "2000", + "rv64f/I-FLE-S-01", "2000", + "rv64f/I-FLT-S-01", "2000", + "rv64f/I-FMADD-S-01", "2000", + "rv64f/I-FMAX-S-01", "2000", + "rv64f/I-FMIN-S-01", "2000", + "rv64f/I-FMSUB-S-01", "2000", + "rv64f/I-FMUL-S-01", "2000", + "rv64f/I-FNMADD-S-01", "2000", + "rv64f/I-FNMSUB-S-01", "2000", + "rv64f/I-FSGNJ-S-01", "2000", + "rv64f/I-FSGNJN-S-01", "2000", + "rv64f/I-FSGNJX-S-01", "2000", + "rv64f/I-FSQRT-S-01", "2000", + "rv64f/I-FSUB-S-01", "2000" + }; + + string tests64d[] = '{ + "rv64d/I-FSD-01", "2000", + "rv64d/I-FLD-01", "2420", + "rv64d/I-FMV-X-D-01", "2000", + "rv64d/I-FMV-D-X-01", "2000", + "rv64d/I-FDIV-D-01", "2000", + "rv64d/I-FNMADD-D-01", "2000", + "rv64d/I-FNMSUB-D-01", "2000", + "rv64d/I-FMSUB-D-01", "2000", + "rv64d/I-FMAX-D-01", "2000", + "rv64d/I-FMIN-D-01", "2000", + "rv64d/I-FLE-D-01", "2000", + "rv64d/I-FLT-D-01", "2000", + "rv64d/I-FEQ-D-01", "2000", + "rv64d/I-FADD-D-01", "2000", + "rv64d/I-FCLASS-D-01", "2000", + "rv64d/I-FMADD-D-01", "2000", + "rv64d/I-FMUL-D-01", "2000", + "rv64d/I-FSGNJ-D-01", "2000", + "rv64d/I-FSGNJN-D-01", "2000", + "rv64d/I-FSGNJX-D-01", "2000", + "rv64d/I-FSQRT-D-01", "2000", + "rv64d/I-FSUB-D-01", "2000", +// "rv64d/I-FCVT-D-L-01", "2000", +// "rv64d/I-FCVT-D-LU-01", "2000", + "rv64d/I-FCVT-D-S-01", "2000", +// "rv64d/I-FCVT-D-W-01", "2000", +// "rv64d/I-FCVT-D-WU-01", "2000", + "rv64d/I-FCVT-L-D-01", "2000", + "rv64d/I-FCVT-LU-D-01", "2000", + "rv64d/I-FCVT-S-D-01", "2000", + "rv64d/I-FCVT-W-D-01", "2000", + "rv64d/I-FCVT-WU-D-01", "2000" +}; + + string tests64a[] = '{ + "rv64a/WALLY-AMO", "2110", + "rv64a/WALLY-LRSC", "2110" + }; + + string tests64m[] = '{ + "rv64i_m/M/div-01", "9010", + "rv64i_m/M/divu-01", "a010", + "rv64i_m/M/divuw-01", "a010", + "rv64i_m/M/divw-01", "9010", + "rv64i_m/M/mul-01", "9010", + "rv64i_m/M/mulh-01", "9010", + "rv64i_m/M/mulhsu-01", "9010", + "rv64i_m/M/mulhu-01", "a010", + "rv64i_m/M/mulw-01", "9010", + "rv64i_m/M/rem-01", "9010", + "rv64i_m/M/remu-01", "a010", + "rv64i_m/M/remuw-01", "a010", + "rv64i_m/M/remw-01", "9010" + }; + + string tests64ic[] = '{ + "rv64i_m/C/cadd-01", "8010", + "rv64i_m/C/caddi-01", "4010", + "rv64i_m/C/caddi16sp-01", "2010", + "rv64i_m/C/caddi4spn-01", "2010", + "rv64i_m/C/caddiw-01", "4010", + "rv64i_m/C/caddw-01", "8010", + "rv64i_m/C/cand-01", "8010", + "rv64i_m/C/candi-01", "4010", + "rv64i_m/C/cbeqz-01", "4010", + "rv64i_m/C/cbnez-01", "5010", + "rv64i_m/C/cebreak-01", "2070", + "rv64i_m/C/cj-01", "3010", + "rv64i_m/C/cjalr-01", "2010", + "rv64i_m/C/cjr-01", "2010", + "rv64i_m/C/cld-01", "2010", + "rv64i_m/C/cldsp-01", "2010", + "rv64i_m/C/cli-01", "2010", + "rv64i_m/C/clui-01", "2010", + "rv64i_m/C/clw-01", "2010", + "rv64i_m/C/clwsp-01", "2010", + "rv64i_m/C/cmv-01", "2010", + "rv64i_m/C/cnop-01", "2010", + "rv64i_m/C/cor-01", "8010", + "rv64i_m/C/csd-01", "3010", + "rv64i_m/C/csdsp-01", "3010", + "rv64i_m/C/cslli-01", "2010", + "rv64i_m/C/csrai-01", "2010", + "rv64i_m/C/csrli-01", "2010", + "rv64i_m/C/csub-01", "8010", + "rv64i_m/C/csubw-01", "8010", + "rv64i_m/C/csw-01", "3010", + "rv64i_m/C/cswsp-01", "3010", + "rv64i_m/C/cxor-01", "8010" + }; + + string tests64iNOc[] = { + "rv64i/I-MISALIGN_JMP-01","2000" + }; + + string tests64i[] = '{ + "rv64i_m/I/add-01", "9010", + "rv64i_m/I/addi-01", "6010", + "rv64i_m/I/addiw-01", "6010", + "rv64i_m/I/addw-01", "9010", + "rv64i_m/I/and-01", "9010", + "rv64i_m/I/andi-01", "6010", + "rv64i_m/I/auipc-01", "2010", + "rv64i_m/I/beq-01", "47010", + "rv64i_m/I/bge-01", "47010", + "rv64i_m/I/bgeu-01", "56010", + "rv64i_m/I/blt-01", "4d010", + "rv64i_m/I/bltu-01", "57010", + "rv64i_m/I/bne-01", "43010", + "rv64i_m/I/fence-01", "2010", + "rv64i_m/I/jal-01", "122010", + "rv64i_m/I/jalr-01", "2010", + "rv64i_m/I/lb-align-01", "2010", + "rv64i_m/I/lbu-align-01", "2010", + "rv64i_m/I/ld-align-01", "2010", + "rv64i_m/I/lh-align-01", "2010", + "rv64i_m/I/lhu-align-01", "2010", + "rv64i_m/I/lui-01", "2010", + "rv64i_m/I/lw-align-01", "2010", + "rv64i_m/I/lwu-align-01", "2010", + "rv64i_m/I/or-01", "9010", + "rv64i_m/I/ori-01", "6010", + "rv64i_m/I/sb-align-01", "3010", + "rv64i_m/I/sd-align-01", "3010", + "rv64i_m/I/sh-align-01", "3010", + "rv64i_m/I/sll-01", "3010", + "rv64i_m/I/slli-01", "2010", + "rv64i_m/I/slliw-01", "2010", + "rv64i_m/I/sllw-01", "3010", + "rv64i_m/I/slt-01", "9010", + "rv64i_m/I/slti-01", "6010", + "rv64i_m/I/sltiu-01", "6010", + "rv64i_m/I/sltu-01", "a010", + "rv64i_m/I/sra-01", "3010", + "rv64i_m/I/srai-01", "2010", + "rv64i_m/I/sraiw-01", "2010", + "rv64i_m/I/sraw-01", "3010", + "rv64i_m/I/srl-01", "3010", + "rv64i_m/I/srli-01", "2010", + "rv64i_m/I/srliw-01", "2010", + "rv64i_m/I/srlw-01", "3010", + "rv64i_m/I/sub-01", "9010", + "rv64i_m/I/subw-01", "9010", + "rv64i_m/I/sw-align-01", "3010", + "rv64i_m/I/xor-01", "9010", + "rv64i_m/I/xori-01", "6010" + }; + + string tests32a[] = '{ + "rv32a/WALLY-AMO", "2110", + "rv32a/WALLY-LRSC", "2110" + }; + + string tests32m[] = '{ + "rv32m/I-MUL-01", "2000", + "rv32m/I-MULH-01", "2000", + "rv32m/I-MULHSU-01", "2000", + "rv32m/I-MULHU-01", "2000", + "rv32m/I-DIV-01", "2000", + "rv32m/I-DIVU-01", "2000", + "rv32m/I-REM-01", "2000", + "rv32m/I-REMU-01", "2000" + }; + + string tests32ic[] = '{ + "rv32ic/I-C-ADD-01", "2000", + "rv32ic/I-C-ADDI-01", "2000", + "rv32ic/I-C-AND-01", "2000", + "rv32ic/I-C-ANDI-01", "2000", + "rv32ic/I-C-BEQZ-01", "2000", + "rv32ic/I-C-BNEZ-01", "2000", + "rv32ic/I-C-EBREAK-01", "2000", + "rv32ic/I-C-J-01", "2000", + "rv32ic/I-C-JALR-01", "3000", + "rv32ic/I-C-JR-01", "3000", + "rv32ic/I-C-LI-01", "2000", + "rv32ic/I-C-LUI-01", "2000", + "rv32ic/I-C-LW-01", "2110", + "rv32ic/I-C-LWSP-01", "2110", + "rv32ic/I-C-MV-01", "2000", + "rv32ic/I-C-NOP-01", "2000", + "rv32ic/I-C-OR-01", "2000", + "rv32ic/I-C-SLLI-01", "2000", + "rv32ic/I-C-SRAI-01", "2000", + "rv32ic/I-C-SRLI-01", "2000", + "rv32ic/I-C-SUB-01", "2000", + "rv32ic/I-C-SW-01", "2000", + "rv32ic/I-C-SWSP-01", "2000", + "rv32ic/I-C-XOR-01", "2000" + }; + + string tests32iNOc[] = { + "rv32i/I-MISALIGN_JMP-01","2000" + }; + + string tests32i[] = { + //"rv32i/WALLY-PIPELINE-100K", "10a800", + "rv32i/I-ADD-01", "2000", + "rv32i/I-ADDI-01","2000", + "rv32i/I-AND-01","2000", + "rv32i/I-ANDI-01","2000", + "rv32i/I-AUIPC-01","2000", + "rv32i/I-BEQ-01","3000", + "rv32i/I-BGE-01","3000", + "rv32i/I-BGEU-01","3000", + "rv32i/I-BLT-01","3000", + "rv32i/I-BLTU-01","3000", + "rv32i/I-BNE-01","3000", + "rv32i/I-DELAY_SLOTS-01","2000", + "rv32i/I-EBREAK-01","2000", + "rv32i/I-ECALL-01","2000", + "rv32i/I-ENDIANESS-01","2010", + "rv32i/I-IO-01","2030rv", + "rv32i/I-JAL-01","3000", + "rv32i/I-JALR-01","3000", + "rv32i/I-LB-01","3020", + "rv32i/I-LBU-01","3020", + "rv32i/I-LH-01","3050", + "rv32i/I-LHU-01","3050", + "rv32i/I-LUI-01","2000", + "rv32i/I-LW-01","3110", + "rv32i/I-MISALIGN_LDST-01","2010", + "rv32i/I-NOP-01","2000", + "rv32i/I-OR-01","2000", + "rv32i/I-ORI-01","2000", + "rv32i/I-RF_size-01","2000", + "rv32i/I-RF_width-01","2000", + "rv32i/I-RF_x0-01","2010", + "rv32i/I-SB-01","3000", + "rv32i/I-SH-01","3000", + "rv32i/I-SLL-01","2000", + "rv32i/I-SLLI-01","2000", + "rv32i/I-SLT-01","2000", + "rv32i/I-SLTI-01","2000", + "rv32i/I-SLTIU-01","2000", + "rv32i/I-SLTU-01","2000", + "rv32i/I-SRA-01","2000", + "rv32i/I-SRAI-01","2000", + "rv32i/I-SRL-01","2000", + "rv32i/I-SRLI-01","2000", + "rv32i/I-SUB-01","2000", + "rv32i/I-SW-01","3000", + "rv32i/I-XOR-01","2000", + "rv32i/I-XORI-01","2000", + "rv32i/WALLY-ADD", "3000", + "rv32i/WALLY-SUB", "3000", + "rv32i/WALLY-ADDI", "2000", + "rv32i/WALLY-ANDI", "2000", + "rv32i/WALLY-ORI", "2000", + "rv32i/WALLY-XORI", "2000", + "rv32i/WALLY-SLTI", "2000", + "rv32i/WALLY-SLTIU", "2000", + "rv32i/WALLY-SLLI", "2000", + "rv32i/WALLY-SRLI", "2000", + "rv32i/WALLY-SRAI", "2000", + "rv32i/WALLY-LOAD", "11c00", + "rv32i/WALLY-SUB", "3000", + "rv32i/WALLY-STORE", "2000", + "rv32i/WALLY-JAL", "3000", + "rv32i/WALLY-JALR", "2000", + "rv32i/WALLY-BEQ" ,"4000", + "rv32i/WALLY-BNE", "4000 ", + "rv32i/WALLY-BLTU", "4000 ", + "rv32i/WALLY-BLT", "4000", + "rv32i/WALLY-BGE", "4000 ", + "rv32i/WALLY-BGEU", "4000 ", + "rv32i/WALLY-CSRRW", "3000", + "rv32i/WALLY-CSRRS", "3000", + "rv32i/WALLY-CSRRC", "4000", + "rv32i/WALLY-CSRRWI", "3000", + "rv32i/WALLY-CSRRSI", "3000", + "rv32i/WALLY-CSRRCI", "3000" + }; + + string testsBP64[] = '{ + "rv64BP/simple", "10000", + "rv64BP/mmm", "1000000", + "rv64BP/linpack_bench", "1000000", + "rv64BP/sieve", "1000000", + "rv64BP/qsort", "1000000", + "rv64BP/dhrystone", "1000000" + }; + + string tests64p[] = '{ + "rv64p/WALLY-MSTATUS", "2000", + "rv64p/WALLY-MCAUSE", "3000", + "rv64p/WALLY-SCAUSE", "2000", + "rv64p/WALLY-MEPC", "5000", + "rv64p/WALLY-SEPC", "4000", + "rv64p/WALLY-MTVAL", "6000", + "rv64p/WALLY-STVAL", "4000", + "rv64p/WALLY-MTVEC", "2000", + "rv64p/WALLY-STVEC", "2000", + "rv64p/WALLY-MARCHID", "4000", + "rv64p/WALLY-MIMPID", "4000", + "rv64p/WALLY-MHARTID", "4000", + "rv64p/WALLY-MVENDORID", "4000", + "rv64p/WALLY-MIE", "3000", + "rv64p/WALLY-MEDELEG", "4000", + "rv64p/WALLY-IP", "2000", + "rv64p/WALLY-CSR-PERMISSIONS-M", "5000", + "rv64p/WALLY-CSR-PERMISSIONS-S", "3000" + }; + + string tests32p[] = '{ + "rv32p/WALLY-MSTATUS", "2000", + "rv32p/WALLY-MCAUSE", "3000", + "rv32p/WALLY-SCAUSE", "2000", + "rv32p/WALLY-MEPC", "5000", + "rv32p/WALLY-SEPC", "4000", + "rv32p/WALLY-MTVAL", "5000", + "rv32p/WALLY-STVAL", "4000", + "rv32p/WALLY-MARCHID", "4000", + "rv32p/WALLY-MIMPID", "4000", + "rv32p/WALLY-MHARTID", "4000", + "rv32p/WALLY-MVENDORID", "4000", + "rv32p/WALLY-MTVEC", "2000", + "rv32p/WALLY-STVEC", "2000", + "rv32p/WALLY-MIE", "3000", + "rv32p/WALLY-MEDELEG", "4000", + "rv32p/WALLY-IP", "3000", + "rv32p/WALLY-CSR-PERMISSIONS-M", "5000", + "rv32p/WALLY-CSR-PERMISSIONS-S", "3000" + }; + + string tests64periph[] = '{ + "rv64i-periph/WALLY-PERIPH", "2000" + }; + + string tests32periph[] = '{ + "rv32i-periph/WALLY-PLIC", "2080" + }; + + string tests[]; + string ProgramAddrMapFile, ProgramLabelMapFile; + logic [`AHBW-1:0] HRDATAEXT; + logic HREADYEXT, HRESPEXT; + logic [31:0] HADDR; + logic [`AHBW-1:0] HWDATA; + logic HWRITE; + logic [2:0] HSIZE; + logic [2:0] HBURST; + logic [3:0] HPROT; + logic [1:0] HTRANS; + logic HMASTLOCK; + logic HCLK, HRESETn; + logic [`XLEN-1:0] PCW; + + logic DCacheFlushDone, DCacheFlushStart; + + flopenr #(`XLEN) PCWReg(clk, reset, ~dut.hart.ieu.dp.StallW, dut.hart.ifu.PCM, PCW); + flopenr #(32) InstrWReg(clk, reset, ~dut.hart.ieu.dp.StallW, dut.hart.ifu.InstrM, InstrW); + + // check assertions for a legal configuration + riscvassertions riscvassertions(); + logging logging(clk, reset, dut.uncore.HADDR, dut.uncore.HTRANS); + + // pick tests based on modes supported + initial begin + if (`XLEN == 64) begin // RV64 + if (`TESTSBP) begin + tests = testsBP64; + // testsbp should not run the other tests. It starts at address 0 rather than + // 0x8000_0000, the next if must remain an else if. + end else if (TESTSPERIPH) + tests = tests64periph; + else if (TESTSPRIV) + tests = tests64p; + else begin + tests = {tests64i}; +// tests = {tests64p,tests64i, tests64periph}; + if (`C_SUPPORTED) tests = {tests, tests64ic}; +// else tests = {tests, tests64iNOc}; + if (`M_SUPPORTED) tests = {tests, tests64m}; +/* if (`F_SUPPORTED) tests = {tests64f, tests}; + if (`D_SUPPORTED) tests = {tests64d, tests}; + if (`MEM_VIRTMEM) tests = {tests64mmu, tests}; + if (`A_SUPPORTED) tests = {tests64a, tests}; */ + end + //tests = {tests64a, tests}; + end else begin // RV32 + // *** add the 32 bit bp tests + if (TESTSPERIPH) + tests = tests32periph; + else if (TESTSPRIV) + tests = tests32p; + else begin + tests = {tests32i, tests32p};//,tests32periph}; *** broken at the moment + if (`C_SUPPORTED % 2 == 1) tests = {tests, tests32ic}; + else tests = {tests, tests32iNOc}; + if (`M_SUPPORTED % 2 == 1) tests = {tests, tests32m}; + if (`F_SUPPORTED) tests = {tests32f, tests}; + if (`MEM_VIRTMEM) tests = {tests32mmu, tests}; + if (`A_SUPPORTED) tests = {tests32a, tests}; + end + end + end + + string tvroot, bootroot, signame, memfilename, romfilename; + + logic [31:0] GPIOPinsIn, GPIOPinsOut, GPIOPinsEn; + logic UARTSin, UARTSout; + + // instantiate device to be tested + assign GPIOPinsIn = 0; + assign UARTSin = 1; + assign HREADYEXT = 1; + assign HRESPEXT = 0; + assign HRDATAEXT = 0; + + wallypipelinedsoc dut(.*); + + // Track names of instructions + instrTrackerTB it(clk, reset, dut.hart.ieu.dp.FlushE, + dut.hart.ifu.icache.FinalInstrRawF, + dut.hart.ifu.InstrD, dut.hart.ifu.InstrE, + dut.hart.ifu.InstrM, dut.hart.ifu.InstrW, + InstrFName, InstrDName, InstrEName, InstrMName, InstrWName); + + // initialize tests + localparam integer MemStartAddr = `TIM_BASE>>(1+`XLEN/32); + localparam integer MemEndAddr = (`TIM_RANGE+`TIM_BASE)>>1+(`XLEN/32); + + initial + begin + test = 0; + totalerrors = 0; + testadr = 0; + // fill memory with defined values to reduce Xs in simulation + // Quick note the memory will need to be initialized. The C library does not + // guarantee the initialized reads. For example a strcmp can read 6 byte + // strings, but uses a load double to read them in. If the last 2 bytes are + // not initialized the compare results in an 'x' which propagates through + // the design. + if (`XLEN == 32) meminit = 32'hFEDC0123; + else meminit = 64'hFEDCBA9876543210; + // *** broken because DTIM also drives RAM + if (`TESTSBP) begin + for (i=MemStartAddr; i= 128 || `MEM_DCACHE == 0) else $error("DCACHE_BLOCKLENINBITS must be at least 128 when caches are enabled"); + assert (`DCACHE_BLOCKLENINBITS < `DCACHE_WAYSIZEINBYTES*8) else $error("DCACHE_BLOCKLENINBITS must be smaller than way size"); + assert (`ICACHE_WAYSIZEINBYTES <= 4096 || `MEM_ICACHE == 0 || `MEM_VIRTMEM == 0) else $error("ICACHE_WAYSIZEINBYTES cannot exceed 4 KiB when caches and vitual memory is enabled (to prevent aliasing)"); + assert (`ICACHE_BLOCKLENINBITS >= 32 || `MEM_ICACHE == 0) else $error("ICACHE_BLOCKLENINBITS must be at least 32 when caches are enabled"); + assert (`ICACHE_BLOCKLENINBITS < `ICACHE_WAYSIZEINBYTES*8) else $error("ICACHE_BLOCKLENINBITS must be smaller than way size"); + assert (2**$clog2(`DCACHE_BLOCKLENINBITS) == `DCACHE_BLOCKLENINBITS) else $error("DCACHE_BLOCKLENINBITS must be a power of 2"); + assert (2**$clog2(`DCACHE_WAYSIZEINBYTES) == `DCACHE_WAYSIZEINBYTES) else $error("DCACHE_WAYSIZEINBYTES must be a power of 2"); + assert (2**$clog2(`ICACHE_BLOCKLENINBITS) == `ICACHE_BLOCKLENINBITS) else $error("ICACHE_BLOCKLENINBITS must be a power of 2"); + assert (2**$clog2(`ICACHE_WAYSIZEINBYTES) == `ICACHE_WAYSIZEINBYTES) else $error("ICACHE_WAYSIZEINBYTES must be a power of 2"); + assert (`ICACHE_NUMWAYS == 1 || `MEM_ICACHE == 0) else $error("Multiple Instruction Cache ways not yet implemented"); + assert (2**$clog2(`ITLB_ENTRIES) == `ITLB_ENTRIES) else $error("ITLB_ENTRIES must be a power of 2"); + assert (2**$clog2(`DTLB_ENTRIES) == `DTLB_ENTRIES) else $error("DTLB_ENTRIES must be a power of 2"); + assert (`TIM_RANGE >= 56'h07FFFFFF) else $error("Some regression tests will fail if TIM_RANGE is less than 56'h07FFFFFF"); + end +endmodule + + +/* verilator lint_on STMTDLY */ +/* verilator lint_on WIDTH */ + +module DCacheFlushFSM + (input logic clk, + input logic reset, + input logic start, + output logic done); + + localparam integer numlines = testbench.dut.hart.lsu.dcache.NUMLINES; + localparam integer numways = testbench.dut.hart.lsu.dcache.NUMWAYS; + localparam integer blockbytelen = testbench.dut.hart.lsu.dcache.BLOCKBYTELEN; + localparam integer numwords = testbench.dut.hart.lsu.dcache.BLOCKLEN/`XLEN; + localparam integer lognumlines = $clog2(numlines); + localparam integer logblockbytelen = $clog2(blockbytelen); + localparam integer lognumways = $clog2(numways); + localparam integer tagstart = lognumlines + logblockbytelen; + + + + genvar index, way, cacheWord; + logic [`XLEN-1:0] CacheData [numways-1:0] [numlines-1:0] [numwords-1:0]; + logic [`XLEN-1:0] CacheTag [numways-1:0] [numlines-1:0] [numwords-1:0]; + logic CacheValid [numways-1:0] [numlines-1:0] [numwords-1:0]; + logic CacheDirty [numways-1:0] [numlines-1:0] [numwords-1:0]; + logic [`PA_BITS-1:0] CacheAdr [numways-1:0] [numlines-1:0] [numwords-1:0]; + genvar adr; + + logic [`XLEN-1:0] ShadowRAM[`TIM_BASE>>(1+`XLEN/32):(`TIM_RANGE+`TIM_BASE)>>1+(`XLEN/32)]; + + generate + for(index = 0; index < numlines; index++) begin + for(way = 0; way < numways; way++) begin + for(cacheWord = 0; cacheWord < numwords; cacheWord++) begin + copyShadow #(.tagstart(tagstart), + .logblockbytelen(logblockbytelen)) + copyShadow(.clk, + .start, + .tag(testbench.dut.hart.lsu.dcache.MemWay[way].CacheTagMem.StoredData[index]), + .valid(testbench.dut.hart.lsu.dcache.MemWay[way].ValidBits[index]), + .dirty(testbench.dut.hart.lsu.dcache.MemWay[way].DirtyBits[index]), + .data(testbench.dut.hart.lsu.dcache.MemWay[way].word[cacheWord].CacheDataMem.StoredData[index]), + .index(index), + .cacheWord(cacheWord), + .CacheData(CacheData[way][index][cacheWord]), + .CacheAdr(CacheAdr[way][index][cacheWord]), + .CacheTag(CacheTag[way][index][cacheWord]), + .CacheValid(CacheValid[way][index][cacheWord]), + .CacheDirty(CacheDirty[way][index][cacheWord])); + end + end + end + endgenerate + + integer i, j, k; + + always @(posedge clk) begin + if (start) begin #1 + #1 + for(i = 0; i < numlines; i++) begin + for(j = 0; j < numways; j++) begin + for(k = 0; k < numwords; k++) begin + if (CacheValid[j][i][k] && CacheDirty[j][i][k]) begin + ShadowRAM[CacheAdr[j][i][k] >> $clog2(`XLEN/8)] = CacheData[j][i][k]; + end + end + end + end + end + end + + + flop #(1) doneReg(.clk(clk), + .d(start), + .q(done)); + +endmodule + +module copyShadow + #(parameter tagstart, logblockbytelen) + (input logic clk, + input logic start, + input logic [`PA_BITS-1:tagstart] tag, + input logic valid, dirty, + input logic [`XLEN-1:0] data, + input logic [32-1:0] index, + input logic [32-1:0] cacheWord, + output logic [`XLEN-1:0] CacheData, + output logic [`PA_BITS-1:0] CacheAdr, + output logic [`XLEN-1:0] CacheTag, + output logic CacheValid, + output logic CacheDirty); + + + always_ff @(posedge clk) begin + if(start) begin + CacheTag = tag; + CacheValid = valid; + CacheDirty = dirty; + CacheData = data; + CacheAdr = (tag << tagstart) + (index << logblockbytelen) + (cacheWord << $clog2(`XLEN/8)); + end + end + +endmodule + diff --git a/wally-pipelined/testbench/testbench-imperas.sv b/wally-pipelined/testbench/testbench-imperas.sv index 38436752e..318140769 100644 --- a/wally-pipelined/testbench/testbench-imperas.sv +++ b/wally-pipelined/testbench/testbench-imperas.sv @@ -755,7 +755,7 @@ module riscvassertions(); assert (2**$clog2(`DCACHE_WAYSIZEINBYTES) == `DCACHE_WAYSIZEINBYTES) else $error("DCACHE_WAYSIZEINBYTES must be a power of 2"); assert (2**$clog2(`ICACHE_BLOCKLENINBITS) == `ICACHE_BLOCKLENINBITS) else $error("ICACHE_BLOCKLENINBITS must be a power of 2"); assert (2**$clog2(`ICACHE_WAYSIZEINBYTES) == `ICACHE_WAYSIZEINBYTES) else $error("ICACHE_WAYSIZEINBYTES must be a power of 2"); - assert (`ICACHE_NUMWAYS == 1 || `MEM_ICACHE == 0) else $error("Multiple Instruction Cache ways not yet implemented"); + assert (`ICACHE_NUMWAYS == 1 || `MEM_ICACHE == 0) else $warning("Multiple Instruction Cache ways not yet implemented"); assert (2**$clog2(`ITLB_ENTRIES) == `ITLB_ENTRIES) else $error("ITLB_ENTRIES must be a power of 2"); assert (2**$clog2(`DTLB_ENTRIES) == `DTLB_ENTRIES) else $error("DTLB_ENTRIES must be a power of 2"); assert (`TIM_RANGE >= 56'h07FFFFFF) else $error("Some regression tests will fail if TIM_RANGE is less than 56'h07FFFFFF");