Skip to content

dpl: remove negotiation standalone padding check - #11089

Open
gudeh wants to merge 5 commits into
The-OpenROAD-Project:masterfrom
gudeh:dpl-remove-negotiation-padding
Open

dpl: remove negotiation standalone padding check#11089
gudeh wants to merge 5 commits into
The-OpenROAD-Project:masterfrom
gudeh:dpl-remove-negotiation-padding

Conversation

@gudeh

@gudeh gudeh commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Summary

We don't need this check since it's already performed in checkDRC() and countDRCViolations(). Removing it eliminates redundancy.

Adding padding during negotiation was creating a corner-case bug for an upcoming branch that modifies negotiation's initial snapping (PR incoming soon). A mismatch existed between negotiation and check_placement padding checks because the latter allows endcaps to disregard padding (allowPaddingOverlap()). Padding isn't needed in the negotiation algorithm—it's a legacy remnant from before DRCs were integrated into negotiation.

Specific bug details: The issue occurred on a private design containing a vertical channel with the exact number of sites required for certain buffers. Two buffers were initially snapped into the same site with overlap. Negotiation never moved them because of padding (+1 on each side) combined with fixed instances (endcaps) on both sides. These buffers were eventually resolved by falling back to a diamond search and moved to valid (DRC-clean) positions. Meanwhile, check_placement correctly did not report a DRC because padding overlap with endcaps is allowed.

Type of Change

  • Bug fix
  • Refactoring

Impact

Waiting for secure-CI to finish. No-op so far, most PDKs don't use padding.

Verification

  • I have verified that the local build succeeds (./etc/Build.sh).
  • I have run the relevant tests and they pass.
  • My code follows the repository's formatting guidelines.
  • I have included tests to prevent regressions.
    • I believe we don't need a new test, the bug is extremely specific.
  • I have signed my commits (DCO).

Related Issues

[Link issues here]

gudeh added 4 commits August 6, 2026 19:17
The helpers return the cell's footprint extended by its left/right padding.
The 'eff' prefix did not convey that, which made the padded-vs-footprint
distinction in the negotiation grid loops hard to follow.

Pure rename, no functional change.

Signed-off-by: Augusto Berndt <augusto.berndt@precisioninno.com>
negotiationCost, addUsage, isCellLegal and the history/sort bookkeeping all
scanned the cell's padded span (footprint plus left/right padding) and
tested Pixel::capacity.  capacity is a plain int, so the class of the
blocking instance is lost: an endcap and a CORE cell look identical.
PlacementDRC::checkPadding does have the class and waives padding entirely
for SP-class neighbours (CORE_SPACER, ENDCAP*) via allowPaddingOverlap, so
the legalizer demanded one more site per SP-class neighbour than
check_placement does.

Worse, capacity == 0 produced kInfCost, a veto rather than a cost.  A cell
whose padded span fits nowhere in its search window gets every candidate
rejected, so findBestLocation returns the incumbent (best_x/best_y are
initialised to the cell's current position) and the cell never moves.
History cost cannot break the deadlock because the alternatives are vetoed,
not merely expensive.  Two cells seeded into the same narrow channel stayed
fully overlapped for the whole run.

Observed on gf12/ca53_cpu with CELL_PAD_IN_SITES_DETAIL_PLACEMENT=1: a
12-site cell in a 12-site channel flanked by ENDCAPTIE12 instances needed a
14-column run of free sites that exists nowhere nearby, so it was stranded.

Movable cells now claim and test only their footprint; their padding is
enforced solely by PlacementDRC, through the checkDRC call in isCellLegal
and the countDRCViolations penalty in findBestLocation.  usage/overuse
consequently means site contention only, which is what the
negotiated-congestion cost model expects.

Padding against fixed instances is unaffected and still hard: buildGrid
continues to blockade each fixed cell's padded range, and that range is
already class-correct because Padding::isPaddedType reports no padding for
SP-class masters.  An endcap therefore blockades only its footprint while a
CORE or CORE_WELLTAP neighbour blockades its padding too.

No change to the dpl regression results: the same 23 pre-existing master
failures, before and after.

Signed-off-by: Augusto Berndt <augusto.berndt@precisioninno.com>
Signed-off-by: Augusto Berndt <augusto.berndt@precisioninno.com>
@gudeh
gudeh requested a review from a team as a code owner August 6, 2026 22:37
@gudeh
gudeh requested a review from osamahammad21 August 6, 2026 22:37

@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 refactors the negotiation legalizer so that movable cells only claim their actual footprint during legalization, leaving padding checks to PlacementDRC, while fixed cells continue to use their padded footprint. The helper functions have been renamed to paddedXBegin and paddedXEnd to reflect this. The review feedback suggests a minor optimization in isCellLegal to hoist the row coordinate calculation out of the inner loop.

Comment on lines 1097 to 1103
for (int dy = 0; dy < cell.height; ++dy) {
for (int gx = xBegin; gx < xEnd; ++gx) {
if (gridAt(gx, cell.y + dy).capacity == 0
|| gridAt(gx, cell.y + dy).overuse() > 0) {
for (int gx = cell.x; gx < cell.x + cell.width; ++gx) {
const Pixel& g = gridAt(gx, cell.y + dy);
if (g.capacity == 0 || g.overuse() > 0) {
return false;
}
}

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.

medium

We can optimize this loop by hoisting the calculation of gy = cell.y + dy to the outer loop. This avoids recomputing cell.y + dy for every pixel in the inner loop.

  for (int dy = 0; dy < cell.height; ++dy) {
    const int gy = cell.y + dy;
    for (int gx = cell.x; gx < cell.x + cell.width; ++gx) {
      const Pixel& g = gridAt(gx, gy);
      if (g.capacity == 0 || g.overuse() > 0) {
        return false;
      }
    }

@gudeh

gudeh commented Aug 6, 2026

Copy link
Copy Markdown
Contributor Author

@github-actions github-actions Bot added the size/S label Aug 6, 2026
…ation (check only with native checkDRC()).

Signed-off-by: Augusto Berndt <augusto.berndt@precisioninno.com>
@gudeh
gudeh requested review from a team as code owners August 7, 2026 16:31
@github-actions github-actions Bot added size/XL and removed size/S labels Aug 7, 2026
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