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))
|
val debug = LazyModule(new TLDebugModule(pbus.beatBytes))
|
||||||
|
|
||||||
debug.node := pbus.toVariableWidthSlaves
|
pbus.toVariableWidthSlave(Some("Debug")){ debug.node }
|
||||||
}
|
}
|
||||||
|
|
||||||
trait HasPeripheryDebugBundle {
|
trait HasPeripheryDebugBundle {
|
||||||
|
@ -71,7 +71,7 @@ trait HasPeripheryBootROM extends HasPeripheryBus {
|
|||||||
|
|
||||||
val bootrom = LazyModule(new TLROM(params.address, params.size, contents, true, pbus.beatBytes))
|
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) */
|
/** 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 that will connect a CLINT to a subsystem */
|
||||||
trait HasPeripheryCLINT extends HasPeripheryBus {
|
trait HasPeripheryCLINT extends HasPeripheryBus {
|
||||||
val clint = LazyModule(new CLINT(p(CLINTKey), pbus.beatBytes))
|
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 {
|
trait HasSystemErrorSlave extends HasSystemBus {
|
||||||
private val params = p(ErrorParams)
|
private val params = p(ErrorParams)
|
||||||
val error = LazyModule(new TLError(params, sbus.beatBytes))
|
val error = LazyModule(new TLError(params, sbus.beatBytes))
|
||||||
|
sbus.toSlave(Some("Error")){ error.node }
|
||||||
error.node := sbus.toSlave
|
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ trait HasPeripheryMaskROMSlave extends HasPeripheryBus {
|
|||||||
val maskROMParams = p(PeripheryMaskROMKey)
|
val maskROMParams = p(PeripheryMaskROMKey)
|
||||||
val maskROMs = maskROMParams map { params =>
|
val maskROMs = maskROMParams map { params =>
|
||||||
val maskROM = LazyModule(new TLMaskROM(params))
|
val maskROM = LazyModule(new TLMaskROM(params))
|
||||||
maskROM.node := pbus.toFixedWidthSingleBeatSlave(maskROM.beatBytes)
|
pbus.toFixedWidthSingleBeatSlave(maskROM.beatBytes, Some("MaskROM")) { maskROM.node }
|
||||||
maskROM
|
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 that will connect a PLIC to a subsystem */
|
||||||
trait HasPeripheryPLIC extends HasInterruptBus with HasPeripheryBus {
|
trait HasPeripheryPLIC extends HasInterruptBus with HasPeripheryBus {
|
||||||
val plic = LazyModule(new TLPLIC(p(PLICKey), pbus.beatBytes))
|
val plic = LazyModule(new TLPLIC(p(PLICKey), pbus.beatBytes)))
|
||||||
plic.node := pbus.toVariableWidthSlaves
|
pbus.toVariableWidthSlave(Some("PLIC")) { plic.node }
|
||||||
plic.intnode := ibus.toPLIC
|
plic.intnode := ibus.toPLIC
|
||||||
}
|
}
|
||||||
|
@ -50,13 +50,16 @@ trait HasMemoryZeroSlave extends HasMemoryBus {
|
|||||||
private val params = p(ZeroParams)
|
private val params = p(ZeroParams)
|
||||||
private val device = new SimpleDevice("rom", Seq("ucbbar,cacheable-zero0"))
|
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 channels = memBuses.size
|
||||||
val base = AddressSet(params.base, params.size-1)
|
val base = AddressSet(params.base, params.size-1)
|
||||||
val filter = AddressSet(channel * cacheBlockBytes, ~((channels-1) * cacheBlockBytes))
|
val filter = AddressSet(channel * cacheBlockBytes, ~((channels-1) * cacheBlockBytes))
|
||||||
val address = base.intersect(filter).get
|
val address = base.intersect(filter).get
|
||||||
val zero = LazyModule(new TLZero(address, beatBytes = params.beatBytes, resources = device.reg("mem")))
|
val zero = LazyModule(new TLZero(address, beatBytes = params.beatBytes, resources = device.reg("mem")))
|
||||||
zero.node := node
|
attach { zero.node }
|
||||||
zero
|
zero
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,15 +28,12 @@ class GroundTestSubsystem(implicit p: Parameters) extends BaseSubsystem
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
tiles.flatMap(_.dcacheOpt).foreach { dc =>
|
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
|
// No PLIC in ground test; so just sink the interrupts to nowhere
|
||||||
IntSinkNode(IntSinkPortSimple()) := ibus.toPLIC
|
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)
|
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. */
|
/** Adds a SRAM to the system for testing purposes. */
|
||||||
trait HasPeripheryTestRAMSlave extends HasPeripheryBus {
|
trait HasPeripheryTestRAMSlave extends HasPeripheryBus {
|
||||||
val testram = LazyModule(new TLRAM(AddressSet(0x52000000, 0xfff), true, true, pbus.beatBytes))
|
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. */
|
/** Adds a fuzzing master to the system for testing purposes. */
|
||||||
trait HasPeripheryTestFuzzMaster extends HasPeripheryBus {
|
trait HasPeripheryTestFuzzMaster extends HasPeripheryBus {
|
||||||
val fuzzer = LazyModule(new TLFuzzer(5000))
|
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
|
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) => {
|
class WithNBitPeripheryBus(nBits: Int) extends Config ((site, here, up) => {
|
||||||
case PeripheryBusKey => up(PeripheryBusKey, site).copy(beatBytes = nBits/8)
|
case PeripheryBusKey => up(PeripheryBusKey, site).copy(beatBytes = nBits/8)
|
||||||
})
|
})
|
||||||
|
@ -8,38 +8,40 @@ import freechips.rocketchip.diplomacy._
|
|||||||
import freechips.rocketchip.tilelink._
|
import freechips.rocketchip.tilelink._
|
||||||
import freechips.rocketchip.util._
|
import freechips.rocketchip.util._
|
||||||
|
|
||||||
case class FrontBusParams(
|
case class FrontBusParams(beatBytes: Int, blockBytes: Int) extends HasTLBusParams
|
||||||
beatBytes: Int,
|
|
||||||
blockBytes: Int,
|
|
||||||
masterBuffering: BufferParams = BufferParams.default,
|
|
||||||
slaveBuffering: BufferParams = BufferParams.default
|
|
||||||
) extends TLBusParams
|
|
||||||
|
|
||||||
case object FrontBusKey extends Field[FrontBusParams]
|
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))
|
def fromPort[D,U,E,B <: Data](
|
||||||
private val master_fixer = LazyModule(new TLFIFOFixer(TLFIFOFixer.all))
|
name: Option[String] = None,
|
||||||
|
buffers: Int = 1)
|
||||||
master_buffer.suggestName(s"${busName}_master_TLBuffer")
|
(gen: => NodeHandle[D,U,E,B,TLClientPortParameters,TLManagerPortParameters,TLEdgeOut,TLBundle]): InwardNodeHandle[D,U,E,B] = {
|
||||||
master_fixer.suggestName(s"${busName}_master_TLFIFOFixer")
|
from(s"Port${name.getOrElse("")}") {
|
||||||
|
val nodes = TLFIFOFixer(TLFIFOFixer.all) +: TLBuffer.chain(buffers)
|
||||||
master_fixer.node :=* master_buffer.node
|
inwardNode :=* nodes.reduce(_ :=* _) :=* gen
|
||||||
inwardNode :=* master_fixer.node
|
}
|
||||||
|
|
||||||
def fromSyncPorts(addBuffers: Int = 0, name: Option[String] = None): TLInwardNode = {
|
|
||||||
TLBuffer.chain(addBuffers).foldLeft(master_buffer.node:TLInwardNode)(_ :=* _)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def fromSyncMasters(addBuffers: Int = 0, name: Option[String] = None): TLInwardNode = {
|
def fromMaster(name: Option[String] = None, buffers: Int = 1)
|
||||||
TLBuffer.chain(addBuffers).foldLeft(master_buffer.node:TLInwardNode)(_ :=* _)
|
(gen: => TLNode): TLInwardNode = {
|
||||||
|
from(s"Master${name.getOrElse("")}") {
|
||||||
|
inwardNode :=* TLBuffer.chain(buffers).reduce(_ :=* _) :=* gen
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def fromCoherentChip: TLInwardNode = inwardNode
|
def fromCoherentChip(gen: => TLNode): TLInwardNode = {
|
||||||
|
from("CoherentChip") { inwardNode :=* gen }
|
||||||
def toSystemBus : TLOutwardNode = TLBuffer(params.slaveBuffering) :=* xbar.node
|
}
|
||||||
|
|
||||||
|
def toSystemBus(buffer: BufferParams = BufferParams.none)
|
||||||
|
(gen: => TLInwardNode) {
|
||||||
|
to("SystemBus") { gen :*= TLBuffer(buffer) :*= outwardNode }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Provides buses that serve as attachment points,
|
/** Provides buses that serve as attachment points,
|
||||||
@ -51,5 +53,7 @@ trait HasFrontBus extends HasSystemBus {
|
|||||||
|
|
||||||
val fbus = LazyModule(new FrontBus(frontbusParams))
|
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())
|
case object BankedL2Key extends Field(BankedL2Params())
|
||||||
|
|
||||||
/** Parameterization of the memory-side bus created for each memory channel */
|
/** Parameterization of the memory-side bus created for each memory channel */
|
||||||
case class MemoryBusParams(
|
case class MemoryBusParams(beatBytes: Int, blockBytes: Int) extends HasTLBusParams
|
||||||
beatBytes: Int,
|
|
||||||
blockBytes: Int,
|
|
||||||
masterBuffering: BufferParams = BufferParams.none,
|
|
||||||
slaveBuffering: BufferParams = BufferParams.none
|
|
||||||
) extends TLBusParams
|
|
||||||
|
|
||||||
case object MemoryBusKey extends Field[MemoryBusParams]
|
case object MemoryBusKey extends Field[MemoryBusParams]
|
||||||
|
|
||||||
/** Wrapper for creating TL nodes from a bus connected to the back of each mem channel */
|
/** 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) {
|
class MemoryBus(params: MemoryBusParams)(implicit p: Parameters) extends TLBusWrapper(params, "MemoryBus")(p)
|
||||||
def fromCoherenceManager: TLInwardNode = inwardBufNode
|
with HasTLXbarPhy {
|
||||||
def toDRAMController: TLOutwardNode = outwardBufNode
|
|
||||||
def toVariableWidthSlave: TLOutwardNode = outwardFragNode
|
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 {
|
trait HasMemoryBus extends HasSystemBus with HasPeripheryBus with HasInterruptBus {
|
||||||
private val mbusParams = p(MemoryBusKey)
|
private val mbusParams = p(MemoryBusKey)
|
||||||
private val l2Params = p(BankedL2Key)
|
private val l2Params = p(BankedL2Key)
|
||||||
val MemoryBusParams(memBusBeatBytes, memBusBlockBytes, _, _) = mbusParams
|
val MemoryBusParams(memBusBeatBytes, memBusBlockBytes) = mbusParams
|
||||||
val BankedL2Params(nMemoryChannels, nBanksPerChannel, coherenceManager) = l2Params
|
val BankedL2Params(nMemoryChannels, nBanksPerChannel, coherenceManager) = l2Params
|
||||||
val nBanks = l2Params.nBanks
|
val nBanks = l2Params.nBanks
|
||||||
val cacheBlockBytes = memBusBlockBytes
|
val cacheBlockBytes = memBusBlockBytes
|
||||||
@ -71,8 +92,8 @@ trait HasMemoryBus extends HasSystemBus with HasPeripheryBus with HasInterruptBu
|
|||||||
val mbus = LazyModule(new MemoryBus(mbusParams))
|
val mbus = LazyModule(new MemoryBus(mbusParams))
|
||||||
for (bank <- 0 until nBanksPerChannel) {
|
for (bank <- 0 until nBanksPerChannel) {
|
||||||
val offset = (bank * nMemoryChannels) + channel
|
val offset = (bank * nMemoryChannels) + channel
|
||||||
ForceFanout(a = true) { implicit p => in := sbus.toMemoryBus }
|
ForceFanout(a = true) { implicit p => sbus.toMemoryBus { in } }
|
||||||
mbus.fromCoherenceManager := TLFilter(TLFilter.Mmask(AddressSet(offset * memBusBlockBytes, mask))) := out
|
mbus.fromCoherenceManager(None) { TLFilter(TLFilter.Mmask(AddressSet(offset * memBusBlockBytes, mask))) } := out
|
||||||
}
|
}
|
||||||
mbus
|
mbus
|
||||||
}
|
}
|
||||||
|
@ -7,41 +7,97 @@ import freechips.rocketchip.config.{Field, Parameters}
|
|||||||
import freechips.rocketchip.diplomacy._
|
import freechips.rocketchip.diplomacy._
|
||||||
import freechips.rocketchip.tilelink._
|
import freechips.rocketchip.tilelink._
|
||||||
|
|
||||||
import freechips.rocketchip.config.Field
|
|
||||||
|
|
||||||
case class PeripheryBusParams(
|
case class PeripheryBusParams(
|
||||||
beatBytes: Int,
|
beatBytes: Int,
|
||||||
blockBytes: Int,
|
blockBytes: Int,
|
||||||
masterBuffering: BufferParams = BufferParams.default,
|
|
||||||
slaveBuffering: BufferParams = BufferParams.none,
|
|
||||||
arithmetic: Boolean = true,
|
|
||||||
frequency: BigInt = BigInt(100000000) // 100 MHz as default bus frequency
|
frequency: BigInt = BigInt(100000000) // 100 MHz as default bus frequency
|
||||||
) extends TLBusParams {
|
) extends HasTLBusParams
|
||||||
}
|
|
||||||
|
|
||||||
case object PeripheryBusKey extends Field[PeripheryBusParams]
|
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) = {
|
private def bufferTo(buffer: BufferParams): TLOutwardNode =
|
||||||
TLFragmenter(widthBytes, params.blockBytes) := outwardWWNode
|
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) = {
|
def toVariableWidthSlave(
|
||||||
TLFragmenter(params.beatBytes, maxXferBytes) := outwardBufNode
|
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 = {
|
def toFixedWidthSlave(
|
||||||
val atomics = LazyModule(new TLAtomicAutomata(arithmetic = params.arithmetic))
|
name: Option[String] = None,
|
||||||
xbar.node :*= TLBuffer(params.masterBuffering) :*= atomics.node
|
buffer: BufferParams = BufferParams.none)
|
||||||
|
(gen: => TLNode): TLOutwardNode = {
|
||||||
|
to(s"Slave${name.getOrElse("")}") {
|
||||||
|
gen :*= fixedWidthTo(buffer)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def toTile(name: Option[String] = None)(gen: Parameters => TLInwardNode) {
|
def toFixedWidthSingleBeatSlave(
|
||||||
this {
|
widthBytes: Int,
|
||||||
LazyScope(s"${busName}ToTile${name.getOrElse("")}") {
|
name: Option[String] = None,
|
||||||
FlipRendering { implicit p =>
|
buffer: BufferParams = BufferParams.none)
|
||||||
gen(p) :*= outwardNode
|
(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))
|
val pbus = LazyModule(new PeripheryBus(pbusParams))
|
||||||
|
|
||||||
// The peripheryBus hangs off of systemBus; here we convert TL-UH -> TL-UL
|
// 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)
|
beatBytes = params.beatBytes)
|
||||||
})
|
})
|
||||||
|
|
||||||
val converter = LazyModule(new TLToAXI4())
|
memBuses.map { m =>
|
||||||
val trim = LazyModule(new AXI4IdIndexer(params.idBits))
|
mem_axi4 := m.toDRAMController(Some("AXI4DRAM")) {
|
||||||
val yank = LazyModule(new AXI4UserYanker)
|
(AXI4UserYanker() := AXI4IdIndexer(params.idBits) := TLToAXI4())
|
||||||
val buffer = LazyModule(new AXI4Buffer)
|
}
|
||||||
|
|
||||||
memBuses.map(_.toDRAMController).foreach { case node =>
|
|
||||||
mem_axi4 := buffer.node := yank.node := trim.node := converter.node := node
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,13 +90,13 @@ trait HasMasterAXI4MMIOPort extends HasSystemBus {
|
|||||||
supportsRead = TransferSizes(1, params.maxXferBytes))),
|
supportsRead = TransferSizes(1, params.maxXferBytes))),
|
||||||
beatBytes = params.beatBytes)))
|
beatBytes = params.beatBytes)))
|
||||||
|
|
||||||
(mmio_axi4
|
mmio_axi4 := sbus.toFixedWidthPort(Some("AXI4MMIO")) {
|
||||||
:= AXI4Buffer()
|
(AXI4Buffer()
|
||||||
:= AXI4UserYanker()
|
:= AXI4UserYanker()
|
||||||
:= AXI4Deinterleaver(sbus.blockBytes)
|
:= AXI4Deinterleaver(sbus.blockBytes)
|
||||||
:= AXI4IdIndexer(params.idBits)
|
:= AXI4IdIndexer(params.idBits)
|
||||||
:= TLToAXI4()
|
:= TLToAXI4())
|
||||||
:= sbus.toFixedWidthPorts)
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Common io name and methods for propagating or tying off the port bundle */
|
/** 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))))))
|
id = IdRange(0, 1 << params.idBits))))))
|
||||||
|
|
||||||
private val fifoBits = 1
|
private val fifoBits = 1
|
||||||
(sbus.fromSyncPorts()
|
sbus.fromPort(Some("AXI4Front")) {
|
||||||
:= TLWidthWidget(params.beatBytes)
|
(TLWidthWidget(params.beatBytes)
|
||||||
:= AXI4ToTL()
|
:= AXI4ToTL()
|
||||||
:= AXI4UserYanker(Some(1 << (params.sourceBits - fifoBits - 1)))
|
:= AXI4UserYanker(Some(1 << (params.sourceBits - fifoBits - 1)))
|
||||||
:= AXI4Fragmenter()
|
:= AXI4Fragmenter()
|
||||||
:= AXI4IdIndexer(fifoBits)
|
:= AXI4IdIndexer(fifoBits))
|
||||||
:= l2FrontendAXI4Node)
|
} := l2FrontendAXI4Node
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Common io name and methods for propagating or tying off the port bundle */
|
/** 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))),
|
supportsPutPartial = TransferSizes(1, sbus.blockBytes))),
|
||||||
beatBytes = params.beatBytes)))
|
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 */
|
/** 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)",
|
name = "Front Port (TL)",
|
||||||
sourceId = IdRange(0, 1 << params.idBits))))))
|
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 */
|
/** 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?
|
// TODO: how specific are these to RocketTiles?
|
||||||
case class TileMasterPortParams(
|
case class TileMasterPortParams(
|
||||||
addBuffers: Int = 0,
|
buffers: Int = 0,
|
||||||
cork: Option[Boolean] = None) {
|
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)(_ :=* _)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
case class TileSlavePortParams(
|
case class TileSlavePortParams(
|
||||||
addBuffers: Int = 0,
|
addBuffers: Int = 0,
|
||||||
@ -41,9 +30,12 @@ case class TileSlavePortParams(
|
|||||||
.map(BasicBusBlockerParams(_, subsystem.pbus.beatBytes, subsystem.sbus.beatBytes))
|
.map(BasicBusBlockerParams(_, subsystem.pbus.beatBytes, subsystem.sbus.beatBytes))
|
||||||
.map(bp => LazyModule(new BasicBusBlocker(bp)))
|
.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))
|
(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
|
// 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 =>
|
DisableMonitors { implicit p =>
|
||||||
tileSlaveBuffering :*= rocket.crossTLIn
|
tileSlaveBuffering :*= pbus.toTile(tp.name) { rocket.crossTLIn }
|
||||||
})}
|
}
|
||||||
|
|
||||||
// Handle all the different types of interrupts crossing to or from the tile:
|
// Handle all the different types of interrupts crossing to or from the tile:
|
||||||
// 1. Debug interrupt is definitely asynchronous in all cases.
|
// 1. Debug interrupt is definitely asynchronous in all cases.
|
||||||
|
@ -8,65 +8,94 @@ import freechips.rocketchip.diplomacy._
|
|||||||
import freechips.rocketchip.tilelink._
|
import freechips.rocketchip.tilelink._
|
||||||
import freechips.rocketchip.util._
|
import freechips.rocketchip.util._
|
||||||
|
|
||||||
case class SystemBusParams(
|
case class SystemBusParams(beatBytes: Int, blockBytes: Int) extends HasTLBusParams
|
||||||
beatBytes: Int,
|
|
||||||
blockBytes: Int,
|
|
||||||
masterBuffering: BufferParams = BufferParams.default,
|
|
||||||
slaveBuffering: BufferParams = BufferParams.default
|
|
||||||
) extends TLBusParams
|
|
||||||
|
|
||||||
case object SystemBusKey extends Field[SystemBusParams]
|
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
|
private val master_splitter = LazyModule(new TLSplitter)
|
||||||
master_splitter.suggestName(s"${busName}_master_TLSplitter")
|
|
||||||
inwardNode :=* master_splitter.node
|
inwardNode :=* master_splitter.node
|
||||||
|
|
||||||
def busView = master_splitter.node.edges.in.head
|
def busView = master_splitter.node.edges.in.head
|
||||||
|
|
||||||
protected def inwardSplitNode: TLInwardNode = master_splitter.node
|
private def bufferTo(buffer: BufferParams): TLOutwardNode =
|
||||||
protected def outwardSplitNode: TLOutwardNode = master_splitter.node
|
TLBuffer(buffer) :*= delayNode :*= outwardNode
|
||||||
|
|
||||||
|
def toPeripheryBus(buffer: BufferParams = BufferParams.none)
|
||||||
private val port_fixer = LazyModule(new TLFIFOFixer(TLFIFOFixer.all))
|
(gen: => TLNode): TLOutwardNode = {
|
||||||
port_fixer.suggestName(s"${busName}_port_TLFIFOFixer")
|
to("PeripheryBus") {
|
||||||
master_splitter.node :=* port_fixer.node
|
(gen
|
||||||
|
:= TLFIFOFixer(TLFIFOFixer.all)
|
||||||
private val pbus_fixer = LazyModule(new TLFIFOFixer(TLFIFOFixer.all))
|
:= TLWidthWidget(params.beatBytes)
|
||||||
pbus_fixer.suggestName(s"${busName}_pbus_TLFIFOFixer")
|
:= bufferTo(buffer))
|
||||||
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 fromSyncPorts(params: BufferParams = BufferParams.default, name: Option[String] = None): TLInwardNode = {
|
def toMemoryBus(gen: => TLInwardNode) {
|
||||||
val buffer = LazyModule(new TLBuffer(params))
|
to("MemoryBus") { gen :*= delayNode :*= outwardNode }
|
||||||
name.foreach { n => buffer.suggestName(s"${busName}_${n}_TLBuffer") }
|
|
||||||
port_fixer.node :=* buffer.node
|
|
||||||
buffer.node
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def fromSyncFIFOMaster(params: BufferParams = BufferParams.default, name: Option[String] = None): TLInwardNode = {
|
def toSlave(name: Option[String] = None, buffer: BufferParams = BufferParams.default)
|
||||||
fromSyncPorts(params, name)
|
(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