We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

Showing results for 
Search instead for 
Did you mean: 

How to Constrain Clock Interactions correctly

Xilinx Employee
Xilinx Employee
5 5 19K

In today's designs it is typical to have a large number of clocks that interact with each other. In order to ensure that Vivado optimizes paths that are critical, it is essential to understand how the clocks interact and how they are related – synchronous and asynchronous clocks.

Synchronous clocks are clocks that are related to each other. For example, generated clocks from an MMCM or PLL are typically synchronous clocks provided the two clocks have a common period. If the clocks from the output of MMCM or PLL do not have a common period, then it is recommended to treat these clocks as asynchronous with proper synchronization techniques. You can easily identify clocks that are synchronous by running the report_clock_interaction report and then looking at the “Path Req (WNS)”, the “Clock Pair Classification” and the “Inter-Clock Constraints” columns. Here are three scenarios where you would treat clocks relationships as asynchronous and apply appropriate timing constraints:

  1. If the clock interaction report has many (or even one) Red "Timed (unsafe)" and/or Orange "Partial False Path (unsafe)" rectangles then you have not constrained asynchronous clocks correctly. If your design has a number of asynchronous clock crossing domains, then you need to constrain those clock interactions.
  2. Look at  the "Clock Pair Classification" and "Inter-Clock Constraints" columns in the Report Clock Interactions reports. If  the clock pair classification is "No Common Clock" or "No Common Period" and/or the Inter-clock Constraints says "Timed (unsafe)" then treat the interactions as asynchronous.
  3. If the “Path Requirement (WNS)” column is very tight, typically less than 1 ns, or the “Inter-Clock Constraints” is Timed “Unsafe” or “Partial False Path (unsafe)” then it is recommended that you treat the clock interaction as asynchronous.

    If the “WNS Path Requirement (ns)” is reasonable (>1 ns) and the "Inter-Clock Constraints is "Timed" and the “Clock Pair Classification” is “clean” then the clock interaction can be treated as synchronous meaning you don't need to add any timing constraints. The timer has automatically timed these paths as synchronous.



In order to constrain asynchronous clock domain crossings correctly, there are four things to consider:

  1. If there are no paths between the two clocks, the simply use set_clock_groups or set_false_path between the two clocks.
  2. If the paths are all single big CDCs then you can use set_clock_groups or set_false_path between the two clocks.
  3. If the paths are all multi-bit paths, and you are concerned about the latency and the skew in the data bits, then use set_max_delay –datapath_only and the set_bus_skew constraint.
  4.  If there are a mix of single bit and multi-bit CDCs between two clocks then use explicit path-to-path false path constraints for the single bit CDCs and for the multi-bit CDCs use set_max_delay –datapath_only and set_bus_skew constraints.

If the clocks are synchronous, there is no need for any constraints. The STA engine in Vivado will automatically time the paths.


First, a quick comment


         1) If there are no paths between the two clocks, the simply use set_clock_groups or set_false_path between the two clocks.


If there are no paths between the clocks (the clock interaction box is black), then there is no need to put an exception between them. In fact, this is almost specifically the point of the clock interaction report - it tells you which clocks have paths between them, and how those paths are timed (and makes a judgement call as to whether it thinks the constraints are "safe" or not).


But now on to the larger discussion of the clock interaction report...


The clock interaction report is a tool for the designer to reflect on the design... Do I understand the paths between these two domains? Did I consider them when I created the design and (importantly) wrote the constraints? Are the constraints between them correct?


While the "rules of thumb" outlined in this post are more or less correct, they may be simplifying  the process a bit - again, the point is for the designer to consider all the paths and think about whether they make sense. If they do not, then correct them. Really this report should be more of a sanity check - the designer should be thinking about the correct constraints as the design is being constructed (and not relying on the clock interaction report as a mechanism for writing constraints).


Finally, it is important to note that this report looks only at the constraints associated with clocks and clock crossing paths. This does not replace the need for proper clock domain crossing circuits - even if the exceptions are correct, this doesn't mean the clock crossing paths are safe. Vivado also has the report_cdc command that helps you further in analyzing the structure of the clock domain crossing circuits.




Xilinx Employee
Xilinx Employee

The main focus on this blog is getting the constraints correct.


While technically there may be no need to constrain clocks that have no paths, I'd err on the side of caution and constrain them for the sake of completeness. If the clock relationships are constrained then there is one less thing to be worried about in case the design changes. 


Constraining all clock relationships, irrespective of whether they have paths or not, is a standard ASIC practice - in ASICs setting clock relationships is essential ( with set_clock_groups -asynchronous) if you want crosstalk analysis. 


 I'd like to also find out what parts are 'more or less correct' :-).  So Avrum, let us have coffee one of these days. :-)


While 'disagree' is probably is very strong word, I'd say, my opinion is different to Avrumw's comment about using the report_clock_interaction report only 'as a sanity check'.The point of the report, in my opinion, is to remove any guesswork. Today's designs are very complex with possibly hundreds of clocks that might come from different individual or teams and even IPs that may or may not come with constraints. The person in charge of the top level constraints may or may not know all the details of the complex clocking topology of the design and the report is to make the job easier. Irrespective of whether you know the design or not you should be able to identify how clocks are related to each other and how to constrain them based on the path topology - 1-bit vs multi-bit. The report allows the designer to easily constrain the design without any guesswork. Get it right, first time (if you are only looking at it towards the end of a project) or everytime (throughout the design cycle as recommended by the UltraFast Design Methodology).


Yes, this blog doesn't talk about the CDC topology (safe CDC circuits) as the main focus as I mentioned earlier, is getting the constraints correct. Safe CDC topology is a blog post in itself and as one of the architects of report_cdc I intend to talk about safe CDC topologies in the near future.


      I'd like to also find out what parts are 'more or less correct' :-)


As Balachander said, our views are "different".


My views are that the constraints between different clocks are not based (at least solely) on the clocks themselves, but on the mechanism in which these clocks transfer data. Specifically, it is my view that any clock domain crossing needs to have a proper clock domain crossing circuit implemented on it, and it is the clock domain crossing circuit that requires constraints.


For example, a Gray code clock domain crossing circuit requires a set_max_delay -datapath_only (or a set_bus_skew) that uses a value that is less than or equal to one source clock period, independent of what the destination clock is. A MUX clock crosser needs a set_max_delay -datapath_only (or set_bus_skew) that has a period that is related to the separation of data going through the clock crosser and the number of synchronization flip-flops. Most event synchronizers need a set_max_delay -datapath_only with a value that is less than or equal to the period of the faster of the two clocks. A single slow changing signal can be constrained by a set_false_path if the latency is not an issue for you, or is determined by how much latency you can tolerate.


Each of these clock domain crossing circuits requires a different constraint. It is my view that you write the constraint appropriate for the clock domain crossing circuit. The design of your clock domain crossing circuit is part of the architecture, and hence your constraints should come from the architecture.


By the time you get to a synthesized design (where you can get the Clock Interaction Report), you should have long completed your architecture. As a result, your constraints should already be in place. It is for this reason that I view the Clock Interaction Report as a "sanity check".


But I agree - clock interactions are complicated, and we don't always live in an ideal world where all the steps are followed in order. And there are cases where the top level designer is not intimitely aware of all the details of the clock crossing that takes place throughout the design (although scoped constraints for the clock domain crossing circuits deep within the design can be a big help here). So, on this we agree - the Clock Interaction Report is an invaluable tool for helping in these situations. Where we "differ" is in the solution to the case where we find something unexpected in the Clock Interaction Report. In my view, rather than apply a constraint based on the report, the structure of the circuit around the paths covered by this interaction should be analyzed to make sure that a proper clock domain crossing circuit is in place, and, if so, what constraint that clock domain crossing circuit should have.


    So Avrum, let us have coffee one of these days. :-)


Absolutely! I am always willing to have a methodology discussion!



Scholar jmcclusk

I have to agree with Avrum on this topic, since a good FPGA design methodology should have CDC contraints nicely in place by the time synthesis is done, and before placement begins.   I would like to point out that simply adding false path constraints between two clock domains with no paths is a dangerous game.   This is because FPGA design in many cases has become a team sport, with a team typically composed of people with a wide range of experience.   It's far too easy for an inexperienced designer to accidently create a CDC when committing new code, and a false path constraint across that accidental CDC path will completely suppress the fact that it was introduced.  


The best methodology is to use "blessed" CDC components that integrate their own timing requirements and constraints, such that post synthesis, a TCL script is invoked for that component to automatically set a max delay (or max bus skew) constraint on the CDC path in that component.   This way, the "blessed" components get automatically constrained, and accidental CDC's show up as a red square on the Clock Interaction Report.   Ideally,  the script that tests for accidental CDC's will identify the code module with the unblessed CDC, then track down the identity of the person who last committed that module, and then send them email about the problem.    I will point out that this scheme also demands a "dummy CDC" module, that just creates a bare naked CDC with no real synchronization,  for the purpose of blessing pseudo-static paths that nobody cares about. 


There still remains the problem of what to do about timed paths with sub-nanosecond timing requirements, which are typically generated by MMCM's with the same root clock source, and rationally related frequencies.   These need to be relaxed to more reasonable values, in order to prevent routing failure.   Accidental CDC's introduced into a relaxed timed path like this won't show up as a red square in the Clock Interaction Report.   The trick here is NOT to relax the subnanosecond timing, but to leave it alone.  Blessed CDC components will relax their own paths, and unblessed CDC's will cause routing failure, thus betraying their existence.    The only thing that's still not easy to automate, is the decision of whether or not to treat a timed path as asynchronous or not.  For me, the region is somewhere between 1 and 3 nanoseconds, depending on the target device speed, technology, etc.


As a final note,  it would be useful if future XPM CDC modules supported automatic CDC path constraints, based on a TCL script that constrains the CDC path based on source and destination clock periods.   These components should also attach a net attribute "BLESSED_CDC" or somesuch to the CDC nets, so that a DRC script can scan the total pool of CDC paths, and find all the paths that DON'T have the "BLESSED_CDC" attribute.    Accidental CDC's must be purged!   Using an attribute to mark CDC nets will keep any accidental ones from hiding in a timed path.    Although you can argue,  if it meets timing,  how can it be broken?

Xilinx Employee
Xilinx Employee

@avrumw and @jmcclusk: Awesome comments, really loving the discussion. 




If you read my blog again, you'd find most of your concerns addressed as far as constraint topology and the right constraints to add in a simple and easy to understand way without confusing the user with the underlying CDC topology.  When to apply false path (1-bit) and when to apply set_max_delay -datapath_only and/or set_bus_skew (mult-bit) is covered.  For mulit-bit irrespective of whether it is gray coded or a MUX type (or even CE-type) will need a set_max_delay -datapath_only and/or set_bus_skew and that's what I've recommended.


@jmcclusk:  I have also covered what to do when dealing with synchronus CDCs by looking at the  "WNS Path Requirement" column. The recommendation of <1 ns is a generic recommendation but obviously it will depend of a number of factors. Again the idea here is to keep it simple - first order of the problem defined with a possible solution.


Folks, the objective here was to educate users about the value of the Clock Interaction Report and how to use it to constrain clock relationships and CDCs (synchronous and asynchronus) in a simple and easy to understand method.


I'd be more than happy to post a blog on your behalf, if you'd like to take a stab of how to use report_cdc (with or without refering to the report_clock_interaction) to analyze CDC topologies. As the archtiect of report_cdc and set_bus_skew/report_bus_skew, I'd be happy to collaborate with you guys. If you want to contribute a blog post, please let me know.


I'm disabling comments to this blog post only, as I think, it has been sliced and diced in every aspect.