LibreLane
LibreLane is the successor to OpenLane 2. It is an infrastructure library for building digital ASIC implementation flows — synthesis, floorplanning, PDN, placement, CTS, routing, DRC/LVS, sign-off timing — out of open-source EDA tools. You write a small configuration file describing your design and LibreLane runs each step in sequence, capturing every intermediate artifact so that runs are reproducible and steppable.
The project was renamed from OpenLane 2 to LibreLane in early 2026 and moved from efabless/openlane2 to librelane/librelane. The code is the same lineage, with the OpenLane 2 history intact; only the name, URL, and version series (3.0.0 was the first LibreLane-branded release) changed. See the Migrating from OpenLane section below.
Key links:
- Documentation: https://librelane.readthedocs.io/
- Source: https://github.com/librelane/librelane
- Project page: https://librelane.org
Table of contents
- Prerequisites
- Installing LibreLane
- Smoke test
- Running the SPM example
- The config file
- Run directories and tags
- Viewing the final design
- Targeting gf180mcu with wafer.space
- Migrating from OpenLane 2.3
- Help
Prerequisites
- Nix. LibreLane’s first-class install path is Nix with the FOSSi binary cache. Set that up first with the Nix tutorial if you haven’t already.
- git. The install clones the LibreLane repository.
- Python 3.10+. LibreLane 3.x requires it; Nix takes care of this for you.
- ciel with a PDK enabled (see Sky130 or gf180mcu). LibreLane defaults to
$HOME/.cielas its PDK root. - On Windows, run everything inside WSL.
Installing LibreLane
Inside a Nix-enabled shell:
git clone https://github.com/librelane/librelane
cd librelane
nix-shell
The first nix-shell pulls prebuilt binaries from the FOSSi cache and takes roughly 10 minutes. Subsequent invocations open in seconds.
Every time you want to use LibreLane, cd into the cloned repo and run nix-shell to enter the environment. Running exit (or Ctrl-D) returns you to your normal shell.
Docker alternative. If Nix is impractical for your setup (e.g. a corporate-managed macOS that blocks the installer), LibreLane also ships a Docker image. After installing it with pip install --upgrade librelane, prefix every librelane command with --dockerized:
python3 -m pip install --upgrade librelane
librelane --dockerized --smoke-test
The Docker path uses the same workflow as the Nix path, just with --dockerized added to every invocation.
pip-only installation is unsupported. You would have to bring your own compiled versions of OpenROAD, Yosys, KLayout, Magic, and Netgen, which defeats the point. Use Nix or Docker.
Smoke test
Inside the nix-shell, verify the install with:
librelane --smoke-test
This runs a minimal design end-to-end through every built-in step. It should finish with Smoke test passed. Warnings are normal; errors are not.
Running the SPM example
LibreLane ships with a collection of example designs. The canonical first run is SPM (a small serial-parallel multiplier):
python3 -m librelane --pdk-root $HOME/.ciel ./librelane/examples/spm/config.yaml
This pulls in the shipped configuration, runs the full Classic flow, and produces the final GDS. Artifacts land in ./librelane/examples/spm/runs/RUN_<timestamp>/.
Inside the run directory you will find:
| Subdirectory | Contents |
|---|---|
final/ | Post-flow GDS, DEF, ODB, SDC, SPEF, Liberty timing |
*-*/ | One directory per flow step, numbered in order |
logs/ | Per-step tool logs |
reports/ | Per-step reports (timing, DRC, LVS summaries) |
metrics.csv | Aggregated metrics for the whole run |
The config file
LibreLane accepts configs in either JSON or YAML. A minimal example for a Sky130 synthesis run:
# config.yaml
DESIGN_NAME: my_design
VERILOG_FILES: ["./src/my_design.v"]
CLOCK_PORT: clk
CLOCK_PERIOD: 10 # ns
PDK: sky130A
Every other knob has a default. The Universal Flow Configuration Variables reference lists all of them. The most-common ones to override in practice:
FP_CORE_UTIL— target core utilization percentageFP_ASPECT_RATIO— core aspect ratio (height/width)DIE_AREA/CORE_AREA— explicit floorplan overridePL_TARGET_DENSITY— placer density targetSYNTH_STRATEGY— yosys synthesis strategyRUN_HEURISTIC_DIODE_INSERTION— antenna mitigationMAX_FANOUT_CONSTRAINT— fanout limitCLOCK_TREE_SYNTHESIS— CTS tool selectionUSE_SLANG— use Slang for SystemVerilog parsing (LibreLane 3+)
If you have a working OpenLane 2 config, read the Migrating from OpenLane section first — several variable names changed.
Run directories and tags
By default, each run creates a fresh directory named RUN_<YYYY-MM-DD>_<HH-MM-SS>. To name a run explicitly, pass --run-tag:
python3 -m librelane --run-tag my_run --pdk-root $HOME/.ciel config.yaml
Re-running with the same tag requires --overwrite:
python3 -m librelane --run-tag my_run --overwrite --pdk-root $HOME/.ciel config.yaml
The shortcut --last-run refers to whichever run finished most recently.
Viewing the final design
You can launch OpenROAD directly against the final database:
openroad -gui
and then inside the OpenROAD GUI load the final ODB, SPEF, SDC, and a Liberty view that matches the corner you want to analyse. For example:
read_lib $env(PDK_ROOT)/sky130A/libs.ref/sky130_fd_sc_hd/lib/sky130_fd_sc_hd__ss_100C_1v60.lib
read_db designs/spm/runs/RUN_<timestamp>/final/odb/spm.odb
read_spef designs/spm/runs/RUN_<timestamp>/final/spef/max/spm.nom.max.spef
read_sdc designs/spm/runs/RUN_<timestamp>/final/sdc/spm.sdc
Save this as a .tcl script and source it to avoid retyping.
See Static Timing Analysis and Multi-Corner Timing Analysis for the report-generation side of things once the design is loaded.
Targeting gf180mcu with wafer.space
wafer.space is a budget MPW service that currently runs a gf180mcu flow on a forked branch of LibreLane. If you are submitting a chip there, you should use their project template rather than the upstream LibreLane you just installed — the template pins the exact LibreLane branch they’ve validated against their PDK fork.
git clone https://github.com/wafer-space/gf180mcu-project-template
cd gf180mcu-project-template
make clone-pdk # clones wafer.space's gf180mcu PDK fork
nix-shell # enters the pinned LibreLane branch
make librelane # run the flow
A few useful make targets once inside the Nix shell:
| Target | What it does |
|---|---|
make librelane | Full digital flow |
make librelane-padring | Build the analog pad ring only |
make librelane-openroad | Open the run in the OpenROAD GUI |
make librelane-klayout | Open the run in KLayout |
make sim | RTL simulation via cocotb + Icarus |
make sim-gl | Gate-level simulation |
make sim-view | GTKWave on the latest waveform |
Slot geometry (die size) is selectable via the SLOT environment variable. Supported values:
make librelane # default: 1x1 slot
SLOT=0p5x1 make librelane # half-width slot
SLOT=1x0p5 make librelane # half-height slot
SLOT=0p5x0p5 make librelane # quarter slot
Before submitting, run the precheck tool against your final GDS:
export PDK_ROOT=gf180mcu
export PDK=gf180mcuD
python3 precheck.py --input chip_top.gds --slot 1x1
Precheck verifies DRC, density, antenna rules, and that the top cell is named chip_top at origin (0, 0) with a 0.001 µm DBU.
Current wafer.space run info, slot pricing, and any submission-packaging rules live on https://wafer.space. Check the site before submission — those details change per run.
Migrating from OpenLane 2.3
If you have a working OpenLane 2.3-era config or tutorial, the main breaking changes you will hit when moving to LibreLane 3.x are:
- Python 3.10+ is required. Older Pythons no longer work.
- Synlig → Slang for SystemVerilog. Set
USE_SLANG: truein your config if you previously relied on Synlig. - “The great
FP_removal.” Many floorplan variables lost theirFP_prefix. Check the Variable Migration Guide and rename anything the loader complains about. - Tilde paths are rejected. The CLI no longer accepts paths with ambiguous
~expansion. Use absolute paths or$HOME. - DRT antenna repair is on by default. If you had previously enabled it explicitly, remove the redundant flag.
MAGIC_NO_EXT_UNIQUE→MAGIC_EXT_UNIQUE(enum). Read the reference for the new values.readable_pathspreprocessor directive removed. Replace with plain paths.
The Migrating from OpenLane guide in the official docs is authoritative; use it as the checklist.
Help
LibreLane has a --help at every level:
librelane --help
librelane --list-flows
librelane --list-steps
OpenROAD (not LibreLane) has man pages accessible from inside its TCL shell at three levels:
- Top-level:
man openroad - Per-module / TCL command:
man clock_tree_synthesis - Error / warning codes:
man CTS-0001
Documentation:
- LibreLane: https://librelane.readthedocs.io/
- OpenROAD: https://openroad.readthedocs.io/
- Community chat: https://fossi-chat.org