Your CDC static-check report is clean. Your chip still fails on the bench.

Your CDC static-check report is clean. Your chip still fails on the bench.
Every ASIC and FPGA team has had this conversation. The static Clock Domain Crossing report is green. Every crossing has a synchronizer. The design has been reviewed. It went through synthesis without warnings. The bench turns on, silicon starts running — and two days later somebody hits an intermittent bug that only reproduces once every million cycles.
The report was not lying. The report was answering the wrong question.
Static CDC analysis proves structure. It says: for each pair of asynchronous flip-flops, is there a synchronization pattern present? It does not, and cannot, say: does that synchronization pattern preserve the protocol your design depends on? That second question is behavioural, and behaviour needs dynamic verification.

This post explains the specific gap between the two, catalogues the techniques that close it, and shares two real bugs my own CDC verification lab caught during preparation of the reference material we ship with engagements.
What static CDC does well
Static CDC analysis is the first modality anyone should run. It scales — a full-chip design with 50 million gates is analysed in minutes. It is exhaustive over the structure it reasons about: no crossing is missed, no synchronizer is overlooked, no reconvergence is left un-flagged.
The rules that a mature static tool (SpyGlass CDC, Questa CDC, JasperGold, VC CDC) checks include:
- Every asynchronous crossing has a recognized synchronization pattern.
- Multi-bit crossings use gray coding, an asynchronous FIFO, or a handshake — not per-bit 2-FF.
- No combinational logic sits between domains.
- Independently synchronized signals from the same source do not reconverge downstream.
- Reset domain crossings are protected with a reset synchronizer.
- Clock-gating cells do not straddle domain boundaries.
Run static as a continuous-integration gate. Fail the build on any unwaived violation. This is table stakes.
Where static analysis stops
The tools that check structure cannot check behaviour, because behaviour requires stimulus and time.
A four-phase handshake with the correct structural shape but the wrong state-machine timing will pass static and fail in silicon. Static sees req, ack, a data bus, and a pair of 2-FF synchronizers. That is a legal structure. It cannot see that the destination samples the data one cycle too early, before the handshake protocol has held the data stable.
An asynchronous FIFO with correct gray-coded pointers and a broken full / empty calculation will pass static and lose data. Static sees the pointer synchronizers. It does not simulate the arithmetic.
A metastable synchronizer output — resolved to a value, but not the value the source intended — will pass static and produce an intermittent functional bug. Static reasons about presence, not about the statistical distribution of resolution times.

Each of these is a real failure class. Each ships regularly on production silicon. Each is what dynamic CDC verification is designed to catch.
The dynamic CDC toolbox
The dynamic verification techniques catalogued in the literature are, in practical terms, five orthogonal ways to stress a synchronizer:
X-propagation testing injects the SystemVerilog X value on the synchronizer's first stage during simulation, then propagates it forward. Downstream logic that assumes a settled value will produce X at its output. The technique catches combinational reconvergence after a synchronizer, missing isolation across power boundaries, and forgotten reset conditions that let X persist into operating cycles.
Bounded metastability modelling (BMM) models the synchronizer's first-stage output as delayed by a random additional time drawn from a truncated exponential distribution. Each simulation run samples a fresh value; over many runs the full distribution is exercised. The technique catches downstream logic that depends on when the synchronizer resolves, not just whether. This is the gold standard for dynamic CDC — the closest simulation gets to silicon behaviour.

Clock jitter and phase randomization add random offset to clock edges, exposing designs that assumed a stable phase relationship. Useful specifically for mesochronous CDC and multi-PLL designs where the "unrelated" clock relationship drifts continuously.
SystemVerilog assertions (SVA) encode protocol invariants as properties the simulator monitors every cycle. For CDC the most useful properties are no-X-on-output, bounded latency, single-cycle pulse width, and stability when a qualifying valid is low. An assertion failure pinpoints the exact cycle and signal — an order of magnitude faster to debug than a scoreboard mismatch discovered many cycles later.
X-aware scoreboarding is the discipline of separating X-corrupted samples from real functional mismatches. Without X-awareness, a scoreboard drowns in false failures the moment X-propagation testing is enabled. With it, X-corruption is a counted event and functional correctness is a separate verdict.
None of these is difficult individually. What matters is the composition — every serious dynamic CDC test enables several at once, stacked on the same testbench and the same DUT.
The two bugs my own lab caught
Here is the part that made writing the reference material worth it.
My team built a companion UVM verification lab as we wrote the CDC technical reference — a deliberately buggy two-clock adder wrapped in a full testbench with all five techniques wired up. The intent was simple: prove every claim in the paper against runnable code before shipping.
Two real bugs came out. Not bugs in the DUT — bugs in the verification code itself. Both would have shipped silently. Both were caught by exactly the dynamic techniques the paper advocates.
Bug 1: The driver that produced no stimulus.
The UVM driver had five configurable stress modes: random delay, X-injection, data jitter, bounded metastability modelling, and SVA enablement. The base test — the smoke test that should exercise the DUT with plain, unmodified transactions — had all five stress modes off by default.
The driver, as written, only drove the interface when at least one stress mode was on. When all five were off, the driver dropped the transaction without ever asserting i_valid. The base test produced zero transactions, and the scoreboard reported zero matches and zero mismatches — a "PASS" that was actually silence.
The bug was not visible from the code review; the driver looked fine on inspection. It was visible only when the sim ran and produced obviously-wrong scoreboard output. A dynamic run with an actual expected-vs-actual comparison caught it in the first attempt.
Bug 2: The assertion property that could never fire.
The lab's testbench had four SVA properties: no-X-on-output, bounded valid latency, single-cycle pulse, and data stability. The valid-latency property was written to sample on slow_clk with a ##[2:3] cycle window.
The DUT clock ratio was 1 : 4. The destination o_valid was a single fast-clock-wide pulse — five nanoseconds long. The slow-clock sample times were twenty nanoseconds apart. The property could not, in principle, observe the pulse it was meant to check. It was a property that would produce false passes for every conforming run and, worse, false failures for corner cases where the slow-clock edge happened to catch the tail of a pulse.
The bug did not exist in a design decision that got documented. It existed in the gap between two engineers' assumptions: one who wrote the DUT with fast-clock outputs, one who wrote the property with slow-clock sampling. Static analysis has no view into that gap. The dynamic simulation run with the assertion enabled caught the property firing incorrectly, and the fix was to resample on fast_clk with a wider window.
Every reader who has done real DV work has some version of these two bugs in their history. What made me want to write about them is that they are exactly the kind of failure the paper's techniques were designed to catch — and they demonstrated the point in the very act of building the material to demonstrate the point.
The composition matters
Static CDC is necessary. Dynamic CDC is necessary. Formal CDC is necessary for the crossings whose protocols matter enough to prove exhaustively. None is sufficient alone.
The pattern that has worked reliably on the engagements I have shipped:
- Static as a CI gate. Every push runs static CDC. Any new violation blocks the merge. Waivers require peer review with a written justification, not a one-line dismissal.
- Dynamic in regression. BMM, X-propagation, and jitter run nightly with a large seed count. SVA properties run inside every regression alongside the scoreboard. Coverage-driven random stimulus stresses each synchronizer chain across both toggle directions.
- Formal on protocol crossings. Handshakes, FIFO pointer arithmetic, and reset domain properties get formal proofs. Data paths that are too large for formal fall back to dynamic.
- Waiver review before sign-off. Every waiver from every tool is audited before tape-out. This is the highest-leverage step in the whole process, and the most commonly skipped.
The composition is what separates a chip that ships and works from a chip that ships and produces a support ticket six months in.
What LogicTiles brings
The material I described above — the lab, the reference document, the sign-off methodology — is the artifact we ship with our CDC engagements. It stays with the engagement partners rather than sitting on a public download page, because the parts of it that make it valuable are the same parts that took real engineering effort to produce.
The ideas travel through this blog. Follow along for the rest of the series — deep dives on multi-bit CDC, reset domain crossing, bounded metastability modelling, Vivado constraint patterns, the open-source ASIC flow, and the sign-off checklist that ties them all together.
If your team is closing a chip, tape-out has slipped once because of CDC-adjacent bugs, or your verification schedule needs a senior engineer to close a specific deliverable — reach out at hr@logictiles.com. We work with hardware startups, product companies, and IP vendors as an embedded senior partner, and we leave the reference material behind.
Share it with someone who runs a CDC sign-off. Or read the source.