Skip to content

Commit

Permalink
Merge pull request #703 from ucb-bar/default-async-reset
Browse files Browse the repository at this point in the history
Make the ChipTop reset pin always async
  • Loading branch information
jerryz123 authored Oct 29, 2020
2 parents d61b31a + f4d7012 commit a385963
Show file tree
Hide file tree
Showing 4 changed files with 15 additions and 60 deletions.
52 changes: 5 additions & 47 deletions generators/chipyard/src/main/scala/Clocks.scala
Original file line number Diff line number Diff line change
Expand Up @@ -15,40 +15,6 @@ import testchipip.{TLTileResetCtrl}

import chipyard.clocking._

/**
* Chipyard provides three baseline, top-level reset schemes, set using the
* [[GlobalResetSchemeKey]] in a Parameters instance. These are:
*
* 1) Synchronous: The input coming to the chip is synchronous to the provided
* clocks and will be used without modification as a synchronous reset.
* This is safe only for use in FireSim and SW simulation.
*
* 2) Asynchronous: The input reset is asynchronous to the input clock, but it
* is caught and synchronized to that clock before it is dissemenated.
* Thus, downsteam modules will be emitted with synchronously reset state
* elements.
*
* 3) Asynchronous Full: The input reset is asynchronous to the input clock,
* and is used globally as an async reset. Downstream modules will be emitted
* with asynchronously reset state elements.
*
*/
sealed trait GlobalResetScheme {
def pinIsAsync: Boolean
}
sealed trait HasAsyncInput { self: GlobalResetScheme =>
def pinIsAsync = true
}

sealed trait HasSyncInput { self: GlobalResetScheme =>
def pinIsAsync = false
}

case object GlobalResetSynchronous extends GlobalResetScheme with HasSyncInput
case object GlobalResetAsynchronous extends GlobalResetScheme with HasAsyncInput
case object GlobalResetAsynchronousFull extends GlobalResetScheme with HasAsyncInput
case object GlobalResetSchemeKey extends Field[GlobalResetScheme](GlobalResetSynchronous)

/**
* A simple reset implementation that punches out reset ports
* for standard Module classes. Three basic reset schemes
Expand All @@ -58,24 +24,16 @@ object GenerateReset {
def apply(chiptop: ChipTop, clock: Clock): Reset = {
implicit val p = chiptop.p
// this needs directionality so generateIOFromSignal works
val reset_wire = Wire(Input(Reset()))
val (reset_io, resetIOCell) = p(GlobalResetSchemeKey) match {
case GlobalResetSynchronous =>
IOCell.generateIOFromSignal(reset_wire, "reset")
case GlobalResetAsynchronousFull =>
IOCell.generateIOFromSignal(reset_wire, "reset", abstractResetAsAsync = true)
case GlobalResetAsynchronous => {
val async_reset_wire = Wire(Input(AsyncReset()))
reset_wire := ResetCatchAndSync(clock, async_reset_wire.asBool())
IOCell.generateIOFromSignal(async_reset_wire, "reset", abstractResetAsAsync = true)
}
}
val async_reset_wire = Wire(Input(AsyncReset()))
val (reset_io, resetIOCell) = IOCell.generateIOFromSignal(async_reset_wire, "reset",
abstractResetAsAsync = true)

chiptop.iocells ++= resetIOCell
chiptop.harnessFunctions += ((th: HasHarnessSignalReferences) => {
reset_io := th.dutReset
Nil
})
reset_wire
async_reset_wire
}
}

Expand Down
18 changes: 8 additions & 10 deletions generators/chipyard/src/main/scala/IOBinders.scala
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@ import barstools.iocell.chisel._
import testchipip._
import icenet.{CanHavePeripheryIceNIC, SimNetwork, NicLoopback, NICKey, NICIOvonly}

import chipyard.GlobalResetSchemeKey

import scala.reflect.{ClassTag}

// System for instantiating binders based
Expand Down Expand Up @@ -157,7 +155,7 @@ class WithGPIOCells extends OverrideIOBinder({
class WithUARTIOCells extends OverrideIOBinder({
(system: HasPeripheryUARTModuleImp) => {
val (ports: Seq[UARTPortIO], cells2d) = system.uart.zipWithIndex.map({ case (u, i) =>
val (port, ios) = IOCell.generateIOFromSignal(u, s"uart_${i}", system.p(IOCellKey))
val (port, ios) = IOCell.generateIOFromSignal(u, s"uart_${i}", system.p(IOCellKey), abstractResetAsAsync = true)
(port, ios)
}).unzip
(ports, cells2d.flatten)
Expand All @@ -173,8 +171,8 @@ class WithSPIIOCells extends OverrideIOBinder({
val iocellBase = s"iocell_${name}"

// SCK and CS are unidirectional outputs
val sckIOs = IOCell.generateFromSignal(s.sck, port.sck, Some(s"${iocellBase}_sck"), system.p(IOCellKey))
val csIOs = IOCell.generateFromSignal(s.cs, port.cs, Some(s"${iocellBase}_cs"), system.p(IOCellKey))
val sckIOs = IOCell.generateFromSignal(s.sck, port.sck, Some(s"${iocellBase}_sck"), system.p(IOCellKey), IOCell.toAsyncReset)
val csIOs = IOCell.generateFromSignal(s.cs, port.cs, Some(s"${iocellBase}_cs"), system.p(IOCellKey), IOCell.toAsyncReset)

// DQ are bidirectional, so then need special treatment
val dqIOs = s.dq.zip(port.dq).zipWithIndex.map { case ((pin, ana), j) =>
Expand All @@ -196,7 +194,7 @@ class WithSPIIOCells extends OverrideIOBinder({
class WithExtInterruptIOCells extends OverrideIOBinder({
(system: HasExtInterruptsModuleImp) => {
if (system.outer.nExtInterrupts > 0) {
val (port: UInt, cells) = IOCell.generateIOFromSignal(system.interrupts, "ext_interrupts", system.p(IOCellKey))
val (port: UInt, cells) = IOCell.generateIOFromSignal(system.interrupts, "ext_interrupts", system.p(IOCellKey), abstractResetAsAsync = true)
(Seq(port), cells)
} else {
(Nil, Nil)
Expand Down Expand Up @@ -240,15 +238,15 @@ class WithDebugIOCells extends OverrideIOBinder({

// Add IOCells for the DMI/JTAG/APB ports
val dmiTuple = debug.clockeddmi.map { d =>
IOCell.generateIOFromSignal(d, "dmi", p(IOCellKey), abstractResetAsAsync = p(GlobalResetSchemeKey).pinIsAsync)
IOCell.generateIOFromSignal(d, "dmi", p(IOCellKey), abstractResetAsAsync = true)
}

val jtagTuple = debug.systemjtag.map { j =>
IOCell.generateIOFromSignal(j.jtag, "jtag", p(IOCellKey), abstractResetAsAsync = p(GlobalResetSchemeKey).pinIsAsync)
IOCell.generateIOFromSignal(j.jtag, "jtag", p(IOCellKey), abstractResetAsAsync = true)
}

val apbTuple = debug.apb.map { a =>
IOCell.generateIOFromSignal(a, "apb", p(IOCellKey), abstractResetAsAsync = p(GlobalResetSchemeKey).pinIsAsync)
IOCell.generateIOFromSignal(a, "apb", p(IOCellKey), abstractResetAsAsync = true)
}

val allTuples = (dmiTuple ++ jtagTuple ++ apbTuple).toSeq
Expand All @@ -260,7 +258,7 @@ class WithDebugIOCells extends OverrideIOBinder({
class WithSerialTLIOCells extends OverrideIOBinder({
(system: CanHavePeripheryTLSerial) => system.serial_tl.map({ s =>
val sys = system.asInstanceOf[BaseSubsystem]
val (port, cells) = IOCell.generateIOFromSignal(s.getWrappedValue, "serial_tl", sys.p(IOCellKey))
val (port, cells) = IOCell.generateIOFromSignal(s.getWrappedValue, "serial_tl", sys.p(IOCellKey), abstractResetAsAsync = true)
(Seq(port), cells)
}).getOrElse((Nil, Nil))
})
Expand Down
3 changes: 1 addition & 2 deletions generators/chipyard/src/main/scala/TestHarness.scala
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,7 @@ class TestHarness(implicit val p: Parameters) extends Module with HasHarnessSign
val harnessReset = WireInit(reset)
val success = io.success

// dutReset assignment can be overridden via a harnessFunction, but by default it is just reset
val dutReset = WireDefault(if (p(GlobalResetSchemeKey).pinIsAsync) reset.asAsyncReset else reset)
val dutReset = reset.asAsyncReset

lazyDut match { case d: HasTestHarnessFunctions =>
d.harnessFunctions.foreach(_(this))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import freechips.rocketchip.util.{ResetCatchAndSync}
* Instantiates a reset synchronizer on all clock-reset pairs in a clock group
*/
class ClockGroupResetSynchronizer(implicit p: Parameters) extends LazyModule {
val node = ClockGroupIdentityNode()
val node = ClockGroupAdapterNode()
lazy val module = new LazyRawModuleImp(this) {
(node.out zip node.in).map { case ((oG, _), (iG, _)) =>
(oG.member.data zip iG.member.data).foreach { case (o, i) =>
Expand Down

0 comments on commit a385963

Please sign in to comment.