Recovery and Removal Checks
Recovery and removal checks explained: setup and hold for asynchronous reset release, why reset deassertion is timed while assertion is not, the keep-out window around the clock edge, a worked example, and why reset is synchronized.
Setup and hold guard the data pin of a flip-flop. Recovery and removal are the exact same idea applied to an asynchronous reset (or set) as it is released. They are the two checks that make sure a flop comes out of reset cleanly, on a known cycle, instead of going metastable at the moment control passes back to the clock.
Reset assertion is free, reset release is timed
Asserting an asynchronous reset is untimed on purpose: the moment reset goes active, the output is forced to its reset value regardless of the clock. That is the whole point of an async reset, it works even when no clock is running. Releasing the reset is different. When reset goes inactive, control of the output hands back to the clock, and the output only updates on the next active edge. If that release lands too close to the active clock edge, some paths inside the flop see the old reset and some see the new one, and the flop can settle to an unknown value. Recovery and removal are the guard band around the edge that prevents this.
Recovery time
Recovery time is the minimum time the reset must already be released and stable before the active clock edge. It is the setup check for reset release: the reset has to let go early enough that the flop is fully back under clock control by the time the edge arrives. Recovery slack = (time of the active edge - recovery time) - (arrival time of the reset release). Positive slack passes; negative means the reset let go too late.
Removal time
Removal time is the minimum time the reset must stay released and stable after the active clock edge. It is the hold check for reset release: the reset must not start changing again until the edge has safely captured. Removal slack = (arrival time of the reset release) - (time of the active edge + removal time). Together, recovery and removal define a keep-out window around the edge inside which the reset release transition must not happen, exactly like the setup-and-hold window for data.
Worked example
Say the recovery requirement is 0.20 ns and the removal requirement is 0.10 ns. If the reset release reaches the flop's reset pin 0.30 ns before the active edge, recovery slack = 0.30 - 0.20 = +0.10 ns, so recovery passes. If a slow reset tree delayed that release to only 0.15 ns before the edge, recovery slack = 0.15 - 0.20 = -0.05 ns, a recovery violation. On the removal side, if the reset stays released 0.25 ns after the edge against a 0.10 ns requirement, removal slack = 0.25 - 0.10 = +0.15 ns, which passes.
Why designs synchronize reset deassertion
An async reset usually comes from a far-off, unclocked source (a power-on circuit, a pin, another domain), so its release edge has no fixed relationship to the local clock and could land anywhere, including inside the keep-out window. The standard fix is a reset synchronizer: assert asynchronously so reset still works with no clock, but release synchronously, timed to the local clock, so the release edge always lands cleanly between clock edges. That is the reset-synchronization technique, and it is what makes recovery and removal met by construction across a domain.
| Check | Guards | Analogous to | Uses |
|---|---|---|---|
| Recovery | Reset released early enough before the edge | Setup | Late (max) reset path |
| Removal | Reset stays released long enough after the edge | Hold | Early (min) reset path |
Reporting: once the asynchronous pin and the clock are defined, the tool checks recovery and removal automatically, and you can target them with report_timing -check_type recovery and -check_type removal. Fix a recovery violation like a setup problem (speed up or rebalance the reset path) and a removal violation like a hold problem, or, better, make sure the reset is properly synchronized so the release edge is always aligned.