SoCs are becoming more complex these days. A lot of functionality is being added to chips and data is frequently transferred from one clock domain to another. Hence, clock domain crossing verification has become one of the major verification challenges in deep submicron designs.
CDC (Clock Domain Crossing) is the process of safely transferring data or signals between two clock domains that do not have a fixed phase or frequency relationship.
In Figure 1, signal A is launched in clock domain C1 and must be safely captured in clock domain C2. The transfer can cause issues depending on the clock relationship, requiring different solutions for reliable capture.
Simulation and STA alone cannot guarantee reliable data transfer across clock domains, so specialized CDC verification methods are needed. In the discussion that follows, C1/C2 denote source and destination clocks, while A/B denote the corresponding flop outputs (assumed positive-edge triggered).
When signal A transitions too close to the active edge of clock C2, the destination flop FB can violate setup/hold timing and enter a metastable state, where its output B becomes unstable, oscillating or taking an indefinite time to settle before the next clock edge.
Consequences of Metastability:
Unstable data driving multiple destinations can cause excessive current flow, potentially leading to chip damage in extreme cases.
Different fan-out paths may capture different values, pushing the design into an undefined functional state.
The output may eventually settle, but with unpredictable delay, creating timing violations and functional errors.
Problem: For example, see Figure 2 . If the input signal A transitions very close to the posedge of clock C2, the output of the destination flop can be metastable.
As a result it can be unstable and may finally settle to 1 or 0 as depicted by signals B1 and B2.
Solution: Metastability can be mitigated by using synchronizers in the destination domain, which give the signal extra time to settle and provide a stable output. The most common is the multi-flop synchronizer, typically used for single-bit data and control signals. For multi-bit data transfers, more advanced schemes like MUX recirculation, handshake protocols, or asynchronous FIFOs are required.
Problem: When new source data is generated, it may not be captured on the first edge of the destination clock (C2) due to metastability. To avoid data loss, the source must remain stable long enough to meet setup/hold requirements relative to at least one C2 edge. If C1 and C2 edges align too closely, capture may be delayed to the second C2 edge, but with enough spacing, the data is captured in the first cycle itself.
Hence, there may not be a cycle by cycle correspondence between the source and destination domain data. Whatever the case, it is important that each transition on the source data should get captured in the destination domain.
Example: If the source clock C1 runs at twice the frequency of the destination clock C2 (with no phase offset) and input data sequence A = 00110011 is generated on C1’s positive edges, then the destination captures B = 0101 on C2’s positive edges. Although not every value of A is sampled, all transitions are preserved, so no data is lost.
Example (Data Loss Case): If the source sequence is A = 00101111, the destination captures B = 0011. In this case, the third data value (1) is missed because it was not stable long enough with respect to the destination clock edge — leading to data loss.
Solution:
To avoid data loss, the source signal must stay stable long enough for at least one valid destination clock edge to capture it.
For synchronous domains, this can be ensured using an FSM to pace data. For asynchronous crossings, handshake protocols or FIFOs are more reliable.
Problem:
When multiple signals cross domains and are synchronized independently, they may not all be captured in the same destination clock cycle due to metastability. Some may settle in the first cycle while others in the next, causing an invalid combination of values at the destination. This loss of data coherency can trigger functional errors if the signals jointly control design logic.
Example (Loss of Coherency):
Valid states are only 00 and 11 for X[1:0] in C1. When both bits rise 0→1, C2 captures X[0] in the first cycle and X[1] in the second (due to edge timing/metastability), producing an intermediate 10 on Y[1:0] — an invalid state, i.e., data coherency is lost.
Solution:
The problem arises because not all bits switch in the same destination clock cycle, creating invalid intermediate states. If the bus is Gray-encoded, only one bit changes during a state transition, so the destination either sees the old value or the new one — never an invalid state.
This approach works well for control buses. For data buses, where Gray-encoding isn’t practical, techniques like handshake protocols (ex. AXI4), FIFOs, or MUX recirculation are used to ensure data coherency during transfer.
The MUX recirculation technique is shown in Figure 8 .
Here, a control signal EN, generated in the source domain is synchronized in the destination domain using a multi-flop synchronizer. The synchronized control signal EN_Sync drives the select pin of the muxes, thereby controlling the data transfer for all bits of the bus A. In this way, individual bits of the bus are not synchronized separately, and hence there is no data incoherency. However, it is important to ensure that when the control signal is active, the source domain data A[0:1] should be held constant.
When clocks have a known phase and frequency relationship (originating from the same clock-root), the crossing is called a synchronous clock domain crossing. These can be categorized as:
Same frequency, zero phase difference
Same frequency, fixed phase difference
Different frequencies with variable phase difference
Integer multiple clocks
Rational multiple clocks
Though not all appear in real designs, these categories help in understanding CDC scenarios. Here, it is assumed that source clock C1 and destination clock C2 share the same jitter, latency, and skew, start with zero phase difference, and that flop delays are idealized as zero.
Case: Same frequency, zero phase difference
Here, clocks C1 and C2 are identical, derived from the same root clock, so data transfer between them is effectively not a true CDC but equivalent to a single-clock design. In this case, one full clock cycle is always available for capture. As long as setup and hold requirements are met and the design is STA clean, data transfer is reliable with no risk of metastability, data loss, or incoherency.
Here, clocks C1 and C2 run at the same frequency but with a fixed phase shift (e.g., inverted clock or a T/4 phase shift). Since the available setup/hold window is reduced by the phase difference, the combinational logic delay between source and destination flops must be tightly controlled. If STA confirms timing closure, data transfer is reliable without metastability, and no synchronizer is needed — the only requirement is that the design remains STA clean.
When C1 and C2 run at different frequencies, their edge relationship drifts, so the phase is effectively variable. Two sub-cases:
Integer multiple (e.g., C2 = 2×C1): Edges realign periodically, but not every cycle; captures can slip by 1+ cycles → use handshake/enable stretching or async FIFO (for data).
Rational multiple (e.g., C2 = 3/2×C1): Edges rarely/irregularly realign; worst for coherency → treat as fully asynchronous with synchronizers (single-bit) and async FIFO/handshake (multi-bit).
Static timing alone isn’t sufficient here; design as CDC with proper synchronization.
Integer-multiple clocks (fast→slow / slow→fast):
When one clock is an integer multiple of the other, edge phase is variable but the minimum phase gap is one period of the faster clock. In timing terms, C2’s capture window can be T, 2T, or 3T (for example), so you must meet setup to the T case and hold to the 0-phase case. If STA closes, you don’t need a synchronizer—no metastability or incoherency expected.
Data loss caveat (fast → slow only):
Crossing from fast to slow can still drop events. Prevent loss by holding the source value for ≥ 1 destination cycle (e.g., throttle with an FSM or enable-stretch). In the example, generating data once every 3 fast cycles avoids loss. Slow → fast generally doesn’t lose data.
Rational-multiple clocks (non-integer ratio, variable phase):
When C1 and C2 have a non-integer frequency ratio, their edges drift and the minimum phase gap can be arbitrarily small, so metastability is possible. Behavior splits into three cases:
Safe margin always: edges never get too close → no metastability.
Occasional near-coincidence: one cycle may be risky, but the next has margin → intermittent risk.
Repeated near-coincidence: many consecutive risky cycles → effectively asynchronous-like.
Design takeaway: unless you can prove a guaranteed phase margin across PVT, treat as CDC—use 2/3-FF synchronizers for single-bit controls and handshake or async FIFO for multi-bit data. STA alone isn’t sufficient.
If the active edges of C1 and C2 never come too close, setup/hold requirements can always be met. For example, if
C1 = f/3 and C2 = f/2 of a root clock (periods 15 ns and 10 ns), the least edge separation is 2.5 ns — enough to avoid metastability as long as no extra combinational delay is added at the crossing. In this case, no synchronizer is required.
For slow → fast crossings, no data loss occurs. For fast → slow, however, data can be dropped unless the source signal is held constant for at least one cycle of the destination clock, ensuring a valid capture edge always exists.
When C1 and C2 edges occasionally come very close (e.g., 10 ns vs 7 ns; min gap ≈ 0.5 ns), setup/hold can be violated → metastability risk. Use a synchronizer. A capture may slip by one cycle (actual B looks like B2 instead of ideal B1), so no data loss, but data incoherency can appear across multiple signals.
Fast → slow caveat:
Events can be dropped. Hold the source value for ≥ 1 destination cycle (e.g., throttle with a simple FSM) to guarantee capture.
When C1 and C2 edges remain very close for several cycles (e.g., 10 ns vs 9 ns), the crossing behaves much like an asynchronous CDC. Here, setup violations may occur when the source leads, and hold violations when the destination leads. This results in metastability, possible data incoherency, and even data loss (e.g., expected B1 vs actual B2 where a data value is skipped).
To avoid loss, the source signal should be held stable for at least two destination cycles using an FSM. However, since incoherency can still arise, more robust solutions like handshake protocols or asynchronous FIFOs are recommended to ensure reliable transfer.
When clocks have no fixed phase or frequency relationship, their edges can align unpredictably, often causing metastability. In such crossings, issues of data loss and data incoherency can occur in both fast→slow and slow→fast transfers.
If clock frequencies are known, data loss can be avoided by holding the source signal stable for two destination cycles. For frequency-independent designs, more robust techniques like handshake protocols or asynchronous FIFOs are required to ensure safe and reliable transfer.