04 · Temporal integrity
CDC & RDC Dynamic Verification
Combine structural CDC analysis with dynamic handshake assertions, Gray-pointer checks, reset stress, and randomized clock phase to expose cross-domain protocol failures.
Clock phase variation can expose bad assumptions, while assertions and structural analysis prove Req–Ack stability, bundled data, Gray-pointer transitions, and reset release.
Jitter ≠ analog metastability model · structural CDC + constraints + MTBF remain required
Why it matters
- Modern SoCs run blocks at different frequencies to save power. Clock Domain Crossing and Reset Domain Crossing failures are major silicon-respin risks.
- Ideal zero-delay RTL simulation cannot reproduce analog metastability, so dynamic verification must target the digital protocols that contain and tolerate it.
- A crossing can fail randomly in the lab when an asynchronous signal is sampled during a transition or when one domain exits reset while another still holds stale state.
What is difficult
- A standard UVM monitor samples on a clock edge, while a real asynchronous signal might arrive 5 ps before that edge and violate setup or hold.
- Full analog metastability behavior is not practical to simulate at SoC scale.
- Control CDC uses synchronizers or a request-acknowledge handshake, while datapath CDC often needs a stable-data protocol, FIFO, or DMUX.
- Asynchronous FIFO pointers must cross in Gray code, with only one bit changing per pointer step.
- Reset-glitch protection must reject pulses shorter than a clock cycle without masking a valid reset.
Failure signatures
- Request changes again before acknowledgement and the destination loses or duplicates an event.
- The data bus changes while a CDC handshake is active.
- A binary pointer, rather than its Gray-coded form, is connected to an asynchronous FIFO synchronizer.
- A short reset glitch escapes the reset synchronizer and partially resets the destination domain.
- A waking block samples stale data from a domain that remains in reset.
- RTL assumes a fixed phase relationship between nominally asynchronous clocks.
- A short control pulse is never observed in the destination domain.
Two viable approaches—and their cost
SVA protocol checkers
Assert Req-Ack-Stable and Gray-pointer invariants at the digital protocol boundary.
- Proves that control and bundled data remain stable for the required handshake.
- Provides a precise failure cycle and signal-level contract.
- Does not prove the physical synchronizer implementation.
- Cannot reproduce analog metastability resolution.
Clock jitter and skew injection
Vary the phase relationship between asynchronous clocks and sample crossings at difficult alignments.
- Exposes RTL that accidentally depends on a fixed phase relationship.
- Stresses reset release and handshake latency across many alignments.
- Requires a flexible clock-control agent and reproducible phase logging.
- Still models digital timing, not transistor-level metastability.
Interview answer, built from the mechanism
- I use a hybrid assertion-and-stress strategy. Structural CDC and RDC are handled by lint or formal tools, while UVM verifies dynamic handshake integrity.
- Assertions require Request to remain stable until Ack, bundled Data to remain stable throughout the active handshake, and asynchronous FIFO Gray pointers to change by one bit per step.
- A clock-control agent varies source and destination phase and adds jitter so simulation visits difficult sampling alignments. Reset tests independently release domains and inject narrow reset glitches.
- For datapath CDC, I verify the selected architecture: stable bundled data before Valid crosses, or FIFO/DMUX behavior with correct pointer and reset-epoch handling.
Component responsibility contract
| Component | Responsibility | Required change |
|---|---|---|
| SVA checker | Handshake and pointer integrity | Check Req-Ack-Stable, bundled-data stability, and one-bit Gray-pointer transitions. |
| CDC interface | Domain-specific sampling | Define source and destination clocking blocks with explicit input and output skews. |
| Clock controller | Phase stress | Vary the asynchronous clock phase and add reproducible jitter. |
| Reset agent | Reset-glitch stress | Inject pulses shorter than one clock and coordinate independent domain release. |
Implementation patterns
// Gray Code pointers only change by 1 bit at a time
property p_gray_code_continuity(ptr);
@(posedge clk)
$changed(ptr) |->
($countones(ptr ^ $past(ptr)) == 1);
endproperty
assert_wr_ptr_gray: assert property (
p_gray_code_continuity(vif.wr_ptr_gray)
);
assert_rd_ptr_gray: assert property (
p_gray_code_continuity(vif.rd_ptr_gray)
);The XOR identifies changed pointer bits and $countones requires exactly one when the pointer changes. The property is applied to both write and read Gray pointers.
property p_data_stability_during_cdc;
@(posedge clk_src)
disable iff (!vif.rst_n)
$rose(vif.req) |->
$stable(vif.data_bus) until_with (vif.ack);
endproperty
assert_cdc_data_stable: assert property (
p_data_stability_during_cdc
)
else
`uvm_error(
"CDC_DATA",
"Data bus toggled during active handshake!"
);After Request rises, the bundled data must remain stable through the cycle in which Ack completes the transfer.
interface cdc_if(input clk_src, input clk_dest);
logic req;
logic ack;
logic [31:0] data;
// Source Clocking Block: Driving logic
clocking src_cb @(posedge clk_src);
default input #1step output #100ps;
output req, data;
input ack;
endclocking
// Destination Clocking Block: Sampling logic
clocking dest_cb @(posedge clk_dest);
default input #200ps output #1step;
input req, data;
output ack;
endclocking
endinterfaceThe source drives req/data and samples ack; the destination samples req/data and drives ack. The slide labels 100 ps source output skew and 200 ps destination input skew.
initial begin
clk_dest = 0;
forever begin
// 1000ps base period (1GHz)
// Add +/- 50ps of jitter every loop iteration
int jitter = $urandom_range(0, 100) - 50;
#((1000 + jitter) / 2.0 * 1ps);
clk_dest = ~clk_dest;
end
endEvery half-cycle uses a 1,000 ps nominal full-period value plus a random integer from -50 ps through +50 ps before division by two.
Stress recipe
- Run structural CDC/RDC analysis first and retain its crossing inventory for dynamic test selection.
- Randomize the source-destination phase across many alignments around the nominal 1 GHz, 1,000 ps destination period.
- Add the source example's integer jitter range of -50 ps through +50 ps and log the seed and phase.
- Drive Request and hold Data stable until Ack; inject a data toggle during the handshake as a negative test.
- Advance asynchronous FIFO read and write pointers and require one-bit Gray transitions.
- Sweep reset pulses around the specified minimum input width. Verify the documented assertion behavior, synchronized deassertion in each domain, and narrow-pulse rejection only when an explicit glitch filter is part of the contract.
- Release source and destination resets independently and check that no stale data or previous-reset pointer escapes.
- Exercise both a control handshake and a datapath FIFO or DMUX crossing.
Follow-up questions
Why do we use Gray code for asynchronous FIFOs?
Gray code changes one bit per adjacent value. That limits ambiguity when a pointer crosses domains. The source describes the sampled pointer as at most one step away, which helps prevent false FIFO full or empty decisions.
How do you verify reset-glitch protection?
Start from the reset contract. Sweep pulses around the specified minimum assertion width, verify asynchronous assertion when that is the architecture, and prove deassertion is synchronized independently in every destination domain. Only expect narrow-pulse rejection when the design contains an explicit, specified glitch filter or primitive with that guarantee.
What is datapath CDC, and how is it different from control CDC?
Control CDC commonly uses a synchronizer or handshake. Datapath CDC often uses a FIFO, a DMUX, or bundled-data protocol. Verify that Data is stable before Valid or Request crosses and remains stable for the receiving contract.
