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
Type | Launch 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
Mistake | What Happens |
---|---|
Missing Constraints | Vivado tries to time async paths |
Assuming Vivado detects CDC | It doesn’t — it needs explicit constraints |
Using synchronizers without constraints | False violations still show |
Not isolating multi-bit crossings | Timing 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:
Usereport_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
- Check every inter-clock path in your report.
➜ If it’s a CDC, it should be cut and should be dealt with “properly”. - Don’t tolerate inter-clock violations.
➜ They’re not real issues — just warnings that you haven’t constrained CDC. - Use Vivado XPM based CDC Schemes.
- 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.