Merge pull request #713 from ucb-bar/better-bus-freq-spec

Better Bus Frequency Specification
This commit is contained in:
David Biancolin
2020-11-09 19:18:44 -08:00
committed by GitHub
8 changed files with 99 additions and 18 deletions

View File

@@ -248,6 +248,12 @@ jobs:
group-key: "group-cores"
project-key: "chipyard-sodor"
timeout: "30m"
chipyard-multiclock-rocket-run-tests:
executor: main-env
steps:
- run-tests:
group-key: "group-cores"
project-key: "chipyard-multiclock-rocket"
chipyard-dmirocket-run-tests:
executor: main-env
steps:

View File

@@ -47,7 +47,7 @@ LOCAL_FIRESIM_DIR=$LOCAL_CHIPYARD_DIR/sims/firesim/sim
# key value store to get the build groups
declare -A grouping
grouping["group-cores"]="chipyard-cva6 chipyard-rocket chipyard-hetero chipyard-boom chipyard-sodor chipyard-digitaltop"
grouping["group-cores"]="chipyard-cva6 chipyard-rocket chipyard-hetero chipyard-boom chipyard-sodor chipyard-digitaltop chipyard-multiclock-rocket"
grouping["group-peripherals"]="chipyard-dmirocket chipyard-blkdev chipyard-spiflashread chipyard-spiflashwrite chipyard-mmios chipyard-lbwif"
grouping["group-accels"]="chipyard-nvdla chipyard-sha3 chipyard-hwacha chipyard-gemmini chipyard-streaming-fir chipyard-streaming-passthrough"
grouping["group-tracegen"]="tracegen tracegen-boom"
@@ -75,6 +75,7 @@ mapping["tracegen"]=" CONFIG=NonBlockingTraceGenL2Config"
mapping["tracegen-boom"]=" CONFIG=BoomTraceGenConfig"
mapping["chipyard-nvdla"]=" CONFIG=SmallNVDLARocketConfig"
mapping["chipyard-sodor"]=" CONFIG=Sodor5StageConfig"
mapping["chipyard-multiclock-rocket"]=" CONFIG=MulticlockRocketConfig"
mapping["firesim"]="SCALA_TEST=firesim.firesim.RocketNICF1Tests"
mapping["firesim-multiclock"]="SCALA_TEST=firesim.firesim.RocketMulticlockF1Tests"

View File

@@ -1,5 +1,6 @@
package chipyard.config
import scala.util.matching.Regex
import chisel3._
import chisel3.util.{log2Up}
@@ -11,6 +12,7 @@ import freechips.rocketchip.devices.debug.{Debug, ExportDebug, DebugModuleKey, D
import freechips.rocketchip.groundtest.{GroundTestSubsystem}
import freechips.rocketchip.tile._
import freechips.rocketchip.rocket.{RocketCoreParams, MulDivParams, DCacheParams, ICacheParams}
import freechips.rocketchip.tilelink.{HasTLBusParams}
import freechips.rocketchip.util.{AsyncResetReg, Symmetric}
import freechips.rocketchip.prci._
@@ -183,6 +185,34 @@ class WithPeripheryBusFrequencyAsDefault extends Config((site, here, up) => {
case DefaultClockFrequencyKey => (site(PeripheryBusKey).dtsFrequency.get / (1000 * 1000)).toDouble
})
class WithSystemBusFrequencyAsDefault extends Config((site, here, up) => {
case DefaultClockFrequencyKey => (site(SystemBusKey).dtsFrequency.get / (1000 * 1000)).toDouble
})
class BusFrequencyAssignment[T <: HasTLBusParams](re: Regex, key: Field[T]) extends Config((site, here, up) => {
case ClockFrequencyAssignersKey => up(ClockFrequencyAssignersKey, site) ++
Seq((cName: String) => site(key).dtsFrequency.flatMap { f =>
re.findFirstIn(cName).map {_ => (f / (1000 * 1000)).toDouble }
})
})
/**
* Provides a diplomatic frequency for all clock sinks with an unspecified
* frequency bound to each bus.
*
* For example, the L2 cache, when bound to the sbus, receives a separate
* clock that appears as "subsystem_sbus_<num>". This fragment ensures that
* clock requests the same frequency as the sbus itself.
*/
class WithInheritBusFrequencyAssignments extends Config(
new BusFrequencyAssignment("subsystem_sbus_\\d+".r, SystemBusKey) ++
new BusFrequencyAssignment("subsystem_pbus_\\d+".r, PeripheryBusKey) ++
new BusFrequencyAssignment("subsystem_cbus_\\d+".r, ControlBusKey) ++
new BusFrequencyAssignment("subsystem_fbus_\\d+".r, FrontBusKey) ++
new BusFrequencyAssignment("subsystem_mbus_\\d+".r, MemoryBusKey)
)
/**
* Mixins to specify crossing types between the 5 traditional TL buses
*
@@ -212,16 +242,19 @@ class WithFbusToSbusCrossingType(xType: ClockCrossingType) extends Config((site,
* up the diplomatic graph to the clock sources.
*/
class WithPeripheryBusFrequency(freqMHz: Double) extends Config((site, here, up) => {
case PeripheryBusKey => up(PeripheryBusKey).copy(dtsFrequency = Some(BigInt((freqMHz * 1e6).toLong)))
case PeripheryBusKey => up(PeripheryBusKey, site).copy(dtsFrequency = Some(BigInt((freqMHz * 1e6).toLong)))
})
class WithMemoryBusFrequency(freqMHz: Double) extends Config((site, here, up) => {
case MemoryBusKey => up(MemoryBusKey).copy(dtsFrequency = Some(BigInt((freqMHz * 1e6).toLong)))
case MemoryBusKey => up(MemoryBusKey, site).copy(dtsFrequency = Some(BigInt((freqMHz * 1e6).toLong)))
})
class WithSystemBusFrequency(freqMHz: Double) extends Config((site, here, up) => {
case SystemBusKey => up(SystemBusKey).copy(dtsFrequency = Some(BigInt((freqMHz * 1e6).toLong)))
case SystemBusKey => up(SystemBusKey, site).copy(dtsFrequency = Some(BigInt((freqMHz * 1e6).toLong)))
})
class WithFrontBusFrequency(freqMHz: Double) extends Config((site, here, up) => {
case FrontBusKey => up(FrontBusKey, site).copy(dtsFrequency = Some(BigInt((freqMHz * 1e6).toLong)))
})
class WithControlBusFrequency(freqMHz: Double) extends Config((site, here, up) => {
case ControlBusKey => up(ControlBusKey).copy(dtsFrequency = Some(BigInt((freqMHz * 1e6).toLong)))
case ControlBusKey => up(ControlBusKey, site).copy(dtsFrequency = Some(BigInt((freqMHz * 1e6).toLong)))
})
class WithRationalMemoryBusCrossing extends WithSbusToMbusCrossingType(RationalCrossing(Symmetric))

View File

@@ -36,17 +36,35 @@ case class CoherentMulticlockBusTopologyParams(
(SBUS, L2, TLBusWrapperConnection(xType = NoCrossing, driveClockFromMaster = Some(true), nodeBinding = BIND_STAR)()),
(L2, MBUS, TLBusWrapperConnection.crossTo(
xType = sbusToMbusXType,
driveClockFromMaster = Some(true),
driveClockFromMaster = None,
nodeBinding = BIND_QUERY))
)
)
// This differs from upstream only in that it does not use the legacy crossTo
// and crossFrom functions, and it ensures driveClockFromMaster = None
case class HierarchicalMulticlockBusTopologyParams(
pbus: PeripheryBusParams,
fbus: FrontBusParams,
cbus: PeripheryBusParams,
xTypes: SubsystemCrossingParams
) extends TLBusWrapperTopology(
instantiations = List(
(PBUS, pbus),
(FBUS, fbus),
(CBUS, cbus)),
connections = List(
(SBUS, CBUS, TLBusWrapperConnection(xType = xTypes.sbusToCbusXType, nodeBinding = BIND_STAR)()),
(CBUS, PBUS, TLBusWrapperConnection(xType = xTypes.cbusToPbusXType, nodeBinding = BIND_STAR)()),
(FBUS, SBUS, TLBusWrapperConnection(xType = xTypes.fbusToSbusXType, nodeBinding = BIND_QUERY, flipRendering = true)()))
)
// For subsystem/Configs.scala
class WithMulticlockCoherentBusTopology extends Config((site, here, up) => {
case TLNetworkTopologyLocated(InSubsystem) => List(
JustOneBusTopologyParams(sbus = site(SystemBusKey)),
HierarchicalBusTopologyParams(
HierarchicalMulticlockBusTopologyParams(
pbus = site(PeripheryBusKey),
fbus = site(FrontBusKey),
cbus = site(ControlBusKey),

View File

@@ -56,6 +56,23 @@ class ChipyardSubsystem(implicit p: Parameters) extends BaseSubsystem
case b: BoomTile => b.module.core.coreMonitorBundle
}.toList
// Relying on [[TLBusWrapperConnection]].driveClockFromMaster for
// bus-couplings that are not asynchronous strips the bus name from the sink
// ClockGroup. This makes it impossible to determine which clocks are driven
// by which bus based on the member names, which is problematic when there is
// a rational crossing between two buses. Instead, provide all bus clocks
// directly from the asyncClockGroupsNode in the subsystem to ensure bus
// names are always preserved in the top-level clock names.
//
// For example, using a RationalCrossing between the Sbus and Cbus, and
// driveClockFromMaster = Some(true) results in all cbus-attached device and
// bus clocks to be given names of the form "subsystem_sbus_[0-9]*".
// Conversly, if an async crossing is used, they instead receive names of the
// form "subsystem_cbus_[0-9]*". The assignment below provides the latter names in all cases.
Seq(PBUS, FBUS, MBUS, CBUS).foreach { loc =>
tlBusWrapperLocationMap.lift(loc).foreach { _.clockGroupNode := asyncClockGroupsNode }
}
override lazy val module = new ChipyardSubsystemModuleImp(this)
}

View File

@@ -43,7 +43,8 @@ class AbstractConfig extends Config(
new chipyard.config.WithUART ++ // add a UART
new chipyard.config.WithL2TLBs(1024) ++ // use L2 TLBs
new chipyard.config.WithNoSubsystemDrivenClocks ++ // drive the subsystem diplomatic clocks from ChipTop instead of using implicit clocks
new chipyard.config.WithPeripheryBusFrequencyAsDefault ++ // Unspecified clocks will match the frequency specified by the pbus dtsFrequency parameter
new chipyard.config.WithInheritBusFrequencyAssignments ++ // Unspecified clocks within a bus will receive the bus frequency if set
new chipyard.config.WithPeripheryBusFrequencyAsDefault ++ // Unspecified frequencies with match the pbus frequency (which is always set)
new freechips.rocketchip.subsystem.WithJtagDTM ++ // set the debug module to expose a JTAG port
new freechips.rocketchip.subsystem.WithNoMMIOPort ++ // no top-level MMIO master port (overrides default set in rocketchip)
new freechips.rocketchip.subsystem.WithNoSlavePort ++ // no top-level MMIO slave port (overrides default set in rocketchip)

View File

@@ -1,6 +1,7 @@
package chipyard
import freechips.rocketchip.config.{Config}
import freechips.rocketchip.diplomacy.{AsynchronousCrossing}
// --------------
// Rocket Configs
@@ -175,13 +176,19 @@ class MMIORocketConfig extends Config(
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
new chipyard.config.AbstractConfig)
class DividedClockRocketConfig extends Config(
new chipyard.config.WithTileFrequency(200.0) ++
new freechips.rocketchip.subsystem.WithRationalRocketTiles ++ // Add rational crossings between RocketTile and uncore
class MulticlockRocketConfig extends Config(
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
new chipyard.config.WithMemoryBusFrequency(50.0) ++
new chipyard.config.WithAsynchrousMemoryBusCrossing ++
new testchipip.WithAsynchronousSerialSlaveCrossing ++
// Frequency specifications
new chipyard.config.WithTileFrequency(1600.0) ++ // Matches the maximum frequency of U540
new chipyard.config.WithSystemBusFrequency(800.0) ++ // Ditto
new chipyard.config.WithMemoryBusFrequency(1000.0) ++ // 2x the U540 freq (appropriate for a 128b Mbus)
new chipyard.config.WithPeripheryBusFrequency(100) ++ // Retains the default pbus frequency
new chipyard.config.WithSystemBusFrequencyAsDefault ++ // All unspecified clock frequencies, notably the implicit clock, will use the sbus freq (800 MHz)
// Crossing specifications
new chipyard.config.WithCbusToPbusCrossingType(AsynchronousCrossing()) ++ // Add Async crossing between PBUS and CBUS
new chipyard.config.WithSbusToMbusCrossingType(AsynchronousCrossing()) ++ // Add Async crossings between backside of L2 and MBUS
new freechips.rocketchip.subsystem.WithRationalRocketTiles ++ // Add rational crossings between RocketTile and uncore
new testchipip.WithAsynchronousSerialSlaveCrossing ++ // Add Async crossing between serial and MBUS. Its master-side is tied to the FBUS
new chipyard.config.AbstractConfig)
class LBWIFRocketConfig extends Config(

View File

@@ -201,8 +201,6 @@ class FireSimCVA6Config extends Config(
//*********************************************************************************/
class FireSimMulticlockRocketConfig extends Config(
new chipyard.config.WithTileFrequency(6400.0) ++ //lol
new WithDefaultFireSimBridges ++
new WithDefaultMemModel ++
new WithFireSimConfigTweaks ++
new chipyard.DividedClockRocketConfig)
new freechips.rocketchip.subsystem.WithRationalRocketTiles ++ // Add rational crossings between RocketTile and uncore
new FireSimRocketConfig)