diff --git a/src/main/scala/diplomacy/Nodes.scala b/src/main/scala/diplomacy/Nodes.scala index 3796f5ec..3e739048 100644 --- a/src/main/scala/diplomacy/Nodes.scala +++ b/src/main/scala/diplomacy/Nodes.scala @@ -50,8 +50,21 @@ abstract class BaseNode protected[diplomacy] def colour: String } -trait InwardNode[DI, UI, BI <: Data] extends BaseNode +case class NodeHandle[DI, UI, BI <: Data, DO, UO, BO <: Data] + (inward: InwardNode[DI, UI, BI], outward: OutwardNode[DO, UO, BO]) + extends Object with InwardNodeHandle[DI, UI, BI] with OutwardNodeHandle[DO, UO, BO] + +trait InwardNodeHandle[DI, UI, BI <: Data] { + val inward: InwardNode[DI, UI, BI] + def := (h: OutwardNodeHandle[DI, UI, BI])(implicit sourceInfo: SourceInfo): Option[LazyModule] = + inward.:=(h)(sourceInfo) +} + +trait InwardNode[DI, UI, BI <: Data] extends BaseNode with InwardNodeHandle[DI, UI, BI] +{ + val inward = this + protected[diplomacy] val numPI: Range.Inclusive require (!numPI.isEmpty, s"No number of inputs would be acceptable to ${name}${lazyModule.line}") require (numPI.start >= 0, s"${name} accepts a negative number of inputs${lazyModule.line}") @@ -75,8 +88,15 @@ trait InwardNode[DI, UI, BI <: Data] extends BaseNode protected[diplomacy] def iConnect: Vec[BI] } -trait OutwardNode[DO, UO, BO <: Data] extends BaseNode +trait OutwardNodeHandle[DO, UO, BO <: Data] { + val outward: OutwardNode[DO, UO, BO] +} + +trait OutwardNode[DO, UO, BO <: Data] extends BaseNode with OutwardNodeHandle[DO, UO, BO] +{ + val outward = this + protected[diplomacy] val numPO: Range.Inclusive require (!numPO.isEmpty, s"No number of outputs would be acceptable to ${name}${lazyModule.line}") require (numPO.start >= 0, s"${name} accepts a negative number of outputs${lazyModule.line}") @@ -136,8 +156,9 @@ class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data]( def iConnect = bundleIn // connects the outward part of a node with the inward part of this node - def := (y: OutwardNode[DI, UI, BI])(implicit sourceInfo: SourceInfo): Option[LazyModule] = { + override def := (h: OutwardNodeHandle[DI, UI, BI])(implicit sourceInfo: SourceInfo): Option[LazyModule] = { val x = this // x := y + val y = h.outward val info = sourceLine(sourceInfo, " at ", "") require (!LazyModule.stack.isEmpty, s"${y.name} cannot be connected to ${x.name} outside of LazyModule scope" + info) val i = x.iPushed diff --git a/src/main/scala/uncore/axi4/package.scala b/src/main/scala/uncore/axi4/package.scala index 4ea7c9ab..6a382b6d 100644 --- a/src/main/scala/uncore/axi4/package.scala +++ b/src/main/scala/uncore/axi4/package.scala @@ -5,5 +5,5 @@ import diplomacy._ package object axi4 { - type AXI4OutwardNode = OutwardNode[AXI4MasterPortParameters, AXI4SlavePortParameters, AXI4Bundle] + type AXI4OutwardNode = OutwardNodeHandle[AXI4MasterPortParameters, AXI4SlavePortParameters, AXI4Bundle] } diff --git a/src/main/scala/uncore/tilelink2/package.scala b/src/main/scala/uncore/tilelink2/package.scala index a0490d7e..e996f2ba 100644 --- a/src/main/scala/uncore/tilelink2/package.scala +++ b/src/main/scala/uncore/tilelink2/package.scala @@ -5,9 +5,9 @@ import diplomacy._ package object tilelink2 { - type TLOutwardNode = OutwardNode[TLClientPortParameters, TLManagerPortParameters, TLBundle] - type TLAsyncOutwardNode = OutwardNode[TLAsyncClientPortParameters, TLAsyncManagerPortParameters, TLAsyncBundle] - type IntOutwardNode = OutwardNode[IntSourcePortParameters, IntSinkPortParameters, Vec[Bool]] + type TLOutwardNode = OutwardNodeHandle[TLClientPortParameters, TLManagerPortParameters, TLBundle] + type TLAsyncOutwardNode = OutwardNodeHandle[TLAsyncClientPortParameters, TLAsyncManagerPortParameters, TLAsyncBundle] + type IntOutwardNode = OutwardNodeHandle[IntSourcePortParameters, IntSinkPortParameters, Vec[Bool]] def OH1ToUInt(x: UInt) = OHToUInt((x << 1 | UInt(1)) ^ x) def UIntToOH1(x: UInt, width: Int) = ~(SInt(-1, width=width).asUInt << x)(width-1, 0) def trailingZeros(x: Int) = if (x > 0) Some(log2Ceil(x & -x)) else None