From 392d5b0801c77960c578293445fe24240f3482a9 Mon Sep 17 00:00:00 2001 From: David Biancolin Date: Wed, 30 Sep 2020 13:18:44 -0700 Subject: [PATCH 01/19] [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/19] [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/19] [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 d958b8e1aab749161f92bfeac954f9d49fd3abc1 Mon Sep 17 00:00:00 2001 From: Jerry Zhao Date: Mon, 12 Oct 2020 17:45:07 -0700 Subject: [PATCH 04/19] [ci skip] Update smartelf2hex to use MemSiz instead of FileSiz elf2hex writes zeros to a segment for which MemSize > FileSize, which adheres to the ELF spec. Thus, we should calculate the total size of the file from the MemSize of the last segment, rather than the FileSize. --- scripts/smartelf2hex.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/smartelf2hex.sh b/scripts/smartelf2hex.sh index dd035690..cc2ea2f8 100755 --- a/scripts/smartelf2hex.sh +++ b/scripts/smartelf2hex.sh @@ -8,7 +8,7 @@ binary=$1 segments=`readelf --segments --wide $binary` entry_hex=`echo -e "$segments" | grep "Entry point" | cut -f3 -d' ' | sed 's/0x//' | tr [:lower:] [:upper:]` entry_dec=`bc <<< "ibase=16;$entry_hex"` -length_hex=`echo "$segments" | grep "LOAD\|TLS" | tail -n 1 | tr -s [:space:] | cut -f4,6 -d' '` +length_hex=`echo "$segments" | grep "LOAD\|TLS" | tail -n 1 | tr -s [:space:] | cut -f4,7 -d' '` length_dec=`echo $length_hex | tr -d x | tr [:lower:] [:upper:] | tr ' ' + | sed 's/^/ibase=16;/' | sed "s/$/-$entry_hex/" | bc` power_2_length=`echo "x=l($length_dec)/l(2); scale=0; 2^((x+1)/1)" | bc -l` width=64 From 211c33f996dd39aeba923b1373c016ee8642f24d Mon Sep 17 00:00:00 2001 From: David Biancolin Date: Wed, 14 Oct 2020 14:42:45 -0700 Subject: [PATCH 05/19] 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 06/19] 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 07/19] [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 4a317b0cab4c4f15d6240a2a309036e720cc4790 Mon Sep 17 00:00:00 2001 From: Alon Amid Date: Thu, 15 Oct 2020 17:07:20 +0000 Subject: [PATCH 08/19] differentiate default config package delimiter --- common.mk | 2 +- .../chipyard/src/main/scala/stage/ChipyardAnnotations.scala | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/common.mk b/common.mk index f8bd4cf4..8ebc262c 100644 --- a/common.mk +++ b/common.mk @@ -110,7 +110,7 @@ generator_temp: $(SCALA_SOURCES) $(sim_files) $(EXTRA_GENERATOR_REQS) --target-dir $(build_dir) \ --name $(long_name) \ --top-module $(MODEL_PACKAGE).$(MODEL) \ - --legacy-configs $(CONFIG_PACKAGE).$(CONFIG)) + --legacy-configs $(CONFIG_PACKAGE):$(CONFIG)) .PHONY: firrtl firrtl: $(FIRRTL_FILE) diff --git a/generators/chipyard/src/main/scala/stage/ChipyardAnnotations.scala b/generators/chipyard/src/main/scala/stage/ChipyardAnnotations.scala index d75c11a1..5d8b128c 100644 --- a/generators/chipyard/src/main/scala/stage/ChipyardAnnotations.scala +++ b/generators/chipyard/src/main/scala/stage/ChipyardAnnotations.scala @@ -12,10 +12,10 @@ private[stage] object UnderscoreDelimitedConfigsAnnotation extends HasShellOptio new ShellOption[String]( longOption = "legacy-configs", toAnnotationSeq = a => { - val split = a.split('.') - val packageName = split.init.mkString(".") + val split = a.split(':') + val packageName = split.head val configs = split.last.split("_") - Seq(new ConfigsAnnotation(configs map { config => s"${packageName}.${config}" } )) + Seq(new ConfigsAnnotation(configs map { config => if (config contains ".") s"${config}" else s"${packageName}.${config}" } )) }, helpText = "A string of underscore-delimited configs (configs have decreasing precendence from left to right).", shortOption = Some("LC") From 2c935b4ad7fff2a0e6a5c2028f8f4511c8b4b5b5 Mon Sep 17 00:00:00 2001 From: Alon Amid Date: Thu, 15 Oct 2020 17:07:51 +0000 Subject: [PATCH 09/19] pull firesim mem model config into firesim tweaks --- generators/firechip/src/main/scala/TargetConfigs.scala | 2 ++ 1 file changed, 2 insertions(+) diff --git a/generators/firechip/src/main/scala/TargetConfigs.scala b/generators/firechip/src/main/scala/TargetConfigs.scala index b70ef647..c7aa556d 100644 --- a/generators/firechip/src/main/scala/TargetConfigs.scala +++ b/generators/firechip/src/main/scala/TargetConfigs.scala @@ -66,6 +66,8 @@ class WithNVDLASmall extends nvidia.blocks.dla.WithNVDLA("small") // Tweaks that are generally applied to all firesim configs class WithFireSimConfigTweaks extends Config( + // Required: Bake in the default FASED memory model + new WithDefaultMemModel ++ // Required*: Uses FireSim ClockBridge and PeekPokeBridge to drive the system with a single clock/reset new WithFireSimSimpleClocks ++ // Required*: When using FireSim-as-top to provide a correct path to the target bootrom source From 20d3b9f9ce0a46bd6160cd7f16eb682593bb634e Mon Sep 17 00:00:00 2001 From: Alon Amid Date: Thu, 15 Oct 2020 17:08:06 +0000 Subject: [PATCH 10/19] bump firesim --- sims/firesim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sims/firesim b/sims/firesim index 6318184f..b35e8142 160000 --- a/sims/firesim +++ b/sims/firesim @@ -1 +1 @@ -Subproject commit 6318184f304315a94b5eb5c670f0eec1a3205f59 +Subproject commit b35e81422c355031ae90b895f4ecb85d6b20af06 From c7a197d79a4273dacc040a2a1c33c2d31dff03c2 Mon Sep 17 00:00:00 2001 From: Alon Amid Date: Thu, 15 Oct 2020 17:51:28 +0000 Subject: [PATCH 11/19] docs --- .../FPGA-Accelerated-Simulation.rst | 22 +++++++++++++------ 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/docs/Simulation/FPGA-Accelerated-Simulation.rst b/docs/Simulation/FPGA-Accelerated-Simulation.rst index 82692643..c46c0fb5 100644 --- a/docs/Simulation/FPGA-Accelerated-Simulation.rst +++ b/docs/Simulation/FPGA-Accelerated-Simulation.rst @@ -46,7 +46,20 @@ and proceed with the rest of the tutorial. Running your Design in FireSim ------------------------------ -Converting a Chipyard config (one in ``chipyard/src/main/scala`` to run in FireSim is simple. We are using the same target (top) RTL, and only need to specify a new set of connection behaviors for the IOs of that module. Simply create a matching config within ``generators/firechip/src/main/scala/TargetConfigs`` that inherits your config defined in ``chipyard``. +Converting a Chipyard config (one in ``chipyard/src/main/scala`` to run in FireSim is simple, and can be done either throught the traditional configuration system or through FireSim's build recipes scheme. + +A FireSim simulation requires 3 additional config fragments: + +* ``WithFireSimConfigTweaks`` modifies your design to better fit the FireSim usage model. For example, FireSim designs typically include a UART. Technically, adding this in is optional, but *strongly* recommended. +* ``WithDefaultMemModel`` sets the external memory model in the FireSim simulation. See the FireSim documentation for details. This config fragment is currently included by default within ``WithFireSimConfigTweaks``, so it isn't neccessary to add in separately, but it is required if you choose not to use ``WithFireSimConfigTweaks``. +* ``WithDefaultFireSimBridges`` sets the ``IOBinders`` key to use FireSim's Bridge system, which can drive target IOs with software bridge models running on the simulation host. See the FireSim documentation for details. + + +The simplest method to add this config fragments to your custom Chipyard config is through FireSim's build recipe scheme. +After your FireSim environment is setup, you will define your custom build recipe in ``sims/firesim/deploy/deploy/config_build_recipes.ini``. By prepending the FireSim config fragments (separated by ``_``) to your Chipyard configuration, these config fragments will be added to you custom configuration as if they were listed in a custom Chisel custom config class definition. For example, if you would like to convert the Chipyard LargeBoomConfig to a FireSim simulation with a DDR3 memory model, the appropriate FireSim ``TARGET_CONFIG`` would be ``DDR3FRFCFSLLC4MB_WithDefaultFireSimBridges_WithFireSimConfigTweaks_chipyard.LargeBoomConfig``. Note that the FireSim config fragments are part of the ``firesim.firsim`` scala package, and therefore there do not need to be prefixed with the full class name, and opposed to the Chipyard config fragments which need to be prefixed with the chipyard package name. + +An alternative method to prepending the FireSim config fragments in the FireSim build recipe is to create a new "permanent" FireChip custom configuration, which includes the FireSim config fragments. +We are using the same target (top) RTL, and only need to specify a new set of connection behaviors for the IOs of that module. Simply create a matching config within ``generators/firechip/src/main/scala/TargetConfigs`` that inherits your config defined in ``chipyard``. .. literalinclude:: ../../generators/firechip/src/main/scala/TargetConfigs.scala @@ -54,9 +67,4 @@ Converting a Chipyard config (one in ``chipyard/src/main/scala`` to run in FireS :start-after: DOC include start: firesimconfig :end-before: DOC include end: firesimconfig - -Only 3 additional config fragments are needed. - -* ``WithFireSimConfigTweaks`` modifies your design to better fit the FireSim usage model. For example, FireSim designs typically include a UART. Technically, adding this in is optional, but *strongly* recommended. -* ``WithDefaultMemModel`` sets the external memory model in the FireSim simulation. See the FireSim documentation for details. -* ``WithDefaultFireSimBridges`` sets the ``IOBinders`` key to use FireSim's Bridge system, which can drive target IOs with software bridge models running on the simulation host. See the FireSim documentation for details. +While this option seems to require the maintainance of additiona configuraiton code, it has the benefit of allowing for the inclusion of more complex config fragments which also accept custom arguments (for example, ``WithDefaultMemModel`` can take an optional argument``) From 6479d54f53f5a71ef9fa04c0a8178a1457c766e5 Mon Sep 17 00:00:00 2001 From: Alon Amid Date: Thu, 15 Oct 2020 17:53:25 +0000 Subject: [PATCH 12/19] bump firesim --- sims/firesim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sims/firesim b/sims/firesim index b35e8142..b9a9061b 160000 --- a/sims/firesim +++ b/sims/firesim @@ -1 +1 @@ -Subproject commit b35e81422c355031ae90b895f4ecb85d6b20af06 +Subproject commit b9a9061b0b23e85daf4d6f3904e10a97680fbb56 From fd4a70dfb64d95e950ac2222c60170d8f3551f45 Mon Sep 17 00:00:00 2001 From: Alon Amid Date: Thu, 15 Oct 2020 18:04:31 +0000 Subject: [PATCH 13/19] docs typos --- docs/Simulation/FPGA-Accelerated-Simulation.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/Simulation/FPGA-Accelerated-Simulation.rst b/docs/Simulation/FPGA-Accelerated-Simulation.rst index c46c0fb5..40432e51 100644 --- a/docs/Simulation/FPGA-Accelerated-Simulation.rst +++ b/docs/Simulation/FPGA-Accelerated-Simulation.rst @@ -56,7 +56,7 @@ A FireSim simulation requires 3 additional config fragments: The simplest method to add this config fragments to your custom Chipyard config is through FireSim's build recipe scheme. -After your FireSim environment is setup, you will define your custom build recipe in ``sims/firesim/deploy/deploy/config_build_recipes.ini``. By prepending the FireSim config fragments (separated by ``_``) to your Chipyard configuration, these config fragments will be added to you custom configuration as if they were listed in a custom Chisel custom config class definition. For example, if you would like to convert the Chipyard LargeBoomConfig to a FireSim simulation with a DDR3 memory model, the appropriate FireSim ``TARGET_CONFIG`` would be ``DDR3FRFCFSLLC4MB_WithDefaultFireSimBridges_WithFireSimConfigTweaks_chipyard.LargeBoomConfig``. Note that the FireSim config fragments are part of the ``firesim.firsim`` scala package, and therefore there do not need to be prefixed with the full class name, and opposed to the Chipyard config fragments which need to be prefixed with the chipyard package name. +After your FireSim environment is setup, you will define your custom build recipe in ``sims/firesim/deploy/deploy/config_build_recipes.ini``. By prepending the FireSim config fragments (separated by ``_``) to your Chipyard configuration, these config fragments will be added to your custom configuration as if they were listed in a custom Chisel config class definition. For example, if you would like to convert the Chipyard ``LargeBoomConfig`` to a FireSim simulation with a DDR3 memory model, the appropriate FireSim ``TARGET_CONFIG`` would be ``DDR3FRFCFSLLC4MB_WithDefaultFireSimBridges_WithFireSimConfigTweaks_chipyard.LargeBoomConfig``. Note that the FireSim config fragments are part of the ``firesim.firesim`` scala package, and therefore there do not need to be prefixed with the full class name, and opposed to the Chipyard config fragments which need to be prefixed with the chipyard package name. An alternative method to prepending the FireSim config fragments in the FireSim build recipe is to create a new "permanent" FireChip custom configuration, which includes the FireSim config fragments. We are using the same target (top) RTL, and only need to specify a new set of connection behaviors for the IOs of that module. Simply create a matching config within ``generators/firechip/src/main/scala/TargetConfigs`` that inherits your config defined in ``chipyard``. @@ -67,4 +67,4 @@ We are using the same target (top) RTL, and only need to specify a new set of co :start-after: DOC include start: firesimconfig :end-before: DOC include end: firesimconfig -While this option seems to require the maintainance of additiona configuraiton code, it has the benefit of allowing for the inclusion of more complex config fragments which also accept custom arguments (for example, ``WithDefaultMemModel`` can take an optional argument``) +While this option seems to require the maintenance of additional configuration code, it has the benefit of allowing for the inclusion of more complex config fragments which also accept custom arguments (for example, ``WithDefaultMemModel`` can take an optional argument``) From 74c1c9d7aba6df6157da3719f0247687e2ed4e33 Mon Sep 17 00:00:00 2001 From: David Biancolin Date: Thu, 15 Oct 2020 10:00:07 -0700 Subject: [PATCH 14/19] 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 15/19] 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 16/19] 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 6eaac63e1be4035a395f3bf8e6c490794c58fad8 Mon Sep 17 00:00:00 2001 From: Alon Amid Date: Fri, 16 Oct 2020 06:34:26 +0000 Subject: [PATCH 17/19] address PR comments --- docs/Simulation/FPGA-Accelerated-Simulation.rst | 8 ++++---- .../src/main/scala/stage/ChipyardAnnotations.scala | 1 + sims/firesim | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/docs/Simulation/FPGA-Accelerated-Simulation.rst b/docs/Simulation/FPGA-Accelerated-Simulation.rst index 40432e51..86f0eb8b 100644 --- a/docs/Simulation/FPGA-Accelerated-Simulation.rst +++ b/docs/Simulation/FPGA-Accelerated-Simulation.rst @@ -46,17 +46,17 @@ and proceed with the rest of the tutorial. Running your Design in FireSim ------------------------------ -Converting a Chipyard config (one in ``chipyard/src/main/scala`` to run in FireSim is simple, and can be done either throught the traditional configuration system or through FireSim's build recipes scheme. +Converting a Chipyard config (one in ``chipyard/src/main/scala`` to run in FireSim is simple, and can be done either through the traditional configuration system or through FireSim's build-recipes scheme. A FireSim simulation requires 3 additional config fragments: -* ``WithFireSimConfigTweaks`` modifies your design to better fit the FireSim usage model. For example, FireSim designs typically include a UART. Technically, adding this in is optional, but *strongly* recommended. -* ``WithDefaultMemModel`` sets the external memory model in the FireSim simulation. See the FireSim documentation for details. This config fragment is currently included by default within ``WithFireSimConfigTweaks``, so it isn't neccessary to add in separately, but it is required if you choose not to use ``WithFireSimConfigTweaks``. +* ``WithFireSimConfigTweaks`` modifies your design to better fit the FireSim usage model. This is composed of multiple smaller config fragments. For example, the removal of clock-gating (using the ``WithoutClockGating`` config fragment) which is required for correct functioning of the compiler. This config fragment also includes other config fragments such as the inclusion of UART in the design, which although may technically be optional,is *strongly* recommended. +* ``WithDefaultMemModel`` provides a default configuration for FASED memory models in the FireSim simulation. See the FireSim documentation for details. This config fragment is currently included by default within ``WithFireSimConfigTweaks``, so it isn't neccessary to add in separately, but it is required if you choose not to use ``WithFireSimConfigTweaks``. * ``WithDefaultFireSimBridges`` sets the ``IOBinders`` key to use FireSim's Bridge system, which can drive target IOs with software bridge models running on the simulation host. See the FireSim documentation for details. The simplest method to add this config fragments to your custom Chipyard config is through FireSim's build recipe scheme. -After your FireSim environment is setup, you will define your custom build recipe in ``sims/firesim/deploy/deploy/config_build_recipes.ini``. By prepending the FireSim config fragments (separated by ``_``) to your Chipyard configuration, these config fragments will be added to your custom configuration as if they were listed in a custom Chisel config class definition. For example, if you would like to convert the Chipyard ``LargeBoomConfig`` to a FireSim simulation with a DDR3 memory model, the appropriate FireSim ``TARGET_CONFIG`` would be ``DDR3FRFCFSLLC4MB_WithDefaultFireSimBridges_WithFireSimConfigTweaks_chipyard.LargeBoomConfig``. Note that the FireSim config fragments are part of the ``firesim.firesim`` scala package, and therefore there do not need to be prefixed with the full class name, and opposed to the Chipyard config fragments which need to be prefixed with the chipyard package name. +After your FireSim environment is setup, you will define your custom build recipe in ``sims/firesim/deploy/deploy/config_build_recipes.ini``. By prepending the FireSim config fragments (separated by ``_``) to your Chipyard configuration, these config fragments will be added to your custom configuration as if they were listed in a custom Chisel config class definition. For example, if you would like to convert the Chipyard ``LargeBoomConfig`` to a FireSim simulation with a DDR3 memory model, the appropriate FireSim ``TARGET_CONFIG`` would be ``DDR3FRFCFSLLC4MB_WithDefaultFireSimBridges_WithFireSimConfigTweaks_chipyard.LargeBoomConfig``. Note that the FireSim config fragments are part of the ``firesim.firesim`` scala package and therefore there do not need to be prefixed with the full package name as opposed to the Chipyard config fragments which need to be prefixed with the chipyard package name. An alternative method to prepending the FireSim config fragments in the FireSim build recipe is to create a new "permanent" FireChip custom configuration, which includes the FireSim config fragments. We are using the same target (top) RTL, and only need to specify a new set of connection behaviors for the IOs of that module. Simply create a matching config within ``generators/firechip/src/main/scala/TargetConfigs`` that inherits your config defined in ``chipyard``. diff --git a/generators/chipyard/src/main/scala/stage/ChipyardAnnotations.scala b/generators/chipyard/src/main/scala/stage/ChipyardAnnotations.scala index 5d8b128c..b1300031 100644 --- a/generators/chipyard/src/main/scala/stage/ChipyardAnnotations.scala +++ b/generators/chipyard/src/main/scala/stage/ChipyardAnnotations.scala @@ -13,6 +13,7 @@ private[stage] object UnderscoreDelimitedConfigsAnnotation extends HasShellOptio longOption = "legacy-configs", toAnnotationSeq = a => { val split = a.split(':') + assert(split.length == 2) val packageName = split.head val configs = split.last.split("_") Seq(new ConfigsAnnotation(configs map { config => if (config contains ".") s"${config}" else s"${packageName}.${config}" } )) diff --git a/sims/firesim b/sims/firesim index b9a9061b..0e4787a0 160000 --- a/sims/firesim +++ b/sims/firesim @@ -1 +1 @@ -Subproject commit b9a9061b0b23e85daf4d6f3904e10a97680fbb56 +Subproject commit 0e4787a04a3d4a0cade9b0c7070b3d67f6679fea From 8de7aa8d69956f2ddc46b11220f3a8b08a8852ad Mon Sep 17 00:00:00 2001 From: Alon Amid Date: Fri, 16 Oct 2020 18:18:35 +0000 Subject: [PATCH 18/19] bump firesim --- sims/firesim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sims/firesim b/sims/firesim index 0e4787a0..f0257a3f 160000 --- a/sims/firesim +++ b/sims/firesim @@ -1 +1 @@ -Subproject commit 0e4787a04a3d4a0cade9b0c7070b3d67f6679fea +Subproject commit f0257a3f737a73373d0f589e7d19ef6a0b4b1d32 From c5e3ad0a016b33ddc8b6685ea3786591988c96ca Mon Sep 17 00:00:00 2001 From: David Biancolin Date: Mon, 19 Oct 2020 15:32:48 +0000 Subject: [PATCH 19/19] 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