From 392d5b0801c77960c578293445fe24240f3482a9 Mon Sep 17 00:00:00 2001 From: David Biancolin Date: Wed, 30 Sep 2020 13:18:44 -0700 Subject: [PATCH 01/10] [clocking] Synchronize all output clocks from DividerOnly generator --- .../chipyard/src/main/scala/Clocks.scala | 5 ++-- .../clocking/DividerOnlyClockGenerator.scala | 5 ++++ .../scala/clocking/ResetSynchronizer.scala | 30 +++++++++++++++++++ .../firechip/src/main/scala/FireSim.scala | 13 ++------ 4 files changed, 41 insertions(+), 12 deletions(-) create mode 100644 generators/chipyard/src/main/scala/clocking/ResetSynchronizer.scala diff --git a/generators/chipyard/src/main/scala/Clocks.scala b/generators/chipyard/src/main/scala/Clocks.scala index 554e9905..4219c914 100644 --- a/generators/chipyard/src/main/scala/Clocks.scala +++ b/generators/chipyard/src/main/scala/Clocks.scala @@ -8,11 +8,11 @@ import freechips.rocketchip.prci._ import freechips.rocketchip.subsystem.{BaseSubsystem, SubsystemDriveAsyncClockGroupsKey} import freechips.rocketchip.config.{Parameters, Field, Config} import freechips.rocketchip.diplomacy.{OutwardNodeHandle, InModuleBody, LazyModule} -import freechips.rocketchip.util.{ResetCatchAndSync, Pow2ClockDivider} +import freechips.rocketchip.util.{ResetCatchAndSync} import barstools.iocell.chisel._ -import chipyard.clocking.{DividerOnlyClockGenerator, ClockGroupNamePrefixer, ClockGroupFrequencySpecifier} +import chipyard.clocking._ /** * Chipyard provides three baseline, top-level reset schemes, set using the @@ -116,6 +116,7 @@ object ClockingSchemeGenerators { val referenceClockSource = ClockSourceNode(Seq(ClockSourceParameters())) (aggregator := ClockGroupFrequencySpecifier(p(ClockFrequencyAssignersKey), p(DefaultClockFrequencyKey)) + := ClockGroupResetSynchronizer() := DividerOnlyClockGenerator() := referenceClockSource) diff --git a/generators/chipyard/src/main/scala/clocking/DividerOnlyClockGenerator.scala b/generators/chipyard/src/main/scala/clocking/DividerOnlyClockGenerator.scala index 4355fc71..fb816c35 100644 --- a/generators/chipyard/src/main/scala/clocking/DividerOnlyClockGenerator.scala +++ b/generators/chipyard/src/main/scala/clocking/DividerOnlyClockGenerator.scala @@ -62,6 +62,10 @@ case class DividerOnlyClockGeneratorNode(pllName: String)(implicit valName: ValN * fast reference clock (roughly LCM(requested frequencies)) which is passed up the * diplomatic graph, and then generates dividers for each unique requested * frequency. + * + * Output resets are not synchronized to generated clocks and should be + * synchronized by the user in a manner they see fit. + * */ class DividerOnlyClockGenerator(pllName: String)(implicit p: Parameters, valName: ValName) extends LazyModule { @@ -87,6 +91,7 @@ class DividerOnlyClockGenerator(pllName: String)(implicit p: Parameters, valName for (((sinkBName, sinkB), sinkP) <- outClocks.member.elements.zip(outSinkParams.members)) { val div = pllConfig.sinkDividerMap(sinkP) sinkB.clock := dividedClocks.getOrElse(div, instantiateDivider(div)) + // Reset handling and synchronization is expected to be handled by a downstream node sinkB.reset := refClock.reset } } diff --git a/generators/chipyard/src/main/scala/clocking/ResetSynchronizer.scala b/generators/chipyard/src/main/scala/clocking/ResetSynchronizer.scala new file mode 100644 index 00000000..13a593c5 --- /dev/null +++ b/generators/chipyard/src/main/scala/clocking/ResetSynchronizer.scala @@ -0,0 +1,30 @@ + +package chipyard.clocking + +import chisel3._ + +import freechips.rocketchip.config.{Parameters} +import freechips.rocketchip.diplomacy._ +import freechips.rocketchip.prci._ +import freechips.rocketchip.util.{ResetCatchAndSync} + +/** + * Instantiates a reset synchronizer on all clock-reset pairs in a clock group + */ +class ClockGroupResetSynchronizer(implicit p: Parameters) extends LazyModule { + val node = ClockGroupIdentityNode() + lazy val module = new LazyRawModuleImp(this) { + (node.out zip node.in).map { case ((oG, _), (iG, _)) => + (oG.member.data zip iG.member.data).foreach { case (o, i) => + o.clock := i.clock + o.reset := ResetCatchAndSync(i.clock, i.reset.asBool) + } + } + } +} + +object ClockGroupResetSynchronizer { + def apply()(implicit p: Parameters, valName: ValName) = LazyModule(new ClockGroupResetSynchronizer()).node +} + + diff --git a/generators/firechip/src/main/scala/FireSim.scala b/generators/firechip/src/main/scala/FireSim.scala index 90fd473a..cfca74f8 100644 --- a/generators/firechip/src/main/scala/FireSim.scala +++ b/generators/firechip/src/main/scala/FireSim.scala @@ -16,7 +16,7 @@ import midas.widgets.{Bridge, PeekPokeBridge, RationalClockBridge, RationalClock import chipyard._ import chipyard.harness._ import chipyard.iobinders._ -import chipyard.clocking.{FrequencyUtils, ClockGroupNamePrefixer, ClockGroupFrequencySpecifier, SimplePllConfiguration} +import chipyard.clocking._ // Determines the number of times to instantiate the DUT in the harness. // Subsumes legacy supernode support @@ -101,6 +101,7 @@ class WithFireSimSimpleClocks extends Config((site, here, up) => { val inputClockSource = ClockGroupSourceNode(Seq(ClockGroupSourceParameters())) (aggregator + := ClockGroupResetSynchronizer() := ClockGroupFrequencySpecifier(p(ClockFrequencyAssignersKey), p(DefaultClockFrequencyKey)) := inputClockSource) @@ -113,15 +114,7 @@ class WithFireSimSimpleClocks extends Config((site, here, up) => { (clockGroupBundle.member.data zip input_clocks.data).foreach { case (clockBundle, inputClock) => clockBundle.clock := inputClock - } - - // Assign resets. The synchronization scheme is still WIP. - for ((name, clockBundle) <- clockGroupBundle.member.elements) { - if (name.contains("core")) { - clockBundle.reset := ResetCatchAndSync(clockBundle.clock, reset.asBool) - } else { - clockBundle.reset := reset - } + clockBundle.reset := reset } val pllConfig = new SimplePllConfiguration("FireSim RationalClockBridge", clockGroupEdge.sink.members) From 30b278687b09a09a8806526fce9754efccf64247 Mon Sep 17 00:00:00 2001 From: David Biancolin Date: Fri, 9 Oct 2020 07:13:55 -0700 Subject: [PATCH 02/10] [clocking] Also aggregate clocks in AsyncClockGroup --- generators/chipyard/src/main/scala/Clocks.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generators/chipyard/src/main/scala/Clocks.scala b/generators/chipyard/src/main/scala/Clocks.scala index 4219c914..bee73b69 100644 --- a/generators/chipyard/src/main/scala/Clocks.scala +++ b/generators/chipyard/src/main/scala/Clocks.scala @@ -111,7 +111,7 @@ object ClockingSchemeGenerators { val aggregator = LazyModule(new ClockGroupAggregator("allClocks")).node chiptop.implicitClockSinkNode := ClockGroup() := aggregator - systemAsyncClockGroup := ClockGroupNamePrefixer() := aggregator + systemAsyncClockGroup :*= ClockGroupNamePrefixer() :*= aggregator val referenceClockSource = ClockSourceNode(Seq(ClockSourceParameters())) (aggregator From 986b5831c871d74608f689c6f9c978ec394d0572 Mon Sep 17 00:00:00 2001 From: David Biancolin Date: Fri, 9 Oct 2020 07:23:17 -0700 Subject: [PATCH 03/10] [clocking] Sketch out a topology that puts the MBUS is a separate domain --- .../src/main/scala/CustomBusTopologies.scala | 100 ++++++++++++++++++ .../src/main/scala/HarnessBinders.scala | 12 +-- .../chipyard/src/main/scala/IOBinders.scala | 30 ++++-- .../main/scala/config/AbstractConfig.scala | 2 +- .../src/main/scala/config/RocketConfigs.scala | 2 + .../src/main/scala/BridgeBinders.scala | 4 +- .../src/main/scala/TargetConfigs.scala | 6 ++ generators/testchipip | 2 +- 8 files changed, 138 insertions(+), 20 deletions(-) create mode 100644 generators/chipyard/src/main/scala/CustomBusTopologies.scala diff --git a/generators/chipyard/src/main/scala/CustomBusTopologies.scala b/generators/chipyard/src/main/scala/CustomBusTopologies.scala new file mode 100644 index 00000000..5dbcfe1d --- /dev/null +++ b/generators/chipyard/src/main/scala/CustomBusTopologies.scala @@ -0,0 +1,100 @@ + +package chipyard + +import freechips.rocketchip.config.{Field, Config, Parameters} +import freechips.rocketchip.diplomacy._ +import freechips.rocketchip.tilelink._ +import freechips.rocketchip.util.{Location, Symmetric} +import freechips.rocketchip.subsystem._ + +// I'm putting this code here temporarily as I think it should be a candidate +// for upstreaming based on input from Henry Cook, but don't wnat to deal with +// an RC branch just yet. + +// For subsystem/BusTopology.scala + +/** + * Keys that serve as a means to define crossing types from a Parameters instance + */ +case object SubsystemCrossingParamsKey extends Field[SubsystemCrossingParams](SubsystemCrossingParams()) +case object MemoryBusCrossingTypeKey extends Field[ClockCrossingType](NoCrossing) + +// Biancolin: This, modified from Henry's email +/** 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, + l2: BankedL2Params, + sbusToMbusXType: ClockCrossingType = NoCrossing +) extends TLBusWrapperTopology( + instantiations = (if (l2.nBanks == 0) Nil else List( + (MBUS, mbus), + (L2, CoherenceManagerWrapperParams(mbus.blockBytes, mbus.beatBytes, l2.nBanks, L2.name)(l2.coherenceManager)))), + connections = if (l2.nBanks == 0) Nil else List( + (SBUS, L2, TLBusWrapperConnection(xType = NoCrossing, driveClockFromMaster = Some(true), nodeBinding = BIND_STAR)()), + (L2, MBUS, TLBusWrapperConnection.crossTo( + xType = sbusToMbusXType, + driveClockFromMaster = Some(true), + nodeBinding = BIND_QUERY)) + ) +) + +// For subsystem/Configs.scala + +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), + sbusToMbusXType = site(MemoryBusCrossingTypeKey))) +}) + +/** + * Mixins to specify crossing types between the 5 traditional TL buses + * + * Note: these presuppose the legacy connections between buses and set + * parameters in SubsystemCrossingParams; they may not be resuable in custom + * topologies (but you can specify the desired crossings in your topology). + * + * @param xType The clock crossing type + * + */ +class WithMemoryBusCrossingType(xType: ClockCrossingType) extends Config((site, here, up) => { + case MemoryBusCrossingTypeKey => xType +}) + +class WithFrontBusCrossingType(xType: ClockCrossingType) extends Config((site, here, up) => { + case SubsystemCrossingParamsKey => up(SubsystemCrossingParamsKey, site) + .copy(fbusToSbusXType = xType) +}) + +class WithControlBusCrossingType(xType: ClockCrossingType) extends Config((site, here, up) => { + case SubsystemCrossingParamsKey => up(SubsystemCrossingParamsKey, site) + .copy(sbusToCbusXType = xType) +}) + +class WithPeripheryBusCrossingType(xType: ClockCrossingType) extends Config((site, here, up) => { + case SubsystemCrossingParamsKey => up(SubsystemCrossingParamsKey, site) + .copy(cbusToPbusXType = xType) +}) + +/** + * Mixins to set the dtsFrequency field of BusParams -- these will percolate it'st way + * through the diplomatic clock graph to the clock sources. + */ +class WithPeripheryBusFrequency(freq: BigInt) extends Config((site, here, up) => { + case PeripheryBusKey => up(PeripheryBusKey).copy(dtsFrequency = Some(freq)) +}) +class WithMemoryBusFrequency(freq: BigInt) extends Config((site, here, up) => { + case MemoryBusKey => up(MemoryBusKey).copy(dtsFrequency = Some(freq)) +}) + +class WithRationalMemoryBusCrossing extends WithMemoryBusCrossingType(RationalCrossing(Symmetric)) +class WithAsynchrousMemoryBusCrossing extends WithMemoryBusCrossingType(AsynchronousCrossing()) diff --git a/generators/chipyard/src/main/scala/HarnessBinders.scala b/generators/chipyard/src/main/scala/HarnessBinders.scala index e5cfacfb..b5992c7b 100644 --- a/generators/chipyard/src/main/scala/HarnessBinders.scala +++ b/generators/chipyard/src/main/scala/HarnessBinders.scala @@ -125,11 +125,11 @@ class WithSimNetwork extends OverrideHarnessBinder({ }) class WithSimAXIMem extends OverrideHarnessBinder({ - (system: CanHaveMasterAXI4MemPort, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[AXI4Bundle]]) => { + (system: CanHaveMasterAXI4MemPort, th: HasHarnessSignalReferences, ports: Seq[ClockedAndResetIO[AXI4Bundle]]) => { val p: Parameters = chipyard.iobinders.GetSystemParameters(system) (ports zip system.memAXI4Node.edges.in).map { case (port, edge) => val mem = LazyModule(new SimAXIMem(edge, size=p(ExtMem).get.master.size)(p)) - withClockAndReset(port.clock, th.harnessReset) { + withClockAndReset(port.clock, port.reset) { Module(mem.module).suggestName("mem") } mem.io_axi4.head <> port.bits @@ -139,7 +139,7 @@ class WithSimAXIMem extends OverrideHarnessBinder({ }) class WithBlackBoxSimMem extends OverrideHarnessBinder({ - (system: CanHaveMasterAXI4MemPort, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[AXI4Bundle]]) => { + (system: CanHaveMasterAXI4MemPort, th: HasHarnessSignalReferences, ports: Seq[ClockedAndResetIO[AXI4Bundle]]) => { val p: Parameters = chipyard.iobinders.GetSystemParameters(system) (ports zip system.memAXI4Node.edges.in).map { case (port, edge) => val memSize = p(ExtMem).get.master.size @@ -147,18 +147,18 @@ class WithBlackBoxSimMem extends OverrideHarnessBinder({ val mem = Module(new SimDRAM(memSize, lineSize, edge.bundle)).suggestName("simdram") mem.io.axi <> port.bits mem.io.clock := port.clock - mem.io.reset := th.harnessReset + mem.io.reset := port.reset } Nil } }) class WithSimAXIMMIO extends OverrideHarnessBinder({ - (system: CanHaveMasterAXI4MMIOPort, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[AXI4Bundle]]) => { + (system: CanHaveMasterAXI4MMIOPort, th: HasHarnessSignalReferences, ports: Seq[ClockedAndResetIO[AXI4Bundle]]) => { val p: Parameters = chipyard.iobinders.GetSystemParameters(system) (ports zip system.mmioAXI4Node.edges.in).map { case (port, edge) => val mmio_mem = LazyModule(new SimAXIMem(edge, size = p(ExtBus).get.size)(p)) - withClockAndReset(port.clock, th.harnessReset) { + withClockAndReset(port.clock, port.reset) { Module(mmio_mem.module).suggestName("mmio_mem") } mmio_mem.io_axi4.head <> port.bits diff --git a/generators/chipyard/src/main/scala/IOBinders.scala b/generators/chipyard/src/main/scala/IOBinders.scala index 4a31e2c0..1ba6c0a9 100644 --- a/generators/chipyard/src/main/scala/IOBinders.scala +++ b/generators/chipyard/src/main/scala/IOBinders.scala @@ -108,14 +108,23 @@ class ComposeIOBinder[T, S <: Data](fn: => (T) => (Seq[S], Seq[IOCell]))(implici }) object BoreHelper { - def apply(name: String, source: Clock): Clock = { - val clock_io = IO(Output(Clock())).suggestName(name) - val clock_wire = Wire(Clock()).suggestName(s"chiptop_${name}") - dontTouch(clock_wire) - clock_wire := false.B.asClock // necessary for BoringUtils to work properly - BoringUtils.bore(source, Seq(clock_wire)) - clock_io := clock_wire - clock_io + def apply[T <: Data](name: String, source: T): T = { + val (io, wire) = source match { + case c: Clock => + val wire = Wire(Clock()) + wire := false.B.asClock + (IO(Output(Clock())), wire) + case r: Reset => + val wire = Wire(Reset()) + wire := false.B + (IO(Output(Reset())), wire) + } + io.suggestName(name) + wire.suggestName(s"chiptop_${name}") + dontTouch(wire) + BoringUtils.bore(source, Seq(wire)) + io := wire + io.asInstanceOf[source.type] } } @@ -257,10 +266,11 @@ class WithSerialTLIOCells extends OverrideIOBinder({ class WithAXI4MemPunchthrough extends OverrideIOBinder({ (system: CanHaveMasterAXI4MemPort) => { - val ports: Seq[ClockedIO[AXI4Bundle]] = system.mem_axi4.zipWithIndex.map({ case (m, i) => - val p = IO(new ClockedIO(DataMirror.internal.chiselTypeClone[AXI4Bundle](m))).suggestName(s"axi4_mem_${i}") + val ports: Seq[ClockedAndResetIO[AXI4Bundle]] = system.mem_axi4.zipWithIndex.map({ case (m, i) => + val p = IO(new ClockedAndResetIO(DataMirror.internal.chiselTypeClone[AXI4Bundle](m))).suggestName(s"axi4_mem_${i}") p.bits <> m p.clock := BoreHelper("axi4_mem_clock", system.asInstanceOf[BaseSubsystem].mbus.module.clock) + p.reset := BoreHelper("axi4_mem_reset", system.asInstanceOf[BaseSubsystem].mbus.module.reset) p }) (ports, Nil) diff --git a/generators/chipyard/src/main/scala/config/AbstractConfig.scala b/generators/chipyard/src/main/scala/config/AbstractConfig.scala index 9b04788c..c4b1c9cf 100644 --- a/generators/chipyard/src/main/scala/config/AbstractConfig.scala +++ b/generators/chipyard/src/main/scala/config/AbstractConfig.scala @@ -49,6 +49,6 @@ class AbstractConfig extends Config( new freechips.rocketchip.subsystem.WithNoSlavePort ++ // no top-level MMIO slave port (overrides default set in rocketchip) new freechips.rocketchip.subsystem.WithInclusiveCache ++ // use Sifive L2 cache new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ // no external interrupts - new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ // hierarchical buses including mbus+l2 + new chipyard.WithCoherentBusTopology ++ // hierarchical buses including mbus+l2 new freechips.rocketchip.system.BaseConfig) // "base" rocketchip system diff --git a/generators/chipyard/src/main/scala/config/RocketConfigs.scala b/generators/chipyard/src/main/scala/config/RocketConfigs.scala index 11399a62..e89727f1 100644 --- a/generators/chipyard/src/main/scala/config/RocketConfigs.scala +++ b/generators/chipyard/src/main/scala/config/RocketConfigs.scala @@ -178,6 +178,8 @@ class DividedClockRocketConfig extends Config( new chipyard.config.WithTileFrequency(200.0) ++ new freechips.rocketchip.subsystem.WithRationalRocketTiles ++ // Add rational crossings between RocketTile and uncore new freechips.rocketchip.subsystem.WithNBigCores(1) ++ + new chipyard.WithMemoryBusFrequency(50 * 1000 * 1000) ++ + new chipyard.WithAsynchrousMemoryBusCrossing ++ new chipyard.config.AbstractConfig) class LBWIFRocketConfig extends Config( diff --git a/generators/firechip/src/main/scala/BridgeBinders.scala b/generators/firechip/src/main/scala/BridgeBinders.scala index 5a0b4837..8fa0b54e 100644 --- a/generators/firechip/src/main/scala/BridgeBinders.scala +++ b/generators/firechip/src/main/scala/BridgeBinders.scala @@ -97,14 +97,14 @@ class WithBlockDeviceBridge extends OverrideHarnessBinder({ }) class WithFASEDBridge extends OverrideHarnessBinder({ - (system: CanHaveMasterAXI4MemPort, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[AXI4Bundle]]) => { + (system: CanHaveMasterAXI4MemPort, th: HasHarnessSignalReferences, ports: Seq[ClockedAndResetIO[AXI4Bundle]]) => { implicit val p: Parameters = GetSystemParameters(system) (ports zip system.memAXI4Node.edges.in).map { case (axi4, edge) => val nastiKey = NastiParameters(axi4.bits.r.bits.data.getWidth, axi4.bits.ar.bits.addr.getWidth, axi4.bits.ar.bits.id.getWidth) system match { - case s: BaseSubsystem => FASEDBridge(axi4.clock, axi4.bits, th.harnessReset.asBool, + case s: BaseSubsystem => FASEDBridge(axi4.clock, axi4.bits, axi4.reset.asBool, CompleteConfig(p(firesim.configs.MemModelKey), nastiKey, Some(AXI4EdgeSummary(edge)), diff --git a/generators/firechip/src/main/scala/TargetConfigs.scala b/generators/firechip/src/main/scala/TargetConfigs.scala index b70ef647..6ff5065f 100644 --- a/generators/firechip/src/main/scala/TargetConfigs.scala +++ b/generators/firechip/src/main/scala/TargetConfigs.scala @@ -73,6 +73,12 @@ class WithFireSimConfigTweaks extends Config( // Optional*: Removing this will require adjusting the UART baud rate and // potential target-software changes to properly capture UART output new WithPeripheryBusFrequency(BigInt(3200000000L)) ++ + // Optional: Removing these two configs will result in the FASED timing model running + // at the pbus freq (above, 3.2 GHz), which is outside the range of valid DDR3 speedgrades. + // 1 GHz matches the FASED default, using some other frequency will require + // runnings the FASED runtime configuration generator to generate faithful DDR3 timing values. + new chipyard.config.WithMemoryBusFrequency(1000 * 1000 * 1000) ++ + new chipyard.config.WithAsynchrousMemoryBusCrossing ++ // Required: Existing FAME-1 transform cannot handle black-box clock gates new WithoutClockGating ++ // Required*: Removes thousands of assertions that would be synthesized (* pending PriorityMux bugfix) diff --git a/generators/testchipip b/generators/testchipip index 10351d36..b3987a3a 160000 --- a/generators/testchipip +++ b/generators/testchipip @@ -1 +1 @@ -Subproject commit 10351d36a961d89e6f5ac1177dff0e9f3efb8c0f +Subproject commit b3987a3a784c7175c81aa58016fb3e2df58924c2 From 211c33f996dd39aeba923b1373c016ee8642f24d Mon Sep 17 00:00:00 2001 From: David Biancolin Date: Wed, 14 Oct 2020 14:42:45 -0700 Subject: [PATCH 04/10] Address comments in #690 --- .../src/main/scala/ConfigFragments.scala | 47 +++++++++++++- .../src/main/scala/CustomBusTopologies.scala | 62 ++++--------------- .../chipyard/src/main/scala/IOBinders.scala | 7 ++- .../main/scala/config/AbstractConfig.scala | 2 +- .../src/main/scala/config/RocketConfigs.scala | 5 +- .../firechip/src/main/scala/FireSim.scala | 2 +- .../src/main/scala/TargetConfigs.scala | 14 ++--- generators/testchipip | 2 +- 8 files changed, 74 insertions(+), 67 deletions(-) diff --git a/generators/chipyard/src/main/scala/ConfigFragments.scala b/generators/chipyard/src/main/scala/ConfigFragments.scala index d7becac6..e66dfb4a 100644 --- a/generators/chipyard/src/main/scala/ConfigFragments.scala +++ b/generators/chipyard/src/main/scala/ConfigFragments.scala @@ -5,13 +5,13 @@ import chisel3.util.{log2Up} import freechips.rocketchip.config.{Field, Parameters, Config} import freechips.rocketchip.subsystem._ -import freechips.rocketchip.diplomacy.{LazyModule, ValName} +import freechips.rocketchip.diplomacy._ import freechips.rocketchip.devices.tilelink.{BootROMLocated} import freechips.rocketchip.devices.debug.{Debug, ExportDebug, DebugModuleKey, DMI} import freechips.rocketchip.groundtest.{GroundTestSubsystem} import freechips.rocketchip.tile._ import freechips.rocketchip.rocket.{RocketCoreParams, MulDivParams, DCacheParams, ICacheParams} -import freechips.rocketchip.util.{AsyncResetReg} +import freechips.rocketchip.util.{AsyncResetReg, Symmetric} import freechips.rocketchip.prci._ import testchipip._ @@ -172,3 +172,46 @@ class WithPeripheryBusFrequencyAsDefault extends Config((site, here, up) => { case DefaultClockFrequencyKey => (site(PeripheryBusKey).dtsFrequency.get / (1000 * 1000)).toDouble }) +/** + * Mixins to specify crossing types between the 5 traditional TL buses + * + * Note: these presuppose the legacy connections between buses and set + * parameters in SubsystemCrossingParams; they may not be resuable in custom + * topologies (but you can specify the desired crossings in your topology). + * + * @param xType The clock crossing type + * + */ + +class WithSbusToMbusCrossingType(xType: ClockCrossingType) extends Config((site, here, up) => { + case SbusToMbusXTypeKey => xType +}) +class WithSbusToCbusCrossingType(xType: ClockCrossingType) extends Config((site, here, up) => { + case SbusToCbusXTypeKey => xType +}) +class WithCbusToPbusCrossingType(xType: ClockCrossingType) extends Config((site, here, up) => { + case CbusToPbusXTypeKey => xType +}) +class WithFbusToSbusCrossingType(xType: ClockCrossingType) extends Config((site, here, up) => { + case FbusToSbusXTypeKey => xType +}) + +/** + * Mixins to set the dtsFrequency field of BusParams -- these will percolate its way + * 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))) +}) +class WithMemoryBusFrequency(freqMHz: Double) extends Config((site, here, up) => { + case MemoryBusKey => up(MemoryBusKey).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))) +}) +class WithControlBusFrequency(freqMHz: Double) extends Config((site, here, up) => { + case ControlBusKey => up(ControlBusKey).copy(dtsFrequency = Some(BigInt((freqMHz * 1e6).toLong))) +}) + +class WithRationalMemoryBusCrossing extends WithSbusToMbusCrossingType(RationalCrossing(Symmetric)) +class WithAsynchrousMemoryBusCrossing extends WithSbusToMbusCrossingType(AsynchronousCrossing()) diff --git a/generators/chipyard/src/main/scala/CustomBusTopologies.scala b/generators/chipyard/src/main/scala/CustomBusTopologies.scala index 5dbcfe1d..c1c09285 100644 --- a/generators/chipyard/src/main/scala/CustomBusTopologies.scala +++ b/generators/chipyard/src/main/scala/CustomBusTopologies.scala @@ -16,12 +16,14 @@ import freechips.rocketchip.subsystem._ /** * Keys that serve as a means to define crossing types from a Parameters instance */ -case object SubsystemCrossingParamsKey extends Field[SubsystemCrossingParams](SubsystemCrossingParams()) -case object MemoryBusCrossingTypeKey extends Field[ClockCrossingType](NoCrossing) +case object SbusToMbusXTypeKey extends Field[ClockCrossingType](NoCrossing) +case object SbusToCbusXTypeKey extends Field[ClockCrossingType](NoCrossing) +case object CbusToPbusXTypeKey extends Field[ClockCrossingType](SynchronousCrossing()) +case object FbusToSbusXTypeKey extends Field[ClockCrossingType](SynchronousCrossing()) // Biancolin: This, modified from Henry's email /** Parameterization of a topology containing a banked coherence manager and a bus for attaching memory devices. */ -case class CoherentBusTopologyParams( +case class CoherentMulticlockBusTopologyParams( sbus: SystemBusParams, // TODO remove this after better width propagation mbus: MemoryBusParams, l2: BankedL2Params, @@ -41,60 +43,20 @@ case class CoherentBusTopologyParams( // For subsystem/Configs.scala -class WithCoherentBusTopology extends Config((site, here, up) => { +class WithMulticlockCoherentBusTopology 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( + xTypes = SubsystemCrossingParams( + sbusToCbusXType = site(SbusToCbusXTypeKey), + cbusToPbusXType = site(CbusToPbusXTypeKey), + fbusToSbusXType = site(FbusToSbusXTypeKey))), + CoherentMulticlockBusTopologyParams( sbus = site(SystemBusKey), mbus = site(MemoryBusKey), l2 = site(BankedL2Key), - sbusToMbusXType = site(MemoryBusCrossingTypeKey))) + sbusToMbusXType = site(SbusToMbusXTypeKey))) }) - -/** - * Mixins to specify crossing types between the 5 traditional TL buses - * - * Note: these presuppose the legacy connections between buses and set - * parameters in SubsystemCrossingParams; they may not be resuable in custom - * topologies (but you can specify the desired crossings in your topology). - * - * @param xType The clock crossing type - * - */ -class WithMemoryBusCrossingType(xType: ClockCrossingType) extends Config((site, here, up) => { - case MemoryBusCrossingTypeKey => xType -}) - -class WithFrontBusCrossingType(xType: ClockCrossingType) extends Config((site, here, up) => { - case SubsystemCrossingParamsKey => up(SubsystemCrossingParamsKey, site) - .copy(fbusToSbusXType = xType) -}) - -class WithControlBusCrossingType(xType: ClockCrossingType) extends Config((site, here, up) => { - case SubsystemCrossingParamsKey => up(SubsystemCrossingParamsKey, site) - .copy(sbusToCbusXType = xType) -}) - -class WithPeripheryBusCrossingType(xType: ClockCrossingType) extends Config((site, here, up) => { - case SubsystemCrossingParamsKey => up(SubsystemCrossingParamsKey, site) - .copy(cbusToPbusXType = xType) -}) - -/** - * Mixins to set the dtsFrequency field of BusParams -- these will percolate it'st way - * through the diplomatic clock graph to the clock sources. - */ -class WithPeripheryBusFrequency(freq: BigInt) extends Config((site, here, up) => { - case PeripheryBusKey => up(PeripheryBusKey).copy(dtsFrequency = Some(freq)) -}) -class WithMemoryBusFrequency(freq: BigInt) extends Config((site, here, up) => { - case MemoryBusKey => up(MemoryBusKey).copy(dtsFrequency = Some(freq)) -}) - -class WithRationalMemoryBusCrossing extends WithMemoryBusCrossingType(RationalCrossing(Symmetric)) -class WithAsynchrousMemoryBusCrossing extends WithMemoryBusCrossingType(AsynchronousCrossing()) diff --git a/generators/chipyard/src/main/scala/IOBinders.scala b/generators/chipyard/src/main/scala/IOBinders.scala index 1ba6c0a9..8537b418 100644 --- a/generators/chipyard/src/main/scala/IOBinders.scala +++ b/generators/chipyard/src/main/scala/IOBinders.scala @@ -112,6 +112,8 @@ object BoreHelper { val (io, wire) = source match { case c: Clock => val wire = Wire(Clock()) + // Provide a dummy assignment to prevent FIRRTL invalid assignment + // errors prior to running the wiring pass wire := false.B.asClock (IO(Output(Clock())), wire) case r: Reset => @@ -269,8 +271,9 @@ class WithAXI4MemPunchthrough extends OverrideIOBinder({ val ports: Seq[ClockedAndResetIO[AXI4Bundle]] = system.mem_axi4.zipWithIndex.map({ case (m, i) => val p = IO(new ClockedAndResetIO(DataMirror.internal.chiselTypeClone[AXI4Bundle](m))).suggestName(s"axi4_mem_${i}") p.bits <> m - p.clock := BoreHelper("axi4_mem_clock", system.asInstanceOf[BaseSubsystem].mbus.module.clock) - p.reset := BoreHelper("axi4_mem_reset", system.asInstanceOf[BaseSubsystem].mbus.module.reset) + val mbus = system.asInstanceOf[HasTileLinkLocations].locateTLBusWrapper(MBUS) + p.clock := BoreHelper("axi4_mem_clock", mbus.module.clock) + p.reset := BoreHelper("axi4_mem_reset", mbus.module.reset) p }) (ports, Nil) diff --git a/generators/chipyard/src/main/scala/config/AbstractConfig.scala b/generators/chipyard/src/main/scala/config/AbstractConfig.scala index c4b1c9cf..301c03d7 100644 --- a/generators/chipyard/src/main/scala/config/AbstractConfig.scala +++ b/generators/chipyard/src/main/scala/config/AbstractConfig.scala @@ -49,6 +49,6 @@ class AbstractConfig extends Config( new freechips.rocketchip.subsystem.WithNoSlavePort ++ // no top-level MMIO slave port (overrides default set in rocketchip) new freechips.rocketchip.subsystem.WithInclusiveCache ++ // use Sifive L2 cache new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ // no external interrupts - new chipyard.WithCoherentBusTopology ++ // hierarchical buses including mbus+l2 + new chipyard.WithMulticlockCoherentBusTopology ++ // hierarchical buses including mbus+l2 new freechips.rocketchip.system.BaseConfig) // "base" rocketchip system diff --git a/generators/chipyard/src/main/scala/config/RocketConfigs.scala b/generators/chipyard/src/main/scala/config/RocketConfigs.scala index e89727f1..a056ec32 100644 --- a/generators/chipyard/src/main/scala/config/RocketConfigs.scala +++ b/generators/chipyard/src/main/scala/config/RocketConfigs.scala @@ -178,8 +178,9 @@ class DividedClockRocketConfig extends Config( new chipyard.config.WithTileFrequency(200.0) ++ new freechips.rocketchip.subsystem.WithRationalRocketTiles ++ // Add rational crossings between RocketTile and uncore new freechips.rocketchip.subsystem.WithNBigCores(1) ++ - new chipyard.WithMemoryBusFrequency(50 * 1000 * 1000) ++ - new chipyard.WithAsynchrousMemoryBusCrossing ++ + new chipyard.config.WithMemoryBusFrequency(50.0) ++ + new chipyard.config.WithAsynchrousMemoryBusCrossing ++ + new testchipip.WithAsynchronousSerialSlaveCrossing ++ new chipyard.config.AbstractConfig) class LBWIFRocketConfig extends Config( diff --git a/generators/firechip/src/main/scala/FireSim.scala b/generators/firechip/src/main/scala/FireSim.scala index cfca74f8..15defa66 100644 --- a/generators/firechip/src/main/scala/FireSim.scala +++ b/generators/firechip/src/main/scala/FireSim.scala @@ -96,7 +96,7 @@ class WithFireSimSimpleClocks extends Config((site, here, up) => { val aggregator = LazyModule(new ClockGroupAggregator("allClocks")).node (chiptop.implicitClockSinkNode := ClockGroup() := aggregator) - (systemAsyncClockGroup := ClockGroupNamePrefixer() := aggregator) + (systemAsyncClockGroup :*= ClockGroupNamePrefixer() :*= aggregator) val inputClockSource = ClockGroupSourceNode(Seq(ClockGroupSourceParameters())) diff --git a/generators/firechip/src/main/scala/TargetConfigs.scala b/generators/firechip/src/main/scala/TargetConfigs.scala index 6ff5065f..ee231419 100644 --- a/generators/firechip/src/main/scala/TargetConfigs.scala +++ b/generators/firechip/src/main/scala/TargetConfigs.scala @@ -37,10 +37,6 @@ class WithBootROM extends Config((site, here, up) => { } }) -class WithPeripheryBusFrequency(freq: BigInt) extends Config((site, here, up) => { - case PeripheryBusKey => up(PeripheryBusKey).copy(dtsFrequency = Some(freq)) -}) - // Disables clock-gating; doesn't play nice with our FAME-1 pass class WithoutClockGating extends Config((site, here, up) => { case DebugModuleKey => up(DebugModuleKey, site).map(_.copy(clockGate = false)) @@ -72,13 +68,15 @@ class WithFireSimConfigTweaks extends Config( new WithBootROM ++ // Optional*: Removing this will require adjusting the UART baud rate and // potential target-software changes to properly capture UART output - new WithPeripheryBusFrequency(BigInt(3200000000L)) ++ - // Optional: Removing these two configs will result in the FASED timing model running + new chipyard.config.WithPeripheryBusFrequency(3200.0) ++ + // Optional: These three configs put the DRAM memory system in it's own clock domian. + // Removing the first config will result in the FASED timing model running // at the pbus freq (above, 3.2 GHz), which is outside the range of valid DDR3 speedgrades. // 1 GHz matches the FASED default, using some other frequency will require // runnings the FASED runtime configuration generator to generate faithful DDR3 timing values. - new chipyard.config.WithMemoryBusFrequency(1000 * 1000 * 1000) ++ + new chipyard.config.WithMemoryBusFrequency(1000.0) ++ new chipyard.config.WithAsynchrousMemoryBusCrossing ++ + new testchipip.WithAsynchronousSerialSlaveCrossing ++ // Required: Existing FAME-1 transform cannot handle black-box clock gates new WithoutClockGating ++ // Required*: Removes thousands of assertions that would be synthesized (* pending PriorityMux bugfix) @@ -133,7 +131,7 @@ class FireSimSmallSystemConfig extends Config( new WithDefaultFireSimBridges ++ new WithDefaultMemModel ++ new WithBootROM ++ - new WithPeripheryBusFrequency(BigInt(3200000000L)) ++ + new chipyard.WithPeripheryBusFrequency(3200.0) ++ new WithoutClockGating ++ new WithoutTLMonitors ++ new freechips.rocketchip.subsystem.WithExtMemSize(1 << 28) ++ diff --git a/generators/testchipip b/generators/testchipip index b3987a3a..51240a9a 160000 --- a/generators/testchipip +++ b/generators/testchipip @@ -1 +1 @@ -Subproject commit b3987a3a784c7175c81aa58016fb3e2df58924c2 +Subproject commit 51240a9a892e871a20f3038ea6bc4293318d73db From 5f488bc0688d0f16edf551412ac0b4087bcb8110 Mon Sep 17 00:00:00 2001 From: David Biancolin Date: Wed, 14 Oct 2020 14:44:48 -0700 Subject: [PATCH 05/10] Bump FireSim for multiclock FAME1 xform fix --- sims/firesim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sims/firesim b/sims/firesim index 801baeb9..64b55aff 160000 --- a/sims/firesim +++ b/sims/firesim @@ -1 +1 @@ -Subproject commit 801baeb901c207beb0511311e09ae10e0dbb8b5f +Subproject commit 64b55aff3997d4cee4494eef72c2f1a15b3002b2 From 9c8d2948af1c6f82243002b6ae12d10200f4af58 Mon Sep 17 00:00:00 2001 From: David Biancolin Date: Wed, 14 Oct 2020 15:33:32 -0700 Subject: [PATCH 06/10] [firechip] Fix a broken config --- generators/firechip/src/main/scala/TargetConfigs.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generators/firechip/src/main/scala/TargetConfigs.scala b/generators/firechip/src/main/scala/TargetConfigs.scala index ee231419..6441136f 100644 --- a/generators/firechip/src/main/scala/TargetConfigs.scala +++ b/generators/firechip/src/main/scala/TargetConfigs.scala @@ -131,7 +131,7 @@ class FireSimSmallSystemConfig extends Config( new WithDefaultFireSimBridges ++ new WithDefaultMemModel ++ new WithBootROM ++ - new chipyard.WithPeripheryBusFrequency(3200.0) ++ + new chipyard.config.WithPeripheryBusFrequency(3200.0) ++ new WithoutClockGating ++ new WithoutTLMonitors ++ new freechips.rocketchip.subsystem.WithExtMemSize(1 << 28) ++ From 74c1c9d7aba6df6157da3719f0247687e2ed4e33 Mon Sep 17 00:00:00 2001 From: David Biancolin Date: Thu, 15 Oct 2020 10:00:07 -0700 Subject: [PATCH 07/10] Punch out reset in AXI4MMIO IOBinder --- generators/chipyard/src/main/scala/IOBinders.scala | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/generators/chipyard/src/main/scala/IOBinders.scala b/generators/chipyard/src/main/scala/IOBinders.scala index 8537b418..87480bfc 100644 --- a/generators/chipyard/src/main/scala/IOBinders.scala +++ b/generators/chipyard/src/main/scala/IOBinders.scala @@ -282,10 +282,12 @@ class WithAXI4MemPunchthrough extends OverrideIOBinder({ class WithAXI4MMIOPunchthrough extends OverrideIOBinder({ (system: CanHaveMasterAXI4MMIOPort) => { - val ports: Seq[ClockedIO[AXI4Bundle]] = system.mmio_axi4.zipWithIndex.map({ case (m, i) => - val p = IO(new ClockedIO(DataMirror.internal.chiselTypeClone[AXI4Bundle](m))).suggestName(s"axi4_mmio_${i}") + val ports: Seq[ClockedAndResetIO[AXI4Bundle]] = system.mmio_axi4.zipWithIndex.map({ case (m, i) => + val p = IO(new ClockedAndResetIO(DataMirror.internal.chiselTypeClone[AXI4Bundle](m))).suggestName(s"axi4_mmio_${i}") p.bits <> m - p.clock := BoreHelper("axi4_mmio_clock", system.asInstanceOf[BaseSubsystem].mbus.module.clock) + val mbus = system.asInstanceOf[HasTileLinkLocations].locateTLBusWrapper(MBUS) + p.clock := BoreHelper("axi4_mmio_clock", mbus.module.clock) + p.reset := BoreHelper("axi4_mmio_reset", mbus.module.reset) p }) (ports, Nil) From b747116363f98d0b2770071b6a434f9c6b34afa5 Mon Sep 17 00:00:00 2001 From: David Biancolin Date: Thu, 15 Oct 2020 10:00:53 -0700 Subject: [PATCH 08/10] Bump FireSim --- sims/firesim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sims/firesim b/sims/firesim index a8900919..89a2ac93 160000 --- a/sims/firesim +++ b/sims/firesim @@ -1 +1 @@ -Subproject commit a8900919cbc826e8e1610805c4229e31a849ad3c +Subproject commit 89a2ac931eddcff72db47006bf863aa201dad206 From 84e0bf7338d1802dea6bc4bcd5f7127bcab7ab3f Mon Sep 17 00:00:00 2001 From: Albert Magyar Date: Thu, 15 Oct 2020 12:25:39 -0700 Subject: [PATCH 09/10] Don't annotate cores with FAMEModelAnnotations --- generators/firechip/src/main/scala/BridgeBinders.scala | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/generators/firechip/src/main/scala/BridgeBinders.scala b/generators/firechip/src/main/scala/BridgeBinders.scala index 760e89c3..110afda8 100644 --- a/generators/firechip/src/main/scala/BridgeBinders.scala +++ b/generators/firechip/src/main/scala/BridgeBinders.scala @@ -18,7 +18,7 @@ import icenet.{CanHavePeripheryIceNIC, SimNetwork, NicLoopback, NICKey, NICIOvon import junctions.{NastiKey, NastiParameters} import midas.models.{FASEDBridge, AXI4EdgeSummary, CompleteConfig} -import midas.targetutils.{FAMEModelAnnotation, MemModelAnnotation, EnableModelMultiThreadingAnnotation} +import midas.targetutils.{MemModelAnnotation, EnableModelMultiThreadingAnnotation} import firesim.bridges._ import firesim.configs.MemModelKey import tracegen.{TraceGenSystemModuleImp} @@ -161,10 +161,8 @@ class WithFireSimFAME5 extends ComposeIOBinder({ (system: HasTilesModuleImp) => { system.outer.tiles.map { case b: BoomTile => - annotate(FAMEModelAnnotation(b.module)) annotate(EnableModelMultiThreadingAnnotation(b.module)) case r: RocketTile => - annotate(FAMEModelAnnotation(r.module)) annotate(EnableModelMultiThreadingAnnotation(r.module)) } (Nil, Nil) From c5e3ad0a016b33ddc8b6685ea3786591988c96ca Mon Sep 17 00:00:00 2001 From: David Biancolin Date: Mon, 19 Oct 2020 15:32:48 +0000 Subject: [PATCH 10/10] Bump tcip and fsim --- sims/firesim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sims/firesim b/sims/firesim index 44649158..1c76c446 160000 --- a/sims/firesim +++ b/sims/firesim @@ -1 +1 @@ -Subproject commit 44649158c0bd0eaf19e82fac3668e5e643beabf7 +Subproject commit 1c76c446dab42b782f8128c3e7e56b4e9ab104d7