Skip to content

Commit

Permalink
Support incoherent access to ExtMem through SBus (#2978)
Browse files Browse the repository at this point in the history
* Add TLResourceRemover

* RegionReplicator: only check prefix when relevant

* Support incoherent access to AXI4 extmem through sbus
  • Loading branch information
jerryz123 authored Sep 14, 2022
1 parent 0f0e0f9 commit 21de34c
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 10 deletions.
4 changes: 4 additions & 0 deletions src/main/scala/subsystem/Configs.scala
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,10 @@ class WithExtMemSize(n: BigInt) extends Config((site, here, up) => {
case ExtMem => up(ExtMem, site).map(x => x.copy(master = x.master.copy(size = n)))
})

class WithExtMemSbusBypass(base: BigInt = x"10_0000_0000") extends Config((site, here, up) => {
case ExtMem => up(ExtMem, site).map(x => x.copy(incohBase = Some(base)))
})

class WithDTS(model: String, compat: Seq[String]) extends Config((site, here, up) => {
case DTSModel => model
case DTSCompat => compat
Expand Down
53 changes: 44 additions & 9 deletions src/main/scala/subsystem/Ports.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

package freechips.rocketchip.subsystem

import chisel3._

import freechips.rocketchip.config.Field
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.tilelink._
Expand All @@ -19,7 +21,8 @@ case class MasterPortParams(

/** Specifies the width of external slave ports */
case class SlavePortParams(beatBytes: Int, idBits: Int, sourceBits: Int)
case class MemoryPortParams(master: MasterPortParams, nMemoryChannels: Int)
// if incohBase is set, creates an incoherent alias for the region that hangs off the sbus
case class MemoryPortParams(master: MasterPortParams, nMemoryChannels: Int, incohBase: Option[BigInt] = None)

case object ExtMem extends Field[Option[MemoryPortParams]](None)
case object ExtBus extends Field[Option[MasterPortParams]](None)
Expand All @@ -33,7 +36,8 @@ trait CanHaveMasterAXI4MemPort { this: BaseSubsystem =>
private val portName = "axi4"
private val device = new MemoryDevice
private val idBits = memPortParamsOpt.map(_.master.idBits).getOrElse(1)
val memAXI4Node = AXI4SlaveNode(memPortParamsOpt.map({ case MemoryPortParams(memPortParams, nMemoryChannels) =>

val memAXI4Node = AXI4SlaveNode(memPortParamsOpt.map({ case MemoryPortParams(memPortParams, nMemoryChannels, _) =>
Seq.tabulate(nMemoryChannels) { channel =>
val base = AddressSet.misaligned(memPortParams.base, memPortParams.size)
val filter = AddressSet(channel * mbus.blockBytes, ~((nMemoryChannels-1) * mbus.blockBytes))
Expand All @@ -51,13 +55,44 @@ trait CanHaveMasterAXI4MemPort { this: BaseSubsystem =>
}
}).toList.flatten)

mbus.coupleTo(s"memory_controller_port_named_$portName") {
(memAXI4Node
:*= AXI4UserYanker()
:*= AXI4IdIndexer(idBits)
:*= TLToAXI4()
:*= TLWidthWidget(mbus.beatBytes)
:*= _)
for (i <- 0 until memAXI4Node.portParams.size) {
val mem_bypass_xbar = mbus { TLXbar() }

// Create an incoherent alias for the AXI4 memory
memPortParamsOpt.foreach(memPortParams => {
memPortParams.incohBase.foreach(incohBase => {
val cohRegion = AddressSet(0, incohBase-1)
val incohRegion = AddressSet(incohBase, incohBase-1)
val replicator = sbus {
val replicator = LazyModule(new RegionReplicator(ReplicatedRegion(cohRegion, cohRegion.widen(incohBase))))
val prefixSource = BundleBridgeSource[UInt](() => UInt(1.W))
replicator.prefix := prefixSource
// prefix is unused for TL uncached, so this is ok
InModuleBody { prefixSource.bundle := 0.U(1.W) }
replicator
}
sbus.coupleTo(s"memory_controller_bypass_port_named_$portName") {
(mbus.crossIn(mem_bypass_xbar)(ValName("bus_xing"))(p(SbusToMbusXTypeKey))
:= TLWidthWidget(sbus.beatBytes)
:= replicator.node
:= TLFilter(TLFilter.mSubtract(cohRegion))
:= TLFilter(TLFilter.mResourceRemover)
:= _
)
}
})
})

mbus.coupleTo(s"memory_controller_port_named_$portName") {
(memAXI4Node
:= AXI4UserYanker()
:= AXI4IdIndexer(idBits)
:= TLToAXI4()
:= TLWidthWidget(mbus.beatBytes)
:= mem_bypass_xbar
:= _
)
}
}

val mem_axi4 = InModuleBody { memAXI4Node.makeIOs() }
Expand Down
5 changes: 5 additions & 0 deletions src/main/scala/tilelink/Filter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,11 @@ object TLFilter
if (c.supports.probe) Some(c) else None
}

// removes resources from managers
def mResourceRemover: ManagerFilter = { m =>
Some(m.v2copy(resources=Nil))
}

// default application applies neither type of filter unless overridden
def apply(
mfilter: ManagerFilter = TLFilter.mIdentity,
Expand Down
2 changes: 1 addition & 1 deletion src/main/scala/tilelink/RegionReplication.scala
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ class RegionReplicator(val params: ReplicatedRegion)(implicit p: Parameters) ext

// Which address within the mask routes to local devices?
val local_prefix = RegNext(prefix.bundle)
assert (params.isLegalPrefix(local_prefix))
assert (params.isLegalPrefix(local_prefix) || !out.b.valid)

val a_addr = in.a.bits.address
val a_contained = params.region.contains(a_addr) || totalContainment.B
Expand Down

0 comments on commit 21de34c

Please sign in to comment.