Merge pull request #37 from sifive/synchronizers
remove duplicate ResetCatchAndSync definition
This commit is contained in:
commit
d5554bfe95
@ -4,6 +4,7 @@ package sifive.blocks.devices.gpio
|
|||||||
import Chisel._
|
import Chisel._
|
||||||
import sifive.blocks.devices.pinctrl.{PinCtrl, Pin, BasePin, EnhancedPin, EnhancedPinCtrl}
|
import sifive.blocks.devices.pinctrl.{PinCtrl, Pin, BasePin, EnhancedPin, EnhancedPinCtrl}
|
||||||
import freechips.rocketchip.config.Parameters
|
import freechips.rocketchip.config.Parameters
|
||||||
|
import freechips.rocketchip.util.SynchronizerShiftReg
|
||||||
import freechips.rocketchip.regmapper._
|
import freechips.rocketchip.regmapper._
|
||||||
import freechips.rocketchip.tilelink._
|
import freechips.rocketchip.tilelink._
|
||||||
import freechips.rocketchip.util.{AsyncResetRegVec, GenericParameterizedBundle}
|
import freechips.rocketchip.util.{AsyncResetRegVec, GenericParameterizedBundle}
|
||||||
@ -106,7 +107,7 @@ trait HasGPIOModuleContents extends Module with HasRegMap {
|
|||||||
// Synchronize Input to get valueReg
|
// Synchronize Input to get valueReg
|
||||||
val inVal = Wire(UInt(0, width=c.width))
|
val inVal = Wire(UInt(0, width=c.width))
|
||||||
inVal := Vec(io.port.pins.map(_.i.ival)).asUInt
|
inVal := Vec(io.port.pins.map(_.i.ival)).asUInt
|
||||||
val inSyncReg = ShiftRegister(inVal, 3)
|
val inSyncReg = SynchronizerShiftReg(inVal, 3, Some("inSyncReg"))
|
||||||
val valueReg = Reg(init = UInt(0, c.width), next = inSyncReg)
|
val valueReg = Reg(init = UInt(0, c.width), next = inSyncReg)
|
||||||
|
|
||||||
// Interrupt Configuration
|
// Interrupt Configuration
|
||||||
|
@ -3,9 +3,8 @@ package sifive.blocks.devices.i2c
|
|||||||
|
|
||||||
import Chisel._
|
import Chisel._
|
||||||
import chisel3.experimental.{withClockAndReset}
|
import chisel3.experimental.{withClockAndReset}
|
||||||
|
import freechips.rocketchip.util.SyncResetSynchronizerShiftReg
|
||||||
import sifive.blocks.devices.pinctrl.{Pin, PinCtrl}
|
import sifive.blocks.devices.pinctrl.{Pin, PinCtrl}
|
||||||
import sifive.blocks.util.ShiftRegisterInit
|
|
||||||
|
|
||||||
|
|
||||||
class I2CPins[T <: Pin](pingen: () => T) extends Bundle {
|
class I2CPins[T <: Pin](pingen: () => T) extends Bundle {
|
||||||
|
|
||||||
@ -19,11 +18,13 @@ class I2CPins[T <: Pin](pingen: () => T) extends Bundle {
|
|||||||
withClockAndReset(clock, reset) {
|
withClockAndReset(clock, reset) {
|
||||||
scl.outputPin(i2c.scl.out, pue=true.B, ie = true.B)
|
scl.outputPin(i2c.scl.out, pue=true.B, ie = true.B)
|
||||||
scl.o.oe := i2c.scl.oe
|
scl.o.oe := i2c.scl.oe
|
||||||
i2c.scl.in := ShiftRegisterInit(scl.i.ival, syncStages, Bool(true))
|
i2c.scl.in := SyncResetSynchronizerShiftReg(scl.i.ival, syncStages, init = Bool(true),
|
||||||
|
name = Some("i2c_scl_sync"))
|
||||||
|
|
||||||
sda.outputPin(i2c.sda.out, pue=true.B, ie = true.B)
|
sda.outputPin(i2c.sda.out, pue=true.B, ie = true.B)
|
||||||
sda.o.oe := i2c.sda.oe
|
sda.o.oe := i2c.sda.oe
|
||||||
i2c.sda.in := ShiftRegisterInit(sda.i.ival, syncStages, Bool(true))
|
i2c.sda.in := SyncResetSynchronizerShiftReg(sda.i.ival, syncStages, init = Bool(true),
|
||||||
|
name = Some("i2c_sda_sync"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package sifive.blocks.devices.mockaon
|
|||||||
|
|
||||||
import Chisel._
|
import Chisel._
|
||||||
import freechips.rocketchip.config.Field
|
import freechips.rocketchip.config.Field
|
||||||
|
import freechips.rocketchip.util.SynchronizerShiftReg
|
||||||
import freechips.rocketchip.coreplex.{HasPeripheryBus, HasInterruptBus}
|
import freechips.rocketchip.coreplex.{HasPeripheryBus, HasInterruptBus}
|
||||||
import freechips.rocketchip.devices.debug.HasPeripheryDebug
|
import freechips.rocketchip.devices.debug.HasPeripheryDebug
|
||||||
import freechips.rocketchip.devices.tilelink.HasPeripheryClint
|
import freechips.rocketchip.devices.tilelink.HasPeripheryClint
|
||||||
@ -43,7 +44,7 @@ trait HasPeripheryMockAONModuleImp extends LazyMultiIOModuleImp with HasPeripher
|
|||||||
outer.aon.module.reset := Bool(true)
|
outer.aon.module.reset := Bool(true)
|
||||||
|
|
||||||
// Synchronize the external toggle into the clint
|
// Synchronize the external toggle into the clint
|
||||||
val rtc_sync = ShiftRegister(outer.aon.module.io.rtc.asUInt.toBool, 3)
|
val rtc_sync = SynchronizerShiftReg(outer.aon.module.io.rtc.asUInt.toBool, 3, Some("rtc"))
|
||||||
val rtc_last = Reg(init = Bool(false), next=rtc_sync)
|
val rtc_last = Reg(init = Bool(false), next=rtc_sync)
|
||||||
val rtc_tick = Reg(init = Bool(false), next=(rtc_sync & (~rtc_last)))
|
val rtc_tick = Reg(init = Bool(false), next=(rtc_sync & (~rtc_last)))
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ import freechips.rocketchip.diplomacy._
|
|||||||
import freechips.rocketchip.tilelink._
|
import freechips.rocketchip.tilelink._
|
||||||
import freechips.rocketchip.util._
|
import freechips.rocketchip.util._
|
||||||
import sifive.blocks.devices.pinctrl.{EnhancedPin}
|
import sifive.blocks.devices.pinctrl.{EnhancedPin}
|
||||||
import sifive.blocks.util.{DeglitchShiftRegister, ResetCatchAndSync}
|
import sifive.blocks.util.{DeglitchShiftRegister}
|
||||||
|
|
||||||
/* The wrapper handles the Clock and Reset Generation for The AON block itself,
|
/* The wrapper handles the Clock and Reset Generation for The AON block itself,
|
||||||
and instantiates real pad controls (aka pull-ups)*/
|
and instantiates real pad controls (aka pull-ups)*/
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
package sifive.blocks.devices.spi
|
package sifive.blocks.devices.spi
|
||||||
|
|
||||||
import Chisel._
|
import Chisel._
|
||||||
import sifive.blocks.util.ShiftRegisterInit
|
import freechips.rocketchip.util.ShiftRegInit
|
||||||
|
|
||||||
class SPIMicroOp(c: SPIParamsBase) extends SPIBundle(c) {
|
class SPIMicroOp(c: SPIParamsBase) extends SPIBundle(c) {
|
||||||
val fn = Bits(width = 1)
|
val fn = Bits(width = 1)
|
||||||
@ -39,8 +39,8 @@ class SPIPhysical(c: SPIParamsBase) extends Module {
|
|||||||
val last = Wire(init = Bool(false))
|
val last = Wire(init = Bool(false))
|
||||||
// Delayed versions
|
// Delayed versions
|
||||||
val setup_d = Reg(next = setup)
|
val setup_d = Reg(next = setup)
|
||||||
val sample_d = ShiftRegisterInit(sample, c.sampleDelay, Bool(false))
|
val sample_d = ShiftRegInit(sample, c.sampleDelay, init = Bool(false))
|
||||||
val last_d = ShiftRegisterInit(last, c.sampleDelay, Bool(false))
|
val last_d = ShiftRegInit(last, c.sampleDelay, init = Bool(false))
|
||||||
|
|
||||||
val scnt = Reg(init = UInt(0, c.countBits))
|
val scnt = Reg(init = UInt(0, c.countBits))
|
||||||
val tcnt = Reg(io.ctrl.sck.div)
|
val tcnt = Reg(io.ctrl.sck.div)
|
||||||
|
@ -4,10 +4,10 @@ package sifive.blocks.devices.uart
|
|||||||
import Chisel._
|
import Chisel._
|
||||||
import chisel3.experimental.{withClockAndReset}
|
import chisel3.experimental.{withClockAndReset}
|
||||||
import freechips.rocketchip.config.Field
|
import freechips.rocketchip.config.Field
|
||||||
|
import freechips.rocketchip.util.SyncResetSynchronizerShiftReg
|
||||||
import freechips.rocketchip.coreplex.{HasPeripheryBus, PeripheryBusParams, HasInterruptBus}
|
import freechips.rocketchip.coreplex.{HasPeripheryBus, PeripheryBusParams, HasInterruptBus}
|
||||||
import freechips.rocketchip.diplomacy.{LazyModule, LazyMultiIOModuleImp}
|
import freechips.rocketchip.diplomacy.{LazyModule, LazyMultiIOModuleImp}
|
||||||
import sifive.blocks.devices.pinctrl.{Pin}
|
import sifive.blocks.devices.pinctrl.{Pin}
|
||||||
import sifive.blocks.util.ShiftRegisterInit
|
|
||||||
|
|
||||||
case object PeripheryUARTKey extends Field[Seq[UARTParams]]
|
case object PeripheryUARTKey extends Field[Seq[UARTParams]]
|
||||||
|
|
||||||
@ -51,7 +51,7 @@ class UARTPins[T <: Pin] (pingen: () => T) extends Bundle {
|
|||||||
withClockAndReset(clock, reset) {
|
withClockAndReset(clock, reset) {
|
||||||
txd.outputPin(uart.txd)
|
txd.outputPin(uart.txd)
|
||||||
val rxd_t = rxd.inputPin()
|
val rxd_t = rxd.inputPin()
|
||||||
uart.rxd := ShiftRegisterInit(rxd_t, syncStages, Bool(true))
|
uart.rxd := SyncResetSynchronizerShiftReg(rxd_t, syncStages, init = Bool(true), name = Some("uart_rxd_sync"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,42 +0,0 @@
|
|||||||
// See LICENSE for license details.
|
|
||||||
package sifive.blocks.util
|
|
||||||
|
|
||||||
import Chisel._
|
|
||||||
import freechips.rocketchip.util.AsyncResetRegVec
|
|
||||||
|
|
||||||
/** Reset: asynchronous assert,
|
|
||||||
* synchronous de-assert
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
class ResetCatchAndSync (sync: Int = 3) extends Module {
|
|
||||||
|
|
||||||
val io = new Bundle {
|
|
||||||
val sync_reset = Bool(OUTPUT)
|
|
||||||
}
|
|
||||||
|
|
||||||
val reset_n_catch_reg = Module (new AsyncResetRegVec(sync, 0))
|
|
||||||
|
|
||||||
reset_n_catch_reg.io.en := Bool(true)
|
|
||||||
reset_n_catch_reg.io.d := Cat(Bool(true), reset_n_catch_reg.io.q >> 1)
|
|
||||||
|
|
||||||
io.sync_reset := ~reset_n_catch_reg.io.q(0)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
object ResetCatchAndSync {
|
|
||||||
|
|
||||||
def apply(clk: Clock, rst: Bool, sync: Int = 3, name: Option[String] = None): Bool = {
|
|
||||||
|
|
||||||
val catcher = Module (new ResetCatchAndSync(sync))
|
|
||||||
if (name.isDefined) {catcher.suggestName(name.get)}
|
|
||||||
catcher.clock := clk
|
|
||||||
catcher.reset := rst
|
|
||||||
|
|
||||||
catcher.io.sync_reset
|
|
||||||
}
|
|
||||||
|
|
||||||
def apply(clk: Clock, rst: Bool, sync: Int, name: String): Bool = apply(clk, rst, sync, Some(name))
|
|
||||||
def apply(clk: Clock, rst: Bool, name: String): Bool = apply(clk, rst, name = Some(name))
|
|
||||||
|
|
||||||
}
|
|
@ -1,54 +0,0 @@
|
|||||||
// See LICENSE for license details.
|
|
||||||
package sifive.blocks.util
|
|
||||||
|
|
||||||
import Chisel._
|
|
||||||
|
|
||||||
object ShiftRegisterInit {
|
|
||||||
def apply[T <: Data](in: T, n: Int, init: T): T =
|
|
||||||
(0 until n).foldLeft(in) {
|
|
||||||
case (next, _) => Reg(next, next = next, init = init)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Similar to the Chisel ShiftRegister but allows the user to suggest a
|
|
||||||
// name to the registers within the module that get instantiated
|
|
||||||
object ShiftRegister
|
|
||||||
{
|
|
||||||
/** Returns the n-cycle delayed version of the input signal.
|
|
||||||
*
|
|
||||||
* @param in input to delay
|
|
||||||
* @param n number of cycles to delay
|
|
||||||
* @param en enable the shift
|
|
||||||
* @param name set the elaborated name of the registers.
|
|
||||||
*/
|
|
||||||
def apply[T <: Chisel.Data](in: T, n: Int, en: Chisel.Bool = Chisel.Bool(true), name: Option[String] = None): T = {
|
|
||||||
// The order of tests reflects the expected use cases.
|
|
||||||
if (n != 0) {
|
|
||||||
val r = Chisel.RegEnable(apply(in, n-1, en, name), en)
|
|
||||||
if (name.isDefined) r.suggestName(s"${name.get}_sync_${n-1}")
|
|
||||||
r
|
|
||||||
} else {
|
|
||||||
in
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns the n-cycle delayed version of the input signal with reset initialization.
|
|
||||||
*
|
|
||||||
* @param in input to delay
|
|
||||||
* @param n number of cycles to delay
|
|
||||||
* @param resetData reset value for each register in the shift
|
|
||||||
* @param en enable the shift
|
|
||||||
* @param name set the elaborated name of the registers.
|
|
||||||
*/
|
|
||||||
def apply[T <: Chisel.Data](in: T, n: Int, resetData: T, en: Chisel.Bool, name: Option[String]): T = {
|
|
||||||
// The order of tests reflects the expected use cases.
|
|
||||||
if (n != 0) {
|
|
||||||
val r = Chisel.RegEnable(apply(in, n-1, resetData, en, name), resetData, en)
|
|
||||||
if (name.isDefined) r.suggestName(s"${name.get}_sync_${n-1}")
|
|
||||||
r
|
|
||||||
} else {
|
|
||||||
in
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user