Skip to content

Commit

Permalink
Add reset pipeline support
Browse files Browse the repository at this point in the history
  • Loading branch information
jerryz123 committed Aug 8, 2024
1 parent 7eb2cc1 commit 20c053b
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 0 deletions.
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)
}
}
}
}
}
}
2 changes: 2 additions & 0 deletions generators/chipyard/src/main/scala/config/ChipConfigs.scala
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ class ChipLikeRocketConfig extends Config(
//==================================
// Set up clock./reset
//==================================
new chipyard.config.WithSyncResetPipeStages(3) ++ // improves timing of sync reset
new chipyard.clocking.WithPLLSelectorDividerClockGenerator ++ // Use a PLL-based clock selector/divider generator structure

// Create the uncore clock group
Expand Down Expand Up @@ -129,6 +130,7 @@ class VerilatorCITetheredChipLikeRocketConfig extends Config(
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.WithSyncResetPipeStages(0) ++
new chipyard.config.WithNoResetSynchronizers ++
new ChipLikeRocketConfig) ++
new chipyard.harness.WithMultiChip(1, new ChipBringupHostConfig))
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)
})

0 comments on commit 20c053b

Please sign in to comment.