IntermediateQuestion 185 of 192Source: Synopsys PrimeTime User Guide: Timing Paths and Exceptions

A hold violation turns out to be a missing multicycle hold. Why must you not fix it with buffers?

From PDVerse PnR Interview Handbook · pdVerse Mentor Guide

Short Answer

When a path has set_multicycle_path 2 -setup (SDC) but no matching hold exception, the hold check moves forward with the setup check and PrimeTime reports a hold violation close to one clock period. That is a constraint bug, not a silicon problem. Fix the SDC with set_multicycle_path 1 -hold (SDC); buffering it wastes area, spends setup margin and leaves the wrong constraint in every later run.

Technical Reference DiagramA hold violation turns out to be a missing multicycle hold. Why must you not fix it with buffers?
Launch and capture clock waveforms showing a setup multicycle of two moving the hold check forward one cycle and creating a near full-period hold violation, then the set_multicycle_path -hold 1 correction moving the hold check back to the launch edge.

Technical Explanation

  • A setup multicycle of 2 makes the second capture edge after launch the setup edge. Hold is always derived from setup: the hold check makes sure data from the setup launch edge is not captured by the capture edge before the setup edge, which is now one full period after launch.
  • So data must arrive a full period plus hold time after launch. A path with ordinary delay shows hold slack close to minus one period.
  • set_multicycle_path 1 -hold (SDC) moves the hold capture edge back by one cycle, to the launch edge, which is the normal hold check.
  • The signature is easy to spot: hold violations of hundreds of picoseconds, close to the period, on paths with generous setup slack. Real hold violations are usually tens of picoseconds.
  • Buffering it means adding nearly a full period of delay per bit. On a wide bus that is hundreds of delay cells, with area, leakage and congestion to match. fix_eco_timing -type hold (PT) will do it if setup has room, because hold fixing only has to avoid new setup and DRC violations, and the eaten setup margin is gone.
  • ICC2 reads the same SDC, so its hold fixing inserts the same buffers. Fix the constraint once and both tools stop.
  • report_exceptions (PT) shows which exceptions apply and why any are partly ignored, and -ignored lists fully ignored ones. It triggers a full timing update, so run it once constraints are loaded. The multicycle-hold-error page covers the SDC error itself; this page covers the ECO cost.

What To Check

  • Hold slack size against the clock period.
  • The capture edge time in the min-delay report.
  • Exceptions on the same from and to points, and whether a hold multicycle exists and is not ignored.
  • Hold buffers already inserted for these paths in earlier rounds.

Command Checks & Actions

PrimeTime (pt_shell)report_timing -delay_type min -from [get_cells FF4] -to [get_cells FF5]

Shows the hold check and its capture edge for the suspect path.

PrimeTime (pt_shell)report_exceptions -from [get_cells FF4] -to [get_cells FF5]

Lists the exceptions that apply to these paths.

PrimeTime (pt_shell)report_exceptions -ignored

Lists exceptions that were fully ignored.

PrimeTime (pt_shell)fix_eco_power -methods {remove_buffer}

After the fix, removes buffers from paths with positive hold slack.

SDC (PrimeTime and ICC2)set_multicycle_path 2 -setup -from [get_cells FF4] -to [get_cells FF5]

The existing two-cycle setup exception.

SDC (PrimeTime and ICC2)set_multicycle_path 1 -hold -from [get_cells FF4] -to [get_cells FF5]

Moves the hold check back to the launch edge.

Healthy, Suspicious & Hard-stop Results

  • Healthy (illustrative): After the hold multicycle is added, hold slack on the bus is +40 ps or more with no buffers.
  • Suspicious (illustrative): Hold slack near minus one period on paths with a setup multicycle and no hold exception.
  • Hard stop: Hold buffers already inserted for a full period on these paths, with setup margin already consumed.

Common Mistake

The Trap: Letting fix_eco_timing -type hold (PT) run on the whole design without reading which paths failed. It pads the multicycle bus with delay cells, 192 of them on a 32-bit path, and reports hold clean. The constraint stays wrong, the setup margin is spent, and the cells must later be found and removed.

What The Interviewer Is Testing

  • Knows how a setup multicycle drags the hold check.
  • Spots a constraint bug from the size of the violation.
  • Fixes the SDC, then cleans up any buffers already added.

Follow-up Question & Model Response

"How do you tell a constraint-bug hold violation from a real one in a report?"

Candidate Model Response: Look at the capture clock edge in the min-delay report. For a normal hold check it matches the launch edge, while a dragged check shows capture one period later. Then look at the size: a real hold failure depends on skew and short data delay and is usually small, while a dragged check fails by close to a period. Finally, report_exceptions (PT) on the same from and to points shows a setup multicycle with no hold partner.

Practical Example

Tapeout Scenario: A 32-bit bus from a configuration register runs on a 1.0 ns clock with set_multicycle_path 2 -setup (SDC) only (illustrative). PrimeTime shows 32 hold violations from -0.93 to -0.95 ns, while setup slack is +1.85 ns. An earlier round had inserted 192 delay cells, about 0.97 ns per bit, leaving setup at +0.88 ns. Adding set_multicycle_path 1 -hold (SDC) makes the cells unnecessary: without them, hold slack would be +0.05 ns. fix_eco_power -methods {remove_buffer} (PT) then takes the 192 cells out, and setup returns to +1.85 ns.

PnR Flow Mentor Guide

Read the complete 8-chapter PnR Flow Mentor Guide free on the web — library setup through placement, clock tree synthesis, routing, chip finishing, hierarchical implementation, and ECO, all the way to stream-out.

Timing Constraints (SDC) Handbook — nine chaptersSDC ConstraintsNine chapters on clocks, exceptions, and constraint linting. →