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

ASYNC_REG - about 1 in 10 builds, I get a timing warning  on an AYNC_REG path that has a CDC sync on it.

ASYNC_REG. golly 358 hits...


About 1 in 10 builds, I get a timing warning  on a path that has a CDC sync on it. 

nearest reference to my question  : this sort of warning. 

Solved: Understanding ASYNC_REG attribute - Community Forums (

I use TCL console and can verify that the netlist thinks 'YES' ASYNC_REG = true for those flip flops. 

in xdc timing I have : 

set sync_inst [get_cells -hier -filter {(ORIG_REF_NAME == asyncX) || (REF_NAME == asyncX)}]
set_property ASYNC_REG TRUE [get_cells [join $sync_inst "/FDRE_inst1a "]]
set_property ASYNC_REG TRUE [get_cells [join $sync_inst "/FDRE_inst1b "]]

and I have verified during synth, these properties are assigned. 

In a PASSED design, no warning, I can using TCL, verify that yes, indeed the timing is terrible and the tool has ignored the path, ASYNC_REG property is set in Cell Properties for those FDREs to TRUE
All three FDREs are placed in the same LOC SLICE.

I will snapshot the result next time this happens and go digging through the implemented design with the error.


0 Kudos
5 Replies
Registered: ‎01-22-2015


In short, you need to write a timing exception on the path coming into the synchronizer.

For discussion, consider the following example of a 2-flip-flop synchronizer.


  1. You are correct that both registers of the synchronizer (meta_2ff_reg and OUT_2FF_reg) need to have their property ASYNC_REG=TRUE.  These are the most important constraints since they ensure that the synchronizer actually does fight metastability
  2. However, timing analysis should still complain about the path coming into the synchronizer.  That is, this path is the actual crossing between the two clock domains (CLK1 and CLK2 in my example).  So, if the clocks associated with the two domains are asynchronous then this path will fail timing analysis.
  3. So, to satisfy timing analysis, we usually write a "set_max_delay -datapath_only" constraint, which looks like the following for my example circuit.  In this constraint, X.X is usually chosen to be the smaller period (ns) of the two clocks.
    set_max_delay –datapath_only -from [get_cells SIG1_reg] –to [get_cells meta_2ff_reg] X.X​
  4. Note how the synchronizer in my example is fed directly from a register.  Make sure your synchronizer is not fed from combinational logic (eg. LUTs) since this can break the synchronizer.
  5. Finally, after opening our implemented design, select "Reports > Timing > Report CDC..." from the Vivado main menus to check that all CDCs in your design have been handled properly.

Finally, you may be wondering why the input to your synchronizer is sometimes passing timing analysis.  Vivado assumes all clocks in your design are synchronous - unless you say otherwise.  So, what probably happened, was that Vivado assumed your two clocks were synchronous (when you know they are not) and Vivado sometimes found a way to make a direct crossing of data between the two clock domains.


Tags (1)
Registered: ‎02-15-2014

Hi Mark

thanks for much for your post and info. and the set_max_delay suggestions.

I had a good look at many of those cdc synchronizer paths this evening, I think you are right,  It would appear that Vivado is timing them up without difficulty ! It's only running at 200 MHz... (Ultrascale+). Build at 350MHz and it still times up those dont care paths OK .... 

I also, in the VHDL file for the synchronizer have : 

attribute ASYNC_REG : string;
attribute ASYNC_REG of signal_in : signal is "TRUE";

signal_in is the input from elsewhere. My understanding was that I needed the FDREs ASYNC_TRUE, and I also needed to apply ASYNC _REG to the signalk

But hang on ! NOOO. how can ASYNC_REG be applied to a signal, and sure enough I can find nothing in the implentnation netlists , properties etc that would suggest that the pin or net  has any such marker. But this is suggested in the Vivado doco . Maybe I am doing it wrong, and Vivado is just ignoring me. I will look a little harder through the warnings and info messages...

I will snapshot a failed -timing build, figure this out, and get back to you. In the meantime, I will look at the use of the  set_max_delay directive.






0 Kudos
Registered: ‎01-22-2015


My understanding was that I needed the FDREs ASYNC_TRUE, and I also needed to apply ASYNC _REG to the signal

ASYNC_REG is a property of a register (FDRE).  The VHDL signal called signal_in that you use in your VHDL attribute statement will become a register called signal_in_reg if signal_in is assigned a value in a VHDL clocked process.  Vivado understands that the VHDL attribute statement is a request to set ASYNC_REG=TRUE on the register associated with a signal - and not on the signal itself.

A few years ago, the VHDL attribute statements we not reliably setting ASYNC_REG=TRUE.  The workaround was to write a Tcl command like the following and place it in the Vivado .xdc constraints file.  This Tcl command can still be used instead of the VHDL attribute statement to set ASYNC_REG=TRUE

set_property ASYNC_REG TRUE [get_cells signal_in_reg]


0 Kudos
Registered: ‎01-23-2009

I think you are confused as to what the ASYNC_REG property does...

The ASYNC_REG does not affect static timing - it is a placement and optimization (and simulation) constraint, not a timing constraint.

The ASYNC_REG does the following things:

  • Sets the flip-flop as DONT_TOUCH so that the flip-flop can't be duplicated, retimed, merged into SRL or absorbed into another block (like the DSP or BRAM)
    • These are all required for a flip-flop acting as part of a metastability reduction chain
  • Annotates the simulation so that the flip-flop will not go X when the setup/hold is violated
    • Metastability flip-flops are expected to fail setup/hold checks - they are clocked asynchronously with respect to the data changing on the source domain
    • Normal flip-flops will go to X under this condition, which would likely cause the simulation to fail (as X's propagate aggressively in Verilog/VHDL)
  • (most importantly) Ensures that multiple flip-flops that are connected Q -> D that have the ASYNC_REG property on them will be placed "as close as possible" - in the same CLB if possible
    • This is required to ensure that the route between them is not long - it needs to be short - way shorter than what would be allowed by the static timing requirement on this path (which would be one destination clock period) in order to allow time for metastability resolution

The ASYNC_REG is supposed to be placed only on the flip-flops of the metastability chain - the N (2 or 3 or more) flip-flops on the destination clock domain that are connected Q->D. These flip-flops are there to reduce the probability of a metastable event (which will occur on the first flip-flop in the chain) from propagating to the output of the chain and causing a system failure. 

Since all these flip-flops are connected Q->D, the timing paths between them are trivially short. So if these paths are failing timing you have a very big problem!

The ASYNC_REG property 

  • Should not be applied to the last flip-flop on the source domain
  • Has no effect on timing of the path between the last flip-flop on the source domain and the first flip-flop on the destination domain

So your original post is confusing - it seems like you are expecting the ASYNC_REG property to somehow affect timing...

For the path from the last flip-flop on the source domain to the first flip-flop on the destination domain you need a timing exception. Since you have instantiated a valid clock domain crossing circuit (CDCC - the back-to back flip-flops with the ASYNC_REG property), then it is legal to put a timing exception on the clock domain crossing path. (assuming the CDCC is valid for this crossing - the back-to-back FFs is only sufficient for a single bit slow changing signal). For these paths (the actual clock domain crossing path when a valid CDCC exists) the normal exceptions are either a set_false_path, but it is better to use the "set_max_delay -datapath_only". The value of the set_max_delay -datapath_only depends on what is being crossed, but the safest is the smaller of the period of the source clock and the destination clock (the min of the two periods). It is this exception that changes the behavior of static timing - not the ASYNC_REG property.


Tags (1)
Registered: ‎02-15-2014

Hi Avrum

thank you very much for the detailed reply. Yes, I was mostly misunderstanding the scope of ASYNC_REG.  

I applied set_max_delay  constraints and I verified application with TCL : report_exceptions

with thanks


0 Kudos