diff --git a/lib/solvers/PackInnerPartitionsSolver/SingleInnerPartitionPackingSolver.ts b/lib/solvers/PackInnerPartitionsSolver/SingleInnerPartitionPackingSolver.ts index 88db103..4446865 100644 --- a/lib/solvers/PackInnerPartitionsSolver/SingleInnerPartitionPackingSolver.ts +++ b/lib/solvers/PackInnerPartitionsSolver/SingleInnerPartitionPackingSolver.ts @@ -38,6 +38,14 @@ export class SingleInnerPartitionPackingSolver extends BaseSolver { } override _step() { + // For decoupling cap partitions, use a clean linear row layout + // instead of the general PackSolver2 to avoid messy overlapping + if (this.partitionInputProblem.partitionType === "decoupling_caps") { + this.layout = this.createLinearDecouplingCapLayout() + this.solved = true + return + } + // Initialize PackSolver2 if not already created if (!this.activeSubSolver) { const packInput = this.createPackInput() @@ -64,6 +72,46 @@ export class SingleInnerPartitionPackingSolver extends BaseSolver { } } + /** + * Arranges decoupling capacitors in a clean horizontal row centered at + * the origin. Chips are sorted by chipId for deterministic, reproducible + * ordering and spaced evenly using decouplingCapsGap (falling back to + * chipGap when not set). + */ + private createLinearDecouplingCapLayout(): OutputLayout { + const chips = Object.entries(this.partitionInputProblem.chipMap).sort( + ([a], [b]) => a.localeCompare(b), + ) + + const gap = + this.partitionInputProblem.decouplingCapsGap ?? + this.partitionInputProblem.chipGap + + // Calculate total width of the row + const totalChipWidth = chips.reduce((sum, [, chip]) => sum + chip.size.x, 0) + const totalGapWidth = Math.max(0, chips.length - 1) * gap + const totalWidth = totalChipWidth + totalGapWidth + + // Place chips left-to-right, centered around x=0 + const chipPlacements: Record = {} + let currentX = -totalWidth / 2 + + for (const [chipId, chip] of chips) { + currentX += chip.size.x / 2 + chipPlacements[chipId] = { + x: currentX, + y: 0, + ccwRotationDegrees: 0, + } + currentX += chip.size.x / 2 + gap + } + + return { + chipPlacements, + groupPlacements: {}, + } + } + private createPackInput(): PackInput { // Fall back to filtered mapping (weak + strong) const pinToNetworkMap = createFilteredNetworkMapping({ diff --git a/pages/LayoutPipelineSolver/LayoutPipelineSolver06.data.ts b/pages/LayoutPipelineSolver/LayoutPipelineSolver06.data.ts new file mode 100644 index 0000000..2edd21a --- /dev/null +++ b/pages/LayoutPipelineSolver/LayoutPipelineSolver06.data.ts @@ -0,0 +1,875 @@ +import type { InputProblem } from "lib/index" + +export const problem: InputProblem = { + chipMap: { + U3: { + chipId: "U3", + pins: [ + "U3.1", + "U3.2", + "U3.3", + "U3.4", + "U3.5", + "U3.6", + "U3.7", + "U3.8", + "U3.9", + "U3.10", + "U3.11", + "U3.12", + "U3.13", + "U3.14", + "U3.15", + "U3.16", + "U3.17", + "U3.18", + "U3.19", + "U3.20", + "U3.21", + "U3.22", + "U3.23", + "U3.24", + "U3.25", + "U3.26", + "U3.27", + "U3.28", + "U3.29", + "U3.30", + "U3.31", + "U3.32", + "U3.33", + "U3.34", + "U3.35", + "U3.36", + "U3.37", + "U3.38", + "U3.39", + "U3.40", + "U3.41", + "U3.42", + "U3.43", + "U3.44", + "U3.45", + "U3.46", + "U3.47", + "U3.48", + "U3.49", + "U3.50", + "U3.51", + "U3.52", + "U3.53", + "U3.54", + "U3.55", + "U3.56", + "U3.57", + ], + size: { + x: 3, + y: 8.400000000000004, + }, + availableRotations: [0, 90, 180, 270], + }, + C12: { + chipId: "C12", + pins: ["C12.1", "C12.2"], + size: { + x: 0.53, + y: 1.06, + }, + availableRotations: [0], + }, + C14: { + chipId: "C14", + pins: ["C14.1", "C14.2"], + size: { + x: 0.53, + y: 1.06, + }, + availableRotations: [0], + }, + C8: { + chipId: "C8", + pins: ["C8.1", "C8.2"], + size: { + x: 0.53, + y: 1.06, + }, + availableRotations: [0], + }, + C13: { + chipId: "C13", + pins: ["C13.1", "C13.2"], + size: { + x: 0.53, + y: 1.06, + }, + availableRotations: [0], + }, + C15: { + chipId: "C15", + pins: ["C15.1", "C15.2"], + size: { + x: 0.53, + y: 1.06, + }, + availableRotations: [0], + }, + C19: { + chipId: "C19", + pins: ["C19.1", "C19.2"], + size: { + x: 0.53, + y: 1.06, + }, + availableRotations: [0], + }, + C18: { + chipId: "C18", + pins: ["C18.1", "C18.2"], + size: { + x: 0.53, + y: 1.06, + }, + availableRotations: [0], + }, + C7: { + chipId: "C7", + pins: ["C7.1", "C7.2"], + size: { + x: 0.53, + y: 1.06, + }, + availableRotations: [0], + }, + C9: { + chipId: "C9", + pins: ["C9.1", "C9.2"], + size: { + x: 0.53, + y: 1.06, + }, + availableRotations: [0], + }, + C10: { + chipId: "C10", + pins: ["C10.1", "C10.2"], + size: { + x: 0.53, + y: 1.06, + }, + availableRotations: [0], + }, + C11: { + chipId: "C11", + pins: ["C11.1", "C11.2"], + size: { + x: 0.53, + y: 1.06, + }, + availableRotations: [0], + }, + }, + chipPinMap: { + "U3.1": { + pinId: "U3.1", + offset: { + x: -1.9, + y: 1.2000000000000015, + }, + side: "x-", + }, + "U3.2": { + pinId: "U3.2", + offset: { + x: -1.9, + y: -1.8000000000000007, + }, + side: "x-", + }, + "U3.3": { + pinId: "U3.3", + offset: { + x: -1.9, + y: -2.000000000000001, + }, + side: "x-", + }, + "U3.4": { + pinId: "U3.4", + offset: { + x: -1.9, + y: -2.200000000000001, + }, + side: "x-", + }, + "U3.5": { + pinId: "U3.5", + offset: { + x: -1.9, + y: -2.4000000000000012, + }, + side: "x-", + }, + "U3.6": { + pinId: "U3.6", + offset: { + x: -1.9, + y: -2.6000000000000014, + }, + side: "x-", + }, + "U3.7": { + pinId: "U3.7", + offset: { + x: -1.9, + y: -2.8000000000000016, + }, + side: "x-", + }, + "U3.8": { + pinId: "U3.8", + offset: { + x: -1.9, + y: -3.0000000000000018, + }, + side: "x-", + }, + "U3.9": { + pinId: "U3.9", + offset: { + x: -1.9, + y: -3.200000000000002, + }, + side: "x-", + }, + "U3.10": { + pinId: "U3.10", + offset: { + x: -1.9, + y: 1.0000000000000013, + }, + side: "x-", + }, + "U3.11": { + pinId: "U3.11", + offset: { + x: -1.9, + y: -3.400000000000002, + }, + side: "x-", + }, + "U3.12": { + pinId: "U3.12", + offset: { + x: -1.9, + y: -3.6000000000000023, + }, + side: "x-", + }, + "U3.13": { + pinId: "U3.13", + offset: { + x: -1.9, + y: -3.8000000000000025, + }, + side: "x-", + }, + "U3.14": { + pinId: "U3.14", + offset: { + x: -1.9, + y: -4.000000000000002, + }, + side: "x-", + }, + "U3.15": { + pinId: "U3.15", + offset: { + x: 1.9, + y: -0.5000000000000009, + }, + side: "x+", + }, + "U3.16": { + pinId: "U3.16", + offset: { + x: 1.9, + y: -0.7000000000000011, + }, + side: "x+", + }, + "U3.17": { + pinId: "U3.17", + offset: { + x: 1.9, + y: -0.9000000000000012, + }, + side: "x+", + }, + "U3.18": { + pinId: "U3.18", + offset: { + x: 1.9, + y: -1.1000000000000014, + }, + side: "x+", + }, + "U3.19": { + pinId: "U3.19", + offset: { + x: 1.9, + y: -1.3000000000000014, + }, + side: "x+", + }, + "U3.20": { + pinId: "U3.20", + offset: { + x: 1.9, + y: -1.9000000000000015, + }, + side: "x+", + }, + "U3.21": { + pinId: "U3.21", + offset: { + x: 1.9, + y: -2.1000000000000014, + }, + side: "x+", + }, + "U3.22": { + pinId: "U3.22", + offset: { + x: -1.9, + y: 0.8000000000000012, + }, + side: "x-", + }, + "U3.23": { + pinId: "U3.23", + offset: { + x: -1.9, + y: 2.8000000000000016, + }, + side: "x-", + }, + "U3.24": { + pinId: "U3.24", + offset: { + x: 1.9, + y: -2.7000000000000015, + }, + side: "x+", + }, + "U3.25": { + pinId: "U3.25", + offset: { + x: 1.9, + y: -2.9000000000000012, + }, + side: "x+", + }, + "U3.26": { + pinId: "U3.26", + offset: { + x: 1.9, + y: -3.1000000000000014, + }, + side: "x+", + }, + "U3.27": { + pinId: "U3.27", + offset: { + x: 1.9, + y: 0.0999999999999992, + }, + side: "x+", + }, + "U3.28": { + pinId: "U3.28", + offset: { + x: 1.9, + y: 0.2999999999999994, + }, + side: "x+", + }, + "U3.29": { + pinId: "U3.29", + offset: { + x: 1.9, + y: 0.49999999999999956, + }, + side: "x+", + }, + "U3.30": { + pinId: "U3.30", + offset: { + x: 1.9, + y: 0.6999999999999997, + }, + side: "x+", + }, + "U3.31": { + pinId: "U3.31", + offset: { + x: 1.9, + y: 0.8999999999999995, + }, + side: "x+", + }, + "U3.32": { + pinId: "U3.32", + offset: { + x: 1.9, + y: 1.0999999999999996, + }, + side: "x+", + }, + "U3.33": { + pinId: "U3.33", + offset: { + x: -1.9, + y: 0.600000000000001, + }, + side: "x-", + }, + "U3.34": { + pinId: "U3.34", + offset: { + x: 1.9, + y: 1.2999999999999998, + }, + side: "x+", + }, + "U3.35": { + pinId: "U3.35", + offset: { + x: 1.9, + y: 1.5, + }, + side: "x+", + }, + "U3.36": { + pinId: "U3.36", + offset: { + x: 1.9, + y: 1.7000000000000002, + }, + side: "x+", + }, + "U3.37": { + pinId: "U3.37", + offset: { + x: 1.9, + y: 1.9000000000000004, + }, + side: "x+", + }, + "U3.38": { + pinId: "U3.38", + offset: { + x: 1.9, + y: 2.500000000000001, + }, + side: "x+", + }, + "U3.39": { + pinId: "U3.39", + offset: { + x: 1.9, + y: 2.700000000000001, + }, + side: "x+", + }, + "U3.40": { + pinId: "U3.40", + offset: { + x: 1.9, + y: 2.9000000000000012, + }, + side: "x+", + }, + "U3.41": { + pinId: "U3.41", + offset: { + x: 1.9, + y: 3.1000000000000014, + }, + side: "x+", + }, + "U3.42": { + pinId: "U3.42", + offset: { + x: -1.9, + y: 0.4000000000000008, + }, + side: "x-", + }, + "U3.43": { + pinId: "U3.43", + offset: { + x: -1.9, + y: -1.6000000000000005, + }, + side: "x-", + }, + "U3.44": { + pinId: "U3.44", + offset: { + x: -1.9, + y: 2.0000000000000018, + }, + side: "x-", + }, + "U3.45": { + pinId: "U3.45", + offset: { + x: -1.9, + y: 1.8000000000000016, + }, + side: "x-", + }, + "U3.46": { + pinId: "U3.46", + offset: { + x: -1.9, + y: -1.4000000000000004, + }, + side: "x-", + }, + "U3.47": { + pinId: "U3.47", + offset: { + x: -1.9, + y: -1.2000000000000002, + }, + side: "x-", + }, + "U3.48": { + pinId: "U3.48", + offset: { + x: -1.9, + y: -1, + }, + side: "x-", + }, + "U3.49": { + pinId: "U3.49", + offset: { + x: -1.9, + y: 0.20000000000000062, + }, + side: "x-", + }, + "U3.50": { + pinId: "U3.50", + offset: { + x: -1.9, + y: 2.600000000000002, + }, + side: "x-", + }, + "U3.51": { + pinId: "U3.51", + offset: { + x: -1.9, + y: 3.0000000000000018, + }, + side: "x-", + }, + "U3.52": { + pinId: "U3.52", + offset: { + x: -1.9, + y: 3.200000000000002, + }, + side: "x-", + }, + "U3.53": { + pinId: "U3.53", + offset: { + x: -1.9, + y: 3.4000000000000017, + }, + side: "x-", + }, + "U3.54": { + pinId: "U3.54", + offset: { + x: -1.9, + y: 3.600000000000002, + }, + side: "x-", + }, + "U3.55": { + pinId: "U3.55", + offset: { + x: -1.9, + y: 3.8000000000000016, + }, + side: "x-", + }, + "U3.56": { + pinId: "U3.56", + offset: { + x: -1.9, + y: 4.000000000000002, + }, + side: "x-", + }, + "U3.57": { + pinId: "U3.57", + offset: { + x: -1.9, + y: -0.39999999999999947, + }, + side: "x-", + }, + "C12.1": { + pinId: "C12.1", + offset: { + x: -3.469446951953614e-17, + y: 0.55, + }, + side: "y+", + }, + "C12.2": { + pinId: "C12.2", + offset: { + x: 3.469446951953614e-17, + y: -0.55, + }, + side: "y-", + }, + "C14.1": { + pinId: "C14.1", + offset: { + x: -3.469446951953614e-17, + y: 0.55, + }, + side: "y+", + }, + "C14.2": { + pinId: "C14.2", + offset: { + x: 3.469446951953614e-17, + y: -0.55, + }, + side: "y-", + }, + "C8.1": { + pinId: "C8.1", + offset: { + x: -3.469446951953614e-17, + y: 0.55, + }, + side: "y+", + }, + "C8.2": { + pinId: "C8.2", + offset: { + x: 3.469446951953614e-17, + y: -0.55, + }, + side: "y-", + }, + "C13.1": { + pinId: "C13.1", + offset: { + x: -3.469446951953614e-17, + y: 0.55, + }, + side: "y+", + }, + "C13.2": { + pinId: "C13.2", + offset: { + x: 3.469446951953614e-17, + y: -0.55, + }, + side: "y-", + }, + "C15.1": { + pinId: "C15.1", + offset: { + x: -3.469446951953614e-17, + y: 0.55, + }, + side: "y+", + }, + "C15.2": { + pinId: "C15.2", + offset: { + x: 3.469446951953614e-17, + y: -0.55, + }, + side: "y-", + }, + "C19.1": { + pinId: "C19.1", + offset: { + x: -3.469446951953614e-17, + y: 0.55, + }, + side: "y+", + }, + "C19.2": { + pinId: "C19.2", + offset: { + x: 3.469446951953614e-17, + y: -0.55, + }, + side: "y-", + }, + "C18.1": { + pinId: "C18.1", + offset: { + x: -3.469446951953614e-17, + y: 0.55, + }, + side: "y+", + }, + "C18.2": { + pinId: "C18.2", + offset: { + x: 3.469446951953614e-17, + y: -0.55, + }, + side: "y-", + }, + "C7.1": { + pinId: "C7.1", + offset: { + x: -3.469446951953614e-17, + y: 0.55, + }, + side: "y+", + }, + "C7.2": { + pinId: "C7.2", + offset: { + x: 3.469446951953614e-17, + y: -0.55, + }, + side: "y-", + }, + "C9.1": { + pinId: "C9.1", + offset: { + x: -3.469446951953614e-17, + y: 0.55, + }, + side: "y+", + }, + "C9.2": { + pinId: "C9.2", + offset: { + x: 3.469446951953614e-17, + y: -0.55, + }, + side: "y-", + }, + "C10.1": { + pinId: "C10.1", + offset: { + x: -3.469446951953614e-17, + y: 0.55, + }, + side: "y+", + }, + "C10.2": { + pinId: "C10.2", + offset: { + x: 3.469446951953614e-17, + y: -0.55, + }, + side: "y-", + }, + "C11.1": { + pinId: "C11.1", + offset: { + x: -3.469446951953614e-17, + y: 0.55, + }, + side: "y+", + }, + "C11.2": { + pinId: "C11.2", + offset: { + x: 3.469446951953614e-17, + y: -0.55, + }, + side: "y-", + }, + }, + netMap: { + V3_3: { + netId: "V3_3", + isPositiveVoltageSource: true, + }, + V1_1: { + netId: "V1_1", + isPositiveVoltageSource: true, + }, + GND: { + netId: "GND", + isGround: true, + }, + }, + pinStrongConnMap: { + "U3.1-C12.1": true, + "C12.1-U3.1": true, + "U3.10-C14.1": true, + "C14.1-U3.10": true, + "U3.22-C8.1": true, + "C8.1-U3.22": true, + "U3.33-C13.1": true, + "C13.1-U3.33": true, + "U3.42-C15.1": true, + "C15.1-U3.42": true, + "U3.49-C19.1": true, + "C19.1-U3.49": true, + "U3.23-C18.1": true, + "C18.1-U3.23": true, + "U3.50-C7.1": true, + "C7.1-U3.50": true, + "C11.1-U3.43": true, + "U3.43-C11.1": true, + "C10.1-U3.44": true, + "U3.44-C10.1": true, + }, + netConnMap: { + "U3.1-V3_3": true, + "U3.10-V3_3": true, + "U3.22-V3_3": true, + "U3.33-V3_3": true, + "U3.42-V3_3": true, + "U3.49-V3_3": true, + "C12.1-V3_3": true, + "C14.1-V3_3": true, + "C8.1-V3_3": true, + "C13.1-V3_3": true, + "C15.1-V3_3": true, + "C19.1-V3_3": true, + "U3.23-V1_1": true, + "U3.50-V1_1": true, + "C18.1-V1_1": true, + "C7.1-V1_1": true, + "C9.1-V1_1": true, + "C12.2-GND": true, + "C14.2-GND": true, + "C8.2-GND": true, + "C13.2-GND": true, + "C15.2-GND": true, + "C19.2-GND": true, + "C18.2-GND": true, + "C7.2-GND": true, + "C9.2-GND": true, + "C10.2-GND": true, + "C11.2-GND": true, + }, + chipGap: 0.6, + decouplingCapsGap: 0.2, + partitionGap: 1.2, +} diff --git a/pages/LayoutPipelineSolver/LayoutPipelineSolver06.page.tsx b/pages/LayoutPipelineSolver/LayoutPipelineSolver06.page.tsx index c0767bb..8cc1eba 100644 --- a/pages/LayoutPipelineSolver/LayoutPipelineSolver06.page.tsx +++ b/pages/LayoutPipelineSolver/LayoutPipelineSolver06.page.tsx @@ -1,880 +1,6 @@ -import type { PackInput } from "calculate-packing" import { LayoutPipelineDebugger } from "lib/components/LayoutPipelineDebugger" -import type { InputProblem } from "lib/index" - -export const problem: InputProblem = { - chipMap: { - U3: { - chipId: "U3", - pins: [ - "U3.1", - "U3.2", - "U3.3", - "U3.4", - "U3.5", - "U3.6", - "U3.7", - "U3.8", - "U3.9", - "U3.10", - "U3.11", - "U3.12", - "U3.13", - "U3.14", - "U3.15", - "U3.16", - "U3.17", - "U3.18", - "U3.19", - "U3.20", - "U3.21", - "U3.22", - "U3.23", - "U3.24", - "U3.25", - "U3.26", - "U3.27", - "U3.28", - "U3.29", - "U3.30", - "U3.31", - "U3.32", - "U3.33", - "U3.34", - "U3.35", - "U3.36", - "U3.37", - "U3.38", - "U3.39", - "U3.40", - "U3.41", - "U3.42", - "U3.43", - "U3.44", - "U3.45", - "U3.46", - "U3.47", - "U3.48", - "U3.49", - "U3.50", - "U3.51", - "U3.52", - "U3.53", - "U3.54", - "U3.55", - "U3.56", - "U3.57", - ], - size: { - x: 3, - y: 8.400000000000004, - }, - availableRotations: [0, 90, 180, 270], - }, - C12: { - chipId: "C12", - pins: ["C12.1", "C12.2"], - size: { - x: 0.53, - y: 1.06, - }, - availableRotations: [0], - }, - C14: { - chipId: "C14", - pins: ["C14.1", "C14.2"], - size: { - x: 0.53, - y: 1.06, - }, - availableRotations: [0], - }, - C8: { - chipId: "C8", - pins: ["C8.1", "C8.2"], - size: { - x: 0.53, - y: 1.06, - }, - availableRotations: [0], - }, - C13: { - chipId: "C13", - pins: ["C13.1", "C13.2"], - size: { - x: 0.53, - y: 1.06, - }, - availableRotations: [0], - }, - C15: { - chipId: "C15", - pins: ["C15.1", "C15.2"], - size: { - x: 0.53, - y: 1.06, - }, - availableRotations: [0], - }, - C19: { - chipId: "C19", - pins: ["C19.1", "C19.2"], - size: { - x: 0.53, - y: 1.06, - }, - availableRotations: [0], - }, - C18: { - chipId: "C18", - pins: ["C18.1", "C18.2"], - size: { - x: 0.53, - y: 1.06, - }, - availableRotations: [0], - }, - C7: { - chipId: "C7", - pins: ["C7.1", "C7.2"], - size: { - x: 0.53, - y: 1.06, - }, - availableRotations: [0], - }, - C9: { - chipId: "C9", - pins: ["C9.1", "C9.2"], - size: { - x: 0.53, - y: 1.06, - }, - availableRotations: [0], - }, - C10: { - chipId: "C10", - pins: ["C10.1", "C10.2"], - size: { - x: 0.53, - y: 1.06, - }, - availableRotations: [0], - }, - C11: { - chipId: "C11", - pins: ["C11.1", "C11.2"], - size: { - x: 0.53, - y: 1.06, - }, - availableRotations: [0], - }, - }, - chipPinMap: { - "U3.1": { - pinId: "U3.1", - offset: { - x: -1.9, - y: 1.2000000000000015, - }, - side: "x-", - }, - "U3.2": { - pinId: "U3.2", - offset: { - x: -1.9, - y: -1.8000000000000007, - }, - side: "x-", - }, - "U3.3": { - pinId: "U3.3", - offset: { - x: -1.9, - y: -2.000000000000001, - }, - side: "x-", - }, - "U3.4": { - pinId: "U3.4", - offset: { - x: -1.9, - y: -2.200000000000001, - }, - side: "x-", - }, - "U3.5": { - pinId: "U3.5", - offset: { - x: -1.9, - y: -2.4000000000000012, - }, - side: "x-", - }, - "U3.6": { - pinId: "U3.6", - offset: { - x: -1.9, - y: -2.6000000000000014, - }, - side: "x-", - }, - "U3.7": { - pinId: "U3.7", - offset: { - x: -1.9, - y: -2.8000000000000016, - }, - side: "x-", - }, - "U3.8": { - pinId: "U3.8", - offset: { - x: -1.9, - y: -3.0000000000000018, - }, - side: "x-", - }, - "U3.9": { - pinId: "U3.9", - offset: { - x: -1.9, - y: -3.200000000000002, - }, - side: "x-", - }, - "U3.10": { - pinId: "U3.10", - offset: { - x: -1.9, - y: 1.0000000000000013, - }, - side: "x-", - }, - "U3.11": { - pinId: "U3.11", - offset: { - x: -1.9, - y: -3.400000000000002, - }, - side: "x-", - }, - "U3.12": { - pinId: "U3.12", - offset: { - x: -1.9, - y: -3.6000000000000023, - }, - side: "x-", - }, - "U3.13": { - pinId: "U3.13", - offset: { - x: -1.9, - y: -3.8000000000000025, - }, - side: "x-", - }, - "U3.14": { - pinId: "U3.14", - offset: { - x: -1.9, - y: -4.000000000000002, - }, - side: "x-", - }, - "U3.15": { - pinId: "U3.15", - offset: { - x: 1.9, - y: -0.5000000000000009, - }, - side: "x+", - }, - "U3.16": { - pinId: "U3.16", - offset: { - x: 1.9, - y: -0.7000000000000011, - }, - side: "x+", - }, - "U3.17": { - pinId: "U3.17", - offset: { - x: 1.9, - y: -0.9000000000000012, - }, - side: "x+", - }, - "U3.18": { - pinId: "U3.18", - offset: { - x: 1.9, - y: -1.1000000000000014, - }, - side: "x+", - }, - "U3.19": { - pinId: "U3.19", - offset: { - x: 1.9, - y: -1.3000000000000014, - }, - side: "x+", - }, - "U3.20": { - pinId: "U3.20", - offset: { - x: 1.9, - y: -1.9000000000000015, - }, - side: "x+", - }, - "U3.21": { - pinId: "U3.21", - offset: { - x: 1.9, - y: -2.1000000000000014, - }, - side: "x+", - }, - "U3.22": { - pinId: "U3.22", - offset: { - x: -1.9, - y: 0.8000000000000012, - }, - side: "x-", - }, - "U3.23": { - pinId: "U3.23", - offset: { - x: -1.9, - y: 2.8000000000000016, - }, - side: "x-", - }, - "U3.24": { - pinId: "U3.24", - offset: { - x: 1.9, - y: -2.7000000000000015, - }, - side: "x+", - }, - "U3.25": { - pinId: "U3.25", - offset: { - x: 1.9, - y: -2.9000000000000012, - }, - side: "x+", - }, - "U3.26": { - pinId: "U3.26", - offset: { - x: 1.9, - y: -3.1000000000000014, - }, - side: "x+", - }, - "U3.27": { - pinId: "U3.27", - offset: { - x: 1.9, - y: 0.0999999999999992, - }, - side: "x+", - }, - "U3.28": { - pinId: "U3.28", - offset: { - x: 1.9, - y: 0.2999999999999994, - }, - side: "x+", - }, - "U3.29": { - pinId: "U3.29", - offset: { - x: 1.9, - y: 0.49999999999999956, - }, - side: "x+", - }, - "U3.30": { - pinId: "U3.30", - offset: { - x: 1.9, - y: 0.6999999999999997, - }, - side: "x+", - }, - "U3.31": { - pinId: "U3.31", - offset: { - x: 1.9, - y: 0.8999999999999995, - }, - side: "x+", - }, - "U3.32": { - pinId: "U3.32", - offset: { - x: 1.9, - y: 1.0999999999999996, - }, - side: "x+", - }, - "U3.33": { - pinId: "U3.33", - offset: { - x: -1.9, - y: 0.600000000000001, - }, - side: "x-", - }, - "U3.34": { - pinId: "U3.34", - offset: { - x: 1.9, - y: 1.2999999999999998, - }, - side: "x+", - }, - "U3.35": { - pinId: "U3.35", - offset: { - x: 1.9, - y: 1.5, - }, - side: "x+", - }, - "U3.36": { - pinId: "U3.36", - offset: { - x: 1.9, - y: 1.7000000000000002, - }, - side: "x+", - }, - "U3.37": { - pinId: "U3.37", - offset: { - x: 1.9, - y: 1.9000000000000004, - }, - side: "x+", - }, - "U3.38": { - pinId: "U3.38", - offset: { - x: 1.9, - y: 2.500000000000001, - }, - side: "x+", - }, - "U3.39": { - pinId: "U3.39", - offset: { - x: 1.9, - y: 2.700000000000001, - }, - side: "x+", - }, - "U3.40": { - pinId: "U3.40", - offset: { - x: 1.9, - y: 2.9000000000000012, - }, - side: "x+", - }, - "U3.41": { - pinId: "U3.41", - offset: { - x: 1.9, - y: 3.1000000000000014, - }, - side: "x+", - }, - "U3.42": { - pinId: "U3.42", - offset: { - x: -1.9, - y: 0.4000000000000008, - }, - side: "x-", - }, - "U3.43": { - pinId: "U3.43", - offset: { - x: -1.9, - y: -1.6000000000000005, - }, - side: "x-", - }, - "U3.44": { - pinId: "U3.44", - offset: { - x: -1.9, - y: 2.0000000000000018, - }, - side: "x-", - }, - "U3.45": { - pinId: "U3.45", - offset: { - x: -1.9, - y: 1.8000000000000016, - }, - side: "x-", - }, - "U3.46": { - pinId: "U3.46", - offset: { - x: -1.9, - y: -1.4000000000000004, - }, - side: "x-", - }, - "U3.47": { - pinId: "U3.47", - offset: { - x: -1.9, - y: -1.2000000000000002, - }, - side: "x-", - }, - "U3.48": { - pinId: "U3.48", - offset: { - x: -1.9, - y: -1, - }, - side: "x-", - }, - "U3.49": { - pinId: "U3.49", - offset: { - x: -1.9, - y: 0.20000000000000062, - }, - side: "x-", - }, - "U3.50": { - pinId: "U3.50", - offset: { - x: -1.9, - y: 2.600000000000002, - }, - side: "x-", - }, - "U3.51": { - pinId: "U3.51", - offset: { - x: -1.9, - y: 3.0000000000000018, - }, - side: "x-", - }, - "U3.52": { - pinId: "U3.52", - offset: { - x: -1.9, - y: 3.200000000000002, - }, - side: "x-", - }, - "U3.53": { - pinId: "U3.53", - offset: { - x: -1.9, - y: 3.4000000000000017, - }, - side: "x-", - }, - "U3.54": { - pinId: "U3.54", - offset: { - x: -1.9, - y: 3.600000000000002, - }, - side: "x-", - }, - "U3.55": { - pinId: "U3.55", - offset: { - x: -1.9, - y: 3.8000000000000016, - }, - side: "x-", - }, - "U3.56": { - pinId: "U3.56", - offset: { - x: -1.9, - y: 4.000000000000002, - }, - side: "x-", - }, - "U3.57": { - pinId: "U3.57", - offset: { - x: -1.9, - y: -0.39999999999999947, - }, - side: "x-", - }, - "C12.1": { - pinId: "C12.1", - offset: { - x: -3.469446951953614e-17, - y: 0.55, - }, - side: "y+", - }, - "C12.2": { - pinId: "C12.2", - offset: { - x: 3.469446951953614e-17, - y: -0.55, - }, - side: "y-", - }, - "C14.1": { - pinId: "C14.1", - offset: { - x: -3.469446951953614e-17, - y: 0.55, - }, - side: "y+", - }, - "C14.2": { - pinId: "C14.2", - offset: { - x: 3.469446951953614e-17, - y: -0.55, - }, - side: "y-", - }, - "C8.1": { - pinId: "C8.1", - offset: { - x: -3.469446951953614e-17, - y: 0.55, - }, - side: "y+", - }, - "C8.2": { - pinId: "C8.2", - offset: { - x: 3.469446951953614e-17, - y: -0.55, - }, - side: "y-", - }, - "C13.1": { - pinId: "C13.1", - offset: { - x: -3.469446951953614e-17, - y: 0.55, - }, - side: "y+", - }, - "C13.2": { - pinId: "C13.2", - offset: { - x: 3.469446951953614e-17, - y: -0.55, - }, - side: "y-", - }, - "C15.1": { - pinId: "C15.1", - offset: { - x: -3.469446951953614e-17, - y: 0.55, - }, - side: "y+", - }, - "C15.2": { - pinId: "C15.2", - offset: { - x: 3.469446951953614e-17, - y: -0.55, - }, - side: "y-", - }, - "C19.1": { - pinId: "C19.1", - offset: { - x: -3.469446951953614e-17, - y: 0.55, - }, - side: "y+", - }, - "C19.2": { - pinId: "C19.2", - offset: { - x: 3.469446951953614e-17, - y: -0.55, - }, - side: "y-", - }, - "C18.1": { - pinId: "C18.1", - offset: { - x: -3.469446951953614e-17, - y: 0.55, - }, - side: "y+", - }, - "C18.2": { - pinId: "C18.2", - offset: { - x: 3.469446951953614e-17, - y: -0.55, - }, - side: "y-", - }, - "C7.1": { - pinId: "C7.1", - offset: { - x: -3.469446951953614e-17, - y: 0.55, - }, - side: "y+", - }, - "C7.2": { - pinId: "C7.2", - offset: { - x: 3.469446951953614e-17, - y: -0.55, - }, - side: "y-", - }, - "C9.1": { - pinId: "C9.1", - offset: { - x: -3.469446951953614e-17, - y: 0.55, - }, - side: "y+", - }, - "C9.2": { - pinId: "C9.2", - offset: { - x: 3.469446951953614e-17, - y: -0.55, - }, - side: "y-", - }, - "C10.1": { - pinId: "C10.1", - offset: { - x: -3.469446951953614e-17, - y: 0.55, - }, - side: "y+", - }, - "C10.2": { - pinId: "C10.2", - offset: { - x: 3.469446951953614e-17, - y: -0.55, - }, - side: "y-", - }, - "C11.1": { - pinId: "C11.1", - offset: { - x: -3.469446951953614e-17, - y: 0.55, - }, - side: "y+", - }, - "C11.2": { - pinId: "C11.2", - offset: { - x: 3.469446951953614e-17, - y: -0.55, - }, - side: "y-", - }, - }, - netMap: { - V3_3: { - netId: "V3_3", - isPositiveVoltageSource: true, - }, - V1_1: { - netId: "V1_1", - isPositiveVoltageSource: true, - }, - GND: { - netId: "GND", - isGround: true, - }, - }, - pinStrongConnMap: { - "U3.1-C12.1": true, - "C12.1-U3.1": true, - "U3.10-C14.1": true, - "C14.1-U3.10": true, - "U3.22-C8.1": true, - "C8.1-U3.22": true, - "U3.33-C13.1": true, - "C13.1-U3.33": true, - "U3.42-C15.1": true, - "C15.1-U3.42": true, - "U3.49-C19.1": true, - "C19.1-U3.49": true, - "U3.23-C18.1": true, - "C18.1-U3.23": true, - "U3.50-C7.1": true, - "C7.1-U3.50": true, - "C11.1-U3.43": true, - "U3.43-C11.1": true, - "C10.1-U3.44": true, - "U3.44-C10.1": true, - }, - netConnMap: { - "U3.1-V3_3": true, - "U3.10-V3_3": true, - "U3.22-V3_3": true, - "U3.33-V3_3": true, - "U3.42-V3_3": true, - "U3.49-V3_3": true, - "C12.1-V3_3": true, - "C14.1-V3_3": true, - "C8.1-V3_3": true, - "C13.1-V3_3": true, - "C15.1-V3_3": true, - "C19.1-V3_3": true, - "U3.23-V1_1": true, - "U3.50-V1_1": true, - "C18.1-V1_1": true, - "C7.1-V1_1": true, - "C9.1-V1_1": true, - "C12.2-GND": true, - "C14.2-GND": true, - "C8.2-GND": true, - "C13.2-GND": true, - "C15.2-GND": true, - "C19.2-GND": true, - "C18.2-GND": true, - "C7.2-GND": true, - "C9.2-GND": true, - "C10.2-GND": true, - "C11.2-GND": true, - }, - chipGap: 0.6, - decouplingCapsGap: 0.2, - partitionGap: 1.2, -} +export { problem } from "./LayoutPipelineSolver06.data" +import { problem } from "./LayoutPipelineSolver06.data" export default function LayoutPipelineSolver06Page() { return diff --git a/tests/IdentifyDecouplingCapsSolver/IdentifyDecouplingCapsSolver06.test.ts b/tests/IdentifyDecouplingCapsSolver/IdentifyDecouplingCapsSolver06.test.ts index 615957c..063bd32 100644 --- a/tests/IdentifyDecouplingCapsSolver/IdentifyDecouplingCapsSolver06.test.ts +++ b/tests/IdentifyDecouplingCapsSolver/IdentifyDecouplingCapsSolver06.test.ts @@ -1,6 +1,6 @@ import { test, expect } from "bun:test" import { IdentifyDecouplingCapsSolver } from "../../lib/solvers/IdentifyDecouplingCapsSolver/IdentifyDecouplingCapsSolver" -import { problem } from "../../pages/LayoutPipelineSolver/LayoutPipelineSolver06.page.tsx" +import { problem } from "../../pages/LayoutPipelineSolver/LayoutPipelineSolver06.data" test("IdentifyDecouplingCapsSolver identifies decoupling capacitor groups from LayoutPipelineSolver06", () => { const solver = new IdentifyDecouplingCapsSolver(problem) diff --git a/tests/PackInnerPartitionsSolver/LinearDecouplingCapLayout.test.ts b/tests/PackInnerPartitionsSolver/LinearDecouplingCapLayout.test.ts new file mode 100644 index 0000000..8773681 --- /dev/null +++ b/tests/PackInnerPartitionsSolver/LinearDecouplingCapLayout.test.ts @@ -0,0 +1,331 @@ +import { test, expect } from "bun:test" +import { LayoutPipelineSolver } from "lib/solvers/LayoutPipelineSolver/LayoutPipelineSolver" +import { IdentifyDecouplingCapsSolver } from "lib/solvers/IdentifyDecouplingCapsSolver/IdentifyDecouplingCapsSolver" +import { ChipPartitionsSolver } from "lib/solvers/ChipPartitionsSolver/ChipPartitionsSolver" +import { SingleInnerPartitionPackingSolver } from "lib/solvers/PackInnerPartitionsSolver/SingleInnerPartitionPackingSolver" +import { getPinIdToStronglyConnectedPinsObj } from "lib/solvers/LayoutPipelineSolver/getPinIdToStronglyConnectedPinsObj" +import type { + InputProblem, + PartitionInputProblem, +} from "lib/types/InputProblem" + +/** + * Minimal test problem with a main chip (U1) and 4 decoupling capacitors + * connected to it via strong pin connections, on GND and VCC nets. + */ +const decouplingCapProblem: InputProblem = { + chipMap: { + U1: { + chipId: "U1", + pins: ["U1.1", "U1.2", "U1.3", "U1.4", "U1.5", "U1.6", "U1.7", "U1.8"], + size: { x: 2, y: 2 }, + availableRotations: [0, 90, 180, 270], + }, + C1: { + chipId: "C1", + pins: ["C1.1", "C1.2"], + size: { x: 0.53, y: 1.06 }, + availableRotations: [0], + }, + C2: { + chipId: "C2", + pins: ["C2.1", "C2.2"], + size: { x: 0.53, y: 1.06 }, + availableRotations: [0], + }, + C3: { + chipId: "C3", + pins: ["C3.1", "C3.2"], + size: { x: 0.53, y: 1.06 }, + availableRotations: [0], + }, + C4: { + chipId: "C4", + pins: ["C4.1", "C4.2"], + size: { x: 0.53, y: 1.06 }, + availableRotations: [0], + }, + }, + chipPinMap: { + "U1.1": { pinId: "U1.1", offset: { x: -1.4, y: 0.6 }, side: "x-" }, + "U1.2": { pinId: "U1.2", offset: { x: -1.4, y: 0.2 }, side: "x-" }, + "U1.3": { pinId: "U1.3", offset: { x: -1.4, y: -0.2 }, side: "x-" }, + "U1.4": { pinId: "U1.4", offset: { x: -1.4, y: -0.6 }, side: "x-" }, + "U1.5": { pinId: "U1.5", offset: { x: 1.4, y: 0.6 }, side: "x+" }, + "U1.6": { pinId: "U1.6", offset: { x: 1.4, y: 0.2 }, side: "x+" }, + "U1.7": { pinId: "U1.7", offset: { x: 1.4, y: -0.2 }, side: "x+" }, + "U1.8": { pinId: "U1.8", offset: { x: 1.4, y: -0.6 }, side: "x+" }, + "C1.1": { pinId: "C1.1", offset: { x: 0, y: 0.55 }, side: "y+" }, + "C1.2": { pinId: "C1.2", offset: { x: 0, y: -0.55 }, side: "y-" }, + "C2.1": { pinId: "C2.1", offset: { x: 0, y: 0.55 }, side: "y+" }, + "C2.2": { pinId: "C2.2", offset: { x: 0, y: -0.55 }, side: "y-" }, + "C3.1": { pinId: "C3.1", offset: { x: 0, y: 0.55 }, side: "y+" }, + "C3.2": { pinId: "C3.2", offset: { x: 0, y: -0.55 }, side: "y-" }, + "C4.1": { pinId: "C4.1", offset: { x: 0, y: 0.55 }, side: "y+" }, + "C4.2": { pinId: "C4.2", offset: { x: 0, y: -0.55 }, side: "y-" }, + }, + netMap: { + VCC: { netId: "VCC", isPositiveVoltageSource: true }, + GND: { netId: "GND", isGround: true }, + }, + pinStrongConnMap: { + "U1.1-C1.1": true, + "C1.1-U1.1": true, + "U1.2-C2.1": true, + "C2.1-U1.2": true, + "U1.3-C3.1": true, + "C3.1-U1.3": true, + "U1.4-C4.1": true, + "C4.1-U1.4": true, + }, + netConnMap: { + "U1.1-VCC": true, + "U1.2-VCC": true, + "U1.3-VCC": true, + "U1.4-VCC": true, + "C1.1-VCC": true, + "C2.1-VCC": true, + "C3.1-VCC": true, + "C4.1-VCC": true, + "C1.2-GND": true, + "C2.2-GND": true, + "C3.2-GND": true, + "C4.2-GND": true, + }, + chipGap: 0.6, + decouplingCapsGap: 0.2, + partitionGap: 1.2, +} + +test("Decoupling caps partition uses linear row layout instead of PackSolver2", () => { + // Run the identify and partition phases to get a decoupling cap partition + const identifySolver = new IdentifyDecouplingCapsSolver(decouplingCapProblem) + identifySolver.solve() + expect(identifySolver.solved).toBe(true) + expect(identifySolver.outputDecouplingCapGroups.length).toBeGreaterThan(0) + + const partitionSolver = new ChipPartitionsSolver({ + inputProblem: decouplingCapProblem, + decouplingCapGroups: identifySolver.outputDecouplingCapGroups, + }) + partitionSolver.solve() + expect(partitionSolver.solved).toBe(true) + + // Find the decoupling cap partition(s) + const decapPartitions = partitionSolver.partitions.filter( + (p) => (p as PartitionInputProblem).partitionType === "decoupling_caps", + ) + expect(decapPartitions.length).toBeGreaterThan(0) + + const pinIdToStronglyConnectedPins = + getPinIdToStronglyConnectedPinsObj(decouplingCapProblem) + + // Test each decoupling cap partition individually + for (const partition of decapPartitions) { + const solver = new SingleInnerPartitionPackingSolver({ + partitionInputProblem: partition as PartitionInputProblem, + pinIdToStronglyConnectedPins, + }) + solver.solve() + expect(solver.solved).toBe(true) + expect(solver.layout).toBeDefined() + + const capChipIds = Object.keys(partition.chipMap) + expect(capChipIds.length).toBeGreaterThanOrEqual(2) + + // All caps should share the same Y coordinate (horizontal row) + const placements = capChipIds.map( + (id) => solver.layout!.chipPlacements[id]!, + ) + const yValues = placements.map((p) => p.y) + const firstY = yValues[0]! + for (const y of yValues) { + expect(y).toBeCloseTo(firstY, 6) + } + + // All caps should have 0 rotation + for (const placement of placements) { + expect(placement.ccwRotationDegrees).toBe(0) + } + + // Sort by X position to check spacing + const sorted = capChipIds + .map((id) => ({ + id, + placement: solver.layout!.chipPlacements[id]!, + chip: partition.chipMap[id]!, + })) + .sort((a, b) => a.placement.x - b.placement.x) + + // Check consistent gap between adjacent caps + const expectedGap = + (partition as PartitionInputProblem).decouplingCapsGap ?? + decouplingCapProblem.chipGap + for (let i = 1; i < sorted.length; i++) { + const prev = sorted[i - 1]! + const curr = sorted[i]! + const edgeDist = + curr.placement.x - + curr.chip.size.x / 2 - + (prev.placement.x + prev.chip.size.x / 2) + expect(edgeDist).toBeCloseTo(expectedGap, 6) + } + } +}) + +test("Full pipeline produces linear decoupling cap layout", () => { + const solver = new LayoutPipelineSolver(decouplingCapProblem) + solver.solve() + + expect(solver.solved).toBe(true) + expect(solver.failed).toBe(false) + + const outputLayout = solver.getOutputLayout() + expect(outputLayout).toBeDefined() + + // Check that all chips have placements + const chipIds = Object.keys(decouplingCapProblem.chipMap) + for (const chipId of chipIds) { + expect(outputLayout.chipPlacements[chipId]).toBeDefined() + } + + // Find decoupling cap partitions from the pipeline + const decapPartitions = solver.chipPartitionsSolver!.partitions.filter( + (p) => (p as PartitionInputProblem).partitionType === "decoupling_caps", + ) + expect(decapPartitions.length).toBeGreaterThan(0) + + // For each decoupling cap partition, verify the caps share the same Y + // in the final layout (offset may differ from 0 due to partition packing) + for (const partition of decapPartitions) { + const capIds = Object.keys(partition.chipMap) + const placements = capIds.map((id) => outputLayout.chipPlacements[id]!) + const yValues = placements.map((p) => p.y) + const firstY = yValues[0]! + + for (const y of yValues) { + expect(y).toBeCloseTo(firstY, 6) + } + } + + // Verify visualization works + const viz = solver.visualize() + expect(viz).toBeDefined() + expect(viz.rects?.length).toBeGreaterThan(0) +}) + +test("Linear layout centers row around origin", () => { + const identifySolver = new IdentifyDecouplingCapsSolver(decouplingCapProblem) + identifySolver.solve() + + const partitionSolver = new ChipPartitionsSolver({ + inputProblem: decouplingCapProblem, + decouplingCapGroups: identifySolver.outputDecouplingCapGroups, + }) + partitionSolver.solve() + + const decapPartitions = partitionSolver.partitions.filter( + (p) => (p as PartitionInputProblem).partitionType === "decoupling_caps", + ) + + const pinIdToStronglyConnectedPins = + getPinIdToStronglyConnectedPinsObj(decouplingCapProblem) + + for (const partition of decapPartitions) { + const solver = new SingleInnerPartitionPackingSolver({ + partitionInputProblem: partition as PartitionInputProblem, + pinIdToStronglyConnectedPins, + }) + solver.solve() + expect(solver.layout).toBeDefined() + + const chipIds = Object.keys(partition.chipMap) + const placements = chipIds.map((id) => solver.layout!.chipPlacements[id]!) + + // Calculate bounding box + const minX = Math.min( + ...placements.map( + (p, i) => p.x - partition.chipMap[chipIds[i]!]!.size.x / 2, + ), + ) + const maxX = Math.max( + ...placements.map( + (p, i) => p.x + partition.chipMap[chipIds[i]!]!.size.x / 2, + ), + ) + + // Center should be approximately at x=0 + const centerX = (minX + maxX) / 2 + expect(centerX).toBeCloseTo(0, 4) + } +}) + +test("Decoupling cap layout is deterministic (sorted by chipId)", () => { + const identifySolver = new IdentifyDecouplingCapsSolver(decouplingCapProblem) + identifySolver.solve() + + const partitionSolver = new ChipPartitionsSolver({ + inputProblem: decouplingCapProblem, + decouplingCapGroups: identifySolver.outputDecouplingCapGroups, + }) + partitionSolver.solve() + + const decapPartitions = partitionSolver.partitions.filter( + (p) => (p as PartitionInputProblem).partitionType === "decoupling_caps", + ) + + const pinIdToStronglyConnectedPins = + getPinIdToStronglyConnectedPinsObj(decouplingCapProblem) + + for (const partition of decapPartitions) { + const solver = new SingleInnerPartitionPackingSolver({ + partitionInputProblem: partition as PartitionInputProblem, + pinIdToStronglyConnectedPins, + }) + solver.solve() + + const chipIds = Object.keys(partition.chipMap) + const sorted = chipIds + .map((id) => ({ + id, + placement: solver.layout!.chipPlacements[id]!, + })) + .sort((a, b) => a.placement.x - b.placement.x) + + // The left-to-right order should match lexicographic sorting of chipIds + const sortedById = [...chipIds].sort((a, b) => a.localeCompare(b)) + for (let i = 0; i < sorted.length; i++) { + expect(sorted[i]!.id).toBe(sortedById[i]!) + } + } +}) + +test("Non-decoupling partitions still use PackSolver2", () => { + const identifySolver = new IdentifyDecouplingCapsSolver(decouplingCapProblem) + identifySolver.solve() + + const partitionSolver = new ChipPartitionsSolver({ + inputProblem: decouplingCapProblem, + decouplingCapGroups: identifySolver.outputDecouplingCapGroups, + }) + partitionSolver.solve() + + // Non-decap partitions should exist (the main chip U1 partition) + const nonDecapPartitions = partitionSolver.partitions.filter( + (p) => (p as PartitionInputProblem).partitionType !== "decoupling_caps", + ) + expect(nonDecapPartitions.length).toBeGreaterThan(0) + + const pinIdToStronglyConnectedPins = + getPinIdToStronglyConnectedPinsObj(decouplingCapProblem) + + for (const partition of nonDecapPartitions) { + const solver = new SingleInnerPartitionPackingSolver({ + partitionInputProblem: partition as PartitionInputProblem, + pinIdToStronglyConnectedPins, + }) + solver.solve() + expect(solver.solved).toBe(true) + expect(solver.layout).toBeDefined() + } +})