From a8ab3c8342f3cea47dd787d599844ba5b7c481e3 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Wed, 20 Dec 2023 12:25:34 -0600 Subject: [PATCH] Ok that is a stange bug. The testbench used logic for the shadow ram, but the memory used bit. This caused questa to allocate huge amounts of memory and crash. Changing shadow ram to bit fixed the issue. --- testbench/common/DCacheFlushFSM.sv | 2 +- testbench/testbench.sv | 116 ++++++++++++++++++++++++----- 2 files changed, 99 insertions(+), 19 deletions(-) diff --git a/testbench/common/DCacheFlushFSM.sv b/testbench/common/DCacheFlushFSM.sv index 152aaa173..1f41968c3 100644 --- a/testbench/common/DCacheFlushFSM.sv +++ b/testbench/common/DCacheFlushFSM.sv @@ -35,7 +35,7 @@ module DCacheFlushFSM import cvw::*; #(parameter cvw_t P) genvar adr; - logic [P.XLEN-1:0] ShadowRAM[P.UNCORE_RAM_BASE>>(1+P.XLEN/32):(P.UNCORE_RAM_RANGE+P.UNCORE_RAM_BASE)>>1+(P.XLEN/32)]; + bit [P.XLEN-1:0] ShadowRAM[P.UNCORE_RAM_BASE>>(1+P.XLEN/32):(P.UNCORE_RAM_RANGE+P.UNCORE_RAM_BASE)>>1+(P.XLEN/32)]; logic startD; if(P.DCACHE_SUPPORTED) begin diff --git a/testbench/testbench.sv b/testbench/testbench.sv index ece7500d5..3607a5f06 100644 --- a/testbench/testbench.sv +++ b/testbench/testbench.sv @@ -85,7 +85,7 @@ module testbench; logic riscofTest; logic Validate; logic SelectTest; - + logic TestComplete; // pick tests based on modes supported initial begin @@ -176,6 +176,7 @@ module testbench; STATE_LOAD_MEMORIES, STATE_RESET_TEST, STATE_RUN_TEST, + STATE_COPY_RAM, STATE_CHECK_TEST, STATE_CHECK_TEST_WAIT, STATE_VALIDATE, @@ -218,8 +219,9 @@ module testbench; 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; + STATE_RUN_TEST: if(TestComplete) NextState = STATE_COPY_RAM; else NextState = STATE_RUN_TEST; + STATE_COPY_RAM: NextState = STATE_CHECK_TEST; STATE_CHECK_TEST: if (DCacheFlushDone) NextState = STATE_VALIDATE; else NextState = STATE_CHECK_TEST_WAIT; STATE_CHECK_TEST_WAIT: if(DCacheFlushDone) NextState = STATE_VALIDATE; @@ -240,6 +242,8 @@ module testbench; assign ResetCntEn = CurrState == STATE_RESET_TEST; assign Validate = CurrState == STATE_VALIDATE; assign SelectTest = CurrState == STATE_INIT_TEST; + assign CopyRAM = TestComplete & CurrState == STATE_RUN_TEST; + assign DCacheFlushStart = CurrState == STATE_COPY_RAM; // fsm reset counter counter #(3) RstCounter(clk, ResetCntRst, ResetCntEn, ResetCount); @@ -271,7 +275,7 @@ module testbench; //////////////////////////////////////////////////////////////////////////////// if(TestBenchReset) test = 1; if (TEST == "coremark") - if (dut.core.EcallFaultM) begin + if (dut.core.priv.priv.EcallFaultM) begin $display("Benchmark: coremark is done."); $stop; end @@ -320,6 +324,7 @@ module testbench; //////////////////////////////////////////////////////////////////////////////// // Some memories are not reset, but should be zeros or set to some initial value for simulation //////////////////////////////////////////////////////////////////////////////// +/* -----\/----- EXCLUDED -----\/----- integer adrindex; always @(posedge clk) begin if (ResetMem) // program memory is sometimes reset @@ -339,13 +344,50 @@ module testbench; end end end + -----/\----- EXCLUDED -----/\----- */ + // still not working in this format +/* -----\/----- EXCLUDED -----\/----- + integer adrindex; + if (P.UNCORE_RAM_SUPPORTED) begin + always @(posedge clk) begin + if (ResetMem) // program memory is sometimes reset + for (adrindex=0; adrindex<(P.UNCORE_RAM_RANGE>>1+(P.XLEN/32)); adrindex = adrindex+1) + dut.uncore.uncore.ram.ram.memory.RAM[adrindex] = '0; + end + end + + genvar adrindex2; + + if (P.BPRED_SUPPORTED & (P.BPRED_TYPE == `BP_LOCAL_AHEAD | P.BPRED_TYPE == `BP_LOCAL_REPAIR)) begin + for(adrindex2 = 0; adrindex2 < 2**P.BPRED_NUM_LHR; adrindex2++) + always @(posedge clk) begin + dut.core.ifu.bpred.bpred.Predictor.DirPredictor.BHT.mem[adrindex2] = 0; + end + end + + if (P.BPRED_SUPPORTED) begin + always @(posedge clk) + dut.core.ifu.bpred.bpred.TargetPredictor.memory.mem[0] = 0; + for(adrindex2 = 0; adrindex2 < 2**P.BTB_SIZE; adrindex2++) + always @(posedge clk) begin + dut.core.ifu.bpred.bpred.TargetPredictor.memory.mem[adrindex2] = 0; + end + for(adrindex2 = 0; adrindex2 < 2**P.BPRED_SIZE; adrindex2++) + always @(posedge clk) begin + dut.core.ifu.bpred.bpred.Predictor.DirPredictor.PHT.mem[adrindex2] = 0; + end + end + -----/\----- EXCLUDED -----/\----- */ + //////////////////////////////////////////////////////////////////////////////// // load memories with program image //////////////////////////////////////////////////////////////////////////////// - always @(posedge clk) begin - if (LoadMem) begin - if (P.SDC_SUPPORTED) begin + + integer IndexTemp; + if (P.SDC_SUPPORTED) begin + always @(posedge clk) begin + if (LoadMem) begin string romfilename, sdcfilename; romfilename = {"../tests/custom/fpga-test-sdc/bin/fpga-test-sdc.memfile"}; sdcfilename = {"../testbench/sdc/ramdisk2.hex"}; @@ -353,13 +395,41 @@ module testbench; //$readmemh(sdcfilename, sdcard.sdcard.FLASHmem); // shorten sdc timers for simulation //dut.uncore.uncore.sdc.SDC.LimitTimers = 1; - end - else if (P.IROM_SUPPORTED) $readmemh(memfilename, dut.core.ifu.irom.irom.rom.ROM); - else if (P.BUS_SUPPORTED) $readmemh(memfilename, dut.uncore.uncore.ram.ram.memory.RAM); - if (P.DTIM_SUPPORTED) $readmemh(memfilename, dut.core.lsu.dtim.dtim.ram.RAM); - $display("Read memfile %s", memfilename); + end end - end + end else if (P.IROM_SUPPORTED) begin + always @(posedge clk) begin + if (LoadMem) begin + $readmemh(memfilename, dut.core.ifu.irom.irom.rom.ROM); + end + end + end else if (P.BUS_SUPPORTED) begin + always @(posedge clk) begin + if (LoadMem) begin + $readmemh(memfilename, dut.uncore.uncore.ram.ram.memory.RAM); + end + if (CopyRAM) begin + for(IndexTemp = 0; IndexTemp < (P.UNCORE_RAM_RANGE)>>1+(P.XLEN/32); IndexTemp++) begin + //if(dut.uncore.uncore.ram.ram.memory.RAM[IndexTemp] === 'bx) break; // end copy early if at the end of the sig *** double check this will be valid for all tests. + testbench.DCacheFlushFSM.ShadowRAM[((P.UNCORE_RAM_BASE)>>1+(P.XLEN/32)) + IndexTemp] = dut.uncore.uncore.ram.ram.memory.RAM[IndexTemp]; + end + end + end + end + if (P.DTIM_SUPPORTED) begin + always @(posedge clk) begin + if (LoadMem) begin + $readmemh(memfilename, dut.core.lsu.dtim.dtim.ram.RAM); + $display("Read memfile %s", memfilename); + end + if (CopyRAM) begin + for(IndexTemp = 0; IndexTemp < (P.DTIM_RANGE)>>1+(P.XLEN/32); IndexTemp++) begin + //if(dut.core.lsu.dtim.dtim.ram.RAM[IndexTemp] === 'bx) break; // end copy early if at the end of the sig *** double check this will be valid for all tests. + testbench.DCacheFlushFSM.ShadowRAM[((P.DTIM_BASE)>>1+(P.XLEN/32)) + IndexTemp] = dut.core.lsu.dtim.dtim.ram.RAM[IndexTemp]; + end + end + end + end //////////////////////////////////////////////////////////////////////////////// // Actual hardware @@ -449,14 +519,15 @@ module testbench; logic ecf; // remove this once we don't rely on old Imperas tests with Ecalls if (P.ZICSR_SUPPORTED) assign ecf = dut.core.priv.priv.EcallFaultM; else assign ecf = 0; - assign DCacheFlushStart = ecf & + assign TestComplete = ecf & (dut.core.ieu.dp.regf.rf[3] == 1 | (dut.core.ieu.dp.regf.we3 & dut.core.ieu.dp.regf.a3 == 3 & dut.core.ieu.dp.regf.wd3 == 1)) | ((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" ); + //assign DCacheFlushStart = TestComplete; + DCacheFlushFSM #(P) DCacheFlushFSM(.clk(clk), .reset(reset), .start(DCacheFlushStart), .done(DCacheFlushDone)); task automatic CheckSignature; @@ -508,15 +579,24 @@ module testbench; testadr = ($unsigned(begin_signature_addr))/(P.XLEN/8); testadrNoBase = (begin_signature_addr - P.UNCORE_RAM_BASE)/(P.XLEN/8); /* verilator lint_off INFINITELOOP */ + /* verilator lint_off WIDTHXZEXPAND */ while (signature[i] !== 'bx) begin + /* verilator lint_on WIDTHXZEXPAND */ logic [P.XLEN-1:0] sig; - if (P.DTIM_SUPPORTED) sig = testbench.dut.core.lsu.dtim.dtim.ram.RAM[testadrNoBase+i]; - else if (P.UNCORE_RAM_SUPPORTED) sig = testbench.dut.uncore.uncore.ram.ram.memory.RAM[testadrNoBase+i]; + // ************************************** + // ***** BUG BUG BUG make sure RT undoes this. + //if (P.DTIM_SUPPORTED) sig = testbench.dut.core.lsu.dtim.dtim.ram.RAM[testadrNoBase+i]; + //else if (P.UNCORE_RAM_SUPPORTED) sig = testbench.dut.uncore.uncore.ram.ram.memory.RAM[testadrNoBase+i]; + if (P.UNCORE_RAM_SUPPORTED) sig = testbench.dut.uncore.uncore.ram.ram.memory.RAM[testadrNoBase+i]; + //if (P.UNCORE_RAM_SUPPORTED) sig = testbench.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] !== testbench.DCacheFlushFSM.ShadowRAM[testadr+i])) begin + //if (signature[i] !== sig & (signature[i] !== testbench.DCacheFlushFSM.ShadowRAM[testadr+i])) begin + if (signature[i] !== testbench.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", TestName, i, (testadr+i)*(P.XLEN/8), testbench.DCacheFlushFSM.ShadowRAM[testadr+i], sig, signature[i]); + //$display(" Error on test %s result %d: adr = %h sim (DTIM_SUPPORTED) = %h, signature = %h", + // TestName, i, (testadr+i)*(P.XLEN/8), testbench.DCacheFlushFSM.ShadowRAM[testadr+i], signature[i]); $stop; //***debug end i = i + 1;