Reference

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 metadata
  • placement.placement_constraints: user placement-constraint JSON
  • placement.timelimit: Gurobi solve time limit in seconds
  • placement.aspect_ratio: target chip aspect ratio; 0 disables the ratio constraint
  • placement.level: objective mode, described below
  • placement.weight_hpwl: tradeoff between pure area and wirelength-driven placement

Outputs

  • stage_3/placement/<topcell>_placement.json
  • stage_3/placement/<topcell>_placement.gds
  • stage_3/placement/primitives/*.gds

What The Placer Solves

  • Every module gets an x, y, w, and h.
  • Every module gets exactly one orientation from R0, R90, R180, and R270.
  • Modules with multiple geometry variants get exactly one active variant.
  • The chip outline W and H are 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

KeyMeaning
placement.timelimitMaximum Gurobi runtime in seconds.
placement.aspect_ratioIf nonzero, constrains W/H to a narrow band around the given value.
placement.level0 minimizes area plus weighted HPWL. 1 adds extra weighted Manhattan distance terms for branch pairs listed in the net JSON.
placement.weight_hpwlBlend factor between area and the wirelength-related objective terms.
placement.plot_htmlIf 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:

  • pairs plus optional self_symmetric
  • modules as 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 about x = axis_x.
  • type: "horizontal" means reflect about y = axis_y.
  • Pair symmetry constrains only the module centers, not orientation or variant equality.
  • self_symmetric means 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 satisfy center_x(A) + center_x(B) = W.
  • type: "horizontal" means symmetry about the chip horizontal midpoint, so paired module centers satisfy center_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 x
  • max_dy: absolute center-to-center separation in y
  • max_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}
  ]
}
  • horizontal means left-to-right ordering.
  • vertical means bottom-to-top ordering.
  • gap defaults to 0 if omitted.

Pad Placement Rules

Pad placement is not configured inside placement_constraint.json, but it is still an important part of the placement solution.

ControlMeaning
pad_modeperiphery places pads on chip edges. bga snaps pad centers to an internal grid.
pad_directionTop-level config input used earlier in the flow to decide which pad sides are legal.
io_pitch, io_hPeriphery pad pitch and pad band height stored in the stage-2 design JSON.
io_row_h, io_col_wOptional reserved edge-band thicknesses for core exclusion in periphery mode.
bga_pitch_x, bga_pitch_yBGA grid pitch when pad_mode is bga.
bga_origin_x, bga_origin_yBGA 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.
  • halo is global; it is not per-module or per-pair.
  • symmetry and chip_symmetry enforce mirrored centers only.
  • Constraints can conflict. For example, a tight region, large halo, and strict ordering can 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.