“How do you approach CDC in RTL review?” The interviewer is asking for a method, not a definition.
A strong answer walks a crossing list: every signal between clocks, its class, its structure, and its constraint. The short answer names the classes: single-bit control, multi-bit values, and data streams.
Classification comes first. The structure follows from the traffic shape.
Crossing | Structure | Constraint to close |
|---|---|---|
Slow single bit (status, enable) | Two-flop synchroniser on the destination clock (baseline). | Scoped exception to the first stage only; keep interstage timing and short routing for settling and MTBF. |
One-cycle pulse | From a fast or comparable clock: toggle synchroniser or handshake. A source pulse guaranteed to span at least three destination edges in every clock mode can use a 2FF plus edge detect (pulse lesson). | As for a single bit, plus a minimum spacing between events. |
Counter or pointer stepping by 1 | Gray code plus one 2FF per bit (bus lesson). | Bus skew and arrival bound below the fastest allowed source step. |
Single word (config, command) | Four-phase handshake or held word with load pulse (handshake). | Data settled before the earliest permitted capture and held through acknowledgement. |
Continuous stream | Async FIFO with Gray pointers (async FIFO). | Gray pointer skew bound; each word written before the pointer that publishes it can be seen. |
Read each row left to right: the traffic shape picks the structure, and the structure brings its own physical obligation.
Asynchronous clock groups remove checks rather than bounding delay. Audit active exception precedence: a broad group or false-path exception may override the required max-delay checks in the right-hand column. Review structural CDC, implemented physical bounds and characterized MTBF separately; see crossing-specific constraints.
Two is a common starting structure, not a frequency-based guarantee. Select depth from characterized device/PVT parameters, actual interstage settling time, asynchronous input activity, and the required system MTBF. Account for all crossings in the reliability budget. More stages add settling time and latency; inspect the implementation's MTBF report (see when to use three flops).
No. Different cells, PVT, input toggle rates and interstage routing can produce different MTBF. Stage count and clock frequency alone are insufficient evidence.
Logic of any kind. No branch may use the first flop output either. Only the second flop feeds destination logic.
No. The source must hold each value for more than one destination period, preferably two. Faster sources need a pulse synchroniser, a handshake, or a FIFO.
“A FIFO fixes every crossing.” A FIFO for a single event wastes area and adds latency. A pulse synchroniser or a handshake fits.
“A false path constraint makes the crossing safe.” It only silences timing. The synchroniser structure is what makes it safe.
A finite digital check of 20 slow toggles across two clocks. It checks delivery under the shown hold and reset assumptions.
// Two-flop synchroniser for one slow single-bit signal.
module sync2 (
input logic clk_d,
input logic rst_d_n,
input logic d,
output logic q
);
logic q1;
always_ff @(posedge clk_d or negedge rst_d_n)
if (!rst_d_n) begin q1 <= 1'b0; q <= 1'b0; end
else begin q1 <= d; q <= q1; end
endmodule
Testbench Run with Icarus Verilog 13.0 (2026-10-16): prints PASS. It checks delivery across 20 slow toggles under the shown hold and reset assumptions. It does not model metastability and is not physical CDC signoff.