diplomacy: remove node arity and allow empty Nexus nodes (Xbars)
This removes the mostly obsolete 'numIn/Out' range restrictions on nodes. It also makes it possible to connect optional crossbars that disappear. val x = TLXbar() x := master slave := x val y = TLXbar() x :=* y // only connect y if it gets used This will create crossbar x, but crossbar y will disappear.
This commit is contained in:
@ -6,7 +6,7 @@ import Chisel._
|
||||
import freechips.rocketchip.config.Parameters
|
||||
import freechips.rocketchip.diplomacy._
|
||||
|
||||
case class TLNodeNumbererNode(nodeAddressOffset: Option[Int] = None)(implicit valName: ValName) extends TLCustomNode(0 to 999, 0 to 999)
|
||||
case class TLNodeNumbererNode(nodeAddressOffset: Option[Int] = None)(implicit valName: ValName) extends TLCustomNode
|
||||
{
|
||||
def resolveStar(iKnown: Int, oKnown: Int, iStars: Int, oStars: Int): (Int, Int) = {
|
||||
require (oStars + iStars <= 1, s"${name} (a custom adapter) appears left of a :*= ${iStars} times and right of a :=* ${oStars} times; at most once is allowed${lazyModule.line}")
|
||||
|
@ -49,26 +49,20 @@ case class TLManagerNode(portParams: Seq[TLManagerPortParameters])(implicit valN
|
||||
|
||||
case class TLAdapterNode(
|
||||
clientFn: TLClientPortParameters => TLClientPortParameters = { s => s },
|
||||
managerFn: TLManagerPortParameters => TLManagerPortParameters = { s => s },
|
||||
num: Range.Inclusive = 0 to 999)(
|
||||
managerFn: TLManagerPortParameters => TLManagerPortParameters = { s => s })(
|
||||
implicit valName: ValName)
|
||||
extends AdapterNode(TLImp)(clientFn, managerFn, num)
|
||||
extends AdapterNode(TLImp)(clientFn, managerFn)
|
||||
|
||||
case class TLIdentityNode()(implicit valName: ValName) extends IdentityNode(TLImp)()
|
||||
|
||||
case class TLNexusNode(
|
||||
clientFn: Seq[TLClientPortParameters] => TLClientPortParameters,
|
||||
managerFn: Seq[TLManagerPortParameters] => TLManagerPortParameters,
|
||||
numClientPorts: Range.Inclusive = 1 to 999,
|
||||
numManagerPorts: Range.Inclusive = 1 to 999)(
|
||||
managerFn: Seq[TLManagerPortParameters] => TLManagerPortParameters)(
|
||||
implicit valName: ValName)
|
||||
extends NexusNode(TLImp)(clientFn, managerFn, numClientPorts, numManagerPorts)
|
||||
extends NexusNode(TLImp)(clientFn, managerFn)
|
||||
|
||||
abstract class TLCustomNode(
|
||||
numClientPorts: Range.Inclusive,
|
||||
numManagerPorts: Range.Inclusive)(
|
||||
implicit valName: ValName)
|
||||
extends CustomNode(TLImp)(numClientPorts, numManagerPorts)
|
||||
abstract class TLCustomNode(implicit valName: ValName)
|
||||
extends CustomNode(TLImp)
|
||||
|
||||
// Asynchronous crossings
|
||||
|
||||
@ -86,10 +80,9 @@ object TLAsyncImp extends SimpleNodeImp[TLAsyncClientPortParameters, TLAsyncMana
|
||||
|
||||
case class TLAsyncAdapterNode(
|
||||
clientFn: TLAsyncClientPortParameters => TLAsyncClientPortParameters = { s => s },
|
||||
managerFn: TLAsyncManagerPortParameters => TLAsyncManagerPortParameters = { s => s },
|
||||
num: Range.Inclusive = 0 to 999)(
|
||||
managerFn: TLAsyncManagerPortParameters => TLAsyncManagerPortParameters = { s => s })(
|
||||
implicit valName: ValName)
|
||||
extends AdapterNode(TLAsyncImp)(clientFn, managerFn, num)
|
||||
extends AdapterNode(TLAsyncImp)(clientFn, managerFn)
|
||||
|
||||
case class TLAsyncIdentityNode()(implicit valName: ValName) extends IdentityNode(TLAsyncImp)()
|
||||
|
||||
@ -119,10 +112,9 @@ object TLRationalImp extends SimpleNodeImp[TLRationalClientPortParameters, TLRat
|
||||
|
||||
case class TLRationalAdapterNode(
|
||||
clientFn: TLRationalClientPortParameters => TLRationalClientPortParameters = { s => s },
|
||||
managerFn: TLRationalManagerPortParameters => TLRationalManagerPortParameters = { s => s },
|
||||
num: Range.Inclusive = 0 to 999)(
|
||||
managerFn: TLRationalManagerPortParameters => TLRationalManagerPortParameters = { s => s })(
|
||||
implicit valName: ValName)
|
||||
extends AdapterNode(TLRationalImp)(clientFn, managerFn, num)
|
||||
extends AdapterNode(TLRationalImp)(clientFn, managerFn)
|
||||
|
||||
case class TLRationalIdentityNode()(implicit valName: ValName) extends IdentityNode(TLRationalImp)()
|
||||
|
||||
|
@ -9,11 +9,9 @@ import freechips.rocketchip.diplomacy._
|
||||
case class SplitterArg[T](newSize: Int, ports: Seq[T])
|
||||
case class TLSplitterNode(
|
||||
clientFn: SplitterArg[TLClientPortParameters] => Seq[TLClientPortParameters],
|
||||
managerFn: SplitterArg[TLManagerPortParameters] => Seq[TLManagerPortParameters],
|
||||
numClientPorts: Range.Inclusive = 0 to 999,
|
||||
numManagerPorts: Range.Inclusive = 0 to 999)(
|
||||
managerFn: SplitterArg[TLManagerPortParameters] => Seq[TLManagerPortParameters])(
|
||||
implicit valName: ValName)
|
||||
extends TLCustomNode(numClientPorts, numManagerPorts)
|
||||
extends TLCustomNode
|
||||
{
|
||||
def resolveStar(iKnown: Int, oKnown: Int, iStars: Int, oStars: Int): (Int, Int) = {
|
||||
require (oKnown == 0, s"${name} (a splitter) appears right of a := or :*=; use a :=* instead${lazyModule.line}")
|
||||
|
@ -31,8 +31,6 @@ private case object ForceFanoutKey extends Field(ForceFanoutParams(false, false,
|
||||
class TLXbar(policy: TLArbiter.Policy = TLArbiter.roundRobin)(implicit p: Parameters) extends LazyModule
|
||||
{
|
||||
val node = TLNexusNode(
|
||||
numClientPorts = 1 to 999,
|
||||
numManagerPorts = 1 to 999,
|
||||
clientFn = { seq =>
|
||||
seq(0).copy(
|
||||
minLatency = seq.map(_.minLatency).min,
|
||||
@ -159,20 +157,20 @@ class TLXbar(policy: TLArbiter.Policy = TLArbiter.roundRobin)(implicit p: Parame
|
||||
val addressA = (in zip edgesIn) map { case (i, e) => e.address(i.a.bits) }
|
||||
val addressC = (in zip edgesIn) map { case (i, e) => e.address(i.c.bits) }
|
||||
|
||||
val requestAIO = Vec(addressA.map { i => Vec(outputPorts.map { o => o(i) }) })
|
||||
val requestCIO = Vec(addressC.map { i => Vec(outputPorts.map { o => o(i) }) })
|
||||
val requestBOI = Vec(out.map { o => Vec(inputIdRanges.map { i => i.contains(o.b.bits.source) }) })
|
||||
val requestDOI = Vec(out.map { o => Vec(inputIdRanges.map { i => i.contains(o.d.bits.source) }) })
|
||||
val requestEIO = Vec(in.map { i => Vec(outputIdRanges.map { o => o.map(_.contains(i.e.bits.sink)).getOrElse(Bool(false)) }) })
|
||||
val requestAIO = addressA.map { i => outputPorts.map { o => o(i) } }
|
||||
val requestCIO = addressC.map { i => outputPorts.map { o => o(i) } }
|
||||
val requestBOI = out.map { o => inputIdRanges.map { i => i.contains(o.b.bits.source) } }
|
||||
val requestDOI = out.map { o => inputIdRanges.map { i => i.contains(o.d.bits.source) } }
|
||||
val requestEIO = in.map { i => outputIdRanges.map { o => o.map(_.contains(i.e.bits.sink)).getOrElse(Bool(false)) } }
|
||||
|
||||
val beatsAI = Vec((in zip edgesIn) map { case (i, e) => e.numBeats1(i.a.bits) })
|
||||
val beatsBO = Vec((out zip edgesOut) map { case (o, e) => e.numBeats1(o.b.bits) })
|
||||
val beatsCI = Vec((in zip edgesIn) map { case (i, e) => e.numBeats1(i.c.bits) })
|
||||
val beatsDO = Vec((out zip edgesOut) map { case (o, e) => e.numBeats1(o.d.bits) })
|
||||
val beatsEI = Vec((in zip edgesIn) map { case (i, e) => e.numBeats1(i.e.bits) })
|
||||
val beatsAI = (in zip edgesIn) map { case (i, e) => e.numBeats1(i.a.bits) }
|
||||
val beatsBO = (out zip edgesOut) map { case (o, e) => e.numBeats1(o.b.bits) }
|
||||
val beatsCI = (in zip edgesIn) map { case (i, e) => e.numBeats1(i.c.bits) }
|
||||
val beatsDO = (out zip edgesOut) map { case (o, e) => e.numBeats1(o.d.bits) }
|
||||
val beatsEI = (in zip edgesIn) map { case (i, e) => e.numBeats1(i.e.bits) }
|
||||
|
||||
// Which pairs support support transfers
|
||||
def transpose[T](x: Seq[Seq[T]]) = Seq.tabulate(x(0).size) { i => Seq.tabulate(x.size) { j => x(j)(i) } }
|
||||
def transpose[T](x: Seq[Seq[T]]) = if (x.isEmpty) Nil else Seq.tabulate(x(0).size) { i => Seq.tabulate(x.size) { j => x(j)(i) } }
|
||||
def filter[T](data: Seq[T], mask: Seq[Boolean]) = (data zip mask).filter(_._2).map(_._1)
|
||||
|
||||
// Fanout the input sources to the output sinks
|
||||
|
Reference in New Issue
Block a user