[firechip] Isolate all firesim-multiclock stuff in a single file

This commit is contained in:
David Biancolin
2020-03-19 10:00:17 -07:00
parent d80c2f7c08
commit 7a17323bed
5 changed files with 122 additions and 56 deletions

View File

@@ -204,5 +204,6 @@ lazy val firechip = conditionalDependsOn(project in file("generators/firechip"))
.dependsOn(chipyard, midasTargetUtils, midas, firesimLib % "test->test;compile->compile") .dependsOn(chipyard, midasTargetUtils, midas, firesimLib % "test->test;compile->compile")
.settings( .settings(
commonSettings, commonSettings,
testGrouping in Test := isolateAllTests( (definedTests in Test).value ) testGrouping in Test := isolateAllTests( (definedTests in Test).value ),
testOptions in Test += Tests.Argument("-oF")
) )

View File

@@ -5,11 +5,9 @@ package firesim.firesim
import chisel3._ import chisel3._
import freechips.rocketchip.config.{Field, Config, Parameters} import freechips.rocketchip.config.{Field, Config, Parameters}
import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp} import freechips.rocketchip.diplomacy.{LazyModule}
import freechips.rocketchip.subsystem.{HasTiles}
import freechips.rocketchip.util.{ResetCatchAndSync}
import midas.widgets.{Bridge, PeekPokeBridge, RationalClockBridge, RationalClock} import midas.widgets.{Bridge, PeekPokeBridge, RationalClockBridge}
import chipyard.{BuildTop} import chipyard.{BuildTop}
import chipyard.iobinders.{IOBinders} import chipyard.iobinders.{IOBinders}
@@ -22,43 +20,20 @@ class WithNumNodes(n: Int) extends Config((pname, site, here) => {
case NumNodes => n case NumNodes => n
}) })
case class FireSimClockParameters(additionalClocks: Seq[RationalClock]) { class FireSim(implicit val p: Parameters) extends RawModule {
def numClocks(): Int = additionalClocks.size + 1 val clockBridge = Module(new RationalClockBridge)
} val clock = clockBridge.io.clocks.head
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)
val reset = WireInit(false.B) val reset = WireInit(false.B)
withClockAndReset(refClock, reset) { withClockAndReset(clock, reset) {
// Instantiate multiple instances of the DUT to implement supernode // Instantiate multiple instances of the DUT to implement supernode
val targets = Seq.fill(p(NumNodes))(p(BuildTop)(p)) 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 // A Seq of partial functions that will instantiate the right bridge only
// if that Mixin trait is present in the target's class instance // if that Mixin trait is present in the target's class instance
// //
// Apply each partial function to each DUT instance // Apply each partial function to each DUT instance
for ((target) <- targets) { 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 })
} }
} }

View File

@@ -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 })
}
}

View File

@@ -12,9 +12,8 @@ import freechips.rocketchip.rocket.DCacheParams
import freechips.rocketchip.subsystem._ import freechips.rocketchip.subsystem._
import freechips.rocketchip.devices.tilelink.BootROMParams import freechips.rocketchip.devices.tilelink.BootROMParams
import freechips.rocketchip.devices.debug.{DebugModuleParams, DebugModuleKey} import freechips.rocketchip.devices.debug.{DebugModuleParams, DebugModuleKey}
import freechips.rocketchip.diplomacy.{RationalCrossing}
import freechips.rocketchip.diplomacy.LazyModule import freechips.rocketchip.diplomacy.LazyModule
import boom.common.{BoomTilesKey, BoomCrossingKey} import boom.common.BoomTilesKey
import testchipip.{BlockDeviceKey, BlockDeviceConfig, SerialKey, TracePortKey, TracePortParams} import testchipip.{BlockDeviceKey, BlockDeviceConfig, SerialKey, TracePortKey, TracePortParams}
import sifive.blocks.devices.uart.{PeripheryUARTKey, UARTParams} import sifive.blocks.devices.uart.{PeripheryUARTKey, UARTParams}
import scala.math.{min, max} import scala.math.{min, max}
@@ -24,7 +23,6 @@ import ariane.ArianeTilesKey
import testchipip.WithRingSystemBus import testchipip.WithRingSystemBus
import firesim.bridges._ import firesim.bridges._
import midas.widgets.{RationalClock}
import firesim.configs._ import firesim.configs._
import chipyard.{BuildTop} import chipyard.{BuildTop}
import chipyard.config.ConfigValName._ import chipyard.config.ConfigValName._
@@ -47,18 +45,6 @@ class WithPeripheryBusFrequency(freq: BigInt) extends Config((site, here, up) =>
case PeripheryBusKey => up(PeripheryBusKey).copy(frequency=freq) 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) => { class WithPerfCounters extends Config((site, here, up) => {
case RocketTilesKey => up(RocketTilesKey) map (tile => tile.copy( case RocketTilesKey => up(RocketTilesKey) map (tile => tile.copy(
@@ -197,7 +183,6 @@ class SupernodeFireSimRocketConfig extends Config(
//********************************************************************************** //**********************************************************************************
//* Ariane Configurations //* Ariane Configurations
//*********************************************************************************/ //*********************************************************************************/
class FireSimArianeConfig extends Config( class FireSimArianeConfig extends Config(
new WithDefaultFireSimBridges ++ new WithDefaultFireSimBridges ++
new WithDefaultMemModel ++ new WithDefaultMemModel ++

View File

@@ -131,23 +131,24 @@ abstract class FireSimTestSuite(
elaborate elaborate
generateTestSuiteMakefrags generateTestSuiteMakefrags
runTest("verilator", "rv64ui-p-simple", false, Seq(s"""EXTRA_SIM_ARGS=+trace-humanreadable0""")) 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")(benchmarks)
runSuite("verilator")(FastBlockdevTests) 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 BoomF1Tests extends FireSimTestSuite("FireSim", "DDR3FRFCFSLLC4MB_FireSimBoomConfig", "BaseF1Config")
class RocketNICF1Tests extends FireSimTestSuite("FireSim", "WithNIC_DDR3FRFCFSLLC4MB_FireSimRocketConfig", "BaseF1Config") { class RocketNICF1Tests extends FireSimTestSuite("FireSim", "WithNIC_DDR3FRFCFSLLC4MB_FireSimRocketConfig", "BaseF1Config") {
runSuite("verilator")(NICLoopbackTests) runSuite("verilator")(NICLoopbackTests)
} }
class RamModelRocketF1Tests extends FireSimTestSuite("FireSim", "FireSimDualRocketConfig", "BaseF1Config_MCRams") // Disabled until RAM optimizations re-enabled in multiclock
class RamModelBoomF1Tests extends FireSimTestSuite("FireSim", "FireSimBoomConfig", "BaseF1Config_MCRams") //class RamModelRocketF1Tests extends FireSimTestSuite("FireSim", "FireSimDualRocketConfig", "BaseF1Config_MCRams")
//class RamModelBoomF1Tests extends FireSimTestSuite("FireSim", "FireSimBoomConfig", "BaseF1Config_MCRams")
// Multiclock tests // Multiclock tests
class RocketMulticlockF1Tests extends FireSimTestSuite( class RocketMulticlockF1Tests extends FireSimTestSuite(
"FireSim", "FireSimMulticlockPOC",
"HalfRateUncore_DDR3FRFCFSLLC4MB_FireSimQuadRocketConfig", "FireSimQuadRocketMulticlockConfig",
"WithSynthAsserts_BaseF1Config") "WithSynthAsserts_BaseF1Config")
abstract class FireSimTraceGenTest(targetConfig: String, platformConfig: String) abstract class FireSimTraceGenTest(targetConfig: String, platformConfig: String)