Skip to content

gpl, rsz: buffer only nets gpl places during timing-driven placement - #12101

Merged
maliberty merged 4 commits into
The-OpenROAD-Project:masterfrom
The-OpenROAD-Project-staging:td-skip-scan-nets
Nov 3, 2026
Merged

maliberty merged 4 commits into
The-OpenROAD-Project:masterfrom
The-OpenROAD-Project-staging:td-skip-scan-nets

Conversation

@maliberty

@maliberty maliberty commented Nov 3, 2026 •

Copy link
Copy Markdown
Member

Timing-driven global placement crashes in NesterovBaseCommon::getWireLengthGradientWA on designs with inserted scan chains (seen in ORFS on sky130hd/aes, sky130hd/ibex, gf180/ibex and ihp-sg13g2/aes with GPL_TIMING_DRIVEN=1).

Cause

gpl models only SIGNAL and CLOCK nets. Pins on any other net, such as the SCAN nets that execute_dft_plan creates, never become gpl pins. During timing-driven placement, Resizer::findResizeSlacks runs repair_design, which buffered a SCAN net. The callback created a GPin for the buffer's input, but the SCAN net had no GNet, so fixPointers left that GPin in the buffer's gcell with a null net, and the wirelength gradient dereferenced it.

Scan nets also shouldn't be buffered before scan_opt reorders the chains. When the chains are restitched, those buffers are left behind on the old connections.

Changes

  • findResizeSlacks takes a predicate for the nets the placer models, and gpl passes its own isValidSigType rule. While the predicate is set, okToBufferNet, the repair_design net loop and fullyRebuffer leave every other net alone, so gpl and rsz work on the same nets. Gate sizing is unaffected, and repair_design run outside placement still buffers scan nets.
  • If fixPointers finds a new pin on a net gpl doesn't place, it now reports GPL-0335 instead of crashing. Unconnected pins are skipped, as in the initial netlist.
  • dft creates the scan-enable port and net as SIGNAL instead of SCAN. Scan enable is a high-fanout control net, not part of a chain that scan_opt reorders, so gpl should place it and timing-driven placement should buffer it. Scan-in, scan-out and chain nets stay SCAN.
  • New test simple01-td-scan-net: marks a high-fanout net SCAN, runs timing-driven placement, and checks that the net keeps all of its loads.

Timing-driven placement calls Resizer::findResizeSlacks, which can add
buffers through repair_design, fullyRebuffer and repair_timing. gpl
only models SIGNAL and CLOCK nets, so a buffer on any other net (for
example the SCAN nets execute_dft_plan creates) had no connections in
the placer. Its input pin then crashed the wirelength gradient. Scan
nets also should not be buffered before scan_opt reorders the chains;
repair_design after scan_opt buffers them.

findResizeSlacks now takes a predicate for the nets the placer models,
and gpl passes its own isValidSigType rule. While it is set,
okToBufferNet, the repair_design net loop and fullyRebuffer leave other
nets alone. Gate sizing is unaffected.

simple01-td-scan-net marks a high-fanout net SCAN and checks that it
keeps all of its loads after timing-driven placement.

Signed-off-by: Matt Liberty <mliberty@precisioninno.com>
fixPointers added every new pin with a GPin to its gcell, even when the
pin's net has no GNet. The wirelength gradient then dereferenced the
null GNet. The resizer now only buffers nets gpl places, so such a pin
means gpl and rsz disagree about the net set; GPL-0335 names the pin
and net. Unconnected pins are skipped, as in the initial netlist.

Signed-off-by: Matt Liberty <mliberty@precisioninno.com>
@maliberty maliberty self-assigned this Nov 3, 2026
@github-actions github-actions Bot added the size/S label Nov 3, 2026

@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 restricts buffering during timing-driven global placement to only the nets modeled by the placer, preventing the buffering of unplaced nets such as SCAN nets. This is implemented by passing a filtering callback to findResizeSlacks and verifying isPlacedNet during rebuffering and driver repair. The review feedback correctly identifies a potential reentrancy issue in PlacedNetGuard where nested calls could prematurely clear the outer callback, and suggests capturing and restoring the previous state of placed_net_ upon destruction.

Comment thread src/rsz/src/Resizer.cc Resolved
The guard cleared placed_net_ on exit. It now restores the value it
replaced, so a nested call could not drop an outer caller's predicate.
Suggested in review.

Signed-off-by: Matt Liberty <mliberty@precisioninno.com>
@maliberty
maliberty marked this pull request as ready for review November 3, 2026 05:20
@maliberty
maliberty requested review from a team as code owners November 3, 2026 05:20
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 3, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ⚠️ Failed 2026-11-03T05:20:58.384645Z
We couldn’t complete this review. Comment @codex review to try again.
f26b722 Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

execute_dft_plan gave every port it creates sigType SCAN, including
scan enable. Scan enable is a high-fanout control net, not part of a
chain that scan_opt reorders, but as a SCAN net gpl does not place it
and timing-driven repair_design does not buffer it. On sky130hd/ibex it
reached placement as one unbuffered 1,939-pin net and was only buffered
in the resize step, after global placement.

The scan-enable port and net are now SIGNAL, the same as an existing
port named for scan enable. Scan-in, scan-out and chain nets stay SCAN.

Signed-off-by: Matt Liberty <mliberty@precisioninno.com>
@openroad-ci
openroad-ci requested a review from a team as a code owner November 3, 2026 05:39
@openroad-ci
openroad-ci requested a review from AcKoucher November 3, 2026 05:39
@github-actions github-actions Bot added size/M and removed size/S labels Nov 3, 2026
@maliberty
maliberty merged commit d3771fc into The-OpenROAD-Project:master Nov 3, 2026
20 checks passed
@maliberty
maliberty deleted the td-skip-scan-nets branch November 3, 2026 06:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant