Your country

Tools that support it use your country for local currency, number formats, units and paper size. Your choice is saved only in this browser.

Type a name or a two-letter code. Use the up and down arrow keys to move through the countries, Enter to choose one and Escape to close.

Digital Design & Verification (Verilog, SystemVerilog, VLSI)  Module 11 – Lint, synthesis, timing, power and test

Logic synthesis with Yosys

Run a Yosys synthesis script pass by pass on an 8-bit counter, see what proc, opt, techmap and abc each do to it, and read the cell statistics.

  • Intermediate
  • 15 minutes
  • Examples run with Python 3.14.8 and Pyodide 314.0.7
  • By MySmartCoPilot
Free core, Pro depth: 6 of 15 minutes free
Free: Synthesis builds cells from always blocks, one pass at a time · Cell statistics show what each pass did. With a pass: 2 in-depth parts and 3 interview answers, about 9 minutes.

What you will learn

  • Run a Yosys synthesis script and explain each major pass
  • Map one design to generic gates, FPGA LUTs and standard cells
  • Read cell statistics and estimate area
  • Recognise synthesis messages that point to RTL problems

Before you start

Synthesis turned this lesson’s 13-line counter into 22 gates and flip-flops, and the design passed through 101 cells on the way there. logic synthesis: The step that turns RTL into a netlist of a target's cells: standard cells for a chip, or look-up tables and flip-flops for an FPGA. More in “How chips are designed and verified” with Yosys is a script of passes, each one a command whose result you can count, so you can watch what every pass does to your design and notice when one does something you did not mean.

Here you run the main passes one at a time on an 8-bit counter, read the cell statistics after each, and check the result against Yosys’s whole default script. Then the same counter goes to three targets, with the area each costs, and two short designs show the synthesis messages that point to bugs in the RTL.

Synthesis builds cells from always blocks, one pass at a time

counter.sv is an 8-bit counter with a synchronous reset and an enable, written as one always_ff block. Yosys reads it into RTLIL: Yosys's internal form of a design: modules made of cells, wires and processes. Every Yosys pass reads RTLIL and writes it back, so a script is a chain of rewrites of one design., its own form of a design, and every pass after that reads RTLIL and rewrites it. Step through the passes of a typical script, with the number of cells the counter has after each:

Interactive · stage by stage The 8-bit counter through the main passes of a synthesis script Step through one script. Each stage is a pass you can run on its own and count with stat.
The 8-bit counter through the main passes of a synthesis script, step 8 of 8. Showing read_verilog -sv, hierarchy -top, proc, opt, fsm and memory, techmap, abc, stat. In focus: stat.read_verilog -svRTL into RTLILhierarchy -toppick the top moduleprocprocesses to cells: 4optmerge and simplify: 2fsm and memoryfind state machinestechmapcells to gates: 101abcoptimise the gates: 22statcount what is left

The drawing shows the whole scene; its 8 steps are listed below.

Every step as text
  1. Read. read_verilog -sv parses counter.sv and turns it into RTLIL, Yosys's own form of a design. The always_ff block is still a process, a list of assignments, not yet any hardware.
  2. The top module. hierarchy -top counter makes counter the top of the design and checks that every module it uses is there. Modules nobody uses are dropped.
  3. Processes become cells. proc turns the always_ff block into four coarse cells, a $dff for the eight flip-flops, a $mux for the enable, a $mux for the reset, and an $add for q plus 1.
  4. Simplify. opt folds both multiplexers into the flip-flop, which becomes one $sdffe, a flip-flop with a synchronous reset and an enable. Two cells are left.
  5. Find structures. fsm looks for state machines to re-encode and memory for arrays to map to RAM. The counter has neither, so nothing changes here.
  6. Gates. techmap replaces each coarse cell with gates from Yosys's own gate library. The 8-bit adder alone becomes dozens of AND, OR and XOR gates, 101 cells in all.
  7. Optimise. abc, the logic optimiser that Yosys runs as a pass, rewrites the gates into fewer of them. The counter ends with 22 cells, 8 of them flip-flops.
  8. Count. stat lists the cells by type after any pass. Reading it after each step is how you see what each pass did, and spot a pass that did something you did not mean.

Two of those passes do the work that a person would call synthesis. proc turns processes, the always blocks, into coarse cells: a $dff for the eight flip-flops, a $mux for the enable and one for the reset, an $add for the increment. techmap later replaces each coarse cell with gates from Yosys’s own gate library, the step called technology mapping: The step of synthesis that replaces generic cells with the cells of a target: gates of a library, look-up tables and flip-flops of an FPGA, or the standard cells of a chip process.. Between and after them, opt merges and removes cells, and abc rewrites the gates into fewer ones.

Yosys’s built-in reader takes Verilog-2005 and a part of SystemVerilog with read_verilog -sv; the build used here also has read_slang, a front end built on the slang compiler, which reads far more of SystemVerilog, as the lesson on structs and interfaces showed on an interface design.

Checkpoint

Check: What the main passes do

  1. Question 1 of 2 Which pass turns the counter's always_ff block into a $dff, two $mux and an $add?

    Choose one answer.

    Show the answer: Question 1 of 2

    Answer: proc

    After proc the counter was 4 coarse cells; every pass after it works on cells, not processes.

  2. Question 2 of 2 After proc the counter had 4 cells; after opt it had 2. What did opt do?

    Choose one answer.

    Show the answer: Question 2 of 2

    Answer: It folded the reset and enable multiplexers into the flip-flop, which became one $sdffe

    opt simplifies and merges coarse cells; here it recognised the reset and enable around the flip-flop.

Cell statistics show what each pass did

stat counts the cells of a design by type, and tee -q -o writes its report to a file. passes.ys runs the four passes by hand and keeps a report after each; the last command runs synth, Yosys’s default script, on the same RTL:

The counter after proc, opt, techmap and abc

hdl/counter.sv

// A W-bit counter with a synchronous reset and an enable: the design that every target synthesises below.
module counter #(
  parameter int W = 8
) (
  input  logic         clk,
  input  logic         rst,      // synchronous, active high
  input  logic         en,
  output logic [W-1:0] q
);
  always_ff @(posedge clk)
    if (rst)     q <= '0;
    else if (en) q <= q + 1'b1;
endmodule

hdl/passes.ys

# The main passes of a synthesis script, one at a time, with the cell statistics after each.
read_verilog -sv counter.sv
hierarchy -check -top counter
proc
tee -q -o proc.txt stat
opt
tee -q -o opt.txt stat
techmap
tee -q -o techmap.txt stat
opt
abc
opt_clean
tee -q -o abc.txt stat

Commands · hdl/passes_session.py

from session import run

# passes.ys runs proc, opt, techmap and abc by hand on the 8-bit counter and keeps the statistics after each; the
# grep shows the cell counts. Then synth, the whole default script, on the same counter.
run("""
yosys -q passes.ys
grep -E "cells|[$]" proc.txt opt.txt techmap.txt abc.txt
yosys -q -p "read_verilog -sv counter.sv; synth -top counter; tee -q -o synth.txt stat"
grep -E "cells|[$]" synth.txt
""")

Output

# Yosys 0.69
$ yosys -q passes.ys
$ grep -E "cells|[$]" proc.txt opt.txt techmap.txt abc.txt
proc.txt:        4 cells
proc.txt:        1   $add
proc.txt:        1   $dff
proc.txt:        2   $mux
opt.txt:        2 cells
opt.txt:        1   $add
opt.txt:        1   $sdffe
techmap.txt:      101 cells
techmap.txt:       32   $_AND_
techmap.txt:        8   $_MUX_
techmap.txt:        8   $_NOT_
techmap.txt:       20   $_OR_
techmap.txt:        8   $_SDFFE_PP0P_
techmap.txt:       25   $_XOR_
abc.txt:       22 cells
abc.txt:        5   $_AND_
abc.txt:        1   $_NAND_
abc.txt:        1   $_NOT_
abc.txt:        8   $_SDFFE_PP0P_
abc.txt:        1   $_XNOR_
abc.txt:        6   $_XOR_
$ yosys -q -p "read_verilog -sv counter.sv; synth -top counter; tee -q -o synth.txt stat"
$ grep -E "cells|[$]" synth.txt
       22 cells
        5   $_AND_
        1   $_NAND_
        1   $_NOT_
        8   $_SDFFE_PP0P_
        1   $_XNOR_
        6   $_XOR_

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 passes_session.py

Read the four reports in order. After proc the counter is 4 cells. After opt it is 2: the two multiplexers went into the flip-flop, now a $sdffe, a flip-flop with a synchronous reset and an enable. techmap turned those 2 cells into 101, and abc brought them down to 22, of which 8 are the flip-flops, as $_SDFFE_PP0P_. Yosys’s cell manual spells that name out: a rising clock edge, an active-high reset that loads 0, and an active-high enable. synth ended at the same 22 cells as the script by hand.

A report like this is a check on the RTL. Eight flip-flops for an 8-bit counter is right; a $_DLATCH_ cell, Yosys’s latch, in a design that should have none is a bug; and a module whose report lists no cells at all has lost its logic.

Yosys 0.69 removed four options

The 0.69 release removed -retime, -noabc9, -abc2 and -abc from its synthesis passes, so older scripts and tutorials that pass them now stop with an error. This track pins Yosys 0.69.

The same RTL can go to three kinds of target, and each is a line of the script:

  • Generic gates: synth alone maps to Yosys’s own gates, a netlist for simulation and quick comparisons.
  • FPGA cells: synth_ice40 maps to an iCE40’s look-up tables, carry cells and flip-flops.
  • Standard cells: dfflibmap and abc read a Liberty file: A text file, in the Liberty format, that describes the cells of a standard-cell library: each cell's function, pins, area, timing and power, at one corner of voltage and temperature. and map to the standard cell: A gate, flip-flop or other small circuit drawn once by a library's makers to a fixed height, so that place and route can line cells up in rows. A chip's logic is built from thousands or millions of them. of a real chip library.

Checkpoint

Check: Reading cell statistics

  1. Question 1 of 2 How many cells did the counter have after abc, the same number that synth reached?

    Type a number.

    Show the answer: Question 1 of 2

    Answer: 22 cells

    techmap made 101 gates, and abc rewrote them into 22 cells, 8 of them the $_SDFFE_PP0P_ flip-flops and 14 gates.

  2. Question 2 of 2 A purely combinational decoder's stat report lists two $_DLATCH_P_ cells among its gates. What does that tell you?

    Choose one answer.

    Show the answer: Question 2 of 2

    Answer: Some path of its combinational block assigns nothing, so synthesis built latches to hold the old value

    The report checks the RTL. Unexpected latch cells, missing flip-flops or no cells at all each point to a bug.

One counter on three targets, with the area each one costs Pro: opens with a Pro, Premium or Ultimate pass

The same 13 lines become different hardware on each target, and only one of the three reports has a real area. This part maps the counter three ways, reads where its 280.27 µm² go, and measures what sharing one adder saves.

In this part:

  • Generic gates, iCE40 cells and SKY130 cells, measured on one counter
  • Where 280.27 µm² goes, worked from the Liberty file
  • Drive strengths: what the _1 at the end of every cell buys
  • A list of cells the mapper must not use
  • Sharing one adder, measured on all three targets

2 runnable examples (Commands, alu8.sv, alu8_shared.sv, sky130.ys) · about 5 minutes

Opening this part with your pass…

This part opens with any MySmartCoPilot pass.

  • Pro pass · 1 week₹79$2.99
  • 30 days₹179$5.99
  • 1 year₹1,699$45

One payment; a pass never renews. The price shown is the total you pay: no fees or charges are added at checkout.

It also opens every other in-depth part in Learn and every Pro tool. Sales are final, except where the law gives you a right to withdraw, for example in the EU and the UK (refund policy).

Synthesis messages that point to RTL bugs, reproduced Pro: opens with a Pro, Premium or Ultimate pass

Synthesis rarely stops on a bug; it builds what the code says and writes a line in its log. This part reproduces two such lines, a latch and an undriven wire that took a whole design with it, and lists the messages worth reading in every log.

In this part:

  • A latch from always @*, reported only as a warning
  • An undriven wire that took a whole MAC with it
  • Five messages worth reading in every log
  • Turning the log into a check that a script can fail

1 runnable example (Commands, dec_latch.v, mac_typo.sv) · about 4 minutes

Opening this part with your pass…Pro part. It opens with the same pass as the part above.

Practise: summarise a stat report

The exercise turns a stat report into the numbers this lesson reads from one: cells, flip-flops, latches and the rest. Its sample tests are the counter’s reports from the passes above:

Exercise · Easy · Python

Summarise a Yosys stat report

Yosys's stat prints a design's cells by type, under a line with their total. After proc, this lesson's counter printed, among its other lines, 4 cells, then 1 $add, 1 $dff and 2 $mux, each indented by spaces.

Write summary(report). It takes the text of one such report, for one module, and returns a dictionary with four counts:

  • "cells": the total;
  • "flip_flops": the cells whose type contains dff in any case, such as $dff, $sdffe or $_SDFFE_PP0P_;
  • "latches": the cells whose type contains dlatch in any case;
  • "other": the rest.

A cell line is a count followed by a type that starts with $ or a letter, and every other line (wires, wire bits, ports, the module's name) is ignored. A report with no cells line, which is what a module that lost all its logic prints, gives four zeros. If the cell lines do not add up to the total, raise ValueError.

Starter code · stat_summary.py

def summary(report):
    """Cells, flip-flops, latches and other cells of one module's stat report."""
    return {"cells": 0, "flip_flops": 0, "latches": 0, "other": 0}
The sample tests · test_stat_summary.py
from stat_summary import summary

PROC = """=== counter ===

        6 wires
       28 wire bits
        4 cells
        1   $add
        1   $dff
        2   $mux
"""

ABC = """=== counter ===
        4 ports
       11 port bits
       22 cells
        5   $_AND_
        1   $_NAND_
        1   $_NOT_
        8   $_SDFFE_PP0P_
        1   $_XNOR_
        6   $_XOR_
"""


def test_after_proc():
    """counts the counter's report after proc: one flip-flop cell and three others"""
    assert summary(PROC) == {"cells": 4, "flip_flops": 1, "latches": 0, "other": 3}


def test_after_abc():
    """counts the eight $_SDFFE_PP0P_ cells as flip-flops"""
    assert summary(ABC) == {"cells": 22, "flip_flops": 8, "latches": 0, "other": 14}


def test_latches():
    """counts $_DLATCH_ cells as latches, not flip-flops"""
    report = "        5 cells\n        2   $_DLATCH_P_\n        3   $_AND_\n"
    assert summary(report) == {"cells": 5, "flip_flops": 0, "latches": 2, "other": 3}


def test_no_cells():
    """gives zeros for a module whose report has wires and ports but no cells"""
    report = "=== mac ===\n        6 wires\n        5 ports\n"
    assert summary(report) == {"cells": 0, "flip_flops": 0, "latches": 0, "other": 0}


def test_total_must_match():
    """refuses a report whose cell lines do not add up to its total"""
    try:
        summary("        3 cells\n        1   $add\n")
    except ValueError:
        return
    raise AssertionError("no ValueError for a total of 3 with 1 cell listed")
A hint

Split each line into words. A line of two words whose first word is a number is either the total (second word cells) or one cell type; match the type with type.lower() and in.

The sample tests run on this device, in your browser (Pyodide): nothing is sent to mysmartcopilot.com. The first run downloads Python (about 13.5 MB), which is kept for the next runs. A check in your browser is feedback for you, not proof that the code is right for every input.

Then test yourself on the passes and the statistics. The questions start where your answers have been weakest so far:

Practice that adapts to you

Practise this lesson

6 questions about 4 ideas of this lesson. Each answer is explained at once, and what you get right is kept in this browser.

  1. Question 1 of 6 What does techmap do in a Yosys script?

    Choose one answer.

    Show the answer: Question 1 of 6

    Answer: It replaces coarse cells such as $add and $sdffe with gates from Yosys's own gate library

    techmap is the technology mapping step to Yosys's own gates; abc then rewrites them.

  2. Question 2 of 6 A script runs techmap before proc. What goes wrong?

    Choose one answer.

    Show the answer: Question 2 of 6

    Answer: techmap finds processes, not cells, so the always blocks are not mapped

    The order in synth is no accident: proc, then opt, then techmap, then abc.

  3. Question 3 of 6 An old tutorial runs synth -top top -retime and fails on Yosys 0.69. What do you conclude?

    Choose one answer.

    Show the answer: Question 3 of 6

    Answer: The option was removed in 0.69, so the script must drop it or use another way to retime

    Read the changelog of the pinned version when an older script fails on an option.

  4. Question 4 of 6 What does the cell name $_SDFFE_PP0P_ say?

    Choose one answer.

    Show the answer: Question 4 of 6

    Answer: A flip-flop on the rising clock edge with an active-high synchronous reset to 0 and an active-high enable

    Yosys's gate-level cell names spell out their behaviour, so a stat report can be read without the netlist.

  5. Question 5 of 6 A 16-bit register on the rising clock edge, with an active-high synchronous reset to 0 and an active-high enable, is synthesised with synth. How many $_SDFFE_PP0P_ cells do you expect in its stat report?

    Type a number.

    Show the answer: Question 5 of 6

    Answer: 16 cells

    Fine-grained flip-flop cells are one bit each, as the 8 of the 8-bit counter were.

  6. Question 6 of 6 After a small change to a 32-bit accumulator, its stat report drops from 400 cells to 40 and synth ends with status 0. What do you conclude first?

    Choose one answer.

    Show the answer: Question 6 of 6

    Answer: Logic has most likely been lost, so the change needs checking before anyone uses the netlist

    Read stat as a check on the RTL: the flip-flops you expect, no latch you did not want, and no module far smaller than its RTL, of which a module with no cells at all is the extreme.

Interview questions

What does Yosys’s proc pass do?

It turns processes, the always blocks of the RTL, into cells. Each clocked block becomes flip-flop cells such as $dff, with multiplexers for its if and case branches, and each combinational block becomes multiplexers and logic; a variable that some path leaves unassigned becomes a latch. In this lesson’s counter, proc made 4 cells: a $dff, two $mux and an $add. Later passes then merge and map those cells.

Three harder questions follow, on a design that synthesised to nothing, an area over budget and comparing FPGA and chip results:

  1. Fresher to mid

    You synthesise a 20-bit multiply-accumulate unit and the statistics list no cells at all, while synthesis ends with status 0 and prints 16 warnings. Walk through what most likely happened, how you would confirm it, and how your flow should catch it before a netlist leaves synthesis.

    Model answer, Pro. Model answers open with any pass; prices are in the notice on this page. First step and follow-ups

  2. Mid to senior

    A block synthesised to SKY130 standard cells comes out 10 % over its area budget. How do you find where the area goes, what would you try first in the RTL, and how do you know a change helped?

    Model answer, Pro. First step and follow-ups

  3. Fresher to mid

    The same 8-bit counter synthesises to 22 of Yosys's generic cells, and to other counts on an iCE40 and in a standard-cell library. A manager asks which number to quote for how big the design is. What do you answer, and how would you compare an FPGA cost with a chip cost?

    Model answer, Pro. First step and follow-ups

Flashcards · 7 cards

Recall it, then check

Say the answer to yourself before you look: recalling it is what makes it stick.

  1. What do the Yosys passes proc, opt, techmap and abc do?

    proc turns always blocks into coarse cells; opt merges and removes cells; techmap replaces coarse cells with gates from Yosys's own library; abc rewrites the gates into fewer ones.

  2. How did the 8-bit counter's cell count change pass by pass?

    4 cells after proc, 2 after opt, 101 after techmap and 22 after abc, 8 of them flip-flops. The default synth script ended at the same 22.

  3. What did opt do with the counter's two multiplexers?

    It folded them into the flip-flop, which became a $sdffe, a flip-flop with a synchronous reset and an enable.

  4. What does the Yosys cell name $_SDFFE_PP0P_ spell out?

    A rising clock edge, an active-high synchronous reset that loads 0, and an active-high enable.

  5. Which stat findings point to an RTL problem?

    A $_DLATCH_ cell in a design that should have no latch, a flip-flop count other than you expect, and a module whose report lists no cells at all, which has lost its logic.

  6. What happens to an older Yosys script that passes -retime, -noabc9, -abc2 or -abc?

    It stops with an error: the 0.69 release removed those options from its synthesis passes.

  7. How does one RTL file go to three kinds of target in Yosys?

    synth maps to Yosys's generic gates; synth_ice40 maps to an iCE40's LUTs, carry cells and flip-flops; dfflibmap and abc read a Liberty file and map to a chip library's standard cells.

Key takeaways

  • Yosys synthesises with a script of passes over RTLIL: proc turns always blocks into cells, opt merges and removes cells, techmap maps them to gates and abc rewrites the gates.
  • Reading stat after each pass shows what it did: the counter went from 4 cells to 2, then 101, then 22.
  • The cell statistics are a check on the RTL: the flip-flops you expect, no latch cells you did not want, and no module with no cells at all.

Terms in this lesson

Liberty file
A text file, in the Liberty format, that describes the cells of a standard-cell library: each cell's function, pins, area, timing and power, at one corner of voltage and temperature.
RTLIL
Yosys's internal form of a design: modules made of cells, wires and processes. Every Yosys pass reads RTLIL and writes it back, so a script is a chain of rewrites of one design.
standard cell
A gate, flip-flop or other small circuit drawn once by a library's makers to a fixed height, so that place and route can line cells up in rows. A chip's logic is built from thousands or millions of them.
technology mapping
The step of synthesis that replaces generic cells with the cells of a target: gates of a library, look-up tables and flip-flops of an FPGA, or the standard cells of a chip process.

References

Report a problem with this lesson

Quick answers and tool search

Type to search tools or to get a quick answer, for example 18% of 2500. Use the up and down arrow keys to move through the results, Enter to choose, and Escape to close.