JC-S
JC-S

Reputation: 33

Possible workaround for async negedge reset?

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?

Upvotes: 3

Views: 862

Answers (2)

Guy Hutchison
Guy Hutchison

Reputation: 145

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.

Upvotes: 2

Jack Koenig
Jack Koenig

Reputation: 6064

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

Upvotes: 2

Related Questions