Apparently, the proper way to constrain some CDCs (Both AsyncResetSynchronizer and transfer via GreyCounters) should use a max_delay constraint and not a false path.
Avrum is an
active fellow on the Xilinx forums whenever clock domain crossing (CDC) issues
crop up. By default, and in contrast to ISE, Vivado assumes all clocks are
related. Thus, even with a proper synchronization circuit, Vivado needs to be
explicitly told not to try and time these paths. Avrum does an excellent job of
explaining the correct constraint relaxation to use and why not use what I call
the "ostrich method" of just setting the clocks as asynchronous using
set_clock_groups -asynchronous or set_false_path between all path between
the clocks. This certainly is the easy way out but means you'll clobber all
other more delicate constraints and could mask a real clock crossing problem
where you've forgotten to synchronize. I've tried to collect his posts here for
reference:
post - constraints on a reset synchronizer and the one of the few places I've seen mentioned using a set_max_delay on a single-bit synchronizer chain
post and post - clever tcl commands to use to find module and register instances
post - more reset syncrhonization with a nice slide attached
post - long discussion about the difference between single bit and bus synchronization
post - long discussion of different types of CDC exceptions and why set_max_delay is almost always preferred
post - not quite clock domain crossing but a clear explanation of IODELAYCTRL instantiation
post - discussion of mean time before failure (MTBF) for synchronizer chain and references new Vivado tcl command report_synchronizer_mtbf for Ultrascale parts
post - subtleties of distributed RAM which "is an odd beast - it is partly a synchronous element (the write) and partly a combinatorial element (the read)."
Apparently, the proper way to constrain some CDCs (Both AsyncResetSynchronizer and transfer via GreyCounters) should use a max_delay constraint and not a false path.
https://forums.xilinx.com/t5/Vivado-TCL-Community/How-to-set-timing-constraint-in-this-case/m-p/510771/highlight/true#M2049
How would one implement this?
A good entry to the rabbit hole: copied from http://www.colmryan.org/avrums-clock-domain-crossing-widsom.html#avrums-clock-domain-crossing-widsom :
Avrum is an active fellow on the Xilinx forums whenever clock domain crossing (CDC) issues crop up. By default, and in contrast to ISE, Vivado assumes all clocks are related. Thus, even with a proper synchronization circuit, Vivado needs to be explicitly told not to try and time these paths. Avrum does an excellent job of explaining the correct constraint relaxation to use and why not use what I call the "ostrich method" of just setting the clocks as asynchronous using
set_clock_groups -asynchronous
orset_false_path
between all path between the clocks. This certainly is the easy way out but means you'll clobber all other more delicate constraints and could mask a real clock crossing problem where you've forgotten to synchronize. I've tried to collect his posts here for reference:set_max_delay
on a single-bit synchronizer chainset_max_delay
is almost always preferredreport_synchronizer_mtbf
for Ultrascale parts