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