===================================== 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 :doc:`flow-a-signoff`). 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 (:doc:`flow-a-signoff`). 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 (:doc:`flow-a-signoff`). 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 ``_placed.def`` (the fully routed layout, used for GDS). * ``set_extraction_rules_file`` + ``extract_parasitics`` + ``write_spef``, once per RC corner: ``_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.