From 78beb3a763e5f041b38a93758eadf5f45a21298f Mon Sep 17 00:00:00 2001 From: Henry Cook Date: Thu, 16 Apr 2020 15:00:52 -0700 Subject: [PATCH 01/32] devices: BuiltInDevices.none --- src/main/scala/devices/tilelink/CanHaveBuiltInDevices.scala | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/scala/devices/tilelink/CanHaveBuiltInDevices.scala b/src/main/scala/devices/tilelink/CanHaveBuiltInDevices.scala index 016c368421..3c580f6d74 100644 --- a/src/main/scala/devices/tilelink/CanHaveBuiltInDevices.scala +++ b/src/main/scala/devices/tilelink/CanHaveBuiltInDevices.scala @@ -17,6 +17,11 @@ sealed trait BuiltInDevices { } object BuiltInDevices { + def none = new BuiltInDevices { + val errorOpt = None + val zeroOpt = None + } + def attach( params: HasBuiltInDeviceParams with HasTLBusParams, outwardNode: TLOutwardNode)(implicit p: Parameters) = new BuiltInDevices { From e7b9aa7ec4efc3260cf25b26c014950c543a382a Mon Sep 17 00:00:00 2001 From: Henry Cook Date: Mon, 9 Mar 2020 21:42:18 -0700 Subject: [PATCH 02/32] subsystem: refine Attachable trait to be based on LocationMap --- src/main/scala/subsystem/Attachable.scala | 55 ++++++++++++++++++++ src/main/scala/subsystem/BaseSubsystem.scala | 30 +---------- 2 files changed, 57 insertions(+), 28 deletions(-) create mode 100644 src/main/scala/subsystem/Attachable.scala diff --git a/src/main/scala/subsystem/Attachable.scala b/src/main/scala/subsystem/Attachable.scala new file mode 100644 index 0000000000..1ea7cef1fd --- /dev/null +++ b/src/main/scala/subsystem/Attachable.scala @@ -0,0 +1,55 @@ +// See LICENSE.SiFive for license details. + +package freechips.rocketchip.subsystem + +import scala.language.dynamics +import freechips.rocketchip.config.Parameters +import freechips.rocketchip.diplomacy.{LazyModule, LazyScope} +import freechips.rocketchip.diplomaticobjectmodel.HasLogicalTreeNode +import freechips.rocketchip.prci.ClockGroupEphemeralNode +import freechips.rocketchip.tilelink.TLBusWrapper +import freechips.rocketchip.util.{Location, LocationMap} + +/** These traits are intended to make it possible to configure to which + * buses optional devices are attached, even after a subsystem has been instantiated. + * Consider them experimental for now. + */ + +trait LazyScopeWithParameters extends LazyScope { this: LazyModule => + implicit val p: Parameters +} + +trait HasLogicalHierarchy extends LazyScopeWithParameters with HasLogicalTreeNode { this: LazyModule => } + +trait HasPRCILocations extends HasLogicalHierarchy { this: LazyModule => + implicit val asyncClockGroupsNode: ClockGroupEphemeralNode + val ibus: InterruptBusWrapper +} + +// TODO make this trait extend Dynamic itself and add the locations to anyLocationMap? +trait HasLocations extends HasPRCILocations { this: LazyModule => + val anyLocationMap = new LocationMap[Any] + def selectDynamic(name: String): Any = anyLocationMap.selectDynamic(name) + def updateDynamic(name: String)(value: Any): Unit = anyLocationMap.updateDynamic(name)(value) + + val tlBusWrapperLocationMap = new LocationMap[TLBusWrapper] + def locateTLBusWrapper(location: TLBusWrapperLocation): TLBusWrapper = locateTLBusWrapper(location.name) + def locateTLBusWrapper(name: String): TLBusWrapper = tlBusWrapperLocationMap.selectDynamic(name) +} + +trait CanInstantiateWithinContext { + def instantiate(context: HasLocations)(implicit p: Parameters): Unit +} + +trait CanConnectWithinContext { + def connect(context: HasLocations)(implicit p: Parameters): Unit +} + +/** Attachable things provide a standard interface by which other things may attach themselves to this target. + * Right now the trait is mostly for backwards compatibility, and in case it eventually becomes valuable + * to be able to define additional resources available to agents trying to attach themselves, other than + * what is being made available via LocationMaps in trait HasLocations. + */ +trait Attachable extends HasLocations { this: LazyModule => + def locateTLBusWrapper(location: TLBusWrapperLocation): TLBusWrapper +} diff --git a/src/main/scala/subsystem/BaseSubsystem.scala b/src/main/scala/subsystem/BaseSubsystem.scala index 9f54ace193..71cb9092c6 100644 --- a/src/main/scala/subsystem/BaseSubsystem.scala +++ b/src/main/scala/subsystem/BaseSubsystem.scala @@ -45,26 +45,8 @@ abstract class BareSubsystemModuleImp[+L <: BareSubsystem](_outer: L) extends La println(outer.dts) } -/** These traits are intended to make it possible to configure to which - * buses optional devices are attached, even after a subsystem has been instantiated. - * Consider them experimental for now. - */ - -trait Attachable extends LazyScope - with HasLogicalTreeNode - with HasBusLocationFunction { this: LazyModule => - implicit val p: Parameters - implicit val asyncClockGroupsNode: ClockGroupEphemeralNode - val ibus: InterruptBusWrapper -} - -trait HasBusLocationFunction { - type BusLocationFunction = PartialFunction[TLBusWrapperLocation, TLBusWrapper] - def locateTLBusWrapper: BusLocationFunction -} - -/** This class the cases matched in baseBusLocateFunc below. - * Extend/override them to offer novel attachment locations. +/** This trait contains the cases matched in baseBusAttachmentFunc below. + * Extend/override them to offer novel attachment locations in subclasses of BaseSubsystem. */ class TLBusWrapperLocation(name: String) extends Location[TLBusWrapper](name) case object SBUS extends TLBusWrapperLocation("subsystem_sbus") @@ -95,14 +77,6 @@ abstract class BaseSubsystem(implicit p: Parameters) extends BareSubsystem val mbus = LazyModule(new MemoryBus(p(MemoryBusKey))) val cbus = LazyModule(new PeripheryBus(p(ControlBusKey), "subsystem_cbus")) - def locateTLBusWrapper: BusLocationFunction = { - case SBUS => sbus - case PBUS => pbus - case FBUS => fbus - case MBUS => mbus - case CBUS => cbus - } - implicit val asyncClockGroupsNode = p(AsyncClockGroupsKey) val async_clock_groups = p(SubsystemDriveAsyncClockGroupsKey) From c1f6fbc3ebaf0196c52c137e7d51ec9fb6bd9a67 Mon Sep 17 00:00:00 2001 From: Henry Cook Date: Mon, 9 Mar 2020 22:11:31 -0700 Subject: [PATCH 03/32] tilelink: enhance TLBusWrapper with connectivity and topology case classes --- src/main/scala/tilelink/BusWrapper.scala | 56 ++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/src/main/scala/tilelink/BusWrapper.scala b/src/main/scala/tilelink/BusWrapper.scala index f2cf771c5b..bcf67869d6 100644 --- a/src/main/scala/tilelink/BusWrapper.scala +++ b/src/main/scala/tilelink/BusWrapper.scala @@ -6,6 +6,7 @@ import Chisel._ import freechips.rocketchip.config.Parameters import freechips.rocketchip.diplomacy._ import freechips.rocketchip.prci._ +import freechips.rocketchip.subsystem._ // TODO this class should be moved to package subsystem import freechips.rocketchip.util._ /** Specifies widths of various attachement points in the SoC */ @@ -86,6 +87,61 @@ abstract class TLBusWrapper(params: HasTLBusParams, val busName: String)(implici } } +trait TLBusWrapperInstantiationLike { + def instantiate(context: HasLocations, loc: Location[TLBusWrapper])(implicit p: Parameters): TLBusWrapper +} + +trait TLBusWrapperConnectionLike { + val xType: ClockCrossingType + def inject(implicit p: Parameters): TLNode = TLNameNode("temp") + def connect(context: HasLocations, from: Location[TLBusWrapper], to: Location[TLBusWrapper])(implicit p: Parameters): Unit +} + +case class TLBusWrapperCrossToConnection + (xType: ClockCrossingType) + (nodeView: (TLBusWrapper, Parameters) => TLInwardNode = { case(w, p) => w.crossInHelper(xType)(p) }, + inject: Parameters => TLNode = { _ => TLNameNode("temp") }) + extends TLBusWrapperConnectionLike +{ + def connect(context: HasLocations, from: Location[TLBusWrapper], to: Location[TLBusWrapper])(implicit p: Parameters): Unit = { + val masterTLBus = context.locateTLBusWrapper(from) + val slaveTLBus = context.locateTLBusWrapper(to) + slaveTLBus.clockGroupNode := asyncMux(xType, context.asyncClockGroupsNode, masterTLBus.clockGroupNode) + masterTLBus.coupleTo(s"bus_named_${masterTLBus.busName}") { + nodeView(slaveTLBus,p) :*= TLWidthWidget(masterTLBus.beatBytes) :*= inject(p) :*= _ + // TODO does BankBinder injection need to be (_ :=* bb :*= _) + } + } +} + +case class TLBusWrapperCrossFromConnection + (xType: ClockCrossingType) + (nodeView: (TLBusWrapper, Parameters) => TLOutwardNode = { case(w, p) => w.crossOutHelper(xType)(p) }, + inject: Parameters => TLNode = { _ => TLNameNode("temp") }) + extends TLBusWrapperConnectionLike +{ + def connect(context: HasLocations, from: Location[TLBusWrapper], to: Location[TLBusWrapper])(implicit p: Parameters): Unit = FlipRendering { implicit p => + val masterTLBus = context.locateTLBusWrapper(to) + val slaveTLBus = context.locateTLBusWrapper(from) + masterTLBus.clockGroupNode := asyncMux(xType, context.asyncClockGroupsNode, slaveTLBus.clockGroupNode) + slaveTLBus.coupleFrom(s"bus_named_${masterTLBus.busName}") { + _ :=* inject(p) :=* TLWidthWidget(masterTLBus.beatBytes) :=* nodeView(masterTLBus, p) + } + } +} + +class TLBusWrapperTopology( + val instantiations: Seq[(Location[TLBusWrapper], TLBusWrapperInstantiationLike)], + val connections: Seq[(Location[TLBusWrapper], Location[TLBusWrapper], TLBusWrapperConnectionLike)] +) extends CanInstantiateWithinContext with CanConnectWithinContext { + def instantiate(context: HasLocations)(implicit p: Parameters): Unit = { + instantiations.foreach { case (loc, params) => params.instantiate(context, loc) } + } + def connect(context: HasLocations)(implicit p: Parameters): Unit = { + connections.foreach { case (from, to, params) => params.connect(context, from, to) } + } +} + trait CanAttachTLSlaves extends HasTLBusParams { this: TLBusWrapper => def toSlave[D,U,E,B <: Data] (name: Option[String] = None, buffer: BufferParams = BufferParams.none) From b9f15852c61f3e197176d8b2a7fff0609e9c039e Mon Sep 17 00:00:00 2001 From: Henry Cook Date: Mon, 9 Mar 2020 22:13:16 -0700 Subject: [PATCH 04/32] subsystem: XBusParams have instantiate methods for their particular TLBusWrapper subclass --- src/main/scala/subsystem/FrontBus.scala | 16 +++++++-- src/main/scala/subsystem/MemoryBus.scala | 38 ++++++--------------- src/main/scala/subsystem/PeripheryBus.scala | 8 +++++ src/main/scala/subsystem/SystemBus.scala | 15 ++++++-- 4 files changed, 43 insertions(+), 34 deletions(-) diff --git a/src/main/scala/subsystem/FrontBus.scala b/src/main/scala/subsystem/FrontBus.scala index 432ca419c9..537c4b2ec0 100644 --- a/src/main/scala/subsystem/FrontBus.scala +++ b/src/main/scala/subsystem/FrontBus.scala @@ -6,6 +6,7 @@ import freechips.rocketchip.config.{Parameters} import freechips.rocketchip.devices.tilelink._ import freechips.rocketchip.diplomacy._ import freechips.rocketchip.tilelink._ +import freechips.rocketchip.util.{Location} case class FrontBusParams( beatBytes: Int, @@ -13,10 +14,19 @@ case class FrontBusParams( dtsFrequency: Option[BigInt] = None, zeroDevice: Option[AddressSet] = None, errorDevice: Option[DevNullParams] = None) - extends HasTLBusParams with HasBuiltInDeviceParams + extends HasTLBusParams + with HasBuiltInDeviceParams + with TLBusWrapperInstantiationLike +{ + def instantiate(context: HasLocations, loc: Location[TLBusWrapper])(implicit p: Parameters): FrontBus = { + val fbus = LazyModule(new FrontBus(this, loc.name)) + context.tlBusWrapperLocationMap.updateDynamic(loc.name)(fbus) + fbus + } +} -class FrontBus(params: FrontBusParams)(implicit p: Parameters) - extends TLBusWrapper(params, "front_bus") +class FrontBus(params: FrontBusParams, name: String = "front_bus")(implicit p: Parameters) + extends TLBusWrapper(params, name) with CanHaveBuiltInDevices with CanAttachTLMasters with HasTLXbarPhy { diff --git a/src/main/scala/subsystem/MemoryBus.scala b/src/main/scala/subsystem/MemoryBus.scala index 6cbe2d8526..98a3746b4b 100644 --- a/src/main/scala/subsystem/MemoryBus.scala +++ b/src/main/scala/subsystem/MemoryBus.scala @@ -10,32 +10,6 @@ import freechips.rocketchip.interrupts._ 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( - nBanks: Int = 1, - coherenceManager: BaseSubsystem => (TLInwardNode, TLOutwardNode, Option[IntOutwardNode]) = { subsystem => - implicit val p = subsystem.p - val BroadcastParams(nTrackers, bufferless) = p(BroadcastKey) - val bh = LazyModule(new TLBroadcast(subsystem.sbus.blockBytes, nTrackers, bufferless)) - val ww = LazyModule(new TLWidthWidget(subsystem.sbus.beatBytes)) - val ss = TLSourceShrinker(nTrackers) - ww.node :*= bh.node - ss :*= ww.node - (bh.node, ss, None) - }) { - require (isPow2(nBanks) || nBanks == 0) -} - /** Parameterization of the memory-side bus created for each memory channel */ case class MemoryBusParams( beatBytes: Int, @@ -47,10 +21,18 @@ case class MemoryBusParams( extends HasTLBusParams with HasBuiltInDeviceParams with HasRegionReplicatorParams + with TLBusWrapperInstantiationLike +{ + def instantiate(context: HasLocations, loc: Location[TLBusWrapper])(implicit p: Parameters): MemoryBus = { + val mbus = LazyModule(new MemoryBus(this, loc.name)) + context.tlBusWrapperLocationMap.updateDynamic(loc.name)(mbus) + mbus + } +} /** 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) +class MemoryBus(params: MemoryBusParams, name: String = "memory_bus")(implicit p: Parameters) + extends TLBusWrapper(params, name)(p) with CanHaveBuiltInDevices with CanAttachTLSlaves { diff --git a/src/main/scala/subsystem/PeripheryBus.scala b/src/main/scala/subsystem/PeripheryBus.scala index 1a3c4ce6f7..144b51721c 100644 --- a/src/main/scala/subsystem/PeripheryBus.scala +++ b/src/main/scala/subsystem/PeripheryBus.scala @@ -26,6 +26,14 @@ case class PeripheryBusParams( extends HasTLBusParams with HasBuiltInDeviceParams with HasRegionReplicatorParams + with TLBusWrapperInstantiationLike +{ + def instantiate(context: HasLocations, loc: Location[TLBusWrapper])(implicit p: Parameters): PeripheryBus = { + val pbus = LazyModule(new PeripheryBus(this, loc.name)) + context.tlBusWrapperLocationMap.updateDynamic(loc.name)(pbus) + pbus + } +} class PeripheryBus(params: PeripheryBusParams, name: String)(implicit p: Parameters) extends TLBusWrapper(params, name) diff --git a/src/main/scala/subsystem/SystemBus.scala b/src/main/scala/subsystem/SystemBus.scala index 4025d398ff..25f8fbf5f4 100644 --- a/src/main/scala/subsystem/SystemBus.scala +++ b/src/main/scala/subsystem/SystemBus.scala @@ -16,10 +16,19 @@ case class SystemBusParams( dtsFrequency: Option[BigInt] = None, zeroDevice: Option[AddressSet] = None, errorDevice: Option[DevNullParams] = None) - extends HasTLBusParams with HasBuiltInDeviceParams + extends HasTLBusParams + with HasBuiltInDeviceParams + with TLBusWrapperInstantiationLike +{ + def instantiate(context: HasLocations, loc: Location[TLBusWrapper])(implicit p: Parameters): SystemBus = { + val sbus = LazyModule(new SystemBus(this, loc.name)) + context.tlBusWrapperLocationMap.updateDynamic(loc.name)(sbus) + sbus + } +} -class SystemBus(params: SystemBusParams)(implicit p: Parameters) - extends TLBusWrapper(params, "system_bus") +class SystemBus(params: SystemBusParams, name: String = "system_bus")(implicit p: Parameters) + extends TLBusWrapper(params, name) with CanHaveBuiltInDevices with CanAttachTLSlaves with CanAttachTLMasters From 6c000fde84767925c90147f088f9e5ec1f1859e8 Mon Sep 17 00:00:00 2001 From: Henry Cook Date: Mon, 9 Mar 2020 22:22:52 -0700 Subject: [PATCH 05/32] subsystem: refactor bus topology to be configurable --- .../groundtest/GroundTestSubsystem.scala | 1 - src/main/scala/subsystem/Attachable.scala | 4 +- src/main/scala/subsystem/BankedL2Params.scala | 63 ++++++++++++++++ src/main/scala/subsystem/BaseSubsystem.scala | 49 +++++-------- src/main/scala/subsystem/BusTopology.scala | 71 +++++++++++++------ src/main/scala/subsystem/Configs.scala | 9 +++ .../scala/system/ExampleRocketSystem.scala | 1 - 7 files changed, 144 insertions(+), 54 deletions(-) create mode 100644 src/main/scala/subsystem/BankedL2Params.scala diff --git a/src/main/scala/groundtest/GroundTestSubsystem.scala b/src/main/scala/groundtest/GroundTestSubsystem.scala index eeba0463c6..f5d3881eee 100644 --- a/src/main/scala/groundtest/GroundTestSubsystem.scala +++ b/src/main/scala/groundtest/GroundTestSubsystem.scala @@ -16,7 +16,6 @@ import scala.math.max case object TileId extends Field[Int] class GroundTestSubsystem(implicit p: Parameters) extends BaseSubsystem - with HasHierarchicalBusTopology with CanHaveMasterAXI4MemPort { val tileParams = p(GroundTestTilesKey) val tiles = tileParams.zipWithIndex.map { case(c, i) => LazyModule(c.build(i, p)) } diff --git a/src/main/scala/subsystem/Attachable.scala b/src/main/scala/subsystem/Attachable.scala index 1ea7cef1fd..0ef3e6546d 100644 --- a/src/main/scala/subsystem/Attachable.scala +++ b/src/main/scala/subsystem/Attachable.scala @@ -33,7 +33,7 @@ trait HasLocations extends HasPRCILocations { this: LazyModule => def updateDynamic(name: String)(value: Any): Unit = anyLocationMap.updateDynamic(name)(value) val tlBusWrapperLocationMap = new LocationMap[TLBusWrapper] - def locateTLBusWrapper(location: TLBusWrapperLocation): TLBusWrapper = locateTLBusWrapper(location.name) + def locateTLBusWrapper(location: Location[TLBusWrapper]): TLBusWrapper = locateTLBusWrapper(location.name) def locateTLBusWrapper(name: String): TLBusWrapper = tlBusWrapperLocationMap.selectDynamic(name) } @@ -51,5 +51,5 @@ trait CanConnectWithinContext { * what is being made available via LocationMaps in trait HasLocations. */ trait Attachable extends HasLocations { this: LazyModule => - def locateTLBusWrapper(location: TLBusWrapperLocation): TLBusWrapper + def locateTLBusWrapper(location: TLBusWrapperLocation): TLBusWrapper = locateTLBusWrapper(location.name) } diff --git a/src/main/scala/subsystem/BankedL2Params.scala b/src/main/scala/subsystem/BankedL2Params.scala new file mode 100644 index 0000000000..70ba35a560 --- /dev/null +++ b/src/main/scala/subsystem/BankedL2Params.scala @@ -0,0 +1,63 @@ +// See LICENSE.SiFive for license details. + +package freechips.rocketchip.subsystem + +import chisel3.util.isPow2 +import freechips.rocketchip.config._ +import freechips.rocketchip.diplomacy._ +import freechips.rocketchip.interrupts._ +import freechips.rocketchip.tilelink._ +import freechips.rocketchip.util._ + +// TODO: applies to all caches, for now +case object CacheBlockBytes extends Field[Int](64) + +case object BroadcastKey extends Field(BroadcastParams()) +case object BankedL2Key extends Field(BankedL2Params()) + +/** L2 Broadcast Hub configuration */ +case class BroadcastParams( + nTrackers: Int = 4, + bufferless: Boolean = false) + +/** L2 memory subsystem configuration */ +case class BankedL2Params( + nBanks: Int = 1, + coherenceManager: CoherenceManagerWrapper.CoherenceManagerInstantiationFn = { subsystem => + implicit val p = subsystem.p + val BroadcastParams(nTrackers, bufferless) = p(BroadcastKey) + val bh = LazyModule(new TLBroadcast(p(CacheBlockBytes), nTrackers, bufferless)) + val ss = TLSourceShrinker(nTrackers) + ss :*= bh.node + (bh.node, ss, None) + } +) { + require (isPow2(nBanks) || nBanks == 0) +} + + +case class CoherenceManagerWrapperParams(blockBytes: Int, beatBytes: Int, name: String) + (val coherenceManager: CoherenceManagerWrapper.CoherenceManagerInstantiationFn) + extends HasTLBusParams + with TLBusWrapperInstantiationLike +{ + val dtsFrequency = None + def instantiate(context: HasLocations, loc: Location[TLBusWrapper])(implicit p: Parameters): CoherenceManagerWrapper = { + val cmWrapper = LazyModule(new CoherenceManagerWrapper(this, context)) + context.updateDynamic(loc.name+"Halt")(cmWrapper.halt) + context.tlBusWrapperLocationMap.updateDynamic(loc.name)(cmWrapper) + cmWrapper + } +} + +object CoherenceManagerWrapper { + type CoherenceManagerInstantiationFn = HasLocations => (TLInwardNode, TLOutwardNode, Option[IntOutwardNode]) +} + +class CoherenceManagerWrapper(params: CoherenceManagerWrapperParams, context: HasLocations)(implicit p: Parameters) extends TLBusWrapper(params, params.name) { + val (temp, outwardNode, halt) = params.coherenceManager(context) + // TODO could remove temp if we could get access to .edges from InwardNodeHandle + val viewNode = TLIdentityNode() + val inwardNode = temp :*= viewNode + def busView: TLEdge = viewNode.edges.out.head +} diff --git a/src/main/scala/subsystem/BaseSubsystem.scala b/src/main/scala/subsystem/BaseSubsystem.scala index 71cb9092c6..8c8972fa6f 100644 --- a/src/main/scala/subsystem/BaseSubsystem.scala +++ b/src/main/scala/subsystem/BaseSubsystem.scala @@ -7,22 +7,14 @@ import freechips.rocketchip.config.{Field, Parameters} import freechips.rocketchip.diplomacy._ import freechips.rocketchip.diplomaticobjectmodel.HasLogicalTreeNode import freechips.rocketchip.diplomaticobjectmodel.logicaltree._ -import freechips.rocketchip.tilelink.TLBusWrapper import freechips.rocketchip.prci._ import freechips.rocketchip.util._ - -case object SystemBusKey extends Field[SystemBusParams] -case object FrontBusKey extends Field[FrontBusParams] -case object PeripheryBusKey extends Field[PeripheryBusParams] -case object ControlBusKey extends Field[PeripheryBusParams] -case object MemoryBusKey extends Field[MemoryBusParams] -case object BankedL2Key extends Field(BankedL2Params()) - -case object BuildSystemBus extends Field[Parameters => SystemBus](p => new SystemBus(p(SystemBusKey))(p)) - case object SubsystemDriveAsyncClockGroupsKey extends Field[Option[ClockGroupDriverParameters]](Some(ClockGroupDriverParameters(1))) case object AsyncClockGroupsKey extends Field[ClockGroupEphemeralNode](ClockGroupEphemeralNode()(ValName("async_clock_groups"))) +case class TLNetworkTopologyLocated(where: String) extends Field[Seq[CanInstantiateWithinContext with CanConnectWithinContext]] + +case class HierarchicalLocation(override val name: String) extends Location[LazyScope](name) class HierarchicalLocation(override val name: String) extends Location[LazyScope](name) case object InTile extends HierarchicalLocation("InTile") @@ -45,16 +37,6 @@ abstract class BareSubsystemModuleImp[+L <: BareSubsystem](_outer: L) extends La println(outer.dts) } -/** This trait contains the cases matched in baseBusAttachmentFunc below. - * Extend/override them to offer novel attachment locations in subclasses of BaseSubsystem. - */ -class TLBusWrapperLocation(name: String) extends Location[TLBusWrapper](name) -case object SBUS extends TLBusWrapperLocation("subsystem_sbus") -case object PBUS extends TLBusWrapperLocation("subsystem_pbus") -case object FBUS extends TLBusWrapperLocation("subsystem_fbus") -case object MBUS extends TLBusWrapperLocation("subsystem_mbus") -case object CBUS extends TLBusWrapperLocation("subsystem_cbus") - trait SubsystemResetScheme case object ResetSynchronous extends SubsystemResetScheme case object ResetAsynchronous extends SubsystemResetScheme @@ -68,23 +50,30 @@ 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(p(BuildSystemBus)(p)) - val pbus = LazyModule(new PeripheryBus(p(PeripheryBusKey), "subsystem_pbus")) - val fbus = LazyModule(new FrontBus(p(FrontBusKey))) - val mbus = LazyModule(new MemoryBus(p(MemoryBusKey))) - val cbus = LazyModule(new PeripheryBus(p(ControlBusKey), "subsystem_cbus")) - implicit val asyncClockGroupsNode = p(AsyncClockGroupsKey) val async_clock_groups = p(SubsystemDriveAsyncClockGroupsKey) .map(_.drive(asyncClockGroupsNode)) .getOrElse(InModuleBody { HeterogeneousBag[ClockGroupBundle](Nil) }) + val location = HierarchicalLocation("InSubsystem") + p(TLNetworkTopologyLocated(location.name)).foreach(_.instantiate(this)) + p(TLNetworkTopologyLocated(location.name)).foreach(_.connect(this)) + + // TODO where should this happen; must there always be an "sbus"? + locateTLBusWrapper(SBUS).clockGroupNode := asyncClockGroupsNode + + // TODO deprecate these public members to see where users are manually hardcoding a particular bus + // TODO additionally, merge all TLBusWrapper subtypes back into a single base class, at least in terms of coupling methods + val sbus = tlBusWrapperLocationMap.select(SBUS).asInstanceOf[SystemBus] + val pbus = tlBusWrapperLocationMap.lift(PBUS).getOrElse(sbus).asInstanceOf[PeripheryBus] + val fbus = tlBusWrapperLocationMap.lift(FBUS).getOrElse(sbus).asInstanceOf[FrontBus] + val mbus = tlBusWrapperLocationMap.lift(MBUS).getOrElse(sbus).asInstanceOf[MemoryBus] + val cbus = tlBusWrapperLocationMap.lift(CBUS).getOrElse(sbus).asInstanceOf[PeripheryBus] + // Collect information for use in DTS - lazy val topManagers = sbus.unifyManagers + lazy val topManagers = locateTLBusWrapper(SBUS).unifyManagers ResourceBinding { val managers = topManagers val max = managers.flatMap(_.address).map(_.max).max diff --git a/src/main/scala/subsystem/BusTopology.scala b/src/main/scala/subsystem/BusTopology.scala index 4b10b3a486..f952199927 100644 --- a/src/main/scala/subsystem/BusTopology.scala +++ b/src/main/scala/subsystem/BusTopology.scala @@ -2,29 +2,60 @@ package freechips.rocketchip.subsystem +import freechips.rocketchip.config.{Field, Parameters} import freechips.rocketchip.diplomacy._ import freechips.rocketchip.tilelink._ +import freechips.rocketchip.util.Location -trait HasHierarchicalBusTopology { this: BaseSubsystem => - sbus.clockGroupNode := asyncClockGroupsNode +// These fields control parameters of the five traditional tilelink bus wrappers +case object SystemBusKey extends Field[SystemBusParams] +case object FrontBusKey extends Field[FrontBusParams] +case object PeripheryBusKey extends Field[PeripheryBusParams] +case object ControlBusKey extends Field[PeripheryBusParams] +case object MemoryBusKey extends Field[MemoryBusParams] - // The sbus masters the cbus; here we convert TL-UH -> TL-UL - sbus.crossToBus(cbus, NoCrossing) +// These object serve as labels for specified attachement targets +// from amongst the five traditional tilelink bus wrappers +class TLBusWrapperLocation(name: String) extends Location[TLBusWrapper](name) +case object SBUS extends TLBusWrapperLocation("subsystem_sbus") +case object PBUS extends TLBusWrapperLocation("subsystem_pbus") +case object FBUS extends TLBusWrapperLocation("subsystem_fbus") +case object MBUS extends TLBusWrapperLocation("subsystem_mbus") +case object CBUS extends TLBusWrapperLocation("subsystem_cbus") +case object L2 extends TLBusWrapperLocation("subsystem_l2") - // The cbus masters the pbus; which might be clocked slower - cbus.crossToBus(pbus, SynchronousCrossing()) +// This case class parameterizes the subsystem in terms of the optional clock-crossings +// which are insertable between some of the five traditional tilelink bus wrappers +case class SubsystemCrossingParams( + sbusToCbusXType: ClockCrossingType = NoCrossing, + cbusToPbusXType: ClockCrossingType = SynchronousCrossing(), + fbusToSbusXType: ClockCrossingType = SynchronousCrossing() +) - // The fbus masters the sbus; both are TL-UH or TL-C - FlipRendering { implicit p => - sbus.crossFromBus(fbus, SynchronousCrossing()) - } - - // The sbus masters the mbus; here we convert TL-C -> TL-UH - private val BankedL2Params(nBanks, coherenceManager) = p(BankedL2Key) - private val (in, out, halt) = coherenceManager(this) - if (nBanks != 0) { - sbus.coupleTo("coherence_manager") { in :*= _ } - mbus.coupleFrom("coherence_manager") { _ :=* BankBinder(mbus.blockBytes * (nBanks-1)) :*= out } - } - mbus.clockGroupNode := sbus.clockGroupNode -} +// This case class provides a backwards-compatibility parameterization of a subsystem +// bus topology that contains thfive traditional tilelink bus wrappers +case class HierarchicalBusTopologyParams( + sbus: SystemBusParams, + pbus: PeripheryBusParams, + fbus: FrontBusParams, + mbus: MemoryBusParams, + cbus: PeripheryBusParams, + l2: BankedL2Params, + xTypes: SubsystemCrossingParams +) extends TLBusWrapperTopology( + instantiations = List( + (SBUS, sbus), + (PBUS, pbus), + (FBUS, fbus), + (CBUS, cbus), + (MBUS, mbus), + (L2, CoherenceManagerWrapperParams(sbus.blockBytes, sbus.beatBytes, L2.name)(l2.coherenceManager))), + connections = List( + (SBUS, CBUS, TLBusWrapperCrossToConnection (xTypes.sbusToCbusXType)()), + (CBUS, PBUS, TLBusWrapperCrossToConnection (xTypes.cbusToPbusXType)()), + (SBUS, FBUS, TLBusWrapperCrossFromConnection(xTypes.fbusToSbusXType)()), + (SBUS, L2, TLBusWrapperCrossToConnection (NoCrossing)()), + (L2, MBUS, TLBusWrapperCrossToConnection (NoCrossing) + (inject = { implicit p => BankBinder(p(CacheBlockBytes) * (l2.nBanks-1)) })) + ) +) diff --git a/src/main/scala/subsystem/Configs.scala b/src/main/scala/subsystem/Configs.scala index 170282a006..44c999aeaa 100644 --- a/src/main/scala/subsystem/Configs.scala +++ b/src/main/scala/subsystem/Configs.scala @@ -43,6 +43,15 @@ class BaseSubsystemConfig extends Config ((site, here, up) => { case DebugModuleKey => Some(DefaultDebugModuleParams(site(XLen))) case CLINTKey => Some(CLINTParams()) case PLICKey => Some(PLICParams()) + case TLNetworkTopologyLocated("InSubsystem") => List( + HierarchicalBusTopologyParams( + sbus = site(SystemBusKey), + pbus = site(PeripheryBusKey), + fbus = site(FrontBusKey), + mbus = site(MemoryBusKey), + cbus = site(ControlBusKey), + l2 = site(BankedL2Key), + xTypes = SubsystemCrossingParams())) }) /* Composable partial function Configs to set individual parameters */ diff --git a/src/main/scala/system/ExampleRocketSystem.scala b/src/main/scala/system/ExampleRocketSystem.scala index fc6c8bacb9..9e06f95e45 100644 --- a/src/main/scala/system/ExampleRocketSystem.scala +++ b/src/main/scala/system/ExampleRocketSystem.scala @@ -12,7 +12,6 @@ import freechips.rocketchip.util.DontTouch /** Example Top with periphery devices and ports, and a Rocket subsystem */ class ExampleRocketSystem(implicit p: Parameters) extends RocketSubsystem - with HasHierarchicalBusTopology with HasAsyncExtInterrupts with CanHaveMasterAXI4MemPort with CanHaveMasterAXI4MMIOPort From 9b56e1e87692c93c57e1b61ead76960994a76ab1 Mon Sep 17 00:00:00 2001 From: Henry Cook Date: Mon, 9 Mar 2020 23:28:35 -0700 Subject: [PATCH 06/32] subsystem: WW in WithIncoherentTiles alteration is now redundant --- src/main/scala/subsystem/Configs.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/scala/subsystem/Configs.scala b/src/main/scala/subsystem/Configs.scala index 44c999aeaa..2fefede243 100644 --- a/src/main/scala/subsystem/Configs.scala +++ b/src/main/scala/subsystem/Configs.scala @@ -203,8 +203,8 @@ class WithIncoherentTiles extends Config((site, here, up) => { r.copy(master = r.master.copy(cork = Some(true))) } case BankedL2Key => up(BankedL2Key, site).copy(coherenceManager = { subsystem => - val ww = LazyModule(new TLWidthWidget(subsystem.sbus.beatBytes)(subsystem.p)) - (ww.node, ww.node, None) + val node = TLNameNode("no_coherence_manager") + (node, node, None) }) }) From 08f40e616d99d02282cafd1571017429e11e4f2c Mon Sep 17 00:00:00 2001 From: Henry Cook Date: Mon, 9 Mar 2020 23:29:12 -0700 Subject: [PATCH 07/32] subsystem: continue special casing l2.nBanks == 0, for now --- src/main/scala/subsystem/BusTopology.scala | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/main/scala/subsystem/BusTopology.scala b/src/main/scala/subsystem/BusTopology.scala index f952199927..527cc733cb 100644 --- a/src/main/scala/subsystem/BusTopology.scala +++ b/src/main/scala/subsystem/BusTopology.scala @@ -53,9 +53,10 @@ case class HierarchicalBusTopologyParams( connections = List( (SBUS, CBUS, TLBusWrapperCrossToConnection (xTypes.sbusToCbusXType)()), (CBUS, PBUS, TLBusWrapperCrossToConnection (xTypes.cbusToPbusXType)()), - (SBUS, FBUS, TLBusWrapperCrossFromConnection(xTypes.fbusToSbusXType)()), - (SBUS, L2, TLBusWrapperCrossToConnection (NoCrossing)()), - (L2, MBUS, TLBusWrapperCrossToConnection (NoCrossing) - (inject = { implicit p => BankBinder(p(CacheBlockBytes) * (l2.nBanks-1)) })) - ) + (SBUS, FBUS, TLBusWrapperCrossFromConnection(xTypes.fbusToSbusXType)())) ++ + (if (l2.nBanks == 0) Nil else List( // TODO this should be two topologies once val mbus in subsystem is truly optional + (SBUS, L2, TLBusWrapperCrossToConnection (NoCrossing)()), + (L2, MBUS, TLBusWrapperCrossToConnection (NoCrossing) + (inject = { implicit p => BankBinder(p(CacheBlockBytes) * (l2.nBanks-1)) })) + )) ) From 37a28f6a702e2d458593b1fbfc64f084980b494b Mon Sep 17 00:00:00 2001 From: Henry Cook Date: Tue, 10 Mar 2020 18:41:12 -0700 Subject: [PATCH 08/32] subsystem: improve bus topology commentary --- src/main/scala/subsystem/BusTopology.scala | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/main/scala/subsystem/BusTopology.scala b/src/main/scala/subsystem/BusTopology.scala index 527cc733cb..13e00491e3 100644 --- a/src/main/scala/subsystem/BusTopology.scala +++ b/src/main/scala/subsystem/BusTopology.scala @@ -7,15 +7,19 @@ import freechips.rocketchip.diplomacy._ import freechips.rocketchip.tilelink._ import freechips.rocketchip.util.Location -// These fields control parameters of the five traditional tilelink bus wrappers +// These fields control parameters of the five traditional tilelink bus wrappers. +// They continue to exist for backwards compatiblity reasons but could eventually be retired. case object SystemBusKey extends Field[SystemBusParams] case object FrontBusKey extends Field[FrontBusParams] case object PeripheryBusKey extends Field[PeripheryBusParams] case object ControlBusKey extends Field[PeripheryBusParams] case object MemoryBusKey extends Field[MemoryBusParams] -// These object serve as labels for specified attachement targets -// from amongst the five traditional tilelink bus wrappers +// These objects serve as labels for specified attachment locations +// from amongst the five traditional tilelink bus wrappers. +// While they represent some tradtionally popular locations to attach devices, +// there is no guarantee that they will exist in subsystems with +// dynamically-configured topologies. class TLBusWrapperLocation(name: String) extends Location[TLBusWrapper](name) case object SBUS extends TLBusWrapperLocation("subsystem_sbus") case object PBUS extends TLBusWrapperLocation("subsystem_pbus") @@ -25,7 +29,8 @@ case object CBUS extends TLBusWrapperLocation("subsystem_cbus") case object L2 extends TLBusWrapperLocation("subsystem_l2") // This case class parameterizes the subsystem in terms of the optional clock-crossings -// which are insertable between some of the five traditional tilelink bus wrappers +// which are insertable between some of the five traditional tilelink bus wrappers. +// They continue to exist for backwards compatiblity reasons but could eventually be retired. case class SubsystemCrossingParams( sbusToCbusXType: ClockCrossingType = NoCrossing, cbusToPbusXType: ClockCrossingType = SynchronousCrossing(), @@ -33,7 +38,9 @@ case class SubsystemCrossingParams( ) // This case class provides a backwards-compatibility parameterization of a subsystem -// bus topology that contains thfive traditional tilelink bus wrappers +// bus topology that contains the five traditional tilelink bus wrappers. +// Users desiring a different topology are free to define a similar subclass, +// or just populate an instance of TLBusWrapperTopology via some other mechanism. case class HierarchicalBusTopologyParams( sbus: SystemBusParams, pbus: PeripheryBusParams, From 21ba4a5537b90e25de70d05fca4e323f212c6722 Mon Sep 17 00:00:00 2001 From: Henry Cook Date: Tue, 10 Mar 2020 18:47:08 -0700 Subject: [PATCH 09/32] subsystem: provide topology accessor and improve commentary --- src/main/scala/subsystem/BaseSubsystem.scala | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/scala/subsystem/BaseSubsystem.scala b/src/main/scala/subsystem/BaseSubsystem.scala index 8c8972fa6f..4d99b2517f 100644 --- a/src/main/scala/subsystem/BaseSubsystem.scala +++ b/src/main/scala/subsystem/BaseSubsystem.scala @@ -50,6 +50,7 @@ abstract class BaseSubsystem(implicit p: Parameters) extends BareSubsystem override val module: BaseSubsystemModuleImp[BaseSubsystem] + // Concrete attachment points for PRCI-related signals. val ibus = new InterruptBusWrapper() implicit val asyncClockGroupsNode = p(AsyncClockGroupsKey) val async_clock_groups = @@ -57,9 +58,12 @@ abstract class BaseSubsystem(implicit p: Parameters) extends BareSubsystem .map(_.drive(asyncClockGroupsNode)) .getOrElse(InModuleBody { HeterogeneousBag[ClockGroupBundle](Nil) }) + // Find the topology configuration for the TL buses located in this subsystem. + // Calling these functions populates tlBusWrapperLocationMap and connects the locations to each other. val location = HierarchicalLocation("InSubsystem") - p(TLNetworkTopologyLocated(location.name)).foreach(_.instantiate(this)) - p(TLNetworkTopologyLocated(location.name)).foreach(_.connect(this)) + val topology = p(TLNetworkTopologyLocated(location.name)) + topology.foreach(_.instantiate(this)) + topology.foreach(_.connect(this)) // TODO where should this happen; must there always be an "sbus"? locateTLBusWrapper(SBUS).clockGroupNode := asyncClockGroupsNode From 97f45549ea3164680b0ad5062a7759d9f83b969a Mon Sep 17 00:00:00 2001 From: Henry Cook Date: Tue, 10 Mar 2020 19:19:17 -0700 Subject: [PATCH 10/32] subsystem: TLBusWrapper base class has all special coupling methods --- src/main/scala/subsystem/FrontBus.scala | 2 -- src/main/scala/subsystem/MemoryBus.scala | 12 ++----- src/main/scala/subsystem/PeripheryBus.scala | 12 +------ src/main/scala/subsystem/SystemBus.scala | 11 ------ src/main/scala/tilelink/BusWrapper.scala | 38 +++++++++++++++++++-- 5 files changed, 38 insertions(+), 37 deletions(-) diff --git a/src/main/scala/subsystem/FrontBus.scala b/src/main/scala/subsystem/FrontBus.scala index 537c4b2ec0..7d0f39b57a 100644 --- a/src/main/scala/subsystem/FrontBus.scala +++ b/src/main/scala/subsystem/FrontBus.scala @@ -27,8 +27,6 @@ case class FrontBusParams( class FrontBus(params: FrontBusParams, name: String = "front_bus")(implicit p: Parameters) extends TLBusWrapper(params, name) - with CanHaveBuiltInDevices - with CanAttachTLMasters with HasTLXbarPhy { val builtInDevices: BuiltInDevices = BuiltInDevices.attach(params, outwardNode) } diff --git a/src/main/scala/subsystem/MemoryBus.scala b/src/main/scala/subsystem/MemoryBus.scala index 98a3746b4b..701ca679bf 100644 --- a/src/main/scala/subsystem/MemoryBus.scala +++ b/src/main/scala/subsystem/MemoryBus.scala @@ -33,20 +33,12 @@ case class MemoryBusParams( /** Wrapper for creating TL nodes from a bus connected to the back of each mem channel */ class MemoryBus(params: MemoryBusParams, name: String = "memory_bus")(implicit p: Parameters) extends TLBusWrapper(params, name)(p) - with CanHaveBuiltInDevices - with CanAttachTLSlaves { - +{ private val xbar = LazyModule(new TLXbar).suggestName(busName + "_xbar") def inwardNode: TLInwardNode = if (params.replicatorMask == 0) xbar.node else { xbar.node :=* RegionReplicator(params.replicatorMask) } def outwardNode: TLOutwardNode = ProbePicker() :*= xbar.node def busView: TLEdge = xbar.node.edges.in.head - val builtInDevices: BuiltInDevices = BuiltInDevices.attach(params, outwardNode) - 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] = - TLNameNode(name)): OutwardNodeHandle[D,U,E,B] = { - to("memory_controller" named name) { gen :*= TLWidthWidget(params.beatBytes) :*= TLBuffer(buffer) :*= outwardNode } - } + val builtInDevices: BuiltInDevices = BuiltInDevices.attach(params, outwardNode) } diff --git a/src/main/scala/subsystem/PeripheryBus.scala b/src/main/scala/subsystem/PeripheryBus.scala index 144b51721c..a1c86fb4bf 100644 --- a/src/main/scala/subsystem/PeripheryBus.scala +++ b/src/main/scala/subsystem/PeripheryBus.scala @@ -37,9 +37,7 @@ case class PeripheryBusParams( class PeripheryBus(params: PeripheryBusParams, name: String)(implicit p: Parameters) extends TLBusWrapper(params, name) - with CanHaveBuiltInDevices - with CanAttachTLSlaves { - +{ private val fixer = LazyModule(new TLFIFOFixer(TLFIFOFixer.all)) private val node: TLNode = params.atomics.map { pa => val in_xbar = LazyModule(new TLXbar) @@ -60,12 +58,4 @@ class PeripheryBus(params: PeripheryBusParams, name: String)(implicit p: Paramet def busView: TLEdge = fixer.node.edges.in.head val builtInDevices: BuiltInDevices = BuiltInDevices.attach(params, outwardNode) - - def toTile - (name: Option[String] = None, buffer: BufferParams = BufferParams.none) - (gen: => TLInwardNode): NoHandle = { - to("tile" named name) { FlipRendering { implicit p => - gen :*= TLWidthWidget(params.beatBytes) :*= TLBuffer(buffer) :*= outwardNode - }} - } } diff --git a/src/main/scala/subsystem/SystemBus.scala b/src/main/scala/subsystem/SystemBus.scala index 25f8fbf5f4..fb9e8e58f9 100644 --- a/src/main/scala/subsystem/SystemBus.scala +++ b/src/main/scala/subsystem/SystemBus.scala @@ -29,9 +29,6 @@ case class SystemBusParams( class SystemBus(params: SystemBusParams, name: String = "system_bus")(implicit p: Parameters) extends TLBusWrapper(params, name) - with CanHaveBuiltInDevices - with CanAttachTLSlaves - with CanAttachTLMasters { private val system_bus_xbar = LazyModule(new TLXbar(policy = params.policy)) def inwardNode: TLInwardNode = system_bus_xbar.node @@ -39,12 +36,4 @@ class SystemBus(params: SystemBusParams, name: String = "system_bus")(implicit p def busView: TLEdge = system_bus_xbar.node.edges.in.head val builtInDevices: BuiltInDevices = BuiltInDevices.attach(params, outwardNode) - - def fromTile - (name: Option[String], buffer: BufferParams = BufferParams.none, cork: Option[Boolean] = None) - (gen: => TLOutwardNode): NoHandle = { - from("tile" named name) { - inwardNode :=* TLBuffer(buffer) :=* TLFIFOFixer(TLFIFOFixer.allVolatile) :=* gen - } - } } diff --git a/src/main/scala/tilelink/BusWrapper.scala b/src/main/scala/tilelink/BusWrapper.scala index bcf67869d6..3352212de2 100644 --- a/src/main/scala/tilelink/BusWrapper.scala +++ b/src/main/scala/tilelink/BusWrapper.scala @@ -5,8 +5,12 @@ package freechips.rocketchip.tilelink import Chisel._ import freechips.rocketchip.config.Parameters import freechips.rocketchip.diplomacy._ + +// TODO This class should be moved to package subsystem to resolve +// the dependency awkwardness of the following imports +import freechips.rocketchip.devices.tilelink._ import freechips.rocketchip.prci._ -import freechips.rocketchip.subsystem._ // TODO this class should be moved to package subsystem +import freechips.rocketchip.subsystem._ import freechips.rocketchip.util._ /** Specifies widths of various attachement points in the SoC */ @@ -27,8 +31,12 @@ trait HasTLBusParams { } abstract class TLBusWrapper(params: HasTLBusParams, val busName: String)(implicit p: Parameters) - extends ClockDomain with HasTLBusParams { - + extends ClockDomain + with HasTLBusParams + with CanHaveBuiltInDevices + with CanAttachTLSlaves + with CanAttachTLMasters +{ private val clockGroupAggregator = LazyModule(new ClockGroupAggregator(busName)).suggestName(busName + "_clock_groups") private val clockGroup = LazyModule(new ClockGroup(busName)) val clockGroupNode = clockGroupAggregator.node // other bus clock groups attach here @@ -143,6 +151,22 @@ class TLBusWrapperTopology( } trait CanAttachTLSlaves extends HasTLBusParams { this: TLBusWrapper => + + def toTile + (name: Option[String] = None, buffer: BufferParams = BufferParams.none) + (gen: => TLInwardNode): NoHandle = { + to("tile" named name) { FlipRendering { implicit p => + gen :*= TLWidthWidget(beatBytes) :*= TLBuffer(buffer) :*= outwardNode + }} + } + + 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] = + TLNameNode(name)): OutwardNodeHandle[D,U,E,B] = { + to("memory_controller" named name) { gen :*= TLWidthWidget(beatBytes) :*= TLBuffer(buffer) :*= outwardNode } + } + 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] = @@ -217,6 +241,14 @@ trait CanAttachTLSlaves extends HasTLBusParams { this: TLBusWrapper => } trait CanAttachTLMasters extends HasTLBusParams { this: TLBusWrapper => + def fromTile + (name: Option[String], buffer: BufferParams = BufferParams.none, cork: Option[Boolean] = None) + (gen: => TLOutwardNode): NoHandle = { + from("tile" named name) { + inwardNode :=* TLBuffer(buffer) :=* TLFIFOFixer(TLFIFOFixer.allVolatile) :=* gen + } + } + def fromMasterNode (name: Option[String] = None, buffer: BufferParams = BufferParams.none) (gen: TLOutwardNode) { From dced4613d4d0cb6a126de90cb27910a3a5a73832 Mon Sep 17 00:00:00 2001 From: Henry Cook Date: Tue, 10 Mar 2020 19:20:49 -0700 Subject: [PATCH 11/32] subsystem: BaseSubsystem treats all legacy bus accessors as instances of TLBusWrapper --- src/main/scala/subsystem/BaseSubsystem.scala | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/main/scala/subsystem/BaseSubsystem.scala b/src/main/scala/subsystem/BaseSubsystem.scala index 4d99b2517f..9500e71ae5 100644 --- a/src/main/scala/subsystem/BaseSubsystem.scala +++ b/src/main/scala/subsystem/BaseSubsystem.scala @@ -65,16 +65,15 @@ abstract class BaseSubsystem(implicit p: Parameters) extends BareSubsystem topology.foreach(_.instantiate(this)) topology.foreach(_.connect(this)) - // TODO where should this happen; must there always be an "sbus"? + // TODO how should this clock driving happen; must there really always be an "sbus"? + val sbus = tlBusWrapperLocationMap.select(SBUS) locateTLBusWrapper(SBUS).clockGroupNode := asyncClockGroupsNode - // TODO deprecate these public members to see where users are manually hardcoding a particular bus - // TODO additionally, merge all TLBusWrapper subtypes back into a single base class, at least in terms of coupling methods - val sbus = tlBusWrapperLocationMap.select(SBUS).asInstanceOf[SystemBus] - val pbus = tlBusWrapperLocationMap.lift(PBUS).getOrElse(sbus).asInstanceOf[PeripheryBus] - val fbus = tlBusWrapperLocationMap.lift(FBUS).getOrElse(sbus).asInstanceOf[FrontBus] - val mbus = tlBusWrapperLocationMap.lift(MBUS).getOrElse(sbus).asInstanceOf[MemoryBus] - val cbus = tlBusWrapperLocationMap.lift(CBUS).getOrElse(sbus).asInstanceOf[PeripheryBus] + // TODO deprecate these public members to see where users are manually hardcoding a particular bus that might actually not exist in a certain dynamic topology + val pbus = tlBusWrapperLocationMap.lift(PBUS).getOrElse(sbus) + val fbus = tlBusWrapperLocationMap.lift(FBUS).getOrElse(sbus) + val mbus = tlBusWrapperLocationMap.lift(MBUS).getOrElse(sbus) + val cbus = tlBusWrapperLocationMap.lift(CBUS).getOrElse(sbus) // Collect information for use in DTS lazy val topManagers = locateTLBusWrapper(SBUS).unifyManagers From 448f33db513e600025e2f0f7c5a131e37115982b Mon Sep 17 00:00:00 2001 From: Henry Cook Date: Tue, 10 Mar 2020 20:01:52 -0700 Subject: [PATCH 12/32] subsystem: split HierarchicalBusTopologyParams into 3 topologies --- src/main/scala/subsystem/BusTopology.scala | 38 ++++++++++++++-------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/src/main/scala/subsystem/BusTopology.scala b/src/main/scala/subsystem/BusTopology.scala index 13e00491e3..455e63ef77 100644 --- a/src/main/scala/subsystem/BusTopology.scala +++ b/src/main/scala/subsystem/BusTopology.scala @@ -41,29 +41,41 @@ case class SubsystemCrossingParams( // bus topology that contains the five traditional tilelink bus wrappers. // Users desiring a different topology are free to define a similar subclass, // or just populate an instance of TLBusWrapperTopology via some other mechanism. -case class HierarchicalBusTopologyParams( + +case class JustOneBusTopologyParams( sbus: SystemBusParams, +) extends TLBusWrapperTopology( + instantiations = List((SBUS, sbus)), + connections = Nil +) + +case class HierarchicalBusTopologyParams( pbus: PeripheryBusParams, fbus: FrontBusParams, - mbus: MemoryBusParams, cbus: PeripheryBusParams, - l2: BankedL2Params, xTypes: SubsystemCrossingParams ) extends TLBusWrapperTopology( instantiations = List( - (SBUS, sbus), (PBUS, pbus), (FBUS, fbus), - (CBUS, cbus), - (MBUS, mbus), - (L2, CoherenceManagerWrapperParams(sbus.blockBytes, sbus.beatBytes, L2.name)(l2.coherenceManager))), + (CBUS, cbus)), connections = List( (SBUS, CBUS, TLBusWrapperCrossToConnection (xTypes.sbusToCbusXType)()), (CBUS, PBUS, TLBusWrapperCrossToConnection (xTypes.cbusToPbusXType)()), - (SBUS, FBUS, TLBusWrapperCrossFromConnection(xTypes.fbusToSbusXType)())) ++ - (if (l2.nBanks == 0) Nil else List( // TODO this should be two topologies once val mbus in subsystem is truly optional - (SBUS, L2, TLBusWrapperCrossToConnection (NoCrossing)()), - (L2, MBUS, TLBusWrapperCrossToConnection (NoCrossing) - (inject = { implicit p => BankBinder(p(CacheBlockBytes) * (l2.nBanks-1)) })) - )) + (SBUS, FBUS, TLBusWrapperCrossFromConnection(xTypes.fbusToSbusXType)())) +) + +case class CoherentBusTopologyParams( + sbus: SystemBusParams, // TODO remove this after better width propagation + mbus: MemoryBusParams, + l2: BankedL2Params +) extends TLBusWrapperTopology( + instantiations = (if (l2.nBanks == 0) Nil else List( + (MBUS, mbus), + (L2, CoherenceManagerWrapperParams(sbus.blockBytes, sbus.beatBytes, L2.name)(l2.coherenceManager)))), + connections = (if (l2.nBanks == 0) Nil else List( + (SBUS, L2, TLBusWrapperCrossToConnection (NoCrossing)()), + (L2, MBUS, TLBusWrapperCrossToConnection (NoCrossing) + (inject = { implicit p => BankBinder(p(CacheBlockBytes) * (l2.nBanks-1)) })) + )) ) From 0b35bbd40a9259ed8795c341dd948b2dcdca1a5e Mon Sep 17 00:00:00 2001 From: Henry Cook Date: Tue, 10 Mar 2020 20:03:03 -0700 Subject: [PATCH 13/32] config: create and use config alterations WithJustOneBus, WithIncoherentTopology, WithCoherentTopology --- src/main/scala/subsystem/Configs.scala | 29 ++++++++++++++++++++++---- src/main/scala/system/Configs.scala | 8 ++++--- 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/src/main/scala/subsystem/Configs.scala b/src/main/scala/subsystem/Configs.scala index 2fefede243..4734073bc3 100644 --- a/src/main/scala/subsystem/Configs.scala +++ b/src/main/scala/subsystem/Configs.scala @@ -43,18 +43,39 @@ class BaseSubsystemConfig extends Config ((site, here, up) => { case DebugModuleKey => Some(DefaultDebugModuleParams(site(XLen))) case CLINTKey => Some(CLINTParams()) case PLICKey => Some(PLICParams()) +}) + +/* Composable partial function Configs to set individual parameters */ + +class WithJustOneBus extends Config((site, here, up) => { case TLNetworkTopologyLocated("InSubsystem") => List( + JustOneBusTopologyParams(sbus = site(SystemBusKey)) + ) +}) + +class WithIncoherentBusTopology extends Config((site, here, up) => { + case TLNetworkTopologyLocated("InSubsystem") => List( + JustOneBusTopologyParams(sbus = site(SystemBusKey)), HierarchicalBusTopologyParams( - sbus = site(SystemBusKey), pbus = site(PeripheryBusKey), fbus = site(FrontBusKey), - mbus = site(MemoryBusKey), cbus = site(ControlBusKey), - l2 = site(BankedL2Key), xTypes = SubsystemCrossingParams())) }) -/* Composable partial function Configs to set individual parameters */ +class WithCoherentBusTopology extends Config((site, here, up) => { + case TLNetworkTopologyLocated("InSubsystem") => List( + JustOneBusTopologyParams(sbus = site(SystemBusKey)), + HierarchicalBusTopologyParams( + pbus = site(PeripheryBusKey), + fbus = site(FrontBusKey), + cbus = site(ControlBusKey), + xTypes = SubsystemCrossingParams()), + CoherentBusTopologyParams( + sbus = site(SystemBusKey), + mbus = site(MemoryBusKey), + l2 = site(BankedL2Key))) +}) class WithNBigCores(n: Int) extends Config((site, here, up) => { case RocketTilesKey => { diff --git a/src/main/scala/system/Configs.scala b/src/main/scala/system/Configs.scala index 2c81ddba1c..b76507bb07 100644 --- a/src/main/scala/system/Configs.scala +++ b/src/main/scala/system/Configs.scala @@ -22,14 +22,14 @@ class BaseConfig extends Config( new BaseSubsystemConfig() ) -class DefaultConfig extends Config(new WithNBigCores(1) ++ new BaseConfig) +class DefaultConfig extends Config(new WithNBigCores(1) ++ new WithCoherentBusTopology ++ new BaseConfig) class DefaultBufferlessConfig extends Config(new WithBufferlessBroadcastHub ++ new DefaultConfig) -class DefaultSmallConfig extends Config(new WithNSmallCores(1) ++ new BaseConfig) +class DefaultSmallConfig extends Config(new WithNSmallCores(1) ++ new WithCoherentBusTopology ++ new BaseConfig) class DefaultRV32Config extends Config(new WithRV32 ++ new DefaultConfig) class DualBankConfig extends Config(new WithNBanks(2) ++ new DefaultConfig) -class DualCoreConfig extends Config( new WithNBigCores(2) ++ new BaseConfig) +class DualCoreConfig extends Config(new WithNBigCores(2) ++ new WithCoherentBusTopology ++ new BaseConfig) class DualChannelConfig extends Config(new WithNMemoryChannels(2) ++ new DefaultConfig) class EightChannelConfig extends Config(new WithNMemoryChannels(8) ++ new DefaultConfig) @@ -54,6 +54,7 @@ class TinyConfig extends Config( new WithNMemoryChannels(0) ++ new WithNBanks(0) ++ new With1TinyCore ++ + new WithIncoherentBusTopology ++ new BaseConfig) class MemPortOnlyConfig extends Config( @@ -69,6 +70,7 @@ class MMIOPortOnlyConfig extends Config( new WithNBanks(0) ++ new WithIncoherentTiles ++ new WithScratchpadsOnly ++ + new WithIncoherentBusTopology ++ new DefaultConfig ) From b2ae234091ca8a47fd62363971beaacb85ff61ca Mon Sep 17 00:00:00 2001 From: Henry Cook Date: Thu, 12 Mar 2020 15:59:37 -0700 Subject: [PATCH 14/32] tilelink: define and use TLTempNode --- src/main/scala/tilelink/BusWrapper.scala | 6 ++---- src/main/scala/tilelink/Nodes.scala | 7 ++++++- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/main/scala/tilelink/BusWrapper.scala b/src/main/scala/tilelink/BusWrapper.scala index 3352212de2..9cd1826480 100644 --- a/src/main/scala/tilelink/BusWrapper.scala +++ b/src/main/scala/tilelink/BusWrapper.scala @@ -101,14 +101,13 @@ trait TLBusWrapperInstantiationLike { trait TLBusWrapperConnectionLike { val xType: ClockCrossingType - def inject(implicit p: Parameters): TLNode = TLNameNode("temp") def connect(context: HasLocations, from: Location[TLBusWrapper], to: Location[TLBusWrapper])(implicit p: Parameters): Unit } case class TLBusWrapperCrossToConnection (xType: ClockCrossingType) (nodeView: (TLBusWrapper, Parameters) => TLInwardNode = { case(w, p) => w.crossInHelper(xType)(p) }, - inject: Parameters => TLNode = { _ => TLNameNode("temp") }) + inject: Parameters => TLNode = { _ => TLTempNode() }) extends TLBusWrapperConnectionLike { def connect(context: HasLocations, from: Location[TLBusWrapper], to: Location[TLBusWrapper])(implicit p: Parameters): Unit = { @@ -117,7 +116,6 @@ case class TLBusWrapperCrossToConnection slaveTLBus.clockGroupNode := asyncMux(xType, context.asyncClockGroupsNode, masterTLBus.clockGroupNode) masterTLBus.coupleTo(s"bus_named_${masterTLBus.busName}") { nodeView(slaveTLBus,p) :*= TLWidthWidget(masterTLBus.beatBytes) :*= inject(p) :*= _ - // TODO does BankBinder injection need to be (_ :=* bb :*= _) } } } @@ -125,7 +123,7 @@ case class TLBusWrapperCrossToConnection case class TLBusWrapperCrossFromConnection (xType: ClockCrossingType) (nodeView: (TLBusWrapper, Parameters) => TLOutwardNode = { case(w, p) => w.crossOutHelper(xType)(p) }, - inject: Parameters => TLNode = { _ => TLNameNode("temp") }) + inject: Parameters => TLNode = { _ => TLTempNode() }) extends TLBusWrapperConnectionLike { def connect(context: HasLocations, from: Location[TLBusWrapper], to: Location[TLBusWrapper])(implicit p: Parameters): Unit = FlipRendering { implicit p => diff --git a/src/main/scala/tilelink/Nodes.scala b/src/main/scala/tilelink/Nodes.scala index 5d74d5a613..279120d4e5 100644 --- a/src/main/scala/tilelink/Nodes.scala +++ b/src/main/scala/tilelink/Nodes.scala @@ -52,7 +52,6 @@ case class TLJunctionNode( extends JunctionNode(TLImp)(clientRatio, managerRatio, clientFn, managerFn) with TLFormatNode case class TLIdentityNode()(implicit valName: ValName) extends IdentityNode(TLImp)() with TLFormatNode -case class TLEphemeralNode()(implicit valName: ValName) extends EphemeralNode(TLImp)() object TLNameNode { def apply(name: ValName) = TLIdentityNode()(name) @@ -60,6 +59,12 @@ object TLNameNode { def apply(name: String): TLIdentityNode = apply(Some(name)) } +case class TLEphemeralNode()(implicit valName: ValName) extends EphemeralNode(TLImp)() + +object TLTempNode { + def apply(): TLEphemeralNode = TLEphemeralNode()(ValName("temp")) +} + case class TLNexusNode( clientFn: Seq[TLMasterPortParameters] => TLMasterPortParameters, managerFn: Seq[TLSlavePortParameters] => TLSlavePortParameters)( From d756856e7c65df41ccf9c96d1a840a9bf51ae92a Mon Sep 17 00:00:00 2001 From: Henry Cook Date: Thu, 12 Mar 2020 16:04:13 -0700 Subject: [PATCH 15/32] tilelink: fix BankBinder require text and add factory method --- src/main/scala/tilelink/BankBinder.scala | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/scala/tilelink/BankBinder.scala b/src/main/scala/tilelink/BankBinder.scala index a687303cfe..c3ce0406fa 100644 --- a/src/main/scala/tilelink/BankBinder.scala +++ b/src/main/scala/tilelink/BankBinder.scala @@ -17,7 +17,7 @@ case class BankBinderNode(mask: BigInt)(implicit valName: ValName) extends TLCus val oStar = if (oStars == 0) 0 else (ports - oKnown) / oStars val iStar = if (iStars == 0) 0 else (ports - iKnown) / iStars require (ports == iKnown + iStar*iStars, s"${name} must have ${ports} inputs, but has ${iKnown} + ${iStar}*${iStars} (at ${lazyModule.line})") - require (ports == oKnown + oStar*oStars, s"${name} must have ${ports} outputs, but has ${iKnown} + ${iStar}*${iStars} (at ${lazyModule.line})") + require (ports == oKnown + oStar*oStars, s"${name} must have ${ports} outputs, but has ${oKnown} + ${oStar}*${oStars} (at ${lazyModule.line})") (iStar, oStar) } @@ -68,4 +68,9 @@ object BankBinder val binder = LazyModule(new BankBinder(mask)) binder.node } + + def apply(nBanks: Int, granularity: Int)(implicit p: Parameters): TLNode = { + if (nBanks > 0) apply(granularity * (nBanks-1)) + else TLTempNode() + } } From 51361c8dea61873f7ad33872dad527efe574d839 Mon Sep 17 00:00:00 2001 From: Henry Cook Date: Thu, 12 Mar 2020 16:08:35 -0700 Subject: [PATCH 16/32] subsystem: MemoryBus supports banking internally/natively --- src/main/scala/subsystem/BusTopology.scala | 3 +-- src/main/scala/subsystem/Configs.scala | 3 ++- src/main/scala/subsystem/MemoryBus.scala | 10 +++++++--- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/main/scala/subsystem/BusTopology.scala b/src/main/scala/subsystem/BusTopology.scala index 455e63ef77..6a8c6e1554 100644 --- a/src/main/scala/subsystem/BusTopology.scala +++ b/src/main/scala/subsystem/BusTopology.scala @@ -75,7 +75,6 @@ case class CoherentBusTopologyParams( (L2, CoherenceManagerWrapperParams(sbus.blockBytes, sbus.beatBytes, L2.name)(l2.coherenceManager)))), connections = (if (l2.nBanks == 0) Nil else List( (SBUS, L2, TLBusWrapperCrossToConnection (NoCrossing)()), - (L2, MBUS, TLBusWrapperCrossToConnection (NoCrossing) - (inject = { implicit p => BankBinder(p(CacheBlockBytes) * (l2.nBanks-1)) })) + (L2, MBUS, TLBusWrapperCrossToConnection (NoCrossing)()) )) ) diff --git a/src/main/scala/subsystem/Configs.scala b/src/main/scala/subsystem/Configs.scala index 4734073bc3..542d6fe83a 100644 --- a/src/main/scala/subsystem/Configs.scala +++ b/src/main/scala/subsystem/Configs.scala @@ -34,7 +34,8 @@ class BaseSubsystemConfig extends Config ((site, here, up) => { case MemoryBusKey => MemoryBusParams( beatBytes = site(XLen)/8, blockBytes = site(CacheBlockBytes), - replicatorMask = site(MultiChipMaskKey)) + replicatorMask = site(MultiChipMaskKey), + nInwardBanks = site(BankedL2Key).nBanks) case FrontBusKey => FrontBusParams( beatBytes = site(XLen)/8, blockBytes = site(CacheBlockBytes)) diff --git a/src/main/scala/subsystem/MemoryBus.scala b/src/main/scala/subsystem/MemoryBus.scala index 701ca679bf..5cb0c35775 100644 --- a/src/main/scala/subsystem/MemoryBus.scala +++ b/src/main/scala/subsystem/MemoryBus.scala @@ -17,7 +17,8 @@ case class MemoryBusParams( dtsFrequency: Option[BigInt] = None, zeroDevice: Option[AddressSet] = None, errorDevice: Option[DevNullParams] = None, - replicatorMask: BigInt = 0) + replicatorMask: BigInt = 0, + nInwardBanks: Int = 0) extends HasTLBusParams with HasBuiltInDeviceParams with HasRegionReplicatorParams @@ -35,8 +36,11 @@ class MemoryBus(params: MemoryBusParams, name: String = "memory_bus")(implicit p extends TLBusWrapper(params, name)(p) { private val xbar = LazyModule(new TLXbar).suggestName(busName + "_xbar") - def inwardNode: TLInwardNode = - if (params.replicatorMask == 0) xbar.node else { xbar.node :=* RegionReplicator(params.replicatorMask) } + private def replicate(node: TLInwardNode): TLInwardNode = + if (params.replicatorMask == 0) node else { node :=* RegionReplicator(params.replicatorMask) } + private def bank(node: TLInwardNode): TLInwardNode = + if (params.nInwardBanks == 0) node else { node :=* BankBinder(params.nInwardBanks, blockBytes) :*= TLTempNode() } + def inwardNode: TLInwardNode = bank(replicate(xbar.node)) def outwardNode: TLOutwardNode = ProbePicker() :*= xbar.node def busView: TLEdge = xbar.node.edges.in.head From 20cf2b7b593163d11122c3ce1a6e3159f27349ea Mon Sep 17 00:00:00 2001 From: Henry Cook Date: Fri, 20 Mar 2020 16:09:28 -0700 Subject: [PATCH 17/32] subsystem: fix redundant HierarchicalLocation --- src/main/scala/subsystem/BaseSubsystem.scala | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/scala/subsystem/BaseSubsystem.scala b/src/main/scala/subsystem/BaseSubsystem.scala index 9500e71ae5..284f3ace88 100644 --- a/src/main/scala/subsystem/BaseSubsystem.scala +++ b/src/main/scala/subsystem/BaseSubsystem.scala @@ -14,8 +14,6 @@ case object SubsystemDriveAsyncClockGroupsKey extends Field[Option[ClockGroupDri case object AsyncClockGroupsKey extends Field[ClockGroupEphemeralNode](ClockGroupEphemeralNode()(ValName("async_clock_groups"))) case class TLNetworkTopologyLocated(where: String) extends Field[Seq[CanInstantiateWithinContext with CanConnectWithinContext]] -case class HierarchicalLocation(override val name: String) extends Location[LazyScope](name) - class HierarchicalLocation(override val name: String) extends Location[LazyScope](name) case object InTile extends HierarchicalLocation("InTile") case object InSubsystem extends HierarchicalLocation("InSubsystem") From 4fdf16ebb2baee056ddf2b37c8f2ae32c1916cd6 Mon Sep 17 00:00:00 2001 From: Henry Cook Date: Fri, 20 Mar 2020 16:09:57 -0700 Subject: [PATCH 18/32] subsystem: BaseSubsystem takes location as a constructor arg --- src/main/scala/subsystem/BaseSubsystem.scala | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/src/main/scala/subsystem/BaseSubsystem.scala b/src/main/scala/subsystem/BaseSubsystem.scala index 284f3ace88..6a3b293a1e 100644 --- a/src/main/scala/subsystem/BaseSubsystem.scala +++ b/src/main/scala/subsystem/BaseSubsystem.scala @@ -43,8 +43,9 @@ case object ResetAsynchronousFull extends SubsystemResetScheme case object SubsystemResetSchemeKey extends Field[SubsystemResetScheme](ResetSynchronous) /** Base Subsystem class with no peripheral devices or ports added */ -abstract class BaseSubsystem(implicit p: Parameters) extends BareSubsystem - with Attachable { +abstract class BaseSubsystem(val location: HierarchicalLocation = InSubsystem) + (implicit p: Parameters) + extends BareSubsystem with Attachable { override val module: BaseSubsystemModuleImp[BaseSubsystem] @@ -58,9 +59,8 @@ abstract class BaseSubsystem(implicit p: Parameters) extends BareSubsystem // Find the topology configuration for the TL buses located in this subsystem. // Calling these functions populates tlBusWrapperLocationMap and connects the locations to each other. - val location = HierarchicalLocation("InSubsystem") val topology = p(TLNetworkTopologyLocated(location.name)) - topology.foreach(_.instantiate(this)) + private val buses = topology.map(_.instantiate(this)) topology.foreach(_.connect(this)) // TODO how should this clock driving happen; must there really always be an "sbus"? @@ -100,14 +100,6 @@ abstract class BaseSubsystem(implicit p: Parameters) extends BareSubsystem lazy val logicalTreeNode = new SubsystemLogicalTreeNode() - private val buses = Seq( - sbus, - pbus, - fbus, - mbus, - cbus - ) - buses.foreach { bus => val builtIn = bus.builtInDevices builtIn.errorOpt.foreach { error => From f31ac5d179f079c895e2bf229b394b17540fb074 Mon Sep 17 00:00:00 2001 From: Henry Cook Date: Mon, 23 Mar 2020 18:14:50 -0700 Subject: [PATCH 19/32] util: make LocationMap actually extend Map trait and stop trying to push Dynamic --- src/main/scala/subsystem/Attachable.scala | 10 ++--- src/main/scala/subsystem/BankedL2Params.scala | 4 +- src/main/scala/subsystem/BaseSubsystem.scala | 2 +- src/main/scala/subsystem/FrontBus.scala | 2 +- src/main/scala/subsystem/MemoryBus.scala | 2 +- src/main/scala/subsystem/PeripheryBus.scala | 2 +- src/main/scala/subsystem/SystemBus.scala | 2 +- src/main/scala/util/Location.scala | 39 ++++++++++++------- 8 files changed, 35 insertions(+), 28 deletions(-) diff --git a/src/main/scala/subsystem/Attachable.scala b/src/main/scala/subsystem/Attachable.scala index 0ef3e6546d..ab4f1f6db3 100644 --- a/src/main/scala/subsystem/Attachable.scala +++ b/src/main/scala/subsystem/Attachable.scala @@ -26,15 +26,11 @@ trait HasPRCILocations extends HasLogicalHierarchy { this: LazyModule => val ibus: InterruptBusWrapper } -// TODO make this trait extend Dynamic itself and add the locations to anyLocationMap? trait HasLocations extends HasPRCILocations { this: LazyModule => - val anyLocationMap = new LocationMap[Any] - def selectDynamic(name: String): Any = anyLocationMap.selectDynamic(name) - def updateDynamic(name: String)(value: Any): Unit = anyLocationMap.updateDynamic(name)(value) - - val tlBusWrapperLocationMap = new LocationMap[TLBusWrapper] + val anyLocationMap = LocationMap.empty[Any] + val tlBusWrapperLocationMap = LocationMap.empty[TLBusWrapper] def locateTLBusWrapper(location: Location[TLBusWrapper]): TLBusWrapper = locateTLBusWrapper(location.name) - def locateTLBusWrapper(name: String): TLBusWrapper = tlBusWrapperLocationMap.selectDynamic(name) + def locateTLBusWrapper(name: String): TLBusWrapper = tlBusWrapperLocationMap(Location[TLBusWrapper](name)) } trait CanInstantiateWithinContext { diff --git a/src/main/scala/subsystem/BankedL2Params.scala b/src/main/scala/subsystem/BankedL2Params.scala index 70ba35a560..4e47765d97 100644 --- a/src/main/scala/subsystem/BankedL2Params.scala +++ b/src/main/scala/subsystem/BankedL2Params.scala @@ -44,8 +44,8 @@ case class CoherenceManagerWrapperParams(blockBytes: Int, beatBytes: Int, name: val dtsFrequency = None def instantiate(context: HasLocations, loc: Location[TLBusWrapper])(implicit p: Parameters): CoherenceManagerWrapper = { val cmWrapper = LazyModule(new CoherenceManagerWrapper(this, context)) - context.updateDynamic(loc.name+"Halt")(cmWrapper.halt) - context.tlBusWrapperLocationMap.updateDynamic(loc.name)(cmWrapper) + cmWrapper.halt.foreach { context.anyLocationMap += loc.halt(_) } + context.tlBusWrapperLocationMap += (loc -> cmWrapper) cmWrapper } } diff --git a/src/main/scala/subsystem/BaseSubsystem.scala b/src/main/scala/subsystem/BaseSubsystem.scala index 6a3b293a1e..d625c2ba91 100644 --- a/src/main/scala/subsystem/BaseSubsystem.scala +++ b/src/main/scala/subsystem/BaseSubsystem.scala @@ -64,7 +64,7 @@ abstract class BaseSubsystem(val location: HierarchicalLocation = InSubsystem) topology.foreach(_.connect(this)) // TODO how should this clock driving happen; must there really always be an "sbus"? - val sbus = tlBusWrapperLocationMap.select(SBUS) + val sbus = tlBusWrapperLocationMap(SBUS) locateTLBusWrapper(SBUS).clockGroupNode := asyncClockGroupsNode // TODO deprecate these public members to see where users are manually hardcoding a particular bus that might actually not exist in a certain dynamic topology diff --git a/src/main/scala/subsystem/FrontBus.scala b/src/main/scala/subsystem/FrontBus.scala index 7d0f39b57a..42e3d4f01d 100644 --- a/src/main/scala/subsystem/FrontBus.scala +++ b/src/main/scala/subsystem/FrontBus.scala @@ -20,7 +20,7 @@ case class FrontBusParams( { def instantiate(context: HasLocations, loc: Location[TLBusWrapper])(implicit p: Parameters): FrontBus = { val fbus = LazyModule(new FrontBus(this, loc.name)) - context.tlBusWrapperLocationMap.updateDynamic(loc.name)(fbus) + context.tlBusWrapperLocationMap += (loc -> fbus) fbus } } diff --git a/src/main/scala/subsystem/MemoryBus.scala b/src/main/scala/subsystem/MemoryBus.scala index 5cb0c35775..d4c6a20949 100644 --- a/src/main/scala/subsystem/MemoryBus.scala +++ b/src/main/scala/subsystem/MemoryBus.scala @@ -26,7 +26,7 @@ case class MemoryBusParams( { def instantiate(context: HasLocations, loc: Location[TLBusWrapper])(implicit p: Parameters): MemoryBus = { val mbus = LazyModule(new MemoryBus(this, loc.name)) - context.tlBusWrapperLocationMap.updateDynamic(loc.name)(mbus) + context.tlBusWrapperLocationMap += (loc -> mbus) mbus } } diff --git a/src/main/scala/subsystem/PeripheryBus.scala b/src/main/scala/subsystem/PeripheryBus.scala index a1c86fb4bf..e2d2a27726 100644 --- a/src/main/scala/subsystem/PeripheryBus.scala +++ b/src/main/scala/subsystem/PeripheryBus.scala @@ -30,7 +30,7 @@ case class PeripheryBusParams( { def instantiate(context: HasLocations, loc: Location[TLBusWrapper])(implicit p: Parameters): PeripheryBus = { val pbus = LazyModule(new PeripheryBus(this, loc.name)) - context.tlBusWrapperLocationMap.updateDynamic(loc.name)(pbus) + context.tlBusWrapperLocationMap += (loc -> pbus) pbus } } diff --git a/src/main/scala/subsystem/SystemBus.scala b/src/main/scala/subsystem/SystemBus.scala index fb9e8e58f9..802d55e3cb 100644 --- a/src/main/scala/subsystem/SystemBus.scala +++ b/src/main/scala/subsystem/SystemBus.scala @@ -22,7 +22,7 @@ case class SystemBusParams( { def instantiate(context: HasLocations, loc: Location[TLBusWrapper])(implicit p: Parameters): SystemBus = { val sbus = LazyModule(new SystemBus(this, loc.name)) - context.tlBusWrapperLocationMap.updateDynamic(loc.name)(sbus) + context.tlBusWrapperLocationMap += (loc -> sbus) sbus } } diff --git a/src/main/scala/util/Location.scala b/src/main/scala/util/Location.scala index 6e187b3fbe..305ff224cd 100644 --- a/src/main/scala/util/Location.scala +++ b/src/main/scala/util/Location.scala @@ -3,22 +3,33 @@ package freechips.rocketchip.util import scala.language.dynamics +import scala.collection.mutable.Map -class Location[T](val name: String) - -class LocationMap[T] extends Dynamic { - private val locationMap = scala.collection.mutable.Map.empty[String, T] +class Location[T](val name: String) extends Dynamic { + def applyDynamic[A](portname: String)(args: A*): (Location[A], A) = { + require(args.size == 1, "Location: can't support multiple things at one port yet") + (new Location[A](s"${name}_${portname}"), args.head) + } + override def toString = s"Location($name)" +} - def lift(location: Location[T]): Option[T] = lift(location.name) - def lift(name: String): Option[T] = locationMap.lift(name) +object Location { + def apply[T](name: String): Location[T] = new Location[T](name) +} - def select(location: Location[T]): T = selectDynamic(location.name) - def selectDynamic(name: String): T = { - locationMap.getOrElse(name, throw new Exception(s"could not find location named $name")) - } +class LocationMap[T] private (val internalMap: Map[String, T]) extends Map[Location[_], T] { + def +=(kv: (Location[_], T)) = { (internalMap += (kv._1.name -> kv._2)); this } + def -=(key: Location[_]) = { (internalMap -= key.name); this } + def get(key: Location[_]) = internalMap.get(key.name) + def iterator = internalMap.iterator.map(kv => (new Location(kv._1), kv._2)) + // TODO override def default to provide specific exception on missing location? + // TODO figure out how to be more clever about applying sub-type casting + // for other the other Map trait methods + def required[L <: T](key: Location[L]): L = internalMap(key.name).asInstanceOf[L] + def optional[L <: T](key: Location[L]): Option[L] = internalMap.lift(key.name).map(_.asInstanceOf[L]) +} - def update(location: Location[T])(value: T): Unit = updateDynamic(location.name)(value) - def updateDynamic(name: String)(value: T): Unit = { - locationMap += name -> value - } +object LocationMap { + def apply[T](lm: Map[String, T]): LocationMap[T] = new LocationMap(lm) + def empty[T]: LocationMap[T] = new LocationMap(Map.empty[String, T]) } From a3e6babd2498345cfcd197933e6a491da5666d3e Mon Sep 17 00:00:00 2001 From: Henry Cook Date: Mon, 23 Mar 2020 18:29:16 -0700 Subject: [PATCH 20/32] tilelink: allow node views of both ends of connections --- src/main/scala/tilelink/BusWrapper.scala | 26 +++++++++++++----------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/main/scala/tilelink/BusWrapper.scala b/src/main/scala/tilelink/BusWrapper.scala index 9cd1826480..8c42d6dc7f 100644 --- a/src/main/scala/tilelink/BusWrapper.scala +++ b/src/main/scala/tilelink/BusWrapper.scala @@ -106,32 +106,34 @@ trait TLBusWrapperConnectionLike { case class TLBusWrapperCrossToConnection (xType: ClockCrossingType) - (nodeView: (TLBusWrapper, Parameters) => TLInwardNode = { case(w, p) => w.crossInHelper(xType)(p) }, + (slaveNodeView: (TLBusWrapper, Parameters) => TLInwardNode = { case(w, p) => w.crossInHelper(xType)(p) }, + masterNodeView: (TLBusWrapper, Parameters) => TLOutwardNode = { case(w, p) => w.outwardNode }, inject: Parameters => TLNode = { _ => TLTempNode() }) extends TLBusWrapperConnectionLike { - def connect(context: HasLocations, from: Location[TLBusWrapper], to: Location[TLBusWrapper])(implicit p: Parameters): Unit = { - val masterTLBus = context.locateTLBusWrapper(from) - val slaveTLBus = context.locateTLBusWrapper(to) + def connect(context: HasLocations, master: Location[TLBusWrapper], slave: Location[TLBusWrapper])(implicit p: Parameters): Unit = { + val masterTLBus = context.locateTLBusWrapper(master) + val slaveTLBus = context.locateTLBusWrapper(slave) slaveTLBus.clockGroupNode := asyncMux(xType, context.asyncClockGroupsNode, masterTLBus.clockGroupNode) - masterTLBus.coupleTo(s"bus_named_${masterTLBus.busName}") { - nodeView(slaveTLBus,p) :*= TLWidthWidget(masterTLBus.beatBytes) :*= inject(p) :*= _ + masterTLBus.to(s"bus_named_${masterTLBus.busName}") { + slaveNodeView(slaveTLBus, p) :*= TLWidthWidget(masterTLBus.beatBytes) :*= inject(p) :*= masterNodeView(masterTLBus, p) } } } case class TLBusWrapperCrossFromConnection (xType: ClockCrossingType) - (nodeView: (TLBusWrapper, Parameters) => TLOutwardNode = { case(w, p) => w.crossOutHelper(xType)(p) }, + (slaveNodeView: (TLBusWrapper, Parameters) => TLInwardNode = { case(w, p) => w.inwardNode }, + masterNodeView: (TLBusWrapper, Parameters) => TLOutwardNode = { case(w, p) => w.crossOutHelper(xType)(p) }, inject: Parameters => TLNode = { _ => TLTempNode() }) extends TLBusWrapperConnectionLike { - def connect(context: HasLocations, from: Location[TLBusWrapper], to: Location[TLBusWrapper])(implicit p: Parameters): Unit = FlipRendering { implicit p => - val masterTLBus = context.locateTLBusWrapper(to) - val slaveTLBus = context.locateTLBusWrapper(from) + def connect(context: HasLocations, slave: Location[TLBusWrapper], master: Location[TLBusWrapper])(implicit p: Parameters): Unit = FlipRendering { implicit p => + val masterTLBus = context.locateTLBusWrapper(master) + val slaveTLBus = context.locateTLBusWrapper(slave) masterTLBus.clockGroupNode := asyncMux(xType, context.asyncClockGroupsNode, slaveTLBus.clockGroupNode) - slaveTLBus.coupleFrom(s"bus_named_${masterTLBus.busName}") { - _ :=* inject(p) :=* TLWidthWidget(masterTLBus.beatBytes) :=* nodeView(masterTLBus, p) + slaveTLBus.from(s"bus_named_${masterTLBus.busName}") { + slaveNodeView(slaveTLBus, p) :=* inject(p) :=* TLWidthWidget(masterTLBus.beatBytes) :=* masterNodeView(masterTLBus, p) } } } From 8cde8b83766cf8d83dbc587dbe5a7d125274a309 Mon Sep 17 00:00:00 2001 From: Henry Cook Date: Mon, 23 Mar 2020 18:27:11 -0700 Subject: [PATCH 21/32] subsystem: HasTileLinkLocations, HasConfigurablePRCILocations, HasConfigurableTLNetworkTopology and other trait name adjustments --- src/main/scala/subsystem/Attachable.scala | 25 ++++++++----- src/main/scala/subsystem/BankedL2Params.scala | 6 ++-- src/main/scala/subsystem/BaseSubsystem.scala | 36 ++++++++++++------- src/main/scala/subsystem/FrontBus.scala | 2 +- src/main/scala/subsystem/MemoryBus.scala | 2 +- src/main/scala/subsystem/PeripheryBus.scala | 2 +- src/main/scala/subsystem/SystemBus.scala | 2 +- src/main/scala/tilelink/BusWrapper.scala | 16 +++++---- 8 files changed, 56 insertions(+), 35 deletions(-) diff --git a/src/main/scala/subsystem/Attachable.scala b/src/main/scala/subsystem/Attachable.scala index ab4f1f6db3..f3196472e6 100644 --- a/src/main/scala/subsystem/Attachable.scala +++ b/src/main/scala/subsystem/Attachable.scala @@ -15,37 +15,46 @@ import freechips.rocketchip.util.{Location, LocationMap} * Consider them experimental for now. */ +/** More nodes can be added to subclasses of this after they have been instantiated, + * and the implicit context-dependent Parameters object is available. + * These qualities comprise the fundamental capabilities of dynamic configurability. + */ trait LazyScopeWithParameters extends LazyScope { this: LazyModule => implicit val p: Parameters } +/** Layers of hierarchy with this trait will be represented as objects in the Object Model */ trait HasLogicalHierarchy extends LazyScopeWithParameters with HasLogicalTreeNode { this: LazyModule => } +/** Layers of hierarchy with this trait contain attachment points for neworks of power, clock, reset, and interrupt resources */ trait HasPRCILocations extends HasLogicalHierarchy { this: LazyModule => implicit val asyncClockGroupsNode: ClockGroupEphemeralNode val ibus: InterruptBusWrapper + val anyLocationMap = LocationMap.empty[Any] } -trait HasLocations extends HasPRCILocations { this: LazyModule => - val anyLocationMap = LocationMap.empty[Any] +/** Layers of hierarchy with this trait contain attachment points for TileLink interfaces */ +trait HasTileLinkLocations extends HasPRCILocations { this: LazyModule => val tlBusWrapperLocationMap = LocationMap.empty[TLBusWrapper] def locateTLBusWrapper(location: Location[TLBusWrapper]): TLBusWrapper = locateTLBusWrapper(location.name) def locateTLBusWrapper(name: String): TLBusWrapper = tlBusWrapperLocationMap(Location[TLBusWrapper](name)) } -trait CanInstantiateWithinContext { - def instantiate(context: HasLocations)(implicit p: Parameters): Unit +/** Subclasses of this trait have the ability to instantiate things inside a context that has TL attachement locations */ +trait CanInstantiateWithinContextThatHasTileLinkLocations { + def instantiate(context: HasTileLinkLocations)(implicit p: Parameters): Unit } -trait CanConnectWithinContext { - def connect(context: HasLocations)(implicit p: Parameters): Unit +/** Subclasses of this trait have the ability to connect things inside a context that has TL attachement locations */ +trait CanConnectWithinContextThatHasTileLinkLocations { + def connect(context: HasTileLinkLocations)(implicit p: Parameters): Unit } /** Attachable things provide a standard interface by which other things may attach themselves to this target. * Right now the trait is mostly for backwards compatibility, and in case it eventually becomes valuable * to be able to define additional resources available to agents trying to attach themselves, other than - * what is being made available via LocationMaps in trait HasLocations. + * what is being made available via the LocationMaps in trait HasTileLinkLocations. */ -trait Attachable extends HasLocations { this: LazyModule => +trait Attachable extends HasTileLinkLocations { this: LazyModule => def locateTLBusWrapper(location: TLBusWrapperLocation): TLBusWrapper = locateTLBusWrapper(location.name) } diff --git a/src/main/scala/subsystem/BankedL2Params.scala b/src/main/scala/subsystem/BankedL2Params.scala index 4e47765d97..dc71da53eb 100644 --- a/src/main/scala/subsystem/BankedL2Params.scala +++ b/src/main/scala/subsystem/BankedL2Params.scala @@ -42,7 +42,7 @@ case class CoherenceManagerWrapperParams(blockBytes: Int, beatBytes: Int, name: with TLBusWrapperInstantiationLike { val dtsFrequency = None - def instantiate(context: HasLocations, loc: Location[TLBusWrapper])(implicit p: Parameters): CoherenceManagerWrapper = { + def instantiate(context: HasTileLinkLocations, loc: Location[TLBusWrapper])(implicit p: Parameters): CoherenceManagerWrapper = { val cmWrapper = LazyModule(new CoherenceManagerWrapper(this, context)) cmWrapper.halt.foreach { context.anyLocationMap += loc.halt(_) } context.tlBusWrapperLocationMap += (loc -> cmWrapper) @@ -51,10 +51,10 @@ case class CoherenceManagerWrapperParams(blockBytes: Int, beatBytes: Int, name: } object CoherenceManagerWrapper { - type CoherenceManagerInstantiationFn = HasLocations => (TLInwardNode, TLOutwardNode, Option[IntOutwardNode]) + type CoherenceManagerInstantiationFn = HasTileLinkLocations => (TLInwardNode, TLOutwardNode, Option[IntOutwardNode]) } -class CoherenceManagerWrapper(params: CoherenceManagerWrapperParams, context: HasLocations)(implicit p: Parameters) extends TLBusWrapper(params, params.name) { +class CoherenceManagerWrapper(params: CoherenceManagerWrapperParams, context: HasTileLinkLocations)(implicit p: Parameters) extends TLBusWrapper(params, params.name) { val (temp, outwardNode, halt) = params.coherenceManager(context) // TODO could remove temp if we could get access to .edges from InwardNodeHandle val viewNode = TLIdentityNode() diff --git a/src/main/scala/subsystem/BaseSubsystem.scala b/src/main/scala/subsystem/BaseSubsystem.scala index d625c2ba91..bc822dcef8 100644 --- a/src/main/scala/subsystem/BaseSubsystem.scala +++ b/src/main/scala/subsystem/BaseSubsystem.scala @@ -12,7 +12,7 @@ import freechips.rocketchip.util._ case object SubsystemDriveAsyncClockGroupsKey extends Field[Option[ClockGroupDriverParameters]](Some(ClockGroupDriverParameters(1))) case object AsyncClockGroupsKey extends Field[ClockGroupEphemeralNode](ClockGroupEphemeralNode()(ValName("async_clock_groups"))) -case class TLNetworkTopologyLocated(where: String) extends Field[Seq[CanInstantiateWithinContext with CanConnectWithinContext]] +case class TLNetworkTopologyLocated(where: String) extends Field[Seq[CanInstantiateWithinContextThatHasTileLinkLocations with CanConnectWithinContextThatHasTileLinkLocations]] class HierarchicalLocation(override val name: String) extends Location[LazyScope](name) case object InTile extends HierarchicalLocation("InTile") @@ -42,30 +42,40 @@ case object ResetAsynchronousFull extends SubsystemResetScheme case object SubsystemResetSchemeKey extends Field[SubsystemResetScheme](ResetSynchronous) -/** Base Subsystem class with no peripheral devices or ports added */ -abstract class BaseSubsystem(val location: HierarchicalLocation = InSubsystem) - (implicit p: Parameters) - extends BareSubsystem with Attachable { - - override val module: BaseSubsystemModuleImp[BaseSubsystem] - - // Concrete attachment points for PRCI-related signals. +/** Concrete attachment points for PRCI-related signals. + * These aren't actually very configurable, yet. + */ +trait HasConfigurablePRCILocations { this: HasPRCILocations => val ibus = new InterruptBusWrapper() implicit val asyncClockGroupsNode = p(AsyncClockGroupsKey) val async_clock_groups = p(SubsystemDriveAsyncClockGroupsKey) .map(_.drive(asyncClockGroupsNode)) .getOrElse(InModuleBody { HeterogeneousBag[ClockGroupBundle](Nil) }) +} - // Find the topology configuration for the TL buses located in this subsystem. +/** Look up the topology configuration for the TL buses located within this layer of the hierarchy */ +trait HasConfigurableTLNetworkTopology { this: HasTileLinkLocations => + val location: HierarchicalLocation // Calling these functions populates tlBusWrapperLocationMap and connects the locations to each other. val topology = p(TLNetworkTopologyLocated(location.name)) private val buses = topology.map(_.instantiate(this)) topology.foreach(_.connect(this)) +} + +/** Base Subsystem class with no peripheral devices, ports or cores added yet */ +abstract class BaseSubsystem(val location: HierarchicalLocation = InSubsystem) + (implicit p: Parameters) + extends BareSubsystem + with Attachable + with HasConfigurablePRCILocations + with HasConfigurableTLNetworkTopology +{ + override val module: BaseSubsystemModuleImp[BaseSubsystem] - // TODO how should this clock driving happen; must there really always be an "sbus"? + // TODO must there really always be an "sbus"? val sbus = tlBusWrapperLocationMap(SBUS) - locateTLBusWrapper(SBUS).clockGroupNode := asyncClockGroupsNode + tlBusWrapperLocationMap.lift(SBUS).map { _.clockGroupNode := asyncClockGroupsNode } // TODO deprecate these public members to see where users are manually hardcoding a particular bus that might actually not exist in a certain dynamic topology val pbus = tlBusWrapperLocationMap.lift(PBUS).getOrElse(sbus) @@ -74,7 +84,7 @@ abstract class BaseSubsystem(val location: HierarchicalLocation = InSubsystem) val cbus = tlBusWrapperLocationMap.lift(CBUS).getOrElse(sbus) // Collect information for use in DTS - lazy val topManagers = locateTLBusWrapper(SBUS).unifyManagers + lazy val topManagers = sbus.unifyManagers ResourceBinding { val managers = topManagers val max = managers.flatMap(_.address).map(_.max).max diff --git a/src/main/scala/subsystem/FrontBus.scala b/src/main/scala/subsystem/FrontBus.scala index 42e3d4f01d..764739d5a0 100644 --- a/src/main/scala/subsystem/FrontBus.scala +++ b/src/main/scala/subsystem/FrontBus.scala @@ -18,7 +18,7 @@ case class FrontBusParams( with HasBuiltInDeviceParams with TLBusWrapperInstantiationLike { - def instantiate(context: HasLocations, loc: Location[TLBusWrapper])(implicit p: Parameters): FrontBus = { + def instantiate(context: HasTileLinkLocations, loc: Location[TLBusWrapper])(implicit p: Parameters): FrontBus = { val fbus = LazyModule(new FrontBus(this, loc.name)) context.tlBusWrapperLocationMap += (loc -> fbus) fbus diff --git a/src/main/scala/subsystem/MemoryBus.scala b/src/main/scala/subsystem/MemoryBus.scala index d4c6a20949..d38b86b942 100644 --- a/src/main/scala/subsystem/MemoryBus.scala +++ b/src/main/scala/subsystem/MemoryBus.scala @@ -24,7 +24,7 @@ case class MemoryBusParams( with HasRegionReplicatorParams with TLBusWrapperInstantiationLike { - def instantiate(context: HasLocations, loc: Location[TLBusWrapper])(implicit p: Parameters): MemoryBus = { + def instantiate(context: HasTileLinkLocations, loc: Location[TLBusWrapper])(implicit p: Parameters): MemoryBus = { val mbus = LazyModule(new MemoryBus(this, loc.name)) context.tlBusWrapperLocationMap += (loc -> mbus) mbus diff --git a/src/main/scala/subsystem/PeripheryBus.scala b/src/main/scala/subsystem/PeripheryBus.scala index e2d2a27726..135c30766f 100644 --- a/src/main/scala/subsystem/PeripheryBus.scala +++ b/src/main/scala/subsystem/PeripheryBus.scala @@ -28,7 +28,7 @@ case class PeripheryBusParams( with HasRegionReplicatorParams with TLBusWrapperInstantiationLike { - def instantiate(context: HasLocations, loc: Location[TLBusWrapper])(implicit p: Parameters): PeripheryBus = { + def instantiate(context: HasTileLinkLocations, loc: Location[TLBusWrapper])(implicit p: Parameters): PeripheryBus = { val pbus = LazyModule(new PeripheryBus(this, loc.name)) context.tlBusWrapperLocationMap += (loc -> pbus) pbus diff --git a/src/main/scala/subsystem/SystemBus.scala b/src/main/scala/subsystem/SystemBus.scala index 802d55e3cb..784c8397c3 100644 --- a/src/main/scala/subsystem/SystemBus.scala +++ b/src/main/scala/subsystem/SystemBus.scala @@ -20,7 +20,7 @@ case class SystemBusParams( with HasBuiltInDeviceParams with TLBusWrapperInstantiationLike { - def instantiate(context: HasLocations, loc: Location[TLBusWrapper])(implicit p: Parameters): SystemBus = { + def instantiate(context: HasTileLinkLocations, loc: Location[TLBusWrapper])(implicit p: Parameters): SystemBus = { val sbus = LazyModule(new SystemBus(this, loc.name)) context.tlBusWrapperLocationMap += (loc -> sbus) sbus diff --git a/src/main/scala/tilelink/BusWrapper.scala b/src/main/scala/tilelink/BusWrapper.scala index 8c42d6dc7f..9c728bfa9c 100644 --- a/src/main/scala/tilelink/BusWrapper.scala +++ b/src/main/scala/tilelink/BusWrapper.scala @@ -96,12 +96,12 @@ abstract class TLBusWrapper(params: HasTLBusParams, val busName: String)(implici } trait TLBusWrapperInstantiationLike { - def instantiate(context: HasLocations, loc: Location[TLBusWrapper])(implicit p: Parameters): TLBusWrapper + def instantiate(context: HasTileLinkLocations, loc: Location[TLBusWrapper])(implicit p: Parameters): TLBusWrapper } trait TLBusWrapperConnectionLike { val xType: ClockCrossingType - def connect(context: HasLocations, from: Location[TLBusWrapper], to: Location[TLBusWrapper])(implicit p: Parameters): Unit + def connect(context: HasTileLinkLocations, from: Location[TLBusWrapper], to: Location[TLBusWrapper])(implicit p: Parameters): Unit } case class TLBusWrapperCrossToConnection @@ -111,7 +111,7 @@ case class TLBusWrapperCrossToConnection inject: Parameters => TLNode = { _ => TLTempNode() }) extends TLBusWrapperConnectionLike { - def connect(context: HasLocations, master: Location[TLBusWrapper], slave: Location[TLBusWrapper])(implicit p: Parameters): Unit = { + def connect(context: HasTileLinkLocations, master: Location[TLBusWrapper], slave: Location[TLBusWrapper])(implicit p: Parameters): Unit = { val masterTLBus = context.locateTLBusWrapper(master) val slaveTLBus = context.locateTLBusWrapper(slave) slaveTLBus.clockGroupNode := asyncMux(xType, context.asyncClockGroupsNode, masterTLBus.clockGroupNode) @@ -128,7 +128,7 @@ case class TLBusWrapperCrossFromConnection inject: Parameters => TLNode = { _ => TLTempNode() }) extends TLBusWrapperConnectionLike { - def connect(context: HasLocations, slave: Location[TLBusWrapper], master: Location[TLBusWrapper])(implicit p: Parameters): Unit = FlipRendering { implicit p => + def connect(context: HasTileLinkLocations, slave: Location[TLBusWrapper], master: Location[TLBusWrapper])(implicit p: Parameters): Unit = FlipRendering { implicit p => val masterTLBus = context.locateTLBusWrapper(master) val slaveTLBus = context.locateTLBusWrapper(slave) masterTLBus.clockGroupNode := asyncMux(xType, context.asyncClockGroupsNode, slaveTLBus.clockGroupNode) @@ -141,11 +141,13 @@ case class TLBusWrapperCrossFromConnection class TLBusWrapperTopology( val instantiations: Seq[(Location[TLBusWrapper], TLBusWrapperInstantiationLike)], val connections: Seq[(Location[TLBusWrapper], Location[TLBusWrapper], TLBusWrapperConnectionLike)] -) extends CanInstantiateWithinContext with CanConnectWithinContext { - def instantiate(context: HasLocations)(implicit p: Parameters): Unit = { +) extends CanInstantiateWithinContextThatHasTileLinkLocations + with CanConnectWithinContextThatHasTileLinkLocations +{ + def instantiate(context: HasTileLinkLocations)(implicit p: Parameters): Unit = { instantiations.foreach { case (loc, params) => params.instantiate(context, loc) } } - def connect(context: HasLocations)(implicit p: Parameters): Unit = { + def connect(context: HasTileLinkLocations)(implicit p: Parameters): Unit = { connections.foreach { case (from, to, params) => params.connect(context, from, to) } } } From bb76a46a8bd87296545cab30925babe3acd6e973 Mon Sep 17 00:00:00 2001 From: Henry Cook Date: Fri, 27 Mar 2020 13:30:16 -0700 Subject: [PATCH 22/32] subsystem: TLManagerViewpointLocated field --- src/main/scala/subsystem/BaseSubsystem.scala | 11 ++++++++--- src/main/scala/subsystem/Configs.scala | 6 +++--- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/main/scala/subsystem/BaseSubsystem.scala b/src/main/scala/subsystem/BaseSubsystem.scala index bc822dcef8..4f679b1bad 100644 --- a/src/main/scala/subsystem/BaseSubsystem.scala +++ b/src/main/scala/subsystem/BaseSubsystem.scala @@ -8,11 +8,13 @@ import freechips.rocketchip.diplomacy._ import freechips.rocketchip.diplomaticobjectmodel.HasLogicalTreeNode import freechips.rocketchip.diplomaticobjectmodel.logicaltree._ import freechips.rocketchip.prci._ +import freechips.rocketchip.tilelink.TLBusWrapper import freechips.rocketchip.util._ case object SubsystemDriveAsyncClockGroupsKey extends Field[Option[ClockGroupDriverParameters]](Some(ClockGroupDriverParameters(1))) case object AsyncClockGroupsKey extends Field[ClockGroupEphemeralNode](ClockGroupEphemeralNode()(ValName("async_clock_groups"))) -case class TLNetworkTopologyLocated(where: String) extends Field[Seq[CanInstantiateWithinContextThatHasTileLinkLocations with CanConnectWithinContextThatHasTileLinkLocations]] +case class TLNetworkTopologyLocated(where: HierarchicalLocation) extends Field[Seq[CanInstantiateWithinContextThatHasTileLinkLocations with CanConnectWithinContextThatHasTileLinkLocations]] +case class TLManagerViewpointLocated(where: HierarchicalLocation) extends Field[Location[TLBusWrapper]](SBUS) class HierarchicalLocation(override val name: String) extends Location[LazyScope](name) case object InTile extends HierarchicalLocation("InTile") @@ -57,10 +59,14 @@ trait HasConfigurablePRCILocations { this: HasPRCILocations => /** Look up the topology configuration for the TL buses located within this layer of the hierarchy */ trait HasConfigurableTLNetworkTopology { this: HasTileLinkLocations => val location: HierarchicalLocation + // Calling these functions populates tlBusWrapperLocationMap and connects the locations to each other. - val topology = p(TLNetworkTopologyLocated(location.name)) + val topology = p(TLNetworkTopologyLocated(location)) private val buses = topology.map(_.instantiate(this)) topology.foreach(_.connect(this)) + + // This is used lazily at DTS binding time to get a view of the network + lazy val topManagers = tlBusWrapperLocationMap(p(TLManagerViewpointLocated(location))).unifyManagers } /** Base Subsystem class with no peripheral devices, ports or cores added yet */ @@ -84,7 +90,6 @@ abstract class BaseSubsystem(val location: HierarchicalLocation = InSubsystem) val cbus = tlBusWrapperLocationMap.lift(CBUS).getOrElse(sbus) // Collect information for use in DTS - lazy val topManagers = sbus.unifyManagers ResourceBinding { val managers = topManagers val max = managers.flatMap(_.address).map(_.max).max diff --git a/src/main/scala/subsystem/Configs.scala b/src/main/scala/subsystem/Configs.scala index 542d6fe83a..89bde9477c 100644 --- a/src/main/scala/subsystem/Configs.scala +++ b/src/main/scala/subsystem/Configs.scala @@ -49,13 +49,13 @@ class BaseSubsystemConfig extends Config ((site, here, up) => { /* Composable partial function Configs to set individual parameters */ class WithJustOneBus extends Config((site, here, up) => { - case TLNetworkTopologyLocated("InSubsystem") => List( + case TLNetworkTopologyLocated(InSubsystem) => List( JustOneBusTopologyParams(sbus = site(SystemBusKey)) ) }) class WithIncoherentBusTopology extends Config((site, here, up) => { - case TLNetworkTopologyLocated("InSubsystem") => List( + case TLNetworkTopologyLocated(InSubsystem) => List( JustOneBusTopologyParams(sbus = site(SystemBusKey)), HierarchicalBusTopologyParams( pbus = site(PeripheryBusKey), @@ -65,7 +65,7 @@ class WithIncoherentBusTopology extends Config((site, here, up) => { }) class WithCoherentBusTopology extends Config((site, here, up) => { - case TLNetworkTopologyLocated("InSubsystem") => List( + case TLNetworkTopologyLocated(InSubsystem) => List( JustOneBusTopologyParams(sbus = site(SystemBusKey)), HierarchicalBusTopologyParams( pbus = site(PeripheryBusKey), From 1b2c8d7d3b92a44c55981904df8501c485586282 Mon Sep 17 00:00:00 2001 From: Henry Cook Date: Mon, 30 Mar 2020 13:46:26 -0700 Subject: [PATCH 23/32] subsystem: suggestName for buses based on location --- src/main/scala/subsystem/BankedL2Params.scala | 1 + src/main/scala/subsystem/FrontBus.scala | 1 + src/main/scala/subsystem/MemoryBus.scala | 1 + src/main/scala/subsystem/PeripheryBus.scala | 1 + src/main/scala/subsystem/SystemBus.scala | 1 + 5 files changed, 5 insertions(+) diff --git a/src/main/scala/subsystem/BankedL2Params.scala b/src/main/scala/subsystem/BankedL2Params.scala index dc71da53eb..457619635e 100644 --- a/src/main/scala/subsystem/BankedL2Params.scala +++ b/src/main/scala/subsystem/BankedL2Params.scala @@ -44,6 +44,7 @@ case class CoherenceManagerWrapperParams(blockBytes: Int, beatBytes: Int, name: val dtsFrequency = None def instantiate(context: HasTileLinkLocations, loc: Location[TLBusWrapper])(implicit p: Parameters): CoherenceManagerWrapper = { val cmWrapper = LazyModule(new CoherenceManagerWrapper(this, context)) + cmWrapper.suggestName(loc.name + "_wrapper") cmWrapper.halt.foreach { context.anyLocationMap += loc.halt(_) } context.tlBusWrapperLocationMap += (loc -> cmWrapper) cmWrapper diff --git a/src/main/scala/subsystem/FrontBus.scala b/src/main/scala/subsystem/FrontBus.scala index 764739d5a0..bf0343a61a 100644 --- a/src/main/scala/subsystem/FrontBus.scala +++ b/src/main/scala/subsystem/FrontBus.scala @@ -20,6 +20,7 @@ case class FrontBusParams( { def instantiate(context: HasTileLinkLocations, loc: Location[TLBusWrapper])(implicit p: Parameters): FrontBus = { val fbus = LazyModule(new FrontBus(this, loc.name)) + fbus.suggestName(loc.name) context.tlBusWrapperLocationMap += (loc -> fbus) fbus } diff --git a/src/main/scala/subsystem/MemoryBus.scala b/src/main/scala/subsystem/MemoryBus.scala index d38b86b942..cfea97fd80 100644 --- a/src/main/scala/subsystem/MemoryBus.scala +++ b/src/main/scala/subsystem/MemoryBus.scala @@ -26,6 +26,7 @@ case class MemoryBusParams( { def instantiate(context: HasTileLinkLocations, loc: Location[TLBusWrapper])(implicit p: Parameters): MemoryBus = { val mbus = LazyModule(new MemoryBus(this, loc.name)) + mbus.suggestName(loc.name) context.tlBusWrapperLocationMap += (loc -> mbus) mbus } diff --git a/src/main/scala/subsystem/PeripheryBus.scala b/src/main/scala/subsystem/PeripheryBus.scala index 135c30766f..bcb3cc0088 100644 --- a/src/main/scala/subsystem/PeripheryBus.scala +++ b/src/main/scala/subsystem/PeripheryBus.scala @@ -30,6 +30,7 @@ case class PeripheryBusParams( { def instantiate(context: HasTileLinkLocations, loc: Location[TLBusWrapper])(implicit p: Parameters): PeripheryBus = { val pbus = LazyModule(new PeripheryBus(this, loc.name)) + pbus.suggestName(loc.name) context.tlBusWrapperLocationMap += (loc -> pbus) pbus } diff --git a/src/main/scala/subsystem/SystemBus.scala b/src/main/scala/subsystem/SystemBus.scala index 784c8397c3..d60d5d83b1 100644 --- a/src/main/scala/subsystem/SystemBus.scala +++ b/src/main/scala/subsystem/SystemBus.scala @@ -22,6 +22,7 @@ case class SystemBusParams( { def instantiate(context: HasTileLinkLocations, loc: Location[TLBusWrapper])(implicit p: Parameters): SystemBus = { val sbus = LazyModule(new SystemBus(this, loc.name)) + sbus.suggestName(loc.name) context.tlBusWrapperLocationMap += (loc -> sbus) sbus } From 6ab84b9c3ce64aabac0f35c4c51651ec563f8fbb Mon Sep 17 00:00:00 2001 From: Henry Cook Date: Mon, 30 Mar 2020 13:47:26 -0700 Subject: [PATCH 24/32] unify TLBusWrapperConnection case classes --- src/main/scala/subsystem/BusTopology.scala | 10 +-- src/main/scala/tilelink/BusWrapper.scala | 91 ++++++++++++++++------ 2 files changed, 71 insertions(+), 30 deletions(-) diff --git a/src/main/scala/subsystem/BusTopology.scala b/src/main/scala/subsystem/BusTopology.scala index 6a8c6e1554..8f2b2fd4d0 100644 --- a/src/main/scala/subsystem/BusTopology.scala +++ b/src/main/scala/subsystem/BusTopology.scala @@ -60,9 +60,9 @@ case class HierarchicalBusTopologyParams( (FBUS, fbus), (CBUS, cbus)), connections = List( - (SBUS, CBUS, TLBusWrapperCrossToConnection (xTypes.sbusToCbusXType)()), - (CBUS, PBUS, TLBusWrapperCrossToConnection (xTypes.cbusToPbusXType)()), - (SBUS, FBUS, TLBusWrapperCrossFromConnection(xTypes.fbusToSbusXType)())) + (SBUS, CBUS, TLBusWrapperConnection .crossTo(xTypes.sbusToCbusXType)), + (CBUS, PBUS, TLBusWrapperConnection .crossTo(xTypes.cbusToPbusXType)), + (FBUS, SBUS, TLBusWrapperConnection.crossFrom(xTypes.fbusToSbusXType))) ) case class CoherentBusTopologyParams( @@ -74,7 +74,7 @@ case class CoherentBusTopologyParams( (MBUS, mbus), (L2, CoherenceManagerWrapperParams(sbus.blockBytes, sbus.beatBytes, L2.name)(l2.coherenceManager)))), connections = (if (l2.nBanks == 0) Nil else List( - (SBUS, L2, TLBusWrapperCrossToConnection (NoCrossing)()), - (L2, MBUS, TLBusWrapperCrossToConnection (NoCrossing)()) + (SBUS, L2, TLBusWrapperConnection.crossTo(NoCrossing)), + (L2, MBUS, TLBusWrapperConnection.crossTo(NoCrossing)) )) ) diff --git a/src/main/scala/tilelink/BusWrapper.scala b/src/main/scala/tilelink/BusWrapper.scala index 9c728bfa9c..e2d7d98175 100644 --- a/src/main/scala/tilelink/BusWrapper.scala +++ b/src/main/scala/tilelink/BusWrapper.scala @@ -101,39 +101,80 @@ trait TLBusWrapperInstantiationLike { trait TLBusWrapperConnectionLike { val xType: ClockCrossingType - def connect(context: HasTileLinkLocations, from: Location[TLBusWrapper], to: Location[TLBusWrapper])(implicit p: Parameters): Unit + def connect(context: HasTileLinkLocations, master: Location[TLBusWrapper], slave: Location[TLBusWrapper])(implicit p: Parameters): Unit } -case class TLBusWrapperCrossToConnection - (xType: ClockCrossingType) - (slaveNodeView: (TLBusWrapper, Parameters) => TLInwardNode = { case(w, p) => w.crossInHelper(xType)(p) }, - masterNodeView: (TLBusWrapper, Parameters) => TLOutwardNode = { case(w, p) => w.outwardNode }, - inject: Parameters => TLNode = { _ => TLTempNode() }) - extends TLBusWrapperConnectionLike -{ - def connect(context: HasTileLinkLocations, master: Location[TLBusWrapper], slave: Location[TLBusWrapper])(implicit p: Parameters): Unit = { - val masterTLBus = context.locateTLBusWrapper(master) - val slaveTLBus = context.locateTLBusWrapper(slave) - slaveTLBus.clockGroupNode := asyncMux(xType, context.asyncClockGroupsNode, masterTLBus.clockGroupNode) - masterTLBus.to(s"bus_named_${masterTLBus.busName}") { - slaveNodeView(slaveTLBus, p) :*= TLWidthWidget(masterTLBus.beatBytes) :*= inject(p) :*= masterNodeView(masterTLBus, p) - } +object TLBusWrapperConnection { + /** Backwards compatibility factory for master driving clock and slave setting cardinality */ + def crossTo( + xType: ClockCrossingType, + driveClockFromMaster: Option[Boolean] = Some(true), + nodeBinding: NodeBinding = BIND_STAR, + flipRendering: Boolean = false) = { + apply(xType, driveClockFromMaster, nodeBinding, flipRendering)( + slaveNodeView = { case(w, p) => w.crossInHelper(xType)(p) }) + } + + /** Backwards compatibility factory for slave driving clock and master setting cardinality */ + def crossFrom( + xType: ClockCrossingType, + driveClockFromMaster: Option[Boolean] = Some(false), + nodeBinding: NodeBinding = BIND_QUERY, + flipRendering: Boolean = true) = { + apply(xType, driveClockFromMaster, nodeBinding, flipRendering)( + masterNodeView = { case(w, p) => w.crossOutHelper(xType)(p) }) + } + + /** Factory for making generic connections between TLBusWrappers */ + def apply + (xType: ClockCrossingType = NoCrossing, + driveClockFromMaster: Option[Boolean] = None, + nodeBinding: NodeBinding = BIND_ONCE, + flipRendering: Boolean = false)( + slaveNodeView: (TLBusWrapper, Parameters) => TLInwardNode = { case(w, _) => w.inwardNode }, + masterNodeView: (TLBusWrapper, Parameters) => TLOutwardNode = { case(w, _) => w.outwardNode }, + inject: Parameters => TLNode = { _ => TLTempNode() }) = { + new TLBusWrapperConnection( + xType, driveClockFromMaster, nodeBinding, flipRendering)( + slaveNodeView, masterNodeView, inject) } } -case class TLBusWrapperCrossFromConnection - (xType: ClockCrossingType) - (slaveNodeView: (TLBusWrapper, Parameters) => TLInwardNode = { case(w, p) => w.inwardNode }, - masterNodeView: (TLBusWrapper, Parameters) => TLOutwardNode = { case(w, p) => w.crossOutHelper(xType)(p) }, - inject: Parameters => TLNode = { _ => TLTempNode() }) +class TLBusWrapperConnection + (val xType: ClockCrossingType, + val driveClockFromMaster: Option[Boolean], + val nodeBinding: NodeBinding, + val flipRendering: Boolean) + (slaveNodeView: (TLBusWrapper, Parameters) => TLInwardNode, + masterNodeView: (TLBusWrapper, Parameters) => TLOutwardNode, + inject: Parameters => TLNode) extends TLBusWrapperConnectionLike { - def connect(context: HasTileLinkLocations, slave: Location[TLBusWrapper], master: Location[TLBusWrapper])(implicit p: Parameters): Unit = FlipRendering { implicit p => + def connect(context: HasTileLinkLocations, master: Location[TLBusWrapper], slave: Location[TLBusWrapper])(implicit p: Parameters): Unit = { val masterTLBus = context.locateTLBusWrapper(master) val slaveTLBus = context.locateTLBusWrapper(slave) - masterTLBus.clockGroupNode := asyncMux(xType, context.asyncClockGroupsNode, slaveTLBus.clockGroupNode) - slaveTLBus.from(s"bus_named_${masterTLBus.busName}") { - slaveNodeView(slaveTLBus, p) :=* inject(p) :=* TLWidthWidget(masterTLBus.beatBytes) :=* masterNodeView(masterTLBus, p) + def bindClocks(implicit p: Parameters) = driveClockFromMaster match { + case Some(true) => slaveTLBus.clockGroupNode := asyncMux(xType, context.asyncClockGroupsNode, masterTLBus.clockGroupNode) + case Some(false) => masterTLBus.clockGroupNode := asyncMux(xType, context.asyncClockGroupsNode, slaveTLBus.clockGroupNode) + case None => + } + def bindTLNodes(implicit p: Parameters) = nodeBinding match { + case BIND_ONCE => slaveNodeView(slaveTLBus, p) := TLWidthWidget(masterTLBus.beatBytes) := inject(p) := masterNodeView(masterTLBus, p) + case BIND_QUERY => slaveNodeView(slaveTLBus, p) :=* TLWidthWidget(masterTLBus.beatBytes) :=* inject(p) :=* masterNodeView(masterTLBus, p) + case BIND_STAR => slaveNodeView(slaveTLBus, p) :*= TLWidthWidget(masterTLBus.beatBytes) :*= inject(p) :*= masterNodeView(masterTLBus, p) + case BIND_FLEX => slaveNodeView(slaveTLBus, p) :*=* TLWidthWidget(masterTLBus.beatBytes) :*=* inject(p) :*=* masterNodeView(masterTLBus, p) + } + + if (flipRendering) { FlipRendering { implicit p => + bindClocks(implicitly[Parameters]) + slaveTLBus.from(s"bus_named_${masterTLBus.busName}") { + bindTLNodes(implicitly[Parameters]) + } + } } else { + bindClocks(implicitly[Parameters]) + masterTLBus.to (s"bus_named_${slaveTLBus.busName}") { + bindTLNodes(implicitly[Parameters]) + } } } } @@ -148,7 +189,7 @@ class TLBusWrapperTopology( instantiations.foreach { case (loc, params) => params.instantiate(context, loc) } } def connect(context: HasTileLinkLocations)(implicit p: Parameters): Unit = { - connections.foreach { case (from, to, params) => params.connect(context, from, to) } + connections.foreach { case (master, slave, params) => { params.connect(context, master, slave) } } } } From e5371b81af0925f93d36e99b47debc2821990aeb Mon Sep 17 00:00:00 2001 From: Henry Cook Date: Mon, 30 Mar 2020 14:13:15 -0700 Subject: [PATCH 25/32] add context wrappers around TLBusWrapperTopology connects and instantiations --- src/main/scala/subsystem/MemoryBus.scala | 2 +- src/main/scala/tilelink/BusWrapper.scala | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/scala/subsystem/MemoryBus.scala b/src/main/scala/subsystem/MemoryBus.scala index cfea97fd80..9ad927f9d3 100644 --- a/src/main/scala/subsystem/MemoryBus.scala +++ b/src/main/scala/subsystem/MemoryBus.scala @@ -41,7 +41,7 @@ class MemoryBus(params: MemoryBusParams, name: String = "memory_bus")(implicit p if (params.replicatorMask == 0) node else { node :=* RegionReplicator(params.replicatorMask) } private def bank(node: TLInwardNode): TLInwardNode = if (params.nInwardBanks == 0) node else { node :=* BankBinder(params.nInwardBanks, blockBytes) :*= TLTempNode() } - def inwardNode: TLInwardNode = bank(replicate(xbar.node)) + def inwardNode: TLInwardNode = this { bank(replicate(xbar.node)) } def outwardNode: TLOutwardNode = ProbePicker() :*= xbar.node def busView: TLEdge = xbar.node.edges.in.head diff --git a/src/main/scala/tilelink/BusWrapper.scala b/src/main/scala/tilelink/BusWrapper.scala index e2d7d98175..6c84fc2d5d 100644 --- a/src/main/scala/tilelink/BusWrapper.scala +++ b/src/main/scala/tilelink/BusWrapper.scala @@ -186,10 +186,10 @@ class TLBusWrapperTopology( with CanConnectWithinContextThatHasTileLinkLocations { def instantiate(context: HasTileLinkLocations)(implicit p: Parameters): Unit = { - instantiations.foreach { case (loc, params) => params.instantiate(context, loc) } + instantiations.foreach { case (loc, params) => context { params.instantiate(context, loc) } } } def connect(context: HasTileLinkLocations)(implicit p: Parameters): Unit = { - connections.foreach { case (master, slave, params) => { params.connect(context, master, slave) } } + connections.foreach { case (master, slave, params) => context { params.connect(context, master, slave) } } } } From 6e50aaceb44af268ebe7b7bac309d2b2c07c9d44 Mon Sep 17 00:00:00 2001 From: Henry Cook Date: Mon, 30 Mar 2020 14:45:15 -0700 Subject: [PATCH 26/32] subsystem: move nBanks and binder to CoherenceManagerWrapper --- src/main/scala/subsystem/BankedL2Params.scala | 15 ++++++++++++--- src/main/scala/subsystem/BusTopology.scala | 10 +++++----- src/main/scala/subsystem/Configs.scala | 3 +-- src/main/scala/subsystem/MemoryBus.scala | 11 ++++------- 4 files changed, 22 insertions(+), 17 deletions(-) diff --git a/src/main/scala/subsystem/BankedL2Params.scala b/src/main/scala/subsystem/BankedL2Params.scala index 457619635e..0149248298 100644 --- a/src/main/scala/subsystem/BankedL2Params.scala +++ b/src/main/scala/subsystem/BankedL2Params.scala @@ -36,7 +36,11 @@ case class BankedL2Params( } -case class CoherenceManagerWrapperParams(blockBytes: Int, beatBytes: Int, name: String) +case class CoherenceManagerWrapperParams( + blockBytes: Int, + beatBytes: Int, + nBanks: Int, + name: String) (val coherenceManager: CoherenceManagerWrapper.CoherenceManagerInstantiationFn) extends HasTLBusParams with TLBusWrapperInstantiationLike @@ -56,9 +60,14 @@ object CoherenceManagerWrapper { } class CoherenceManagerWrapper(params: CoherenceManagerWrapperParams, context: HasTileLinkLocations)(implicit p: Parameters) extends TLBusWrapper(params, params.name) { - val (temp, outwardNode, halt) = params.coherenceManager(context) + val (tempIn, tempOut, halt) = params.coherenceManager(context) + // TODO could remove temp if we could get access to .edges from InwardNodeHandle val viewNode = TLIdentityNode() - val inwardNode = temp :*= viewNode def busView: TLEdge = viewNode.edges.out.head + val inwardNode = tempIn :*= viewNode + + private def banked(node: TLOutwardNode): TLOutwardNode = + if (params.nBanks == 0) node else { TLTempNode() :=* BankBinder(params.nBanks, params.blockBytes) :*= node } + val outwardNode = banked(tempOut) } diff --git a/src/main/scala/subsystem/BusTopology.scala b/src/main/scala/subsystem/BusTopology.scala index 8f2b2fd4d0..c29c58b063 100644 --- a/src/main/scala/subsystem/BusTopology.scala +++ b/src/main/scala/subsystem/BusTopology.scala @@ -72,9 +72,9 @@ case class CoherentBusTopologyParams( ) extends TLBusWrapperTopology( instantiations = (if (l2.nBanks == 0) Nil else List( (MBUS, mbus), - (L2, CoherenceManagerWrapperParams(sbus.blockBytes, sbus.beatBytes, L2.name)(l2.coherenceManager)))), - connections = (if (l2.nBanks == 0) Nil else List( - (SBUS, L2, TLBusWrapperConnection.crossTo(NoCrossing)), - (L2, MBUS, TLBusWrapperConnection.crossTo(NoCrossing)) - )) + (L2, CoherenceManagerWrapperParams(sbus.blockBytes, sbus.beatBytes, l2.nBanks, L2.name)(l2.coherenceManager)))), + connections = if (l2.nBanks == 0) Nil else List( + (SBUS, L2, TLBusWrapperConnection(driveClockFromMaster = Some(true), nodeBinding = BIND_STAR)()), + (L2, MBUS, TLBusWrapperConnection(driveClockFromMaster = Some(true), nodeBinding = BIND_QUERY)()) + ) ) diff --git a/src/main/scala/subsystem/Configs.scala b/src/main/scala/subsystem/Configs.scala index 89bde9477c..739cd0063c 100644 --- a/src/main/scala/subsystem/Configs.scala +++ b/src/main/scala/subsystem/Configs.scala @@ -34,8 +34,7 @@ class BaseSubsystemConfig extends Config ((site, here, up) => { case MemoryBusKey => MemoryBusParams( beatBytes = site(XLen)/8, blockBytes = site(CacheBlockBytes), - replicatorMask = site(MultiChipMaskKey), - nInwardBanks = site(BankedL2Key).nBanks) + replicatorMask = site(MultiChipMaskKey)) case FrontBusKey => FrontBusParams( beatBytes = site(XLen)/8, blockBytes = site(CacheBlockBytes)) diff --git a/src/main/scala/subsystem/MemoryBus.scala b/src/main/scala/subsystem/MemoryBus.scala index 9ad927f9d3..d912d0bcf6 100644 --- a/src/main/scala/subsystem/MemoryBus.scala +++ b/src/main/scala/subsystem/MemoryBus.scala @@ -17,8 +17,7 @@ case class MemoryBusParams( dtsFrequency: Option[BigInt] = None, zeroDevice: Option[AddressSet] = None, errorDevice: Option[DevNullParams] = None, - replicatorMask: BigInt = 0, - nInwardBanks: Int = 0) + replicatorMask: BigInt = 0) extends HasTLBusParams with HasBuiltInDeviceParams with HasRegionReplicatorParams @@ -38,11 +37,9 @@ class MemoryBus(params: MemoryBusParams, name: String = "memory_bus")(implicit p { private val xbar = LazyModule(new TLXbar).suggestName(busName + "_xbar") private def replicate(node: TLInwardNode): TLInwardNode = - if (params.replicatorMask == 0) node else { node :=* RegionReplicator(params.replicatorMask) } - private def bank(node: TLInwardNode): TLInwardNode = - if (params.nInwardBanks == 0) node else { node :=* BankBinder(params.nInwardBanks, blockBytes) :*= TLTempNode() } - def inwardNode: TLInwardNode = this { bank(replicate(xbar.node)) } - def outwardNode: TLOutwardNode = ProbePicker() :*= xbar.node + if (params.replicatorMask == 0) node else { node :*=* RegionReplicator(params.replicatorMask) } + val inwardNode: TLInwardNode = replicate(xbar.node) + val outwardNode: TLOutwardNode = ProbePicker() :*= xbar.node def busView: TLEdge = xbar.node.edges.in.head val builtInDevices: BuiltInDevices = BuiltInDevices.attach(params, outwardNode) From 9b2762507c59ffff140b19c186496018b0857a4d Mon Sep 17 00:00:00 2001 From: Henry Cook Date: Wed, 1 Apr 2020 14:35:37 -0700 Subject: [PATCH 27/32] util: better combo of Location.selectDynamic w/ LocationMap.optional --- src/main/scala/util/Location.scala | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/scala/util/Location.scala b/src/main/scala/util/Location.scala index 305ff224cd..c936226411 100644 --- a/src/main/scala/util/Location.scala +++ b/src/main/scala/util/Location.scala @@ -6,6 +6,7 @@ import scala.language.dynamics import scala.collection.mutable.Map class Location[T](val name: String) extends Dynamic { + def selectDynamic[A](portname: String): Location[A] = new Location[A](s"${name}_${portname}") def applyDynamic[A](portname: String)(args: A*): (Location[A], A) = { require(args.size == 1, "Location: can't support multiple things at one port yet") (new Location[A](s"${name}_${portname}"), args.head) @@ -25,8 +26,8 @@ class LocationMap[T] private (val internalMap: Map[String, T]) extends Map[Locat // TODO override def default to provide specific exception on missing location? // TODO figure out how to be more clever about applying sub-type casting // for other the other Map trait methods - def required[L <: T](key: Location[L]): L = internalMap(key.name).asInstanceOf[L] - def optional[L <: T](key: Location[L]): Option[L] = internalMap.lift(key.name).map(_.asInstanceOf[L]) + def required[L <: T](key: Location[_]): L = internalMap(key.name).asInstanceOf[L] + def optional[L <: T](key: Location[_]): Option[L] = internalMap.lift(key.name).map(_.asInstanceOf[L]) } object LocationMap { From 63bbe15e0a754450f5b71ee4c089adc55126c786 Mon Sep 17 00:00:00 2001 From: Henry Cook Date: Thu, 2 Apr 2020 13:27:53 -0700 Subject: [PATCH 28/32] tilelink: TLBusWrapperConnection comment --- src/main/scala/tilelink/BusWrapper.scala | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/main/scala/tilelink/BusWrapper.scala b/src/main/scala/tilelink/BusWrapper.scala index 6c84fc2d5d..927750c914 100644 --- a/src/main/scala/tilelink/BusWrapper.scala +++ b/src/main/scala/tilelink/BusWrapper.scala @@ -140,6 +140,21 @@ object TLBusWrapperConnection { } } +/** TLBusWrapperConnection is a parameterization of a connection between two TLBusWrappers. + * It has the following serializable parameters: + * - xType: What type of TL clock crossing adapter to insert between the buses. + * The appropriate half of the crossing adapter ends up inside each bus. + * - driveClockFromMaster: if None, don't bind the bus's diplomatic clockGroupNode, + * otherwise have either the master or the slave bus bind the other one's clockGroupNode, + * assuming the inserted crossing type is not asynchronous. + * - nodeBinding: fine-grained control of multi-edge cardinality resolution for diplomatic bindings within the connection. + * - flipRendering: fine-grained control of the graphML rendering of the connection. + * If has the following non-serializable parameters: + * - slaveNodeView: programmatic control of the specific attachment point within the slave bus. + * - masterNodeView: programmatic control of the specific attachment point within the master bus. + * - injectNode: programmatic injection of additional nodes into the middle of the connection. + * The connect method applies all these parameters to create a diplomatic connection between two Location[TLBusWrapper]s. + */ class TLBusWrapperConnection (val xType: ClockCrossingType, val driveClockFromMaster: Option[Boolean], From be3d74c5a22aa0a9a410f974037a04ea6525a680 Mon Sep 17 00:00:00 2001 From: Henry Cook Date: Wed, 8 Apr 2020 09:40:46 -0700 Subject: [PATCH 29/32] subsystem: more bus topology comments --- src/main/scala/subsystem/BusTopology.scala | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/main/scala/subsystem/BusTopology.scala b/src/main/scala/subsystem/BusTopology.scala index c29c58b063..c1889c08d2 100644 --- a/src/main/scala/subsystem/BusTopology.scala +++ b/src/main/scala/subsystem/BusTopology.scala @@ -9,6 +9,7 @@ import freechips.rocketchip.util.Location // These fields control parameters of the five traditional tilelink bus wrappers. // They continue to exist for backwards compatiblity reasons but could eventually be retired. + case object SystemBusKey extends Field[SystemBusParams] case object FrontBusKey extends Field[FrontBusParams] case object PeripheryBusKey extends Field[PeripheryBusParams] @@ -20,6 +21,7 @@ case object MemoryBusKey extends Field[MemoryBusParams] // While they represent some tradtionally popular locations to attach devices, // there is no guarantee that they will exist in subsystems with // dynamically-configured topologies. + class TLBusWrapperLocation(name: String) extends Location[TLBusWrapper](name) case object SBUS extends TLBusWrapperLocation("subsystem_sbus") case object PBUS extends TLBusWrapperLocation("subsystem_pbus") @@ -28,20 +30,23 @@ case object MBUS extends TLBusWrapperLocation("subsystem_mbus") case object CBUS extends TLBusWrapperLocation("subsystem_cbus") case object L2 extends TLBusWrapperLocation("subsystem_l2") -// This case class parameterizes the subsystem in terms of the optional clock-crossings -// which are insertable between some of the five traditional tilelink bus wrappers. -// They continue to exist for backwards compatiblity reasons but could eventually be retired. +/** Parameterizes the subsystem in terms of optional clock-crossings + * that are insertable between some of the five traditional tilelink bus wrappers. + * This class exists for backwards compatiblity reasons but could eventually be retired + * in favor of manually filling in crossing types within each custom TLBusWrapperTopology. + */ case class SubsystemCrossingParams( sbusToCbusXType: ClockCrossingType = NoCrossing, cbusToPbusXType: ClockCrossingType = SynchronousCrossing(), fbusToSbusXType: ClockCrossingType = SynchronousCrossing() ) -// This case class provides a backwards-compatibility parameterization of a subsystem -// bus topology that contains the five traditional tilelink bus wrappers. +// Taken together these case classes provide a backwards-compatibility parameterization +// of a bus topology that contains the five traditional tilelink bus wrappers. // Users desiring a different topology are free to define a similar subclass, // or just populate an instance of TLBusWrapperTopology via some other mechanism. +/** Parameterization of a topology containing a single bus named "subsystem_sbus". */ case class JustOneBusTopologyParams( sbus: SystemBusParams, ) extends TLBusWrapperTopology( @@ -49,6 +54,7 @@ case class JustOneBusTopologyParams( connections = Nil ) +/** Parameterization of a topology containing three additional, optional buses for attaching MMIO devices. */ case class HierarchicalBusTopologyParams( pbus: PeripheryBusParams, fbus: FrontBusParams, @@ -65,6 +71,7 @@ case class HierarchicalBusTopologyParams( (FBUS, SBUS, TLBusWrapperConnection.crossFrom(xTypes.fbusToSbusXType))) ) +/** Parameterization of a topology containing a banked coherence manager and a bus for attaching memory devices. */ case class CoherentBusTopologyParams( sbus: SystemBusParams, // TODO remove this after better width propagation mbus: MemoryBusParams, From d92fdba308600e5453d9ae655115062327856523 Mon Sep 17 00:00:00 2001 From: Henry Cook Date: Wed, 15 Apr 2020 12:39:26 -0700 Subject: [PATCH 30/32] subsystem: put two CoherenceManagerInstantiationFns in CoherenceManagerWrapper object --- src/main/scala/subsystem/BankedL2Params.scala | 42 +++++++++++-------- src/main/scala/subsystem/Configs.scala | 7 ++-- 2 files changed, 28 insertions(+), 21 deletions(-) diff --git a/src/main/scala/subsystem/BankedL2Params.scala b/src/main/scala/subsystem/BankedL2Params.scala index 0149248298..717434c506 100644 --- a/src/main/scala/subsystem/BankedL2Params.scala +++ b/src/main/scala/subsystem/BankedL2Params.scala @@ -8,40 +8,34 @@ import freechips.rocketchip.diplomacy._ import freechips.rocketchip.interrupts._ import freechips.rocketchip.tilelink._ import freechips.rocketchip.util._ +import CoherenceManagerWrapper._ -// TODO: applies to all caches, for now +/** Global cache coherence granularity, which applies to all caches, for now. */ case object CacheBlockBytes extends Field[Int](64) +/** L2 Broadcast Hub configuration */ case object BroadcastKey extends Field(BroadcastParams()) -case object BankedL2Key extends Field(BankedL2Params()) -/** L2 Broadcast Hub configuration */ case class BroadcastParams( nTrackers: Int = 4, bufferless: Boolean = false) /** L2 memory subsystem configuration */ +case object BankedL2Key extends Field(BankedL2Params()) + case class BankedL2Params( nBanks: Int = 1, - coherenceManager: CoherenceManagerWrapper.CoherenceManagerInstantiationFn = { subsystem => - implicit val p = subsystem.p - val BroadcastParams(nTrackers, bufferless) = p(BroadcastKey) - val bh = LazyModule(new TLBroadcast(p(CacheBlockBytes), nTrackers, bufferless)) - val ss = TLSourceShrinker(nTrackers) - ss :*= bh.node - (bh.node, ss, None) - } + coherenceManager: CoherenceManagerInstantiationFn = broadcastManager ) { require (isPow2(nBanks) || nBanks == 0) } - case class CoherenceManagerWrapperParams( blockBytes: Int, beatBytes: Int, nBanks: Int, name: String) - (val coherenceManager: CoherenceManagerWrapper.CoherenceManagerInstantiationFn) + (val coherenceManager: CoherenceManagerInstantiationFn) extends HasTLBusParams with TLBusWrapperInstantiationLike { @@ -55,10 +49,6 @@ case class CoherenceManagerWrapperParams( } } -object CoherenceManagerWrapper { - type CoherenceManagerInstantiationFn = HasTileLinkLocations => (TLInwardNode, TLOutwardNode, Option[IntOutwardNode]) -} - class CoherenceManagerWrapper(params: CoherenceManagerWrapperParams, context: HasTileLinkLocations)(implicit p: Parameters) extends TLBusWrapper(params, params.name) { val (tempIn, tempOut, halt) = params.coherenceManager(context) @@ -71,3 +61,21 @@ class CoherenceManagerWrapper(params: CoherenceManagerWrapperParams, context: Ha if (params.nBanks == 0) node else { TLTempNode() :=* BankBinder(params.nBanks, params.blockBytes) :*= node } val outwardNode = banked(tempOut) } + +object CoherenceManagerWrapper { + type CoherenceManagerInstantiationFn = HasTileLinkLocations => (TLInwardNode, TLOutwardNode, Option[IntOutwardNode]) + + val broadcastManager: CoherenceManagerInstantiationFn = { context => + implicit val p = context.p + val BroadcastParams(nTrackers, bufferless) = p(BroadcastKey) + val bh = LazyModule(new TLBroadcast(p(CacheBlockBytes), nTrackers, bufferless)) + val ss = TLSourceShrinker(nTrackers) + ss :*= bh.node + (bh.node, ss, None) + } + + val incoherentManager: CoherenceManagerInstantiationFn = { _ => + val node = TLNameNode("no_coherence_manager") + (node, node, None) + } +} diff --git a/src/main/scala/subsystem/Configs.scala b/src/main/scala/subsystem/Configs.scala index 739cd0063c..eccd42832b 100644 --- a/src/main/scala/subsystem/Configs.scala +++ b/src/main/scala/subsystem/Configs.scala @@ -223,10 +223,9 @@ 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 = { subsystem => - val node = TLNameNode("no_coherence_manager") - (node, node, None) - }) + case BankedL2Key => up(BankedL2Key, site).copy( + coherenceManager = CoherenceManagerWrapper.incoherentManager + ) }) class WithRV32 extends Config((site, here, up) => { From 15bb0678efe0817c5f1a048dc5149e7d61d38379 Mon Sep 17 00:00:00 2001 From: Henry Cook Date: Wed, 15 Apr 2020 15:00:52 -0700 Subject: [PATCH 31/32] config: L2 should have outer data width driven by mbus --- src/main/scala/subsystem/BusTopology.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/subsystem/BusTopology.scala b/src/main/scala/subsystem/BusTopology.scala index c1889c08d2..3dae4b00b6 100644 --- a/src/main/scala/subsystem/BusTopology.scala +++ b/src/main/scala/subsystem/BusTopology.scala @@ -79,7 +79,7 @@ case class CoherentBusTopologyParams( ) extends TLBusWrapperTopology( instantiations = (if (l2.nBanks == 0) Nil else List( (MBUS, mbus), - (L2, CoherenceManagerWrapperParams(sbus.blockBytes, sbus.beatBytes, l2.nBanks, L2.name)(l2.coherenceManager)))), + (L2, CoherenceManagerWrapperParams(mbus.blockBytes, mbus.beatBytes, l2.nBanks, L2.name)(l2.coherenceManager)))), connections = if (l2.nBanks == 0) Nil else List( (SBUS, L2, TLBusWrapperConnection(driveClockFromMaster = Some(true), nodeBinding = BIND_STAR)()), (L2, MBUS, TLBusWrapperConnection(driveClockFromMaster = Some(true), nodeBinding = BIND_QUERY)()) From def1061b8ca7d36aaf8ead9c54c29cd5ae30b39f Mon Sep 17 00:00:00 2001 From: Henry Cook Date: Thu, 16 Apr 2020 14:28:57 -0700 Subject: [PATCH 32/32] subsystem: clean up handling of BuiltInDevices --- src/main/scala/subsystem/BankedL2Params.scala | 2 ++ src/main/scala/subsystem/BaseSubsystem.scala | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/scala/subsystem/BankedL2Params.scala b/src/main/scala/subsystem/BankedL2Params.scala index 717434c506..f6e1512953 100644 --- a/src/main/scala/subsystem/BankedL2Params.scala +++ b/src/main/scala/subsystem/BankedL2Params.scala @@ -4,6 +4,7 @@ package freechips.rocketchip.subsystem import chisel3.util.isPow2 import freechips.rocketchip.config._ +import freechips.rocketchip.devices.tilelink.BuiltInDevices import freechips.rocketchip.diplomacy._ import freechips.rocketchip.interrupts._ import freechips.rocketchip.tilelink._ @@ -56,6 +57,7 @@ class CoherenceManagerWrapper(params: CoherenceManagerWrapperParams, context: Ha val viewNode = TLIdentityNode() def busView: TLEdge = viewNode.edges.out.head val inwardNode = tempIn :*= viewNode + val builtInDevices = BuiltInDevices.none private def banked(node: TLOutwardNode): TLOutwardNode = if (params.nBanks == 0) node else { TLTempNode() :=* BankBinder(params.nBanks, params.blockBytes) :*= node } diff --git a/src/main/scala/subsystem/BaseSubsystem.scala b/src/main/scala/subsystem/BaseSubsystem.scala index 4f679b1bad..a72994850e 100644 --- a/src/main/scala/subsystem/BaseSubsystem.scala +++ b/src/main/scala/subsystem/BaseSubsystem.scala @@ -62,7 +62,7 @@ trait HasConfigurableTLNetworkTopology { this: HasTileLinkLocations => // Calling these functions populates tlBusWrapperLocationMap and connects the locations to each other. val topology = p(TLNetworkTopologyLocated(location)) - private val buses = topology.map(_.instantiate(this)) + topology.map(_.instantiate(this)) topology.foreach(_.connect(this)) // This is used lazily at DTS binding time to get a view of the network @@ -115,7 +115,7 @@ abstract class BaseSubsystem(val location: HierarchicalLocation = InSubsystem) lazy val logicalTreeNode = new SubsystemLogicalTreeNode() - buses.foreach { bus => + tlBusWrapperLocationMap.values.foreach { bus => val builtIn = bus.builtInDevices builtIn.errorOpt.foreach { error => LogicalModuleTree.add(logicalTreeNode, error.logicalTreeNode)