Showing results for 
Show  only  | Search instead for 
Did you mean: 
Registered: ‎08-02-2009

Timing Failure - MCMM with multiple outputs



I have been using ISE for a 7 series design no problem and am trying to upgrade to vivado and rewriting constraints etc.


I have a master input 40MHz clock going into a MCMM and and using output 0 to get 128MHz (0 allows none integer multiplication). The only other output is no 1 at 80MHz.


Clock domain crossing is done safely between the two clocks but I think timing is failing becase I need to tell the tools that the relationship between the clocks if not important.


In xdc file I used.....

create_clock -name mclk_1 -period 25.000 [get_ports mclk_1]

for the master input.


I tried all sorts to get the set_false_path command to work with no sucess.


What is the best way of doing this?


If I try to use get_clocks on the MCMM outputs I get a warining saying that the I need to use create_clock on the signals first. Using create clock looks to kind of work but then brings up other warinings.


I tried create_generated_clock but I couldnt use it for a none integer multiplier?


Any ideas.



0 Kudos
5 Replies
Registered: ‎01-16-2013



I will recommend you to use asynchronous clock groups to avoid analysis.

Refer (Page # 69)




0 Kudos
Registered: ‎01-23-2009


As you figured out, due to the relationships between the periods of the clocks, it is not possible to move data synchronously from one clock domain to the other. When this occurs, and you do need to move data between the two domains, you need to put in a clock crossing circuit.

The whole point of the clock crossing circuit is to have the data transfer be done in an asynchronous manner - specifically to alleviate the timing requirement on the path that is crossing the domain. The tool has to be told that the path between the domains is not to be handled synchronously - you need a timing exception on that path.

Depending on the type of clock crossing circuit you are using, there are different exceptions that you can use, and different ways to apply them.

First, lets start with the fact that you (normally) don't need to mess with the clocks themselves. Doing a create_clock on the pin that brings in your 40MHz clock is correct. When the clock goes through the MMCM, the Vivado will automatically create generated clocks on the outputs of the MMCM. These clocks can be seen in the "report_clocks" command.

Now for the clock crossing. There are three types of exceptions that can be used

  • set_clock_groups
  • set_false_path
  • set_max_delay -datapath_only

Then, there multiple ways of applying these constraints. The are different combinations of

  • applying the constraints directly to the clock crossing paths
  • applying the constraints to the clocks



Lets start with set_clock_groups. This tells the tools that all paths between the two clock domains are false (in both directions). That means that no matter what else you do these paths will not be timed. The set_clock_groups can only be applied to the clocks.

However, since the clocks are automatically generated, you can't reliably know the names of the clocks. You can look them up in the report_clocks command, but the names are auto generated, so they may change. Instead, you want to get the clocks using a pin or net that carries the clock.

One way to do this is to use the pins of the clock generator. If you instantiated the MMCM directly, then you can use the CLKOUT0 and CLKOUT1 pins of the MMCM. If you use the IP catalog, you can use the top level pins of the created core.

set_clock_groups -group [get_clocks -of_objects [get_pins <MMCM_instance_name>/CLKOUT0]] \
                 -group [get_clocks -of_objects [get_pins <MMCM_instance_name>/CLKOUT]]


The MMCM_instance_name is the hierarchical name of the MMCM instance.

For an IP generated clocking core, use the full hierarchical name to the instance of the generated core.

Another good choice is to use the net at the top level of your hierarchy that carries the clocks. For example if, in your RTL the 128MHz clock is called clk128 and the other one clk80, then you can use

set_clock_groups -group [get_clocks -of_objects [get_nets clk128 ]] \
                 -group [get_clocks -of_objects [get_nets clk80]]



For the set_false_path, you have two choices - apply them to the clocks or to the crossing path themselves.

When applied to the clock, they are done almost exactly the same as I showed with the set_clock_groups - again, apply them to the clocks carried by a net or pin

set_false path -from [get_clocks -of_objects [get_nets clk128 ]] \
               -to [get_clocks -of_objects [get_nets clk80]]

This is almost the same as the set_clock_groups, but it only goes one way. To have the same effect as the set_clock_groups use

set_false path -to [get_clocks -of_objects [get_nets clk128 ]] \
               -from [get_clocks -of_objects [get_nets clk80]]

As well (to break the relationship in both directions).

The other way of doing it is to apply it to the paths. Here, you need to identify the startpoint(s) and endpoint(s) of the static timing paths to which you want to apply the exception. These real startpoint is the CLK input pins of the flip-flop(s) that is/are the start of the path - in this case, the last FFs on the source domain, and the real endpoints is/are the D input pins of the flip-flops capturing the data (in this case the first flip-flops on the destination domain).

However, the tool allows you to just use the cell instead of the pin, which is a bit easier.

set_false_path -from [get_cells <hierarchical_name_to_startpoints>] \
               -to [get_cells <hierarchical_name_to_endpoints>]

Applying the constraints directly to the path is generally safer than doing it to the clocks. For example, if you inadvertently had a path between the two domains where you forgot to use a clock crossing circuit, the clock based constraints would disable the timing on it, thus masking your problem...


set_max_delay -datapath_only

The other constraint is set_max_delay -datapath_only

Here, instead of declaring the paths false, you give them a requirement in terms of nanoseconds for the path. Some clock crossing circuits need this constraint to prevent excessive skew on the routing of the nets from breaking the clock crosser. Generally, you want to constrain the path to less than either the source or destination clock (depending on the type of clock crosser), or the minimum of the two. Lets say we do the latter - the requirement would be 8ns.

Again, set_max_delay -datapath_only can be aplied to the clock or the path

set_max_delay  8 -datapath_only -from [get_clocks -of_objects [get_nets clk128 ]] \
                                -to [get_clocks -of_objects [get_nets clk80]]


set_max_delay 8 -datapath_only  -from [get_cells <hierarchical_name_to_startpoints>]  \
                                -to [get_cells <hierarchical_name_to_endpoints>]

Applying the constraint to the clocks, again, has the potential to mask problems with paths that don't have clock crossing circuits.

In general I prefer (and highly recommend) the last one - the set_max_delay -datapath_only command on the actual path. I hate constraints between the clocks, since they can mask errors, and most clock crossers need skew control, so I prefer the set_max_delay -datapath_only. For some clock crossing circuits (like the simple one bit slow changing signal clock crosser) this overconstrains the path (since it could be declared false), but the cost of this is usually very small (in terms of placement restrictions), and I think is worth it.

It is also important to note that there is inherent priority in exceptions. The set_clock_group and set_false_path commands have higher priority than the set_max_delay -datapath_only. So you can't do both. One common mistake is that the designer uses the set_clock_groups between the clocks, and then the set_max_delay on the path. This doesn't work, since the path will be covered by both exceptions, and the set_clock_groups will win - the set_max_delay -datapath_only will be ignored.


Registered: ‎08-26-2014

Avrum, that´s an amazing reply. Thank you for sharing the knowledge.
0 Kudos
Registered: ‎10-29-2015



Kudos to you for such a knowledgable post. From your post can I conclude the following:


If I see a failed timing path between a Source and Destination clock where the destination clock is derived from the source clock, then before setting a false path I first need to see whether the designer has implemented a CDC synchronizer circuit like a staggered flip flop or a FIFO. Only after being sure, then I can set the path as false. To do that, analysis of RTL and schematic is necessary.


For example, I am getting a hold violation in the timing report where source clock is clkout0 and destination clock is sgmii_clk_f. In report_clocks command output I see this:


Generated Clock   : sgmii_port_4/U0/sgmii_logic/clock_generation/sgmii_clk_f
Master Source     : sgmii_port_0/U0/core_clocking_i/mmcm_adv_inst/CLKOUT0
Master Clock      : clkout0
Divide By         : 2
Generated Sources : {sgmii_port_4/U0/sgmii_logic/clock_generation/sgmii_clk_f_reg/Q}


So, for a generated clock by MMCM which has a frequency and phase relation ship with the source clock, can I set a false path at all? Or, should I first check analyze in the failed timing path the designer has included a CDC synchronizing circuit?


Thanks for your valuable inputs.




0 Kudos
Registered: ‎01-23-2009

It's very hard to say from the information you have posted. While the sgmii_clk_f is derived from the MMCM output clock, its not clear from this how it was derived - for example is this generating the forwarded SGMII clock that is going out of the FPGA? If so, then this path is not false - it may be badly constrained, but it's not false.


You need to understand the path, and determine what the intent of this path is. Yes, in some you can and should declare paths false even when they are between closely related clocks, if the structure of the design warrants that - it's not particularly common, but it does happen. False paths can even occur on the same clock...


But, you have to understand the consequences. If you declare a path false, then the tools will simply stop complaining about that path. If that set_false_path constraint is incorrect, you will ultimately get a system that does not work reliably in the lab or in the field. So you must be extra careful with all timing exceptions. Unlike other kinds of bugs, there is no place where they are likely to be caught before you get to hardware (as contrasted to, say, an RTL bug, which can/should be caught by verification using RTL simulation).


And, again, I generally prefer set_max_delay -datapath_only constraints to set_false_path constraints - even on individual paths; most CDC circuits require some limit on skew, and hence should have some constraint covering the path.