diff --git a/src/main/scala/diplomacy/Nodes.scala b/src/main/scala/diplomacy/Nodes.scala index 8906f64b..06103b3c 100644 --- a/src/main/scala/diplomacy/Nodes.scala +++ b/src/main/scala/diplomacy/Nodes.scala @@ -4,10 +4,27 @@ package freechips.rocketchip.diplomacy import Chisel._ import chisel3.internal.sourceinfo.SourceInfo -import freechips.rocketchip.config.Parameters +import freechips.rocketchip.config.{Parameters,Field} import freechips.rocketchip.util.HeterogeneousBag import scala.collection.mutable.ListBuffer +object CardinalityInferenceDirection { + val cases = Seq(SOURCE_TO_SINK, SINK_TO_SOURCE, NO_INFERENCE) + sealed trait T { + def flip = this match { + case SOURCE_TO_SINK => SINK_TO_SOURCE + case SINK_TO_SOURCE => SOURCE_TO_SINK + case NO_INFERENCE => NO_INFERENCE + } + } + + case object SOURCE_TO_SINK extends T + case object SINK_TO_SOURCE extends T + case object NO_INFERENCE extends T +} + +case object CardinalityInferenceDirectionKey extends Field[CardinalityInferenceDirection.T] + // DI = Downwards flowing Parameters received on the inner side of the node // UI = Upwards flowing Parameters generated by the inner side of the node // EI = Edge Parameters describing a connection on the inner side of the node @@ -84,6 +101,8 @@ trait InwardNodeHandle[DI, UI, BI <: Data] inward.:*=(h)(p, sourceInfo) def :=* (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): Option[MonitorBase] = inward.:=*(h)(p, sourceInfo) + def :=? (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): Option[MonitorBase] = + inward.:=?(h)(p, sourceInfo) } sealed trait NodeBinding @@ -264,6 +283,14 @@ abstract class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data]( override def := (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): Option[MonitorBase] = bind(h, BIND_ONCE, true) override def :*= (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): Option[MonitorBase] = bind(h, BIND_STAR, true) override def :=* (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): Option[MonitorBase] = bind(h, BIND_QUERY, true) + override def :=? (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): Option[MonitorBase] = { + p.lift(CardinalityInferenceDirectionKey) match { + case Some(CardinalityInferenceDirection.SOURCE_TO_SINK) => this :=* h + case Some(CardinalityInferenceDirection.SINK_TO_SOURCE) => this :*= h + case Some(CardinalityInferenceDirection.NO_INFERENCE) => this := h + case None => this := h + } + } def connectButDontMonitor(h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): Option[MonitorBase] = bind(h, BIND_ONCE, false) def connectButDontMonitorSlaves(h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): Option[MonitorBase] = bind(h, BIND_STAR, false) diff --git a/src/main/scala/diplomacy/package.scala b/src/main/scala/diplomacy/package.scala index 64219a1c..0567f2fa 100644 --- a/src/main/scala/diplomacy/package.scala +++ b/src/main/scala/diplomacy/package.scala @@ -3,6 +3,7 @@ package freechips.rocketchip import chisel3.internal.sourceinfo.{SourceInfo, SourceLine, UnlocatableSourceInfo} +import freechips.rocketchip.config.Parameters package object diplomacy { @@ -20,4 +21,20 @@ package object diplomacy bitIndexes(x.clearBit(lowest), lowest +: tail) } } + + def LeftStar[T](body: Parameters => T)(implicit p: Parameters) = body(p.alterPartial { + case CardinalityInferenceDirectionKey => CardinalityInferenceDirection.SINK_TO_SOURCE + }) + def RightStar[T](body: Parameters => T)(implicit p: Parameters) = body(p.alterPartial { + case CardinalityInferenceDirectionKey => CardinalityInferenceDirection.SOURCE_TO_SINK + }) + def NoStar[T](body: Parameters => T)(implicit p: Parameters) = body(p.alterPartial { + case CardinalityInferenceDirectionKey => CardinalityInferenceDirection.NO_INFERENCE + }) + def FlipStar[T](body: Parameters => T)(implicit p: Parameters) = body(p.alterPartial { + case CardinalityInferenceDirectionKey => p + .lift(CardinalityInferenceDirectionKey) + .map(_.flip) + .getOrElse(CardinalityInferenceDirection.NO_INFERENCE) + }) }