package Testing; import Assert::*; import StmtFSM::*; import Cntrs::*; // A CycleCounter keeps a count of total elapsed cycles in a // simulation, as well as cycles since the last reset. interface CycleCounter; // _read returns the number of cycles since the last time reset() // was called. method Bit#(32) _read(); // reset resets the cycle counter. The counter will read 1 on the // cycle following the call to reset. method Action reset(); // all returns the number of cycles elapsed since simulation start, // for use in $display and the like. method Bit#(32) all(); endinterface module mkCycleCounter(CycleCounter); let total <- mkCount(0); let cnt <- mkCount(0); (* no_implicit_conditions, fire_when_enabled *) rule count_up; cnt.incr(1); total.incr(1); endrule method _read = cnt._read; method Action reset(); cnt.update(0); endmethod method all = total._read; endmodule interface TestFlags; method Bool verbose(); endinterface module mkTestFlags(TestFlags); Wire#(Bool) verbose_val <- mkBypassWire(); rule every; let v <- $test$plusargs("v"); verbose_val <= v; endrule method verbose = verbose_val; endmodule // mkTest runs the given test, printing status text before and after // the run. Tests can be nested. function Stmt mkTest(String name, Stmt test); seq $display("RUN %s", name); test; $display("OK %s", name); endseq; endfunction // runTest runs the given test with a timeout. module runTest(Integer cycle_limit, Stmt test, Empty ifc); Bit#(32) max = fromInteger(cycle_limit); let cnt <- mkCount(0); (* no_implicit_conditions, fire_when_enabled *) rule cycle_deadline; dynamicAssert(cnt < max, "Test timed out"); cnt.incr(1); endrule mkAutoFSM(seq $display("Running test with %0d cycle timeout", max); test; endseq); endmodule endpackage