In digital design, particularly in FPGA development, managing signal transfers across different clock domains is critical. Failure to handle Clock Domain Crossing (CDC) correctly can lead to elusive, non-reproducible bugs that are nearly impossible to debug in post-silicon. This blog post explores the fundamentals of clock domains, when clocks are considered asynchronous, and why CDC safety is non-negotiable, even between seemingly related clocks.
What Are Clock Domains in Digital Design?
In digital systems like FPGAs and ASICs, a clock domain is a group of registers (flip-flops) and logic that are driven by the same clock signal.
Formal Definition:
A clock domain is a region of a digital design in which all sequential elements (e.g., flip-flops, latches, memory blocks) are triggered by the same clock source, or a clock signal that is phase-aligned and frequency-matched.
Why Do Clock Domains Exist?
Most real-world digital designs use multiple clocks. Reasons include:
- Different functional blocks running at different speeds (e.g., CPU vs. peripherals)
- External interfaces needing specific clocks (e.g., HDMI, Ethernet, DDR)
- Power-saving (lower clocks in idle regions)
- IP blocks with their own clocks
- Asynchronous inputs (buttons, sensors)
Types of Clock Domain Relationships
Type | Description |
Single Clock Domain | Everything runs off the same clock. Timing is simple. |
Synchronous Domains | Clocks are related (e.g., same MMCM/PLL source, fixed phase/frequency relationship) |
Asynchronous Domains | Clocks are unrelated (e.g., separate crystals or PLLs). Need CDC handling. |
Why Clock Domains Crossings Matter?
- When signals stay within the same clock domain, timing is predictable and safe.
- When signals cross from one domain to another, you must use Clock Domain Crossing (CDC) techniques to avoid metastability and timing errors.
- Static Timing Analysis (STA) works only within a clock domain or across known, related clocks.
Problems Without Proper Clock Domain Crossing
- Metastability: Occurs if a flip-flop samples data during a transition from another clock domain.
- Data loss or corruption: Multi-bit signals crossing domains can glitch.
- False timing violations: If timing tools (like Vivado) don’t know clocks are unrelated, they’ll report invalid errors or waste build time.
When Are Two Clock Domains Called Asynchronous?
Two clock domains are called asynchronous when: There is no known, fixed phase or frequency relationship between the two clocks.
This means:
- Their rising and falling edges do not align in any predictable way
- They are derived from independent sources (e.g., separate oscillators or PLLs)
- One may drift or jitter with respect to the other over time
Asynchronous Clocks — Examples
Clock A | Clock B | Asynchronous? |
100 MHz from onboard oscillator | 66 MHz from external interface | Yes |
100 MHz from PLL0 | 125 MHz from PLL1 | Yes (usually) |
50 MHz system clock | Button input debounced at 1 Hz | Yes |
Ethernet RX clock | FPGA system clock | Yes |
Unless there is a documented, locked phase relationship (e.g., derived from same PLL with known divider), assume clocks are asynchronous.
The Key Idea:
Asynchronous clocks can shift in time relative to each other infinitely. Even if they’re close in frequency (e.g., 100 MHz and 101 MHz), their edges will align occasionally and misalign again — unpredictably.
This makes it unsafe to directly pass data between them.
What if Frequencies Are Related?
If two clocks are:
- Generated from the same PLL/MMCM
- Have a fixed phase/frequency relationship
- And the design knows that relationship
…then they may be treated as synchronous (e.g., clk and clk/2).
But if there’s any jitter, independent PLLs, or external clocks, then they are asynchronous by definition.
Engineering Rule of Thumb
Unless you can prove the clocks are phase-aligned and frequency-locked, treat them as asynchronous and use proper CDC design and constraints.
Why It Matters in Vivado?
Vivado can only do valid Static Timing Analysis (STA) when it knows the relationship between clocks.
If clocks are asynchronous, you must:
- Use proper CDC techniques
- Cut invalid paths with constraints
Otherwise, Vivado will try to time them and report false setup/hold violations.
Clock Relationships
Term | What It Means | Example |
Edge-aligned | The rising (or falling) edges of both clocks occur at the exact same moment periodically | 100 MHz and 100 MHz clocks with 0° phase shift |
Phase-aligned | The clocks have a fixed, known phase offset (e.g., one always lags the other by 90° or 2.5 ns) | 100 MHz and 100 MHz with 90° shift |
Phase-related | The clocks are derived from the same source and their frequency/phase relationship is deterministic, but their edges don’t align regularly | 100 MHz and 66.67 MHz from same MMCM |
Asynchronous | Clocks have no fixed phase or frequency relationship; edges drift relative to each other | 100 MHz from onboard oscillator and 27 MHz from external sensor |
Edge-Aligned Clocks
Breakdown with Examples
- Frequency: same
- Phase: 0°
- Edges rise together
Example:
clkA: |‾‾‾|___|‾‾‾|___|‾‾‾
clkB: |‾‾‾|___|‾‾‾|___|‾‾‾
Used in synchronous multi-clock systems (e.g., when using a BUFG or create_generated_clock in Vivado).
Phase-Aligned (but Not Edge-Aligned)
- Frequency: same
- Phase: fixed (e.g., 90° shift)
- Edges don’t align, but timing is predictable
Example:
clkA: |‾‾‾|___|‾‾‾|___|‾‾‾
clkB: |‾‾‾|___|‾‾‾|___|
Used for DDR interfaces, skewed clocks for hold violation fixing, etc.
Phase-Related, Edge-Misaligned
- Different frequencies (but derived from same MMCM)
- LCM (Least Common Multiple) of periods may make them coincide sometimes
- But in general, edges drift
Example:
100 MHz (10 ns) and 66.67 MHz (15 ns)
clkA: |‾‾‾|___|‾‾‾|___|‾‾‾
clkB: |‾‾‾‾‾|_____|‾‾‾‾‾|
These are synchronous in terms of Vivado (same MMCM), but potentially not safe for direct sampling — they may need CDC logic.
Asynchronous
- No stable frequency or phase relationship
- Edges are unpredictable with respect to each other
Example:
clkA: |‾‾‾|___|‾‾‾|___|‾‾‾
clkB: |‾‾‾‾‾|_____|‾‾‾‾‾|
These require CDC synchronizers, and CDC timing constraints
Are Two Clocks from the Same MMCM Synchronous or Asynchronous?
If both clocks are generated by the same MMCM, then:
They are synchronous, in the sense that they are frequency-locked and have a known phase relationship (even if they don’t have the same frequency).
What Makes Them Synchronous?
- Same clock source (MMCM input)
- Known divider/multiplier ratios
- Toolchain (Vivado) understands their relationship
Even if the output clocks are:
- 100 MHz (CLK_OUT1)
- 66.667 MHz (CLK_OUT2)
…as long as they’re derived from the same input and MMCM instance, they do not drift apart over time. Their edges may not align often, but their relationship is deterministic and repeatable.
This makes them synchronous but not edge aligned.
Final Thought
CDC errors are subtle, dangerous, and hard to debug. If you see inter-clock violations in Vivado’s timing report, it usually means you haven’t handled CDC properly.
Worse — if you see no violations but have unsafe crossings, you’ve created a ticking time bomb.