@tscircuit/schematic-trace-solver 0.0.104 → 0.0.106
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 +133 -80
- package/lib/solvers/TraceCleanupSolver/minimizeTurnsWithFilteredLabels.ts +78 -23
- package/lib/solvers/TraceCleanupSolver/sameNetRailAlignment/geometry.ts +40 -20
- package/package.json +1 -1
- package/site/bug-reports/bug-report-20260721T221026Z.page.tsx +4 -0
- package/tests/bug-reports/bug-report-20260721T221026Z/__snapshots__/bug-report-20260721T221026Z.snap.svg +345 -0
- package/tests/bug-reports/bug-report-20260721T221026Z/bug-report-20260721T221026Z.json +1750 -0
- package/tests/bug-reports/bug-report-20260721T221026Z/bug-report-20260721T221026Z.test.ts +12 -0
- package/tests/examples/__snapshots__/example19.snap.svg +3 -3
- package/tests/examples/example19.test.ts +4 -0
- package/tests/repros/__snapshots__/bugreport-001-gnd-overlap.snap.svg +1 -1
- package/tests/repros/__snapshots__/repro-core-subcircuit-missing-ground.snap.svg +56 -0
- package/tests/repros/__snapshots__/repro-example35-minimize-trace-crossing.snap.svg +256 -0
- package/tests/repros/__snapshots__/repro-vcc-pin1-detour.snap.svg +47 -0
- package/tests/repros/assets/repro-core-subcircuit-missing-ground.input.json +103 -0
- package/tests/repros/assets/repro-example35-minimize-trace-crossing.input.json +1561 -0
- package/tests/repros/repro-core-subcircuit-missing-ground.test.ts +14 -0
- package/tests/repros/repro-example35-minimize-trace-crossing.test.ts +22 -0
- package/tests/repros/repro-vcc-pin1-detour.test.ts +166 -0
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { expect, test } from "bun:test"
|
|
2
|
+
import { SchematicTracePipelineSolver } from "lib/solvers/SchematicTracePipelineSolver/SchematicTracePipelineSolver"
|
|
3
|
+
import "tests/fixtures/matcher"
|
|
4
|
+
import inputProblem from "./assets/repro-core-subcircuit-missing-ground.input.json"
|
|
5
|
+
|
|
6
|
+
// Captured from @tscircuit/core main repro154: two crossed connections enter
|
|
7
|
+
// the solver, but only the VOUT_3V3-to-3V3 connection is routed.
|
|
8
|
+
test("core repro154 omits one of two crossed subcircuit connections", () => {
|
|
9
|
+
const solver = new SchematicTracePipelineSolver(inputProblem as any)
|
|
10
|
+
|
|
11
|
+
solver.solve()
|
|
12
|
+
|
|
13
|
+
expect(solver).toMatchSolverSnapshot(import.meta.path)
|
|
14
|
+
})
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { expect, test } from "bun:test"
|
|
2
|
+
import { SchematicTracePipelineSolver } from "lib/solvers/SchematicTracePipelineSolver/SchematicTracePipelineSolver"
|
|
3
|
+
import inputProblem from "./assets/repro-example35-minimize-trace-crossing.input.json"
|
|
4
|
+
import "tests/fixtures/matcher"
|
|
5
|
+
|
|
6
|
+
test("example35 keeps capacitor-chain zig-zags aligned with same-net branches", () => {
|
|
7
|
+
const solver = new SchematicTracePipelineSolver(inputProblem as any)
|
|
8
|
+
|
|
9
|
+
solver.solve()
|
|
10
|
+
|
|
11
|
+
const trace = solver
|
|
12
|
+
.netLabelTraceCollisionSolver!.getOutput()
|
|
13
|
+
.traces.find((candidate) => candidate.mspPairId === "C5.1-C4.2")
|
|
14
|
+
|
|
15
|
+
expect(trace?.tracePath).toEqual([
|
|
16
|
+
{ x: -4, y: -2.6199999999999997 },
|
|
17
|
+
{ x: -4, y: -1.9999999999999996 },
|
|
18
|
+
{ x: -3, y: -1.9999999999999996 },
|
|
19
|
+
{ x: -3, y: -1.38 },
|
|
20
|
+
])
|
|
21
|
+
expect(solver).toMatchSolverSnapshot(import.meta.path)
|
|
22
|
+
})
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { expect, test } from "bun:test"
|
|
2
|
+
import type { NetLabelPlacement } from "lib/solvers/NetLabelPlacementSolver/NetLabelPlacementSolver"
|
|
3
|
+
import type { SolvedTracePath } from "lib/solvers/SchematicTraceLinesSolver/SchematicTraceLinesSolver"
|
|
4
|
+
import { TraceCleanupSolver } from "lib/solvers/TraceCleanupSolver/TraceCleanupSolver"
|
|
5
|
+
import type { InputPin, InputProblem } from "lib/types/InputProblem"
|
|
6
|
+
import "tests/fixtures/matcher"
|
|
7
|
+
|
|
8
|
+
const inputProblem: InputProblem = {
|
|
9
|
+
chips: [
|
|
10
|
+
{
|
|
11
|
+
chipId: "J1",
|
|
12
|
+
center: { x: -1.8, y: 0.5 },
|
|
13
|
+
width: 0.6,
|
|
14
|
+
height: 0.4,
|
|
15
|
+
pins: [
|
|
16
|
+
{
|
|
17
|
+
pinId: "J1.1",
|
|
18
|
+
x: -1.5,
|
|
19
|
+
y: 0.5,
|
|
20
|
+
_facingDirection: "x+",
|
|
21
|
+
},
|
|
22
|
+
],
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
chipId: "U1",
|
|
26
|
+
center: { x: 0, y: 0.25 },
|
|
27
|
+
width: 1,
|
|
28
|
+
height: 1.5,
|
|
29
|
+
pins: [
|
|
30
|
+
{
|
|
31
|
+
pinId: "U1.1",
|
|
32
|
+
x: -0.5,
|
|
33
|
+
y: 0.5,
|
|
34
|
+
_facingDirection: "x-",
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
pinId: "U1.6",
|
|
38
|
+
x: -0.5,
|
|
39
|
+
y: 0,
|
|
40
|
+
_facingDirection: "x-",
|
|
41
|
+
},
|
|
42
|
+
],
|
|
43
|
+
},
|
|
44
|
+
],
|
|
45
|
+
directConnections: [],
|
|
46
|
+
netConnections: [
|
|
47
|
+
{
|
|
48
|
+
netId: "VCC",
|
|
49
|
+
pinIds: ["J1.1", "U1.1", "U1.6"],
|
|
50
|
+
netLabelWidth: 0.48,
|
|
51
|
+
netLabelHeight: 0.42,
|
|
52
|
+
},
|
|
53
|
+
],
|
|
54
|
+
textBoxes: [],
|
|
55
|
+
availableNetLabelOrientations: { VCC: ["y+"] },
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const pin = (chipId: "J1" | "U1", pinId: string) => ({
|
|
59
|
+
...inputProblem.chips
|
|
60
|
+
.find((chip) => chip.chipId === chipId)!
|
|
61
|
+
.pins.find((candidate) => candidate.pinId === pinId)!,
|
|
62
|
+
chipId,
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
const createTrace = ({
|
|
66
|
+
mspPairId,
|
|
67
|
+
pins,
|
|
68
|
+
tracePath,
|
|
69
|
+
globalConnNetId = "vcc-net",
|
|
70
|
+
userNetId = "VCC",
|
|
71
|
+
}: {
|
|
72
|
+
mspPairId: string
|
|
73
|
+
pins: [InputPin & { chipId: string }, InputPin & { chipId: string }]
|
|
74
|
+
tracePath: SolvedTracePath["tracePath"]
|
|
75
|
+
globalConnNetId?: string
|
|
76
|
+
userNetId?: string
|
|
77
|
+
}): SolvedTracePath => ({
|
|
78
|
+
mspPairId,
|
|
79
|
+
dcConnNetId: globalConnNetId,
|
|
80
|
+
globalConnNetId,
|
|
81
|
+
userNetId,
|
|
82
|
+
pins,
|
|
83
|
+
tracePath,
|
|
84
|
+
mspConnectionPairIds: [mspPairId],
|
|
85
|
+
pinIds: pins.map((candidate) => candidate.pinId),
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
const pin1Detour = createTrace({
|
|
89
|
+
mspPairId: "U1.1-J1.1",
|
|
90
|
+
pins: [pin("U1", "U1.1"), pin("J1", "J1.1")],
|
|
91
|
+
tracePath: [
|
|
92
|
+
{ x: -0.5, y: 0.5 },
|
|
93
|
+
{ x: -0.7, y: 0.5 },
|
|
94
|
+
{ x: -0.7, y: 0.9 },
|
|
95
|
+
{ x: -1.3, y: 0.9 },
|
|
96
|
+
{ x: -1.3, y: 0.5 },
|
|
97
|
+
{ x: -1.5, y: 0.5 },
|
|
98
|
+
],
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
const pin6Branch = createTrace({
|
|
102
|
+
mspPairId: "U1.6-J1.1",
|
|
103
|
+
pins: [pin("U1", "U1.6"), pin("J1", "J1.1")],
|
|
104
|
+
tracePath: [
|
|
105
|
+
{ x: -0.5, y: 0 },
|
|
106
|
+
{ x: -1.3, y: 0 },
|
|
107
|
+
{ x: -1.3, y: 0.5 },
|
|
108
|
+
{ x: -1.5, y: 0.5 },
|
|
109
|
+
],
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
const vccLabel: NetLabelPlacement = {
|
|
113
|
+
globalConnNetId: "vcc-net",
|
|
114
|
+
dcConnNetId: "vcc-net",
|
|
115
|
+
netId: "VCC",
|
|
116
|
+
mspConnectionPairIds: [pin1Detour.mspPairId, pin6Branch.mspPairId],
|
|
117
|
+
pinIds: ["J1.1", "U1.1", "U1.6"],
|
|
118
|
+
orientation: "y+",
|
|
119
|
+
anchorPoint: { x: -1.3, y: 0.5 },
|
|
120
|
+
center: { x: -1.3, y: 0.74 },
|
|
121
|
+
width: 0.42,
|
|
122
|
+
height: 0.48,
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const createSolver = (traces: SolvedTracePath[]) =>
|
|
126
|
+
new TraceCleanupSolver({
|
|
127
|
+
inputProblem,
|
|
128
|
+
allTraces: traces,
|
|
129
|
+
allLabelPlacements: [vccLabel],
|
|
130
|
+
mergedLabelNetIdMap: {},
|
|
131
|
+
paddingBuffer: 0.1,
|
|
132
|
+
operations: ["minimizing_turns"],
|
|
133
|
+
})
|
|
134
|
+
|
|
135
|
+
test("VCC pin 1 routes directly left through its same-net branch", () => {
|
|
136
|
+
const solver = createSolver([pin1Detour, pin6Branch])
|
|
137
|
+
|
|
138
|
+
solver.solve()
|
|
139
|
+
|
|
140
|
+
const pin1Trace = solver
|
|
141
|
+
.getOutput()
|
|
142
|
+
.traces.find((trace) => trace.mspPairId === pin1Detour.mspPairId)!
|
|
143
|
+
expect(pin1Trace.tracePath).toEqual([
|
|
144
|
+
{ x: -0.5, y: 0.5 },
|
|
145
|
+
{ x: -1.5, y: 0.5 },
|
|
146
|
+
])
|
|
147
|
+
expect(solver).toMatchSolverSnapshot(import.meta.path)
|
|
148
|
+
})
|
|
149
|
+
|
|
150
|
+
test("pin 1 keeps the detour when the blocking branch is another net", () => {
|
|
151
|
+
const signalBranch = {
|
|
152
|
+
...pin6Branch,
|
|
153
|
+
mspPairId: "signal-branch",
|
|
154
|
+
dcConnNetId: "signal-net",
|
|
155
|
+
globalConnNetId: "signal-net",
|
|
156
|
+
userNetId: "SIGNAL",
|
|
157
|
+
}
|
|
158
|
+
const solver = createSolver([pin1Detour, signalBranch])
|
|
159
|
+
|
|
160
|
+
solver.solve()
|
|
161
|
+
|
|
162
|
+
const pin1Trace = solver
|
|
163
|
+
.getOutput()
|
|
164
|
+
.traces.find((trace) => trace.mspPairId === pin1Detour.mspPairId)!
|
|
165
|
+
expect(pin1Trace.tracePath).toEqual(pin1Detour.tracePath)
|
|
166
|
+
})
|