[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")
.settings(
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 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 })
}
}

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.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 ++

View File

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