DigiFlopDebug CDC violations →

One clock's certainty is another clock's coin flip.

VLSI Concept · RTL
Clock Domain Crossing (CDC)
One clock's certainty is another clock's coin flip.

Any signal that crosses from one clock domain into a different, asynchronous clock domain risks arriving too close to the receiving clock edge, violating setup/hold and pushing the sampling flip-flop into metastability — a brief unresolved state that can settle to either 0 or 1, or resolve too slowly, corrupting downstream logic.

Because RTL simulators are zero-delay, this failure mode is invisible to ordinary functional simulation, which is exactly why CDC bugs are one of the most common causes of real first-silicon failures. Industry designs guard against it with a small, well-established toolkit used on nearly every multi-clock chip: a 2-flop (or 3-flop, for extra MTBF margin) synchronizer for single-bit control signals; gray-code encoded pointers for multi-bit counters crossing domains — the backbone of every asynchronous FIFO; and req/ack handshake or MUX-based synchronizers when a full multi-bit data bus has to cross safely without gray coding.

Because these bugs slip past simulation, industry teams run dedicated static/structural CDC signoff tools (e.g. Real Intent Meridian CDC, Cadence Conformal CDC, Synopsys SpyGlass CDC) that classify every crossing and flag specific violation categories — the same categories real design teams triage every tapeout.

Common techniques2-FF / 3-FF synchronizer (single-bit signals) · Gray-code pointers + async FIFO (multi-bit counters/data, e.g. USB, PCIe, AXI clock bridges) · req/ack handshake or MUX synchronizer (multi-bit buses, quasi-static control signals)
Real exampleAn async FIFO between a fast core clock and a slower peripheral clock uses gray-coded read/write pointers so only one bit ever changes at a time — avoiding a multi-bit value being sampled half-updated on the other side.
DATA vs CNTL crossingsStatic CDC tools (e.g. Real Intent Meridian CDC) classify every boundary-crossing signal as CNTL if it correctly feeds a synchronizer, or DATA if it does not — a multi-bit DATA signal reaching a destination flop with no synchronizer, handshake, or gray-coding is treated as a serious structural violation, since a plain 2-FF synchronizer only protects a single bit, not a bus.
W_GLITCH violationFlags combinational logic (a gate, a mux) inserted between the source register and the first synchronizer flop. Combinational glitches are harmless inside one clock domain, but a glitch sampled mid-transition by an asynchronous synchronizer can latch a false value — so nothing but a direct register-to-register wire is allowed into a synchronizer.
W_MASYNC violation"Multiple async signals combining" — two or more independently synchronized signals (each individually safe) feed the same downstream logic cone, but since each resolved on its own unrelated clock edge, their combination can momentarily be an illegal/inconsistent combination even though every input looks valid. This is the classic reconvergence / loss-of-correlation bug, and it is invisible unless the tool tracks relationships across whole groups of signals, not one wire at a time.
W_ASYNC_RST_FLOPS / W_HALFW_ASYNC_RST_FLOPS flags asynchronous resets whose de-assertion (release) isn't itself synchronized — "assert asynchronously, release synchronously" is the standard fix. W_HALF / W_RST_HALF flags a bus or reset group where only some bits or some flops were protected, leaving the rest exposed — a common copy-paste mistake when a design is modified after the CDC scheme was already signed off.
Why it mattersCDC bugs pass functional simulation because it's zero-delay, so a dedicated structural/formal CDC signoff step — not simulation — is what actually catches these violation classes before tapeout, on every multi-clock design.
▶ Try the interactive version