tilelink: Xbar now allows for fanout control
This commit is contained in:
parent
e831acba9c
commit
6879f5bfb1
@ -293,3 +293,14 @@ object BufferParams
|
|||||||
val flow = BufferParams(1, true, false)
|
val flow = BufferParams(1, true, false)
|
||||||
val pipe = BufferParams(1, false, true)
|
val pipe = BufferParams(1, false, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case class TriStateValue(value: Boolean, set: Boolean)
|
||||||
|
{
|
||||||
|
def update(orig: Boolean) = if (set) value else orig
|
||||||
|
}
|
||||||
|
|
||||||
|
object TriStateValue
|
||||||
|
{
|
||||||
|
implicit def apply(value: Boolean): TriStateValue = TriStateValue(value, true)
|
||||||
|
def unset = TriStateValue(false, false)
|
||||||
|
}
|
||||||
|
@ -3,9 +3,31 @@
|
|||||||
package freechips.rocketchip.tilelink
|
package freechips.rocketchip.tilelink
|
||||||
|
|
||||||
import Chisel._
|
import Chisel._
|
||||||
import freechips.rocketchip.config.Parameters
|
import freechips.rocketchip.config._
|
||||||
import freechips.rocketchip.diplomacy._
|
import freechips.rocketchip.diplomacy._
|
||||||
|
|
||||||
|
// Trades off slave port proximity against routing resource cost
|
||||||
|
object ForceFanout
|
||||||
|
{
|
||||||
|
def apply[T](
|
||||||
|
a: TriStateValue = TriStateValue.unset,
|
||||||
|
b: TriStateValue = TriStateValue.unset,
|
||||||
|
c: TriStateValue = TriStateValue.unset,
|
||||||
|
d: TriStateValue = TriStateValue.unset,
|
||||||
|
e: TriStateValue = TriStateValue.unset)(body: Parameters => T)(implicit p: Parameters) =
|
||||||
|
{
|
||||||
|
body(p.alterPartial {
|
||||||
|
case ForceFanoutKey => p(ForceFanoutKey) match {
|
||||||
|
case ForceFanoutParams(pa, pb, pc, pd, pe) =>
|
||||||
|
ForceFanoutParams(a.update(pa), b.update(pb), c.update(pc), d.update(pd), e.update(pe))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private case class ForceFanoutParams(a: Boolean, b: Boolean, c: Boolean, d: Boolean, e: Boolean)
|
||||||
|
private case object ForceFanoutKey extends Field(ForceFanoutParams(false, false, false, false, false))
|
||||||
|
|
||||||
class TLXbar(policy: TLArbiter.Policy = TLArbiter.roundRobin)(implicit p: Parameters) extends LazyModule
|
class TLXbar(policy: TLArbiter.Policy = TLArbiter.roundRobin)(implicit p: Parameters) extends LazyModule
|
||||||
{
|
{
|
||||||
val node = TLNexusNode(
|
val node = TLNexusNode(
|
||||||
@ -157,11 +179,11 @@ class TLXbar(policy: TLArbiter.Policy = TLArbiter.roundRobin)(implicit p: Parame
|
|||||||
def filter[T](data: Seq[T], mask: Seq[Boolean]) = (data zip mask).filter(_._2).map(_._1)
|
def filter[T](data: Seq[T], mask: Seq[Boolean]) = (data zip mask).filter(_._2).map(_._1)
|
||||||
|
|
||||||
// Fanout the input sources to the output sinks
|
// Fanout the input sources to the output sinks
|
||||||
val portsAOI = transpose((in zip requestAIO) map { case (i, r) => TLXbar.fanout(i.a, r) })
|
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) })
|
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) })
|
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) })
|
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) })
|
val portsEOI = transpose((in zip requestEIO) map { case (i, r) => TLXbar.fanout(i.e, r, node.paramsOut.map(_(ForceFanoutKey).e)) })
|
||||||
|
|
||||||
// Arbitrate amongst the sources
|
// Arbitrate amongst the sources
|
||||||
for (o <- 0 until out.size) {
|
for (o <- 0 until out.size) {
|
||||||
@ -216,10 +238,10 @@ object TLXbar
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Replicate an input port to each output port
|
// Replicate an input port to each output port
|
||||||
def fanout[T <: TLChannel](input: DecoupledIO[T], select: Seq[Bool]) = {
|
def fanout[T <: TLChannel](input: DecoupledIO[T], select: Seq[Bool], force: Seq[Boolean] = Nil) = {
|
||||||
val filtered = Wire(Vec(select.size, input))
|
val filtered = Wire(Vec(select.size, input))
|
||||||
for (i <- 0 until select.size) {
|
for (i <- 0 until select.size) {
|
||||||
filtered(i).bits := IdentityModule(input.bits) // force fanout of wires
|
filtered(i).bits := (if (force.lift(i).getOrElse(false)) IdentityModule(input.bits) else input.bits)
|
||||||
filtered(i).valid := input.valid && select(i)
|
filtered(i).valid := input.valid && select(i)
|
||||||
}
|
}
|
||||||
input.ready := Mux1H(select, filtered.map(_.ready))
|
input.ready := Mux1H(select, filtered.map(_.ready))
|
||||||
|
Loading…
Reference in New Issue
Block a user