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!


How to set timing constraint in this case.

Posts: 33
Registered: ‎04-24-2008

How to set timing constraint in this case.

My design have 5 different clock. clka, clkb, clkc, clkd and clke. All these clocks are async. I have another clock named cpmclk, which is running very fast to packing parellel signal to serail and transfer between FPGAs.

The path between cpmclk and clka, clkb...clke is async, but I need control the datapath delay to one cpmclk.


In the past (ISE), I can set all the clock clka, clkb...clke and cpmclk to async, and add a set_max_delay datapath_only between cpmclk and  clka, clkb...clke.


But in vivado the set_clock_groups have the higher priority, if I set them to async the set_max_delay constraint will be ignore by the tools.


How to set timing constraint in this case. Thanks.




Posts: 4,540
Registered: ‎01-23-2009

Re: How to constrain clock crossing paths

[ Edited ]

Using set_max_delay -datapath_only between two clocks tells the tool to ignore mechanism it usually uses to derive the requirement for the path, and instead use the requirement given in the set_max_delay. Therefore, this constraint is a different (but equally valid, or even better) way of telling the tool that the clocks are asynchronous. So, if you use a set_max_delay -datapath_only, you don't need to use a set_false_path or set_clock_groups on that path. So, if you have


set_max_delay <value> -from [get_clocks cpmclk] -to         [get_clocks {clka clkb clkc clkd clke}] -datapath_only

set_max_delay <value> -to       [get_clocks cpmclk] -from    [get_clocks {clka clkb clkc clkd clke}] -datapath_only


There is no additional need to do anything to make cpmclk "async" to all the rest.


If all the other clocks are really async, then you can do

set_clock_groups -asynchronous \

   -group [get_clocks clka] \

   -group [get_clocks clkb] \

   -group [get_clocks clkc] \

   -group [get_clocks clkd] \

   -group [get_clocks clke]


But (here is my standard word of caution) - declaring paths as false (which is what set_clock_groups does) is rarely the correct thing to do. If there are no paths between any pairs of these clocks, then you don't need any constraints - setting them as asyncrhonous doesn't do anything. If there are paths between them, then these paths must have clock crossing circuits. Except for the "single slow changing signal" clock crosser, almost all clock crossing circuits need constraints - setting them as false paths underconstrains the clock crossing circuit, which can result in system failure. For most circuits, you need a set_max_delay -datapath_only constraint on the path between the domains. The value of the max_delay depends on the clock crosser, but almost all of them have a requirement.


In my opinion, there are very few places where a set_false_path or set_clock_groups shoud be used...



Posts: 902
Registered: ‎11-21-2013

Re: How to set timing constraint in this case.


Can you please explain what do you mean by your word of caution? If VIVADO by default assumes all clocks are related, and if they are not, one has to tell this to the tool otherwise it will workd harder and give lots of timing violations etc. But both of us know that, so maybe I misunderstood the message you are trying to convey? And if I may ask, why do you think using false_path is rarely correct thing to do?

Thank you very much


Vladislav Muravin
Posts: 4,540
Registered: ‎01-23-2009

Re: How to constrain clock crossing paths

[ Edited ]

So, yes, Vivado assumes all clocks are related. And, yes, if they are not, in fact, related, then we need a timing exception to tell the tool that the normal "synchronous" timing checks on the path are not to be performed. There are three ways to do this

  - set_false_path

  - set_clock_groups (which is really the same as set_false_path between pairs of clocks)

  - set_max_delay -datapath_only


It is my argument that, in most cases, only the last one is correct.


Lets break this down into a couple of cases...


If two clocks are not related, but there are no paths between them, then no additional constraints are required; since no paths exist, the tools will not have any paths to optimize, so it becomes irrelevent whether the clocks are related or not. The "report_clock_interaction" command is perfect for identifying these.


If two clocks are not related, but paths exist between them, then there must be a clock crossing circuit between them. The clock crossing circuit allows data to be moved across the unrelated clock domain boundary in spite of the fact that no known phase relationship exists between the two clocks (and this includes clocks that are unrelated in either frequency or phase, since the net result is the same, there is no minimum guaranteed separation between the edges of the source and destination clock). This clock crossing circuit must accurately bring data across the boundary in spite of the fact that no phase relationship exists, and therefore must deal with

  - metastability, since you may well violate the setup/hold requirement of the capture FF in the destination domain

  - bus coherency (if the data being crossed is more than a single bit wide)


A lot of discussion on clock crossing revolves around metastability; when the D input of a FF changes too close to the active edge of the clock (and hence violates the setup or hold time), the FF may

   - keep its old state

   - transition to the new state

   - go metastable

       - once metastable, it will eventually resolve to either the old or new state, and the amount of time required for the metastability to resolve is probabilistic and (theoretically) unbounded


Metastability resolution circuits reduce the risk that a metastable signal will be used in the system in a way that causes a system failure; reduces it, but can never eliminate it entirely; asynchronous signals always cause some possibility  that your system will fail; the goal is to reduce the probability to low enough that your "Mean Time Between Failures (MTBF)" is sufficiently large to meet your systems goals. This is generally done with two (or more) back to back flip-flops; these flip-flops must have the ASYNC_REG property set on them, and should have set_max_delay constraints on them.


Bus coherency is different. If the data crossing the barrier is more than one bit wide, then the datum must be passed through accurately. If a bus changes from one datum (data_old) to a new datum (data_new) near a destination clock edge, then most clock crossing circuits must be designed in such a way to yield either of the two data (either data_old or data_new); it is impossible to know which one will get through, but it must be one or the other, and not some "other" datum. (Some clock crossers have a way of signalling "no data", when a reliable crossing cannot be done).


Bus coherency is actually the tougher problem. There are many approaches to crossing multiple-bit data. Lets take (common) problem of crossing a counting value from one domain into another (or more specifically, sampling the value of a counter in one domain using another domain). On any destination clock edge, the value of the counter in the source domain will be <cnt>. However, if we sample the value when it is transitioning between <cnt> and <cnt+1>, then the value received on the destination side must either be <cnt> or <cnt+1>.


We know this doesn't work with conventional binary counting sequences. If <cnt> = 4'b0111  (i.e. the decimal value 7), then what is received on the other side must either be 7 or 8. A simple metastability resolution circuit on each of the 4 bits won't get this; in this case, all 4 bits are transitioning, and hence each one may give

  - the old value

  - the new value

  - or go metastable

After metastability resolution each of the 4 bits (which are all transitioning), will resolve to either the old value or the new value. Thus, each will independently resolve to either a 0 or a 1, thus resulting in any value from 0000 to 1111 in the destination domain - this is a system failure, only 0111 or 1000 are correct.


One solution to this is to use a Gray code counter. Instead of counting in binary fashion (0000 0001 0010 0011 0010...) we count in a Gray code fashion, where each value in the counting sequence differs from the preceding one by only one bit change

    0000 = 0

    0001 = 1

    0011 = 2

    0010 = 3

    0110 =4

    0111 =5

    0101 =6

    0100 =7

    1100 =8

    1101 =9

    1111 =10

    1110 =11

    1010 =12

    1011 =13

    1001 =14

    1000 =15

Now, each transition from <cnt> to <cnt+1> has only one bit changing. If we sample around that point, only the one bit in question can be unknown, which guarantees that on the destination side we will get either the old value <cnt> or the new value <cnt+1>. Note that the "+" operator here is not done using 2s compliment addition, but with Gray code addition (a different logical function).


But, lets look at a potential problem. If we declare the clock crossing path false (with set_false_path or set_clock_groups) then there is no constraint on the path between the last FF in the source domain and the first FF in the destination domain. If we do this, the clock crosser can fail!


With no constraints (or false path constraints), the tool has no constraint on the path. Therefore, it can place the source and destination FF of the path anywhere on the die, and route them any way it wants. There is no limit on the propagation delay between the last FF on the source domain and the first FF on the destination domain.


Lets say the route for bit 1 is pretty short, but the route on bit 0 is very very long - lets say that it is more than one source clock period in length. To put real numbers on it, say the source clock is 10ns, the routing on bit 0 is 12ns and the routing on bit 1 is 1ns; remember, while this is unlikely, it is possible since there are no constraints on the path.


So lets look at the transition from 0 -> 1 -> 2


When the source counter transitions from 0->1 (lets call that time 0), bit 0 changes from a 0 to 1. It will take 12 ns for that to reach the sample FF on the destination domain. One clock later (at time 10ns), the counter transitions from 1->2; bit 0 will remain at a 1, but bit 1 will transition from a 0->1. It takes 1ns for that change to propagate to the capture FF, thus will arrive at  time 11.


In this case, what is at the input of the destination FFs between time 11 and time 12? The propagation of bit 1 has made it to the destination (so it is a 1), but the propagation of bit 0 has not yet (it will arrive at time 12), so it is still a 0. Thus the bus will be sampled as 0010. This is the code for the value 3! Thus, in the destination domain, it looks like our counter has gone 0 -> 3 -> 1 -> 2 -> 3 (assuming it is sampled fast enough). This is a system failure. 


So, how do we fix this. We need to constrain the clock crossing paths so that this is impossible. What we really need to do is ensure that the skew on the different bits of our Gray code bus is less than one source clock period. Even in Vivado, we cannot directly constrain skew. But, if we constrain the maximum delay on the path to be less than one source clock period, then we can (indirectly) constrain the skew. How do we do this


set_max_delay -from <source_FFs_on_source_domain> -to <destination_FFs_on_destination_domain> <value_less_than_source_clock_period> -datapath_only


Now, the skew is constrained, so the clock crosser can't fail.


Note: We can do this on the individual FFs on involved in the path, or we can do this on the clocks themselves. However, if we do a set_false_path between the clocks or a set_clock_groups on the clocks, then that constraint has the highest priority - even if we also do a set_max_delay on the FFs involved in the path, the set_clock_groups will override it, and the path will still be unconstrained.


This is a perfect example as to why set_false_path or set_clock_groups is incorrect for this path, but set_max_delay -datapath_only is correct.


Other clock crossers have similar (but different requirements). For example, if a clock crosser looks for a stable point to sample data by waiting until "just after a transition" on a bus that has infrequent transitions, then you end up with a skew requirement on the signal that crosses the clock domain which is signalling the change in the bus and the rest of the bits of the bus (hence it also needs a set_max_delay -datapath_only).


Furthermore, at the heart of any clock crossing FIFO is a Gray code clock crosser; this is used to cross the address from one domain to the other to calculate empty and full. Again, it needs a set_max_delay -datapath_only (unless it is the built-in FIFO, where the clock crosser is hardened).


This is what I mean by the set_false_path -from/to clocks or set_clock_groups rarely being the correct constraint. These do work if your only crossers on the domain are (or ever will be)

  - single bit slow changing signals or

  - clock crossing FIFOs using the built-in (hardened) FIFO


All other clock crossers will be underconstrained if you use set_clock_groups or set_false_path.



Posts: 902
Registered: ‎11-21-2013

Re: How to constrain clock crossing paths

Thank you for detailed answer. I understand now what you meant. I agree with you on the cause of the metastabilities as well as on the techniques to deal with this, and of course all the well-known clock domain crossings, bus transfers and coherency, FIFOs etc. We have a library of little modules that are designed to just deal with this.


My question was asked rather in the context of having a timing constraints that make the tool work more than it should. (which may not be as important as first of all one's making sure he/she has a proper education on *all* aspects of the CDC)


Say I have a clock domain such as 100 MHz that runs all the configuration that configures how my design would operate. And the rest of the design runs off completely different clock domain, which may or may not be related, and it is something like 333 MHz.


If I define a relationship between these clocks using the set_max_delay -datapath_only, the tool creates a completely different placement where the logic I don't care about its timing starts to be blended with the logic I do care about its timing and makes the tool work harder etc as it tries to put all the design together. I saw it on the floorplan.


If I tell the tool that these clocks are not related, and decouple them there is a completely different story. The non-related FFs are being thrown away, and runtime goes lower as the tool does not have to work more to do its job, TNS is 0 etc.


Again, I believe what you said is very important and as such, people should deal with the CDC situations. I guess what I want to emphasize is that, and again, this is said in the context of designers who *know* what they are doing, if there are constraints that may not have to exist, they should not exist.


For the Shihua, I believe that using set_false_paths followed by *correct* use of the set_max_delay for things like bus crossers and double-D oversamplers (which are exactly what Avrum mentioned), is another way to go. This is how we constrain our designs but perhaps there are designs where not using set_false_paths and just using set_max_delay would work better. Shihua can choose what's better for his application.


Thanks again for your response


Vladislav Muravin
Posts: 4,540
Registered: ‎01-23-2009

Re: How to constrain clock crossing paths

[ Edited ]



Your example is a good one if it is designed correctly. This condition (where configuration registers are on a different clock domain from the datapath) happens "not infrequently". As long as you make sure that your data path is in reset (or some other mechanism to make sure it is not sensitive to configuration changes) when the configration registers are changed, then these can be declared as false paths. The are, in fact, really multicycle paths with very large multipliers (based on the minimum number of clocks between the last update of your configuration register and the re-enabling of your datapath), but it is pretty safe to call them false.


This is one of the few cases where a path between different domains does not have a clock crossing circuit (and is still correct). From the timing point of view on your datapath, the configuration inputs are considered "pseudo-static".


I will re-warn about one thing, though...


The set_false_path has an inherently higher priority than other path exceptions (including set_max_delay). So if you have FFA on CLKA and FFB on CLKB then


set_clock_groups -group CLKA -group CLKB

set_max_delay -from [get_cells FFA] -to [get_cells FFB] 5 -datapath_only


will not constrain the path between FFA and FFB. This path is included in the enumeration of both constraints, but the set_clock_groups has higher priority than the set_max_delay, so the path from FFA to FFB will remain a false_path. If the FFA to FFB path is part of your clock crosser then it will end up underconstrained.


Lets take your example. Most of the paths from the configiuration domain to the datapath domain are false. However, there is (at least) one that isn't; presumably one configuration bit controls the "enable" or "reset" to your datapath that ensures that it is idle when you change other configuration registers. This bit needs a clock crosser to bring it into the datapath domain. With a set_clock_groups, you cannot constrain it. (Although, this probably isn't a problem since it is a slow changing single bit signal, so is one of the clock crosser types that will work without a constraint).


Anyway, I hope you can see why I really discourage set_clock_groups or set_false_path -from <clock> -to <clock>; once these are done, no other constraints on paths between the domains will matter. Furthermore, you will not get any error or warning that the set_max_delay is not accomplishing anything. If paths are false (like yours), and the designer is sure of it, then he can declare them false - but I still recommend doing it by enumerating the FFs involved in the clock crossing; not by declaring the clocks false or unrelated.



Posts: 902
Registered: ‎11-21-2013

Re: How to constrain clock crossing paths

Oh well, I guess you are right 100%. Our example is that we make the designs not to care about these inter-clock domain stuff. And the way we use set_max_delay is slightly different in its purpose.


And, I'd add Xilinx should figure out a way to allow more flexibility on this topic (while properly educating the designers). One should be able to decouple 2 or more clock domains to timing-except 99% of the paths while still allowing the use of something equivalent to set_max_delay between maybe 1% of the path we may want to care about.


Regards Vlad

Vladislav Muravin
Posts: 4,540
Registered: ‎01-23-2009

Re: How to constrain clock crossing paths

And, I'd add Xilinx should figure out a way to allow more flexibility on this topic (while properly educating the designers). One should be able to decouple 2 or more clock domains to timing-except 99% of the paths while still allowing the use of something equivalent to set_max_delay between maybe 1% of the path we may want to care about.


Unfortunately, this is not how SDC (as defined by Synopsys works) - the constraint priority stuff is part of the open standard SDC constraint system...


We are stuck with it!



Posts: 902
Registered: ‎11-21-2013

Re: How to constrain clock crossing paths

Let's look on the bright side: if this is our worst problem, we are the happiest ppk on this Earth :)
Vladislav Muravin
Xilinx Employee
Posts: 162
Registered: ‎03-24-2008

Re: How to constrain clock crossing paths

Avrum gave you some fantastic detail in his response and he is 100% correct.  I will add a tiny bit to this.  We are not really stuck w/ SDC technically speaking.  For example the datapath_only option to set_max_delay is after all an extension that we implemented that diverges from accepted SDC semantics.  We did that based on historical tools support from TRCE and customer requests.  I will point out however that ASIC designs, and our competitor who supports SDC have no such constraint.  Why is that?  The consequences of allowing a cross-clock domain violation into a $100M ASIC are far, far greater, and the tools cost a GREAT deal more than FPGA tools - surely there is a fancier/easier way to constrain these crossings if you the designer are absolutely certain you have designed your circuit correctly.


We could offer additional extensions - but it does not solve the root problem.  Frankly speaking it is not safe to do so - and that is why SDC and Vivado make the assumption that clocks are synchronous by default.  You as the designer must make sure there are no crossings for which you have not designed a proper synchronizing circuit to provide immunity from metastaiblity which will certainly happen in the crossing.  If you do that, all you need is the datapathonly to constraint the grey code interfaces - and you do not need the datapthonly constraint to not be overridden by set_clock_groups.


One final thought here.  The datapthonly constraint is extremely expensive computationally speaking in STA.  It is non-standard SDC - and when applied broadly such as between entire clock domains - it creates large fanin and fanout cones of logic that have to be traversed to apply the constraint.  This will really slow down the implementation runs and take a lot of memory.  It is best to use them very judiciously - only on the actual sync chains with a specfici -from and -to on the individual sync instances.  And then use report_clock_interaction and report_cdc (coming new with 2014.3) with good methodology checks and DRCs to make sure there are no undesired clock crossings.  

Greg Daughtry
Vivado Product Marketing Director, Xilinx, Inc.