From 4cd8742467afcdc3be8febabb895b5b9ea6d1222 Mon Sep 17 00:00:00 2001 From: Severin Ibarluzea Date: Fri, 5 Sep 2025 10:50:25 -0700 Subject: [PATCH 1/2] fix net label placement for port-only pins --- .../solvePortOnlyPin.ts | 49 +++- .../examples/__snapshots__/example01.snap.svg | 64 ++--- .../examples/__snapshots__/example03.snap.svg | 138 ++++----- .../examples/__snapshots__/example08.snap.svg | 50 ++-- .../examples/__snapshots__/example09.snap.svg | 264 +++++++++--------- .../examples/__snapshots__/example10.snap.svg | 8 +- .../examples/__snapshots__/example11.snap.svg | 70 ++--- .../examples/__snapshots__/example12.snap.svg | 60 ++-- .../SingleNetLabelPlacementSolver01.test.ts | 4 +- 9 files changed, 373 insertions(+), 334 deletions(-) diff --git a/lib/solvers/NetLabelPlacementSolver/SingleNetLabelPlacementSolver/solvePortOnlyPin.ts b/lib/solvers/NetLabelPlacementSolver/SingleNetLabelPlacementSolver/solvePortOnlyPin.ts index dc67d6c..b84484c 100644 --- a/lib/solvers/NetLabelPlacementSolver/SingleNetLabelPlacementSolver/solvePortOnlyPin.ts +++ b/lib/solvers/NetLabelPlacementSolver/SingleNetLabelPlacementSolver/solvePortOnlyPin.ts @@ -51,16 +51,22 @@ export function solveNetLabelPlacementForPortOnlyPin(params: { } } - // Find pin coordinates + // Find pin coordinates and chip bounds let pin: { x: number; y: number } | null = null + let pinChip: { + center: { x: number; y: number } + width: number + height: number + } | null = null for (const chip of inputProblem.chips) { const p = chip.pins.find((pp) => pp.pinId === pinId) if (p) { pin = { x: p.x, y: p.y } + pinChip = { center: chip.center, width: chip.width, height: chip.height } break } } - if (!pin) { + if (!pin || !pinChip) { return { placement: null, testedCandidates: [], @@ -73,7 +79,6 @@ export function solveNetLabelPlacementForPortOnlyPin(params: { ? availableOrientations : (["x+", "x-", "y+", "y-"] as FacingDirection[]) - const anchor = { x: pin.x, y: pin.y } const outwardOf = (o: FacingDirection) => o === "x+" ? { x: 1, y: 0 } @@ -94,18 +99,48 @@ export function solveNetLabelPlacementForPortOnlyPin(params: { hostSegIndex: number }> = [] + const chipBounds = { + minX: pinChip.center.x - pinChip.width / 2, + maxX: pinChip.center.x + pinChip.width / 2, + minY: pinChip.center.y - pinChip.height / 2, + maxY: pinChip.center.y + pinChip.height / 2, + } + for (const orientation of orientations) { const { width, height } = getDimsForOrientation(orientation) - // Place label fully outside the chip: shift center slightly outward + + const anchor: { x: number; y: number } = { x: pin.x, y: pin.y } + + const distanceToEdge = + orientation === "x+" + ? chipBounds.maxX - pin.x + : orientation === "x-" + ? pin.x - chipBounds.minX + : orientation === "y+" + ? chipBounds.maxY - pin.y + : pin.y - chipBounds.minY + + console.debug( + "[solvePortOnlyPin] orientation", + orientation, + "anchor", + anchor, + "distanceToEdge", + distanceToEdge, + ) + + // Place label fully outside the chip: shift center outward past chip edge const baseCenter = getCenterFromAnchor(anchor, orientation, width, height) const outward = outwardOf(orientation) - const offset = 1e-3 + const offset = distanceToEdge + 1e-3 const center = { x: baseCenter.x + outward.x * offset, y: baseCenter.y + outward.y * offset, } const bounds = getRectBounds(center, width, height) + console.debug("[solvePortOnlyPin] center", center, "bounds", bounds) + // Chip collision check const chips = chipObstacleSpatialIndex.getChipsInBounds(bounds) if (chips.length > 0) { @@ -119,6 +154,7 @@ export function solveNetLabelPlacementForPortOnlyPin(params: { status: "chip-collision", hostSegIndex: -1, }) + console.debug("[solvePortOnlyPin] chip collision") continue } @@ -141,6 +177,7 @@ export function solveNetLabelPlacementForPortOnlyPin(params: { status: "trace-collision", hostSegIndex: -1, }) + console.debug("[solvePortOnlyPin] trace collision") continue } @@ -156,6 +193,8 @@ export function solveNetLabelPlacementForPortOnlyPin(params: { hostSegIndex: -1, }) + console.debug("[solvePortOnlyPin] found valid placement") + const placement: NetLabelPlacement = { globalConnNetId: overlappingSameNetTraceGroup.globalConnNetId, dcConnNetId: undefined, diff --git a/tests/examples/__snapshots__/example01.snap.svg b/tests/examples/__snapshots__/example01.snap.svg index 3e85213..0cdde78 100644 --- a/tests/examples/__snapshots__/example01.snap.svg +++ b/tests/examples/__snapshots__/example01.snap.svg @@ -2,100 +2,100 @@ +x-" data-x="-0.8" data-y="0.2" cx="391.2088711143429" cy="299.6400654426468" r="3" fill="hsl(319, 100%, 50%, 0.8)" /> +x-" data-x="-0.8" data-y="0" cx="391.2088711143429" cy="320" r="3" fill="hsl(320, 100%, 50%, 0.8)" /> +x-" data-x="-0.8" data-y="-0.2" cx="391.2088711143429" cy="340.3599345573532" r="3" fill="hsl(321, 100%, 50%, 0.8)" /> +x+" data-x="0.8" data-y="-0.2" cx="554.0883475731687" cy="340.3599345573532" r="3" fill="hsl(322, 100%, 50%, 0.8)" /> +x+" data-x="0.8" data-y="0" cx="554.0883475731687" cy="320" r="3" fill="hsl(323, 100%, 50%, 0.8)" /> +x+" data-x="0.8" data-y="0.2" cx="554.0883475731687" cy="299.6400654426468" r="3" fill="hsl(324, 100%, 50%, 0.8)" /> +y+" data-x="-2" data-y="0.5" cx="269.04926377022366" cy="269.100163606617" r="3" fill="hsl(121, 100%, 50%, 0.8)" /> +y-" data-x="-2" data-y="-0.5" cx="269.04926377022366" cy="370.899836393383" r="3" fill="hsl(122, 100%, 50%, 0.8)" /> +y+" data-x="-4" data-y="0.5" cx="65.44991819669156" cy="269.100163606617" r="3" fill="hsl(2, 100%, 50%, 0.8)" /> +y-" data-x="-4" data-y="-0.5" cx="65.44991819669156" cy="370.899836393383" r="3" fill="hsl(3, 100%, 50%, 0.8)" /> - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - +