Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add reset pipeline support #1983

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import testchipip.clocking.{ClockGroupFakeResetSynchronizer}
case class ChipyardPRCIControlParams(
slaveWhere: TLBusWrapperLocation = CBUS,
baseAddress: BigInt = 0x100000,
resetPipeStages: Int = 0,
enableTileClockGating: Boolean = true,
enableTileResetSetting: Boolean = true,
enableResetSynchronizers: Boolean = true // this should only be disabled to work around verilator async-reset initialization problems
Expand Down Expand Up @@ -66,6 +67,7 @@ trait HasChipyardPRCI { this: BaseSubsystem with InstantiatesHierarchicalElement
// diplomatic IOBinder should drive
val frequencySpecifier = ClockGroupFrequencySpecifier(p(ClockFrequencyAssignersKey))
val clockGroupCombiner = ClockGroupCombiner()
val resetPipeline = prci_ctrl_domain { LazyModule(new ResetPipeline(prciParams.resetPipeStages)) }
val resetSynchronizer = prci_ctrl_domain {
if (prciParams.enableResetSynchronizers) ClockGroupResetSynchronizer() else ClockGroupFakeResetSynchronizer()
}
Expand Down Expand Up @@ -105,6 +107,7 @@ RTL SIMULATORS, NAMELY VERILATOR.

(aggregator
:= frequencySpecifier
:= resetPipeline.node
:= clockGroupCombiner
:= resetSynchronizer
:= tileClockGater.map(_.clockNode).getOrElse(ClockGroupEphemeralNode()(ValName("temp")))
Expand Down
34 changes: 34 additions & 0 deletions generators/chipyard/src/main/scala/clocking/ResetPipeline.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package chipyard.clocking

import chisel3._
import chisel3.util._
import org.chipsalliance.cde.config._
import org.chipsalliance.diplomacy._
import org.chipsalliance.diplomacy.lazymodule._
import freechips.rocketchip.prci.{ClockGroupAdapterNode}

/** This adapter takes input synchronous resets and stretch them via a reset pipeline
* This is useful for distributing a synchronous reset across the chip
*/
class ResetPipeline(stages: Int)(implicit p: Parameters) extends LazyModule {
val node = ClockGroupAdapterNode()(ValName(s"reset_pipeline_$stages"))
override lazy val desiredName = s"ResetPipeline$stages"
lazy val module = new Impl
class Impl extends LazyRawModuleImp(this) {
(node.in zip node.out).foreach { case ((iG, _), (oG, _)) =>
(oG.member.data zip iG.member.data).foreach { case (out, in) =>
out.clock := in.clock
withClock (in.clock) {
if (stages == 0) {
out.reset := in.reset
} else {
val regs = Seq.fill(stages)(Reg(Bool()))
regs.head := in.reset
out.reset := regs.last
(regs.init zip regs.tail).foreach(t => t._2 := t._1)
}
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -133,3 +133,11 @@ class WithNoResetSynchronizers extends Config((site, here, up) => {
class WithNoClockTap extends Config((site, here, up) => {
case ClockTapKey => false
})

// Adds a reset pipeline after the ResetSynchronizer in chipyard's clock/reset path
// This assists with PD and timing of sync reset
// NOTE: This will likely result in spurious early assertions when reset-assertion
// is propagating through the pipeline. You may ignore these in RTL simulators
class WithSyncResetPipeStages(stages: Int) extends Config((site, here, up) => {
case ChipyardPRCIControlKey => up(ChipyardPRCIControlKey).copy(resetPipeStages = stages)
})
Loading