diplomacy: include edge type in inward/outward node handles
This is necessary capture the node implementation in the handle, which is in turn necessary to support cloning a Node.
This commit is contained in:
		| @@ -122,50 +122,53 @@ object BaseNode | ||||
| 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] | ||||
| trait NodeHandle[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data] | ||||
|   extends InwardNodeHandle[DI, UI, EI, BI] with OutwardNodeHandle[DO, UO, EO, 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] = { 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] = { 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] = { 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] = { bind(h, p(CardinalityInferenceDirectionKey)); NodeHandle(h, this) } | ||||
|   override def :=  [DX, UX, EX, BX <: Data, EY](h: NodeHandle[DX, UX, EX, BX, DI, UI, EY, BI])(implicit p: Parameters, sourceInfo: SourceInfo): NodeHandle[DX, UX, EX, BX, DO, UO, EO, BO] = { bind(h, BIND_ONCE);  NodeHandle(h, this) } | ||||
|   override def :*= [DX, UX, EX, BX <: Data, EY](h: NodeHandle[DX, UX, EX, BX, DI, UI, EY, BI])(implicit p: Parameters, sourceInfo: SourceInfo): NodeHandle[DX, UX, EX, BX, DO, UO, EO, BO] = { bind(h, BIND_STAR);  NodeHandle(h, this) } | ||||
|   override def :=* [DX, UX, EX, BX <: Data, EY](h: NodeHandle[DX, UX, EX, BX, DI, UI, EY, BI])(implicit p: Parameters, sourceInfo: SourceInfo): NodeHandle[DX, UX, EX, BX, DO, UO, EO, BO] = { bind(h, BIND_QUERY); NodeHandle(h, this) } | ||||
|   override def :=? [DX, UX, EX, BX <: Data, EY](h: NodeHandle[DX, UX, EX, BX, DI, UI, EY, BI])(implicit p: Parameters, sourceInfo: SourceInfo): NodeHandle[DX, UX, EX, BX, DO, UO, EO, BO] = { 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] = { bind(h, BIND_ONCE);  this } | ||||
|   override def :*= (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): OutwardNodeHandle[DO, UO, BO] = { bind(h, BIND_STAR);  this } | ||||
|   override def :=* (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): OutwardNodeHandle[DO, UO, BO] = { bind(h, BIND_QUERY); this } | ||||
|   override def :=? (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): OutwardNodeHandle[DO, UO, BO] = { bind(h, p(CardinalityInferenceDirectionKey)); this } | ||||
|   override def :=  [EY](h: OutwardNodeHandle[DI, UI, EY, BI])(implicit p: Parameters, sourceInfo: SourceInfo): OutwardNodeHandle[DO, UO, EO, BO] = { bind(h, BIND_ONCE);  this } | ||||
|   override def :*= [EY](h: OutwardNodeHandle[DI, UI, EY, BI])(implicit p: Parameters, sourceInfo: SourceInfo): OutwardNodeHandle[DO, UO, EO, BO] = { bind(h, BIND_STAR);  this } | ||||
|   override def :=* [EY](h: OutwardNodeHandle[DI, UI, EY, BI])(implicit p: Parameters, sourceInfo: SourceInfo): OutwardNodeHandle[DO, UO, EO, BO] = { bind(h, BIND_QUERY); this } | ||||
|   override def :=? [EY](h: OutwardNodeHandle[DI, UI, EY, BI])(implicit p: Parameters, sourceInfo: SourceInfo): OutwardNodeHandle[DO, UO, EO, BO] = { 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) | ||||
|   def apply[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data](i: InwardNodeHandle[DI, UI, EI, BI], o: OutwardNodeHandle[DO, UO, EO, BO]) = new 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 NodeHandle[DI, UI, BI, DO, UO, BO] | ||||
| class NodeHandlePair[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data] | ||||
|   (inwardHandle: InwardNodeHandle[DI, UI, EI, BI], outwardHandle: OutwardNodeHandle[DO, UO, EO, BO]) | ||||
|   extends NodeHandle[DI, UI, EI, BI, DO, UO, EO, BO] | ||||
| { | ||||
|   val inward = inwardHandle.inward | ||||
|   val outward = outwardHandle.outward | ||||
|   def inner = inwardHandle.inner | ||||
|   def outer = outwardHandle.outer | ||||
| } | ||||
|  | ||||
| trait InwardNodeHandle[DI, UI, BI <: Data] extends NoHandle | ||||
| trait InwardNodeHandle[DI, UI, EI, BI <: Data] extends NoHandle | ||||
| { | ||||
|   def inward: InwardNode[DI, UI, BI] | ||||
|   def parentsIn: Seq[LazyModule] = inward.parents | ||||
|   def bind(h: OutwardNodeHandle[DI, UI, BI], binding: NodeBinding)(implicit p: Parameters, sourceInfo: SourceInfo): Unit = inward.bind(h.outward, binding) | ||||
|   def inner: InwardNodeImp[DI, UI, EI, BI] | ||||
|  | ||||
|   protected def bind[EY](h: OutwardNodeHandle[DI, UI, EY, BI], binding: NodeBinding)(implicit p: Parameters, sourceInfo: SourceInfo): Unit = inward.bind(h.outward, binding) | ||||
|  | ||||
|   // 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] = { 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] = { 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] = { 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] = { bind(h, p(CardinalityInferenceDirectionKey)); h } | ||||
|   def :=  [DX, UX, EX, BX <: Data, EY](h: NodeHandle[DX, UX, EX, BX, DI, UI, EY, BI])(implicit p: Parameters, sourceInfo: SourceInfo): InwardNodeHandle[DX, UX, EX, BX] = { bind(h, BIND_ONCE);  h } | ||||
|   def :*= [DX, UX, EX, BX <: Data, EY](h: NodeHandle[DX, UX, EX, BX, DI, UI, EY, BI])(implicit p: Parameters, sourceInfo: SourceInfo): InwardNodeHandle[DX, UX, EX, BX] = { bind(h, BIND_STAR);  h } | ||||
|   def :=* [DX, UX, EX, BX <: Data, EY](h: NodeHandle[DX, UX, EX, BX, DI, UI, EY, BI])(implicit p: Parameters, sourceInfo: SourceInfo): InwardNodeHandle[DX, UX, EX, BX] = { bind(h, BIND_QUERY); h } | ||||
|   def :=? [DX, UX, EX, BX <: Data, EY](h: NodeHandle[DX, UX, EX, BX, DI, UI, EY, BI])(implicit p: Parameters, sourceInfo: SourceInfo): InwardNodeHandle[DX, UX, EX, BX] = { 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 = { bind(h, BIND_ONCE);  NoHandleObject } | ||||
|   def :*= (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): NoHandle = { bind(h, BIND_STAR);  NoHandleObject } | ||||
|   def :=* (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): NoHandle = { bind(h, BIND_QUERY); NoHandleObject } | ||||
|   def :=? (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): NoHandle = { bind(h, p(CardinalityInferenceDirectionKey)); NoHandleObject } | ||||
|   def :=  [EY](h: OutwardNodeHandle[DI, UI, EY, BI])(implicit p: Parameters, sourceInfo: SourceInfo): NoHandle = { bind(h, BIND_ONCE);  NoHandleObject } | ||||
|   def :*= [EY](h: OutwardNodeHandle[DI, UI, EY, BI])(implicit p: Parameters, sourceInfo: SourceInfo): NoHandle = { bind(h, BIND_STAR);  NoHandleObject } | ||||
|   def :=* [EY](h: OutwardNodeHandle[DI, UI, EY, BI])(implicit p: Parameters, sourceInfo: SourceInfo): NoHandle = { bind(h, BIND_QUERY); NoHandleObject } | ||||
|   def :=? [EY](h: OutwardNodeHandle[DI, UI, EY, BI])(implicit p: Parameters, sourceInfo: SourceInfo): NoHandle = { bind(h, p(CardinalityInferenceDirectionKey)); NoHandleObject } | ||||
| } | ||||
|  | ||||
| sealed trait NodeBinding | ||||
| @@ -182,10 +185,8 @@ object NodeBinding | ||||
|   } | ||||
| } | ||||
|  | ||||
| trait InwardNode[DI, UI, BI <: Data] extends BaseNode with InwardNodeHandle[DI, UI, BI] | ||||
| trait InwardNode[DI, UI, BI <: Data] extends BaseNode | ||||
| { | ||||
|   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}") | ||||
| @@ -211,16 +212,14 @@ trait InwardNode[DI, UI, BI <: Data] extends BaseNode with InwardNodeHandle[DI, | ||||
|   protected[diplomacy] def bind(h: OutwardNode[DI, UI, BI], binding: NodeBinding)(implicit p: Parameters, sourceInfo: SourceInfo): Unit | ||||
| } | ||||
|  | ||||
| trait OutwardNodeHandle[DO, UO, BO <: Data] extends NoHandle | ||||
| trait OutwardNodeHandle[DO, UO, EO, BO <: Data] extends NoHandle | ||||
| { | ||||
|   def outward: OutwardNode[DO, UO, BO] | ||||
|   def parentsOut: Seq[LazyModule] = outward.parents | ||||
|   def outer: OutwardNodeImp[DO, UO, EO, BO] | ||||
| } | ||||
|  | ||||
| trait OutwardNode[DO, UO, BO <: Data] extends BaseNode with OutwardNodeHandle[DO, UO, BO] | ||||
| trait OutwardNode[DO, UO, BO <: Data] extends BaseNode | ||||
| { | ||||
|   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}") | ||||
| @@ -251,13 +250,16 @@ case class UpwardCycleException(loop: Seq[String] = Nil) extends CycleException( | ||||
|  | ||||
| case class Edges[EI, EO](in: EI, out: EO) | ||||
| sealed abstract class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data]( | ||||
|   inner: InwardNodeImp [DI, UI, EI, BI], | ||||
|   outer: OutwardNodeImp[DO, UO, EO, BO])( | ||||
|   val inner: InwardNodeImp [DI, UI, EI, BI], | ||||
|   val outer: OutwardNodeImp[DO, UO, EO, BO])( | ||||
|   protected[diplomacy] val numPO: Range.Inclusive, | ||||
|   protected[diplomacy] val numPI: Range.Inclusive)( | ||||
|   implicit valName: ValName) | ||||
|   extends BaseNode with NodeHandle[DI, UI, BI, DO, UO, BO] with InwardNode[DI, UI, BI] with OutwardNode[DO, UO, BO] | ||||
|   extends BaseNode with NodeHandle[DI, UI, EI, BI, DO, UO, EO, BO] with InwardNode[DI, UI, BI] with OutwardNode[DO, UO, BO] | ||||
| { | ||||
|   val inward = this | ||||
|   val outward = this | ||||
|  | ||||
|   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] | ||||
|   protected[diplomacy] def mapParamsU(n: Int, p: Seq[UO]): Seq[UI] | ||||
|   | ||||
| @@ -7,7 +7,7 @@ import freechips.rocketchip.config.Parameters | ||||
|  | ||||
| package object diplomacy | ||||
| { | ||||
|   type SimpleNodeHandle[D, U, B <: Chisel.Data] = NodeHandle[D, U, B, D, U, B] | ||||
|   type SimpleNodeHandle[D, U, E, B <: Chisel.Data] = NodeHandle[D, U, E, B, D, U, E, B] | ||||
|  | ||||
|   def sourceLine(sourceInfo: SourceInfo, prefix: String = " (", suffix: String = ")") = sourceInfo match { | ||||
|     case SourceLine(filename, line, col) => s"$prefix$filename:$line:$col$suffix" | ||||
|   | ||||
		Reference in New Issue
	
	Block a user