Mechanism and evidence
Hold the payload while the request crosses.
Change clock alignment, then trace one bundled-data transaction from its source to acknowledgement.
Checkpoint 1 · Establish the payload.
- SOURCE REQ
- 0
- DEST. ACK
- 0
- PAYLOAD
- 0x2A
- CAPTURE
- —
Compare all 4 checkpoints
1 · Establish the payload.
- SOURCE REQ
- 0
- DEST. ACK
- 0
- PAYLOAD
- 0x2A
- CAPTURE
- —
2 · Raise REQ and keep data stable.
- SOURCE REQ
- 1
- DEST. ACK
- 0
- PAYLOAD
- 0x2A
- CAPTURE
- pending
3 · Destination capture follows the selected phase.
- SOURCE REQ
- 1
- DEST. ACK
- 0
- PAYLOAD
- 0x2A
- CAPTURE
- edge 2
4 · ACK returns ownership to the source.
- SOURCE REQ
- 0
- DEST. ACK
- 1
- PAYLOAD
- released
- CAPTURE
- complete
Establish the payload.
- Payload
- 0x2A
- Request
- 0
The source writes payload 0x2A while request is low. The destination has no new transaction yet.
Observe stable data before the request transition.
Inspect the checker Selected checkpoint pseudocode
payload = 0x2A;
req = 0;Example contract & limitations
Example contract. The source establishes data before REQ and holds it through observed ACK. Capture latency varies with the selected fixed alignment. Digital protocol checks do not simulate analog metastability or prove CDC/RDC structural sign-off. Checkpoints show selected state changes, not equally spaced simulation cycles.
Read the complete walkthrough
Early destination edge
- Establish the payload.. The source writes payload 0x2A while request is low. The destination has no new transaction yet. Evidence: Observe stable data before the request transition.
- Raise REQ and keep data stable.. The request begins crossing to the destination. The source must not reuse the payload register. Evidence: Check source-side stability while the exchange is outstanding.
- Destination capture follows the selected phase.. The fixed clock profile captures 0x2A on destination edge 2. A different delay must not change the payload. Evidence: Compare payload provenance and the selected destination capture point.
- ACK returns ownership to the source.. Only after the source observes acknowledgement can it lower REQ and prepare a new payload. Evidence: Verify one destination consumption for this request.
Late destination edge
- Establish the payload.. The source writes payload 0x2A while request is low. The destination has no new transaction yet. Evidence: Observe stable data before the request transition.
- Raise REQ and keep data stable.. The request begins crossing to the destination. The source must not reuse the payload register. Evidence: Check source-side stability while the exchange is outstanding.
- Destination capture follows the selected phase.. The fixed clock profile captures 0x2A on destination edge 3. A different delay must not change the payload. Evidence: Compare payload provenance and the selected destination capture point.
- ACK returns ownership to the source.. Only after the source observes acknowledgement can it lower REQ and prepare a new payload. Evidence: Verify one destination consumption for this request.
Slower destination clock
- Establish the payload.. The source writes payload 0x2A while request is low. The destination has no new transaction yet. Evidence: Observe stable data before the request transition.
- Raise REQ and keep data stable.. The request begins crossing to the destination. The source must not reuse the payload register. Evidence: Check source-side stability while the exchange is outstanding.
- Destination capture follows the selected phase.. The fixed clock profile captures 0x2A on destination edge 5. A different delay must not change the payload. Evidence: Compare payload provenance and the selected destination capture point.
- ACK returns ownership to the source.. Only after the source observes acknowledgement can it lower REQ and prepare a new payload. Evidence: Verify one destination consumption for this request.
Change data before ACK
- Establish the payload.. The source writes payload 0x2A while request is low. The destination has no new transaction yet. Evidence: Observe stable data before the request transition.
- Raise REQ and keep data stable.. The request begins crossing to the destination. The source must not reuse the payload register. Evidence: Check source-side stability while the exchange is outstanding.
- An early data change breaks the contract.. The source overwrites 0x2A with 0x35 before acknowledgement. Which value is captured can now depend on clock alignment. Evidence: Compare payload provenance and the selected destination capture point.
- ACK returns ownership to the source.. Only after the source observes acknowledgement can it lower REQ and prepare a new payload. Evidence: Verify one destination consumption for this request.
Related implementation: Bundled-data stability assertion
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.
Understand the failure+
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
Dynamic CDC verification boundary
Structural tools identify the crossing; dynamic assertions and phase stress verify the protocol that transports control, data, pointers, and reset state.
- Source domain
- Launches Req, bundled Data, or a Gray-coded FIFO pointer on clk_src.
- Synchronizer / FIFO / DMUX
- Implements the selected control or datapath crossing architecture.
- Destination domain
- Samples on clk_dest, returns Ack, and may leave reset independently.
- SVA layer
- Checks Req-Ack-Stable, data stability, and Gray-pointer continuity.
- Clock and reset agents
- Vary phase, add ±50 ps jitter, and inject narrow reset pulses.
- Req + stable Data -> crossing architecture
- Destination capture -> Ack
- Binary pointer -> Gray encode -> synchronizer -> destination pointer logic
- Clock phase and jitter -> sampling alignment
- Independent reset release -> RDC stale-state check
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.
Compare approaches+
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.
Explain it in an interview+
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.
Assign responsibilities+
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. |
Build the checker+
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 the design+
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.

