vram/VRAM: add tests for the arbitration glue and the entire VRAM stack
This commit is contained in:
parent
8247661a38
commit
f7e3f36254
|
@ -16,6 +16,8 @@ export VRAMAddr, VRAMData, VRAMRequest(..), VRAMResponse(..);
|
|||
export VRAMServer(..);
|
||||
export VRAM(..), mkVRAM;
|
||||
|
||||
export mkArbitratedVRAMServers;
|
||||
|
||||
// A VRAMServer is a memory port.
|
||||
typedef Server#(VRAMRequest, VRAMResponse) VRAMServer;
|
||||
|
||||
|
|
|
@ -0,0 +1,136 @@
|
|||
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
|
Loading…
Reference in New Issue