@tscircuit/core 0.0.1849 → 0.0.1850
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 +467 -19
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -21600,6 +21600,7 @@ function* routeViaMinimalWindingAlternativesSteps(params, maximumAlternatives =
|
|
|
21600
21600
|
allowSameNetMerges = false,
|
|
21601
21601
|
maximumRouteOrderAttempts,
|
|
21602
21602
|
reservedVias = [],
|
|
21603
|
+
softReservedVias = [],
|
|
21603
21604
|
gridStepDivisor = 1,
|
|
21604
21605
|
preferTargetDirectedLaneBias = false,
|
|
21605
21606
|
allowSourceLayerRouting = false,
|
|
@@ -21647,6 +21648,36 @@ function* routeViaMinimalWindingAlternativesSteps(params, maximumAlternatives =
|
|
|
21647
21648
|
point: { x: gridMinX + column * gridStep, y: gridMinY + row * gridStep }
|
|
21648
21649
|
};
|
|
21649
21650
|
});
|
|
21651
|
+
const softViaCosts = softReservedVias.length ? new Float32Array(nodeCount) : void 0;
|
|
21652
|
+
if (softViaCosts) {
|
|
21653
|
+
for (const { via } of softReservedVias) {
|
|
21654
|
+
if (!via.spanLayers.includes(targetLayer)) continue;
|
|
21655
|
+
const radius = via.diameter / 2 + traceWidth / 2 + clearance;
|
|
21656
|
+
const minimumColumn = Math.max(
|
|
21657
|
+
0,
|
|
21658
|
+
Math.ceil((via.center.x - radius - gridMinX) / gridStep)
|
|
21659
|
+
);
|
|
21660
|
+
const maximumColumn = Math.min(
|
|
21661
|
+
columnCount - 1,
|
|
21662
|
+
Math.floor((via.center.x + radius - gridMinX) / gridStep)
|
|
21663
|
+
);
|
|
21664
|
+
const minimumRow = Math.max(
|
|
21665
|
+
0,
|
|
21666
|
+
Math.ceil((via.center.y - radius - gridMinY) / gridStep)
|
|
21667
|
+
);
|
|
21668
|
+
const maximumRow = Math.min(
|
|
21669
|
+
rowCount - 1,
|
|
21670
|
+
Math.floor((via.center.y + radius - gridMinY) / gridStep)
|
|
21671
|
+
);
|
|
21672
|
+
for (let row = minimumRow; row <= maximumRow; row++) {
|
|
21673
|
+
for (let column = minimumColumn; column <= maximumColumn; column++) {
|
|
21674
|
+
const index = row * columnCount + column;
|
|
21675
|
+
if (distance9(nodes[index].point, via.center) < radius)
|
|
21676
|
+
softViaCosts[index] = softViaCosts[index] + 25 * gridStep;
|
|
21677
|
+
}
|
|
21678
|
+
}
|
|
21679
|
+
}
|
|
21680
|
+
}
|
|
21650
21681
|
const sampledGridPoints = includeVisualization ? nodes.filter(
|
|
21651
21682
|
(_, index) => index % Math.max(1, Math.ceil(nodes.length / 1e3)) === 0
|
|
21652
21683
|
).map((node) => node.point) : [];
|
|
@@ -22052,7 +22083,7 @@ function* routeViaMinimalWindingAlternativesSteps(params, maximumAlternatives =
|
|
|
22052
22083
|
boundaryDirection
|
|
22053
22084
|
);
|
|
22054
22085
|
const lanePenalty = laneBias === 0 ? 0 : laneBias > 0 ? Math.max(0, targetTrack - nextTrack) * 0.2 : Math.max(0, nextTrack - targetTrack) * 0.2;
|
|
22055
|
-
const nextDistance = currentDistance + (deltaColumn !== 0 && deltaRow !== 0 ? gridStep * Math.SQRT2 : gridStep) + (addsTurn ? gridStep * 0.2 : 0) + lanePenalty;
|
|
22086
|
+
const nextDistance = currentDistance + (deltaColumn !== 0 && deltaRow !== 0 ? gridStep * Math.SQRT2 : gridStep) + (addsTurn ? gridStep * 0.2 : 0) + lanePenalty + (softViaCosts?.[nextNode] ?? 0);
|
|
22056
22087
|
const nextState = nextNode * 9 + directionIndex;
|
|
22057
22088
|
if (nextDistance >= distances[nextState] - EPSILON7) continue;
|
|
22058
22089
|
const edgeIndex = current.node * 8 + directionIndex;
|
|
@@ -22440,6 +22471,59 @@ function getWindingCrossoverLayer(params) {
|
|
|
22440
22471
|
(layer) => layer !== escapeLayer
|
|
22441
22472
|
);
|
|
22442
22473
|
}
|
|
22474
|
+
function getDistributedBoundaryTargetTracks(params) {
|
|
22475
|
+
const { bus, boundaryDirection, traceWidth, clearance } = params;
|
|
22476
|
+
if (getCornerSide(bus) || !busUsesCoordinatedWindingChannel(bus))
|
|
22477
|
+
return void 0;
|
|
22478
|
+
const layers = new Set(
|
|
22479
|
+
bus.connections.map(
|
|
22480
|
+
(connection) => connection.exitTargetPoint?.layer ?? getPointLayer2(connection.targetPoint)
|
|
22481
|
+
)
|
|
22482
|
+
);
|
|
22483
|
+
if (layers.size < 2) return void 0;
|
|
22484
|
+
const minimum = isHorizontal(boundaryDirection) ? bus.sharedBoundary.minY : bus.sharedBoundary.minX;
|
|
22485
|
+
const maximum = isHorizontal(boundaryDirection) ? bus.sharedBoundary.maxY : bus.sharedBoundary.maxX;
|
|
22486
|
+
const tracks = bus.connections.map(
|
|
22487
|
+
(connection) => Math.max(
|
|
22488
|
+
minimum,
|
|
22489
|
+
Math.min(
|
|
22490
|
+
maximum,
|
|
22491
|
+
getPerpendicularAxis2(
|
|
22492
|
+
connection.exitTargetPoint ?? connection.targetPoint,
|
|
22493
|
+
boundaryDirection
|
|
22494
|
+
)
|
|
22495
|
+
)
|
|
22496
|
+
)
|
|
22497
|
+
).toSorted((a, b) => a - b);
|
|
22498
|
+
const pitch = traceWidth + clearance;
|
|
22499
|
+
if (tracks.every(
|
|
22500
|
+
(track, index) => index === 0 || track - tracks[index - 1] >= pitch - 1e-9
|
|
22501
|
+
))
|
|
22502
|
+
return void 0;
|
|
22503
|
+
if (maximum - minimum < (tracks.length - 1) * pitch - 1e-9) return void 0;
|
|
22504
|
+
const blocks = [];
|
|
22505
|
+
for (const [index, track] of tracks.entries()) {
|
|
22506
|
+
blocks.push({ start: index, count: 1, mean: track - index * pitch });
|
|
22507
|
+
while (blocks.length > 1 && blocks.at(-2).mean > blocks.at(-1).mean) {
|
|
22508
|
+
const second = blocks.pop();
|
|
22509
|
+
const first = blocks.pop();
|
|
22510
|
+
blocks.push({
|
|
22511
|
+
start: first.start,
|
|
22512
|
+
count: first.count + second.count,
|
|
22513
|
+
mean: (first.mean * first.count + second.mean * second.count) / (first.count + second.count)
|
|
22514
|
+
});
|
|
22515
|
+
}
|
|
22516
|
+
}
|
|
22517
|
+
for (const block of blocks) {
|
|
22518
|
+
const mean = Math.max(
|
|
22519
|
+
minimum,
|
|
22520
|
+
Math.min(maximum - (tracks.length - 1) * pitch, block.mean)
|
|
22521
|
+
);
|
|
22522
|
+
for (let index = block.start; index < block.start + block.count; index++)
|
|
22523
|
+
tracks[index] = mean + index * pitch;
|
|
22524
|
+
}
|
|
22525
|
+
return tracks;
|
|
22526
|
+
}
|
|
22443
22527
|
function getBoundaryTargetTrack(params) {
|
|
22444
22528
|
const requestedTrack = getPerpendicularAxis2(
|
|
22445
22529
|
params.connection.exitTargetPoint ?? params.connection.targetPoint,
|
|
@@ -22447,6 +22531,19 @@ function getBoundaryTargetTrack(params) {
|
|
|
22447
22531
|
);
|
|
22448
22532
|
const boundaryMinimum = isHorizontal(params.boundaryDirection) ? params.bus.sharedBoundary.minY : params.bus.sharedBoundary.minX;
|
|
22449
22533
|
const boundaryMaximum = isHorizontal(params.boundaryDirection) ? params.bus.sharedBoundary.maxY : params.bus.sharedBoundary.maxX;
|
|
22534
|
+
const distributedTracks = params.traceWidth !== void 0 && params.clearance !== void 0 ? getDistributedBoundaryTargetTracks({
|
|
22535
|
+
...params,
|
|
22536
|
+
traceWidth: params.traceWidth,
|
|
22537
|
+
clearance: params.clearance
|
|
22538
|
+
}) : void 0;
|
|
22539
|
+
if (distributedTracks && params.layerNames && params.targetLayer) {
|
|
22540
|
+
const { rank } = getWindingTargetRank({
|
|
22541
|
+
...params,
|
|
22542
|
+
layerNames: params.layerNames,
|
|
22543
|
+
targetLayer: params.targetLayer
|
|
22544
|
+
});
|
|
22545
|
+
return distributedTracks[rank];
|
|
22546
|
+
}
|
|
22450
22547
|
return Math.max(boundaryMinimum, Math.min(boundaryMaximum, requestedTrack));
|
|
22451
22548
|
}
|
|
22452
22549
|
function getCornerTargetTrack(params) {
|
|
@@ -22936,7 +23033,11 @@ function buildPlan2(params) {
|
|
|
22936
23033
|
}) : usesLayeredWindingChannel ? getBoundaryTargetTrack({
|
|
22937
23034
|
bus,
|
|
22938
23035
|
connection: preparedConnection,
|
|
22939
|
-
boundaryDirection
|
|
23036
|
+
boundaryDirection,
|
|
23037
|
+
traceWidth,
|
|
23038
|
+
clearance,
|
|
23039
|
+
layerNames,
|
|
23040
|
+
targetLayer
|
|
22940
23041
|
}) : track;
|
|
22941
23042
|
const connectionRank = getConnectionRank(bus, preparedConnection);
|
|
22942
23043
|
const localCornerSide = getLocalCornerSide(bus);
|
|
@@ -24019,6 +24120,7 @@ function* routeBusAlternativesSteps(params, maxAlternatives = 1, includeVisualiz
|
|
|
24019
24120
|
stopAfterFirstRejectedViaMinimalCandidate = false,
|
|
24020
24121
|
fixedViaPointsByConnectionIndex,
|
|
24021
24122
|
reservedVias = [],
|
|
24123
|
+
softReservedVias = [],
|
|
24022
24124
|
viaMinimalOnly = false,
|
|
24023
24125
|
allowBoundarySideViaFallback = false,
|
|
24024
24126
|
preferCornerBoundaryVia = false,
|
|
@@ -24113,7 +24215,12 @@ function* routeBusAlternativesSteps(params, maxAlternatives = 1, includeVisualiz
|
|
|
24113
24215
|
})
|
|
24114
24216
|
);
|
|
24115
24217
|
const maximumThroughAllRouteOrderAttempts = 24;
|
|
24116
|
-
const windingTargetOrderCount = cornerSide
|
|
24218
|
+
const windingTargetOrderCount = cornerSide || getDistributedBoundaryTargetTracks({
|
|
24219
|
+
bus,
|
|
24220
|
+
boundaryDirection,
|
|
24221
|
+
traceWidth,
|
|
24222
|
+
clearance
|
|
24223
|
+
}) ? getWindingTargetOrders({
|
|
24117
24224
|
bus,
|
|
24118
24225
|
boundaryDirection,
|
|
24119
24226
|
layerNames,
|
|
@@ -24217,7 +24324,12 @@ function* routeBusAlternativesSteps(params, maxAlternatives = 1, includeVisualiz
|
|
|
24217
24324
|
useViaInPad: true,
|
|
24218
24325
|
getViaHandedness: () => 0
|
|
24219
24326
|
};
|
|
24220
|
-
const coordinatedViaPoints = fixedViaPointsByConnectionIndex ?? (!allowBlindAndBuriedVias && bus.connections.length >= 8
|
|
24327
|
+
const coordinatedViaPoints = fixedViaPointsByConnectionIndex ?? (!allowBlindAndBuriedVias && (bus.connections.length >= 8 || getDistributedBoundaryTargetTracks({
|
|
24328
|
+
bus,
|
|
24329
|
+
boundaryDirection,
|
|
24330
|
+
traceWidth,
|
|
24331
|
+
clearance
|
|
24332
|
+
})) && reservedVias.length === 0 ? matchComponentDogboneViaSites([bus], {
|
|
24221
24333
|
viaDiameter,
|
|
24222
24334
|
viaHoleDiameter,
|
|
24223
24335
|
traceWidth,
|
|
@@ -24321,7 +24433,12 @@ function* routeBusAlternativesSteps(params, maxAlternatives = 1, includeVisualiz
|
|
|
24321
24433
|
}) : getBoundaryTargetTrack({
|
|
24322
24434
|
bus,
|
|
24323
24435
|
connection: preparedConnection,
|
|
24324
|
-
boundaryDirection
|
|
24436
|
+
boundaryDirection,
|
|
24437
|
+
traceWidth,
|
|
24438
|
+
clearance,
|
|
24439
|
+
layerNames,
|
|
24440
|
+
targetLayer,
|
|
24441
|
+
windingOrderIndex: terminalPattern.windingOrderIndex
|
|
24325
24442
|
});
|
|
24326
24443
|
return {
|
|
24327
24444
|
connection: preparedConnection,
|
|
@@ -24405,6 +24522,7 @@ function* routeBusAlternativesSteps(params, maxAlternatives = 1, includeVisualiz
|
|
|
24405
24522
|
alignGridToPads,
|
|
24406
24523
|
includeReverseTargetRotation: terminalPattern.localDogboneRepair,
|
|
24407
24524
|
reservedVias,
|
|
24525
|
+
softReservedVias,
|
|
24408
24526
|
gridStepDivisor,
|
|
24409
24527
|
preferTargetDirectedLaneBias: terminalPattern.preferTargetDirectedLaneBias
|
|
24410
24528
|
},
|
|
@@ -24473,7 +24591,11 @@ function* routeBusAlternativesSteps(params, maxAlternatives = 1, includeVisualiz
|
|
|
24473
24591
|
}) : getBoundaryTargetTrack({
|
|
24474
24592
|
bus,
|
|
24475
24593
|
connection: preparedConnection,
|
|
24476
|
-
boundaryDirection
|
|
24594
|
+
boundaryDirection,
|
|
24595
|
+
traceWidth,
|
|
24596
|
+
clearance,
|
|
24597
|
+
layerNames,
|
|
24598
|
+
targetLayer
|
|
24477
24599
|
})
|
|
24478
24600
|
);
|
|
24479
24601
|
const finalExitPoints = finalTracks.map(
|
|
@@ -24549,7 +24671,50 @@ function* routeBusAlternativesSteps(params, maxAlternatives = 1, includeVisualiz
|
|
|
24549
24671
|
})
|
|
24550
24672
|
)
|
|
24551
24673
|
) : [];
|
|
24674
|
+
const matchedVias = bus.connections.map(
|
|
24675
|
+
(connection) => fixedViaPointsByConnectionIndex.get(connection.connectionIndex)
|
|
24676
|
+
);
|
|
24677
|
+
const packageEdgeViaCandidates = [
|
|
24678
|
+
{
|
|
24679
|
+
distance: sourceCenter.x - bus.componentBounds.minX,
|
|
24680
|
+
axis: "x",
|
|
24681
|
+
value: bus.componentBounds.minX - 2 * insetStep
|
|
24682
|
+
},
|
|
24683
|
+
{
|
|
24684
|
+
distance: bus.componentBounds.maxX - sourceCenter.x,
|
|
24685
|
+
axis: "x",
|
|
24686
|
+
value: bus.componentBounds.maxX + 2 * insetStep
|
|
24687
|
+
},
|
|
24688
|
+
{
|
|
24689
|
+
distance: sourceCenter.y - bus.componentBounds.minY,
|
|
24690
|
+
axis: "y",
|
|
24691
|
+
value: bus.componentBounds.minY - 2 * insetStep
|
|
24692
|
+
},
|
|
24693
|
+
{
|
|
24694
|
+
distance: bus.componentBounds.maxY - sourceCenter.y,
|
|
24695
|
+
axis: "y",
|
|
24696
|
+
value: bus.componentBounds.maxY + 2 * insetStep
|
|
24697
|
+
}
|
|
24698
|
+
].toSorted((a, b) => a.distance - b.distance).flatMap(({ axis, value }) => {
|
|
24699
|
+
const otherAxis = axis === "x" ? "y" : "x";
|
|
24700
|
+
const mean = matchedVias.reduce((sum, via) => sum + via[otherAxis], 0) / matchedVias.length;
|
|
24701
|
+
const order = matchedVias.map((via, index) => ({ index, track: via[otherAxis] })).toSorted((a, b) => a.track - b.track || a.index - b.index);
|
|
24702
|
+
const pitch = viaDiameter + clearance;
|
|
24703
|
+
const points = matchedVias.map((via, index) => ({
|
|
24704
|
+
...via,
|
|
24705
|
+
[axis]: value,
|
|
24706
|
+
[otherAxis]: order.length === 2 && Math.abs(order[1].track - order[0].track) < pitch ? mean + (order.findIndex((v) => v.index === index) - 0.5) * pitch : via[otherAxis]
|
|
24707
|
+
}));
|
|
24708
|
+
return points.length === 2 ? [points, [points[1], points[0]]] : [points];
|
|
24709
|
+
});
|
|
24710
|
+
const preferPackageEdgeVias = bus.connections.length === 2 && Boolean(getCornerSide(bus));
|
|
24552
24711
|
const viaCandidates = [
|
|
24712
|
+
...(preferPackageEdgeVias ? packageEdgeViaCandidates : []).map(
|
|
24713
|
+
(points) => ({
|
|
24714
|
+
points,
|
|
24715
|
+
boundarySide: false
|
|
24716
|
+
})
|
|
24717
|
+
),
|
|
24553
24718
|
...displacedViaCandidates.map((points) => ({
|
|
24554
24719
|
points,
|
|
24555
24720
|
boundarySide: false
|
|
@@ -24557,7 +24722,16 @@ function* routeBusAlternativesSteps(params, maxAlternatives = 1, includeVisualiz
|
|
|
24557
24722
|
...boundaryViaCandidates.map((points) => ({
|
|
24558
24723
|
points,
|
|
24559
24724
|
boundarySide: true
|
|
24560
|
-
}))
|
|
24725
|
+
})),
|
|
24726
|
+
// Preserve existing centered and singleton escapes before trying a short
|
|
24727
|
+
// source-layer route beyond the package. The target layer can then wind to the exit
|
|
24728
|
+
// without a local via being fenced in by an already-routed wide bus.
|
|
24729
|
+
...(!preferPackageEdgeVias ? packageEdgeViaCandidates : []).map(
|
|
24730
|
+
(points) => ({
|
|
24731
|
+
points,
|
|
24732
|
+
boundarySide: false
|
|
24733
|
+
})
|
|
24734
|
+
)
|
|
24561
24735
|
];
|
|
24562
24736
|
for (const { points: boundaryViaPoints, boundarySide } of viaCandidates) {
|
|
24563
24737
|
const boundaryVias = bus.connections.map((connection, index) => ({
|
|
@@ -24608,6 +24782,7 @@ function* routeBusAlternativesSteps(params, maxAlternatives = 1, includeVisualiz
|
|
|
24608
24782
|
allowBlindAndBuriedVias,
|
|
24609
24783
|
allowSameNetMerges,
|
|
24610
24784
|
maximumRouteOrderAttempts: bus.connections.length === 1 ? 3 : 6,
|
|
24785
|
+
softReservedVias,
|
|
24611
24786
|
reservedVias: bus.connections.length > 1 ? [...reservedVias, ...boundaryVias] : reservedVias,
|
|
24612
24787
|
gridStepDivisor: 2,
|
|
24613
24788
|
allowSourceLayerRouting: true,
|
|
@@ -24651,6 +24826,7 @@ function* routeBusAlternativesSteps(params, maxAlternatives = 1, includeVisualiz
|
|
|
24651
24826
|
allowSameNetMerges,
|
|
24652
24827
|
maximumRouteOrderAttempts: 6,
|
|
24653
24828
|
reservedVias,
|
|
24829
|
+
softReservedVias,
|
|
24654
24830
|
gridStepDivisor: 2,
|
|
24655
24831
|
alignGridToPads: true
|
|
24656
24832
|
},
|
|
@@ -24701,7 +24877,7 @@ function* routeBusAlternativesSteps(params, maxAlternatives = 1, includeVisualiz
|
|
|
24701
24877
|
);
|
|
24702
24878
|
return {
|
|
24703
24879
|
...sourceLayerPlan,
|
|
24704
|
-
...preferCornerBoundaryVia || bus.connections.length > 1 ? { sourceEscapeSegmentCount: sourceLayerPlan.segments.length } : {},
|
|
24880
|
+
...preferCornerBoundaryVia || bus.connections.length > 1 || !boundarySide ? { sourceEscapeSegmentCount: sourceLayerPlan.segments.length } : {},
|
|
24705
24881
|
targetLayer,
|
|
24706
24882
|
exitPoint: finalExitPoint,
|
|
24707
24883
|
via,
|
|
@@ -25511,6 +25687,99 @@ function matchBusPlanLengths(params) {
|
|
|
25511
25687
|
if (++attempts >= 4) break;
|
|
25512
25688
|
}
|
|
25513
25689
|
}
|
|
25690
|
+
if (!acceptedPlans && params.allowUnconstrainedLaneRerouting) {
|
|
25691
|
+
let rerouteAttempts = 0;
|
|
25692
|
+
candidateSearch: for (const targetAddedLength of targetAddedLengths) {
|
|
25693
|
+
const candidates = createTunedPlanCandidates({
|
|
25694
|
+
plan: shortest,
|
|
25695
|
+
bus,
|
|
25696
|
+
targetAddedLength,
|
|
25697
|
+
clearance,
|
|
25698
|
+
sharedBoundary: bus.sharedBoundary,
|
|
25699
|
+
allowInsideDenseBounds: allowMatchingInsideDenseBounds
|
|
25700
|
+
});
|
|
25701
|
+
for (const candidate of candidates) {
|
|
25702
|
+
if (!fanoutPlansAreClear({
|
|
25703
|
+
plans: [candidate],
|
|
25704
|
+
srj: inputSrj,
|
|
25705
|
+
sharedBoundary,
|
|
25706
|
+
clearance,
|
|
25707
|
+
allowBlindAndBuriedVias,
|
|
25708
|
+
allowSameNetMerges
|
|
25709
|
+
}))
|
|
25710
|
+
continue;
|
|
25711
|
+
const blockers = matchedPlans.filter(
|
|
25712
|
+
(plan) => plan !== shortest && !fanoutPlansAreMutuallyClear({
|
|
25713
|
+
plans: [candidate, plan],
|
|
25714
|
+
srj: inputSrj,
|
|
25715
|
+
clearance,
|
|
25716
|
+
allowSameNetMerges
|
|
25717
|
+
})
|
|
25718
|
+
);
|
|
25719
|
+
if (blockers.length !== 1) continue;
|
|
25720
|
+
const blocker = blockers[0];
|
|
25721
|
+
const blockerBus = preparedBuses.find(
|
|
25722
|
+
(prepared) => prepared.busId === blocker.busId
|
|
25723
|
+
);
|
|
25724
|
+
if (!blockerBus || blockerBus.termination.type !== "boundary" || blockerBus.maxLengthSkew !== void 0 || blockerBus.connections.length !== 1 || !blocker.via || blocker.additionalVias?.length || blocker.planeEndpointVia || blocker.segments.filter(
|
|
25725
|
+
(segment2) => segment2.layer === blocker.sourceLayer
|
|
25726
|
+
).length !== 1)
|
|
25727
|
+
continue;
|
|
25728
|
+
const nextPlans = matchedPlans.map(
|
|
25729
|
+
(plan) => plan === shortest ? candidate : plan
|
|
25730
|
+
);
|
|
25731
|
+
for (const alignGridToPads of [true, false]) {
|
|
25732
|
+
if (rerouteAttempts++ >= 4) break candidateSearch;
|
|
25733
|
+
const rerouted = routeViaMinimalWinding({
|
|
25734
|
+
srj: inputSrj,
|
|
25735
|
+
bus: blockerBus,
|
|
25736
|
+
terminals: [
|
|
25737
|
+
{
|
|
25738
|
+
connection: blockerBus.connections[0],
|
|
25739
|
+
viaPoint: blocker.via.center,
|
|
25740
|
+
exitPoint: blocker.exitPoint
|
|
25741
|
+
}
|
|
25742
|
+
],
|
|
25743
|
+
targetLayer: blocker.targetLayer,
|
|
25744
|
+
acceptedPlans: nextPlans.filter((plan) => plan !== blocker),
|
|
25745
|
+
layerNames: getCopperLayerNames(inputSrj.layerCount),
|
|
25746
|
+
traceWidth: blocker.segments[0].width,
|
|
25747
|
+
viaDiameter: blocker.via.diameter,
|
|
25748
|
+
viaHoleDiameter: blocker.via.holeDiameter,
|
|
25749
|
+
clearance,
|
|
25750
|
+
allowBlindAndBuriedVias,
|
|
25751
|
+
allowSameNetMerges,
|
|
25752
|
+
gridStepDivisor: 2,
|
|
25753
|
+
alignGridToPads,
|
|
25754
|
+
maximumRouteOrderAttempts: 1,
|
|
25755
|
+
preferTargetDirectedLaneBias: true
|
|
25756
|
+
})?.[0];
|
|
25757
|
+
if (!rerouted) continue;
|
|
25758
|
+
const repaired = createPlanWithSegments(blocker, [
|
|
25759
|
+
blocker.segments[0],
|
|
25760
|
+
...rerouted.segments.slice(1)
|
|
25761
|
+
]);
|
|
25762
|
+
if (!repaired) continue;
|
|
25763
|
+
const repairedPlans = nextPlans.map(
|
|
25764
|
+
(plan) => plan === blocker ? repaired : plan
|
|
25765
|
+
);
|
|
25766
|
+
if (getBusSkew(
|
|
25767
|
+
repairedPlans.filter((plan) => plan.busId === bus.busId)
|
|
25768
|
+
) > maxLengthSkew + EPSILON8 || !fanoutPlansAreClear({
|
|
25769
|
+
plans: repairedPlans,
|
|
25770
|
+
srj: inputSrj,
|
|
25771
|
+
sharedBoundary,
|
|
25772
|
+
clearance,
|
|
25773
|
+
allowBlindAndBuriedVias,
|
|
25774
|
+
allowSameNetMerges
|
|
25775
|
+
}) || candidatePlansAreFeasible && !candidatePlansAreFeasible(repairedPlans))
|
|
25776
|
+
continue;
|
|
25777
|
+
acceptedPlans = repairedPlans;
|
|
25778
|
+
break candidateSearch;
|
|
25779
|
+
}
|
|
25780
|
+
}
|
|
25781
|
+
}
|
|
25782
|
+
}
|
|
25514
25783
|
if (!acceptedPlans) return { plans: null, failedBus: bus };
|
|
25515
25784
|
matchedPlans = acceptedPlans;
|
|
25516
25785
|
}
|
|
@@ -30598,6 +30867,7 @@ var FanoutSolver = class extends BaseSolver {
|
|
|
30598
30867
|
*/
|
|
30599
30868
|
*routeDenseThroughAllMixedTerminationSteps(params) {
|
|
30600
30869
|
if (this.config.allowBlindAndBuriedVias) return null;
|
|
30870
|
+
let boundaryViaPointsForRetry = params.preferredBoundaryViaPoints;
|
|
30601
30871
|
const usePadAlignedDenseRouting = params.denseRoutingStrategy !== "boundary-aligned";
|
|
30602
30872
|
const debugDense = (...values) => {
|
|
30603
30873
|
if (process.env.FANOUT_DEBUG_DENSE === "1") {
|
|
@@ -30632,7 +30902,7 @@ var FanoutSolver = class extends BaseSolver {
|
|
|
30632
30902
|
this.config.allowBlindAndBuriedVias
|
|
30633
30903
|
);
|
|
30634
30904
|
const useConfiguredDensePlaneRouting = configuredDensePlaneRouting || useAdaptiveDensePlaneRouting;
|
|
30635
|
-
const useAdaptiveJointPlaneSelection = useAdaptiveDensePlaneRouting && (params.planeReservationRetryCount ?? 0) === 0;
|
|
30905
|
+
const useAdaptiveJointPlaneSelection = useAdaptiveDensePlaneRouting && ((params.planeReservationRetryCount ?? 0) === 0 || Boolean(params.preferredBoundaryViaPoints));
|
|
30636
30906
|
const matchLengthsAfterPlanes = useConfiguredDensePlaneRouting && params.lengthMatchingStage !== "before-planes";
|
|
30637
30907
|
const useJointBoundaryViaReservation = shouldUseJointBoundaryViaReservation(
|
|
30638
30908
|
unsortedBoundaryBuses.map((bus) => bus.connections.length)
|
|
@@ -30895,9 +31165,23 @@ var FanoutSolver = class extends BaseSolver {
|
|
|
30895
31165
|
const throughAllLeadingSingletonBuses = hasThreeWideBoundaryBuses ? singletonBoundaryBuses.filter((singletonBus) => {
|
|
30896
31166
|
const containingWideBus = getContainingWideSourceField(singletonBus);
|
|
30897
31167
|
const singletonTargetLayer = params.busLayerAssignments[singletonBus.busId];
|
|
30898
|
-
|
|
31168
|
+
if (!containingWideBus || !singletonTargetLayer) return false;
|
|
31169
|
+
const containingWideLayers = containingWideBus.routableEscapeLayers ?? containingWideBus.allowedLayers ?? [];
|
|
31170
|
+
const sourceAxis = singletonBus.exitEdge === "left" || singletonBus.exitEdge === "right" ? "x" : "y";
|
|
31171
|
+
const wideCoordinates = containingWideBus.connections.map(
|
|
31172
|
+
(connection) => connection.sourcePoint[sourceAxis]
|
|
31173
|
+
);
|
|
31174
|
+
const outwardSourceCoordinate = singletonBus.exitEdge === "left" || singletonBus.exitEdge === "bottom" ? Math.min(...wideCoordinates) : Math.max(...wideCoordinates);
|
|
31175
|
+
const isOnOutwardSourceEdge = singletonBus.connections.every(
|
|
31176
|
+
(connection) => Math.abs(
|
|
31177
|
+
connection.sourcePoint[sourceAxis] - outwardSourceCoordinate
|
|
31178
|
+
) < 1e-9
|
|
31179
|
+
);
|
|
30899
31180
|
return Boolean(
|
|
30900
|
-
|
|
31181
|
+
!containingWideLayers.includes(singletonTargetLayer) || useAdaptiveDensePlaneRouting && isOnOutwardSourceEdge && getCornerBandSide(
|
|
31182
|
+
singletonBus.exitEdge,
|
|
31183
|
+
singletonBus.preferredExit
|
|
31184
|
+
)
|
|
30901
31185
|
);
|
|
30902
31186
|
}) : [];
|
|
30903
31187
|
const throughAllLeadingCompanionBuses = throughAllLeadingSingletonBuses.flatMap((singletonBus) => {
|
|
@@ -30940,8 +31224,15 @@ var FanoutSolver = class extends BaseSolver {
|
|
|
30940
31224
|
...process.env.FANOUT_DEBUG_PROVISIONAL_NARROW === "1" ? boundaryBuses.filter((bus) => bus.connections.length < 8) : [],
|
|
30941
31225
|
...singletonDeferralCandidates.filter((bus) => {
|
|
30942
31226
|
const containingBus = getContainingWideSourceField(bus);
|
|
30943
|
-
const
|
|
30944
|
-
|
|
31227
|
+
const sourcePoint = bus.connections[0].sourcePoint;
|
|
31228
|
+
const componentCenter = {
|
|
31229
|
+
x: (bus.componentBounds.minX + bus.componentBounds.maxX) / 2,
|
|
31230
|
+
y: (bus.componentBounds.minY + bus.componentBounds.maxY) / 2
|
|
31231
|
+
};
|
|
31232
|
+
const boundaryDirection = bus.exitEdge ? getDirectionForExitEdge(bus.exitEdge) : bus.direction;
|
|
31233
|
+
const inwardProjection = boundaryDirection === "right" ? componentCenter.x - sourcePoint.x : boundaryDirection === "left" ? sourcePoint.x - componentCenter.x : boundaryDirection === "up" ? componentCenter.y - sourcePoint.y : sourcePoint.y - componentCenter.y;
|
|
31234
|
+
const reserveEmbeddedSourceEscape = usePadAlignedDenseRouting && !useConfiguredDensePlaneRouting && containingBus && (params.busLayerAssignments[containingBus.busId] === params.busLayerAssignments[bus.busId] || inwardProjection > 1e-9);
|
|
31235
|
+
return !leadingWideSingletonBuses.includes(bus) && !reserveEmbeddedSourceEscape;
|
|
30945
31236
|
}),
|
|
30946
31237
|
...hasThreeWideBoundaryBuses ? boundaryBuses.filter(
|
|
30947
31238
|
(bus) => bus.connections.length === 2 && !narrowBusOverlapsWideTargetSpan(bus) && !leadingWideSingletonBuses.includes(bus)
|
|
@@ -30972,6 +31263,7 @@ var FanoutSolver = class extends BaseSolver {
|
|
|
30972
31263
|
traceWidth: this.config.traceWidth,
|
|
30973
31264
|
clearance: this.config.clearance,
|
|
30974
31265
|
maximumSearchStates: 1e5,
|
|
31266
|
+
preferredViaPointsByConnectionIndex: params.preferredBoundaryViaPoints,
|
|
30975
31267
|
preferredBoundaryPerpendicularSideByBusId,
|
|
30976
31268
|
preferBoundaryOutwardByBusId,
|
|
30977
31269
|
additionalObstacles: denseAdditionalObstacles,
|
|
@@ -30987,6 +31279,7 @@ var FanoutSolver = class extends BaseSolver {
|
|
|
30987
31279
|
traceWidth: this.config.traceWidth,
|
|
30988
31280
|
clearance: this.config.clearance,
|
|
30989
31281
|
maximumSearchStates: 2e4,
|
|
31282
|
+
preferredViaPointsByConnectionIndex: params.preferredBoundaryViaPoints,
|
|
30990
31283
|
preferredBoundaryPerpendicularSideByBusId,
|
|
30991
31284
|
preferBoundaryOutwardByBusId,
|
|
30992
31285
|
additionalObstacles: denseAdditionalObstacles,
|
|
@@ -31034,6 +31327,7 @@ var FanoutSolver = class extends BaseSolver {
|
|
|
31034
31327
|
traceWidth: this.config.traceWidth,
|
|
31035
31328
|
clearance: this.config.clearance,
|
|
31036
31329
|
maximumSearchStates: 1e5,
|
|
31330
|
+
preferredViaPointsByConnectionIndex: params.preferredBoundaryViaPoints,
|
|
31037
31331
|
preferredBoundaryPerpendicularSideByBusId,
|
|
31038
31332
|
preferBoundaryOutwardByBusId,
|
|
31039
31333
|
fixedViaPointsByConnectionIndex: seedViaPoints,
|
|
@@ -31084,6 +31378,74 @@ var FanoutSolver = class extends BaseSolver {
|
|
|
31084
31378
|
bus
|
|
31085
31379
|
])
|
|
31086
31380
|
];
|
|
31381
|
+
const areAdjacentInvertedNarrowBuses = (first, second) => {
|
|
31382
|
+
if (!usePadAlignedDenseRouting || useConfiguredDensePlaneRouting || first.componentId !== second.componentId || first.exitEdge !== second.exitEdge || first.direction !== second.direction || getCornerBandSide(first.exitEdge, first.preferredExit) !== getCornerBandSide(second.exitEdge, second.preferredExit) || params.busLayerAssignments[first.busId] !== params.busLayerAssignments[second.busId] || getContainingWideSourceField(first) !== getContainingWideSourceField(second) || !getContainingWideSourceField(first))
|
|
31383
|
+
return false;
|
|
31384
|
+
const firstCenter = {
|
|
31385
|
+
x: first.connections.reduce(
|
|
31386
|
+
(sum, connection) => sum + connection.sourcePoint.x,
|
|
31387
|
+
0
|
|
31388
|
+
) / first.connections.length,
|
|
31389
|
+
y: first.connections.reduce(
|
|
31390
|
+
(sum, connection) => sum + connection.sourcePoint.y,
|
|
31391
|
+
0
|
|
31392
|
+
) / first.connections.length
|
|
31393
|
+
};
|
|
31394
|
+
const secondCenter = {
|
|
31395
|
+
x: second.connections.reduce(
|
|
31396
|
+
(sum, connection) => sum + connection.sourcePoint.x,
|
|
31397
|
+
0
|
|
31398
|
+
) / second.connections.length,
|
|
31399
|
+
y: second.connections.reduce(
|
|
31400
|
+
(sum, connection) => sum + connection.sourcePoint.y,
|
|
31401
|
+
0
|
|
31402
|
+
) / second.connections.length
|
|
31403
|
+
};
|
|
31404
|
+
if (Math.hypot(
|
|
31405
|
+
firstCenter.x - secondCenter.x,
|
|
31406
|
+
firstCenter.y - secondCenter.y
|
|
31407
|
+
) > 1.5 * Math.min(first.pitchX, first.pitchY))
|
|
31408
|
+
return false;
|
|
31409
|
+
const axis = first.exitEdge === "left" || first.exitEdge === "right" ? "y" : "x";
|
|
31410
|
+
const targetTrack = (bus) => bus.connections.reduce(
|
|
31411
|
+
(sum, connection) => sum + (connection.exitTargetPoint ?? connection.targetPoint)[axis],
|
|
31412
|
+
0
|
|
31413
|
+
) / bus.connections.length;
|
|
31414
|
+
return (firstCenter[axis] - secondCenter[axis]) * (targetTrack(first) - targetTrack(second)) < -1e-9;
|
|
31415
|
+
};
|
|
31416
|
+
const centeredPairPromotionGroups = /* @__PURE__ */ new Set();
|
|
31417
|
+
for (const singleton of multiLayerLeadingSingletonBuses) {
|
|
31418
|
+
if (getCornerBandSide(singleton.exitEdge, singleton.preferredExit))
|
|
31419
|
+
continue;
|
|
31420
|
+
for (const pair of boundaryBuses) {
|
|
31421
|
+
if (pair.connections.length !== 2 || !areAdjacentInvertedNarrowBuses(pair, singleton))
|
|
31422
|
+
continue;
|
|
31423
|
+
const pairIndex = denseBoundaryBusesInRoutingOrder.indexOf(pair);
|
|
31424
|
+
const singletonIndex = denseBoundaryBusesInRoutingOrder.indexOf(singleton);
|
|
31425
|
+
if (pairIndex > singletonIndex) {
|
|
31426
|
+
denseBoundaryBusesInRoutingOrder.splice(pairIndex, 1);
|
|
31427
|
+
denseBoundaryBusesInRoutingOrder.splice(singletonIndex, 0, pair);
|
|
31428
|
+
centeredPairPromotionGroups.add(
|
|
31429
|
+
`${pair.componentId}:${pair.exitEdge}`
|
|
31430
|
+
);
|
|
31431
|
+
}
|
|
31432
|
+
}
|
|
31433
|
+
}
|
|
31434
|
+
for (const pair of boundaryBuses) {
|
|
31435
|
+
if (!centeredPairPromotionGroups.has(
|
|
31436
|
+
`${pair.componentId}:${pair.exitEdge}`
|
|
31437
|
+
) || pair.connections.length !== 2 || !getCornerBandSide(pair.exitEdge, pair.preferredExit))
|
|
31438
|
+
continue;
|
|
31439
|
+
for (const singleton of singletonBoundaryBuses) {
|
|
31440
|
+
if (!areAdjacentInvertedNarrowBuses(singleton, pair)) continue;
|
|
31441
|
+
const singletonIndex = denseBoundaryBusesInRoutingOrder.indexOf(singleton);
|
|
31442
|
+
const pairIndex = denseBoundaryBusesInRoutingOrder.indexOf(pair);
|
|
31443
|
+
if (singletonIndex > pairIndex) {
|
|
31444
|
+
denseBoundaryBusesInRoutingOrder.splice(singletonIndex, 1);
|
|
31445
|
+
denseBoundaryBusesInRoutingOrder.splice(pairIndex, 0, singleton);
|
|
31446
|
+
}
|
|
31447
|
+
}
|
|
31448
|
+
}
|
|
31087
31449
|
let fixedViaPointsByConnectionIndex = seedViaPoints;
|
|
31088
31450
|
let matchedPlans = [];
|
|
31089
31451
|
let matchedRoutingSucceeded = true;
|
|
@@ -31169,7 +31531,9 @@ var FanoutSolver = class extends BaseSolver {
|
|
|
31169
31531
|
allowBoundarySideViaFallback: bus.connections.length === 1,
|
|
31170
31532
|
preferCornerBoundaryVia: useConfiguredDensePlaneRouting,
|
|
31171
31533
|
adaptiveWindingRouteOrder,
|
|
31172
|
-
|
|
31534
|
+
// Retain pad-aligned channels even when plane sites are reserved
|
|
31535
|
+
// adaptively; the boundary grid can fence off a turning wide bus.
|
|
31536
|
+
alignWindingGridToPads: usePadAlignedDenseRouting && !configuredDensePlaneRouting,
|
|
31173
31537
|
fixedViaFallbackRouteOrderAttempts: adaptiveWindingRouteOrder ? 60 : useConfiguredDensePlaneRouting ? 6 : 24,
|
|
31174
31538
|
cornerBandTargetTrackOffset: getCornerBandTargetTrackOffset(bus)
|
|
31175
31539
|
};
|
|
@@ -31194,6 +31558,7 @@ var FanoutSolver = class extends BaseSolver {
|
|
|
31194
31558
|
(candidate) => candidate.connections.length < 8 && getContainingWideSourceField(candidate) === bus && matchedPlans.some((plan) => plan.busId === candidate.busId)
|
|
31195
31559
|
);
|
|
31196
31560
|
const preferSingleLayerWinding = useConfiguredDensePlaneRouting && singleLayerBus !== bus && !embeddedNarrowBusAlreadyRouted;
|
|
31561
|
+
let usedSoftPlaneRepair = false;
|
|
31197
31562
|
let busPlans = (yield* routeAlternatives(
|
|
31198
31563
|
preferSingleLayerWinding ? { ...routeParams, bus: singleLayerBus } : routeParams,
|
|
31199
31564
|
1
|
|
@@ -31293,6 +31658,71 @@ var FanoutSolver = class extends BaseSolver {
|
|
|
31293
31658
|
}
|
|
31294
31659
|
}
|
|
31295
31660
|
}
|
|
31661
|
+
if (!busPlans && bus.connections.length >= 8 && boundaryBuses.some(
|
|
31662
|
+
(candidate) => candidate.connections.length >= 8 && matchedPlans.some((plan) => plan.busId === candidate.busId)
|
|
31663
|
+
)) {
|
|
31664
|
+
const committedNames = new Set(
|
|
31665
|
+
matchedPlans.map((plan) => plan.connectionName)
|
|
31666
|
+
);
|
|
31667
|
+
const futurePlaneNames = new Set(
|
|
31668
|
+
this.preparedBuses.filter((candidate) => candidate.termination.type === "plane").flatMap(
|
|
31669
|
+
(candidate) => candidate.connections.map(
|
|
31670
|
+
(connection) => connection.connection.name
|
|
31671
|
+
)
|
|
31672
|
+
).filter((name) => !committedNames.has(name))
|
|
31673
|
+
);
|
|
31674
|
+
const freePlans = (yield* routeAlternatives(
|
|
31675
|
+
{
|
|
31676
|
+
...routeParams,
|
|
31677
|
+
fixedViaPointsByConnectionIndex: void 0,
|
|
31678
|
+
reservedVias: routeParams.reservedVias.filter(
|
|
31679
|
+
(reserved) => !futurePlaneNames.has(reserved.connectionName)
|
|
31680
|
+
),
|
|
31681
|
+
softReservedVias: routeParams.reservedVias.filter(
|
|
31682
|
+
(reserved) => futurePlaneNames.has(reserved.connectionName)
|
|
31683
|
+
)
|
|
31684
|
+
},
|
|
31685
|
+
1
|
|
31686
|
+
))[0];
|
|
31687
|
+
if (freePlans) {
|
|
31688
|
+
const allPlans = [...matchedPlans, ...freePlans];
|
|
31689
|
+
const rematchedPoints = matchComponentDogboneViaSites(
|
|
31690
|
+
this.preparedBuses,
|
|
31691
|
+
{
|
|
31692
|
+
viaDiameter: this.config.viaDiameter,
|
|
31693
|
+
viaHoleDiameter: this.config.viaHoleDiameter,
|
|
31694
|
+
traceWidth: this.config.traceWidth,
|
|
31695
|
+
clearance: this.config.clearance,
|
|
31696
|
+
maximumSearchStates: 3e6,
|
|
31697
|
+
preferredBoundaryPerpendicularSideByBusId,
|
|
31698
|
+
preferBoundaryOutwardByBusId,
|
|
31699
|
+
fixedViaPointsByConnectionIndex: new Map(
|
|
31700
|
+
allPlans.filter((plan) => plan.via).map((plan) => [plan.connectionIndex, plan.via.center])
|
|
31701
|
+
),
|
|
31702
|
+
preferredViaPointsByConnectionIndex: fixedViaPointsByConnectionIndex,
|
|
31703
|
+
blockingSegments: allPlans.flatMap(
|
|
31704
|
+
(plan) => plan.segments.map((segment2) => ({
|
|
31705
|
+
connectionIndex: plan.connectionIndex,
|
|
31706
|
+
segment: segment2
|
|
31707
|
+
}))
|
|
31708
|
+
),
|
|
31709
|
+
additionalObstacles: this.routingSrj.obstacles,
|
|
31710
|
+
preferPlaneCheckerboardSites: useConfiguredDensePlaneRouting,
|
|
31711
|
+
canShareCopper
|
|
31712
|
+
}
|
|
31713
|
+
);
|
|
31714
|
+
debugDense(
|
|
31715
|
+
"free-sites:rematched",
|
|
31716
|
+
bus.busId,
|
|
31717
|
+
rematchedPoints?.size ?? "failed"
|
|
31718
|
+
);
|
|
31719
|
+
if (rematchedPoints) {
|
|
31720
|
+
busPlans = freePlans;
|
|
31721
|
+
fixedViaPointsByConnectionIndex = rematchedPoints;
|
|
31722
|
+
usedSoftPlaneRepair = true;
|
|
31723
|
+
}
|
|
31724
|
+
}
|
|
31725
|
+
}
|
|
31296
31726
|
if (busPlans && bus.maxLengthSkew !== void 0) {
|
|
31297
31727
|
const lengths = busPlans.map((plan) => plan.length);
|
|
31298
31728
|
const rawSkew = Math.max(...lengths) - Math.min(...lengths);
|
|
@@ -31302,7 +31732,7 @@ var FanoutSolver = class extends BaseSolver {
|
|
|
31302
31732
|
rawSkew,
|
|
31303
31733
|
maximumSkew: bus.maxLengthSkew
|
|
31304
31734
|
});
|
|
31305
|
-
if (needsRouteDiversity && !matchLengthsAfterPlanes) {
|
|
31735
|
+
if (needsRouteDiversity && !matchLengthsAfterPlanes && !usedSoftPlaneRepair) {
|
|
31306
31736
|
busPlans = (yield* routeAlternatives(routeParams, 3)).toSorted(
|
|
31307
31737
|
(first, second) => {
|
|
31308
31738
|
const firstLengths = first.map((plan) => plan.length);
|
|
@@ -31317,6 +31747,20 @@ var FanoutSolver = class extends BaseSolver {
|
|
|
31317
31747
|
return false;
|
|
31318
31748
|
}
|
|
31319
31749
|
matchedPlans.push(...busPlans);
|
|
31750
|
+
if (matchedPlans.length === boundaryBuses.reduce(
|
|
31751
|
+
(sum, candidate) => sum + candidate.connections.length,
|
|
31752
|
+
0
|
|
31753
|
+
) && matchedPlans.some((plan) => {
|
|
31754
|
+
const bus2 = boundaryBuses.find(
|
|
31755
|
+
(candidate) => candidate.busId === plan.busId
|
|
31756
|
+
);
|
|
31757
|
+
if (bus2?.connections.length !== 1 || !plan.via) return false;
|
|
31758
|
+
const { center } = plan.via;
|
|
31759
|
+
return center.x < bus2.componentBounds.minX || center.x > bus2.componentBounds.maxX || center.y < bus2.componentBounds.minY || center.y > bus2.componentBounds.maxY;
|
|
31760
|
+
}))
|
|
31761
|
+
boundaryViaPointsForRetry = new Map(
|
|
31762
|
+
matchedPlans.filter((plan) => plan.via).map((plan) => [plan.connectionIndex, plan.via.center])
|
|
31763
|
+
);
|
|
31320
31764
|
debugDense("route:complete", bus.busId, busPlans.length);
|
|
31321
31765
|
return true;
|
|
31322
31766
|
}.bind(this);
|
|
@@ -31753,7 +32197,9 @@ var FanoutSolver = class extends BaseSolver {
|
|
|
31753
32197
|
}
|
|
31754
32198
|
let alternatePlaneSearchStates = 0;
|
|
31755
32199
|
const maximumAlternatePlaneSearchStates = Number(
|
|
31756
|
-
process.env.FANOUT_DEBUG_ALTERNATE_SEARCH_STATES ??
|
|
32200
|
+
process.env.FANOUT_DEBUG_ALTERNATE_SEARCH_STATES ?? // Keep the initial search short before reserving blocked
|
|
32201
|
+
// plane sites. Later joint repairs retain the full budget.
|
|
32202
|
+
(useAdaptiveDensePlaneRouting && (params.planeReservationRetryCount ?? 0) === 0 ? 1e4 : useConfiguredDensePlaneRouting ? 3e6 : 1e3)
|
|
31757
32203
|
);
|
|
31758
32204
|
const maximumAlternatePlaneRoutes = Number(
|
|
31759
32205
|
process.env.FANOUT_DEBUG_ALTERNATE_ROUTE_COUNT ?? (useConfiguredDensePlaneRouting ? 128 : 8)
|
|
@@ -32494,7 +32940,8 @@ var FanoutSolver = class extends BaseSolver {
|
|
|
32494
32940
|
allowBlindAndBuriedVias: false,
|
|
32495
32941
|
allowSameNetMerges: this.config.allowSameNetMerges,
|
|
32496
32942
|
allowMatchingInsideDenseBounds: true,
|
|
32497
|
-
allowPairLaneSpreading: true
|
|
32943
|
+
allowPairLaneSpreading: true,
|
|
32944
|
+
allowUnconstrainedLaneRerouting: true
|
|
32498
32945
|
};
|
|
32499
32946
|
let matchedLengthResult = matchBusPlanLengths(lengthMatchingParams);
|
|
32500
32947
|
const shortenedBusIds = /* @__PURE__ */ new Set();
|
|
@@ -32569,6 +33016,7 @@ var FanoutSolver = class extends BaseSolver {
|
|
|
32569
33016
|
debugDense("promote-reservations", refinedPromotions);
|
|
32570
33017
|
return yield* this.routeDenseThroughAllMixedTerminationSteps({
|
|
32571
33018
|
...params,
|
|
33019
|
+
preferredBoundaryViaPoints: boundaryViaPointsForRetry,
|
|
32572
33020
|
promotedPlaneReservationBusIds: [
|
|
32573
33021
|
...params.promotedPlaneReservationBusIds ?? [],
|
|
32574
33022
|
...refinedPromotions
|
|
@@ -46511,7 +46959,7 @@ function Group_getRoutingPhasePlans(group) {
|
|
|
46511
46959
|
var package_default = {
|
|
46512
46960
|
name: "@tscircuit/core",
|
|
46513
46961
|
type: "module",
|
|
46514
|
-
version: "0.0.
|
|
46962
|
+
version: "0.0.1849",
|
|
46515
46963
|
types: "dist/index.d.ts",
|
|
46516
46964
|
main: "dist/index.js",
|
|
46517
46965
|
module: "dist/index.js",
|
|
@@ -46551,7 +46999,7 @@ var package_default = {
|
|
|
46551
46999
|
"@tscircuit/common": "^0.0.20",
|
|
46552
47000
|
"@tscircuit/copper-pour-solver": "^0.0.52",
|
|
46553
47001
|
"@tscircuit/create-fdm-enclosure": "0.0.4",
|
|
46554
|
-
"@tscircuit/fanout-solver": "0.0.
|
|
47002
|
+
"@tscircuit/fanout-solver": "0.0.60",
|
|
46555
47003
|
"@tscircuit/footprinter": "^0.0.426",
|
|
46556
47004
|
"@tscircuit/image-utils": "^0.0.8",
|
|
46557
47005
|
"@tscircuit/implicit-copper-pour-solver": "github:tscircuit/implicit-copper-pour-solver#a5cbbda0cd65fd4707c5c1af25779837c25aba92",
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tscircuit/core",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.1850",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"module": "dist/index.js",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"@tscircuit/common": "^0.0.20",
|
|
42
42
|
"@tscircuit/copper-pour-solver": "^0.0.52",
|
|
43
43
|
"@tscircuit/create-fdm-enclosure": "0.0.4",
|
|
44
|
-
"@tscircuit/fanout-solver": "0.0.
|
|
44
|
+
"@tscircuit/fanout-solver": "0.0.60",
|
|
45
45
|
"@tscircuit/footprinter": "^0.0.426",
|
|
46
46
|
"@tscircuit/image-utils": "^0.0.8",
|
|
47
47
|
"@tscircuit/implicit-copper-pour-solver": "github:tscircuit/implicit-copper-pour-solver#a5cbbda0cd65fd4707c5c1af25779837c25aba92",
|