From 4b6b34e131363d8eca9bb0114b76db9f2350236c Mon Sep 17 00:00:00 2001 From: David Anderson Date: Mon, 9 Sep 2024 11:15:43 -0700 Subject: [PATCH] vram/VRAMCore: add tests, fix bug found by same --- vram/VRAMCore.bsv | 4 +- vram/VRAMCore_Test.bsv | 196 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 198 insertions(+), 2 deletions(-) create mode 100644 vram/VRAMCore_Test.bsv diff --git a/vram/VRAMCore.bsv b/vram/VRAMCore.bsv index bc120d6..b704c95 100644 --- a/vram/VRAMCore.bsv +++ b/vram/VRAMCore.bsv @@ -120,7 +120,7 @@ module mkByteRAMArray(Integer num_chips, ByteRAM ifc); method Action put(ChipAddr chip_select, Bool write, ByteAddr addr, VRAMData data_in); for (Integer i=0; i 0); + dynamicAssert(write_cycle_time == 1, "write didn't happen every cycle"); + write_cycle_time.reset(); + + let data <- next_value(); + let req = VRAMRequest{ + addr: idx, + data: tagged Valid data + }; + dut.request.put(req); + + if (flags.verbose) + $display("%0d: write(%0d, %0d)", cycles.all, idx, data); + + if (remaining == 1) + $display("Wrote %0d values in %0d cycles", total, cycles); + remaining <= remaining-1; + idx <= idx+1; + endrule + + method Action start(VRAMAddr start_addr, VRAMAddr count) if (remaining == 0); + cycles.reset(); + write_cycle_time.reset(); + total <= count; + remaining <= count; + idx <= start_addr; + endmethod + + method Bool done(); + return remaining == 0; + endmethod +endmodule + +module mkReader(Server#(VRAMRequest, VRAMResponse) dut, ValFn next_value, Machine ifc); + let flags <- mkTestFlags(); + let cycles <- mkCycleCounter(); + + Reg#(VRAMAddr) total <- mkReg(0); + + Reg#(VRAMAddr) issue_remaining <- mkReg(0); + Reg#(VRAMAddr) issue_idx <- mkReg(0); + + Reg#(VRAMAddr) verify_remaining <- mkReg(0); + Reg#(VRAMAddr) verify_idx <- mkReg(0); + + rule issue_read (issue_remaining > 0); + let req = VRAMRequest{ + addr: issue_idx, + data: tagged Invalid + }; + dut.request.put(req); + + if (flags.verbose) + $display("%0d: issue_read(%0d)", cycles.all, issue_idx); + + if (issue_remaining == 1) + $display("Issued %0d reads in %0d cycles", total, cycles); + issue_remaining <= issue_remaining-1; + issue_idx <= issue_idx+1; + endrule + + rule verify_read (verify_remaining > 0); + let got <- dut.response.get(); + let want <- next_value(); + dynamicAssert(got.data == want, "wrong value seen during read"); + + if (flags.verbose) + $display("%0d: verify_read(%0d) = %0d, want %0d", cycles.all, verify_idx, got, want); + + if (verify_remaining == 1) + $display("Verified %0d reads in %0d cycles", total, cycles); + verify_remaining <= verify_remaining-1; + verify_idx <= verify_idx+1; + endrule + + method Action start(VRAMAddr start_addr, VRAMAddr count) if (issue_remaining == 0 && verify_remaining == 0); + cycles.reset(); + total <= count; + issue_remaining <= count; + verify_remaining <= count; + issue_idx <= start_addr; + verify_idx <= start_addr; + endmethod + + method Bool done(); + return issue_remaining == 0 && verify_remaining == 0; + endmethod +endmodule + +(* descending_urgency="writer.write,reader.issue_read" *) +module mkSimpleTest(VRAMCore dut, Stmt ret); + let winc <- mkIncrementingValue(); + let writer <- mkWriter(dut.portA, winc); + + let rinc <- mkIncrementingValue(); + let reader <- mkReader(dut.portA, rinc); + + return (seq + writer.start(3000, 6000); + await(writer.done); + + reader.start(3000, 6000); + await(reader.done); + endseq); +endmodule + +module mkTwoPortTest(VRAMCore dut, Stmt ret); + let winc <- mkIncrementingValue(); + let writer <- mkWriter(dut.portA, winc); + + let rinc <- mkIncrementingValue(); + let reader <- mkReader(dut.portB, rinc); + + return (seq + writer.start(0, 1000); + // Delay a little before starting the reader, so it's + // trailing the writer by a few addrs. + repeat (2) noAction; + reader.start(0, 1000); + await(writer.done); + await(reader.done); + endseq); +endmodule + +(* descending_urgency="simple.reader.issue_read,two_port.writer.write" *) +module mkTB(Empty); + let dut <- mkVRAMCore(112); + + let simple <- mkSimpleTest(dut); + let two_port <- mkTwoPortTest(dut); + + runTest(100000, + mkTest("VRAMCore", seq + mkTest("VRAMCore/simple", simple); + mkTest("VRAMCore/two_port", two_port); + endseq)); +endmodule + +endpackage