@tscircuit/fanout-solver 0.0.38 → 0.0.40

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 CHANGED
@@ -86,6 +86,13 @@ and treats each bus-layer decision atomically.
86
86
  - `allowSameNetMerges` lets grouped branches such as VCC or GND reuse connected
87
87
  copper instead of reserving artificial clearance from one another. It is
88
88
  opt-in; different electrical nets remain hard obstacles.
89
+ - `allowBlindAndBuriedVias` describes the host board's manufacturing rule. It
90
+ defaults to `true` for standalone compatibility; hosts that manufacture
91
+ through-all vias should pass `false`, which reserves every copper layer in
92
+ route planning and emitted-copper DRC while preserving each route's logical
93
+ layer transition.
94
+ - Via-in-pad remains opt-in through `SimpleRouteJson.allowViaInPad === true`.
95
+ Undefined or false uses an offset dogbone, including plane terminations.
89
96
  - Audits route continuity, unique connection coverage, boundary exits, and
90
97
  retained downstream endpoints before marking a solution complete.
91
98
  - `completeOriginalEndpoints` adds a bounded fail-first completion stage after
@@ -0,0 +1,48 @@
1
+ import type { SimpleRouteJson } from "@tscircuit/capacity-autorouter"
2
+ import { getViaSpanLayers } from "./layer-names"
3
+ import type {
4
+ FanoutSimplifiedPcbTrace,
5
+ SimpleRouteJsonWithFanoutPlanes,
6
+ } from "./types"
7
+
8
+ export function addViaLayerMetadataToTrace(params: {
9
+ trace: FanoutSimplifiedPcbTrace
10
+ layerNames: string[]
11
+ allowBlindAndBuriedVias: boolean
12
+ }): FanoutSimplifiedPcbTrace {
13
+ const { trace, layerNames, allowBlindAndBuriedVias } = params
14
+ return {
15
+ ...trace,
16
+ route: trace.route.map((routePoint) =>
17
+ routePoint.route_type === "via" && !allowBlindAndBuriedVias
18
+ ? {
19
+ ...routePoint,
20
+ layers: getViaSpanLayers({
21
+ fromLayer: routePoint.from_layer,
22
+ toLayer: routePoint.to_layer,
23
+ layerNames,
24
+ allowBlindAndBuriedVias,
25
+ }),
26
+ }
27
+ : { ...routePoint },
28
+ ),
29
+ }
30
+ }
31
+
32
+ export function addViaLayerMetadataToSrj(params: {
33
+ srj: SimpleRouteJsonWithFanoutPlanes | SimpleRouteJson
34
+ layerNames: string[]
35
+ allowBlindAndBuriedVias: boolean
36
+ }): SimpleRouteJsonWithFanoutPlanes {
37
+ const { srj, layerNames, allowBlindAndBuriedVias } = params
38
+ return {
39
+ ...srj,
40
+ traces: (srj.traces ?? []).map((trace) =>
41
+ addViaLayerMetadataToTrace({
42
+ trace,
43
+ layerNames,
44
+ allowBlindAndBuriedVias,
45
+ }),
46
+ ),
47
+ }
48
+ }
@@ -12,8 +12,8 @@ import {
12
12
  } from "./geometry"
13
13
  import { obstacleSharesElectricalNet } from "./net-identity"
14
14
  import type {
15
- FanoutEndpointCompletionReport,
16
15
  FanoutDownstreamRouter,
16
+ FanoutEndpointCompletionReport,
17
17
  FanoutRoutePlan,
18
18
  Point2D,
19
19
  } from "./types"
@@ -267,6 +267,7 @@ function findLocalBranch(params: {
267
267
  viaDiameter: number
268
268
  viaHoleDiameter: number
269
269
  clearance: number
270
+ allowBlindAndBuriedVias: boolean
270
271
  }): {
271
272
  trace?: SimplifiedPcbTrace
272
273
  blockingConnectionNames: string[]
@@ -280,6 +281,7 @@ function findLocalBranch(params: {
280
281
  viaDiameter,
281
282
  viaHoleDiameter,
282
283
  clearance,
284
+ allowBlindAndBuriedVias,
283
285
  } = params
284
286
  const { outward, perpendicular } = getTerminalDirections({ inputSrj, plan })
285
287
  const branchStarts: Array<Point2D & { layer: string }> = [
@@ -414,6 +416,7 @@ function findLocalBranch(params: {
414
416
  inputSrj,
415
417
  routedSrj: candidateSrj,
416
418
  clearance,
419
+ allowBlindAndBuriedVias,
417
420
  })
418
421
  if (!drc.valid) {
419
422
  if (drc.issues.length < bestIssueCount) {
@@ -457,6 +460,7 @@ function runLocalCompletionPass(params: {
457
460
  viaDiameter: number
458
461
  viaHoleDiameter: number
459
462
  clearance: number
463
+ allowBlindAndBuriedVias: boolean
460
464
  }): CompletionAttempt {
461
465
  const {
462
466
  inputSrj,
@@ -466,6 +470,7 @@ function runLocalCompletionPass(params: {
466
470
  viaDiameter,
467
471
  viaHoleDiameter,
468
472
  clearance,
473
+ allowBlindAndBuriedVias,
469
474
  } = params
470
475
  const traces: SimplifiedPcbTrace[] = []
471
476
  const failedConnectionNames: string[] = []
@@ -480,6 +485,7 @@ function runLocalCompletionPass(params: {
480
485
  viaDiameter,
481
486
  viaHoleDiameter,
482
487
  clearance,
488
+ allowBlindAndBuriedVias,
483
489
  })
484
490
  if (result.trace) {
485
491
  traces.push(result.trace)
@@ -506,6 +512,7 @@ function runLocalCompletionPass(params: {
506
512
  inputSrj,
507
513
  routedSrj: simpleRouteJson,
508
514
  clearance,
515
+ allowBlindAndBuriedVias,
509
516
  }),
510
517
  }
511
518
  }
@@ -598,8 +605,16 @@ function acceptDownstreamTraces(params: {
598
605
  localTraces: SimplifiedPcbTrace[]
599
606
  candidates: SimplifiedPcbTrace[]
600
607
  clearance: number
608
+ allowBlindAndBuriedVias: boolean
601
609
  }): SimplifiedPcbTrace[] {
602
- const { inputSrj, fanoutSrj, localTraces, candidates, clearance } = params
610
+ const {
611
+ inputSrj,
612
+ fanoutSrj,
613
+ localTraces,
614
+ candidates,
615
+ clearance,
616
+ allowBlindAndBuriedVias,
617
+ } = params
603
618
  const baselineTraces = [...(fanoutSrj.traces ?? []), ...localTraces]
604
619
  const baselineSrj = { ...fanoutSrj, traces: baselineTraces }
605
620
  const baselineConnectivity = validateOriginalEndpointConnectivity({
@@ -638,6 +653,7 @@ function acceptDownstreamTraces(params: {
638
653
  inputSrj,
639
654
  routedSrj: combinedSrj,
640
655
  clearance,
656
+ allowBlindAndBuriedVias,
641
657
  }).valid
642
658
  ) {
643
659
  return usefulCandidates
@@ -655,6 +671,7 @@ function acceptDownstreamTraces(params: {
655
671
  inputSrj,
656
672
  routedSrj: candidateSrj,
657
673
  clearance,
674
+ allowBlindAndBuriedVias,
658
675
  })
659
676
  if (!drc.valid) continue
660
677
  const before = validateOriginalEndpointConnectivity({
@@ -729,6 +746,7 @@ function findDownstreamTerminalBranch(params: {
729
746
  viaDiameter: number
730
747
  viaHoleDiameter: number
731
748
  clearance: number
749
+ allowBlindAndBuriedVias: boolean
732
750
  }): SimplifiedPcbTrace | undefined {
733
751
  const {
734
752
  inputSrj,
@@ -739,6 +757,7 @@ function findDownstreamTerminalBranch(params: {
739
757
  viaDiameter,
740
758
  viaHoleDiameter,
741
759
  clearance,
760
+ allowBlindAndBuriedVias,
742
761
  } = params
743
762
  const branchStart = {
744
763
  x: plan.exitPoint.x,
@@ -782,6 +801,7 @@ function findDownstreamTerminalBranch(params: {
782
801
  inputSrj,
783
802
  routedSrj: candidateSrj,
784
803
  clearance,
804
+ allowBlindAndBuriedVias,
785
805
  }).valid
786
806
  ) {
787
807
  return undefined
@@ -880,6 +900,7 @@ export function completeOriginalEndpoints(params: {
880
900
  viaDiameter: number
881
901
  viaHoleDiameter: number
882
902
  clearance: number
903
+ allowBlindAndBuriedVias?: boolean
883
904
  effort?: number
884
905
  routeDownstreamConnections?: FanoutDownstreamRouter
885
906
  }): CompleteOriginalEndpointsResult {
@@ -891,6 +912,7 @@ export function completeOriginalEndpoints(params: {
891
912
  viaDiameter,
892
913
  viaHoleDiameter,
893
914
  clearance,
915
+ allowBlindAndBuriedVias = true,
894
916
  effort = 1,
895
917
  routeDownstreamConnections,
896
918
  } = params
@@ -899,6 +921,7 @@ export function completeOriginalEndpoints(params: {
899
921
  inputSrj,
900
922
  routedSrj: fanoutSrj,
901
923
  clearance,
924
+ allowBlindAndBuriedVias,
902
925
  })
903
926
  const baselineConnectivity = validateOriginalEndpointConnectivity({
904
927
  inputSrj,
@@ -952,6 +975,7 @@ export function completeOriginalEndpoints(params: {
952
975
  viaDiameter,
953
976
  viaHoleDiameter,
954
977
  clearance,
978
+ allowBlindAndBuriedVias,
955
979
  })
956
980
  searchPassCount++
957
981
  if (
@@ -995,6 +1019,7 @@ export function completeOriginalEndpoints(params: {
995
1019
  viaDiameter,
996
1020
  viaHoleDiameter,
997
1021
  clearance,
1022
+ allowBlindAndBuriedVias,
998
1023
  })
999
1024
  if (terminalBranch) directDownstreamTraces.push(terminalBranch)
1000
1025
  }
@@ -1052,6 +1077,7 @@ export function completeOriginalEndpoints(params: {
1052
1077
  downstreamConnectionNames.has(trace.connection_name),
1053
1078
  ),
1054
1079
  clearance,
1080
+ allowBlindAndBuriedVias,
1055
1081
  })
1056
1082
  } catch (error) {
1057
1083
  errors.push(
@@ -1102,6 +1128,7 @@ export function completeOriginalEndpoints(params: {
1102
1128
  viaDiameter,
1103
1129
  viaHoleDiameter,
1104
1130
  clearance,
1131
+ allowBlindAndBuriedVias,
1105
1132
  })
1106
1133
  if (terminalBranch) traces.push(terminalBranch)
1107
1134
  }
@@ -1121,6 +1148,7 @@ export function completeOriginalEndpoints(params: {
1121
1148
  inputSrj,
1122
1149
  routedSrj: simpleRouteJson,
1123
1150
  clearance,
1151
+ allowBlindAndBuriedVias,
1124
1152
  })
1125
1153
  if (!drc.valid) {
1126
1154
  errors.push("Final endpoint-completion output failed emitted-copper DRC")