some linux testbench cleanup

This commit is contained in:
bbracker 2021-10-25 10:04:30 -07:00
parent 9fdfc750eb
commit 9b98a499d7

View File

@ -43,17 +43,23 @@
`endif
module testbench();
///////////////////////////////////////////////////////////////////////////////
/////////////////////////////////// CONFIG ////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
parameter INSTR_LIMIT = 0; // # of instructions at which to stop
parameter INSTR_WAVEON = (INSTR_LIMIT > 10000) ? INSTR_LIMIT-10000 : 1; // # of instructions at which to turn on waves in graphical sim
string ProgramAddrMapFile, ProgramLabelMapFile;
parameter INSTR_WAVEON = 8.7e6;//(INSTR_LIMIT > 10000) ? INSTR_LIMIT-10000 : 1; // # of instructions at which to turn on waves in graphical sim
//parameter CHECKPOINT = 0;
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////// DUT /////////////////////////////////////
////////////////////////////////// HARDWARE ///////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
logic clk, reset;
logic [`AHBW-1:0] readDataExpected;
logic clk, reset;
initial begin reset <= 1; # 22; reset <= 0; end
always begin clk <= 1; # 5; clk <= 0; # 5; end
logic [`AHBW-1:0] HRDATAEXT;
logic HREADYEXT, HRESPEXT;
logic HCLK, HRESETn;
logic [31:0] HADDR;
logic [`AHBW-1:0] HWDATA;
logic HWRITE;
@ -62,50 +68,44 @@ module testbench();
logic [3:0] HPROT;
logic [1:0] HTRANS;
logic HMASTLOCK;
logic HCLK, HRESETn;
logic [`AHBW-1:0] HRDATAEXT;
logic HREADYEXT, HRESPEXT;
logic [31:0] GPIOPinsIn;
logic [31:0] GPIOPinsOut, GPIOPinsEn;
logic UARTSin, UARTSout;
logic UARTSin;
logic UARTSout;
assign GPIOPinsIn = 0;
assign UARTSin = 1;
wallypipelinedsoc dut(.clk, .reset,
.HRDATAEXT, .HREADYEXT, .HRESPEXT, .HCLK, .HRESETn, .HADDR,
.HWDATA, .HWRITE, .HSIZE, .HBURST, .HPROT, .HTRANS, .HMASTLOCK,
.GPIOPinsIn, .GPIOPinsOut, .GPIOPinsEn,
.UARTSin, .UARTSout);
wallypipelinedsoc dut(.*);
// Write Back stage signals not needed by Wally itself
logic [`XLEN-1:0] PCW;
logic [31:0] InstrW;
logic InstrValidW;
logic [`XLEN-1:0] MemAdrW, WriteDataW;
logic TrapW;
`define FLUSHW dut.hart.FlushW
`define STALLW dut.hart.StallW
flopenrc #(`XLEN) PCWReg(clk, reset, `FLUSHW, ~`STALLW, dut.hart.ifu.PCM, PCW);
flopenr #(32) InstrWReg(clk, reset, ~`STALLW, `FLUSHW ? nop : dut.hart.ifu.InstrM, InstrW);
flopenrc #(1) controlregW(clk, reset, `FLUSHW, ~`STALLW, dut.hart.ieu.c.InstrValidM, InstrValidW);
flopenrc #(`XLEN) MemAdrWReg(clk, reset, `FLUSHW, ~`STALLW, dut.hart.ieu.dp.MemAdrM, MemAdrW);
flopenrc #(`XLEN) WriteDataWReg(clk, reset, `FLUSHW, ~`STALLW, dut.hart.WriteDataM, WriteDataW);
flopenr #(1) TrapWReg(clk, reset, ~`STALLW, dut.hart.hzu.TrapM, TrapW);
///////////////////////////////////////////////////////////////////////////////
//////////////////////// Signals & Shared Macros ///////////////////////////
//////////////////////// AKA stuff that comes first ///////////////////////////
//////////////////////// Signals & Macro DECLARATIONS /////////////////////////
///////////////////////////////////////////////////////////////////////////////
// Sorry if these have gotten decontextualized.
// Verilog expects them to be defined before they are used.
// -------------------
// Signal Declarations
// -------------------
// Testbench Core
integer warningCount = 0;
integer errorCount = 0;
integer MIPexpected;
// P, Instr Checking
integer data_file_all;
string name;
// Write Back stage signals needed for trace compare, but don't actually
// exist in CPU.
logic [`XLEN-1:0] MemAdrW, WriteDataW;
logic [`XLEN-1:0] PCW;
logic [31:0] InstrW;
logic InstrValidW;
// Write Back trace signals
logic checkInstrW;
integer fault;
logic TrapW;
// Signals used to parse the trace file.
logic checkInstrM;
integer fault;
string ProgramAddrMapFile, ProgramLabelMapFile;
// Signals used to parse the trace file
integer data_file_all;
string name;
integer matchCount;
string line;
logic [`XLEN-1:0] ExpectedPCM;
@ -118,8 +118,9 @@ module testbench();
integer TokenIndex;
integer MarkerIndex;
integer NumCSRM;
// Memory stage expected values from trace
logic checkInstrM;
integer MIPexpected;
string RegWriteM;
integer ExpectedRegAdrM;
logic [`XLEN-1:0] ExpectedRegValueM;
@ -127,8 +128,9 @@ module testbench();
logic [`XLEN-1:0] ExpectedMemAdrM, ExpectedMemReadDataM, ExpectedMemWriteDataM;
string ExpectedCSRArrayM[10:0];
logic [`XLEN-1:0] ExpectedCSRArrayValueM[10:0];
logic [`AHBW-1:0] readDataExpected;
// Write back stage expected values from trace
logic checkInstrW;
logic [`XLEN-1:0] ExpectedPCW;
logic [31:0] ExpectedInstrW;
string textW;
@ -147,26 +149,75 @@ module testbench();
integer NumCSRPostWIndex;
logic [`XLEN-1:0] InstrCountW;
integer RequestDelayedMIP;
// ------
// Macros
// ------
`define CSRwarn(CSR) \
// Useful Aliases
`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
// Common Macros
`define checkCSR(CSR) \
begin \
$display("CSR: %s = %016x, expected = %016x", ExpectedCSRArrayW[NumCSRPostWIndex], CSR, ExpectedCSRArrayValueW[NumCSRPostWIndex]); \
if (CSR != ExpectedCSRArrayValueW[NumCSRPostWIndex]) begin \
$display("%tns, %d instrs: CSR %s = %016x, does not equal expected value %016x", $time, InstrCountW, ExpectedCSRArrayW[NumCSRPostWIndex], CSR, ExpectedCSRArrayValueW[NumCSRPostWIndex]); \
if(`DEBUG_TRACE >= 3) fault = 1; \
end \
end
`define checkEQ(NAME, VAL, EXPECTED) \
if(VAL != EXPECTED) begin \
$display("%tns, %d instrs: %s %x differs from expected %x", $time, InstrCountW, NAME, VAL, EXPECTED); \
if ((NAME == "PCW") || (`DEBUG_TRACE >= 2)) fault = 1; \
end
///////////////////////////////////////////////////////////////////////////////
/////////////////////////////// INITIALIZATION ////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
initial begin
$readmemh({`LINUX_TEST_VECTORS,"bootmem.txt"}, dut.uncore.bootdtim.bootdtim.RAM, 'h1000 >> 3);
`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.mem);
$readmemb(`BTB_PRELOAD, dut.hart.ifu.bpred.bpred.TargetPredictor.memory.mem);
ProgramAddrMapFile = {`LINUX_TEST_VECTORS,"vmlinux.objdump.addr"};
ProgramLabelMapFile = {`LINUX_TEST_VECTORS,"vmlinux.objdump.lab"};
`ifdef CHECKPOINT
data_file_all = $fopen({`CHECKPOINT_DIR,"all.txt"}, "r");
`else
@ -182,19 +233,9 @@ module testbench();
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 = InstrValidW & ~dut.hart.StallW; // trapW will already be invalid in there was an InstrPageFault in the previous instruction.
// Additonal W stage registers
`define FLUSHW dut.hart.FlushW
`define STALLW dut.hart.StallW
flopenr #(32) InstrWReg(clk, reset, ~`STALLW, `FLUSHW ? nop : dut.hart.ifu.InstrM, InstrW);
flopenrc #(`XLEN) MemAdrWReg(clk, reset, `FLUSHW, ~`STALLW, dut.hart.ieu.dp.MemAdrM, MemAdrW);
flopenrc #(`XLEN) WriteDataWReg(clk, reset, `FLUSHW, ~`STALLW, dut.hart.WriteDataM, WriteDataW);
flopenrc #(`XLEN) PCWReg(clk, reset, `FLUSHW, ~`STALLW, dut.hart.ifu.PCM, PCW);
flopenr #(1) TrapWReg(clk, reset, ~`STALLW, dut.hart.hzu.TrapM, TrapW);
flopenrc #(5) controlregW(clk, reset, `FLUSHW, ~`STALLW, dut.hart.ieu.c.InstrValidM, InstrValidW);
///////////////////////////////////////////////////////////////////////////////
//////////////////////////////////// CORE /////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// Because qemu does not match exactly to wally it is necessary to read the the
// trace in the memory stage and detect if anything in wally must be overwritten.
// This includes mtimer, interrupts, and various bits in mstatus and xtval.
@ -203,6 +244,7 @@ module testbench();
// on the next falling edge the expected state is compared to the wally state.
// step 0: read the expected state
assign checkInstrM = dut.hart.ieu.InstrValidM & ~dut.hart.priv.trap.InstrPageFaultM & ~dut.hart.priv.trap.InterruptM & ~dut.hart.StallM;
always @(negedge clk) begin
// always check PC, instruction bits
if (checkInstrM) begin
@ -352,6 +394,7 @@ module testbench();
end
// step2: make all checks in the write back stage.
assign checkInstrW = InstrValidW & ~dut.hart.StallW; // trapW will already be invalid in there was an InstrPageFault in the previous instruction.
always @(negedge clk) begin
if(RequestDelayedMIP) begin
$display("%tns: Updating MIP to %x",$time,ExpectedCSRArrayValueW[NumCSRM]);
@ -371,7 +414,8 @@ module testbench();
fault = 0;
if (`DEBUG_TRACE >= 1) begin
`checkEQ("PCW",PCW,ExpectedPCW)
`checkEQ("InstrW",InstrW,ExpectedInstrW)
//`checkEQ("InstrW",InstrW,ExpectedInstrW) <-- not viable because of
// compressed to uncompressed conversion
`checkEQ("Instr Count",dut.hart.priv.csr.genblk1.counters.genblk1.INSTRET_REGW,InstrCountW)
#2; // delay 2 ns.
if(`DEBUG_TRACE >= 5) begin
@ -397,19 +441,19 @@ module testbench();
// check csr
for(NumCSRPostWIndex = 0; NumCSRPostWIndex < NumCSRW; NumCSRPostWIndex++) begin
case(ExpectedCSRArrayW[NumCSRPostWIndex])
"mhartid": `CSRwarn(dut.hart.priv.csr.genblk1.csrm.MHARTID_REGW)
"mstatus": `CSRwarn(dut.hart.priv.csr.genblk1.csrm.MSTATUS_REGW)
"mtvec": `CSRwarn(dut.hart.priv.csr.genblk1.csrm.MTVEC_REGW)
"mip": `CSRwarn(dut.hart.priv.csr.genblk1.csrm.MIP_REGW)
"mie": `CSRwarn(dut.hart.priv.csr.genblk1.csrm.MIE_REGW)
"mideleg":`CSRwarn(dut.hart.priv.csr.genblk1.csrm.MIDELEG_REGW)
"medeleg": `CSRwarn(dut.hart.priv.csr.genblk1.csrm.MEDELEG_REGW)
"mepc": `CSRwarn(dut.hart.priv.csr.genblk1.csrm.MEPC_REGW)
"mtval": `CSRwarn(dut.hart.priv.csr.genblk1.csrm.MTVAL_REGW)
"sepc": `CSRwarn(dut.hart.priv.csr.genblk1.csrs.SEPC_REGW)
"scause": `CSRwarn(dut.hart.priv.csr.genblk1.csrs.genblk1.SCAUSE_REGW)
"stvec": `CSRwarn(dut.hart.priv.csr.genblk1.csrs.STVEC_REGW)
"stval": `CSRwarn(dut.hart.priv.csr.genblk1.csrs.genblk1.STVAL_REGW)
"mhartid": `checkCSR(dut.hart.priv.csr.genblk1.csrm.MHARTID_REGW)
"mstatus": `checkCSR(dut.hart.priv.csr.genblk1.csrm.MSTATUS_REGW)
"mtvec": `checkCSR(dut.hart.priv.csr.genblk1.csrm.MTVEC_REGW)
"mip": `checkCSR(dut.hart.priv.csr.genblk1.csrm.MIP_REGW)
"mie": `checkCSR(dut.hart.priv.csr.genblk1.csrm.MIE_REGW)
"mideleg": `checkCSR(dut.hart.priv.csr.genblk1.csrm.MIDELEG_REGW)
"medeleg": `checkCSR(dut.hart.priv.csr.genblk1.csrm.MEDELEG_REGW)
"mepc": `checkCSR(dut.hart.priv.csr.genblk1.csrm.MEPC_REGW)
"mtval": `checkCSR(dut.hart.priv.csr.genblk1.csrm.MTVAL_REGW)
"sepc": `checkCSR(dut.hart.priv.csr.genblk1.csrs.SEPC_REGW)
"scause": `checkCSR(dut.hart.priv.csr.genblk1.csrs.genblk1.SCAUSE_REGW)
"stvec": `checkCSR(dut.hart.priv.csr.genblk1.csrs.STVEC_REGW)
"stval": `checkCSR(dut.hart.priv.csr.genblk1.csrs.genblk1.STVAL_REGW)
endcase
end
if (fault == 1) begin
@ -429,63 +473,7 @@ module testbench();
.ProgramLabelMapFile(ProgramLabelMapFile));
///////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////// Testbench Core /////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
// --------------
// Initialization
// --------------
/*`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]; \
@ -573,36 +561,10 @@ module testbench();
`endif
initial begin
reset <= 1; # 22; reset <= 0;
$stop;
end
// initial loading of memories
initial begin
$readmemh({`LINUX_TEST_VECTORS,"bootmem.txt"}, dut.uncore.bootdtim.bootdtim.RAM, 'h1000 >> 3);
`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.mem);
$readmemb(`BTB_PRELOAD, dut.hart.ifu.bpred.bpred.TargetPredictor.memory.mem);
ProgramAddrMapFile = {`LINUX_TEST_VECTORS,"vmlinux.objdump.addr"};
ProgramLabelMapFile = {`LINUX_TEST_VECTORS,"vmlinux.objdump.lab"};
end
// -------
// Running
// -------
always
begin
clk <= 1; # 5; clk <= 0; # 5;
end
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////// Miscellaneous ///////////////////////////////
//////////////////////////////// Extra Features ///////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// Instr Opcode Tracking
// For waveview convenience