Skip to content

Commit 9a7077b

Browse files
committed
Add reset pipeline support
1 parent 7eb2cc1 commit 9a7077b

File tree

3 files changed

+45
-0
lines changed

3 files changed

+45
-0
lines changed

generators/chipyard/src/main/scala/clocking/HasChipyardPRCI.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import testchipip.clocking.{ClockGroupFakeResetSynchronizer}
2020
case class ChipyardPRCIControlParams(
2121
slaveWhere: TLBusWrapperLocation = CBUS,
2222
baseAddress: BigInt = 0x100000,
23+
resetPipeStages: Int = 0,
2324
enableTileClockGating: Boolean = true,
2425
enableTileResetSetting: Boolean = true,
2526
enableResetSynchronizers: Boolean = true // this should only be disabled to work around verilator async-reset initialization problems
@@ -66,6 +67,7 @@ trait HasChipyardPRCI { this: BaseSubsystem with InstantiatesHierarchicalElement
6667
// diplomatic IOBinder should drive
6768
val frequencySpecifier = ClockGroupFrequencySpecifier(p(ClockFrequencyAssignersKey))
6869
val clockGroupCombiner = ClockGroupCombiner()
70+
val resetPipeline = prci_ctrl_domain { LazyModule(new ResetPipeline(prciParams.resetPipeStages)) }
6971
val resetSynchronizer = prci_ctrl_domain {
7072
if (prciParams.enableResetSynchronizers) ClockGroupResetSynchronizer() else ClockGroupFakeResetSynchronizer()
7173
}
@@ -105,6 +107,7 @@ RTL SIMULATORS, NAMELY VERILATOR.
105107

106108
(aggregator
107109
:= frequencySpecifier
110+
:= resetPipeline.node
108111
:= clockGroupCombiner
109112
:= resetSynchronizer
110113
:= tileClockGater.map(_.clockNode).getOrElse(ClockGroupEphemeralNode()(ValName("temp")))
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package chipyard.clocking
2+
3+
import chisel3._
4+
import chisel3.util._
5+
import org.chipsalliance.cde.config._
6+
import org.chipsalliance.diplomacy._
7+
import org.chipsalliance.diplomacy.lazymodule._
8+
import freechips.rocketchip.prci.{ClockGroupAdapterNode}
9+
10+
/** This adapter takes input synchronous resets and stretch them via a reset pipeline
11+
* This is useful for distributing a synchronous reset across the chip
12+
*/
13+
class ResetPipeline(stages: Int)(implicit p: Parameters) extends LazyModule {
14+
val node = ClockGroupAdapterNode()(ValName(s"reset_pipeline_$stages"))
15+
override lazy val desiredName = s"ResetPipeline$stages"
16+
lazy val module = new Impl
17+
class Impl extends LazyRawModuleImp(this) {
18+
(node.in zip node.out).foreach { case ((iG, _), (oG, _)) =>
19+
(oG.member.data zip iG.member.data).foreach { case (out, in) =>
20+
out.clock := in.clock
21+
withClock (in.clock) {
22+
if (stages == 0) {
23+
out.reset := in.reset
24+
} else {
25+
val regs = Seq.fill(stages)(Reg(Bool()))
26+
regs.head := in.reset
27+
out.reset := regs.last
28+
(regs.init zip regs.tail).foreach(t => t._2 := t._1)
29+
}
30+
}
31+
}
32+
}
33+
}
34+
}

generators/chipyard/src/main/scala/config/fragments/ClockingFragments.scala

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,3 +133,11 @@ class WithNoResetSynchronizers extends Config((site, here, up) => {
133133
class WithNoClockTap extends Config((site, here, up) => {
134134
case ClockTapKey => false
135135
})
136+
137+
// Adds a reset pipeline after the ResetSynchronizer in chipyard's clock/reset path
138+
// This assists with PD and timing of sync reset
139+
// NOTE: This will likely result in spurious early assertions when reset-assertion
140+
// is propagating through the pipeline. You may ignore these in RTL simulators
141+
class WithSyncResetPipeStages(stages: Int) extends Config((site, here, up) => {
142+
case ChipyardPRCIControlKey => up(ChipyardPRCIControlKey).copy(resetPipeStages = stages)
143+
})

0 commit comments

Comments
 (0)