Place and Route: Stage by Stage

This page walks through scripts/pnr.tcl in execution order. Each stage has a one-liner (what it does), the command and settings used in examples/custom_myfir (from scripts/yosys_common.tcl and scripts/tech/sky130hd.tcl), the design choices behind them, and where there is a measured value from the final run, that value. Numbers are from the final run (28 ns clock, repaired against ss, 0.5 ns setup margin; see Flow A: Signoff and Results).

0. Setup (before any layout exists)

One-liner: load the technology, library, netlist and constraints, and tell the tools what they may not use.

  • Technology LEF, cell LEF, Liberty. The tech LEF gives layers, vias and the placement site; the cell LEF gives cell shapes and pins; the Liberty file gives timing and power. PNR_LIB can replace the Liberty used by the optimisation steps (default: the tech file’s tt library).

  • read_verilog / link_design load the mapped gate netlist.

  • load_constraints.tcl reads the SDC (28 ns clock, input/output delays, driving cell, load), so every later step is timing-driven.

  • tech_wire_rc: wire RC used for estimates before real routes exist; signal nets on met2, clock nets on met5.

  • set_dont_use: the resizer, repair steps and CTS may not use probe_p_8, probec_p_8 or lpflow_*, the same list as synthesis.

Design choices. One SDC for every script, so pre-route, post-route and power numbers share constraints. One dont_use list for synthesis and P&R, so the resizer cannot reintroduce a cell synthesis avoided.

1. Floorplan

One-liner: decide the die and core size and draw the cell rows and routing tracks.

  • initialize_floorplan + make_tracks

  • Settings: utilisation 40 %, aspect ratio 1 (square), core-to-die margin 2 µm, site unithd.

Design choices. 40 % utilisation leaves room for CTS buffers, repair cells, diodes and fillers and avoids congestion; higher utilisation gives a smaller die but harder routing. Measured: utilisation is 42 % after taps and PDN and 43 % after CTS (the “100 %” printed in ppa.log and postroute.log is an artefact of reading the netlist without a floorplan).

2. Tap cells

One-liner: place well and substrate tap cells at regular spacing so latch-up cannot occur.

  • tapcell with tapvpwrvgnd_1, distance 14 µm.

Design choices. Taps go in before the power grid and before placement so they have a fixed position and placement works around them. Measured: area 72,957 µm² (synthesis) → 75,923 µm² after taps and PDN.

3. Power grid

One-liner: build the VDD/VSS grid that every cell draws power from.

  • tech_pdn defines the global connections (VDD/VPWR/VPB, VSS/VGND/VNB); pdngen builds the grid.

  • met1 rails along the rows (0.48 µm wide, pitch 5.44 µm), met4 stripes (1.6 µm wide, pitch 27.14 µm), met5 stripes (1.6 µm wide, pitch 27.2 µm), plus the vias between layers.

Design choices. This is the standard Sky130 HD grid used by OpenROAD-flow-scripts; it gives every cell a low-resistance supply path without hand tuning.

4. Tie cells

One-liner: drive constant 0/1 nets from a tie cell instead of the rail.

  • insert_tiecells with conb_1.

Design choices. A constant must not connect straight to a rail. Consequence: the LVS deck cannot see conb_1, so lvs_prep.py rewrites it to rail connections in the schematic; those connections are therefore not verified by LVS (Flow A: Signoff and Results).

5. Pin placement and global placement

One-liner: put the I/O pins on the die edge and spread the cells over the core.

  • place_pins on met3 (horizontal) and met2 (vertical). It is called before and again after global_placement so the second call can use the cell positions.

  • global_placement -density 0.45: cells are spread to reduce wire length and congestion. At this point they overlap slightly and are not legal.

Design choices. A placement density of 0.45 (rather than 1.0) keeps the cells from packing tightly, which helps routability and leaves space for the buffers and diodes added later.

6. Parasitic estimate, design repair and legalisation

One-liner: fix electrical violations and legalise the placement before building the clock tree.

  • estimate_parasitics -placement gives wire delay estimates from cell positions.

  • repair_design fixes slew, capacitance and fanout violations and buffers long and high-fanout nets (RST_n and VIN each drive more than 100 pins).

  • detailed_placement moves cells to legal row positions without overlap.

  • Checkpoint PNR_STOP=place stops here.

Design choices. repair_design runs before CTS so the clock tree is not built on an electrically broken netlist. Measured: area 76,057 µm² after this stage; at the ss library setup is −1.75 ns and hold 0.00 ns (clock still ideal), which is the gap the later repair has to close.

7. Clock tree synthesis

One-liner: build a balanced buffer tree from the clock port to every flip-flop and switch timing to the real clock.

  • clock_tree_synthesis -root_buf clkbuf_4 -buf_list {clkbuf_2 clkbuf_4 clkbuf_8}

  • set_propagated_clock [all_clocks]: the clock is no longer ideal. Before this point clock delay is 0, as in the pre-route PPA report.

  • detailed_placement and estimate_parasitics legalise the new buffers and refresh the estimates.

Design choices. The buffer list restricts CTS to three drive strengths (clkbuf_2, clkbuf_4, clkbuf_8), with clkbuf_4 at the root. Propagating the clock makes every later slack include the real tree delay.

8. Timing repair

One-liner: fix setup and hold violations by sizing, buffering and inserting delay cells.

  • repair_timing -setup -hold -setup_margin 0.5 -hold_margin 0.35 (environment variables SETUP_MARGIN and HOLD_MARGIN).

  • Runs against the liberty in PNR_LIB; make pnr-ss uses ss_100C_1v60.

  • Checkpoint PNR_STOP=cts stops here.

Design choices.

  • Hold margin 0.35 ns. Input-port-to-flop hold paths lose about 0.3 ns between tt and ss: the clock tree gets slower while the external input delay stays fixed. The margin keeps hold positive at ss.

  • Repair at the ss library. repair_timing only fixes violations it sees. Repaired at tt the design left ss at −2.26 ns; repaired at ss with margin 0 it reached −0.22 ns; with a 0.5 ns setup margin it closed at +0.29 ns. This is optional (make pnr-ss) and not part of make all.

Measured: after this stage area is 77,174 µm² (43 %), setup +0.50 ns, hold +0.46 ns, TNS 0 (at the repair library).

9. Routing layers and global route

One-liner: plan the rough path of every net before real wires exist.

  • set_routing_layers: signals on met1–met5, clock nets on met3–met5.

  • global_route writes a congestion report.

Design choices. Clock nets use the upper layers because they have lower resistance than the thin lower layers. Global route is an estimate, not the final wires. Measured: global-route usage was about 22 % in the baseline run.

10. Antenna check and repair

One-liner: insert diodes where long metal could charge a gate during manufacturing.

  • check_antennas; repair_antennas diode_2 -iterations 3 -ratio_margin 40 (ANT_MARGIN).

  • detailed_placement and check_placement legalise and check the inserted diodes.

Design choices. The 40 % margin protects ahead of time because final wires are longer than the global-route estimate. Measured: 11 violating nets → 0 after repair on the global-route estimate; 7 remain after detailed route (all met1 side-area). The set changes from run to run and does not converge to zero with a larger margin, so it is reported, not chased (Flow A: Signoff and Results).

11. Detailed routing

One-liner: lay the real wires and vias on the tracks, following the design rules.

  • detailed_route, run headless because the GUI crashes on it. This is the slow stage (about 20 to 30 minutes here).

Measured: router DRC violations 3313 → 370 → 0 over its iterations. This count covers routing layers only; the KLayout deck covers all layers.

12. Fillers and final checks

One-liner: fill the empty row space and run the final placement and antenna checks.

  • filler_placement adds fillers for well and implant continuity, which the DRC deck requires.

  • check_placement and check_antennas; the final antenna report is the number to quote.

13. Global connect

One-liner: give the cells added after the power grid their power pins.

  • global_connect re-applies the connection rules to repair buffers, CTS buffers, diodes and fillers.

Design choices. Without this step LVS sees dangling power pins on those cells.

14. Outputs and extraction

One-liner: write the routed layout, the parasitics and the netlists.

  • write_def writes <design>_placed.def (the fully routed layout, used for GDS).

  • set_extraction_rules_file + extract_parasitics + write_spef, once per RC corner: <design>_route.spef (nom), _route_min.spef and _route_max.spef.

  • write_verilog writes the routed gate netlist; write_cdl -masters writes the netlist for the LVS schematic.

Design choices.

  • Three extractions. make multicorner needs a SPEF per corner: ss uses max, ff min, tt nominal. The three rules files differ in resistance only, so this is a resistance spread.

  • No timing or power reports here. OpenSTA ignores parasitics until read_spef is called, so numbers produced inside pnr.tcl would ignore the real wires. post_route.tcl reads the SPEF first and then reports.

Measured (post-route, tt): setup +14.15 ns, hold +0.39 ns; at ss +0.29 ns and at ff +19.56 ns.