Debugging Is the Real Job
Running timing is easy. The hard part is reading a violation (a failed timing check). The real skill is finding its true cause. Interviewers test this skill often. This chapter shows worked debug examples. Each one has four parts. First a symptom. Then a stepby-step look. Then the root cause. Then the fix. Do this often enough and it becomes a reflex (an automatic habit). One rule ties it all together. Never fix the first thing you see. Walk the whole path. Find the part that hurts most. Then check that your setup is honest before you change any logic.

A General Method Before the Scenarios
For any failing path, ask five questions in order.
- 1. Is the constraint correct? A constraint is a timing rule you give the tool. A bad clock or a missing
rule makes fake failures. Check this first.
- 2. Is the path even real? Can the signal truly travel it? Or should it be marked as a path to ignore?
- 3. Where is the time going? Walk the path. Find the slow part. It could be a big cell, a long wire, high
fanout (one output driving many inputs), or clock skew (clock arriving at different times).
- 4. Is the analysis honest? Too much safety margin can invent a failure. Too little can hide one.
- 5. What is the cheapest correct fix? Try this order: fix the constraint, then resize cells, then
restructure logic. Change the architecture only as a last resort.
Worked STA Debug Scenarios
| Question | Tool view | Typical finding |
|---|---|---|
| Constraint right? | report constraints/exceptions | missing rule, wrong clock |
| Path real? | functional reasoning | path to ignore |
| Time going where? | path report breakdown | slow net/cell/skew |
| Analysis honest? | derate/CPPR/corner check | double-counted margin |
| Cheapest fix? | what-if | resize vs restructure |
Scenario 1 — Huge Setup Violation That "Shouldn't Exist"
Symptom: a register-to-register path reports a slack (timing margin) of −2.6 ns. The clock period is only 1.8 ns. That gap is far bigger than any logic could cause. Investigation: walk the path report. The data path is only about 1.2 ns. Yet the required time is tiny. Check the clocks. The capture register uses a generated clock (a clock made from another clock). Its source link was never declared. So the tool guessed a default edge. That guess made a nonsense capture time. Root cause: a missing or wrong generated-clock setup. This is a constraint bug, not a logic bug. Fix: define the generated clock against its real source. The path now shows a sane, small slack, or it passes.
# standard (SDC) — declare the divided clock so capture edges are correct
create_generated_clock -name clk_div2 -source [get_pins div/CK] \
-divide_by 2 [get_pins div/Q]
Lesson: a wildly large violation is almost always a clock or constraint error. It is rarely real logic.
Scenario 2 — Hold Violation After Fixing Setup
Symptom: setup closed cleanly. But now many hold violations appear. They sit on short paths near the same registers. Investigation: the setup fix used clock skew. It delayed a capture clock to help setup. That same delay makes data arrive too early for a different launch. So hold breaks on nearby short paths. Root cause: the setup and hold trade-off of clock skew. Helping one side hurt the other. Fix: limit the skew. Add hold buffers (extra delay) on the short paths. Check both setup and hold together. Never sign off setup and hold from separate runs.
| After action | Setup | Hold |
|---|---|---|
| Delay capture clock | improves | worsens |
| Add hold buffers | neutral | improves |
| Cap useful-skew | slightly worse setup | protects hold |
Lesson: setup and hold are linked. Fix and check them together.
Scenario 3 — Path Fails Only at One Corner
Symptom: a path passes at typical and fast corners. But it fails setup badly at the slow corner (low voltage, high heat). Investigation: this is expected. Setup is worst when cells are slowest. But the size of the failure looks odd. Walk the path. It is ruled by a long, resistive wire. That wire gets much slower at the slow corner. The wire model was also too rough. Root cause: a truly slow corner plus a wire-heavy path. The corner is doing its job. The wire is the real problem. Fix: attack the worst part. Shorten or widen the wire. Add a repeater (a buffer in the middle). Or make the driver bigger. Do not just upsize every cell. Confirm the slow corner now passes. Check hold at the fast corner too. Lesson: corner-only failures are normal. Find whether cells or wires dominate first. Then pick the lever.
Scenario 4 — Violation That Disappears With CPPR
Symptom: a register-to-register path inside one clock domain shows a medium setup violation. This is under basic OCV (on-chip variation, a margin for chip-to-chip spread).
Investigation: launch and capture share a long common clock wire. Basic OCV derated that shared wire in opposite ways for launch and capture. That double-counts variation. A shared wire cannot truly differ from itself. Root cause: clock pessimism on the shared wire was not removed. Fix: turn on CPPR (common-path pessimism removal). It credits the shared part correctly. The fake violation clears. If it still fails after CPPR, then it is real.
# illustrative — generic, not tool-specific
set_analysis_option -cppr enabled
report_timing -from launch_ff -to capture_ff -show_cppr
Lesson: before optimizing a same-domain path, check that extra margin is not making the violation.
Scenario 5 — A Path That Can Never Happen
Symptom: a long path runs between two blocks in different modes. It reports a violation. It looks fake. Investigation: the path goes through a mode mux (a switch that picks a mode). When the source mode is active, the destination is held fixed by case analysis (forcing a signal to a constant). So the two ends are never live at the same time. The path exists in the wires. But it can never carry a real signal. Root cause: a real path-to-ignore that was never declared. Or a missing mode constant. Fix: declare the false path. Or set the mode constant. Do this carefully. A too-broad rule can hide real failures on nearby paths.
# standard (SDC) — exclude a genuinely non-functional path
set_false_path -from [get_pins modeA_src/Q] -to [get_pins modeB_dst/D]
Lesson: exception rules are strong but risky. Declare the narrowest rule you can prove is correct.
Scenario 6 — Glitchy Failure Only With SI On
Symptom: a path passes without crosstalk. But it fails setup once SI-aware timing is on. SI means signal integrity (effects from nearby wires). Investigation: the victim net runs beside a strong, fast aggressor (a noisy neighbor wire). Their switching windows overlap. Both switch in opposite directions at the same time. This nearly doubles the coupling effect. It adds a large extra delay. Root cause: crosstalk delay on a coupling-sensitive net. Fix: cut the coupling. Add spacing or shielding. Make the victim driver bigger. Or slow and space the aggressor. Re-run the SI loop. Confirm the extra delay shrank.
Lesson: an SI-only failure points at a neighbor, not the path's own logic. Fix the coupling, not the gates.
A Compact Debug Reference
| Symptom | Most likely cause | First move |
|---|---|---|
| Implausibly large violation | clock/constraint error | check clock & exceptions |
| New hold after setup fix | skew trade-off | bound skew, add hold buffers |
| Fails one corner only | slow corner + dominant net/cell | fix the dominant term |
| Clears with CPPR | shared-wire pessimism | enable CPPR before optimizing |
| Path can't happen | undeclared false/case | narrowest correct exception |
| Fails only with SI | crosstalk extra delay | reduce coupling, re-run SI |
| Unconstrained path warning | missing constraint | add the missing I/O/clock |
Interview Q&A
first? A constraint or clock error. Most often an undeclared or wrong generated clock. Or a wrong clock relationship. It is rarely real logic. Check the clocks and rules before touching gates.
skew. That made data arrive too early for hold on short paths. Limit the skew. Add hold buffers on those paths. Check setup and hold together in one run.
shared clock wire in opposite ways for launch and capture. That double-counts variation. A shared wire cannot differ from itself. CPPR removes that margin. Only a violation that survives CPPR and honest margin is real.
slow corner? Walk the path report. Find the slowest part. If a long resistive wire dominates, fix the wire with a repeater, more width, or a bigger driver. If a cell dominates, resize or restructure cells. Do not upsize everything.
strong aggressor with an overlapping window and opposite switching adds extra delay. Cut the coupling with spacing or shielding. Strengthen the victim. Or tame the aggressor. Then re-run the SI loop.
drop real paths. They may share the same from and to scope. That hides true violations. Always declare the narrowest rule you can prove cannot work.
Key Takeaways
- Debug in a fixed order: constraint correct? path real? where's the time? analysis honest?
cheapest fix?
- Huge violations are clock or constraint bugs. Same-domain violations may be CPPR margin.
- Setup and hold are linked. Fix and sign off together.
- Walk the path. See if a cell or a wire dominates before you pick a lever.
- SI-only failures point at neighbors. Exception rules must be the narrowest you can prove.
ChipBuddy
← Home
Comments
Leave a Reply