package MemArbiter_Test; import Assert::*; import StmtFSM::*; import Testing::*; import Printf::*; import List::*; import Vector::*; import BuildVector::*; import MemArbiter::*; typedef UInt#(4) Addr; typedef struct { String name; Vector#(n, Maybe#(MemArbiterOp#(Addr))) reqs; Maybe#(Addr) forbid_addr; Vector#(n, Bool) want_grants; Maybe#(Addr) want_forbid_addr; } TestCase#(numeric type n) deriving (Bits, Eq); function Maybe#(MemArbiterOp#(Addr)) read(Addr addr); return tagged Valid MemArbiterOp{write: False, addr: addr}; endfunction function Maybe#(MemArbiterOp#(Addr)) write(Addr addr); return tagged Valid MemArbiterOp{write: True, addr: addr}; endfunction function Maybe#(MemArbiterOp#(Addr)) idle(); return tagged Invalid; endfunction function Maybe#(Addr) noForbid(); return tagged Invalid; endfunction function Maybe#(Addr) forbid(Addr a); return tagged Valid a; endfunction function Vector#(n, Bool) grant(Integer granted); function gen(idx); return idx == granted; endfunction return genWith(gen); endfunction function Vector#(n, Bool) noGrant(); return replicate(False); endfunction function TestCase#(n) testCase(String name, Vector#(n, Maybe#(MemArbiterOp#(Addr))) reqs, Maybe#(Addr) forbid_addr, Vector#(n, Bool) want_grants, Maybe#(Addr) want_forbid_addr); return TestCase{ name: name, reqs: reqs, forbid_addr: forbid_addr, want_grants: want_grants, want_forbid_addr: want_forbid_addr }; endfunction interface TB; method Action start(); (* always_ready *) method Bool done(); endinterface module mkArbiterTB(MemArbiter#(n, Addr) dut, Vector#(m, TestCase#(n)) tests, TB ifc); let cycles <- mkCycleCounter(); Reg#(Bit#(TLog#(m))) idx <- mkReg(0); Reg#(Bool) running <- mkReg(False); for (Integer i=0; i"); tagged Valid .a: return $format("%0d", a); endcase endfunction (* no_implicit_conditions, fire_when_enabled *) rule check (running); let test = tests[idx]; let reqs = test.reqs; let want_grants = test.want_grants; let want_forbid_addr = test.want_forbid_addr; Vector#(n, Bool) got_grants = newVector; for (Integer i=0; i