@tscircuit/fanout-solver 0.0.66 → 0.0.67
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/fanout-solver.ts +97 -3
- package/package.json +1 -1
package/lib/fanout-solver.ts
CHANGED
|
@@ -1811,6 +1811,49 @@ export class FanoutSolver extends BaseSolver {
|
|
|
1811
1811
|
const wideBoundaryBuses = unsortedBoundaryBuses.filter(
|
|
1812
1812
|
(bus) => bus.connections.length >= 8,
|
|
1813
1813
|
)
|
|
1814
|
+
const hasForeignAllLayerObstaclesInComponent = wideBoundaryBuses.some(
|
|
1815
|
+
(bus) =>
|
|
1816
|
+
this.routingSrj.obstacles.some(
|
|
1817
|
+
(obstacle) =>
|
|
1818
|
+
obstacle.componentId !== bus.componentId &&
|
|
1819
|
+
this.config.layerNames.every((layer) =>
|
|
1820
|
+
obstacle.layers.includes(layer),
|
|
1821
|
+
) &&
|
|
1822
|
+
obstacle.center.x >= bus.componentBounds.minX &&
|
|
1823
|
+
obstacle.center.x <= bus.componentBounds.maxX &&
|
|
1824
|
+
obstacle.center.y >= bus.componentBounds.minY &&
|
|
1825
|
+
obstacle.center.y <= bus.componentBounds.maxY,
|
|
1826
|
+
),
|
|
1827
|
+
)
|
|
1828
|
+
const dogboneCandidateCountByConnectionIndex = new Map<number, number>()
|
|
1829
|
+
if (hasForeignAllLayerObstaclesInComponent) {
|
|
1830
|
+
for (const candidate of getComponentDogboneViaSiteCandidates(
|
|
1831
|
+
unsortedBoundaryBuses,
|
|
1832
|
+
{
|
|
1833
|
+
viaDiameter: this.config.viaDiameter,
|
|
1834
|
+
viaHoleDiameter: this.config.viaHoleDiameter,
|
|
1835
|
+
traceWidth: this.config.traceWidth,
|
|
1836
|
+
clearance: this.config.clearance,
|
|
1837
|
+
additionalObstacles: this.routingSrj.obstacles,
|
|
1838
|
+
},
|
|
1839
|
+
)) {
|
|
1840
|
+
dogboneCandidateCountByConnectionIndex.set(
|
|
1841
|
+
candidate.connectionIndex,
|
|
1842
|
+
(dogboneCandidateCountByConnectionIndex.get(
|
|
1843
|
+
candidate.connectionIndex,
|
|
1844
|
+
) ?? 0) + 1,
|
|
1845
|
+
)
|
|
1846
|
+
}
|
|
1847
|
+
}
|
|
1848
|
+
const getBusDogboneCandidateCount = (bus: PreparedBus): number =>
|
|
1849
|
+
bus.connections.reduce(
|
|
1850
|
+
(total, connection) =>
|
|
1851
|
+
total +
|
|
1852
|
+
(dogboneCandidateCountByConnectionIndex.get(
|
|
1853
|
+
connection.connectionIndex,
|
|
1854
|
+
) ?? 0),
|
|
1855
|
+
0,
|
|
1856
|
+
)
|
|
1814
1857
|
// A single-layer turning bus beside the end of a centered source field
|
|
1815
1858
|
// has fewer escape choices than a corner bus farther behind it. Reserve
|
|
1816
1859
|
// that turning channel before the farther bus fences its local via sites.
|
|
@@ -1953,6 +1996,18 @@ export class FanoutSolver extends BaseSolver {
|
|
|
1953
1996
|
? first.connections.length - second.connections.length
|
|
1954
1997
|
: second.connections.length - first.connections.length
|
|
1955
1998
|
if (connectionCountDifference !== 0) return connectionCountDifference
|
|
1999
|
+
if (
|
|
2000
|
+
hasForeignAllLayerObstaclesInComponent &&
|
|
2001
|
+
first.connections.length >= 8 &&
|
|
2002
|
+
second.connections.length >= 8
|
|
2003
|
+
) {
|
|
2004
|
+
const dogboneCandidateCountDifference =
|
|
2005
|
+
getBusDogboneCandidateCount(first) -
|
|
2006
|
+
getBusDogboneCandidateCount(second)
|
|
2007
|
+
if (dogboneCandidateCountDifference !== 0) {
|
|
2008
|
+
return dogboneCandidateCountDifference
|
|
2009
|
+
}
|
|
2010
|
+
}
|
|
1956
2011
|
}
|
|
1957
2012
|
const firstLayer = params.busLayerAssignments[first.busId]
|
|
1958
2013
|
const secondLayer = params.busLayerAssignments[second.busId]
|
|
@@ -2571,11 +2626,14 @@ export class FanoutSolver extends BaseSolver {
|
|
|
2571
2626
|
yield
|
|
2572
2627
|
if (seedViaPoints) {
|
|
2573
2628
|
const denseBoundaryBusesInRoutingOrder = [
|
|
2574
|
-
...
|
|
2629
|
+
...(hasForeignAllLayerObstaclesInComponent
|
|
2630
|
+
? []
|
|
2631
|
+
: multiLayerLeadingSingletonBuses),
|
|
2575
2632
|
...boundaryBuses
|
|
2576
2633
|
.filter(
|
|
2577
2634
|
(bus) =>
|
|
2578
|
-
|
|
2635
|
+
(hasForeignAllLayerObstaclesInComponent ||
|
|
2636
|
+
!multiLayerLeadingSingletonBuses.includes(bus)) &&
|
|
2579
2637
|
!throughAllLeadingBuses.includes(bus),
|
|
2580
2638
|
)
|
|
2581
2639
|
.flatMap((bus) => [
|
|
@@ -4643,7 +4701,7 @@ export class FanoutSolver extends BaseSolver {
|
|
|
4643
4701
|
debugDense("plane-route:start", bus.busId)
|
|
4644
4702
|
const targetLayer = params.busLayerAssignments[bus.busId]
|
|
4645
4703
|
const blockingBusCounts = new Map<string, number>()
|
|
4646
|
-
|
|
4704
|
+
let busPlans = targetLayer
|
|
4647
4705
|
? routeBus({
|
|
4648
4706
|
srj: this.routingSrj,
|
|
4649
4707
|
bus,
|
|
@@ -4662,6 +4720,42 @@ export class FanoutSolver extends BaseSolver {
|
|
|
4662
4720
|
fixedViaPointsByConnectionIndex,
|
|
4663
4721
|
})
|
|
4664
4722
|
: null
|
|
4723
|
+
if (
|
|
4724
|
+
!busPlans &&
|
|
4725
|
+
targetLayer &&
|
|
4726
|
+
hasForeignAllLayerObstaclesInComponent
|
|
4727
|
+
) {
|
|
4728
|
+
// Plane dogbones are matched before their full routes exist. A
|
|
4729
|
+
// preceding plane escape can therefore consume copper clearance
|
|
4730
|
+
// that the site matcher could not account for. Re-select only the
|
|
4731
|
+
// failed dogbone against the routes that are actually committed.
|
|
4732
|
+
busPlans = routeBus({
|
|
4733
|
+
srj: this.routingSrj,
|
|
4734
|
+
bus,
|
|
4735
|
+
targetLayer,
|
|
4736
|
+
acceptedPlans: matchedPlans,
|
|
4737
|
+
layerNames: this.config.layerNames,
|
|
4738
|
+
traceWidth: this.config.traceWidth,
|
|
4739
|
+
viaDiameter: this.config.viaDiameter,
|
|
4740
|
+
viaHoleDiameter: this.config.viaHoleDiameter,
|
|
4741
|
+
clearance: this.config.clearance,
|
|
4742
|
+
compactBusTracks: this.config.compactBusTracks,
|
|
4743
|
+
allowBlindAndBuriedVias: false,
|
|
4744
|
+
allowSameNetMerges: this.config.allowSameNetMerges,
|
|
4745
|
+
staticClearanceCache: this.routeStaticClearanceCache,
|
|
4746
|
+
blockingBusCounts,
|
|
4747
|
+
})
|
|
4748
|
+
if (busPlans) {
|
|
4749
|
+
fixedViaPointsByConnectionIndex = new Map([
|
|
4750
|
+
...fixedViaPointsByConnectionIndex,
|
|
4751
|
+
...busPlans.flatMap((plan) =>
|
|
4752
|
+
plan.via
|
|
4753
|
+
? [[plan.connectionIndex, plan.via.center] as const]
|
|
4754
|
+
: [],
|
|
4755
|
+
),
|
|
4756
|
+
])
|
|
4757
|
+
}
|
|
4758
|
+
}
|
|
4665
4759
|
if (!busPlans) {
|
|
4666
4760
|
debugDense(
|
|
4667
4761
|
"plane-route:failed",
|