Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion lib/solvers/LongDistancePairSolver/LongDistancePairSolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,16 @@ export class LongDistancePairSolver extends BaseSolver {
}
}

// Build helpers to skip nets that are handled by net labels only
// (mirrors the same logic in MspConnectionPairSolver).
const directlyWiredPinIds = new Set<PinId>()
for (const dc of inputProblem.directConnections) {
for (const pid of dc.pinIds) directlyWiredPinIds.add(pid)
}
const netLabelOrientedNets = new Set<string>(
Object.keys(inputProblem.availableNetLabelOrientations ?? {}),
)

// 2. Generate candidate pairs using N-Nearest-Neighbors approach
const candidatePairs: Array<
[InputPin & { chipId: string }, InputPin & { chipId: string }]
Expand All @@ -76,8 +86,18 @@ export class LongDistancePairSolver extends BaseSolver {
const allPinIdsInNet = netConnMap.getIdsConnectedToNet(netId)
if (allPinIdsInNet.length < 2) continue

// Skip nets that are handled by net labels only — same logic as
// MspConnectionPairSolver: no direct-wired pin AND has a label orientation.
const hasDirect = allPinIdsInNet.some((id: string) =>
directlyWiredPinIds.has(id),
)
const hasLabel = allPinIdsInNet.some((id: string) =>
netLabelOrientedNets.has(id),
)
if (!hasDirect && hasLabel) continue

const unconnectedPinIds = allPinIdsInNet.filter(
(pinId) => !primaryConnectedPinIds.has(pinId),
(pinId: string) => !primaryConnectedPinIds.has(pinId),
)

for (const unconnectedPinId of unconnectedPinIds) {
Expand Down
35 changes: 34 additions & 1 deletion lib/solvers/MspConnectionPairSolver/MspConnectionPairSolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,40 @@ export class MspConnectionPairSolver extends BaseSolver {
}
}

this.queuedDcNetIds = Object.keys(netConnMap.netMap)
// Build a set of all pinIds that have explicit direct wire connections.
const directlyWiredPinIds = new Set<string>()
for (const dc of inputProblem.directConnections) {
for (const pid of dc.pinIds) {
directlyWiredPinIds.add(pid)
}
}

// Build a set of nets that have configured net-label orientations.
// These nets will be represented by net labels in the schematic, not wire
// traces — but only when none of their pins appear in directConnections.
const netLabelOrientedNets = new Set<string>(
Object.keys(inputProblem.availableNetLabelOrientations ?? {}),
)

// Only queue nets that need wire traces:
// • Nets with at least one directly-wired pin always need a trace.
// • Nets with NO directly-wired pins but also NO label orientations still
// need a trace (there is no other way to show the connection).
// • Nets with NO directly-wired pins AND a label orientation are skipped
// because NetLabelPlacementSolver will place the label instead.
this.queuedDcNetIds = Object.keys(netConnMap.netMap).filter((netId) => {
const connectedIds = netConnMap.getIdsConnectedToNet(netId) as string[]
const hasDirect = connectedIds.some((id) => directlyWiredPinIds.has(id))
if (hasDirect) return true
// connectedIds includes the user-provided net label string (e.g. "GND")
// because ConnectivityMap treats the net label as just another member of
// the group. Check whether any connected ID is a net with a configured
// label orientation — if so, NetLabelPlacementSolver will handle it.
const hasLabelOrientation = connectedIds.some((id) =>
netLabelOrientedNets.has(id),
)
return !hasLabelOrientation
})
}

override getConstructorParams(): ConstructorParameters<
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/**
* Demo page for issue #79:
* "Fix extra net label in repro61, or remove trace"
*
* This circuit has VCC and GND connected exclusively via netConnections
* with availableNetLabelOrientations. Before the fix both nets also
* produced spurious wire traces on top of their net labels. After the
* fix only the two signal traces (U1.out→R1.pin1, U1.sigA→R1.pin2)
* are drawn; VCC and GND are shown by net labels only.
*/
import { PipelineDebugger } from "site/components/PipelineDebugger"
import type { InputProblem } from "lib/types/InputProblem"

export const inputProblem: InputProblem = {
chips: [
{
chipId: "U1",
center: { x: 0, y: 0 },
width: 2.4,
height: 1.0,
pins: [
{ pinId: "U1.1", x: -1.2, y: 0.3 },
{ pinId: "U1.2", x: -1.2, y: 0.1 },
{ pinId: "U1.3", x: -1.2, y: -0.3 },
{ pinId: "U1.4", x: 1.2, y: 0.3 },
],
},
{
chipId: "R1",
center: { x: 2.5, y: 0.3 },
width: 1.0,
height: 0.4,
pins: [
{ pinId: "R1.1", x: 2.0, y: 0.3 },
{ pinId: "R1.2", x: 3.0, y: 0.3 },
],
},
{
chipId: "C1",
center: { x: -2.5, y: -0.3 },
width: 0.5,
height: 0.8,
pins: [
{ pinId: "C1.1", x: -2.5, y: 0.1 },
{ pinId: "C1.2", x: -2.5, y: -0.7 },
],
},
],
directConnections: [
{ pinIds: ["U1.4", "R1.1"], netId: "U1.out to R1.pin1" },
{ pinIds: ["U1.2", "R1.2"], netId: "U1.sigA to R1.pin2" },
],
netConnections: [
{ netId: "VCC", pinIds: ["U1.1", "C1.1"] },
{ netId: "GND", pinIds: ["U1.3", "C1.2"] },
],
availableNetLabelOrientations: {
VCC: ["y+"],
GND: ["y-"],
},
maxMspPairDistance: 5,
}

export default () => <PipelineDebugger inputProblem={inputProblem} />
64 changes: 35 additions & 29 deletions tests/examples/__snapshots__/example01.snap.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading