From 8cc6657644925231cdabe2e68c602ee227c9a355 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Tue, 10 Oct 2023 17:46:12 -0500 Subject: [PATCH 1/6] Changed SDC outputs to ensure they are aligned to the falling edge of the divided down clock rather than the processor clock. --- fpga/src/axi_sdc_controller.v | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fpga/src/axi_sdc_controller.v b/fpga/src/axi_sdc_controller.v index 28994182d..c32a6a783 100644 --- a/fpga/src/axi_sdc_controller.v +++ b/fpga/src/axi_sdc_controller.v @@ -205,7 +205,7 @@ always @(posedge clock) reset_sync <= {reset_sync[1:0], !async_resetn}; reg [7:0] clock_cnt; -reg clock_state; +(* mark_debug = "true" *) reg clock_state; (* mark_debug = "true" *) reg clock_posedge; reg clock_data_in; wire fifo_almost_full; @@ -265,7 +265,7 @@ wire sd_dat_oe; // IOBUF IOBUF_dat2 (.O(sd_dat_i[2]), .IO(sdio_dat[2]), .I(sd_dat_reg_o[2]), .T(sd_dat_reg_t)); // IOBUF IOBUF_dat3 (.O(sd_dat_i[3]), .IO(sdio_dat[3]), .I(sd_dat_reg_o[3]), .T(sd_dat_reg_t)); -always @(negedge clock) begin +always @(negedge sdio_clk) begin // Output data delayed by 1/2 clock cycle (5ns) to ensure // required hold time: default speed - min 5ns, high speed - min 2ns (actual 5ns) if (sdio_reset) begin From 3d917f29d3f7766f1cd42e51ee4d2893c23926fc Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Tue, 10 Oct 2023 18:05:35 -0500 Subject: [PATCH 2/6] Fixed bug with flash script. --- linux/sdcard/flash-sd.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux/sdcard/flash-sd.sh b/linux/sdcard/flash-sd.sh index 9e00e0600..73c9e1b9e 100755 --- a/linux/sdcard/flash-sd.sh +++ b/linux/sdcard/flash-sd.sh @@ -56,7 +56,7 @@ done IMAGES=$BUILDROOT/output/images FW_JUMP=$IMAGES/fw_jump.bin LINUX_KERNEL=$IMAGES/Image -DEVICE_TREE=$IMAGES/$DEVICE_TREE +#DEVICE_TREE=$IMAGES/$DEVICE_TREE SDCARD=${ARGS[0]} From 4884f3d527f45be3bb0875fa5b254eca87292070 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Fri, 13 Oct 2023 12:30:21 -0500 Subject: [PATCH 3/6] Change to flash-sd.sh to fix relative path to device tree. --- linux/sdcard/flash-sd.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux/sdcard/flash-sd.sh b/linux/sdcard/flash-sd.sh index 9e00e0600..73c9e1b9e 100755 --- a/linux/sdcard/flash-sd.sh +++ b/linux/sdcard/flash-sd.sh @@ -56,7 +56,7 @@ done IMAGES=$BUILDROOT/output/images FW_JUMP=$IMAGES/fw_jump.bin LINUX_KERNEL=$IMAGES/Image -DEVICE_TREE=$IMAGES/$DEVICE_TREE +#DEVICE_TREE=$IMAGES/$DEVICE_TREE SDCARD=${ARGS[0]} From 63d6b1d1c86ceff30eef8be7b474b689106711f2 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Fri, 13 Oct 2023 14:08:17 -0500 Subject: [PATCH 4/6] Removed P.FPGA from testbench. --- testbench/testbench-xcelium.sv | 16 +++++++--------- testbench/testbench.sv | 22 ++++++++++------------ 2 files changed, 17 insertions(+), 21 deletions(-) diff --git a/testbench/testbench-xcelium.sv b/testbench/testbench-xcelium.sv index f50259ca8..89a7cc995 100644 --- a/testbench/testbench-xcelium.sv +++ b/testbench/testbench-xcelium.sv @@ -265,9 +265,7 @@ module testbench; // 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) - if(!P.FPGA) begin - updateProgramAddrLabelArray(ProgramAddrMapFile, ProgramLabelMapFile, ProgramAddrLabelArray); - end + updateProgramAddrLabelArray(ProgramAddrMapFile, ProgramLabelMapFile, ProgramAddrLabelArray); end //////////////////////////////////////////////////////////////////////////////// @@ -361,21 +359,21 @@ module testbench; //////////////////////////////////////////////////////////////////////////////// // load memories with program image //////////////////////////////////////////////////////////////////////////////// - if (P.FPGA) `define TB_FPGA // this is a gross hack for xcelium and verilator + if (P.SDC_SUPPORTED) `define TB_SDC_SUPPORTED // this is a gross hack for xcelium and verilator if (P.IROM_SUPPORTED) `define TB_IROM_SUPPORTED if (P.DTIM_SUPPORTED) `define TB_DTIM_SUPPORTED if (P.BUS_SUPPORTED) `define TB_BUS_SUPPORTED always @(posedge clk) begin if (LoadMem) begin - if (P.FPGA) begin - `ifdef TB_FPGA + if (P.SDC_SUPPORTED) begin + `ifdef TB_SDC_SUPPORTED string romfilename, sdcfilename; romfilename = {"../tests/custom/fpga-test-sdc/bin/fpga-test-sdc.memfile"}; sdcfilename = {"../testbench/sdc/ramdisk2.hex"}; - $readmemh(romfilename, dut.uncore.uncore.bootrom.bootrom.memory.ROM); - $readmemh(sdcfilename, sdcard.sdcard.FLASHmem); + //$readmemh(romfilename, dut.uncore.uncore.bootrom.bootrom.memory.ROM); + //$readmemh(sdcfilename, sdcard.sdcard.FLASHmem); // shorten sdc timers for simulation - dut.uncore.uncore.sdc.SDC.LimitTimers = 1; + //dut.uncore.uncore.sdc.SDC.LimitTimers = 1; `endif end else if (P.IROM_SUPPORTED) begin diff --git a/testbench/testbench.sv b/testbench/testbench.sv index 74077e547..8635a4920 100644 --- a/testbench/testbench.sv +++ b/testbench/testbench.sv @@ -37,9 +37,9 @@ module testbench; parameter DEBUG=0; parameter TEST="none"; parameter PrintHPMCounters=1; - parameter BPRED_LOGGER=0; - parameter I_CACHE_ADDR_LOGGER=0; - parameter D_CACHE_ADDR_LOGGER=0; + parameter BPRED_LOGGER=1; + parameter I_CACHE_ADDR_LOGGER=1; + parameter D_CACHE_ADDR_LOGGER=1; `include "parameter-defs.vh" @@ -260,9 +260,7 @@ module testbench; // 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) - if(!P.FPGA) begin - updateProgramAddrLabelArray(ProgramAddrMapFile, ProgramLabelMapFile, ProgramAddrLabelArray); - end + updateProgramAddrLabelArray(ProgramAddrMapFile, ProgramLabelMapFile, ProgramAddrLabelArray); end //////////////////////////////////////////////////////////////////////////////// @@ -344,14 +342,14 @@ module testbench; //////////////////////////////////////////////////////////////////////////////// always @(posedge clk) begin if (LoadMem) begin - if (P.FPGA) begin + if (P.SDC_SUPPORTED) begin string romfilename, sdcfilename; romfilename = {"../tests/custom/fpga-test-sdc/bin/fpga-test-sdc.memfile"}; sdcfilename = {"../testbench/sdc/ramdisk2.hex"}; - $readmemh(romfilename, dut.uncore.uncore.bootrom.bootrom.memory.ROM); - $readmemh(sdcfilename, sdcard.sdcard.FLASHmem); + //$readmemh(romfilename, dut.uncore.uncore.bootrom.bootrom.memory.ROM); + //$readmemh(sdcfilename, sdcard.sdcard.FLASHmem); // shorten sdc timers for simulation - dut.uncore.uncore.sdc.SDC.LimitTimers = 1; + //dut.uncore.uncore.sdc.SDC.LimitTimers = 1; end else if (P.IROM_SUPPORTED) $readmemh(memfilename, dut.core.ifu.irom.irom.rom.ROM); else if (P.BUS_SUPPORTED) $readmemh(memfilename, dut.uncore.uncore.ram.ram.memory.RAM); @@ -377,7 +375,7 @@ module testbench; assign {HRESPEXT, HRDATAEXT} = '0; end - if(P.FPGA) begin : sdcard + if(P.SDC_SUPPORTED) begin : sdcard // *** fix later /* -----\/----- EXCLUDED -----\/----- sdModel sdcard @@ -394,7 +392,7 @@ module testbench; assign SDCIntr = '0; end - wallypipelinedsoc #(P) dut(.clk, .reset_ext, .reset, .HRDATAEXT,.HREADYEXT, .HRESPEXT, .HSELEXT, .HSELEXTSDC, + 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); From 045b0adbbd49c6f2ea1440e174ddc0214542bba7 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Fri, 13 Oct 2023 14:56:45 -0500 Subject: [PATCH 5/6] Renamed testbench_imperas.sv to testbench-imperas.sv --- testbench/testbench-linux.sv | 2 +- testbench/testbench_imperas.sv | 369 --------------------------------- 2 files changed, 1 insertion(+), 370 deletions(-) delete mode 100644 testbench/testbench_imperas.sv diff --git a/testbench/testbench-linux.sv b/testbench/testbench-linux.sv index 683f55952..54cfc66e4 100644 --- a/testbench/testbench-linux.sv +++ b/testbench/testbench-linux.sv @@ -27,7 +27,7 @@ `include "config.vh" import cvw::*; -`define DEBUG_TRACE 0 +`define DEBUG_TRACE 1 // Debug Levels // 0: don't check against QEMU // 1: print disagreements with QEMU, but only halt on PCW disagreements diff --git a/testbench/testbench_imperas.sv b/testbench/testbench_imperas.sv deleted file mode 100644 index ac7e49a48..000000000 --- a/testbench/testbench_imperas.sv +++ /dev/null @@ -1,369 +0,0 @@ -/////////////////////////////////////////// -// testbench.sv -// -// Written: David_Harris@hmc.edu 9 January 2021 -// Modified: -// -// Purpose: Wally Testbench and helper modules -// Applies test programs from the riscv-arch-test and Imperas suites -// -// A component of the Wally configurable RISC-V project. -// -// Copyright (C) 2021 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. -//////////////////////////////////////////////////////////////////////////////////////////////// - -`include "config.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; - parameter DEBUG=0; - -`ifdef USE_IMPERAS_DV - import idvPkg::*; - import rvviApiPkg::*; - import idvApiPkg::*; -`endif - - `include "parameter-defs.vh" - - logic clk; - logic reset_ext, reset; - - - 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.XLEN-1:0] PCW; - - 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; - - logic SDCIntr; - - logic HREADY; - logic HSELEXT; - - logic InitializingMemories; - integer ResetCount, ResetThreshold; - logic InReset; - - // Imperas look here. - initial - begin - ResetCount = 0; - ResetThreshold = 2; - InReset = 1; - testadr = 0; - testadrNoBase = 0; - - if ($value$plusargs("testDir=%s", testDir)) begin - memfilename = {testDir, "/ref/ref.elf.memfile"}; - elffilename = {testDir, "/ref/ref.elf"}; - $display($sformatf("%m @ t=%0t: loading testDir %0s", $time, testDir)); - end else begin - $error("Must specify test directory using plusarg testDir"); - end - - if (P.BUS_SUPPORTED) $readmemh(memfilename, dut.uncore.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"}; - - // 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); - $display("Read memfile %s", memfilename); - - end - -`ifdef USE_IMPERAS_DV - - rvviTrace #(.XLEN(P.XLEN), .FLEN(P.FLEN)) rvvi(); - wallyTracer #(P) wallyTracer(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); - - initial begin - - 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)); - - 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.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!!!! - - end - - always @(dut.core.MTimerInt) void'(rvvi.net_push("MTimerInterrupt", dut.core.MTimerInt)); - always @(dut.core.MExtInt) void'(rvvi.net_push("MExternalInterrupt", dut.core.MExtInt)); - always @(dut.core.SExtInt) void'(rvvi.net_push("SExternalInterrupt", dut.core.SExtInt)); - always @(dut.core.MSwInt) void'(rvvi.net_push("MSWInterrupt", dut.core.MSwInt)); - always @(dut.core.priv.priv.csr.csrs.csrs.STimerInt) void'(rvvi.net_push("STimerInterrupt", dut.core.priv.priv.csr.csrs.csrs.STimerInt)); - - - final begin - void'(rvviRefShutdown()); - end - -`endif - - flopenr #(P.XLEN) PCWReg(clk, reset, ~dut.core.ieu.dp.StallW, dut.core.ifu.PCM, PCW); - flopenr #(32) InstrWReg(clk, reset, ~dut.core.ieu.dp.StallW, dut.core.ifu.InstrM, InstrW); - - // check assertions for a legal configuration - riscvassertions #(P) riscvassertions(); - - - // 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.FPGA) 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); - - // Track names of instructions - instrTrackerTB it(clk, reset, dut.core.ieu.dp.FlushE, - dut.core.ifu.InstrRawF[31:0], - dut.core.ifu.InstrD, dut.core.ifu.InstrE, - dut.core.ifu.InstrM, InstrW, - 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 - - // 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)) | - ((dut.core.ifu.InstrM == 32'h6f | dut.core.ifu.InstrM == 32'hfc32a423 | dut.core.ifu.InstrM == 32'hfc32a823) & dut.core.ieu.c.InstrValidM ) | - ((dut.core.lsu.IEUAdrM == ProgramAddrLabelArray["tohost"]) & InstrMName == "SW" ); - - DCacheFlushFSM #(P) DCacheFlushFSM(.clk(clk), - .reset(reset), - .start(DCacheFlushStart), - .done(DCacheFlushDone)); - - // 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]; - end - end - end - - watchdog #(P.XLEN, 1000000) watchdog(.clk, .reset); // check if PCW is stuck - -endmodule - - -/* verilator lint_on STMTDLY */ -/* verilator lint_on WIDTH */ - - -task automatic updateProgramAddrLabelArray; - input string ProgramAddrMapFile, ProgramLabelMapFile; - inout integer ProgramAddrLabelArray [string]; - // Gets the memory location of begin_signature - integer ProgramLabelMapFP, ProgramAddrMapFP; - ProgramLabelMapFP = $fopen(ProgramLabelMapFile, "r"); - ProgramAddrMapFP = $fopen(ProgramAddrMapFile, "r"); - - if (ProgramLabelMapFP & ProgramAddrMapFP) begin // check we found both files - while (!$feof(ProgramLabelMapFP)) begin - string label, adrstr; - integer returncode; - returncode = $fscanf(ProgramLabelMapFP, "%s\n", label); - returncode = $fscanf(ProgramAddrMapFP, "%s\n", adrstr); - if (ProgramAddrLabelArray.exists(label)) - ProgramAddrLabelArray[label] = adrstr.atohex(); - end - end - $fclose(ProgramLabelMapFP); - $fclose(ProgramAddrMapFP); -endtask - From 0a06effdcaafffe66c98487734519dc8c38a589c Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Fri, 13 Oct 2023 15:10:58 -0500 Subject: [PATCH 6/6] Added missing files. --- sim/wally-imperas.do | 2 +- testbench/testbench-imperas.sv | 369 +++++++++++++++++++++++++++++++++ 2 files changed, 370 insertions(+), 1 deletion(-) create mode 100644 testbench/testbench-imperas.sv diff --git a/sim/wally-imperas.do b/sim/wally-imperas.do index cc1c3845a..118e44d10 100644 --- a/sim/wally-imperas.do +++ b/sim/wally-imperas.do @@ -40,7 +40,7 @@ vlog +incdir+../config/$1 \ $env(IMPERAS_HOME)/ImpProprietary/source/host/idv/trace2cov.sv \ $env(IMPERAS_HOME)/ImpProprietary/source/host/idv/trace2bin.sv \ ../src/cvw.sv \ - ../testbench/testbench_imperas.sv \ + ../testbench/testbench-imperas.sv \ ../testbench/common/*.sv \ ../src/*/*.sv \ ../src/*/*/*.sv \ diff --git a/testbench/testbench-imperas.sv b/testbench/testbench-imperas.sv new file mode 100644 index 000000000..ac7e49a48 --- /dev/null +++ b/testbench/testbench-imperas.sv @@ -0,0 +1,369 @@ +/////////////////////////////////////////// +// testbench.sv +// +// Written: David_Harris@hmc.edu 9 January 2021 +// Modified: +// +// Purpose: Wally Testbench and helper modules +// Applies test programs from the riscv-arch-test and Imperas suites +// +// A component of the Wally configurable RISC-V project. +// +// Copyright (C) 2021 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. +//////////////////////////////////////////////////////////////////////////////////////////////// + +`include "config.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; + parameter DEBUG=0; + +`ifdef USE_IMPERAS_DV + import idvPkg::*; + import rvviApiPkg::*; + import idvApiPkg::*; +`endif + + `include "parameter-defs.vh" + + logic clk; + logic reset_ext, reset; + + + 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.XLEN-1:0] PCW; + + 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; + + logic SDCIntr; + + logic HREADY; + logic HSELEXT; + + logic InitializingMemories; + integer ResetCount, ResetThreshold; + logic InReset; + + // Imperas look here. + initial + begin + ResetCount = 0; + ResetThreshold = 2; + InReset = 1; + testadr = 0; + testadrNoBase = 0; + + if ($value$plusargs("testDir=%s", testDir)) begin + memfilename = {testDir, "/ref/ref.elf.memfile"}; + elffilename = {testDir, "/ref/ref.elf"}; + $display($sformatf("%m @ t=%0t: loading testDir %0s", $time, testDir)); + end else begin + $error("Must specify test directory using plusarg testDir"); + end + + if (P.BUS_SUPPORTED) $readmemh(memfilename, dut.uncore.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"}; + + // 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); + $display("Read memfile %s", memfilename); + + end + +`ifdef USE_IMPERAS_DV + + rvviTrace #(.XLEN(P.XLEN), .FLEN(P.FLEN)) rvvi(); + wallyTracer #(P) wallyTracer(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); + + initial begin + + 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)); + + 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.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!!!! + + end + + always @(dut.core.MTimerInt) void'(rvvi.net_push("MTimerInterrupt", dut.core.MTimerInt)); + always @(dut.core.MExtInt) void'(rvvi.net_push("MExternalInterrupt", dut.core.MExtInt)); + always @(dut.core.SExtInt) void'(rvvi.net_push("SExternalInterrupt", dut.core.SExtInt)); + always @(dut.core.MSwInt) void'(rvvi.net_push("MSWInterrupt", dut.core.MSwInt)); + always @(dut.core.priv.priv.csr.csrs.csrs.STimerInt) void'(rvvi.net_push("STimerInterrupt", dut.core.priv.priv.csr.csrs.csrs.STimerInt)); + + + final begin + void'(rvviRefShutdown()); + end + +`endif + + flopenr #(P.XLEN) PCWReg(clk, reset, ~dut.core.ieu.dp.StallW, dut.core.ifu.PCM, PCW); + flopenr #(32) InstrWReg(clk, reset, ~dut.core.ieu.dp.StallW, dut.core.ifu.InstrM, InstrW); + + // check assertions for a legal configuration + riscvassertions #(P) riscvassertions(); + + + // 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.FPGA) 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); + + // Track names of instructions + instrTrackerTB it(clk, reset, dut.core.ieu.dp.FlushE, + dut.core.ifu.InstrRawF[31:0], + dut.core.ifu.InstrD, dut.core.ifu.InstrE, + dut.core.ifu.InstrM, InstrW, + 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 + + // 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)) | + ((dut.core.ifu.InstrM == 32'h6f | dut.core.ifu.InstrM == 32'hfc32a423 | dut.core.ifu.InstrM == 32'hfc32a823) & dut.core.ieu.c.InstrValidM ) | + ((dut.core.lsu.IEUAdrM == ProgramAddrLabelArray["tohost"]) & InstrMName == "SW" ); + + DCacheFlushFSM #(P) DCacheFlushFSM(.clk(clk), + .reset(reset), + .start(DCacheFlushStart), + .done(DCacheFlushDone)); + + // 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]; + end + end + end + + watchdog #(P.XLEN, 1000000) watchdog(.clk, .reset); // check if PCW is stuck + +endmodule + + +/* verilator lint_on STMTDLY */ +/* verilator lint_on WIDTH */ + + +task automatic updateProgramAddrLabelArray; + input string ProgramAddrMapFile, ProgramLabelMapFile; + inout integer ProgramAddrLabelArray [string]; + // Gets the memory location of begin_signature + integer ProgramLabelMapFP, ProgramAddrMapFP; + ProgramLabelMapFP = $fopen(ProgramLabelMapFile, "r"); + ProgramAddrMapFP = $fopen(ProgramAddrMapFile, "r"); + + if (ProgramLabelMapFP & ProgramAddrMapFP) begin // check we found both files + while (!$feof(ProgramLabelMapFP)) begin + string label, adrstr; + integer returncode; + returncode = $fscanf(ProgramLabelMapFP, "%s\n", label); + returncode = $fscanf(ProgramAddrMapFP, "%s\n", adrstr); + if (ProgramAddrLabelArray.exists(label)) + ProgramAddrLabelArray[label] = adrstr.atohex(); + end + end + $fclose(ProgramLabelMapFP); + $fclose(ProgramAddrMapFP); +endtask +