Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AddressAdjuster patches #2470

Merged
merged 7 commits into from
May 20, 2020
44 changes: 27 additions & 17 deletions src/main/scala/tilelink/AddressAdjuster.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,27 @@ import chisel3.util._
import freechips.rocketchip.config._
import freechips.rocketchip.diplomacy._

// forceLocal -> used to ensure special devices (like debug) remain reacheable at chip_id=0 even if in params.region
class AddressAdjuster(val params: ReplicatedRegion, val forceLocal: Seq[AddressSet] = Nil)(implicit p: Parameters) extends LazyModule {
class AddressAdjuster(
val params: ReplicatedRegion, // only devices in this region get adjusted
val forceLocal: Seq[AddressSet] = Nil, // ensure special devices (e.g. debug) remain reacheable at id=0 even if in params.region
val localBaseAddressDefault: Option[BigInt] = None // default local base address used for reporting manager address metadata
)(implicit p: Parameters) extends LazyModule {
val mask = params.replicationMask
// Which bits are in the mask?
val bits = AddressSet.enumerateBits(mask)
// Find the portion of the addresses which correspond to prefix0
private def prefix0(region: Seq[AddressSet]): Seq[AddressSet] = {
region.flatMap { _.intersect(params.local) }
}
private def prefixNot0(region: Seq[AddressSet]): Seq[AddressSet] = {
region.flatMap { _.subtract(params.local) }
// Default region is used to display address map metadata which corresponds to the expected default choice of prefix value
private val defaultRegion: AddressSet = params.local.copy(base = params.local.base + localBaseAddressDefault.getOrElse(0))
private def prefixDefault(region: Seq[AddressSet]): Seq[AddressSet] = {
region.flatMap { _.intersect(defaultRegion) }
}
private def prefixNotDefault(region: Seq[AddressSet]): Seq[AddressSet] = {
region.flatMap { _.subtract(defaultRegion) }
}

// forceLocal better only go one place (the low index)
forceLocal.foreach { as => require((as.max & mask) == 0) }

Expand Down Expand Up @@ -167,12 +176,13 @@ class AddressAdjuster(val params: ReplicatedRegion, val forceLocal: Seq[AddressS
val r = container.get
requireContainerSupport(l, r)

// The address can be dynamically adjusted to anywhere in the adjustable region, but we take the 0 setting as default for DTS output
// The local address can be dynamically adjusted to any masked location in the adjustable region.
// We can report a particular local base address for DTS output, or default to reporting the 0th region.
// Any address space holes in the local adjustable region will be plugged with the error device.
// All other PMAs are replaced with the capabilities of the remote path, since that's all we can know statically.
// Capabilities supported by the remote but not the local will result in dynamic re-reouting to the error device.
// All device PMAs are replaced with the capabilities of the remote path, since that's all we can know statically.
// Capabilities supported by the remote but not the local device will result in dynamic re-rerouting to the error device.
l.v1copy(
address = AddressSet.unify(prefix0(l.address) ++ (if (Some(l) == errorDev) holes else Nil)),
address = AddressSet.unify(prefixDefault(l.address ++ (if (Some(l) == errorDev) holes else Nil))),
regionType = r.regionType,
executable = r.executable,
supportsAcquireT = r.supportsAcquireT,
Expand All @@ -192,7 +202,7 @@ class AddressAdjuster(val params: ReplicatedRegion, val forceLocal: Seq[AddressS
// Actually rewrite the PMAs for the adjustable remote region too, to account for the differing FIFO domains under the mask
val newRemotes = adjustableRemoteManagers.map { r =>
r.v1copy(
address = prefixNot0(r.address),
address = prefixNotDefault(r.address),
fifoId = Some(0))
}

Expand Down Expand Up @@ -248,8 +258,8 @@ class AddressAdjuster(val params: ReplicatedRegion, val forceLocal: Seq[AddressS
parent.a.ready := Mux(a_local, local.a.ready, remote.a.ready) && !a_stall
local .a.valid := parent.a.valid && a_local && !a_stall
remote.a.valid := parent.a.valid && !a_local && !a_stall
local .a.bits := parent.a.bits
remote.a.bits := parent.a.bits
local .a.bits :<= parent.a.bits
remote.a.bits :<= parent.a.bits

// Count beats
val a_first = parentEdge.first(parent.a)
Expand Down Expand Up @@ -311,11 +321,11 @@ class AddressAdjuster(val params: ReplicatedRegion, val forceLocal: Seq[AddressS
val local_d = Wire(chiselTypeOf(parent.d)) // type-cast, because 'sink' width differs
local.d.ready := local_d.ready
local_d.valid := local.d.valid
local_d.bits := local.d.bits
local_d.bits :<= local.d.bits
val remote_d = Wire(chiselTypeOf(parent.d))
remote.d.ready := remote_d.ready
remote_d.valid := remote.d.valid
remote_d.bits := remote.d.bits
remote_d.bits :<= remote.d.bits
remote_d.bits.sink := remote.d.bits.sink +& sink_threshold
TLArbiter.robin(parentEdge, parent.d, local_d, remote_d)

Expand All @@ -330,16 +340,16 @@ class AddressAdjuster(val params: ReplicatedRegion, val forceLocal: Seq[AddressS
parent.c.ready := Mux(c_local, local.c.ready, remote.c.ready)
local .c.valid := parent.c.valid && c_local
remote.c.valid := parent.c.valid && !c_local
local .c.bits := parent.c.bits
remote.c.bits := parent.c.bits
local .c.bits :<= parent.c.bits
remote.c.bits :<= parent.c.bits

// Route E by sink
val e_local = parent.e.bits.sink < sink_threshold
parent.e.ready := Mux(e_local, local.e.ready, remote.e.ready)
local .e.valid := parent.e.valid && e_local
remote.e.valid := parent.e.valid && !e_local
local .e.bits := parent.e.bits
remote.e.bits := parent.e.bits
local .e.bits :<= parent.e.bits
remote.e.bits :<= parent.e.bits
remote.e.bits.sink := parent.e.bits.sink - sink_threshold
}
}
Expand Down
5 changes: 3 additions & 2 deletions src/main/scala/tilelink/BusWrapper.scala
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,8 @@ case class AddressAdjusterWrapperParams(
blockBytes: Int,
beatBytes: Int,
replication: Option[ReplicatedRegion],
forceLocal: Seq[AddressSet] = Nil
forceLocal: Seq[AddressSet] = Nil,
localBaseAddressDefault: Option[BigInt] = None
)
extends HasTLBusParams
with TLBusWrapperInstantiationLike
Expand All @@ -371,7 +372,7 @@ case class AddressAdjusterWrapperParams(
}

class AddressAdjusterWrapper(params: AddressAdjusterWrapperParams, name: String)(implicit p: Parameters) extends TLBusWrapper(params, name) {
private val address_adjuster = params.replication.map { r => LazyModule(new AddressAdjuster(r, params.forceLocal)) }
private val address_adjuster = params.replication.map { r => LazyModule(new AddressAdjuster(r, params.forceLocal, params.localBaseAddressDefault)) }
private val viewNode = TLIdentityNode()
val inwardNode: TLInwardNode = address_adjuster.map(_.node :*=* viewNode).getOrElse(viewNode)
def outwardNode: TLOutwardNode = address_adjuster.map(_.node).getOrElse(viewNode)
Expand Down