Skip to content

bug: a single oscillating net pair aborts TraceOverlapShiftSolver and leaves independent cross-net overlaps unresolved #1102

Description

@tcsenpai

TraceOverlapShiftSolver treats its A -> B -> A oscillation guard as a reason to stop the entire solve. The first net pair that oscillates aborts the whole pass, so every other cross-net overlap still queued at that moment is silently left in the output, even though those pairs are independent and would have been corrected in the next few iterations.

Sub-solver

lib/solvers/TraceOverlapShiftSolver/TraceOverlapShiftSolver.ts, in _step():

if (this.returnsToPreviousTraceState(nextTraceState)) {
  this.activeSubSolver = null
  this.solved = true   // <- ends the whole solver, not just this net pair
  return
}

Reproduction

Minimized from tests/repros/assets/board-1273-trace-overlap-cycle.input.json (74 chips -> 5 chips, 14 pins). Two cross-net collinear overlaps survive the shift solver: GND/VBUS and RTS/DTR. Only the GND/VBUS pair actually oscillates.

{
 "chips": [
  {
   "chipId": "schematic_component_23",
   "center": {
    "x": 11.084375,
    "y": -5.325
   },
   "width": 2.3000000000000007,
   "height": 3.2000000000000006,
   "pins": [
    {
     "pinId": "schematic_port_75",
     "x": 9.934375,
     "y": -4.325
    },
    {
     "pinId": "schematic_port_79",
     "x": 9.934375,
     "y": -5.125
    },
    {
     "pinId": "schematic_port_80",
     "x": 9.934375,
     "y": -5.325
    },
    {
     "pinId": "schematic_port_96",
     "x": 12.234375,
     "y": -5.025
    },
    {
     "pinId": "schematic_port_100",
     "x": 12.234375,
     "y": -4.2250000000000005
    },
    {
     "pinId": "schematic_port_101",
     "x": 12.234375,
     "y": -4.025
    }
   ],
   "sectionId": "USB to UART"
  },
  {
   "chipId": "schematic_component_26",
   "center": {
    "x": 7.629375,
    "y": -3.9250000000000007
   },
   "width": 0.7800000000000002,
   "height": 0.7600000000000011,
   "pins": [
    {
     "pinId": "schematic_port_106",
     "x": 7.564375,
     "y": -4.3050000000000015,
     "_facingDirection": "y-"
    }
   ],
   "sectionId": "USB to UART"
  },
  {
   "chipId": "schematic_component_27",
   "center": {
    "x": 9.221875,
    "y": -5.55
   },
   "width": 1.205,
   "height": 0.5999999999999996,
   "pins": [
    {
     "pinId": "schematic_port_108",
     "x": 8.944374999999999,
     "y": -5.25,
     "_facingDirection": "y+"
    },
    {
     "pinId": "schematic_port_109",
     "x": 8.944374999999999,
     "y": -5.85,
     "_facingDirection": "y-"
    }
   ],
   "sectionId": "USB to UART"
  },
  {
   "chipId": "schematic_component_28",
   "center": {
    "x": 9.221875,
    "y": -4.23
   },
   "width": 1.205,
   "height": 0.6000000000000014,
   "pins": [
    {
     "pinId": "schematic_port_111",
     "x": 8.944374999999999,
     "y": -3.9299999999999997
    }
   ],
   "sectionId": "USB to UART"
  },
  {
   "chipId": "schematic_component_32",
   "center": {
    "x": 15.769374999999998,
    "y": -4.724999999999999
   },
   "width": 2,
   "height": 0.8000000000000007,
   "pins": [
    {
     "pinId": "schematic_port_118",
     "x": 14.769374999999998,
     "y": -4.524999999999999
    },
    {
     "pinId": "schematic_port_119",
     "x": 14.769374999999998,
     "y": -4.724999999999999
    },
    {
     "pinId": "schematic_port_121",
     "x": 16.769374999999997,
     "y": -4.924999999999999
    },
    {
     "pinId": "schematic_port_122",
     "x": 16.769374999999997,
     "y": -4.724999999999999
    }
   ],
   "sectionId": "USB to UART"
  }
 ],
 "directConnections": [
  {
   "netId": ".R5 > .pin1 to .U6 > .VBUS",
   "pinIds": [
    "schematic_port_108",
    "schematic_port_80"
   ]
  }
 ],
 "netConnections": [
  {
   "netId": "GND",
   "isGround": true,
   "netLabelWidth": 0.42,
   "netLabelHeight": 0.48,
   "pinIds": [
    "schematic_port_75",
    "schematic_port_101",
    "schematic_port_106",
    "schematic_port_109"
   ]
  },
  {
   "netId": "VBUS",
   "netLabelWidth": 0.42,
   "netLabelHeight": 0.6,
   "pinIds": [
    "schematic_port_79",
    "schematic_port_111"
   ]
  },
  {
   "netId": "RTS",
   "netLabelWidth": 0.48,
   "pinIds": [
    "schematic_port_96",
    "schematic_port_118",
    "schematic_port_122"
   ]
  },
  {
   "netId": "DTR",
   "netLabelWidth": 0.48,
   "pinIds": [
    "schematic_port_100",
    "schematic_port_119",
    "schematic_port_121"
   ]
  }
 ],
 "textBoxes": [],
 "availableNetLabelOrientations": {
  "GND": [
   "y-"
  ],
  "VBUS": [
   "y+"
  ],
  "RTS": [
   "x-",
   "x+"
  ],
  "DTR": [
   "x-",
   "x+"
  ]
 },
 "maxMspPairDistance": 8,
 "_hideRatsNet": false
}
const solver = new SchematicTracePipelineSolver(inputProblem)
solver.solve()
// inspect solver.traceOverlapShiftSolver.correctedTraceMap for
// cross-net segments that are collinear and overlapping

Observed

The solver stops at iteration 9 with solved === true, and two distinct cross-net pairs still overlap collinearly:

connectivity_net0 ~ connectivity_net1   (GND / VBUS, the oscillating pair)
connectivity_net3 ~ connectivity_net4   (RTS / DTR, independent)

The RTS/DTR traces share an exact coordinate over a positive-length span, so they render as one wire.

On the full board-1273 fixture the same abort leaves 6 unresolved cross-net pairs after 27 iterations.

Expected

Oscillation between two nets should suspend only that net pair. Independent overlaps should keep being corrected until no correctable overlap remains. For this input only connectivity_net0 ~ connectivity_net1 should remain; RTS/DTR should be separated.

On board-1273 this takes the unresolved pairs from 6 down to 1 (the single genuinely oscillating pair), with the same 135 traces routed and no trace added or dropped.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions