From 3f436a76127a78d7c1e1700712f53f014aec8cea Mon Sep 17 00:00:00 2001 From: Henry Cook Date: Thu, 15 Feb 2018 14:01:49 -0800 Subject: [PATCH] subsystem: new bus attachment api --- src/main/scala/devices/debug/Periphery.scala | 2 +- src/main/scala/devices/tilelink/BootROM.scala | 2 +- src/main/scala/devices/tilelink/CLINT.scala | 2 +- src/main/scala/devices/tilelink/Error.scala | 3 +- src/main/scala/devices/tilelink/MaskROM.scala | 2 +- src/main/scala/devices/tilelink/Plic.scala | 4 +- src/main/scala/devices/tilelink/Zero.scala | 7 +- src/main/scala/groundtest/Coreplex.scala | 9 +- src/main/scala/subsystem/Configs.scala | 4 - src/main/scala/subsystem/FrontBus.scala | 52 ++++---- src/main/scala/subsystem/MemoryBus.scala | 47 +++++-- src/main/scala/subsystem/PeripheryBus.scala | 100 +++++++++++---- src/main/scala/subsystem/Ports.scala | 47 +++---- .../scala/subsystem/RocketSubsystem.scala | 32 ++--- src/main/scala/subsystem/SystemBus.scala | 121 +++++++++++------- src/main/scala/tilelink/Bus.scala | 85 ------------ src/main/scala/tilelink/BusWrapper.scala | 57 +++++++++ 17 files changed, 324 insertions(+), 252 deletions(-) delete mode 100644 src/main/scala/tilelink/Bus.scala create mode 100644 src/main/scala/tilelink/BusWrapper.scala diff --git a/src/main/scala/devices/debug/Periphery.scala b/src/main/scala/devices/debug/Periphery.scala index 4d18ec7a..17ba6425 100644 --- a/src/main/scala/devices/debug/Periphery.scala +++ b/src/main/scala/devices/debug/Periphery.scala @@ -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 { diff --git a/src/main/scala/devices/tilelink/BootROM.scala b/src/main/scala/devices/tilelink/BootROM.scala index d4def318..3f12ac32 100644 --- a/src/main/scala/devices/tilelink/BootROM.scala +++ b/src/main/scala/devices/tilelink/BootROM.scala @@ -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) */ diff --git a/src/main/scala/devices/tilelink/CLINT.scala b/src/main/scala/devices/tilelink/CLINT.scala index 12d2a8a5..39e0aab0 100644 --- a/src/main/scala/devices/tilelink/CLINT.scala +++ b/src/main/scala/devices/tilelink/CLINT.scala @@ -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 } } diff --git a/src/main/scala/devices/tilelink/Error.scala b/src/main/scala/devices/tilelink/Error.scala index b8b1de94..05c0b82c 100644 --- a/src/main/scala/devices/tilelink/Error.scala +++ b/src/main/scala/devices/tilelink/Error.scala @@ -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 } } diff --git a/src/main/scala/devices/tilelink/MaskROM.scala b/src/main/scala/devices/tilelink/MaskROM.scala index a5e15d45..2d30352c 100644 --- a/src/main/scala/devices/tilelink/MaskROM.scala +++ b/src/main/scala/devices/tilelink/MaskROM.scala @@ -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 } } diff --git a/src/main/scala/devices/tilelink/Plic.scala b/src/main/scala/devices/tilelink/Plic.scala index f2aa9af2..7bbab18f 100644 --- a/src/main/scala/devices/tilelink/Plic.scala +++ b/src/main/scala/devices/tilelink/Plic.scala @@ -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 } diff --git a/src/main/scala/devices/tilelink/Zero.scala b/src/main/scala/devices/tilelink/Zero.scala index 33d46f36..4085175d 100644 --- a/src/main/scala/devices/tilelink/Zero.scala +++ b/src/main/scala/devices/tilelink/Zero.scala @@ -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 } } diff --git a/src/main/scala/groundtest/Coreplex.scala b/src/main/scala/groundtest/Coreplex.scala index b2cf5971..7fa8d440 100644 --- a/src/main/scala/groundtest/Coreplex.scala +++ b/src/main/scala/groundtest/Coreplex.scala @@ -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 } } diff --git a/src/main/scala/subsystem/Configs.scala b/src/main/scala/subsystem/Configs.scala index 189e054a..ab7df567 100644 --- a/src/main/scala/subsystem/Configs.scala +++ b/src/main/scala/subsystem/Configs.scala @@ -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) }) diff --git a/src/main/scala/subsystem/FrontBus.scala b/src/main/scala/subsystem/FrontBus.scala index a55852f6..69cd9457 100644 --- a/src/main/scala/subsystem/FrontBus.scala +++ b/src/main/scala/subsystem/FrontBus.scala @@ -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 } } + } } diff --git a/src/main/scala/subsystem/MemoryBus.scala b/src/main/scala/subsystem/MemoryBus.scala index a401ecc5..be90db73 100644 --- a/src/main/scala/subsystem/MemoryBus.scala +++ b/src/main/scala/subsystem/MemoryBus.scala @@ -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 } diff --git a/src/main/scala/subsystem/PeripheryBus.scala b/src/main/scala/subsystem/PeripheryBus.scala index 6c52bd92..70c86e4c 100644 --- a/src/main/scala/subsystem/PeripheryBus.scala +++ b/src/main/scala/subsystem/PeripheryBus.scala @@ -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 } } } diff --git a/src/main/scala/subsystem/Ports.scala b/src/main/scala/subsystem/Ports.scala index 864b86b8..f2a62320 100644 --- a/src/main/scala/subsystem/Ports.scala +++ b/src/main/scala/subsystem/Ports.scala @@ -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 */ diff --git a/src/main/scala/subsystem/RocketSubsystem.scala b/src/main/scala/subsystem/RocketSubsystem.scala index 5c512dad..7c80ccef 100644 --- a/src/main/scala/subsystem/RocketSubsystem.scala +++ b/src/main/scala/subsystem/RocketSubsystem.scala @@ -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. diff --git a/src/main/scala/subsystem/SystemBus.scala b/src/main/scala/subsystem/SystemBus.scala index 3d510874..790615b6 100644 --- a/src/main/scala/subsystem/SystemBus.scala +++ b/src/main/scala/subsystem/SystemBus.scala @@ -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 + } } } diff --git a/src/main/scala/tilelink/Bus.scala b/src/main/scala/tilelink/Bus.scala deleted file mode 100644 index 02169b61..00000000 --- a/src/main/scala/tilelink/Bus.scala +++ /dev/null @@ -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 - -} diff --git a/src/main/scala/tilelink/BusWrapper.scala b/src/main/scala/tilelink/BusWrapper.scala new file mode 100644 index 00000000..16db71b6 --- /dev/null +++ b/src/main/scala/tilelink/BusWrapper.scala @@ -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 +}