bootstrap website templates

© Copyright 2018 Verien Design Group, LLC  Concord, MA All Rights Reserved

XDC (SDC) Reference Guide

This is a reference guide for Xilinx Design Constraints format, used in Xilinx FPGA and SOC designs.  XDC is an offshoot from Synopsys Design Constraint (SDC) format, with Xilinx customized syntax.  This list is meant to be a searchable reference containing commonly used properties that are found in most designs, as well as some of the trickier timing constraints.  This list is intended to be added to over time.  If you have  a suggestion of something to add, please click at the email link at the bottom and send it along.

Constraint Order

The order of the constraints actually matters in the file.  The reason is that the contents in the file are actually TCL commands.  Below is the recommended order from Xilinx:

  • Primary clocks 
  • Virtual clocks
  • Generated clocks
  • Clock Groups
  • Bus Skew constraints
  • Input and output delay constraints
  • False Paths
  • Max Delay / Min Delay
  • Multicycle Paths
  • Case Analysis
  • Disable Timing
  • located anywhere in the file, preferably before or after the timing constraints or stored in a separate constraint file

Physical Constraints

Set the Configuration Bank Voltage

set_property CFGBVS VCCO [current_design]
set_property CONFIG_VOLTAGE 3.3 [current_design] 

On Series 7 devices, the CFGBVS property must be set for either VCCO or GND to indicate configuration bank voltage.  It is set for VCCO if bank 0 is connected to 3.3v or 2.5v, and GND if bank 0 is set for 1.8v or 1.5v.  The CFGBVS pin is also set to the bank 0 voltage on the board.  The CONFIG_VOLTAGE property is set to the actual voltage: 3.3, 2.5, 1.8 or 1.5.  

Pin Definition

set_property PACKAGE_PIN T10 [get_ports I2C_SDA]  
set_property PACKAGE_PIN U12 [get_ports I2C_SCL]

I/O Standard

This shows bit 0 of a vector being set to LVCMOS 3.3v:
 set_property IOSTANDARD LVCMOS33 [get_ports {LOOPBACK_EN[0]}]

 Another example set a clock to LVDS 2.5v standard.  This doesn't need to be done if the LVDS buffer is instantiated:
set_property IOSTANDARD LVDS_25 [get_ports CLK100M_P]

Other common standards: LVTTL, LVCMOS18 (for 1.8v), LVCMOS25.  The full list is in the SelectIO Resources User Guide.

Output Slew Rate

set_property SLEW FAST [get_ports SCLK]

Note that the default is slow slew rate.

I/O Direction

set_property PIO_DIRECTION OUTPUT [get_ports CS_L]

Designate a Flip-Flop to be in the I/O Ring

set_property IOB TRUE [get_ports ADC_SDIO]

Note that I've found it helps to apply a "DONT_TOUCH" attribute to the signal to keep it from being renamed in synthesis if the IOB is an internal signal.

Set the Output Drive Current

set_property DRIVE 8 [get_ports PULSE_DAC_SCLK]

The above sets the output for 8 mA drive.  The allowed values vary for different FPGA families and with the I/O standard.  Common values are 4, 8, 12, 16 and 24 mA.  

Add a Pullup or Pulldown to the I/O Pin

set_property PULLDOWN true [get_ports {GPIO[0]}]

The above enables the pulldown on bit 0 of vector GPIO.  The keyword PULLUP can also be used.


set_property LOC IDELAYCTRL_X1Y2 [get_cells idelayctrl_c1234]

When using multiple IDELAYCTRL modules, the locations often have to be manually specified using the above syntax.  In the above example, IDELAYCTRL_X1Y2 is a specific idelayctrl module on the die, and idelayctrl_c1234 corresponds to the label on the instantiation in the HDL.

Enable the Differential Terminator

set_property DIFF_TERM TRUE [get_ports ADC1_DCO_P]

For LVDS and other standards, it's useful and electrically beneficial to use the 100 ohm terminator in the FPGA input.  The above syntax enables this. It only needs to be specified on one of the two signals in the pair.  If instantiating the LVDS buffer, it can also be done in the instantiation.

Set the MMCM Location

set_property LOC MMCME2_ADV_X1Y3 [get_cells \ clk64m_dcm_c/U0/mmcm_adv_inst]

Sometimes it's necessary to locate the MMCM.  This can be accomplished with the above syntax.  MMCME2_ADV_X1Y3 is the location, and mmcm_adv_inst is the instance with included path.

Locating Logic

set_property LOC SLICE_X35Y24 [get_cells {edge_recov_inst_c2/oct0_s1_reg}]

The above locates a register oct0_s1_reg at location SLICE_X35Y24.  Note that the instance name is the post synthesis name, so this will be ignored in synthesis and used during implementation.

Prohibit the Tools from Placing Logic on a Pin

set_property PROHIBIT true [get_sites R15]

The above prohibits the placer from using pin R15.  When you set the type of configuration, the tool can be configured to prohibit the configuration pins so that they are assigned as regular I/O using the above syntax.

Using Wildcards

set_property IOSTANDARD LVCMOS33 [get_ports {USB_DATA[*]}]

The above example sets all of the USB_DATA pins to LVCMOS33.

Timing Constraints

Modern FPGAs use static timing analysis to place and route the design, to report the estimated timing prior to placement and final timing after routing.  The static timing analyzer will attempt to meet the timing defined in the constraints file.  An understanding of static timing analysis is necessary to really understand how timing constraints are defined.  For a brief explanation, click here for my technote on static timing analysis.

The Basic Clock Constraint

create_clock -name clk20m -period 50.000 [get_ports CLK20M_IN]

Definitions for clocks is necessary for correct synthesis and implementation.  The tools are good a propagating clocks, i.e. adding the definitions of clock outputs from MMCMs and PLLs. But even so, there must be a primary clock somewhere coming into the chip; the input to the MMCM must be a clock and must be defined. The above syntax can be used to define a 20 MHz clock on the port CLK20M_IN port and name it "clk20m". Note that you can also specify the duty cycle using the -waveform syntax.

Renaming Propagated Clocks

create_generated_clock -name clk100m \
[get_pins clk_dcm_c/U0/mmcm_adv_inst/CLKOUT0]

It can be handy to rename the auto-generated clocks from the MMCM and PLL outputs.  The above syntax creates a clock named clk100m and ties it to the CLKOUT0 pin of the mmcm in the above path.  Note that it is proper to define the clock from the MMCM or PLL output pin, and not from the clock buffer drives the clock net.  Note that it can be a challenge to figure out the path and name of the MMCM output pin.  The best way I've found is to open up the netlist in Vivado, drill down the MMCM and draw a schematic.  Keep in mind that it is attached to one of the clock output pins from the MMCM and not the net.

You can also use TCL scripts to find it.  get_cells -hierarchical *mmcm* will find all cells with the name mmcm.  Once you know the one you want, you can generate a schematic with: show_schematic [get_cells mci_dcm_c/inst/mmcm_adv_inst] . Then you can simply click on the MMCM output pins to expand them and find the one that you're looking for.

Input Setup Timing

set_input_delay -clock [get_clocks clk] -max 2.00 [get_ports {FX3_DATA[*]}]

Input setup timing is really the clock to Q of the driving device - not the setup time to the FPGA as one would think. So  if the period is 10 ns and the clock to Q of the device driving the FPGA is 2 ns providing a setup to the FPGA of 8 ns, then the setup would be specified with a -max as shown above.  To check input timing, you can use: report_timing -from [get_ports DIN] -max_paths 20.

Input Hold Timing

set_input_delay -clock [get_clocks clk] -min 2.00 [get_ports {FX3_DATA[*]}]

Input hold timing is the hold timing of the driving device, 2 ns in the example above.

Output Delay Timing

set_output_delay -clock CLK100M 4 [get_ports [get_ports {FX3_ADDR[*]}]

Output timing is really the setup to the next stage, so if you  subtract the reported timing from the clock period you will have the actual delay. For example, if you have a 10 ns period and the setup time in the receiving device is 4 ns, you would use a set_output_delay of 4 ns and the tools will optimize for a 10 - 4 = 6 ns output delay. To check output timing, you can use: report_timing -to [all_outputs] -max_paths 100 .

Ignoring False Paths

set_false_path -from [get_clocks RXUSRCLK2] -to [get_clocks TXUSRCLK2]
set_false_path -from [get_clocks TXUSRCLK2] -to [get_clocks RXUSRCLK2]

The Xilinx Vivado tool will attempt to analyze all paths in the design by default, and this includes analzying paths between asynchronous clock domains.  If the logic between clock domains is properly synchronized through the use of dual rank synchronizers or dual clock domain FIFOs, then these domains can be ignored in timing analysis.  The syntax above can be used to ignore paths between RXUSRCLK2 to TXUSRCLK2.   

If one uses an asychronous reset, this can be ignored with the following syntax:

set_false_path -through [get_nets RESET_L]

Defining Multicycle Paths

set_multicycle_path -from [get_pins gpif_interface_c/fx3_reg/C] \
-to [get_ports {FX3_DATA[*]}] 2

By default, the static timing analyzer analyzes paths within 1 cycle time of the defined clock.  But sometimes you have a path which takes longer than one clock cycle, and you've designed it to sample the output after multiple clocks.  For example, you have an arithmetic operation that takes 12 ns and you have a 100 MHz clock. The output won't be available in time for the next clock edge, but you use a clock enable and register the output after two clock cycles.  By design, this will work, but there needs to be some method to tell the tools that this operation is taking two clock cycles.  This is accomplished with a multicycle path using the syntax above.  The path is defined using "from" "to" syntax.  In the above example, the starting point is the clock pin on a register and the ending points are the ports for a data bus.


Tech Notes
IP Cores


Phone: 978-405-3102 

© Copyright 2019 Verien Design Group, LLC Concord, MA All Rights Reserved