Enabling disable all the PLLSelectorDivider features for Verilator CI
This is to work-around Verilator's modeling of reset, which does not model a posedge reset as t=0
This commit is contained in:
@@ -14,7 +14,10 @@ import barstools.iocell.chisel._
|
||||
// blocks, which allow memory-mapped control of clock division, and clock muxing
|
||||
// between the FakePLL and the slow off-chip clock
|
||||
// Note: This will not simulate properly with firesim
|
||||
class WithPLLSelectorDividerClockGenerator extends OverrideLazyIOBinder({
|
||||
// Unsetting enable will prevent the divider/selector from actually modifying the clock,
|
||||
// while preserving the address map. Unsetting enable should only be done for RTL
|
||||
// simulators (Verilator) which do not model reset properly
|
||||
class WithPLLSelectorDividerClockGenerator(enable: Boolean = true) extends OverrideLazyIOBinder({
|
||||
(system: HasChipyardPRCI) => {
|
||||
// Connect the implicit clock
|
||||
implicit val p = GetSystemParameters(system)
|
||||
@@ -30,8 +33,8 @@ class WithPLLSelectorDividerClockGenerator extends OverrideLazyIOBinder({
|
||||
}
|
||||
val tlbus = system.asInstanceOf[BaseSubsystem].locateTLBusWrapper(system.prciParams.slaveWhere)
|
||||
val baseAddress = system.prciParams.baseAddress
|
||||
val clockDivider = system.prci_ctrl_domain { LazyModule(new TLClockDivider (baseAddress + 0x20000, tlbus.beatBytes)) }
|
||||
val clockSelector = system.prci_ctrl_domain { LazyModule(new TLClockSelector(baseAddress + 0x30000, tlbus.beatBytes)) }
|
||||
val clockDivider = system.prci_ctrl_domain { LazyModule(new TLClockDivider (baseAddress + 0x20000, tlbus.beatBytes, enable=enable)) }
|
||||
val clockSelector = system.prci_ctrl_domain { LazyModule(new TLClockSelector(baseAddress + 0x30000, tlbus.beatBytes, enable=enable)) }
|
||||
val pllCtrl = system.prci_ctrl_domain { LazyModule(new FakePLLCtrl (baseAddress + 0x40000, tlbus.beatBytes)) }
|
||||
|
||||
clockDivider.tlNode := system.prci_ctrl_domain { TLFragmenter(tlbus.beatBytes, tlbus.blockBytes) := system.prci_ctrl_bus.get }
|
||||
|
||||
@@ -15,11 +15,27 @@ import testchipip._
|
||||
|
||||
// This module adds a TileLink memory-mapped clock divider to the clock graph
|
||||
// The output clock/reset pairs from this module should be synchronized later
|
||||
class TLClockDivider(address: BigInt, beatBytes: Int, divBits: Int = 8)(implicit p: Parameters) extends LazyModule {
|
||||
// If enable is unset, this will not divide the clock
|
||||
// DO NOT unset enable for VLSI, or prototyping flows. The disable feature is a work around for
|
||||
// some RTL simulators which do not simulate the reset synchronization properly
|
||||
class TLClockDivider(address: BigInt, beatBytes: Int, divBits: Int = 8, enable: Boolean = true)(implicit p: Parameters) extends LazyModule {
|
||||
val device = new SimpleDevice(s"clk-div-ctrl", Nil)
|
||||
val clockNode = ClockGroupIdentityNode()
|
||||
val tlNode = TLRegisterNode(Seq(AddressSet(address, 4096-1)), device, "reg/control", beatBytes=beatBytes)
|
||||
|
||||
if (!enable) println(Console.RED + s"""
|
||||
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
WARNING:
|
||||
|
||||
YOU ARE USING THE TLCLOCKDIVIDER IN
|
||||
"DISABLED" MODE. THIS SHOULD ONLY BE DONE
|
||||
FOR RTL SIMULATION
|
||||
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
""" + Console.RESET)
|
||||
|
||||
lazy val module = new LazyModuleImp(this) {
|
||||
require (clockNode.out.size == 1)
|
||||
val sources = clockNode.in.head._1.member.data.toSeq
|
||||
@@ -45,13 +61,21 @@ class TLClockDivider(address: BigInt, beatBytes: Int, divBits: Int = 8)(implicit
|
||||
// by setting divisor=0. The divisor signal into the ClockDividerOrPass is synchronized internally
|
||||
divider.io.divisor := Mux(busReset.asBool, 0.U, reg.io.q)
|
||||
divider.io.resetAsync := ResetStretcher(sources(i).clock, asyncReset, 20).asAsyncReset
|
||||
sinks(i)._2.clock := divider.io.clockOut
|
||||
|
||||
// Note this is not synchronized to the output clock, which takes time to appear
|
||||
// so this is still asyncreset
|
||||
// Stretch the reset for 40 cycles, to give enough time to reset any downstream
|
||||
// digital logic
|
||||
sinks(i)._2.reset := ResetStretcher(sources(i).clock, asyncReset, 40).asAsyncReset
|
||||
if (enable) {
|
||||
sinks(i)._2.clock := divider.io.clockOut
|
||||
|
||||
// Note this is not synchronized to the output clock, which takes time to appear
|
||||
// so this is still asyncreset
|
||||
// Stretch the reset for 40 cycles, to give enough time to reset any downstream
|
||||
// digital logic
|
||||
sinks(i)._2.reset := ResetStretcher(sources(i).clock, asyncReset, 40).asAsyncReset
|
||||
} else {
|
||||
// WARNING: THIS IS FOR RTL SIMULATION ONLY
|
||||
sinks(i)._2.clock := sources(i).clock
|
||||
sinks(i)._2.reset := sources(i).reset
|
||||
}
|
||||
|
||||
reg
|
||||
}
|
||||
|
||||
|
||||
@@ -21,12 +21,30 @@ case class ClockSelNode()(implicit valName: ValName)
|
||||
|
||||
// This module adds a TileLink memory-mapped clock mux for each downstream clock domain
|
||||
// in the clock graph. The output clock/reset should be synchronized downstream
|
||||
class TLClockSelector(address: BigInt, beatBytes: Int)(implicit p: Parameters) extends LazyModule {
|
||||
// If enable is unset, this will always pass through the 0'th clock
|
||||
// DO NOT unset enable for VLSI, or prototyping flows. The disable feature is a work around for
|
||||
// some RTL simulators which do not simulate the reset synchronization properly
|
||||
class TLClockSelector(address: BigInt, beatBytes: Int, enable: Boolean = true)(implicit p: Parameters) extends LazyModule {
|
||||
val device = new SimpleDevice("clk-sel-ctrl", Nil)
|
||||
val tlNode = TLRegisterNode(Seq(AddressSet(address, 4096-1)), device, "reg/control", beatBytes=beatBytes)
|
||||
|
||||
val clockNode = ClockSelNode()
|
||||
|
||||
if (!enable) println(Console.RED + s"""
|
||||
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
WARNING:
|
||||
|
||||
YOU ARE USING THE TLCLOCKSELECTOR IN
|
||||
"DISABLED" MODE. THIS SHOULD ONLY BE DONE
|
||||
FOR RTL SIMULATION
|
||||
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
""" + Console.RESET)
|
||||
|
||||
|
||||
|
||||
lazy val module = new LazyModuleImp(this) {
|
||||
val asyncReset = clockNode.in.map(_._1).map(_.reset).toSeq(0)
|
||||
val clocks = clockNode.in.map(_._1).map(_.clock)
|
||||
@@ -43,10 +61,15 @@ class TLClockSelector(address: BigInt, beatBytes: Int)(implicit p: Parameters) e
|
||||
val mux = testchipip.ClockMutexMux(clocks).suggestName(s"${sinkName}_clkmux")
|
||||
mux.io.sel := sel
|
||||
mux.io.resetAsync := asyncReset.asAsyncReset
|
||||
sinks(i).clock := mux.io.clockOut
|
||||
// Stretch the reset for 20 cycles, to give time to reset any downstream digital logic
|
||||
sinks(i).reset := ResetStretcher(clocks(0), asyncReset, 20).asAsyncReset
|
||||
|
||||
if (enable) {
|
||||
sinks(i).clock := mux.io.clockOut
|
||||
// Stretch the reset for 20 cycles, to give time to reset any downstream digital logic
|
||||
sinks(i).reset := ResetStretcher(clocks(0), asyncReset, 20).asAsyncReset
|
||||
} else {
|
||||
// WARNING: THIS IS FOR RTL SIMULATION ONLY
|
||||
sinks(i).clock := clocks(0)
|
||||
sinks(i).reset := asyncReset
|
||||
}
|
||||
reg
|
||||
}
|
||||
tlNode.regmap((0 until sinks.size).map { i =>
|
||||
|
||||
@@ -110,7 +110,8 @@ class TetheredChipLikeRocketConfig extends Config(
|
||||
class VerilatorCITetheredChipLikeRocketConfig extends Config(
|
||||
new chipyard.harness.WithAbsoluteFreqHarnessClockInstantiator ++ // use absolute freqs for sims in the harness
|
||||
new chipyard.harness.WithMultiChipSerialTL(0, 1) ++ // connect the serial-tl ports of the chips together
|
||||
new chipyard.harness.WithMultiChip(0,
|
||||
new chipyard.harness.WithMultiChip(0, // These fragments remove all troublesome
|
||||
new chipyard.clocking.WithPLLSelectorDividerClockGenerator(enable=false) ++ // clocking features from the design
|
||||
new chipyard.iobinders.WithDebugIOCells(syncReset = false) ++
|
||||
new chipyard.config.WithNoResetSynchronizers ++
|
||||
new ChipLikeRocketConfig) ++
|
||||
|
||||
Reference in New Issue
Block a user