Skip to guide

Temporal integrity

CDC & RDC Dynamic Verification

04 of 4 · State, Power & Clock Integrity

Combine structural CDC analysis with dynamic handshake assertions, Gray-pointer checks, reset stress, and randomized clock phase to expose cross-domain protocol failures.

Trace the mechanism from failure signature through independent evidence, component ownership, stress, and recovery.

Native mechanism diagram2 implementation tradeoffs3 interview follow-ups
The ground movesOne reusable contract across 1 cases.
  1. 01RUNObserve valid architectural state
  2. 02DISRUPTReset, gate a clock, or remove power
  3. 03CONTAINKill, clamp, flush, preserve, or pause
  4. 04RECOVERRelease only after initialization is valid

CDC DV

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.

Mechanism · failure · evidence · recovery
Two clocks, one protocolStress phase; prove the digital containment contract.

Clock phase variation can expose bad assumptions, while assertions and structural analysis prove Req–Ack stability, bundled data, Gray-pointer transitions, and reset release.

CLK_AREQCLK_BACK
Source domainREQ + stable DATADestination FF1may resolveDestination FF2synchronized levelProtocolACK releases DATA

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.

Strengths
  • Proves that control and bundled data remain stable for the required handshake.
  • Provides a precise failure cycle and signal-level contract.
Costs
  • 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.

Strengths
  • Exposes RTL that accidentally depends on a fixed phase relationship.
  • Stresses reset release and handshake latency across many alignments.
Costs
  • Requires a flexible clock-control agent and reproducible phase logging.
  • Still models digital timing, not transistor-level metastability.

Interview answer, built from the mechanism

  1. 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.
  2. 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.
  3. 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.
  4. 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 responsibilities and required verification changes for CDC & RDC Dynamic Verification
ComponentResponsibilityRequired change
SVA checkerHandshake and pointer integrityCheck Req-Ack-Stable, bundled-data stability, and one-bit Gray-pointer transitions.
CDC interfaceDomain-specific samplingDefine source and destination clocking blocks with explicit input and output skews.
Clock controllerPhase stressVary the asynchronous clock phase and add reproducible jitter.
Reset agentReset-glitch stressInject pulses shorter than one clock and coordinate independent domain release.

Implementation patterns

Gray-pointer one-bit transition assertionsystemverilog
// 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.

Bundled-data stability assertionsystemverilog
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.

Source and destination clocking blockssystemverilog
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
endinterface

The 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.

1 GHz destination clock with ±50 ps jittersystemverilog
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
end

Every 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

  1. Run structural CDC/RDC analysis first and retain its crossing inventory for dynamic test selection.
  2. Randomize the source-destination phase across many alignments around the nominal 1 GHz, 1,000 ps destination period.
  3. Add the source example's integer jitter range of -50 ps through +50 ps and log the seed and phase.
  4. Drive Request and hold Data stable until Ack; inject a data toggle during the handshake as a negative test.
  5. Advance asynchronous FIFO read and write pointers and require one-bit Gray transitions.
  6. 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.
  7. Release source and destination resets independently and check that no stale data or previous-reset pointer escapes.
  8. 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.