An asynchronous reset forces the flop to its reset value at once, without waiting for the clock. It appears in the sensitivity list beside the clock edge.
module dff_arst (
input logic clk, rst_n, d,
output logic q
);
always_ff @(posedge clk or negedge rst_n)
if (!rst_n) q <= 1'b0; // reset wins: no clock needed
else q <= d;
endmoduleThe waveform simulates both styles in one testbench. The reset drops just after a falling clock edge, so the asynchronous flop clears at once while the synchronous one waits.
Early slots: both flops capture d of 1, so both q outputs read 1.
Reset assertion: rst_n falls between edges, and the asynchronous q clears at once.
Same slot: the synchronous q still reads 1 until the next rising edge.
Later slots: after release, both flops capture d of 1 again.
Assertion at any time is safe, but release near an edge is dangerous. Some flops can then leave reset on different edges, so the design wakes inconsistently.
The release edge has recovery and removal times, like setup and hold. The standard recipe is asynchronous assertion with synchronous release.
A two-flop synchronizer handles the release edge. The incoming arst_n holds both flops in reset.
After release, a 1 shifts through two flops in simulation. The output rst_n nominally deasserts on a clock edge two edges later. The second flop lowers the chance that metastability reaches the output but cannot remove it. Real designs must still meet recovery and removal times, check MTBF, and balance the reset tree. See the reset strategies and synchronizer lessons for those details.
Asynchronous reset | Notes | |
|---|---|---|
Assert | Immediate | Useful when the clock may be stopped or not yet running |
Release | Must be synchronized | Use the two-flop reset synchronizer per clock domain |
Hardware | Flops with an async-reset pin | Slightly larger cell, no extra logic on D |
Glitches on reset | Dangerous: a glitch resets the design | Drive the source from a flop, not from combinational logic, then feed each clock domain through its own reset synchronizer |
Reset needs a clean driver and a synchronized release.
arst_n away from a clock edge, and why does rst_n still stay low for two edges afterwards?Releasing near an edge would test the recovery/removal window, which RTL simulation does not model. After release, the first flop captures a 1 on the next edge and the second one on the edge after, so in simulation the downstream reset nominally deasserts two edges later, on a clock edge. That latency is nominal only; it shows reduced risk in RTL, not a physical guarantee.
The reset synchronizer with a testbench that checks instant assertion and release two edges later.
module reset_sync (
input logic clk, arst_n,
output logic rst_n
);
logic meta;
always_ff @(posedge clk or negedge arst_n)
if (!arst_n) begin meta <= 1'b0; rst_n <= 1'b0; end // assert asynchronously
else begin meta <= 1'b1; rst_n <= meta; end // release on a clock edge, two flops deep
endmodule