From 9cfbf2ef1ab645cf54176e57ce93681fadff62a0 Mon Sep 17 00:00:00 2001 From: Jerry Zhao Date: Tue, 31 Jan 2023 19:24:42 -0800 Subject: [PATCH] Support CloneCluster --- .../groundtest/GroundTestSubsystem.scala | 4 +- .../subsystem/BankedCoherenceParams.scala | 3 +- src/main/scala/subsystem/BusTopology.scala | 15 ++- src/main/scala/subsystem/Cluster.scala | 45 +++++--- src/main/scala/subsystem/Configs.scala | 101 +++++++++++------- src/main/scala/subsystem/HasElements.scala | 84 +++++++-------- src/main/scala/subsystem/HasTiles.scala | 19 ++-- .../scala/subsystem/RocketSubsystem.scala | 2 +- 8 files changed, 166 insertions(+), 107 deletions(-) diff --git a/src/main/scala/groundtest/GroundTestSubsystem.scala b/src/main/scala/groundtest/GroundTestSubsystem.scala index 81a40c681f0..cb43ec793d7 100644 --- a/src/main/scala/groundtest/GroundTestSubsystem.scala +++ b/src/main/scala/groundtest/GroundTestSubsystem.scala @@ -31,7 +31,7 @@ class GroundTestSubsystem(implicit p: Parameters) // No PLIC in ground test; so just sink the interrupts to nowhere IntSinkNode(IntSinkPortSimple()) :=* ibus.toPLIC - val tileStatusNodes = totalTiles.collect { case t: GroundTestTile => t.statusNode.makeSink() } + val tileStatusNodes = totalTiles.values.collect { case t: GroundTestTile => t.statusNode.makeSink() } val clintOpt = None val debugOpt = None val plicOpt = None @@ -41,6 +41,6 @@ class GroundTestSubsystem(implicit p: Parameters) class GroundTestSubsystemModuleImp[+L <: GroundTestSubsystem](_outer: L) extends BaseSubsystemModuleImp(_outer) { val success = IO(Output(Bool())) - val status = dontTouch(DebugCombiner(outer.tileStatusNodes.map(_.bundle))) + val status = dontTouch(DebugCombiner(outer.tileStatusNodes.map(_.bundle).toSeq)) success := outer.tileCeaseSinkNode.in.head._1.asUInt.andR } diff --git a/src/main/scala/subsystem/BankedCoherenceParams.scala b/src/main/scala/subsystem/BankedCoherenceParams.scala index a07bc229874..640ba8f3c15 100644 --- a/src/main/scala/subsystem/BankedCoherenceParams.scala +++ b/src/main/scala/subsystem/BankedCoherenceParams.scala @@ -24,7 +24,8 @@ case class BroadcastParams( filterFactory: TLBroadcast.ProbeFilterFactory = BroadcastFilter.factory) /** Coherence manager configuration */ -case object BankedCoherenceKey extends Field(BankedCoherenceParams()) +case object SubsystemBankedCoherenceKey extends Field(BankedCoherenceParams()) +case class ClusterBankedCoherenceKey(clusterId: Int) extends Field(BankedCoherenceParams(nBanks=0)) case class BankedCoherenceParams( nBanks: Int = 1, diff --git a/src/main/scala/subsystem/BusTopology.scala b/src/main/scala/subsystem/BusTopology.scala index 2a26c9dbc6e..cc8275d9925 100644 --- a/src/main/scala/subsystem/BusTopology.scala +++ b/src/main/scala/subsystem/BusTopology.scala @@ -109,11 +109,20 @@ case class CoherentBusTopologyParams( case class ClusterBusTopologyParams( clusterId: Int, csbus: SystemBusParams, - ccbus: PeripheryBusParams + ccbus: PeripheryBusParams, + coherence: BankedCoherenceParams ) extends TLBusWrapperTopology( instantiations = List( (SBUS, csbus), - (CBUS, ccbus)), - connections = Nil + (CBUS, ccbus)) ++ (if (coherence.nBanks == 0) Nil else List( + (MBUS, csbus), + (COH , CoherenceManagerWrapperParams(csbus.blockBytes, csbus.beatBytes, coherence.nBanks, COH.name)(coherence.coherenceManager)))), + connections = if (coherence.nBanks == 0) Nil else List( + (SBUS, COH , TLBusWrapperConnection(driveClockFromMaster = Some(true), nodeBinding = BIND_STAR)()), + (COH , MBUS, TLBusWrapperConnection.crossTo( + xType = NoCrossing, + driveClockFromMaster = Some(true), + nodeBinding = BIND_QUERY)) + ) ) diff --git a/src/main/scala/subsystem/Cluster.scala b/src/main/scala/subsystem/Cluster.scala index 325dd606227..74543b120e5 100644 --- a/src/main/scala/subsystem/Cluster.scala +++ b/src/main/scala/subsystem/Cluster.scala @@ -14,6 +14,7 @@ import freechips.rocketchip.tilelink._ import freechips.rocketchip.devices.debug.{TLDebugModule} import freechips.rocketchip.devices.tilelink._ import freechips.rocketchip.util._ +import scala.collection.immutable.ListMap case class ClustersLocated(loc: HierarchicalLocation) extends Field[Seq[CanAttachCluster]](Nil) @@ -45,12 +46,13 @@ class Cluster( val csbus = tlBusWrapperLocationMap(SBUS) // like the sbus in the base subsystem val ccbus = tlBusWrapperLocationMap(CBUS) // like the cbus in the base subsystem + val cmbus = tlBusWrapperLocationMap.lift(MBUS).getOrElse(csbus) csbus.clockGroupNode := allClockGroupsNode ccbus.clockGroupNode := allClockGroupsNode val slaveNode = ccbus.inwardNode - val masterNode = csbus.outwardNode + val masterNode = cmbus.outwardNode @@ -58,16 +60,17 @@ class Cluster( ibus.clockNode := csbus.fixedClockNode - lazy val msipNodes = totalTileIdList.map { i => (i, IntIdentityNode()) }.toMap - lazy val meipNodes = totalTileIdList.map { i => (i, IntIdentityNode()) }.toMap - lazy val seipNodes = totalTileIdList.map { i => (i, IntIdentityNode()) }.toMap - lazy val tileToPlicNodes = totalTileIdList.map { i => (i, IntIdentityNode()) }.toMap - lazy val debugNodes = totalTileIdList.map { i => (i, IntSyncIdentityNode()) }.toMap - lazy val nmiNodes = totalTiles.filter(_.tileParams.core.useNMI).map { t => (t.tileId, BundleBridgeIdentityNode[NMI]()) }.toMap - lazy val tileHartIdNodes = totalTileIdList.map { i => (i, BundleBridgeIdentityNode[UInt]()) }.toMap - lazy val tileResetVectorNodes = totalTileIdList.map { i => (i, BundleBridgeIdentityNode[UInt]()) }.toMap - lazy val traceCoreNodes = totalTileIdList.map { i => (i, BundleBridgeIdentityNode[TraceCoreInterface]()) }.toMap - lazy val traceNodes = totalTileIdList.map { i => (i, BundleBridgeIdentityNode[Vec[TracedInstruction]]()) }.toMap + lazy val msipNodes = totalTileIdList.map { i => (i, IntIdentityNode()) }.to(ListMap) + lazy val meipNodes = totalTileIdList.map { i => (i, IntIdentityNode()) }.to(ListMap) + lazy val seipNodes = totalTileIdList.map { i => (i, IntIdentityNode()) }.to(ListMap) + lazy val tileToPlicNodes = totalTileIdList.map { i => (i, IntIdentityNode()) }.to(ListMap) + lazy val debugNodes = totalTileIdList.map { i => (i, IntSyncIdentityNode()) }.to(ListMap) + lazy val nmiNodes = totalTiles.filter { case (i,t) => t.tileParams.core.useNMI } + .mapValues(_ => BundleBridgeIdentityNode[NMI]()).to(ListMap) + lazy val tileHartIdNodes = totalTileIdList.map { i => (i, BundleBridgeIdentityNode[UInt]()) }.to(ListMap) + lazy val tileResetVectorNodes = totalTileIdList.map { i => (i, BundleBridgeIdentityNode[UInt]()) }.to(ListMap) + lazy val traceCoreNodes = totalTileIdList.map { i => (i, BundleBridgeIdentityNode[TraceCoreInterface]()) }.to(ListMap) + lazy val traceNodes = totalTileIdList.map { i => (i, BundleBridgeIdentityNode[Vec[TracedInstruction]]()) }.to(ListMap) // TODO fix: shouldn't need to connect dummy notifications tileHaltXbarNode := NullIntSource() @@ -102,7 +105,7 @@ trait CanAttachCluster { def clusterParams: ClusterParams def crossingParams: ElementCrossingParamsLike - def instantiate(allClusterParams: Seq[ClusterParams], instantiatedClusters: Seq[ClusterPRCIDomain])(implicit p: Parameters): ClusterPRCIDomain = { + def instantiate(allClusterParams: Seq[ClusterParams], instantiatedClusters: ListMap[Int, ClusterPRCIDomain])(implicit p: Parameters): ClusterPRCIDomain = { val clockSinkParams = clusterParams.clockSinkParams.copy(name = Some(clusterParams.uniqueName)) val cluster_prci_domain = LazyModule(new ClusterPRCIDomain( clockSinkParams, crossingParams, clusterParams, PriorityMuxClusterIdFromSeq(allClusterParams))) @@ -209,3 +212,21 @@ case class ClusterAttachParams( clusterParams: ClusterParams, crossingParams: ElementCrossingParamsLike ) extends CanAttachCluster + +case class CloneClusterAttachParams( + sourceClusterId: Int, + cloneParams: CanAttachCluster +) extends CanAttachCluster { + def clusterParams = cloneParams.clusterParams + def crossingParams = cloneParams.crossingParams + + override def instantiate(allClusterParams: Seq[ClusterParams], instantiatedClusters: ListMap[Int, ClusterPRCIDomain])(implicit p: Parameters): ClusterPRCIDomain = { + require(instantiatedClusters.contains(sourceClusterId)) + val clockSinkParams = clusterParams.clockSinkParams.copy(name = Some(clusterParams.uniqueName)) + val cluster_prci_domain = CloneLazyModule( + new ClusterPRCIDomain(clockSinkParams, crossingParams, clusterParams, PriorityMuxClusterIdFromSeq(allClusterParams)), + instantiatedClusters(sourceClusterId) + ) + cluster_prci_domain + } +} diff --git a/src/main/scala/subsystem/Configs.scala b/src/main/scala/subsystem/Configs.scala index dd5a390f890..3cda835c82b 100644 --- a/src/main/scala/subsystem/Configs.scala +++ b/src/main/scala/subsystem/Configs.scala @@ -83,7 +83,7 @@ class WithCoherentBusTopology extends Config((site, here, up) => { driveClocksFromSBus = site(DriveClocksFromSBus)), CoherentBusTopologyParams( mbus = site(MemoryBusKey), - coherence = site(BankedCoherenceKey), + coherence = site(SubsystemBankedCoherenceKey), sbusToMbusXType = site(SbusToMbusXTypeKey), driveMBusClockFromSBus = site(DriveClocksFromSBus))) }) @@ -155,8 +155,8 @@ class WithNSmallCores( crossing: RocketCrossingParams = RocketCrossingParams(), location: HierarchicalLocation = InSubsystem ) extends Config((site, here, up) => { - case TilesLocated(InSubsystem) => { - val prev = up(TilesLocated(InSubsystem), site) + case TilesLocated(`location`) => { + val prev = up(TilesLocated(location), site) val idOffset = up(NumTiles) val small = RocketTileParams( core = RocketCoreParams(useVM = false, fpu = None), @@ -233,14 +233,19 @@ class WithCluster( ClusterBusTopologyParams( clusterId = clusterId, csbus = site(SystemBusKey), - ccbus = site(ControlBusKey).copy(errorDevice = None) + ccbus = site(ControlBusKey).copy(errorDevice = None), + coherence = site(ClusterBankedCoherenceKey(clusterId)) ) ) case PossibleTileLocations => up(PossibleTileLocations) :+ InCluster(clusterId) }) +class WithClusterBanks(clusterId: Int, nBanks: Int = 1) extends Config((site, here, up) => { + case ClusterBankedCoherenceKey(`clusterId`) => up(ClusterBankedCoherenceKey(clusterId)).copy(nBanks=nBanks) +}) + class WithNBanks(n: Int) extends Config((site, here, up) => { - case BankedCoherenceKey => up(BankedCoherenceKey, site).copy(nBanks = n) + case SubsystemBankedCoherenceKey => up(SubsystemBankedCoherenceKey, site).copy(nBanks = n) }) class WithNTrackersPerBank(n: Int) extends Config((site, here, up) => { @@ -249,7 +254,7 @@ class WithNTrackersPerBank(n: Int) extends Config((site, here, up) => { // This is the number of icache sets for all Rocket tiles class WithL1ICacheSets(sets: Int) extends Config((site, here, up) => { - case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { + case TilesLocated(location) => up(TilesLocated(location), site) map { case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy( icache = tp.tileParams.icache.map(_.copy(nSets = sets)))) case t => t @@ -258,7 +263,7 @@ class WithL1ICacheSets(sets: Int) extends Config((site, here, up) => { // This is the number of icache sets for all Rocket tiles class WithL1DCacheSets(sets: Int) extends Config((site, here, up) => { - case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { + case TilesLocated(location) => up(TilesLocated(location), site) map { case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy( dcache = tp.tileParams.dcache.map(_.copy(nSets = sets)))) case t => t @@ -266,7 +271,7 @@ class WithL1DCacheSets(sets: Int) extends Config((site, here, up) => { }) class WithL1ICacheWays(ways: Int) extends Config((site, here, up) => { - case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { + case TilesLocated(location) => up(TilesLocated(location), site) map { case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy( icache = tp.tileParams.icache.map(_.copy(nWays = ways)))) case t => t @@ -274,7 +279,7 @@ class WithL1ICacheWays(ways: Int) extends Config((site, here, up) => { }) class WithL1DCacheWays(ways: Int) extends Config((site, here, up) => { - case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { + case TilesLocated(location) => up(TilesLocated(location), site) map { case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy( dcache = tp.tileParams.dcache.map(_.copy(nWays = ways)))) case t => t @@ -302,7 +307,7 @@ class WithBufferlessBroadcastHub extends Config((site, here, up) => { * DO NOT use this configuration. */ class WithIncoherentTiles extends Config((site, here, up) => { - case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { + case TilesLocated(location) => up(TilesLocated(location), site) map { case tp: RocketTileAttachParams => tp.copy(crossingParams = tp.crossingParams.copy( master = tp.crossingParams.master match { case x: ElementMasterPortParams => x.copy(cork = Some(true)) @@ -310,14 +315,14 @@ class WithIncoherentTiles extends Config((site, here, up) => { })) case t => t } - case BankedCoherenceKey => up(BankedCoherenceKey, site).copy( + case SubsystemBankedCoherenceKey => up(SubsystemBankedCoherenceKey, site).copy( coherenceManager = CoherenceManagerWrapper.incoherentManager ) }) class WithRV32 extends Config((site, here, up) => { case XLen => 32 - case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { + case TilesLocated(location) => up(TilesLocated(location), site) map { case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy( core = tp.tileParams.core.copy( fpu = tp.tileParams.core.fpu.map(_.copy(fLen = 32)), @@ -327,7 +332,7 @@ class WithRV32 extends Config((site, here, up) => { }) class WithFP16 extends Config((site, here, up) => { - case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { + case TilesLocated(location) => up(TilesLocated(location), site) map { case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy( core = tp.tileParams.core.copy( fpu = tp.tileParams.core.fpu.map(_.copy(minFLen = 16)) @@ -338,7 +343,7 @@ class WithFP16 extends Config((site, here, up) => { }) class WithNonblockingL1(nMSHRs: Int) extends Config((site, here, up) => { - case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { + case TilesLocated(location) => up(TilesLocated(location), site) map { case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy( dcache = tp.tileParams.dcache.map(_.copy(nMSHRs = nMSHRs)))) case t => t @@ -346,7 +351,7 @@ class WithNonblockingL1(nMSHRs: Int) extends Config((site, here, up) => { }) class WithNBreakpoints(hwbp: Int) extends Config ((site, here, up) => { - case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { + case TilesLocated(location) => up(TilesLocated(location), site) map { case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy( core = tp.tileParams.core.copy(nBreakpoints = hwbp))) case t => t @@ -354,7 +359,7 @@ class WithNBreakpoints(hwbp: Int) extends Config ((site, here, up) => { }) class WithHypervisor(hext: Boolean = true) extends Config((site, here, up) => { - case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { + case TilesLocated(location) => up(TilesLocated(location), site) map { case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy( core = tp.tileParams.core.copy(useHypervisor = hext))) case t => t @@ -382,7 +387,7 @@ class WithRoccExample extends Config((site, here, up) => { }) class WithDefaultBtb extends Config((site, here, up) => { - case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { + case TilesLocated(location) => up(TilesLocated(location), site) map { case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy( btb = Some(BTBParams()))) case t => t @@ -390,7 +395,7 @@ class WithDefaultBtb extends Config((site, here, up) => { }) class WithFastMulDiv extends Config((site, here, up) => { - case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { + case TilesLocated(location) => up(TilesLocated(location), site) map { case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy( core = tp.tileParams.core.copy(mulDiv = Some( MulDivParams(mulUnroll = 8, mulEarlyOut = (site(XLen) > 32), divEarlyOut = true))))) @@ -399,7 +404,7 @@ class WithFastMulDiv extends Config((site, here, up) => { }) class WithoutMulDiv extends Config((site, here, up) => { - case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { + case TilesLocated(location) => up(TilesLocated(location), site) map { case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy( core = tp.tileParams.core.copy(mulDiv = None))) case t => t @@ -407,7 +412,7 @@ class WithoutMulDiv extends Config((site, here, up) => { }) class WithoutFPU extends Config((site, here, up) => { - case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { + case TilesLocated(location) => up(TilesLocated(location), site) map { case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy( core = tp.tileParams.core.copy(fpu = None))) case t => t @@ -415,7 +420,7 @@ class WithoutFPU extends Config((site, here, up) => { }) class WithFPUWithoutDivSqrt extends Config((site, here, up) => { - case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { + case TilesLocated(location) => up(TilesLocated(location), site) map { case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy( core = tp.tileParams.core.copy(fpu = tp.tileParams.core.fpu.map(_.copy(divSqrt = false))))) case t => t @@ -423,7 +428,7 @@ class WithFPUWithoutDivSqrt extends Config((site, here, up) => { }) class WithBitManip extends Config((site, here, up) => { - case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { + case TilesLocated(location) => up(TilesLocated(location), site) map { case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy( core = tp.tileParams.core.copy(useBitManip = true))) case t => t @@ -431,7 +436,7 @@ class WithBitManip extends Config((site, here, up) => { }) class WithBitManipCrypto extends Config((site, here, up) => { - case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { + case TilesLocated(location) => up(TilesLocated(location), site) map { case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy( core = tp.tileParams.core.copy(useBitManipCrypto = true))) case t => t @@ -439,7 +444,7 @@ class WithBitManipCrypto extends Config((site, here, up) => { }) class WithCryptoNIST extends Config((site, here, up) => { - case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { + case TilesLocated(location) => up(TilesLocated(location), site) map { case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy( core = tp.tileParams.core.copy(useCryptoNIST = true))) case t => t @@ -447,7 +452,7 @@ class WithCryptoNIST extends Config((site, here, up) => { }) class WithCryptoSM extends Config((site, here, up) => { - case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { + case TilesLocated(location) => up(TilesLocated(location), site) map { case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy( core = tp.tileParams.core.copy(useCryptoSM = true))) case t => t @@ -463,7 +468,7 @@ class WithClockGateModel(file: String = "/vsrc/EICG_wrapper.v") extends Config(( }) class WithSynchronousRocketTiles extends Config((site, here, up) => { - case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { + case TilesLocated(location) => up(TilesLocated(location), site) map { case tp: RocketTileAttachParams => tp.copy(crossingParams = tp.crossingParams.copy( crossingType = SynchronousCrossing())) case t => t @@ -471,7 +476,7 @@ class WithSynchronousRocketTiles extends Config((site, here, up) => { }) class WithAsynchronousRocketTiles(depth: Int, sync: Int) extends Config((site, here, up) => { - case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { + case TilesLocated(location) => up(TilesLocated(location), site) map { case tp: RocketTileAttachParams => tp.copy(crossingParams = tp.crossingParams.copy( crossingType = AsynchronousCrossing())) case t => t @@ -479,7 +484,7 @@ class WithAsynchronousRocketTiles(depth: Int, sync: Int) extends Config((site, h }) class WithRationalRocketTiles extends Config((site, here, up) => { - case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { + case TilesLocated(location) => up(TilesLocated(location), site) map { case tp: RocketTileAttachParams => tp.copy(crossingParams = tp.crossingParams.copy( crossingType = RationalCrossing())) case t => t @@ -489,7 +494,6 @@ class WithRationalRocketTiles extends Config((site, here, up) => { class WithEdgeDataBits(dataBits: Int) extends Config((site, here, up) => { case MemoryBusKey => up(MemoryBusKey, site).copy(beatBytes = dataBits/8) case ExtIn => up(ExtIn, site).map(_.copy(beatBytes = dataBits/8)) - }) class WithJtagDTM extends Config ((site, here, up) => { @@ -571,7 +575,7 @@ class WithNoSlavePort extends Config((site, here, up) => { }) class WithScratchpadsOnly extends Config((site, here, up) => { - case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { + case TilesLocated(location) => up(TilesLocated(location), site) map { case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy( core = tp.tileParams.core.copy(useVM = false), dcache = tp.tileParams.dcache.map(_.copy( @@ -630,16 +634,41 @@ class WithDontDriveBusClocksFromSBus extends Config((site, here, up) => { case DriveClocksFromSBus => false }) -class WithCloneRocketTiles(n: Int = 1, cloneHart: Int = 0, overrideIdOffset: Option[Int] = None) extends Config((site, here, up) => { - case TilesLocated(InSubsystem) => { - val prev = up(TilesLocated(InSubsystem), site) - val idOffset = overrideIdOffset.getOrElse(prev.size) - val tileAttachParams = prev(cloneHart).asInstanceOf[RocketTileAttachParams] +class WithCloneRocketTiles( + n: Int = 1, + cloneTileId: Int = 0, + location: HierarchicalLocation = InSubsystem, + cloneLocation: HierarchicalLocation = InSubsystem +) extends Config((site, here, up) => { + case TilesLocated(`location`) => { + val prev = up(TilesLocated(location), site) + val idOffset = up(NumTiles) + val tileAttachParams = up(TilesLocated(cloneLocation)).find(_.tileParams.tileId == cloneTileId) + .get.asInstanceOf[RocketTileAttachParams] (0 until n).map { i => - CloneTileAttachParams(cloneHart, tileAttachParams.copy( + CloneTileAttachParams(cloneTileId, tileAttachParams.copy( tileParams = tileAttachParams.tileParams.copy(tileId = i + idOffset) )) } ++ prev } + case NumTiles => up(NumTiles) + n }) +class WithCloneCluster( + clusterId: Int, + cloneClusterId: Int = 0, + location: HierarchicalLocation = InSubsystem, + cloneLocation: HierarchicalLocation = InSubsystem +) extends Config((site, here, up) => { + case ClustersLocated(`location`) => { + val prev = up(ClustersLocated(location)) + val clusterAttachParams = up(ClustersLocated(cloneLocation)).find(_.clusterParams.clusterId == cloneClusterId) + .get.asInstanceOf[ClusterAttachParams] + prev :+ CloneClusterAttachParams( + cloneClusterId, + clusterAttachParams.copy(clusterParams = clusterAttachParams.clusterParams.copy(clusterId = clusterId)) + ) + } + case TLNetworkTopologyLocated(InCluster(`clusterId`)) => site(TLNetworkTopologyLocated(InCluster(cloneClusterId))) + case PossibleTileLocations => up(PossibleTileLocations) :+ InCluster(clusterId) +}) diff --git a/src/main/scala/subsystem/HasElements.scala b/src/main/scala/subsystem/HasElements.scala index 0993f5347dd..6055e21f654 100644 --- a/src/main/scala/subsystem/HasElements.scala +++ b/src/main/scala/subsystem/HasElements.scala @@ -14,6 +14,7 @@ import freechips.rocketchip.tilelink._ import freechips.rocketchip.prci.{ClockGroup, ResetCrossingType, ClockGroupNode} import freechips.rocketchip.util._ import freechips.rocketchip.rocket.{TracedInstruction} +import scala.collection.immutable.ListMap /** A default implementation of parameterizing the connectivity of the port where the tile is the master. * Optional timing buffers and/or an optional CacheCork can be inserted in the interconnect's clock domain. @@ -66,28 +67,28 @@ trait InstantiatesElements { this: LazyModule with Attachable => val tileCrossingTypes: Seq[ClockCrossingType] = tileAttachParams.map(_.crossingParams.crossingType) /** The actual list of instantiated tiles in this block. */ - val tile_prci_domains: Seq[TilePRCIDomain[_]] = tileAttachParams.foldLeft(Seq[TilePRCIDomain[_]]()) { - case (instantiated, params) => instantiated :+ params.instantiate(tileParams, instantiated)(p) + val tile_prci_domains: ListMap[Int, TilePRCIDomain[_]] = tileAttachParams.foldLeft(ListMap[Int, TilePRCIDomain[_]]()) { + case (instantiated, params) => instantiated + (params.tileParams.tileId -> params.instantiate(tileParams, instantiated)(p)) } val clusterAttachParams: Seq[CanAttachCluster] = p(ClustersLocated(location)).sortBy(_.clusterParams.clusterId) val clusterParams: Seq[ClusterParams] = clusterAttachParams.map(_.clusterParams) val clusterCrossingTypes: Seq[ClockCrossingType] = clusterAttachParams.map(_.crossingParams.crossingType) - val cluster_prci_domains: Seq[ClusterPRCIDomain] = clusterAttachParams.foldLeft(Seq[ClusterPRCIDomain]()) { - case (instantiated, params) => instantiated :+ params.instantiate(clusterParams, instantiated)(p) + val cluster_prci_domains: ListMap[Int, ClusterPRCIDomain] = clusterAttachParams.foldLeft(ListMap[Int, ClusterPRCIDomain]()) { + case (instantiated, params) => instantiated + (params.clusterParams.clusterId -> params.instantiate(clusterParams, instantiated)(p)) } - val element_prci_domains: Seq[ElementPRCIDomain[_]] = tile_prci_domains ++ cluster_prci_domains + val element_prci_domains: Seq[ElementPRCIDomain[_]] = tile_prci_domains.values.toSeq ++ cluster_prci_domains.values.toSeq - val leafTiles: Seq[BaseTile] = tile_prci_domains.map(_.element.asInstanceOf[BaseTile]).sortBy(_.tileId) - val totalTiles: Seq[BaseTile] = (leafTiles ++ cluster_prci_domains.map(_.element.asInstanceOf[Cluster].totalTiles).flatten).sortBy(_.tileId) + val leafTiles: ListMap[Int, BaseTile] = tile_prci_domains.mapValues(_.element.asInstanceOf[BaseTile]).to(ListMap) + val totalTiles: ListMap[Int, BaseTile] = (leafTiles ++ cluster_prci_domains.values.map(_.element.totalTiles).flatten) // Helper functions for accessing certain parameters that are popular to refer to in subsystem code def nLeafTiles: Int = leafTiles.size def nTotalTiles: Int = totalTiles.size - def leafTileIdList: Seq[Int] = leafTiles.map(_.tileId) - def totalTileIdList: Seq[Int] = totalTiles.map(_.tileId) - def localIntCounts: Seq[Int] = totalTiles.map(_.tileParams.core.nLocalInterrupts) + def leafTileIdList: Seq[Int] = leafTiles.keys.toSeq.sorted + def totalTileIdList: Seq[Int] = totalTiles.keys.toSeq.sorted + def localIntCounts: ListMap[Int, Int] = totalTiles.mapValues(_.tileParams.core.nLocalInterrupts).to(ListMap) require(totalTileIdList.distinct.size == totalTiles.size, s"Every tile must be statically assigned a unique id, but got:\n${totalTileIdList}") } @@ -98,12 +99,11 @@ trait HasElements extends DefaultElementContextType implicit val p: Parameters // connect all the tiles to interconnect attachment points made available in this subsystem context - tileAttachParams.zip(tile_prci_domains).foreach { case (params, td) => - params.connect(td.asInstanceOf[TilePRCIDomain[params.TileType]], this.asInstanceOf[params.TileContextType]) + tileAttachParams.foreach { params => + params.connect(tile_prci_domains(params.tileParams.tileId).asInstanceOf[TilePRCIDomain[params.TileType]], this.asInstanceOf[params.TileContextType]) } - - clusterAttachParams.zip(cluster_prci_domains).foreach { case (params, cd) => - params.connect(cd.asInstanceOf[ClusterPRCIDomain], this.asInstanceOf[params.ClusterContextType]) + clusterAttachParams.foreach { params => + params.connect(cluster_prci_domains(params.clusterParams.clusterId).asInstanceOf[ClusterPRCIDomain], this.asInstanceOf[params.ClusterContextType]) } } @@ -142,16 +142,16 @@ trait DefaultElementContextType extends Attachable with HasTileNotificationSinks { this: LazyModule with Attachable => - val msipNodes: Map[Int, IntNode] - val meipNodes: Map[Int, IntNode] - val seipNodes: Map[Int, IntNode] - val tileToPlicNodes: Map[Int, IntNode] - val debugNodes: Map[Int, IntSyncNode] - val nmiNodes: Map[Int, BundleBridgeNode[NMI]] - val tileHartIdNodes: Map[Int, BundleBridgeNode[UInt]] - val tileResetVectorNodes: Map[Int, BundleBridgeNode[UInt]] - val traceCoreNodes: Map[Int, BundleBridgeNode[TraceCoreInterface]] - val traceNodes: Map[Int, BundleBridgeNode[Vec[TracedInstruction]]] + val msipNodes: ListMap[Int, IntNode] + val meipNodes: ListMap[Int, IntNode] + val seipNodes: ListMap[Int, IntNode] + val tileToPlicNodes: ListMap[Int, IntNode] + val debugNodes: ListMap[Int, IntSyncNode] + val nmiNodes: ListMap[Int, BundleBridgeNode[NMI]] + val tileHartIdNodes: ListMap[Int, BundleBridgeNode[UInt]] + val tileResetVectorNodes: ListMap[Int, BundleBridgeNode[UInt]] + val traceCoreNodes: ListMap[Int, BundleBridgeNode[TraceCoreInterface]] + val traceNodes: ListMap[Int, BundleBridgeNode[Vec[TracedInstruction]]] } /** This trait provides the tile attachment context for the root (outermost) subsystem */ @@ -164,47 +164,45 @@ trait HasElementsRootContext val plicOpt: Option[TLPLIC] val debugOpt: Option[TLDebugModule] - val msipNodes: Map[Int, IntNode] = (0 until nTotalTiles).map { i => + val msipNodes: ListMap[Int, IntNode] = (0 until nTotalTiles).map { i => (i, IntEphemeralNode() := clintOpt.map(_.intnode).getOrElse(NullIntSource(sources = CLINTConsts.ints))) - }.toMap + }.to(ListMap) val meipIONode = Option.when(plicOpt.isEmpty)(IntNexusNode( sourceFn = { _ => IntSourcePortParameters(Seq(IntSourceParameters(1))) }, sinkFn = { _ => IntSinkPortParameters(Seq(IntSinkParameters())) }, outputRequiresInput = false, inputRequiresOutput = false)) - val meipNodes: Map[Int, IntNode] = (0 until nTotalTiles).map { i => + val meipNodes: ListMap[Int, IntNode] = (0 until nTotalTiles).map { i => (i, IntEphemeralNode() := plicOpt.map(_.intnode).getOrElse(meipIONode.get)) - }.toMap + }.to(ListMap) val seipIONode = Option.when(plicOpt.isEmpty)(IntNexusNode( sourceFn = { _ => IntSourcePortParameters(Seq(IntSourceParameters(1))) }, sinkFn = { _ => IntSinkPortParameters(Seq(IntSinkParameters())) }, outputRequiresInput = false, inputRequiresOutput = false)) - val seipNodes: Map[Int, IntNode] = totalTiles.filter(_.tileParams.core.hasSupervisorMode) - .map(_.tileId).map { i => - (i, IntEphemeralNode() := plicOpt.map(_.intnode).getOrElse(seipIONode.get)) - }.toMap + val seipNodes: ListMap[Int, IntNode] = totalTiles.filter { case (_, t) => t.tileParams.core.hasSupervisorMode } + .mapValues( _ => IntEphemeralNode() := plicOpt.map(_.intnode).getOrElse(seipIONode.get)).to(ListMap) - val tileToPlicNodes: Map[Int, IntNode] = (0 until nTotalTiles).map { i => + val tileToPlicNodes: ListMap[Int, IntNode] = (0 until nTotalTiles).map { i => plicOpt.map(o => (i, o.intnode :=* IntEphemeralNode())) - }.flatten.toMap + }.flatten.to(ListMap) - val debugNodes: Map[Int, IntSyncNode] = (0 until nTotalTiles).map { i => + val debugNodes: ListMap[Int, IntSyncNode] = (0 until nTotalTiles).map { i => (i, IntSyncIdentityNode()) - }.toMap + }.to(ListMap) debugNodes.foreach { case (hartid, node) => node := debugOpt.map(_.intnode).getOrElse(IntSyncCrossingSource() := NullIntSource()) } - val nmiHarts = totalTiles.filter(_.tileParams.core.useNMI).map(_.tileId) - val nmiIONodes = nmiHarts.map { i => (i, BundleBridgeSource[NMI]()) }.toMap - val nmiNodes: Map[Int, BundleBridgeNode[NMI]] = nmiIONodes.map { case (i, n) => + val nmiHarts = totalTiles.filter { case (_, t) => t.tileParams.core.useNMI }.keys + val nmiIONodes = nmiHarts.map { i => (i, BundleBridgeSource[NMI]()) }.to(ListMap) + val nmiNodes: ListMap[Int, BundleBridgeNode[NMI]] = nmiIONodes.map { case (i, n) => (i, BundleBridgeEphemeralNode[NMI]() := n) - }.toMap + }.to(ListMap) - val traceCoreNodes: Map[Int, BundleBridgeSink[TraceCoreInterface]] = (0 until nTotalTiles).map { i => (i, BundleBridgeSink[TraceCoreInterface]()) }.toMap - val traceNodes: Map[Int, BundleBridgeSink[Vec[TracedInstruction]]] = (0 until nTotalTiles).map { i => (i, BundleBridgeSink[Vec[TracedInstruction]]()) }.toMap + val traceCoreNodes: ListMap[Int, BundleBridgeSink[TraceCoreInterface]] = (0 until nTotalTiles).map { i => (i, BundleBridgeSink[TraceCoreInterface]()) }.to(ListMap) + val traceNodes: ListMap[Int, BundleBridgeSink[Vec[TracedInstruction]]] = (0 until nTotalTiles).map { i => (i, BundleBridgeSink[Vec[TracedInstruction]]()) }.to(ListMap) } diff --git a/src/main/scala/subsystem/HasTiles.scala b/src/main/scala/subsystem/HasTiles.scala index 365fd60d42a..37ec628475a 100644 --- a/src/main/scala/subsystem/HasTiles.scala +++ b/src/main/scala/subsystem/HasTiles.scala @@ -14,6 +14,7 @@ import freechips.rocketchip.tilelink._ import freechips.rocketchip.prci._ import freechips.rocketchip.util._ import freechips.rocketchip.rocket.{TracedInstruction} +import scala.collection.immutable.ListMap /** Entry point for Config-uring the presence of Tiles */ case class TilesLocated(loc: HierarchicalLocation) extends Field[Seq[CanAttachTile]](Nil) @@ -52,9 +53,9 @@ case object HasTilesExternalResetVectorKey extends Field[Boolean](true) */ trait HasTileInputConstants { this: LazyModule with Attachable with InstantiatesElements => /** tileHartIdNode is used to collect publishers and subscribers of hartids. */ - val tileHartIdNodes: Map[Int, BundleBridgeEphemeralNode[UInt]] = (0 until nTotalTiles).map { i => + val tileHartIdNodes: ListMap[Int, BundleBridgeEphemeralNode[UInt]] = (0 until nTotalTiles).map { i => (i, BundleBridgeEphemeralNode[UInt]()) - }.toMap + }.to(ListMap) /** tileHartIdNexusNode is a BundleBridgeNexus that collects dynamic hart prefixes. * @@ -81,9 +82,9 @@ trait HasTileInputConstants { this: LazyModule with Attachable with Instantiates // TODO: Replace the DebugModuleHartSelFuncs config key with logic to consume the dynamic hart IDs /** tileResetVectorNode is used to collect publishers and subscribers of tile reset vector addresses. */ - val tileResetVectorNodes: Map[Int, BundleBridgeEphemeralNode[UInt]] = (0 until nTotalTiles).map { i => + val tileResetVectorNodes: ListMap[Int, BundleBridgeEphemeralNode[UInt]] = (0 until nTotalTiles).map { i => (i, BundleBridgeEphemeralNode[UInt]()) - }.toMap + }.to(ListMap) /** tileResetVectorNexusNode is a BundleBridgeNexus that accepts a single reset vector source, and broadcasts it to all tiles. */ val tileResetVectorNexusNode = BundleBroadcast[UInt]( @@ -154,7 +155,7 @@ trait CanAttachTile { def crossingParams: ElementCrossingParamsLike /** Narrow waist through which all tiles are intended to pass while being instantiated. */ - def instantiate(allTileParams: Seq[TileParams], instantiatedTiles: Seq[TilePRCIDomain[_]])(implicit p: Parameters): TilePRCIDomain[TileType] = { + def instantiate(allTileParams: Seq[TileParams], instantiatedTiles: ListMap[Int, TilePRCIDomain[_]])(implicit p: Parameters): TilePRCIDomain[TileType] = { val clockSinkParams = tileParams.clockSinkParams.copy(name = Some(tileParams.uniqueName)) val tile_prci_domain = LazyModule(new TilePRCIDomain[TileType](clockSinkParams, crossingParams) { self => val element = self.element_reset_domain { LazyModule(tileParams.instantiate(crossingParams, PriorityMuxHartIdFromSeq(allTileParams))) } @@ -292,7 +293,7 @@ trait CanAttachTile { } case class CloneTileAttachParams( - sourceHart: Int, + sourceTileId: Int, cloneParams: CanAttachTile ) extends CanAttachTile { type TileType = cloneParams.TileType @@ -301,14 +302,14 @@ case class CloneTileAttachParams( def tileParams = cloneParams.tileParams def crossingParams = cloneParams.crossingParams - override def instantiate(allTileParams: Seq[TileParams], instantiatedTiles: Seq[TilePRCIDomain[_]])(implicit p: Parameters): TilePRCIDomain[TileType] = { - require(sourceHart < instantiatedTiles.size) + override def instantiate(allTileParams: Seq[TileParams], instantiatedTiles: ListMap[Int, TilePRCIDomain[_]])(implicit p: Parameters): TilePRCIDomain[TileType] = { + require(instantiatedTiles.contains(sourceTileId)) val clockSinkParams = tileParams.clockSinkParams.copy(name = Some(tileParams.uniqueName)) val tile_prci_domain = CloneLazyModule( new TilePRCIDomain[TileType](clockSinkParams, crossingParams) { self => val element = self.element_reset_domain { LazyModule(tileParams.instantiate(crossingParams, PriorityMuxHartIdFromSeq(allTileParams))) } }, - instantiatedTiles(sourceHart).asInstanceOf[TilePRCIDomain[TileType]] + instantiatedTiles(sourceTileId).asInstanceOf[TilePRCIDomain[TileType]] ) tile_prci_domain } diff --git a/src/main/scala/subsystem/RocketSubsystem.scala b/src/main/scala/subsystem/RocketSubsystem.scala index ea8c9ef36d9..2d3080cf442 100644 --- a/src/main/scala/subsystem/RocketSubsystem.scala +++ b/src/main/scala/subsystem/RocketSubsystem.scala @@ -26,7 +26,7 @@ case class RocketTileAttachParams( trait HasRocketTiles { this: BaseSubsystem with InstantiatesElements => - val rocketTiles = totalTiles.collect { case r: RocketTile => r } + val rocketTiles = totalTiles.values.collect { case r: RocketTile => r } def coreMonitorBundles = (rocketTiles map { t => t.module.core.rocketImpl.coreMonitorBundle