Vivado XDC Constraints Cheatsheet
The dozen constraint lines that cover 95% of Artix/Kintex/Zynq designs.
Clocks
# Primary clock on a pin: 100 MHz
create_clock -period 10.000 -name sys_clk [get_ports clk]
# Clock from a transceiver / GT refclk
create_clock -period 6.400 -name gt_refclk [get_ports gt_refclk_p]
# Generated clocks from MMCM/PLL are derived AUTOMATICALLY - don't redeclare.
# Only constrain manually if you divide with fabric logic (avoid doing that):
create_generated_clock -name slow_clk -source [get_pins div_reg/C] \
-divide_by 2 [get_pins div_reg/Q]
# Two asynchronous clock groups (tells timing to ignore paths between them -
# you MUST have proper CDC logic on every crossing)
set_clock_groups -asynchronous -group [get_clocks sys_clk] \
-group [get_clocks -include_generated_clocks gt_refclk]
I/O pins
set_property PACKAGE_PIN E3 [get_ports clk]
set_property IOSTANDARD LVCMOS33 [get_ports clk]
# Vectors
set_property PACKAGE_PIN {A1 B2 C3 D4} [get_ports {led[0] led[1] led[2] led[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led[*]}]
# Pullup / drive / slew when you need them
set_property PULLUP true [get_ports uart_rx]
set_property DRIVE 8 [get_ports sda]
set_property SLEW SLOW [get_ports sda]
I/O timing (only for real synchronous interfaces)
# Input arrives 2.0-4.5 ns after the external device's clock edge
set_input_delay -clock sys_clk -min 2.0 [get_ports din]
set_input_delay -clock sys_clk -max 4.5 [get_ports din]
# Output must be stable 1.5 ns before / hold 0.5 ns after the edge at the pin
set_output_delay -clock sys_clk -max 1.5 [get_ports dout]
set_output_delay -clock sys_clk -min -0.5 [get_ports dout]
Path exceptions (use sparingly, justify every one)
# Static configuration register read by another domain
set_false_path -from [get_cells cfg_reg_reg[*]]
# CDC with a 2-flop synchronizer: bound the latency instead of false-pathing
set_max_delay -datapath_only 8.0 \
-from [get_cells src_reg_reg] -to [get_cells sync_ff0_reg]
# Multicycle: result consumed every 2nd cycle (setup 2, hold 1)
set_multicycle_path -setup 2 -from [get_cells mult_a_reg[*]] \
-to [get_cells mult_p_reg[*]]
set_multicycle_path -hold 1 -from [get_cells mult_a_reg[*]] \
-to [get_cells mult_p_reg[*]]
Bitstream / config essentials
set_property CFGBVS VCCO [current_design]
set_property CONFIG_VOLTAGE 3.3 [current_design]
set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design]
set_property BITSTREAM.CONFIG.CONFIGRATE 33 [current_design]
Debugging constraints
report_clocks
report_timing_summary -delay_type min_max
report_timing -from [get_clocks a] -to [get_clocks b] -max_paths 5
check_timing # unconstrained endpoints
report_cdc # clock-domain-crossing audit
report_exceptions -ignored # constraints that match nothing!
Rules of thumb
- Every clock pin gets a
create_clock; everything else derives from it. get_portsin XDC match ports,get_cellsmatch instances — a registerqbecomes cellq_reg.- A constraint that matches zero objects is silently useless: check
report_exceptions -ignoredand the synthesis log's critical warnings. - Never
set_false_pathbetween async clocks wholesale to "fix" timing; useset_clock_groupsonce and design real CDC.