Constraints should be broken up into multiple files based on the type of constraint. For Dynamic Function eXchange, Xilinx recommends breaking up the design constraints into the three following types:
- Constraints (physical or timing) that reference only static objects (cell/pins/nets/ports), and do not reference any objects within an RP. These are global constraints and are applied to static synthesis, or at implementation of the initial configuration. It is not recommended to reapply these constraints for subsequent configurations where static is imported, as these constraints should already exist within the static DCP and reapplying them can cause unintended constraint interactions.
- These are timing constraints (such as
set_false_path) that reference objects in both static and the RP. Write these constraints referencing the RP pin object, and not objects internal to the RM. For example, take the following two constraints:
set_false_path -from [get_pins static_reset/C] -through [get_pins rp_inst/rst] set_false_path -from [get_pins static_reset/C] -to [get_pins rp_inst/*foo*/D]
The first constraint is preferred, as this constraint will not be lost when the RMs are converted to a black box after the initial configuration. Even when the RMs are carved out, the RP interface still exists in the static design, and the
rp_inst/rstpin referenced in the constraint still exists in the design. If a constraint is defined using objects inside the RM, as shown in the second constraint, the constraint becomes invalid and is dropped from the design after carving. These constraints would have to be reapplied for every configuration if written using this syntax.
- Constraints (physical or timing) that reference only RM logic. While these
constraints should all be scoped to the RM, how they get applied will depend on
what type of constraints they are:
Important: If an RP has embedded I/O, the I/O (PACKAGE_PIN, IOSTANDARD, direction) must be reapplied for every configuration, even if the I/O pins are identical between every RM. In the Vivado database, a port is a top-level object. However, the I/O constraint information associated with that port is intentionally cleared out during caving of the RM if the associated I/O buffer is part of an RP.
- General RM constraints
- These constraints apply to every instance of the RM. An example is a
timing constraint, like a false path, multi-cycle exception, or a
create_clockfor a local RM clock. These apply to the RM regardless of the physical location.
- RP specific RM constraints
- These constraints are specific to the location (Pblock) in which the RM is being implemented. An example is physical constraints like specific block RAM placement, or PACKAGE_PIN constraints for embedded I/O.
In addition to this, it is also recommended to separate physical (Pblock, LOC, PACKAGE_PIN, etc) and timing constraints into separate XDC files. This allows for better control of when constraints are applied (synthesis vs implementation), and easier management of constraint files if constraints need to be modified.