Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Possible workaround for async negedge reset?

Tags:

reset

chisel

I'd like to have a register with async reset signal, like following:

always @(posedge clk or negedge rst_n)
begin
    if(!rst_n)
        out <= 1'b0
    else
        out <= in
end

I have tried class AsyncReset() and withReset(). However, the generated code uses a posedge reset and the variable of AsyncReset() does not accept !.

Is there any workaround for this?

like image 570
JC-S Avatar asked Nov 26 '25 05:11

JC-S


2 Answers

While you cannot invert the AsyncReset type directly (generally applying logic to an AsyncReset is bad because it can glitch), you can cast to a Bool and back:

  val reset_n = (!reset.asBool).asAsyncReset
  val reg = withReset(reset_n)(RegInit(0.U(8.W)))

Runnable example: https://scastie.scala-lang.org/ERy0qHt2Q3OvWIsp9qiiNg

like image 131
Jack Koenig Avatar answered Nov 28 '25 15:11

Jack Koenig


I thought Jack's quick comment about avoiding glitches deserved a longer explanation.

Using an asynchronous reset creates a second timing arc in the design, from the reset to the end flop. The reset signal can be asserted at any time but needs to be de-asserted synchronous to the clock otherwise the flop can become metastable.

A common technique to do this is to use a reset synchronizer.
https://scastie.scala-lang.org/hutch31/EPozcu39QBOmaB5So6fyeA/13

The synchronizer shown in the above code is coded directly in Verilog as I do not know a way to keep the FIRRTL optimizer from pruning through constant optimization. The logic downstream of the reset sync can be either sync or async reset.

like image 20
Guy Hutchison Avatar answered Nov 28 '25 16:11

Guy Hutchison



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!