Add some comments on harness/chiptop clocking APIs
This commit is contained in:
@@ -13,6 +13,9 @@ import chipyard.iobinders.HasIOBinders
|
|||||||
import chipyard.clocking.{SimplePllConfiguration, ClockDividerN}
|
import chipyard.clocking.{SimplePllConfiguration, ClockDividerN}
|
||||||
import chipyard.HarnessClockInstantiatorKey
|
import chipyard.HarnessClockInstantiatorKey
|
||||||
|
|
||||||
|
|
||||||
|
// HarnessClockInstantiators are classes which generate clocks that drive
|
||||||
|
// TestHarness simulation models and any Clock inputs to the ChipTop
|
||||||
trait HarnessClockInstantiator {
|
trait HarnessClockInstantiator {
|
||||||
val _clockMap: LinkedHashMap[String, (Double, ClockBundle)] = LinkedHashMap.empty
|
val _clockMap: LinkedHashMap[String, (Double, ClockBundle)] = LinkedHashMap.empty
|
||||||
|
|
||||||
@@ -23,9 +26,13 @@ trait HarnessClockInstantiator {
|
|||||||
clockBundle
|
clockBundle
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// refClock is the clock generated by TestDriver that is
|
||||||
|
// passed to the TestHarness as its implicit clock
|
||||||
def instantiateHarnessClocks(refClock: ClockBundle): Unit
|
def instantiateHarnessClocks(refClock: ClockBundle): Unit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The DividerOnlyHarnessClockInstantiator uses synthesizable clock divisors
|
||||||
|
// to approximate frequency ratios between the requested clocks
|
||||||
class DividerOnlyHarnessClockInstantiator extends HarnessClockInstantiator {
|
class DividerOnlyHarnessClockInstantiator extends HarnessClockInstantiator {
|
||||||
// connect all clock wires specified to a divider only PLL
|
// connect all clock wires specified to a divider only PLL
|
||||||
def instantiateHarnessClocks(refClock: ClockBundle): Unit = {
|
def instantiateHarnessClocks(refClock: ClockBundle): Unit = {
|
||||||
@@ -62,6 +69,10 @@ class DividerOnlyHarnessClockInstantiator extends HarnessClockInstantiator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The AbsoluteFreqHarnessClockInstantiator uses a Verilog blackbox to
|
||||||
|
// provide the precise requested frequency.
|
||||||
|
// This ClockInstantiator cannot be synthesized, run in Verilator, or run in FireSim
|
||||||
|
// It is useful for VCS/Xcelium-driven RTL simulations
|
||||||
class AbsoluteFreqHarnessClockInstantiator extends HarnessClockInstantiator {
|
class AbsoluteFreqHarnessClockInstantiator extends HarnessClockInstantiator {
|
||||||
def instantiateHarnessClocks(refClock: ClockBundle): Unit = {
|
def instantiateHarnessClocks(refClock: ClockBundle): Unit = {
|
||||||
val sinks = _clockMap.map({ case (name, (freq, bundle)) =>
|
val sinks = _clockMap.map({ case (name, (freq, bundle)) =>
|
||||||
|
|||||||
@@ -13,6 +13,9 @@ class ClockWithFreq(val freqMHz: Double) extends Bundle {
|
|||||||
val clock = Clock()
|
val clock = Clock()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This uses synthesizable clock divisors to approximate frequency rations
|
||||||
|
// between the requested clocks. This is currently the defualt clock generator "model",
|
||||||
|
// as it can be used in VCS/Xcelium/Verilator/FireSim
|
||||||
class WithDividerOnlyClockGenerator extends OverrideLazyIOBinder({
|
class WithDividerOnlyClockGenerator extends OverrideLazyIOBinder({
|
||||||
(system: HasChipyardPRCI) => {
|
(system: HasChipyardPRCI) => {
|
||||||
// Connect the implicit clock
|
// Connect the implicit clock
|
||||||
@@ -52,6 +55,10 @@ class WithDividerOnlyClockGenerator extends OverrideLazyIOBinder({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// This uses the FakePLL, which uses a ClockAtFreq Verilog blackbox to generate
|
||||||
|
// the requested clocks. This also adds TileLink ClockDivider and ClockSelector
|
||||||
|
// 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 verilator or firesim
|
// Note: This will not simulate properly with verilator or firesim
|
||||||
class WithPLLSelectorDividerClockGenerator extends OverrideLazyIOBinder({
|
class WithPLLSelectorDividerClockGenerator extends OverrideLazyIOBinder({
|
||||||
(system: HasChipyardPRCI) => {
|
(system: HasChipyardPRCI) => {
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ import freechips.rocketchip.util.ElaborationArtefacts
|
|||||||
|
|
||||||
import testchipip._
|
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 {
|
class TLClockDivider(address: BigInt, beatBytes: Int, divBits: Int = 8)(implicit p: Parameters) extends LazyModule {
|
||||||
val device = new SimpleDevice(s"clk-div-ctrl", Nil)
|
val device = new SimpleDevice(s"clk-div-ctrl", Nil)
|
||||||
val clockNode = ClockGroupIdentityNode()
|
val clockNode = ClockGroupIdentityNode()
|
||||||
|
|||||||
@@ -36,6 +36,8 @@ case class ClockSelNode()(implicit valName: ValName)
|
|||||||
uFn = { u => ClockSinkParameters() }
|
uFn = { u => ClockSinkParameters() }
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// 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 {
|
class TLClockSelector(address: BigInt, beatBytes: Int)(implicit p: Parameters) extends LazyModule {
|
||||||
val device = new SimpleDevice("clk-sel-ctrl", Nil)
|
val device = new SimpleDevice("clk-sel-ctrl", Nil)
|
||||||
val tlNode = TLRegisterNode(Seq(AddressSet(address, 4096-1)), device, "reg/control", beatBytes=beatBytes)
|
val tlNode = TLRegisterNode(Seq(AddressSet(address, 4096-1)), device, "reg/control", beatBytes=beatBytes)
|
||||||
|
|||||||
Reference in New Issue
Block a user