How it is built
Architecture overview
A chip design flow turns a hardware description (RTL written in Verilog or VHDL) plus a timing and area budget into a layout that a fab can make. It is not one program but a chain of tools passing files: a netlist of gates, then a placement of every gate on a grid of rows, then a clock tree, then routing of every wire on the metal layers. Each stage solves an NP-hard problem heuristically, and each stage's output is only judged by the next: the one idea that makes the flow work is that timing is the shared objective, checked by a static timing analyser after every stage and fed back into it (nets with little slack get more weight in placement, cells on critical paths get resized). OpenROAD-flow-scripts is the open reference for the ASIC flow; Vivado is the closed reference for FPGAs, where "place and route" maps onto a fixed device instead of free silicon.
Parts:
- Verification front end — simulate and formally check the RTL before and after each transformation —
event-driven-logic-simulation(no page yet), Binary decision diagrams, CDCL SAT solving - Logic synthesis — RTL to a netlist of library cells —
and-inverter-graphs(no page yet),technology-mapping(no page yet), Binary decision diagrams - Timing engine — arrival and required times, slack, in every stage — Static timing analysis
- Floorplan and partitioning — die size, macro positions, power grid, hierarchy cuts — Graph partitioning,
simulated-annealing(no page yet) - Placement — where every cell sits —
analytical-placement(no page yet), Conjugate gradient - Clock tree — distributes the clock with bounded skew —
clock-tree-synthesis(no page yet),steiner-trees(no page yet) - Routing — connects pins on metal layers without violating design rules —
maze-routing(no page yet), A* search,steiner-trees(no page yet) - Geometry database — the shapes of cells, wires and vias, queried by every stage — R-tree, Interval tree
RTL (Verilog) ─► simulate ◄──── testbench
│
▼
logic synthesis ──► AIG ─► optimise ─► technology map (.lib) ─► gate netlist + SDC
│ (equivalence check: BDD / SAT miter) │
▼ ▼
floorplan ─► macro place ─► PDN ─► global place ─► resize/buffer ─► legalise ─► clock tree ─► global route ─► detailed route
▲ ▲ ▲ ▲ ▲ │
└──────────────── static timing analysis (slack, critical paths) ───────────┴───────────────┴───────────────┘
layout (DEF/GDSII) ─► DRC/LVS
The stage list above is the one OpenROAD-flow-scripts documents: synthesis, floorplan (macro placement, power distribution), placement (global, resizing and buffering, detailed), clock tree synthesis, routing (global, detailed), then finishing (fill, signoff timing, GDSII, design-rule and layout-versus-schematic checks).
How the parts fit together
Verification front end
Event-driven logic simulation (event-driven-logic-simulation, no page yet)
is how RTL is run against a testbench: signals change at timestamped events, only gates whose inputs changed are
re-evaluated, and delta cycles order zero-delay updates. Icarus Verilog is a pure event-driven simulator; Verilator
instead compiles synthesisable RTL to C++ and evaluates it cycle by cycle, which is much faster but restricts the
language subset. Simulation finds bugs; it cannot prove their absence. For that, two engines compete. Binary
decision diagrams give a canonical form of a Boolean function (Bryant 1986), so two
circuits are equal if their diagrams are the same node, but they blow up on multipliers and wide datapaths.
CDCL SAT solving takes the opposite trade: build a miter (both circuits fed the same inputs,
outputs XORed) and ask a solver whether an input can make it 1; learned clauses make this scale to circuits that
break BDDs, which is why modern equivalence checkers use SAT with structural hashing first.
Logic synthesis
Yosys turns RTL into a netlist, then calls ABC for combinational logic optimisation and mapping. The data structure
in the middle is the and-inverter-graphs (no page yet): every function is two-input ANDs with optional inversion
on edges, so structural hashing merges duplicate nodes for free and local rewriting is cheap. Mishchenko, Chatterjee
and Brayton's DAG-aware AIG rewriting (DAC 2006) is the reference for the restructuring that ABC performs on it.
technology-mapping (no page yet) then covers the AIG with cells from the Liberty library: enumerate small cuts at
each node, match each cut's function to a cell, and choose the cover that meets delay first and then minimises area.
The contract at the output is a gate-level netlist plus the constraints file (SDC) that the timing engine reads.
BDDs and SAT are reused here: BDDs for small-function manipulation and don't-care computation, SAT for
checking that a rewrite did not change the function.
Timing engine
Static timing analysis (STA) computes, for every pin, the latest arrival time and the earliest required time from cell delays (Liberty tables of delay against input slew and output load) and wire delays (from the parasitics), and reports slack. It is the only objective every stage shares. OpenROAD embeds OpenSTA (a library, not a separate process), so placement can ask "what are the slacks now?" in memory. The contract is incremental update: after a cell moves or is resized, only the affected cone is retimed, otherwise every optimisation step would pay for a full-chip analysis.
Floorplan and partitioning
A floorplan sets the die outline, the rows, the I/O pins and, for blocks with memories or IP, the macro positions.
Graph partitioning enters twice: to cluster a large netlist hierarchically before placing
macros, and to split a design across dies or FPGAs. OpenROAD's par module is TritonPart, a multilevel
(coarsen, partition, refine) hypergraph partitioner with timing-driven and fixed-vertex constraints (source: OpenROAD
src/par README). Macro placement (mpl, Hier-RTLMP) searches over macro positions with simulated-annealing
(no page yet): a random move of a macro, accepted if the cost drops or, with a shrinking probability, if it
rises; the cost mixes wirelength, overlap and boundary penalties.
Placement
Placement chooses a legal position for every cell so that wirelength, congestion and timing are good together.
analytical-placement (no page yet) models it as a smooth optimisation. Quadratic placers minimise squared
wirelength, which is a sparse linear system solved by Conjugate gradient. Modern placers
such as RePlAce (Cheng et al., TCAD 2019) and ePlace add a density force by treating cells as electric charges and
solve the nonlinear problem with Nesterov's method. OpenROAD's gpl module is RePlAce and, per its README, uses
Nesterov's method with timing-driven net weighting from a virtual repair of the design. The output of global
placement still has overlaps; the detailed placer (dpl) legalises it by moving cells to legal sites on rows with
minimum displacement. Between the two, the resizer buffers long nets and swaps gate sizes to fix slew and timing.
Clock tree
The clock is the largest net on the chip and must reach all sinks with small skew (arrival-time spread).
clock-tree-synthesis (no page yet) builds a balanced tree of buffers: cluster nearby sinks, route a symmetric
H-tree over the clusters, insert buffers to respect slew and capacitance. TritonCTS, OpenROAD's cts module, does
exactly this, with optional sink clustering that creates one level of subtrees before the H-tree is built (source:
src/cts README). The tree shape is a steiner-trees (no page yet) problem: the shortest tree to connect a set of
points when extra junction points are allowed, which is also how wirelength of every ordinary net is estimated.
Routing
Routing is split in two. Global routing divides the die into coarse tiles and assigns each net a path through tiles
so that no tile's wire capacity is exceeded; FastRoute (the basis of OpenROAD's grt) iterates rip-up and reroute to
remove congestion, with a configurable iteration limit. Each net first gets a Steiner-tree topology. Detailed
routing (drt, TritonRoute) then places the real wire segments and vias on tracks. Its building blocks per the
README are pin access analysis, track assignment, initial routing, search and repair, and a design-rule-check engine.
maze-routing (no page yet) is the search at the core: expand a wavefront from a pin on a grid graph of
tracks and vias with costs for length, layer change and violation, which is A* search with a good
heuristic. Detailed routers run it inside parallel windows and repair what remains in a search-and-repair loop.
Geometry database
All stages share one database of shapes (OpenDB in OpenROAD, which reads LEF/DEF). Two index structures matter. An R-tree answers "which shapes overlap this window?", needed by the DRC engine and by routers to find blockages; an Interval tree answers the 1-D version on a single track: which wire segments overlap this span, used when assigning segments to tracks and when checking spacing along a track. Both exist so a query costs roughly the output size, not the number of shapes on a chip with billions of them.
Data and control flow
One synthesis-to-layout run (OpenROAD-style):
- Read RTL, Liberty (
.lib), LEF and SDC. Yosys elaborates and maps; ABC optimises; the output is a netlist. - Floorplan: size the die from the netlist area and target utilisation, place pins, place macros, build the power grid.
- Global placement (with timing-driven weights), then resize and buffer, then legalise. STA after each.
- Build the clock tree; re-run timing with real clock arrival times; repair hold and setup violations.
- Global route, then detailed route; extract parasitics; sign-off timing; write GDSII; run DRC/LVS.
Time goes mostly to detailed routing and to placement of large designs. The flow is run many times with different settings, because each stage's outcome is statistical.
Timing closure loop: if slack is negative after routing, the failing paths feed back as higher net weights in placement, tighter synthesis constraints, or a bigger gate on the path. One run is rarely enough.
Scaling
- Design size: placement and routing grow roughly with the number of cells and nets. Levers: hierarchical partitioning, macro clustering, multi-threaded routers, windowed (tiled) routing.
- Runtime of timing: every optimisation needs fresh slacks. Lever: incremental STA, reuse of parasitics.
- Congestion: routing fails if placement ignored wires. Lever: routability-driven placement, cell padding, a larger die.
- Equivalence checking: BDDs blow up. Lever: SAT with structural hashing and cut-point decomposition.
- Many runs: design-space exploration is embarrassingly parallel; run variants of parameters on a cluster and keep the best, rather than trusting one run.
Failure modes
| Failure | Symptom | Cause | Fix |
|---|---|---|---|
| Timing not closing | negative slack after routing | optimistic wire models in synthesis or placement | timing-driven placement, resize, loosen frequency, re-run with real parasitics |
| Routing congestion | router cannot finish, many DRC errors | placement packed cells where wires cannot pass | lower utilisation, routability-driven placement, change macro placement |
| Clock skew | hold violations | unbalanced tree, uneven sink density | clustered CTS, delay buffers, useful skew only if intended |
| Overlaps after global placement | illegal cell positions | global placement is continuous | legalise, then re-time |
| Equivalence check blows up | solver runs out of memory | BDDs on multipliers, no structural similarity | SAT miters, hierarchical and cut-point checking |
| Simulation/synthesis mismatch | gate-level sim differs from RTL sim | blocking vs non-blocking assignments, X-handling, latch inferred | lint, formal equivalence of netlist against RTL |
| Non-deterministic results | different layout per run | threading, floating point, seed | fixed seeds, deterministic mode (gpl documents deterministic output across compilers and OSes) |
Real implementations
| name | what it is | repo | licence | notes |
|---|---|---|---|---|
| OpenROAD | the placement, CTS, routing, timing database as one application | The-OpenROAD-Project/OpenROAD | BSD-3-Clause | modules gpl, dpl, cts, grt, drt, rsz, par, mpl, ppl |
| OpenROAD-flow-scripts | scripted RTL-to-GDSII flow around Yosys and OpenROAD | The-OpenROAD-Project/OpenROAD-flow-scripts | see repo | the flow in the diagram above |
| Yosys | RTL synthesis framework, drives ABC | YosysHQ/yosys | ISC | |
| ABC | logic synthesis and verification, AIG-based | berkeley-abc/abc | UC Regents licence (copyright.txt) | |
| OpenSTA | the timing engine used inside OpenROAD | The-OpenROAD-Project/OpenSTA | GPL-3.0 | |
| OpenLane | another flow wrapper around the same tools | The-OpenROAD-Project/OpenLane | Apache-2.0 | |
| Icarus Verilog | event-driven Verilog simulator | steveicarus/iverilog | GPL-2.0 | |
| Verilator | RTL to C++ cycle-based simulator | verilator/verilator | LGPL-3.0 | |
| nextpnr | place and route for FPGAs | YosysHQ/nextpnr | ISC | the FPGA analogue |
| Vivado | AMD FPGA flow: synthesis, then implementation (place, route) | — | closed | see UG892 |
The alternative: FPGA flows replace layout with mapping onto a fixed fabric: LUT mapping instead of standard-cell mapping, placement on legal sites, and routing over a fixed interconnect graph (nextpnr, Vivado). Pick the ASIC flow when you control the silicon and the budget is power and area, the FPGA flow when the device is fixed and the loop must take minutes to hours, not days.
Sources
- AMD, Vivado Design Suite User Guide: Design Flows Overview (UG892): docs.
- OpenROAD documentation and module READMEs: docs,
repo (flow stages in README,
src/gpl,src/cts,src/grt,src/drt,src/par,src/mpl,src/dpl). - T. Ajayi et al., Toward an Open-Source Digital Flow: First Learnings from the OpenROAD Project, DAC 2019: DOI 10.1145/3316781.3326334.
- C.-K. Cheng et al., RePlAce: Advancing Solution Quality and Routability Validation in Global Placement, IEEE TCAD 2019: DOI 10.1109/TCAD.2018.2859220.
- A. Mishchenko, S. Chatterjee, R. Brayton, DAG-aware AIG rewriting: a fresh look at combinational logic synthesis, DAC 2006: DOI 10.1145/1146909.1147048.
- R. Bryant, Graph-Based Algorithms for Boolean Function Manipulation, IEEE Trans. Computers 1986: PDF.
- Yosys documentation: docs; ABC: repo.