@tscircuit/schematic-trace-solver 0.0.157 → 0.0.158
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +143 -55
- package/lib/solvers/SameNetJunctionAlignmentSolver/alignSameNetJunctions.ts +196 -67
- package/package.json +1 -1
- package/site/bug-reports/bug-report-20260826T072956Z.page.tsx +4 -0
- package/tests/bug-reports/bug-report-20260706T213649Z/__snapshots__/bug-report-20260706T213649Z.snap.svg +2 -2
- package/tests/bug-reports/bug-report-20260706T220324Z/__snapshots__/bug-report-20260706T220324Z.snap.svg +2 -2
- package/tests/bug-reports/bug-report-20260707T020342Z/__snapshots__/bug-report-20260707T020342Z.snap.svg +2 -2
- package/tests/bug-reports/bug-report-20260707T092615Z/__snapshots__/bug-report-20260707T092615Z.snap.svg +2 -2
- package/tests/bug-reports/bug-report-20260707T134549Z/__snapshots__/bug-report-20260707T134549Z.snap.svg +2 -2
- package/tests/bug-reports/bug-report-20260707T134722Z/__snapshots__/bug-report-20260707T134722Z.snap.svg +2 -2
- package/tests/bug-reports/bug-report-20260707T140410Z/__snapshots__/bug-report-20260707T140410Z.snap.svg +2 -2
- package/tests/bug-reports/bug-report-20260707T141025Z/__snapshots__/bug-report-20260707T141025Z.snap.svg +2 -2
- package/tests/bug-reports/bug-report-20260707T141421Z/__snapshots__/bug-report-20260707T141421Z.snap.svg +2 -2
- package/tests/bug-reports/bug-report-20260707T230831Z/__snapshots__/bug-report-20260707T230831Z.snap.svg +2 -2
- package/tests/bug-reports/bug-report-20260708T053736Z/__snapshots__/bug-report-20260708T053736Z.snap.svg +2 -2
- package/tests/bug-reports/bug-report-20260708T055430Z/__snapshots__/bug-report-20260708T055430Z.snap.svg +2 -2
- package/tests/bug-reports/bug-report-20260708T095725Z/__snapshots__/bug-report-20260708T095725Z.snap.svg +2 -2
- package/tests/bug-reports/bug-report-20260716T144856Z/__snapshots__/bug-report-20260716T144856Z.snap.svg +2 -2
- package/tests/bug-reports/bug-report-20260717T022934Z/__snapshots__/bug-report-20260717T022934Z.snap.svg +2 -2
- package/tests/bug-reports/bug-report-20260717T031704Z/__snapshots__/bug-report-20260717T031704Z.snap.svg +2 -2
- package/tests/bug-reports/bug-report-20260717T042845Z/__snapshots__/bug-report-20260717T042845Z.snap.svg +2 -2
- package/tests/bug-reports/bug-report-20260721T221026Z/__snapshots__/bug-report-20260721T221026Z.snap.svg +2 -2
- package/tests/bug-reports/bug-report-20260724T175257Z/__snapshots__/bug-report-20260724T175257Z.snap.svg +2 -2
- package/tests/bug-reports/bug-report-20260728T144234Z/__snapshots__/bug-report-20260728T144234Z.snap.svg +4 -4
- package/tests/bug-reports/bug-report-20260728T225606Z/__snapshots__/bug-report-20260728T225606Z.snap.svg +2 -2
- package/tests/bug-reports/bug-report-20260730T061837Z/__snapshots__/bug-report-20260730T061837Z.snap.svg +2 -2
- package/tests/bug-reports/bug-report-20260731T052229Z/__snapshots__/bug-report-20260731T052229Z.snap.svg +2 -2
- package/tests/bug-reports/bug-report-20260804T095800Z/__snapshots__/bug-report-20260804T095800Z.snap.svg +2 -2
- package/tests/bug-reports/bug-report-20260804T171919Z/__snapshots__/bug-report-20260804T171919Z.snap.svg +2 -2
- package/tests/bug-reports/bug-report-20260804T225912Z/__snapshots__/bug-report-20260804T225912Z.snap.svg +2 -2
- package/tests/bug-reports/bug-report-20260805T061316Z/__snapshots__/bug-report-20260805T061316Z.snap.svg +2 -2
- package/tests/bug-reports/bug-report-20260806T061548Z/__snapshots__/bug-report-20260806T061548Z.snap.svg +2 -2
- package/tests/bug-reports/bug-report-20260806T093501Z/__snapshots__/bug-report-20260806T093501Z.snap.svg +2 -2
- package/tests/bug-reports/bug-report-20260811T075142Z/__snapshots__/bug-report-20260811T075142Z.snap.svg +2 -2
- package/tests/bug-reports/bug-report-20260815T073240Z/__snapshots__/bug-report-20260815T073240Z.snap.svg +2 -2
- package/tests/bug-reports/bug-report-20260819T091818Z/__snapshots__/bug-report-20260819T091818Z.snap.svg +2 -2
- package/tests/bug-reports/bug-report-20260825T045913Z/__snapshots__/bug-report-20260825T045913Z.snap.svg +2 -2
- package/tests/bug-reports/bug-report-20260825T103621Z/__snapshots__/bug-report-20260825T103621Z.snap.svg +2 -2
- package/tests/bug-reports/bug-report-20260826T072956Z/__snapshots__/bug-report-20260826T072956Z.snap.svg +842 -0
- package/tests/bug-reports/bug-report-20260826T072956Z/bug-report-20260826T072956Z.json +2452 -0
- package/tests/bug-reports/bug-report-20260826T072956Z/bug-report-20260826T072956Z.test.ts +12 -0
- package/tests/examples/__snapshots__/example01.snap.svg +2 -2
- package/tests/examples/__snapshots__/example02.snap.svg +12 -12
- package/tests/examples/__snapshots__/example03.snap.svg +2 -2
- package/tests/examples/__snapshots__/example04.snap.svg +2 -2
- package/tests/examples/__snapshots__/example05.snap.svg +2 -2
- package/tests/examples/__snapshots__/example06.snap.svg +2 -2
- package/tests/examples/__snapshots__/example07.snap.svg +2 -2
- package/tests/examples/__snapshots__/example08.snap.svg +2 -2
- package/tests/examples/__snapshots__/example09.snap.svg +2 -2
- package/tests/examples/__snapshots__/example10.snap.svg +2 -2
- package/tests/examples/__snapshots__/example11.snap.svg +2 -2
- package/tests/examples/__snapshots__/example12.snap.svg +2 -2
- package/tests/examples/__snapshots__/example13.snap.svg +2 -2
- package/tests/examples/__snapshots__/example14.snap.svg +2 -2
- package/tests/examples/__snapshots__/example15.snap.svg +2 -2
- package/tests/examples/__snapshots__/example16.snap.svg +2 -2
- package/tests/examples/__snapshots__/example17.snap.svg +2 -2
- package/tests/examples/__snapshots__/example18.snap.svg +2 -2
- package/tests/examples/__snapshots__/example19.snap.svg +2 -2
- package/tests/examples/__snapshots__/example20.snap.svg +2 -2
- package/tests/examples/__snapshots__/example21.snap.svg +2 -2
- package/tests/examples/__snapshots__/example22.snap.svg +2 -2
- package/tests/examples/__snapshots__/example23.snap.svg +2 -2
- package/tests/examples/__snapshots__/example24.snap.svg +2 -2
- package/tests/examples/__snapshots__/example25.snap.svg +2 -2
- package/tests/examples/__snapshots__/example26.snap.svg +2 -2
- package/tests/examples/__snapshots__/example27.snap.svg +2 -2
- package/tests/examples/__snapshots__/example28.snap.svg +2 -2
- package/tests/examples/__snapshots__/example29.snap.svg +2 -2
- package/tests/examples/__snapshots__/example30.snap.svg +2 -2
- package/tests/examples/__snapshots__/example31.snap.svg +2 -2
- package/tests/examples/__snapshots__/example32.snap.svg +2 -2
- package/tests/examples/__snapshots__/example33.snap.svg +2 -2
- package/tests/examples/__snapshots__/example34.snap.svg +2 -2
- package/tests/examples/__snapshots__/example35.snap.svg +2 -2
- package/tests/examples/__snapshots__/example36.snap.svg +2 -2
- package/tests/examples/__snapshots__/example37.snap.svg +2 -2
- package/tests/examples/__snapshots__/example38.snap.svg +2 -2
- package/tests/examples/__snapshots__/example39.snap.svg +2 -2
- package/tests/examples/__snapshots__/example40.snap.svg +2 -2
- package/tests/examples/__snapshots__/example41.snap.svg +2 -2
- package/tests/examples/__snapshots__/example42.snap.svg +2 -2
- package/tests/examples/__snapshots__/example43.snap.svg +2 -2
- package/tests/examples/__snapshots__/example44.snap.svg +2 -2
- package/tests/examples/__snapshots__/example45.snap.svg +2 -2
- package/tests/examples/__snapshots__/example46.snap.svg +2 -2
- package/tests/examples/__snapshots__/example47.snap.svg +2 -2
- package/tests/examples/__snapshots__/example48.snap.svg +2 -2
- package/tests/examples/__snapshots__/example49.snap.svg +2 -2
- package/tests/examples/__snapshots__/example50.snap.svg +2 -2
- package/tests/examples/__snapshots__/example51.snap.svg +4 -4
- package/tests/fixtures/matcher.ts +3 -3
- package/tests/repros/__snapshots__/board-1273-trace-overlap-cycle.snap.svg +4 -4
- package/tests/repros/__snapshots__/board-15984-same-net-junction.snap.svg +12 -12
- package/tests/repros/__snapshots__/board1096-usb-label-overlap-iteration.snap.svg +5 -5
- package/tests/repros/__snapshots__/bugreport-001-gnd-overlap.snap.svg +2 -2
- package/tests/repros/__snapshots__/manufacturePartNumber-text-box.snap.svg +2 -2
- package/tests/repros/__snapshots__/netlabel-connector-through-rail-label.snap.svg +2 -2
- package/tests/repros/__snapshots__/repro-atmega328p-fault-pullup.snap.svg +2 -2
- package/tests/repros/__snapshots__/repro-atmega328p-missing-gnd-netlabel.snap.svg +2 -2
- package/tests/repros/__snapshots__/repro-board-589-regulator-section.snap.svg +2 -2
- package/tests/repros/__snapshots__/repro-board-648-esp12f-section.snap.svg +2 -2
- package/tests/repros/__snapshots__/repro-bq24074-battery-charger.snap.svg +2 -2
- package/tests/repros/__snapshots__/repro-bq25895-cross-net-trace-overlap.snap.svg +2 -2
- package/tests/repros/__snapshots__/repro-cc2340r5.snap.svg +2 -2
- package/tests/repros/__snapshots__/repro-core-555-power-cross-net-overlap.snap.svg +2 -2
- package/tests/repros/__snapshots__/repro-core-subcircuit-missing-ground.snap.svg +2 -2
- package/tests/repros/__snapshots__/repro-core-tb67s579ftg-inline-label-routing.snap.svg +2 -2
- package/tests/repros/__snapshots__/repro-dc-power-isolated-routing.snap.svg +2 -2
- package/tests/repros/__snapshots__/repro-example35-minimize-trace-crossing.snap.svg +2 -2
- package/tests/repros/__snapshots__/repro-ground-label-on-lower-rail-end.snap.svg +2 -2
- package/tests/repros/__snapshots__/repro-ina237-current-monitor.snap.svg +2 -2
- package/tests/repros/__snapshots__/repro-missing-trace-netlabel.snap.svg +2 -2
- package/tests/repros/__snapshots__/repro-mspm0l1306-capacitor-symmetry.snap.svg +182 -0
- package/tests/repros/__snapshots__/repro-netlabel-collision-687.snap.svg +2 -2
- package/tests/repros/__snapshots__/repro-netlabel-overlap-trace.snap.svg +2 -2
- package/tests/repros/__snapshots__/repro-nrf52810-clock-routing.snap.svg +2 -2
- package/tests/repros/__snapshots__/repro-pga300-c6-trace-alignment.snap.svg +2 -2
- package/tests/repros/__snapshots__/repro-pga300-redundant-ground-traces.snap.svg +288 -0
- package/tests/repros/__snapshots__/repro-pmp11282-isolated-dcdc.snap.svg +4 -4
- package/tests/repros/__snapshots__/repro-power-group-rail-labels.snap.svg +2 -2
- package/tests/repros/__snapshots__/repro-rectifier-trace-overlap.snap.svg +2 -2
- package/tests/repros/__snapshots__/repro-rp2040-gamepad-trace-alignment.snap.svg +2 -2
- package/tests/repros/__snapshots__/repro-rp2040-usb-cc2-ground-overlap.snap.svg +2 -2
- package/tests/repros/__snapshots__/repro-rp2040-v3v3-label-placement.snap.svg +2 -2
- package/tests/repros/__snapshots__/repro-rp2040-zero-crystal-fallback-netlabels.snap.svg +2 -2
- package/tests/repros/__snapshots__/repro-ti-power-output-section.snap.svg +4 -4
- package/tests/repros/__snapshots__/repro-tida00553-j4-cell-divider.snap.svg +2 -2
- package/tests/repros/__snapshots__/repro-tida010076-j4-ground-bus.snap.svg +2 -2
- package/tests/repros/__snapshots__/repro-tida010076-page02.snap.svg +2 -2
- package/tests/repros/__snapshots__/repro-tps61222-trace-intersection.snap.svg +4 -4
- package/tests/repros/__snapshots__/repro-type-c-16pin-self-connection.snap.svg +2 -2
- package/tests/repros/__snapshots__/repro-type-c-16pin-to-resistor.snap.svg +2 -2
- package/tests/repros/__snapshots__/repro-type-c-vbus-led-ground-label.snap.svg +2 -2
- package/tests/repros/__snapshots__/repro-usb-power-vbus-label-detour.snap.svg +2 -2
- package/tests/repros/__snapshots__/repro-vcc-pin1-detour.snap.svg +2 -2
- package/tests/repros/__snapshots__/repro129-host-custom-symbol-passives.snap.svg +2 -2
- package/tests/repros/__snapshots__/repro130-bq27441-fuel-gauge-trace-through-c1.snap.svg +2 -2
- package/tests/repros/__snapshots__/repro161-power-section-autolayout.snap.svg +4 -4
- package/tests/repros/__snapshots__/repro47-endpoint-obstacle-detour.snap.svg +2 -2
- package/tests/repros/__snapshots__/repro48-555-timer-vcc-rail-label.snap.svg +2 -2
- package/tests/repros/__snapshots__/repro5-escape-padded-text-obstacles.snap.svg +2 -2
- package/tests/repros/__snapshots__/repro51-overlap-junction-crossing.snap.svg +2 -2
- package/tests/repros/__snapshots__/repro84-stacked-gnd-label-orientation.snap.svg +2 -2
- package/tests/repros/__snapshots__/small-variant-resistor-facing-direction.snap.svg +2 -2
- package/tests/repros/__snapshots__/trace-overlap-box-resistor.snap.svg +2 -2
- package/tests/repros/assets/repro-mspm0l1306-capacitor-symmetry.input.json +537 -0
- package/tests/repros/assets/repro-pga300-redundant-ground-traces.input.json +858 -0
- package/tests/repros/repro-mspm0l1306-capacitor-symmetry.test.ts +54 -0
- package/tests/repros/repro-pga300-redundant-ground-traces.test.ts +33 -0
- package/tests/solvers/InlineNetLabelSolver/__snapshots__/anchored-net-label-width.snap.svg +2 -2
- package/tests/solvers/InlineNetLabelSolver/__snapshots__/inline-net-label-anchored-label-clearance.snap.svg +2 -2
- package/tests/solvers/InlineNetLabelSolver/__snapshots__/inline-net-label-port-stub.snap.svg +2 -2
- package/tests/solvers/InlineNetLabelSolver/__snapshots__/inline-net-label-two-pin-net.snap.svg +2 -2
- package/tests/solvers/InlineNetLabelSolver/__snapshots__/inline-net-label01.snap.svg +2 -2
- package/tests/solvers/InlineNetLabelSolver/__snapshots__/inline-net-label02.snap.svg +2 -2
- package/tests/solvers/InlineNetLabelSolver/__snapshots__/terminal-stub-trace-clearance.snap.svg +2 -2
- package/tests/solvers/SameNetJunctionAlignmentSolver/parallel-load-rails.test.ts +291 -0
- package/tests/solvers/SchematicTraceSingleLineSolver2/__snapshots__/SchematicTraceSingleLineSolver2_01-example17-d1_1-u1_1.snap.svg +2 -2
- package/tests/solvers/SchematicTraceSingleLineSolver2/__snapshots__/SchematicTraceSingleLineSolver2_repro47-short-opposing-pins.snap.svg +2 -2
- package/tests/solvers/TraceCleanupSolver/__snapshots__/TraceCleanupSolver.snap.svg +2 -2
- package/tests/solvers/TraceLabelOverlapAvoidanceSolver/__snapshots__/TraceLabelOverlapAvoidanceSolver.snap.svg +2 -2
- package/tests/solvers/TraceLabelOverlapAvoidanceSolver/sub-solver/__snapshots__/MergedNetLabelObstacles.snap.svg +2 -2
- package/tests/solvers/TraceLabelOverlapAvoidanceSolver/sub-solver/__snapshots__/OverlapAvoidanceStepSolver.snap.svg +2 -2
- package/tests/solvers/TraceLabelOverlapAvoidanceSolver/sub-solver/__snapshots__/SingleOverlapSolver.snap.svg +2 -2
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { expect, test } from "bun:test"
|
|
2
|
+
import { SchematicTracePipelineSolver } from "lib/solvers/SchematicTracePipelineSolver/SchematicTracePipelineSolver"
|
|
3
|
+
import type { InputProblem } from "lib/types/InputProblem"
|
|
4
|
+
import "tests/fixtures/matcher"
|
|
5
|
+
import inputProblem from "./assets/repro-mspm0l1306-capacitor-symmetry.input.json"
|
|
6
|
+
|
|
7
|
+
// Captured from tscircuit/ti#119, Microcontroller_MSPM0L1306 at b5ee159.
|
|
8
|
+
// Only opaque component/port IDs and display metadata were normalized.
|
|
9
|
+
// C1/C2 are already level; their VDD/VSS rail junctions should be level too.
|
|
10
|
+
test("repro: MSPM0L1306 aligned decoupling capacitor rails", async () => {
|
|
11
|
+
const solver = new SchematicTracePipelineSolver(
|
|
12
|
+
inputProblem as unknown as InputProblem,
|
|
13
|
+
{
|
|
14
|
+
hideRatsNet: true,
|
|
15
|
+
},
|
|
16
|
+
)
|
|
17
|
+
solver.solve()
|
|
18
|
+
|
|
19
|
+
expect(solver.solved).toBe(true)
|
|
20
|
+
expect(solver.failed).toBe(false)
|
|
21
|
+
|
|
22
|
+
const traces = solver.netLabelToTraceSolver!.getOutput().traces
|
|
23
|
+
const getTrace = (...pinIds: string[]) => {
|
|
24
|
+
const trace = traces.find((trace) =>
|
|
25
|
+
pinIds.every((pinId) => trace.pinIds.includes(pinId)),
|
|
26
|
+
)
|
|
27
|
+
expect(trace).toBeDefined()
|
|
28
|
+
return trace!
|
|
29
|
+
}
|
|
30
|
+
for (const [pin, railY] of [
|
|
31
|
+
[1, 2.05],
|
|
32
|
+
[2, 0.65],
|
|
33
|
+
] as const) {
|
|
34
|
+
const path = getTrace(`C1.${pin}`, `C2.${pin}`).tracePath
|
|
35
|
+
const horizontalSegments = path.slice(1).flatMap((end, index) => {
|
|
36
|
+
const start = path[index]!
|
|
37
|
+
return Math.abs(start.y - end.y) < 1e-6 ? [[start, end]] : []
|
|
38
|
+
})
|
|
39
|
+
expect(horizontalSegments).toHaveLength(1)
|
|
40
|
+
const [start, end] = horizontalSegments[0]!
|
|
41
|
+
expect(start!.y).toBeCloseTo(railY, 6)
|
|
42
|
+
expect(end!.y).toBeCloseTo(railY, 6)
|
|
43
|
+
expect([start!.x, end!.x].sort()).toEqual([-3.5, -4.5].sort())
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// The lower return should continue the C1 column, not introduce a third
|
|
47
|
+
// column between C1/C2 or an extra horizontal step near VSS.
|
|
48
|
+
const returnPath = getTrace("C3.2", "C2.2").tracePath
|
|
49
|
+
expect(returnPath.some((point) => Math.abs(point.x + 4.5) < 1e-6)).toBe(true)
|
|
50
|
+
expect(returnPath.every((point) => [-4.5, -3.5].includes(point.x))).toBe(true)
|
|
51
|
+
expect(returnPath.some((point) => Math.abs(point.y - 0.65) < 1e-6)).toBe(true)
|
|
52
|
+
|
|
53
|
+
await expect(solver).toMatchSolverSnapshot(import.meta.path)
|
|
54
|
+
})
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { expect, test } from "bun:test"
|
|
2
|
+
import { SchematicTracePipelineSolver } from "lib/solvers/SchematicTracePipelineSolver/SchematicTracePipelineSolver"
|
|
3
|
+
import type { InputProblem } from "lib/types/InputProblem"
|
|
4
|
+
import "tests/fixtures/matcher"
|
|
5
|
+
import inputProblem from "./assets/repro-pga300-redundant-ground-traces.input.json"
|
|
6
|
+
|
|
7
|
+
// Full solver input captured from tscircuit/ti#117 at 067b6a2 using
|
|
8
|
+
// `tsci build ... --schematic-only --disable-pcb --solver-debug`.
|
|
9
|
+
// Only the debug serializer's { value_type: "undefined" } markers were removed.
|
|
10
|
+
const COMP = "schematic_port_10"
|
|
11
|
+
const GND = "schematic_port_7"
|
|
12
|
+
const C3_GND = "schematic_port_32"
|
|
13
|
+
const R1_GND = "schematic_port_38"
|
|
14
|
+
|
|
15
|
+
test("repro: PGA300 adds redundant ground branches at COMP", async () => {
|
|
16
|
+
const solver = new SchematicTracePipelineSolver(
|
|
17
|
+
inputProblem as unknown as InputProblem,
|
|
18
|
+
)
|
|
19
|
+
solver.solve()
|
|
20
|
+
|
|
21
|
+
expect(solver.solved).toBe(true)
|
|
22
|
+
const { traces } = solver.netLabelToTraceSolver!.getOutput()
|
|
23
|
+
const hasPair = (a: string, b: string) =>
|
|
24
|
+
traces.some((trace) => trace.pinIds.includes(a) && trace.pinIds.includes(b))
|
|
25
|
+
|
|
26
|
+
// Current bug: the global GND spanning tree substitutes these two branches
|
|
27
|
+
// for the explicitly requested COMP -> R1 connection in the source circuit.
|
|
28
|
+
expect(hasPair(COMP, GND)).toBe(true)
|
|
29
|
+
expect(hasPair(COMP, C3_GND)).toBe(true)
|
|
30
|
+
expect(hasPair(COMP, R1_GND)).toBe(false)
|
|
31
|
+
|
|
32
|
+
await expect(solver).toMatchSolverSnapshot(import.meta.path)
|
|
33
|
+
})
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<svg width="
|
|
1
|
+
<svg width="1200" height="2016" viewBox="0 0 1200 2016" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Solver debug visualization on top and Circuit JSON schematic on the bottom">
|
|
2
2
|
<g transform="translate(0, 0) scale(1.875, 1.875) translate(0, 0)">
|
|
3
3
|
<rect width="100%" height="100%" fill="white"/><g><polyline data-points="5.575,1.4 2.045,2.6" data-type="line" data-label="" points="447.56446991404016,256.8863419293219 258.75835721107927,192.70296084049664" fill="none" stroke="hsl(193, 100%, 50%, 0.8)" stroke-width="1px"/></g><g><polyline data-points="5.575,1.2 2.045,2.4" data-type="line" data-label="" points="447.56446991404016,267.5835721107927 258.75835721107927,203.40019102196752" fill="none" stroke="hsl(191, 100%, 50%, 0.8)" stroke-width="1px"/></g><g><polyline data-points="5.575,1 2.045,2.2" data-type="line" data-label="" points="447.56446991404016,278.2808022922636 258.75835721107927,214.0974212034384" fill="none" stroke="hsl(72, 100%, 50%, 0.8)" stroke-width="1px"/></g><g><polyline data-points="5.575,0.8 2.045,2" data-type="line" data-label="" points="447.56446991404016,288.97803247373446 258.75835721107927,224.79465138490926" fill="none" stroke="hsl(74, 100%, 50%, 0.8)" stroke-width="1px"/></g><g><polyline data-points="5.575,0.6 2.045,0.7" data-type="line" data-label="" points="447.56446991404016,299.67526265520536 258.75835721107927,294.3266475644699" fill="none" stroke="hsl(184, 100%, 50%, 0.8)" stroke-width="1px"/></g><g><polyline data-points="5.575,1.4 5.375,1.4 5.375,2.6 2.045,2.6" data-type="line" data-label="" points="447.56446991404016,256.8863419293219 436.86723973256926,256.8863419293219 436.86723973256926,192.70296084049664 258.75835721107927,192.70296084049664" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="5.575,1.2 3.81,1.2 3.81,2.4 2.045,2.4" data-type="line" data-label="" points="447.56446991404016,267.5835721107927 353.1614135625597,267.5835721107927 353.1614135625597,203.40019102196752 258.75835721107927,203.40019102196752" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="5.575,1 3.71,1 3.71,2.2 2.045,2.2" data-type="line" data-label="" points="447.56446991404016,278.2808022922636 347.81279847182424,278.2808022922636 347.81279847182424,214.0974212034384 258.75835721107927,214.0974212034384" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="5.575,0.8 2.245,0.8 2.245,2 2.045,2" data-type="line" data-label="" points="447.56446991404016,288.97803247373446 269.4555873925501,288.97803247373446 269.4555873925501,224.79465138490926 258.75835721107927,224.79465138490926" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="5.575,0.6 3.81,0.6 3.81,0.7 2.045,0.7" data-type="line" data-label="" points="447.56446991404016,299.67526265520536 353.1614135625597,299.67526265520536 353.1614135625597,294.3266475644699 258.75835721107927,294.3266475644699" fill="none" stroke="purple" stroke-width="1px"/></g><g><rect data-type="rect" data-label="U1" data-x="0" data-y="0" x="40" y="161.9484240687679" width="218.75835721107927" height="339.6370582617001" fill="hsl(164, 100%, 50%, 0.8)" stroke="black" stroke-width="0.018696428571428572"/></g><g><rect data-type="rect" data-label="J4" data-x="7" data-y="-0.4" x="447.5644699140401" y="246.189111747851" width="152.43553008595984" height="213.94460362941737" fill="hsl(186, 100%, 50%, 0.8)" stroke="black" stroke-width="0.018696428571428572"/></g><g><rect data-type="rect" data-label="TB67S579FTG" data-x="2.405" data-y="3.525" x="242.71251193887292" y="138.41451766953202" width="70.60171919770775" height="9.627507163323742" fill="rgba(160, 0, 220, 0.14)" stroke="black" stroke-width="0.018696428571428572"/></g><g><rect data-type="rect" data-label="U1" data-x="1.865" data-y="3.29" x="239.50334288443167" y="149.11174785100286" width="19.25501432664757" height="13.371537726838596" fill="rgba(160, 0, 220, 0.14)" stroke="black" stroke-width="0.018696428571428572"/></g><g><rect data-type="rect" data-label="J4" data-x="6.095" data-y="1.715" x="465.74976122254054" y="233.35243553008593" width="19.255014326647597" height="13.371537726838568" fill="rgba(160, 0, 220, 0.14)" stroke="black" stroke-width="0.018696428571428572"/></g><g><rect data-type="rect" data-label="INLINE netId: OUT_A_P
|
|
4
4
|
axis: x
|
|
@@ -70,7 +70,7 @@ SERIAL_IN" data-x="4.6925" data-y="0.6" cx="400.3629417382999" cy="299.675262655
|
|
|
70
70
|
});
|
|
71
71
|
]]></script>
|
|
72
72
|
</g>
|
|
73
|
-
<g transform="translate(
|
|
73
|
+
<g transform="translate(0, 1216)">
|
|
74
74
|
<style>
|
|
75
75
|
.boundary { fill: rgb(245, 241, 237); }
|
|
76
76
|
.schematic-boundary { fill: none; stroke: #fff; }
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<svg width="
|
|
1
|
+
<svg width="1200" height="2016" viewBox="0 0 1200 2016" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Solver debug visualization on top and Circuit JSON schematic on the bottom">
|
|
2
2
|
<g transform="translate(0, 0) scale(1.875, 1.875) translate(0, 0)">
|
|
3
3
|
<rect width="100%" height="100%" fill="white"/><g><polyline data-points="-0.7,0.2 -1.3290000000000002,0.2" data-type="line" data-label="" points="337.7926421404682,320 219.98662207357856,320" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="-0.7,0.4 -1.3290000000000002,0.4" data-type="line" data-label="" points="337.7926421404682,282.54180602006693 219.98662207357856,282.54180602006693" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="-0.7,0 -1.38,0" data-type="line" data-label="" points="337.7926421404682,357.4581939799331 210.43478260869568,357.4581939799331" fill="none" stroke="purple" stroke-width="1px"/></g><g><rect data-type="rect" data-label="U1" data-x="0" data-y="0.2" x="337.79264214046816" y="226.35451505016724" width="262.2073578595318" height="187.29096989966553" fill="hsl(164, 100%, 50%, 0.8)" stroke="black" stroke-width="0.005339285714285715"/></g><g><rect data-type="rect" data-label="netId: D_MINUS
|
|
4
4
|
globalConnNetId: connectivity_net0" data-x="-1.81" data-y="0.4" x="40" y="263.81270903010034" width="179.79933110367892" height="37.45819397993313" fill="hsl(40, 100%, 50%, 0.35)" stroke="black" stroke-width="0.005339285714285715"/></g><g><rect data-type="rect" data-label="netId: D_PLUS
|
|
@@ -55,7 +55,7 @@ SWCLK" data-x="-1.04" data-y="0" cx="274.11371237458195" cy="357.4581939799331"
|
|
|
55
55
|
});
|
|
56
56
|
]]></script>
|
|
57
57
|
</g>
|
|
58
|
-
<g transform="translate(
|
|
58
|
+
<g transform="translate(0, 1216)">
|
|
59
59
|
<style>
|
|
60
60
|
.boundary { fill: rgb(245, 241, 237); }
|
|
61
61
|
.schematic-boundary { fill: none; stroke: #fff; }
|
package/tests/solvers/InlineNetLabelSolver/__snapshots__/inline-net-label-port-stub.snap.svg
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<svg width="
|
|
1
|
+
<svg width="1200" height="2016" viewBox="0 0 1200 2016" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Solver debug visualization on top and Circuit JSON schematic on the bottom">
|
|
2
2
|
<g transform="translate(0, 0) scale(1.875, 1.875) translate(0, 0)">
|
|
3
3
|
<rect width="100%" height="100%" fill="white"/><g><polyline data-points="-0.5,0.3 -2.3499999999999996,0.3" data-type="line" data-label="" points="262.79569892473114,271.8279569892473 40,271.8279569892473" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="0.5,-0.2 2.3,-0.2" data-type="line" data-label="" points="383.2258064516129,332.04301075268813 600,332.04301075268813" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="-0.5,-0.1 -2.3499999999999996,-0.1" data-type="line" data-label="" points="262.79569892473114,320 40,320" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="-0.2,0.5 -0.2,1.45" data-type="line" data-label="" points="298.9247311827957,247.74193548387095 298.9247311827957,133.33333333333331" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="0.2,-0.5 0.2,-1.65" data-type="line" data-label="" points="347.09677419354836,368.17204301075265 347.09677419354836,506.66666666666663" fill="none" stroke="purple" stroke-width="1px"/></g><g><rect data-type="rect" data-label="U1" data-x="0" data-y="0" x="262.79569892473114" y="247.74193548387098" width="120.43010752688178" height="120.4301075268817" fill="hsl(164, 100%, 50%, 0.8)" stroke="black" stroke-width="0.008303571428571428"/></g><g><rect data-type="rect" data-label="INLINE netId: NET_PRU0_MII_TX_CLK1
|
|
4
4
|
axis: x
|
|
@@ -65,7 +65,7 @@ NET_BOTTOM" data-x="0.2" data-y="-1.075" cx="347.09677419354836" cy="437.4193548
|
|
|
65
65
|
});
|
|
66
66
|
]]></script>
|
|
67
67
|
</g>
|
|
68
|
-
<g transform="translate(
|
|
68
|
+
<g transform="translate(0, 1216)">
|
|
69
69
|
<style>
|
|
70
70
|
.boundary { fill: rgb(245, 241, 237); }
|
|
71
71
|
.schematic-boundary { fill: none; stroke: #fff; }
|
package/tests/solvers/InlineNetLabelSolver/__snapshots__/inline-net-label-two-pin-net.snap.svg
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<svg width="
|
|
1
|
+
<svg width="1200" height="2016" viewBox="0 0 1200 2016" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Solver debug visualization on top and Circuit JSON schematic on the bottom">
|
|
2
2
|
<g transform="translate(0, 0) scale(1.875, 1.875) translate(0, 0)">
|
|
3
3
|
<rect width="100%" height="100%" fill="white"/><g><polyline data-points="-0.5,1 0.5,1" data-type="line" data-label="" points="264,208 376,208" fill="none" stroke="hsl(253, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="-0.5,1 0.5,1" data-type="line" data-label="" points="264,208 376,208" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="-1.5,-1 -0.19999999999999996,-1" data-type="line" data-label="" points="152,432 297.6,432" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="1.5,-1 0.19999999999999996,-1" data-type="line" data-label="" points="488,432 342.4,432" fill="none" stroke="purple" stroke-width="1px"/></g><g><rect data-type="rect" data-label="U1" data-x="-1" data-y="1" x="152" y="152" width="112" height="112" fill="hsl(164, 100%, 50%, 0.8)" stroke="black" stroke-width="0.008928571428571428"/></g><g><rect data-type="rect" data-label="U2" data-x="1" data-y="1" x="376" y="152" width="112" height="112" fill="hsl(165, 100%, 50%, 0.8)" stroke="black" stroke-width="0.008928571428571428"/></g><g><rect data-type="rect" data-label="U3" data-x="-2" data-y="-1" x="40" y="376" width="112" height="112" fill="hsl(166, 100%, 50%, 0.8)" stroke="black" stroke-width="0.008928571428571428"/></g><g><rect data-type="rect" data-label="U4" data-x="2" data-y="-1" x="488" y="376" width="112" height="112" fill="hsl(167, 100%, 50%, 0.8)" stroke="black" stroke-width="0.008928571428571428"/></g><g><rect data-type="rect" data-label="INLINE netId: NET_ROUTED
|
|
4
4
|
axis: x
|
|
@@ -58,7 +58,7 @@ NET_SECTIONED" data-x="0.85" data-y="-1" cx="415.2" cy="432" r="3" fill="green"/
|
|
|
58
58
|
});
|
|
59
59
|
]]></script>
|
|
60
60
|
</g>
|
|
61
|
-
<g transform="translate(
|
|
61
|
+
<g transform="translate(0, 1216)">
|
|
62
62
|
<style>
|
|
63
63
|
.boundary { fill: rgb(245, 241, 237); }
|
|
64
64
|
.schematic-boundary { fill: none; stroke: #fff; }
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<svg width="
|
|
1
|
+
<svg width="1200" height="2016" viewBox="0 0 1200 2016" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Solver debug visualization on top and Circuit JSON schematic on the bottom">
|
|
2
2
|
<g transform="translate(0, 0) scale(1.875, 1.875) translate(0, 0)">
|
|
3
3
|
<rect width="100%" height="100%" fill="white"/><g><polyline data-points="0.5,0 2.5,0" data-type="line" data-label="" points="214.33962264150944,71.69811320754715 425.66037735849056,71.69811320754715" fill="none" stroke="hsl(48, 100%, 50%, 0.8)" stroke-width="1px"/></g><g><polyline data-points="0,-2.5 0,-4" data-type="line" data-label="" points="161.50943396226415,335.84905660377353 161.50943396226415,494.33962264150944" fill="none" stroke="hsl(136, 100%, 50%, 0.8)" stroke-width="1px"/></g><g><polyline data-points="0.5,0 2.5,0" data-type="line" data-label="" points="214.33962264150944,71.69811320754715 425.66037735849056,71.69811320754715" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="0,-2.5 0,-4" data-type="line" data-label="" points="161.50943396226415,335.84905660377353 161.50943396226415,494.33962264150944" fill="none" stroke="purple" stroke-width="1px"/></g><g><rect data-type="rect" data-label="U1" data-x="0" data-y="0" x="108.67924528301887" y="39.999999999999986" width="105.66037735849056" height="63.39622641509433" fill="hsl(164, 100%, 50%, 0.8)" stroke="black" stroke-width="0.009464285714285715"/></g><g><rect data-type="rect" data-label="U2" data-x="3" data-y="0" x="425.66037735849056" y="39.999999999999986" width="105.66037735849056" height="63.39622641509433" fill="hsl(165, 100%, 50%, 0.8)" stroke="black" stroke-width="0.009464285714285715"/></g><g><rect data-type="rect" data-label="U3" data-x="0" data-y="-2" x="129.81132075471697" y="230.18867924528303" width="63.39622641509436" height="105.66037735849054" fill="hsl(166, 100%, 50%, 0.8)" stroke="black" stroke-width="0.009464285714285715"/></g><g><rect data-type="rect" data-label="U4" data-x="0" data-y="-4.5" x="129.81132075471697" y="494.3396226415094" width="63.39622641509436" height="105.66037735849056" fill="hsl(167, 100%, 50%, 0.8)" stroke="black" stroke-width="0.009464285714285715"/></g><g><rect data-type="rect" data-label="INLINE netId: USER_LED_ANODE
|
|
4
4
|
axis: x
|
|
@@ -55,7 +55,7 @@ SPI_SCK" data-x="0" data-y="-3.25" cx="161.50943396226415" cy="415.0943396226415
|
|
|
55
55
|
});
|
|
56
56
|
]]></script>
|
|
57
57
|
</g>
|
|
58
|
-
<g transform="translate(
|
|
58
|
+
<g transform="translate(0, 1216)">
|
|
59
59
|
<style>
|
|
60
60
|
.boundary { fill: rgb(245, 241, 237); }
|
|
61
61
|
.schematic-boundary { fill: none; stroke: #fff; }
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<svg width="
|
|
1
|
+
<svg width="1200" height="2016" viewBox="0 0 1200 2016" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Solver debug visualization on top and Circuit JSON schematic on the bottom">
|
|
2
2
|
<g transform="translate(0, 0) scale(1.875, 1.875) translate(0, 0)">
|
|
3
3
|
<rect width="100%" height="100%" fill="white"/><g><polyline data-points="0.6000000000000001,-0.30000000000000004 2.435,0" data-type="line" data-label="" points="201.34453781512605,376.47058823529414 448.06722689075633,336.1344537815126" fill="none" stroke="hsl(48, 100%, 50%, 0.8)" stroke-width="1px"/></g><g><polyline data-points="0.6000000000000001,-0.30000000000000004 1.5175,-0.30000000000000004 1.5175,0 2.435,0" data-type="line" data-label="" points="201.34453781512605,376.47058823529414 324.7058823529412,376.47058823529414 324.7058823529412,336.1344537815126 448.06722689075633,336.1344537815126" fill="none" stroke="purple" stroke-width="1px"/></g><g><rect data-type="rect" data-label="schematic_component_0" data-x="0" data-y="0" x="40" y="268.9075630252101" width="161.34453781512605" height="134.45378151260502" fill="hsl(24, 100%, 50%, 0.8)" stroke="black" stroke-width="0.0074375"/></g><g><rect data-type="rect" data-label="schematic_component_1" data-x="3" data-y="0.13249999999999998" x="448.0672268907564" y="256.8067226890756" width="151.93277310924367" height="123.02521008403363" fill="hsl(24, 100%, 50%, 0.8)" stroke="black" stroke-width="0.0074375"/></g><g><rect data-type="rect" data-label="U1" data-x="-0.08000000000000002" data-y="0.615" x="85.7142857142857" y="236.6386554621849" width="48.40336134453783" height="33.613445378151255" fill="rgba(160, 0, 220, 0.14)" stroke="black" stroke-width="0.0074375"/></g><g><rect data-type="rect" data-label="INLINE netId: USER_LED_ANODE
|
|
4
4
|
axis: x
|
|
@@ -58,7 +58,7 @@ USER_LED_ANODE" data-x="1.5175" data-y="0" cx="324.7058823529412" cy="336.134453
|
|
|
58
58
|
});
|
|
59
59
|
]]></script>
|
|
60
60
|
</g>
|
|
61
|
-
<g transform="translate(
|
|
61
|
+
<g transform="translate(0, 1216)">
|
|
62
62
|
<style>
|
|
63
63
|
.boundary { fill: rgb(245, 241, 237); }
|
|
64
64
|
.schematic-boundary { fill: none; stroke: #fff; }
|
package/tests/solvers/InlineNetLabelSolver/__snapshots__/terminal-stub-trace-clearance.snap.svg
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<svg width="
|
|
1
|
+
<svg width="1200" height="2016" viewBox="0 0 1200 2016" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Solver debug visualization on top and Circuit JSON schematic on the bottom">
|
|
2
2
|
<g transform="translate(0, 0) scale(1.875, 1.875) translate(0, 0)">
|
|
3
3
|
<rect width="100%" height="100%" fill="white"/><g><polyline data-points="0.5,-0.1 1,-0.1 1,0.5" data-type="line" data-label="" points="413.33333333333337,394.66666666666663 600,394.66666666666663 600,170.66666666666666" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="0.5,0.3 0.95,0.3" data-type="line" data-label="" points="413.33333333333337,245.33333333333331 581.3333333333333,245.33333333333331" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="0.5,0.1 0.95,0.1" data-type="line" data-label="" points="413.33333333333337,320 581.3333333333333,320" fill="none" stroke="purple" stroke-width="1px"/></g><g><rect data-type="rect" data-label="U1" data-x="0" data-y="0.1" x="40" y="170.66666666666669" width="373.33333333333337" height="298.66666666666663" fill="hsl(164, 100%, 50%, 0.8)" stroke="black" stroke-width="0.0026785714285714286"/></g><g><rect data-type="rect" data-label="INLINE netId: SCL
|
|
4
4
|
axis: x
|
|
@@ -54,7 +54,7 @@ SDA" data-x="0.725" data-y="0.1" cx="497.3333333333333" cy="320" r="3" fill="gre
|
|
|
54
54
|
});
|
|
55
55
|
]]></script>
|
|
56
56
|
</g>
|
|
57
|
-
<g transform="translate(
|
|
57
|
+
<g transform="translate(0, 1216)">
|
|
58
58
|
<style>
|
|
59
59
|
.boundary { fill: rgb(245, 241, 237); }
|
|
60
60
|
.schematic-boundary { fill: none; stroke: #fff; }
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
import { expect, test } from "bun:test"
|
|
2
|
+
import { alignSameNetJunctions } from "lib/solvers/SameNetJunctionAlignmentSolver/alignSameNetJunctions"
|
|
3
|
+
import type { SolvedTracePath } from "lib/solvers/SchematicTraceLinesSolver/SchematicTraceLinesSolver"
|
|
4
|
+
import type { NetLabelPlacement } from "lib/solvers/NetLabelPlacementSolver/NetLabelPlacementSolver"
|
|
5
|
+
import { tracePathContainsPoint } from "lib/solvers/RailNetLabelCornerPlacementSolver/geometry"
|
|
6
|
+
import type { InputProblem } from "lib/types/InputProblem"
|
|
7
|
+
|
|
8
|
+
const createFixture = (mirrorX = 1, mirrorY = 1) => {
|
|
9
|
+
const point = (x: number, y: number) => ({ x: x * mirrorX, y: y * mirrorY })
|
|
10
|
+
const facing = mirrorY === 1 ? "y-" : "y+"
|
|
11
|
+
const pins: Array<SolvedTracePath["pins"][number]> = [
|
|
12
|
+
{ pinId: "A.1", chipId: "A", ...point(0, 1), _facingDirection: facing },
|
|
13
|
+
{ pinId: "B.1", chipId: "B", ...point(2, 1), _facingDirection: facing },
|
|
14
|
+
{ pinId: "C.1", chipId: "C", ...point(2, -1), _facingDirection: facing },
|
|
15
|
+
{
|
|
16
|
+
pinId: "U.1",
|
|
17
|
+
chipId: "U",
|
|
18
|
+
...point(3, 0.6),
|
|
19
|
+
_facingDirection: mirrorX === 1 ? "x-" : "x+",
|
|
20
|
+
},
|
|
21
|
+
]
|
|
22
|
+
const trace = (
|
|
23
|
+
id: string,
|
|
24
|
+
indexes: [number, number],
|
|
25
|
+
coordinates: number[][],
|
|
26
|
+
): SolvedTracePath => ({
|
|
27
|
+
mspPairId: id,
|
|
28
|
+
dcConnNetId: "rail",
|
|
29
|
+
globalConnNetId: "rail",
|
|
30
|
+
userNetId: "RAIL",
|
|
31
|
+
mspConnectionPairIds: [id],
|
|
32
|
+
pins: [pins[indexes[0]]!, pins[indexes[1]]!],
|
|
33
|
+
pinIds: indexes.map((index) => pins[index]!.pinId),
|
|
34
|
+
tracePath: coordinates.map(([x, y]) => point(x!, y!)),
|
|
35
|
+
})
|
|
36
|
+
const traces = [
|
|
37
|
+
trace(
|
|
38
|
+
"parallel",
|
|
39
|
+
[1, 0],
|
|
40
|
+
[
|
|
41
|
+
[2, 1],
|
|
42
|
+
[2, 0.8],
|
|
43
|
+
[0, 0.8],
|
|
44
|
+
[0, 1],
|
|
45
|
+
],
|
|
46
|
+
),
|
|
47
|
+
trace(
|
|
48
|
+
"supply",
|
|
49
|
+
[3, 1],
|
|
50
|
+
[
|
|
51
|
+
[3, 0.6],
|
|
52
|
+
[2, 0.6],
|
|
53
|
+
[2, 1],
|
|
54
|
+
],
|
|
55
|
+
),
|
|
56
|
+
trace(
|
|
57
|
+
"return",
|
|
58
|
+
[2, 1],
|
|
59
|
+
[
|
|
60
|
+
[2, -1],
|
|
61
|
+
[2, -1.2],
|
|
62
|
+
[1.2, -1.2],
|
|
63
|
+
[1.2, 0.8],
|
|
64
|
+
[2, 0.8],
|
|
65
|
+
[2, 1],
|
|
66
|
+
],
|
|
67
|
+
),
|
|
68
|
+
]
|
|
69
|
+
const inputProblem: InputProblem = {
|
|
70
|
+
chips: pins.map((pin, index) => ({
|
|
71
|
+
chipId: pin.chipId,
|
|
72
|
+
center:
|
|
73
|
+
index === 3 ? point(3.2, 0.6) : { x: pin.x, y: pin.y + 0.2 * mirrorY },
|
|
74
|
+
width: 0.4,
|
|
75
|
+
height: 0.4,
|
|
76
|
+
pins: [pin],
|
|
77
|
+
})),
|
|
78
|
+
directConnections: [],
|
|
79
|
+
netConnections: [],
|
|
80
|
+
availableNetLabelOrientations: {},
|
|
81
|
+
}
|
|
82
|
+
return {
|
|
83
|
+
inputProblem,
|
|
84
|
+
traces,
|
|
85
|
+
point,
|
|
86
|
+
netLabelPlacements: [] as NetLabelPlacement[],
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
for (const mirrorX of [1, -1]) {
|
|
91
|
+
for (const mirrorY of [1, -1]) {
|
|
92
|
+
test(`levels parallel rails and aligns return columns (${mirrorX}, ${mirrorY})`, () => {
|
|
93
|
+
const fixture = createFixture(mirrorX, mirrorY)
|
|
94
|
+
const before = structuredClone(fixture.traces)
|
|
95
|
+
const result = alignSameNetJunctions(fixture)
|
|
96
|
+
expect(result.alignedJunctionCount).toBe(2)
|
|
97
|
+
const parallel = result.traces.find(
|
|
98
|
+
(trace) => trace.mspPairId === "parallel",
|
|
99
|
+
)!
|
|
100
|
+
expect(parallel.tracePath).toEqual([
|
|
101
|
+
fixture.point(2, 1),
|
|
102
|
+
fixture.point(2, 0.6),
|
|
103
|
+
fixture.point(0, 0.6),
|
|
104
|
+
fixture.point(0, 1),
|
|
105
|
+
])
|
|
106
|
+
const branch = result.traces.find(
|
|
107
|
+
(trace) => trace.mspPairId === "return",
|
|
108
|
+
)!
|
|
109
|
+
expect(branch.tracePath).toEqual([
|
|
110
|
+
fixture.point(2, -1),
|
|
111
|
+
fixture.point(2, -1.2),
|
|
112
|
+
fixture.point(0, -1.2),
|
|
113
|
+
fixture.point(0, 0.6),
|
|
114
|
+
fixture.point(2, 0.6),
|
|
115
|
+
fixture.point(2, 1),
|
|
116
|
+
])
|
|
117
|
+
for (const trace of result.traces) {
|
|
118
|
+
expect(trace.tracePath[0]).toEqual({
|
|
119
|
+
x: trace.pins[0]!.x,
|
|
120
|
+
y: trace.pins[0]!.y,
|
|
121
|
+
})
|
|
122
|
+
expect(trace.tracePath.at(-1)).toEqual({
|
|
123
|
+
x: trace.pins[1]!.x,
|
|
124
|
+
y: trace.pins[1]!.y,
|
|
125
|
+
})
|
|
126
|
+
}
|
|
127
|
+
expect(fixture.traces).toEqual(before)
|
|
128
|
+
expect(
|
|
129
|
+
alignSameNetJunctions({ ...fixture, traces: result.traces }).traces,
|
|
130
|
+
).toEqual(result.traces)
|
|
131
|
+
})
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
test("reversing trace order and endpoints preserves the aligned geometry", () => {
|
|
136
|
+
const fixture = createFixture()
|
|
137
|
+
fixture.traces.reverse()
|
|
138
|
+
for (const trace of fixture.traces) {
|
|
139
|
+
trace.pins.reverse()
|
|
140
|
+
trace.pinIds.reverse()
|
|
141
|
+
trace.tracePath.reverse()
|
|
142
|
+
}
|
|
143
|
+
const result = alignSameNetJunctions(fixture)
|
|
144
|
+
expect(result.alignedJunctionCount).toBe(2)
|
|
145
|
+
const branch = result.traces.find((trace) => trace.mspPairId === "return")!
|
|
146
|
+
expect(
|
|
147
|
+
branch.tracePath.every((point) => point.x === 0 || point.x === 2),
|
|
148
|
+
).toBe(true)
|
|
149
|
+
})
|
|
150
|
+
|
|
151
|
+
test("does not route a return column through a component", () => {
|
|
152
|
+
const fixture = createFixture()
|
|
153
|
+
fixture.inputProblem.chips.push({
|
|
154
|
+
chipId: "obstacle",
|
|
155
|
+
center: { x: 0, y: 0 },
|
|
156
|
+
width: 0.2,
|
|
157
|
+
height: 0.2,
|
|
158
|
+
pins: [],
|
|
159
|
+
})
|
|
160
|
+
const original = structuredClone(fixture.traces[2]!)
|
|
161
|
+
const result = alignSameNetJunctions(fixture)
|
|
162
|
+
expect(result.traces.find((trace) => trace.mspPairId === "return")).toEqual(
|
|
163
|
+
original,
|
|
164
|
+
)
|
|
165
|
+
})
|
|
166
|
+
|
|
167
|
+
for (const [name, path] of [
|
|
168
|
+
[
|
|
169
|
+
"perpendicular",
|
|
170
|
+
[
|
|
171
|
+
{ x: -0.5, y: 0 },
|
|
172
|
+
{ x: 0.5, y: 0 },
|
|
173
|
+
],
|
|
174
|
+
],
|
|
175
|
+
[
|
|
176
|
+
"collinear",
|
|
177
|
+
[
|
|
178
|
+
{ x: 0, y: -0.5 },
|
|
179
|
+
{ x: 0, y: 0.3 },
|
|
180
|
+
],
|
|
181
|
+
],
|
|
182
|
+
] as const) {
|
|
183
|
+
test(`does not introduce a ${name} cross-net intersection`, () => {
|
|
184
|
+
const fixture = createFixture()
|
|
185
|
+
const original = structuredClone(fixture.traces[2]!)
|
|
186
|
+
fixture.traces.push({
|
|
187
|
+
...original,
|
|
188
|
+
mspPairId: "foreign",
|
|
189
|
+
globalConnNetId: "foreign",
|
|
190
|
+
tracePath: [...path],
|
|
191
|
+
})
|
|
192
|
+
const result = alignSameNetJunctions(fixture)
|
|
193
|
+
expect(result.traces.find((trace) => trace.mspPairId === "return")).toEqual(
|
|
194
|
+
original,
|
|
195
|
+
)
|
|
196
|
+
})
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
test("shortens the return escape when the original length would cross another net", () => {
|
|
200
|
+
const fixture = createFixture()
|
|
201
|
+
fixture.traces.push({
|
|
202
|
+
...fixture.traces[2]!,
|
|
203
|
+
mspPairId: "foreign",
|
|
204
|
+
globalConnNetId: "foreign",
|
|
205
|
+
tracePath: [
|
|
206
|
+
{ x: -0.5, y: -1.1 },
|
|
207
|
+
{ x: 1, y: -1.1 },
|
|
208
|
+
{ x: 1, y: -1.3 },
|
|
209
|
+
],
|
|
210
|
+
})
|
|
211
|
+
const result = alignSameNetJunctions(fixture)
|
|
212
|
+
const branch = result.traces.find((trace) => trace.mspPairId === "return")!
|
|
213
|
+
expect(
|
|
214
|
+
branch.tracePath.every((point) => point.x === 0 || point.x === 2),
|
|
215
|
+
).toBe(true)
|
|
216
|
+
expect(Math.min(...branch.tracePath.map((point) => point.y))).toBeCloseTo(
|
|
217
|
+
-1.05,
|
|
218
|
+
6,
|
|
219
|
+
)
|
|
220
|
+
})
|
|
221
|
+
|
|
222
|
+
test("keeps a label attached when the return branch moves", () => {
|
|
223
|
+
const fixture = createFixture()
|
|
224
|
+
fixture.netLabelPlacements.push({
|
|
225
|
+
globalConnNetId: "rail",
|
|
226
|
+
dcConnNetId: "rail",
|
|
227
|
+
netId: "RAIL",
|
|
228
|
+
mspConnectionPairIds: ["return"],
|
|
229
|
+
pinIds: ["C.1", "B.1"],
|
|
230
|
+
anchorPoint: { x: 1.2, y: 0 },
|
|
231
|
+
center: { x: 1.1, y: 0 },
|
|
232
|
+
width: 0.2,
|
|
233
|
+
height: 0.1,
|
|
234
|
+
orientation: "x-",
|
|
235
|
+
})
|
|
236
|
+
const result = alignSameNetJunctions(fixture)
|
|
237
|
+
const branch = result.traces.find((trace) => trace.mspPairId === "return")!
|
|
238
|
+
expect(
|
|
239
|
+
branch.tracePath.every((point) => point.x === 0 || point.x === 2),
|
|
240
|
+
).toBe(true)
|
|
241
|
+
expect(
|
|
242
|
+
tracePathContainsPoint(
|
|
243
|
+
branch.tracePath,
|
|
244
|
+
result.netLabelPlacements[0]!.anchorPoint,
|
|
245
|
+
),
|
|
246
|
+
).toBe(true)
|
|
247
|
+
})
|
|
248
|
+
|
|
249
|
+
test("does not combine rails belonging to different nets", () => {
|
|
250
|
+
const fixture = createFixture()
|
|
251
|
+
fixture.traces[2]!.globalConnNetId = "different"
|
|
252
|
+
const original = structuredClone(fixture.traces[2]!)
|
|
253
|
+
const result = alignSameNetJunctions(fixture)
|
|
254
|
+
expect(result.traces.find((trace) => trace.mspPairId === "return")).toEqual(
|
|
255
|
+
original,
|
|
256
|
+
)
|
|
257
|
+
})
|
|
258
|
+
|
|
259
|
+
test("does not force an outer return column onto staggered load pins", () => {
|
|
260
|
+
const fixture = createFixture()
|
|
261
|
+
fixture.traces[0]!.pins[1].y = 1.4
|
|
262
|
+
fixture.traces[0]!.tracePath.at(-1)!.y = 1.4
|
|
263
|
+
const original = structuredClone(fixture.traces[2]!)
|
|
264
|
+
const result = alignSameNetJunctions(fixture)
|
|
265
|
+
expect(result.traces.find((trace) => trace.mspPairId === "return")).toEqual(
|
|
266
|
+
original,
|
|
267
|
+
)
|
|
268
|
+
})
|
|
269
|
+
|
|
270
|
+
for (const net of ["rail", "foreign"]) {
|
|
271
|
+
test(`does not enter a ${net} label while extending the return column`, () => {
|
|
272
|
+
const fixture = createFixture()
|
|
273
|
+
fixture.netLabelPlacements.push({
|
|
274
|
+
globalConnNetId: net,
|
|
275
|
+
dcConnNetId: net,
|
|
276
|
+
netId: net,
|
|
277
|
+
mspConnectionPairIds: [],
|
|
278
|
+
pinIds: [],
|
|
279
|
+
orientation: "x+",
|
|
280
|
+
anchorPoint: { x: -0.1, y: 0 },
|
|
281
|
+
center: { x: 0, y: 0 },
|
|
282
|
+
width: 0.2,
|
|
283
|
+
height: 0.2,
|
|
284
|
+
})
|
|
285
|
+
const original = structuredClone(fixture.traces[2]!)
|
|
286
|
+
const result = alignSameNetJunctions(fixture)
|
|
287
|
+
expect(result.traces.find((trace) => trace.mspPairId === "return")).toEqual(
|
|
288
|
+
original,
|
|
289
|
+
)
|
|
290
|
+
})
|
|
291
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<svg width="
|
|
1
|
+
<svg width="1200" height="2016" viewBox="0 0 1200 2016" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Solver debug visualization on top and Circuit JSON schematic on the bottom">
|
|
2
2
|
<g transform="translate(0, 0) scale(1.875, 1.875) translate(0, 0)">
|
|
3
3
|
<rect width="100%" height="100%" fill="white"/><g><polyline data-points="1.15,-0.30000000000000004 1.8499999999999996,-0.3000000000000007" data-type="line" data-label="" points="336.1256544502618,395.86387434554973 387.43455497382195,395.8638743455498" fill="none" stroke="hsl(160, 100%, 50%, 0.1)" stroke-width="1px"/></g><g><polyline data-points="2.95,-0.3000000000000007 3.6500000000000004,-0.3000000000000007" data-type="line" data-label="" points="468.0628272251309,395.8638743455498 519.3717277486911,395.8638743455498" fill="none" stroke="hsl(48, 100%, 50%, 0.1)" stroke-width="1px"/></g><g><polyline data-points="-1.15,0.30000000000000004 -1.1500000000000004,1.15" data-type="line" data-label="" points="167.5392670157068,351.8848167539267 167.5392670157068,289.58115183246076" fill="none" stroke="hsl(280, 100%, 50%, 0.1)" stroke-width="1px"/></g><g><polyline data-points="-1.15,0.10000000000000003 -1.85,0.10000000000000002" data-type="line" data-label="" points="167.5392670157068,366.5445026178011 116.2303664921466,366.5445026178011" fill="none" stroke="hsl(48, 100%, 50%, 0.1)" stroke-width="1px"/></g><g><polyline data-points="-1.15,0.30000000000000004 -1.3499999999999999,0.30000000000000004 -1.3499999999999999,0.7250000000000001 -1.1500000000000004,0.7250000000000001 -1.1500000000000004,1.15" data-type="line" data-label="" points="167.5392670157068,351.8848167539267 152.87958115183247,351.8848167539267 152.87958115183247,320.73298429319374 167.5392670157068,320.73298429319374 167.5392670157068,289.58115183246076" fill="none" stroke="red" stroke-width="1px" stroke-dasharray="4 4"/></g><g><polyline data-points="-1.15,0.30000000000000004 -1.1500000000000004,1.15" data-type="line" data-label="" points="167.5392670157068,351.8848167539267 167.5392670157068,289.58115183246076" fill="none" stroke="blue" stroke-width="1px" stroke-dasharray="5 5"/></g><g><polyline data-points="-1.15,0.30000000000000004 -1.3499999999999999,0.30000000000000004 -1.3499999999999999,0.7250000000000001 -1.1500000000000004,0.7250000000000001 -1.1500000000000004,1.15" data-type="line" data-label="" points="167.5392670157068,351.8848167539267 152.87958115183247,351.8848167539267 152.87958115183247,320.73298429319374 167.5392670157068,320.73298429319374 167.5392670157068,289.58115183246076" fill="none" stroke="green" stroke-width="1px"/></g><g><rect data-type="rect" data-label="schematic_component_0" data-x="0" data-y="0" x="167.5392670157068" y="337.22513089005236" width="168.58638743455498" height="73.29842931937173" fill="hsl(24, 100%, 50%, 0.1)" stroke="black" stroke-width="0.013642857142857144"/></g><g><rect data-type="rect" data-label="schematic_component_1" data-x="-1.1500000000000004" data-y="1.6700000000000002" x="129.4240837696335" y="213.3507853403141" width="76.2303664921466" height="76.23036649214663" fill="hsl(24, 100%, 50%, 0.1)" stroke="black" stroke-width="0.013642857142857144"/></g><g><rect data-type="rect" data-label="schematic_component_2" data-x="-2.37" data-y="0.10000000000000009" x="40.000000000000014" y="346.75392670157066" width="76.2303664921466" height="39.58115183246076" fill="hsl(24, 100%, 50%, 0.1)" stroke="black" stroke-width="0.013642857142857144"/></g><g><rect data-type="rect" data-label="schematic_component_3" data-x="2.4" data-y="-0.3000000000000007" x="387.43455497382195" y="365.07853403141365" width="80.62827225130894" height="61.57068062827227" fill="hsl(24, 100%, 50%, 0.1)" stroke="black" stroke-width="0.013642857142857144"/></g><g><rect data-type="rect" data-label="schematic_component_4" data-x="4.2" data-y="-0.3000000000000007" x="519.371727748691" y="365.07853403141365" width="80.62827225130889" height="61.57068062827227" fill="hsl(24, 100%, 50%, 0.1)" stroke="black" stroke-width="0.013642857142857144"/></g><g><circle data-type="point" data-label="U1.1
|
|
4
4
|
x-" data-x="-1.15" data-y="0.30000000000000004" cx="167.5392670157068" cy="351.8848167539267" r="3" fill="hsl(319, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.2
|
|
@@ -61,7 +61,7 @@ x+" data-x="4.75" data-y="-0.3000000000000007" cx="600" cy="395.8638743455498" r
|
|
|
61
61
|
});
|
|
62
62
|
]]></script>
|
|
63
63
|
</g>
|
|
64
|
-
<g transform="translate(
|
|
64
|
+
<g transform="translate(0, 1216)">
|
|
65
65
|
<style>
|
|
66
66
|
.boundary { fill: rgb(245, 241, 237); }
|
|
67
67
|
.schematic-boundary { fill: none; stroke: #fff; }
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<svg width="
|
|
1
|
+
<svg width="1200" height="2016" viewBox="0 0 1200 2016" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Solver debug visualization on top and Circuit JSON schematic on the bottom">
|
|
2
2
|
<g transform="translate(0, 0) scale(1.875, 1.875) translate(0, 0)">
|
|
3
3
|
<rect width="100%" height="100%" fill="white"/><g><polyline data-points="3.4,0.095 3.61,0.045" data-type="line" data-label="" points="261.78217821782187,306.13861386138615 378.21782178217813,333.86138613861385" fill="none" stroke="hsl(112, 100%, 50%, 0.1)" stroke-width="1px"/></g><g><polyline data-points="3.4,0.095 3.465,0.095 3.505,0.095 3.505,0.045 3.545,0.045 3.61,0.045" data-type="line" data-label="" points="261.78217821782187,306.13861386138615 297.82178217821775,306.13861386138615 320,306.13861386138615 320,333.86138613861385 342.17821782178225,333.86138613861385 378.21782178217813,333.86138613861385" fill="none" stroke="red" stroke-width="1px" stroke-dasharray="4 4"/></g><g><polyline data-points="3.4,0.095 3.61,0.045" data-type="line" data-label="" points="261.78217821782187,306.13861386138615 378.21782178217813,333.86138613861385" fill="none" stroke="blue" stroke-width="1px" stroke-dasharray="5 5"/></g><g><polyline data-points="3.4,0.095 3.465,0.095 3.505,0.095 3.505,0.045 3.545,0.045 3.61,0.045" data-type="line" data-label="" points="261.78217821782187,306.13861386138615 297.82178217821775,306.13861386138615 320,306.13861386138615 320,333.86138613861385 342.17821782178225,333.86138613861385 378.21782178217813,333.86138613861385" fill="none" stroke="green" stroke-width="1px"/></g><g><rect data-type="rect" data-label="D2" data-x="3.2" data-y="0.095" x="40" y="250.69306930693068" width="221.7821782178221" height="110.89108910891093" fill="hsl(358, 100%, 50%, 0.1)" stroke="black" stroke-width="0.0018035714285714283"/></g><g><rect data-type="rect" data-label="SW2" data-x="3.81" data-y="0.045" x="378.21782178217825" y="278.41584158415844" width="221.78217821782187" height="110.89108910891088" fill="hsl(70, 100%, 50%, 0.1)" stroke="black" stroke-width="0.0018035714285714283"/></g><g><circle data-type="point" data-label="D2.cathode
|
|
4
4
|
x+" data-x="3.4" data-y="0.095" cx="261.78217821782187" cy="306.13861386138615" r="3" fill="hsl(22, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="SW2.pin1
|
|
@@ -47,7 +47,7 @@ x-" data-x="3.61" data-y="0.045" cx="378.21782178217813" cy="333.86138613861385"
|
|
|
47
47
|
});
|
|
48
48
|
]]></script>
|
|
49
49
|
</g>
|
|
50
|
-
<g transform="translate(
|
|
50
|
+
<g transform="translate(0, 1216)">
|
|
51
51
|
<style>
|
|
52
52
|
.boundary { fill: rgb(245, 241, 237); }
|
|
53
53
|
.schematic-boundary { fill: none; stroke: #fff; }
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<svg width="
|
|
1
|
+
<svg width="1200" height="2016" viewBox="0 0 1200 2016" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Solver debug visualization on top and Circuit JSON schematic on the bottom">
|
|
2
2
|
<g transform="translate(0, 0) scale(1.875, 1.875) translate(0, 0)">
|
|
3
3
|
<rect width="100%" height="100%" fill="white"/><g><polyline data-points="1.2000000000000002,-0.30000000000000004 1.6,-2.295" data-type="line" data-label="" points="308.80000000000007,241.88 353.6,465.31999999999994" fill="none" stroke="hsl(157, 100%, 50%, 0.1)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="1.2000000000000002,0.30000000000000004 1.6,-1.895" data-type="line" data-label="" points="308.80000000000007,174.68 353.6,420.52" fill="none" stroke="hsl(190, 100%, 50%, 0.1)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="1.2000000000000002,-0.30000000000000004 1.4000000000000001,-0.30000000000000004 1.4000000000000001,-1.2975000000000003 1.049,-1.2975000000000003 1.049,-2.2950000000000004 1.6,-2.295" data-type="line" data-label="" points="308.80000000000007,241.88 331.20000000000005,241.88 331.20000000000005,353.6 291.88800000000003,353.6 291.88800000000003,465.32000000000005 353.6,465.31999999999994" fill="none" stroke="red" stroke-width="1px"/></g><g><rect data-type="rect" data-label="schematic_component_0" data-x="0" data-y="0" x="40" y="152.28000000000003" width="268.80000000000007" height="111.99999999999997" fill="hsl(24, 100%, 50%, 0.1)" stroke="black" stroke-width="0.008928571428571428"/></g><g><rect data-type="rect" data-label="schematic_component_1" data-x="2.7" data-y="-2.095" x="353.6000000000001" y="398.12" width="246.39999999999998" height="89.60000000000002" fill="hsl(24, 100%, 50%, 0.1)" stroke="black" stroke-width="0.008928571428571428"/></g><g><circle data-type="point" data-label="U1.1
|
|
4
4
|
x+" data-x="1.2000000000000002" data-y="-0.30000000000000004" cx="308.80000000000007" cy="241.88" r="3" fill="hsl(319, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.2
|
|
@@ -56,7 +56,7 @@ x-" data-x="1.6" data-y="-2.295" cx="353.6" cy="465.31999999999994" r="3" fill="
|
|
|
56
56
|
});
|
|
57
57
|
]]></script>
|
|
58
58
|
</g>
|
|
59
|
-
<g transform="translate(
|
|
59
|
+
<g transform="translate(0, 1216)">
|
|
60
60
|
<style>
|
|
61
61
|
.boundary { fill: rgb(245, 241, 237); }
|
|
62
62
|
.schematic-boundary { fill: none; stroke: #fff; }
|