Merge pull request #703 from ucb-bar/default-async-reset
Make the ChipTop reset pin always async
This commit is contained in:
@@ -15,40 +15,6 @@ import testchipip.{TLTileResetCtrl}
|
|||||||
|
|
||||||
import chipyard.clocking._
|
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
|
* A simple reset implementation that punches out reset ports
|
||||||
* for standard Module classes. Three basic reset schemes
|
* for standard Module classes. Three basic reset schemes
|
||||||
@@ -58,24 +24,16 @@ object GenerateReset {
|
|||||||
def apply(chiptop: ChipTop, clock: Clock): Reset = {
|
def apply(chiptop: ChipTop, clock: Clock): Reset = {
|
||||||
implicit val p = chiptop.p
|
implicit val p = chiptop.p
|
||||||
// this needs directionality so generateIOFromSignal works
|
// 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()))
|
val async_reset_wire = Wire(Input(AsyncReset()))
|
||||||
reset_wire := ResetCatchAndSync(clock, async_reset_wire.asBool())
|
val (reset_io, resetIOCell) = IOCell.generateIOFromSignal(async_reset_wire, "reset",
|
||||||
IOCell.generateIOFromSignal(async_reset_wire, "reset", abstractResetAsAsync = true)
|
abstractResetAsAsync = true)
|
||||||
}
|
|
||||||
}
|
|
||||||
chiptop.iocells ++= resetIOCell
|
chiptop.iocells ++= resetIOCell
|
||||||
chiptop.harnessFunctions += ((th: HasHarnessSignalReferences) => {
|
chiptop.harnessFunctions += ((th: HasHarnessSignalReferences) => {
|
||||||
reset_io := th.dutReset
|
reset_io := th.dutReset
|
||||||
Nil
|
Nil
|
||||||
})
|
})
|
||||||
reset_wire
|
async_reset_wire
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,8 +24,6 @@ import barstools.iocell.chisel._
|
|||||||
import testchipip._
|
import testchipip._
|
||||||
import icenet.{CanHavePeripheryIceNIC, SimNetwork, NicLoopback, NICKey, NICIOvonly}
|
import icenet.{CanHavePeripheryIceNIC, SimNetwork, NicLoopback, NICKey, NICIOvonly}
|
||||||
|
|
||||||
import chipyard.GlobalResetSchemeKey
|
|
||||||
|
|
||||||
import scala.reflect.{ClassTag}
|
import scala.reflect.{ClassTag}
|
||||||
|
|
||||||
// System for instantiating binders based
|
// System for instantiating binders based
|
||||||
@@ -157,7 +155,7 @@ class WithGPIOCells extends OverrideIOBinder({
|
|||||||
class WithUARTIOCells extends OverrideIOBinder({
|
class WithUARTIOCells extends OverrideIOBinder({
|
||||||
(system: HasPeripheryUARTModuleImp) => {
|
(system: HasPeripheryUARTModuleImp) => {
|
||||||
val (ports: Seq[UARTPortIO], cells2d) = system.uart.zipWithIndex.map({ case (u, i) =>
|
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)
|
(port, ios)
|
||||||
}).unzip
|
}).unzip
|
||||||
(ports, cells2d.flatten)
|
(ports, cells2d.flatten)
|
||||||
@@ -173,8 +171,8 @@ class WithSPIIOCells extends OverrideIOBinder({
|
|||||||
val iocellBase = s"iocell_${name}"
|
val iocellBase = s"iocell_${name}"
|
||||||
|
|
||||||
// SCK and CS are unidirectional outputs
|
// SCK and CS are unidirectional outputs
|
||||||
val sckIOs = IOCell.generateFromSignal(s.sck, port.sck, Some(s"${iocellBase}_sck"), 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))
|
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
|
// DQ are bidirectional, so then need special treatment
|
||||||
val dqIOs = s.dq.zip(port.dq).zipWithIndex.map { case ((pin, ana), j) =>
|
val dqIOs = s.dq.zip(port.dq).zipWithIndex.map { case ((pin, ana), j) =>
|
||||||
@@ -196,7 +194,7 @@ class WithSPIIOCells extends OverrideIOBinder({
|
|||||||
class WithExtInterruptIOCells extends OverrideIOBinder({
|
class WithExtInterruptIOCells extends OverrideIOBinder({
|
||||||
(system: HasExtInterruptsModuleImp) => {
|
(system: HasExtInterruptsModuleImp) => {
|
||||||
if (system.outer.nExtInterrupts > 0) {
|
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)
|
(Seq(port), cells)
|
||||||
} else {
|
} else {
|
||||||
(Nil, Nil)
|
(Nil, Nil)
|
||||||
@@ -240,15 +238,15 @@ class WithDebugIOCells extends OverrideIOBinder({
|
|||||||
|
|
||||||
// Add IOCells for the DMI/JTAG/APB ports
|
// Add IOCells for the DMI/JTAG/APB ports
|
||||||
val dmiTuple = debug.clockeddmi.map { d =>
|
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 =>
|
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 =>
|
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
|
val allTuples = (dmiTuple ++ jtagTuple ++ apbTuple).toSeq
|
||||||
@@ -260,7 +258,7 @@ class WithDebugIOCells extends OverrideIOBinder({
|
|||||||
class WithSerialTLIOCells extends OverrideIOBinder({
|
class WithSerialTLIOCells extends OverrideIOBinder({
|
||||||
(system: CanHavePeripheryTLSerial) => system.serial_tl.map({ s =>
|
(system: CanHavePeripheryTLSerial) => system.serial_tl.map({ s =>
|
||||||
val sys = system.asInstanceOf[BaseSubsystem]
|
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)
|
(Seq(port), cells)
|
||||||
}).getOrElse((Nil, Nil))
|
}).getOrElse((Nil, Nil))
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -39,8 +39,7 @@ class TestHarness(implicit val p: Parameters) extends Module with HasHarnessSign
|
|||||||
val harnessReset = WireInit(reset)
|
val harnessReset = WireInit(reset)
|
||||||
val success = io.success
|
val success = io.success
|
||||||
|
|
||||||
// dutReset assignment can be overridden via a harnessFunction, but by default it is just reset
|
val dutReset = reset.asAsyncReset
|
||||||
val dutReset = WireDefault(if (p(GlobalResetSchemeKey).pinIsAsync) reset.asAsyncReset else reset)
|
|
||||||
|
|
||||||
lazyDut match { case d: HasTestHarnessFunctions =>
|
lazyDut match { case d: HasTestHarnessFunctions =>
|
||||||
d.harnessFunctions.foreach(_(this))
|
d.harnessFunctions.foreach(_(this))
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import freechips.rocketchip.util.{ResetCatchAndSync}
|
|||||||
* Instantiates a reset synchronizer on all clock-reset pairs in a clock group
|
* Instantiates a reset synchronizer on all clock-reset pairs in a clock group
|
||||||
*/
|
*/
|
||||||
class ClockGroupResetSynchronizer(implicit p: Parameters) extends LazyModule {
|
class ClockGroupResetSynchronizer(implicit p: Parameters) extends LazyModule {
|
||||||
val node = ClockGroupIdentityNode()
|
val node = ClockGroupAdapterNode()
|
||||||
lazy val module = new LazyRawModuleImp(this) {
|
lazy val module = new LazyRawModuleImp(this) {
|
||||||
(node.out zip node.in).map { case ((oG, _), (iG, _)) =>
|
(node.out zip node.in).map { case ((oG, _), (iG, _)) =>
|
||||||
(oG.member.data zip iG.member.data).foreach { case (o, i) =>
|
(oG.member.data zip iG.member.data).foreach { case (o, i) =>
|
||||||
|
|||||||
Reference in New Issue
Block a user