subsystem: new bus attachment api
This commit is contained in:
parent
8462ea3d5b
commit
3f436a7612
@ -31,7 +31,7 @@ trait HasPeripheryDebug extends HasPeripheryBus {
|
||||
|
||||
val debug = LazyModule(new TLDebugModule(pbus.beatBytes))
|
||||
|
||||
debug.node := pbus.toVariableWidthSlaves
|
||||
pbus.toVariableWidthSlave(Some("Debug")){ debug.node }
|
||||
}
|
||||
|
||||
trait HasPeripheryDebugBundle {
|
||||
|
@ -71,7 +71,7 @@ trait HasPeripheryBootROM extends HasPeripheryBus {
|
||||
|
||||
val bootrom = LazyModule(new TLROM(params.address, params.size, contents, true, pbus.beatBytes))
|
||||
|
||||
bootrom.node := pbus.toVariableWidthSlaves
|
||||
pbus.toVariableWidthSlave(Some("BootROM")){ bootrom.node }
|
||||
}
|
||||
|
||||
/** Subsystem will power-on running at 0x10040 (BootROM) */
|
||||
|
@ -93,5 +93,5 @@ class CLINT(params: CLINTParams, beatBytes: Int)(implicit p: Parameters) extends
|
||||
/** Trait that will connect a CLINT to a subsystem */
|
||||
trait HasPeripheryCLINT extends HasPeripheryBus {
|
||||
val clint = LazyModule(new CLINT(p(CLINTKey), pbus.beatBytes))
|
||||
clint.node := pbus.toVariableWidthSlaves
|
||||
pbus.toVariableWidthSlave(Some("CLINT")) { clint.node }
|
||||
}
|
||||
|
@ -121,6 +121,5 @@ class DeadlockDevice(params: ErrorParams, beatBytes: Int = 4)(implicit p: Parame
|
||||
trait HasSystemErrorSlave extends HasSystemBus {
|
||||
private val params = p(ErrorParams)
|
||||
val error = LazyModule(new TLError(params, sbus.beatBytes))
|
||||
|
||||
error.node := sbus.toSlave
|
||||
sbus.toSlave(Some("Error")){ error.node }
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ trait HasPeripheryMaskROMSlave extends HasPeripheryBus {
|
||||
val maskROMParams = p(PeripheryMaskROMKey)
|
||||
val maskROMs = maskROMParams map { params =>
|
||||
val maskROM = LazyModule(new TLMaskROM(params))
|
||||
maskROM.node := pbus.toFixedWidthSingleBeatSlave(maskROM.beatBytes)
|
||||
pbus.toFixedWidthSingleBeatSlave(maskROM.beatBytes, Some("MaskROM")) { maskROM.node }
|
||||
maskROM
|
||||
}
|
||||
}
|
||||
|
@ -270,7 +270,7 @@ class TLPLIC(params: PLICParams, beatBytes: Int)(implicit p: Parameters) extends
|
||||
|
||||
/** Trait that will connect a PLIC to a subsystem */
|
||||
trait HasPeripheryPLIC extends HasInterruptBus with HasPeripheryBus {
|
||||
val plic = LazyModule(new TLPLIC(p(PLICKey), pbus.beatBytes))
|
||||
plic.node := pbus.toVariableWidthSlaves
|
||||
val plic = LazyModule(new TLPLIC(p(PLICKey), pbus.beatBytes)))
|
||||
pbus.toVariableWidthSlave(Some("PLIC")) { plic.node }
|
||||
plic.intnode := ibus.toPLIC
|
||||
}
|
||||
|
@ -50,13 +50,16 @@ trait HasMemoryZeroSlave extends HasMemoryBus {
|
||||
private val params = p(ZeroParams)
|
||||
private val device = new SimpleDevice("rom", Seq("ucbbar,cacheable-zero0"))
|
||||
|
||||
val zeros = memBuses.map(_.toVariableWidthSlave).zipWithIndex.map { case (node, channel) =>
|
||||
val zeros = memBuses
|
||||
.map(m => m.toVariableWidthSlave(Some("Zero"))(_))
|
||||
.zipWithIndex
|
||||
.map { case (attach, channel) =>
|
||||
val channels = memBuses.size
|
||||
val base = AddressSet(params.base, params.size-1)
|
||||
val filter = AddressSet(channel * cacheBlockBytes, ~((channels-1) * cacheBlockBytes))
|
||||
val address = base.intersect(filter).get
|
||||
val zero = LazyModule(new TLZero(address, beatBytes = params.beatBytes, resources = device.reg("mem")))
|
||||
zero.node := node
|
||||
attach { zero.node }
|
||||
zero
|
||||
}
|
||||
}
|
||||
|
@ -28,15 +28,12 @@ class GroundTestSubsystem(implicit p: Parameters) extends BaseSubsystem
|
||||
)}
|
||||
|
||||
tiles.flatMap(_.dcacheOpt).foreach { dc =>
|
||||
sbus.fromTile(None) { implicit p => TileMasterPortParams(addBuffers = 1).adapt(this)(dc.node) }
|
||||
sbus.fromTile(None, buffers = 1){ dc.node }
|
||||
}
|
||||
|
||||
// No PLIC in ground test; so just sink the interrupts to nowhere
|
||||
IntSinkNode(IntSinkPortSimple()) := ibus.toPLIC
|
||||
|
||||
val pbusRAM = LazyModule(new TLRAM(AddressSet(testRamAddr, 0xffff), true, false, pbus.beatBytes))
|
||||
pbusRAM.node := pbus.toVariableWidthSlaves
|
||||
|
||||
override lazy val module = new GroundTestSubsystemModule(this)
|
||||
}
|
||||
|
||||
@ -53,11 +50,11 @@ class GroundTestSubsystemModule[+L <: GroundTestSubsystem](_outer: L) extends Ba
|
||||
/** Adds a SRAM to the system for testing purposes. */
|
||||
trait HasPeripheryTestRAMSlave extends HasPeripheryBus {
|
||||
val testram = LazyModule(new TLRAM(AddressSet(0x52000000, 0xfff), true, true, pbus.beatBytes))
|
||||
testram.node := pbus.toVariableWidthSlaves
|
||||
pbus.toVariableWidthSlave(Some("TestRAM")) { testram.node }
|
||||
}
|
||||
|
||||
/** Adds a fuzzing master to the system for testing purposes. */
|
||||
trait HasPeripheryTestFuzzMaster extends HasPeripheryBus {
|
||||
val fuzzer = LazyModule(new TLFuzzer(5000))
|
||||
pbus.bufferFromMasters := fuzzer.node
|
||||
pbus.fromOtherMaster(Some("Fuzzer")) { fuzzer.node }
|
||||
}
|
||||
|
@ -270,10 +270,6 @@ class WithJtagDTM extends Config ((site, here, up) => {
|
||||
case IncludeJtagDTM => true
|
||||
})
|
||||
|
||||
class WithNoPeripheryArithAMO extends Config ((site, here, up) => {
|
||||
case PeripheryBusKey => up(PeripheryBusKey, site).copy(arithmetic = false)
|
||||
})
|
||||
|
||||
class WithNBitPeripheryBus(nBits: Int) extends Config ((site, here, up) => {
|
||||
case PeripheryBusKey => up(PeripheryBusKey, site).copy(beatBytes = nBits/8)
|
||||
})
|
||||
|
@ -8,38 +8,40 @@ import freechips.rocketchip.diplomacy._
|
||||
import freechips.rocketchip.tilelink._
|
||||
import freechips.rocketchip.util._
|
||||
|
||||
case class FrontBusParams(
|
||||
beatBytes: Int,
|
||||
blockBytes: Int,
|
||||
masterBuffering: BufferParams = BufferParams.default,
|
||||
slaveBuffering: BufferParams = BufferParams.default
|
||||
) extends TLBusParams
|
||||
case class FrontBusParams(beatBytes: Int, blockBytes: Int) extends HasTLBusParams
|
||||
|
||||
case object FrontBusKey extends Field[FrontBusParams]
|
||||
|
||||
class FrontBus(params: FrontBusParams)(implicit p: Parameters) extends TLBusWrapper(params, "FrontBus") {
|
||||
class FrontBus(params: FrontBusParams, val crossing: SubsystemClockCrossing = SynchronousCrossing())
|
||||
(implicit p: Parameters) extends TLBusWrapper(params, "FrontBus")
|
||||
with HasTLXbarPhy
|
||||
with HasCrossing {
|
||||
|
||||
private val master_buffer = LazyModule(new TLBuffer(params.masterBuffering))
|
||||
private val master_fixer = LazyModule(new TLFIFOFixer(TLFIFOFixer.all))
|
||||
|
||||
master_buffer.suggestName(s"${busName}_master_TLBuffer")
|
||||
master_fixer.suggestName(s"${busName}_master_TLFIFOFixer")
|
||||
|
||||
master_fixer.node :=* master_buffer.node
|
||||
inwardNode :=* master_fixer.node
|
||||
|
||||
def fromSyncPorts(addBuffers: Int = 0, name: Option[String] = None): TLInwardNode = {
|
||||
TLBuffer.chain(addBuffers).foldLeft(master_buffer.node:TLInwardNode)(_ :=* _)
|
||||
def fromPort[D,U,E,B <: Data](
|
||||
name: Option[String] = None,
|
||||
buffers: Int = 1)
|
||||
(gen: => NodeHandle[D,U,E,B,TLClientPortParameters,TLManagerPortParameters,TLEdgeOut,TLBundle]): InwardNodeHandle[D,U,E,B] = {
|
||||
from(s"Port${name.getOrElse("")}") {
|
||||
val nodes = TLFIFOFixer(TLFIFOFixer.all) +: TLBuffer.chain(buffers)
|
||||
inwardNode :=* nodes.reduce(_ :=* _) :=* gen
|
||||
}
|
||||
}
|
||||
|
||||
def fromSyncMasters(addBuffers: Int = 0, name: Option[String] = None): TLInwardNode = {
|
||||
TLBuffer.chain(addBuffers).foldLeft(master_buffer.node:TLInwardNode)(_ :=* _)
|
||||
def fromMaster(name: Option[String] = None, buffers: Int = 1)
|
||||
(gen: => TLNode): TLInwardNode = {
|
||||
from(s"Master${name.getOrElse("")}") {
|
||||
inwardNode :=* TLBuffer.chain(buffers).reduce(_ :=* _) :=* gen
|
||||
}
|
||||
}
|
||||
|
||||
def fromCoherentChip: TLInwardNode = inwardNode
|
||||
|
||||
def toSystemBus : TLOutwardNode = TLBuffer(params.slaveBuffering) :=* xbar.node
|
||||
def fromCoherentChip(gen: => TLNode): TLInwardNode = {
|
||||
from("CoherentChip") { inwardNode :=* gen }
|
||||
}
|
||||
|
||||
def toSystemBus(buffer: BufferParams = BufferParams.none)
|
||||
(gen: => TLInwardNode) {
|
||||
to("SystemBus") { gen :*= TLBuffer(buffer) :*= outwardNode }
|
||||
}
|
||||
}
|
||||
|
||||
/** Provides buses that serve as attachment points,
|
||||
@ -51,5 +53,7 @@ trait HasFrontBus extends HasSystemBus {
|
||||
|
||||
val fbus = LazyModule(new FrontBus(frontbusParams))
|
||||
|
||||
FlipRendering { implicit p => sbus.fromFrontBus :=* fbus.toSystemBus }
|
||||
FlipRendering { implicit p =>
|
||||
fbus.toSystemBus() { sbus.fromFrontBus { fbus.crossTLOut } }
|
||||
}
|
||||
}
|
||||
|
@ -36,26 +36,47 @@ case class BankedL2Params(
|
||||
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 class MemoryBusParams(beatBytes: Int, blockBytes: Int) extends HasTLBusParams
|
||||
|
||||
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
|
||||
class MemoryBus(params: MemoryBusParams)(implicit p: Parameters) extends TLBusWrapper(params, "MemoryBus")(p)
|
||||
with HasTLXbarPhy {
|
||||
|
||||
private def bufferTo(buffer: BufferParams): TLOutwardNode =
|
||||
TLBuffer(buffer) :*= delayNode :*= outwardNode
|
||||
|
||||
def fromCoherenceManager(
|
||||
name: Option[String] = None,
|
||||
buffer: BufferParams = BufferParams.none)
|
||||
(gen: => TLNode): TLInwardNode = {
|
||||
from(s"CoherenceManager${name.getOrElse("")}") {
|
||||
inwardNode :*= TLBuffer(buffer) :*= gen
|
||||
}
|
||||
}
|
||||
|
||||
def toDRAMController[D,U,E,B <: Data](
|
||||
name: Option[String] = None,
|
||||
buffer: BufferParams = BufferParams.none)
|
||||
(gen: => NodeHandle[TLClientPortParameters,TLManagerPortParameters,TLEdgeIn,TLBundle,D,U,E,B]): OutwardNodeHandle[D,U,E,B] = {
|
||||
to(s"DRAMController${name.getOrElse("")}") { gen := bufferTo(buffer) }
|
||||
}
|
||||
|
||||
def toVariableWidthSlave(
|
||||
name: Option[String] = None,
|
||||
buffer: BufferParams = BufferParams.none)
|
||||
(gen: => TLNode): TLOutwardNode = {
|
||||
to(s"Slave${name.getOrElse("")}") {
|
||||
gen :*= TLFragmenter(params.beatBytes, params.blockBytes) :*= bufferTo(buffer)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
trait HasMemoryBus extends HasSystemBus with HasPeripheryBus with HasInterruptBus {
|
||||
private val mbusParams = p(MemoryBusKey)
|
||||
private val l2Params = p(BankedL2Key)
|
||||
val MemoryBusParams(memBusBeatBytes, memBusBlockBytes, _, _) = mbusParams
|
||||
val MemoryBusParams(memBusBeatBytes, memBusBlockBytes) = mbusParams
|
||||
val BankedL2Params(nMemoryChannels, nBanksPerChannel, coherenceManager) = l2Params
|
||||
val nBanks = l2Params.nBanks
|
||||
val cacheBlockBytes = memBusBlockBytes
|
||||
@ -71,8 +92,8 @@ trait HasMemoryBus extends HasSystemBus with HasPeripheryBus with HasInterruptBu
|
||||
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
|
||||
ForceFanout(a = true) { implicit p => sbus.toMemoryBus { in } }
|
||||
mbus.fromCoherenceManager(None) { TLFilter(TLFilter.Mmask(AddressSet(offset * memBusBlockBytes, mask))) } := out
|
||||
}
|
||||
mbus
|
||||
}
|
||||
|
@ -7,41 +7,97 @@ import freechips.rocketchip.config.{Field, Parameters}
|
||||
import freechips.rocketchip.diplomacy._
|
||||
import freechips.rocketchip.tilelink._
|
||||
|
||||
import freechips.rocketchip.config.Field
|
||||
|
||||
case class PeripheryBusParams(
|
||||
beatBytes: Int,
|
||||
blockBytes: Int,
|
||||
masterBuffering: BufferParams = BufferParams.default,
|
||||
slaveBuffering: BufferParams = BufferParams.none,
|
||||
arithmetic: Boolean = true,
|
||||
frequency: BigInt = BigInt(100000000) // 100 MHz as default bus frequency
|
||||
) extends TLBusParams {
|
||||
}
|
||||
) extends HasTLBusParams
|
||||
|
||||
case object PeripheryBusKey extends Field[PeripheryBusParams]
|
||||
|
||||
class PeripheryBus(params: PeripheryBusParams)(implicit p: Parameters) extends TLBusWrapper(params, "PeripheryBus") {
|
||||
class PeripheryBus(params: PeripheryBusParams, val crossing: SubsystemClockCrossing = SynchronousCrossing())
|
||||
(implicit p: Parameters) extends TLBusWrapper(params, "PeripheryBus")
|
||||
with HasTLXbarPhy
|
||||
with HasCrossing {
|
||||
|
||||
def toFixedWidthSingleBeatSlave(widthBytes: Int) = {
|
||||
TLFragmenter(widthBytes, params.blockBytes) := outwardWWNode
|
||||
private def bufferTo(buffer: BufferParams): TLOutwardNode =
|
||||
TLBuffer(buffer) :*= delayNode :*= outwardNode
|
||||
|
||||
private def fragmentTo(minSize: Int, maxSize: Int, buffer: BufferParams): TLOutwardNode =
|
||||
TLFragmenter(minSize, maxSize) :*= bufferTo(buffer)
|
||||
|
||||
private def fixedWidthTo(buffer: BufferParams): TLOutwardNode =
|
||||
TLWidthWidget(params.beatBytes) :*= bufferTo(buffer)
|
||||
|
||||
def toSlave(
|
||||
name: Option[String] = None,
|
||||
buffer: BufferParams = BufferParams.none)
|
||||
(gen: => TLNode): TLOutwardNode = {
|
||||
to(s"Slave${name.getOrElse("")}") { gen :*= bufferTo(buffer) }
|
||||
}
|
||||
|
||||
def toLargeBurstSlave(maxXferBytes: Int) = {
|
||||
TLFragmenter(params.beatBytes, maxXferBytes) := outwardBufNode
|
||||
def toVariableWidthSlave(
|
||||
name: Option[String] = None,
|
||||
buffer: BufferParams = BufferParams.none)
|
||||
(gen: => TLNode): TLOutwardNode = {
|
||||
to(s"Slave${name.getOrElse("")}") {
|
||||
gen :*= fragmentTo(params.beatBytes, params.blockBytes, buffer)
|
||||
}
|
||||
}
|
||||
|
||||
val fromSystemBus: TLInwardNode = {
|
||||
val atomics = LazyModule(new TLAtomicAutomata(arithmetic = params.arithmetic))
|
||||
xbar.node :*= TLBuffer(params.masterBuffering) :*= atomics.node
|
||||
def toFixedWidthSlave(
|
||||
name: Option[String] = None,
|
||||
buffer: BufferParams = BufferParams.none)
|
||||
(gen: => TLNode): TLOutwardNode = {
|
||||
to(s"Slave${name.getOrElse("")}") {
|
||||
gen :*= fixedWidthTo(buffer)
|
||||
}
|
||||
}
|
||||
|
||||
def toTile(name: Option[String] = None)(gen: Parameters => TLInwardNode) {
|
||||
this {
|
||||
LazyScope(s"${busName}ToTile${name.getOrElse("")}") {
|
||||
FlipRendering { implicit p =>
|
||||
gen(p) :*= outwardNode
|
||||
}
|
||||
def toFixedWidthSingleBeatSlave(
|
||||
widthBytes: Int,
|
||||
name: Option[String] = None,
|
||||
buffer: BufferParams = BufferParams.none)
|
||||
(gen: => TLNode): TLOutwardNode = {
|
||||
to(s"Slave${name.getOrElse("")}") {
|
||||
gen :*= TLFragmenter(widthBytes, params.blockBytes) :*= fixedWidthTo(buffer)
|
||||
}
|
||||
}
|
||||
|
||||
def toLargeBurstSlave(
|
||||
maxXferBytes: Int,
|
||||
name: Option[String] = None,
|
||||
buffer: BufferParams = BufferParams.none)
|
||||
(gen: => TLNode): TLOutwardNode = {
|
||||
to(s"Slave${name.getOrElse("")}") {
|
||||
gen :*= fragmentTo(params.beatBytes, maxXferBytes, buffer)
|
||||
}
|
||||
}
|
||||
|
||||
def fromSystemBus(
|
||||
arithmetic: Boolean = true,
|
||||
buffer: BufferParams = BufferParams.default)
|
||||
(gen: => TLOutwardNode) {
|
||||
from("SystemBus") {
|
||||
(inwardNode
|
||||
:*= TLBuffer(buffer)
|
||||
:*= TLAtomicAutomata(arithmetic = arithmetic)
|
||||
:*= gen)
|
||||
}
|
||||
}
|
||||
|
||||
def fromOtherMaster(
|
||||
name: Option[String] = None,
|
||||
buffer: BufferParams = BufferParams.none)
|
||||
(gen: => TLNode): TLInwardNode = {
|
||||
from(s"OtherMaster${name.getOrElse("")}") { inwardNode :*= TLBuffer(buffer) :*= gen }
|
||||
}
|
||||
|
||||
|
||||
def toTile(name: Option[String] = None)(gen: => TLNode): TLOutwardNode = {
|
||||
to(s"Tile${name.getOrElse("")}") {
|
||||
FlipRendering { implicit p =>
|
||||
gen :*= delayNode :*= outwardNode
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -57,5 +113,5 @@ trait HasPeripheryBus extends HasSystemBus {
|
||||
val pbus = LazyModule(new PeripheryBus(pbusParams))
|
||||
|
||||
// The peripheryBus hangs off of systemBus; here we convert TL-UH -> TL-UL
|
||||
pbus.fromSystemBus :*= sbus.toPeripheryBus()
|
||||
pbus.fromSystemBus() { sbus.toPeripheryBus() { pbus.crossTLIn } }
|
||||
}
|
||||
|
@ -49,13 +49,10 @@ trait HasMasterAXI4MemPort extends HasMemoryBus {
|
||||
beatBytes = params.beatBytes)
|
||||
})
|
||||
|
||||
val converter = LazyModule(new TLToAXI4())
|
||||
val trim = LazyModule(new AXI4IdIndexer(params.idBits))
|
||||
val yank = LazyModule(new AXI4UserYanker)
|
||||
val buffer = LazyModule(new AXI4Buffer)
|
||||
|
||||
memBuses.map(_.toDRAMController).foreach { case node =>
|
||||
mem_axi4 := buffer.node := yank.node := trim.node := converter.node := node
|
||||
memBuses.map { m =>
|
||||
mem_axi4 := m.toDRAMController(Some("AXI4DRAM")) {
|
||||
(AXI4UserYanker() := AXI4IdIndexer(params.idBits) := TLToAXI4())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -93,13 +90,13 @@ trait HasMasterAXI4MMIOPort extends HasSystemBus {
|
||||
supportsRead = TransferSizes(1, params.maxXferBytes))),
|
||||
beatBytes = params.beatBytes)))
|
||||
|
||||
(mmio_axi4
|
||||
:= AXI4Buffer()
|
||||
:= AXI4UserYanker()
|
||||
:= AXI4Deinterleaver(sbus.blockBytes)
|
||||
:= AXI4IdIndexer(params.idBits)
|
||||
:= TLToAXI4()
|
||||
:= sbus.toFixedWidthPorts)
|
||||
mmio_axi4 := sbus.toFixedWidthPort(Some("AXI4MMIO")) {
|
||||
(AXI4Buffer()
|
||||
:= AXI4UserYanker()
|
||||
:= AXI4Deinterleaver(sbus.blockBytes)
|
||||
:= AXI4IdIndexer(params.idBits)
|
||||
:= TLToAXI4())
|
||||
}
|
||||
}
|
||||
|
||||
/** Common io name and methods for propagating or tying off the port bundle */
|
||||
@ -128,13 +125,13 @@ trait HasSlaveAXI4Port extends HasSystemBus {
|
||||
id = IdRange(0, 1 << params.idBits))))))
|
||||
|
||||
private val fifoBits = 1
|
||||
(sbus.fromSyncPorts()
|
||||
:= TLWidthWidget(params.beatBytes)
|
||||
:= AXI4ToTL()
|
||||
:= AXI4UserYanker(Some(1 << (params.sourceBits - fifoBits - 1)))
|
||||
:= AXI4Fragmenter()
|
||||
:= AXI4IdIndexer(fifoBits)
|
||||
:= l2FrontendAXI4Node)
|
||||
sbus.fromPort(Some("AXI4Front")) {
|
||||
(TLWidthWidget(params.beatBytes)
|
||||
:= AXI4ToTL()
|
||||
:= AXI4UserYanker(Some(1 << (params.sourceBits - fifoBits - 1)))
|
||||
:= AXI4Fragmenter()
|
||||
:= AXI4IdIndexer(fifoBits))
|
||||
} := l2FrontendAXI4Node
|
||||
}
|
||||
|
||||
/** Common io name and methods for propagating or tying off the port bundle */
|
||||
@ -173,7 +170,9 @@ trait HasMasterTLMMIOPort extends HasSystemBus {
|
||||
supportsPutPartial = TransferSizes(1, sbus.blockBytes))),
|
||||
beatBytes = params.beatBytes)))
|
||||
|
||||
mmio_tl := TLBuffer() := TLSourceShrinker(1 << params.idBits) := sbus.toFixedWidthPorts
|
||||
mmio_tl := sbus.toFixedWidthPort(Some("TLMMIO")) {
|
||||
TLBuffer() := TLSourceShrinker(1 << params.idBits)
|
||||
}
|
||||
}
|
||||
|
||||
/** Common io name and methods for propagating or tying off the port bundle */
|
||||
@ -208,7 +207,9 @@ trait HasSlaveTLPort extends HasSystemBus {
|
||||
name = "Front Port (TL)",
|
||||
sourceId = IdRange(0, 1 << params.idBits))))))
|
||||
|
||||
sbus.fromSyncPorts() := TLSourceShrinker(1 << params.sourceBits) := TLWidthWidget(params.beatBytes) := l2FrontendTLNode
|
||||
sbus.fromPort(Some("TLFront")) {
|
||||
TLSourceShrinker(1 << params.sourceBits) := TLWidthWidget(params.beatBytes)
|
||||
} := l2FrontendTLNode
|
||||
}
|
||||
|
||||
/** Common io name and methods for propagating or tying off the port bundle */
|
||||
|
@ -15,19 +15,8 @@ import freechips.rocketchip.util._
|
||||
|
||||
// TODO: how specific are these to RocketTiles?
|
||||
case class TileMasterPortParams(
|
||||
addBuffers: Int = 0,
|
||||
cork: Option[Boolean] = None) {
|
||||
|
||||
def adapt(subsystem: HasPeripheryBus)
|
||||
(masterNode: TLOutwardNode)
|
||||
(implicit p: Parameters, sourceInfo: SourceInfo): TLOutwardNode = {
|
||||
val tile_master_cork = cork.map(u => (LazyModule(new TLCacheCork(unsafe = u))))
|
||||
val tile_master_fixer = LazyModule(new TLFIFOFixer(TLFIFOFixer.allUncacheable))
|
||||
|
||||
(Seq(tile_master_fixer.node) ++ TLBuffer.chain(addBuffers) ++ tile_master_cork.map(_.node))
|
||||
.foldRight(masterNode)(_ :=* _)
|
||||
}
|
||||
}
|
||||
buffers: Int = 0,
|
||||
cork: Option[Boolean] = None)
|
||||
|
||||
case class TileSlavePortParams(
|
||||
addBuffers: Int = 0,
|
||||
@ -41,9 +30,12 @@ case class TileSlavePortParams(
|
||||
.map(BasicBusBlockerParams(_, subsystem.pbus.beatBytes, subsystem.sbus.beatBytes))
|
||||
.map(bp => LazyModule(new BasicBusBlocker(bp)))
|
||||
|
||||
tile_slave_blocker.foreach { _.controlNode := subsystem.pbus.toVariableWidthSlaves }
|
||||
tile_slave_blocker.foreach { b =>
|
||||
subsystem.pbus.toVariableWidthSlave(Some("TileSlavePortBusBlocker")) { b.controlNode }
|
||||
}
|
||||
|
||||
(Seq() ++ tile_slave_blocker.map(_.node) ++ TLBuffer.chain(addBuffers))
|
||||
.foldLeft(slaveNode)(_ :*= _)
|
||||
.foldLeft(slaveNode)(_ :*= _)
|
||||
}
|
||||
}
|
||||
|
||||
@ -111,7 +103,9 @@ trait HasRocketTiles extends HasTiles
|
||||
}
|
||||
}
|
||||
|
||||
sbus.fromTile(tp.name) { implicit p => crossing.master.adapt(this)(rocket.crossTLOut :=* tileMasterBuffering) }
|
||||
sbus.fromTile(tp.name, crossing.master.buffers, crossing.master.cork) {
|
||||
rocket.crossTLOut
|
||||
} :=* tileMasterBuffering
|
||||
|
||||
// Connect the slave ports of the tile to the periphery bus
|
||||
|
||||
@ -123,9 +117,9 @@ trait HasRocketTiles extends HasTiles
|
||||
}
|
||||
}
|
||||
|
||||
pbus.toTile(tp.name) { implicit p => crossing.slave.adapt(this)( DisableMonitors { implicit p =>
|
||||
tileSlaveBuffering :*= rocket.crossTLIn
|
||||
})}
|
||||
DisableMonitors { implicit p =>
|
||||
tileSlaveBuffering :*= pbus.toTile(tp.name) { rocket.crossTLIn }
|
||||
}
|
||||
|
||||
// Handle all the different types of interrupts crossing to or from the tile:
|
||||
// 1. Debug interrupt is definitely asynchronous in all cases.
|
||||
|
@ -8,65 +8,94 @@ import freechips.rocketchip.diplomacy._
|
||||
import freechips.rocketchip.tilelink._
|
||||
import freechips.rocketchip.util._
|
||||
|
||||
case class SystemBusParams(
|
||||
beatBytes: Int,
|
||||
blockBytes: Int,
|
||||
masterBuffering: BufferParams = BufferParams.default,
|
||||
slaveBuffering: BufferParams = BufferParams.default
|
||||
) extends TLBusParams
|
||||
case class SystemBusParams(beatBytes: Int, blockBytes: Int) extends HasTLBusParams
|
||||
|
||||
case object SystemBusKey extends Field[SystemBusParams]
|
||||
|
||||
class SystemBus(params: SystemBusParams)(implicit p: Parameters) extends TLBusWrapper(params, "SystemBus") {
|
||||
class SystemBus(params: SystemBusParams)(implicit p: Parameters) extends TLBusWrapper(params, "SystemBus")
|
||||
with HasTLXbarPhy {
|
||||
|
||||
private val master_splitter = LazyModule(new TLSplitter) // Allows cycle-free connection to external networks
|
||||
master_splitter.suggestName(s"${busName}_master_TLSplitter")
|
||||
private val master_splitter = LazyModule(new TLSplitter)
|
||||
inwardNode :=* master_splitter.node
|
||||
|
||||
def busView = master_splitter.node.edges.in.head
|
||||
|
||||
protected def inwardSplitNode: TLInwardNode = master_splitter.node
|
||||
protected def outwardSplitNode: TLOutwardNode = master_splitter.node
|
||||
private def bufferTo(buffer: BufferParams): TLOutwardNode =
|
||||
TLBuffer(buffer) :*= delayNode :*= outwardNode
|
||||
|
||||
|
||||
private val port_fixer = LazyModule(new TLFIFOFixer(TLFIFOFixer.all))
|
||||
port_fixer.suggestName(s"${busName}_port_TLFIFOFixer")
|
||||
master_splitter.node :=* port_fixer.node
|
||||
|
||||
private val pbus_fixer = LazyModule(new TLFIFOFixer(TLFIFOFixer.all))
|
||||
pbus_fixer.suggestName(s"${busName}_pbus_TLFIFOFixer")
|
||||
pbus_fixer.node :*= outwardWWNode
|
||||
|
||||
def toSplitSlaves: TLOutwardNode = outwardSplitNode
|
||||
|
||||
def toPeripheryBus(addBuffers: Int = 0): TLOutwardNode = {
|
||||
TLBuffer.chain(addBuffers).foldRight(pbus_fixer.node:TLOutwardNode)(_ :*= _)
|
||||
}
|
||||
|
||||
val toMemoryBus: TLOutwardNode = outwardNode
|
||||
|
||||
val toSlave: TLOutwardNode = outwardBufNode
|
||||
|
||||
def fromCoherentChip: TLInwardNode = inwardNode
|
||||
|
||||
def fromFrontBus: TLInwardNode = master_splitter.node
|
||||
|
||||
def fromTile(name: Option[String])(gen: Parameters => TLOutwardNode) {
|
||||
this {
|
||||
LazyScope(s"${busName}FromTile${name.getOrElse("")}") {
|
||||
master_splitter.node :=* gen(p)
|
||||
}
|
||||
def toPeripheryBus(buffer: BufferParams = BufferParams.none)
|
||||
(gen: => TLNode): TLOutwardNode = {
|
||||
to("PeripheryBus") {
|
||||
(gen
|
||||
:= TLFIFOFixer(TLFIFOFixer.all)
|
||||
:= TLWidthWidget(params.beatBytes)
|
||||
:= bufferTo(buffer))
|
||||
}
|
||||
}
|
||||
|
||||
def fromSyncPorts(params: BufferParams = BufferParams.default, name: Option[String] = None): TLInwardNode = {
|
||||
val buffer = LazyModule(new TLBuffer(params))
|
||||
name.foreach { n => buffer.suggestName(s"${busName}_${n}_TLBuffer") }
|
||||
port_fixer.node :=* buffer.node
|
||||
buffer.node
|
||||
def toMemoryBus(gen: => TLInwardNode) {
|
||||
to("MemoryBus") { gen :*= delayNode :*= outwardNode }
|
||||
}
|
||||
|
||||
def fromSyncFIFOMaster(params: BufferParams = BufferParams.default, name: Option[String] = None): TLInwardNode = {
|
||||
fromSyncPorts(params, name)
|
||||
def toSlave(name: Option[String] = None, buffer: BufferParams = BufferParams.default)
|
||||
(gen: => TLNode): TLOutwardNode = {
|
||||
to(s"Slave${name.getOrElse("")}") { gen :*= bufferTo(buffer) }
|
||||
}
|
||||
|
||||
def toSplitSlave(name: Option[String] = None)
|
||||
(gen: => TLNode): TLOutwardNode = {
|
||||
to(s"Slave${name.getOrElse("")}") { gen :*= master_splitter.node }
|
||||
}
|
||||
|
||||
def toVariableWidthSlave(
|
||||
name: Option[String] = None,
|
||||
buffer: BufferParams = BufferParams.default)
|
||||
(gen: => TLNode): TLOutwardNode = {
|
||||
to(s"Slave${name.getOrElse("")}") {
|
||||
gen :*= TLFragmenter(params.beatBytes, params.blockBytes) :*= bufferTo(buffer)
|
||||
}
|
||||
}
|
||||
|
||||
def fromCoherentChip(gen: => TLNode): TLInwardNode = {
|
||||
from("CoherentChip") { inwardNode :=* gen }
|
||||
}
|
||||
|
||||
def fromFrontBus(gen: => TLNode): TLInwardNode = {
|
||||
from("FrontBus") { master_splitter.node :=* gen }
|
||||
}
|
||||
|
||||
def fromTile(
|
||||
name: Option[String],
|
||||
buffers: Int = 0,
|
||||
cork: Option[Boolean] = None)
|
||||
(gen: => TLNode): TLInwardNode = {
|
||||
from(s"Tile${name.getOrElse("")}") {
|
||||
(List(master_splitter.node, TLFIFOFixer(TLFIFOFixer.allUncacheable)) ++
|
||||
TLBuffer.chain(buffers) ++
|
||||
cork.map(u => TLCacheCork(unsafe = u))
|
||||
).reduce(_ :=* _) :=* gen
|
||||
}
|
||||
}
|
||||
|
||||
def toFixedWidthPort[D,U,E,B <: Data](
|
||||
name: Option[String] = None,
|
||||
buffer: BufferParams = BufferParams.default)
|
||||
(gen: => NodeHandle[TLClientPortParameters,TLManagerPortParameters,TLEdgeIn,TLBundle,D,U,E,B]): OutwardNodeHandle[D,U,E,B] = {
|
||||
to(s"Port${name.getOrElse("")}") {
|
||||
gen := TLWidthWidget(params.beatBytes) := bufferTo(buffer)
|
||||
}
|
||||
}
|
||||
|
||||
def fromPort[D,U,E,B <: Data](
|
||||
name: Option[String] = None,
|
||||
buffers: Int = 0)
|
||||
(gen: => NodeHandle[D,U,E,B,TLClientPortParameters,TLManagerPortParameters,TLEdgeOut,TLBundle]): InwardNodeHandle[D,U,E,B] = {
|
||||
from(s"Port${name.getOrElse("")}") {
|
||||
(List(
|
||||
master_splitter.node,
|
||||
TLFIFOFixer(TLFIFOFixer.all)) ++
|
||||
TLBuffer.chain(buffers)).reduce(_ :=* _) :=* gen
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,85 +0,0 @@
|
||||
// See LICENSE.SiFive for license details.
|
||||
|
||||
package freechips.rocketchip.tilelink
|
||||
|
||||
import Chisel._
|
||||
import freechips.rocketchip.config.{Field, Parameters}
|
||||
import freechips.rocketchip.diplomacy._
|
||||
|
||||
case object TLBusDelayProbability extends Field[Double](0.0)
|
||||
|
||||
/** Specifies widths of various attachement points in the SoC */
|
||||
trait TLBusParams {
|
||||
val beatBytes: Int
|
||||
val blockBytes: Int
|
||||
val masterBuffering: BufferParams
|
||||
val slaveBuffering: BufferParams
|
||||
|
||||
def beatBits: Int = beatBytes * 8
|
||||
def blockBits: Int = blockBytes * 8
|
||||
def blockBeats: Int = blockBytes / beatBytes
|
||||
def blockOffset: Int = log2Up(blockBytes)
|
||||
}
|
||||
|
||||
abstract class TLBusWrapper(params: TLBusParams, val busName: String)(implicit p: Parameters)
|
||||
extends SimpleLazyModule with LazyScope with TLBusParams {
|
||||
|
||||
val beatBytes = params.beatBytes
|
||||
val blockBytes = params.blockBytes
|
||||
val masterBuffering = params.masterBuffering
|
||||
val slaveBuffering = params.slaveBuffering
|
||||
require(blockBytes % beatBytes == 0)
|
||||
private val delayProb = p(TLBusDelayProbability)
|
||||
|
||||
protected val xbar = LazyModule(new TLXbar)
|
||||
xbar.suggestName(busName)
|
||||
|
||||
private val master_buffer = LazyModule(new TLBuffer(masterBuffering))
|
||||
master_buffer.suggestName(s"${busName}_master_TLBuffer")
|
||||
private val slave_buffer = LazyModule(new TLBuffer(slaveBuffering))
|
||||
slave_buffer.suggestName(s"${busName}_slave_TLBuffer")
|
||||
private val slave_frag = LazyModule(new TLFragmenter(beatBytes, blockBytes))
|
||||
slave_frag.suggestName(s"${busName}_slave_TLFragmenter")
|
||||
|
||||
private val slave_ww = LazyModule(new TLWidthWidget(beatBytes))
|
||||
slave_ww.suggestName(s"${busName}_slave_TLWidthWidget")
|
||||
|
||||
private val delayedNode = if (delayProb > 0.0) {
|
||||
val firstDelay = LazyModule(new TLDelayer(delayProb))
|
||||
val flowDelay = LazyModule(new TLBuffer(BufferParams.flow))
|
||||
val secondDelay = LazyModule(new TLDelayer(delayProb))
|
||||
firstDelay.node :*= xbar.node
|
||||
flowDelay.node :*= firstDelay.node
|
||||
secondDelay.node :*= flowDelay.node
|
||||
secondDelay.node
|
||||
} else {
|
||||
xbar.node
|
||||
}
|
||||
|
||||
xbar.node :=* master_buffer.node
|
||||
slave_buffer.node :*= delayedNode
|
||||
slave_frag.node :*= slave_buffer.node
|
||||
slave_ww.node :*= slave_buffer.node
|
||||
|
||||
protected def outwardNode: TLOutwardNode = delayedNode
|
||||
protected def outwardBufNode: TLOutwardNode = slave_buffer.node
|
||||
protected def outwardFragNode: TLOutwardNode = slave_frag.node
|
||||
protected def outwardWWNode: TLOutwardNode = slave_ww.node
|
||||
protected def inwardNode: TLInwardNode = xbar.node
|
||||
protected def inwardBufNode: TLInwardNode = master_buffer.node
|
||||
|
||||
def bufferFromMasters: TLInwardNode = inwardBufNode
|
||||
|
||||
def bufferToSlaves: TLOutwardNode = outwardBufNode
|
||||
|
||||
def toSyncSlaves(name: Option[String] = None, addBuffers: Int = 0): TLOutwardNode = {
|
||||
TLBuffer.chain(addBuffers).foldRight(outwardBufNode)(_ :*= _)
|
||||
}
|
||||
|
||||
def toVariableWidthSlaves: TLOutwardNode = outwardFragNode
|
||||
|
||||
def toFixedWidthSlaves: TLOutwardNode = outwardWWNode
|
||||
|
||||
def toFixedWidthPorts: TLOutwardNode = outwardWWNode // TODO, do/don't buffer here; knowing we will after the necessary port conversions
|
||||
|
||||
}
|
57
src/main/scala/tilelink/BusWrapper.scala
Normal file
57
src/main/scala/tilelink/BusWrapper.scala
Normal file
@ -0,0 +1,57 @@
|
||||
// See LICENSE.SiFive for license details.
|
||||
|
||||
package freechips.rocketchip.tilelink
|
||||
|
||||
import Chisel._
|
||||
import freechips.rocketchip.config.{Field, Parameters}
|
||||
import freechips.rocketchip.diplomacy._
|
||||
|
||||
case object TLBusDelayProbability extends Field[Double](0.0)
|
||||
|
||||
/** Specifies widths of various attachement points in the SoC */
|
||||
trait HasTLBusParams {
|
||||
val beatBytes: Int
|
||||
val blockBytes: Int
|
||||
|
||||
def beatBits: Int = beatBytes * 8
|
||||
def blockBits: Int = blockBytes * 8
|
||||
def blockBeats: Int = blockBytes / beatBytes
|
||||
def blockOffset: Int = log2Up(blockBytes)
|
||||
}
|
||||
|
||||
abstract class TLBusWrapper(params: HasTLBusParams, val busName: String)(implicit p: Parameters)
|
||||
extends SimpleLazyModule with LazyScope with HasTLBusParams {
|
||||
|
||||
val beatBytes = params.beatBytes
|
||||
val blockBytes = params.blockBytes
|
||||
require(blockBytes % beatBytes == 0)
|
||||
|
||||
protected def inwardNode: TLInwardNode
|
||||
protected def outwardNode: TLOutwardNode
|
||||
|
||||
protected def delayNode(implicit p: Parameters): TLNode = {
|
||||
val delayProb = p(TLBusDelayProbability)
|
||||
if (delayProb > 0.0) {
|
||||
TLDelayer(delayProb) :*=* TLBuffer(BufferParams.flow) :*=* TLDelayer(delayProb)
|
||||
} else {
|
||||
val nodelay = TLIdentityNode()
|
||||
nodelay
|
||||
}
|
||||
}
|
||||
|
||||
protected def to[T](name: String)(body: => T): T = {
|
||||
this { LazyScope(s"${busName}To${name}") { body } }
|
||||
}
|
||||
|
||||
protected def from[T](name: String)(body: => T): T = {
|
||||
this { LazyScope(s"${busName}From${name}") { body } }
|
||||
}
|
||||
}
|
||||
|
||||
trait HasTLXbarPhy { this: TLBusWrapper =>
|
||||
private val xbar = LazyModule(new TLXbar)
|
||||
xbar.suggestName(busName)
|
||||
|
||||
protected def inwardNode: TLInwardNode = xbar.node
|
||||
protected def outwardNode: TLOutwardNode = xbar.node
|
||||
}
|
Loading…
Reference in New Issue
Block a user