1
0

Simplify AsyncResetReg

No need for AsyncSetReg, as AsyncResetReg can be used exclusively with
inverted inputs.
This commit is contained in:
Andrew Waterman 2016-10-08 20:36:43 -07:00 committed by Yunsup Lee
parent a84a961a39
commit 7f429e8799
3 changed files with 11 additions and 77 deletions

View File

@ -30,8 +30,7 @@ import cde.{Parameters}
* *
*/ */
abstract class AbstractBBReg extends BlackBox { class AsyncResetReg extends BlackBox {
val io = new Bundle { val io = new Bundle {
val d = Bool(INPUT) val d = Bool(INPUT)
val q = Bool(OUTPUT) val q = Bool(OUTPUT)
@ -40,58 +39,43 @@ abstract class AbstractBBReg extends BlackBox {
val clk = Clock(INPUT) val clk = Clock(INPUT)
val rst = Bool(INPUT) val rst = Bool(INPUT)
} }
} }
class AsyncResetReg extends AbstractBBReg
class AsyncSetReg extends AbstractBBReg
class SimpleRegIO(val w: Int) extends Bundle{ class SimpleRegIO(val w: Int) extends Bundle{
val d = UInt(INPUT, width = w) val d = UInt(INPUT, width = w)
val q = UInt(OUTPUT, width = w) val q = UInt(OUTPUT, width = w)
val en = Bool(INPUT) val en = Bool(INPUT)
} }
class AsyncResetRegVec(val w: Int, val init: BigInt) extends Module { class AsyncResetRegVec(val w: Int, val init: BigInt) extends Module {
val io = new SimpleRegIO(w) val io = new SimpleRegIO(w)
val async_regs: List[AbstractBBReg] = List.tabulate(w)( val async_regs = List.fill(w)(Module(new AsyncResetReg))
i => Module (
if (((init >> i) % 2) > 0)
new AsyncSetReg
else
new AsyncResetReg)
)
io.q := async_regs.map(_.io.q).asUInt val q = for ((reg, idx) <- async_regs.zipWithIndex) yield {
def maybeInvert(x: Bool) = if (((init >> idx) & 1) == 1) !x else x
for ((reg, idx) <- async_regs.zipWithIndex) {
reg.io.clk := clock reg.io.clk := clock
reg.io.rst := reset reg.io.rst := reset
reg.io.d := io.d(idx) reg.io.d := maybeInvert(io.d(idx))
reg.io.en := io.en reg.io.en := io.en
reg.suggestName(s"reg_$idx") reg.suggestName(s"reg_$idx")
maybeInvert(reg.io.q)
} }
io.q := q.asUInt
} }
object AsyncResetReg { object AsyncResetReg {
// Create Single Registers // Create Single Registers
def apply(d: Bool, clk: Clock, rst: Bool, init: Boolean, name: Option[String]): Bool = { def apply(d: Bool, clk: Clock, rst: Bool, init: Boolean, name: Option[String]): Bool = {
val reg: AbstractBBReg = def maybeInvert(x: Bool) = if (init) !x else x
if (init) Module (new AsyncSetReg) val reg = Module(new AsyncResetReg)
else Module(new AsyncResetReg) reg.io.d := maybeInvert(d)
reg.io.d := d
reg.io.clk := clk reg.io.clk := clk
reg.io.rst := rst reg.io.rst := rst
reg.io.en := Bool(true) reg.io.en := Bool(true)
name.foreach(reg.suggestName(_)) name.foreach(reg.suggestName(_))
reg.io.q maybeInvert(reg.io.q)
} }
def apply(d: Bool, clk: Clock, rst: Bool): Bool = apply(d, clk, rst, false, None) def apply(d: Bool, clk: Clock, rst: Bool): Bool = apply(d, clk, rst, false, None)
@ -118,5 +102,4 @@ object AsyncResetReg {
def apply(updateData: UInt): UInt = apply(updateData, resetData=BigInt(0), enable=Bool(true)) def apply(updateData: UInt): UInt = apply(updateData, resetData=BigInt(0), enable=Bool(true))
def apply(updateData: UInt, name:String): UInt = apply(updateData, resetData=BigInt(0), enable=Bool(true), Some(name)) def apply(updateData: UInt, name:String): UInt = apply(updateData, resetData=BigInt(0), enable=Bool(true), Some(name))
} }

View File

@ -7,8 +7,6 @@
bb_vsrcs = $(base_dir)/vsrc/DebugTransportModuleJtag.v \ bb_vsrcs = $(base_dir)/vsrc/DebugTransportModuleJtag.v \
$(base_dir)/vsrc/jtag_vpi.v \ $(base_dir)/vsrc/jtag_vpi.v \
$(base_dir)/vsrc/AsyncResetReg.v \ $(base_dir)/vsrc/AsyncResetReg.v \
$(base_dir)/vsrc/AsyncSetReg.v \
sim_vsrcs = \ sim_vsrcs = \
$(generated_dir)/$(long_name).v \ $(generated_dir)/$(long_name).v \

View File

@ -1,47 +0,0 @@
/** This black-boxes an Async Set
* Reg.
*
* Because Chisel doesn't support
* parameterized black boxes,
* we unfortunately have to
* instantiate a number of these.
*
* We also have to hard-code the set/reset.
*
* 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
* @param en Write Enable Input
*
*/
module AsyncSetReg (
input d,
output reg q,
input en,
input clk,
input rst);
always @(posedge clk or posedge rst) begin
if (rst) begin
q <= 1'b1;
end else if (en) begin
q <= d;
end
end
endmodule // AsyncSetReg