This topic will be explored with the example of "Out of Context" synthesis, where a VHDL component is synthesised in isolation to the larger design which typically handles IO buffers and specified timing constraints at the top level. Here I just want to mimic the timing constraints that would have been applied had the input been driven by another part of the design, and the output driving another part of the design.
This version submitted on 28 July 2022 replaces the previous one date 16 May 2021 which had inaccuracies.

- Constraints Definition
- Input Delay
- Output Delay
- Hold Violation
- Solution
- Extraction of Device Timing Data
- Constraints Definition
- Verification
- Input Setup Time
- Input Hold Time
- Output Setup Time
- Output Hold Time
- Notes on Clock Uncertainty
- set_clock_uncertainty
- Over-Constraining Timing
- Tool Configuration
- References
Constraints Definition
Parameter | Definition | E.g. FDRE in Zynq UltraScale+ Device (xazu2eg-sbva484-1-i) |
---|---|---|
Setup Time | Data must be settled on the input to registers by this amount of time in advance of the capture clock edge in order to be reliably copied to the output. | Setup_FDRE_C_D: \(T_{SUf}\), Fast = 0.023 ns, \(T_{SUs}\), Slow = 0.027 ns |
Hold Time | Data must remain settled on the input to registers for at least this time after the capture clock edge in order to be reliably copied to the output. | Hold_FDRE_C_D: \(T_{Hf}\), Fast = 0.046 ns, \(T_{Hs}\), Slow = 0.053 ns |

Input Delay
set_input_delay defines the allowed range of delays of the data toggle after a clock. Use set_input_delay to represent the amount of time that the input will be held steady after the clock on the feeding external register. It specifies the feeding register's hold time after which propagation delays can start to be timed prior to the DUT's setup time (already known).

Use 'min' process delay values for Hold times. Essentially we are proposing to use the fast and slow hold times for the input delay values.

The input delay range can be modelled by the fast and slow hold times of the previous register outside of the DUT.
Output Delay
set_output_delay defines the allowed range of delays of the data toggle before a clock. Use set_output_delay to represent the required time on the external register before the clock. It's the deadline for propagation delays after the DUT's hold time (already known), i.e. external register's setup time.

Use 'max' process delay values for Setup times. Essentially we are proposing to use the fast and slow setup times for the output delay values. Note it is possible for the minimum output delay to be negative. This occurs in a different modelling situation when the minimum output delay is required to provide a hold time.
"The set_output_delay -min is the negative of the hold requirement."
Significance of set_output_delay -max/-min negative and positive values?

The output delay range can be modelled by the fast and slow setup times of the subsequent register outside of the DUT.
Hold Violation
However a device such as xc7z007sclg225-2 shows up an issue with the plan so far. Note the large difference in hold times between fast and slow processes.
Process | Hold Time (ns) |
---|---|
Fast | 0.112 |
Slow | 0.255 |

Calculating the Hold Time on Slow Process uses the wrong mix of values:
- using minimum input delay (0.112 ns)
- using larger hold time (0.255 ns)
Solution
Claim: It is safe to use the slow process setup and hold times only.
- For a fast process, the registers will still use \(T_{Hf}\) for hold timing within the DUT.
- Only the input delays will be 'laggy', not the register outputs.
- Static timing analysis needs to satisfy both fast and slow processes and this is achieved using register delays. Hence the use of \(T_{Hs}\) for input delays matters little as fast hold times are catered for and a late input must be accommodated for slow hold times anyway.
- 'Max' timing delay calculations include the clock uncertainty too, so add \(T_{CU}\), plus "a bit".
- Similar for output delays and \(T_{SU}\).

Feels like there's room for Xilinx to develop a feature in Vivado to make this scenario a standard offering. It ought to be easy enough to automatically apply nominal device delays to all inputs and outputs in Out of Context synthesis (with appropriate caveats).
Extraction of Device Timing Data
Annoyingly, there's no TCL command to extract theses figures directly from the device library. So instead you'll have to run timing reports under controlled situations.

- Create the following timing reports:
- Setup Times:
Fast 'max' delay- Slow 'max' delay
- Hold Times:
Fast 'min' delay- Slow 'min' delay
- Hint: Perform one at a time (2 separate reports) to avoid confusion
- Setup Times:
- Extract delay values for:
- Setup_FDRE_C_D
- Hold_FDRE_C_D
- NB. The values change with 'fanout' (fo)
- Suggest using value for "fo = 1"
So far, we have assumed all inputs are presented to 'D' pin of flops. This is not so clever for CE pin:
- Setup_FDRE_C_CE /= Setup_FDRE_C_D
- Hold_FDRE_C_CE /= Hold_FDRE_C_D
config_timing_corners -corner Slow -delay_type max
config_timing_corners -corner Fast -delay_type none
report_timing_summary -delay_type max -report_unconstrained -check_timing_verbose -max_paths 10 -input_pins -routable_nets -name slow_max
config_timing_corners -corner Slow -delay_type min
report_timing_summary -delay_type min -report_unconstrained -check_timing_verbose -max_paths 10 -input_pins -routable_nets -name slow_min
#
# Revert the timing corners and generate the full static timing analysis report:
#
config_timing_corners -corner Slow -delay_type min_max
config_timing_corners -corner Fast -delay_type min_max
Constraints Definition
Deciphered from Xilinx Forum article "how to write output delay constraints with device setup hold specified". This forum article suggests the following timing constraints should be used for Out of Context Synthesis.
# Clock uncertainty (from a timing report), looks to be device independent
set tcu 0.035
# Part: xazu2eg-sbva484-1-i
# FDRE Setup Time (Setup_FDRE_C_D) in ns (Fast Process, max delay for Setup times)
#set tsuf 0.023
# FDRE Setup Time (Setup_FDRE_C_D) in ns (Slow Process, max delay for Setup times)
set tsus 0.027
# FDRE Hold Time (Hold_FDRE_C_D) in ns (Fast Process, min delay for Hold times)
#set thf 0.046
# FDRE Hold Time (Hold_FDRE_C_D) in ns (Slow Process, min delay for Hold times)
set ths 0.053
# Choose these:
#
# Extra slack (on hold time), designer's choice
set txs 0.008
# Additional clock uncertainty desired for over constraining the design, set by designer choice
set tcu_add 0.000
#
create_clock -period 0.780 -name clk [get_ports clk]
#create_clock -period 0.740 -name clk [get_ports clk]
#create_clock -period 0.650 -name clk [get_ports clk]
set input_ports {data[*] data_valid reset}
set output_ports {hdr_valid}
#
# Standard timing setup, allocate the device delays into the meaningful variables
#
# https://www.xilinx.com/publications/prod_mktg/club_vivado/presentation-2015/paris/Xilinx-TimingClosure.pdf
# Recommended technique for over-constraining a design:
if {[string match "rtl*" [get_design -quiet]]} {
puts "Skipping 'set_clock_uncertainty' command as this is only an elaborated design."
} else {
set_clock_uncertainty -quiet -setup $tcu_add [get_clocks]
}
# Input Delay = Flop Hold Time (slow corner) + clock uncertainty
set input_delay [expr $ths + $tcu + $txs]
# Output Delay = Flop Setup Time (slow corner)
set output_delay $tsus
set_input_delay -clock [get_clocks clk] $input_delay $input_ports
set_output_delay -clock [get_clocks clk] $output_delay $output_ports
Verification
Example reports to verify each of the timing paths.
Input Setup Time
Slack (MET) : 0.239ns (required time - arrival time) Source: data[1] (input port clocked by clk {rise@0.000ns fall@0.390ns period=0.780ns}) Destination: checksumh_reg[8]/D (rising edge-triggered cell FDRE clocked by clk {rise@0.000ns fall@0.390ns period=0.780ns}) Path Group: clk Path Type: Setup (Max at Slow Process Corner) Requirement: 0.780ns (clk rise@0.780ns - clk rise@0.000ns) Data Path Delay: 0.437ns (logic 0.376ns (86.041%) route 0.061ns (13.959%)) Logic Levels: 3 (CARRY8=2 LUT3=1) Input Delay: 0.096ns Clock Uncertainty: 0.035ns ((TSJ^2 + TIJ^2)^1/2 + DJ) / 2 + PE Total System Jitter (TSJ): 0.071ns Total Input Jitter (TIJ): 0.000ns Discrete Jitter (DJ): 0.000ns Phase Error (PE): 0.000ns Location Delay type Incr(ns) Path(ns) Netlist Resource(s) ------------------------------------------------------------------- ------------------- (clock clk rise edge) 0.000 0.000 r input delay 0.096 0.096 0.000 0.096 r data[1] (IN) net (fo=1, unset) 0.000 0.096 data[1] r checksumh[7]_i_8/I1 LUT3 (Prop_LUT3_I1_O) 0.063 0.159 r checksumh[7]_i_8/O net (fo=1, unplaced) 0.025 0.184 checksumh[7]_i_8_n_0 r checksumh_reg[7]_i_1/S[1] CARRY8 (Prop_CARRY8_S[1]_CO[7]) 0.245 0.429 r checksumh_reg[7]_i_1/CO[7] net (fo=1, unplaced) 0.007 0.436 checksumh_reg[7]_i_1_n_0 r checksumh_reg[8]_i_1/CI CARRY8 (Prop_CARRY8_CI_CO[0]) 0.068 0.504 r checksumh_reg[8]_i_1/CO[0] net (fo=1, unplaced) 0.029 0.533 checksumh[8] FDRE r checksumh_reg[8]/D ------------------------------------------------------------------- ------------------- (clock clk rise edge) 0.780 0.780 r 0.000 0.780 r clk (IN) net (fo=19, unset) 0.000 0.780 clk FDRE r checksumh_reg[8]/C clock pessimism 0.000 0.780 clock uncertainty -0.035 0.745 FDRE (Setup_FDRE_C_D) 0.027 0.772 checksumh_reg[8] ------------------------------------------------------------------- required time 0.772 arrival time -0.533 ------------------------------------------------------------------- slack 0.239

Input Hold Time
Slack (MET) : 0.100ns (arrival time - required time) Source: data[0] (input port clocked by clk {rise@0.000ns fall@0.390ns period=0.780ns}) Destination: checksuml_reg[0]/D (rising edge-triggered cell FDRE clocked by clk {rise@0.000ns fall@0.390ns period=0.780ns}) Path Group: clk Path Type: Hold (Min at Fast Process Corner) Requirement: 0.000ns (clk rise@0.000ns - clk rise@0.000ns) Data Path Delay: 0.050ns (logic 0.033ns (66.000%) route 0.017ns (34.000%)) Logic Levels: 2 (CARRY8=1 LUT3=1) Input Delay: 0.096ns Location Delay type Incr(ns) Path(ns) Netlist Resource(s) ------------------------------------------------------------------- ------------------- (clock clk rise edge) 0.000 0.000 r input delay 0.096 0.096 0.000 0.096 r data[0] (IN) net (fo=1, unset) 0.000 0.096 data[0] r checksuml[7]_i_9/I2 LUT3 (Prop_LUT3_I2_O) 0.014 0.110 r checksuml[7]_i_9/O net (fo=1, unplaced) 0.010 0.120 checksuml[7]_i_9_n_0 r checksuml_reg[7]_i_1/S[0] CARRY8 (Prop_CARRY8_S[0]_O[0]) 0.019 0.139 r checksuml_reg[7]_i_1/O[0] net (fo=1, unplaced) 0.007 0.146 checksuml[0] FDRE r checksuml_reg[0]/D ------------------------------------------------------------------- ------------------- (clock clk rise edge) 0.000 0.000 r 0.000 0.000 r clk (IN) net (fo=19, unset) 0.000 0.000 clk FDRE r checksuml_reg[0]/C clock pessimism 0.000 0.000 FDRE (Hold_FDRE_C_D) 0.046 0.046 checksuml_reg[0] ------------------------------------------------------------------- required time -0.046 arrival time 0.146 ------------------------------------------------------------------- slack 0.100

Output Setup Time
Slack (MET) : 0.625ns (required time - arrival time) Source: hdr_valid_reg/C (rising edge-triggered cell FDRE clocked by clk {rise@0.000ns fall@0.390ns period=0.780ns}) Destination: hdr_valid (output port clocked by clk {rise@0.000ns fall@0.390ns period=0.780ns}) Path Group: clk Path Type: Max at Slow Process Corner Requirement: 0.780ns (clk rise@0.780ns - clk rise@0.000ns) Data Path Delay: 0.093ns (logic 0.093ns (100.000%) route 0.000ns (0.000%)) Logic Levels: 0 Output Delay: 0.027ns Clock Uncertainty: 0.035ns ((TSJ^2 + TIJ^2)^1/2 + DJ) / 2 + PE Total System Jitter (TSJ): 0.071ns Total Input Jitter (TIJ): 0.000ns Discrete Jitter (DJ): 0.000ns Phase Error (PE): 0.000ns Location Delay type Incr(ns) Path(ns) Netlist Resource(s) ------------------------------------------------------------------- ------------------- (clock clk rise edge) 0.000 0.000 r 0.000 0.000 r clk (IN) net (fo=19, unset) 0.000 0.000 clk FDRE r hdr_valid_reg/C ------------------------------------------------------------------- ------------------- FDRE (Prop_FDRE_C_Q) 0.093 0.093 r hdr_valid_reg/Q net (fo=0) 0.000 0.093 hdr_valid r hdr_valid (OUT) ------------------------------------------------------------------- ------------------- (clock clk rise edge) 0.780 0.780 r clock pessimism 0.000 0.780 clock uncertainty -0.035 0.745 output delay -0.027 0.718 ------------------------------------------------------------------- required time 0.718 arrival time -0.093 ------------------------------------------------------------------- slack 0.625
No need to repeat the timing diagram here, just note that the output delay has been correctly included.
Output Hold Time
Slack (MET) : 0.065ns (arrival time - required time) Source: hdr_valid_reg/C (rising edge-triggered cell FDRE clocked by clk {rise@0.000ns fall@0.390ns period=0.780ns}) Destination: hdr_valid (output port clocked by clk {rise@0.000ns fall@0.390ns period=0.780ns}) Path Group: clk Path Type: Min at Fast Process Corner Requirement: 0.000ns (clk rise@0.000ns - clk rise@0.000ns) Data Path Delay: 0.038ns (logic 0.038ns (100.000%) route 0.000ns (0.000%)) Logic Levels: 0 Output Delay: 0.027ns Location Delay type Incr(ns) Path(ns) Netlist Resource(s) ------------------------------------------------------------------- ------------------- (clock clk rise edge) 0.000 0.000 r 0.000 0.000 r clk (IN) net (fo=19, unset) 0.000 0.000 clk FDRE r hdr_valid_reg/C ------------------------------------------------------------------- ------------------- FDRE (Prop_FDRE_C_Q) 0.038 0.038 r hdr_valid_reg/Q net (fo=0) 0.000 0.038 hdr_valid r hdr_valid (OUT) ------------------------------------------------------------------- ------------------- (clock clk rise edge) 0.000 0.000 r clock pessimism 0.000 0.000 output delay -0.027 -0.027 ------------------------------------------------------------------- required time 0.027 arrival time 0.038 ------------------------------------------------------------------- slack 0.065
Notes on Clock Uncertainty
Whether clock uncertainty is included in the calculation depends on whether its for setup or hold times. With setup times the calculations are performed between adjacent clock edges, hence the clock uncertainty is part of the equation. With hold times the calculations are performed on the same clock edge hence there is no additional clock uncertainty to add. This is explained well in the Xilinx Forum article Timing summary understanding.
I found a useful tip for the best way to over-constrain a design in a Xilinx presentation Top 5 Timing Closure Techniques.
set_clock_uncertainty
This command is used to add to the uncertainty of a clock in the design, and does not override the default jitter calculation. This is referred to as the user clock uncertainty. The set_clock_uncertainty command provides a convenient means to over-constrain some clocks in the design without changing the clock definitions and relationships. It can constrain setup and hold paths separately using the -setup and -hold options.
So this is a misnoma, the command should be called something more like set_additional_clock_uncertainty! Revert the uncertainty with "set_clock_uncertainty 0.0 [get_clocks]", which leaves the default clock uncertainty of (often) 0.035 ns.
# set_clock_uncertainty 0 <clockOptions> E.g.
set_clock_uncertainty 0.020 [get_clocks]
I found this worked in the above example, adding 0.020 ns uncertainty to the mandated 0.035 ns for a total of 0.055 ns. Setting the uncertainty back to zero reduces the total back to just 0.035 ns. When in context synthesis is performed, the clock uncertainty can rise, in my case to 0.053 ns, so over constraining the design unit out of context ought to pay dividends on integration. Note that you should not just increase the demand for slack in the input and output delay values as this will only affect the boundary conditions whereas increasing clock uncertainty affects the entire design.
Over-Constraining Timing
Method | Over-clock | set_clock_uncertainty |
---|---|---|
Setup | Affected | Affected by default |
Hold | Unaffected | Affected by default |
Application | Subtract TOC from the period | set_clock_uncertainty TOC/2 for both setup and hold Or setup only using set_clock_uncertainty -setup TOC |
Provision is made in the template constraints file above for adding additional clock uncertainty.
Tool Configuration
Don't forget to set up the command line switch for Out of Context synthesis, either through the GUI or from a TCL script as illustrated below.
# Project Mode
set_property \
-name {STEPS.SYNTH_DESIGN.ARGS.MORE OPTIONS} \
-value {-mode out_of_context} \
-objects \[get_runs synth_1\]
# Non-project mode out of context synthesis
synth_design -mode out_of_context ...

References
- Xilinx Forum article "how to write output delay constraints with device setup hold specified".
- Eli Billauer's blog "Meaning of set_input_delay and set_output_delay in SDC timing constraints".
- Xilinx Forum article "Significance of set_output_delay -max/-min negative and positive values?".
- Lecture notes in Specifying Timing Constraints.
- Lecture notes in Synopsis Design Constraints.
- Xilinx Forum article Timing summary understanding.
- Vivado User Group article Top 5 Timing Closure Techniques, Paris 2015.
1 comment
Comment from: philip Member

Thank you, I think I have found the replacement at https://support.xilinx.com/s/question/0D52E00006hpKmUSAU/timing-summary-understanding?language=en_US and now updated the link above.