Each exception answers one question about the path. The table lists the SDC command, its meaning, and that question.
Exception | Meaning | Question to answer first |
|---|---|---|
| Path may take N cycles for setup | Does the capture register really sample only every N cycles? Does the source hold? |
| Restores same-edge hold for the matching-clock example | Which hold edge must remain? Derive the pairing from launch/capture waveforms |
| Path is never timed | Can this path never be sensitised, or is it an asynchronous / static signal handled elsewhere? |
| Pin is constant in this mode | Is it really constant in the mode being analysed (configuration straps, test mode)? |
| Disable a timing arc | Breaking a combinational loop or an unused path through a cell |
| Replace the default requirement with an explicit delay bound | Typically for asynchronous crossings that still need a bounded delay |
To choose between them, ask the questions in this order and stop at the first yes.
Each diamond asks for a guarantee from the RTL or the mode; each box is the constraint that records it. The bottom box is the common answer: most failing paths are real.
These rules keep exceptions narrow and reviewable. Each one ties the constraint back to the RTL.
Smallest scope. Use -from and -to with specific register groups. Never apply to a whole clock.
One reason per exception, written as a comment next to it, naming the RTL that guarantees it.
Review setup and hold together. The N / N-1 recipe here assumes matching same-clock waveforms; inspect reported edges and choose -start / -end deliberately for differing clocks.
Back it with a test or assertion. An SVA that checks the enable spacing or source stability turns the promise into something that can fail loudly.
Review exceptions like code. Treat a pull request that adds one as a design change.
# Good: narrow scope, reason stated, paired setup/hold
# RTL: a_r and b_r load only when 'start' is accepted and hold for 3 cycles;
# y captures on the 3rd cycle (see mc_mult.sv, assertion a_r_stable).
set_multicycle_path 3 -setup -from [get_cells {a_r* b_r*}] -to [get_cells y*]
set_multicycle_path 2 -hold -from [get_cells {a_r* b_r*}] -to [get_cells y*]
# Bad: broad scope, no reason, no matching hold
set_multicycle_path 4 -from [get_clocks clk] -to [get_clocks clk]Case analysis changes the logic that STA sees instead of removing a check. A mux input is constant, so only one data input is considered.
Each other mode needs its own run with different case settings.
set_false_path -to [get_ports dout*] because the output timing fails. What is the right response?Reject it. A failing output path is a real requirement, not a false path. Either register the outputs, fix the logic, or negotiate the output delay budget with the receiving block. A false path would simply stop checking the interface.