-
Notifications
You must be signed in to change notification settings - Fork 0
Placement
Placement assigns a legal physical location to every standard cell in the design. Floorplanning decided where the macros go; placement fills the remaining core area with the tens or hundreds of thousands of gates between them.
It's the first stage where timing estimates become meaningful, because for the first time every cell has a real location and therefore a real wire length to its neighbors.
- Timing — put connected cells close together, weighted by criticality
- Congestion — spread cells so routing demand never exceeds supply
- Power — short wires switch less capacitance
- Legality — every cell on-site, in-row, no overlaps
- Runtime — placement is run many times; it has to be fast enough to iterate
Timing and congestion pull in opposite directions. Packing critical cells tightly is good for delay and bad for routability. Managing that tension is the job.
flowchart LR
A[Power Planning] --> B[Placement]
B --> C[CTS]
C --> D[Routing]
B -.->|congestion or<br/>timing failure| E[Floorplanning]
style B fill:#2d6a9f,color:#fff
Placement runs on the post-PDN database and hands a placed, optimized netlist to Clock Tree Synthesis. When placement can't close, the honest fix is usually upstream in Floorplanning, not more placement effort.
| Phase | What happens | Result |
|---|---|---|
| Global placement | Cells spread across the core to minimize wirelength subject to a density target | Roughly correct positions, cells may overlap |
| Legalization | Cells snapped to legal sites and rows, overlaps removed | Legal but slightly worse than global |
| Detailed placement | Local swaps and shifts to recover what legalization cost | Legal and optimized |
Global placement does the real optimization; the other two clean up after it.
Modern placers are analytical. Model each net as a spring pulling its cells together, then solve for minimum energy. The classic objective is quadratic wirelength:
W = Σ over nets w · [ (x_i − x_j)² + (y_i − y_j)² ]
Minimizing that alone collapses every cell onto a single point — so the placer adds a density penalty that pushes cells apart wherever they pile up. The solution balances the two forces.
Two consequences worth internalizing:
- It's a local optimizer. It finds a good answer near where it starts. That starting configuration is set by Floorplanning — which is why a bad floorplan can't be rescued here.
-
Net weights are the steering wheel. Timing-driven placement works by raising
won critical nets so the solver pulls them tighter. Congestion-driven placement works by locally raising the density penalty.
HPWL (half-perimeter wirelength) — the half-perimeter of each net's bounding box — is the standard cheap proxy for wirelength. It's exact for 2- and 3-pin nets and fast enough to evaluate millions of times.
Placement isn't only about moving cells. The tool simultaneously restructures logic:
| Technique | What it does | Watch out for |
|---|---|---|
| Gate sizing | Swaps a cell for a stronger/weaker variant | Upsizing grows area and leakage |
| Buffer insertion | Breaks long nets into driveable segments | Buffers can be 10–20% of final cell count |
| Cloning | Duplicates a high-fanout driver | Costs area, helps fanout delay |
| Restructuring | Rewrites logic cones for depth | Makes the netlist diverge from synthesis |
| Pin swapping | Uses commutative inputs to shorten a critical net | Free — always on |
| Useful skew prep | Leaves room for Clock Tree Synthesis to borrow time | Needs launch/capture flops physically close |
This is why the cell count and area after placement don't match synthesis — expect 10–20% area growth.
# Effort and mode
set_db place_global_timing_effort high
set_db place_global_cong_effort auto
set_db place_detail_wire_length_opt_effort high
# Global + detailed placement with timing optimization
place_opt_design
# Or step through it
place_design ;# global + legalize + detail
opt_design -pre_cts ;# timing optimization
# Checks
check_place ;# legality: overlaps, off-site cells
report_congestion -hotspot ;# where routing will struggle
report_timing -max_paths 50 -path_group reg2reg
report_design_rule_violations ;# max_tran / max_cap / max_fanout
report_areaKey commands explained:
-
place_opt_design— the workhorse: global placement, legalization, detailed placement, and pre-CTS timing optimization in one pass -
opt_design -pre_cts— optimization with ideal clocks (no clock tree exists yet), so setup slack here is optimistic -
check_place— legality only; a design can be legal and still terrible -
report_congestion -hotspot— the number that predicts whether Routing will succeed
# Cap density in a congested region
create_place_blockage -area {400 400 600 600} -type partial -density 50
# Keep a group of cells together
create_guide -name ctrl_group -area {100 100 400 400}
add_to_guide -guide ctrl_group -insts {u_ctrl/*}
# Protect critical cells from being moved
set_dont_touch [get_cells u_datapath/array/*] true| Metric | Typical target | If it's bad |
|---|---|---|
| WNS (worst negative slack) | Small negative is fine pre-CTS | Check for cross-die nets; revisit macro placement |
| TNS (total negative slack) | Falling run over run | Many small violations = systemic, not local |
| Congestion overflow | ~0%, no hotspots | Lower density target, add partial blockages |
| Cell density | 70–85% post-optimization | Above ~90% locally, routing usually fails |
| HPWL | Lower is better | Correlates with power, delay, and congestion at once |
| Area growth vs. synthesis | 10–20% | Much more means synthesis constraints were unrealistic |
| DRV count (max_tran/cap/fanout) | Zero before CTS | Fix here; they get worse later |
Pre-CTS timing is optimistic. Clocks are ideal, so real skew and insertion delay aren't modeled yet. Don't celebrate a clean pre-CTS report.
| Problem | Root cause | Fix |
|---|---|---|
| Congestion hotspot | Too many connected cells packed into one region | Partial blockage, lower density target, check Floorplanning |
| Timing fails only on long nets | Cells that talk are far apart | Guides to cluster them; fix macro placement upstream |
| Huge buffer count | Long nets the placer couldn't shorten | Usually a floorplan problem, not a placement one |
| Cells stranded near macros | Narrow channels between macros | Widen or block the channel in Floorplanning |
| Legalization moves cells far | Local density over 100% | Reduce target density; check for a placement blockage gap |
| Great pre-CTS, terrible post-CTS | Ideal-clock optimism | Leave margin; use realistic clock uncertainty in Design Constraints |
| High-fanout net dominates | Reset or enable with thousands of sinks | Let the tool build a buffer tree; consider set_max_fanout
|
- Fix congestion before timing. A congested placement produces meaningless timing, because routing will change everything.
- Start with a lower density target than you think you need. 70% behaves very differently from 80%.
- Look at the congestion map, not the average. Local hotspots are what fail.
- Don't over-constrain with guides and fences. Every constraint removes optimization freedom; use them where you know something the tool doesn't.
- Keep realistic clock uncertainty pre-CTS so the optimizer leaves margin for the skew it can't see yet.
- If placement can't close, look upstream. Persistent failure is a floorplan message, not a call for more effort levels.
- Save the database before each experiment so you can compare rather than guess.
See also: Floorplanning · Power Planning · Clock Tree Synthesis · Timing Closure · Physical Design