@tscircuit/fanout-solver 0.0.10
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/LICENSE +21 -0
- package/README.md +366 -0
- package/lib/build-output.ts +140 -0
- package/lib/fanout-solver.ts +617 -0
- package/lib/geometry.ts +162 -0
- package/lib/index.ts +20 -0
- package/lib/layer-colors.ts +21 -0
- package/lib/layer-names.ts +137 -0
- package/lib/prepare-buses.ts +1016 -0
- package/lib/route-bus.ts +934 -0
- package/lib/route-single-layer-adaptive-exits.ts +1179 -0
- package/lib/route-single-layer-push-shove.ts +1233 -0
- package/lib/types.ts +212 -0
- package/package.json +56 -0
package/lib/types.ts
ADDED
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
ConnectionPoint,
|
|
3
|
+
Obstacle,
|
|
4
|
+
SimpleRouteBus,
|
|
5
|
+
SimpleRouteConnection,
|
|
6
|
+
SimpleRouteJson,
|
|
7
|
+
SimplifiedPcbTrace,
|
|
8
|
+
} from "@tscircuit/capacity-autorouter"
|
|
9
|
+
|
|
10
|
+
export type FanoutDirection = "left" | "right" | "up" | "down"
|
|
11
|
+
|
|
12
|
+
export type FanoutEdge = "left" | "right" | "top" | "bottom"
|
|
13
|
+
|
|
14
|
+
export type FanoutCorner =
|
|
15
|
+
| "top-left"
|
|
16
|
+
| "top-right"
|
|
17
|
+
| "bottom-left"
|
|
18
|
+
| "bottom-right"
|
|
19
|
+
|
|
20
|
+
export type FanoutBorderTarget = FanoutEdge | FanoutCorner
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* A directed region of the shared fanout boundary. Corner regions are named
|
|
24
|
+
* after the edge they belong to, so `top_left` exits through the top edge and
|
|
25
|
+
* `left_top` exits through the left edge.
|
|
26
|
+
*/
|
|
27
|
+
export type FanoutAvailableCornerAndSide =
|
|
28
|
+
| "top_left"
|
|
29
|
+
| "top_middle"
|
|
30
|
+
| "top_right"
|
|
31
|
+
| "right_top"
|
|
32
|
+
| "right_middle"
|
|
33
|
+
| "right_bottom"
|
|
34
|
+
| "bottom_right"
|
|
35
|
+
| "bottom_middle"
|
|
36
|
+
| "bottom_left"
|
|
37
|
+
| "left_bottom"
|
|
38
|
+
| "left_middle"
|
|
39
|
+
| "left_top"
|
|
40
|
+
|
|
41
|
+
/** Convenient aliases for the middle region of each boundary edge. */
|
|
42
|
+
export type FanoutAvailableCornerAndSideAlias = FanoutEdge
|
|
43
|
+
|
|
44
|
+
export type FanoutAvailableCornerAndSideInput =
|
|
45
|
+
| FanoutAvailableCornerAndSide
|
|
46
|
+
| FanoutAvailableCornerAndSideAlias
|
|
47
|
+
|
|
48
|
+
export type FanoutBorderDistribution = "preserve" | "even"
|
|
49
|
+
|
|
50
|
+
export type FanoutBusTermination =
|
|
51
|
+
| {
|
|
52
|
+
type: "boundary"
|
|
53
|
+
}
|
|
54
|
+
| {
|
|
55
|
+
type: "plane"
|
|
56
|
+
layer: string
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export interface FanoutBusSpec extends SimpleRouteBus {
|
|
60
|
+
/** Component whose connection endpoints should be escaped. */
|
|
61
|
+
sourceComponentId?: string
|
|
62
|
+
direction?: FanoutDirection
|
|
63
|
+
preferredExit?: FanoutBorderTarget
|
|
64
|
+
/**
|
|
65
|
+
* Defaults to `{ type: "boundary" }`.
|
|
66
|
+
*
|
|
67
|
+
* Plane-terminated connections are considered complete at their escaped via
|
|
68
|
+
* and are removed from the downstream SimpleRouteJson connection list.
|
|
69
|
+
*/
|
|
70
|
+
termination?: FanoutBusTermination
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export interface FanoutSolverOptions {
|
|
74
|
+
buses?: FanoutBusSpec[]
|
|
75
|
+
/** Default source component for every bus in this fanout operation. */
|
|
76
|
+
sourceComponentId?: string
|
|
77
|
+
/** Default direction for every bus in this fanout operation. */
|
|
78
|
+
defaultDirection?: FanoutDirection
|
|
79
|
+
/** Default boundary target for every bus in this fanout operation. */
|
|
80
|
+
defaultPreferredExit?: FanoutBorderTarget
|
|
81
|
+
/**
|
|
82
|
+
* Restricts boundary-terminated buses to these directed boundary regions.
|
|
83
|
+
*
|
|
84
|
+
* For example, `["top_left", "top", "top_right"]` permits exits only
|
|
85
|
+
* through the top edge. `top`, `right`, `bottom`, and `left` are aliases for
|
|
86
|
+
* their respective `*_middle` regions. Omit this option to leave every edge
|
|
87
|
+
* available.
|
|
88
|
+
*/
|
|
89
|
+
availableCornersAndSides?: readonly FanoutAvailableCornerAndSideInput[]
|
|
90
|
+
busDirections?: Readonly<Record<string, FanoutDirection>>
|
|
91
|
+
busExitPreferences?: Readonly<Record<string, FanoutBorderTarget>>
|
|
92
|
+
componentBounds?: Readonly<Record<string, Bounds>>
|
|
93
|
+
sharedBoundary?: Bounds
|
|
94
|
+
escapeLayers?: string[]
|
|
95
|
+
maxLayerCombinations?: number
|
|
96
|
+
traceWidth?: number
|
|
97
|
+
viaDiameter?: number
|
|
98
|
+
viaHoleDiameter?: number
|
|
99
|
+
clearance?: number
|
|
100
|
+
compactBusTracks?: boolean
|
|
101
|
+
singleLayerPushAndShove?: boolean
|
|
102
|
+
/**
|
|
103
|
+
* When preferred single-layer exits cannot coexist, allow a global
|
|
104
|
+
* same-net-aware pass to choose alternate shared-boundary sides. This
|
|
105
|
+
* fallback currently applies to singleton buses only.
|
|
106
|
+
*/
|
|
107
|
+
singleLayerAdaptiveExits?: boolean
|
|
108
|
+
borderDistribution?: FanoutBorderDistribution
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export interface FanoutAttemptSummary {
|
|
112
|
+
assignmentIndex: number
|
|
113
|
+
busLayerAssignments: Readonly<Record<string, string>>
|
|
114
|
+
routedBusCount: number
|
|
115
|
+
routedConnectionCount: number
|
|
116
|
+
failedBusIds: string[]
|
|
117
|
+
score: number
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export interface FanoutSolverOutput {
|
|
121
|
+
simpleRouteJson: SimpleRouteJson
|
|
122
|
+
fanoutTraces: SimplifiedPcbTrace[]
|
|
123
|
+
planeTerminations: FanoutPlaneTermination[]
|
|
124
|
+
busLayerAssignments: Readonly<Record<string, string>>
|
|
125
|
+
busDirections: Readonly<Record<string, FanoutDirection>>
|
|
126
|
+
attempts: FanoutAttemptSummary[]
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export interface Point2D {
|
|
130
|
+
x: number
|
|
131
|
+
y: number
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export interface Bounds {
|
|
135
|
+
minX: number
|
|
136
|
+
maxX: number
|
|
137
|
+
minY: number
|
|
138
|
+
maxY: number
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export interface PreparedConnection {
|
|
142
|
+
connection: SimpleRouteConnection
|
|
143
|
+
connectionIndex: number
|
|
144
|
+
sourcePoint: ConnectionPoint
|
|
145
|
+
sourcePointIndex: number
|
|
146
|
+
sourceLayer: string
|
|
147
|
+
sourceObstacle: Obstacle
|
|
148
|
+
targetPoint: ConnectionPoint
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export interface PreparedBus {
|
|
152
|
+
busId: string
|
|
153
|
+
direction: FanoutDirection
|
|
154
|
+
preferredExit?: FanoutBorderTarget
|
|
155
|
+
termination: FanoutBusTermination
|
|
156
|
+
connections: PreparedConnection[]
|
|
157
|
+
componentId: string
|
|
158
|
+
componentObstacles: Obstacle[]
|
|
159
|
+
componentBounds: Bounds
|
|
160
|
+
sharedBoundary: Bounds
|
|
161
|
+
xCoordinates: number[]
|
|
162
|
+
yCoordinates: number[]
|
|
163
|
+
pitchX: number
|
|
164
|
+
pitchY: number
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
export interface RoutedSegment {
|
|
168
|
+
start: Point2D
|
|
169
|
+
end: Point2D
|
|
170
|
+
width: number
|
|
171
|
+
layer: string
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
export interface RoutedVia {
|
|
175
|
+
center: Point2D
|
|
176
|
+
diameter: number
|
|
177
|
+
holeDiameter: number
|
|
178
|
+
fromLayer: string
|
|
179
|
+
toLayer: string
|
|
180
|
+
spanLayers: string[]
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
export interface FanoutRoutePlan {
|
|
184
|
+
busId: string
|
|
185
|
+
connectionName: string
|
|
186
|
+
connectionIndex: number
|
|
187
|
+
sourcePointIndex: number
|
|
188
|
+
sourcePoint: ConnectionPoint
|
|
189
|
+
sourceObstacle: Obstacle
|
|
190
|
+
sourceLayer: string
|
|
191
|
+
targetLayer: string
|
|
192
|
+
termination: FanoutBusTermination
|
|
193
|
+
direction: FanoutDirection
|
|
194
|
+
exitPoint: Point2D
|
|
195
|
+
trace: SimplifiedPcbTrace
|
|
196
|
+
segments: RoutedSegment[]
|
|
197
|
+
via?: RoutedVia
|
|
198
|
+
length: number
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
export interface FanoutPlaneTermination {
|
|
202
|
+
busId: string
|
|
203
|
+
connectionName: string
|
|
204
|
+
layer: string
|
|
205
|
+
via: RoutedVia
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
export interface AssignmentAttempt {
|
|
209
|
+
summary: FanoutAttemptSummary
|
|
210
|
+
plans: FanoutRoutePlan[]
|
|
211
|
+
outputSrj: SimpleRouteJson
|
|
212
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@tscircuit/fanout-solver",
|
|
3
|
+
"version": "0.0.10",
|
|
4
|
+
"description": "BGA fanout solver with coordinated bus-layer escapes for SimpleRouteJson",
|
|
5
|
+
"module": "lib/index.ts",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"files": [
|
|
8
|
+
"lib"
|
|
9
|
+
],
|
|
10
|
+
"license": "MIT",
|
|
11
|
+
"repository": {
|
|
12
|
+
"type": "git",
|
|
13
|
+
"url": "https://github.com/tscircuit/fanout-solver.git"
|
|
14
|
+
},
|
|
15
|
+
"publishConfig": {
|
|
16
|
+
"access": "public"
|
|
17
|
+
},
|
|
18
|
+
"exports": {
|
|
19
|
+
".": {
|
|
20
|
+
"import": "./lib/index.ts",
|
|
21
|
+
"types": "./lib/index.ts"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"scripts": {
|
|
25
|
+
"start": "cosmos",
|
|
26
|
+
"build:site": "cosmos-export",
|
|
27
|
+
"build": "bunx tsc --noEmit",
|
|
28
|
+
"typecheck": "bunx tsc --noEmit",
|
|
29
|
+
"test": "bun test",
|
|
30
|
+
"benchmark": "bun benchmarks/run-benchmark.ts",
|
|
31
|
+
"render:dataset": "bun scripts/render-dataset-pngs.ts",
|
|
32
|
+
"format": "biome format --write .",
|
|
33
|
+
"format:check": "biome format ."
|
|
34
|
+
},
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"@tscircuit/capacity-autorouter": "0.0.718",
|
|
37
|
+
"@tscircuit/solver-utils": "0.0.19",
|
|
38
|
+
"graphics-debug": "0.0.96"
|
|
39
|
+
},
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"@biomejs/biome": "2.5.5",
|
|
42
|
+
"@tscircuit/footprinter": "0.0.394",
|
|
43
|
+
"@types/bun": "1.3.14",
|
|
44
|
+
"@types/react": "19.2.14",
|
|
45
|
+
"@types/react-dom": "19.2.3",
|
|
46
|
+
"circuit-json": "0.0.455",
|
|
47
|
+
"react": "19.2.8",
|
|
48
|
+
"react-cosmos": "7.3.0",
|
|
49
|
+
"react-cosmos-plugin-vite": "7.3.0",
|
|
50
|
+
"react-dom": "19.2.8",
|
|
51
|
+
"vite": "8.1.5"
|
|
52
|
+
},
|
|
53
|
+
"peerDependencies": {
|
|
54
|
+
"typescript": "^5"
|
|
55
|
+
}
|
|
56
|
+
}
|