diff --git a/src/main/scala/amba/axi4/AsyncCrossing.scala b/src/main/scala/amba/axi4/AsyncCrossing.scala index 3110ef23..ed2dd7f2 100644 --- a/src/main/scala/amba/axi4/AsyncCrossing.scala +++ b/src/main/scala/amba/axi4/AsyncCrossing.scala @@ -7,7 +7,7 @@ import freechips.rocketchip.config.Parameters import freechips.rocketchip.diplomacy._ import freechips.rocketchip.tilelink._ import freechips.rocketchip.util._ -import freechips.rocketchip.coreplex.{CrossingWrapper, AsynchronousCrossing} +import freechips.rocketchip.subsystem.{CrossingWrapper, AsynchronousCrossing} class AXI4AsyncCrossingSource(sync: Int = 3)(implicit p: Parameters) extends LazyModule { diff --git a/src/main/scala/coreplex/FrontBus.scala b/src/main/scala/coreplex/FrontBus.scala deleted file mode 100644 index adab063a..00000000 --- a/src/main/scala/coreplex/FrontBus.scala +++ /dev/null @@ -1,55 +0,0 @@ -// See LICENSE.SiFive for license details. - -package freechips.rocketchip.coreplex - -import Chisel._ -import freechips.rocketchip.config.{Field, Parameters} -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 object FrontBusKey extends Field[FrontBusParams] - -class FrontBus(params: FrontBusParams)(implicit p: Parameters) extends TLBusWrapper(params, "FrontBus") { - - 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 fromSyncMasters(addBuffers: Int = 0, name: Option[String] = None): TLInwardNode = { - TLBuffer.chain(addBuffers).foldLeft(master_buffer.node:TLInwardNode)(_ :=* _) - } - - def fromCoherentChip: TLInwardNode = inwardNode - - def toSystemBus : TLOutwardNode = TLBuffer(params.slaveBuffering) :=* xbar.node - -} - -/** Provides buses that serve as attachment points, - * for use in traits that connect individual devices or external ports. - */ -trait HasFrontBus extends HasSystemBus { - private val frontbusParams = p(FrontBusKey) - val frontbusBeatBytes = frontbusParams.beatBytes - - val fbus = LazyModule(new FrontBus(frontbusParams)) - - FlipRendering { implicit p => sbus.fromFrontBus :=* fbus.toSystemBus } -} diff --git a/src/main/scala/coreplex/MemoryBus.scala b/src/main/scala/coreplex/MemoryBus.scala deleted file mode 100644 index 105f132b..00000000 --- a/src/main/scala/coreplex/MemoryBus.scala +++ /dev/null @@ -1,79 +0,0 @@ -// See LICENSE.SiFive for license details. - -package freechips.rocketchip.coreplex - -import Chisel._ -import freechips.rocketchip.config._ -import freechips.rocketchip.diplomacy._ -import freechips.rocketchip.tilelink._ -import freechips.rocketchip.util._ - -// TODO: applies to all caches, for now -case object CacheBlockBytes extends Field[Int](64) - -/** L2 Broadcast Hub configuration */ -case class BroadcastParams( - nTrackers: Int = 4, - bufferless: Boolean = false) - -case object BroadcastKey extends Field(BroadcastParams()) - -/** L2 memory subsystem configuration */ -case class BankedL2Params( - nMemoryChannels: Int = 1, - nBanksPerChannel: Int = 1, - coherenceManager: HasMemoryBus => (TLInwardNode, TLOutwardNode, () => Option[Bool]) = { coreplex => - implicit val p = coreplex.p - val BroadcastParams(nTrackers, bufferless) = p(BroadcastKey) - val bh = LazyModule(new TLBroadcast(coreplex.memBusBlockBytes, nTrackers, bufferless)) - val ww = LazyModule(new TLWidthWidget(coreplex.sbusBeatBytes)) - ww.node :*= bh.node - (bh.node, ww.node, () => None) - }) { - val nBanks = nMemoryChannels*nBanksPerChannel -} - -case object BankedL2Key extends Field(BankedL2Params()) - -/** Parameterization of the memory-side bus created for each memory channel */ -case class MemoryBusParams( - beatBytes: Int, - blockBytes: Int, - masterBuffering: BufferParams = BufferParams.none, - slaveBuffering: BufferParams = BufferParams.none -) extends TLBusParams - -case object MemoryBusKey extends Field[MemoryBusParams] - -/** Wrapper for creating TL nodes from a bus connected to the back of each mem channel */ -class MemoryBus(params: MemoryBusParams)(implicit p: Parameters) extends TLBusWrapper(params, "MemoryBus")(p) { - def fromCoherenceManager: TLInwardNode = inwardBufNode - def toDRAMController: TLOutwardNode = outwardBufNode - def toVariableWidthSlave: TLOutwardNode = outwardFragNode -} - -trait HasMemoryBus extends HasSystemBus with HasPeripheryBus with HasInterruptBus { - private val mbusParams = p(MemoryBusKey) - private val l2Params = p(BankedL2Key) - val MemoryBusParams(memBusBeatBytes, memBusBlockBytes, _, _) = mbusParams - val BankedL2Params(nMemoryChannels, nBanksPerChannel, coherenceManager) = l2Params - val nBanks = l2Params.nBanks - val cacheBlockBytes = memBusBlockBytes - private val (in, out, halt) = coherenceManager(this) - def memBusCanCauseHalt: () => Option[Bool] = halt - - require (isPow2(nMemoryChannels) || nMemoryChannels == 0) - require (isPow2(nBanksPerChannel)) - require (isPow2(memBusBlockBytes)) - - private val mask = ~BigInt((nBanks-1) * memBusBlockBytes) - val memBuses = Seq.tabulate(nMemoryChannels) { channel => - val mbus = LazyModule(new MemoryBus(mbusParams)) - for (bank <- 0 until nBanksPerChannel) { - val offset = (bank * nMemoryChannels) + channel - ForceFanout(a = true) { implicit p => in := sbus.toMemoryBus } - mbus.fromCoherenceManager := TLFilter(TLFilter.Mmask(AddressSet(offset * memBusBlockBytes, mask))) := out - } - mbus - } -} diff --git a/src/main/scala/coreplex/PeripheryBus.scala b/src/main/scala/coreplex/PeripheryBus.scala deleted file mode 100644 index 7b56f1ec..00000000 --- a/src/main/scala/coreplex/PeripheryBus.scala +++ /dev/null @@ -1,61 +0,0 @@ -// See LICENSE.SiFive for license details. - -package freechips.rocketchip.coreplex - -import Chisel._ -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 { -} - -case object PeripheryBusKey extends Field[PeripheryBusParams] - -class PeripheryBus(params: PeripheryBusParams)(implicit p: Parameters) extends TLBusWrapper(params, "PeripheryBus") { - - def toFixedWidthSingleBeatSlave(widthBytes: Int) = { - TLFragmenter(widthBytes, params.blockBytes) := outwardWWNode - } - - def toLargeBurstSlave(maxXferBytes: Int) = { - TLFragmenter(params.beatBytes, maxXferBytes) := outwardBufNode - } - - val fromSystemBus: TLInwardNode = { - val atomics = LazyModule(new TLAtomicAutomata(arithmetic = params.arithmetic)) - xbar.node :*= TLBuffer(params.masterBuffering) :*= atomics.node - } - - def toTile(name: Option[String] = None)(gen: Parameters => TLInwardNode) { - this { - LazyScope(s"${busName}ToTile${name.getOrElse("")}") { - FlipRendering { implicit p => - gen(p) :*= outwardNode - } - } - } - } -} - -/** Provides buses that serve as attachment points, - * for use in traits that connect individual devices or external ports. - */ -trait HasPeripheryBus extends HasSystemBus { - private val pbusParams = p(PeripheryBusKey) - val pbusBeatBytes = pbusParams.beatBytes - - val pbus = LazyModule(new PeripheryBus(pbusParams)) - - // The peripheryBus hangs off of systemBus; here we convert TL-UH -> TL-UL - pbus.fromSystemBus :*= sbus.toPeripheryBus() -} diff --git a/src/main/scala/coreplex/SystemBus.scala b/src/main/scala/coreplex/SystemBus.scala deleted file mode 100644 index 1f403d95..00000000 --- a/src/main/scala/coreplex/SystemBus.scala +++ /dev/null @@ -1,83 +0,0 @@ -// See LICENSE.SiFive for license details. - -package freechips.rocketchip.coreplex - -import Chisel._ -import freechips.rocketchip.config.{Field, Parameters} -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 object SystemBusKey extends Field[SystemBusParams] - -class SystemBus(params: SystemBusParams)(implicit p: Parameters) extends TLBusWrapper(params, "SystemBus") { - - private val master_splitter = LazyModule(new TLSplitter) // Allows cycle-free connection to external networks - master_splitter.suggestName(s"${busName}_master_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 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 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 fromSyncFIFOMaster(params: BufferParams = BufferParams.default, name: Option[String] = None): TLInwardNode = { - fromSyncPorts(params, name) - } -} - -/** Provides buses that serve as attachment points, - * for use in traits that connect individual devices or external ports. - */ -trait HasSystemBus extends HasInterruptBus { - private val sbusParams = p(SystemBusKey) - val sbusBeatBytes = sbusParams.beatBytes - - val sbus = LazyModule(new SystemBus(sbusParams)) - - def sharedMemoryTLEdge: TLEdge = sbus.busView -} diff --git a/src/main/scala/devices/debug/Periphery.scala b/src/main/scala/devices/debug/Periphery.scala index 2496b15d..e76509da 100644 --- a/src/main/scala/devices/debug/Periphery.scala +++ b/src/main/scala/devices/debug/Periphery.scala @@ -5,7 +5,7 @@ package freechips.rocketchip.devices.debug import Chisel._ import chisel3.core.{IntParam, Input, Output} import freechips.rocketchip.config.{Field, Parameters} -import freechips.rocketchip.coreplex.HasPeripheryBus +import freechips.rocketchip.subsystem._ import freechips.rocketchip.devices.tilelink._ import freechips.rocketchip.diplomacy._ import freechips.rocketchip.jtag._ @@ -26,12 +26,9 @@ class DebugIO(implicit val p: Parameters) extends ParameterizedBundle()(p) with /** Either adds a JTAG DTM to system, and exports a JTAG interface, * or exports the Debug Module Interface (DMI), based on a global parameter. */ -trait HasPeripheryDebug extends HasPeripheryBus { - val module: HasPeripheryDebugModuleImp - +trait HasPeripheryDebug { this: BaseSubsystem => 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 1110171c..83bf3b29 100644 --- a/src/main/scala/devices/tilelink/BootROM.scala +++ b/src/main/scala/devices/tilelink/BootROM.scala @@ -4,7 +4,7 @@ package freechips.rocketchip.devices.tilelink import Chisel._ import freechips.rocketchip.config.{Field, Parameters} -import freechips.rocketchip.coreplex._ +import freechips.rocketchip.subsystem.{BaseSubsystem, HasResetVectorWire} import freechips.rocketchip.diplomacy._ import freechips.rocketchip.tilelink._ import freechips.rocketchip.util._ @@ -58,8 +58,8 @@ class TLROM(val base: BigInt, val size: Int, contentsDelayed: => Seq[Byte], exec } } -/** Adds a boot ROM that contains the DTB describing the system's coreplex. */ -trait HasPeripheryBootROM extends HasPeripheryBus { +/** Adds a boot ROM that contains the DTB describing the system's subsystem. */ +trait HasPeripheryBootROM { this: BaseSubsystem => val dtb: DTB private val params = p(BootROMParams) private lazy val contents = { @@ -71,10 +71,10 @@ 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 } } -/** Coreplex will power-on running at 0x10040 (BootROM) */ +/** Subsystem will power-on running at 0x10040 (BootROM) */ trait HasPeripheryBootROMModuleImp extends LazyModuleImp with HasResetVectorWire { val outer: HasPeripheryBootROM diff --git a/src/main/scala/devices/tilelink/BusBypass.scala b/src/main/scala/devices/tilelink/BusBypass.scala index 9c99a3a1..9668fb89 100644 --- a/src/main/scala/devices/tilelink/BusBypass.scala +++ b/src/main/scala/devices/tilelink/BusBypass.scala @@ -4,7 +4,6 @@ package freechips.rocketchip.devices.tilelink import Chisel._ import freechips.rocketchip.config.{Field, Parameters} -import freechips.rocketchip.coreplex.HasPeripheryBus import freechips.rocketchip.diplomacy._ import freechips.rocketchip.tilelink._ import freechips.rocketchip.util._ diff --git a/src/main/scala/devices/tilelink/Clint.scala b/src/main/scala/devices/tilelink/CLINT.scala similarity index 81% rename from src/main/scala/devices/tilelink/Clint.scala rename to src/main/scala/devices/tilelink/CLINT.scala index 75f16ab7..5c9d3358 100644 --- a/src/main/scala/devices/tilelink/Clint.scala +++ b/src/main/scala/devices/tilelink/CLINT.scala @@ -4,7 +4,7 @@ package freechips.rocketchip.devices.tilelink import Chisel._ import freechips.rocketchip.config.{Field, Parameters} -import freechips.rocketchip.coreplex.HasPeripheryBus +import freechips.rocketchip.subsystem.BaseSubsystem import freechips.rocketchip.diplomacy._ import freechips.rocketchip.regmapper._ import freechips.rocketchip.tilelink._ @@ -12,7 +12,7 @@ import freechips.rocketchip.interrupts._ import freechips.rocketchip.util._ import scala.math.{min,max} -object ClintConsts +object CLINTConsts { def msipOffset(hart: Int) = hart * msipBytes def timecmpOffset(hart: Int) = 0x4000 + hart * timecmpBytes @@ -25,16 +25,16 @@ object ClintConsts def ints = 2 } -case class ClintParams(baseAddress: BigInt = 0x02000000, intStages: Int = 0) +case class CLINTParams(baseAddress: BigInt = 0x02000000, intStages: Int = 0) { - def address = AddressSet(baseAddress, ClintConsts.size-1) + def address = AddressSet(baseAddress, CLINTConsts.size-1) } -case object ClintKey extends Field(ClintParams()) +case object CLINTKey extends Field(CLINTParams()) -class CoreplexLocalInterrupter(params: ClintParams, beatBytes: Int)(implicit p: Parameters) extends LazyModule +class CLINT(params: CLINTParams, beatBytes: Int)(implicit p: Parameters) extends LazyModule { - import ClintConsts._ + import CLINTConsts._ // clint0 => at most 4095 devices val device = new SimpleDevice("clint", Seq("riscv,clint0")) { @@ -90,8 +90,8 @@ class CoreplexLocalInterrupter(params: ClintParams, beatBytes: Int)(implicit p: } } -/** Trait that will connect a Clint to a coreplex */ -trait HasPeripheryClint extends HasPeripheryBus { - val clint = LazyModule(new CoreplexLocalInterrupter(p(ClintKey), pbus.beatBytes)) - clint.node := pbus.toVariableWidthSlaves +/** Trait that will connect a CLINT to a subsystem */ +trait HasPeripheryCLINT { this: BaseSubsystem => + val clint = LazyModule(new CLINT(p(CLINTKey), pbus.beatBytes)) + 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 ebe66ab2..3d47e7a5 100644 --- a/src/main/scala/devices/tilelink/Error.scala +++ b/src/main/scala/devices/tilelink/Error.scala @@ -4,7 +4,7 @@ package freechips.rocketchip.devices.tilelink import Chisel._ import freechips.rocketchip.config.{Field, Parameters} -import freechips.rocketchip.coreplex.HasSystemBus +import freechips.rocketchip.subsystem.BaseSubsystem import freechips.rocketchip.diplomacy._ import freechips.rocketchip.tilelink._ import freechips.rocketchip.util._ @@ -118,9 +118,8 @@ class DeadlockDevice(params: ErrorParams, beatBytes: Int = 4)(implicit p: Parame } } -trait HasSystemErrorSlave extends HasSystemBus { +trait HasSystemErrorSlave { this: BaseSubsystem => 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 d40526ae..e82576ad 100644 --- a/src/main/scala/devices/tilelink/MaskROM.scala +++ b/src/main/scala/devices/tilelink/MaskROM.scala @@ -3,9 +3,9 @@ package freechips.rocketchip.devices.tilelink import Chisel._ -import freechips.rocketchip.coreplex.{HasPeripheryBus} import freechips.rocketchip.config.{Field, Parameters} import freechips.rocketchip.diplomacy._ +import freechips.rocketchip.subsystem.BaseSubsystem import freechips.rocketchip.tilelink._ import freechips.rocketchip.util._ @@ -13,11 +13,11 @@ case class MaskROMParams(address: BigInt, name: String, depth: Int = 2048, width case object PeripheryMaskROMKey extends Field[Seq[MaskROMParams]] -trait HasPeripheryMaskROMSlave extends HasPeripheryBus { +trait HasPeripheryMaskROMSlave { this: BaseSubsystem => 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 c0a0b75b..1a2b2b15 100644 --- a/src/main/scala/devices/tilelink/Plic.scala +++ b/src/main/scala/devices/tilelink/Plic.scala @@ -5,7 +5,7 @@ package freechips.rocketchip.devices.tilelink import Chisel._ import Chisel.ImplicitConversions._ import freechips.rocketchip.config.{Field, Parameters} -import freechips.rocketchip.coreplex.{HasInterruptBus, HasPeripheryBus} +import freechips.rocketchip.subsystem.BaseSubsystem import freechips.rocketchip.diplomacy._ import freechips.rocketchip.regmapper._ import freechips.rocketchip.tilelink._ @@ -268,9 +268,9 @@ class TLPLIC(params: PLICParams, beatBytes: Int)(implicit p: Parameters) extends } } -/** Trait that will connect a PLIC to a coreplex */ -trait HasPeripheryPLIC extends HasInterruptBus with HasPeripheryBus { +/** Trait that will connect a PLIC to a subsystem */ +trait HasPeripheryPLIC { this: BaseSubsystem => val plic = LazyModule(new TLPLIC(p(PLICKey), pbus.beatBytes)) - plic.node := pbus.toVariableWidthSlaves + 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 229fc55d..0dd6eef4 100644 --- a/src/main/scala/devices/tilelink/Zero.scala +++ b/src/main/scala/devices/tilelink/Zero.scala @@ -4,7 +4,7 @@ package freechips.rocketchip.devices.tilelink import Chisel._ import freechips.rocketchip.config.{Field, Parameters} -import freechips.rocketchip.coreplex.HasMemoryBus +import freechips.rocketchip.subsystem.BaseSubsystem import freechips.rocketchip.diplomacy._ import freechips.rocketchip.tilelink._ @@ -46,17 +46,17 @@ case class ZeroParams(base: Long, size: Long, beatBytes: Int) case object ZeroParams extends Field[ZeroParams] /** Adds a /dev/null slave that generates zero-filled responses to reads */ -trait HasMemoryZeroSlave extends HasMemoryBus { +trait HasMemoryZeroSlave { this: BaseSubsystem => 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.zipWithIndex.map { case (bus, channel) => val channels = memBuses.size val base = AddressSet(params.base, params.size-1) - val filter = AddressSet(channel * cacheBlockBytes, ~((channels-1) * cacheBlockBytes)) + val filter = AddressSet(channel * bus.blockBytes, ~((channels-1) * bus.blockBytes)) val address = base.intersect(filter).get val zero = LazyModule(new TLZero(address, beatBytes = params.beatBytes, resources = device.reg("mem"))) - zero.node := node + bus.toVariableWidthSlave(Some("Zero")) { zero.node } zero } } diff --git a/src/main/scala/diplomacy/LazyModule.scala b/src/main/scala/diplomacy/LazyModule.scala index e7468ecf..78f7e65a 100644 --- a/src/main/scala/diplomacy/LazyModule.scala +++ b/src/main/scala/diplomacy/LazyModule.scala @@ -25,50 +25,30 @@ abstract class LazyModule()(implicit val p: Parameters) parent.foreach(p => p.children = this :: p.children) // suggestedName accumulates Some(names), taking the final one. Nones are ignored. - private var suggestedName: Option[String] = None + private var suggestedNameVar: Option[String] = None def suggestName(x: String): this.type = suggestName(Some(x)) def suggestName(x: Option[String]): this.type = { - x.foreach { n => suggestedName = Some(n) } + x.foreach { n => suggestedNameVar = Some(n) } this } - private lazy val childNames = - getClass.getMethods.filter { m => - m.getParameterTypes.isEmpty && - !java.lang.reflect.Modifier.isStatic(m.getModifiers) && - m.getName != "children" && - m.getName != "getChildren" - }.flatMap { m => - if (classOf[LazyModule].isAssignableFrom(m.getReturnType)) { - val obj = m.invoke(this) - if (obj eq null) Seq() else Seq((m.getName, obj)) - } else if (classOf[Seq[LazyModule]].isAssignableFrom(m.getReturnType)) { - val obj = m.invoke(this) - if (obj eq null) Seq() else { - val seq = try { obj.asInstanceOf[Seq[Object]] } catch { case _: Throwable => null } - if (seq eq null) Seq() else { - seq.zipWithIndex.map { case (l, i) => (m.getName + "_" + i, l) } - } - } - } else Seq() - } - private def findValName = - parent.flatMap(_.childNames.find(_._2 eq this)).map(_._1) - private def findClassName(c: Class[_]): String = { val n = c.getName.split('.').last if (n.contains('$')) findClassName(c.getSuperclass) else n } lazy val className = findClassName(getClass) - lazy val valName = suggestedName.orElse(findValName) - lazy val outerName = if (nodes.size != 1) None else nodes(0).gco.flatMap(_.lazyModule.valName) + lazy val suggestedName = suggestedNameVar.getOrElse(className) + lazy val desiredName = className // + hashcode? - def moduleName = className + valName.orElse(outerName).map("_" + _).getOrElse("") - def instanceName = valName.getOrElse(outerName.map(_ + "_").getOrElse("") + className) - def name = valName.getOrElse(className) + def name = suggestedName // className + suggestedName ++ hashcode ? def line = sourceLine(info) + // Accessing these names can only be done after circuit elaboration! + lazy val moduleName = module.name // The final Verilog Module name + lazy val pathName = module.pathName + lazy val instanceName = pathName.split('.').last // The final Verilog instance name + def instantiate() { } // a hook for running things in module scope (after children exist, but before dangles+auto exists) def module: LazyModuleImpLike @@ -79,7 +59,7 @@ abstract class LazyModule()(implicit val p: Parameters) buf ++= "\n" buf ++= " \n" buf ++= " \n" - buf ++= " \n" + buf ++= " \n" buf ++= " \n" nodesGraphML(buf, " ") edgesGraphML(buf, " ") @@ -92,11 +72,13 @@ abstract class LazyModule()(implicit val p: Parameters) private def nodesGraphML(buf: StringBuilder, pad: String) { buf ++= s"""${pad}\n""" - buf ++= s"""${pad} ${module.instanceName}\n""" + buf ++= s"""${pad} ${instanceName}\n""" + buf ++= s"""${pad} ${moduleName} (${pathName})\n""" buf ++= s"""${pad} \n""" nodes.filter(!_.omitGraphML).foreach { n => buf ++= s"""${pad} \n""" - buf ++= s"""${pad} ${n.nodedebugstring}\n""" + buf ++= s"""${pad} \n""" + buf ++= s"""${pad} ${n.nodedebugstring}\n""" buf ++= s"""${pad} \n""" } children.filter(!_.omitGraphML).foreach { _.nodesGraphML(buf, pad + " ") } @@ -149,6 +131,7 @@ object LazyModule require (scope.get eq bc, s"LazyModule() applied to ${bc.name} before ${scope.get.name} ${sourceLine(sourceInfo)}") scope = bc.parent bc.info = sourceInfo + if (!bc.suggestedNameVar.isDefined) bc.suggestName(valName.name) bc } } @@ -162,8 +145,8 @@ sealed trait LazyModuleImpLike extends BaseModule // .module had better not be accessed while LazyModules are still being built! require (!LazyModule.scope.isDefined, s"${wrapper.name}.module was constructed before LazyModule() was run on ${LazyModule.scope.get.name}") - override def desiredName = wrapper.moduleName - suggestName(wrapper.instanceName) + override def desiredName = wrapper.desiredName + suggestName(wrapper.suggestedName) implicit val p = wrapper.p @@ -186,7 +169,7 @@ sealed trait LazyModuleImpLike extends BaseModule val auto = IO(new AutoBundle(forward.map { d => (d.name, d.data, d.flipped) }:_*)) val dangles = (forward zip auto.elements) map { case (d, (_, io)) => if (d.flipped) { d.data <> io } else { io <> d.data } - d.copy(data = io, name = wrapper.valName.getOrElse("anon") + "_" + d.name) + d.copy(data = io, name = wrapper.suggestedName + "_" + d.name) } wrapper.instantiate() (auto, dangles) diff --git a/src/main/scala/diplomacy/Nodes.scala b/src/main/scala/diplomacy/Nodes.scala index e41ed238..fae689f0 100644 --- a/src/main/scala/diplomacy/Nodes.scala +++ b/src/main/scala/diplomacy/Nodes.scala @@ -32,7 +32,6 @@ trait InwardNodeImp[DI, UI, EI, BI <: Data] // optional methods to track node graph def mixI(pu: UI, node: InwardNode[DI, UI, BI]): UI = pu // insert node into parameters - def getO(pu: UI): Option[BaseNode] = None // most-outward common node } // DO = Downwards flowing Parameters generated by the outer side of the node @@ -91,8 +90,6 @@ abstract class BaseNode(implicit val valName: ValName) if (name.isEmpty) "" else name + "_" } - protected[diplomacy] def gci: Option[BaseNode] // greatest common inner - protected[diplomacy] def gco: Option[BaseNode] // greatest common outer def inputs: Seq[(BaseNode, RenderedEdge)] def outputs: Seq[(BaseNode, RenderedEdge)] @@ -322,9 +319,6 @@ sealed abstract class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data]( } } - protected[diplomacy] def gco = if (uiParams.size != 1) None else inner.getO(uiParams(0)) - protected[diplomacy] def gci = if (doParams.size != 1) None else outer.getI(doParams(0)) - protected[diplomacy] lazy val edgesOut = (oPorts zip doParams).map { case ((i, n, p, s), o) => outer.edgeO(o, n.uiParams(i), p, s) } protected[diplomacy] lazy val edgesIn = (iPorts zip uiParams).map { case ((o, n, p, s), i) => inner.edgeI(n.doParams(o), i, p, s) } diff --git a/src/main/scala/diplomacy/Resources.scala b/src/main/scala/diplomacy/Resources.scala index b6729874..58ba6415 100644 --- a/src/main/scala/diplomacy/Resources.scala +++ b/src/main/scala/diplomacy/Resources.scala @@ -211,7 +211,7 @@ case class Resource(owner: Device, key: String) } } -/** The resource binding scope for a LazyModule that generates a device tree (currently Coreplex only). */ +/** The resource binding scope for a LazyModule that generates a device tree (currently Subsystem only). */ trait BindingScope { this: LazyModule => diff --git a/src/main/scala/groundtest/Configs.scala b/src/main/scala/groundtest/Configs.scala index 067202a8..c9aca2a8 100644 --- a/src/main/scala/groundtest/Configs.scala +++ b/src/main/scala/groundtest/Configs.scala @@ -5,13 +5,13 @@ package freechips.rocketchip.groundtest import Chisel._ import freechips.rocketchip.config.Config -import freechips.rocketchip.coreplex._ +import freechips.rocketchip.subsystem._ import freechips.rocketchip.rocket.{DCacheParams} import freechips.rocketchip.tile.{MaxHartIdBits, XLen} /** Actual testing target Configs */ -class TraceGenConfig extends Config(new WithTraceGen(List.fill(2){ DCacheParams(nSets = 16, nWays = 1) }) ++ new BaseCoreplexConfig) +class TraceGenConfig extends Config(new WithTraceGen(List.fill(2){ DCacheParams(nSets = 16, nWays = 1) }) ++ new BaseSubsystemConfig) class TraceGenBufferlessConfig extends Config(new WithBufferlessBroadcastHub ++ new TraceGenConfig) diff --git a/src/main/scala/groundtest/Coreplex.scala b/src/main/scala/groundtest/GroundTestSubsystem.scala similarity index 62% rename from src/main/scala/groundtest/Coreplex.scala rename to src/main/scala/groundtest/GroundTestSubsystem.scala index ba044c46..0e09286d 100644 --- a/src/main/scala/groundtest/Coreplex.scala +++ b/src/main/scala/groundtest/GroundTestSubsystem.scala @@ -7,7 +7,7 @@ import Chisel._ import freechips.rocketchip.config.{Field, Parameters} import freechips.rocketchip.diplomacy._ import freechips.rocketchip.interrupts._ -import freechips.rocketchip.coreplex._ +import freechips.rocketchip.subsystem._ import freechips.rocketchip.tilelink._ import freechips.rocketchip.tile._ @@ -15,10 +15,9 @@ import scala.math.max case object TileId extends Field[Int] -class GroundTestCoreplex(implicit p: Parameters) extends BaseCoreplex +class GroundTestSubsystem(implicit p: Parameters) extends BaseSubsystem with HasMasterAXI4MemPort - with HasPeripheryTestRAMSlave - with HasInterruptBus { + with HasPeripheryTestRAMSlave { val tileParams = p(GroundTestTilesKey) val tiles = tileParams.zipWithIndex.map { case(c, i) => LazyModule( c.build(i, p.alterPartial { @@ -28,19 +27,16 @@ class GroundTestCoreplex(implicit p: Parameters) extends BaseCoreplex )} 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 GroundTestCoreplexModule(this) + override lazy val module = new GroundTestSubsystemModuleImp(this) } -class GroundTestCoreplexModule[+L <: GroundTestCoreplex](_outer: L) extends BaseCoreplexModule(_outer) +class GroundTestSubsystemModuleImp[+L <: GroundTestSubsystem](_outer: L) extends BaseSubsystemModuleImp(_outer) with HasMasterAXI4MemPortModuleImp { val success = IO(Bool(OUTPUT)) @@ -51,13 +47,13 @@ class GroundTestCoreplexModule[+L <: GroundTestCoreplex](_outer: L) extends Base } /** Adds a SRAM to the system for testing purposes. */ -trait HasPeripheryTestRAMSlave extends HasPeripheryBus { +trait HasPeripheryTestRAMSlave { this: BaseSubsystem => 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 { +trait HasPeripheryTestFuzzMaster { this: BaseSubsystem => val fuzzer = LazyModule(new TLFuzzer(5000)) - pbus.bufferFromMasters := fuzzer.node + pbus.fromOtherMaster(Some("Fuzzer")) { fuzzer.node } } diff --git a/src/main/scala/groundtest/TestHarness.scala b/src/main/scala/groundtest/TestHarness.scala index 6f2f447e..877ad08d 100644 --- a/src/main/scala/groundtest/TestHarness.scala +++ b/src/main/scala/groundtest/TestHarness.scala @@ -9,7 +9,7 @@ import freechips.rocketchip.diplomacy.LazyModule class TestHarness(implicit p: Parameters) extends Module { val io = new Bundle { val success = Bool(OUTPUT) } - val dut = Module(LazyModule(new GroundTestCoreplex).module) + val dut = Module(LazyModule(new GroundTestSubsystem).module) io.success := dut.success dut.connectSimAXIMem() } diff --git a/src/main/scala/groundtest/Tile.scala b/src/main/scala/groundtest/Tile.scala index e38ebb05..2eb6593b 100644 --- a/src/main/scala/groundtest/Tile.scala +++ b/src/main/scala/groundtest/Tile.scala @@ -6,7 +6,7 @@ package freechips.rocketchip.groundtest import Chisel._ import freechips.rocketchip.config._ import freechips.rocketchip.diplomacy._ -import freechips.rocketchip.coreplex._ +import freechips.rocketchip.subsystem._ import freechips.rocketchip.interrupts._ import freechips.rocketchip.rocket.{DCache, RocketCoreParams} import freechips.rocketchip.tile._ diff --git a/src/main/scala/rocket/BTB.scala b/src/main/scala/rocket/BTB.scala index 90413d0b..0693b1a6 100644 --- a/src/main/scala/rocket/BTB.scala +++ b/src/main/scala/rocket/BTB.scala @@ -6,7 +6,7 @@ package freechips.rocketchip.rocket import Chisel._ import Chisel.ImplicitConversions._ import freechips.rocketchip.config.Parameters -import freechips.rocketchip.coreplex.CacheBlockBytes +import freechips.rocketchip.subsystem.CacheBlockBytes import freechips.rocketchip.tile.HasCoreParameters import freechips.rocketchip.util._ diff --git a/src/main/scala/rocket/DCache.scala b/src/main/scala/rocket/DCache.scala index 83d1df9c..2c5f2408 100644 --- a/src/main/scala/rocket/DCache.scala +++ b/src/main/scala/rocket/DCache.scala @@ -5,7 +5,7 @@ package freechips.rocketchip.rocket import Chisel._ import Chisel.ImplicitConversions._ import freechips.rocketchip.config.Parameters -import freechips.rocketchip.coreplex.{RocketTilesKey} +import freechips.rocketchip.subsystem.{RocketTilesKey} import freechips.rocketchip.diplomacy.{AddressSet, RegionType} import freechips.rocketchip.tilelink._ import freechips.rocketchip.util._ diff --git a/src/main/scala/rocket/Frontend.scala b/src/main/scala/rocket/Frontend.scala index bf053231..4eae78ca 100644 --- a/src/main/scala/rocket/Frontend.scala +++ b/src/main/scala/rocket/Frontend.scala @@ -7,7 +7,7 @@ import Chisel._ import Chisel.ImplicitConversions._ import chisel3.core.withReset import freechips.rocketchip.config._ -import freechips.rocketchip.coreplex._ +import freechips.rocketchip.subsystem._ import freechips.rocketchip.diplomacy._ import freechips.rocketchip.tilelink._ import freechips.rocketchip.tile._ diff --git a/src/main/scala/rocket/HellaCache.scala b/src/main/scala/rocket/HellaCache.scala index 030c2ce5..17b53b73 100644 --- a/src/main/scala/rocket/HellaCache.scala +++ b/src/main/scala/rocket/HellaCache.scala @@ -6,7 +6,7 @@ package freechips.rocketchip.rocket import Chisel._ import chisel3.experimental.dontTouch import freechips.rocketchip.config.{Parameters, Field} -import freechips.rocketchip.coreplex._ +import freechips.rocketchip.subsystem._ import freechips.rocketchip.diplomacy._ import freechips.rocketchip.tile._ import freechips.rocketchip.tilelink._ diff --git a/src/main/scala/rocket/ICache.scala b/src/main/scala/rocket/ICache.scala index abb68428..ac2219e1 100644 --- a/src/main/scala/rocket/ICache.scala +++ b/src/main/scala/rocket/ICache.scala @@ -6,7 +6,7 @@ package freechips.rocketchip.rocket import Chisel._ import Chisel.ImplicitConversions._ import freechips.rocketchip.config.Parameters -import freechips.rocketchip.coreplex.RocketTilesKey +import freechips.rocketchip.subsystem.RocketTilesKey import freechips.rocketchip.diplomacy._ import freechips.rocketchip.tile._ import freechips.rocketchip.tilelink._ diff --git a/src/main/scala/rocket/PTW.scala b/src/main/scala/rocket/PTW.scala index 9d63a90b..1e7b8117 100644 --- a/src/main/scala/rocket/PTW.scala +++ b/src/main/scala/rocket/PTW.scala @@ -6,7 +6,7 @@ package freechips.rocketchip.rocket import Chisel._ import Chisel.ImplicitConversions._ import freechips.rocketchip.config.Parameters -import freechips.rocketchip.coreplex.CacheBlockBytes +import freechips.rocketchip.subsystem.CacheBlockBytes import freechips.rocketchip.tile._ import freechips.rocketchip.tilelink._ import freechips.rocketchip.util._ diff --git a/src/main/scala/rocket/TLB.scala b/src/main/scala/rocket/TLB.scala index 9ecae1e0..5eca04ec 100644 --- a/src/main/scala/rocket/TLB.scala +++ b/src/main/scala/rocket/TLB.scala @@ -7,7 +7,7 @@ import Chisel._ import Chisel.ImplicitConversions._ import freechips.rocketchip.config.{Field, Parameters} -import freechips.rocketchip.coreplex.CacheBlockBytes +import freechips.rocketchip.subsystem.CacheBlockBytes import freechips.rocketchip.diplomacy.RegionType import freechips.rocketchip.tile.{XLen, CoreModule, CoreBundle} import freechips.rocketchip.tilelink._ diff --git a/src/main/scala/coreplex/BaseCoreplex.scala b/src/main/scala/subsystem/BaseSubsystem.scala similarity index 57% rename from src/main/scala/coreplex/BaseCoreplex.scala rename to src/main/scala/subsystem/BaseSubsystem.scala index 94c90a5c..8ff54586 100644 --- a/src/main/scala/coreplex/BaseCoreplex.scala +++ b/src/main/scala/subsystem/BaseSubsystem.scala @@ -1,6 +1,6 @@ // See LICENSE.SiFive for license details. -package freechips.rocketchip.coreplex +package freechips.rocketchip.subsystem import Chisel._ import freechips.rocketchip.config.Parameters @@ -9,14 +9,14 @@ import freechips.rocketchip.tilelink._ import freechips.rocketchip.devices.tilelink._ import freechips.rocketchip.util._ -/** BareCoreplex is the root class for creating a coreplex sub-system */ -abstract class BareCoreplex(implicit p: Parameters) extends LazyModule with BindingScope { +/** BareSubsystem is the root class for creating a subsystem */ +abstract class BareSubsystem(implicit p: Parameters) extends LazyModule with BindingScope { lazy val dts = DTS(bindingTree) lazy val dtb = DTB(dts) lazy val json = JSON(bindingTree) } -abstract class BareCoreplexModule[+L <: BareCoreplex](_outer: L) extends LazyModuleImp(_outer) { +abstract class BareSubsystemModuleImp[+L <: BareSubsystem](_outer: L) extends LazyModuleImp(_outer) { val outer = _outer ElaborationArtefacts.add("graphml", outer.graphML) ElaborationArtefacts.add("dts", outer.dts) @@ -25,16 +25,54 @@ abstract class BareCoreplexModule[+L <: BareCoreplex](_outer: L) extends LazyMod println(outer.dts) } -/** Base Coreplex class with no peripheral devices or ports added */ -abstract class BaseCoreplex(implicit p: Parameters) extends BareCoreplex - with HasInterruptBus - with HasSystemBus - with HasPeripheryBus - with HasMemoryBus { - override val module: BaseCoreplexModule[BaseCoreplex] +/** Base Subsystem class with no peripheral devices or ports added */ +abstract class BaseSubsystem(implicit p: Parameters) extends BareSubsystem { + override val module: BaseSubsystemModuleImp[BaseSubsystem] + + // These are wrappers around the standard buses available in all subsytems, where + // peripherals, tiles, ports, and other masters and slaves can attach themselves. + val ibus = new InterruptBusWrapper() + val sbus = LazyModule(new SystemBus(p(SystemBusKey))) + val pbus = LazyModule(new PeripheryBus(p(PeripheryBusKey))) + val fbus = LazyModule(new FrontBus(p(FrontBusKey))) + + // The sbus masters the pbus; here we convert TL-UH -> TL-UL + pbus.fromSystemBus { sbus.toPeripheryBus { pbus.crossTLIn } } + + // The fbus masters the sbus; both are TL-UH or TL-C + FlipRendering { implicit p => + fbus.toSystemBus { sbus.fromFrontBus { fbus.crossTLOut } } + } + + // The sbus masters the mbus; here we convert TL-C -> TL-UH + private val mbusParams = p(MemoryBusKey) + private val l2Params = p(BankedL2Key) + val MemoryBusParams(memBusBeatBytes, memBusBlockBytes) = mbusParams + val BankedL2Params(nMemoryChannels, nBanksPerChannel, coherenceManager) = l2Params + val nBanks = l2Params.nBanks + val cacheBlockBytes = memBusBlockBytes + // TODO: the below call to coherenceManager should be wrapped in a LazyScope here, + // but plumbing halt is too annoying for now. + private val (in, out, halt) = coherenceManager(this) + def memBusCanCauseHalt: () => Option[Bool] = halt + + require (isPow2(nMemoryChannels) || nMemoryChannels == 0) + require (isPow2(nBanksPerChannel)) + require (isPow2(memBusBlockBytes)) + + private val mask = ~BigInt((nBanks-1) * memBusBlockBytes) + val memBuses = Seq.tabulate(nMemoryChannels) { channel => + val mbus = LazyModule(new MemoryBus(mbusParams)(p)) + for (bank <- 0 until nBanksPerChannel) { + val offset = (bank * nMemoryChannels) + channel + ForceFanout(a = true) { implicit p => sbus.toMemoryBus { in } } + mbus.fromCoherenceManager(None) { TLFilter(TLFilter.Mmask(AddressSet(offset * memBusBlockBytes, mask))) } := out + } + mbus + } // Make topManagers an Option[] so as to avoid LM name reflection evaluating it... - lazy val topManagers = Some(ManagerUnification(sharedMemoryTLEdge.manager.managers)) + lazy val topManagers = Some(ManagerUnification(sbus.busView.manager.managers)) ResourceBinding { val managers = topManagers.get val max = managers.flatMap(_.address).map(_.max).max @@ -59,9 +97,9 @@ abstract class BaseCoreplex(implicit p: Parameters) extends BareCoreplex } } -abstract class BaseCoreplexModule[+L <: BaseCoreplex](_outer: L) extends BareCoreplexModule(_outer) { +abstract class BaseSubsystemModuleImp[+L <: BaseSubsystem](_outer: L) extends BareSubsystemModuleImp(_outer) { println("Generated Address Map") - private val aw = (outer.sharedMemoryTLEdge.bundle.addressBits-1)/4 + 1 + private val aw = (outer.sbus.busView.bundle.addressBits-1)/4 + 1 private val fmt = s"\t%${aw}x - %${aw}x %c%c%c%c%c %s" private def collect(path: List[String], value: ResourceValue): List[(String, ResourceAddress)] = { diff --git a/src/main/scala/coreplex/Configs.scala b/src/main/scala/subsystem/Configs.scala similarity index 96% rename from src/main/scala/coreplex/Configs.scala rename to src/main/scala/subsystem/Configs.scala index b5840a41..98f3a3f8 100644 --- a/src/main/scala/coreplex/Configs.scala +++ b/src/main/scala/subsystem/Configs.scala @@ -1,7 +1,7 @@ // See LICENSE.SiFive for license details. // See LICENSE.Berkeley for license details. -package freechips.rocketchip.coreplex +package freechips.rocketchip.subsystem import Chisel._ import freechips.rocketchip.config._ @@ -13,7 +13,7 @@ import freechips.rocketchip.tile._ import freechips.rocketchip.tilelink._ import freechips.rocketchip.util._ -class BaseCoreplexConfig extends Config ((site, here, up) => { +class BaseSubsystemConfig extends Config ((site, here, up) => { // Tile parameters case PgLevels => if (site(XLen) == 64) 3 /* Sv39 */ else 2 /* Sv32 */ case XLen => 64 // Applies to all cores @@ -23,6 +23,7 @@ class BaseCoreplexConfig extends Config ((site, here, up) => { case SystemBusKey => SystemBusParams(beatBytes = site(XLen)/8, blockBytes = site(CacheBlockBytes)) case PeripheryBusKey => PeripheryBusParams(beatBytes = site(XLen)/8, blockBytes = site(CacheBlockBytes)) case MemoryBusKey => MemoryBusParams(beatBytes = site(XLen)/8, blockBytes = site(CacheBlockBytes)) + case FrontBusKey => FrontBusParams(beatBytes = site(XLen)/8, blockBytes = site(CacheBlockBytes)) // Additional device Parameters case ErrorParams => ErrorParams(Seq(AddressSet(0x3000, 0xfff)), maxAtomic=site(XLen)/8, maxTransfer=4096) case BootROMParams => BootROMParams(contentFileName = "./bootrom/bootrom.img") @@ -155,8 +156,8 @@ class WithIncoherentTiles extends Config((site, here, up) => { case RocketCrossingKey => up(RocketCrossingKey, site) map { r => r.copy(master = r.master.copy(cork = Some(true))) } - case BankedL2Key => up(BankedL2Key, site).copy(coherenceManager = { coreplex => - val ww = LazyModule(new TLWidthWidget(coreplex.sbusBeatBytes)(coreplex.p)) + case BankedL2Key => up(BankedL2Key, site).copy(coherenceManager = { subsystem => + val ww = LazyModule(new TLWidthWidget(subsystem.sbus.beatBytes)(subsystem.p)) (ww.node, ww.node, () => None) }) }) @@ -270,10 +271,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/coreplex/CrossingWrapper.scala b/src/main/scala/subsystem/CrossingWrapper.scala similarity index 69% rename from src/main/scala/coreplex/CrossingWrapper.scala rename to src/main/scala/subsystem/CrossingWrapper.scala index f76b058c..0875c678 100644 --- a/src/main/scala/coreplex/CrossingWrapper.scala +++ b/src/main/scala/subsystem/CrossingWrapper.scala @@ -1,6 +1,6 @@ // See LICENSE.SiFive for license details. -package freechips.rocketchip.coreplex +package freechips.rocketchip.subsystem import Chisel._ import freechips.rocketchip.config._ @@ -11,16 +11,16 @@ import freechips.rocketchip.interrupts._ import freechips.rocketchip.util._ /** Enumerates the three types of clock crossing between tiles and system bus */ -sealed trait CoreplexClockCrossing +sealed trait SubsystemClockCrossing { def sameClock = this match { case _: SynchronousCrossing => true case _ => false } } -case class SynchronousCrossing(params: BufferParams = BufferParams.default) extends CoreplexClockCrossing -case class RationalCrossing(direction: RationalDirection = FastToSlow) extends CoreplexClockCrossing -case class AsynchronousCrossing(depth: Int, sync: Int = 3) extends CoreplexClockCrossing +case class SynchronousCrossing(params: BufferParams = BufferParams.default) extends SubsystemClockCrossing +case class RationalCrossing(direction: RationalDirection = FastToSlow) extends SubsystemClockCrossing +case class AsynchronousCrossing(depth: Int, sync: Int = 3) extends SubsystemClockCrossing private case class CrossingCheck(out: Boolean, source: BaseNode, sink: BaseNode) @@ -45,26 +45,26 @@ trait HasCrossingMethods extends LazyModule with LazyScope // TileLink def crossTLSyncInOut(out: Boolean)(params: BufferParams = BufferParams.default)(implicit p: Parameters): TLNode = { - val node = this { LazyModule(new TLBuffer(params)).node } - checks = CrossingCheck(out, node, node) :: checks - node + val sync_xing = this { LazyModule(new TLBuffer(params)).node } + checks = CrossingCheck(out, sync_xing, sync_xing) :: checks + sync_xing } def crossTLAsyncInOut(out: Boolean)(depth: Int = 8, sync: Int = 3)(implicit p: Parameters): TLNode = { - lazy val asource = LazyModule(new TLAsyncCrossingSource(sync)) - lazy val asink = LazyModule(new TLAsyncCrossingSink(depth, sync)) - val source = if (out) this { asource } else asource - val sink = if (out) asink else this { asink } + lazy val async_xing_source = LazyModule(new TLAsyncCrossingSource(sync)) + lazy val async_xing_sink = LazyModule(new TLAsyncCrossingSink(depth, sync)) + val source = if (out) this { async_xing_source } else async_xing_source + val sink = if (out) async_xing_sink else this { async_xing_sink } sink.node :*=* source.node checks = CrossingCheck(out, source.node, sink.node) :: checks NodeHandle(source.node, sink.node) } def crossTLRationalInOut(out: Boolean)(direction: RationalDirection)(implicit p: Parameters): TLNode = { - lazy val rsource = LazyModule(new TLRationalCrossingSource) - lazy val rsink = LazyModule(new TLRationalCrossingSink(if (out) direction else direction.flip)) - val source = if (out) this { rsource } else rsource - val sink = if (out) rsink else this { rsink } + lazy val rational_xing_source = LazyModule(new TLRationalCrossingSource) + lazy val rational_xing_sink = LazyModule(new TLRationalCrossingSink(if (out) direction else direction.flip)) + val source = if (out) this { rational_xing_source } else rational_xing_source + val sink = if (out) rational_xing_sink else this { rational_xing_sink } sink.node :*=* source.node checks = CrossingCheck(out, source.node, sink.node) :: checks NodeHandle(source.node, sink.node) @@ -77,13 +77,13 @@ trait HasCrossingMethods extends LazyModule with LazyScope def crossTLRationalIn (direction: RationalDirection)(implicit p: Parameters): TLNode = crossTLRationalInOut(false)(direction) def crossTLRationalOut(direction: RationalDirection)(implicit p: Parameters): TLNode = crossTLRationalInOut(true )(direction) - def crossTLIn(arg: CoreplexClockCrossing)(implicit p: Parameters): TLNode = arg match { + def crossTLIn(arg: SubsystemClockCrossing)(implicit p: Parameters): TLNode = arg match { case x: SynchronousCrossing => crossTLSyncIn(x.params) case x: AsynchronousCrossing => crossTLAsyncIn(x.depth, x.sync) case x: RationalCrossing => crossTLRationalIn(x.direction) } - def crossTLOut(arg: CoreplexClockCrossing)(implicit p: Parameters): TLNode = arg match { + def crossTLOut(arg: SubsystemClockCrossing)(implicit p: Parameters): TLNode = arg match { case x: SynchronousCrossing => crossTLSyncOut(x.params) case x: AsynchronousCrossing => crossTLAsyncOut(x.depth, x.sync) case x: RationalCrossing => crossTLRationalOut(x.direction) @@ -92,16 +92,16 @@ trait HasCrossingMethods extends LazyModule with LazyScope // AXI4 def crossAXI4SyncInOut(out: Boolean)(params: BufferParams = BufferParams.default)(implicit p: Parameters): AXI4Node = { - val node = this { LazyModule(new AXI4Buffer(params)).node } - checks = CrossingCheck(out, node, node) :: checks - node + val axi4_sync_xing = this { LazyModule(new AXI4Buffer(params)).node } + checks = CrossingCheck(out, axi4_sync_xing, axi4_sync_xing) :: checks + axi4_sync_xing } def crossAXI4AsyncInOut(out: Boolean)(depth: Int = 8, sync: Int = 3)(implicit p: Parameters): AXI4Node = { - lazy val axi4asource = LazyModule(new AXI4AsyncCrossingSource(sync)) - lazy val axi4asink = LazyModule(new AXI4AsyncCrossingSink(depth, sync)) - val source = if (out) this { axi4asource } else axi4asource - val sink = if (out) axi4asink else this { axi4asink } + lazy val axi4_async_xing_source = LazyModule(new AXI4AsyncCrossingSource(sync)) + lazy val axi4_async_xing_sink = LazyModule(new AXI4AsyncCrossingSink(depth, sync)) + val source = if (out) this { axi4_async_xing_source } else axi4_async_xing_source + val sink = if (out) axi4_async_xing_sink else this { axi4_async_xing_sink } sink.node :*=* source.node checks = CrossingCheck(out, source.node, sink.node) :: checks NodeHandle(source.node, sink.node) @@ -112,13 +112,13 @@ trait HasCrossingMethods extends LazyModule with LazyScope def crossAXI4AsyncIn (depth: Int = 8, sync: Int = 3)(implicit p: Parameters): AXI4Node = crossAXI4AsyncInOut(false)(depth, sync) def crossAXI4AsyncOut(depth: Int = 8, sync: Int = 3)(implicit p: Parameters): AXI4Node = crossAXI4AsyncInOut(true )(depth, sync) - def crossAXI4In(arg: CoreplexClockCrossing)(implicit p: Parameters): AXI4Node = arg match { + def crossAXI4In(arg: SubsystemClockCrossing)(implicit p: Parameters): AXI4Node = arg match { case x: SynchronousCrossing => crossAXI4SyncIn(x.params) case x: AsynchronousCrossing => crossAXI4AsyncIn(x.depth, x.sync) case x: RationalCrossing => throw new IllegalArgumentException("AXI4 Rational crossing unimplemented") } - def crossAXI4Out(arg: CoreplexClockCrossing)(implicit p: Parameters): AXI4Node = arg match { + def crossAXI4Out(arg: SubsystemClockCrossing)(implicit p: Parameters): AXI4Node = arg match { case x: SynchronousCrossing => crossAXI4SyncOut(x.params) case x: AsynchronousCrossing => crossAXI4AsyncOut(x.depth, x.sync) case x: RationalCrossing => throw new IllegalArgumentException("AXI4 Rational crossing unimplemented") @@ -127,30 +127,30 @@ trait HasCrossingMethods extends LazyModule with LazyScope // Interrupts def crossIntSyncInOut(out: Boolean)(alreadyRegistered: Boolean = false)(implicit p: Parameters): IntNode = { - lazy val intssource = LazyModule(new IntSyncCrossingSource(alreadyRegistered)) - lazy val intssink = LazyModule(new IntSyncCrossingSink(0)) - val source = if (out) this { intssource } else intssource - val sink = if (out) intssink else this { intssink } + lazy val int_sync_xing_source = LazyModule(new IntSyncCrossingSource(alreadyRegistered)) + lazy val int_sync_xing_sink = LazyModule(new IntSyncCrossingSink(0)) + val source = if (out) this { int_sync_xing_source } else int_sync_xing_source + val sink = if (out) int_sync_xing_sink else this { int_sync_xing_sink } sink.node :*=* source.node checks = CrossingCheck(out, source.node, sink.node) :: checks NodeHandle(source.node, sink.node) } def crossIntAsyncInOut(out: Boolean)(sync: Int = 3, alreadyRegistered: Boolean = false)(implicit p: Parameters): IntNode = { - lazy val intasource = LazyModule(new IntSyncCrossingSource(alreadyRegistered)) - lazy val intasink = LazyModule(new IntSyncCrossingSink(sync)) - val source = if (out) this { intasource } else intasource - val sink = if (out) intasink else this { intasink } + lazy val int_async_xing_source = LazyModule(new IntSyncCrossingSource(alreadyRegistered)) + lazy val int_async_xing_sink = LazyModule(new IntSyncCrossingSink(sync)) + val source = if (out) this { int_async_xing_source } else int_async_xing_source + val sink = if (out) int_async_xing_sink else this { int_async_xing_sink } sink.node :*=* source.node checks = CrossingCheck(out, source.node, sink.node) :: checks NodeHandle(source.node, sink.node) } def crossIntRationalInOut(out: Boolean)(alreadyRegistered: Boolean = false)(implicit p: Parameters): IntNode = { - lazy val intrsource = LazyModule(new IntSyncCrossingSource(alreadyRegistered)) - lazy val intrsink = LazyModule(new IntSyncCrossingSink(1)) - val source = if (out) this { intrsource } else intrsource - val sink = if (out) intrsink else this { intrsink } + lazy val int_rational_xing_source = LazyModule(new IntSyncCrossingSource(alreadyRegistered)) + lazy val int_rational_xing_sink = LazyModule(new IntSyncCrossingSink(1)) + val source = if (out) this { int_rational_xing_source } else int_rational_xing_source + val sink = if (out) int_rational_xing_sink else this { int_rational_xing_sink } sink.node :*=* source.node checks = CrossingCheck(out, source.node, sink.node) :: checks NodeHandle(source.node, sink.node) @@ -163,26 +163,26 @@ trait HasCrossingMethods extends LazyModule with LazyScope def crossIntRationalIn (alreadyRegistered: Boolean = false)(implicit p: Parameters): IntNode = crossIntRationalInOut(false)(alreadyRegistered) def crossIntRationalOut(alreadyRegistered: Boolean = false)(implicit p: Parameters): IntNode = crossIntRationalInOut(true )(alreadyRegistered) - def crossIntIn(arg: CoreplexClockCrossing, alreadyRegistered: Boolean)(implicit p: Parameters): IntNode = arg match { + def crossIntIn(arg: SubsystemClockCrossing, alreadyRegistered: Boolean)(implicit p: Parameters): IntNode = arg match { case x: SynchronousCrossing => crossIntSyncIn(alreadyRegistered) case x: AsynchronousCrossing => crossIntAsyncIn(x.sync, alreadyRegistered) case x: RationalCrossing => crossIntRationalIn(alreadyRegistered) } - def crossIntOut(arg: CoreplexClockCrossing, alreadyRegistered: Boolean)(implicit p: Parameters): IntNode = arg match { + def crossIntOut(arg: SubsystemClockCrossing, alreadyRegistered: Boolean)(implicit p: Parameters): IntNode = arg match { case x: SynchronousCrossing => crossIntSyncOut(alreadyRegistered) case x: AsynchronousCrossing => crossIntAsyncOut(x.sync, alreadyRegistered) case x: RationalCrossing => crossIntRationalOut(alreadyRegistered) } - def crossIntIn (arg: CoreplexClockCrossing)(implicit p: Parameters): IntNode = crossIntIn (arg, false) - def crossIntOut(arg: CoreplexClockCrossing)(implicit p: Parameters): IntNode = crossIntOut(arg, false) + def crossIntIn (arg: SubsystemClockCrossing)(implicit p: Parameters): IntNode = crossIntIn (arg, false) + def crossIntOut(arg: SubsystemClockCrossing)(implicit p: Parameters): IntNode = crossIntOut(arg, false) } trait HasCrossing extends HasCrossingMethods { this: LazyModule => - val crossing: CoreplexClockCrossing + val crossing: SubsystemClockCrossing def crossTLIn (implicit p: Parameters): TLNode = crossTLIn (crossing) def crossTLOut (implicit p: Parameters): TLNode = crossTLOut (crossing) @@ -195,4 +195,4 @@ trait HasCrossing extends HasCrossingMethods def crossIntOut(alreadyRegistered: Boolean)(implicit p: Parameters): IntNode = crossIntOut(crossing, alreadyRegistered) } -class CrossingWrapper(val crossing: CoreplexClockCrossing)(implicit p: Parameters) extends SimpleLazyModule with HasCrossing +class CrossingWrapper(val crossing: SubsystemClockCrossing)(implicit p: Parameters) extends SimpleLazyModule with HasCrossing diff --git a/src/main/scala/subsystem/FrontBus.scala b/src/main/scala/subsystem/FrontBus.scala new file mode 100644 index 00000000..2539ccdc --- /dev/null +++ b/src/main/scala/subsystem/FrontBus.scala @@ -0,0 +1,50 @@ +// See LICENSE.SiFive for license details. + +package freechips.rocketchip.subsystem + +import Chisel._ +import freechips.rocketchip.config.{Field, Parameters} +import freechips.rocketchip.diplomacy._ +import freechips.rocketchip.tilelink._ +import freechips.rocketchip.util._ + +case class FrontBusParams( + beatBytes: Int, + blockBytes: Int, + sbusCrossing: SubsystemClockCrossing = SynchronousCrossing(), + sbusBuffer: BufferParams = BufferParams.default) extends HasTLBusParams + +case object FrontBusKey extends Field[FrontBusParams] + +class FrontBus(params: FrontBusParams) + (implicit p: Parameters) extends TLBusWrapper(params, "front_bus") + with HasTLXbarPhy + with HasCrossing { + val crossing = params.sbusCrossing + + def fromPort[D,U,E,B <: Data] + (name: Option[String] = None, buffers: Int = 1) + (gen: => NodeHandle[D,U,E,B,TLClientPortParameters,TLManagerPortParameters,TLEdgeOut,TLBundle] = + TLIdentity.gen): InwardNodeHandle[D,U,E,B] = { + from("port" named name) { fixFrom(TLFIFOFixer.all, buffers) :=* gen } + } + + def fromMasterNode(name: Option[String] = None, buffers: Int = 1)(gen: TLOutwardNode) { + from("master" named name) { fixFrom(TLFIFOFixer.all, buffers) :=* gen } + } + + def fromMaster[D,U,E,B <: Data] + (name: Option[String] = None, buffers: Int = 1) + (gen: => NodeHandle[D,U,E,B,TLClientPortParameters,TLManagerPortParameters,TLEdgeOut,TLBundle] = + TLIdentity.gen): InwardNodeHandle[D,U,E,B] = { + from("master" named name) { fixFrom(TLFIFOFixer.all, buffers) :=* gen } + } + + def fromCoherentChip(gen: => TLNode): TLInwardNode = { + from("coherent_subsystem") { inwardNode :=* gen } + } + + def toSystemBus(gen: => TLInwardNode) { + to("sbus") { gen :=* TLBuffer(params.sbusBuffer) :=* outwardNode } + } +} diff --git a/src/main/scala/coreplex/HasTiles.scala b/src/main/scala/subsystem/HasTiles.scala similarity index 92% rename from src/main/scala/coreplex/HasTiles.scala rename to src/main/scala/subsystem/HasTiles.scala index 49a958f8..2b479d20 100644 --- a/src/main/scala/coreplex/HasTiles.scala +++ b/src/main/scala/subsystem/HasTiles.scala @@ -1,6 +1,6 @@ // See LICENSE.SiFive for license details. -package freechips.rocketchip.coreplex +package freechips.rocketchip.subsystem import Chisel._ import chisel3.experimental.dontTouch @@ -14,12 +14,14 @@ class ClockedTileInputs(implicit val p: Parameters) extends ParameterizedBundle with HasExternallyDrivenTileConstants with Clocked -trait HasTiles extends HasSystemBus { +trait HasTiles { this: BaseSubsystem => + implicit val p: Parameters val tiles: Seq[BaseTile] protected def tileParams: Seq[TileParams] = tiles.map(_.tileParams) def nTiles: Int = tileParams.size def hartIdList: Seq[Int] = tileParams.map(_.hartId) def localIntCounts: Seq[Int] = tileParams.map(_.core.nLocalInterrupts) + def sharedMemoryTLEdge = sbus.busView } trait HasTilesBundle { diff --git a/src/main/scala/coreplex/InterruptBus.scala b/src/main/scala/subsystem/InterruptBus.scala similarity index 89% rename from src/main/scala/coreplex/InterruptBus.scala rename to src/main/scala/subsystem/InterruptBus.scala index a9def505..55cbf68c 100644 --- a/src/main/scala/coreplex/InterruptBus.scala +++ b/src/main/scala/subsystem/InterruptBus.scala @@ -1,6 +1,6 @@ // See LICENSE.SiFive for license details. -package freechips.rocketchip.coreplex +package freechips.rocketchip.subsystem import Chisel._ import freechips.rocketchip.config.{Field, Parameters} @@ -24,11 +24,6 @@ class InterruptBusWrapper(implicit p: Parameters) { def toPLIC: IntOutwardNode = int_bus.intnode } -trait HasInterruptBus { - implicit val p: Parameters - val ibus = new InterruptBusWrapper -} - /** Specifies the number of external interrupts */ case object NExtTopInterrupts extends Field[Int](0) @@ -36,7 +31,7 @@ case object NExtTopInterrupts extends Field[Int](0) * However, it should not be used directly; instead one of the below * synchronization wiring child traits should be used. */ -abstract trait HasExtInterrupts extends HasInterruptBus { +abstract trait HasExtInterrupts { this: BaseSubsystem => private val device = new Device with DeviceInterrupts { def describe(resources: ResourceBindings): Description = { Description("soc/external-interrupts", describeInterrupts(resources)) @@ -50,7 +45,7 @@ abstract trait HasExtInterrupts extends HasInterruptBus { /** This trait should be used if the External Interrupts have NOT * already been synchronized to the Periphery (PLIC) Clock. */ -trait HasAsyncExtInterrupts extends HasExtInterrupts { +trait HasAsyncExtInterrupts extends HasExtInterrupts { this: BaseSubsystem => if (nExtInterrupts > 0) { ibus.fromAsync := extInterrupts } @@ -59,7 +54,7 @@ trait HasAsyncExtInterrupts extends HasExtInterrupts { /** This trait can be used if the External Interrupts have already been synchronized * to the Periphery (PLIC) Clock. */ -trait HasSyncExtInterrupts extends HasExtInterrupts { +trait HasSyncExtInterrupts extends HasExtInterrupts { this: BaseSubsystem => if (nExtInterrupts > 0) { ibus.fromSync := extInterrupts } diff --git a/src/main/scala/subsystem/MemoryBus.scala b/src/main/scala/subsystem/MemoryBus.scala new file mode 100644 index 00000000..2a23b657 --- /dev/null +++ b/src/main/scala/subsystem/MemoryBus.scala @@ -0,0 +1,77 @@ +// See LICENSE.SiFive for license details. + +package freechips.rocketchip.subsystem + +import Chisel._ +import freechips.rocketchip.config._ +import freechips.rocketchip.diplomacy._ +import freechips.rocketchip.tilelink._ +import freechips.rocketchip.util._ + +// TODO: applies to all caches, for now +case object CacheBlockBytes extends Field[Int](64) + +/** L2 Broadcast Hub configuration */ +case class BroadcastParams( + nTrackers: Int = 4, + bufferless: Boolean = false) + +case object BroadcastKey extends Field(BroadcastParams()) + +/** L2 memory subsystem configuration */ +case class BankedL2Params( + nMemoryChannels: Int = 1, + nBanksPerChannel: Int = 1, + coherenceManager: BaseSubsystem => (TLInwardNode, TLOutwardNode, () => Option[Bool]) = { subsystem => + implicit val p = subsystem.p + val BroadcastParams(nTrackers, bufferless) = p(BroadcastKey) + val bh = LazyModule(new TLBroadcast(subsystem.memBusBlockBytes, nTrackers, bufferless)) + val ww = LazyModule(new TLWidthWidget(subsystem.sbus.beatBytes)) + ww.node :*= bh.node + (bh.node, ww.node, () => None) + }) { + val nBanks = nMemoryChannels*nBanksPerChannel +} + +case object BankedL2Key extends Field(BankedL2Params()) + +/** Parameterization of the memory-side bus created for each memory channel */ +case class MemoryBusParams(beatBytes: Int, blockBytes: Int) 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, "memory_bus")(p) + with HasTLXbarPhy { + + def fromCoherenceManager( + name: Option[String] = None, + buffer: BufferParams = BufferParams.none) + (gen: => TLNode): TLInwardNode = { + from("coherence_manager" named name) { + 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] = + TLIdentity.gen): OutwardNodeHandle[D,U,E,B] = { + to("memory_controller" named name) { gen := bufferTo(buffer) } + } + + def toVariableWidthSlave[D,U,E,B <: Data] + (name: Option[String] = None, buffer: BufferParams = BufferParams.none) + (gen: => NodeHandle[TLClientPortParameters,TLManagerPortParameters,TLEdgeIn,TLBundle,D,U,E,B] = + TLIdentity.gen): OutwardNodeHandle[D,U,E,B] = { + to("slave" named name) { gen :*= fragmentTo(buffer) } + } + + def toFixedWidthSlave[D,U,E,B <: Data] + (name: Option[String] = None, buffer: BufferParams = BufferParams.none) + (gen: => NodeHandle[TLClientPortParameters,TLManagerPortParameters,TLEdgeIn,TLBundle,D,U,E,B] = + TLIdentity.gen): OutwardNodeHandle[D,U,E,B] = { + to("slave" named name) { gen :*= fixedWidthTo(buffer) } + } + +} diff --git a/src/main/scala/subsystem/PeripheryBus.scala b/src/main/scala/subsystem/PeripheryBus.scala new file mode 100644 index 00000000..27fc0e72 --- /dev/null +++ b/src/main/scala/subsystem/PeripheryBus.scala @@ -0,0 +1,117 @@ +// See LICENSE.SiFive for license details. + +package freechips.rocketchip.subsystem + +import Chisel._ +import freechips.rocketchip.config.{Field, Parameters} +import freechips.rocketchip.diplomacy._ +import freechips.rocketchip.tilelink._ +import freechips.rocketchip.util._ + +case class PeripheryBusParams( + beatBytes: Int, + blockBytes: Int, + arithmeticAtomics: Boolean = true, + bufferAtomics: BufferParams = BufferParams.default, + sbusCrossingType: SubsystemClockCrossing = SynchronousCrossing(), // relative to sbus + frequency: BigInt = BigInt(100000000) // 100 MHz as default bus frequency +) extends HasTLBusParams + +case object PeripheryBusKey extends Field[PeripheryBusParams] + +class PeripheryBus(params: PeripheryBusParams) + (implicit p: Parameters) extends TLBusWrapper(params, "periphery_bus") + with HasTLXbarPhy + with HasCrossing { + val crossing = params.sbusCrossingType + + def toSlave[D,U,E,B <: Data] + (name: Option[String] = None, buffer: BufferParams = BufferParams.none) + (gen: => NodeHandle[TLClientPortParameters,TLManagerPortParameters,TLEdgeIn,TLBundle,D,U,E,B] = + TLIdentity.gen): OutwardNodeHandle[D,U,E,B] = { + to("slave" named name) { gen :*= bufferTo(buffer) } + } + + def toVariableWidthSlaveNode(name: Option[String] = None, buffer: BufferParams = BufferParams.none)(node: TLInwardNode) { toVariableWidthSlaveNodeOption(name, buffer)(Some(node)) } + + def toVariableWidthSlaveNodeOption(name: Option[String] = None, buffer: BufferParams = BufferParams.none)(node: Option[TLInwardNode]) { + node foreach { n => to("slave" named name) { n :*= fragmentTo(buffer) } } + } + + def toVariableWidthSlave[D,U,E,B <: Data] + (name: Option[String] = None, buffer: BufferParams = BufferParams.none) + (gen: => NodeHandle[TLClientPortParameters,TLManagerPortParameters,TLEdgeIn,TLBundle,D,U,E,B] = + TLIdentity.gen): OutwardNodeHandle[D,U,E,B] = { + to("slave" named name) { gen :*= fragmentTo(buffer) } + } + + def toFixedWidthSlaveNode(name: Option[String] = None, buffer: BufferParams = BufferParams.none)(gen: TLInwardNode) { + to("slave" named name) { gen :*= fixedWidthTo(buffer) } + } + + def toFixedWidthSlave[D,U,E,B <: Data] + (name: Option[String] = None, buffer: BufferParams = BufferParams.none) + (gen: => NodeHandle[TLClientPortParameters,TLManagerPortParameters,TLEdgeIn,TLBundle,D,U,E,B] = + TLIdentity.gen): OutwardNodeHandle[D,U,E,B] = { + to("slave" named name) { gen :*= fixedWidthTo(buffer) } + } + + def toFixedWidthSingleBeatSlaveNode + (widthBytes: Int, name: Option[String] = None, buffer: BufferParams = BufferParams.none) + (gen: TLInwardNode) { + to("slave" named name) { + gen :*= TLFragmenter(widthBytes, params.blockBytes) :*= fixedWidthTo(buffer) + } + } + + def toFixedWidthSingleBeatSlave[D,U,E,B <: Data] + (widthBytes: Int, name: Option[String] = None, buffer: BufferParams = BufferParams.none) + (gen: => NodeHandle[TLClientPortParameters,TLManagerPortParameters,TLEdgeIn,TLBundle,D,U,E,B] = + TLIdentity.gen): OutwardNodeHandle[D,U,E,B] = { + to("slave" named name) { + gen :*= TLFragmenter(widthBytes, params.blockBytes) :*= fixedWidthTo(buffer) + } + } + + def toLargeBurstSlave[D,U,E,B <: Data] + (maxXferBytes: Int, name: Option[String] = None, buffer: BufferParams = BufferParams.none) + (gen: => NodeHandle[TLClientPortParameters,TLManagerPortParameters,TLEdgeIn,TLBundle,D,U,E,B] = + TLIdentity.gen): OutwardNodeHandle[D,U,E,B] = { + to("slave" named name) { + gen :*= fragmentTo(params.beatBytes, maxXferBytes, buffer) + } + } + + def toFixedWidthPort[D,U,E,B <: Data] + (name: Option[String] = None, buffer: BufferParams = BufferParams.none) + (gen: => NodeHandle[TLClientPortParameters,TLManagerPortParameters,TLEdgeIn,TLBundle,D,U,E,B] = + TLIdentity.gen): OutwardNodeHandle[D,U,E,B] = { + to("port" named name) { gen := fixedWidthTo(buffer) } + } + + + def fromSystemBus(gen: => TLOutwardNode) { + from("sbus") { + (inwardNode + :*= TLBuffer(params.bufferAtomics) + :*= TLAtomicAutomata(arithmetic = params.arithmeticAtomics) + :*= gen) + } + } + + def fromOtherMaster[D,U,E,B <: Data] + (name: Option[String] = None, buffer: BufferParams = BufferParams.none) + (gen: => NodeHandle[D,U,E,B,TLClientPortParameters,TLManagerPortParameters,TLEdgeOut,TLBundle] = + TLIdentity.gen): InwardNodeHandle[D,U,E,B] = { + from("master" named name) { bufferFrom(buffer) :=* gen } + } + + + def toTile + (name: Option[String] = None, buffers: Int = 0) + (gen: => TLNode): TLOutwardNode = { + to("tile" named name) { FlipRendering { implicit p => + gen :*= bufferTo(buffers) + }} + } +} diff --git a/src/main/scala/coreplex/Ports.scala b/src/main/scala/subsystem/Ports.scala similarity index 84% rename from src/main/scala/coreplex/Ports.scala rename to src/main/scala/subsystem/Ports.scala index 438e0d1e..40d38a34 100644 --- a/src/main/scala/coreplex/Ports.scala +++ b/src/main/scala/subsystem/Ports.scala @@ -1,6 +1,6 @@ // See LICENSE.SiFive for license details. -package freechips.rocketchip.coreplex +package freechips.rocketchip.subsystem import Chisel._ import freechips.rocketchip.config.{Field, Parameters} @@ -27,11 +27,13 @@ case object ExtIn extends Field[SlavePortParams] ///// The following traits add ports to the sytem, in some cases converting to different interconnect standards /** Adds a port to the system intended to master an AXI4 DRAM controller. */ -trait HasMasterAXI4MemPort extends HasMemoryBus { +trait HasMasterAXI4MemPort { this: BaseSubsystem => val module: HasMasterAXI4MemPortModuleImp private val params = p(ExtMem) + private val portName = "axi4" private val device = new MemoryDevice + val nMemoryChannels: Int val mem_axi4 = AXI4SlaveNode(Seq.tabulate(nMemoryChannels) { channel => val base = AddressSet(params.base, params.size-1) @@ -49,13 +51,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(portName)) { + (AXI4UserYanker() := AXI4IdIndexer(params.idBits) := TLToAXI4()) + } } } @@ -75,15 +74,17 @@ trait HasMasterAXI4MemPortBundle { /** Actually generates the corresponding IO in the concrete Module */ trait HasMasterAXI4MemPortModuleImp extends LazyModuleImp with HasMasterAXI4MemPortBundle { val outer: HasMasterAXI4MemPort + val mem_axi4 = IO(HeterogeneousBag.fromNode(outer.mem_axi4.in)) (mem_axi4 zip outer.mem_axi4.in) foreach { case (i, (o, _)) => i <> o } val nMemoryChannels = outer.nMemoryChannels } /** Adds a AXI4 port to the system intended to master an MMIO device bus */ -trait HasMasterAXI4MMIOPort extends HasSystemBus { +trait HasMasterAXI4MMIOPort { this: BaseSubsystem => private val params = p(ExtBus) - private val device = new SimpleBus("mmio", Nil) + private val portName = "mmio_port_axi4" + private val device = new SimpleBus(portName.kebab, Nil) val mmio_axi4 = AXI4SlaveNode(Seq(AXI4SlavePortParameters( slaves = Seq(AXI4SlaveParameters( address = AddressSet.misaligned(params.base, params.size), @@ -93,13 +94,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(portName)) { + (AXI4Buffer() + := AXI4UserYanker() + := AXI4Deinterleaver(sbus.blockBytes) + := AXI4IdIndexer(params.idBits) + := TLToAXI4()) + } } /** Common io name and methods for propagating or tying off the port bundle */ @@ -120,21 +121,22 @@ trait HasMasterAXI4MMIOPortModuleImp extends LazyModuleImp with HasMasterAXI4MMI } /** Adds an AXI4 port to the system intended to be a slave on an MMIO device bus */ -trait HasSlaveAXI4Port extends HasSystemBus { +trait HasSlaveAXI4Port { this: BaseSubsystem => private val params = p(ExtIn) + private val portName = "slave_port_axi4" val l2FrontendAXI4Node = AXI4MasterNode(Seq(AXI4MasterPortParameters( masters = Seq(AXI4MasterParameters( - name = "AXI4 periphery", + name = portName.kebab, 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(portName)) { + (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 */ @@ -160,9 +162,10 @@ trait HasSlaveAXI4PortModuleImp extends LazyModuleImp with HasSlaveAXI4PortBundl } /** Adds a TileLink port to the system intended to master an MMIO device bus */ -trait HasMasterTLMMIOPort extends HasSystemBus { +trait HasMasterTLMMIOPort { this: BaseSubsystem => private val params = p(ExtBus) - private val device = new SimpleBus("mmio", Nil) + private val portName = "mmio_port_tl" + private val device = new SimpleBus(portName.kebab, Nil) val mmio_tl = TLManagerNode(Seq(TLManagerPortParameters( managers = Seq(TLManagerParameters( address = AddressSet.misaligned(params.base, params.size), @@ -173,7 +176,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(portName)) { + TLBuffer() := TLSourceShrinker(1 << params.idBits) + } } /** Common io name and methods for propagating or tying off the port bundle */ @@ -201,14 +206,17 @@ trait HasMasterTLMMIOPortModuleImp extends LazyModuleImp with HasMasterTLMMIOPor /** Adds an TL port to the system intended to be a slave on an MMIO device bus. * NOTE: this port is NOT allowed to issue Acquires. */ -trait HasSlaveTLPort extends HasSystemBus { +trait HasSlaveTLPort { this: BaseSubsystem => private val params = p(ExtIn) + private val portName = "slave_port_tl" val l2FrontendTLNode = TLClientNode(Seq(TLClientPortParameters( clients = Seq(TLClientParameters( - name = "Front Port (TL)", + name = portName.kebab, sourceId = IdRange(0, 1 << params.idBits)))))) - sbus.fromSyncPorts() := TLSourceShrinker(1 << params.sourceBits) := TLWidthWidget(params.beatBytes) := l2FrontendTLNode + sbus.fromPort(Some(portName)) { + 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/coreplex/RTC.scala b/src/main/scala/subsystem/RTC.scala similarity index 82% rename from src/main/scala/coreplex/RTC.scala rename to src/main/scala/subsystem/RTC.scala index e21e29e1..000dbad2 100644 --- a/src/main/scala/coreplex/RTC.scala +++ b/src/main/scala/subsystem/RTC.scala @@ -1,13 +1,13 @@ // See LICENSE.SiFive for license details. -package freechips.rocketchip.coreplex +package freechips.rocketchip.subsystem import Chisel._ import freechips.rocketchip.diplomacy.{LazyModuleImp, DTSTimebase} -import freechips.rocketchip.devices.tilelink.HasPeripheryClint +import freechips.rocketchip.devices.tilelink.HasPeripheryCLINT trait HasRTCModuleImp extends LazyModuleImp { - val outer: HasPeripheryClint + val outer: BaseSubsystem with HasPeripheryCLINT private val pbusFreq = outer.p(PeripheryBusKey).frequency private val rtcFreq = outer.p(DTSTimebase) private val internalPeriod: BigInt = pbusFreq / rtcFreq diff --git a/src/main/scala/coreplex/ResetVector.scala b/src/main/scala/subsystem/ResetVector.scala similarity index 86% rename from src/main/scala/coreplex/ResetVector.scala rename to src/main/scala/subsystem/ResetVector.scala index d66de529..56366d17 100644 --- a/src/main/scala/coreplex/ResetVector.scala +++ b/src/main/scala/subsystem/ResetVector.scala @@ -1,6 +1,6 @@ // See LICENSE.SiFive for license details. -package freechips.rocketchip.coreplex +package freechips.rocketchip.subsystem import Chisel._ diff --git a/src/main/scala/coreplex/RocketCoreplex.scala b/src/main/scala/subsystem/RocketSubsystem.scala similarity index 68% rename from src/main/scala/coreplex/RocketCoreplex.scala rename to src/main/scala/subsystem/RocketSubsystem.scala index db3702bd..da7bb6f9 100644 --- a/src/main/scala/coreplex/RocketCoreplex.scala +++ b/src/main/scala/subsystem/RocketSubsystem.scala @@ -1,6 +1,6 @@ // See LICENSE.SiFive for license details. -package freechips.rocketchip.coreplex +package freechips.rocketchip.subsystem import Chisel._ import chisel3.internal.sourceinfo.SourceInfo @@ -14,41 +14,11 @@ import freechips.rocketchip.interrupts._ import freechips.rocketchip.util._ // TODO: how specific are these to RocketTiles? -case class TileMasterPortParams( - addBuffers: Int = 0, - cork: Option[Boolean] = None) { - - def adapt(coreplex: 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( - addBuffers: Int = 0, - blockerCtrlAddr: Option[BigInt] = None) { - - def adapt(coreplex: HasPeripheryBus) - (slaveNode: TLInwardNode) - (implicit p: Parameters, sourceInfo: SourceInfo): TLInwardNode = { - val tile_slave_blocker = - blockerCtrlAddr - .map(BasicBusBlockerParams(_, coreplex.pbus.beatBytes, coreplex.sbus.beatBytes)) - .map(bp => LazyModule(new BasicBusBlocker(bp))) - - tile_slave_blocker.foreach { _.controlNode := coreplex.pbus.toVariableWidthSlaves } - (Seq() ++ tile_slave_blocker.map(_.node) ++ TLBuffer.chain(addBuffers)) - .foldLeft(slaveNode)(_ :*= _) - } -} +case class TileMasterPortParams(buffers: Int = 0, cork: Option[Boolean] = None) +case class TileSlavePortParams(buffers: Int = 0, blockerCtrlAddr: Option[BigInt] = None) case class RocketCrossingParams( - crossingType: CoreplexClockCrossing = SynchronousCrossing(), + crossingType: SubsystemClockCrossing = SynchronousCrossing(), master: TileMasterPortParams = TileMasterPortParams(), slave: TileSlavePortParams = TileSlavePortParams()) { def knownRatio: Option[Int] = crossingType match { @@ -61,10 +31,9 @@ case object RocketTilesKey extends Field[Seq[RocketTileParams]](Nil) case object RocketCrossingKey extends Field[Seq[RocketCrossingParams]](List(RocketCrossingParams())) trait HasRocketTiles extends HasTiles - with HasPeripheryBus with HasPeripheryPLIC - with HasPeripheryClint - with HasPeripheryDebug { + with HasPeripheryCLINT + with HasPeripheryDebug { this: BaseSubsystem => val module: HasRocketTilesModuleImp protected val rocketTileParams = p(RocketTilesKey) @@ -95,7 +64,7 @@ trait HasRocketTiles extends HasTiles def tileMasterBuffering: TLOutwardNode = rocket { // The buffers needed to cut feed-through paths are microarchitecture specific, so belong here - val masterBuffer = LazyModule(new TLBuffer(BufferParams.none, BufferParams.flow, BufferParams.none, BufferParams.flow, BufferParams(1))) + val masterBufferNode = TLBuffer(BufferParams.none, BufferParams.flow, BufferParams.none, BufferParams.flow, BufferParams(1)) crossing.crossingType match { case _: AsynchronousCrossing => rocket.masterNode case SynchronousCrossing(b) => @@ -104,28 +73,41 @@ trait HasRocketTiles extends HasTiles case RationalCrossing(dir) => require (dir != SlowToFast, "Misconfiguration? Core slower than fabric") if (tp.boundaryBuffers) { - masterBuffer.node :=* rocket.masterNode + masterBufferNode :=* rocket.masterNode } else { rocket.masterNode } } } - sbus.fromTile(tp.name) { implicit p => crossing.master.adapt(this)(rocket.crossTLOut :=* tileMasterBuffering) } + sbus.fromTile(tp.name, crossing.master.buffers) { + crossing.master.cork + .map { u => TLCacheCork(unsafe = u) } + .map { _ :=* rocket.crossTLOut } + .getOrElse { rocket.crossTLOut } + } :=* tileMasterBuffering // Connect the slave ports of the tile to the periphery bus def tileSlaveBuffering: TLInwardNode = rocket { - val slaveBuffer = LazyModule(new TLBuffer(BufferParams.flow, BufferParams.none, BufferParams.none, BufferParams.none, BufferParams.none)) + val slaveBufferNode = TLBuffer(BufferParams.flow, BufferParams.none, BufferParams.none, BufferParams.none, BufferParams.none) crossing.crossingType match { - case RationalCrossing(_) if (tp.boundaryBuffers) => rocket.slaveNode :*= slaveBuffer.node + case RationalCrossing(_) if (tp.boundaryBuffers) => rocket.slaveNode :*= slaveBufferNode case _ => rocket.slaveNode } } - pbus.toTile(tp.name) { implicit p => crossing.slave.adapt(this)( DisableMonitors { implicit p => - tileSlaveBuffering :*= rocket.crossTLIn - })} + DisableMonitors { implicit p => + tileSlaveBuffering :*= pbus.toTile(tp.name) { + crossing.slave.blockerCtrlAddr + .map { BasicBusBlockerParams(_, pbus.beatBytes, sbus.beatBytes) } + .map { bbbp => LazyModule(new BasicBusBlocker(bbbp)) } + .map { bbb => + pbus.toVariableWidthSlave(Some("bus_blocker")) { bbb.controlNode } + rocket.crossTLIn :*= bbb.node + } .getOrElse { rocket.crossTLIn } + } + } // Handle all the different types of interrupts crossing to or from the tile: // 1. Debug interrupt is definitely asynchronous in all cases. @@ -163,13 +145,13 @@ trait HasRocketTilesModuleImp extends HasTilesModuleImp val outer: HasRocketTiles } -class RocketCoreplex(implicit p: Parameters) extends BaseCoreplex +class RocketSubsystem(implicit p: Parameters) extends BaseSubsystem with HasRocketTiles { val tiles = rocketTiles - override lazy val module = new RocketCoreplexModule(this) + override lazy val module = new RocketSubsystemModuleImp(this) } -class RocketCoreplexModule[+L <: RocketCoreplex](_outer: L) extends BaseCoreplexModule(_outer) +class RocketSubsystemModuleImp[+L <: RocketSubsystem](_outer: L) extends BaseSubsystemModuleImp(_outer) with HasRocketTilesModuleImp { tile_inputs.zip(outer.hartIdList).foreach { case(wire, i) => wire.clock := clock diff --git a/src/main/scala/subsystem/SystemBus.scala b/src/main/scala/subsystem/SystemBus.scala new file mode 100644 index 00000000..b8c957a2 --- /dev/null +++ b/src/main/scala/subsystem/SystemBus.scala @@ -0,0 +1,109 @@ +// See LICENSE.SiFive for license details. + +package freechips.rocketchip.subsystem + +import Chisel._ +import freechips.rocketchip.config.{Field, Parameters} +import freechips.rocketchip.diplomacy._ +import freechips.rocketchip.tilelink._ +import freechips.rocketchip.util._ + +case class SystemBusParams( + beatBytes: Int, + blockBytes: Int, + pbusBuffer: BufferParams = BufferParams.none) extends HasTLBusParams + +case object SystemBusKey extends Field[SystemBusParams] + +class SystemBus(params: SystemBusParams)(implicit p: Parameters) extends TLBusWrapper(params, "system_bus") + with HasTLXbarPhy { + + private val master_splitter = LazyModule(new TLSplitter) + inwardNode :=* master_splitter.node + + protected def fixFromThenSplit(policy: TLFIFOFixer.Policy, buffers: Int): TLInwardNode = + master_splitter.node :=* TLBuffer.chain(buffers).foldLeft(TLFIFOFixer(policy))(_ :=* _) + + def busView = master_splitter.node.edges.in.head + + def toPeripheryBus(gen: => TLNode): TLOutwardNode = { + to("pbus") { + (gen + := TLFIFOFixer(TLFIFOFixer.all) + := TLWidthWidget(params.beatBytes) + := bufferTo(params.pbusBuffer)) + } + } + + def toMemoryBus(gen: => TLInwardNode) { + to("mbus") { gen := delayNode := outwardNode } + } + + def toSlave[D,U,E,B <: Data] + (name: Option[String] = None, buffer: BufferParams = BufferParams.default) + (gen: => NodeHandle[TLClientPortParameters,TLManagerPortParameters,TLEdgeIn,TLBundle,D,U,E,B] = + TLIdentity.gen): OutwardNodeHandle[D,U,E,B] = { + to("slave" named name) { gen :*= bufferTo(buffer) } + } + + def toSplitSlave[D,U,E,B <: Data] + (name: Option[String] = None) + (gen: => NodeHandle[TLClientPortParameters,TLManagerPortParameters,TLEdgeIn,TLBundle,D,U,E,B] = + TLIdentity.gen): OutwardNodeHandle[D,U,E,B] = { + to("slave" named name) { gen :=* master_splitter.node } + } + + def toFixedWidthSlave[D,U,E,B <: Data] + (name: Option[String] = None, buffer: BufferParams = BufferParams.default) + (gen: => NodeHandle[TLClientPortParameters,TLManagerPortParameters,TLEdgeIn,TLBundle,D,U,E,B] = + TLIdentity.gen): OutwardNodeHandle[D,U,E,B] = { + to("slave" named name) { gen :*= fixedWidthTo(buffer) } + } + + def toVariableWidthSlave[D,U,E,B <: Data] + (name: Option[String] = None, buffer: BufferParams = BufferParams.default) + (gen: => NodeHandle[TLClientPortParameters,TLManagerPortParameters,TLEdgeIn,TLBundle,D,U,E,B] = + TLIdentity.gen): OutwardNodeHandle[D,U,E,B] = { + to("slave" named name) { gen :*= fragmentTo(buffer) } + } + + def fromFrontBus(gen: => TLNode): TLInwardNode = { + from("front_bus") { master_splitter.node :=* gen } + } + + def fromTile + (name: Option[String], buffers: Int = 0, cork: Option[Boolean] = None) + (gen: => TLNode): TLInwardNode = { + from("tile" named name) { + fixFromThenSplit(TLFIFOFixer.allUncacheable, buffers) :=* 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] = + TLIdentity.gen): OutwardNodeHandle[D,U,E,B] = { + to("port" named name) { gen := fixedWidthTo(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] = + TLIdentity.gen): InwardNodeHandle[D,U,E,B] = { + from("port" named name) { fixFromThenSplit(TLFIFOFixer.all, buffers) :=* gen } + } + + def fromCoherentMaster[D,U,E,B <: Data] + (name: Option[String] = None, buffers: Int = 0) + (gen: => NodeHandle[D,U,E,B,TLClientPortParameters,TLManagerPortParameters,TLEdgeOut,TLBundle] = + TLIdentity.gen): InwardNodeHandle[D,U,E,B] = { + from("coherent_master" named name) { fixFrom(TLFIFOFixer.all, buffers) :=* gen } + } + + def fromMaster[D,U,E,B <: Data] + (name: Option[String] = None, buffers: Int = 0) + (gen: => NodeHandle[D,U,E,B,TLClientPortParameters,TLManagerPortParameters,TLEdgeOut,TLBundle] = + TLIdentity.gen): InwardNodeHandle[D,U,E,B] = { + from("master" named name) { fixFromThenSplit(TLFIFOFixer.all, buffers) :=* gen } + } +} diff --git a/src/main/scala/system/Configs.scala b/src/main/scala/system/Configs.scala index 5aab4f1f..b7fd2d90 100644 --- a/src/main/scala/system/Configs.scala +++ b/src/main/scala/system/Configs.scala @@ -5,13 +5,13 @@ package freechips.rocketchip.system import Chisel._ import freechips.rocketchip.config.Config -import freechips.rocketchip.coreplex._ +import freechips.rocketchip.subsystem._ import freechips.rocketchip.devices.debug.{IncludeJtagDTM, JtagDTMKey} import freechips.rocketchip.diplomacy._ -class WithJtagDTMSystem extends freechips.rocketchip.coreplex.WithJtagDTM +class WithJtagDTMSystem extends freechips.rocketchip.subsystem.WithJtagDTM -class BaseConfig extends Config(new BaseCoreplexConfig().alter((site,here,up) => { +class BaseConfig extends Config(new BaseSubsystemConfig().alter((site,here,up) => { // DTS descriptive parameters case DTSModel => "freechips,rocketchip-unknown" case DTSCompat => Nil diff --git a/src/main/scala/system/ExampleRocketSystem.scala b/src/main/scala/system/ExampleRocketSystem.scala index 981f7a0d..a09b96bf 100644 --- a/src/main/scala/system/ExampleRocketSystem.scala +++ b/src/main/scala/system/ExampleRocketSystem.scala @@ -4,22 +4,22 @@ package freechips.rocketchip.system import Chisel._ import freechips.rocketchip.config.Parameters -import freechips.rocketchip.coreplex._ +import freechips.rocketchip.subsystem._ import freechips.rocketchip.devices.tilelink._ import freechips.rocketchip.util.DontTouch -/** Example Top with periphery devices and ports, and a Rocket coreplex */ -class ExampleRocketSystem(implicit p: Parameters) extends RocketCoreplex +/** Example Top with periphery devices and ports, and a Rocket subsystem */ +class ExampleRocketSystem(implicit p: Parameters) extends RocketSubsystem with HasAsyncExtInterrupts with HasMasterAXI4MemPort with HasMasterAXI4MMIOPort with HasSlaveAXI4Port with HasPeripheryBootROM with HasSystemErrorSlave { - override lazy val module = new ExampleRocketSystemModule(this) + override lazy val module = new ExampleRocketSystemModuleImp(this) } -class ExampleRocketSystemModule[+L <: ExampleRocketSystem](_outer: L) extends RocketCoreplexModule(_outer) +class ExampleRocketSystemModuleImp[+L <: ExampleRocketSystem](_outer: L) extends RocketSubsystemModuleImp(_outer) with HasRTCModuleImp with HasExtInterruptsModuleImp with HasMasterAXI4MemPortModuleImp diff --git a/src/main/scala/system/Generator.scala b/src/main/scala/system/Generator.scala index db5f69b6..62c1d5ea 100644 --- a/src/main/scala/system/Generator.scala +++ b/src/main/scala/system/Generator.scala @@ -2,13 +2,13 @@ package freechips.rocketchip.system -import freechips.rocketchip.coreplex.RocketTilesKey +import freechips.rocketchip.subsystem.RocketTilesKey import freechips.rocketchip.tile.XLen import freechips.rocketchip.util.GeneratorApp import scala.collection.mutable.LinkedHashSet -/** A Generator for platforms containing Rocket Coreplexes */ +/** A Generator for platforms containing Rocket Subsystemes */ object Generator extends GeneratorApp { val rv64RegrTestNames = LinkedHashSet( @@ -50,7 +50,7 @@ object Generator extends GeneratorApp { override def addTestSuites { import DefaultTestSuites._ val xlen = params(XLen) - // TODO: for now only generate tests for the first core in the first coreplex + // TODO: for now only generate tests for the first core in the first subsystem val tileParams = params(RocketTilesKey).head val coreParams = tileParams.core val vm = coreParams.useVM diff --git a/src/main/scala/tile/BaseTile.scala b/src/main/scala/tile/BaseTile.scala index 40f2b8da..4586379d 100644 --- a/src/main/scala/tile/BaseTile.scala +++ b/src/main/scala/tile/BaseTile.scala @@ -5,7 +5,7 @@ package freechips.rocketchip.tile import Chisel._ import freechips.rocketchip.config._ -import freechips.rocketchip.coreplex._ +import freechips.rocketchip.subsystem._ import freechips.rocketchip.diplomacy._ import freechips.rocketchip.interrupts._ import freechips.rocketchip.rocket._ @@ -122,7 +122,7 @@ trait HasTileParameters { } /** Base class for all Tiles that use TileLink */ -abstract class BaseTile(tileParams: TileParams, val crossing: CoreplexClockCrossing) +abstract class BaseTile(tileParams: TileParams, val crossing: SubsystemClockCrossing) (implicit p: Parameters) extends LazyModule with HasTileParameters with HasCrossing { def module: BaseTileModuleImp[BaseTile] diff --git a/src/main/scala/tile/Interrupts.scala b/src/main/scala/tile/Interrupts.scala index 6e81f109..3f012ba5 100644 --- a/src/main/scala/tile/Interrupts.scala +++ b/src/main/scala/tile/Interrupts.scala @@ -18,7 +18,7 @@ class TileInterrupts(implicit p: Parameters) extends CoreBundle()(p) { val lip = Vec(coreParams.nLocalInterrupts, Bool()) } -// Use diplomatic interrupts to external interrupts from the coreplex into the tile +// Use diplomatic interrupts to external interrupts from the subsystem into the tile trait HasExternalInterrupts { this: BaseTile => val intInwardNode = intXbar.intnode @@ -50,7 +50,7 @@ trait HasExternalInterrupts { this: BaseTile => // TODO: the order of the following two functions must match, and // also match the order which things are connected to the - // per-tile crossbar in coreplex.HasRocketTiles + // per-tile crossbar in subsystem.HasRocketTiles // debug, msip, mtip, meip, seip, lip offsets in CSRs def csrIntMap: List[Int] = { diff --git a/src/main/scala/tile/L1Cache.scala b/src/main/scala/tile/L1Cache.scala index 811a9773..4b0e11d8 100644 --- a/src/main/scala/tile/L1Cache.scala +++ b/src/main/scala/tile/L1Cache.scala @@ -5,7 +5,7 @@ package freechips.rocketchip.tile import Chisel._ import freechips.rocketchip.config.{Parameters, Field} -import freechips.rocketchip.coreplex.CacheBlockBytes +import freechips.rocketchip.subsystem.CacheBlockBytes import freechips.rocketchip.tilelink.ClientMetadata import freechips.rocketchip.util._ diff --git a/src/main/scala/tile/LazyRoCC.scala b/src/main/scala/tile/LazyRoCC.scala index 49dff340..33d70c0c 100644 --- a/src/main/scala/tile/LazyRoCC.scala +++ b/src/main/scala/tile/LazyRoCC.scala @@ -6,7 +6,7 @@ package freechips.rocketchip.tile import Chisel._ import freechips.rocketchip.config._ -import freechips.rocketchip.coreplex._ +import freechips.rocketchip.subsystem._ import freechips.rocketchip.diplomacy._ import freechips.rocketchip.rocket._ import freechips.rocketchip.tilelink._ diff --git a/src/main/scala/tile/RocketTile.scala b/src/main/scala/tile/RocketTile.scala index 79b565bf..e4ace503 100644 --- a/src/main/scala/tile/RocketTile.scala +++ b/src/main/scala/tile/RocketTile.scala @@ -5,7 +5,7 @@ package freechips.rocketchip.tile import Chisel._ import freechips.rocketchip.config._ -import freechips.rocketchip.coreplex.CoreplexClockCrossing +import freechips.rocketchip.subsystem.SubsystemClockCrossing import freechips.rocketchip.devices.tilelink._ import freechips.rocketchip.diplomacy._ import freechips.rocketchip.interrupts._ @@ -33,7 +33,7 @@ case class RocketTileParams( class RocketTile( val rocketParams: RocketTileParams, - crossing: CoreplexClockCrossing) + crossing: SubsystemClockCrossing) (implicit p: Parameters) extends BaseTile(rocketParams, crossing)(p) with HasExternalInterrupts with HasLazyRoCC // implies CanHaveSharedFPU with CanHavePTW with HasHellaCache diff --git a/src/main/scala/tilelink/AsyncCrossing.scala b/src/main/scala/tilelink/AsyncCrossing.scala index 4e4a9300..8c7d5300 100644 --- a/src/main/scala/tilelink/AsyncCrossing.scala +++ b/src/main/scala/tilelink/AsyncCrossing.scala @@ -7,7 +7,7 @@ import freechips.rocketchip.config.Parameters import freechips.rocketchip.diplomacy._ import freechips.rocketchip.util._ import freechips.rocketchip.util.property._ -import freechips.rocketchip.coreplex.{CrossingWrapper, AsynchronousCrossing} +import freechips.rocketchip.subsystem.{CrossingWrapper, AsynchronousCrossing} class TLAsyncCrossingSource(sync: Int = 3)(implicit p: Parameters) extends LazyModule { 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..ecb784ae --- /dev/null +++ b/src/main/scala/tilelink/BusWrapper.scala @@ -0,0 +1,87 @@ +// 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 bufferFrom(buffer: BufferParams): TLInwardNode = + inwardNode :=* TLBuffer(buffer) + + protected def bufferFrom(buffers: Int): TLInwardNode = + TLBuffer.chain(buffers).foldLeft(inwardNode)(_ :=* _) + + protected def fixFrom(policy: TLFIFOFixer.Policy, buffers: Int): TLInwardNode = + inwardNode :=* TLBuffer.chain(buffers).foldLeft(TLFIFOFixer(policy))(_ :=* _) + + protected def bufferTo(buffer: BufferParams): TLOutwardNode = + TLBuffer(buffer) :*= delayNode :*= outwardNode + + protected def bufferTo(buffers: Int): TLOutwardNode = + TLBuffer.chain(buffers).foldRight(delayNode)(_ :*= _) :*= outwardNode + + protected def fixedWidthTo(buffer: BufferParams): TLOutwardNode = + TLWidthWidget(beatBytes) :*= bufferTo(buffer) + + protected def fragmentTo(buffer: BufferParams): TLOutwardNode = + TLFragmenter(beatBytes, blockBytes) :*= bufferTo(buffer) + + protected def fragmentTo(minSize: Int, maxSize: Int, buffer: BufferParams): TLOutwardNode = + TLFragmenter(minSize, maxSize) :*= bufferTo(buffer) + + 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"coupler_to_${name}") { body } } + } + + protected def from[T](name: String)(body: => T): T = { + this { LazyScope(s"coupler_from_${name}") { body } } + } +} + +trait HasTLXbarPhy { this: TLBusWrapper => + private val xbar = LazyModule(new TLXbar).suggestName(busName + "_xbar") + + protected def inwardNode: TLInwardNode = xbar.node + protected def outwardNode: TLOutwardNode = xbar.node +} + +object TLIdentity { + def gen: TLNode = { + val passthru = TLIdentityNode() + passthru + } +} diff --git a/src/main/scala/tilelink/Nodes.scala b/src/main/scala/tilelink/Nodes.scala index c629c0b9..6c563227 100644 --- a/src/main/scala/tilelink/Nodes.scala +++ b/src/main/scala/tilelink/Nodes.scala @@ -30,18 +30,6 @@ object TLImp extends NodeImp[TLClientPortParameters, TLManagerPortParameters, TL pd.copy(clients = pd.clients.map { c => c.copy (nodePath = node +: c.nodePath) }) override def mixI(pu: TLManagerPortParameters, node: InwardNode[TLClientPortParameters, TLManagerPortParameters, TLBundle]): TLManagerPortParameters = pu.copy(managers = pu.managers.map { m => m.copy (nodePath = node +: m.nodePath) }) - override def getO(pu: TLManagerPortParameters): Option[BaseNode] = { - val head = pu.managers.map(_.nodePath.headOption) - if (head.exists(!_.isDefined) || head.map(_.get).distinct.size != 1) { - None - } else { - val subproblem = pu.copy(managers = pu.managers.map(m => m.copy(nodePath = m.nodePath.tail))) - getO(subproblem) match { - case Some(x) => Some(x) - case None => Some(head(0).get) - } - } - } } case class TLClientNode(portParams: Seq[TLClientPortParameters])(implicit valName: ValName) extends SourceNode(TLImp)(portParams) diff --git a/src/main/scala/unittest/Configs.scala b/src/main/scala/unittest/Configs.scala index 4eb75458..996141b8 100644 --- a/src/main/scala/unittest/Configs.scala +++ b/src/main/scala/unittest/Configs.scala @@ -7,7 +7,7 @@ import freechips.rocketchip.amba.ahb._ import freechips.rocketchip.amba.apb._ import freechips.rocketchip.amba.axi4._ import freechips.rocketchip.config._ -import freechips.rocketchip.coreplex.{BaseCoreplexConfig} +import freechips.rocketchip.subsystem.{BaseSubsystemConfig} import freechips.rocketchip.devices.tilelink._ import freechips.rocketchip.tilelink._ @@ -79,7 +79,7 @@ class WithTLXbarUnitTests extends Config((site, here, up) => { Module(new TLMulticlientXbarTest(4,4, txns=2*txns, timeout=timeout)) ) } }) -class AMBAUnitTestConfig extends Config(new WithAMBAUnitTests ++ new WithTestDuration(10) ++ new BaseCoreplexConfig) -class TLSimpleUnitTestConfig extends Config(new WithTLSimpleUnitTests ++ new WithTestDuration(10) ++ new BaseCoreplexConfig) -class TLWidthUnitTestConfig extends Config(new WithTLWidthUnitTests ++ new WithTestDuration(10) ++ new BaseCoreplexConfig) -class TLXbarUnitTestConfig extends Config(new WithTLXbarUnitTests ++ new WithTestDuration(10) ++ new BaseCoreplexConfig) +class AMBAUnitTestConfig extends Config(new WithAMBAUnitTests ++ new WithTestDuration(10) ++ new BaseSubsystemConfig) +class TLSimpleUnitTestConfig extends Config(new WithTLSimpleUnitTests ++ new WithTestDuration(10) ++ new BaseSubsystemConfig) +class TLWidthUnitTestConfig extends Config(new WithTLWidthUnitTests ++ new WithTestDuration(10) ++ new BaseSubsystemConfig) +class TLXbarUnitTestConfig extends Config(new WithTLXbarUnitTests ++ new WithTestDuration(10) ++ new BaseSubsystemConfig) diff --git a/src/main/scala/util/GeneratorUtils.scala b/src/main/scala/util/GeneratorUtils.scala index 18b1a9b7..4a151cd3 100644 --- a/src/main/scala/util/GeneratorUtils.scala +++ b/src/main/scala/util/GeneratorUtils.scala @@ -108,7 +108,7 @@ trait GeneratorApp extends App with HasGeneratorUtilities { /** Output software test Makefrags, which provide targets for integration testing. */ def generateTestSuiteMakefrags { addTestSuites - writeOutputFile(td, s"$longName.d", TestGeneration.generateMakefrag) // Coreplex-specific test suites + writeOutputFile(td, s"$longName.d", TestGeneration.generateMakefrag) // Subsystem-specific test suites } def addTestSuites { diff --git a/src/main/scala/util/package.scala b/src/main/scala/util/package.scala index 37b06da1..481ed2e2 100644 --- a/src/main/scala/util/package.scala +++ b/src/main/scala/util/package.scala @@ -43,6 +43,28 @@ package object util { def readAndHold(addr: UInt, enable: Bool): T = x.read(addr, enable) holdUnless RegNext(enable) } + implicit class StringToAugmentedString(val x: String) extends AnyVal { + /** converts from camel case to to underscores, also removing all spaces */ + def underscore: String = x.tail.foldLeft(x.headOption.map(_.toLower + "") getOrElse "") { + case (acc, c) if c.isUpper => acc + "_" + c.toLower + case (acc, c) if c == ' ' => acc + case (acc, c) => acc + c + } + + /** converts spaces or underscores to hyphens, also lowering case */ + def kebab: String = x.toLowerCase map { + case ' ' => '-' + case '_' => '-' + case c => c + } + + def named(name: Option[String]): String = { + x + name.map("_named_" + _ ).getOrElse("_with_no_name") + } + + def named(name: String): String = named(Some(name)) + } + implicit def uintToBitPat(x: UInt): BitPat = BitPat(x) implicit def wcToUInt(c: WideCounter): UInt = c.value