mirror of
https://github.com/openhwgroup/cvw.git
synced 2025-04-24 22:07:12 -04:00
Added performance new counter prints to testbench.
This commit is contained in:
parent
17adba5fd5
commit
f6e97cf516
1 changed files with 125 additions and 136 deletions
|
@ -155,9 +155,9 @@ logic [3:0] dummy;
|
||||||
logic HREADY;
|
logic HREADY;
|
||||||
logic HSELEXT;
|
logic HSELEXT;
|
||||||
|
|
||||||
logic InitializingMemories;
|
logic InitializingMemories;
|
||||||
integer ResetCount, ResetThreshold;
|
integer ResetCount, ResetThreshold;
|
||||||
logic InReset;
|
logic InReset;
|
||||||
|
|
||||||
// instantiate device to be tested
|
// instantiate device to be tested
|
||||||
assign GPIOPinsIn = 0;
|
assign GPIOPinsIn = 0;
|
||||||
|
@ -228,7 +228,7 @@ logic [3:0] dummy;
|
||||||
// read test vectors into memory
|
// read test vectors into memory
|
||||||
pathname = tvpaths[tests[0].atoi()];
|
pathname = tvpaths[tests[0].atoi()];
|
||||||
/* if (tests[0] == `IMPERASTEST)
|
/* if (tests[0] == `IMPERASTEST)
|
||||||
pathname = tvpaths[0];
|
pathname = tvpaths[0];
|
||||||
else pathname = tvpaths[1]; */
|
else pathname = tvpaths[1]; */
|
||||||
if (riscofTest) memfilename = {pathname, tests[test], "/ref/ref.elf.memfile"};
|
if (riscofTest) memfilename = {pathname, tests[test], "/ref/ref.elf.memfile"};
|
||||||
else memfilename = {pathname, tests[test], ".elf.memfile"};
|
else memfilename = {pathname, tests[test], ".elf.memfile"};
|
||||||
|
@ -268,9 +268,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;
|
||||||
|
|
||||||
|
@ -285,97 +282,97 @@ logic [3:0] dummy;
|
||||||
ResetCount = 0;
|
ResetCount = 0;
|
||||||
end
|
end
|
||||||
end else begin
|
end else begin
|
||||||
if (TEST == "coremark")
|
if (TEST == "coremark")
|
||||||
if (dut.core.priv.priv.EcallFaultM) begin
|
if (dut.core.priv.priv.EcallFaultM) begin
|
||||||
$display("Benchmark: coremark is done.");
|
$display("Benchmark: coremark is done.");
|
||||||
$stop;
|
$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
|
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
|
// Check errors
|
||||||
errors = (i == SIGNATURESIZE+1); // error if file is empty
|
errors = (i == SIGNATURESIZE+1); // error if file is empty
|
||||||
i = 0;
|
i = 0;
|
||||||
/* verilator lint_off INFINITELOOP */
|
/* verilator lint_off INFINITELOOP */
|
||||||
while (signature[i] !== 'bx) begin
|
while (signature[i] !== 'bx) begin
|
||||||
logic [`XLEN-1:0] sig;
|
logic [`XLEN-1:0] sig;
|
||||||
if (`DTIM_SUPPORTED) sig = dut.core.lsu.dtim.dtim.ram.RAM[testadrNoBase+i];
|
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];
|
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);
|
//$display("signature[%h] = %h sig = %h", i, signature[i], sig);
|
||||||
if (signature[i] !== sig & (signature[i] !== DCacheFlushFSM.ShadowRAM[testadr+i])) begin
|
if (signature[i] !== sig & (signature[i] !== DCacheFlushFSM.ShadowRAM[testadr+i])) begin
|
||||||
errors = errors+1;
|
errors = errors+1;
|
||||||
$display(" Error on test %s result %d: adr = %h sim (D$) %h sim (DTIM_SUPPORTED) = %h, signature = %h",
|
$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]);
|
tests[test], i, (testadr+i)*(`XLEN/8), DCacheFlushFSM.ShadowRAM[testadr+i], sig, signature[i]);
|
||||||
$stop;//***debug
|
$stop;//***debug
|
||||||
end
|
end
|
||||||
i = i + 1;
|
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
|
end
|
||||||
/* verilator lint_on INFINITELOOP */
|
// move onto the next test, check to see if we're done
|
||||||
if (errors == 0) begin
|
test = test + 1;
|
||||||
$display("%s succeeded. Brilliant!!!", tests[test]);
|
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
|
end
|
||||||
else begin
|
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;
|
InitializingMemories = 1;
|
||||||
// If there are still additional tests to run, read in information for the next test
|
// If there are still additional tests to run, read in information for the next test
|
||||||
//pathname = tvpaths[tests[0]];
|
//pathname = tvpaths[tests[0]];
|
||||||
|
@ -394,12 +391,12 @@ logic [3:0] dummy;
|
||||||
ProgramLabelMapFile = {pathname, tests[test], ".elf.objdump.lab"};
|
ProgramLabelMapFile = {pathname, tests[test], ".elf.objdump.lab"};
|
||||||
end
|
end
|
||||||
ProgramAddrLabelArray = '{ "begin_signature" : 0, "tohost" : 0 };
|
ProgramAddrLabelArray = '{ "begin_signature" : 0, "tohost" : 0 };
|
||||||
if(!`FPGA) begin
|
if(!`FPGA) begin
|
||||||
updateProgramAddrLabelArray(ProgramAddrMapFile, ProgramLabelMapFile, ProgramAddrLabelArray);
|
updateProgramAddrLabelArray(ProgramAddrMapFile, ProgramLabelMapFile, ProgramAddrLabelArray);
|
||||||
$display("Read memfile %s", memfilename);
|
$display("Read memfile %s", memfilename);
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end // if (DCacheFlushDone)
|
||||||
end // if (DCacheFlushDone)
|
|
||||||
end
|
end
|
||||||
end // always @ (negedge clk)
|
end // always @ (negedge clk)
|
||||||
|
|
||||||
|
@ -409,19 +406,29 @@ logic [3:0] dummy;
|
||||||
string HPMCnames[] = '{"Mcycle",
|
string HPMCnames[] = '{"Mcycle",
|
||||||
"------",
|
"------",
|
||||||
"InstRet",
|
"InstRet",
|
||||||
"Load Stall",
|
|
||||||
"Br Dir Wrong",
|
|
||||||
"Br Count",
|
"Br Count",
|
||||||
"Br Target Wrong",
|
|
||||||
"Jump, JR, Jal",
|
"Jump, JR, Jal",
|
||||||
|
"Return",
|
||||||
|
"Br Dir Wrong",
|
||||||
|
"Br Pred Wrong",
|
||||||
|
"Br Target Wrong",
|
||||||
"RAS Wrong",
|
"RAS Wrong",
|
||||||
"ret",
|
|
||||||
"Instr Class Wrong",
|
"Instr Class Wrong",
|
||||||
|
"Load Stall",
|
||||||
|
"Store Stall",
|
||||||
"D Cache Access",
|
"D Cache Access",
|
||||||
"D Cache Miss",
|
"D Cache Miss",
|
||||||
|
"D Cache Cycles",
|
||||||
"I Cache Access",
|
"I Cache Access",
|
||||||
"I Cache Miss",
|
"I Cache Miss",
|
||||||
"Br Pred Wrong"};
|
"I Cache Cycles",
|
||||||
|
"CSR Write",
|
||||||
|
"FenceI",
|
||||||
|
"SFenceVMA",
|
||||||
|
"Interrupt",
|
||||||
|
"Exception",
|
||||||
|
"Divide Cycles"
|
||||||
|
};
|
||||||
always @(negedge clk) begin
|
always @(negedge clk) begin
|
||||||
if(DCacheFlushStart & ~DCacheFlushDone) begin
|
if(DCacheFlushStart & ~DCacheFlushDone) begin
|
||||||
for(HPMCindex = 0; HPMCindex < HPMCnames.size(); HPMCindex += 1) begin
|
for(HPMCindex = 0; HPMCindex < HPMCnames.size(); HPMCindex += 1) begin
|
||||||
|
@ -487,40 +494,22 @@ logic [3:0] dummy;
|
||||||
|
|
||||||
|
|
||||||
if (`BPRED_SUPPORTED == 1) begin
|
if (`BPRED_SUPPORTED == 1) begin
|
||||||
/* -----\/----- EXCLUDED -----\/-----
|
if (`BPRED_LOGGER) begin
|
||||||
genvar adrindex;
|
string direction;
|
||||||
// Initializing all zeroes into the branch predictor memory.
|
int file;
|
||||||
for(adrindex = 0; adrindex < 2**`BTB_SIZE; adrindex++) begin
|
logic PCSrcM;
|
||||||
initial begin
|
flopenrc #(1) PCSrcMReg(clk, reset, dut.core.FlushM, ~dut.core.StallM, dut.core.ifu.bpred.bpred.Predictor.DirPredictor.PCSrcE, PCSrcM);
|
||||||
force dut.core.ifu.bpred.bpred.TargetPredictor.memory.mem[adrindex] = 0;
|
initial begin
|
||||||
#1;
|
file = $fopen("branch.log", "w");
|
||||||
release dut.core.ifu.bpred.bpred.TargetPredictor.memory.mem[adrindex];
|
end
|
||||||
end
|
always @(posedge clk) begin
|
||||||
end
|
if(dut.core.ifu.InstrClassM[0] & ~dut.core.StallW & ~dut.core.FlushW & dut.core.InstrValidM) begin
|
||||||
for(adrindex = 0; adrindex < 2**`BPRED_SIZE; adrindex++) begin
|
direction = PCSrcM ? "t" : "n";
|
||||||
initial begin
|
$fwrite(file, "%h %s\n", dut.core.PCM, direction);
|
||||||
force dut.core.ifu.bpred.bpred.Predictor.DirPredictor.PHT.mem[adrindex] = 0;
|
end
|
||||||
#1;
|
end
|
||||||
release dut.core.ifu.bpred.bpred.Predictor.DirPredictor.PHT.mem[adrindex];
|
|
||||||
end
|
|
||||||
end
|
|
||||||
-----/\----- EXCLUDED -----/\----- */
|
|
||||||
|
|
||||||
if (`BPRED_LOGGER) begin
|
|
||||||
string direction;
|
|
||||||
int file;
|
|
||||||
logic PCSrcM;
|
|
||||||
flopenrc #(1) PCSrcMReg(clk, reset, dut.core.FlushM, ~dut.core.StallM, dut.core.ifu.bpred.bpred.Predictor.DirPredictor.PCSrcE, PCSrcM);
|
|
||||||
initial
|
|
||||||
file = $fopen("branch.log", "w");
|
|
||||||
always @(posedge clk) begin
|
|
||||||
if(dut.core.ifu.InstrClassM[0] & ~dut.core.StallW & ~dut.core.FlushW & dut.core.InstrValidM) begin
|
|
||||||
direction = PCSrcM ? "t" : "n";
|
|
||||||
$fwrite(file, "%h %s\n", dut.core.PCM, direction);
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
// check for hange up.
|
// check for hange up.
|
||||||
logic [`XLEN-1:0] OldPCW;
|
logic [`XLEN-1:0] OldPCW;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue