Updated testbenches to capture InstrM because it may be optimized out of IFU

This commit is contained in:
David Harris 2023-11-03 05:24:15 -07:00
parent 9b7f385c50
commit 0b35c2ea56
6 changed files with 47 additions and 20 deletions

View File

@ -388,14 +388,14 @@ module ifu import cvw::*; #(parameter cvw_t P) (
// Instruction and PC pipeline registers flush to NOP, not zero // Instruction and PC pipeline registers flush to NOP, not zero
mux2 #(32) FlushInstrEMux(InstrD, nop, FlushE, NextInstrD); mux2 #(32) FlushInstrEMux(InstrD, nop, FlushE, NextInstrD);
mux2 #(32) FlushInstrMMux(InstrE, nop, FlushM, NextInstrE);
flopenr #(32) InstrEReg(clk, reset, ~StallE, NextInstrD, InstrE); flopenr #(32) InstrEReg(clk, reset, ~StallE, NextInstrD, InstrE);
flopenr #(P.XLEN) PCEReg(clk, reset, ~StallE, PCD, PCE); flopenr #(P.XLEN) PCEReg(clk, reset, ~StallE, PCD, PCE);
// InstrM is only needed with CSRs or atomic operations // InstrM is only needed with CSRs or atomic operations
if (P.ZICSR_SUPPORTED | P.A_SUPPORTED | 1) if (P.ZICSR_SUPPORTED | P.A_SUPPORTED) begin
mux2 #(32) FlushInstrMMux(InstrE, nop, FlushM, NextInstrE);
flopenr #(32) InstrMReg(clk, reset, ~StallM, NextInstrE, InstrM); flopenr #(32) InstrMReg(clk, reset, ~StallM, NextInstrE, InstrM);
else assign InstrM = 0; end else assign InstrM = 0;
// PCM is only needed with CSRs or branch prediction // PCM is only needed with CSRs or branch prediction
if (P.ZICSR_SUPPORTED | P.BPRED_SUPPORTED) if (P.ZICSR_SUPPORTED | P.BPRED_SUPPORTED)
flopenr #(P.XLEN) PCMReg(clk, reset, ~StallM, PCE, PCM); flopenr #(P.XLEN) PCMReg(clk, reset, ~StallM, PCE, PCM);

View File

@ -214,7 +214,7 @@ module testbench;
`endif `endif
flopenr #(P.XLEN) PCWReg(clk, reset, ~dut.core.ieu.dp.StallW, dut.core.ifu.PCM, PCW); 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); flopenr #(32) InstrWReg(clk, reset, ~dut.core.ieu.dp.StallW, InstrM, InstrW);
// check assertions for a legal configuration // check assertions for a legal configuration
riscvassertions #(P) riscvassertions(); riscvassertions #(P) riscvassertions();
@ -261,7 +261,7 @@ module testbench;
instrTrackerTB it(clk, reset, dut.core.ieu.dp.FlushE, instrTrackerTB it(clk, reset, dut.core.ieu.dp.FlushE,
dut.core.ifu.InstrRawF[31:0], dut.core.ifu.InstrRawF[31:0],
dut.core.ifu.InstrD, dut.core.ifu.InstrE, dut.core.ifu.InstrD, dut.core.ifu.InstrE,
dut.core.ifu.InstrM, InstrW, InstrM, InstrW,
InstrFName, InstrDName, InstrEName, InstrMName, InstrWName); InstrFName, InstrDName, InstrEName, InstrMName, InstrWName);
// initialize tests // initialize tests
@ -298,6 +298,11 @@ module testbench;
.ProgramLabelMapFile(ProgramLabelMapFile)); .ProgramLabelMapFile(ProgramLabelMapFile));
end end
// 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);
// Termination condition // Termination condition
// terminate on a specific ECALL after li x3,1 for old Imperas tests, *** remove this when old imperas tests are removed // 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 sw gp,-56(t0) for new Imperas tests
@ -311,7 +316,7 @@ module testbench;
(dut.core.ieu.dp.regf.we3 & (dut.core.ieu.dp.regf.we3 &
dut.core.ieu.dp.regf.a3 == 3 & dut.core.ieu.dp.regf.a3 == 3 &
dut.core.ieu.dp.regf.wd3 == 1)) | 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 ) | ((InstrM == 32'h6f | InstrM == 32'hfc32a423 | InstrM == 32'hfc32a823) & dut.core.ieu.c.InstrValidM ) |
((dut.core.lsu.IEUAdrM == ProgramAddrLabelArray["tohost"]) & InstrMName == "SW" ); ((dut.core.lsu.IEUAdrM == ProgramAddrLabelArray["tohost"]) & InstrMName == "SW" );
DCacheFlushFSM #(P) DCacheFlushFSM(.clk(clk), DCacheFlushFSM #(P) DCacheFlushFSM(.clk(clk),

View File

@ -229,10 +229,16 @@ module testbench;
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
/////////////////////////////// Cache Issue /////////////////////////////////// /////////////////////////////// Cache Issue ///////////////////////////////////
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// 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);
logic probe; logic probe;
if (NO_SPOOFING) if (NO_SPOOFING)
assign probe = testbench.dut.core.PCM == 64'hffffffff80200c8c assign probe = testbench.dut.core.PCM == 64'hffffffff80200c8c
& testbench.dut.core.InstrM != 32'h14021273 & InstrM != 32'h14021273
& testbench.dut.core.InstrValidM; & testbench.dut.core.InstrValidM;
@ -452,7 +458,7 @@ module testbench;
`define FLUSHW dut.core.FlushW `define FLUSHW dut.core.FlushW
`define STALLW dut.core.StallW `define STALLW dut.core.StallW
flopenrc #(P.XLEN) PCWReg(clk, reset, `FLUSHW, ~`STALLW, `PCM, PCW); flopenrc #(P.XLEN) PCWReg(clk, reset, `FLUSHW, ~`STALLW, `PCM, PCW);
flopenr #(32) InstrWReg(clk, reset, ~`STALLW, `FLUSHW ? nop : dut.core.ifu.InstrM, InstrW); flopenr #(32) InstrWReg(clk, reset, ~`STALLW, `FLUSHW ? nop : InstrM, InstrW);
flopenrc #(1) controlregW(clk, reset, `FLUSHW, ~`STALLW, dut.core.ieu.c.InstrValidM, InstrValidW); flopenrc #(1) controlregW(clk, reset, `FLUSHW, ~`STALLW, dut.core.ieu.c.InstrValidM, InstrValidW);
flopenrc #(P.XLEN) IEUAdrWReg(clk, reset, `FLUSHW, ~`STALLW, dut.core.IEUAdrM, IEUAdrW); flopenrc #(P.XLEN) IEUAdrWReg(clk, reset, `FLUSHW, ~`STALLW, dut.core.IEUAdrM, IEUAdrW);
flopenrc #(P.XLEN) WriteDataWReg(clk, reset, `FLUSHW, ~`STALLW, dut.core.lsu.WriteDataM, WriteDataW); flopenrc #(P.XLEN) WriteDataWReg(clk, reset, `FLUSHW, ~`STALLW, dut.core.lsu.WriteDataM, WriteDataW);
@ -969,7 +975,7 @@ module testbench;
instrTrackerTB it(clk, reset, dut.core.ieu.dp.FlushE, instrTrackerTB it(clk, reset, dut.core.ieu.dp.FlushE,
dut.core.ifu.InstrRawF[31:0], dut.core.ifu.InstrRawF[31:0],
dut.core.ifu.InstrD, dut.core.ifu.InstrE, dut.core.ifu.InstrD, dut.core.ifu.InstrE,
dut.core.ifu.InstrM, InstrW, InstrM, InstrW,
InstrFName, InstrDName, InstrEName, InstrMName, InstrWName); InstrFName, InstrDName, InstrEName, InstrMName, InstrWName);
// ------------------ // ------------------

View File

@ -212,10 +212,16 @@ module testbench;
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
/////////////////////////////// Cache Issue /////////////////////////////////// /////////////////////////////// Cache Issue ///////////////////////////////////
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// 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(dut.core.clk, dut.core.reset, ~dut.core.ifu.StallM, NextInstrE, InstrM);
logic probe; logic probe;
if (NO_SPOOFING) if (NO_SPOOFING)
assign probe = testbench.dut.core.PCM == 64'hffffffff80200c8c assign probe = testbench.dut.core.PCM == 64'hffffffff80200c8c
& testbench.dut.core.InstrM != 32'h14021273 & InstrM != 32'h14021273
& testbench.dut.core.InstrValidM; & testbench.dut.core.InstrValidM;
@ -280,7 +286,7 @@ module testbench;
`define FLUSHW dut.core.FlushW `define FLUSHW dut.core.FlushW
`define STALLW dut.core.StallW `define STALLW dut.core.StallW
flopenrc #(P.XLEN) PCWReg(clk, reset, `FLUSHW, ~`STALLW, `PCM, PCW); flopenrc #(P.XLEN) PCWReg(clk, reset, `FLUSHW, ~`STALLW, `PCM, PCW);
flopenr #(32) InstrWReg(clk, reset, ~`STALLW, `FLUSHW ? nop : dut.core.ifu.InstrM, InstrW); flopenr #(32) InstrWReg(clk, reset, ~`STALLW, `FLUSHW ? nop : InstrM, InstrW);
flopenrc #(1) controlregW(clk, reset, `FLUSHW, ~`STALLW, dut.core.ieu.c.InstrValidM, InstrValidW); flopenrc #(1) controlregW(clk, reset, `FLUSHW, ~`STALLW, dut.core.ieu.c.InstrValidM, InstrValidW);
flopenrc #(P.XLEN) IEUAdrWReg(clk, reset, `FLUSHW, ~`STALLW, dut.core.IEUAdrM, IEUAdrW); flopenrc #(P.XLEN) IEUAdrWReg(clk, reset, `FLUSHW, ~`STALLW, dut.core.IEUAdrM, IEUAdrW);
flopenrc #(P.XLEN) WriteDataWReg(clk, reset, `FLUSHW, ~`STALLW, dut.core.lsu.WriteDataM, WriteDataW); flopenrc #(P.XLEN) WriteDataWReg(clk, reset, `FLUSHW, ~`STALLW, dut.core.lsu.WriteDataM, WriteDataW);
@ -794,7 +800,7 @@ module testbench;
instrTrackerTB it(clk, reset, dut.core.ieu.dp.FlushE, instrTrackerTB it(clk, reset, dut.core.ieu.dp.FlushE,
dut.core.ifu.InstrRawF[31:0], dut.core.ifu.InstrRawF[31:0],
dut.core.ifu.InstrD, dut.core.ifu.InstrE, dut.core.ifu.InstrD, dut.core.ifu.InstrE,
dut.core.ifu.InstrM, InstrW, InstrM, InstrW,
InstrFName, InstrDName, InstrEName, InstrMName, InstrWName); InstrFName, InstrDName, InstrEName, InstrMName, InstrWName);
// ------------------ // ------------------

View File

@ -440,20 +440,25 @@ module testbench;
// Support logic // 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 // Track names of instructions
string InstrFName, InstrDName, InstrEName, InstrMName, InstrWName; string InstrFName, InstrDName, InstrEName, InstrMName, InstrWName;
logic [31:0] InstrW; logic [31:0] InstrW;
flopenr #(32) InstrWReg(clk, reset, ~dut.core.ieu.dp.StallW, dut.core.ifu.InstrM, InstrW); flopenr #(32) InstrWReg(clk, reset, ~dut.core.ieu.dp.StallW, InstrM, InstrW);
instrTrackerTB it(clk, reset, dut.core.ieu.dp.FlushE, instrTrackerTB it(clk, reset, dut.core.ieu.dp.FlushE,
dut.core.ifu.InstrRawF[31:0], dut.core.ifu.InstrRawF[31:0],
dut.core.ifu.InstrD, dut.core.ifu.InstrE, dut.core.ifu.InstrD, dut.core.ifu.InstrE,
dut.core.ifu.InstrM, InstrW, InstrM, InstrW,
InstrFName, InstrDName, InstrEName, InstrMName, InstrWName); InstrFName, InstrDName, InstrEName, InstrMName, InstrWName);
// watch for problems such as lockup, reading unitialized memory, bad configs // watch for problems such as lockup, reading unitialized memory, bad configs
watchdog #(P.XLEN, 1000000) watchdog(.clk, .reset); // check if PCW is stuck 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, ramxdetector #(P.XLEN, P.LLEN) ramxdetector(clk, dut.core.lsu.MemRWM[1], dut.core.lsu.LSULoadAccessFaultM, dut.core.lsu.ReadDataM,
dut.core.ifu.PCM, dut.core.ifu.InstrM, dut.core.lsu.IEUAdrM, InstrMName); dut.core.ifu.PCM, InstrM, dut.core.lsu.IEUAdrM, InstrMName);
riscvassertions #(P) riscvassertions(); // check assertions for a legal configuration riscvassertions #(P) riscvassertions(); // check assertions for a legal configuration
loggers #(P, TEST, PrintHPMCounters, I_CACHE_ADDR_LOGGER, D_CACHE_ADDR_LOGGER, BPRED_LOGGER) loggers #(P, TEST, PrintHPMCounters, I_CACHE_ADDR_LOGGER, D_CACHE_ADDR_LOGGER, BPRED_LOGGER)
loggers (clk, reset, DCacheFlushStart, DCacheFlushDone, memfilename); loggers (clk, reset, DCacheFlushStart, DCacheFlushDone, memfilename);
@ -478,7 +483,7 @@ module testbench;
(dut.core.ieu.dp.regf.we3 & (dut.core.ieu.dp.regf.we3 &
dut.core.ieu.dp.regf.a3 == 3 & dut.core.ieu.dp.regf.a3 == 3 &
dut.core.ieu.dp.regf.wd3 == 1)) | 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 ) | ((InstrM == 32'h6f | InstrM == 32'hfc32a423 | InstrM == 32'hfc32a823) & dut.core.ieu.c.InstrValidM ) |
((dut.core.lsu.IEUAdrM == ProgramAddrLabelArray["tohost"]) & InstrMName == "SW" ); ((dut.core.lsu.IEUAdrM == ProgramAddrLabelArray["tohost"]) & InstrMName == "SW" );
DCacheFlushFSM #(P) DCacheFlushFSM(.clk(clk), .reset(reset), .start(DCacheFlushStart), .done(DCacheFlushDone)); DCacheFlushFSM #(P) DCacheFlushFSM(.clk(clk), .reset(reset), .start(DCacheFlushStart), .done(DCacheFlushDone));

View File

@ -408,20 +408,25 @@ module testbench;
// Support logic // 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 // Track names of instructions
string InstrFName, InstrDName, InstrEName, InstrMName, InstrWName; string InstrFName, InstrDName, InstrEName, InstrMName, InstrWName;
logic [31:0] InstrW; logic [31:0] InstrW;
flopenr #(32) InstrWReg(clk, reset, ~dut.core.ieu.dp.StallW, dut.core.ifu.InstrM, InstrW); flopenr #(32) InstrWReg(clk, reset, ~dut.core.ieu.dp.StallW, InstrM, InstrW);
instrTrackerTB it(clk, reset, dut.core.ieu.dp.FlushE, instrTrackerTB it(clk, reset, dut.core.ieu.dp.FlushE,
dut.core.ifu.InstrRawF[31:0], dut.core.ifu.InstrRawF[31:0],
dut.core.ifu.InstrD, dut.core.ifu.InstrE, dut.core.ifu.InstrD, dut.core.ifu.InstrE,
dut.core.ifu.InstrM, InstrW, InstrM, InstrW,
InstrFName, InstrDName, InstrEName, InstrMName, InstrWName); InstrFName, InstrDName, InstrEName, InstrMName, InstrWName);
// watch for problems such as lockup, reading unitialized memory, bad configs // watch for problems such as lockup, reading unitialized memory, bad configs
watchdog #(P.XLEN, 1000000) watchdog(.clk, .reset); // check if PCW is stuck 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, ramxdetector #(P.XLEN, P.LLEN) ramxdetector(clk, dut.core.lsu.MemRWM[1], dut.core.lsu.LSULoadAccessFaultM, dut.core.lsu.ReadDataM,
dut.core.ifu.PCM, dut.core.ifu.InstrM, dut.core.lsu.IEUAdrM, InstrMName); dut.core.ifu.PCM, InstrM, dut.core.lsu.IEUAdrM, InstrMName);
riscvassertions #(P) riscvassertions(); // check assertions for a legal configuration riscvassertions #(P) riscvassertions(); // check assertions for a legal configuration
loggers #(P, TEST, PrintHPMCounters, I_CACHE_ADDR_LOGGER, D_CACHE_ADDR_LOGGER, BPRED_LOGGER) loggers #(P, TEST, PrintHPMCounters, I_CACHE_ADDR_LOGGER, D_CACHE_ADDR_LOGGER, BPRED_LOGGER)
loggers (clk, reset, DCacheFlushStart, DCacheFlushDone, memfilename); loggers (clk, reset, DCacheFlushStart, DCacheFlushDone, memfilename);
@ -446,7 +451,7 @@ module testbench;
(dut.core.ieu.dp.regf.we3 & (dut.core.ieu.dp.regf.we3 &
dut.core.ieu.dp.regf.a3 == 3 & dut.core.ieu.dp.regf.a3 == 3 &
dut.core.ieu.dp.regf.wd3 == 1)) | 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 ) | ((InstrM == 32'h6f | InstrM == 32'hfc32a423 | InstrM == 32'hfc32a823) & dut.core.ieu.c.InstrValidM ) |
((dut.core.lsu.IEUAdrM == ProgramAddrLabelArray["tohost"]) & InstrMName == "SW" ); ((dut.core.lsu.IEUAdrM == ProgramAddrLabelArray["tohost"]) & InstrMName == "SW" );
DCacheFlushFSM #(P) DCacheFlushFSM(.clk(clk), .reset(reset), .start(DCacheFlushStart), .done(DCacheFlushDone)); DCacheFlushFSM #(P) DCacheFlushFSM(.clk(clk), .reset(reset), .start(DCacheFlushStart), .done(DCacheFlushDone));