1
0

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:
Wesley W. Terpstra
2017-11-30 14:43:43 -08:00
parent 6a25a3b7ac
commit e489c4226e
16 changed files with 155 additions and 182 deletions

View File

@ -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}")

View File

@ -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)()

View File

@ -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}")

View File

@ -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