ServicesHow we workDesign flowInsightsAboutCareersTalk to an engineer

Multicycle Path and False Path in STA: Setup/Hold Multipliers, -start/-end and Exception Precedence

Learn how multicycle paths and false paths work in STA: setup N with hold N-1, -start vs -end, clock groups, exception precedence and debugging.

  • Physical Design
  • Timing
  • VLSI Interview QA
Multicycle Path and False Path in STA: Setup/Hold Multipliers, -start/-end and Exception Precedence
On this page 13 sections
  1. The default: single-cycle setup and hold
  2. What a multicycle path is
  3. How set_multicycle_path moves the checks
  4. Worked example 1: a 3-cycle path on one clock (illustrative)
  5. Multicycle paths between different clocks: -start and -end
    1. Worked example 2: slow to fast (illustrative)
    2. Worked example 3: fast to slow (illustrative)
  6. What a false path is
    1. Asynchronous clocks: use clock groups, not a pile of false paths
    2. False paths that are dangerous
  7. Exception precedence
  8. Exceptions in the physical design flow
  9. Debugging exception problems
  10. Interview questions and answers
  11. FAQ
  12. Summary
  13. References

By default, static timing analysis (STA) assumes that every path between two registers has exactly one clock cycle to deliver its data. Most of the time that is right. Sometimes it isn't. A path may be designed to take two or three cycles, or it may never carry a meaningful transition at all. Timing exceptions tell the STA tool about those cases, and the two most common ones are the multicycle path and the false path.

Exceptions get misused a lot. A missing exception makes the tool burn area and power fixing violations that don't exist. A wrong one hides a real failure that shows up only in silicon. This guide explains how set_multicycle_path moves setup and hold checks, why a setup multicycle almost always needs a matching hold multicycle, what -start and -end mean across clocks of different frequencies, when a false path is valid and when it is dangerous, how exceptions take priority over one another, and how to debug them. It includes illustrative worked examples, a debugging flowchart, interview questions and an FAQ.

Related reading: Static Timing Analysis (STA) in VLSI, Setup and Hold Violations, Standard Design Constraints (SDC) and Time Budgeting in VLSI.

The default: single-cycle setup and hold#

For a path launched and captured by the same clock with period T, STA picks the launch edge at time 0 and makes two checks:

  • Setup is checked at the next capturing edge, at time T. The data must arrive at least one setup time before that edge.
  • Hold is checked at the edge one cycle before the setup capture edge, which for a single-cycle path is the launch edge itself, at time 0. The data launched at 0 must not arrive before the capture flop has finished holding the previous value.

Written as slack equations (ideal clocks, no skew or uncertainty, to keep the arithmetic visible):

  • Setup slack = (T + capture clock latency − setup time) − (launch clock latency + max data delay)
  • Hold slack = (launch clock latency + min data delay) − (capture clock latency + hold time)

The important idea for everything that follows is that the hold check is placed relative to the setup check. Move the setup edge and, unless you say otherwise, the hold edge moves with it.

Figure 1. By default, setup is checked one period after launch and hold is checked at the launch edge (illustrative).

What a multicycle path is#

A multicycle path is a path whose data is allowed to take more than one clock cycle to reach its destination, because the design guarantees that the destination only uses the data every N cycles. Common cases:

  • A slow arithmetic block (a divider, a wide multiplier) whose result is sampled by a register that is only enabled every second or third cycle.
  • Configuration or control registers that are written and then read several cycles later by a state machine that waits on purpose.
  • Data moving between two synchronous clocks of different frequencies that come from the same source, where the design launches or samples only on some of the edges.

The design must actually enforce this, usually with a clock enable on the capturing register (or with a handshake or counter that guarantees it). If the capturing flop samples on every edge, the path is not multicycle no matter what the constraint says, and the chip can fail.

How set_multicycle_path moves the checks#

The basic command is:

Code
set_multicycle_path 3 -setup -from [get_cells u_div/q_reg*] -to [get_cells u_res/r_reg*] set_multicycle_path 2 -hold -from [get_cells u_div/q_reg*] -to [get_cells u_res/r_reg*]

The numbers mean different things for setup and hold, which is the source of most confusion.

  • Setup multiplier N says on which edge, counting from the launch edge, the setup check happens. The default is 1. A setup multiplier of 3 moves the setup capture edge from T to 3T.
  • Hold multiplier M says how many cycles to move the hold check back toward the launch edge from its default position. The default is 0.

When you move setup to 3T, the default hold check follows it to one cycle before, which is 2T. That asks the data launched at time 0 to stay stable until 2T plus the hold time at the capture flop, which means the minimum data delay must exceed two clock periods. No real path is that slow on its fastest corner, so the tool reports a huge hold violation and the hold-fixing step tries to fix it by inserting long chains of delay buffers.

That is why a setup multicycle of N is almost always paired with a hold multicycle of N − 1. With -hold 2, the hold check moves back two cycles from 2T to 0, which is the same place it was for a normal single-cycle path.

Figure 2. A setup multicycle of 3 drags the default hold check to 2T; a hold multicycle of 2 moves it back to the launch edge (illustrative).

There are rare designs where you want the hold check left at a later edge (for example when the launching register is also only updated every N cycles and the receiver's enable is arranged to make that safe), but treat that as an exception that must be reviewed, not a default.

Worked example 1: a 3-cycle path on one clock (illustrative)#

Suppose a 1 GHz clock (T = 1.0 ns) drives a divider whose result register is enabled every third cycle. Ideal clocks, no skew, and these illustrative numbers:

Data table
Item Value
Max data delay (slow corner) 2.60 ns
Min data delay (fast corner) 0.40 ns
Setup time 0.05 ns
Hold time 0.03 ns

Without any exception:

  • Setup slack = (1.00 − 0.05) − 2.60 = −1.65 ns. The tool will try to speed up the divider, upsizing cells and restructuring logic for a violation that isn't real.
  • Hold slack = 0.40 − 0.03 = +0.37 ns.

With set_multicycle_path 3 -setup only:

  • Setup slack = (3.00 − 0.05) − 2.60 = +0.35 ns.
  • Hold is now checked at 2.0 ns: hold slack = 0.40 − (2.00 + 0.03) = −1.63 ns. That is a constraint error, not a real hold problem.

With set_multicycle_path 3 -setup and set_multicycle_path 2 -hold:

  • Setup slack = +0.35 ns.
  • Hold is back at 0: hold slack = 0.40 − 0.03 = +0.37 ns.

The numbers are made up for illustration, but the pattern is exactly what you see in real timing reports: a setup-only multicycle swaps a fake setup violation for a fake hold violation of almost the same size.

Multicycle paths between different clocks: -start and -end#

When launch and capture clocks have different periods, "one cycle" is ambiguous: one cycle of which clock? The -start and -end options decide that.

  • -end counts cycles of the capture (end point) clock.
  • -start counts cycles of the launch (start point) clock.

In SDC, the default for setup is -end and the default for hold is -start. For a same-clock path the choice does not matter. Between clocks of different frequency it matters a lot.

Worked example 2: slow to fast (illustrative)#

Launch clock CLKA has a 4 ns period and capture clock CLKB has a 2 ns period, both derived from the same source and aligned at time 0. By default the tool checks setup at the first CLKB edge after the launch, at 2 ns. If the design guarantees that the receiver only samples every second CLKB edge, you move the capture edge by one CLKB cycle:

Code
set_multicycle_path 2 -setup -end -from [get_clocks CLKA] -to [get_clocks CLKB] set_multicycle_path 1 -hold -end -from [get_clocks CLKA] -to [get_clocks CLKB]

The setup check moves to 4 ns. The hold multicycle, counted in CLKB cycles, brings the hold check back to the 0 ns edge.

Worked example 3: fast to slow (illustrative)#

Now CLKA has a 2 ns period and CLKB a 4 ns period. The capture edge is at 4 ns, and by default the tool uses the latest CLKA launch edge before it, at 2 ns, giving only 2 ns. If the design launches new data only every second CLKA cycle, you move the launch edge back by one CLKA cycle:

Code
set_multicycle_path 2 -setup -start -from [get_clocks CLKA] -to [get_clocks CLKB] set_multicycle_path 1 -hold -start -from [get_clocks CLKA] -to [get_clocks CLKB]

The setup budget becomes 4 ns, and the hold multicycle, counted in CLKA cycles, puts the hold check back where it belongs.

Using -end in the fast-to-slow case would move the capture edge by a whole CLKB period (4 ns) instead of a CLKA period, which gives a different and usually wrong budget. Always ask which clock's edges the design is actually skipping, and count in that clock.

Figure 3. Between clocks of different periods, -end counts capture clock cycles and -start counts launch clock cycles (illustrative).

What a false path is#

A false path is a path that exists structurally in the netlist but can never propagate a transition that matters for timing. set_false_path removes both setup and hold checks on it (you can restrict it with -setup or -hold). Typical valid uses:

  • Quasi-static signals: mode or configuration registers that are written once while the logic that reads them is idle, and never change during normal operation.
  • Paths that are logically impossible: for example a path through two multiplexers whose select lines can never be set to sensitize it at the same time.
  • Test-only paths in functional mode, although set_case_analysis on the test-mode pin is usually cleaner, because it removes exactly the logic that cannot toggle instead of a hand-written list of paths.

Asynchronous clocks: use clock groups, not a pile of false paths#

Paths between truly asynchronous clocks can't be timed meaningfully, because the phase between the clocks is not fixed. The usual way to say that is:

Code
set_clock_groups -asynchronous -group [get_clocks CLK_CPU] -group [get_clocks CLK_USB]

This removes timing between the groups in both directions with one readable line. For clocks that share a pin through a multiplexer and can never be active together, use -logically_exclusive or -physically_exclusive instead, so crosstalk analysis knows whether the clocks can coexist.

Removing the timing does not make a clock domain crossing safe. Safety comes from the synchronizer design (two-flop synchronizers for single bits, gray-coded pointers in asynchronous FIFOs, handshakes for buses), which is checked with clock-domain-crossing tools. For crossings where the skew between bits still matters, such as gray-coded FIFO pointers, many teams replace a blanket false path with a set_max_delay on the crossing data path that ignores clock latency (for example -ignore_clock_latency in PrimeTime or -datapath_only in Vivado), so the bits arrive close enough together.

False paths that are dangerous#

  • Asynchronous resets that are not synchronized: their de-assertion must meet recovery and removal checks. Cutting them hides a real failure. See Recovery and Removal Time.
  • Wildcards that are too broad, such as -to [get_pins */D] or a -through on a net that many unrelated paths share. One careless pattern can switch off timing on thousands of real paths.
  • "Fixing" violations by false-pathing them because they are hard to close. If you can't explain in one sentence why the path can never matter, it isn't false.

Exception precedence#

When several exceptions cover the same path, the STA tool needs a rule to decide which one wins. Following the SDC conventions that tools implement:

  1. set_false_path has the highest priority.
  2. set_max_delay and set_min_delay come next.
  3. set_multicycle_path has the lowest priority among these.

Within the same type of exception, the more specific one wins: an exception -from a pin beats one -from a cell, which beats one -from a clock, and an exception with both -from and -to beats one with only -from or -to. The exact ranking of -through relative to the others can differ by tool, so check your tool's documentation rather than relying on memory.

The practical consequence: a broad set_false_path silently overrides a careful multicycle you wrote later. Read the exceptions report, which lists which exception is actually applied to a path and which ones were ignored or overridden.

Figure 4. Exception precedence: false path beats max/min delay, which beats multicycle path; more specific exceptions win within a type.

Exceptions in the physical design flow#

Exceptions don't only change sign-off reports. They drive what the implementation tool optimizes at every step.

  • Synthesis and placement optimize setup on the paths the constraints say are critical. A missing multicycle wastes area and power on fake violations; a missing false path can pull cells together and add congestion for a path that doesn't matter.
  • CTS and hold fixing use the hold checks. A setup multicycle without its hold partner makes hold fixing insert long buffer chains, which costs area and can create new setup problems.
  • Block-level budgets carry exceptions down to blocks. If a top-level multicycle crosses a block boundary, the block's SDC and its I/O delay budgets must reflect it, as discussed in Time Budgeting in VLSI.
  • Sign-off STA must use the same exceptions as implementation. A mismatch between the implementation SDC and the sign-off SDC is a classic cause of late surprises.

Good teams keep exceptions under review like code: each one has an owner and a one-line reason, the RTL designer confirms the multicycle or false behaviour, and the list is revisited when the RTL changes. Formal or simulation-based exception verification tools can check that a declared multicycle or false path really behaves that way.

Debugging exception problems#

Most exception bugs show up as one of four symptoms: a huge setup violation on a path everyone knows is slow by design, a huge hold violation right after someone added a multicycle, a path that is "unconstrained" when it shouldn't be, or a fix that does nothing because a different exception is actually applied.

Figure 5. A step-by-step flow for debugging timing exception problems.

A practical sequence:

  1. Report the path with its exceptions. Ask the tool which exception, if any, is applied to the path. Most STA tools print it in the path header or in a dedicated exceptions report.
  2. Check that the design really behaves as constrained. Find the clock enable or handshake that makes the path multicycle, or the reason it is false. If you can't find one, the violation may be real.
  3. Check the setup/hold pairing. A large hold violation of roughly (N − 1) clock periods on a multicycle path almost always means the hold multicycle is missing.
  4. Check -start and -end on paths between clocks of different periods, and confirm the launch and capture edges in the report are the ones you expect.
  5. Check precedence and coverage. Look for a broader false path or max delay that overrides your multicycle, and for exceptions that match nothing (often a typo or a register renamed by synthesis).
  6. Re-run timing and compare. Confirm the violation moves as expected and that no unrelated paths lost their timing checks.

Interview questions and answers#

1. What is a multicycle path? A path whose data is allowed more than one clock cycle to reach the capture register, because the design guarantees the data is only used every N cycles, typically through a clock enable on the capturing flop.

2. If you set a setup multicycle of 3, what hold multicycle do you usually need, and why? Two. Moving setup to the third edge also moves the default hold check to the second edge, which would require the minimum data delay to exceed two periods. A hold multicycle of 2 moves the hold check back to the launch edge.

3. What are the default -start/-end settings for setup and hold multicycles? Setup defaults to -end (capture clock cycles) and hold defaults to -start (launch clock cycles).

4. When would you use -start for a setup multicycle? For a fast-to-slow transfer where the design skips launch edges, so the budget should be extended by launch clock periods.

5. What is a false path? Give two valid examples. A structural path that can never propagate a timing-relevant transition. Examples: a static configuration register read only after it settles, and a path through multiplexers whose selects can never sensitize it together.

6. How should you constrain paths between asynchronous clocks? With set_clock_groups -asynchronous, while relying on proper synchronizers verified by clock-domain-crossing checks. Where bit-to-bit skew still matters, add a max delay on the crossing.

7. Which wins when a path has both a false path and a multicycle path? The false path, because false paths have the highest priority among exceptions.

8. Why is false-pathing an asynchronous reset dangerous? Reset de-assertion has recovery and removal requirements. Cutting the path hides violations that can leave flops in different states after reset.

9. What is the difference between set_false_path and set_case_analysis for test logic? set_case_analysis sets a pin to a constant so the tool removes only the logic that can't toggle in that mode. A false path removes a hand-chosen set of paths and is easier to get wrong.

10. A multicycle path shows a hold violation of about two clock periods. What is your first suspect? A setup multicycle of 3 without its matching hold multicycle of 2.

FAQ#

Is a multicycle path the same as a false path? No. A multicycle path is still timed, just with a longer budget. A false path is not timed at all.

Does a multicycle path need special hardware? Yes. The design must guarantee that the destination only samples the data every N cycles, usually with a clock enable, a counter or a handshake. The constraint only describes that behaviour.

Can I use multicycle paths to close timing on a hard path? Only if the RTL actually allows more than one cycle. Otherwise the constraint is wrong and the silicon will fail at speed.

Should exceptions be written on clocks, cells or pins? As narrowly as the intent allows. Clock-level exceptions are fine for whole-domain relationships; register-level exceptions are safer for specific datapaths. Use names that survive synthesis, or regenerate them after netlist changes.

Do exceptions affect hold fixing? Yes. Hold fixing uses the hold checks after exceptions are applied, so a missing hold multicycle causes unnecessary delay insertion.

Summary#

  • STA assumes one cycle per path by default, with hold checked one cycle before the setup edge.
  • set_multicycle_path N -setup moves the setup check to the Nth edge. Pair it with -hold N−1 to bring the hold check back to the launch edge.
  • Setup multicycles default to -end and hold multicycles to -start. Between clocks of different periods, count in the clock whose edges the design actually skips.
  • False paths remove timing entirely. Use them only for paths that can never matter, use set_clock_groups for asynchronous clocks, and never cut unsynchronized resets.
  • False paths beat max/min delay, which beat multicycle paths, and more specific exceptions win. Always read the exceptions report and confirm design intent with the RTL owner.

References#

  • J. Bhasker and R. Chadha, Static Timing Analysis for Nanometer Designs: A Practical Approach, Springer, 2009 (chapters on timing verification and multicycle paths).
  • S. Gangadharan and S. Churiwala, Constraining Designs for Synthesis and Timing Analysis: A Practical Guide to Synopsys Design Constraints (SDC), Springer, 2013.
  • Synopsys, Using the Synopsys Design Constraints Format: Application Note (SDC specification, freely distributed by Synopsys).

Written by

Swasti Pujari

Associate Director, Backend Engineering at CoreIC Technologies, with 15+ years in VLSI Physical Design and backend engineering. Previously Practice Head at UST Global, leading Physical Design, STA, EMIR, DFT, and Physical Verification. Delivered 3nm, 6nm and 7nm projects for AMD, Intel, and Microchip, and published IEEE research on hybrid AI-EDA floorplanning.