From 36b39358c6073e9bba4192431dbf49fa5fd6b874 Mon Sep 17 00:00:00 2001 From: bbracker Date: Sun, 24 Oct 2021 06:47:35 -0700 Subject: [PATCH] add checkpointing to linux testbench --- wally-pipelined/src/privileged/csr.sv | 3 +- wally-pipelined/src/privileged/csrc.sv | 3 +- wally-pipelined/src/privileged/csrsr.sv | 4 +- wally-pipelined/testbench/testbench-linux.sv | 191 +++++++++++++++++-- 4 files changed, 178 insertions(+), 23 deletions(-) diff --git a/wally-pipelined/src/privileged/csr.sv b/wally-pipelined/src/privileged/csr.sv index b995a3bb..a14c2c7a 100644 --- a/wally-pipelined/src/privileged/csr.sv +++ b/wally-pipelined/src/privileged/csr.sv @@ -63,7 +63,8 @@ module csr #(parameter output logic STATUS_MIE, STATUS_SIE, output logic STATUS_MXR, STATUS_SUM, STATUS_MPRV, STATUS_TW, output var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0], - output var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW [`PMP_ENTRIES-1:0], + output var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW[`PMP_ENTRIES-1:0], + input logic [4:0] SetFflagsM, output logic [2:0] FRM_REGW, // output logic [11:0] MIP_REGW, SIP_REGW, UIP_REGW, MIE_REGW, SIE_REGW, UIE_REGW, diff --git a/wally-pipelined/src/privileged/csrc.sv b/wally-pipelined/src/privileged/csrc.sv index 3b1e544d..e0148f29 100644 --- a/wally-pipelined/src/privileged/csrc.sv +++ b/wally-pipelined/src/privileged/csrc.sv @@ -103,7 +103,8 @@ module csrc #(parameter logic WriteCYCLEM, WriteINSTRETM; logic WriteHPMCOUNTER3M, WriteHPMCOUNTER4M; logic [4:0] CounterNumM; - logic [`COUNTERS-1:3][`XLEN-1:0] HPMCOUNTER_REGW, HPMCOUNTERH_REGW; + logic [`XLEN-1:0] HPMCOUNTER_REGW [`COUNTERS-1:3]; + logic [`XLEN-1:0] HPMCOUNTERH_REGW [`COUNTERS-1:3]; logic InstrValidNotFlushedM; assign InstrValidNotFlushedM = InstrValidM & ~StallW & ~FlushW; diff --git a/wally-pipelined/src/privileged/csrsr.sv b/wally-pipelined/src/privileged/csrsr.sv index dfa2132d..08bcea31 100644 --- a/wally-pipelined/src/privileged/csrsr.sv +++ b/wally-pipelined/src/privileged/csrsr.sv @@ -51,7 +51,7 @@ module csrsr ( // Lower privilege status registers are a subset of the full status register // *** consider adding MBE, SBE, UBE fields later from 20210108 draft spec generate - if (`XLEN==64) begin// RV64 + if (`XLEN==64) begin: csrsr64 // RV64 assign MSTATUS_REGW = {STATUS_SD, 27'b0, STATUS_SXL, STATUS_UXL, 9'b0, STATUS_TSR, STATUS_TW, STATUS_TVM, STATUS_MXR, STATUS_SUM, STATUS_MPRV, STATUS_XS, STATUS_FS, STATUS_MPP, 2'b0, @@ -67,7 +67,7 @@ module csrsr ( /* STATUS_XS, STATUS_FS, /*STATUS_MPP, 8'b0, */ /*STATUS_SPP, STATUS_MPIE, 1'b0 2'b0, STATUS_SPIE,*/ STATUS_UPIE, /*STATUS_MIE, 1'b0*/ 3'b0, /*STATUS_SIE, */STATUS_UIE}; - end else begin// RV32 + end else begin: csrsr32 // RV32 assign MSTATUS_REGW = {STATUS_SD, 8'b0, STATUS_TSR, STATUS_TW, STATUS_TVM, STATUS_MXR, STATUS_SUM, STATUS_MPRV, STATUS_XS, STATUS_FS, STATUS_MPP, 2'b0, diff --git a/wally-pipelined/testbench/testbench-linux.sv b/wally-pipelined/testbench/testbench-linux.sv index 76a1841b..06ad07fb 100644 --- a/wally-pipelined/testbench/testbench-linux.sv +++ b/wally-pipelined/testbench/testbench-linux.sv @@ -27,7 +27,7 @@ `include "wally-config.vh" -`define DEBUG_TRACE 0 +`define DEBUG_TRACE 2 // Debug Levels // 0: don't check against QEMU // 1: print disagreements with QEMU, but only halt on PCW disagreements @@ -35,10 +35,16 @@ // 3: halt on all disagreements with QEMU // 4: print memory accesses whenever they happen // 5: print everything +// +// uncomment the following line to activate checkpoint +`define CHECKPOINT 8500000 +`ifdef CHECKPOINT + `define CHECKPOINT_DIR {`LINUX_TEST_VECTORS, "checkpoint", `"`CHECKPOINT`", "/"} +`endif module testbench(); - - parameter waveOnICount = `BUSYBEAR*140000 + `BUILDROOT*8700000; // # of instructions at which to turn on waves in graphical sim + + parameter waveOnICount = `BUSYBEAR*140000 + `BUILDROOT*0; // # of instructions at which to turn on waves in graphical sim string ProgramAddrMapFile, ProgramLabelMapFile; /////////////////////////////////////////////////////////////////////////////// @@ -91,9 +97,8 @@ module testbench(); // Write Back trace signals logic checkInstrW; - //integer RegAdr; - integer fault; - logic TrapW; + integer fault; + logic TrapW; // Signals used to parse the trace file. logic checkInstrM; @@ -141,7 +146,6 @@ module testbench(); // ------ // Macros // ------ - `define CSRwarn(CSR) \ begin \ $display("CSR: %s = %016x, expected = %016x", ExpectedCSRArrayW[NumCSRPostWIndex], CSR, ExpectedCSRArrayValueW[NumCSRPostWIndex]); \ @@ -158,14 +162,21 @@ module testbench(); end initial begin - data_file_all = $fopen({`LINUX_TEST_VECTORS,"all.txt"}, "r"); - InstrCountW = '0; + `ifdef CHECKPOINT + data_file_all = $fopen({`CHECKPOINT_DIR,"all.txt"}, "r"); + `else + data_file_all = $fopen({`LINUX_TEST_VECTORS,"all.txt"}, "r"); + `endif + `ifdef CHECKPOINT + InstrCountW = `CHECKPOINT; + `else + InstrCountW = '0; + `endif force dut.hart.priv.SwIntM = 0; force dut.hart.priv.TimerIntM = 0; force dut.hart.priv.ExtIntM = 0; end - assign checkInstrM = dut.hart.ieu.InstrValidM & ~dut.hart.priv.trap.InstrPageFaultM & ~dut.hart.priv.trap.InterruptM & ~dut.hart.StallM; assign checkInstrW = dut.hart.ieu.InstrValidW & ~dut.hart.StallW; // trapW will already be invalid in there was an InstrPageFault in the previous instruction. @@ -345,7 +356,7 @@ module testbench(); end if (RegWriteW == "GPR") begin `checkEQ("Reg Write Address",dut.hart.ieu.dp.regf.a3,ExpectedRegAdrW) - $sprintf(name,"RF[%02d]",ExpectedRegAdrW); + $sformat(name,"RF[%02d]",ExpectedRegAdrW); `checkEQ(name, dut.hart.ieu.dp.regf.rf[ExpectedRegAdrW], ExpectedRegValueW) end if (MemOpW.substr(0,2) == "Mem") begin @@ -394,21 +405,163 @@ module testbench(); .ProgramLabelMapFile(ProgramLabelMapFile)); - /////////////////////////////////////////////////////////////////////////////// - //////////////////////////////// Testbench Core /////////////////////////////// - /////////////////////////////////////////////////////////////////////////////// - + /////////////////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////// Testbench Core ///////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////////////// // -------------- // Initialization // -------------- - initial - begin - reset <= 1; # 22; reset <= 0; + /*`ifdef CHECKPOINT + var [`XLEN-1:0] initRF[31:1]; + var [`COUNTERS-1:3][`XLEN-1:0] initHPMCOUNTER; + var [7:0][`PMP_ENTRIES-1:0] initPMPCFG; + var [`XLEN-1:0][`PMP_ENTRIES-1:0] initPMPADDR; + var initMIDELEG, initMCAUSE, initMCOUNTEREN, initMEDELEG, initMEPC, initMTVEC, initMIE, + initMIP, initMSCRATCH, initMSTATUS, initSCAUSE, initSSCRATCH, initSATP, initSCOUNTEREN, + initSEPC, initSTVEC; + + `endif*/ + `ifdef CHECKPOINT + `define RF dut.hart.ieu.dp.regf.rf + `define PC dut.hart.ifu.pcreg.q + `define CSR_BASE dut.hart.priv.csr.genblk1 + `define HPMCOUNTER `CSR_BASE.counters.genblk1.HPMCOUNTER_REGW + `define PMP_BASE `CSR_BASE.csrm.genblk4 + `define PMPCFG genblk2.PMPCFGreg.q + `define PMPADDR PMPADDRreg.q + `define MEDELEG `CSR_BASE.csrm.genblk1.MEDELEGreg.q + `define MIDELEG `CSR_BASE.csrm.genblk1.MIDELEGreg.q + `define MIE `CSR_BASE.csri.MIE_REGW + `define MIP `CSR_BASE.csri.MIP_REGW + `define MCAUSE `CSR_BASE.csrm.MCAUSEreg.q + `define SCAUSE `CSR_BASE.csrs.genblk1.SCAUSEreg.q + `define MEPC `CSR_BASE.csrm.MEPCreg.q + `define SEPC `CSR_BASE.csrs.genblk1.SEPCreg.q + `define MCOUNTEREN `CSR_BASE.csrm.genblk3.MCOUNTERENreg.q + `define SCOUNTEREN `CSR_BASE.csrs.genblk1.genblk3.SCOUNTERENreg.q + `define MSCRATCH `CSR_BASE.csrm.MSCRATCHreg.q + `define SSCRATCH `CSR_BASE.csrs.genblk1.SSCRATCHreg.q + `define MTVEC `CSR_BASE.csrm.MTVECreg.q + `define STVEC `CSR_BASE.csrs.genblk1.STVECreg.q + `define SATP `CSR_BASE.csrs.genblk1.genblk2.SATPreg.q + `define MSTATUS `CSR_BASE.csrsr.MSTATUS_REGW + `define STATUS_TSR `CSR_BASE.csrsr.STATUS_TSR_INT + `define STATUS_TW `CSR_BASE.csrsr.STATUS_TW_INT + `define STATUS_TVM `CSR_BASE.csrsr.STATUS_TVM_INT + `define STATUS_MXR `CSR_BASE.csrsr.STATUS_MXR_INT + `define STATUS_SUM `CSR_BASE.csrsr.STATUS_SUM_INT + `define STATUS_MPRV `CSR_BASE.csrsr.STATUS_MPRV_INT + `define STATUS_FS `CSR_BASE.csrsr.STATUS_FS_INT + `define STATUS_MPP `CSR_BASE.csrsr.STATUS_MPP + `define STATUS_SPP `CSR_BASE.csrsr.STATUS_SPP + `define STATUS_MPIE `CSR_BASE.csrsr.STATUS_MPIE + `define STATUS_SPIE `CSR_BASE.csrsr.STATUS_SPIE + `define STATUS_UPIE `CSR_BASE.csrsr.STATUS_UPIE + `define STATUS_MIE `CSR_BASE.csrsr.STATUS_MIE + `define STATUS_SIE `CSR_BASE.csrsr.STATUS_SIE + `define STATUS_UIE `CSR_BASE.csrsr.STATUS_UIE + `define CURR_PRIV dut.hart.priv.privmodereg.q + `define INSTRET dut.hart.priv.csr.genblk1.counters.genblk1.genblk2.INSTRETreg.q + + `define INIT_CHECKPOINT_VAL(SIGNAL_BASE,SIGNAL,DIM,LARGE_INDEX,SMALL_INDEX) \ + logic DIM init``SIGNAL [LARGE_INDEX:SMALL_INDEX]; \ + initial $readmemh({`CHECKPOINT_DIR,"checkpoint-",`"SIGNAL`"}, init``SIGNAL); \ + for (i=SMALL_INDEX; i> 3); - $readmemh({`LINUX_TEST_VECTORS,"ram.txt"}, dut.uncore.dtim.RAM); + `ifdef CHECKPOINT + $readmemh({`CHECKPOINT_DIR,"ram.txt"}, dut.uncore.dtim.RAM); + `else + + $readmemh({`LINUX_TEST_VECTORS,"ram.txt"}, dut.uncore.dtim.RAM); + `endif $readmemb(`TWO_BIT_PRELOAD, dut.hart.ifu.bpred.bpred.Predictor.DirPredictor.PHT.memory); $readmemb(`BTB_PRELOAD, dut.hart.ifu.bpred.bpred.TargetPredictor.memory.memory); ProgramAddrMapFile = {`LINUX_TEST_VECTORS,"vmlinux.objdump.addr"};