1
0

tilelink2: allow 0-stage backpressure in combinational regmap

This commit is contained in:
Wesley W. Terpstra 2016-09-02 21:42:37 -07:00
parent 4746cf00ce
commit 6a378e79e3

View File

@ -10,14 +10,20 @@ object RegReadFn
// (ivalid: Bool, oready: Bool) => (iready: Bool, ovalid: Bool, data: UInt)
// iready may combinationally depend on oready
// all other combinational dependencies forbidden (e.g. ovalid <= ivalid)
// effects must become visible only on the cycle after ovalid && oready
// effects must become visible on the cycle after ovalid && oready
implicit def apply(x: (Bool, Bool) => (Bool, Bool, UInt)) =
new RegReadFn(false, x)
// (ofire: Bool) => (data: UInt)
// effects must become visible on the cycle after ofire
implicit def apply(x: Bool => UInt) =
// (ready: Bool) => (valid: Bool, data: UInt)
// valid must not combinationally depend on ready
// effects must become visible on the cycle after valid && ready
// ready is only guaranteed to stay high if fed by an Irrevocable (eg: TL2 or concurrency > 0)
// ... which is irrelevant if you can service the read immediately
// ... if irrevocable, you may start reading on rising ready and raise valid when done
// ... otherwise, use the more general in&out ready-valid method above
implicit def apply(x: Bool => (Bool, UInt)) =
new RegReadFn(true, { case (_, oready) =>
(Bool(true), Bool(true), x(oready))
val (ovalid, data) = x(oready)
(Bool(true), ovalid, data)
})
// read from a register
implicit def apply(x: UInt) =
@ -37,15 +43,20 @@ object RegWriteFn
// (ivalid: Bool, oready: Bool, data: UInt) => (iready: Bool, ovalid: Bool)
// iready may combinationally depend on both oready and data
// all other combinational dependencies forbidden (e.g. ovalid <= ivalid)
// effects must become visible only on the cycle after ovalid && oready
// effects must become visible on the cycle after ovalid && oready
implicit def apply(x: (Bool, Bool, UInt) => (Bool, Bool)) =
new RegWriteFn(false, x)
// (ofire: Bool, data: UInt) => ()
// effects must become visible on the cycle after ofire
implicit def apply(x: (Bool, UInt) => Unit) =
// (valid: Bool, data: UInt) => (ready: Bool)
// ready may combinationally depend on data (but not valid)
// effects must become visible on the cycle after valid && ready
// valid is only guaranteed to stay high if fed by an Irrevocable (eg: TL2 or concurrency > 0)
// ... which is irrelevant if you can service the write immediately
// ... if irrevocable, you may start writing on rising valid and raise ready when done
// ... otherwise, use the more general in&out ready-valid method above
implicit def apply(x: (Bool, UInt) => Bool) =
// combinational => data valid on oready
new RegWriteFn(true, { case (_, oready, data) =>
x(oready, data)
(Bool(true), Bool(true))
(Bool(true), x(oready, data))
})
// updates a register
implicit def apply(x: UInt) =