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?
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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With