The most dangerous CDC sentence after "same frequency" is "but it passed simulation". Simulation is essential for CDC work and almost useless as CDC proof. This lesson draws the line.
Functional RTL simulation uses ideal clocks with no setup, hold, or delay: a signal change is visible to every sampler at once, and every flop captures a clean 0 or 1. Metastability cannot appear, skew cannot appear, and a pulse placed by the testbench lands exactly where the testbench put it. A crossing that is broken in silicon looks perfect here, because the failure physics is absent from the model.
Adding delays or randomising clock skew samples some relative phases on some runs. That finds easy bugs, which is worth doing, but it proves nothing: a design exercised at a thousand skews can still fail at the thousand-and-first, and a simulator resolves near-coincident edges deterministically while silicon resolves them statistically. Absence of failure in simulation is one data point, not a bound on the failure rate. Gate-level runs have a second gap: they model one timing corner, while the tape-out must survive all of them.
Method | What it establishes | What it does not do |
|---|---|---|
Structural analysis | Every crossing is found and each has an approved scheme with its rules (no logic between synchroniser flops, one-bit-only, stable data, and similar checks) | Prove the protocol correct under all timings |
Formal property checking | The crossing protocol holds for every possible clock alignment and input sequence (no missed or duplicated events, no torn values) | Model the analogue settling of a real flop |
Simulation | The design behaves correctly when crossings resolve cleanly, and the protocol makes progress under traffic | Prove anything about the cases it did not hit |
The three methods cover each other's blind spots: structure guarantees the synchroniser is present and wired legally, formal guarantees the protocol is correct for all timings, and simulation guarantees the surrounding logic actually works. Signoff needs all three; any one alone leaves a hole.
Check the protocol: handshakes complete, FIFOs never overflow or underflow, back-pressure propagates, all under traffic and stalls.
Exercise both directions and extreme ratios: fast-to-slow pulses, slow-to-fast holds, bursts, and resets during transfers.
Run metastability-aware models: a capture flop that resolves randomly to old or new when data changes inside a window (deterministic with a fixed seed or an explicit pattern, as in the RTL synchroniser lessons). A protocol that survives arbitrary resolutions is robust; one that needs lucky resolutions is broken. But the model validates the protocol, not the flop physics: it cannot give a failure rate.
Proof: the run sampled some timings at one corner and found no bug, which exercises the protocol but bounds nothing. Safety needs the structural result (correct Gray pointers, legal synchronisers) and ideally a formal proof of the full/empty logic, plus this simulation as behavioural evidence.
That the handshake protocol tolerates either resolution of each crossing, i.e. the protocol is robust. It did not prove anything about the real flop's likelihood of hitting the window or settling in time; that is the structural and electrical argument.