tilelink2: allow 0-stage backpressure in combinational regmap
This commit is contained in:
parent
4746cf00ce
commit
6a378e79e3
@ -10,14 +10,20 @@ object RegReadFn
|
|||||||
// (ivalid: Bool, oready: Bool) => (iready: Bool, ovalid: Bool, data: UInt)
|
// (ivalid: Bool, oready: Bool) => (iready: Bool, ovalid: Bool, data: UInt)
|
||||||
// iready may combinationally depend on oready
|
// iready may combinationally depend on oready
|
||||||
// all other combinational dependencies forbidden (e.g. ovalid <= ivalid)
|
// 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)) =
|
implicit def apply(x: (Bool, Bool) => (Bool, Bool, UInt)) =
|
||||||
new RegReadFn(false, x)
|
new RegReadFn(false, x)
|
||||||
// (ofire: Bool) => (data: UInt)
|
// (ready: Bool) => (valid: Bool, data: UInt)
|
||||||
// effects must become visible on the cycle after ofire
|
// valid must not combinationally depend on ready
|
||||||
implicit def apply(x: Bool => UInt) =
|
// 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) =>
|
new RegReadFn(true, { case (_, oready) =>
|
||||||
(Bool(true), Bool(true), x(oready))
|
val (ovalid, data) = x(oready)
|
||||||
|
(Bool(true), ovalid, data)
|
||||||
})
|
})
|
||||||
// read from a register
|
// read from a register
|
||||||
implicit def apply(x: UInt) =
|
implicit def apply(x: UInt) =
|
||||||
@ -37,15 +43,20 @@ object RegWriteFn
|
|||||||
// (ivalid: Bool, oready: Bool, data: UInt) => (iready: Bool, ovalid: Bool)
|
// (ivalid: Bool, oready: Bool, data: UInt) => (iready: Bool, ovalid: Bool)
|
||||||
// iready may combinationally depend on both oready and data
|
// iready may combinationally depend on both oready and data
|
||||||
// all other combinational dependencies forbidden (e.g. ovalid <= ivalid)
|
// 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)) =
|
implicit def apply(x: (Bool, Bool, UInt) => (Bool, Bool)) =
|
||||||
new RegWriteFn(false, x)
|
new RegWriteFn(false, x)
|
||||||
// (ofire: Bool, data: UInt) => ()
|
// (valid: Bool, data: UInt) => (ready: Bool)
|
||||||
// effects must become visible on the cycle after ofire
|
// ready may combinationally depend on data (but not valid)
|
||||||
implicit def apply(x: (Bool, UInt) => Unit) =
|
// 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) =>
|
new RegWriteFn(true, { case (_, oready, data) =>
|
||||||
x(oready, data)
|
(Bool(true), x(oready, data))
|
||||||
(Bool(true), Bool(true))
|
|
||||||
})
|
})
|
||||||
// updates a register
|
// updates a register
|
||||||
implicit def apply(x: UInt) =
|
implicit def apply(x: UInt) =
|
||||||
|
Loading…
Reference in New Issue
Block a user