Introduction
Floorplanning sets physical constraints for the rest of place/route. Good floorplans reduce congestion, skew, IR drop, and wirelength; bad ones make timing closure painful. With the open-source stack (OpenROAD, Magic, OpenSTA), you can plan and validate a robust floorplan for real designs.
Inputs you need
- Gate-level netlist (from Yosys) and target clock(s).
- PDK + standard cell libraries (LEF/Liberty; e.g., Sky130).
- Macro abstracts (LEF) for SRAMs, PLLs, hard IP, etc.
- IO/pad requirements (count, sides, ESD strategy if applicable).
- Power targets and metal stack constraints for PDN.
Die size, utilization & aspect ratio
Start from cell area and a utilization target. Utilization of 45–60% is common for early passes (leave room for buffering and routing). Aspect ratio close to 1.0 minimizes worst-case wirelength unless IO or packaging dictates otherwise.
# area_std_cells: sum of all cell areas from your library report
core_area = area_std_cells / utilization
# choose aspect ratio (AR = height/width); usually ≈ 1.0
width = sqrt(core_area / AR)
height = width * AR
IO ring & pin placement
Place IO pins to minimize long detours. Keep clocks/resets away from noisy neighbors. For pad-based designs, define a ring (or per-side pads). For core-limited blocks, evenly distribute signal pins along edges.
# After reading LEFs/Libs and linking the netlist
set die_w 1200
set die_h 1200
initialize_floorplan -die_area "0 0 $die_w $die_h" -core_space 20
# Place pins on sides (N, E, S, W) with equal spacing
place_pins -hor_layers met2 -ver_layers met3 -random
# Or specify pins:
# place_pins -pins {clk rst_n} -layer met2 -side N
# place_pins -pins {uart_tx uart_rx} -layer met3 -side E
Macros, halos & blockages
Align macros to tracks, put them near related logic, and leave routing channels between large blocks. Add halos (keep-out margins) to prevent tight cell packing that chokes routing around macros. Use blockages to reserve streets for global routes or power straps.
# Example: place an SRAM macro and add a halo (keep-out)
place_cell sram0 200 300 N
# Add a 10um halo around all macros
set_halo 10 10 10 10 -all_macros
# Create a soft blockage stripe as a routing channel
create_placement_blockage -box "300 80 340 520" -type soft
Power planning & PDN
Define global power/ground nets, create rings around core (optional), and generate metal stripes (PDN) per your PDK guidance. For Sky130, common straps use met4/met5 with reasonable pitch/width based on current estimates.
# Connect std-cell rails to global VDD/VSS
add_global_connection -net VDD -inst_pattern .* -pin_pattern {^VDD$}
add_global_connection -net VSS -inst_pattern .* -pin_pattern {^VSS$}
global_connect
# Define a PDN grid and generate horizontal/vertical straps
define_pdn_grid -name core_grid
add_pdn_stripe -grid core_grid -layer met4 -width 1.6 -pitch 40 -offset 20 -starts_with POWER
add_pdn_stripe -grid core_grid -layer met5 -width 1.6 -pitch 40 -offset 20 -starts_with GROUND
add_pdn_connect -grid core_grid -layers {met4 met5}
# Optional: ring around the core
# add_pdn_ring -grid core_grid -layers {met4 met5} -widths {2 2} -spacings {0.8 0.8} -core_offsets {5 5 5 5}
OpenROAD floorplan flow (TCL)
Below is a minimal, reproducible TCL that you can tailor. It gets you from LEF/Libs + netlist to a floorplan with pins, macros, and PDN.
read_lef sky130_fd_sc_hd.tlef
read_lef sky130_fd_sc_hd__merged.lef
# Add macro LEFs:
# read_lef sram_1rw1r_32x256_8.lef
read_liberty sky130_fd_sc_hd__tt_025C_1v80.lib
read_verilog top_netlist.v
link_design top
# Size and initialize
set die_w 1400
set die_h 1400
initialize_floorplan -die_area "0 0 $die_w $die_h" -core_space 20
# IO pins
place_pins -hor_layers met2 -ver_layers met3 -random
# Macro placement (example)
# place_cell sram0 200 300 N
set_halo 10 10 10 10 -all_macros
create_placement_blockage -box "360 80 400 520" -type soft
# Power intent
add_global_connection -net VDD -inst_pattern .* -pin_pattern {^VDD$}
add_global_connection -net VSS -inst_pattern .* -pin_pattern {^VSS$}
global_connect
# PDN
define_pdn_grid -name core_grid
add_pdn_stripe -grid core_grid -layer met4 -width 1.6 -pitch 40 -offset 20 -starts_with POWER
add_pdn_stripe -grid core_grid -layer met5 -width 1.6 -pitch 40 -offset 20 -starts_with GROUND
add_pdn_connect -grid core_grid -layers {met4 met5}
# Save DEF for inspection
write_def floorplan.def
Tip: keep all coordinates and sizes in one “config.tcl” and source it from your flow so experiments are versioned.
Sanity checks & reports
- Utilization:
report_utilization
— adjust core size or utilization target. - Congestion hotspots: do a trial global route and
report_congestion
. - Timing risk: run OpenSTA early with rough parasitics or wireload estimates.
- DRC: open the DEF in Magic and run
drc check
to catch obvious spacing issues.
report_utilization
estimate_parasitics -global_routing
report_congestion
# STA sketch
read_sdc top.sdc
report_checks -path_delay min_max -digits 3
Iterating for PPA
- Move or rotate macros to reduce detours on the top two critical nets.
- Increase routing channels or soften blockages where congestion spikes.
- Widen PDN straps or change pitch if IR drop or EM margins are tight.
- Adjust aspect ratio if one direction is congested after trial route.
FAQ
What’s a good initial utilization? 45–60% for first passes. Push higher only after timing/DRC margins look healthy.
How big should halos be? Start with 5–10 µm around macros, widen if detours pile up.
Which metals for PDN? Follow your PDK notes. For Sky130, met4/met5 straps are common in open examples.
You might also like