Skip to content

flow: simplifications/deletions now that estimate_parasitics is smart - #4691

Open
oharboe wants to merge 2 commits into
The-OpenROAD-Project:masterfrom
oharboe:estimate-parasitics-auto
Open

oharboe wants to merge 2 commits into
The-OpenROAD-Project:masterfrom
oharboe:estimate-parasitics-auto

Conversation

@oharboe

@oharboe oharboe commented Oct 16, 2026 •

Copy link
Copy Markdown
Collaborator

Draft: depends on The-OpenROAD-Project/OpenROAD#11788, which this can use once it's merged and tools/OpenROAD includes it.

The flow decides which parasitics to time with in four places: open.tcl, generate_abstract.tcl, write_endpoint_slack and final_outputs.tcl. Each decides from the stage number, grt::have_routes and whether a .spef file exists. Those rules are easy to get wrong. #4688 fixes one copy: an abstract written from global route was timed with placement parasitics, 6.9 ns instead of 1.8 ns on one arc.

Gemini Code Assist's review of #4688 is a concrete example. It suggested reading $stem.spef from stage 5 on whenever the file exists (comment). It reads as a sensible improvement, and it's wrong:

  • Only the final stage writes a SPEF, so before final that branch can only match a leftover file.
  • Re-running a flow from place or global route leaves the previous final's SPEF in RESULTS_DIR. The re-run stage's timing would silently use parasitics from a different netlist, and nothing in the log would show it.

The rules are subtle enough that an AI reviewer, given the code, proposed a change that turns a loud failure into a silent wrong number. A reviewer reading only the diff, human or bot, couldn't have caught it either: the decision is spread over four scripts and depends on which files a previous run left behind. So the rules belong somewhere they can't be gotten wrong.

Whether a file is on disk is not a valid test, and a stage number is a second copy of a fact OpenROAD already has. So:

  • OpenROAD decides what: a flagless estimate_parasitics uses global routes if they exist, otherwise placement. It fails loudly on an unplaced design, zero wire RC, or a congested route that wasn't accepted, and does nothing once read_spef has run.
  • The flow decides when: log_cmd estimate_parasitics wherever it wants to pay for an estimate (the log shows the time), and an unconditional read_spef exactly where its configuration says a SPEF was made. final_extracts_parasitics says so from RCX_RULES and SKIP_DETAILED_ROUTE. A missing SPEF fails loudly, and a stale one is never read.

On gcd (asap7 and nangate45), the flow with this change and the OpenROAD one is byte-identical to today's at every stage: the .odb files from place through final, the abstract's .lib and .lef, and 6_final.spef apart from its *DATE line. What changes is what happens to a SPEF that is missing or doesn't belong to the design:

generate_abstract on gcd's results today with this change
6_final, SPEF missing succeeds without a word, estimates fails: cannot read file .../6_final.spef
6_final, detailed route skipped, leftover SPEF reads the leftover estimates from the global routes
6_final, extracted SPEF reads it reads it

Changes in behaviour:

  • With RCX configured, a missing 6_final.spef fails open and generate_abstract instead of falling back to an estimate.
  • A global route that is congested and wasn't accepted fails estimate_parasitics instead of being timed without parasitics. To look at one, open it with GUI_TIMING=0. A failed route written with GENERATE_ARTIFACTS_ON_FAILURE gets no endpoint-slack snapshot.
  • generate_abstract from global route or later is timed with global-route parasitics instead of placement parasitics. This supersedes generate_abstract: time a global-route abstract with the route's parasitics #4688's change.
  • The endpoint-slack snapshot records where OpenROAD's parasitics came from: 6_final says spef instead of rcx, and 3_1_place_gp_skip_io with unplaced pins says none instead of placement.

SKIP_DETAILED_ROUTE now reaches generate_abstract, which needs it to know whether 6_final has a SPEF.

Integration test: The-OpenROAD-Project/bazel-orfs#1284, which runs ORFS's generate_abstract.tcl on copies of gcd's results (missing, leftover and extracted SPEF, and an abstract from global route) on asap7 and nangate45.

🤖 Generated with Claude Code

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request simplifies and standardizes parasitics estimation across various flow scripts by replacing explicit estimation flags (such as -placement or -global_routing) with a bare estimate_parasitics call, allowing OpenROAD to automatically determine the correct source based on the design's state. It also introduces the final_extracts_parasitics helper function, updates documentation, and extends the SKIP_DETAILED_ROUTE variable to the generate_abstract stage. There are no review comments, so I have no feedback to provide.

The flow decided which parasitics to time with in four places, open.tcl,
generate_abstract.tcl, write_endpoint_slack and final_outputs.tcl, from
the stage number, grt::have_routes and whether a .spef file exists. A
file on disk says nothing about whether it belongs to the design being
timed: re-running a flow from place or global route leaves the previous
final's SPEF in the results directory.

estimate_parasitics without a flag now picks the source itself: global
routes when there are any, else placement, nothing after read_spef. The
stage scripts call it bare, under log_cmd, where they want to pay for an
estimate. 6_final is timed with 6_final.spef when the final stage
extracted it, which final_extracts_parasitics says from RCX_RULES and
SKIP_DETAILED_ROUTE; read_spef fails if the file is missing. A placed
design is timed with parasitics, a design before placement without.

Changes in behavior:

- With RCX configured, a missing 6_final.spef fails open and
  generate_abstract instead of falling back to an estimate.
- A global route that is congested and was not accepted fails
  estimate_parasitics instead of timing without parasitics; open with
  GUI_TIMING=0 to look at it. A failed route written with
  GENERATE_ARTIFACTS_ON_FAILURE gets no endpoint slack snapshot.
- generate_abstract from global route or later is timed with global
  route parasitics instead of placement parasitics.
- The endpoint slack snapshot records where OpenROAD's parasitics came
  from: 6_final says spef instead of rcx, and 3_1_place_gp_skip_io with
  unplaced pins says none instead of placement.

SKIP_DETAILED_ROUTE reaches generate_abstract, which needs it to know
whether 6_final has a SPEF.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
@oharboe
oharboe force-pushed the estimate-parasitics-auto branch from 410dfb2 to 2447d20 Compare October 16, 2026 12:33
@openroad-ci

openroad-ci commented Oct 16, 2026 •

Copy link
Copy Markdown
Member

🔍 QoR check

Metrics reflect the PR merge build — i.e. what will land on the target branch.

Commit 6c7303b · Jenkins build #4 · Baseline: none resolved · View build on dashboard

62 design(s) checked — 0 with regression(s), 62 without a comparable baseline.

@oharboe
oharboe marked this pull request as ready for review October 20, 2026 22:04
generate_abstract.tcl conflicted with The-OpenROAD-Project#4688 (695436e), which this
change supersedes: the flagless estimate_parasitics times an abstract
from global route on with the route's parasitics, and the SPEF is read
only where final_extracts_parasitics says one was made. Kept this
branch's side.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
@oharboe
oharboe requested a review from eder-matheus October 20, 2026 22:21
@oharboe oharboe changed the title flow: OpenROAD picks the parasitics, the flow says when flow: simplifications/deletions now that estimate_parasitics is smart Oct 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants