Ensures repair_timing analysis is conducted correctly within OpenROAD to prevent misleading results from fast-grt flows.

Install

mkdir -p .claude/skills/repair-timing-grt && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/19033" && unzip -o skill.zip -d .claude/skills/repair-timing-grt && rm skill.zip

Installs to .claude/skills/repair-timing-grt

Activation

This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.

Investigate OpenROAD global-route repair_timing correctly — the grt "grind"/timeout, hold- and setup-buffer insertion. Covers why a skip-repair (fast) grt measures nothing about repair, why repair_timing must run inside global_route.tcl on the pre-GR ODB, and how to split the grind into setup vs hold before blaming either. Use when a grt stage times out or runs for hours, when a change is meant to affect repair_timing, or when reasoning about hold vs setup buffer insertion at global route.
494 chars✓ has a “when” triggerlonger than Claude Code's old 250-char listing cap (fine on current versions)
Advanced

Key capabilities

  • Investigate `repair_timing` at global route
  • Identify reasons for grt stage timeouts or long runs
  • Analyze hold- and setup-buffer insertion
  • Confirm `repair_timing` actually ran
  • Split grind runtime into setup vs. hold components
  • Reconcile hypotheses against measured setup/hold split

How it works

The skill guides the user to run the full global-route flow with repair enabled, ensuring `repair_timing` runs inside `global_route.tcl` on the pre-GR ODB, and then analyzes the log for repair activity and setup/hold contributions.

Inputs & outputs

You give it
OpenROAD global-route configuration and log files
You get back
Trustworthy analysis of `repair_timing` behavior, including grind attribution and buffer insertion details

When to use repair-timing-grt

  • Debugging grt stage timeouts
  • Analyzing hold buffer insertion
  • Investigating setup buffer placement
  • Validating timing repair changes

About this skill

Goal

Get a trustworthy answer about repair_timing at global route: whether it grinds, why, and whether a proposed change moves it. The traps below have each wasted hours-long runs; clear them all before drawing any conclusion.

Trap 1 — a skip-repair / fast grt measures nothing about repair

When the question is about repair_timing (the grt grind/timeout, hold- or setup-buffer insertion), do NOT use a fast/skip-repair grt flow (SKIP_INCREMENTAL_REPAIR=1, SKIP_CTS_REPAIR_TIMING=1, or a grt_skiprepair-style extract). It skips repair_design / repair_timing entirely — it only global-routes and estimates parasitics — so a clean, fast exit tells you nothing about whether repair grinds. Using it to "test the grind" is structurally meaningless.

The fast-grt flow is built for clock skew / parasitic re-measurement, where skipping repair is exactly what you want. For anything about repair, run the FULL grt with repair enabled (SKIP_INCREMENTAL_REPAIR=0).

Trap 2 — repair_timing needs the live global-route structures

repair_timing must run inside global_route.tcl, on the pre-GR ODB. It needs the live global-route structures (GR grid, congestion, routing guides) that are not persisted in the saved post-GR ODB. So you cannot bolt repair_timing onto a saved post-GR ODB in a fresh session — it must happen in the same openroad session as global_route, which is exactly what global_route.tcl does:

# (shape of the flow script)
global_route
if { !$SKIP_INCREMENTAL_REPAIR } {
  repair_design_helper
  repair_timing_helper
}

To test repair on a modified netlist, stage the PRE-GR ODB (the CTS-stage output) into the grt extract and run the grt stage with SKIP_INCREMENTAL_REPAIR=0, so global_route rebuilds the structures and repair runs live. Do NOT reuse a saved post-GR ODB.

Trap 3 — measuring the win in WNS, or in percentages of it

Report min_period = clk_period - WNS, and report differences between arms in picoseconds of that. Never a percentage of WNS.

Near closure WNS is a small number, so a percentage of it is dominated by the clock you happened to pick rather than by anything the flow did: the same absolute improvement reads as 5% or 500% depending on the constraint. min_period is the quantity a designer actually trades against, it stays roughly invariant to the constraint (which is why it is comparable across arms at all), and a delta in it is a delta in what the design can run at.

check_pareto.py already takes this position for its period axis — clock - WNS, never WNS itself, with the reasoning written out there — and test/pre_route_pessimism/stage_ladder.tcl reads it the same way.

Two corollaries when the arms are repair settings:

  • A percentage of a percentage is worse. "The gap moved 17%" where the gap is itself a ratio of periods is unreadable. Quote the periods.
  • Watch the constraint-invariance assumption. It is only roughly true. Measured on one design, min_period at global route moved 322.3 -> 322.0 ps between a 1000 ps and a 330 ps clock (invariant to 0.1%), while at placement it moved 287.3 -> 285.7 ps between 330 and 290 (0.6%). Fine for comparing arms, not fine for treating a sub-percent difference as signal.

Trap 4 — repair stops at WNS zero, so a closing design measures nothing

repair_timing works until the violation is gone. Once WNS reaches zero it stops, so every setting of a repair knob reaches the same floor and the achieved period cannot separate them. What differs is runtime.

This is not the same as "nothing to repair", and the difference matters when calibrating a study:

  • A design that closes without repair exercises no repair at all. Any knob measured on it reports zero because nothing ran.
  • A design that closes because repair worked exercised it fully. A knob swept there still cannot move the period.

Both look identical in a post-repair slack report, which is the trap: reading positive WNS and concluding "the knob does nothing" conflates them.

And repair's recovery is not a fixed budget you can calibrate past. It tracks the constraint. Measured on one design at global route, over two clocks 25 ps apart:

clockmin_period before repairafter repairrecovered
290 ps322 ps289.7 ps (WNS +0.29)32 ps
265 ps322 ps265.8 ps (WNS -0.85)56 ps

Repair stopped just shy of the target in both cases, so post-repair min_period mostly echoes the clock rather than reporting a property of the design. Tightening the clock does not "get past" repair; it just makes repair work harder for the same near-zero result.

So calibrate to slightly negative WNS so repair is still working when it stops — that is achievable and is what you want. But do not expect the achieved period to separate repair settings at such a clock: it cannot, by construction. Expect the separation in runtime, which is what a coverage knob like TNS_END_PERCENT claims to trade anyway, and report both. Achieved period only becomes informative at a clock repair demonstrably falls short of, which may be far tighter than the point WNS first goes negative.

And turn off what you are not studying. Last gasp is the long tail of repair_timing and there is no reason to expect a min_period cliff in it, so SKIP_LAST_GASP=1 buys back the runtime that makes an ensemble affordable.

Trap 5 — split the grind into setup vs hold before blaming either

The grind can be setup-dominated (a large count of setup-violated endpoints at negative clock slack — a design far from setup closure) or hold-dominated (many hold endpoints → many hold buffers), and the two want completely different fixes. A hold-side fix does not touch a setup-dominated grind, and vice versa.

Before trusting any grt result about repair, always:

  1. Confirm repair_timing actually ran — grep the log for repair_timing, RSZ- messages, and Took N seconds: repair_timing. If absent, a SKIP_* flag routed around it (Trap 1).
  2. Split setup vs hold — read the setup-violated vs hold-violated endpoint counts and the setup- vs hold-buffer counts from the RSZ messages. Attribute the runtime to whichever dominates.
  3. Reconcile your hypothesis against the split. If you framed the problem as a "hold pathology" but the measured grind is setup, the framing is wrong — fix the attribution before proposing a hold fix.

Note on the effort dial

repair_timing -effort low|medium|high instruments the setup phase's marginal-progress stop (it bails out of a non-convergent setup grind early). It does not currently have an equivalent knob for the hold phase, and hold repair is generally harder to bound than setup — so do not expect -effort low to shorten a hold-dominated grind. See the deps-preflight skill for confirming which effort actually reaches the tool.

Pairs with byo-openroad (iterate on a repair change) and orfs-deps-preflight (validate the code path before the hours-long run).

When not to use it

  • When using a fast/skip-repair grt flow to test repair_timing
  • When running `repair_timing` on a saved post-GR ODB in a fresh session
  • When the question is about clock skew or parasitic re-measurement

Limitations

  • A skip-repair grt flow measures nothing about repair
  • `repair_timing` must run inside `global_route.tcl`, on the pre-GR ODB
  • The `-effort` dial only instruments the setup phase's marginal-progress stop

How it compares

This skill provides a methodology to correctly investigate `repair_timing` by avoiding common pitfalls that lead to misleading results, unlike simply running a fast or incorrectly configured grt flow.

Compared to similar skills

repair-timing-grt side by side with the closest alternatives in the catalog.

SkillInstallsUpdatedSafetyDifficulty
repair-timing-grt (this skill)01moNo flagsAdvanced
python-testing-patterns773moReviewIntermediate
chrome-devtools418moReviewIntermediate
bats98moReviewIntermediate

Try saying

Example prompts that trigger this skill in your AI assistant.

You might also like

python-testing-patterns

wshobson

Implement comprehensive testing strategies with pytest, fixtures, mocking, and test-driven development. Use when writing Python tests, setting up test suites, or implementing testing best practices.

77204

chrome-devtools

mrgoonie

Browser automation, debugging, and performance analysis using Puppeteer CLI scripts. Use for automating browsers, taking screenshots, analyzing performance, monitoring network traffic, web scraping, form automation, and JavaScript debugging.

41157

bats

OleksandrKucherenko

Bash Automated Testing System (BATS) for TDD-style testing of shell scripts. Use when: (1) Writing unit or integration tests for Bash scripts, (2) Testing CLI tools or shell functions, (3) Setting up test infrastructure with setup/teardown hooks, (4) Mocking external commands (curl, git, docker), (5) Generating JUnit reports for CI/CD, (6) Debugging test failures or flaky tests, (7) Implementing test-driven development for shell scripts.

991

browser-daemon

noiv

Persistent browser automation via Playwright daemon. Keep a browser window open and send it commands (navigate, execute JS, inspect console). Perfect for interactive debugging, development, and testing web applications. Use when you need to interact with a browser repeatedly without opening/closing it.

587

performance-profiling

davila7

Performance profiling principles. Measurement, analysis, and optimization techniques.

633

obsidian-local-dev-loop

jeremylongshore

Configure Obsidian plugin development with hot-reload and fast iteration. Use when setting up development workflow, configuring test vaults, or establishing a rapid development cycle. Trigger with phrases like "obsidian dev loop", "obsidian hot reload", "obsidian development workflow", "develop obsidian plugin".

328

Search skills

Search the agent skills registry