diplomacy: support := composition
This makes it possible to treat chained composition associatively. x := y :=? z :=* a ... It also makes it easy to chain multiple optional adapters: node :=? (Seq(a, b) ++ c ++ d)
This commit is contained in:
parent
b48ab985d0
commit
e894d64bca
@ -119,23 +119,51 @@ object BaseNode
|
||||
protected[diplomacy] var serial = 0
|
||||
}
|
||||
|
||||
// !!! rename the nodes we bind?
|
||||
case class NodeHandle[DI, UI, BI <: Data, DO, UO, BO <: Data]
|
||||
trait NoHandle
|
||||
case object NoHandleObject extends NoHandle
|
||||
|
||||
trait NodeHandle[DI, UI, BI <: Data, DO, UO, BO <: Data]
|
||||
extends InwardNodeHandle[DI, UI, BI] with OutwardNodeHandle[DO, UO, BO]
|
||||
{
|
||||
// connecting two full nodes => full node
|
||||
override def := [DX, UX, BX <: Data](h: NodeHandle[DX, UX, BX, DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): NodeHandle[DX, UX, BX, DO, UO, BO] = { inward.bind(h, BIND_ONCE); NodeHandle(h, this) }
|
||||
override def :*= [DX, UX, BX <: Data](h: NodeHandle[DX, UX, BX, DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): NodeHandle[DX, UX, BX, DO, UO, BO] = { inward.bind(h, BIND_STAR); NodeHandle(h, this) }
|
||||
override def :=* [DX, UX, BX <: Data](h: NodeHandle[DX, UX, BX, DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): NodeHandle[DX, UX, BX, DO, UO, BO] = { inward.bind(h, BIND_QUERY); NodeHandle(h, this) }
|
||||
override def :=? [DX, UX, BX <: Data](h: NodeHandle[DX, UX, BX, DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): NodeHandle[DX, UX, BX, DO, UO, BO] = { inward.bind(h, p(CardinalityInferenceDirectionKey)); NodeHandle(h, this) }
|
||||
// connecting a full node with an output => an output
|
||||
override def := (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): OutwardNodeHandle[DO, UO, BO] = { inward.bind(h, BIND_ONCE); this }
|
||||
override def :*= (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): OutwardNodeHandle[DO, UO, BO] = { inward.bind(h, BIND_STAR); this }
|
||||
override def :=* (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): OutwardNodeHandle[DO, UO, BO] = { inward.bind(h, BIND_QUERY); this }
|
||||
override def :=? (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): OutwardNodeHandle[DO, UO, BO] = { inward.bind(h, p(CardinalityInferenceDirectionKey)); this }
|
||||
}
|
||||
|
||||
object NodeHandle
|
||||
{
|
||||
def apply[DI, UI, BI <: Data, DO, UO, BO <: Data](i: InwardNodeHandle[DI, UI, BI], o: OutwardNodeHandle[DO, UO, BO]) = NodeHandlePair(i, o)
|
||||
}
|
||||
|
||||
case class NodeHandlePair[DI, UI, BI <: Data, DO, UO, BO <: Data]
|
||||
(inwardHandle: InwardNodeHandle[DI, UI, BI], outwardHandle: OutwardNodeHandle[DO, UO, BO])
|
||||
extends Object with InwardNodeHandle[DI, UI, BI] with OutwardNodeHandle[DO, UO, BO]
|
||||
extends NodeHandle[DI, UI, BI, DO, UO, BO]
|
||||
{
|
||||
val inward = inwardHandle.inward
|
||||
val outward = outwardHandle.outward
|
||||
}
|
||||
|
||||
trait InwardNodeHandle[DI, UI, BI <: Data]
|
||||
trait InwardNodeHandle[DI, UI, BI <: Data] extends NoHandle
|
||||
{
|
||||
protected[diplomacy] val inward: InwardNode[DI, UI, BI]
|
||||
def parentsIn: Seq[LazyModule] = inward.parents
|
||||
def := (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo) { inward.:=(h)(p, sourceInfo) }
|
||||
def :*= (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo) { inward.:*=(h)(p, sourceInfo) }
|
||||
def :=* (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo) { inward.:=*(h)(p, sourceInfo) }
|
||||
def :=? (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo) { inward.:=?(h)(p, sourceInfo) }
|
||||
// connecting an input node with a full nodes => an input node
|
||||
def := [DX, UX, BX <: Data](h: NodeHandle[DX, UX, BX, DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): InwardNodeHandle[DX, UX, BX] = { inward.bind(h, BIND_ONCE); h }
|
||||
def :*= [DX, UX, BX <: Data](h: NodeHandle[DX, UX, BX, DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): InwardNodeHandle[DX, UX, BX] = { inward.bind(h, BIND_STAR); h }
|
||||
def :=* [DX, UX, BX <: Data](h: NodeHandle[DX, UX, BX, DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): InwardNodeHandle[DX, UX, BX] = { inward.bind(h, BIND_QUERY); h }
|
||||
def :=? [DX, UX, BX <: Data](h: NodeHandle[DX, UX, BX, DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): InwardNodeHandle[DX, UX, BX] = { inward.bind(h, p(CardinalityInferenceDirectionKey)); h }
|
||||
// connecting input node with output node => no node
|
||||
def := (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): NoHandle = { inward.bind(h, BIND_ONCE); NoHandleObject }
|
||||
def :*= (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): NoHandle = { inward.bind(h, BIND_STAR); NoHandleObject }
|
||||
def :=* (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): NoHandle = { inward.bind(h, BIND_QUERY); NoHandleObject }
|
||||
def :=? (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): NoHandle = { inward.bind(h, p(CardinalityInferenceDirectionKey)); NoHandleObject }
|
||||
}
|
||||
|
||||
sealed trait NodeBinding
|
||||
@ -143,6 +171,15 @@ case object BIND_ONCE extends NodeBinding
|
||||
case object BIND_QUERY extends NodeBinding
|
||||
case object BIND_STAR extends NodeBinding
|
||||
|
||||
object NodeBinding
|
||||
{
|
||||
implicit def apply(card: CardinalityInferenceDirection.T): NodeBinding = card match {
|
||||
case CardinalityInferenceDirection.SOURCE_TO_SINK => BIND_QUERY
|
||||
case CardinalityInferenceDirection.SINK_TO_SOURCE => BIND_STAR
|
||||
case CardinalityInferenceDirection.NO_INFERENCE => BIND_ONCE
|
||||
}
|
||||
}
|
||||
|
||||
trait InwardNode[DI, UI, BI <: Data] extends BaseNode with InwardNodeHandle[DI, UI, BI]
|
||||
{
|
||||
protected[diplomacy] val inward = this
|
||||
@ -168,9 +205,11 @@ trait InwardNode[DI, UI, BI <: Data] extends BaseNode with InwardNodeHandle[DI,
|
||||
protected[diplomacy] val iStar: Int
|
||||
protected[diplomacy] val iPortMapping: Seq[(Int, Int)]
|
||||
protected[diplomacy] val iParams: Seq[UI]
|
||||
|
||||
protected[diplomacy] def bind(h: OutwardNodeHandle[DI, UI, BI], binding: NodeBinding)(implicit p: Parameters, sourceInfo: SourceInfo): Unit
|
||||
}
|
||||
|
||||
trait OutwardNodeHandle[DO, UO, BO <: Data]
|
||||
trait OutwardNodeHandle[DO, UO, BO <: Data] extends NoHandle
|
||||
{
|
||||
protected[diplomacy] val outward: OutwardNode[DO, UO, BO]
|
||||
def parentsOut: Seq[LazyModule] = outward.parents
|
||||
@ -215,7 +254,7 @@ sealed abstract class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data](
|
||||
protected[diplomacy] val numPO: Range.Inclusive,
|
||||
protected[diplomacy] val numPI: Range.Inclusive)(
|
||||
implicit valName: ValName)
|
||||
extends BaseNode with InwardNode[DI, UI, BI] with OutwardNode[DO, UO, BO]
|
||||
extends BaseNode with NodeHandle[DI, UI, BI, DO, UO, BO] with InwardNode[DI, UI, BI] with OutwardNode[DO, UO, BO]
|
||||
{
|
||||
protected[diplomacy] def resolveStar(iKnown: Int, oKnown: Int, iStar: Int, oStar: Int): (Int, Int)
|
||||
protected[diplomacy] def mapParamsD(n: Int, p: Seq[DI]): Seq[DO]
|
||||
@ -341,7 +380,7 @@ sealed abstract class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data](
|
||||
}
|
||||
|
||||
// connects the outward part of a node with the inward part of this node
|
||||
private def bind(h: OutwardNodeHandle[DI, UI, BI], binding: NodeBinding)(implicit p: Parameters, sourceInfo: SourceInfo) {
|
||||
protected[diplomacy] def bind(h: OutwardNodeHandle[DI, UI, BI], binding: NodeBinding)(implicit p: Parameters, sourceInfo: SourceInfo) {
|
||||
val x = this // x := y
|
||||
val y = h.outward
|
||||
val info = sourceLine(sourceInfo, " at ", "")
|
||||
@ -354,17 +393,6 @@ sealed abstract class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data](
|
||||
x.iPush(o, y, binding)
|
||||
}
|
||||
|
||||
override def := (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo) = bind(h, BIND_ONCE)
|
||||
override def :*= (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo) = bind(h, BIND_STAR)
|
||||
override def :=* (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo) = bind(h, BIND_QUERY)
|
||||
override def :=? (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo) = {
|
||||
p(CardinalityInferenceDirectionKey) match {
|
||||
case CardinalityInferenceDirection.SOURCE_TO_SINK => this :=* h
|
||||
case CardinalityInferenceDirection.SINK_TO_SOURCE => this :*= h
|
||||
case CardinalityInferenceDirection.NO_INFERENCE => this := h
|
||||
}
|
||||
}
|
||||
|
||||
// meta-data for printing the node graph
|
||||
protected[diplomacy] def inputs = (iPorts zip edgesIn) map { case ((_, n, p, _), e) =>
|
||||
val re = inner.render(e)
|
||||
|
@ -71,6 +71,12 @@ object TLBuffer
|
||||
buffer.node :=? x
|
||||
buffer.node
|
||||
}
|
||||
|
||||
def chain(depth: Int, name: Option[String] = None)(implicit p: Parameters): Seq[TLNode] = {
|
||||
val buffers = Seq.fill(depth) { LazyModule(new TLBuffer()) }
|
||||
name.foreach { n => buffers.zipWithIndex.foreach { case (b, i) => b.suggestName(s"${n}_${i}") } }
|
||||
buffers.map(_.node)
|
||||
}
|
||||
}
|
||||
|
||||
object TLNodeChain {
|
||||
|
@ -9,7 +9,7 @@ package object tilelink
|
||||
{
|
||||
type TLInwardNode = InwardNodeHandle[TLClientPortParameters, TLManagerPortParameters, TLBundle]
|
||||
type TLOutwardNode = OutwardNodeHandle[TLClientPortParameters, TLManagerPortParameters, TLBundle]
|
||||
type TLNode = TLInwardNode with TLOutwardNode
|
||||
type TLNode = NodeHandle[TLClientPortParameters, TLManagerPortParameters, TLBundle, TLClientPortParameters, TLManagerPortParameters, TLBundle]
|
||||
type TLAsyncInwardNode = InwardNodeHandle[TLAsyncClientPortParameters, TLAsyncManagerPortParameters, TLAsyncBundle]
|
||||
type TLAsyncOutwardNode = OutwardNodeHandle[TLAsyncClientPortParameters, TLAsyncManagerPortParameters, TLAsyncBundle]
|
||||
type TLRationalInwardNode = InwardNodeHandle[TLRationalClientPortParameters, TLRationalManagerPortParameters, TLRationalBundle]
|
||||
|
Loading…
Reference in New Issue
Block a user