diplomacy: remove the :=? operator in favour of magic :*=* (#1139)
The reason for the :=? operator was for when you have an adapter chain whose direction of cardinality you could not know. We used explicit directives to tell these compositions which way to go. Unfortunately, that makes the API leaky. You think the chain of adapters is just one adapter, but you have to use strange Cardinality scopes to use it. That's just bad. The new :*=* just automagically figures it out from the graph.
This commit is contained in:
parent
dedf396915
commit
b8098d18be
@ -55,7 +55,7 @@ trait HasCrossingMethods extends LazyModule with LazyScope
|
|||||||
lazy val asink = LazyModule(new TLAsyncCrossingSink(depth, sync))
|
lazy val asink = LazyModule(new TLAsyncCrossingSink(depth, sync))
|
||||||
val source = if (out) this { asource } else asource
|
val source = if (out) this { asource } else asource
|
||||||
val sink = if (out) asink else this { asink }
|
val sink = if (out) asink else this { asink }
|
||||||
sink.node :=? source.node
|
sink.node :*=* source.node
|
||||||
checks = CrossingCheck(out, source.node, sink.node) :: checks
|
checks = CrossingCheck(out, source.node, sink.node) :: checks
|
||||||
NodeHandle(source.node, sink.node)
|
NodeHandle(source.node, sink.node)
|
||||||
}
|
}
|
||||||
@ -65,7 +65,7 @@ trait HasCrossingMethods extends LazyModule with LazyScope
|
|||||||
lazy val rsink = LazyModule(new TLRationalCrossingSink(if (out) direction else direction.flip))
|
lazy val rsink = LazyModule(new TLRationalCrossingSink(if (out) direction else direction.flip))
|
||||||
val source = if (out) this { rsource } else rsource
|
val source = if (out) this { rsource } else rsource
|
||||||
val sink = if (out) rsink else this { rsink }
|
val sink = if (out) rsink else this { rsink }
|
||||||
sink.node :=? source.node
|
sink.node :*=* source.node
|
||||||
checks = CrossingCheck(out, source.node, sink.node) :: checks
|
checks = CrossingCheck(out, source.node, sink.node) :: checks
|
||||||
NodeHandle(source.node, sink.node)
|
NodeHandle(source.node, sink.node)
|
||||||
}
|
}
|
||||||
@ -102,7 +102,7 @@ trait HasCrossingMethods extends LazyModule with LazyScope
|
|||||||
lazy val axi4asink = LazyModule(new AXI4AsyncCrossingSink(depth, sync))
|
lazy val axi4asink = LazyModule(new AXI4AsyncCrossingSink(depth, sync))
|
||||||
val source = if (out) this { axi4asource } else axi4asource
|
val source = if (out) this { axi4asource } else axi4asource
|
||||||
val sink = if (out) axi4asink else this { axi4asink }
|
val sink = if (out) axi4asink else this { axi4asink }
|
||||||
sink.node :=? source.node
|
sink.node :*=* source.node
|
||||||
checks = CrossingCheck(out, source.node, sink.node) :: checks
|
checks = CrossingCheck(out, source.node, sink.node) :: checks
|
||||||
NodeHandle(source.node, sink.node)
|
NodeHandle(source.node, sink.node)
|
||||||
}
|
}
|
||||||
@ -131,7 +131,7 @@ trait HasCrossingMethods extends LazyModule with LazyScope
|
|||||||
lazy val intssink = LazyModule(new IntSyncCrossingSink(0))
|
lazy val intssink = LazyModule(new IntSyncCrossingSink(0))
|
||||||
val source = if (out) this { intssource } else intssource
|
val source = if (out) this { intssource } else intssource
|
||||||
val sink = if (out) intssink else this { intssink }
|
val sink = if (out) intssink else this { intssink }
|
||||||
sink.node :=? source.node
|
sink.node :*=* source.node
|
||||||
checks = CrossingCheck(out, source.node, sink.node) :: checks
|
checks = CrossingCheck(out, source.node, sink.node) :: checks
|
||||||
NodeHandle(source.node, sink.node)
|
NodeHandle(source.node, sink.node)
|
||||||
}
|
}
|
||||||
@ -141,7 +141,7 @@ trait HasCrossingMethods extends LazyModule with LazyScope
|
|||||||
lazy val intasink = LazyModule(new IntSyncCrossingSink(sync))
|
lazy val intasink = LazyModule(new IntSyncCrossingSink(sync))
|
||||||
val source = if (out) this { intasource } else intasource
|
val source = if (out) this { intasource } else intasource
|
||||||
val sink = if (out) intasink else this { intasink }
|
val sink = if (out) intasink else this { intasink }
|
||||||
sink.node :=? source.node
|
sink.node :*=* source.node
|
||||||
checks = CrossingCheck(out, source.node, sink.node) :: checks
|
checks = CrossingCheck(out, source.node, sink.node) :: checks
|
||||||
NodeHandle(source.node, sink.node)
|
NodeHandle(source.node, sink.node)
|
||||||
}
|
}
|
||||||
@ -151,7 +151,7 @@ trait HasCrossingMethods extends LazyModule with LazyScope
|
|||||||
lazy val intrsink = LazyModule(new IntSyncCrossingSink(1))
|
lazy val intrsink = LazyModule(new IntSyncCrossingSink(1))
|
||||||
val source = if (out) this { intrsource } else intrsource
|
val source = if (out) this { intrsource } else intrsource
|
||||||
val sink = if (out) intrsink else this { intrsink }
|
val sink = if (out) intrsink else this { intrsink }
|
||||||
sink.node :=? source.node
|
sink.node :*=* source.node
|
||||||
checks = CrossingCheck(out, source.node, sink.node) :: checks
|
checks = CrossingCheck(out, source.node, sink.node) :: checks
|
||||||
NodeHandle(source.node, sink.node)
|
NodeHandle(source.node, sink.node)
|
||||||
}
|
}
|
||||||
|
@ -28,12 +28,12 @@ class FrontBus(params: FrontBusParams)(implicit p: Parameters) extends TLBusWrap
|
|||||||
master_fixer.node :=* master_buffer.node
|
master_fixer.node :=* master_buffer.node
|
||||||
inwardNode :=* master_fixer.node
|
inwardNode :=* master_fixer.node
|
||||||
|
|
||||||
def fromSyncPorts(addBuffers: Int = 0, name: Option[String] = None): TLInwardNode = SourceCardinality { implicit p =>
|
def fromSyncPorts(addBuffers: Int = 0, name: Option[String] = None): TLInwardNode = {
|
||||||
TLBuffer.chain(addBuffers).foldLeft(master_buffer.node:TLInwardNode)(_ :=? _)
|
TLBuffer.chain(addBuffers).foldLeft(master_buffer.node:TLInwardNode)(_ :=* _)
|
||||||
}
|
}
|
||||||
|
|
||||||
def fromSyncMasters(addBuffers: Int = 0, name: Option[String] = None): TLInwardNode = SourceCardinality { implicit p =>
|
def fromSyncMasters(addBuffers: Int = 0, name: Option[String] = None): TLInwardNode = {
|
||||||
TLBuffer.chain(addBuffers).foldLeft(master_buffer.node:TLInwardNode)(_ :=? _)
|
TLBuffer.chain(addBuffers).foldLeft(master_buffer.node:TLInwardNode)(_ :=* _)
|
||||||
}
|
}
|
||||||
|
|
||||||
def fromCoherentChip: TLInwardNode = inwardNode
|
def fromCoherentChip: TLInwardNode = inwardNode
|
||||||
|
@ -39,10 +39,8 @@ class PeripheryBus(params: PeripheryBusParams)(implicit p: Parameters) extends T
|
|||||||
def toTile(name: Option[String] = None)(gen: Parameters => TLInwardNode) {
|
def toTile(name: Option[String] = None)(gen: Parameters => TLInwardNode) {
|
||||||
this {
|
this {
|
||||||
LazyScope(s"${busName}ToTile${name.getOrElse("")}") {
|
LazyScope(s"${busName}ToTile${name.getOrElse("")}") {
|
||||||
SinkCardinality { implicit p =>
|
FlipRendering { implicit p =>
|
||||||
FlipRendering { implicit p =>
|
gen(p) :*= outwardNode
|
||||||
gen(p) :*= outwardNode
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -112,7 +112,7 @@ trait HasRocketTiles extends HasTiles
|
|||||||
wrapper.intXbar.intnode := wrapper { IntSyncCrossingSink(3) } := debug.intnode // 1. always async crossign
|
wrapper.intXbar.intnode := wrapper { IntSyncCrossingSink(3) } := debug.intnode // 1. always async crossign
|
||||||
|
|
||||||
// 2. clint+plic conditionak crossing
|
// 2. clint+plic conditionak crossing
|
||||||
val periphIntNode = SourceCardinality { implicit p => wrapper.intXbar.intnode :=? wrapper.crossIntIn }
|
val periphIntNode = wrapper.intXbar.intnode :=* wrapper.crossIntIn
|
||||||
periphIntNode := clint.intnode // msip+mtip
|
periphIntNode := clint.intnode // msip+mtip
|
||||||
periphIntNode := plic.intnode // meip
|
periphIntNode := plic.intnode // meip
|
||||||
if (tp.core.useVM) periphIntNode := plic.intnode // seip
|
if (tp.core.useVM) periphIntNode := plic.intnode // seip
|
||||||
@ -121,9 +121,9 @@ trait HasRocketTiles extends HasTiles
|
|||||||
|
|
||||||
// From core to PLIC
|
// From core to PLIC
|
||||||
wrapper.rocket.intOutputNode.foreach { i => // 4. conditional crossing
|
wrapper.rocket.intOutputNode.foreach { i => // 4. conditional crossing
|
||||||
FlipRendering { implicit p => SourceCardinality { implicit p =>
|
FlipRendering { implicit p =>
|
||||||
plic.intnode :=? wrapper.crossIntOut :=? i
|
plic.intnode :=* wrapper.crossIntOut :=* i
|
||||||
} }
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wrapper
|
wrapper
|
||||||
|
@ -53,9 +53,7 @@ class SystemBus(params: SystemBusParams)(implicit p: Parameters) extends TLBusWr
|
|||||||
def fromTile(name: Option[String])(gen: Parameters => TLOutwardNode) {
|
def fromTile(name: Option[String])(gen: Parameters => TLOutwardNode) {
|
||||||
this {
|
this {
|
||||||
LazyScope(s"${busName}FromTile${name.getOrElse("")}") {
|
LazyScope(s"${busName}FromTile${name.getOrElse("")}") {
|
||||||
SourceCardinality { implicit p =>
|
master_splitter.node :=* gen(p)
|
||||||
master_splitter.node :=* gen(p)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,24 +9,6 @@ import freechips.rocketchip.util.HeterogeneousBag
|
|||||||
import scala.collection.mutable.ListBuffer
|
import scala.collection.mutable.ListBuffer
|
||||||
import scala.util.matching._
|
import scala.util.matching._
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
private case object CardinalityInferenceDirectionKey extends
|
|
||||||
Field[CardinalityInferenceDirection.T](CardinalityInferenceDirection.NO_INFERENCE)
|
|
||||||
|
|
||||||
case object MonitorsEnabled extends Field[Boolean](true)
|
case object MonitorsEnabled extends Field[Boolean](true)
|
||||||
case object RenderFlipped extends Field[Boolean](false)
|
case object RenderFlipped extends Field[Boolean](false)
|
||||||
|
|
||||||
@ -113,6 +95,9 @@ abstract class BaseNode(implicit val valName: ValName)
|
|||||||
protected[diplomacy] def gco: Option[BaseNode] // greatest common outer
|
protected[diplomacy] def gco: Option[BaseNode] // greatest common outer
|
||||||
def inputs: Seq[(BaseNode, RenderedEdge)]
|
def inputs: Seq[(BaseNode, RenderedEdge)]
|
||||||
def outputs: Seq[(BaseNode, RenderedEdge)]
|
def outputs: Seq[(BaseNode, RenderedEdge)]
|
||||||
|
|
||||||
|
protected[diplomacy] val sinkCard: Int
|
||||||
|
protected[diplomacy] val sourceCard: Int
|
||||||
}
|
}
|
||||||
|
|
||||||
object BaseNode
|
object BaseNode
|
||||||
@ -130,12 +115,12 @@ trait NodeHandle[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data]
|
|||||||
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_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_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, 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) }
|
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_FLEX); NodeHandle(h, this) }
|
||||||
// connecting a full node with an output => an output
|
// connecting a full node with an output => an output
|
||||||
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_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_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, 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 }
|
override def :*=*[EY](h: OutwardNodeHandle[DI, UI, EY, BI])(implicit p: Parameters, sourceInfo: SourceInfo): OutwardNodeHandle[DO, UO, EO, BO] = { bind(h, BIND_FLEX); this }
|
||||||
}
|
}
|
||||||
|
|
||||||
object NodeHandle
|
object NodeHandle
|
||||||
@ -164,27 +149,19 @@ trait InwardNodeHandle[DI, UI, EI, BI <: Data] extends NoHandle
|
|||||||
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_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_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, 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 }
|
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_FLEX); h }
|
||||||
// connecting input node with output node => no node
|
// connecting input node with output node => no node
|
||||||
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_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_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, BIND_QUERY); NoHandleObject }
|
||||||
def :=? [EY](h: OutwardNodeHandle[DI, UI, EY, 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_FLEX); NoHandleObject }
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed trait NodeBinding
|
sealed trait NodeBinding
|
||||||
case object BIND_ONCE extends NodeBinding
|
case object BIND_ONCE extends NodeBinding
|
||||||
case object BIND_QUERY extends NodeBinding
|
case object BIND_QUERY extends NodeBinding
|
||||||
case object BIND_STAR extends NodeBinding
|
case object BIND_STAR extends NodeBinding
|
||||||
|
case object BIND_FLEX 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
|
trait InwardNode[DI, UI, BI <: Data] extends BaseNode
|
||||||
{
|
{
|
||||||
@ -253,27 +230,51 @@ sealed abstract class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data](
|
|||||||
protected[diplomacy] def mapParamsD(n: Int, p: Seq[DI]): Seq[DO]
|
protected[diplomacy] def mapParamsD(n: Int, p: Seq[DI]): Seq[DO]
|
||||||
protected[diplomacy] def mapParamsU(n: Int, p: Seq[UO]): Seq[UI]
|
protected[diplomacy] def mapParamsU(n: Int, p: Seq[UO]): Seq[UI]
|
||||||
|
|
||||||
|
protected[diplomacy] lazy val sinkCard = oBindings.count(_._3 == BIND_QUERY) + iBindings.count(_._3 == BIND_STAR)
|
||||||
|
protected[diplomacy] lazy val sourceCard = iBindings.count(_._3 == BIND_QUERY) + oBindings.count(_._3 == BIND_STAR)
|
||||||
|
protected[diplomacy] lazy val flexOffset = { // positive = sink cardinality; define 0 to be sink (both should work)
|
||||||
|
def DFS(v: BaseNode, visited: Set[BaseNode]): Set[BaseNode] = {
|
||||||
|
if (visited.contains(v)) {
|
||||||
|
visited
|
||||||
|
} else {
|
||||||
|
val flexes = oBindings.filter(_._3 == BIND_FLEX).map(_._2) ++ iBindings.filter(_._3 == BIND_FLEX).map(_._2)
|
||||||
|
flexes.foldLeft(visited + v)((sum, n) => DFS(n, sum))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val flexSet = DFS(this, Set())
|
||||||
|
val allSink = flexSet.map(_.sinkCard).sum
|
||||||
|
val allSource = flexSet.map(_.sourceCard).sum
|
||||||
|
require (flexSet.size == 1 || allSink == 0 || allSource == 0,
|
||||||
|
s"The nodes ${flexSet.map(_.name)} which are inter-connected by :*=* have ${allSink} :*= operators and ${allSource} :=* operators connected to them, making it impossible to determine cardinality inference direction.")
|
||||||
|
allSink - allSource
|
||||||
|
}
|
||||||
|
|
||||||
private var starCycleGuard = false
|
private var starCycleGuard = false
|
||||||
protected[diplomacy] lazy val (oPortMapping, iPortMapping, oStar, iStar) = {
|
protected[diplomacy] lazy val (oPortMapping, iPortMapping, oStar, iStar) = {
|
||||||
try {
|
try {
|
||||||
if (starCycleGuard) throw StarCycleException()
|
if (starCycleGuard) throw StarCycleException()
|
||||||
val oStars = oBindings.filter { case (_,_,b,_,_) => b == BIND_STAR }.size
|
starCycleGuard = true
|
||||||
val iStars = iBindings.filter { case (_,_,b,_,_) => b == BIND_STAR }.size
|
val oStars = oBindings.count { case (_,_,b,_,_) => b == BIND_STAR || (b == BIND_FLEX && flexOffset < 0) }
|
||||||
|
val iStars = iBindings.count { case (_,_,b,_,_) => b == BIND_STAR || (b == BIND_FLEX && flexOffset >= 0) }
|
||||||
val oKnown = oBindings.map { case (_, n, b, _, _) => b match {
|
val oKnown = oBindings.map { case (_, n, b, _, _) => b match {
|
||||||
case BIND_ONCE => 1
|
case BIND_ONCE => 1
|
||||||
|
case BIND_FLEX => { if (flexOffset < 0) 0 else n.iStar }
|
||||||
case BIND_QUERY => n.iStar
|
case BIND_QUERY => n.iStar
|
||||||
case BIND_STAR => 0 }}.foldLeft(0)(_+_)
|
case BIND_STAR => 0 }}.foldLeft(0)(_+_)
|
||||||
val iKnown = iBindings.map { case (_, n, b, _, _) => b match {
|
val iKnown = iBindings.map { case (_, n, b, _, _) => b match {
|
||||||
case BIND_ONCE => 1
|
case BIND_ONCE => 1
|
||||||
|
case BIND_FLEX => { if (flexOffset >= 0) 0 else n.oStar }
|
||||||
case BIND_QUERY => n.oStar
|
case BIND_QUERY => n.oStar
|
||||||
case BIND_STAR => 0 }}.foldLeft(0)(_+_)
|
case BIND_STAR => 0 }}.foldLeft(0)(_+_)
|
||||||
val (iStar, oStar) = resolveStar(iKnown, oKnown, iStars, oStars)
|
val (iStar, oStar) = resolveStar(iKnown, oKnown, iStars, oStars)
|
||||||
val oSum = oBindings.map { case (_, n, b, _, _) => b match {
|
val oSum = oBindings.map { case (_, n, b, _, _) => b match {
|
||||||
case BIND_ONCE => 1
|
case BIND_ONCE => 1
|
||||||
|
case BIND_FLEX => { if (flexOffset < 0) oStar else n.iStar }
|
||||||
case BIND_QUERY => n.iStar
|
case BIND_QUERY => n.iStar
|
||||||
case BIND_STAR => oStar }}.scanLeft(0)(_+_)
|
case BIND_STAR => oStar }}.scanLeft(0)(_+_)
|
||||||
val iSum = iBindings.map { case (_, n, b, _, _) => b match {
|
val iSum = iBindings.map { case (_, n, b, _, _) => b match {
|
||||||
case BIND_ONCE => 1
|
case BIND_ONCE => 1
|
||||||
|
case BIND_FLEX => { if (flexOffset >= 0) iStar else n.oStar }
|
||||||
case BIND_QUERY => n.oStar
|
case BIND_QUERY => n.oStar
|
||||||
case BIND_STAR => iStar }}.scanLeft(0)(_+_)
|
case BIND_STAR => iStar }}.scanLeft(0)(_+_)
|
||||||
val oTotal = oSum.lastOption.getOrElse(0)
|
val oTotal = oSum.lastOption.getOrElse(0)
|
||||||
@ -385,6 +386,7 @@ sealed abstract class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data](
|
|||||||
val o = y.oPushed
|
val o = y.oPushed
|
||||||
y.oPush(i, x, binding match {
|
y.oPush(i, x, binding match {
|
||||||
case BIND_ONCE => BIND_ONCE
|
case BIND_ONCE => BIND_ONCE
|
||||||
|
case BIND_FLEX => BIND_FLEX
|
||||||
case BIND_STAR => BIND_QUERY
|
case BIND_STAR => BIND_QUERY
|
||||||
case BIND_QUERY => BIND_STAR })
|
case BIND_QUERY => BIND_STAR })
|
||||||
x.iPush(o, y, binding)
|
x.iPush(o, y, binding)
|
||||||
|
@ -31,18 +31,6 @@ package object diplomacy
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def SinkCardinality[T](body: Parameters => T)(implicit p: Parameters) = body(p.alterPartial {
|
|
||||||
case CardinalityInferenceDirectionKey => CardinalityInferenceDirection.SINK_TO_SOURCE
|
|
||||||
})
|
|
||||||
def SourceCardinality[T](body: Parameters => T)(implicit p: Parameters) = body(p.alterPartial {
|
|
||||||
case CardinalityInferenceDirectionKey => CardinalityInferenceDirection.SOURCE_TO_SINK
|
|
||||||
})
|
|
||||||
def UnaryCardinality[T](body: Parameters => T)(implicit p: Parameters) = body(p.alterPartial {
|
|
||||||
case CardinalityInferenceDirectionKey => CardinalityInferenceDirection.NO_INFERENCE
|
|
||||||
})
|
|
||||||
def FlipCardinality[T](body: Parameters => T)(implicit p: Parameters) = body(p.alterPartial {
|
|
||||||
case CardinalityInferenceDirectionKey => p(CardinalityInferenceDirectionKey).flip
|
|
||||||
})
|
|
||||||
def EnableMonitors[T](body: Parameters => T)(implicit p: Parameters) = body(p.alterPartial {
|
def EnableMonitors[T](body: Parameters => T)(implicit p: Parameters) = body(p.alterPartial {
|
||||||
case MonitorsEnabled => true
|
case MonitorsEnabled => true
|
||||||
})
|
})
|
||||||
|
@ -72,8 +72,8 @@ abstract class TLBusWrapper(params: TLBusParams, val busName: String)(implicit p
|
|||||||
|
|
||||||
def bufferToSlaves: TLOutwardNode = outwardBufNode
|
def bufferToSlaves: TLOutwardNode = outwardBufNode
|
||||||
|
|
||||||
def toSyncSlaves(name: Option[String] = None, addBuffers: Int = 0): TLOutwardNode = SinkCardinality { implicit p =>
|
def toSyncSlaves(name: Option[String] = None, addBuffers: Int = 0): TLOutwardNode = {
|
||||||
TLBuffer.chain(addBuffers).foldRight(outwardBufNode)(_ :=? _)
|
TLBuffer.chain(addBuffers).foldRight(outwardBufNode)(_ :*= _)
|
||||||
}
|
}
|
||||||
|
|
||||||
def toVariableWidthSlaves: TLOutwardNode = outwardFragNode
|
def toVariableWidthSlaves: TLOutwardNode = outwardFragNode
|
||||||
|
Loading…
Reference in New Issue
Block a user