mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-02 17:55:19 +00:00
Major cleanup of testbench.
This commit is contained in:
parent
87fb9a3e16
commit
af046d4772
@ -87,8 +87,6 @@ module testbench;
|
||||
logic Validate;
|
||||
logic SelectTest;
|
||||
|
||||
// check assertions for a legal configuration
|
||||
riscvassertions #(P) riscvassertions();
|
||||
|
||||
// pick tests based on modes supported
|
||||
initial begin
|
||||
@ -204,89 +202,52 @@ module testbench;
|
||||
if (TestBenchReset) CurrState <= #1 STATE_TESTBENCH_RESET;
|
||||
else CurrState <= #1 NextState;
|
||||
|
||||
|
||||
// fsm next state logic
|
||||
always_comb begin
|
||||
reset_ext = 0;
|
||||
ResetMem = 0;
|
||||
LoadMem = 0;
|
||||
ResetCntEn = 0;
|
||||
ResetCntRst = 0;
|
||||
Validate = 0;
|
||||
SelectTest = 0;
|
||||
// riscof tests have a different signature, tests[0] == "1" refers to RiscvArchTests
|
||||
// and tests[0] == "2" refers to WallyRiscvArchTests
|
||||
riscofTest = tests[0] == "1" | tests[0] == "2";
|
||||
pathname = tvpaths[tests[0].atoi()];
|
||||
|
||||
case(CurrState)
|
||||
STATE_TESTBENCH_RESET: begin
|
||||
NextState = STATE_INIT_TEST;
|
||||
reset_ext = 1;
|
||||
end
|
||||
STATE_INIT_TEST: begin
|
||||
NextState = STATE_RESET_MEMORIES;
|
||||
ResetCntRst = 1;
|
||||
SelectTest = 1;
|
||||
reset_ext = 1;
|
||||
end
|
||||
STATE_RESET_MEMORIES: begin
|
||||
NextState = STATE_RESET_MEMORIES2;
|
||||
reset_ext = 1;
|
||||
if (TEST == "coremark") ResetMem = 1; // this initialization is very expensive, only do it for coremark.
|
||||
end
|
||||
STATE_RESET_MEMORIES2: begin // Give the reset enough time to ensure the bus is reset before loading the memories.
|
||||
NextState = STATE_LOAD_MEMORIES;
|
||||
reset_ext = 1;
|
||||
// this initialization is very expensive, only do it for coremark.
|
||||
if (TEST == "coremark") ResetMem = 1;
|
||||
end
|
||||
STATE_LOAD_MEMORIES: begin
|
||||
NextState = STATE_RESET_TEST;
|
||||
reset_ext = 1;
|
||||
LoadMem = 1;
|
||||
end
|
||||
STATE_RESET_TEST: begin
|
||||
reset_ext = 1;
|
||||
ResetCntEn = 1;
|
||||
if(ResetCount < ResetThreshold) begin
|
||||
NextState = STATE_RESET_TEST;
|
||||
end else begin
|
||||
NextState = STATE_RUN_TEST;
|
||||
end
|
||||
end
|
||||
STATE_RUN_TEST:
|
||||
if(DCacheFlushStart) begin
|
||||
NextState = STATE_CHECK_TEST;
|
||||
end else begin
|
||||
NextState = STATE_RUN_TEST;
|
||||
end
|
||||
STATE_CHECK_TEST: begin
|
||||
if (DCacheFlushDone) begin
|
||||
NextState = STATE_VALIDATE;
|
||||
end else begin
|
||||
NextState = STATE_CHECK_TEST_WAIT;
|
||||
end
|
||||
end
|
||||
STATE_CHECK_TEST_WAIT: begin
|
||||
if(DCacheFlushDone) begin
|
||||
NextState = STATE_VALIDATE;
|
||||
end else begin
|
||||
NextState = STATE_CHECK_TEST_WAIT;
|
||||
end
|
||||
end
|
||||
STATE_VALIDATE: begin
|
||||
NextState = STATE_INIT_TEST;
|
||||
Validate = '1;
|
||||
end
|
||||
STATE_INCR_TEST: begin
|
||||
NextState = STATE_INIT_TEST;
|
||||
end
|
||||
default: NextState = STATE_TESTBENCH_RESET;
|
||||
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(ResetCount < ResetThreshold) NextState = STATE_RESET_TEST;
|
||||
else NextState = STATE_RUN_TEST;
|
||||
STATE_RUN_TEST: if(DCacheFlushStart) NextState = STATE_CHECK_TEST;
|
||||
else NextState = STATE_RUN_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) & TEST == "coremark";
|
||||
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;
|
||||
|
||||
// fsm reset counter
|
||||
counter #(3) RstCounter(clk, ResetCntRst, ResetCntEn, ResetCount);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Find the test vector files and populate the PC to function label converter
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
assign begin_signature_addr = ProgramAddrLabelArray["begin_signature"];
|
||||
always @(posedge clk) begin
|
||||
|
||||
if(SelectTest) begin
|
||||
if (riscofTest) memfilename = {pathname, tests[test], "/ref/ref.elf.memfile"};
|
||||
else memfilename = {pathname, tests[test], ".elf.memfile"};
|
||||
@ -305,14 +266,17 @@ module testbench;
|
||||
end
|
||||
end
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Verify the test ran correctly by checking the memory against a known signature.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
if(TestBenchReset) test = 1;
|
||||
if (TEST == "coremark")
|
||||
if (dut.core.EcallFaultM) begin
|
||||
$display("Benchmark: coremark is done.");
|
||||
$stop;
|
||||
end
|
||||
if(Validate) begin
|
||||
if (TEST == "coremark")
|
||||
if (dut.core.EcallFaultM) begin
|
||||
$display("Benchmark: coremark is done.");
|
||||
$stop;
|
||||
end
|
||||
else if (TEST == "embench") begin
|
||||
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.
|
||||
@ -347,13 +311,10 @@ module testbench;
|
||||
end
|
||||
end
|
||||
|
||||
counter #(3) RstCounter(clk, ResetCntRst, ResetCntEn, ResetCount);
|
||||
assign begin_signature_addr = ProgramAddrLabelArray["begin_signature"];
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Some memories are not reset, but should be zeros or set to some initial value for simulation
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
integer adrindex;
|
||||
always @(posedge clk) begin
|
||||
if (ResetMem) // program memory is sometimes reset
|
||||
@ -394,8 +355,11 @@ module testbench;
|
||||
$display("Read memfile %s", memfilename);
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Actual hardware
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// instantiate device to be tested
|
||||
assign GPIOIN = 0;
|
||||
assign UARTSin = 1;
|
||||
@ -403,12 +367,10 @@ module testbench;
|
||||
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);
|
||||
.HREADRam(HRDATAEXT), .HREADYRam(HREADYEXT), .HRESPRam(HRESPEXT), .HREADY, .HWSTRB);
|
||||
end else begin
|
||||
assign HREADYEXT = 1;
|
||||
assign HRESPEXT = 0;
|
||||
assign HRDATAEXT = 0;
|
||||
assign {HRESPEXT, HRDATAEXT} = '0;
|
||||
end
|
||||
|
||||
if(P.FPGA) begin : sdcard
|
||||
@ -426,9 +388,29 @@ module testbench;
|
||||
end
|
||||
|
||||
wallypipelinedsoc #(P) dut(.clk, .reset_ext, .reset, .HRDATAEXT,.HREADYEXT, .HRESPEXT,.HSELEXT,
|
||||
.HCLK, .HRESETn, .HADDR, .HWDATA, .HWSTRB, .HWRITE, .HSIZE, .HBURST, .HPROT,
|
||||
.HTRANS, .HMASTLOCK, .HREADY, .TIMECLK(1'b0), .GPIOIN, .GPIOOUT, .GPIOEN,
|
||||
.UARTSin, .UARTSout, .SDCCmdIn, .SDCCmdOut, .SDCCmdOE, .SDCDatIn, .SDCCLK);
|
||||
.HCLK, .HRESETn, .HADDR, .HWDATA, .HWSTRB, .HWRITE, .HSIZE, .HBURST, .HPROT,
|
||||
.HTRANS, .HMASTLOCK, .HREADY, .TIMECLK(1'b0), .GPIOIN, .GPIOOUT, .GPIOEN,
|
||||
.UARTSin, .UARTSout, .SDCCmdIn, .SDCCmdOut, .SDCCmdOE, .SDCDatIn, .SDCCLK);
|
||||
|
||||
// generate clock to sequence tests
|
||||
always begin
|
||||
clk = 1; # 5; clk = 0; # 5;
|
||||
end
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Support logic
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
watchdog #(P.XLEN, 1000000) watchdog(.clk, .reset); // check if PCW is stuck
|
||||
riscvassertions #(P) riscvassertions(); // check assertions for a legal configuration
|
||||
loggers #(P, TEST, PrintHPMCounters, I_CACHE_ADDR_LOGGER, D_CACHE_ADDR_LOGGER, BPRED_LOGGER)
|
||||
loggers (clk, reset, DCacheFlushStart, DCacheFlushDone, memfilename);
|
||||
|
||||
// track the current function or global label
|
||||
if (DEBUG == 1 | (PrintHPMCounters & P.ZICOUNTERS_SUPPORTED)) begin : FunctionName
|
||||
FunctionName #(P) FunctionName(.reset(reset_ext | TestBenchReset),
|
||||
.clk(clk), .ProgramAddrMapFile(ProgramAddrMapFile), .ProgramLabelMapFile(ProgramLabelMapFile));
|
||||
end
|
||||
|
||||
// Track names of instructions
|
||||
string InstrFName, InstrDName, InstrEName, InstrMName, InstrWName;
|
||||
@ -440,22 +422,6 @@ module testbench;
|
||||
dut.core.ifu.InstrM, InstrW,
|
||||
InstrFName, InstrDName, InstrEName, InstrMName, InstrWName);
|
||||
|
||||
// generate clock to sequence tests
|
||||
always
|
||||
begin
|
||||
clk = 1; # 5; clk = 0; # 5;
|
||||
// if ($time % 100000 == 0) $display("Time is %0t", $time);
|
||||
end
|
||||
|
||||
|
||||
// track the current function or global label
|
||||
if (DEBUG == 1 | (PrintHPMCounters & P.ZICOUNTERS_SUPPORTED)) begin : FunctionName
|
||||
FunctionName #(P) FunctionName(.reset(reset_ext | TestBenchReset),
|
||||
.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
|
||||
@ -472,14 +438,7 @@ module testbench;
|
||||
((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));
|
||||
|
||||
watchdog #(P.XLEN, 1000000) watchdog(.clk, .reset);
|
||||
loggers #(P, TEST, PrintHPMCounters, I_CACHE_ADDR_LOGGER, D_CACHE_ADDR_LOGGER, BPRED_LOGGER)
|
||||
loggers (clk, reset, DCacheFlushStart, DCacheFlushDone, memfilename);
|
||||
DCacheFlushFSM #(P) DCacheFlushFSM(.clk(clk), .reset(reset), .start(DCacheFlushStart), .done(DCacheFlushDone));
|
||||
|
||||
task automatic CheckSignature;
|
||||
// This task must be declared inside this module as it needs access to parameter P. There is
|
||||
|
Loading…
Reference in New Issue
Block a user