Add example clocking configs and SingleClockBroadcast option
This commit is contained in:
@@ -102,38 +102,28 @@ class WithPassthroughClockGenerator extends OverrideLazyIOBinder({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// Broadcasts a single clock IO to all clock domains
|
// Broadcasts a single clock IO to all clock domains. Ignores all requested frequencies
|
||||||
class WithSingleClockBroadcastClockGenerator extends OverrideLazyIOBinder({
|
class WithSingleClockBroadcastClockGenerator(freqMHz: Int = 100) extends OverrideLazyIOBinder({
|
||||||
(system: HasChipyardPRCI) => {
|
(system: HasChipyardPRCI) => {
|
||||||
implicit val p = GetSystemParameters(system)
|
implicit val p = GetSystemParameters(system)
|
||||||
val implicitClockSinkNode = ClockSinkNode(Seq(ClockSinkParameters(name = Some("implicit_clock"))))
|
|
||||||
system.connectImplicitClockSinkNode(implicitClockSinkNode)
|
|
||||||
InModuleBody {
|
|
||||||
val implicit_clock = implicitClockSinkNode.in.head._1.clock
|
|
||||||
val implicit_reset = implicitClockSinkNode.in.head._1.reset
|
|
||||||
system.asInstanceOf[BaseSubsystem].module match { case l: LazyModuleImp => {
|
|
||||||
l.clock := implicit_clock
|
|
||||||
l.reset := implicit_reset
|
|
||||||
}}
|
|
||||||
}
|
|
||||||
|
|
||||||
val clockGroupsAggregateNode = ClockGroupAggregateNode("single_clock")
|
val clockGroupsAggregator = LazyModule(new ClockGroupAggregator("single_clock"))
|
||||||
val clockGroupsSourceNode = ClockGroupSourceNode(Seq(ClockGroupSourceParameters()))
|
val clockGroupsSourceNode = ClockGroupSourceNode(Seq(ClockGroupSourceParameters()))
|
||||||
system.allClockGroupsNode :*= clockGroupsAggregateNode := clockGroupsSourceNode
|
system.chiptopClockGroupsNode :*= clockGroupsAggregator.node := clockGroupsSourceNode
|
||||||
|
|
||||||
InModuleBody {
|
InModuleBody {
|
||||||
val clock_wire = Wire(Input(new ClockWithFreq(100)))
|
val clock_wire = Wire(Input(Clock()))
|
||||||
val reset_wire = Wire(Input(AsyncReset()))
|
val reset_wire = Wire(Input(AsyncReset()))
|
||||||
val (clock_io, clockIOCell) = IOCell.generateIOFromSignal(clock_wire, "clock", p(IOCellKey))
|
val (clock_io, clockIOCell) = IOCell.generateIOFromSignal(clock_wire, "clock", p(IOCellKey))
|
||||||
val (reset_io, resetIOCell) = IOCell.generateIOFromSignal(reset_wire, "reset", p(IOCellKey))
|
val (reset_io, resetIOCell) = IOCell.generateIOFromSignal(reset_wire, "reset", p(IOCellKey))
|
||||||
|
|
||||||
clockGroupsSourceNode.out.foreach { case (bundle, edge) =>
|
clockGroupsSourceNode.out.foreach { case (bundle, edge) =>
|
||||||
bundle.member.data.foreach { b =>
|
bundle.member.data.foreach { b =>
|
||||||
b.clock := clock_io.clock
|
b.clock := clock_io
|
||||||
b.reset := reset_io
|
b.reset := reset_io
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(Seq(clock_io, reset_io), clockIOCell ++ resetIOCell)
|
(Seq(ClockPort(() => clock_io, freqMHz), ResetPort(() => reset_io)), clockIOCell ++ resetIOCell)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package chipyard
|
||||||
|
|
||||||
|
import org.chipsalliance.cde.config.{Config}
|
||||||
|
import freechips.rocketchip.diplomacy._
|
||||||
|
import freechips.rocketchip.subsystem.{MBUS, SBUS}
|
||||||
|
import testchipip.soc.{OBUS}
|
||||||
|
|
||||||
|
//==================================================
|
||||||
|
// This file contains examples of the different ways
|
||||||
|
// clocks can be generated for chiypard designs
|
||||||
|
//==================================================
|
||||||
|
|
||||||
|
// The default constructs IOs for all requested clocks in the chiptopClockGroupsNode
|
||||||
|
// Note: This is what designs inheriting from AbstractConfig do by default
|
||||||
|
class DefaultClockingRocketConfig extends Config(
|
||||||
|
new chipyard.clocking.WithPassthroughClockGenerator ++
|
||||||
|
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
||||||
|
new chipyard.config.AbstractConfig)
|
||||||
|
|
||||||
|
// This is a more physically realistic approach, normally we can't punch out a separate
|
||||||
|
// pin for each clock domain. The standard "test chip" approach is to punch a few slow clock
|
||||||
|
// inputs, integrate a PLL, and generate an array of selectors/dividers to configure the
|
||||||
|
// clocks for each domain. See the source for WithPLLSelectorDividerClockGenerator for more info
|
||||||
|
class ChipLikeClockingRocketConfig extends Config(
|
||||||
|
new chipyard.clocking.WithPLLSelectorDividerClockGenerator ++
|
||||||
|
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
||||||
|
new chipyard.config.AbstractConfig)
|
||||||
|
|
||||||
|
// This merges all the clock domains in chiptopClockGroupsNode into one, then generates a single
|
||||||
|
// clock input pin.
|
||||||
|
class SingleClockBroadcastRocketConfig extends Config(
|
||||||
|
new chipyard.clocking.WithSingleClockBroadcastClockGenerator ++
|
||||||
|
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
||||||
|
new chipyard.config.AbstractConfig)
|
||||||
Reference in New Issue
Block a user