package DelayLine; import List::*; interface DelayLine#(type value); method Action _write (value v); method value _read(); method Bool ready(); endinterface module mkDelayLine(Integer delay_cycles, DelayLine#(a) ifc) provisos (Bits#(a, a_sz)); DelayLine#(a) ret = ?; if (delay_cycles == 0) begin RWire#(a) w <- mkRWire(); ret = (interface DelayLine; method Action _write(a value); w.wset(value); endmethod method a _read() if (w.wget matches tagged Valid .val); return val; endmethod method Bool ready(); return isValid(w.wget); endmethod endinterface); end else begin RWire#(a) inputVal <- mkRWire; List#(Reg#(Maybe#(a))) delay = tagged Nil; for (Integer i = 0; i < delay_cycles; i = i+1) begin let r <- mkReg(tagged Invalid); delay = cons(r, delay); end (* no_implicit_conditions, fire_when_enabled *) rule pump_line; delay[0] <= inputVal.wget(); for (Integer i = 0; i < delay_cycles-1; i = i+1) delay[i+1] <= delay[i]; endrule ret = (interface DelayLine; method Action _write(a value); inputVal.wset(value); endmethod method a _read() if (delay[delay_cycles-1] matches tagged Valid .val); return val; endmethod method Bool ready(); return isValid(delay[delay_cycles-1]); endmethod endinterface); end return ret; endmodule endpackage