From 0ed75a3ff511212ec92a764eb1f4f7d2d8816277 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Fri, 17 May 2024 16:48:29 -0500 Subject: [PATCH] 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