← Home Design Constraints (SDC)
49 Design Constraints (SDC)

Quick Reference & Worked Examples

Timing constraints — clocks, generated clocks, I/O delays, exceptions, OCV and MCMM setup

Quick Reference & Worked Examples

This chapter is the page you keep open while writing constraints. It gathers the commands you use most into one table, then walks through four worked examples with real arithmetic, and finishes with a complete small SDC script you can read top to bottom. Use it as a refresher, not a tutorial; the earlier chapters explain the why.

Command Cheat-Sheet

The table lists the common commands, what each does, and whether it is portable standard SDC or a reporting or run command whose exact name varies by tool.

CommandPurposeType
create_clockDefine a clock with period and waveformstandard SDC (real)
create_generated_clockDerive a divided or multiplied clock from astandard SDC (real)

source

set_input_delay	State when an input is valid relative to a	standard SDC (real)

clock

set_output_delay	State how much period downstream logic	standard SDC (real)

needs

set_false_path	Remove a never-exercised path from	standard SDC (real)

analysis

set_multicycle_path	Allow a path more than one clock period	standard SDC (real)
set_clock_groups	Declare clocks related or asynchronous	standard SDC (real)
set_case_analysis	Fix a pin to a constant and propagate	standard SDC (real)
set_disable_timing	Turn off a specific timing arc	standard SDC (real)
set_max_transition	Cap how slowly a signal may switch	standard SDC (real)
set_max_capacitance	Cap the load a driver may see	standard SDC (real)
set_drive	Set driver strength on an input port	standard SDC (real)
group_pathCollect paths into a named report groupstandard SDC (real)
report_timingShow worst paths and slackillustrative (varies by

tool)

report_clocks	List defined clocks	illustrative (varies by

tool)

report_ports -unconstrained	List ports with no delay set	illustrative (varies by

tool)

Worked Example: A Clock Constraint

A design has a primary clock running at 312.5 MHz and an on-chip divider producing a half-rate clock. Step 1: convert frequency to period. 1000 / 312.5 = 3.20 ns. Step 2: the divider's output is half the rate, so its period is 6.40 ns. Step 3: declare the primary clock, then derive the divided one so it tracks the source.

# standard SDC — portable across compliant tools
# 312.5 MHz primary clock: period = 1000 / 312.5 = 3.20 ns
create_clock -name main_clk -period 3.20 [get_ports main_clk]
# Divide-by-two output is 6.40 ns, derived so it tracks main_clk
create_generated_clock -name main_clk_div2 \
-source [get_ports main_clk] -divide_by 2 [get_pins div_reg/Q]

If main_clk later changes to 3.10 ns, main_clk_div2 automatically becomes 6.20 ns. That is the payoff of deriving instead of declaring a second independent clock.

Technical diagram

A 250 MHz interface, period 1000 / 250 = 4.00 ns, connects the chip to external logic. The external source guarantees data valid no later than 1.70 ns after the clock edge and stable until 0.50 ns after the edge. On the output side, the external receiver needs 1.30 ns of setup before its capturing edge. For the input, max delay is 1.70 ns and min delay is 0.50 ns. The on-chip path then has 4.00 minus 1.70 = 2.30 ns to capture, before setup and skew. For the output, output delay is 1.30 ns, leaving 4.00 minus 1.30 = 2.70 ns for the on-chip path to produce the output.

# standard SDC — portable across compliant tools
create_clock -name if_clk -period 4.00 [get_ports if_clk]
# Input: latest valid 1.70 ns after edge, earliest 0.50 ns after edge
set_input_delay  -clock if_clk -max 1.70 [get_ports rx_data*]
set_input_delay  -clock if_clk -min 0.50 [get_ports rx_data*]
# Output: external receiver needs 1.30 ns of the period
set_output_delay -clock if_clk -max 1.30 [get_ports tx_data*]
SideDelay setPeriod left on-chip
Input max1.70 ns4.00 - 1.70 = 2.30 ns
Input min0.50 nsused for hold
Output max1.30 ns4.00 - 1.30 = 2.70 ns

The on-chip logic must fit inside 2.30 ns on the input side and 2.70 ns on the output side. If it does not, you either speed up the logic or renegotiate the external numbers.

Worked Example: Multicycle Setup and Hold

A slow multiply block produces a result used only every third cycle. The clock is 2.80 ns. The path can take up to three periods. Setup: a multicycle of 3 gives 3 times 2.80 = 8.40 ns for the setup check instead of one period of 2.80 ns. Hold: you must set hold to N minus 1, which is 2, to pull the hold check back to one cycle after launch at 2.80 ns rather than three cycles at 8.40 ns.

# standard SDC — portable across compliant tools
# Path may take 3 cycles; setup gets 3 x 2.80 = 8.40 ns
set_multicycle_path 3 -setup -from [get_pins mult_reg/Q] -to [get_pins res_reg/D]
# Hold must be N-1 = 2 so the hold check lands at 2.80 ns, not 8.40 ns
set_multicycle_path 2 -hold  -from [get_pins mult_reg/Q] -to [get_pins res_reg/D]
CheckMultiplierEdge timeWindow
Setup38.40 nspath has 8.40 ns minus setup
Hold (correct)22.80 nsone cycle after launch
Hold (if forgotten)default8.40 nsimpossible, false violation

Forgetting the hold line is the classic trap. The default hold check would land at 8.40 ns and demand the data hold stable for three full cycles, an impossible requirement that shows up as unfixable hold violations.

A Full Small SDC Script

This is a complete, readable constraint file for a small block with one primary clock, one divided clock, budgeted I/O, an asynchronous reset, one false path, and basic design rules. Real portable commands are tagged; the final reporting lines are illustrative.

# standard SDC — portable across compliant tools
# ---- Central values ----
set MAIN_PERIOD 3.20   ;# 312.5 MHz
# ---- Clocks ----
create_clock -name main_clk -period $MAIN_PERIOD [get_ports main_clk]
create_generated_clock -name main_clk_div2 \
-source [get_ports main_clk] -divide_by 2 [get_pins div_reg/Q]
# ---- Treat reset as an ideal network ----
set_ideal_network [get_ports rst_n]
# ---- Input and output delays (budgeted) ----
set_input_delay  -clock main_clk -max 1.40 [get_ports data_in*]
set_input_delay  -clock main_clk -min 0.45 [get_ports data_in*]
set_output_delay -clock main_clk -max 1.10 [get_ports data_out*]
# ---- Safety net so no port is left unconstrained ----
set_input_delay  -clock main_clk 1.00 [all_inputs]
set_output_delay -clock main_clk 1.00 [all_outputs]
# ---- Exceptions ----
# Asynchronous reset is not a timed data path
set_false_path -from [get_ports rst_n]
# Slow status path used every other cycle: multicycle 2 with hold 1
set_multicycle_path 2 -setup -from [get_pins stat_reg/Q] -to [get_pins cap_reg/D]
set_multicycle_path 1 -hold  -from [get_pins stat_reg/Q] -to [get_pins cap_reg/D]
# ---- Mode pruning: force functional mode, exclude scan ----
set_case_analysis 0 [get_ports scan_en]
# ---- Design rules ----
set_max_transition  0.30 [current_design]
set_max_capacitance 0.16 [current_design]
# illustrative — names vary by tool
# ---- Sanity reporting after reading the constraints ----
report_clocks
report_ports -unconstrained
report_timing -max_paths 20

Read the script top to bottom and you see the order that keeps a constraint file safe: central values first, then clocks, then the I/O budget with a safety net, then exceptions, then mode pruning, then design rules, and finally the reporting that proves coverage. Everything that affects timing comes before the reports that check it.

Key Takeaways

  • Keep the cheat-sheet handy: most work uses a dozen portable commands, with reporting names varying by tool.
  • Frequency to period is 1000 / MHz: 312.5 MHz is 3.20 ns, and a divide-by-two of it is 6.40 ns.
  • I/O budgeting is subtraction: the on-chip path gets the period minus the I/O delay you set.
  • Multicycle needs both lines: setup of N and hold of N-1, or you create impossible hold checks.
  • Order a script safely: values, clocks, I/O with a safety net, exceptions, mode pruning, design rules, then reporting.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *

Replying to