Commit f7f3caf9 authored by Adrian Byszuk's avatar Adrian Byszuk

Add scoped XDC constraints for CDC modules

These XDC files can be used by Vivado projects to automatically infer
proper timing constraints for CDC paths.
parent 93195673
......@@ -44,6 +44,13 @@ In [modules/common](modules/common) there are general purpose cores:
contains a complex handling for asynchronous signals (crossing clock
domains, deglitcher, edge detection, pulse extension...)
* CDC modules come also with specific timing contraints in [modules/common/xdc](modules/common/xdc).
These constraints can be used in Vivado projects (so-called "module-bound" constraints)
to automatically derive proper timing constraints for CDC paths in each module.
To use it, add specific constraint file to your project and set `SCOPED_TO_REF`
property in GUI or your TCL file.
(e.g. add `gc_sync.xdc` if you use `gc_sync.vhd` and set `SCOPED_TO_REF=gc_sync`)
* For reset generation, you can use [gc_reset](modules/common/gc_reset.vhd)
which generate synchronous resets once all the PLL lock signals are set.
The module [gc_reset_multi_aasd](modules/common/gc_reset_multi_aasd.vhd)
......
# the "-quiet" option is added for the use case where this module is added to
# the project, but not instatiated (e.g. because of generic settings)
# in that case Vivado would throw critical warnings during P&$
set_false_path -quiet -to [get_pins -hierarchical *rst_chains_reg[*]/CLR]
# Timing constrains for basic 1 bit synchroniser.
# In many cases this could be solved with simple set_false_path, but in some
# cases this module is used in more time-critical applications, eg. inferred FIFO.
# In that case it makes sense to apply some max_delay constraint.
#
# You can always override any of these max_delay constraints in your global XDC
# with set_false_path because it has the highest priority.
set clk [get_clocks -of_objects [get_ports clk_i]]
set clk_period [get_property PERIOD $clk]
# ATTENTION: we can't use "all_fanin" to find the source register because
# apparently this command doesn't traverse outside of scoped reference (even with -flat switch)
# This method won't work properly if there's a combinational path between a source and target FF;
# but in a proper CDC circuit it's forbidded to have logic between FFs anyway!
set dst_ff [get_pins sync_*.sync0_*/D]
set src_ff [get_cells -of_objects [get_pins -filter {IS_LEAF && DIRECTION == OUT} -of_objects [get_nets -segments -of_objects $dst_ff]]]
# We use -quiet switch, because otherwise Vivado will throw critical warning
# if module is not used in the project (e.g. due to generics)
set_max_delay $clk_period -quiet -datapath_only -from $src_ff -to $dst_ff
# Timing constrains for basic bit vector synchroniser.
#
# This is similar to gc_sync, but vector synchronisation is usually more tricky.
# Usually you really want to limit bus skew and delay to one clock cycle.
#
# You can always override any of these max_delay constraints in your global XDC
# with set_false_path because it has the highest priority.
set clk [get_clocks -of_objects [get_ports clk_i]]
set clk_period [get_property PERIOD $clk]
# ATTENTION: we can't use "all_fanin" to find the source register because
# apparently this command doesn't traverse outside of scoped reference (even with -flat switch)
# This method won't work properly if there's a combinational path between a source and target FF;
# but in a proper CDC circuit it's forbidded to have logic between FFs anyway!
set dst_ff [get_pins sync0_*[*]/D]
set src_ff [get_cells -of_objects [get_pins -filter {IS_LEAF && DIRECTION == OUT} -of_objects [get_nets -segments -of_objects $dst_ff]]]
# We use -quiet switch, because otherwise Vivado will throw critical warning
# if module is not used in the project (e.g. due to generics)
set_max_delay $clk_period -quiet -datapath_only -from $src_ff -to $dst_ff
set_bus_skew $clk_period -quiet -from $src_ff -to $dst_ff
# Timing constrains for read word synchronizer.
# Flag handskaking is done by pulse synchroniser submodule which should have its
# own constraint file and thus isn't covered here
set src_clk [get_clocks -of_objects [get_ports clk_in_i]]
set dst_clk [get_clocks -of_objects [get_ports clk_out_i]]
set src_clk_period [get_property PERIOD $src_clk]
set dst_clk_period [get_property PERIOD $dst_clk]
set skew_value [expr {(($src_clk_period < $dst_clk_period) ? $src_clk_period : $dst_clk_period)}]
set src_ff [get_pins gc_sync_word_data*[*]/C]
set dst_ff [get_pins data_out*[*]/D]
# We use -quiet switch, because otherwise Vivado will throw critical warning
# if module is not used in the project (e.g. due to generics)
set_max_delay $skew_value -quiet -datapath_only -from $src_ff -to $dst_ff
set_bus_skew $skew_value -quiet -from $src_ff -to $dst_ff
# Timing constrains for write word synchronizer.
# Flag handskaking is done by pulse synchroniser submodule which should have its
# own constraint file and thus isn't covered here
set src_clk [get_clocks -of_objects [get_ports clk_in_i]]
set dst_clk [get_clocks -of_objects [get_ports clk_out_i]]
set src_clk_period [get_property PERIOD $src_clk]
set dst_clk_period [get_property PERIOD $dst_clk]
set skew_value [expr {(($src_clk_period < $dst_clk_period) ? $src_clk_period : $dst_clk_period)}]
set src_ff [get_pins gc_sync_word_data*[*]/C]
set dst_ff [get_pins dat_out*[*]/D]
# We use -quiet switch, because otherwise Vivado will throw critical warning
# if module is not used in the project (e.g. due to generics)
set_max_delay $skew_value -quiet -datapath_only -from $src_ff -to $dst_ff
set_bus_skew $skew_value -quiet -from $src_ff -to $dst_ff
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment