@tscircuit/fanout-solver 0.0.24 → 0.0.26
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/lib/build-output.ts +8 -3
- package/lib/complete-original-endpoints.ts +6 -1
- package/lib/fanout-output-ids.ts +33 -0
- package/lib/fanout-solver.ts +6 -7
- package/lib/index.ts +1 -0
- package/lib/prepare-buses.ts +29 -8
- package/lib/route-bus.ts +14 -5
- package/lib/route-single-layer-adaptive-exits.ts +7 -3
- package/lib/route-single-layer-push-shove.ts +12 -4
- package/lib/types.ts +11 -0
- package/package.json +7 -1
package/lib/build-output.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Obstacle, SimpleRouteJson } from "@tscircuit/capacity-autorouter"
|
|
2
|
+
import { createFanoutOutputIds } from "./fanout-output-ids"
|
|
2
3
|
import type { FanoutRoutePlan, SimpleRouteJsonWithFanoutPlanes } from "./types"
|
|
3
4
|
|
|
4
5
|
function createViaObstacle(
|
|
@@ -17,8 +18,11 @@ function createViaObstacle(
|
|
|
17
18
|
}
|
|
18
19
|
return layerIndex
|
|
19
20
|
})
|
|
21
|
+
const outputIds = createFanoutOutputIds(plan)
|
|
20
22
|
return {
|
|
21
|
-
obstacleId:
|
|
23
|
+
obstacleId: endpoint
|
|
24
|
+
? outputIds.planeEndpointViaObstacleId
|
|
25
|
+
: outputIds.viaObstacleId,
|
|
22
26
|
type: "rect",
|
|
23
27
|
center: via.center,
|
|
24
28
|
width: via.diameter,
|
|
@@ -50,14 +54,15 @@ export function buildOutputSimpleRouteJson(params: {
|
|
|
50
54
|
`FanoutSolver: output connection index ${plan.connectionIndex} is missing`,
|
|
51
55
|
)
|
|
52
56
|
}
|
|
57
|
+
const outputIds = createFanoutOutputIds(plan)
|
|
53
58
|
connection.pointsToConnect[plan.sourcePointIndex] = {
|
|
54
59
|
x: plan.exitPoint.x,
|
|
55
60
|
y: plan.exitPoint.y,
|
|
56
61
|
layer: plan.targetLayer,
|
|
57
62
|
pointId:
|
|
58
63
|
plan.termination.type === "plane"
|
|
59
|
-
?
|
|
60
|
-
:
|
|
64
|
+
? outputIds.planeExitPointId
|
|
65
|
+
: outputIds.boundaryExitPointId,
|
|
61
66
|
}
|
|
62
67
|
if (plan.termination.type === "plane") {
|
|
63
68
|
planeTerminatedConnectionNames.add(plan.connectionName)
|
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
type SimpleRouteJson,
|
|
6
6
|
type SimplifiedPcbTrace,
|
|
7
7
|
} from "@tscircuit/capacity-autorouter"
|
|
8
|
+
import { createFanoutCompletionTraceId } from "./fanout-output-ids"
|
|
8
9
|
import {
|
|
9
10
|
distance,
|
|
10
11
|
distancePointToSegment,
|
|
@@ -226,7 +227,11 @@ function createBranchTrace(params: {
|
|
|
226
227
|
|
|
227
228
|
return {
|
|
228
229
|
type: "pcb_trace",
|
|
229
|
-
pcb_trace_id:
|
|
230
|
+
pcb_trace_id: createFanoutCompletionTraceId({
|
|
231
|
+
connectionName: plan.connectionName,
|
|
232
|
+
sourcePointIndex: plan.sourcePointIndex,
|
|
233
|
+
candidateIndex,
|
|
234
|
+
}),
|
|
230
235
|
connection_name: plan.connectionName,
|
|
231
236
|
route,
|
|
232
237
|
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export interface FanoutOutputIds {
|
|
2
|
+
boundaryExitPointId: string
|
|
3
|
+
planeExitPointId: string
|
|
4
|
+
traceId: string
|
|
5
|
+
viaObstacleId: string
|
|
6
|
+
planeEndpointPointId: string
|
|
7
|
+
planeEndpointTraceId: string
|
|
8
|
+
planeEndpointViaObstacleId: string
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function createFanoutOutputIds(input: {
|
|
12
|
+
connectionName: string
|
|
13
|
+
sourcePointIndex: number
|
|
14
|
+
}): FanoutOutputIds {
|
|
15
|
+
const endpointKey = `${input.connectionName}:source-${input.sourcePointIndex}`
|
|
16
|
+
return {
|
|
17
|
+
boundaryExitPointId: `fanout-exit:${endpointKey}`,
|
|
18
|
+
planeExitPointId: `fanout-plane:${endpointKey}`,
|
|
19
|
+
traceId: `fanout:${endpointKey}`,
|
|
20
|
+
viaObstacleId: `fanout-via:${endpointKey}`,
|
|
21
|
+
planeEndpointPointId: `fanout-plane-endpoint-point:${endpointKey}`,
|
|
22
|
+
planeEndpointTraceId: `fanout-plane-endpoint:${endpointKey}`,
|
|
23
|
+
planeEndpointViaObstacleId: `fanout-plane-endpoint-via:${endpointKey}`,
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function createFanoutCompletionTraceId(input: {
|
|
28
|
+
connectionName: string
|
|
29
|
+
sourcePointIndex: number
|
|
30
|
+
candidateIndex: number
|
|
31
|
+
}): string {
|
|
32
|
+
return `fanout-completion:${input.connectionName}:source-${input.sourcePointIndex}:${input.candidateIndex}`
|
|
33
|
+
}
|
package/lib/fanout-solver.ts
CHANGED
|
@@ -208,15 +208,14 @@ function getBusDistanceToBoundary(bus: PreparedBus): number {
|
|
|
208
208
|
}
|
|
209
209
|
}
|
|
210
210
|
|
|
211
|
-
function
|
|
211
|
+
function busUsesDestinationGuidedTracks(bus: PreparedBus): boolean {
|
|
212
212
|
const isHorizontal = bus.direction === "left" || bus.direction === "right"
|
|
213
213
|
return bus.connections.some((connection) => {
|
|
214
|
+
const exitTargetPoint = connection.exitTargetPoint ?? connection.targetPoint
|
|
214
215
|
const sourceTrack = isHorizontal
|
|
215
216
|
? connection.sourcePoint.y
|
|
216
217
|
: connection.sourcePoint.x
|
|
217
|
-
const targetTrack = isHorizontal
|
|
218
|
-
? connection.targetPoint.y
|
|
219
|
-
: connection.targetPoint.x
|
|
218
|
+
const targetTrack = isHorizontal ? exitTargetPoint.y : exitTargetPoint.x
|
|
220
219
|
return Math.abs(sourceTrack - targetTrack) > 1e-6
|
|
221
220
|
})
|
|
222
221
|
}
|
|
@@ -293,7 +292,7 @@ function createPreferredLayerAssignment(params: {
|
|
|
293
292
|
)
|
|
294
293
|
if (
|
|
295
294
|
routableEscapeLayers.includes(sourceLayer) &&
|
|
296
|
-
(
|
|
295
|
+
(busUsesDestinationGuidedTracks(bus) || busIsOnOutwardComponentEdge(bus))
|
|
297
296
|
) {
|
|
298
297
|
assignment[bus.busId] = sourceLayer
|
|
299
298
|
} else if (viaLayers.length > 0) {
|
|
@@ -795,7 +794,7 @@ export class FanoutSolver extends BaseSolver {
|
|
|
795
794
|
(count, bus) => {
|
|
796
795
|
if (
|
|
797
796
|
bus.termination.type !== "boundary" ||
|
|
798
|
-
!
|
|
797
|
+
!busUsesDestinationGuidedTracks(bus)
|
|
799
798
|
) {
|
|
800
799
|
return count
|
|
801
800
|
}
|
|
@@ -840,7 +839,7 @@ export class FanoutSolver extends BaseSolver {
|
|
|
840
839
|
)
|
|
841
840
|
}
|
|
842
841
|
const sourceLayer = bus.connections[0]?.sourceLayer
|
|
843
|
-
const preferSourceLayer =
|
|
842
|
+
const preferSourceLayer = busUsesDestinationGuidedTracks(bus)
|
|
844
843
|
const orderedLayers = candidateLayers.toSorted(
|
|
845
844
|
(first, second) =>
|
|
846
845
|
(layerLoads.get(first) ?? 0) - (layerLoads.get(second) ?? 0) ||
|
package/lib/index.ts
CHANGED
package/lib/prepare-buses.ts
CHANGED
|
@@ -643,6 +643,7 @@ function prepareConnection(params: {
|
|
|
643
643
|
sourceGrid: ComponentGrid
|
|
644
644
|
componentGrids: ComponentGrid[]
|
|
645
645
|
termination: FanoutBusTermination
|
|
646
|
+
exitTargetPoint?: { x: number; y: number }
|
|
646
647
|
}): PreparedConnection {
|
|
647
648
|
const {
|
|
648
649
|
connection,
|
|
@@ -650,6 +651,7 @@ function prepareConnection(params: {
|
|
|
650
651
|
sourceGrid,
|
|
651
652
|
componentGrids,
|
|
652
653
|
termination,
|
|
654
|
+
exitTargetPoint,
|
|
653
655
|
} = params
|
|
654
656
|
for (
|
|
655
657
|
let sourcePointIndex = 0;
|
|
@@ -671,6 +673,12 @@ function prepareConnection(params: {
|
|
|
671
673
|
`FanoutSolver: connection "${connection.name}" has no source layer shared with its BGA pad`,
|
|
672
674
|
)
|
|
673
675
|
}
|
|
676
|
+
const targetPoint = chooseTargetPoint(
|
|
677
|
+
sourcePoint,
|
|
678
|
+
connection,
|
|
679
|
+
sourcePointIndex,
|
|
680
|
+
termination,
|
|
681
|
+
)
|
|
674
682
|
return {
|
|
675
683
|
connection,
|
|
676
684
|
connectionIndex,
|
|
@@ -678,12 +686,8 @@ function prepareConnection(params: {
|
|
|
678
686
|
sourcePointIndex,
|
|
679
687
|
sourceLayer,
|
|
680
688
|
sourceObstacle: sourceMatch.obstacle,
|
|
681
|
-
targetPoint
|
|
682
|
-
|
|
683
|
-
connection,
|
|
684
|
-
sourcePointIndex,
|
|
685
|
-
termination,
|
|
686
|
-
),
|
|
689
|
+
targetPoint,
|
|
690
|
+
exitTargetPoint: exitTargetPoint ?? targetPoint,
|
|
687
691
|
}
|
|
688
692
|
}
|
|
689
693
|
throw new Error(
|
|
@@ -698,8 +702,10 @@ function inferDirection(
|
|
|
698
702
|
let dx = 0
|
|
699
703
|
let dy = 0
|
|
700
704
|
for (const preparedConnection of connections) {
|
|
701
|
-
|
|
702
|
-
|
|
705
|
+
const exitTargetPoint =
|
|
706
|
+
preparedConnection.exitTargetPoint ?? preparedConnection.targetPoint
|
|
707
|
+
dx += exitTargetPoint.x - preparedConnection.sourcePoint.x
|
|
708
|
+
dy += exitTargetPoint.y - preparedConnection.sourcePoint.y
|
|
703
709
|
}
|
|
704
710
|
if (Math.abs(dx) < 1e-9 && Math.abs(dy) < 1e-9) {
|
|
705
711
|
throw new Error(
|
|
@@ -941,6 +947,20 @@ export function prepareFanoutBuses(
|
|
|
941
947
|
srj.connections.map((connection, index) => [connection.name, index]),
|
|
942
948
|
)
|
|
943
949
|
const resolvedBusInputs = resolveBusSpecs(srj, options).map((busSpec) => {
|
|
950
|
+
for (const [connectionName, point] of Object.entries(
|
|
951
|
+
busSpec.connectionExitTargets ?? {},
|
|
952
|
+
)) {
|
|
953
|
+
if (!busSpec.connectionNames.includes(connectionName)) {
|
|
954
|
+
throw new Error(
|
|
955
|
+
`FanoutSolver: connectionExitTargets contains connection "${connectionName}" outside bus "${busSpec.busId}"`,
|
|
956
|
+
)
|
|
957
|
+
}
|
|
958
|
+
if (!Number.isFinite(point.x) || !Number.isFinite(point.y)) {
|
|
959
|
+
throw new Error(
|
|
960
|
+
`FanoutSolver: connectionExitTargets for connection "${connectionName}" must contain finite x and y coordinates`,
|
|
961
|
+
)
|
|
962
|
+
}
|
|
963
|
+
}
|
|
944
964
|
const connections = busSpec.connectionNames.map((connectionName) => {
|
|
945
965
|
const connectionIndex = connectionIndexByName.get(connectionName)
|
|
946
966
|
if (connectionIndex === undefined) {
|
|
@@ -962,6 +982,7 @@ export function prepareFanoutBuses(
|
|
|
962
982
|
sourceGrid,
|
|
963
983
|
componentGrids,
|
|
964
984
|
termination: busSpec.termination ?? { type: "boundary" },
|
|
985
|
+
exitTargetPoint: busSpec.connectionExitTargets?.[connection.name],
|
|
965
986
|
}),
|
|
966
987
|
)
|
|
967
988
|
return { busSpec, sourceGrid, preparedConnections }
|
package/lib/route-bus.ts
CHANGED
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
distanceSegmentToObstacle,
|
|
11
11
|
segmentsAreClear,
|
|
12
12
|
} from "./geometry"
|
|
13
|
+
import { createFanoutOutputIds } from "./fanout-output-ids"
|
|
13
14
|
import { getLayerSpan } from "./layer-names"
|
|
14
15
|
import {
|
|
15
16
|
connectionsShareElectricalNet,
|
|
@@ -294,7 +295,7 @@ function getPreferredTrack(params: {
|
|
|
294
295
|
connection: PreparedConnection
|
|
295
296
|
}): number {
|
|
296
297
|
return getPerpendicularAxis(
|
|
297
|
-
params.connection.targetPoint,
|
|
298
|
+
params.connection.exitTargetPoint ?? params.connection.targetPoint,
|
|
298
299
|
params.bus.direction,
|
|
299
300
|
)
|
|
300
301
|
}
|
|
@@ -636,6 +637,10 @@ function buildPlan(params: {
|
|
|
636
637
|
})
|
|
637
638
|
}
|
|
638
639
|
|
|
640
|
+
const outputIds = createFanoutOutputIds({
|
|
641
|
+
connectionName: preparedConnection.connection.name,
|
|
642
|
+
sourcePointIndex: preparedConnection.sourcePointIndex,
|
|
643
|
+
})
|
|
639
644
|
return {
|
|
640
645
|
busId: bus.busId,
|
|
641
646
|
connectionName: preparedConnection.connection.name,
|
|
@@ -651,16 +656,16 @@ function buildPlan(params: {
|
|
|
651
656
|
exitPoint,
|
|
652
657
|
trace: {
|
|
653
658
|
type: "pcb_trace",
|
|
654
|
-
pcb_trace_id:
|
|
659
|
+
pcb_trace_id: outputIds.traceId,
|
|
655
660
|
connection_name: preparedConnection.connection.name,
|
|
656
661
|
connectsTo: [
|
|
657
|
-
preparedConnection.connection.name,
|
|
658
662
|
...(preparedConnection.sourcePoint.pointId
|
|
659
663
|
? [preparedConnection.sourcePoint.pointId]
|
|
660
664
|
: []),
|
|
661
665
|
...(preparedConnection.sourcePoint.pcb_port_id
|
|
662
666
|
? [preparedConnection.sourcePoint.pcb_port_id]
|
|
663
667
|
: []),
|
|
668
|
+
outputIds.boundaryExitPointId,
|
|
664
669
|
],
|
|
665
670
|
route,
|
|
666
671
|
},
|
|
@@ -804,18 +809,22 @@ function addPlaneEndpointTerminal(params: {
|
|
|
804
809
|
toLayer: targetEndpointLayer,
|
|
805
810
|
spanLayers,
|
|
806
811
|
}
|
|
812
|
+
const outputIds = createFanoutOutputIds({
|
|
813
|
+
connectionName: preparedConnection.connection.name,
|
|
814
|
+
sourcePointIndex: preparedConnection.sourcePointIndex,
|
|
815
|
+
})
|
|
807
816
|
const planeEndpointTrace: SimplifiedPcbTrace = {
|
|
808
817
|
type: "pcb_trace",
|
|
809
|
-
pcb_trace_id:
|
|
818
|
+
pcb_trace_id: outputIds.planeEndpointTraceId,
|
|
810
819
|
connection_name: preparedConnection.connection.name,
|
|
811
820
|
connectsTo: [
|
|
812
|
-
preparedConnection.connection.name,
|
|
813
821
|
...(preparedConnection.targetPoint.pointId
|
|
814
822
|
? [preparedConnection.targetPoint.pointId]
|
|
815
823
|
: []),
|
|
816
824
|
...(preparedConnection.targetPoint.pcb_port_id
|
|
817
825
|
? [preparedConnection.targetPoint.pcb_port_id]
|
|
818
826
|
: []),
|
|
827
|
+
outputIds.planeEndpointPointId,
|
|
819
828
|
],
|
|
820
829
|
route: [
|
|
821
830
|
{
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
distanceSegmentToObstacle,
|
|
10
10
|
distanceSegmentToSegment,
|
|
11
11
|
} from "./geometry"
|
|
12
|
+
import { createFanoutOutputIds } from "./fanout-output-ids"
|
|
12
13
|
import { type AvailableBoundaryRegion, getRegionAnchor } from "./prepare-buses"
|
|
13
14
|
import type {
|
|
14
15
|
FanoutDirection,
|
|
@@ -815,6 +816,10 @@ function buildPlan(route: FlowRoute, traceWidth: number): FanoutRoutePlan {
|
|
|
815
816
|
: {}),
|
|
816
817
|
}),
|
|
817
818
|
)
|
|
819
|
+
const outputIds = createFanoutOutputIds({
|
|
820
|
+
connectionName: item.connection.connection.name,
|
|
821
|
+
sourcePointIndex: item.connection.sourcePointIndex,
|
|
822
|
+
})
|
|
818
823
|
return {
|
|
819
824
|
busId: item.bus.busId,
|
|
820
825
|
connectionName: item.connection.connection.name,
|
|
@@ -830,17 +835,16 @@ function buildPlan(route: FlowRoute, traceWidth: number): FanoutRoutePlan {
|
|
|
830
835
|
exitPoint: points.at(-1)!,
|
|
831
836
|
trace: {
|
|
832
837
|
type: "pcb_trace",
|
|
833
|
-
pcb_trace_id:
|
|
838
|
+
pcb_trace_id: outputIds.traceId,
|
|
834
839
|
connection_name: item.connection.connection.name,
|
|
835
840
|
connectsTo: [
|
|
836
|
-
item.connection.connection.name,
|
|
837
|
-
item.netKey,
|
|
838
841
|
...(item.connection.sourcePoint.pointId
|
|
839
842
|
? [item.connection.sourcePoint.pointId]
|
|
840
843
|
: []),
|
|
841
844
|
...(item.connection.sourcePoint.pcb_port_id
|
|
842
845
|
? [item.connection.sourcePoint.pcb_port_id]
|
|
843
846
|
: []),
|
|
847
|
+
outputIds.boundaryExitPointId,
|
|
844
848
|
],
|
|
845
849
|
route: traceRoute,
|
|
846
850
|
},
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
distanceSegmentToObstacle,
|
|
9
9
|
distanceSegmentToSegment,
|
|
10
10
|
} from "./geometry"
|
|
11
|
+
import { createFanoutOutputIds } from "./fanout-output-ids"
|
|
11
12
|
import type {
|
|
12
13
|
FanoutBorderDistribution,
|
|
13
14
|
FanoutCorner,
|
|
@@ -197,7 +198,10 @@ function getCornerChannelPrefixes(params: {
|
|
|
197
198
|
maximum: bus.componentBounds.maxX,
|
|
198
199
|
}
|
|
199
200
|
const directionalDistance = sign * (componentExitAxis - sourceAxis)
|
|
200
|
-
const targetTrack = getPerpendicularAxis(
|
|
201
|
+
const targetTrack = getPerpendicularAxis(
|
|
202
|
+
connection.exitTargetPoint ?? connection.targetPoint,
|
|
203
|
+
direction,
|
|
204
|
+
)
|
|
201
205
|
const lanePitch = traceWidth + clearance
|
|
202
206
|
const exitAxis = getExitAxis(bus)
|
|
203
207
|
const candidates = ([-1, 1] as const)
|
|
@@ -280,7 +284,7 @@ function completeCornerChannelRoute(params: {
|
|
|
280
284
|
const minimumTrack = boundaryMinimum + traceWidth / 2
|
|
281
285
|
const maximumTrack = boundaryMaximum - traceWidth / 2
|
|
282
286
|
const targetTrack = getPerpendicularAxis(
|
|
283
|
-
item.connection.targetPoint,
|
|
287
|
+
item.connection.exitTargetPoint ?? item.connection.targetPoint,
|
|
284
288
|
direction,
|
|
285
289
|
)
|
|
286
290
|
const trackStep = lanePitch / 2
|
|
@@ -748,6 +752,10 @@ function buildPlan(path: RoutedPath): FanoutRoutePlan {
|
|
|
748
752
|
? { start_pcb_port_id: item.connection.sourcePoint.pcb_port_id }
|
|
749
753
|
: {}),
|
|
750
754
|
}))
|
|
755
|
+
const outputIds = createFanoutOutputIds({
|
|
756
|
+
connectionName: item.connection.connection.name,
|
|
757
|
+
sourcePointIndex: item.connection.sourcePointIndex,
|
|
758
|
+
})
|
|
751
759
|
return {
|
|
752
760
|
busId: item.bus.busId,
|
|
753
761
|
connectionName: item.connection.connection.name,
|
|
@@ -763,16 +771,16 @@ function buildPlan(path: RoutedPath): FanoutRoutePlan {
|
|
|
763
771
|
exitPoint: points.at(-1)!,
|
|
764
772
|
trace: {
|
|
765
773
|
type: "pcb_trace",
|
|
766
|
-
pcb_trace_id:
|
|
774
|
+
pcb_trace_id: outputIds.traceId,
|
|
767
775
|
connection_name: item.connection.connection.name,
|
|
768
776
|
connectsTo: [
|
|
769
|
-
item.connection.connection.name,
|
|
770
777
|
...(item.connection.sourcePoint.pointId
|
|
771
778
|
? [item.connection.sourcePoint.pointId]
|
|
772
779
|
: []),
|
|
773
780
|
...(item.connection.sourcePoint.pcb_port_id
|
|
774
781
|
? [item.connection.sourcePoint.pcb_port_id]
|
|
775
782
|
: []),
|
|
783
|
+
outputIds.boundaryExitPointId,
|
|
776
784
|
],
|
|
777
785
|
route,
|
|
778
786
|
},
|
package/lib/types.ts
CHANGED
|
@@ -63,6 +63,15 @@ export interface FanoutBusSpec extends SimpleRouteBus {
|
|
|
63
63
|
sourceComponentId?: string
|
|
64
64
|
direction?: FanoutDirection
|
|
65
65
|
preferredExit?: FanoutBorderTarget
|
|
66
|
+
/**
|
|
67
|
+
* Preferred downstream routing point for each connection after it leaves the
|
|
68
|
+
* fanout boundary. This is routing guidance only and does not replace the
|
|
69
|
+
* connection's electrical endpoint in SimpleRouteJson.
|
|
70
|
+
*
|
|
71
|
+
* A caller coordinating two fanouts can pass the paired fanout's selected
|
|
72
|
+
* exit here so both sides aim toward the same track.
|
|
73
|
+
*/
|
|
74
|
+
connectionExitTargets?: Readonly<Record<string, Point2D>>
|
|
66
75
|
/**
|
|
67
76
|
* Defaults to `{ type: "boundary" }`.
|
|
68
77
|
*
|
|
@@ -209,6 +218,8 @@ export interface PreparedConnection {
|
|
|
209
218
|
sourceLayer: string
|
|
210
219
|
sourceObstacle: Obstacle
|
|
211
220
|
targetPoint: ConnectionPoint
|
|
221
|
+
/** Preferred downstream point used to choose the boundary exit track. */
|
|
222
|
+
exitTargetPoint?: Point2D
|
|
212
223
|
}
|
|
213
224
|
|
|
214
225
|
export interface PreparedBus {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tscircuit/fanout-solver",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.26",
|
|
4
4
|
"description": "BGA fanout solver with coordinated bus-layer escapes for SimpleRouteJson",
|
|
5
5
|
"module": "lib/index.ts",
|
|
6
6
|
"type": "module",
|
|
@@ -42,16 +42,22 @@
|
|
|
42
42
|
"@biomejs/biome": "2.5.5",
|
|
43
43
|
"@tsci/tscircuit.dataset-srj19-bga-passive-overlays": "github:tscircuit/dataset-srj19#c1206f3",
|
|
44
44
|
"@tsci/tscircuit.dataset-srj29-bga-decoupling": "github:tscircuit/dataset-srj29-bga-decoupling#bfdf7bc",
|
|
45
|
+
"@tscircuit/alphabet": "0.0.25",
|
|
46
|
+
"@tscircuit/circuit-json-util": "0.0.97",
|
|
45
47
|
"@tscircuit/footprinter": "0.0.394",
|
|
46
48
|
"@types/bun": "1.3.14",
|
|
47
49
|
"@types/react": "19.2.14",
|
|
48
50
|
"@types/react-dom": "19.2.3",
|
|
49
51
|
"bun-match-svg": "^0.0.16",
|
|
50
52
|
"circuit-json": "0.0.455",
|
|
53
|
+
"circuit-json-to-connectivity-map": "0.0.23",
|
|
54
|
+
"circuit-to-svg": "0.0.364",
|
|
55
|
+
"format-si-unit": "0.0.7",
|
|
51
56
|
"react": "19.2.8",
|
|
52
57
|
"react-cosmos": "7.3.0",
|
|
53
58
|
"react-cosmos-plugin-vite": "7.3.0",
|
|
54
59
|
"react-dom": "19.2.8",
|
|
60
|
+
"schematic-symbols": "0.0.231",
|
|
55
61
|
"vite": "8.1.5"
|
|
56
62
|
},
|
|
57
63
|
"peerDependencies": {
|