@tscircuit/fanout-solver 0.0.21 → 0.0.23
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/README.md +15 -0
- package/lib/build-output.ts +30 -12
- package/lib/complete-original-endpoints.ts +1208 -0
- package/lib/fanout-solver.ts +150 -20
- package/lib/index.ts +4 -0
- package/lib/route-bus.ts +339 -87
- package/lib/route-single-layer-adaptive-exits.ts +1 -0
- package/lib/route-single-layer-push-shove.ts +1 -0
- package/lib/types.ts +50 -0
- package/lib/validate-fanout-solution.ts +152 -79
- package/lib/validate-original-endpoint-connectivity.ts +42 -1
- package/lib/validate-routed-copper-drc.ts +23 -2
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -64,6 +64,9 @@ and treats each bus-layer decision atomically.
|
|
|
64
64
|
- `compactBusTracks` bends each bus into a trace/clearance-pitch routing
|
|
65
65
|
envelope, so a wide pad row does not consume a disproportionately wide
|
|
66
66
|
breakout corridor.
|
|
67
|
+
- `preferOriginalEndpointTracks` projects boundary tracks onto the original
|
|
68
|
+
downstream pad coordinates and prefers their layer when legal. This lets
|
|
69
|
+
ordered edge-pad buses make direct, visibly continuous pad connections.
|
|
67
70
|
- Chamfers orthogonal routing corners into 45° segments before validating and
|
|
68
71
|
emitting the fanout.
|
|
69
72
|
- Verifies oriented-pad, via, trace, and already-routed fanout clearance on
|
|
@@ -77,6 +80,13 @@ and treats each bus-layer decision atomically.
|
|
|
77
80
|
opt-in; different electrical nets remain hard obstacles.
|
|
78
81
|
- Audits route continuity, unique connection coverage, boundary exits, and
|
|
79
82
|
retained downstream endpoints before marking a solution complete.
|
|
83
|
+
- `completeOriginalEndpoints` adds a bounded fail-first completion stage after
|
|
84
|
+
fanout. It first places DRC-gated interstitial capacitor escapes, then tries
|
|
85
|
+
breakout-to-pad routes with layer transitions at interior points along the
|
|
86
|
+
existing fanout copper, and finally a bounded capacity-router fallback. Vias
|
|
87
|
+
at original or moved routing endpoints are rejected. A candidate is retained
|
|
88
|
+
only when it improves independently proven original endpoint connectivity
|
|
89
|
+
and the complete emitted copper remains DRC-clean.
|
|
80
90
|
- Emits supplied fanout traces, via obstacles, and moved breakout endpoints in a
|
|
81
91
|
new `SimpleRouteJson`. The returned problem is ready for a downstream
|
|
82
92
|
autorouter to finish.
|
|
@@ -115,6 +125,7 @@ const fanoutSolver = new FanoutSolver(simpleRouteJson, {
|
|
|
115
125
|
availableCornersAndSides: ["top_left", "top", "top_right"],
|
|
116
126
|
borderDistribution: "even",
|
|
117
127
|
compactBusTracks: true,
|
|
128
|
+
preferOriginalEndpointTracks: true,
|
|
118
129
|
buses: [
|
|
119
130
|
{
|
|
120
131
|
busId: "ground",
|
|
@@ -186,6 +197,10 @@ bus-layer combination search.
|
|
|
186
197
|
|
|
187
198
|
- `simpleRouteJson`: the downstream routing problem with fanout prefixes
|
|
188
199
|
- `fanoutTraces`: the newly supplied pad-to-breakout traces
|
|
200
|
+
- `completionTraces`: optional DRC-gated traces from breakouts to original
|
|
201
|
+
endpoints
|
|
202
|
+
- `endpointCompletion`: optional independent connectivity/DRC reports and
|
|
203
|
+
bounded-search diagnostics
|
|
189
204
|
- `planeTerminations`: the completed local-via connection, layer, and via data
|
|
190
205
|
- `busLayerAssignments`: the selected layer for every bus
|
|
191
206
|
- `busDirections`: the direction shared by each bus
|
package/lib/build-output.ts
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import type { Obstacle, SimpleRouteJson } from "@tscircuit/capacity-autorouter"
|
|
2
|
-
import type { FanoutRoutePlan } from "./types"
|
|
2
|
+
import type { FanoutRoutePlan, SimpleRouteJsonWithFanoutPlanes } from "./types"
|
|
3
3
|
|
|
4
4
|
function createViaObstacle(
|
|
5
5
|
plan: FanoutRoutePlan,
|
|
6
6
|
layerNames: string[],
|
|
7
|
+
endpoint = false,
|
|
7
8
|
): Obstacle | null {
|
|
8
|
-
|
|
9
|
-
|
|
9
|
+
const via = endpoint ? plan.planeEndpointVia : plan.via
|
|
10
|
+
if (!via) return null
|
|
11
|
+
const zLayers = via.spanLayers.map((layer) => {
|
|
10
12
|
const layerIndex = layerNames.indexOf(layer)
|
|
11
13
|
if (layerIndex < 0) {
|
|
12
14
|
throw new Error(
|
|
@@ -16,12 +18,12 @@ function createViaObstacle(
|
|
|
16
18
|
return layerIndex
|
|
17
19
|
})
|
|
18
20
|
return {
|
|
19
|
-
obstacleId:
|
|
21
|
+
obstacleId: `${endpoint ? "fanout-plane-endpoint-via" : "fanout-via"}:${plan.connectionName}`,
|
|
20
22
|
type: "rect",
|
|
21
|
-
center:
|
|
22
|
-
width:
|
|
23
|
-
height:
|
|
24
|
-
layers:
|
|
23
|
+
center: via.center,
|
|
24
|
+
width: via.diameter,
|
|
25
|
+
height: via.diameter,
|
|
26
|
+
layers: via.spanLayers,
|
|
25
27
|
zLayers,
|
|
26
28
|
__zLayers: zLayers,
|
|
27
29
|
connectedTo: [plan.connectionName, plan.trace.pcb_trace_id],
|
|
@@ -32,7 +34,7 @@ export function buildOutputSimpleRouteJson(params: {
|
|
|
32
34
|
inputSrj: SimpleRouteJson
|
|
33
35
|
plans: FanoutRoutePlan[]
|
|
34
36
|
layerNames: string[]
|
|
35
|
-
}):
|
|
37
|
+
}): SimpleRouteJsonWithFanoutPlanes {
|
|
36
38
|
const { inputSrj, plans, layerNames } = params
|
|
37
39
|
const outputConnections = inputSrj.connections.map((connection) => ({
|
|
38
40
|
...connection,
|
|
@@ -62,9 +64,15 @@ export function buildOutputSimpleRouteJson(params: {
|
|
|
62
64
|
}
|
|
63
65
|
const viaObstacle = createViaObstacle(plan, layerNames)
|
|
64
66
|
if (viaObstacle) viaObstacles.push(viaObstacle)
|
|
67
|
+
const endpointViaObstacle = createViaObstacle(plan, layerNames, true)
|
|
68
|
+
if (endpointViaObstacle) viaObstacles.push(endpointViaObstacle)
|
|
65
69
|
}
|
|
66
|
-
const
|
|
67
|
-
plan.trace
|
|
70
|
+
const planTraces = plans.flatMap((plan) => [
|
|
71
|
+
plan.trace,
|
|
72
|
+
...(plan.planeEndpointTrace ? [plan.planeEndpointTrace] : []),
|
|
73
|
+
])
|
|
74
|
+
const coordinateRoutePoints = planTraces.flatMap((trace) =>
|
|
75
|
+
trace.route.filter(
|
|
68
76
|
(
|
|
69
77
|
routePoint,
|
|
70
78
|
): routePoint is Extract<typeof routePoint, { x: number; y: number }> =>
|
|
@@ -107,6 +115,16 @@ export function buildOutputSimpleRouteJson(params: {
|
|
|
107
115
|
|
|
108
116
|
return {
|
|
109
117
|
...inputSrj,
|
|
118
|
+
fanoutPlaneConnectivity: plans.flatMap((plan) =>
|
|
119
|
+
plan.termination.type === "plane"
|
|
120
|
+
? [
|
|
121
|
+
{
|
|
122
|
+
connectionName: plan.connectionName,
|
|
123
|
+
layer: plan.termination.layer,
|
|
124
|
+
},
|
|
125
|
+
]
|
|
126
|
+
: [],
|
|
127
|
+
),
|
|
110
128
|
bounds: outputBounds,
|
|
111
129
|
connections: outputConnections.filter(
|
|
112
130
|
(connection) => !planeTerminatedConnectionNames.has(connection.name),
|
|
@@ -134,7 +152,7 @@ export function buildOutputSimpleRouteJson(params: {
|
|
|
134
152
|
...trace,
|
|
135
153
|
route: trace.route.map((routePoint) => ({ ...routePoint })),
|
|
136
154
|
})),
|
|
137
|
-
...
|
|
155
|
+
...planTraces,
|
|
138
156
|
],
|
|
139
157
|
}
|
|
140
158
|
}
|