Placement
COmPOSER uses a Gurobi-based mixed-integer floorplanner. The placer chooses module positions, legal rotations, optional module variants, pad locations, and chip size while minimizing a weighted combination of area and wirelength.
Command
python3 perform_placement.py --config EXAMPLES/LNA_1/config.json
Primary Inputs
project_name/stage_2/<topcell>_design.json: module sizes, module variants, pins, and chip pad metadataplacement.placement_constraints: user placement-constraint JSONplacement.timelimit: Gurobi solve time limit in secondsplacement.aspect_ratio: target chip aspect ratio;0disables the ratio constraintplacement.level: objective mode, described belowplacement.weight_hpwl: tradeoff between pure area and wirelength-driven placement
Outputs
stage_3/placement/<topcell>_placement.jsonstage_3/placement/<topcell>_placement.gdsstage_3/placement/primitives/*.gds
What The Placer Solves
- Every module gets an
x,y,w, andh. - Every module gets exactly one orientation from
R0,R90,R180, andR270. - Modules with multiple geometry variants get exactly one active variant.
- The chip outline
WandHare solved along with the placement. - Pads are constrained either to the periphery or to a BGA lattice, depending on
pad_mode. - Net wirelength uses orientation-aware pin positions, not just module centers.
Objective Controls
| Key | Meaning |
|---|---|
placement.timelimit | Maximum Gurobi runtime in seconds. |
placement.aspect_ratio | If nonzero, constrains W/H to a narrow band around the given value. |
placement.level | 0 minimizes area plus weighted HPWL. 1 adds extra weighted Manhattan distance terms for branch pairs listed in the net JSON. |
placement.weight_hpwl | Blend factor between area and the wirelength-related objective terms. |
placement.plot_html | If true, writes an interactive placement plot. |
Constraint File Format
The placement-constraint file is a JSON object. All keys are optional. A minimal valid file can be as small as:
{
"halo": 1000
}
A richer example looks like this:
{
"halo": 1000,
"keepouts": [
{"ll": [0, 0], "ur": [20000, 15000]}
],
"regions": {
"input": {"ll": [0, 40000], "ur": [80000, 140000]}
},
"symmetry": [
{
"pairs": [["Lleft", "Lright"]],
"self_symmetric": ["CenterTap"],
"type": "vertical",
"axis_x": 150000
}
],
"chip_symmetry": [
{
"modules": ["BiasLeft", "BiasCenter", "BiasRight"],
"type": "vertical"
}
],
"alignment": [
{"modules": ["gnd0", "input", "gnd1"], "type": "bottom"}
],
"proximity": [
{"modules": ["cas_mos", "bias_mos"], "max_dx": 40000, "max_dy": 20000}
],
"ordering": [
{"modules": ["gnd0", "input", "gnd1"], "type": "horizontal", "gap": 5000}
]
}
Supported Constraint Types
halo
halo is a global spacing rule applied to every module pair. It expands the non-overlap requirement by the same amount in all directions.
{
"halo": 3000
}
If module A is to the left of module B, the solver enforces xA + wA + halo <= xB. This is the simplest way to get uniform white space between blocks.
keepouts
keepouts define forbidden rectangles. Every module must lie entirely outside each keepout.
{
"keepouts": [
{"ll": [0, 0], "ur": [10000, 20000]},
{"ll": [200000, 50000], "ur": [260000, 90000]}
]
}
Each keepout is an axis-aligned rectangle with lower-left ll and upper-right ur.
regions
regions assign a legal placement box to specific modules. A constrained module must be placed completely inside its region.
{
"regions": {
"input": {"ll": [0, 80000], "ur": [120000, 180000]},
"output": {"ll": [220000, 80000], "ur": [360000, 180000]}
}
}
This is useful when a block must stay near an edge, near a matching network, or inside a reserved floorplan zone.
symmetry
symmetry mirrors modules about a fixed numeric axis that you provide explicitly.
Supported forms:
pairsplus optionalself_symmetricmodulesas an ordered list; the code automatically pairs outside-in, and an odd middle module becomes self-symmetric
Vertical symmetry example:
{
"symmetry": [
{
"pairs": [["L1", "R1"], ["L2", "R2"]],
"self_symmetric": ["CenterBlock"],
"type": "vertical",
"axis_x": 150000
}
]
}
Ordered-list example:
{
"symmetry": [
{
"modules": ["L2", "L1", "C", "R1", "R2"],
"type": "vertical",
"axis_x": 150000
}
]
}
Semantics:
type: "vertical"means reflect aboutx = axis_x.type: "horizontal"means reflect abouty = axis_y.- Pair symmetry constrains only the module centers, not orientation or variant equality.
self_symmetricmeans the module center is forced onto the axis.
Important limitation: a block containing only self_symmetric is not currently accepted by the parser. Use either pairs or a modules list with at least two names.
chip_symmetry
chip_symmetry uses the same syntax as symmetry, but reflects modules about the solved chip centerline rather than a fixed numeric axis.
{
"chip_symmetry": [
{
"pairs": [["LeftPA", "RightPA"]],
"self_symmetric": ["OutputMatch"],
"type": "vertical"
}
]
}
{
"chip_symmetry": [
{
"modules": ["BottomBias", "CenterBias", "TopBias"],
"type": "horizontal"
}
]
}
Semantics:
type: "vertical"means symmetry about the chip vertical midpoint, so paired module centers satisfycenter_x(A) + center_x(B) = W.type: "horizontal"means symmetry about the chip horizontal midpoint, so paired module centers satisfycenter_y(A) + center_y(B) = H.- As with
symmetry, this is geometric center symmetry only. It does not force identical orientation, identical variant choice, or mirrored pin selection.
The same parser limitation applies here too: a chip_symmetry block cannot contain only self_symmetric names.
alignment
alignment aligns a set of modules to the first module listed.
Supported types are top, bottom, left, right, center_x, and center_y.
{
"alignment": [
{"modules": ["gnd0", "input", "gnd1"], "type": "bottom"},
{"modules": ["M1", "M2", "M3"], "type": "center_x"}
]
}
bottom aligns all module lower edges. center_x aligns all module horizontal centers. The first module in the list is the reference for the others.
proximity
proximity limits how far apart two module centers may be.
Supported forms:
max_dx: absolute center-to-center separation in xmax_dy: absolute center-to-center separation in ymax_dist: Euclidean center-to-center distance
{
"proximity": [
{"modules": ["cas_mos", "bias_mos"], "max_dx": 40000, "max_dy": 20000},
{"modules": ["L1", "C1"], "max_dist": 60000}
]
}
Important limitation: min_dist is explicitly rejected by the code today.
ordering
ordering enforces a chain order with an optional minimum gap between consecutive modules.
{
"ordering": [
{"modules": ["gnd0", "input", "gnd1"], "type": "horizontal", "gap": 5000},
{"modules": ["source_ind", "cas_mos", "drain_ind"], "type": "vertical", "gap": 10000}
]
}
horizontalmeans left-to-right ordering.verticalmeans bottom-to-top ordering.gapdefaults to0if omitted.
Pad Placement Rules
Pad placement is not configured inside placement_constraint.json, but it is still an important part of the placement solution.
| Control | Meaning |
|---|---|
pad_mode | periphery places pads on chip edges. bga snaps pad centers to an internal grid. |
pad_direction | Top-level config input used earlier in the flow to decide which pad sides are legal. |
io_pitch, io_h | Periphery pad pitch and pad band height stored in the stage-2 design JSON. |
io_row_h, io_col_w | Optional reserved edge-band thicknesses for core exclusion in periphery mode. |
bga_pitch_x, bga_pitch_y | BGA grid pitch when pad_mode is bga. |
bga_origin_x, bga_origin_y | BGA lattice origin. |
In periphery mode, non-pad modules are kept out of the reserved IO bands. In BGA mode, there is no automatic edge band because pads can live inside the array.
Constraint Interaction Notes
- All module names must match the stage-2 design JSON exactly.
halois global; it is not per-module or per-pair.symmetryandchip_symmetryenforce mirrored centers only.- Constraints can conflict. For example, a tight
region, largehalo, and strictorderingcan easily make the problem infeasible. - The solver also accounts for module rotation and multi-variant module dimensions when enforcing these constraints.
Practical Starting Point
A good first constraint file usually contains only halo, one or two ordering rules, and a small number of regions or symmetry blocks. Add stronger constraints only after the unconstrained or lightly constrained placement is already behaving reasonably.