2016-11-28 01:16:37 +01:00
|
|
|
// See LICENSE.SiFive for license details.
|
|
|
|
|
2017-07-07 19:48:16 +02:00
|
|
|
package freechips.rocketchip.util
|
2016-09-09 05:01:03 +02:00
|
|
|
|
|
|
|
import Chisel._
|
|
|
|
|
|
|
|
/** This black-boxes an Async Reset
|
2016-09-16 22:50:09 +02:00
|
|
|
* (or Set)
|
|
|
|
* Register.
|
2016-09-09 05:01:03 +02:00
|
|
|
*
|
|
|
|
* Because Chisel doesn't support
|
|
|
|
* parameterized black boxes,
|
|
|
|
* we unfortunately have to
|
|
|
|
* instantiate a number of these.
|
|
|
|
*
|
2016-09-16 22:50:09 +02:00
|
|
|
* We also have to hard-code the set/
|
|
|
|
* reset behavior.
|
|
|
|
*
|
2016-09-09 05:01:03 +02:00
|
|
|
* Do not confuse an asynchronous
|
|
|
|
* reset signal with an asynchronously
|
|
|
|
* reset reg. You should still
|
|
|
|
* properly synchronize your reset
|
|
|
|
* deassertion.
|
|
|
|
*
|
|
|
|
* @param d Data input
|
|
|
|
* @param q Data Output
|
|
|
|
* @param clk Clock Input
|
|
|
|
* @param rst Reset Input
|
2016-09-16 22:50:09 +02:00
|
|
|
* @param en Write Enable Input
|
2016-09-09 05:01:03 +02:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2016-10-09 05:36:43 +02:00
|
|
|
class AsyncResetReg extends BlackBox {
|
2016-09-09 05:01:03 +02:00
|
|
|
val io = new Bundle {
|
|
|
|
val d = Bool(INPUT)
|
|
|
|
val q = Bool(OUTPUT)
|
2016-09-16 22:50:09 +02:00
|
|
|
val en = Bool(INPUT)
|
2016-09-09 05:01:03 +02:00
|
|
|
|
|
|
|
val clk = Clock(INPUT)
|
|
|
|
val rst = Bool(INPUT)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-09-10 01:24:35 +02:00
|
|
|
class SimpleRegIO(val w: Int) extends Bundle{
|
2016-09-09 05:01:03 +02:00
|
|
|
val d = UInt(INPUT, width = w)
|
|
|
|
val q = UInt(OUTPUT, width = w)
|
|
|
|
val en = Bool(INPUT)
|
|
|
|
}
|
|
|
|
|
2016-09-15 23:45:47 +02:00
|
|
|
class AsyncResetRegVec(val w: Int, val init: BigInt) extends Module {
|
2016-09-10 01:24:35 +02:00
|
|
|
val io = new SimpleRegIO(w)
|
2016-09-09 05:01:03 +02:00
|
|
|
|
2016-10-09 05:36:43 +02:00
|
|
|
val async_regs = List.fill(w)(Module(new AsyncResetReg))
|
2016-09-09 05:01:03 +02:00
|
|
|
|
2016-10-09 05:36:43 +02:00
|
|
|
val q = for ((reg, idx) <- async_regs.zipWithIndex) yield {
|
|
|
|
def maybeInvert(x: Bool) = if (((init >> idx) & 1) == 1) !x else x
|
2016-09-09 05:01:03 +02:00
|
|
|
reg.io.clk := clock
|
|
|
|
reg.io.rst := reset
|
2016-10-09 05:36:43 +02:00
|
|
|
reg.io.d := maybeInvert(io.d(idx))
|
2016-09-16 22:50:09 +02:00
|
|
|
reg.io.en := io.en
|
2016-10-01 01:19:25 +02:00
|
|
|
reg.suggestName(s"reg_$idx")
|
2016-10-09 05:36:43 +02:00
|
|
|
maybeInvert(reg.io.q)
|
2016-09-09 05:01:03 +02:00
|
|
|
}
|
|
|
|
|
2016-10-09 05:36:43 +02:00
|
|
|
io.q := q.asUInt
|
2017-08-25 00:33:53 +02:00
|
|
|
|
|
|
|
override def desiredName = s"AsyncResetRegVec_w${w}_i${init}"
|
|
|
|
|
2016-09-09 05:01:03 +02:00
|
|
|
}
|
2016-09-15 23:45:47 +02:00
|
|
|
|
|
|
|
object AsyncResetReg {
|
2016-10-01 01:19:25 +02:00
|
|
|
// Create Single Registers
|
|
|
|
def apply(d: Bool, clk: Clock, rst: Bool, init: Boolean, name: Option[String]): Bool = {
|
2016-10-09 05:36:43 +02:00
|
|
|
def maybeInvert(x: Bool) = if (init) !x else x
|
|
|
|
val reg = Module(new AsyncResetReg)
|
|
|
|
reg.io.d := maybeInvert(d)
|
2016-09-15 23:45:47 +02:00
|
|
|
reg.io.clk := clk
|
|
|
|
reg.io.rst := rst
|
2016-09-16 22:50:09 +02:00
|
|
|
reg.io.en := Bool(true)
|
2016-10-01 01:19:25 +02:00
|
|
|
name.foreach(reg.suggestName(_))
|
2016-10-09 05:36:43 +02:00
|
|
|
maybeInvert(reg.io.q)
|
2016-09-15 23:45:47 +02:00
|
|
|
}
|
|
|
|
|
2016-10-01 01:19:25 +02:00
|
|
|
def apply(d: Bool, clk: Clock, rst: Bool): Bool = apply(d, clk, rst, false, None)
|
|
|
|
def apply(d: Bool, clk: Clock, rst: Bool, name: String): Bool = apply(d, clk, rst, false, Some(name))
|
2016-09-15 23:45:47 +02:00
|
|
|
|
2016-10-01 01:19:25 +02:00
|
|
|
// Create Vectors of Registers
|
|
|
|
def apply(updateData: UInt, resetData: BigInt, enable: Bool, name: Option[String] = None): UInt = {
|
2016-09-15 23:45:47 +02:00
|
|
|
val w = updateData.getWidth max resetData.bitLength
|
|
|
|
val reg = Module(new AsyncResetRegVec(w, resetData))
|
2016-10-01 01:19:25 +02:00
|
|
|
name.foreach(reg.suggestName(_))
|
2016-09-15 23:45:47 +02:00
|
|
|
reg.io.d := updateData
|
|
|
|
reg.io.en := enable
|
|
|
|
reg.io.q
|
|
|
|
}
|
2016-10-01 01:19:25 +02:00
|
|
|
def apply(updateData: UInt, resetData: BigInt, enable: Bool, name: String): UInt = apply(updateData,
|
|
|
|
resetData, enable, Some(name))
|
|
|
|
|
2016-09-15 23:45:47 +02:00
|
|
|
|
2016-09-16 22:50:09 +02:00
|
|
|
def apply(updateData: UInt, resetData: BigInt): UInt = apply(updateData, resetData, enable=Bool(true))
|
2016-10-01 01:19:25 +02:00
|
|
|
def apply(updateData: UInt, resetData: BigInt, name: String): UInt = apply(updateData, resetData, enable=Bool(true), Some(name))
|
2016-09-15 23:45:47 +02:00
|
|
|
|
2016-09-16 22:50:09 +02:00
|
|
|
def apply(updateData: UInt, enable: Bool): UInt = apply(updateData, resetData=BigInt(0), enable)
|
2016-10-01 01:19:25 +02:00
|
|
|
def apply(updateData: UInt, enable: Bool, name: String): UInt = apply(updateData, resetData=BigInt(0), enable, Some(name))
|
2016-09-15 23:45:47 +02:00
|
|
|
|
2016-09-16 22:50:09 +02:00
|
|
|
def apply(updateData: UInt): UInt = apply(updateData, resetData=BigInt(0), enable=Bool(true))
|
2016-10-01 01:19:25 +02:00
|
|
|
def apply(updateData: UInt, name:String): UInt = apply(updateData, resetData=BigInt(0), enable=Bool(true), Some(name))
|
2016-09-15 23:45:47 +02:00
|
|
|
}
|
2017-08-30 20:58:25 +02:00
|
|
|
|