[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

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