diplomacy: change API to auto-create node bundles => cross-module refs
This commit is contained in:
@ -63,22 +63,21 @@ class TLXbar(policy: TLArbiter.Policy = TLArbiter.roundRobin)(implicit p: Parame
|
||||
})
|
||||
|
||||
lazy val module = new LazyModuleImp(this) {
|
||||
val io = new Bundle {
|
||||
val in = node.bundleIn
|
||||
val out = node.bundleOut
|
||||
if ((node.in.size * node.out.size) > (8*32)) {
|
||||
println (s"!!! WARNING !!!")
|
||||
println (s" Your TLXbar ($name) is very large, with ${node.in.size} Masters and ${node.out.size} Slaves.")
|
||||
println (s"!!! WARNING !!!")
|
||||
}
|
||||
|
||||
if ((io.in.size * io.out.size) > (8*32)) {
|
||||
println (s"!!! WARNING !!!")
|
||||
println (s" Your TLXbar ($name) is very large, with ${io.in.size} Masters and ${io.out.size} Slaves.")
|
||||
println (s"!!! WARNING !!!")
|
||||
}
|
||||
val (io_in, edgesIn) = node.in.unzip
|
||||
val (io_out, edgesOut) = node.out.unzip
|
||||
|
||||
// Grab the port ID mapping
|
||||
val inputIdRanges = TLXbar.mapInputIds(node.edgesIn.map(_.client))
|
||||
val outputIdRanges = TLXbar.mapOutputIds(node.edgesOut.map(_.manager))
|
||||
val inputIdRanges = TLXbar.mapInputIds(edgesIn.map(_.client))
|
||||
val outputIdRanges = TLXbar.mapOutputIds(edgesOut.map(_.manager))
|
||||
|
||||
// Find a good mask for address decoding
|
||||
val port_addrs = node.edgesOut.map(_.manager.managers.map(_.address).flatten)
|
||||
val port_addrs = edgesOut.map(_.manager.managers.map(_.address).flatten)
|
||||
val routingMask = AddressDecoder(port_addrs)
|
||||
val route_addrs = port_addrs.map(seq => AddressSet.unify(seq.map(_.widen(~routingMask)).distinct))
|
||||
val outputPorts = route_addrs.map(seq => (addr: UInt) => seq.map(_.contains(addr)).reduce(_ || _))
|
||||
@ -97,70 +96,70 @@ class TLXbar(policy: TLArbiter.Policy = TLArbiter.roundRobin)(implicit p: Parame
|
||||
// Print the ID mapping
|
||||
if (false) {
|
||||
println(s"XBar ${name} mapping:")
|
||||
(node.edgesIn zip inputIdRanges).zipWithIndex.foreach { case ((edge, id), i) =>
|
||||
(edgesIn zip inputIdRanges).zipWithIndex.foreach { case ((edge, id), i) =>
|
||||
println(s"\t$i assigned ${id} for ${edge.client.clients.map(_.name).mkString(", ")}")
|
||||
}
|
||||
println("")
|
||||
}
|
||||
|
||||
// We need an intermediate size of bundle with the widest possible identifiers
|
||||
val wide_bundle = TLBundleParameters.union(io.in.map(_.params) ++ io.out.map(_.params))
|
||||
val wide_bundle = TLBundleParameters.union(io_in.map(_.params) ++ io_out.map(_.params))
|
||||
|
||||
// Handle size = 1 gracefully (Chisel3 empty range is broken)
|
||||
def trim(id: UInt, size: Int) = if (size <= 1) UInt(0) else id(log2Ceil(size)-1, 0)
|
||||
|
||||
// Transform input bundle sources (sinks use global namespace on both sides)
|
||||
val in = Wire(Vec(io.in.size, TLBundle(wide_bundle)))
|
||||
val in = Wire(Vec(io_in.size, TLBundle(wide_bundle)))
|
||||
for (i <- 0 until in.size) {
|
||||
val r = inputIdRanges(i)
|
||||
|
||||
in(i).a <> io.in(i).a
|
||||
io.in(i).d <> in(i).d
|
||||
in(i).a.bits.source := io.in(i).a.bits.source | UInt(r.start)
|
||||
io.in(i).d.bits.source := trim(in(i).d.bits.source, r.size)
|
||||
in(i).a <> io_in(i).a
|
||||
io_in(i).d <> in(i).d
|
||||
in(i).a.bits.source := io_in(i).a.bits.source | UInt(r.start)
|
||||
io_in(i).d.bits.source := trim(in(i).d.bits.source, r.size)
|
||||
|
||||
if (node.edgesIn(i).client.anySupportProbe && node.edgesOut.exists(_.manager.anySupportAcquireB)) {
|
||||
in(i).c <> io.in(i).c
|
||||
in(i).e <> io.in(i).e
|
||||
io.in(i).b <> in(i).b
|
||||
in(i).c.bits.source := io.in(i).c.bits.source | UInt(r.start)
|
||||
io.in(i).b.bits.source := trim(in(i).b.bits.source, r.size)
|
||||
if (edgesIn(i).client.anySupportProbe && edgesOut.exists(_.manager.anySupportAcquireB)) {
|
||||
in(i).c <> io_in(i).c
|
||||
in(i).e <> io_in(i).e
|
||||
io_in(i).b <> in(i).b
|
||||
in(i).c.bits.source := io_in(i).c.bits.source | UInt(r.start)
|
||||
io_in(i).b.bits.source := trim(in(i).b.bits.source, r.size)
|
||||
} else {
|
||||
in(i).c.valid := Bool(false)
|
||||
in(i).e.valid := Bool(false)
|
||||
in(i).b.ready := Bool(false)
|
||||
io.in(i).c.ready := Bool(true)
|
||||
io.in(i).e.ready := Bool(true)
|
||||
io.in(i).b.valid := Bool(false)
|
||||
io_in(i).c.ready := Bool(true)
|
||||
io_in(i).e.ready := Bool(true)
|
||||
io_in(i).b.valid := Bool(false)
|
||||
}
|
||||
}
|
||||
|
||||
// Transform output bundle sinks (sources use global namespace on both sides)
|
||||
val out = Wire(Vec(io.out.size, TLBundle(wide_bundle)))
|
||||
val out = Wire(Vec(io_out.size, TLBundle(wide_bundle)))
|
||||
for (i <- 0 until out.size) {
|
||||
val r = outputIdRanges(i)
|
||||
|
||||
io.out(i).a <> out(i).a
|
||||
out(i).d <> io.out(i).d
|
||||
out(i).d.bits.sink := io.out(i).d.bits.sink | UInt(r.map(_.start).getOrElse(0))
|
||||
io_out(i).a <> out(i).a
|
||||
out(i).d <> io_out(i).d
|
||||
out(i).d.bits.sink := io_out(i).d.bits.sink | UInt(r.map(_.start).getOrElse(0))
|
||||
|
||||
if (node.edgesOut(i).manager.anySupportAcquireB && node.edgesIn.exists(_.client.anySupportProbe)) {
|
||||
io.out(i).c <> out(i).c
|
||||
io.out(i).e <> out(i).e
|
||||
out(i).b <> io.out(i).b
|
||||
io.out(i).e.bits.sink := trim(out(i).e.bits.sink, r.map(_.size).getOrElse(0))
|
||||
if (edgesOut(i).manager.anySupportAcquireB && edgesIn.exists(_.client.anySupportProbe)) {
|
||||
io_out(i).c <> out(i).c
|
||||
io_out(i).e <> out(i).e
|
||||
out(i).b <> io_out(i).b
|
||||
io_out(i).e.bits.sink := trim(out(i).e.bits.sink, r.map(_.size).getOrElse(0))
|
||||
} else {
|
||||
out(i).c.ready := Bool(false)
|
||||
out(i).e.ready := Bool(false)
|
||||
out(i).b.valid := Bool(false)
|
||||
io.out(i).c.valid := Bool(false)
|
||||
io.out(i).e.valid := Bool(false)
|
||||
io.out(i).b.ready := Bool(true)
|
||||
io_out(i).c.valid := Bool(false)
|
||||
io_out(i).e.valid := Bool(false)
|
||||
io_out(i).b.ready := Bool(true)
|
||||
}
|
||||
}
|
||||
|
||||
val addressA = (in zip node.edgesIn) map { case (i, e) => e.address(i.a.bits) }
|
||||
val addressC = (in zip node.edgesIn) map { case (i, e) => e.address(i.c.bits) }
|
||||
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) }) })
|
||||
@ -168,28 +167,28 @@ class TLXbar(policy: TLArbiter.Policy = TLArbiter.roundRobin)(implicit p: Parame
|
||||
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 beatsAI = Vec((in zip node.edgesIn) map { case (i, e) => e.numBeats1(i.a.bits) })
|
||||
val beatsBO = Vec((out zip node.edgesOut) map { case (o, e) => e.numBeats1(o.b.bits) })
|
||||
val beatsCI = Vec((in zip node.edgesIn) map { case (i, e) => e.numBeats1(i.c.bits) })
|
||||
val beatsDO = Vec((out zip node.edgesOut) map { case (o, e) => e.numBeats1(o.d.bits) })
|
||||
val beatsEI = Vec((in zip node.edgesIn) map { case (i, e) => e.numBeats1(i.e.bits) })
|
||||
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) })
|
||||
|
||||
// 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 filter[T](data: Seq[T], mask: Seq[Boolean]) = (data zip mask).filter(_._2).map(_._1)
|
||||
|
||||
// Fanout the input sources to the output sinks
|
||||
val portsAOI = transpose((in zip requestAIO) map { case (i, r) => TLXbar.fanout(i.a, r, node.paramsOut.map(_(ForceFanoutKey).a)) })
|
||||
val portsBIO = transpose((out zip requestBOI) map { case (o, r) => TLXbar.fanout(o.b, r, node.paramsIn .map(_(ForceFanoutKey).b)) })
|
||||
val portsCOI = transpose((in zip requestCIO) map { case (i, r) => TLXbar.fanout(i.c, r, node.paramsOut.map(_(ForceFanoutKey).c)) })
|
||||
val portsDIO = transpose((out zip requestDOI) map { case (o, r) => TLXbar.fanout(o.d, r, node.paramsIn .map(_(ForceFanoutKey).d)) })
|
||||
val portsEOI = transpose((in zip requestEIO) map { case (i, r) => TLXbar.fanout(i.e, r, node.paramsOut.map(_(ForceFanoutKey).e)) })
|
||||
val portsAOI = transpose((in zip requestAIO) map { case (i, r) => TLXbar.fanout(i.a, r, edgesOut.map(_.params(ForceFanoutKey).a)) })
|
||||
val portsBIO = transpose((out zip requestBOI) map { case (o, r) => TLXbar.fanout(o.b, r, edgesIn .map(_.params(ForceFanoutKey).b)) })
|
||||
val portsCOI = transpose((in zip requestCIO) map { case (i, r) => TLXbar.fanout(i.c, r, edgesOut.map(_.params(ForceFanoutKey).c)) })
|
||||
val portsDIO = transpose((out zip requestDOI) map { case (o, r) => TLXbar.fanout(o.d, r, edgesIn .map(_.params(ForceFanoutKey).d)) })
|
||||
val portsEOI = transpose((in zip requestEIO) map { case (i, r) => TLXbar.fanout(i.e, r, edgesOut.map(_.params(ForceFanoutKey).e)) })
|
||||
|
||||
// Arbitrate amongst the sources
|
||||
for (o <- 0 until out.size) {
|
||||
val allowI = Seq.tabulate(in.size) { i =>
|
||||
node.edgesIn(i).client.anySupportProbe &&
|
||||
node.edgesOut(o).manager.anySupportAcquireB
|
||||
edgesIn(i).client.anySupportProbe &&
|
||||
edgesOut(o).manager.anySupportAcquireB
|
||||
}
|
||||
TLArbiter(policy)(out(o).a, (beatsAI zip portsAOI(o) ):_*)
|
||||
TLArbiter(policy)(out(o).c, filter(beatsCI zip portsCOI(o), allowI):_*)
|
||||
@ -198,8 +197,8 @@ class TLXbar(policy: TLArbiter.Policy = TLArbiter.roundRobin)(implicit p: Parame
|
||||
|
||||
for (i <- 0 until in.size) {
|
||||
val allowO = Seq.tabulate(out.size) { o =>
|
||||
node.edgesIn(i).client.anySupportProbe &&
|
||||
node.edgesOut(o).manager.anySupportAcquireB
|
||||
edgesIn(i).client.anySupportProbe &&
|
||||
edgesOut(o).manager.anySupportAcquireB
|
||||
}
|
||||
TLArbiter(policy)(in(i).b, filter(beatsBO zip portsBIO(i), allowO):_*)
|
||||
TLArbiter(policy)(in(i).d, (beatsDO zip portsDIO(i) ):_*)
|
||||
@ -264,7 +263,7 @@ class TLRAMXbar(nManagers: Int, txns: Int)(implicit p: Parameters) extends LazyM
|
||||
ram.node := TLFragmenter(4, 256)(TLDelayer(0.1)(xbar.node))
|
||||
}
|
||||
|
||||
lazy val module = new LazyModuleImp(this) with HasUnitTestIO {
|
||||
lazy val module = new LazyModuleImp(this) with UnitTestModule {
|
||||
io.finished := fuzz.module.io.finished
|
||||
}
|
||||
}
|
||||
@ -287,7 +286,7 @@ class TLMulticlientXbar(nManagers: Int, nClients: Int, txns: Int)(implicit p: Pa
|
||||
ram.node := TLFragmenter(4, 256)(TLDelayer(0.1)(xbar.node))
|
||||
}
|
||||
|
||||
lazy val module = new LazyModuleImp(this) with HasUnitTestIO {
|
||||
lazy val module = new LazyModuleImp(this) with UnitTestModule {
|
||||
io.finished := fuzzers.last.module.io.finished
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user