From 7a17323bed90dc8a7e64dc286b57a1d0fa456e94 Mon Sep 17 00:00:00 2001 From: David Biancolin Date: Thu, 19 Mar 2020 10:00:17 -0700 Subject: [PATCH] [firechip] Isolate all firesim-multiclock stuff in a single file --- build.sbt | 3 +- .../firechip/src/main/scala/FireSim.scala | 41 ++----- .../src/main/scala/FireSimMulticlockPOC.scala | 104 ++++++++++++++++++ .../src/main/scala/TargetConfigs.scala | 17 +-- .../src/test/scala/ScalaTestSuite.scala | 13 ++- 5 files changed, 122 insertions(+), 56 deletions(-) create mode 100644 generators/firechip/src/main/scala/FireSimMulticlockPOC.scala diff --git a/build.sbt b/build.sbt index a633066f..b0eea0a8 100644 --- a/build.sbt +++ b/build.sbt @@ -204,5 +204,6 @@ lazy val firechip = conditionalDependsOn(project in file("generators/firechip")) .dependsOn(chipyard, midasTargetUtils, midas, firesimLib % "test->test;compile->compile") .settings( commonSettings, - testGrouping in Test := isolateAllTests( (definedTests in Test).value ) + testGrouping in Test := isolateAllTests( (definedTests in Test).value ), + testOptions in Test += Tests.Argument("-oF") ) diff --git a/generators/firechip/src/main/scala/FireSim.scala b/generators/firechip/src/main/scala/FireSim.scala index c6293e90..221548c3 100644 --- a/generators/firechip/src/main/scala/FireSim.scala +++ b/generators/firechip/src/main/scala/FireSim.scala @@ -5,11 +5,9 @@ package firesim.firesim import chisel3._ import freechips.rocketchip.config.{Field, Config, Parameters} -import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp} -import freechips.rocketchip.subsystem.{HasTiles} -import freechips.rocketchip.util.{ResetCatchAndSync} +import freechips.rocketchip.diplomacy.{LazyModule} -import midas.widgets.{Bridge, PeekPokeBridge, RationalClockBridge, RationalClock} +import midas.widgets.{Bridge, PeekPokeBridge, RationalClockBridge} import chipyard.{BuildTop} import chipyard.iobinders.{IOBinders} @@ -22,43 +20,20 @@ class WithNumNodes(n: Int) extends Config((pname, site, here) => { case NumNodes => n }) -case class FireSimClockParameters(additionalClocks: Seq[RationalClock]) { - def numClocks(): Int = additionalClocks.size + 1 -} -case object FireSimClockKey extends Field[FireSimClockParameters](FireSimClockParameters(Seq())) - -trait HasAdditionalClocks extends LazyModuleImp { - val clocks = IO(Vec(p(FireSimClockKey).numClocks, Input(Clock()))) -} - -trait HasFireSimClockingImp extends HasAdditionalClocks { - val outer: HasTiles - val (tileClock, tileReset) = p(FireSimClockKey).additionalClocks.headOption match { - case Some(RationalClock(_, numer, denom)) if numer != denom => (clocks(1), ResetCatchAndSync(clocks(1), reset.toBool)) - case None => (clocks(0), reset) - } - - outer.tiles.foreach({ case tile => - tile.module.clock := tileClock - tile.module.reset := tileReset - }) -} - -class FireSim[T <: LazyModule](implicit val p: Parameters) extends RawModule { - val clockBridge = Module(new RationalClockBridge(p(FireSimClockKey).additionalClocks:_*)) - val refClock = clockBridge.io.clocks(0) +class FireSim(implicit val p: Parameters) extends RawModule { + val clockBridge = Module(new RationalClockBridge) + val clock = clockBridge.io.clocks.head val reset = WireInit(false.B) - withClockAndReset(refClock, reset) { + withClockAndReset(clock, reset) { // Instantiate multiple instances of the DUT to implement supernode val targets = Seq.fill(p(NumNodes))(p(BuildTop)(p)) - val peekPokeBridge = PeekPokeBridge(refClock, reset) + val peekPokeBridge = PeekPokeBridge(clock, reset) // A Seq of partial functions that will instantiate the right bridge only // if that Mixin trait is present in the target's class instance // // Apply each partial function to each DUT instance for ((target) <- targets) { - p(IOBinders).values.map(fn => fn(refClock, reset.asBool, false.B, target)) + p(IOBinders).values.map(fn => fn(clock, reset.asBool, false.B, target)) } - targets.collect({ case t: HasAdditionalClocks => t.clocks := clockBridge.io.clocks }) } } diff --git a/generators/firechip/src/main/scala/FireSimMulticlockPOC.scala b/generators/firechip/src/main/scala/FireSimMulticlockPOC.scala new file mode 100644 index 00000000..318e3547 --- /dev/null +++ b/generators/firechip/src/main/scala/FireSimMulticlockPOC.scala @@ -0,0 +1,104 @@ +//See LICENSE for license details. + +package firesim.firesim + +import chisel3._ + +import freechips.rocketchip.config.{Field, Config, Parameters} +import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp, RationalCrossing} +import freechips.rocketchip.subsystem._ +import freechips.rocketchip.util.{ResetCatchAndSync} + +import boom.common.{BoomTilesKey, BoomCrossingKey} + +import midas.widgets.{Bridge, PeekPokeBridge, RationalClockBridge, RationalClock} +import firesim.configs._ + +import chipyard.{BuildTop, Top, TopModule} +import chipyard.config.ConfigValName._ +import chipyard.iobinders.{IOBinders} + +// WIP! This file is a sketch of one means of defining a multiclock target-design +// that can be simulated in FireSim, pending a canonicalized form in Chipyard. +// +// Note, the main prerequisite for supporting an additional clock domain in a +// FireSim simulation is to supply an additional clock parameter +// (RationalClock) to the clock bridge (RationalClockBridge). The bridge +// produces a vector of clocks, based on the provided parameter list, which you +// may use freely without further modifications to your target design. + +case class FireSimClockParameters(additionalClocks: Seq[RationalClock]) { + def numClocks(): Int = additionalClocks.size + 1 +} +case object FireSimClockKey extends Field[FireSimClockParameters](FireSimClockParameters(Seq())) + +trait HasAdditionalClocks extends LazyModuleImp { + val clocks = IO(Vec(p(FireSimClockKey).numClocks, Input(Clock()))) +} + +// Presupposes only 1 or 2 clocks. +trait HasFireSimClockingImp extends HasAdditionalClocks { + val outer: HasTiles + val (tileClock, tileReset) = p(FireSimClockKey).additionalClocks.headOption match { + case Some(RationalClock(_, numer, denom)) if numer != denom => (clocks(1), ResetCatchAndSync(clocks(1), reset.toBool)) + case None => (clocks.head, reset) + } + + outer.tiles.foreach({ case tile => + tile.module.clock := tileClock + tile.module.reset := tileReset + }) +} + +// Config Fragment +class WithSingleRationalTileDomain(multiplier: Int, divisor: Int) extends Config((site, here, up) => { + case FireSimClockKey => FireSimClockParameters(Seq(RationalClock("TileDomain", multiplier, divisor))) + case RocketCrossingKey => up(RocketCrossingKey, site) map { r => + r.copy(crossingType = RationalCrossing()) + } + case BoomCrossingKey => up(BoomCrossingKey, site) map { r => + r.copy(crossingType = RationalCrossing()) + } +}) + +class HalfRateUncore extends WithSingleRationalTileDomain(2,1) + +class WithFiresimMulticlockTop extends Config((site, here, up) => { + case BuildTop => (p: Parameters) => Module(LazyModule(new FiresimMulticlockTop()(p)).suggestName("Top").module) +}) + +// Complete Config +class FireSimQuadRocketMulticlockConfig extends Config( + new HalfRateUncore ++ + new WithFiresimMulticlockTop ++ + new FireSimQuadRocketConfig) + +// Top Definition +class FiresimMulticlockTop(implicit p: Parameters) extends chipyard.Top +{ + override lazy val module = new FiresimMulticlockTopModule(this) +} + +class FiresimMulticlockTopModule[+L <: Top](l: L) extends chipyard.TopModule(l) with HasFireSimClockingImp + +// Harness Definition +class FireSimMulticlockPOC(implicit val p: Parameters) extends RawModule { + val clockBridge = Module(new RationalClockBridge(p(FireSimClockKey).additionalClocks:_*)) + val refClock = clockBridge.io.clocks.head + val reset = WireInit(false.B) + withClockAndReset(refClock, reset) { + // Instantiate multiple instances of the DUT to implement supernode + val targets = Seq.fill(p(NumNodes))(p(BuildTop)(p)) + val peekPokeBridge = PeekPokeBridge(refClock, reset) + // A Seq of partial functions that will instantiate the right bridge only + // if that Mixin trait is present in the target's class instance + // + // Apply each partial function to each DUT instance + for ((target) <- targets) { + p(IOBinders).values.map(fn => fn(refClock, reset.asBool, false.B, target)) + } + targets.collect({ case t: HasAdditionalClocks => t.clocks := clockBridge.io.clocks }) + } +} + + diff --git a/generators/firechip/src/main/scala/TargetConfigs.scala b/generators/firechip/src/main/scala/TargetConfigs.scala index ae5d7852..1f9791ee 100644 --- a/generators/firechip/src/main/scala/TargetConfigs.scala +++ b/generators/firechip/src/main/scala/TargetConfigs.scala @@ -12,9 +12,8 @@ import freechips.rocketchip.rocket.DCacheParams import freechips.rocketchip.subsystem._ import freechips.rocketchip.devices.tilelink.BootROMParams import freechips.rocketchip.devices.debug.{DebugModuleParams, DebugModuleKey} -import freechips.rocketchip.diplomacy.{RationalCrossing} import freechips.rocketchip.diplomacy.LazyModule -import boom.common.{BoomTilesKey, BoomCrossingKey} +import boom.common.BoomTilesKey import testchipip.{BlockDeviceKey, BlockDeviceConfig, SerialKey, TracePortKey, TracePortParams} import sifive.blocks.devices.uart.{PeripheryUARTKey, UARTParams} import scala.math.{min, max} @@ -24,7 +23,6 @@ import ariane.ArianeTilesKey import testchipip.WithRingSystemBus import firesim.bridges._ -import midas.widgets.{RationalClock} import firesim.configs._ import chipyard.{BuildTop} import chipyard.config.ConfigValName._ @@ -47,18 +45,6 @@ class WithPeripheryBusFrequency(freq: BigInt) extends Config((site, here, up) => case PeripheryBusKey => up(PeripheryBusKey).copy(frequency=freq) }) -class WithRationalTiles(multiplier: Int, divisor: Int) extends Config((site, here, up) => { - case FireSimClockKey => FireSimClockParameters(Seq(RationalClock("TileDomain", multiplier, divisor))) - case RocketCrossingKey => up(RocketCrossingKey, site) map { r => - r.copy(crossingType = RationalCrossing()) - } - case BoomCrossingKey => up(BoomCrossingKey, site) map { r => - r.copy(crossingType = RationalCrossing()) - } -}) - -class HalfRateUncore extends WithRationalTiles(2,1) - class WithPerfCounters extends Config((site, here, up) => { case RocketTilesKey => up(RocketTilesKey) map (tile => tile.copy( @@ -197,7 +183,6 @@ class SupernodeFireSimRocketConfig extends Config( //********************************************************************************** //* Ariane Configurations //*********************************************************************************/ - class FireSimArianeConfig extends Config( new WithDefaultFireSimBridges ++ new WithDefaultMemModel ++ diff --git a/generators/firechip/src/test/scala/ScalaTestSuite.scala b/generators/firechip/src/test/scala/ScalaTestSuite.scala index 161167d9..ee368052 100644 --- a/generators/firechip/src/test/scala/ScalaTestSuite.scala +++ b/generators/firechip/src/test/scala/ScalaTestSuite.scala @@ -131,23 +131,24 @@ abstract class FireSimTestSuite( elaborate generateTestSuiteMakefrags runTest("verilator", "rv64ui-p-simple", false, Seq(s"""EXTRA_SIM_ARGS=+trace-humanreadable0""")) - diffTracelog("rv64ui-p-simple.out") + //diffTracelog("rv64ui-p-simple.out") runSuite("verilator")(benchmarks) runSuite("verilator")(FastBlockdevTests) } -class RocketF1Tests extends FireSimTestSuite("FireSim", "DDR3FRFCFSLLC4MB_FireSimQuadRocketConfig", "BaseF1Config") +class RocketF1Tests extends FireSimTestSuite("FireSim", "DDR3FRFCFSLLC4MB_FireSimQuadRocketConfig", "WithSynthAsserts_BaseF1Config") class BoomF1Tests extends FireSimTestSuite("FireSim", "DDR3FRFCFSLLC4MB_FireSimBoomConfig", "BaseF1Config") class RocketNICF1Tests extends FireSimTestSuite("FireSim", "WithNIC_DDR3FRFCFSLLC4MB_FireSimRocketConfig", "BaseF1Config") { runSuite("verilator")(NICLoopbackTests) } -class RamModelRocketF1Tests extends FireSimTestSuite("FireSim", "FireSimDualRocketConfig", "BaseF1Config_MCRams") -class RamModelBoomF1Tests extends FireSimTestSuite("FireSim", "FireSimBoomConfig", "BaseF1Config_MCRams") +// Disabled until RAM optimizations re-enabled in multiclock +//class RamModelRocketF1Tests extends FireSimTestSuite("FireSim", "FireSimDualRocketConfig", "BaseF1Config_MCRams") +//class RamModelBoomF1Tests extends FireSimTestSuite("FireSim", "FireSimBoomConfig", "BaseF1Config_MCRams") // Multiclock tests class RocketMulticlockF1Tests extends FireSimTestSuite( - "FireSim", - "HalfRateUncore_DDR3FRFCFSLLC4MB_FireSimQuadRocketConfig", + "FireSimMulticlockPOC", + "FireSimQuadRocketMulticlockConfig", "WithSynthAsserts_BaseF1Config") abstract class FireSimTraceGenTest(targetConfig: String, platformConfig: String)