CDC-101.3: Why You Should Never See Inter-Clock Violations

In a well-constrained FPGA design, Vivado’s timing report should tell a clean story. So, if you’re seeing inter-clock violations, it’s not just a design issue — it’s a constraint failure.

This post will focus on the real reason inter-clock violations appear in Vivado:

Because you haven’t told Vivado what it shouldn’t be analyzing.

Intra-Clock vs Inter-Clock Paths: Quick Refresher

TypeLaunch Clock = Capture Clock?Timed by Vivado?Should Fail?
Intra-Clock✅ Yes✅ Yes❌ Ideally Not
Inter-Clock❌ No⚠️ Maybe❌ Should Not Appear
  • Intra-clock paths are valid timing paths and must be analyzed for setup/hold.
  • Inter-clock paths (i.e., CDC paths) must be excluded from STA using proper constraints.

Why Inter-Clock Violations Should Never Be in Your Timing Report

Vivado doesn’t inherently know whether two clocks are:

  • Asynchronous (e.g., clk_a and clk_b from separate oscillators)
  • Synchronous but unrelated (e.g., clk_100MHz and clk_125MHz)
  • Synchronous and phase-aligned (e.g., derived from the same PLL)

So by default, Vivado assumes every clock might be related — and tries to time all paths between them. That includes cross-domain paths that have no deterministic phase relationship.

This results in inter-clock timing analysis that is meaningless — and potentially misleading.

Example:

Say you transfer a signal from clk_A to clk_B, using a proper CDC synchronizer. If you haven’t added constraints to tell Vivado that these clocks are asynchronous, Vivado will:

  • Try to time the path
  • Generate invalid setup/hold paths between unrelated clock domains
  • Show artificial violations
  • Waste build time analyzing these false paths

How to Correctly Handle Inter-Clock Paths

We will cover this in detail in our next blog post.

Synchronous Clocks that Are Still Not Safe

Sometimes, two clocks are generated from the same PLL but have different phase offsets or frequencies. Vivado assumes a relationship unless told otherwise.

Common Mistakes That Cause Inter-Clock Violations

MistakeWhat Happens
Missing ConstraintsVivado tries to time async paths
Assuming Vivado detects CDCIt doesn’t — it needs explicit constraints
Using synchronizers without constraintsFalse violations still show
Not isolating multi-bit crossingsTiming paths report glitches/violations

Why This Matters: Build Time & Design Clarity

Every time Vivado tries to analyze a cross-clock path, it:

  • Computes false arrival/requirement times
  • Uses internal resources for invalid paths
  • Increases implementation run time
  • Fills timing reports with noise

This makes it harder to see real issues (e.g., intra-clock violations), and bloats the design effort.

What Should Be in a Clean Timing Report?

Intra-clock violations only (and ideally, none!)
No inter-clock setup/hold violations
Proper CDC constraints present
Safe crossing mechanisms

Tools That Help

  • Vivado CDC Report:
    Use report_cdc to find unguarded crossings.
  • Xilinx IP Integrator XPM FIFO / CDC blocks:
    These auto-instantiate proper constraints.
  • Hierarchy-aware constraints:
    Use hierarchical names in XDC to cleanly cut paths.

Summary: What to Do

  1. Check every inter-clock path in your report.
    ➜ If it’s a CDC, it should be cut and should be dealt with “properly”.
  2. Don’t tolerate inter-clock violations.
    ➜ They’re not real issues — just warnings that you haven’t constrained CDC.
  3. Use Vivado XPM based CDC Schemes.
  4. Educate your team
    ➜ Inter-clock violations ≠ timing failure. They = constraint failure.

Final Word

Static Timing Analysis is only as smart as the constraints you provide.
If Vivado is reporting inter-clock violations, it’s because it’s trying to help — but it’s looking in the wrong places.

Don’t let false timing paths distract you from real design issues. Cut the noise. Constrain your CDC properly.