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/docs/Simulation/FPGA-Accelerated-Simulation.rst b/docs/Simulation/FPGA-Accelerated-Simulation.rst index 82692643..86f0eb8b 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 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. 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 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``. .. 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 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``) diff --git a/generators/chipyard/src/main/scala/Clocks.scala b/generators/chipyard/src/main/scala/Clocks.scala index 8dfb9ac6..70fe38e7 100644 --- a/generators/chipyard/src/main/scala/Clocks.scala +++ b/generators/chipyard/src/main/scala/Clocks.scala @@ -8,12 +8,12 @@ import freechips.rocketchip.prci._ import freechips.rocketchip.subsystem.{BaseSubsystem, SubsystemDriveAsyncClockGroupsKey, InstantiatesTiles} 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 testchipip.{TLTileResetCtrl} -import chipyard.clocking.{DividerOnlyClockGenerator, ClockGroupNamePrefixer, ClockGroupFrequencySpecifier} +import chipyard.clocking._ /** * Chipyard provides three baseline, top-level reset schemes, set using the @@ -121,13 +121,14 @@ object ClockingSchemeGenerators { := ClockGroup() := aggregator) (systemAsyncClockGroup - := resetSetter - := ClockGroupNamePrefixer() - := aggregator) + :*= resetSetter + :*= ClockGroupNamePrefixer() + :*= aggregator) val referenceClockSource = ClockSourceNode(Seq(ClockSourceParameters())) (aggregator := ClockGroupFrequencySpecifier(p(ClockFrequencyAssignersKey), p(DefaultClockFrequencyKey)) + := ClockGroupResetSynchronizer() := DividerOnlyClockGenerator() := referenceClockSource) 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 new file mode 100644 index 00000000..c1c09285 --- /dev/null +++ b/generators/chipyard/src/main/scala/CustomBusTopologies.scala @@ -0,0 +1,62 @@ + +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 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 CoherentMulticlockBusTopologyParams( + 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 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( + sbusToCbusXType = site(SbusToCbusXTypeKey), + cbusToPbusXType = site(CbusToPbusXTypeKey), + fbusToSbusXType = site(FbusToSbusXTypeKey))), + CoherentMulticlockBusTopologyParams( + sbus = site(SystemBusKey), + mbus = site(MemoryBusKey), + l2 = site(BankedL2Key), + sbusToMbusXType = site(SbusToMbusXTypeKey))) +}) diff --git a/generators/chipyard/src/main/scala/HarnessBinders.scala b/generators/chipyard/src/main/scala/HarnessBinders.scala index 3cf70f3e..2ff8ad94 100644 --- a/generators/chipyard/src/main/scala/HarnessBinders.scala +++ b/generators/chipyard/src/main/scala/HarnessBinders.scala @@ -126,11 +126,11 @@ class WithSimNetwork extends OverrideHarnessBinder({ }) class WithSimAXIMem extends OverrideHarnessBinder({ - (system: CanHaveMasterAXI4MemPort, th: BaseModule with 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 @@ -140,7 +140,7 @@ class WithSimAXIMem extends OverrideHarnessBinder({ }) class WithBlackBoxSimMem extends OverrideHarnessBinder({ - (system: CanHaveMasterAXI4MemPort, th: BaseModule with 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 @@ -148,18 +148,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: BaseModule with 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 b083b5c0..6bf8a6df 100644 --- a/generators/chipyard/src/main/scala/IOBinders.scala +++ b/generators/chipyard/src/main/scala/IOBinders.scala @@ -30,7 +30,7 @@ import scala.reflect.{ClassTag} object IOBinderTypes { type IOBinderTuple = (Seq[Data], Seq[IOCell]) - type IOBinderFunction = (Boolean, =>Any) => ModuleValue[IOBinderTuple] + type IOBinderFunction = (Boolean, => Any) => ModuleValue[IOBinderTuple] } import IOBinderTypes._ @@ -100,7 +100,6 @@ class ConcreteIOBinder[T](composes: Boolean, fn: T => IOBinderTuple)(implicit ta }}): IOBinderFunction) ) - class LazyIOBinder[T](composes: Boolean, fn: T => ModuleValue[IOBinderTuple])(implicit tag: ClassTag[T]) extends IOBinder[T]( up => (if (composes) up else Nil) ++ Seq(((isLazy, t) => { val empty = new ModuleValue[IOBinderTuple] { @@ -268,14 +267,16 @@ class WithAXI4MemPunchthrough extends OverrideLazyIOBinder({ (system: CanHaveMasterAXI4MemPort) => { implicit val p: Parameters = GetSystemParameters(system) val clockSinkNode = p(ExtMem).map(_ => ClockSinkNode(Seq(ClockSinkParameters()))) - clockSinkNode.map(_ := system.asInstanceOf[BaseSubsystem].mbus.fixedClockNode) + val mbus = system.asInstanceOf[HasTileLinkLocations].locateTLBusWrapper(MBUS) + clockSinkNode.map(_ := mbus.fixedClockNode) def clockBundle = clockSinkNode.get.in.head._1 InModuleBody { - 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 := clockBundle.clock + p.reset := clockBundle.reset p }) (ports, Nil) @@ -287,14 +288,16 @@ class WithAXI4MMIOPunchthrough extends OverrideLazyIOBinder({ (system: CanHaveMasterAXI4MMIOPort) => { implicit val p: Parameters = GetSystemParameters(system) val clockSinkNode = p(ExtBus).map(_ => ClockSinkNode(Seq(ClockSinkParameters()))) - clockSinkNode.map(_ := system.asInstanceOf[BaseSubsystem].mbus.fixedClockNode) + val mbus = system.asInstanceOf[HasTileLinkLocations].locateTLBusWrapper(MBUS) + clockSinkNode.map(_ := mbus.fixedClockNode) def clockBundle = clockSinkNode.get.in.head._1 InModuleBody { - 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 := clockBundle.clock + p.reset := clockBundle.reset p }) (ports, Nil) 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/chipyard/src/main/scala/config/AbstractConfig.scala b/generators/chipyard/src/main/scala/config/AbstractConfig.scala index 9b04788c..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 freechips.rocketchip.subsystem.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 ab0e16ec..d413cc12 100644 --- a/generators/chipyard/src/main/scala/config/RocketConfigs.scala +++ b/generators/chipyard/src/main/scala/config/RocketConfigs.scala @@ -179,6 +179,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.config.WithMemoryBusFrequency(50.0) ++ + new chipyard.config.WithAsynchrousMemoryBusCrossing ++ + new testchipip.WithAsynchronousSerialSlaveCrossing ++ new chipyard.config.AbstractConfig) class LBWIFRocketConfig extends Config( diff --git a/generators/chipyard/src/main/scala/stage/ChipyardAnnotations.scala b/generators/chipyard/src/main/scala/stage/ChipyardAnnotations.scala index d75c11a1..b1300031 100644 --- a/generators/chipyard/src/main/scala/stage/ChipyardAnnotations.scala +++ b/generators/chipyard/src/main/scala/stage/ChipyardAnnotations.scala @@ -12,10 +12,11 @@ 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(':') + assert(split.length == 2) + 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") diff --git a/generators/firechip/src/main/scala/BridgeBinders.scala b/generators/firechip/src/main/scala/BridgeBinders.scala index 2fa49fc3..e4f691e2 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} @@ -98,14 +98,14 @@ class WithBlockDeviceBridge extends OverrideHarnessBinder({ }) class WithFASEDBridge extends OverrideHarnessBinder({ - (system: CanHaveMasterAXI4MemPort, th: FireSim, ports: Seq[ClockedIO[AXI4Bundle]]) => { + (system: CanHaveMasterAXI4MemPort, th: FireSim, 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)), @@ -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) diff --git a/generators/firechip/src/main/scala/FireSim.scala b/generators/firechip/src/main/scala/FireSim.scala index 70116456..acbdbc6b 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 @@ -96,11 +96,12 @@ 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())) (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) diff --git a/generators/firechip/src/main/scala/TargetConfigs.scala b/generators/firechip/src/main/scala/TargetConfigs.scala index b70ef647..719599f4 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)) @@ -66,13 +62,23 @@ 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 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)) ++ + 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.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) @@ -127,7 +133,7 @@ class FireSimSmallSystemConfig extends Config( new WithDefaultFireSimBridges ++ new WithDefaultMemModel ++ new WithBootROM ++ - new WithPeripheryBusFrequency(BigInt(3200000000L)) ++ + new chipyard.config.WithPeripheryBusFrequency(3200.0) ++ new WithoutClockGating ++ new WithoutTLMonitors ++ new freechips.rocketchip.subsystem.WithExtMemSize(1 << 28) ++ diff --git a/generators/testchipip b/generators/testchipip index 56bfaa3f..03af7aa5 160000 --- a/generators/testchipip +++ b/generators/testchipip @@ -1 +1 @@ -Subproject commit 56bfaa3f9bcd11206d93fdfa3c8e7656665e462a +Subproject commit 03af7aa53988dd96dffd613d1d50a5c6661e0a82 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 diff --git a/sims/firesim b/sims/firesim index 6318184f..1c76c446 160000 --- a/sims/firesim +++ b/sims/firesim @@ -1 +1 @@ -Subproject commit 6318184f304315a94b5eb5c670f0eec1a3205f59 +Subproject commit 1c76c446dab42b782f8128c3e7e56b4e9ab104d7