gary/vram/VRAM_Test.bsv

137 lines
4.4 KiB
Plaintext

package VRAM_Test;
import Assert::*;
import StmtFSM::*;
import GetPut::*;
import ClientServer::*;
import Connectable::*;
import Vector::*;
import MemArbiter::*;
import Testing::*;
import VRAM::*;
interface FakeVRAM;
interface VRAMServer server;
method Action next_response(VRAMResponse resp);
method Maybe#(VRAMRequest) last_request();
endinterface
module mkFakeVRAM(FakeVRAM);
Reg#(Maybe#(VRAMRequest)) req <- mkReg(tagged Invalid);
Reg#(Maybe#(VRAMResponse)) resp <- mkReg(tagged Invalid);
interface VRAMServer server;
interface Put request;
method Action put(r);
req <= tagged Valid r;
endmethod
endinterface
interface Get response;
method ActionValue#(VRAMResponse) get() if (resp matches tagged Valid .respval &&& req matches tagged Valid .reqval &&& reqval.data matches tagged Invalid);
resp <= tagged Invalid;
return respval;
endmethod
endinterface
endinterface
method Action next_response(r) if (resp matches tagged Invalid);
resp <= tagged Valid r;
endmethod
method Maybe#(VRAMRequest) last_request();
return req;
endmethod
endmodule
module mkArbitratedVRAMServersTest(FSM);
let testflags <- mkTestFlags();
let cycles <- mkCycleCounter();
let vram <- mkFakeVRAM();
MemArbiter#(3, VRAMAddr) arb <- mkPriorityMemArbiter();
Vector#(3, VRAMServer) ports <- mkArbitratedVRAMServers(vram.server, arb);
function Action check_read(VRAMServer port, VRAMAddr want_addr, VRAMData want_data);
return action
let want_request = VRAMRequest{addr: want_addr, data: tagged Invalid};
if (testflags.verbose)
$display("Last received VRAM request: ", fshow(vram.last_request), " want ", fshow(want_request));
dynamicAssert(vram.last_request == tagged Valid want_request, "wrong request seen by vram for read");
let got <- port.response.get();
if (testflags.verbose)
$display("VRAM.read() = %0d, want %0d", got.data, want_data);
dynamicAssert(got.data == want_data, "wrong data seen in vram read");
endaction;
endfunction
function Action check_write(VRAMAddr want_addr, VRAMData data);
return action
let want = VRAMRequest{addr: want_addr, data: tagged Valid data};
if (testflags.verbose)
$display("Last received VRAM request: ", fshow(vram.last_request), " want ", fshow(want));
dynamicAssert(vram.last_request == tagged Valid want, "wrong request seen by vram for write");
endaction;
endfunction
let fsm <- mkFSM(seq
// Single write
ports[1].request.put(VRAMRequest{addr: 123, data: tagged Valid 42});
check_write(123, 42);
// Single read
vram.next_response(VRAMResponse{data: 23});
ports[1].request.put(VRAMRequest{addr: 124, data: tagged Invalid});
check_read(ports[1], 124, 23);
// Concurrent ops, process port 1 response first to check
// buffering allows port 0 op to finish and port 1 to proceed
vram.next_response(VRAMResponse{data: 11});
par
vram.next_response(VRAMResponse{data: 66});
ports[0].request.put(VRAMRequest{addr: 123, data: tagged Invalid});
ports[1].request.put(VRAMRequest{addr: 125, data: tagged Invalid});
endpar
check_read(ports[1], 125, 66);
check_read(ports[0], 125, 11); // note, 125 because the last op is still port 1's read
endseq);
return fsm;
endmodule
module mkTestFull(FSM);
let testflags <- mkTestFlags();
let dut <- mkVRAM(4);
let fsm <- mkFSM(seq
dut.cpu.request.put(VRAMRequest{addr: 1, data: tagged Valid 42});
dut.cpu.request.put(VRAMRequest{addr: 1, data: tagged Invalid});
action
let resp <- dut.cpu.response.get();
if (testflags.verbose)
$display("vram read: ", fshow(resp));
dynamicAssert(resp.data == 42, "wrong data read after writing");
endaction
endseq);
return fsm;
endmodule
module mkTB();
let testGlue <- mkArbitratedVRAMServersTest();
let testFull <- mkTestFull();
runTest(100,
mkTest("VRAM", seq
mkTest("VRAM/Glue", seq
testGlue.start();
await(testGlue.done);
endseq);
mkTest("VRAM/Full", seq
testFull.start();
await(testFull.done);
endseq);
endseq));
endmodule
endpackage