subsystem: new bus attachment api
This commit is contained in:
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user