mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Stripped out all signature checking.
Removed multiple tests loop. Only runs 1 test now.
This commit is contained in:
parent
8ee80c5d54
commit
5112ffcbc9
@ -30,7 +30,6 @@
|
|||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
`include "wally-config.vh"
|
`include "wally-config.vh"
|
||||||
`include "tests.vh"
|
|
||||||
|
|
||||||
|
|
||||||
module testbench;
|
module testbench;
|
||||||
@ -40,17 +39,12 @@ module testbench;
|
|||||||
logic clk;
|
logic clk;
|
||||||
logic reset_ext, reset;
|
logic reset_ext, reset;
|
||||||
|
|
||||||
parameter SIGNATURESIZE = 5000000;
|
|
||||||
|
|
||||||
int test, i, errors, totalerrors;
|
|
||||||
logic [31:0] sig32[0:SIGNATURESIZE];
|
|
||||||
logic [`XLEN-1:0] signature[0:SIGNATURESIZE];
|
|
||||||
logic [`XLEN-1:0] testadr, testadrNoBase;
|
logic [`XLEN-1:0] testadr, testadrNoBase;
|
||||||
string InstrFName, InstrDName, InstrEName, InstrMName, InstrWName;
|
string InstrFName, InstrDName, InstrEName, InstrMName, InstrWName;
|
||||||
logic [31:0] InstrW;
|
logic [31:0] InstrW;
|
||||||
|
|
||||||
string tests[];
|
logic [3:0] dummy;
|
||||||
logic [3:0] dummy;
|
|
||||||
|
|
||||||
logic [`AHBW-1:0] HRDATAEXT;
|
logic [`AHBW-1:0] HRDATAEXT;
|
||||||
logic HREADYEXT, HRESPEXT;
|
logic HREADYEXT, HRESPEXT;
|
||||||
@ -68,77 +62,9 @@ logic [3:0] dummy;
|
|||||||
|
|
||||||
string ProgramAddrMapFile, ProgramLabelMapFile;
|
string ProgramAddrMapFile, ProgramLabelMapFile;
|
||||||
integer ProgramAddrLabelArray [string] = '{ "begin_signature" : 0, "tohost" : 0 };
|
integer ProgramAddrLabelArray [string] = '{ "begin_signature" : 0, "tohost" : 0 };
|
||||||
|
|
||||||
logic DCacheFlushDone, DCacheFlushStart;
|
logic DCacheFlushDone, DCacheFlushStart;
|
||||||
logic riscofTest;
|
string testName;
|
||||||
|
string memfilename, pathname, adrstr;
|
||||||
flopenr #(`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 riscvassertions();
|
|
||||||
|
|
||||||
// pick tests based on modes supported
|
|
||||||
initial begin
|
|
||||||
$display("TEST is %s", TEST);
|
|
||||||
//tests = '{};
|
|
||||||
if (`XLEN == 64) begin // RV64
|
|
||||||
case (TEST)
|
|
||||||
"arch64i": tests = arch64i;
|
|
||||||
"arch64priv": tests = arch64priv;
|
|
||||||
"arch64c": if (`C_SUPPORTED)
|
|
||||||
if (`ZICSR_SUPPORTED) tests = {arch64c, arch64cpriv};
|
|
||||||
else tests = {arch64c};
|
|
||||||
"arch64m": if (`M_SUPPORTED) tests = arch64m;
|
|
||||||
"arch64f": if (`F_SUPPORTED) tests = arch64f;
|
|
||||||
"arch64d": if (`D_SUPPORTED) tests = arch64d;
|
|
||||||
"imperas64i": tests = imperas64i;
|
|
||||||
"imperas64f": if (`F_SUPPORTED) tests = imperas64f;
|
|
||||||
"imperas64d": if (`D_SUPPORTED) tests = imperas64d;
|
|
||||||
"imperas64m": if (`M_SUPPORTED) tests = imperas64m;
|
|
||||||
"wally64a": if (`A_SUPPORTED) tests = wally64a;
|
|
||||||
"imperas64c": if (`C_SUPPORTED) tests = imperas64c;
|
|
||||||
else tests = imperas64iNOc;
|
|
||||||
"custom": tests = custom;
|
|
||||||
"wally64i": tests = wally64i;
|
|
||||||
"wally64priv": tests = wally64priv;
|
|
||||||
"wally64periph": tests = wally64periph;
|
|
||||||
"coremark": tests = coremark;
|
|
||||||
"fpga": tests = fpga;
|
|
||||||
"ahb" : tests = ahb;
|
|
||||||
endcase
|
|
||||||
end else begin // RV32
|
|
||||||
case (TEST)
|
|
||||||
"arch32i": tests = arch32i;
|
|
||||||
"arch32priv": tests = arch32priv;
|
|
||||||
"arch32c": if (`C_SUPPORTED)
|
|
||||||
if (`ZICSR_SUPPORTED) tests = {arch32c, arch32cpriv};
|
|
||||||
else tests = {arch32c};
|
|
||||||
"arch32m": if (`M_SUPPORTED) tests = arch32m;
|
|
||||||
"arch32f": if (`F_SUPPORTED) tests = arch32f;
|
|
||||||
"arch32d": if (`D_SUPPORTED) tests = arch32d;
|
|
||||||
"imperas32i": tests = imperas32i;
|
|
||||||
"imperas32f": if (`F_SUPPORTED) tests = imperas32f;
|
|
||||||
"imperas32m": if (`M_SUPPORTED) tests = imperas32m;
|
|
||||||
"wally32a": if (`A_SUPPORTED) tests = wally32a;
|
|
||||||
"imperas32c": if (`C_SUPPORTED) tests = imperas32c;
|
|
||||||
else tests = imperas32iNOc;
|
|
||||||
"wally32i": tests = wally32i;
|
|
||||||
"wally32e": tests = wally32e;
|
|
||||||
"wally32priv": tests = wally32priv;
|
|
||||||
"wally32periph": tests = wally32periph;
|
|
||||||
"embench": tests = embench;
|
|
||||||
"coremark": tests = coremark;
|
|
||||||
endcase
|
|
||||||
end
|
|
||||||
if (tests.size() == 0) begin
|
|
||||||
$display("TEST %s not supported in this configuration", TEST);
|
|
||||||
$stop;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
string signame, memfilename, pathname, objdumpfilename, adrstr, outputfile;
|
|
||||||
integer outputFilePointer;
|
|
||||||
|
|
||||||
logic [31:0] GPIOPinsIn, GPIOPinsOut, GPIOPinsEn;
|
logic [31:0] GPIOPinsIn, GPIOPinsOut, GPIOPinsEn;
|
||||||
logic UARTSin, UARTSout;
|
logic UARTSin, UARTSout;
|
||||||
@ -158,6 +84,41 @@ logic [3:0] dummy;
|
|||||||
integer ResetCount, ResetThreshold;
|
integer ResetCount, ResetThreshold;
|
||||||
logic InReset;
|
logic InReset;
|
||||||
|
|
||||||
|
// Imperas look here.
|
||||||
|
initial
|
||||||
|
begin
|
||||||
|
ResetCount = 0;
|
||||||
|
ResetThreshold = 2;
|
||||||
|
InReset = 1;
|
||||||
|
testadr = 0;
|
||||||
|
testadrNoBase = 0;
|
||||||
|
|
||||||
|
testName = "rv64i_m/I/src/add-01.S";
|
||||||
|
|
||||||
|
pathname = "../../tests/riscof/work/riscv-arch-test/";
|
||||||
|
memfilename = {pathname, testName, "/ref/ref.elf.memfile"};
|
||||||
|
if (`BUS) $readmemh(memfilename, dut.uncore.uncore.ram.ram.memory.RAM);
|
||||||
|
else $error("Imperas test bench requires BUS.");
|
||||||
|
|
||||||
|
ProgramAddrMapFile = {pathname, testName, "/ref/ref.elf.objdump.addr"};
|
||||||
|
ProgramLabelMapFile = {pathname, testName, "/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
|
||||||
|
|
||||||
|
rvviTrace rvviTrace();
|
||||||
|
|
||||||
|
|
||||||
|
flopenr #(`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 riscvassertions();
|
||||||
|
|
||||||
|
|
||||||
// instantiate device to be tested
|
// instantiate device to be tested
|
||||||
assign GPIOPinsIn = 0;
|
assign GPIOPinsIn = 0;
|
||||||
assign UARTSin = 1;
|
assign UARTSin = 1;
|
||||||
@ -200,65 +161,6 @@ logic [3:0] dummy;
|
|||||||
InstrFName, InstrDName, InstrEName, InstrMName, InstrWName);
|
InstrFName, InstrDName, InstrEName, InstrMName, InstrWName);
|
||||||
|
|
||||||
// initialize tests
|
// initialize tests
|
||||||
localparam integer MemStartAddr = 0;
|
|
||||||
localparam integer MemEndAddr = `UNCORE_RAM_RANGE>>1+(`XLEN/32);
|
|
||||||
|
|
||||||
initial
|
|
||||||
begin
|
|
||||||
ResetCount = 0;
|
|
||||||
ResetThreshold = 2;
|
|
||||||
InReset = 1;
|
|
||||||
test = 1;
|
|
||||||
totalerrors = 0;
|
|
||||||
testadr = 0;
|
|
||||||
testadrNoBase = 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";
|
|
||||||
// fill memory with defined values to reduce Xs in simulation
|
|
||||||
// Quick note the memory will need to be initialized. The C library does not
|
|
||||||
// guarantee the initialized reads. For example a strcmp can read 6 byte
|
|
||||||
// strings, but uses a load double to read them in. If the last 2 bytes are
|
|
||||||
// not initialized the compare results in an 'x' which propagates through
|
|
||||||
// the design.
|
|
||||||
if (TEST == "coremark")
|
|
||||||
for (i=MemStartAddr; i<MemEndAddr; i = i+1)
|
|
||||||
dut.uncore.uncore.ram.ram.memory.RAM[i] = 64'h0;
|
|
||||||
|
|
||||||
// read test vectors into memory
|
|
||||||
pathname = tvpaths[tests[0].atoi()];
|
|
||||||
/* if (tests[0] == `IMPERASTEST)
|
|
||||||
pathname = tvpaths[0];
|
|
||||||
else pathname = tvpaths[1]; */
|
|
||||||
if (riscofTest) memfilename = {pathname, tests[test], "/ref/ref.elf.memfile"};
|
|
||||||
else memfilename = {pathname, tests[test], ".elf.memfile"};
|
|
||||||
if (`FPGA) 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);
|
|
||||||
// force sdc timers
|
|
||||||
force dut.uncore.uncore.sdc.SDC.LimitTimers = 1;
|
|
||||||
end else begin
|
|
||||||
if (`IROM_SUPPORTED) $readmemh(memfilename, dut.core.ifu.irom.irom.rom.ROM);
|
|
||||||
else if (`BUS) $readmemh(memfilename, dut.uncore.uncore.ram.ram.memory.RAM);
|
|
||||||
if (`DTIM_SUPPORTED) $readmemh(memfilename, dut.core.lsu.dtim.dtim.ram.RAM);
|
|
||||||
end
|
|
||||||
|
|
||||||
if (riscofTest) begin
|
|
||||||
ProgramAddrMapFile = {pathname, tests[test], "/ref/ref.elf.objdump.addr"};
|
|
||||||
ProgramLabelMapFile = {pathname, tests[test], "/ref/ref.elf.objdump.lab"};
|
|
||||||
end else begin
|
|
||||||
ProgramAddrMapFile = {pathname, tests[test], ".elf.objdump.addr"};
|
|
||||||
ProgramLabelMapFile = {pathname, tests[test], ".elf.objdump.lab"};
|
|
||||||
end
|
|
||||||
// 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(!`FPGA) begin
|
|
||||||
updateProgramAddrLabelArray(ProgramAddrMapFile, ProgramLabelMapFile, ProgramAddrLabelArray);
|
|
||||||
$display("Read memfile %s", memfilename);
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
// generate clock to sequence tests
|
// generate clock to sequence tests
|
||||||
always
|
always
|
||||||
@ -267,9 +169,6 @@ logic [3:0] dummy;
|
|||||||
// if ($time % 100000 == 0) $display("Time is %0t", $time);
|
// if ($time % 100000 == 0) $display("Time is %0t", $time);
|
||||||
end
|
end
|
||||||
|
|
||||||
logic [`XLEN-1:0] debugmemoryadr;
|
|
||||||
// assign debugmemoryadr = dut.uncore.uncore.ram.ram.memory.RAM[5140];
|
|
||||||
|
|
||||||
// check results
|
// check results
|
||||||
assign reset_ext = InReset;
|
assign reset_ext = InReset;
|
||||||
|
|
||||||
@ -284,126 +183,13 @@ logic [3:0] dummy;
|
|||||||
ResetCount = 0;
|
ResetCount = 0;
|
||||||
end
|
end
|
||||||
end else begin
|
end else begin
|
||||||
if (TEST == "coremark")
|
if(DCacheFlushStart) begin
|
||||||
if (dut.core.priv.priv.EcallFaultM) begin
|
$stop;
|
||||||
$display("Benchmark: coremark is done.");
|
end
|
||||||
$stop;
|
|
||||||
end
|
|
||||||
// Termination condition (i.e. we finished running current test)
|
|
||||||
if (DCacheFlushDone) begin
|
|
||||||
integer begin_signature_addr;
|
|
||||||
InReset = 1;
|
|
||||||
begin_signature_addr = ProgramAddrLabelArray["begin_signature"];
|
|
||||||
if (!begin_signature_addr)
|
|
||||||
$display("begin_signature addr not found in %s", ProgramLabelMapFile);
|
|
||||||
testadr = ($unsigned(begin_signature_addr))/(`XLEN/8);
|
|
||||||
testadrNoBase = (begin_signature_addr - `UNCORE_RAM_BASE)/(`XLEN/8);
|
|
||||||
#600; // give time for instructions in pipeline to finish
|
|
||||||
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
|
|
||||||
// also begin_signature contains the results of the self checking mechanism, which will be read by the python script for error checking
|
|
||||||
$display("Embench Benchmark: %s is done.", tests[test]);
|
|
||||||
if (riscofTest) outputfile = {pathname, tests[test], "/ref/ref.sim.output"};
|
|
||||||
else outputfile = {pathname, tests[test], ".sim.output"};
|
|
||||||
outputFilePointer = $fopen(outputfile);
|
|
||||||
i = 0;
|
|
||||||
while ($unsigned(i) < $unsigned(5'd5)) begin
|
|
||||||
$fdisplayh(outputFilePointer, DCacheFlushFSM.ShadowRAM[testadr+i]);
|
|
||||||
i = i + 1;
|
|
||||||
end
|
|
||||||
$fclose(outputFilePointer);
|
|
||||||
$display("Embench Benchmark: created output file: %s", outputfile);
|
|
||||||
end else begin
|
|
||||||
// for tests with no self checking mechanism, read .signature.output file and compare to check for errors
|
|
||||||
// clear signature to prevent contamination from previous tests
|
|
||||||
for(i=0; i<SIGNATURESIZE; i=i+1) begin
|
|
||||||
sig32[i] = 'bx;
|
|
||||||
end
|
|
||||||
if (riscofTest) signame = {pathname, tests[test], "/ref/Reference-sail_c_simulator.signature"};
|
|
||||||
else signame = {pathname, tests[test], ".signature.output"};
|
|
||||||
// read signature, reformat in 64 bits if necessary
|
|
||||||
$readmemh(signame, sig32);
|
|
||||||
i = 0;
|
|
||||||
while (i < SIGNATURESIZE) begin
|
|
||||||
if (`XLEN == 32) begin
|
|
||||||
signature[i] = sig32[i];
|
|
||||||
i = i+1;
|
|
||||||
end else begin
|
|
||||||
signature[i/2] = {sig32[i+1], sig32[i]};
|
|
||||||
i = i + 2;
|
|
||||||
end
|
|
||||||
if (i >= 4 & sig32[i-4] === 'bx) begin
|
|
||||||
if (i == 4) begin
|
|
||||||
i = SIGNATURESIZE+1; // flag empty file
|
|
||||||
$display(" Error: empty test file");
|
|
||||||
end else i = SIGNATURESIZE; // skip over the rest of the x's for efficiency
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
// Check errors
|
|
||||||
errors = (i == SIGNATURESIZE+1); // error if file is empty
|
|
||||||
i = 0;
|
|
||||||
/* verilator lint_off INFINITELOOP */
|
|
||||||
while (signature[i] !== 'bx) begin
|
|
||||||
logic [`XLEN-1:0] sig;
|
|
||||||
if (`DTIM_SUPPORTED) sig = dut.core.lsu.dtim.dtim.ram.RAM[testadrNoBase+i];
|
|
||||||
else if (`UNCORE_RAM_SUPPORTED) sig = dut.uncore.uncore.ram.ram.memory.RAM[testadrNoBase+i];
|
|
||||||
//$display("signature[%h] = %h sig = %h", i, signature[i], sig);
|
|
||||||
if (signature[i] !== sig & (signature[i] !== DCacheFlushFSM.ShadowRAM[testadr+i])) begin
|
|
||||||
errors = errors+1;
|
|
||||||
$display(" Error on test %s result %d: adr = %h sim (D$) %h sim (DTIM_SUPPORTED) = %h, signature = %h",
|
|
||||||
tests[test], i, (testadr+i)*(`XLEN/8), DCacheFlushFSM.ShadowRAM[testadr+i], sig, signature[i]);
|
|
||||||
$stop;//***debug
|
|
||||||
end
|
|
||||||
i = i + 1;
|
|
||||||
end
|
|
||||||
/* verilator lint_on INFINITELOOP */
|
|
||||||
if (errors == 0) begin
|
|
||||||
$display("%s succeeded. Brilliant!!!", tests[test]);
|
|
||||||
end
|
|
||||||
else begin
|
|
||||||
$display("%s failed with %d errors. :(", tests[test], errors);
|
|
||||||
totalerrors = totalerrors+1;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
// move onto the next test, check to see if we're done
|
|
||||||
test = test + 1;
|
|
||||||
if (test == tests.size()) begin
|
|
||||||
if (totalerrors == 0) $display("SUCCESS! All tests ran without failures.");
|
|
||||||
else $display("FAIL: %d test programs had errors", totalerrors);
|
|
||||||
$stop;
|
|
||||||
end
|
|
||||||
else begin
|
|
||||||
InitializingMemories = 1;
|
|
||||||
// If there are still additional tests to run, read in information for the next test
|
|
||||||
//pathname = tvpaths[tests[0]];
|
|
||||||
if (riscofTest) memfilename = {pathname, tests[test], "/ref/ref.elf.memfile"};
|
|
||||||
else memfilename = {pathname, tests[test], ".elf.memfile"};
|
|
||||||
//$readmemh(memfilename, dut.uncore.uncore.ram.ram.memory.RAM);
|
|
||||||
if (`IROM_SUPPORTED) $readmemh(memfilename, dut.core.ifu.irom.irom.rom.ROM);
|
|
||||||
else if (`UNCORE_RAM_SUPPORTED) $readmemh(memfilename, dut.uncore.uncore.ram.ram.memory.RAM);
|
|
||||||
if (`DTIM_SUPPORTED) $readmemh(memfilename, dut.core.lsu.dtim.dtim.ram.RAM);
|
|
||||||
|
|
||||||
if (riscofTest) begin
|
|
||||||
ProgramAddrMapFile = {pathname, tests[test], "/ref/ref.elf.objdump.addr"};
|
|
||||||
ProgramLabelMapFile = {pathname, tests[test], "/ref/ref.elf.objdump.lab"};
|
|
||||||
end else begin
|
|
||||||
ProgramAddrMapFile = {pathname, tests[test], ".elf.objdump.addr"};
|
|
||||||
ProgramLabelMapFile = {pathname, tests[test], ".elf.objdump.lab"};
|
|
||||||
end
|
|
||||||
ProgramAddrLabelArray = '{ "begin_signature" : 0, "tohost" : 0 };
|
|
||||||
if(!`FPGA) begin
|
|
||||||
updateProgramAddrLabelArray(ProgramAddrMapFile, ProgramLabelMapFile, ProgramAddrLabelArray);
|
|
||||||
$display("Read memfile %s", memfilename);
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end // if (DCacheFlushDone)
|
|
||||||
end
|
end
|
||||||
end // always @ (negedge clk)
|
end // always @ (negedge clk)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// track the current function or global label
|
// track the current function or global label
|
||||||
if (DEBUG == 1) begin : FunctionName
|
if (DEBUG == 1) begin : FunctionName
|
||||||
FunctionName FunctionName(.reset(reset),
|
FunctionName FunctionName(.reset(reset),
|
||||||
@ -469,7 +255,6 @@ logic [3:0] dummy;
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
rvviTrace rvviTrace();
|
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
@ -653,55 +438,3 @@ task automatic updateProgramAddrLabelArray;
|
|||||||
$fclose(ProgramAddrMapFP);
|
$fclose(ProgramAddrMapFP);
|
||||||
endtask
|
endtask
|
||||||
|
|
||||||
`define NUM_REGS 32
|
|
||||||
`define NUM_CSRS 4096
|
|
||||||
|
|
||||||
module rvviTrace();
|
|
||||||
|
|
||||||
// wally specific signals
|
|
||||||
logic reset;
|
|
||||||
|
|
||||||
logic [`XLEN-1:0] PCM, PCW;
|
|
||||||
logic [`XLEN-1:0] InstrRawD, InstrRawE, InstrRawM, InstrRawW;
|
|
||||||
logic InstrValidM, InstrValidW;
|
|
||||||
logic StallE, StallM, StallW;
|
|
||||||
logic FlushE, FlushM, FlushW;
|
|
||||||
|
|
||||||
// tracer signals
|
|
||||||
logic clk;
|
|
||||||
logic valid;
|
|
||||||
logic [`XLEN-1:0] insn;
|
|
||||||
logic [`XLEN-1:0 ] pc_rdata;
|
|
||||||
|
|
||||||
assign clk = testbench.dut.clk;
|
|
||||||
assign InstrValidM = testbench.dut.core.ieu.InstrValidM;
|
|
||||||
assign InstrRawD = testbench.dut.core.ifu.InstrRawD;
|
|
||||||
assign PCM = testbench.dut.core.ifu.PCM;
|
|
||||||
assign reset = testbench.reset;
|
|
||||||
assign StallE = testbench.dut.core.StallE;
|
|
||||||
assign StallM = testbench.dut.core.StallM;
|
|
||||||
assign StallW = testbench.dut.core.StallW;
|
|
||||||
assign FlushE = testbench.dut.core.FlushE;
|
|
||||||
assign FlushM = testbench.dut.core.FlushM;
|
|
||||||
assign FlushW = testbench.dut.core.FlushW;
|
|
||||||
|
|
||||||
// pipeline to writeback stage
|
|
||||||
flopenrc #(`XLEN) InstrRawEReg (clk, reset, FlushE, ~StallE, InstrRawD, InstrRawE);
|
|
||||||
flopenrc #(`XLEN) InstrRawMReg (clk, reset, FlushM, ~StallM, InstrRawE, InstrRawM);
|
|
||||||
flopenrc #(`XLEN) InstrRawWReg (clk, reset, FlushW, ~StallW, InstrRawM, InstrRawW);
|
|
||||||
flopenrc #(`XLEN) PCWReg (clk, reset, FlushW, ~StallW, PCM, PCW);
|
|
||||||
flopenrc #(1) InstrValidMReg (clk, reset, FlushW, ~StallW, InstrValidM, InstrValidW);
|
|
||||||
|
|
||||||
assign valid = InstrValidW & ~StallW & ~FlushW;
|
|
||||||
assign insn = InstrRawW;
|
|
||||||
assign pc_rdata = PCW;
|
|
||||||
|
|
||||||
always_ff @(posedge clk) begin
|
|
||||||
if(valid) begin
|
|
||||||
$display("PC = %x, insn = %x", pc_rdata, insn);
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
endmodule
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user