@tscircuit/matchpack 0.0.14 → 0.0.15

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.d.ts CHANGED
@@ -74,8 +74,13 @@ type InputProblem = {
74
74
  chipGap: number;
75
75
  /** The minimum gap between two partitions */
76
76
  partitionGap: number;
77
+ decouplingCapsGap?: number;
77
78
  inferDecouplingCaps?: boolean;
78
79
  };
80
+ interface PartitionInputProblem extends InputProblem {
81
+ isPartition?: true;
82
+ partitionType?: "default" | "decoupling_caps";
83
+ }
79
84
 
80
85
  /**
81
86
  * Identifies decoupling capacitor groups based on specific criteria:
@@ -131,7 +136,7 @@ declare class IdentifyDecouplingCapsSolver extends BaseSolver {
131
136
 
132
137
  declare class ChipPartitionsSolver extends BaseSolver {
133
138
  inputProblem: InputProblem;
134
- partitions: InputProblem[];
139
+ partitions: PartitionInputProblem[];
135
140
  decouplingCapGroups?: DecouplingCapGroup[];
136
141
  constructor({ inputProblem, decouplingCapGroups, }: {
137
142
  inputProblem: InputProblem;
@@ -173,10 +178,14 @@ type OutputLayout = {
173
178
  */
174
179
 
175
180
  declare class SingleInnerPartitionPackingSolver extends BaseSolver {
176
- inputProblem: InputProblem;
181
+ partitionInputProblem: PartitionInputProblem;
177
182
  layout: OutputLayout | null;
178
183
  activeSubSolver: PackSolver2 | null;
179
- constructor(inputProblem: InputProblem);
184
+ pinIdToStronglyConnectedPins: Record<PinId, ChipPin[]>;
185
+ constructor(params: {
186
+ partitionInputProblem: PartitionInputProblem;
187
+ pinIdToStronglyConnectedPins: Record<PinId, ChipPin[]>;
188
+ });
180
189
  _step(): void;
181
190
  private createPackInput;
182
191
  private createLayoutFromPackingResult;
@@ -200,7 +209,12 @@ declare class PackInnerPartitionsSolver extends BaseSolver {
200
209
  completedSolvers: SingleInnerPartitionPackingSolver[];
201
210
  activeSolver: SingleInnerPartitionPackingSolver | null;
202
211
  currentPartitionIndex: number;
203
- constructor(partitions: InputProblem[]);
212
+ activeSubSolver: SingleInnerPartitionPackingSolver | null;
213
+ pinIdToStronglyConnectedPins: Record<PinId, ChipPin[]>;
214
+ constructor(params: {
215
+ partitions: InputProblem[];
216
+ pinIdToStronglyConnectedPins: Record<PinId, ChipPin[]>;
217
+ });
204
218
  _step(): void;
205
219
  visualize(): GraphicsObject;
206
220
  getConstructorParams(): [InputProblem[]];
@@ -249,6 +263,7 @@ declare class LayoutPipelineSolver extends BaseSolver {
249
263
  endTimeOfPhase: Record<string, number>;
250
264
  timeSpentOnPhase: Record<string, number>;
251
265
  firstIterationOfPhase: Record<string, number>;
266
+ pinIdToStronglyConnectedPins: Record<PinId, ChipPin[]>;
252
267
  inputProblem: InputProblem;
253
268
  chipPartitions?: ChipPartitionsSolver["partitions"];
254
269
  packedPartitions?: PackedPartition[];
@@ -284,4 +299,4 @@ declare class LayoutPipelineSolver extends BaseSolver {
284
299
  getOutputLayout(): OutputLayout;
285
300
  }
286
301
 
287
- export { type Chip, type ChipId, type ChipPin, type Group, type GroupId, type GroupPin, type InputProblem, LayoutPipelineSolver, type Net, type NetId, type OutputLayout, type PinId, type Placement };
302
+ export { type Chip, type ChipId, type ChipPin, type Group, type GroupId, type GroupPin, type InputProblem, LayoutPipelineSolver, type Net, type NetId, type OutputLayout, type PartitionInputProblem, type PinId, type Placement };
package/dist/index.js CHANGED
@@ -380,10 +380,16 @@ var ChipPartitionsSolver = class extends BaseSolver {
380
380
  }
381
381
  }
382
382
  }
383
- const allPartitions = [...decapGroupPartitions, ...nonDecapPartitions];
384
- return allPartitions.map(
385
- (partition) => this.createInputProblemFromPartition(partition, inputProblem)
386
- );
383
+ return [
384
+ ...decapGroupPartitions.map(
385
+ (partition) => this.createInputProblemFromPartition(partition, inputProblem, {
386
+ partitionType: "decoupling_caps"
387
+ })
388
+ ),
389
+ ...nonDecapPartitions.map(
390
+ (partition) => this.createInputProblemFromPartition(partition, inputProblem)
391
+ )
392
+ ];
387
393
  }
388
394
  /**
389
395
  * Finds the owner chip of a given pin
@@ -422,7 +428,7 @@ var ChipPartitionsSolver = class extends BaseSolver {
422
428
  /**
423
429
  * Creates a new InputProblem containing only the components in the given partition
424
430
  */
425
- createInputProblemFromPartition(partition, originalProblem) {
431
+ createInputProblemFromPartition(partition, originalProblem, opts) {
426
432
  const chipIds = partition;
427
433
  const relevantPinIds = /* @__PURE__ */ new Set();
428
434
  for (const chipId of chipIds) {
@@ -469,13 +475,14 @@ var ChipPartitionsSolver = class extends BaseSolver {
469
475
  }
470
476
  }
471
477
  return {
478
+ ...originalProblem,
472
479
  chipMap,
473
480
  chipPinMap,
474
481
  netMap,
475
482
  pinStrongConnMap,
476
483
  netConnMap,
477
- chipGap: originalProblem.chipGap,
478
- partitionGap: originalProblem.partitionGap
484
+ isPartition: true,
485
+ partitionType: opts?.partitionType
479
486
  };
480
487
  }
481
488
  visualize() {
@@ -668,14 +675,17 @@ ${group.decouplingCapGroupId}`;
668
675
  import { PackSolver2 } from "calculate-packing";
669
676
 
670
677
  // lib/utils/networkFiltering.ts
671
- function createFilteredNetworkMapping(inputProblem) {
678
+ function createFilteredNetworkMapping(params) {
679
+ const { inputProblem, pinIdToStronglyConnectedPins } = params;
672
680
  const pinToNetworkMap = /* @__PURE__ */ new Map();
673
681
  const filteredPins = /* @__PURE__ */ new Set();
682
+ let hasStrongConnections = false;
674
683
  const strongConnectedChipSides = /* @__PURE__ */ new Map();
675
684
  for (const [connKey, connected] of Object.entries(
676
685
  inputProblem.pinStrongConnMap
677
686
  )) {
678
687
  if (!connected) continue;
688
+ hasStrongConnections = true;
679
689
  const pins = connKey.split("-");
680
690
  if (pins.length === 2 && pins[0] && pins[1]) {
681
691
  const pin1 = inputProblem.chipPinMap[pins[0]];
@@ -698,45 +708,59 @@ function createFilteredNetworkMapping(inputProblem) {
698
708
  }
699
709
  }
700
710
  }
701
- for (const [connKey, connected] of Object.entries(inputProblem.netConnMap)) {
702
- if (!connected) continue;
703
- const [pinId, netId] = connKey.split("-");
704
- if (pinId && netId) {
705
- const pin = inputProblem.chipPinMap[pinId];
706
- if (!pin) continue;
707
- const chipId = pinId.split(".")[0];
708
- let shouldIncludeInNetwork = true;
709
- for (const [
710
- strongKey,
711
- strongSides
712
- ] of strongConnectedChipSides.entries()) {
713
- const [fromChip, toChip] = strongKey.split("-");
714
- if (fromChip === chipId) {
715
- for (const [otherConnKey, otherConnected] of Object.entries(
716
- inputProblem.netConnMap
717
- )) {
718
- if (!otherConnected) continue;
719
- const [otherPinId, otherNetId] = otherConnKey.split("-");
720
- if (otherNetId === netId && otherPinId && otherPinId !== pinId) {
721
- const otherPin = inputProblem.chipPinMap[otherPinId];
722
- if (!otherPin) continue;
723
- const otherChipId = otherPinId.split(".")[0];
724
- if (otherChipId === toChip) {
725
- if (!strongSides.has(otherPin.side)) {
726
- shouldIncludeInNetwork = false;
727
- break;
711
+ if (hasStrongConnections) {
712
+ for (const [connKey, connected] of Object.entries(
713
+ inputProblem.netConnMap
714
+ )) {
715
+ if (!connected) continue;
716
+ const [pinId, netId] = connKey.split("-");
717
+ if (pinId && netId) {
718
+ filteredPins.add(pinId);
719
+ }
720
+ }
721
+ } else {
722
+ for (const [connKey, connected] of Object.entries(
723
+ inputProblem.netConnMap
724
+ )) {
725
+ if (!connected) continue;
726
+ const [pinId, netId] = connKey.split("-");
727
+ if (pinId && netId) {
728
+ const pin = inputProblem.chipPinMap[pinId];
729
+ if (!pin) continue;
730
+ const chipId = pinId.split(".")[0];
731
+ let shouldIncludeInNetwork = true;
732
+ for (const [
733
+ strongKey,
734
+ strongSides
735
+ ] of strongConnectedChipSides.entries()) {
736
+ const [fromChip, toChip] = strongKey.split("-");
737
+ if (fromChip === chipId) {
738
+ for (const [otherConnKey, otherConnected] of Object.entries(
739
+ inputProblem.netConnMap
740
+ )) {
741
+ if (!otherConnected) continue;
742
+ const [otherPinId, otherNetId] = otherConnKey.split("-");
743
+ if (otherNetId === netId && otherPinId && otherPinId !== pinId) {
744
+ const otherPin = inputProblem.chipPinMap[otherPinId];
745
+ if (!otherPin) continue;
746
+ const otherChipId = otherPinId.split(".")[0];
747
+ if (otherChipId === toChip) {
748
+ if (!strongSides.has(otherPin.side)) {
749
+ shouldIncludeInNetwork = false;
750
+ break;
751
+ }
728
752
  }
729
753
  }
730
754
  }
731
755
  }
732
756
  }
733
- }
734
- if (shouldIncludeInNetwork) {
735
- pinToNetworkMap.set(pinId, netId);
736
- } else {
737
- const disconnectedNetworkId = `${pinId}_opposite-strong-side-disconnected`;
738
- pinToNetworkMap.set(pinId, disconnectedNetworkId);
739
- filteredPins.add(pinId);
757
+ if (shouldIncludeInNetwork) {
758
+ pinToNetworkMap.set(pinId, netId);
759
+ } else {
760
+ const disconnectedNetworkId = `${pinId}_opposite-strong-side-disconnected`;
761
+ pinToNetworkMap.set(pinId, disconnectedNetworkId);
762
+ filteredPins.add(pinId);
763
+ }
740
764
  }
741
765
  }
742
766
  }
@@ -782,11 +806,13 @@ var getPadsBoundingBox = (pads) => {
782
806
  // lib/solvers/PackInnerPartitionsSolver/SingleInnerPartitionPackingSolver.ts
783
807
  var PIN_SIZE = 0.1;
784
808
  var SingleInnerPartitionPackingSolver = class extends BaseSolver {
785
- inputProblem;
809
+ partitionInputProblem;
786
810
  layout = null;
787
- constructor(inputProblem) {
811
+ pinIdToStronglyConnectedPins;
812
+ constructor(params) {
788
813
  super();
789
- this.inputProblem = inputProblem;
814
+ this.partitionInputProblem = params.partitionInputProblem;
815
+ this.pinIdToStronglyConnectedPins = params.pinIdToStronglyConnectedPins;
790
816
  }
791
817
  _step() {
792
818
  if (!this.activeSubSolver) {
@@ -809,53 +835,55 @@ var SingleInnerPartitionPackingSolver = class extends BaseSolver {
809
835
  }
810
836
  }
811
837
  createPackInput() {
812
- const { pinToNetworkMap } = createFilteredNetworkMapping(this.inputProblem);
813
- const packComponents = Object.entries(this.inputProblem.chipMap).map(
814
- ([chipId, chip]) => {
815
- const pads = [];
816
- for (const pinId of chip.pins) {
817
- const pin = this.inputProblem.chipPinMap[pinId];
818
- if (!pin) continue;
819
- const networkId = pinToNetworkMap.get(pinId) || `${pinId}_isolated`;
820
- pads.push({
821
- padId: pinId,
822
- networkId,
823
- type: "rect",
824
- offset: { x: pin.offset.x, y: pin.offset.y },
825
- size: { x: PIN_SIZE, y: PIN_SIZE }
826
- // Small size for pins
827
- });
828
- }
829
- const padsBoundingBox = getPadsBoundingBox(pads);
830
- const padsBoundingBoxSize = {
831
- x: padsBoundingBox.maxX - padsBoundingBox.minX,
832
- y: padsBoundingBox.maxY - padsBoundingBox.minY
833
- };
838
+ const pinToNetworkMap = createFilteredNetworkMapping({
839
+ inputProblem: this.partitionInputProblem,
840
+ pinIdToStronglyConnectedPins: this.pinIdToStronglyConnectedPins
841
+ }).pinToNetworkMap;
842
+ const packComponents = Object.entries(
843
+ this.partitionInputProblem.chipMap
844
+ ).map(([chipId, chip]) => {
845
+ const pads = [];
846
+ for (const pinId of chip.pins) {
847
+ const pin = this.partitionInputProblem.chipPinMap[pinId];
848
+ if (!pin) continue;
849
+ const networkId = pinToNetworkMap.get(pinId) || `${pinId}_isolated`;
834
850
  pads.push({
835
- padId: `${chipId}_body`,
836
- networkId: `${chipId}_body_disconnected`,
851
+ padId: pinId,
852
+ networkId,
837
853
  type: "rect",
838
- offset: { x: 0, y: 0 },
839
- size: {
840
- x: Math.max(padsBoundingBoxSize.x, chip.size.x),
841
- y: Math.max(padsBoundingBoxSize.y, chip.size.y)
842
- }
854
+ offset: { x: pin.offset.x, y: pin.offset.y },
855
+ size: { x: PIN_SIZE, y: PIN_SIZE }
856
+ // Small size for pins
843
857
  });
844
- return {
845
- componentId: chipId,
846
- pads,
847
- availableRotationDegrees: chip.availableRotations || [
848
- 0,
849
- 90,
850
- 180,
851
- 270
852
- ]
853
- };
854
858
  }
855
- );
859
+ const padsBoundingBox = getPadsBoundingBox(pads);
860
+ const padsBoundingBoxSize = {
861
+ x: padsBoundingBox.maxX - padsBoundingBox.minX,
862
+ y: padsBoundingBox.maxY - padsBoundingBox.minY
863
+ };
864
+ pads.push({
865
+ padId: `${chipId}_body`,
866
+ networkId: `${chipId}_body_disconnected`,
867
+ type: "rect",
868
+ offset: { x: 0, y: 0 },
869
+ size: {
870
+ x: Math.max(padsBoundingBoxSize.x, chip.size.x),
871
+ y: Math.max(padsBoundingBoxSize.y, chip.size.y)
872
+ }
873
+ });
874
+ return {
875
+ componentId: chipId,
876
+ pads,
877
+ availableRotationDegrees: chip.availableRotations || [0, 90, 180, 270]
878
+ };
879
+ });
880
+ let minGap = this.partitionInputProblem.chipGap;
881
+ if (this.partitionInputProblem.partitionType === "decoupling_caps") {
882
+ minGap = this.partitionInputProblem.decouplingCapsGap ?? minGap;
883
+ }
856
884
  return {
857
885
  components: packComponents,
858
- minGap: this.inputProblem.chipGap,
886
+ minGap,
859
887
  packOrderStrategy: "largest_to_smallest",
860
888
  packPlacementStrategy: "minimum_closest_sum_squared_distance"
861
889
  };
@@ -880,13 +908,13 @@ var SingleInnerPartitionPackingSolver = class extends BaseSolver {
880
908
  return this.activeSubSolver.visualize();
881
909
  }
882
910
  if (!this.layout) {
883
- const basicLayout = doBasicInputProblemLayout(this.inputProblem);
884
- return visualizeInputProblem(this.inputProblem, basicLayout);
911
+ const basicLayout = doBasicInputProblemLayout(this.partitionInputProblem);
912
+ return visualizeInputProblem(this.partitionInputProblem, basicLayout);
885
913
  }
886
- return visualizeInputProblem(this.inputProblem, this.layout);
914
+ return visualizeInputProblem(this.partitionInputProblem, this.layout);
887
915
  }
888
916
  getConstructorParams() {
889
- return [this.inputProblem];
917
+ return [this.partitionInputProblem];
890
918
  }
891
919
  };
892
920
 
@@ -898,9 +926,11 @@ var PackInnerPartitionsSolver = class extends BaseSolver {
898
926
  completedSolvers = [];
899
927
  activeSolver = null;
900
928
  currentPartitionIndex = 0;
901
- constructor(partitions) {
929
+ pinIdToStronglyConnectedPins;
930
+ constructor(params) {
902
931
  super();
903
- this.partitions = partitions;
932
+ this.partitions = params.partitions;
933
+ this.pinIdToStronglyConnectedPins = params.pinIdToStronglyConnectedPins;
904
934
  }
905
935
  _step() {
906
936
  if (this.currentPartitionIndex >= this.partitions.length) {
@@ -909,9 +939,10 @@ var PackInnerPartitionsSolver = class extends BaseSolver {
909
939
  }
910
940
  if (!this.activeSolver) {
911
941
  const currentPartition = this.partitions[this.currentPartitionIndex];
912
- this.activeSolver = new SingleInnerPartitionPackingSolver(
913
- currentPartition
914
- );
942
+ this.activeSolver = new SingleInnerPartitionPackingSolver({
943
+ partitionInputProblem: currentPartition,
944
+ pinIdToStronglyConnectedPins: this.pinIdToStronglyConnectedPins
945
+ });
915
946
  this.activeSubSolver = this.activeSolver;
916
947
  }
917
948
  this.activeSolver.step();
@@ -1225,6 +1256,29 @@ var PartitionPackingSolver = class extends BaseSolver {
1225
1256
  }
1226
1257
  };
1227
1258
 
1259
+ // lib/solvers/LayoutPipelineSolver/getPinIdToStronglyConnectedPinsObj.ts
1260
+ var getPinIdToStronglyConnectedPinsObj = (inputProblem) => {
1261
+ const pinIdToStronglyConnectedPins = {};
1262
+ const pinIds = Object.keys(inputProblem.chipPinMap);
1263
+ for (let i = 0; i < pinIds.length; i++) {
1264
+ for (let j = i + 1; j < pinIds.length; j++) {
1265
+ const pinId1 = pinIds[i];
1266
+ const pinId2 = pinIds[j];
1267
+ if (inputProblem.pinStrongConnMap[`${pinId1}-${pinId2}`] || inputProblem.pinStrongConnMap[`${pinId2}-${pinId1}`]) {
1268
+ pinIdToStronglyConnectedPins[pinId1] ??= [];
1269
+ pinIdToStronglyConnectedPins[pinId2] ??= [];
1270
+ pinIdToStronglyConnectedPins[pinId1].push(
1271
+ inputProblem.chipPinMap[pinId2]
1272
+ );
1273
+ pinIdToStronglyConnectedPins[pinId2].push(
1274
+ inputProblem.chipPinMap[pinId1]
1275
+ );
1276
+ }
1277
+ }
1278
+ }
1279
+ return pinIdToStronglyConnectedPins;
1280
+ };
1281
+
1228
1282
  // lib/solvers/LayoutPipelineSolver/LayoutPipelineSolver.ts
1229
1283
  function definePipelineStep(solverName, solverClass, getConstructorParams, opts = {}) {
1230
1284
  return {
@@ -1243,6 +1297,8 @@ var LayoutPipelineSolver = class extends BaseSolver {
1243
1297
  endTimeOfPhase;
1244
1298
  timeSpentOnPhase;
1245
1299
  firstIterationOfPhase;
1300
+ // Computed utility objects
1301
+ pinIdToStronglyConnectedPins;
1246
1302
  inputProblem;
1247
1303
  chipPartitions;
1248
1304
  packedPartitions;
@@ -1274,7 +1330,12 @@ var LayoutPipelineSolver = class extends BaseSolver {
1274
1330
  definePipelineStep(
1275
1331
  "packInnerPartitionsSolver",
1276
1332
  PackInnerPartitionsSolver,
1277
- () => [this.chipPartitions || [this.inputProblem]],
1333
+ () => [
1334
+ {
1335
+ partitions: this.chipPartitions,
1336
+ pinIdToStronglyConnectedPins: this.pinIdToStronglyConnectedPins
1337
+ }
1338
+ ],
1278
1339
  {
1279
1340
  onSolved: (_solver) => {
1280
1341
  this.packedPartitions = this.packInnerPartitionsSolver.packedPartitions;
@@ -1304,6 +1365,7 @@ var LayoutPipelineSolver = class extends BaseSolver {
1304
1365
  this.endTimeOfPhase = {};
1305
1366
  this.timeSpentOnPhase = {};
1306
1367
  this.firstIterationOfPhase = {};
1368
+ this.pinIdToStronglyConnectedPins = getPinIdToStronglyConnectedPinsObj(inputProblem);
1307
1369
  }
1308
1370
  currentPipelineStepIndex = 0;
1309
1371
  _step() {
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@tscircuit/matchpack",
3
3
  "main": "dist/index.js",
4
4
  "type": "module",
5
- "version": "0.0.14",
5
+ "version": "0.0.15",
6
6
  "files": [
7
7
  "dist"
8
8
  ],