1
0
Fork 0
rocket-chip/src/main/scala/subsystem/MemoryBus.scala

80 lines
2.9 KiB
Scala

// See LICENSE.SiFive for license details.
package freechips.rocketchip.subsystem
import Chisel._
import freechips.rocketchip.config._
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.tilelink._
import freechips.rocketchip.util._
// TODO: applies to all caches, for now
case object CacheBlockBytes extends Field[Int](64)
/** L2 Broadcast Hub configuration */
case class BroadcastParams(
nTrackers: Int = 4,
bufferless: Boolean = false)
case object BroadcastKey extends Field(BroadcastParams())
/** L2 memory subsystem configuration */
case class BankedL2Params(
nMemoryChannels: Int = 1,
nBanksPerChannel: Int = 1,
coherenceManager: HasMemoryBus => (TLInwardNode, TLOutwardNode, () => Option[Bool]) = { subsystem =>
implicit val p = subsystem.p
val BroadcastParams(nTrackers, bufferless) = p(BroadcastKey)
val bh = LazyModule(new TLBroadcast(subsystem.memBusBlockBytes, nTrackers, bufferless))
val ww = LazyModule(new TLWidthWidget(subsystem.sbusBeatBytes))
ww.node :*= bh.node
(bh.node, ww.node, () => None)
}) {
val nBanks = nMemoryChannels*nBanksPerChannel
}
case object BankedL2Key extends Field(BankedL2Params())
/** Parameterization of the memory-side bus created for each memory channel */
case class MemoryBusParams(
beatBytes: Int,
blockBytes: Int,
masterBuffering: BufferParams = BufferParams.none,
slaveBuffering: BufferParams = BufferParams.none
) extends TLBusParams
case object MemoryBusKey extends Field[MemoryBusParams]
/** Wrapper for creating TL nodes from a bus connected to the back of each mem channel */
class MemoryBus(params: MemoryBusParams)(implicit p: Parameters) extends TLBusWrapper(params, "MemoryBus")(p) {
def fromCoherenceManager: TLInwardNode = inwardBufNode
def toDRAMController: TLOutwardNode = outwardBufNode
def toVariableWidthSlave: TLOutwardNode = outwardFragNode
}
trait HasMemoryBus extends HasSystemBus with HasPeripheryBus with HasInterruptBus {
private val mbusParams = p(MemoryBusKey)
private val l2Params = p(BankedL2Key)
val MemoryBusParams(memBusBeatBytes, memBusBlockBytes, _, _) = mbusParams
val BankedL2Params(nMemoryChannels, nBanksPerChannel, coherenceManager) = l2Params
val nBanks = l2Params.nBanks
val cacheBlockBytes = memBusBlockBytes
private val (in, out, halt) = coherenceManager(this)
def memBusCanCauseHalt: () => Option[Bool] = halt
require (isPow2(nMemoryChannels) || nMemoryChannels == 0)
require (isPow2(nBanksPerChannel))
require (isPow2(memBusBlockBytes))
private val mask = ~BigInt((nBanks-1) * memBusBlockBytes)
val memBuses = Seq.tabulate(nMemoryChannels) { channel =>
val mbus = LazyModule(new MemoryBus(mbusParams))
for (bank <- 0 until nBanksPerChannel) {
val offset = (bank * nMemoryChannels) + channel
ForceFanout(a = true) { implicit p => in := sbus.toMemoryBus }
mbus.fromCoherenceManager := TLFilter(TLFilter.Mmask(AddressSet(offset * memBusBlockBytes, mask))) := out
}
mbus
}
}