Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,20 @@
* Uses a packing algorithm to arrange chips and their connections within the partition.
*/

import type { GraphicsObject } from "graphics-debug"
import { type PackInput, PackSolver2 } from "calculate-packing"
import { BaseSolver } from "../BaseSolver"
import type { OutputLayout, Placement } from "../../types/OutputLayout"
import type { GraphicsObject } from "graphics-debug"
import type {
InputProblem,
PinId,
ChipId,
NetId,
ChipPin,
InputProblem,
PartitionInputProblem,
PinId,
} from "../../types/InputProblem"
import { visualizeInputProblem } from "../LayoutPipelineSolver/visualizeInputProblem"
import type { OutputLayout, Placement } from "../../types/OutputLayout"
import { createFilteredNetworkMapping } from "../../utils/networkFiltering"
import { getPadsBoundingBox } from "./getPadsBoundingBox"
import { BaseSolver } from "../BaseSolver"
import { doBasicInputProblemLayout } from "../LayoutPipelineSolver/doBasicInputProblemLayout"
import { visualizeInputProblem } from "../LayoutPipelineSolver/visualizeInputProblem"
import { getPadsBoundingBox } from "./getPadsBoundingBox"

const PIN_SIZE = 0.1

Expand All @@ -38,6 +36,12 @@ export class SingleInnerPartitionPackingSolver extends BaseSolver {
}

override _step() {
if (this.partitionInputProblem.partitionType === "decoupling_caps") {
this.layout = this.createDecouplingCapLayout()
this.solved = true
return
}

// Initialize PackSolver2 if not already created
if (!this.activeSubSolver) {
const packInput = this.createPackInput()
Expand Down Expand Up @@ -141,6 +145,46 @@ export class SingleInnerPartitionPackingSolver extends BaseSolver {
}
}

private createDecouplingCapLayout(): OutputLayout {
const chipPlacements: Record<string, Placement> = {}
const gap =
this.partitionInputProblem.decouplingCapsGap ??
this.partitionInputProblem.chipGap

const chipIds = Object.keys(this.partitionInputProblem.chipMap).sort(
(a, b) =>
a.localeCompare(b, undefined, {
numeric: true,
sensitivity: "base",
}),
)

const widths = chipIds.map((chipId) => {
const chip = this.partitionInputProblem.chipMap[chipId]!
return chip.size.x
})
const totalWidth =
widths.reduce((sum, width) => sum + width, 0) +
Math.max(0, chipIds.length - 1) * gap

let cursorX = -totalWidth / 2
for (let i = 0; i < chipIds.length; i++) {
const chipId = chipIds[i]!
const width = widths[i]!
chipPlacements[chipId] = {
x: cursorX + width / 2,
y: 0,
ccwRotationDegrees: 0,
}
cursorX += width + gap
}

return {
chipPlacements,
groupPlacements: {},
}
}

private createLayoutFromPackingResult(
packedComponents: PackSolver2["packedComponents"],
): OutputLayout {
Expand Down
61 changes: 61 additions & 0 deletions tests/PackInnerPartitionsSolver/decoupling-caps-layout.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { expect, test } from "bun:test"
import { SingleInnerPartitionPackingSolver } from "lib/solvers/PackInnerPartitionsSolver/SingleInnerPartitionPackingSolver"
import type { PartitionInputProblem } from "lib/types/InputProblem"

const problem: PartitionInputProblem = {
isPartition: true,
partitionType: "decoupling_caps",
chipGap: 0.25,
partitionGap: 1,
decouplingCapsGap: 0.5,
chipMap: {
C10: {
chipId: "C10",
pins: ["C10.1", "C10.2"],
size: { x: 0.5, y: 1 },
availableRotations: [0],
},
C2: {
chipId: "C2",
pins: ["C2.1", "C2.2"],
size: { x: 0.5, y: 1 },
availableRotations: [0],
},
C1: {
chipId: "C1",
pins: ["C1.1", "C1.2"],
size: { x: 0.5, y: 1 },
availableRotations: [0],
},
},
chipPinMap: {
"C1.1": { pinId: "C1.1", offset: { x: 0, y: 0.25 }, side: "y+" },
"C1.2": { pinId: "C1.2", offset: { x: 0, y: -0.25 }, side: "y-" },
"C2.1": { pinId: "C2.1", offset: { x: 0, y: 0.25 }, side: "y+" },
"C2.2": { pinId: "C2.2", offset: { x: 0, y: -0.25 }, side: "y-" },
"C10.1": { pinId: "C10.1", offset: { x: 0, y: 0.25 }, side: "y+" },
"C10.2": { pinId: "C10.2", offset: { x: 0, y: -0.25 }, side: "y-" },
},
netMap: {},
pinStrongConnMap: {},
netConnMap: {},
}

test("decoupling capacitor partitions are packed into a clean horizontal row", () => {
const solver = new SingleInnerPartitionPackingSolver({
partitionInputProblem: problem,
pinIdToStronglyConnectedPins: {},
})
solver.solve()

expect(solver.solved).toBe(true)
const placements = solver.layout!.chipPlacements
expect(Object.keys(placements)).toHaveLength(3)
expect(placements.C1!.y).toBe(0)
expect(placements.C2!.y).toBe(0)
expect(placements.C10!.y).toBe(0)
expect(placements.C1!.x).toBeLessThan(placements.C2!.x)
expect(placements.C2!.x).toBeLessThan(placements.C10!.x)
expect(placements.C2!.x - placements.C1!.x).toBeCloseTo(1)
expect(placements.C10!.x - placements.C2!.x).toBeCloseTo(1)
})