yosys Documentation

Yosys Open SYnthesis Suite

4,826 stars C++ C++ 103 files ยท ~127,073 tokens
RAW Doc

Technical Documentation: YosysHQ/yosys

โ„น๏ธ Provenance: Multi-Tier Ingestion ยท CodeWiki Reference

Overview (`README.md`)

yosys โ€“ Yosys Open SYnthesis Suite

This is a framework for RTL synthesis tools. It currently has
extensive Verilog-2005 support and provides a basic set of
synthesis algorithms for various application domains.

Yosys is using sv-elab and slang libraries to provide comprehensive SystemVerilog support.
It supports an (informally defined) synthesizable subset of SystemVerilog in version IEEE 1800-2017 or IEEE 1800-2023.

Yosys can be adapted to perform any synthesis job by combining
the existing passes (algorithms) using synthesis scripts and
adding additional passes as needed by extending the yosys C++
code base.

Yosys is free software licensed under the ISC license (a GPL
compatible license that is similar in terms to the MIT license
or the 2-clause BSD license).

Third-party software distributed alongside this software
is licensed under compatible licenses.
Please refer to abc and libs subdirectories for their license terms.

Web Site and Other Resources

More information and documentation can be found on the Yosys web site:

If you have any Yosys-related questions, please post them on the Discourse group:

Documentation from this repository is automatically built and available on Read
the Docs:

Users interested in formal verification might want to use the formal
verification front-end for Yosys, SBY:

The Yosys blog has news and articles from users:

Installation

Yosys is part of the Tabby CAD Suite and the OSS CAD Suite! The easiest way to use yosys is to install the binary software suite, which contains all required dependencies and related tools.

Make sure to get a Tabby CAD Suite Evaluation License if you need features such as industry-grade SystemVerilog and VHDL parsers!

For more information about the difference between Tabby CAD Suite and the OSS CAD Suite, please visit https://www.yosyshq.com/tabby-cad-datasheet

Many Linux distributions also provide Yosys binaries, some more up to date than others. Check with your package manager!

Building from Source

TL;DR

The following libraries are required, this command will install them on Ubuntu Linux 22.04 LTS based systems:

$ sudo apt-get install gawk git make python3 lld bison clang flex
libffi-dev libfl-dev libreadline-dev pkg-config tcl-dev zlib1g-dev
graphviz xdot

This sequence of commands will build Yosys from source using the default preset:

text
$ git clone --recurse-submodules https://github.com/YosysHQ/yosys.git
$ cd yosys
$ cmake --preset default
$ cmake --build build --parallel $(nproc)

For release builds, substitute the cmake commands with these:

text
$ cmake --preset release
$ cmake --build build-rel --config Release --parallel $(nproc)

To run tests, run the following:

$ export BUILD_DIR=$(realpath build-rel) && make -C tests -j"$(nproc)" vanilla-test

Detailed instructions

For more details, and instructions for other platforms, check building from
source
and running the tests
on Read the Docs.

Getting Started

Yosys can be used with the interactive command shell, with
synthesis scripts or with command line arguments. Let's perform
a simple synthesis job using the interactive command shell:

text
$ ./build/yosys
yosys>

the command help can be used to print a list of all available
commands and help <command> to print details on the specified command:

text
yosys> help help

reading and elaborating the design using the Verilog frontend:

text
yosys> read -sv tests/simple/fiedler-cooley.v
yosys> hierarchy -top up3down5

writing the design to the console in the RTLIL format used by Yosys
internally:

text
yosys> write_rtlil

convert processes (always blocks) to netlist elements and perform
some simple optimizations:

text
yosys> proc; opt

display design netlist using xdot:

text
yosys> show

the same thing using gv as postscript viewer:

text
yosys> show -format ps -viewer gv

translating netlist to gate logic and perform some simple optimizations:

text
yosys> techmap; opt

write design netlist to a new Verilog file:

text
yosys> write_verilog synth.v

or using a simple synthesis script:

text
$ cat synth.ys
read -sv tests/simple/fiedler-cooley.v
hierarchy -top up3down5
proc; opt; techmap; opt
write_verilog synth.v

$ ./yosys synth.ys

If ABC is enabled in the Yosys build configuration and a cell library is given
in the liberty file mycells.lib, the following synthesis script will
synthesize for the given cell library:

text
# read design
read -sv tests/simple/fiedler-cooley.v
hierarchy -top up3down5

# the high-level stuff
proc; fsm; opt; memory; opt

# mapping to internal cell library
techmap; opt

# mapping flip-flops to mycells.lib
dfflibmap -liberty mycells.lib

# mapping logic to mycells.lib
abc -liberty mycells.lib

# cleanup
clean

If you do not have a liberty file but want to test this synthesis script,
you can use the file examples/cmos/cmos_cells.lib from the yosys sources
as simple example.

Liberty file downloads for and information about free and open ASIC standard
cell libraries can be found here:

The command synth provides a good default synthesis script (see
help synth):

text
read -sv tests/simple/fiedler-cooley.v
synth -top up3down5

# mapping to target cells
dfflibmap -liberty mycells.lib
abc -liberty mycells.lib
clean

The command prep provides a good default word-level synthesis script, as
used in SMT-based formal verification.

Additional information

The read_verilog command, used by default when calling read with Verilog
source input, does not perform syntax checking. You should instead lint your
source with another tool such as
Verilator first, e.g. by calling
verilator --lint-only.

Building the documentation

Note that there is no need to build the manual if you just want to read it.
Simply visit https://yosys.readthedocs.io/en/latest/ instead.
If you're offline, you can read the sources, replacing .../en/latest
with docs/source.

In addition to those packages listed above for building Yosys from source, the
following are used for building the website:

text
$ sudo apt install pdf2svg faketime

Or for MacOS, using homebrew:

text
$ brew install pdf2svg libfaketime

PDFLaTeX, included with most LaTeX distributions, is also needed during the
build process for the website. Or, run the following:

text
$ sudo apt install texlive-latex-base texlive-latex-extra latexmk

Or for MacOS, using homebrew:

text
$ brew install basictex
$ sudo tlmgr update --self
$ sudo tlmgr install collection-latexextra latexmk tex-gyre

The Python package, Sphinx, is needed along with those listed in
docs/source/requirements.txt:

text
$ pip install -U sphinx -r docs/source/requirements.txt

DOCS (e.g.)

text
$ cmake --build build --target docs-html --parallel

This will build/rebuild yosys as necessary before generating the website
documentation from the yosys help commands. To build for pdf instead of html,
use the docs-latexpdf target.


Overview (`passes/pmgen/README.md`)

Pattern Matcher Generator

The program pmgen.py reads a .pmg (Pattern Matcher Generator) file and
writes a header-only C++ library that implements that pattern matcher.

The "patterns" in this context are subgraphs in a Yosys RTLIL netlist.

The algorithm used in the generated pattern matcher is a simple recursive
search with backtracking. It is left to the author of the .pmg file to
determine an efficient cell order for the search that allows for maximum
use of indices and early backtracking.

API of Generated Matcher

When pmgen.py reads a foobar.pmg file, it writes foobar_pm.h containing
a class foobar_pm. That class is instantiated with an RTLIL module and a
list of cells from that module:

text
foobar_pm pm(module, module->selected_cells());

The caller must make sure that none of the cells in the 2nd argument are
deleted for as long as the pattern matcher instance is used.

At any time it is possible to disable cells, preventing them from showing
up in any future matches:

text
pm.blacklist(some_cell);

The .run_(callback_function) method searches for all matches
for the pattern`` and calls the callback function for each found
match:

text
pm.run_foobar([&](){
    log("found matching 'foo' cell: %s\n", pm.st.foo);
    log("          with 'bar' cell: %s\n", pm.st.bar);
});

The .pmg file declares matcher state variables that are accessible via the
.st_.<state_name> members. (The .st_ member is
of type foobar_pm::state__t.)

Similarly the .pmg file declares user data variables that become members of
.ud_, a struct of type foobar_pm::udata__t.

There are three versions of the run_() method: Without callback,
callback without arguments, and callback with reference to pm. All versions
of the run_() method return the number of found matches.

The .pmg File Format

The .pmg file format is a simple line-based file format. For the most part
lines consist of whitespace-separated tokens.

Lines in .pmg files starting with // are comments.

Declaring a pattern

A .pmg file contains one or more patterns. Each pattern starts with a line
with the pattern keyword followed by the name of the pattern.

Declaring state variables

One or more state variables can be declared using the state statement,
followed by a C++ type in angle brackets, followed by a whitespace separated
list of variable names. For example:

text
state  flag1 flag2 happy big
state <SigSpec> sigA sigB sigY

State variables are automatically managed by the generated backtracking algorithm
and saved and restored as needed.

They are automatically initialized to the default constructed value of their type
when .run_(callback_function) is called.

Declaring udata variables

Udata (user-data) variables can be used for example to configure the matcher or
the callback function used to perform actions on found matches.

There is no automatic management of udata variables. For this reason it is
recommended that the user-supplied matcher code treats them as read-only
variables.

They are declared like state variables, just using the udata statement:

text
udata  min_data_width max_data_width
udata  data_port_name

They are automatically initialized to the default constructed value of their type
when the pattern matcher object is constructed.

Embedded C++ code

Many statements in a .pmg file contain C++ code. However, there are some
slight additions to regular C++/Yosys/RTLIL code that make it a bit easier to
write matchers:

  • Identifiers starting with a dollar sign or backslash are automatically
    converted to special IdString variables that are initialized when the
    matcher object is constructed.

  • The port(<cell>, ) function is a handy alias for
    sigmap(<cell>->getPort()).

  • Similarly param(<cell>, ) looks up a parameter on a cell.

  • The function nusers(<sigspec>) returns the number of different cells
    connected to any of the given signal bits, plus one if any of the signal
    bits is also a primary input or primary output.

  • In code..endcode blocks there exist accept, reject, branch,
    finish, and subpattern statements.

  • In index statements there is a special === operator for the index
    lookup.

Matching cells

Cells are matched using match..endmatch blocks. For example:

text
match mul
    if ff
    select mul->type == $mul
    select nusers(port(mul, \Y) == 2
    index <SigSpec> port(mul, \Y) === port(ff, \D)
    filter some_weird_function(mul) < other_weird_function(ff)
    optional
endmatch

A match block starts with match <statevar> and implicitly generates
a state variable <statevar> of type RTLIL::Cell*.

All statements in the match block are optional. (An empty match block
would simply match each and every cell in the module.)

The if <expression> statement makes the match block conditional. If
<expression> evaluates to false then the match block will be ignored
and the corresponding state variable is set to nullptr. In our example
we only try to match the mul cell if the ff state variable points
to a cell. (Presumably ff is provided by a prior match block.)

The select lines are evaluated once for each cell when the matcher is
initialized. A match block will only consider cells for which all select
expressions evaluated to true. Note that the state variable corresponding to
the match (in the example mul) is the only state variable that may be used
in select lines.

Index lines are using the index <type> expr1 === expr2 syntax. expr1 is
evaluated during matcher initialization and the same restrictions apply as for
select expressions. expr2 is evaluated when the match is calculated. It is a
function of any state variables assigned to by previous blocks. Both expression
are converted to the given type and compared for equality. Only cells for which
all index statements in the block pass are considered by the match.

Note that select and index are fast operations. Thus select and index
should be used whenever possible to create efficient matchers.

Finally, filter <expression> narrows down the remaining list of cells. For
performance reasons filter statements should only be used for things that
can't be done using select and index.

The optional statement marks optional matches. That is, the matcher will also
explore the case where mul is set to nullptr. Without the optional
statement a match may only be assigned nullptr when one of the if expressions
evaluates to false.

The semioptional statement marks matches that must match if at least one
matching cell exists, but if no matching cell exists it is set to nullptr.

Slices and choices

Cell matches can contain "slices" and "choices". Slices can be used to
create matches for different sections of a cell. For example:

text
state  pmux_slice

match pmux
    select pmux->type == $pmux
    slice idx GetSize(port(pmux, \S))
    index <SigBit> port(pmux, \S)[idx] === port(eq, \Y)
    set pmux_slice idx
endmatch

The first argument to slice is the local variable name used to identify the
slice. The second argument is the number of slices that should be created for
this cell. The set statement can be used to copy that index into a state
variable so that later matches and/or code blocks can refer to it.

A similar mechanism is "choices", where a list of options is given as
second argument, and the matcher will iterate over those options:

text
state <SigSpec> foo bar
state  eq_ab eq_ba

match eq
    select eq->type == $eq
    choice  AB {\A, \B}
    define  BA (AB == \A ? \B : \A)
    index <SigSpec> port(eq, AB) === foo
    index <SigSpec> port(eq, BA) === bar
    set eq_ab AB
    set eq_ba BA
endmatch

Notice how define can be used to define additional local variables similar
to the loop variables defined by slice and choice.

Additional code

Interleaved with match..endmatch blocks there may be code..endcode blocks.
Such a block starts with the keyword code followed by a list of state variables
that the block may modify. For example:

text
code addAB sigS
    if (addA) {
        addAB = addA;
        sigS = port(addA, \B);
    }
    if (addB) {
        addAB = addB;
        sigS = port(addB, \A);
    }
endcode

The special keyword reject can be used to reject the current state and
backtrack. For example:

text
code
    if (ffA && ffB) {
        if (port(ffA, \CLK) != port(ffB, \CLK))
            reject;
        if (param(ffA, \CLK_POLARITY) != param(ffB, \CLK_POLARITY))
            reject;
    }
endcode

Similarly, the special keyword accept can be used to accept the current
state. (accept will not backtrack. This means it continues with the current
branch and may accept a larger match later.)

The special keyword branch can be used to explore different cases. Note that
each code block has an implicit branch at the end. So most use-cases of the
branch keyword need to end the block with reject to avoid the implicit
branch at the end. For example:

text
state  mode

code mode
    for (mode = 0; mode < 8; mode++)
        branch;
    reject;
endcode

But in some cases it is more natural to utilize the implicit branch statement:

text
state  portAB

code portAB
    portAB = \A;
    branch;
    portAB = \B;
endcode

There is an implicit code..endcode block at the end of each (sub)pattern
that just rejects.

A code..finally..endcode block executes the code after finally during
back-tracking. This is useful for maintaining user data state or printing
debug messages. For example:

text
udata <vector<Cell*>> stack

code
    stack.push_back(addAB);
    ...
finally
    stack.pop_back();
endcode

accept and finish statements can be used inside the finally section,
but not reject, branch, or subpattern.

Declaring a subpattern

A subpattern starts with a line containing the subpattern keyword followed
by the name of the subpattern. Subpatterns can be called from a code block
using a subpattern(<subpattern_name>); C statement.

Arguments may be passed to subpattern via state variables. The subpattern
line must be followed by a arg <arg1> <arg2> ... line that lists the
state variables used to pass arguments.

text
state  foobar_type
state  foobar_state

code foobar_type foobar_state
    foobar_state = false;
    foobar_type = $add;
    subpattern(foo);
    foobar_type = $sub;
    subpattern(bar);
endcode

subpattern foo
arg foobar_type foobar_state

match addsub
    index  addsub->type === foobar_type
    ...
endmatch

code
    if (foobar_state) {
        subpattern(tail);
    } else {
        foobar_state = true;
        subpattern(bar);
    }
endcode

subpattern bar
arg foobar_type foobar_state

match addsub
    index  addsub->type === foobar_type
    ...
endmatch

code
    if (foobar_state) {
        subpattern(tail);
    } else {
        foobar_state = true;
        subpattern(foo);
    }
endcode

subpattern tail
...

Subpatterns can be called recursively.

If a subpattern statement is preceded by a fallthrough statement, this is
equivalent to calling the subpattern at the end of the preceding block.

Generate Blocks

Match blocks may contain an optional generate section that is used for automatic
test-case generation. For example:

text
match mul
    ...
generate 10 0
    SigSpec Y = port(ff, \D);
    SigSpec A = module->addWire(NEW_ID, GetSize(Y) - rng(GetSize(Y)/2));
    SigSpec B = module->addWire(NEW_ID, GetSize(Y) - rng(GetSize(Y)/2));
    module->addMul(NEW_ID, A, B, Y, rng(2));
endmatch

The expression rng(n) returns a non-negative integer less than n.

The first argument to generate is the chance of this generate block being
executed when the match block did not match anything, in percent.

The second argument to generate is the chance of this generate block being
executed when the match block did match something, in percent.

The special statement finish can be used within generate blocks to terminate
the current pattern matcher run.


Overview (`tests/functional/README.md`)

Tests for the functional backend use pytest as a testrunner.

Run with pytest -v

Pytest options you might want:

  • -v: More progress indication.

  • --basetemp tmp: Store test files (including vcd results) in tmp.
    CAREFUL: contents of tmp will be deleted

  • -k : Run only tests that contain the pattern, e.g.
    -k cxx or -k smt or -k demux or -k 'cxx[demux

  • -s: Don't hide stdout/stderr from the test code.

Custom options for functional backend tests:

  • --per-cell N: Run only N tests for each cell.

Source Bib (`docs/source/bib.rst`)

.. only:: html

text
Literature references
=====================

.. rubric:: Bibliography

.. bibliography:: literature.bib

.. todo:: see if we can get the two hanging appnotes as lit references


Source Cell Index (`docs/source/cell_index.rst`)

Internal cell library

The intermediate language used by Yosys (RTLIL) represents logic and memory with
a series of cells. This section provides details for those cells, breaking them
down into two major categories: coarse-grain word-level cells; and fine-grain
gate-level cells. An additional section contains a list of properties which may
be shared across multiple cells.

.. toctree::
:maxdepth: 2

/cell/index_word
/cell/index_gate
/cell/properties


Source Cmd Ref (`docs/source/cmd_ref.rst`)

================================================================================ Command line reference

.. literalinclude:: /generated/yosys
:start-at: Usage

.. _cmd_ref:

Command reference

.. todo:: Can we warn on command groups that aren't included anywhere?

:ref:List of all commands<cmd-cmd>

.. toctree::
:maxdepth: 2

/appendix/env_vars
/cmd/index_frontends
/cmd/index_backends
/cmd/index_kernel
/cmd/index_formal

.. toctree::
:maxdepth: 3

/cmd/index_passes
/cmd/index_techlibs

.. toctree::
:maxdepth: 2

/cmd/index_internal


Source Index (`docs/source/index.rst`)

================================================================================ Yosys Open SYnthesis Suite

Yosys is an open source framework for RTL synthesis. To learn more about Yosys,
see :doc:/introduction. For a quick guide on how to get started using Yosys,
check out :doc:/getting_started/index. For the complete list of commands
available, go to :ref:cmd_ref.

.. todo:: look into command ref improvements

  • Search bar with live drop down suggestions for matching on title /
    autocompleting commands
  • Scroll the left sidebar to the current location on page load
  • Also the formatting in pdf uses link formatting instead of code formatting

.. todolist::

.. toctree::
:maxdepth: 3
:includehidden:

Yosys (index)
introduction

getting_started/index
using_yosys/index
yosys_internals/index

.. toctree::
:caption: Appendix
:titlesonly:
:includehidden:

appendix/primer
appendix/rtlil_text
appendix/auxlibs
appendix/auxprogs

bib

cell_index
cmd_ref


Source Introduction (`docs/source/introduction.rst`)

What is Yosys

Yosys began as a BSc thesis project by Claire Wolf intended to support synthesis
for a CGRA (coarse-grained reconfigurable architecture). It then expanded into
more general infrastructure for research on synthesis.

Modern Yosys has full support for the synthesizable subset of Verilog-2005 and
has been described as "the GCC of hardware synthesis." Freely available and
open source_, Yosys finds use across hobbyist and commercial applications as
well as academic.

.. _open source: https://github.com/YosysHQ/yosys

.. note:: Yosys is released under the ISC License:

A permissive license lets people do anything with your code with proper
attribution and without warranty. The ISC license is functionally equivalent
to the BSD 2-Clause and MIT licenses, removing some language that is no
longer necessary.

Together with the place and route tool nextpnr, Yosys can be used to program
some FPGAs with a fully end-to-end open source flow (Lattice iCE40 and ECP5). It
also does the synthesis portion for the OpenLane flow
, targeting the SkyWater
130nm open source PDK for fully open source ASIC design. Yosys can also do
formal verification with backends for solver formats like SMT2_.

.. _nextpnr: https://github.com/YosysHQ/nextpnr
.. _OpenLane flow: https://github.com/The-OpenROAD-Project/OpenLane
.. _SMT2: https://smtlib.cs.uiowa.edu/

Yosys, and the accompanying Open Source EDA ecosystem, is currently maintained
by Yosys Headquarters, with many of the core developers employed by YosysHQ GmbH. A commercial extension, Tabby CAD Suite_, includes the Verific
frontend for industry-grade SystemVerilog and VHDL support, formal verification
with SVA, and formal apps.

.. _Yosys Headquarters: https://github.com/YosysHQ
.. _YosysHQ GmbH: https://www.yosyshq.com/about
.. _Tabby CAD Suite: https://www.yosyshq.com/tabby-cad-datasheet

.. figure:: /_static/logo.png
:class: width-helper

What you can do with Yosys

  • Read and process (most of) modern Verilog-2005 code
  • Perform all kinds of operations on netlist (RTL, Logic, Gate)
  • Perform logic optimizations and gate mapping with ABC

Typical applications for Yosys

text
- Synthesis of final production designs
- Pre-production synthesis (trial runs before investing in other tools)
- Conversion of full-featured Verilog to simple Verilog
- Conversion of Verilog to other formats (BLIF, BTOR, etc)
- Demonstrating synthesis algorithms (e.g. for educational purposes)
- Framework for experimenting with new algorithms
- Framework for building custom flows (Not limited to synthesis but also formal
  verification, reverse engineering, ...)

Things you can't do
~~~~~~~~~~~~~~~~~~~

- Process high-level languages such as C/C++/SystemC
- Create physical layouts (place&route)

  - Check out `nextpnr`_ for that

- Rely on built-in syntax checking

  - Use an external tool like `verilator`_ instead

.. todo:: nextpnr for FPGAs, consider mentioning openlane, vpr, coriolis

.. _nextpnr: https://github.com/YosysHQ/nextpnr
.. _verilator: https://www.veripool.org/verilator/

The Yosys family
----------------

As mentioned above, `YosysHQ`_ maintains not just Yosys but an entire family of
tools built around it.  In no particular order:

.. _YosysHQ: https://github.com/YosysHQ

SBY for formal verification
   Yosys provides input parsing and conversion to the formats used by the solver
   engines.  Yosys also provides a unified witness framework for providing cover
   traces and counter examples for engines which don't natively support this.
   `SBY source`_ | `SBY docs`_

.. _SBY source: https://github.com/YosysHQ/sby
.. _SBY docs: https://yosyshq.readthedocs.io/projects/sby

EQY for equivalence checking
   In addition to input parsing and preparation, Yosys provides  the plugin
   support enabling EQY to operate on designs directly. `EQY source`_ | `EQY
   docs`_

.. _EQY source: https://github.com/YosysHQ/eqy
.. _EQY docs: https://yosyshq.readthedocs.io/projects/eqy

MCY for mutation coverage
   Yosys is used to read the source design, generate a list of possible
   mutations to maximise design coverage, and then perform selected mutations.
   `MCY source`_ | `MCY docs`_

.. _MCY source: https://github.com/YosysHQ/mcy
.. _MCY docs: https://yosyshq.readthedocs.io/projects/mcy

SCY for deep formal traces
   Since SCY generates and runs SBY, Yosys provides the same utility for SCY as
   it does for SBY.  Yosys additionally provides the trace concatenation needed
   for outputting the deep traces. `SCY source`_

.. _SCY source: https://github.com/YosysHQ/scy

The original thesis abstract
----------------------------

The first version of the Yosys documentation was published as a bachelor thesis
at the Vienna University of Technology :cite:p:`BACC`.

:Abstract:
	Most of today's digital design is done in HDL code (mostly Verilog or
	VHDL) and with the help of HDL synthesis tools.

	In special cases such as synthesis for coarse-grain cell libraries or
	when testing new synthesis algorithms it might be necessary to write a
	custom HDL synthesis tool or add new features to an existing one. In
	these cases the availability of a Free and Open Source (FOSS) synthesis
	tool that can be used as basis for custom tools would be helpful.

	In the absence of such a tool, the Yosys Open SYnthesis Suite (Yosys)
	was developed. This document covers the design and implementation of
	this tool. At the moment the main focus of Yosys lies on the high-level
	aspects of digital synthesis. The pre-existing FOSS logic-synthesis tool
	ABC is used by Yosys to perform advanced gate-level optimizations.

	An evaluation of Yosys based on real-world designs is included. It is
	shown that Yosys can be used as-is to synthesize such designs. The
	results produced by Yosys in this tests where successfully verified
	using formal verification and are comparable in quality to the results
	produced by a commercial synthesis tool.

Yosys is a Verilog HDL synthesis tool. This means that it takes a behavioural
design description as input and generates an RTL, logical gate or physical gate
level description of the design as output. Yosys' main strengths are behavioural
and RTL synthesis. A wide range of commands (synthesis passes) exist within
Yosys that can be used to perform a wide range of synthesis tasks within the
domain of behavioural, rtl and logic synthesis. Yosys is designed to be
extensible and therefore is a good basis for implementing custom synthesis tools
for specialised tasks.

.. figure:: /_images/primer/levels_of_abstraction.*
    :class: width-helper invert-helper
    :name: fig:Levels_of_abstraction

    Where Yosys exists in the layers of abstraction

Benefits of open source HDL synthesis
  • Cost (also applies to free as in free beer solutions):

    Today the cost for a mask set in 180nm technology is far less than the cost
    for the design tools needed to design the mask layouts. Open Source ASIC flows
    are an important enabler for ASIC-level Open Source Hardware.

  • Availability and Reproducibility:

    If you are a researcher who is publishing, you want to use tools that everyone
    else can also use. Even if most universities have access to all major
    commercial tools, you usually do not have easy access to the version that was
    used in a research project a couple of years ago. With Open Source tools you
    can even release the source code of the tool you have used alongside your
    data.

  • Framework:

    Yosys is not only a tool. It is a framework that can be used as basis for
    other developments, so researchers and hackers alike do not need to re-invent
    the basic functionality. Extensibility was one of Yosys' design goals.

  • All-in-one:

    Because of the framework characteristics of Yosys, an increasing number of
    features become available in one tool. Yosys not only can be used for circuit
    synthesis but also for formal equivalence checking, SAT solving, and for
    circuit analysis, to name just a few other application domains. With
    proprietary software one needs to learn a new tool for each of these
    applications.

  • Educational Tool:

    Proprietary synthesis tools are at times very secretive about their inner
    workings. They often are black boxes. Yosys is very open about its
    internals and it is easy to observe the different steps of synthesis.

History of Yosys

text
.. todo:: Consider a less academic version of the History of Yosys

A Hardware Description Language (HDL) is a computer language used to describe
circuits. A HDL synthesis tool is a computer program that takes a formal
description of a circuit written in an HDL as input and generates a netlist that
implements the given circuit as output.

Currently the most widely used and supported HDLs for digital circuits are
Verilog :cite:p:`Verilog2005,VerilogSynth` and :abbr:`VHDL (VHSIC HDL, where
VHSIC is an acronym for Very-High-Speed Integrated Circuits)`
:cite:p:`VHDL,VHDLSynth`. Both HDLs are used for test and verification purposes
as well as logic synthesis, resulting in a set of synthesizable and a set of
non-synthesizable language features. In this document we only look at the
synthesizable subset of the language features.

In recent work on heterogeneous coarse-grain reconfigurable logic
:cite:p:`intersynth` the need for a custom application-specific HDL synthesis
tool emerged. It was soon realised that a synthesis tool that understood Verilog
or VHDL would be preferred over a synthesis tool for a custom HDL. Given an
existing Verilog or VHDL front end, the work for writing the necessary
additional features and integrating them in an existing tool can be estimated to
be about the same as writing a new tool with support for a minimalistic custom
HDL.

The proposed custom HDL synthesis tool should be licensed under a Free and Open
Source Software (FOSS) licence. So an existing FOSS Verilog or VHDL synthesis
tool would have been needed as basis to build upon. The main advantages of
choosing Verilog or VHDL is the ability to synthesize existing HDL code and to
mitigate the requirement for circuit-designers to learn a new language. In order
to take full advantage of any existing FOSS Verilog or VHDL tool, such a tool
would have to provide a feature-complete implementation of the synthesizable HDL
subset.

Basic RTL synthesis is a well understood field :cite:p:`LogicSynthesis`. Lexing,
parsing and processing of computer languages :cite:p:`Dragonbook` is a
thoroughly researched field. All the information required to write such tools
has been openly available for a long time, and it is therefore likely that a
FOSS HDL synthesis tool with a feature-complete Verilog or VHDL front end must
exist which can be used as a basis for a custom RTL synthesis tool.

Due to the author's preference for Verilog over VHDL it was decided early on to
go for Verilog instead of VHDL [#]_. So the existing FOSS Verilog synthesis
tools were evaluated. The results of this evaluation are utterly devastating.
Therefore a completely new Verilog synthesis tool was implemented and is
recommended as basis for custom synthesis tools. This is the tool that is
discussed in this document.

.. [#]
   A quick investigation into FOSS VHDL tools yielded similar grim results for
   FOSS VHDL synthesis tools.

---

### Source Requirements (`docs/source/requirements.txt`)

furo-ys @ git+https://github.com/YosysHQ/furo-ys
sphinxcontrib-bibtex
rtds-action
sphinx-inline-tabs
click

---

### Source Appendix APPNOTE 010 Verilog To BLIF (`docs/source/appendix/APPNOTE_010_Verilog_to_BLIF.rst`)

:orphan:

====================================
010: Converting Verilog to BLIF page
====================================

Abstract
========

Verilog-2005 is a powerful Hardware Description Language (HDL) that can be used
to easily create complex designs from small HDL code. It is the preferred method
of design entry for many designers.

The Berkeley Logic Interchange Format (BLIF) is a simple file format for
exchanging sequential logic between programs. It is easy to generate and easy to
parse and is therefore the preferred method of design entry for many authors of
logic synthesis tools.

Yosys is a feature-rich Open-Source Verilog synthesis tool that can be used to
bridge the gap between the two file formats. It implements most of Verilog-2005
and thus can be used to import modern behavioral Verilog designs into BLIF-based
design flows without dependencies on proprietary synthesis tools.

The scope of Yosys goes of course far beyond Verilog logic synthesis. But it is
a useful and important feature and this Application Note will focus on this
aspect of Yosys.

Download
========

This document was originally published in April 2015:
:download:`Converting Verilog to BLIF PDF</_downloads/APPNOTE_010_Verilog_to_BLIF.pdf>`

..
   Installation
   ============

   Yosys written in C++ (using features from C++11) and is tested on modern
   Linux. It should compile fine on most UNIX systems with a C++11
   compiler. The README file contains useful information on building Yosys
   and its prerequisites.

   Yosys is a large and feature-rich program with a couple of dependencies.
   It is, however, possible to deactivate some of the dependencies in the
   Makefile, resulting in features in Yosys becoming unavailable. When
   problems with building Yosys are encountered, a user who is only
   interested in the features of Yosys that are discussed in this
   Application Note may deactivate TCL, Qt and MiniSAT support in the
   Makefile and may opt against building yosys-abc.

   This Application Note is based on `Yosys GIT`_ `Rev. e216e0e`_  from 2013-11-23.
   The Verilog sources used for the examples are taken from `yosys-bigsim`_, a
   collection of real-world designs used for regression testing Yosys.

   .. _Yosys GIT: https://github.com/YosysHQ/yosys

   .. _Rev. e216e0e: https://github.com/YosysHQ/yosys/tree/e216e0e

   .. _yosys-bigsim: https://github.com/YosysHQ/yosys-bigsim

   Getting started
   ===============

   We start our tour with the Navrรฉ processor from yosys-bigsim. The `Navrรฉ
   processor`_ is an Open Source AVR clone. It is a single module (softusb_navre)
   in a single design file (softusb_navre.v). It also is using only features that
   map nicely to the BLIF format, for example it only uses synchronous resets.

   .. _Navrรฉ processor: http://opencores.org/projects/navre

   Converting softusb_navre.v to softusb_navre.blif could not be easier:

   .. code:: sh

      yosys -o softusb_navre.blif -S softusb_navre.v

   Behind the scenes Yosys is controlled by synthesis scripts that execute
   commands that operate on Yosys' internal state. For example, the -o
   softusb_navre.blif option just adds the command write_blif
   softusb_navre.blif to the end of the script. Likewise a file on the
   command line โ€“ softusb_navre.v in this case โ€“ adds the command
   read_verilog softusb_navre.v to the beginning of the synthesis script.
   In both cases the file type is detected from the file extension.

   Finally the option -S instantiates a built-in default synthesis script.
   Instead of using -S one could also specify the synthesis commands for
   the script on the command line using the -p option, either using
   individual options for each command or by passing one big command string
   with a semicolon-separated list of commands. But in most cases it is
   more convenient to use an actual script file.

   Using a synthesis script
   ========================

   With a script file we have better control over Yosys. The following
   script file replicates what the command from the last section did:

   .. code:: yoscrypt

      read_verilog softusb_navre.v
      hierarchy
      proc; opt; memory; opt; techmap; opt
      write_blif softusb_navre.blif

   The first and last line obviously read the Verilog file and write the
   BLIF file.

   The 2nd line checks the design hierarchy and instantiates parametrized
   versions of the modules in the design, if necessary. In the case of this
   simple design this is a no-op. However, as a general rule a synthesis
   script should always contain this command as first command after reading
   the input files.

   The 3rd line does most of the actual work:

   -  The command opt is the Yosys' built-in optimizer. It can perform some
      simple optimizations such as const-folding and removing unconnected
      parts of the design. It is common practice to call opt after each
      major step in the synthesis procedure. In cases where too much
      optimization is not appreciated (for example when analyzing a
      design), it is recommended to call clean instead of opt.

   -  The command proc converts processes (Yosys' internal representation
      of Verilog always- and initial-blocks) to circuits of multiplexers
      and storage elements (various types of flip-flops).

   -  The command memory converts Yosys' internal representations of arrays
      and array accesses to multi-port block memories, and then maps this
      block memories to address decoders and flip-flops, unless the option
      -nomap is used, in which case the multi-port block memories stay in
      the design and can then be mapped to architecture-specific memory
      primitives using other commands.

   -  The command techmap turns a high-level circuit with coarse grain
      cells such as wide adders and multipliers to a fine-grain circuit of
      simple logic primitives and single-bit storage elements. The command
      does that by substituting the complex cells by circuits of simpler
      cells. It is possible to provide a custom set of rules for this
      process in the form of a Verilog source file, as we will see in the
      next section.

   Now Yosys can be run with the filename of the synthesis script as
   argument:

   .. code:: sh

      yosys softusb_navre.ys

   Now that we are using a synthesis script we can easily modify how Yosys
   synthesizes the design. The first thing we should customize is the call
   to the hierarchy command:

   Whenever it is known that there are no implicit blackboxes in the
   design, i.e. modules that are referenced but are not defined, the
   hierarchy command should be called with the -check option. This will
   then cause synthesis to fail when implicit blackboxes are found in the
   design.

   The 2nd thing we can improve regarding the hierarchy command is that we
   can tell it the name of the top level module of the design hierarchy. It
   will then automatically remove all modules that are not referenced from
   this top level module.

   For many designs it is also desired to optimize the encodings for the
   finite state machines (FSMs) in the design. The fsm command finds FSMs,
   extracts them, performs some basic optimizations and then generate a
   circuit from the extracted and optimized description. It would also be
   possible to tell the fsm command to leave the FSMs in their extracted
   form, so they can be further processed using custom commands. But in
   this case we don't want that.

   So now we have the final synthesis script for generating a BLIF file for
   the Navrรฉ CPU:

   .. code:: yoscrypt

      read_verilog softusb_navre.v
      hierarchy -check -top softusb_navre
      proc; opt; memory; opt; fsm; opt; techmap; opt
      write_blif softusb_navre.blif

   Advanced example: The Amber23 ARMv2a CPU
   ========================================

   Our 2nd example is the `Amber23 ARMv2a CPU`_. Once again we base our example on
   the Verilog code that is included in `yosys-bigsim`_.

   .. _Amber23 ARMv2a CPU: http://opencores.org/projects/amber

   .. code-block:: yoscrypt
      :caption: `amber23.ys`
      :name: amber23.ys

      read_verilog a23_alu.v
      read_verilog a23_barrel_shift_fpga.v
      read_verilog a23_barrel_shift.v
      read_verilog a23_cache.v
      read_verilog a23_coprocessor.v
      read_verilog a23_core.v
      read_verilog a23_decode.v
      read_verilog a23_execute.v
      read_verilog a23_fetch.v
      read_verilog a23_multiply.v
      read_verilog a23_ram_register_bank.v
      read_verilog a23_register_bank.v
      read_verilog a23_wishbone.v
      read_verilog generic_sram_byte_en.v
      read_verilog generic_sram_line_en.v
      hierarchy -check -top a23_core
      add -global_input globrst 1
      proc -global_arst globrst
      techmap -map adff2dff.v
      opt; memory; opt; fsm; opt; techmap
      write_blif amber23.blif

   The problem with this core is that it contains no dedicated reset logic. Instead
   the coding techniques shown in :numref:`glob_arst` are used to define reset
   values for the global asynchronous reset in an FPGA implementation. This design
   can not be expressed in BLIF as it is. Instead we need to use a synthesis script
   that transforms this form to synchronous resets that can be expressed in BLIF.

   (Note that there is no problem if this coding techniques are used to model ROM,
   where the register is initialized using this syntax but is never updated
   otherwise.)

   :numref:`amber23.ys` shows the synthesis script for the Amber23 core. In line 17
   the add command is used to add a 1-bit wide global input signal with the name
   ``globrst``. That means that an input with that name is added to each module in the
   design hierarchy and then all module instantiations are altered so that this new
   signal is connected throughout the whole design hierarchy.

   .. code-block:: verilog
      :caption: Implicit coding of global asynchronous resets
      :name: glob_arst

      reg [7:0] a = 13, b;
      initial b = 37;

   .. code-block:: verilog
      :caption: `adff2dff.v`
      :name: adff2dff.v

      (* techmap_celltype = "$adff" *)
      module adff2dff (CLK, ARST, D, Q);

      parameter WIDTH = 1;
      parameter CLK_POLARITY = 1;
      parameter ARST_POLARITY = 1;
      parameter ARST_VALUE = 0;

      input CLK, ARST;
      input [WIDTH-1:0] D;
      output reg [WIDTH-1:0] Q;

      wire [1023:0] _TECHMAP_DO_ = "proc";

      wire _TECHMAP_FAIL_ =
         !CLK_POLARITY || !ARST_POLARITY;

      always @(posedge CLK)
            if (ARST)
                     Q <= ARST_VALUE;
            else
                     Q <= D;

      endmodule

   In line 18 the :cmd:ref:`proc` command is called. But in this script the signal
   name globrst is passed to the command as a global reset signal for resetting the
   registers to their assigned initial values.

   Finally in line 19 the techmap command is used to replace all instances of
   flip-flops with asynchronous resets with flip-flops with synchronous resets. The
   map file used for this is shown in :numref:`adff2dff.v`. Note how the
   ``techmap_celltype`` attribute is used in line 1 to tell the techmap command
   which cells to replace in the design, how the ``_TECHMAP_FAIL_`` wire in lines
   15 and 16 (which evaluates to a constant value) determines if the parameter set
   is compatible with this replacement circuit, and how the ``_TECHMAP_DO_`` wire
   in line 13 provides a mini synthesis-script to be used to process this cell.

   .. code-block:: c
      :caption: Test program for the Amber23 CPU (Sieve of Eratosthenes). Compiled
               using GCC 4.6.3 for ARM with ``-Os -marm -march=armv2a
         -mno-thumb-interwork -ffreestanding``, linked with ``--fix-v4bx``
         set and booted with a custom setup routine written in ARM assembler.
      :name: sieve

      #include <stdint.h>
      #include <stdbool.h>

      #define BITMAP_SIZE 64
      #define OUTPORT 0x10000000

      static uint32_t bitmap[BITMAP_SIZE/32];

      static void bitmap_set(uint32_t idx) { bitmap[idx/32] |= 1 << (idx % 32); }
      static bool bitmap_get(uint32_t idx) { return (bitmap[idx/32] & (1 << (idx % 32))) != 0; }
      static void output(uint32_t val) { *((volatile uint32_t*)OUTPORT) = val; }

      int main() {
         uint32_t i, j, k;
         output(2);
         for (i = 0; i < BITMAP_SIZE; i++) {
            if (bitmap_get(i)) continue;
            output(3+2*i);
            for (j = 2*(3+2*i);; j += 3+2*i) {
                  if (j%2 == 0) continue;
                  k = (j-3)/2;
                  if (k >= BITMAP_SIZE) break;
                  bitmap_set(k);
            }
         }
         output(0);
         return 0;
      }

   Verification of the Amber23 CPU
   ===============================

   The BLIF file for the Amber23 core, generated using :numref:`amber23.ys` and
   :numref:`adff2dff.v` and the version of the Amber23 RTL source that is bundled
   with yosys-bigsim, was verified using the test-bench from yosys-bigsim. It
   successfully executed the program shown in :numref:`sieve` in the test-bench.

   For simulation the BLIF file was converted back to Verilog using `ABC`_. So this
   test includes the successful transformation of the BLIF file into ABC's internal
   format as well.

   .. _ABC: https://github.com/berkeley-abc/abc

   The only thing left to write about the simulation itself is that it probably was
   one of the most energy inefficient and time consuming ways of successfully
   calculating the first 31 primes the author has ever conducted.

   Limitations
   ===========

   At the time of this writing Yosys does not support multi-dimensional memories,
   does not support writing to individual bits of array elements, does not support
   initialization of arrays with ``$readmemb`` and ``$readmemh``, and has only
   limited support for tristate logic, to name just a few limitations.

   That being said, Yosys can synthesize an overwhelming majority of real-world
   Verilog RTL code. The remaining cases can usually be modified to be compatible
   with Yosys quite easily.

   The various designs in yosys-bigsim are a good place to look for examples of
   what is within the capabilities of Yosys.

   Conclusion
   ==========

   Yosys is a feature-rich Verilog-2005 synthesis tool. It has many uses, but one
   is to provide an easy gateway from high-level Verilog code to low-level logic
   circuits.

   The command line option ``-S`` can be used to quickly synthesize Verilog code to
   BLIF files without a hassle.

   With custom synthesis scripts it becomes possible to easily perform high-level
   optimizations, such as re-encoding FSMs. In some extreme cases, such as the
   Amber23 ARMv2 CPU, the more advanced Yosys features can be used to change a
   design to fit a certain need without actually touching the RTL code.

---

### Source Appendix APPNOTE 012 Verilog To BTOR (`docs/source/appendix/APPNOTE_012_Verilog_to_BTOR.rst`)

:orphan:

====================================
012: Converting Verilog to BTOR page
====================================

Abstract
========

Verilog-2005 is a powerful Hardware Description Language (HDL) that can be used
to easily create complex designs from small HDL code. BTOR is a bit-precise
word-level format for model checking. It is a simple format and easy to parse.
It allows to model the model checking problem over the theory of bit-vectors
with one-dimensional arrays, thus enabling to model Verilog designs with
registers and memories. Yosys is an Open-Source Verilog synthesis tool that can
be used to convert Verilog designs with simple assertions to BTOR format.

Download
========

This document was originally published in November 2013:
:download:`Converting Verilog to BTOR PDF</_downloads/APPNOTE_012_Verilog_to_BTOR.pdf>`

..
   Installation
   ============

   Yosys written in C++ (using features from C++11) and is tested on modern Linux.
   It should compile fine on most UNIX systems with a C++11 compiler. The README
   file contains useful information on building Yosys and its prerequisites.

   Yosys is a large and feature-rich program with some dependencies. For this work,
   we may deactivate other extra features such as TCL and ABC support in the
   Makefile.

   This Application Note is based on `Yosys GIT`_ `Rev. 082550f` from 2015-04-04.

   .. _Yosys GIT: https://github.com/YosysHQ/yosys

   .. _Rev. 082550f: https://github.com/YosysHQ/yosys/tree/082550f

   Quick start
   ===========

   We assume that the Verilog design is synthesizable and we also assume that the
   design does not have multi-dimensional memories. As BTOR implicitly initializes
   registers to zero value and memories stay uninitialized, we assume that the
   Verilog design does not contain initial blocks. For more details about the BTOR
   format, please refer to :cite:p:`btor`.

   We provide a shell script ``verilog2btor.sh`` which can be used to convert a
   Verilog design to BTOR. The script can be found in the ``backends/btor``
   directory. The following example shows its usage:

   .. code:: sh

      verilog2btor.sh fsm.v fsm.btor test

   The script ``verilog2btor.sh`` takes three parameters. In the above example, the
   first parameter ``fsm.v`` is the input design, the second parameter ``fsm.btor``
   is the file name of BTOR output, and the third parameter ``test`` is the name of
   top module in the design.

   To specify the properties (that need to be checked), we have two
   options:

   -  We can use the Verilog ``assert`` statement in the procedural block or module
      body of the Verilog design, as shown in :numref:`specifying_property_assert`.
      This is the preferred option.

   -  We can use a single-bit output wire, whose name starts with ``safety``. The
      value of this output wire needs to be driven low when the property is met,
      i.e. the solver will try to find a model that makes the safety pin go high.
      This is demonstrated in :numref:`specifying_property_output`.

   .. code-block:: verilog
      :caption: Specifying property in Verilog design with ``assert``
      :name: specifying_property_assert

      module test(input clk, input rst, output y);

      reg [2:0] state;

      always @(posedge clk) begin
         if (rst || state == 3) begin
            state <= 0;
         end else begin
            assert(state < 3);
            state <= state + 1;
         end
      end

      assign y = state[2];

      assert property (y !== 1'b1);

      endmodule

   .. code-block:: verilog
      :caption: Specifying property in Verilog design with output wire
      :name: specifying_property_output

      module test(input clk, input rst,
         output y, output safety1);

      reg [2:0] state;

      always @(posedge clk) begin
         if (rst || state == 3)
            state <= 0;
         else
            state <= state + 1;
      end

      assign y = state[2];

      assign safety1 = !(y !== 1'b1);

      endmodule

   We can run `Boolector`_ ``1.4.1`` [1]_ on the generated BTOR file:

   .. _Boolector: http://fmv.jku.at/boolector/

   .. code:: sh

      $ boolector fsm.btor
      unsat

   We can also use `nuXmv`_, but on BTOR designs it does not support memories yet.
   With the next release of nuXmv, we will be also able to verify designs with
   memories.

   .. _nuXmv: https://es-static.fbk.eu/tools/nuxmv/index.php

   Detailed flow
   =============

   Yosys is able to synthesize Verilog designs up to the gate level. We are
   interested in keeping registers and memories when synthesizing the design. For
   this purpose, we describe a customized Yosys synthesis flow, that is also
   provided by the ``verilog2btor.sh`` script. :numref:`btor_script_memory` shows
   the Yosys commands that are executed by ``verilog2btor.sh``.

   .. code-block:: yoscrypt
      :caption: Synthesis Flow for BTOR with memories
      :name: btor_script_memory

      read_verilog -sv $1;
      hierarchy -top $3; hierarchy -libdir $DIR;
      hierarchy -check;
      proc; opt;
      opt_expr -mux_undef; opt;
      rename -hide;;;
      splice; opt;
      memory_dff -wr_only; memory_collect;;
      flatten;;
      memory_unpack;
      splitnets -driver;
      setundef -zero -undriven;
      opt;;;
      write_btor $2;

   Here is short description of what is happening in the script line by
   line:

   #. Reading the input file.

   #. Setting the top module in the hierarchy and trying to read automatically the
      files which are given as ``include`` in the file read in first line.

   #. Checking the design hierarchy.

   #. Converting processes to multiplexers (muxs) and flip-flops.

   #. Removing undef signals from muxs.

   #. Hiding all signal names that are not used as module ports.

   #. Explicit type conversion, by introducing slice and concat cells in the
      circuit.

   #. Converting write memories to synchronous memories, and collecting the
      memories to multi-port memories.

   #. Flattening the design to get only one module.

   #. Separating read and write memories.

   #. Splitting the signals that are partially assigned

   #. Setting undef to zero value.

   #. Final optimization pass.

   #. Writing BTOR file.

   For detailed description of the commands mentioned above, please refer
   to the Yosys documentation, or run ``yosys -h <command_name>``.

   The script presented earlier can be easily modified to have a BTOR file that
   does not contain memories. This is done by removing the line number 8 and 10,
   and introduces a new command :cmd:ref:`memory` at line number 8.
   :numref:`btor_script_without_memory` shows the modified Yosys script file:

   .. code-block:: sh
      :caption: Synthesis Flow for BTOR without memories
      :name: btor_script_without_memory

      read_verilog -sv $1;
      hierarchy -top $3; hierarchy -libdir $DIR;
      hierarchy -check;
      proc; opt;
      opt_expr -mux_undef; opt;
      rename -hide;;;
      splice; opt;
      memory;;
      flatten;;
      splitnets -driver;
      setundef -zero -undriven;
      opt;;;
      write_btor $2;

   Example
   =======

   Here is an example Verilog design that we want to convert to BTOR:

   .. code-block:: verilog
      :caption: Example - Verilog Design
      :name: example_verilog

      module array(input clk);

      reg [7:0] counter;
      reg [7:0] mem [7:0];

      always @(posedge clk) begin
         counter <= counter + 8'd1;
         mem[counter] <= counter;
      end

      assert property (!(counter > 8'd0) ||
         mem[counter - 8'd1] == counter - 8'd1);

      endmodule

   The generated BTOR file that contain memories, using the script shown in
   :numref:`btor_memory`:

   .. code-block::
      :caption: Example - Converted BTOR with memory
      :name: btor_memory

      1 var 1 clk
      2 array 8 3
      3 var 8 $auto$rename.cc:150:execute$20
      4 const 8 00000001
      5 sub 8 3 4
      6 slice 3 5 2 0
      7 read 8 2 6
      8 slice 3 3 2 0
      9 add 8 3 4
      10 const 8 00000000
      11 ugt 1 3 10
      12 not 1 11
      13 const 8 11111111
      14 slice 1 13 0 0
      15 one 1
      16 eq 1 1 15
      17 and 1 16 14
      18 write 8 3 2 8 3
      19 acond 8 3 17 18 2
      20 anext 8 3 2 19
      21 eq 1 7 5
      22 or 1 12 21
      23 const 1 1
      24 one 1
      25 eq 1 23 24
      26 cond 1 25 22 24
      27 root 1 -26
      28 cond 8 1 9 3
      29 next 8 3 28

   And the BTOR file obtained by the script shown in
   :numref:`btor_without_memory`, which expands the memory into individual
   elements:

   .. code-block::
      :caption: Example - Converted BTOR with memory
      :name: btor_without_memory

      1 var 1 clk
      2 var 8 mem[0]
      3 var 8 $auto$rename.cc:150:execute$20
      4 slice 3 3 2 0
      5 slice 1 4 0 0
      6 not 1 5
      7 slice 1 4 1 1
      8 not 1 7
      9 slice 1 4 2 2
      10 not 1 9
      11 and 1 8 10
      12 and 1 6 11
      13 cond 8 12 3 2
      14 cond 8 1 13 2
      15 next 8 2 14
      16 const 8 00000001
      17 add 8 3 16
      18 const 8 00000000
      19 ugt 1 3 18
      20 not 1 19
      21 var 8 mem[2]
      22 and 1 7 10
      23 and 1 6 22
      24 cond 8 23 3 21
      25 cond 8 1 24 21
      26 next 8 21 25
      27 sub 8 3 16

      ...

      54 cond 1 53 50 52
      55 root 1 -54

      ...

      77 cond 8 76 3 44
      78 cond 8 1 77 44
      79 next 8 44 78

   Limitations
   ===========

   BTOR does not support initialization of memories and registers, i.e. they are
   implicitly initialized to value zero, so the initial block for memories need to
   be removed when converting to BTOR. It should also be kept in consideration that
   BTOR does not support the ``x`` or ``z`` values of Verilog.

   Another thing to bear in mind is that Yosys will convert multi-dimensional
   memories to one-dimensional memories and address decoders. Therefore
   out-of-bounds memory accesses can yield unexpected results.

   Conclusion
   ==========

   Using the described flow, we can use Yosys to generate word-level verification
   benchmarks with or without memories from Verilog designs.

   .. [1]
      Newer version of Boolector do not support sequential models.
      Boolector 1.4.1 can be built with picosat-951. Newer versions of
      picosat have an incompatible API.

---

### Source Appendix Auxlibs (`docs/source/appendix/auxlibs.rst`)

Auxiliary libraries
===================

The Yosys source distribution contains some auxiliary libraries that are
compiled into Yosys and can be used in plugins.

BigInt
------

The files in ``libs/bigint/`` provide a library for performing arithmetic with
arbitrary length integers. It is written by Matt McCutchen.

The BigInt library is used for evaluating constant expressions, e.g. using the
ConstEval class provided in kernel/consteval.h.

See also: http://mattmccutchen.net/bigint/

dlfcn-win32
-----------

The ``dlfcn`` library enables runtime loading of plugins without requiring
recompilation of Yosys.  The files in ``libs/dlfcn-win32`` provide an
implementation of ``dlfcn`` for Windows.

See also: https://github.com/dlfcn-win32/dlfcn-win32

ezSAT
-----

The files in ``libs/ezsat`` provide a library for simplifying generating CNF
formulas for SAT solvers. It also contains bindings of MiniSAT. The ezSAT
library is written by C. Wolf. It is used by the `sat` pass.

fst
---

``libfst`` files from `gtkwave`_ are included in ``libs/fst`` to support
reading/writing signal traces from/to the GTKWave developed FST format.  This is
primarily used in the `sim` command.

.. _gtkwave: https://github.com/gtkwave/gtkwave

json11
------

For reading/writing designs from/to JSON, `read_json` and
`write_json` should be used.  For everything else there is the `json11
library`_:

   json11 is a tiny JSON library for C++11, providing JSON parsing and
   serialization.

This library is used for outputting machine-readable statistics (`stat`
with ``-json`` flag), using the RPC frontend (`connect_rpc`), and the
yosys-witness ``yw`` format.

.. _json11 library: https://github.com/dropbox/json11

MiniSAT
-------

The files in ``libs/minisat`` provide a high-performance SAT solver, used by the
`sat` command.

SHA1
----

The files in ``libs/sha1/`` provide a public domain SHA1 implementation written
by Steve Reid, Bruce Guenter, and Volker Grabsch. It is used for generating
unique names when specializing parameterized modules.

.. _sec:SubCircuit:

SubCircuit
----------

The files in ``libs/subcircuit`` provide a library for solving the subcircuit
isomorphism problem. It is written by C. Wolf and based on the Ullmann Subgraph
Isomorphism Algorithm :cite:p:`UllmannSubgraphIsomorphism`. It is used by the
`extract` pass.

---

### Source Appendix Auxprogs (`docs/source/appendix/auxprogs.rst`)

Auxiliary programs
==================

Besides the main yosys executable, the Yosys distribution contains a set of
additional helper programs.

yosys-config
------------

The ``yosys-config`` tool (an auto-generated shell-script) can be used to query
compiler options and other information needed for building loadable modules for
Yosys. See :doc:`/yosys_internals/extending_yosys/extensions` for details.

.. literalinclude:: /generated/yosys-config
    :start-at: Usage

.. _sec:filterlib:

yosys-filterlib
---------------

.. todo:: how does a filterlib rules-file work?

The ``yosys-filterlib`` tool is a small utility that can be used to strip or
extract information from a Liberty file.  This can be useful for removing
sensitive or proprietary information such as timing or other trade secrets.

.. literalinclude:: /generated/yosys-filterlib
    :start-at: Usage

yosys-abc
---------

This is a fork of ABC with a small set of custom modifications that have not yet
been accepted upstream. Not all versions of Yosys work with all versions of ABC.
So Yosys comes with its own yosys-abc to avoid compatibility issues between the
two.

.. literalinclude:: /generated/yosys-abc
    :start-at: usage

yosys-smtbmc
------------

The ``yosys-smtbmc`` tool is a utility used by SBY for interacting with smt
solvers.

.. literalinclude:: /generated/yosys-smtbmc

yosys-witness
-------------

``yosys-witness`` is a new tool to inspect and convert yosys witness traces.
This is used in SBY and SCY for producing traces in a consistent format
independent of the solver.

.. literalinclude:: /generated/yosys-witness
    :start-at: Usage

.. note:: ``yosys-witness`` requires `click`_ Python package for use.

.. _click: https://pypi.org/project/click/

---

### Source Appendix Env Vars (`docs/source/appendix/env_vars.rst`)

Yosys environment variables
===========================

``HOME``
   Yosys command history is stored in :file:`$HOME/.yosys_history`.  Graphics
   (from `show` and `viz` commands) will output to this
   directory by default.  This environment variable is also used in some cases
   for resolving filenames with :file:`~`.

``PATH``
   May be used in OpenBSD builds for finding the location of Yosys executable.

``TMPDIR``
   Used for storing temporary files.

``ABC``
   When compiling Yosys with out-of-tree ABC using
   :makevar:`YOSYS_ABC_EXECUTABLE`, this variable can be used to override the
   external ABC executable.

``YOSYS_NOVERIFIC``
   If Yosys was built with Verific, this environment variable can be used to
   temporarily disable Verific support.

``YOSYS_COVER_DIR`` and ``YOSYS_COVER_FILE``
   When using code coverage, these environment variables control the output file
   name/location.

``YOSYS_ABORT_ON_LOG_ERROR``
   Can be used for debugging Yosys internals.  Setting it to 1 causes abort() to
   be called when Yosys terminates with an error message.

---

### Source Appendix Primer (`docs/source/appendix/primer.rst`)

.. role:: verilog(code)
	:language: Verilog

.. _chapter:basics:

A primer on digital circuit synthesis
=====================================

This chapter contains a short introduction to the basic principles of digital
circuit synthesis.

Levels of abstraction
---------------------

Digital circuits can be represented at different levels of abstraction. During
the design process a circuit is usually first specified using a higher level
abstraction. Implementation can then be understood as finding a functionally
equivalent representation at a lower abstraction level. When this is done
automatically using software, the term synthesis is used.

So synthesis is the automatic conversion of a high-level representation of a
circuit to a functionally equivalent low-level representation of a circuit.
:numref:`Figure %s <fig:Basics_abstractions>` lists the different levels of
abstraction and how they relate to different kinds of synthesis.

.. figure:: /_images/primer/basics_abstractions.*
	:class: width-helper invert-helper
	:name: fig:Basics_abstractions

	Different levels of abstraction and synthesis.

Regardless of the way a lower level representation of a circuit is obtained
(synthesis or manual design), the lower level representation is usually verified
by comparing simulation results of the lower level and the higher level
representation  [1]_. Therefore even if no synthesis is used, there must still
be a simulatable representation of the circuit in all levels to allow for
verification of the design.

Note: The exact meaning of terminology such as "High-Level" is of course not
fixed over time. For example the HDL "ABEL" was first introduced in 1985 as "A
High-Level Design Language for Programmable Logic Devices" :cite:p:`ABEL`, but
would not be considered a "High-Level Language" today.

System level
~~~~~~~~~~~~

The System Level abstraction of a system only looks at its biggest building
blocks like CPUs and computing cores. At this level the circuit is usually
described using traditional programming languages like C/C++ or Matlab.
Sometimes special software libraries are used that are aimed at simulation
circuits on the system level, such as SystemC.

Usually no synthesis tools are used to automatically transform a system level
representation of a circuit to a lower-level representation. But system level
design tools exist that can be used to connect system level building blocks.

The IEEE 1685-2009 standard defines the IP-XACT file format that can be used to
represent designs on the system level and building blocks that can be used in
such system level designs. :cite:p:`IP-XACT`

High level
~~~~~~~~~~

The high-level abstraction of a system (sometimes referred to as algorithmic
level) is also often represented using traditional programming languages, but
with a reduced feature set. For example when representing a design at the high
level abstraction in C, pointers can only be used to mimic concepts that can be
found in hardware, such as memory interfaces. Full featured dynamic memory
management is not allowed as it has no corresponding concept in digital
circuits.

Tools exist to synthesize high level code (usually in the form of C/C++/SystemC
code with additional metadata) to behavioural HDL code (usually in the form of
Verilog or VHDL code). Aside from the many commercial tools for high level
synthesis there are also a number of FOSS tools for high level synthesis.

Behavioural level

At the behavioural abstraction level a language aimed at hardware description
such as Verilog or VHDL is used to describe the circuit, but so-called
behavioural modelling is used in at least part of the circuit description. In
behavioural modelling there must be a language feature that allows for
imperative programming to be used to describe data paths and registers. This is
the always-block in Verilog and the process-block in VHDL.

In behavioural modelling, code fragments are provided together with a
sensitivity list; a list of signals and conditions. In simulation, the code
fragment is executed whenever a signal in the sensitivity list changes its value
or a condition in the sensitivity list is triggered. A synthesis tool must be
able to transfer this representation into an appropriate datapath followed by
the appropriate types of register.

For example consider the following Verilog code fragment:

.. code:: verilog
:number-lines:

always @(posedge clk)
y <= a + b;

In simulation the statement y <= a + b is executed whenever a positive edge
on the signal clk is detected. The synthesis result however will contain an
adder that calculates the sum a + b all the time, followed by a d-type
flip-flop with the adder output on its D-input and the signal y on its
Q-output.

Usually the imperative code fragments used in behavioural modelling can contain
statements for conditional execution (if- and case-statements in
Verilog) as well as loops, as long as those loops can be completely unrolled.

Interestingly there seems to be no other FOSS Tool that is capable of performing
Verilog or VHDL behavioural syntheses besides Yosys.

Register-Transfer Level (RTL)

text
On the Register-Transfer Level the design is represented by combinatorial data
paths and registers (usually d-type flip flops). The following Verilog code
fragment is equivalent to the previous Verilog example, but is in RTL
representation:

.. code:: verilog
   :number-lines:

   assign tmp = a + b;       // combinatorial data path

   always @(posedge clk)     // register
       y <= tmp;

A design in RTL representation is usually stored using HDLs like Verilog and
VHDL. But only a very limited subset of features is used, namely minimalistic
always-blocks (Verilog) or process-blocks (VHDL) that model the register type
used and unconditional assignments for the datapath logic. The use of HDLs on
this level simplifies simulation as no additional tools are required to simulate
a design in RTL representation.

Many optimizations and analyses can be performed best at the RTL level. Examples
include FSM detection and optimization, identification of memories or other
larger building blocks and identification of shareable resources.

Note that RTL is the first abstraction level in which the circuit is represented
as a graph of circuit elements (registers and combinatorial cells) and signals.
Such a graph, when encoded as list of cells and connections, is called a
netlist.

RTL synthesis is easy as each circuit node element in the netlist can simply be
replaced with an equivalent gate-level circuit. However, usually the term RTL
synthesis does not only refer to synthesizing an RTL netlist to a gate level
netlist but also to performing a number of highly sophisticated optimizations
within the RTL representation, such as the examples listed above.

A number of FOSS tools exist that can perform isolated tasks within the domain
of RTL synthesis steps. But there seems to be no FOSS tool that covers a wide
range of RTL synthesis operations.

Logical gate level
~~~~~~~~~~~~~~~~~~

At the logical gate level the design is represented by a netlist that uses only
cells from a small number of single-bit cells, such as basic logic gates (AND,
OR, NOT, XOR, etc.) and registers (usually D-Type Flip-flops).

A number of netlist formats exists that can be used on this level, e.g. the
Electronic Design Interchange Format (EDIF), but for ease of simulation often a
HDL netlist is used. The latter is a HDL file (Verilog or VHDL) that only uses
the most basic language constructs for instantiation and connecting of cells.

There are two challenges in logic synthesis: First finding opportunities for
optimizations within the gate level netlist and second the optimal (or at least
good) mapping of the logic gate netlist to an equivalent netlist of physically
available gate types.

The simplest approach to logic synthesis is two-level logic synthesis, where a
logic function is converted into a sum-of-products representation, e.g. using a
Karnaugh map. This is a simple approach, but has exponential worst-case effort
and cannot make efficient use of physical gates other than AND/NAND-, OR/NOR-
and NOT-Gates.

Therefore modern logic synthesis tools utilize much more complicated multi-level
logic synthesis algorithms :cite:p:`MultiLevelLogicSynth`. Most of these
algorithms convert the logic function to a Binary-Decision-Diagram (BDD) or
And-Inverter-Graph (AIG) and work from that representation. The former has the
advantage that it has a unique normalized form. The latter has much better worst
case performance and is therefore better suited for the synthesis of large logic
functions.

Good FOSS tools exists for multi-level logic synthesis.

Yosys contains basic logic synthesis functionality but can also use ABC for the
logic synthesis step. Using ABC is recommended.

Physical gate level
~~~~~~~~~~~~~~~~~~~

On the physical gate level only gates are used that are physically available on
the target architecture. In some cases this may only be NAND, NOR and NOT gates
as well as D-Type registers. In other cases this might include cells that are
more complex than the cells used at the logical gate level (e.g. complete
half-adders). In the case of an FPGA-based design the physical gate level
representation is a netlist of LUTs with optional output registers, as these are
the basic building blocks of FPGA logic cells.

For the synthesis tool chain this abstraction is usually the lowest level. In
case of an ASIC-based design the cell library might contain further information
on how the physical cells map to individual switches (transistors).

Switch level
~~~~~~~~~~~~

A switch level representation of a circuit is a netlist utilizing single
transistors as cells. Switch level modelling is possible in Verilog and VHDL,
but is seldom used in modern designs, as in modern digital ASIC or FPGA flows
the physical gates are considered the atomic build blocks of the logic circuit.

Yosys
~~~~~

Yosys is a Verilog HDL synthesis tool. This means that it takes a behavioural
design description as input and generates an RTL, logical gate or physical gate
level description of the design as output. Yosys' main strengths are behavioural
and RTL synthesis. A wide range of commands (synthesis passes) exist within
Yosys that can be used to perform a wide range of synthesis tasks within the
domain of behavioural, RTL and logic synthesis. Yosys is designed to be
extensible and therefore is a good basis for implementing custom synthesis tools
for specialised tasks.

Features of synthesizable Verilog
---------------------------------

The subset of Verilog :cite:p:`Verilog2005` that is synthesizable is specified
in a separate IEEE standards document, the IEEE standard 1364.1-2002
:cite:p:`VerilogSynth`. This standard also describes how certain language
constructs are to be interpreted in the scope of synthesis.

This section provides a quick overview of the most important features of
synthesizable Verilog, structured in order of increasing complexity.

Structural Verilog
~~~~~~~~~~~~~~~~~~

Structural Verilog (also known as Verilog Netlists) is a Netlist in Verilog
syntax. Only the following language constructs are used in this
case:

-  Constant values
-  Wire and port declarations
-  Static assignments of signals to other signals
-  Cell instantiations

Many tools (especially at the back end of the synthesis chain) only support
structural Verilog as input. ABC is an example of such a tool. Unfortunately
there is no standard specifying what Structural Verilog actually is, leading to
some confusion about what syntax constructs are supported in structural Verilog
when it comes to features such as attributes or multi-bit signals.

Expressions in Verilog
~~~~~~~~~~~~~~~~~~~~~~

In all situations where Verilog accepts a constant value or signal name,
expressions using arithmetic operations such as ``+``, ``-`` and ``*``, boolean
operations such as ``&`` (AND), ``|`` (OR) and ``^`` (XOR) and many others
(comparison operations, unary operator, etc.) can also be used.

During synthesis these operators are replaced by cells that implement the
respective function.

Many FOSS tools that claim to be able to process Verilog in fact only support
basic structural Verilog and simple expressions. Yosys can be used to convert
full featured synthesizable Verilog to this simpler subset, thus enabling such
applications to be used with a richer set of Verilog features.

Behavioural modelling
~~~~~~~~~~~~~~~~~~~~~

Code that utilizes the Verilog always statement is using Behavioural Modelling.
In behavioural modelling, a circuit is described by means of imperative program
code that is executed on certain events, namely any change, a rising edge, or a
falling edge of a signal. This is a very flexible construct during simulation
but is only synthesizable when one
of the following is modelled:

-  | **Asynchronous or latched logic**
   | In this case the sensitivity list must contain all expressions that
     are used within the always block. The syntax ``@*`` can be used for
     these cases. Examples of this kind include:

   .. code:: verilog
      :number-lines:

      // asynchronous
      always @* begin
          if (add_mode)
              y <= a + b;
          else
              y <= a - b;
      end

      // latched
      always @* begin
          if (!hold)
              y <= a + b;
      end

   Note that latched logic is often considered bad style and in many
   cases just the result of sloppy HDL design. Therefore many synthesis
   tools generate warnings whenever latched logic is generated.

-  | **Synchronous logic (with optional synchronous reset)**
   | This is logic with d-type flip-flops on the output. In this case
     the sensitivity list must only contain the respective clock edge.
     Example:

   .. code:: verilog
      :number-lines:

      // counter with synchronous reset
      always @(posedge clk) begin
          if (reset)
              y <= 0;
          else
              y <= y + 1;
      end

-  | **Synchronous logic with asynchronous reset**
   | This is logic with d-type flip-flops with asynchronous resets on
     the output. In this case the sensitivity list must only contain the
     respective clock and reset edges. The values assigned in the reset
     branch must be constant. Example:

   .. code:: verilog
      :number-lines:

      // counter with asynchronous reset
      always @(posedge clk, posedge reset) begin
          if (reset)
              y <= 0;
          else
              y <= y + 1;
      end

Many synthesis tools support a wider subset of flip-flops that can be modelled
using always-statements (including Yosys). But only the ones listed above are
covered by the Verilog synthesis standard and when writing new designs one
should limit herself or himself to these cases.

In behavioural modelling, blocking assignments (=) and non-blocking assignments
(<=) can be used. The concept of blocking vs. non-blocking assignment is one of
the most misunderstood constructs in Verilog :cite:p:`Cummings00`.

The blocking assignment behaves exactly like an assignment in any imperative
programming language, while with the non-blocking assignment the right hand side
of the assignment is evaluated immediately but the actual update of the left
hand side register is delayed until the end of the time-step. For example the
Verilog code ``a <= b; b <= a;`` exchanges the values of the two registers.


Functions and tasks
~~~~~~~~~~~~~~~~~~~

Verilog supports Functions and Tasks to bundle statements that are used in
multiple places (similar to Procedures in imperative programming). Both
constructs can be implemented easily by substituting the function/task-call with
the body of the function or task.

Conditionals, loops and generate-statements

Verilog supports if-else-statements and for-loops inside
always-statements.

It also supports both features in generate-statements on the module level.
This can be used to selectively enable or disable parts of the module based on
the module parameters (if-else) or to generate a set of similar subcircuits
(for).

While the if-else-statement inside an always-block is part of behavioural
modelling, the three other cases are (at least for a synthesis tool) part of a
built-in macro processor. Therefore it must be possible for the synthesis tool
to completely unroll all loops and evaluate the condition in all
if-else-statement in generate-statements using const-folding..

Arrays and memories

text
Verilog supports arrays. This is in general a synthesizable language feature. In
most cases arrays can be synthesized by generating addressable memories.
However, when complex or asynchronous access patterns are used, it is not
possible to model an array as memory. In these cases the array must be modelled
using individual signals for each word and all accesses to the array must be
implemented using large multiplexers.

In some cases it would be possible to model an array using memories, but it is
not desired. Consider the following delay circuit:

.. code:: verilog
   :number-lines:

   module (clk, in_data, out_data);

   parameter BITS = 8;
   parameter STAGES = 4;

   input clk;
   input [BITS-1:0] in_data;
   output [BITS-1:0] out_data;
   reg [BITS-1:0] ffs [STAGES-1:0];

   integer i;
   always @(posedge clk) begin
       ffs[0] <= in_data;
       for (i = 1; i < STAGES; i = i+1)
           ffs[i] <= ffs[i-1];
   end

   assign out_data = ffs[STAGES-1];

   endmodule

This could be implemented using an addressable memory with STAGES input and
output ports. A better implementation would be to use a simple chain of
flip-flops (a so-called shift register). This better implementation can either
be obtained by first creating a memory-based implementation and then optimizing
it based on the static address signals for all ports or directly identifying
such situations in the language front end and converting all memory accesses to
direct accesses to the correct signals.

Challenges in digital circuit synthesis
---------------------------------------

This section summarizes the most important challenges in digital circuit
synthesis. Tools can be characterized by how well they address these topics.

Standards compliance

The most important challenge is compliance with the HDL standards in question
(in case of Verilog the IEEE Standards 1364.1-2002 and 1364-2005). This can be
broken down in two items:

  • Completeness of implementation of the standard
  • Correctness of implementation of the standard

Completeness is mostly important to guarantee compatibility with existing HDL
code. Once a design has been verified and tested, HDL designers are very
reluctant regarding changes to the design, even if it is only about a few minor
changes to work around a missing feature in a new synthesis tool.

Correctness is crucial. In some areas this is obvious (such as correct synthesis
of basic behavioural models). But it is also crucial for the areas that concern
minor details of the standard, such as the exact rules for handling signed
expressions, even when the HDL code does not target different synthesis tools.
This is because (unlike software source code that is only processed by
compilers), in most design flows HDL code is not only processed by the synthesis
tool but also by one or more simulators and sometimes even a formal verification
tool. It is key for this verification process that all these tools use the same
interpretation for the HDL code.

Optimizations

text
Generally it is hard to give a one-dimensional description of how well a
synthesis tool optimizes the design. First of all because not all optimizations
are applicable to all designs and all synthesis tasks. Some optimizations work
(best) on a coarse-grained level (with complex cells such as adders or
multipliers) and others work (best) on a fine-grained level (single bit gates).
Some optimizations target area and others target speed. Some work well on large
designs while others don't scale well and can only be applied to small designs.

A good tool is capable of applying a wide range of optimizations at different
levels of abstraction and gives the designer control over which optimizations
are performed (or skipped) and what the optimization goals are.

Technology mapping

Technology mapping is the process of converting the design into a netlist of
cells that are available in the target architecture. In an ASIC flow this might
be the process-specific cell library provided by the fab. In an FPGA flow this
might be LUT cells as well as special function units such as dedicated
multipliers. In a coarse-grain flow this might even be more complex special
function units.

An open and vendor independent tool is especially of interest if it supports a
wide range of different types of target architectures.

Script-based synthesis flows

A digital design is usually started by implementing a high-level or system-level
simulation of the desired function. This description is then manually
transformed (or re-implemented) into a synthesizable lower-level description
(usually at the behavioural level) and the equivalence of the two
representations is verified by simulating both and comparing the simulation
results.

Then the synthesizable description is transformed to lower-level representations
using a series of tools and the results are again verified using simulation.
This process is illustrated in :numref:Fig. %s <fig:Basics_flow>.

.. figure:: /_images/primer/basics_flow.*
:class: width-helper invert-helper
:name: fig:Basics_flow

text
Typical design flow.  Green boxes represent manually created models.
Orange boxes represent models generated by synthesis tools.

In this example the System Level Model and the Behavioural Model are both
manually written design files. After the equivalence of system level model and
behavioural model has been verified, the lower level representations of the
design can be generated using synthesis tools. Finally the RTL Model and the
Gate-Level Model are verified and the design process is finished.

However, in any real-world design effort there will be multiple iterations for
this design process. The reason for this can be the late change of a design
requirement or the fact that the analysis of a low-abstraction model
(e.g. gate-level timing analysis) revealed that a design change is required in
order to meet the design requirements (e.g. maximum possible clock speed).

Whenever the behavioural model or the system level model is changed their
equivalence must be re-verified by re-running the simulations and comparing the
results. Whenever the behavioural model is changed the synthesis must be re-run
and the synthesis results must be re-verified.

In order to guarantee reproducibility it is important to be able to re-run all
automatic steps in a design project with a fixed set of settings easily. Because
of this, usually all programs used in a synthesis flow can be controlled using
scripts. This means that all functions are available via text commands. When
such a tool provides a GUI, this is complementary to, and not instead of, a
command line interface.

Usually a synthesis flow in an UNIX/Linux environment would be controlled by a
shell script that calls all required tools (synthesis and
simulation/verification in this example) in the correct order. Each of these
tools would be called with a script file containing commands for the respective
tool. All settings required for the tool would be provided by these script files
so that no manual interaction would be necessary. These script files are
considered design sources and should be kept under version control just like the
source code of the system level and the behavioural model.

Methods from compiler design

Some parts of synthesis tools involve problem domains that are traditionally
known from compiler design. This section addresses some of these domains.

Lexing and parsing

text
The best known concepts from compiler design are probably lexing and parsing.
These are two methods that together can be used to process complex computer
languages easily. :cite:p:`Dragonbook`

A lexer consumes single characters from the input and generates a stream of
lexical tokens that consist of a type and a value. For example the Verilog input
:verilog:`assign foo = bar + 42;` might be translated by the lexer to the list
of lexical tokens given in :numref:`Tab. %s <tab:Basics_tokens>`.

.. table:: Exemplary token list for the statement :verilog:`assign foo = bar + 42;`
	:name: tab:Basics_tokens

	============== ===============
	Token-Type     Token-Value
	============== ===============
	TOK_ASSIGN     \-
	TOK_IDENTIFIER "foo"
	TOK_EQ         \-
	TOK_IDENTIFIER "bar"
	TOK_PLUS       \-
	TOK_NUMBER     42
	TOK_SEMICOLON  \-
	============== ===============

The lexer is usually generated by a lexer generator (e.g. flex) from a
description file that is using regular expressions to specify the text pattern
that should match the individual tokens.

The lexer is also responsible for skipping ignored characters (such as
whitespace outside string constants and comments in the case of Verilog) and
converting the original text snippet to a token value.

Note that individual keywords use different token types (instead of a keyword
type with different token values). This is because the parser usually can only
use the Token-Type to make a decision on the grammatical role of a token.

The parser then transforms the list of tokens into a parse tree that closely
resembles the productions from the computer languages grammar. As the lexer, the
parser is also typically generated by a code generator (e.g. bison) from a
grammar description in Backus-Naur Form (BNF).

Let's consider the following BNF (in Bison syntax):

.. code:: none
   :number-lines:

   assign_stmt: TOK_ASSIGN TOK_IDENTIFIER TOK_EQ expr TOK_SEMICOLON;
   expr: TOK_IDENTIFIER | TOK_NUMBER | expr TOK_PLUS expr;

.. figure:: /_images/primer/basics_parsetree.*
	:class: width-helper invert-helper
	:name: fig:Basics_parsetree

	Example parse tree for the Verilog expression
	:verilog:`assign foo = bar + 42;`

The parser converts the token list to the parse tree in :numref:`Fig. %s
<fig:Basics_parsetree>`. Note that the parse tree never actually exists as a
whole as data structure in memory. Instead the parser calls user-specified code
snippets (so-called reduce-functions) for all inner nodes of the parse tree in
depth-first order.

In some very simple applications (e.g. code generation for stack machines) it is
possible to perform the task at hand directly in the reduce functions. But
usually the reduce functions are only used to build an in-memory data structure
with the relevant information from the parse tree. This data structure is called
an abstract syntax tree (AST).

The exact format for the abstract syntax tree is application specific (while the
format of the parse tree and token list are mostly dictated by the grammar of
the language at hand). :numref:`Figure %s <fig:Basics_ast>` illustrates what an
AST for the parse tree in :numref:`Fig. %s <fig:Basics_parsetree>` could look
like.

Usually the AST is then converted into yet another representation that is more
suitable for further processing. In compilers this is often an assembler-like
three-address-code intermediate representation. :cite:p:`Dragonbook`

.. figure:: /_images/primer/basics_ast.*
	:class: width-helper invert-helper
	:name: fig:Basics_ast

	Example abstract syntax tree for the Verilog expression
	:verilog:`assign foo = bar + 42;`


Multi-pass compilation

Complex problems are often best solved when split up into smaller problems. This
is certainly true for compilers as well as for synthesis tools. The components
responsible for solving the smaller problems can be connected in two different
ways: through Single-Pass Pipelining and by using Multiple Passes.

Traditionally a parser and lexer are connected using the pipelined approach: The
lexer provides a function that is called by the parser. This function reads data
from the input until a complete lexical token has been read. Then this token is
returned to the parser. So the lexer does not first generate a complete list of
lexical tokens and then pass it to the parser. Instead they run concurrently and
the parser can consume tokens as the lexer produces them.

The single-pass pipelining approach has the advantage of lower memory footprint
(at no time must the complete design be kept in memory) but has the disadvantage
of tighter coupling between the interacting components.

Therefore single-pass pipelining should only be used when the lower memory
footprint is required or the components are also conceptually tightly coupled.
The latter certainly is the case for a parser and its lexer. But when data is
passed between two conceptually loosely coupled components it is often
beneficial to use a multi-pass approach.

In the multi-pass approach the first component processes all the data and the
result is stored in a in-memory data structure. Then the second component is
called with this data. This reduces complexity, as only one component is running
at a time. It also improves flexibility as components can be exchanged easier.

Most modern compilers are multi-pass compilers.

Static Single Assignment (SSA) form

text
In imperative programming (and behavioural HDL design) it is possible to assign
the same variable multiple times. This can either mean that the variable is
independently used in two different contexts or that the final value of the
variable depends on a condition.

The following examples show C code in which one variable is used independently
in two different contexts:

.. code:: c++
   :number-lines:

   void demo1()
   {
       int a = 1;
       printf("%d\n", a);

       a = 2;
       printf("%d\n", a);
   }

.. code:: c++

   void demo1()
   {
       int a = 1;
       printf("%d\n", a);

       int b = 2;
       printf("%d\n", b);
   }

.. code:: c++
   :number-lines:

   void demo2(bool foo)
   {
       int a;
       if (foo) {
           a = 23;
           printf("%d\n", a);
       } else {
           a = 42;
           printf("%d\n", a);
       }
   }

.. code:: c++

   void demo2(bool foo)
   {
       int a, b;
       if (foo) {
           a = 23;
           printf("%d\n", a);
       } else {
           b = 42;
           printf("%d\n", b);
       }
   }

In both examples the left version (only variable ``a``) and the right version
(variables ``a`` and ``b``) are equivalent. Therefore it is desired for further
processing to bring the code in an equivalent form for both cases.

In the following example the variable is assigned twice but it cannot be easily
replaced by two variables:

.. code:: c++

   void demo3(bool foo)
   {
       int a = 23
       if (foo)
           a = 42;
       printf("%d\n", a);
   }

Static single assignment (SSA) form is a representation of imperative code that
uses identical representations for the left and right version of demos 1 and 2,
but can still represent demo 3. In SSA form each assignment assigns a new
variable (usually written with an index). But it also introduces a special
:math:`\Phi`-function to merge the different instances of a variable when
needed. In C-pseudo-code the demo 3 would be written as follows using SSA from:

.. code:: c++

   void demo3(bool foo)
   {
       int a_1, a_2, a_3;
       a_1 = 23
       if (foo)
           a_2 = 42;
       a_3 = phi(a_1, a_2);
       printf("%d\n", a_3);
   }

The :math:`\Phi`-function is usually interpreted as "these variables must be
stored in the same memory location" during code generation. Most modern
compilers for imperative languages such as C/C++ use SSA form for at least some
of its passes as it is very easy to manipulate and analyse.

.. [1]
   In recent years formal equivalence checking also became an important
   verification method for validating RTL and lower abstraction
   representation of the design.

---

### Source Appendix Rtlil Text (`docs/source/appendix/rtlil_text.rst`)

.. _chapter:textrtlil:

RTLIL text representation
-------------------------

This appendix documents the text representation of RTLIL in extended Backus-Naur
form (EBNF).

The grammar is not meant to represent semantic limitations. That is, the grammar
is "permissive", and later stages of processing perform more rigorous checks.

The grammar is also not meant to represent the exact grammar used in the RTLIL
frontend, since that grammar is specific to processing by lex and yacc, is even
more permissive, and is somewhat less understandable than simple EBNF notation.

Finally, note that all statements (rules ending in ``-stmt``) terminate in an
end-of-line. Because of this, a statement cannot be broken into multiple lines.

Lexical elements
~~~~~~~~~~~~~~~~

Characters
^^^^^^^^^^

An RTLIL file is a stream of bytes. Strictly speaking, a "character" in an RTLIL
file is a single byte. The lexer treats multi-byte encoded characters as
consecutive single-byte characters. While other encodings *may* work, UTF-8 is
known to be safe to use. Byte order marks at the beginning of the file will
cause an error.

ASCII spaces (32) and tabs (9) separate lexer tokens.

A ``nonws`` character, used in identifiers, is any character whose encoding
consists solely of bytes above ASCII space (32).

An ``eol`` is one or more consecutive ASCII newlines (10) and carriage returns
(13).

Identifiers
^^^^^^^^^^^

There are two types of identifiers in RTLIL:

-  Publically visible identifiers
-  Auto-generated identifiers

.. code:: BNF

                ::=  | <autogen-id>
         ::= \ <nonws>+
    <autogen-id>    ::= $ <nonws>+

Values
^^^^^^

A *value* consists of a width in bits and a bit representation, most
significant bit first. Bits may be any of:

-  ``0``: A logic zero value
-  ``1``: A logic one value
-  ``x``: An unknown logic value (or don't care in case patterns)
-  ``z``: A high-impedance value (or don't care in case patterns)
-  ``m``: A marked bit (internal use only)
-  ``-``: A don't care value

When the bit representation has fewer bits than the width, it is padded to the width with
the most significant explicit bit, or ``0`` if the most significant explicit bit is ``1``,
or ``x`` if there are no explicit bits.

An *integer* is simply a signed integer value in decimal format. **Warning:**
Integer constants are limited to 32 bits. That is, they may only be in the range
:math:`[-2147483648, 2147483648)`. Integers outside this range will result in an
error.

.. code:: BNF

    <value>         ::= <decimal-digit>+ ' *
    <decimal-digit> ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
      ::= 0 | 1 | x | z | m | -
           ::= -? <decimal-digit>+

Strings
^^^^^^^

A string is a series of characters delimited by double-quote characters. Within
a string, any character except ASCII NUL (0) may be used. In addition, certain
escapes can be used:

-  ``\n``: A newline
-  ``\t``: A tab
-  ``\ooo``: A character specified as a one, two, or three digit octal value

All other characters may be escaped by a backslash, and become the following
character. Thus:

-  ``\\``: A backslash
-  ``\"``: A double-quote
-  ``\r``: An 'r' character

Comments
^^^^^^^^

A comment starts with a ``#`` character and proceeds to the end of the line. All
comments are ignored.

File
~~~~

A file consists of an optional autoindex statement followed by zero or more
modules.

.. code:: BNF

    <file> ::= <autoidx-stmt>? <module>*

Autoindex statements
^^^^^^^^^^^^^^^^^^^^

The autoindex statement sets the global autoindex value used by Yosys when it
needs to generate a unique name, e.g. ``flattenN``. The N part is filled with
the value of the global autoindex value, which is subsequently incremented. This
global has to be dumped into RTLIL, otherwise e.g. dumping and running a pass
would have different properties than just running a pass on a warm design.

.. code:: BNF

    <autoidx-stmt> ::= autoidx <integer> <eol>

Modules
^^^^^^^

Declares a module, with zero or more attributes, consisting of zero or more
wires, memories, cells, processes, and connections.

.. code:: BNF

    <module>            ::= <attr-stmt>* <module-stmt> <module-body> <module-end-stmt>
    <module-stmt>       ::= module <id> <eol>
    <module-body>       ::= (<param-stmt>
                         |   <conn-stmt>
                         |   <wire>
                         |   <memory>
                         |   <cell>
                         |   <process>)*
    <param-stmt>        ::= parameter <id> <constant>? <eol>
    <constant>          ::= <value> | <integer> | <string>
    <module-end-stmt>   ::= end <eol>

Attribute statements
^^^^^^^^^^^^^^^^^^^^

Declares an attribute with the given identifier and value.

.. code:: BNF

    <attr-stmt> ::= attribute <id> <constant> <eol>

Signal specifications
^^^^^^^^^^^^^^^^^^^^^

A signal is anything that can be applied to a cell port, i.e. a constant value,
all bits or a selection of bits from a wire, or concatenations of those.

**Warning:** When an integer constant is a sigspec, it is always 32 bits wide,
2's complement. For example, a constant of :math:`-1` is the same as
``32'11111111111111111111111111111111``, while a constant of :math:`1` is the
same as ``32'1``.

See :ref:`sec:rtlil_sigspec` for an overview of signal specifications.

.. code:: BNF

    <sigspec> ::= <constant>
               |  <wire-id>
               |  <sigspec> [ <integer> (:<integer>)? ]
               |  { <sigspec>* }

When a ``<wire-id>`` is specified, the wire must have been previously declared.

When a signal slice is specified, the left-hand integer must be greather than or
equal to the right-hand integer.

Connections
^^^^^^^^^^^

Declares a connection between the given signals.

.. code:: BNF

    <conn-stmt> ::= connect <sigspec> <sigspec> <eol>

Wires
^^^^^

Declares a wire, with zero or more attributes, with the given identifier and
options in the enclosing module.

See :ref:`sec:rtlil_cell_wire` for an overview of wires.

.. code:: BNF

    <wire>          ::= <attr-stmt>* <wire-stmt>
    <wire-stmt>     ::= wire <wire-option>* <wire-id> <eol>
    <wire-id>       ::= <id>
    <wire-option>   ::= width <integer>
                     |  offset <integer>
                     |  input <integer>
                     |  output <integer>
                     |  inout <integer>
                     |  upto
                     |  signed

Memories
^^^^^^^^

Declares a memory, with zero or more attributes, with the given identifier and
options in the enclosing module.

See :ref:`sec:rtlil_memory` for an overview of memory cells, and
:ref:`sec:memcells` for details about memory cell types.

.. code:: BNF

    <memory>        ::= <attr-stmt>* <memory-stmt>
    <memory-stmt>   ::= memory <memory-option>* <id> <eol>
    <memory-option> ::= width <integer>
                     |  size <integer>
                     |  offset <integer>

Cells
^^^^^

Declares a cell, with zero or more attributes, with the given identifier and
type in the enclosing module.

Cells perform functions on input signals. See :doc:`/cell_index` for a detailed
list of cell types.

.. code:: BNF

    <cell>              ::= <attr-stmt>* <cell-stmt> <cell-body-stmt>* <cell-end-stmt>
    <cell-stmt>         ::= cell <cell-type> <cell-id> <eol>
    <cell-id>           ::= <id>
    <cell-type>         ::= <id>
    <cell-body-stmt>    ::= parameter (signed | real)? <id> <constant> <eol>
                         |  connect <id> <sigspec> <eol>
    <cell-end-stmt>     ::= end <eol>


Processes
^^^^^^^^^

Declares a process, with zero or more attributes, with the given identifier in
the enclosing module. The body of a process consists of zero or more
assignments followed by zero or more switches and zero or more syncs.

See :ref:`sec:rtlil_process` for an overview of processes.

.. code:: BNF

    <process>       ::= <attr-stmt>* <proc-stmt> <process-body> <proc-end-stmt>
    <proc-stmt>     ::= process <id> <eol>
    <process-body>  ::= <assign-stmt>* <switch>* <sync>*
    <assign-stmt>   ::= assign <dest-sigspec> <src-sigspec> <eol>
    <dest-sigspec>  ::= <sigspec>
    <src-sigspec>   ::= <sigspec>
    <proc-end-stmt> ::= end <eol>

Switches
^^^^^^^^

Switches test a signal for equality against a list of cases. Each case specifies
a comma-separated list of signals to check against. If there are no signals in
the list, then the case is the default case. The body of a case consists of zero
or more assignments followed by zero or more switches. Both switches and cases
may have zero or more attributes.

.. code:: BNF

    <switch>            ::= <switch-stmt> <case>* <switch-end-stmt>
    <switch-stmt>       ::= <attr-stmt>* switch <sigspec> <eol>
    <case>              ::= <attr-stmt>* <case-stmt> <case-body>
    <case-stmt>         ::= case <compare>? <eol>
    <compare>           ::= <sigspec> (, <sigspec>)*
    <case-body>         ::= <assign-stmt>* <switch>*
    <switch-end-stmt>   ::= end <eol>

Syncs
^^^^^

Syncs update signals with other signals when an event happens. Such an event may
be:

-  An edge or level on a signal
-  Global clock ticks
-  Initialization
-  Always

.. code:: BNF

    <sync>          ::= <sync-stmt> <update-stmt>*
    <sync-stmt>     ::= sync <sync-type> <sigspec> <eol>
                     |  sync global <eol>
                     |  sync init <eol>
                     |  sync always <eol>
    <sync-type>     ::= low | high | posedge | negedge | edge
    <update-stmt>   ::= update <dest-sigspec> <src-sigspec> <eol>
                     |  <attr-stmt>* memwr <id> <sigspec> <sigspec> <sigspec> <constant> <eol>

---

### Source Cell Gate Comb Combined (`docs/source/cell/gate_comb_combined.rst`)

.. role:: verilog(code)
   :language: Verilog

Combinatorial cells (combined)
------------------------------

These cells combine two or more combinatorial cells (simple) into a single cell.

.. table:: Cell types for gate level combinatorial cells (combined)

   ======================================= =============
   Verilog                                 Cell Type
   ======================================= =============
   :verilog:`Y = A & ~B`                   `$_ANDNOT_`
   :verilog:`Y = A | ~B`                   `$_ORNOT_`
   :verilog:`Y = ~((A & B) | C)`           `$_AOI3_`
   :verilog:`Y = ~((A | B) & C)`           `$_OAI3_`
   :verilog:`Y = ~((A & B) | (C & D))`     `$_AOI4_`
   :verilog:`Y = ~((A | B) & (C | D))`     `$_OAI4_`
   :verilog:`Y = ~(S ? B : A)`             `$_NMUX_`
   (see below)                             `$_MUX4_`
   (see below)                             `$_MUX8_`
   (see below)                             `$_MUX16_`
   ======================================= =============

The `$_MUX4_`, `$_MUX8_` and `$_MUX16_` cells are used to model wide muxes, and
correspond to the following Verilog code:

.. code-block:: verilog
   :force:

   // $_MUX4_
   assign Y = T ? (S ? D : C) :
                  (S ? B : A);
   // $_MUX8_
   assign Y = U ? T ? (S ? H : G) :
                      (S ? F : E) :
                  T ? (S ? D : C) :
                      (S ? B : A);
   // $_MUX16_
   assign Y = V ? U ? T ? (S ? P : O) :
                          (S ? N : M) :
                      T ? (S ? L : K) :
                          (S ? J : I) :
                  U ? T ? (S ? H : G) :
                          (S ? F : E) :
                      T ? (S ? D : C) :
                          (S ? B : A);

.. autocellgroup:: comb_combined
   :members:
   :source:
   :linenos:

---

### Source Cell Gate Comb Simple (`docs/source/cell/gate_comb_simple.rst`)

.. role:: verilog(code)
   :language: Verilog

Combinatorial cells (simple)
----------------------------

.. table:: Cell types for gate level combinatorial cells (simple)

   ======================================= =============
   Verilog                                 Cell Type
   ======================================= =============
   :verilog:`Y = A`                        `$_BUF_`
   :verilog:`Y = ~A`                       `$_NOT_`
   :verilog:`Y = A & B`                    `$_AND_`
   :verilog:`Y = ~(A & B)`                 `$_NAND_`
   :verilog:`Y = A | B`                    `$_OR_`
   :verilog:`Y = ~(A | B)`                 `$_NOR_`
   :verilog:`Y = A ^ B`                    `$_XOR_`
   :verilog:`Y = ~(A ^ B)`                 `$_XNOR_`
   :verilog:`Y = S ? B : A`                `$_MUX_`
   ======================================= =============

.. autocellgroup:: comb_simple
   :members:
   :source:
   :linenos:

---

### Source Cell Gate Other (`docs/source/cell/gate_other.rst`)

Other gate-level cells
----------------------

.. autocellgroup:: gate_other
   :caption: Other gate-level cells
   :members:
   :source:
   :linenos:

---

### Source Cell Gate Reg Ff (`docs/source/cell/gate_reg_ff.rst`)

.. role:: verilog(code)
   :language: Verilog

Flip-flop cells
---------------

The cell types `$_DFF_N_` and `$_DFF_P_` represent d-type flip-flops.

.. table:: Cell types for basic flip-flops

   ======================================= =============
   Verilog                                 Cell Type
   ======================================= =============
   :verilog:`always @(negedge C) Q <= D`   `$_DFF_N_`
   :verilog:`always @(posedge C) Q <= D`   `$_DFF_P_`
   ======================================= =============

The cell types ``$_DFFE_[NP][NP]_`` implement d-type flip-flops with enable. The
values in the table for these cell types relate to the following Verilog code
template.

.. code-block:: verilog
   :force:

   always @(CLK_EDGE C)
      if (EN == EN_LVL)
         Q <= D;


.. table:: Cell types for gate level logic networks (FFs with enable)
   :name: tab:CellLib_gates_dffe

   ================== ============= ============
   :math:`ClkEdge`    :math:`EnLvl` Cell Type
   ================== ============= ============
   :verilog:`negedge` ``0``         `$_DFFE_NN_`
   :verilog:`negedge` ``1``         `$_DFFE_NP_`
   :verilog:`posedge` ``0``         `$_DFFE_PN_`
   :verilog:`posedge` ``1``         `$_DFFE_PP_`
   ================== ============= ============

The cell types ``$_DFF_[NP][NP][01]_`` implement d-type flip-flops with
asynchronous reset. The values in the table for these cell types relate to the
following Verilog code template, where ``RST_EDGE`` is ``posedge`` if
``RST_LVL`` if ``1``, and ``negedge`` otherwise.

.. code-block:: verilog
   :force:

   always @(CLK_EDGE C, RST_EDGE R)
      if (R == RST_LVL)
         Q <= RST_VAL;
      else
         Q <= D;

The cell types ``$_SDFF_[NP][NP][01]_`` implement d-type flip-flops with
synchronous reset. The values in the table for these cell types relate to the
following Verilog code template:

.. code-block:: verilog
   :force:

   always @(CLK_EDGE C)
      if (R == RST_LVL)
         Q <= RST_VAL;
      else
         Q <= D;

.. table:: Cell types for gate level logic networks (FFs with reset)
   :name: tab:CellLib_gates_adff

   ================== ============== ============== ===========================
   :math:`ClkEdge`    :math:`RstLvl` :math:`RstVal` Cell Type
   ================== ============== ============== ===========================
   :verilog:`negedge` ``0``          ``0``          `$_DFF_NN0_`, `$_SDFF_NN0_`
   :verilog:`negedge` ``0``          ``1``          `$_DFF_NN1_`, `$_SDFF_NN1_`
   :verilog:`negedge` ``1``          ``0``          `$_DFF_NP0_`, `$_SDFF_NP0_`
   :verilog:`negedge` ``1``          ``1``          `$_DFF_NP1_`, `$_SDFF_NP1_`
   :verilog:`posedge` ``0``          ``0``          `$_DFF_PN0_`, `$_SDFF_PN0_`
   :verilog:`posedge` ``0``          ``1``          `$_DFF_PN1_`, `$_SDFF_PN1_`
   :verilog:`posedge` ``1``          ``0``          `$_DFF_PP0_`, `$_SDFF_PP0_`
   :verilog:`posedge` ``1``          ``1``          `$_DFF_PP1_`, `$_SDFF_PP1_`
   ================== ============== ============== ===========================

The cell types ``$_DFFE_[NP][NP][01][NP]_`` implement d-type flip-flops with
asynchronous reset and enable. The values in the table for these cell types
relate to the following Verilog code template, where ``RST_EDGE`` is ``posedge``
if ``RST_LVL`` if ``1``, and ``negedge`` otherwise.

.. code-block:: verilog
   :force:

   always @(CLK_EDGE C, RST_EDGE R)
      if (R == RST_LVL)
         Q <= RST_VAL;
      else if (EN == EN_LVL)
         Q <= D;

The cell types ``$_SDFFE_[NP][NP][01][NP]_`` implement d-type flip-flops with
synchronous reset and enable, with reset having priority over enable. The values
in the table for these cell types relate to the following Verilog code template:

.. code-block:: verilog
   :force:

   always @(CLK_EDGE C)
      if (R == RST_LVL)
         Q <= RST_VAL;
      else if (EN == EN_LVL)
         Q <= D;

The cell types ``$_SDFFCE_[NP][NP][01][NP]_`` implement d-type flip-flops with
synchronous reset and enable, with enable having priority over reset. The values
in the table for these cell types relate to the following Verilog code template:

.. code-block:: verilog
   :force:

   always @(CLK_EDGE C)
      if (EN == EN_LVL)
         if (R == RST_LVL)
            Q <= RST_VAL;
         else
            Q <= D;


.. table:: Cell types for gate level logic networks (FFs with reset and enable)
   :name: tab:CellLib_gates_adffe

   ================== ============== ============== ============= =================================================
   :math:`ClkEdge`    :math:`RstLvl` :math:`RstVal` :math:`EnLvl` Cell Type
   ================== ============== ============== ============= =================================================
   :verilog:`negedge` ``0``          ``0``          ``0``         `$_DFFE_NN0N_`, `$_SDFFE_NN0N_`, `$_SDFFCE_NN0N_`
   :verilog:`negedge` ``0``          ``0``          ``1``         `$_DFFE_NN0P_`, `$_SDFFE_NN0P_`, `$_SDFFCE_NN0P_`
   :verilog:`negedge` ``0``          ``1``          ``0``         `$_DFFE_NN1N_`, `$_SDFFE_NN1N_`, `$_SDFFCE_NN1N_`
   :verilog:`negedge` ``0``          ``1``          ``1``         `$_DFFE_NN1P_`, `$_SDFFE_NN1P_`, `$_SDFFCE_NN1P_`
   :verilog:`negedge` ``1``          ``0``          ``0``         `$_DFFE_NP0N_`, `$_SDFFE_NP0N_`, `$_SDFFCE_NP0N_`
   :verilog:`negedge` ``1``          ``0``          ``1``         `$_DFFE_NP0P_`, `$_SDFFE_NP0P_`, `$_SDFFCE_NP0P_`
   :verilog:`negedge` ``1``          ``1``          ``0``         `$_DFFE_NP1N_`, `$_SDFFE_NP1N_`, `$_SDFFCE_NP1N_`
   :verilog:`negedge` ``1``          ``1``          ``1``         `$_DFFE_NP1P_`, `$_SDFFE_NP1P_`, `$_SDFFCE_NP1P_`
   :verilog:`posedge` ``0``          ``0``          ``0``         `$_DFFE_PN0N_`, `$_SDFFE_PN0N_`, `$_SDFFCE_PN0N_`
   :verilog:`posedge` ``0``          ``0``          ``1``         `$_DFFE_PN0P_`, `$_SDFFE_PN0P_`, `$_SDFFCE_PN0P_`
   :verilog:`posedge` ``0``          ``1``          ``0``         `$_DFFE_PN1N_`, `$_SDFFE_PN1N_`, `$_SDFFCE_PN1N_`
   :verilog:`posedge` ``0``          ``1``          ``1``         `$_DFFE_PN1P_`, `$_SDFFE_PN1P_`, `$_SDFFCE_PN1P_`
   :verilog:`posedge` ``1``          ``0``          ``0``         `$_DFFE_PP0N_`, `$_SDFFE_PP0N_`, `$_SDFFCE_PP0N_`
   :verilog:`posedge` ``1``          ``0``          ``1``         `$_DFFE_PP0P_`, `$_SDFFE_PP0P_`, `$_SDFFCE_PP0P_`
   :verilog:`posedge` ``1``          ``1``          ``0``         `$_DFFE_PP1N_`, `$_SDFFE_PP1N_`, `$_SDFFCE_PP1N_`
   :verilog:`posedge` ``1``          ``1``          ``1``         `$_DFFE_PP1P_`, `$_SDFFE_PP1P_`, `$_SDFFCE_PP1P_`
   ================== ============== ============== ============= =================================================

The cell types ``$_DFFSR_[NP][NP][NP]_`` implement d-type flip-flops with
asynchronous set and reset. The values in the table for these cell types relate
to the following Verilog code template, where ``RST_EDGE`` is ``posedge`` if
``RST_LVL`` if ``1``, ``negedge`` otherwise, and ``SET_EDGE`` is ``posedge`` if
``SET_LVL`` if ``1``, ``negedge`` otherwise.

When both set and reset are active, the state and output is undefined. The Verilog
code model does not correspond to this due to limitations
of synthesizable Verilog.

.. code-block:: verilog
   :force:

   always @(CLK_EDGE C, RST_EDGE R, SET_EDGE S)
      if (R == RST_LVL)
         Q <= 0;
      else if (S == SET_LVL)
         Q <= 1;
      else
         Q <= D;

.. table:: Cell types for gate level logic networks (FFs with set and reset)
   :name: tab:CellLib_gates_dffsr

   ================== ============== ============== ==============
   :math:`ClkEdge`    :math:`SetLvl` :math:`RstLvl` Cell Type
   ================== ============== ============== ==============
   :verilog:`negedge` ``0``          ``0``          `$_DFFSR_NNN_`
   :verilog:`negedge` ``0``          ``1``          `$_DFFSR_NNP_`
   :verilog:`negedge` ``1``          ``0``          `$_DFFSR_NPN_`
   :verilog:`negedge` ``1``          ``1``          `$_DFFSR_NPP_`
   :verilog:`posedge` ``0``          ``0``          `$_DFFSR_PNN_`
   :verilog:`posedge` ``0``          ``1``          `$_DFFSR_PNP_`
   :verilog:`posedge` ``1``          ``0``          `$_DFFSR_PPN_`
   :verilog:`posedge` ``1``          ``1``          `$_DFFSR_PPP_`
   ================== ============== ============== ==============

The cell types ``$_DFFSRE_[NP][NP][NP][NP]_`` implement d-type flip-flops with
asynchronous set and reset and enable. The values in the table for these cell
types relate to the following Verilog code template, where ``RST_EDGE`` is
``posedge`` if ``RST_LVL`` if ``1``, ``negedge`` otherwise, and ``SET_EDGE`` is
``posedge`` if ``SET_LVL`` if ``1``, ``negedge`` otherwise.

When both set and reset are active, the state and output is undefined. The Verilog
code model does not correspond to this due to limitations
of synthesizable Verilog.

.. code-block:: verilog
   :force:

   always @(CLK_EDGE C, RST_EDGE R, SET_EDGE S)
      if (R == RST_LVL)
         Q <= 0;
      else if (S == SET_LVL)
         Q <= 1;
      else if (E == EN_LVL)
         Q <= D;


.. table:: Cell types for gate level logic networks (FFs with set and reset and enable)
   :name: tab:CellLib_gates_dffsre

   ================== ============== ============== ============= ================
   :math:`ClkEdge`    :math:`SetLvl` :math:`RstLvl` :math:`EnLvl` Cell Type
   ================== ============== ============== ============= ================
   :verilog:`negedge` ``0``          ``0``          ``0``         `$_DFFSRE_NNNN_`
   :verilog:`negedge` ``0``          ``0``          ``1``         `$_DFFSRE_NNNP_`
   :verilog:`negedge` ``0``          ``1``          ``0``         `$_DFFSRE_NNPN_`
   :verilog:`negedge` ``0``          ``1``          ``1``         `$_DFFSRE_NNPP_`
   :verilog:`negedge` ``1``          ``0``          ``0``         `$_DFFSRE_NPNN_`
   :verilog:`negedge` ``1``          ``0``          ``1``         `$_DFFSRE_NPNP_`
   :verilog:`negedge` ``1``          ``1``          ``0``         `$_DFFSRE_NPPN_`
   :verilog:`negedge` ``1``          ``1``          ``1``         `$_DFFSRE_NPPP_`
   :verilog:`posedge` ``0``          ``0``          ``0``         `$_DFFSRE_PNNN_`
   :verilog:`posedge` ``0``          ``0``          ``1``         `$_DFFSRE_PNNP_`
   :verilog:`posedge` ``0``          ``1``          ``0``         `$_DFFSRE_PNPN_`
   :verilog:`posedge` ``0``          ``1``          ``1``         `$_DFFSRE_PNPP_`
   :verilog:`posedge` ``1``          ``0``          ``0``         `$_DFFSRE_PPNN_`
   :verilog:`posedge` ``1``          ``0``          ``1``         `$_DFFSRE_PPNP_`
   :verilog:`posedge` ``1``          ``1``          ``0``         `$_DFFSRE_PPPN_`
   :verilog:`posedge` ``1``          ``1``          ``1``         `$_DFFSRE_PPPP_`
   ================== ============== ============== ============= ================

.. todo:: flip-flops with async load, ``$_ALDFFE?_[NP]{2,3}_``

.. autocellgroup:: reg_ff
   :members:
   :source:
   :linenos:

---

### Source Cell Gate Reg Latch (`docs/source/cell/gate_reg_latch.rst`)

.. role:: verilog(code)
   :language: Verilog

Latch cells
-----------

The cell types `$_DLATCH_N_` and `$_DLATCH_P_` represent d-type latches.

.. table:: Cell types for basic latches

   ======================================= =============
   Verilog                                 Cell Type
   ======================================= =============
   :verilog:`always @* if (!E) Q <= D`     `$_DLATCH_N_`
   :verilog:`always @* if (E)  Q <= D`     `$_DLATCH_P_`
   ======================================= =============

The cell types ``$_DLATCH_[NP][NP][01]_`` implement d-type latches with reset.
The values in the table for these cell types relate to the following Verilog
code template:

.. code-block:: verilog
   :force:

   always @*
      if (R == RST_LVL)
         Q <= RST_VAL;
      else if (E == EN_LVL)
         Q <= D;

.. table:: Cell types for gate level logic networks (latches with reset)
   :name: tab:CellLib_gates_adlatch

   ============= ============== ============== ===============
   :math:`EnLvl` :math:`RstLvl` :math:`RstVal` Cell Type
   ============= ============== ============== ===============
   ``0``         ``0``          ``0``          `$_DLATCH_NN0_`
   ``0``         ``0``          ``1``          `$_DLATCH_NN1_`
   ``0``         ``1``          ``0``          `$_DLATCH_NP0_`
   ``0``         ``1``          ``1``          `$_DLATCH_NP1_`
   ``1``         ``0``          ``0``          `$_DLATCH_PN0_`
   ``1``         ``0``          ``1``          `$_DLATCH_PN1_`
   ``1``         ``1``          ``0``          `$_DLATCH_PP0_`
   ``1``         ``1``          ``1``          `$_DLATCH_PP1_`
   ============= ============== ============== ===============

The cell types ``$_DLATCHSR_[NP][NP][NP]_`` implement d-type latches with set
and reset. The values in the table for these cell types relate to the following
Verilog code template:

.. code-block:: verilog
   :force:

   always @*
      if (R == RST_LVL)
         Q <= 0;
      else if (S == SET_LVL)
         Q <= 1;
      else if (E == EN_LVL)
         Q <= D;

.. table:: Cell types for gate level logic networks (latches with set and reset)
   :name: tab:CellLib_gates_dlatchsr

   ============= ============== ============== =================
   :math:`EnLvl` :math:`SetLvl` :math:`RstLvl` Cell Type
   ============= ============== ============== =================
   ``0``         ``0``          ``0``          `$_DLATCHSR_NNN_`
   ``0``         ``0``          ``1``          `$_DLATCHSR_NNP_`
   ``0``         ``1``          ``0``          `$_DLATCHSR_NPN_`
   ``0``         ``1``          ``1``          `$_DLATCHSR_NPP_`
   ``1``         ``0``          ``0``          `$_DLATCHSR_PNN_`
   ``1``         ``0``          ``1``          `$_DLATCHSR_PNP_`
   ``1``         ``1``          ``0``          `$_DLATCHSR_PPN_`
   ``1``         ``1``          ``1``          `$_DLATCHSR_PPP_`
   ============= ============== ============== =================

The cell types ``$_SR_[NP][NP]_`` implement sr-type latches. The values in the
table for these cell types relate to the following Verilog code template:

.. code-block:: verilog
   :force:

   always @*
      if (R == RST_LVL)
         Q <= 0;
      else if (S == SET_LVL)
         Q <= 1;

.. table:: Cell types for gate level logic networks (SR latches)
   :name: tab:CellLib_gates_sr

   ============== ============== ==========
   :math:`SetLvl` :math:`RstLvl` Cell Type
   ============== ============== ==========
   ``0``          ``0``          `$_SR_NN_`
   ``0``          ``1``          `$_SR_NP_`
   ``1``          ``0``          `$_SR_PN_`
   ``1``          ``1``          `$_SR_PP_`
   ============== ============== ==========

.. autocellgroup:: reg_latch
   :members:
   :source:
   :linenos:

---

### Source Cell Index Gate (`docs/source/cell/index_gate.rst`)

.. _sec:celllib_gates:

Gate-level cells
----------------

For gate level logic networks, fixed function single bit cells are used that do
not provide any parameters.

Simulation models for these cells can be found in the file
:file:`techlibs/common/simcells.v` in the Yosys source tree.

In most cases gate level logic networks are created from RTL networks using the
techmap pass. The flip-flop cells from the gate level logic network can be
mapped to physical flip-flop cells from a Liberty file using the dfflibmap pass.
The combinatorial logic cells can be mapped to physical cells from a Liberty
file via ABC using the abc pass.

.. toctree::
   :maxdepth: 2

   /cell/gate_comb_simple
   /cell/gate_comb_combined
   /cell/gate_reg_ff
   /cell/gate_reg_latch
   /cell/gate_other

---

### Source Cell Index Word (`docs/source/cell/index_word.rst`)

Word-level cells
----------------

Most of the RTL cells closely resemble the operators available in HDLs such as
Verilog or VHDL. Therefore Verilog operators are used in the following sections
to define the behaviour of the RTL cells.

Note that all RTL cells have parameters indicating the size of inputs and
outputs. When passes modify RTL cells they must always keep the values of these
parameters in sync with the size of the signals connected to the inputs and
outputs.

Simulation models for the RTL cells can be found in the file
:file:`techlibs/common/simlib.v` in the Yosys source tree.

.. toctree::
   :maxdepth: 2

   /cell/word_unary
   /cell/word_binary
   /cell/word_mux
   /cell/word_reg
   /cell/word_mem
   /cell/word_fsm
   /cell/word_arith
   /cell/word_logic
   /cell/word_spec
   /cell/word_formal
   /cell/word_debug
   /cell/word_wire

---

### Source Cell Properties (`docs/source/cell/properties.rst`)

Cell properties
---------------

.. cell:defprop:: is_evaluable

   These cells are able to be used in conjunction with the `eval` command.  Some
   passes, such as `opt_expr`, may also be able to perform additional
   optimizations on cells which are evaluable.

.. cell:defprop:: x-aware

   Some passes will treat these cells as the non 'x' aware cell.  For example,
   during synthesis `$eqx` will typically be treated as `$eq`.

.. cell:defprop:: x-output

   These cells can produce 'x' output even if all inputs are defined.  For
   example, a `$div` cell with divisor (``B``) equal to zero has undefined
   output.

Refer to the :ref:`propindex` for the list of cells with a given property.

---

### Source Cell Word Arith (`docs/source/cell/word_arith.rst`)

Coarse arithmetics
------------------

.. todo:: Add information about `$alu`, `$fa`, `$macc_v2`, and `$lcu` cells.

The `$macc` cell type represents a generalized multiply and accumulate
operation. The cell is purely combinational. It outputs the result of summing up
a sequence of products and other injected summands.

.. code-block::

   Y = 0 +- a0factor1 * a0factor2 +- a1factor1 * a1factor2 +- ...
        + B[0] + B[1] + ...

The A port consists of concatenated pairs of multiplier inputs ("factors"). A
zero length factor2 acts as a constant 1, turning factor1 into a simple summand.

In this pseudocode, ``u(foo)`` means an unsigned int that's foo bits long.

.. code-block::

   struct A {
      u(CONFIG.mul_info[0].factor1_len) a0factor1;
      u(CONFIG.mul_info[0].factor2_len) a0factor2;
      u(CONFIG.mul_info[1].factor1_len) a1factor1;
      u(CONFIG.mul_info[1].factor2_len) a1factor2;
      ...
   };

The cell's ``CONFIG`` parameter determines the layout of cell port ``A``. The
CONFIG parameter carries the following information:

.. code-block::

   struct CONFIG {
      u4 num_bits;
      struct mul_info {
         bool is_signed;
         bool is_subtract;
         u(num_bits) factor1_len;
         u(num_bits) factor2_len;
      }[num_ports];
   };

B is an array of concatenated 1-bit-wide unsigned integers to also be summed up.

.. autocellgroup:: arith
   :members:
   :source:
   :linenos:

---

### Source Cell Word Binary (`docs/source/cell/word_binary.rst`)

.. role:: verilog(code)
   :language: Verilog

Binary operators
~~~~~~~~~~~~~~~~

All binary RTL cells have two input ports ``A`` and ``B`` and one output port
``Y``. They also have the following parameters:

``A_SIGNED``
   Set to a non-zero value if the input ``A`` is signed and therefore should be
   sign-extended when needed.

``A_WIDTH``
   The width of the input port ``A``.

``B_SIGNED``
   Set to a non-zero value if the input ``B`` is signed and therefore should be
   sign-extended when needed.

``B_WIDTH``
   The width of the input port ``B``.

``Y_WIDTH``
   The width of the output port ``Y``.

.. table:: Cell types for binary operators with their corresponding Verilog expressions.

   ======================= =============== ======================= ===========
   Verilog                 Cell Type       Verilog                 Cell Type
   ======================= =============== ======================= ===========
   :verilog:`Y = A  & B`   `$and`          :verilog:`Y = A ** B`   `$pow`
   :verilog:`Y = A  | B`   `$or`           :verilog:`Y = A <  B`   `$lt`
   :verilog:`Y = A  ^ B`   `$xor`          :verilog:`Y = A <= B`   `$le`
   :verilog:`Y = A ~^ B`   `$xnor`         :verilog:`Y = A == B`   `$eq`
   :verilog:`Y = A << B`   `$shl`          :verilog:`Y = A != B`   `$ne`
   :verilog:`Y = A >> B`   `$shr`          :verilog:`Y = A >= B`   `$ge`
   :verilog:`Y = A <<< B`  `$sshl`         :verilog:`Y = A >  B`   `$gt`
   :verilog:`Y = A >>> B`  `$sshr`         :verilog:`Y = A  + B`   `$add`
   :verilog:`Y = A && B`   `$logic_and`    :verilog:`Y = A  - B`   `$sub`
   :verilog:`Y = A || B`   `$logic_or`     :verilog:`Y = A  * B`   `$mul`
   :verilog:`Y = A === B`  `$eqx`          :verilog:`Y = A  / B`   `$div`
   :verilog:`Y = A !== B`  `$nex`          :verilog:`Y = A  % B`   `$mod`
   ``N/A``                 `$shift`        ``N/A``                 `$divfloor`
   ``N/A``                 `$shiftx`       ``N/A``                 `$modfloor`
   ======================= =============== ======================= ===========

The `$shl` and `$shr` cells implement logical shifts, whereas the `$sshl` and
`$sshr` cells implement arithmetic shifts. The `$shl` and `$sshl` cells
implement the same operation. All four of these cells interpret the second
operand as unsigned, and require ``B_SIGNED`` to be zero.

Two additional shift operator cells are available that do not directly
correspond to any operator in Verilog, `$shift` and `$shiftx`. The `$shift` cell
performs a right logical shift if the second operand is positive (or unsigned),
and a left logical shift if it is negative. The `$shiftx` cell performs the same
operation as the `$shift` cell, but the vacated bit positions are filled with
undef (x) bits, and corresponds to the Verilog indexed part-select expression.

For the binary cells that output a logical value (`$logic_and`, `$logic_or`,
`$eqx`, `$nex`, `$lt`, `$le`, `$eq`, `$ne`, `$ge`, `$gt`), when the ``Y_WIDTH``
parameter is greater than 1, the output is zero-extended, and only the least
significant bit varies.

Division and modulo cells are available in two rounding modes. The original
`$div` and `$mod` cells are based on truncating division, and correspond to the
semantics of the verilog ``/`` and ``%`` operators. The `$divfloor` and
`$modfloor` cells represent flooring division and flooring modulo, the latter of
which corresponds to the ``%`` operator in Python. See the following table for a
side-by-side comparison between the different semantics.

.. table:: Comparison between different rounding modes for division and modulo cells.

   +-----------+--------+-----------+-----------+-----------+-----------+
   | Division  | Result |      Truncating       |        Flooring       |
   +-----------+--------+-----------+-----------+-----------+-----------+
   |           |        | $div      | $mod      | $divfloor | $modfloor |
   +===========+========+===========+===========+===========+===========+
   | -10 / 3   | -3.3   | -3        |        -1 | -4        |  2        |
   +-----------+--------+-----------+-----------+-----------+-----------+
   | 10 / -3   | -3.3   | -3        |         1 | -4        | -2        |
   +-----------+--------+-----------+-----------+-----------+-----------+
   | -10 / -3  |  3.3   |  3        |        -1 |  3        | -1        |
   +-----------+--------+-----------+-----------+-----------+-----------+
   | 10 / 3    |  3.3   |  3        |         1 |  3        |  1        |
   +-----------+--------+-----------+-----------+-----------+-----------+

.. autocellgroup:: binary
   :members:
   :source:
   :linenos:

---

### Source Cell Word Debug (`docs/source/cell/word_debug.rst`)

.. role:: verilog(code)
   :language: Verilog

Debugging cells
---------------

The `$print` cell is used to log the values of signals, akin to (and
translatable to) the ``$display`` and ``$write`` family of tasks in Verilog.  It
has the following parameters:

``FORMAT``
   The internal format string.  The syntax is described below.

``ARGS_WIDTH``
   The width (in bits) of the signal on the ``ARGS`` port.

``TRG_ENABLE``
   True if triggered on specific signals defined in ``TRG``; false if triggered
   whenever ``ARGS`` or ``EN`` change and ``EN`` is 1.

If ``TRG_ENABLE`` is true, the following parameters also apply:

``TRG_WIDTH``
   The number of bits in the ``TRG`` port.

``TRG_POLARITY``
   For each bit in ``TRG``, 1 if that signal is positive-edge triggered, 0 if
   negative-edge triggered.

``PRIORITY``
   When multiple `$print` or `$check` cells fire on the same trigger, they
   execute in descending priority order.

Ports:

``TRG``
   The signals that control when this `$print` cell is triggered.

   If the width of this port is zero and ``TRG_ENABLE`` is true, the cell is
   triggered during initial evaluation (time zero) only.

``EN``
   Enable signal for the whole cell.

``ARGS``
   The values to be displayed, in format string order.

.. autocellgroup:: debug
   :members:
   :source:
   :linenos:

Format string syntax
~~~~~~~~~~~~~~~~~~~~

The format string syntax resembles Python f-strings.  Regular text is passed
through unchanged until a format specifier is reached, starting with a ``{``.

Format specifiers have the following syntax.  Unless noted, all items are
required:

``{``
   Denotes the start of the format specifier.

size
   Signal size in bits; this many bits are consumed from the ``ARGS`` port by
   this specifier.

``:``
   Separates the size from the remaining items.

justify
   ``>`` for right-justified, ``<`` for left-justified.

padding
   ``0`` for zero-padding, or a space for space-padding.

width\ *?*
   (optional) The number of characters wide to pad to.

base
   * ``b`` for base-2 integers (binary)
   * ``o`` for base-8 integers	(octal)
   * ``d`` for base-10 integers (decimal)
   * ``h`` for base-16	integers (hexadecimal)
   * ``c`` for ASCII characters/strings
   * ``t`` and ``r`` for simulation time (corresponding to :verilog:`$time` and
     :verilog:`$realtime`)

For integers, this item may follow:

``+``\ *?*
   (optional, decimals only) Include a leading plus for non-negative numbers.
   This can assist with symmetry with negatives in tabulated output.

signedness
   ``u`` for unsigned, ``s`` for signed.  This distinction is only respected
   when rendering decimals.

ASCII characters/strings have no special options, but the signal size must be
divisible by 8.

For simulation time, the signal size must be zero.

Finally:

``}``
   Denotes the end of the format specifier.

Some example format specifiers:

+ ``{8:>02hu}`` - 8-bit unsigned integer rendered as hexadecimal,
  right-justified, zero-padded to 2 characters wide.
+ ``{32:< 15d+s}`` - 32-bit signed integer rendered as decimal, left-justified,
  space-padded to 15 characters wide, positive values prefixed with ``+``.
+ ``{16:< 10hu}`` - 16-bit unsigned integer rendered as hexadecimal,
  left-justified, space-padded to 10 characters wide.
+ ``{0:>010t}`` - simulation time, right-justified, zero-padded to 10 characters
  wide.

To include literal ``{`` and ``}`` characters in your format string, use ``{{``
and ``}}`` respectively.

It is an error for a format string to consume more or less bits from ``ARGS``
than the port width.

Values are never truncated, regardless of the specified width.

Note that further restrictions on allowable combinations of options may apply
depending on the backend used.

For example, Verilog does not have a format specifier that allows zero-padding a
string (i.e. more than 1 ASCII character), though zero-padding a single
character is permitted.

Thus, while the RTLIL format specifier ``{8:>02c}`` translates to ``%02c``,
``{16:>02c}`` cannot be represented in Verilog and will fail to emit.  In this
case, ``{16:> 02c}`` must be used, which translates to ``%2s``.

---

### Source Cell Word Formal (`docs/source/cell/word_formal.rst`)

Formal verification cells
-------------------------

.. role:: yoscrypt(code)
   :language: yoscrypt

.. note::

   Some front-ends may not support the generic `$check` cell, in such cases
   calling :yoscrypt:`chformal -lower` will convert each `$check` cell into it's
   equivalent.  See `chformal` for more.

.. todo:: Describe formal cells

   `$check`, `$assert`, `$assume`, `$live`, `$fair`, `$cover`, `$equiv`,
   `$initstate`, `$anyconst`, `$anyseq`, `$anyinit`, `$allconst`, and `$allseq`.

   Also `$ff` and `$_FF_` cells.

.. autocellgroup:: formal
   :members:
   :source:
   :linenos:

Formal support cells
~~~~~~~~~~~~~~~~~~~~

.. autocellgroup:: formal_tag
   :members:
   :source:
   :linenos:

---

### Source Cell Word Fsm (`docs/source/cell/word_fsm.rst`)

Finite state machines
---------------------

.. todo:: Describe `$fsm` cell

.. autocellgroup:: fsm
   :members:
   :source:
   :linenos:

---

### Source Cell Word Logic (`docs/source/cell/word_logic.rst`)

Arbitrary logic functions
-------------------------

The `$lut` cell type implements a single-output LUT (lookup table). It
implements an arbitrary logic function with its ``\LUT`` parameter to map input
port ``\A`` to values of ``\Y`` output port values. In psuedocode: ``Y =
\LUT[A]``. ``\A`` has width set by parameter ``\WIDTH`` and ``\Y`` has a width
of 1. Every logic function with a single bit output has a unique `$lut`
representation.

The `$sop` cell type implements a sum-of-products expression, also known as
disjunctive normal form (DNF). It implements an arbitrary logic function. Its
structure mimics a programmable logic array (PLA). Output port ``\Y`` is the sum
of products of the bits of the input port ``\A`` as defined by parameter
``\TABLE``. ``\A`` is ``\WIDTH`` bits wide. The number of products in the sum is
set by parameter ``\DEPTH``, and each product has two bits for each input bit -
for the presence of the unnegated and negated version of said input bit in the
product. Therefore the ``\TABLE`` parameter holds ``2 * \WIDTH * \DEPTH`` bits.

For example:

Let ``\WIDTH`` be 3. We would like to represent ``\Y =~\A[0] + \A[1]~\A[2]``.
There are 2 products to be summed, so ``\DEPTH`` shall be 2.

.. code-block::

    ~A[2]-----+
     A[2]----+|
    ~A[1]---+||
     A[1]--+|||
    ~A[0]-+||||
     A[0]+|||||
         |||||| product formula
         010000 ~\A[0]
         001001 \A[1]~\A[2]

So the value of ``\TABLE`` will become ``010000001001``.

Any logic function with a single bit output can be represented with ``$sop`` but
may have variously minimized or ordered summands represented in the ``\TABLE``
values.

.. autocellgroup:: logic
   :members:
   :source:
   :linenos:

---

### Source Cell Word Mem (`docs/source/cell/word_mem.rst`)

.. role:: verilog(code)
   :language: Verilog

.. _sec:memcells:

Memories
~~~~~~~~

Memories are either represented using ``RTLIL::Memory`` objects, `$memrd_v2`,
`$memwr_v2`, and `$meminit_v2` cells, or by `$mem_v2` cells alone.

In the first alternative the ``RTLIL::Memory`` objects hold the general metadata
for the memory (bit width, size in number of words, etc.) and for each port a
`$memrd_v2` (read port) or `$memwr_v2` (write port) cell is created. Having
individual cells for read and write ports has the advantage that they can be
consolidated using resource sharing passes. In some cases this drastically
reduces the number of required ports on the memory cell. In this alternative,
memory initialization data is represented by `$meminit_v2` cells, which allow
delaying constant folding for initialization addresses and data until after the
frontend finishes.

The `$memrd_v2` cells have a clock input ``CLK``, an enable input ``EN``, an
address input ``ADDR``, a data output ``DATA``, an asynchronous reset input
``ARST``, and a synchronous reset input ``SRST``. They also have the following
parameters:

``MEMID``
   The name of the ``RTLIL::Memory`` object that is associated with this read
   port.

``ABITS``
   The number of address bits (width of the ``ADDR`` input port).

``WIDTH``
   The number of data bits (width of the ``DATA`` output port).  Note that this
   may be a power-of-two multiple of the underlying memory's width -- such ports
   are called wide ports and access an aligned group of cells at once.  In this
   case, the corresponding low bits of ``ADDR`` must be tied to 0.

``CLK_ENABLE``
   When this parameter is non-zero, the clock is used. Otherwise this read port
   is asynchronous and the ``CLK`` input is not used.

``CLK_POLARITY``
   Clock is active on the positive edge if this parameter has the value ``1'b1``
   and on the negative edge if this parameter is ``1'b0``.

``TRANSPARENCY_MASK``
   This parameter is a bitmask of write ports that this read port is transparent
   with. The bits of this parameter are indexed by the write port's ``PORTID``
   parameter. Transparency can only be enabled between synchronous ports sharing
   a clock domain. When transparency is enabled for a given port pair, a read
   and write to the same address in the same cycle will return the new value.
   Otherwise the old value is returned.

``COLLISION_X_MASK``
   This parameter is a bitmask of write ports that have undefined collision
   behavior with this port. The bits of this parameter are indexed by the write
   port's ``PORTID`` parameter. This behavior can only be enabled between
   synchronous ports sharing a clock domain. When undefined collision is enabled
   for a given port pair, a read and write to the same address in the same cycle
   will return the undefined (all-X) value.This option is exclusive (for a given
   port pair) with the transparency option.

``ARST_VALUE``
   Whenever the ``ARST`` input is asserted, the data output will be reset to
   this value. Only used for synchronous ports.

``SRST_VALUE``
   Whenever the ``SRST`` input is synchronously asserted, the data output will
   be reset to this value. Only used for synchronous ports.

``INIT_VALUE``
   The initial value of the data output, for synchronous ports.

``CE_OVER_SRST``
   If this parameter is non-zero, the ``SRST`` input is only recognized when
   ``EN`` is true. Otherwise, ``SRST`` is recognized regardless of ``EN``.

The `$memwr_v2` cells have a clock input ``CLK``, an enable input ``EN`` (one
enable bit for each data bit), an address input ``ADDR`` and a data input
``DATA``. They also have the following parameters:

``MEMID``
   The name of the ``RTLIL::Memory`` object that is associated with this write
   port.

``ABITS``
   The number of address bits (width of the ``ADDR`` input port).

``WIDTH``
   The number of data bits (width of the ``DATA`` output port). Like with
   `$memrd_v2` cells, the width is allowed to be any power-of-two multiple of
   memory width, with the corresponding restriction on address.

``CLK_ENABLE``
   When this parameter is non-zero, the clock is used. Otherwise this write port
   is asynchronous and the ``CLK`` input is not used.

``CLK_POLARITY``
   Clock is active on positive edge if this parameter has the value ``1'b1`` and
   on the negative edge if this parameter is ``1'b0``.

``PORTID``
   An identifier for this write port, used to index write port bit mask
   parameters.

``PRIORITY_MASK``
   This parameter is a bitmask of write ports that this write port has priority
   over in case of writing to the same address.  The bits of this parameter are
   indexed by the other write port's ``PORTID`` parameter. Write ports can only
   have priority over write ports with lower port ID. When two ports write to
   the same address and neither has priority over the other, the result is
   undefined.  Priority can only be set between two synchronous ports sharing
   the same clock domain.

The `$meminit_v2` cells have an address input ``ADDR``, a data input ``DATA``,
with the width of the ``DATA`` port equal to ``WIDTH`` parameter times ``WORDS``
parameter, and a bit enable mask input ``EN`` with width equal to ``WIDTH``
parameter. All three of the inputs must resolve to a constant for synthesis to
succeed.

``MEMID``
   The name of the ``RTLIL::Memory`` object that is associated with this
   initialization cell.

``ABITS``
   The number of address bits (width of the ``ADDR`` input port).

``WIDTH``
   The number of data bits per memory location.

``WORDS``
   The number of consecutive memory locations initialized by this cell.

``PRIORITY``
   The cell with the higher integer value in this parameter wins an
   initialization conflict.

The HDL frontend models a memory using ``RTLIL::Memory`` objects and
asynchronous `$memrd_v2` and `$memwr_v2` cells. The `memory` pass (i.e. its
various sub-passes) migrates `$dff` cells into the `$memrd_v2` and `$memwr_v2`
cells making them synchronous, then converts them to a single `$mem_v2` cell and
(optionally) maps this cell type to `$dff` cells for the individual words and
multiplexer-based address decoders for the read and write interfaces. When the
last step is disabled or not possible, a `$mem_v2` cell is left in the design.

The `$mem_v2` cell provides the following parameters:

``MEMID``
   The name of the original ``RTLIL::Memory`` object that became this `$mem_v2`
   cell.

``SIZE``
   The number of words in the memory.

``ABITS``
   The number of address bits.

``WIDTH``
   The number of data bits per word.

``INIT``
   The initial memory contents.

``RD_PORTS``
   The number of read ports on this memory cell.

``RD_WIDE_CONTINUATION``
   This parameter is ``RD_PORTS`` bits wide, containing a bitmask of "wide
   continuation" read ports. Such ports are used to represent the extra data
   bits of wide ports in the combined cell, and must have all control signals
   identical with the preceding port, except for address, which must have the
   proper sub-cell address encoded in the low bits.

``RD_CLK_ENABLE``
   This parameter is ``RD_PORTS`` bits wide, containing a clock enable bit for
   each read port.

``RD_CLK_POLARITY``
   This parameter is ``RD_PORTS`` bits wide, containing a clock polarity bit for
   each read port.

``RD_TRANSPARENCY_MASK``
   This parameter is ``RD_PORTS*WR_PORTS`` bits wide, containing a concatenation
   of all ``TRANSPARENCY_MASK`` values of the original `$memrd_v2` cells.

``RD_COLLISION_X_MASK``
   This parameter is ``RD_PORTS*WR_PORTS`` bits wide, containing a concatenation
   of all ``COLLISION_X_MASK`` values of the original `$memrd_v2` cells.

``RD_CE_OVER_SRST``
   This parameter is ``RD_PORTS`` bits wide, determining relative synchronous
   reset and enable priority for each read port.

``RD_INIT_VALUE``
   This parameter is ``RD_PORTS*WIDTH`` bits wide, containing the initial value
   for each synchronous read port.

``RD_ARST_VALUE``
   This parameter is ``RD_PORTS*WIDTH`` bits wide, containing the asynchronous
   reset value for each synchronous read port.

``RD_SRST_VALUE``
   This parameter is ``RD_PORTS*WIDTH`` bits wide, containing the synchronous
   reset value for each synchronous read port.

``WR_PORTS``
   The number of write ports on this memory cell.

``WR_WIDE_CONTINUATION``
   This parameter is ``WR_PORTS`` bits wide, containing a bitmask of "wide
   continuation" write ports.

``WR_CLK_ENABLE``
   This parameter is ``WR_PORTS`` bits wide, containing a clock enable bit for
   each write port.

``WR_CLK_POLARITY``
   This parameter is ``WR_PORTS`` bits wide, containing a clock polarity bit for
   each write port.

``WR_PRIORITY_MASK``
   This parameter is ``WR_PORTS*WR_PORTS`` bits wide, containing a concatenation
   of all ``PRIORITY_MASK`` values of the original `$memwr_v2` cells.

The `$mem_v2` cell has the following ports:

``RD_CLK``
   This input is ``RD_PORTS`` bits wide, containing all clock signals for the
   read ports.

``RD_EN``
   This input is ``RD_PORTS`` bits wide, containing all enable signals for the
   read ports.

``RD_ADDR``
   This input is ``RD_PORTS*ABITS`` bits wide, containing all address signals
   for the read ports.

``RD_DATA``
   This output is ``RD_PORTS*WIDTH`` bits wide, containing all data signals for
   the read ports.

``RD_ARST``
   This input is ``RD_PORTS`` bits wide, containing all asynchronous reset
   signals for the read ports.

``RD_SRST``
   This input is ``RD_PORTS`` bits wide, containing all synchronous reset
   signals for the read ports.

``WR_CLK``
   This input is ``WR_PORTS`` bits wide, containing all clock signals for the
   write ports.

``WR_EN``
   This input is ``WR_PORTS*WIDTH`` bits wide, containing all enable signals for
   the write ports.

``WR_ADDR``
   This input is ``WR_PORTS*ABITS`` bits wide, containing all address signals
   for the write ports.

``WR_DATA``
   This input is ``WR_PORTS*WIDTH`` bits wide, containing all data signals for
   the write ports.

The `memory_collect` pass can be used to convert discrete `$memrd_v2`,
`$memwr_v2`, and `$meminit_v2` cells belonging to the same memory to a single
`$mem_v2` cell, whereas the `memory_unpack` pass performs the inverse operation.
The `memory_dff` pass can combine asynchronous memory ports that are fed by or
feeding registers into synchronous memory ports. The `memory_bram` pass can be
used to recognize `$mem_v2` cells that can be implemented with a block RAM
resource on an FPGA. The `memory_map` pass can be used to implement `$mem_v2`
cells as basic logic: word-wide DFFs and address decoders.

.. autocellgroup:: mem
   :members:
   :source:
   :linenos:

---

### Source Cell Word Mux (`docs/source/cell/word_mux.rst`)

.. role:: verilog(code)
   :language: Verilog

Multiplexers
------------

Multiplexers are generated by the Verilog HDL frontend for ``?:``-expressions.
Multiplexers are also generated by the proc pass to map the decision trees from
RTLIL::Process objects to logic.

The simplest multiplexer cell type is `$mux`. Cells of this type have a
``WITDH`` parameter and data inputs ``A`` and ``B`` and a data output ``Y``, all
of the specified width. This cell also has a single bit control input ``S``. If
``S`` is 0 the value from the input ``A`` is sent to the output, if it is 1 the
value from the ``B`` input is sent to the output. So the `$mux` cell implements
the function :verilog:`Y = S ? B : A`.

The `$pmux` cell is used to multiplex between many inputs using a one-hot select
signal. Cells of this type have a ``WIDTH`` and a ``S_WIDTH`` parameter and
inputs ``A``, ``B``, and ``S`` and an output ``Y``. The ``S`` input is
``S_WIDTH`` bits wide. The ``A`` input and the output are both ``WIDTH`` bits
wide and the ``B`` input is ``WIDTH*S_WIDTH`` bits wide. When all bits of ``S``
are zero, the value from ``A`` input is sent to the output. If the :math:`n`\
'th bit from ``S`` is set, the value :math:`n`\ 'th ``WIDTH`` bits wide slice of
the ``B`` input is sent to the output. When more than one bit from ``S`` is set
the output is undefined. Cells of this type are used to model "parallel cases"
(defined by using the ``parallel_case`` attribute, the ``unique`` or ``unique0``
SystemVerilog keywords, or detected by an optimization).

The `$tribuf` cell is used to implement tristate logic. Cells of this type have
a ``WIDTH`` parameter and inputs ``A`` and ``EN`` and an output ``Y``. The ``A``
input and ``Y`` output are ``WIDTH`` bits wide, and the ``EN`` input is one bit
wide. When ``EN`` is 0, the output is not driven. When ``EN`` is 1, the value
from ``A`` input is sent to the ``Y`` output. Therefore, the `$tribuf` cell
implements the function :verilog:`Y = EN ? A : 'bz`.

Behavioural code with cascaded if-then-else- and case-statements usually results
in trees of multiplexer cells. Many passes (from various optimizations to FSM
extraction) heavily depend on these multiplexer trees to understand dependencies
between signals. Therefore optimizations should not break these multiplexer
trees (e.g. by replacing a multiplexer between a calculated signal and a
constant zero with an `$and` gate).

.. autocellgroup:: mux
   :members:
   :source:
   :linenos:

---

### Source Cell Word Reg (`docs/source/cell/word_reg.rst`)

.. role:: verilog(code)
   :language: Verilog

Registers
---------

SR-type latches are represented by `$sr` cells. These cells have input ports
``SET`` and ``CLR`` and an output port ``Q``. They have the following
parameters:

``WIDTH``
   The width of inputs ``SET`` and ``CLR`` and output ``Q``.

``SET_POLARITY``
   The set input bits are active-high if this parameter has the value ``1'b1``
   and active-low if this parameter is ``1'b0``.

``CLR_POLARITY``
   The reset input bits are active-high if this parameter has the value ``1'b1``
   and active-low if this parameter is ``1'b0``.

Both set and reset inputs have separate bits for every output bit. When both the
set and reset inputs of an `$sr` cell are active for a given bit index, the
reset input takes precedence.

D-type flip-flops are represented by `$dff` cells. These cells have a clock port
``CLK``, an input port ``D`` and an output port ``Q``. The following parameters
are available for `$dff` cells:

``WIDTH``
   The width of input ``D`` and output ``Q``.

``CLK_POLARITY``
   Clock is active on the positive edge if this parameter has the value ``1'b1``
   and on the negative edge if this parameter is ``1'b0``.

D-type flip-flops with asynchronous reset are represented by `$adff` cells. As
the `$dff` cells they have ``CLK``, ``D`` and ``Q`` ports. In addition they also
have a single-bit ``ARST`` input port for the reset pin and the following
additional two parameters:

``ARST_POLARITY``
   The asynchronous reset is active-high if this parameter has the value
   ``1'b1`` and active-low if this parameter is ``1'b0``.

``ARST_VALUE``
      The state of ``Q`` will be set to this value when the reset is active.

Usually these cells are generated by the `proc` pass using the information in
the designs RTLIL::Process objects.

D-type flip-flops with synchronous reset are represented by `$sdff` cells. As
the `$dff` cells they have ``CLK``, ``D`` and ``Q`` ports. In addition they also
have a single-bit ``SRST`` input port for the reset pin and the following
additional two parameters:

``SRST_POLARITY``
   The synchronous reset is active-high if this parameter has the value ``1'b1``
   and active-low if this parameter is ``1'b0``.

``SRST_VALUE``
   The state of ``Q`` will be set to this value when the reset is active.

Note that the `$adff` and `$sdff` cells can only be used when the reset value is
constant.

D-type flip-flops with asynchronous load are represented by `$aldff` cells. As
the `$dff` cells they have ``CLK``, ``D`` and ``Q`` ports. In addition they also
have a single-bit ``ALOAD`` input port for the async load enable pin, a ``AD``
input port with the same width as data for the async load data, and the
following additional parameter:

``ALOAD_POLARITY``
   The asynchronous load is active-high if this parameter has the value ``1'b1``
   and active-low if this parameter is ``1'b0``.

D-type flip-flops with asynchronous set and reset are represented by `$dffsr`
cells. As the `$dff` cells they have ``CLK``, ``D`` and ``Q`` ports. In addition
they also have multi-bit ``SET`` and ``CLR`` input ports and the corresponding
polarity parameters, like `$sr` cells.
When both set and reset are active, the state and output is undefined.

D-type flip-flops with enable are represented by `$dffe`, `$adffe`, `$aldffe`,
`$dffsre`, `$sdffe`, and `$sdffce` cells, which are enhanced variants of `$dff`,
`$adff`, `$aldff`, `$dffsr`, `$sdff` (with reset over enable) and `$sdff` (with
enable over reset) cells, respectively.  They have the same ports and parameters
as their base cell. In addition they also have a single-bit ``EN`` input port
for the enable pin and the following parameter:

``EN_POLARITY``
   The enable input is active-high if this parameter has the value ``1'b1`` and
   active-low if this parameter is ``1'b0``.

D-type latches are represented by `$dlatch` cells.  These cells have an enable
port ``EN``, an input port ``D``, and an output port ``Q``.  The following
parameters are available for `$dlatch` cells:

``WIDTH``
   The width of input ``D`` and output ``Q``.

``EN_POLARITY``
   The enable input is active-high if this parameter has the value ``1'b1`` and
   active-low if this parameter is ``1'b0``.

The latch is transparent when the ``EN`` input is active.

D-type latches with reset are represented by `$adlatch` cells.  In addition to
`$dlatch` ports and parameters, they also have a single-bit ``ARST`` input port
for the reset pin and the following additional parameters:

``ARST_POLARITY``
   The asynchronous reset is active-high if this parameter has the value
   ``1'b1`` and active-low if this parameter is ``1'b0``.

``ARST_VALUE``
   The state of ``Q`` will be set to this value when the reset is active.

D-type latches with set and reset are represented by `$dlatchsr` cells. In
addition to `$dlatch` ports and parameters, they also have multi-bit ``SET`` and
``CLR`` input ports and the corresponding polarity parameters, like `$sr` cells.

.. autocellgroup:: reg
   :members:
   :source:
   :linenos:

---

### Source Cell Word Spec (`docs/source/cell/word_spec.rst`)

Specify rules
-------------

.. todo:: `$specify2`, `$specify3`, and `$specrule` cells.

.. autocellgroup:: spec
   :members:
   :source:
   :linenos:

---

### Source Cell Word Unary (`docs/source/cell/word_unary.rst`)

.. role:: verilog(code)
   :language: Verilog

Unary operators
---------------

All unary RTL cells have one input port ``A`` and one output port ``Y``. They
also have the following parameters:

``A_SIGNED``
   Set to a non-zero value if the input ``A`` is signed and therefore should be
   sign-extended when needed.

``A_WIDTH``
   The width of the input port ``A``.

``Y_WIDTH``
   The width of the output port ``Y``.

.. table:: Cell types for unary operators with their corresponding Verilog expressions.

   ================== ==============
   Verilog            Cell Type
   ================== ==============
   :verilog:`Y =  ~A` `$not`
   :verilog:`Y =  +A` `$pos`
   :verilog:`Y =  -A` `$neg`
   :verilog:`Y =  &A` `$reduce_and`
   :verilog:`Y =  |A` `$reduce_or`
   :verilog:`Y =  ^A` `$reduce_xor`
   :verilog:`Y = ~^A` `$reduce_xnor`
   :verilog:`Y =  |A` `$reduce_bool`
   :verilog:`Y =  !A` `$logic_not`
   ================== ==============

For the unary cells that output a logical value (`$reduce_and`, `$reduce_or`,
`$reduce_xor`, `$reduce_xnor`, `$reduce_bool`, `$logic_not`), when the
``Y_WIDTH`` parameter is greater than 1, the output is zero-extended, and only
the least significant bit varies.

Note that `$reduce_or` and `$reduce_bool` generally represent the same logic
function. But the `read_verilog` frontend will generate them in different
situations. A `$reduce_or` cell is generated when the prefix ``|`` operator is
being used. A `$reduce_bool` cell is generated when a bit vector is used as a
condition in an ``if``-statement or ``?:``-expression.

.. autocellgroup:: unary
   :members:
   :source:
   :linenos:

---

### Source Cell Word Wire (`docs/source/cell/word_wire.rst`)

Wire cells
-------------------------

.. todo:: Add information about `$slice` and `$concat` cells.

.. autocellgroup:: wire
   :members:
   :source:
   :linenos:

---

### Source Cmd Index Backends (`docs/source/cmd/index_backends.rst`)

Writing output files
--------------------

.. autocmdgroup:: backends
   :members:

---

### Source Cmd Index Formal (`docs/source/cmd/index_formal.rst`)

Formal verification
-------------------

.. autocmdgroup:: formal
   :members:

---

### Source Cmd Index Frontends (`docs/source/cmd/index_frontends.rst`)

Reading input files
-------------------

.. autocmdgroup:: frontends
   :members:

---

### Source Cmd Index Internal (`docs/source/cmd/index_internal.rst`)

Internal commands for developers
--------------------------------

.. autocmdgroup:: internal
   :members:

Writing command help
--------------------

- use `chformal` as an example
- generated help content below

.. _chformal autocmd:

.. autocmd:: chformal
   :noindex:

The ``formatted_help()`` method
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

- ``PrettyHelp::get_current()``
- ``PrettyHelp::set_group()``

  + used with ``.. autocmdgroup:: <group>``
  + can assign group and return false
  + if no group is set, will try to use ``source_location`` and assign group
    from path to source file

- return value

  + true means help content added to current ``PrettyHelp``
  + false to use ``Pass::help()``

- adding content

  + help content is a list of ``ContentListing`` nodes, each one having a type,
    body, and its own list of children ``ContentListing``\ s
  + ``PrettyHelp::get_root()`` returns the root ``ContentListing`` (``type="root"``)
  + ``ContentListing::{usage, option, codeblock, paragraph}`` each add a
    ``ContentListing`` to the current node, with type the same as the method

    * the first argument is the body of the new node
    * ``usage`` shows how to call the command (i.e. its "signature")
    * ``paragraph`` content is formatted as a paragraph of text with line breaks
      added automatically
    * ``codeblock`` content is displayed verbatim, use line breaks as desired;
      takes an optional ``language`` argument for assigning the language in RST
      output for code syntax highlighting (use ``yoscrypt`` for yosys script
      syntax highlighting)
    * ``option`` lists a single option for the command, usually starting with a
      dash (``-``); takes an optional second argument which adds a paragraph
      node as a means of description

  + ``ContentListing::open_usage`` creates and returns a new usage node, can be
    used to e.g. add text/options specific to a given usage of the command
  + ``ContentListing::open_option`` creates and returns a new option node, can
    be used to e.g. add multiple paragraphs to an option's description
  + paragraphs are treated as raw RST, allowing for inline formatting and
    references as if it were written in the RST file itself

.. literalinclude:: /generated/chformal.cc
   :language: c++
   :start-at: bool formatted_help()
   :end-before: void execute
   :caption: ``ChformalPass::formatted_help()`` from :file:`passes/cmds/chformal.cc`

Dumping command help to json
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

- `help -dump-cmds-json cmds.json`

  + generates a ``ContentListing`` for each command registered in Yosys
  + tries to parse unformatted ``Pass::help()`` output if
    ``Pass::formatted_help()`` is unimplemented or returns false

    * if a line starts with four spaces followed by the name of the command then
      a space, it is parsed as a signature (usage node)
    * if a line is indented and starts with a dash (``-``), it is parsed as an
      option
    * anything else is parsed as a codeblock and added to either the root node
      or the current option depending on the indentation

  + dictionary of command name to ``ContentListing``

    * uses ``ContentListing::to_json()`` recursively for each node in root
    * root node used for source location of class definition
    * includes flags set during pass constructor (e.g. ``experimental_flag`` set
      by ``Pass::experimental()``)
    * also title (``short_help`` argument in ``Pass::Pass``), group, and class
      name

  + dictionary of group name to list of commands in that group

- used by sphinx autodoc to generate help content

.. literalinclude:: /generated/cmds.json
   :language: json
   :start-at: "chformal": {
   :end-before: "chparam": {
   :caption: `chformal` in generated :file:`cmds.json`

.. note:: Synthesis command scripts are special cased

   If the final block of help output starts with the string `"The following
   commands are executed by this synthesis command:\n"`, then the rest of the
   code block is formatted as ``yoscrypt`` (e.g. `synth_ice40`).  The caveat
   here is that if the ``script()`` calls ``run()`` on any commands *prior* to
   the first ``check_label`` then the auto detection will break and revert to
   unformatted code (e.g. `synth_fabulous`).

Command line rendering
~~~~~~~~~~~~~~~~~~~~~~

- if ``Pass::formatted_help()`` returns true, will call
  ``PrettyHelp::log_help()``

  + traverse over the children of the root node and render as plain text
  + effectively the reverse of converting unformatted ``Pass::help()`` text
  + lines are broken at 80 characters while maintaining indentation (controlled
    by ``MAX_LINE_LEN`` in :file:`kernel/log_help.cc`)
  + each line is broken into words separated by spaces, if a given word starts
    and ends with backticks they will be stripped

- if it returns false it will call ``Pass::help()`` which should call ``log()``
  directly to print and format help text

  + if ``Pass::help()`` is not overridden then a default message about missing
    help will be displayed

.. literalinclude:: /generated/chformal.log
   :lines: 2-

RST generated from autocmd
~~~~~~~~~~~~~~~~~~~~~~~~~~

- below is the raw RST output from ``autocmd`` (``YosysCmdDocumenter`` class in
  :file:`docs/util/cmd_documenter.py`) for `chformal` command
- heading will be rendered as a subheading of the most recent heading (see
  `chformal autocmd`_ above rendered under `Writing command help`_)
- ``.. cmd:def:: <cmd>`` line is indexed for cross references with ``:cmd:ref:``
  directive (`chformal autocmd`_ above uses ``:noindex:`` option so that
  `chformal` still links to the correct location)

  + ``:title:`` option controls text that appears when hovering over the
    `chformal` link

- commands with warning flags (experimental or internal) add a ``.. warning``
  block before any of the help content
- if a command has no ``source_location`` the ``.. note`` at the bottom will
  instead link to :doc:`/cmd/index_other`

.. autocmd_rst:: chformal

---

### Source Cmd Index Kernel (`docs/source/cmd/index_kernel.rst`)

Yosys kernel commands
---------------------

.. autocmdgroup:: kernel
   :members:

---

### Source Cmd Index Other (`docs/source/cmd/index_other.rst`)

:orphan:

Other commands
==============

Unknown source location

.. autocmdgroup:: unknown
   :members:

---

### Source Cmd Index Passes (`docs/source/cmd/index_passes.rst`)

Passes
------

.. toctree::
   :maxdepth: 2
   :glob:

   /cmd/index_passes_hierarchy
   /cmd/index_passes_proc
   /cmd/index_passes_fsm
   /cmd/index_passes_memory
   /cmd/index_passes_opt
   /cmd/index_passes_techmap
   /cmd/index_passes_*

---

### Source Cmd Index Passes Cmds (`docs/source/cmd/index_passes_cmds.rst`)

Design modification
-------------------

.. autocmdgroup:: passes/cmds
   :members:

---

### Source Cmd Index Passes Equiv (`docs/source/cmd/index_passes_equiv.rst`)

Equivalence checking
--------------------

.. autocmdgroup:: passes/equiv
   :members:

---

### Source Cmd Index Passes Fsm (`docs/source/cmd/index_passes_fsm.rst`)

FSM handling
------------

.. autocmdgroup:: passes/fsm
   :members:

---

### Source Cmd Index Passes Hierarchy (`docs/source/cmd/index_passes_hierarchy.rst`)

Working with hierarchy
----------------------

.. autocmdgroup:: passes/hierarchy
   :members:

---

### Source Cmd Index Passes Memory (`docs/source/cmd/index_passes_memory.rst`)

Memory handling
---------------

.. autocmdgroup:: passes/memory
   :members:

---

### Source Cmd Index Passes Opt (`docs/source/cmd/index_passes_opt.rst`)

Optimization passes
-------------------

.. autocmdgroup:: passes/opt
   :members:

---

### Source Cmd Index Passes Proc (`docs/source/cmd/index_passes_proc.rst`)

Converting process blocks
-------------------------

.. autocmdgroup:: passes/proc
   :members:

---

### Source Cmd Index Passes Sat (`docs/source/cmd/index_passes_sat.rst`)

Simulating circuits
-------------------

.. autocmdgroup:: passes/sat
   :members:

---

### Source Cmd Index Passes Status (`docs/source/cmd/index_passes_status.rst`)

Design status
-------------

.. autocmdgroup:: passes/status
   :members:

---

### Source Cmd Index Passes Techmap (`docs/source/cmd/index_passes_techmap.rst`)

Technology mapping
------------------

.. seealso:: :doc:`/cmd/index_techlibs`

.. autocmdgroup:: passes/techmap
   :members:

---

### Source Cmd Index Techlibs (`docs/source/cmd/index_techlibs.rst`)

Technology libraries
====================

Listed in alphabetical order.

.. toctree::
   :maxdepth: 2
   :glob:

   /cmd/index_techlibs_common
   /cmd/index_techlibs_*

---

### Source Cmd Index Techlibs Achronix (`docs/source/cmd/index_techlibs_achronix.rst`)

Achronix
------------------

.. autocmdgroup:: techlibs/achronix
   :members:

---

### Source Cmd Index Techlibs Anlogic (`docs/source/cmd/index_techlibs_anlogic.rst`)

Anlogic
------------------

.. autocmdgroup:: techlibs/anlogic
   :members:

---

### Source Cmd Index Techlibs Common (`docs/source/cmd/index_techlibs_common.rst`)

Generic
------------------

.. autocmdgroup:: techlibs/common
   :members:

---

### Source Cmd Index Techlibs Easic (`docs/source/cmd/index_techlibs_easic.rst`)

eASIC
------------------

.. autocmdgroup:: techlibs/easic
   :members:

---

### Source Cmd Index Techlibs Fabulous (`docs/source/cmd/index_techlibs_fabulous.rst`)

FABulous
------------------

.. autocmdgroup:: techlibs/fabulous
   :members:

---

### Source Cmd Index Techlibs Gatemate (`docs/source/cmd/index_techlibs_gatemate.rst`)

Gatemate
------------------

.. autocmdgroup:: techlibs/gatemate
   :members:

---

### Source Cmd Index Techlibs Gowin (`docs/source/cmd/index_techlibs_gowin.rst`)

Gowin
------------------

.. autocmdgroup:: techlibs/gowin
   :members:

---

### Source Cmd Index Techlibs Ice40 (`docs/source/cmd/index_techlibs_ice40.rst`)

iCE40
------------------

.. autocmdgroup:: techlibs/ice40
   :members:

---

### Source Cmd Index Techlibs Intel (`docs/source/cmd/index_techlibs_intel.rst`)

Intel (MAX10, Cyclone IV)
-------------------------

.. autocmdgroup:: techlibs/intel
   :members:

---

### Source Cmd Index Techlibs Intel Alm (`docs/source/cmd/index_techlibs_intel_alm.rst`)

Intel ALM (Cyclone V, Arria V, Cyclone 10 GX)
---------------------------------------------

.. autocmdgroup:: techlibs/intel_alm
   :members:

---

### Source Cmd Index Techlibs Lattice (`docs/source/cmd/index_techlibs_lattice.rst`)

Lattice
------------------

.. autocmdgroup:: techlibs/lattice
   :members:

---

### Source Cmd Index Techlibs Microchip (`docs/source/cmd/index_techlibs_microchip.rst`)

Microchip
------------------

.. autocmdgroup:: techlibs/microchip
   :members:

---

### Source Cmd Index Techlibs Microchip Sf2 (`docs/source/cmd/index_techlibs_microchip_sf2.rst`)

Microchip - SmartFusion2/IGLOO2
-----------------------------------

.. autocmdgroup:: techlibs/sf2
   :members:

---

### Source Cmd Index Techlibs Nanoxplore (`docs/source/cmd/index_techlibs_nanoxplore.rst`)

NanoXplore
------------------

.. autocmdgroup:: techlibs/nanoxplore
   :members:

---

### Source Cmd Index Techlibs Quicklogic (`docs/source/cmd/index_techlibs_quicklogic.rst`)

QuickLogic
------------------

.. autocmdgroup:: techlibs/quicklogic
   :members:

---

### Source Cmd Index Techlibs Xilinx (`docs/source/cmd/index_techlibs_xilinx.rst`)

Xilinx
------------------

.. autocmdgroup:: techlibs/xilinx
   :members:

---

### Source Getting Started Example Synth (`docs/source/getting_started/example_synth.rst`)

Synthesis starter
-----------------

This page will be a guided walkthrough of the prepackaged iCE40 FPGA synthesis
script - `synth_ice40`.  We will take a simple design through each step, looking
at the commands being called and what they do to the design. While `synth_ice40`
is specific to the iCE40 platform, most of the operations we will be discussing
are common across the majority of FPGA synthesis scripts. Thus, this document
will provide a good foundational understanding of how synthesis in Yosys is
performed, regardless of the actual architecture being used.

.. seealso:: Advanced usage docs for
   :doc:`/using_yosys/synthesis/synth`

Demo design
~~~~~~~~~~~

.. role:: yoscrypt(code)
   :language: yoscrypt

First, let's quickly look at the design we'll be synthesizing:

.. todo:: reconsider including the whole (~77 line) design like this

.. literalinclude:: /code_examples/fifo/fifo.v
   :language: Verilog
   :linenos:
   :caption: :file:`fifo.v`
   :name: fifo-v

.. todo:: fifo.v description

While the open source `read_verilog` frontend generally does a pretty good job
at processing valid Verilog input, it does not provide very good error handling
or reporting.  Using an external tool such as `verilator`_ before running Yosys
is highly recommended. We can quickly check the Verilog syntax of our design by
calling ``verilator --lint-only fifo.v``.

.. _verilator: https://www.veripool.org/verilator/

Loading the design
~~~~~~~~~~~~~~~~~~

Let's load the design into Yosys.  From the command line, we can call ``yosys
fifo.v``.  This will open an interactive Yosys shell session and immediately
parse the code from :ref:`fifo-v` and convert it into an Abstract Syntax Tree
(AST).  If you are interested in how this happens, there is more information in
the document, :doc:`/yosys_internals/flow/verilog_frontend`.  For now, suffice
it to say that we do this to simplify further processing of the design.  You
should see something like the following:

.. literalinclude:: /code_examples/fifo/fifo.out
   :language: console
   :start-at: $ yosys fifo.v
   :end-before: echo on

.. seealso:: Advanced usage docs for
   :doc:`/using_yosys/more_scripting/load_design`

Elaboration
~~~~~~~~~~~

Now that we are in the interactive shell, we can call Yosys commands directly.
Our overall goal is to call :yoscrypt:`synth_ice40 -top fifo`, but for now we
can run each of the commands individually for a better sense of how each part
contributes to the flow.  We will also start with just a single module;
``addr_gen``.

At the bottom of the `help` output for
`synth_ice40` is the complete list of commands called by this script.
Let's start with the section labeled ``begin``:

.. literalinclude:: /code_examples/macro_commands/synth_ice40.ys
   :language: yoscrypt
   :start-after: begin:
   :end-before: flatten:
   :dedent:
   :caption: ``begin`` section
   :name: synth_begin

:yoscrypt:`read_verilog -D ICE40_HX -lib -specify +/ice40/cells_sim.v` loads the
iCE40 cell models which allows us to include platform specific IP blocks in our
design.  PLLs are a common example of this, where we might need to reference
``SB_PLL40_CORE`` directly rather than being able to rely on mapping passes
later.  Since our simple design doesn't use any of these IP blocks, we can skip
this command for now.  Because these cell models will also be needed once we
start mapping to hardware we will still need to load them later.

.. note::

   ``+/`` is a dynamic reference to the Yosys ``share`` directory.  By default,
   this is ``/usr/local/share/yosys``.  If using a locally built version of
   Yosys from the source directory, this will be the ``share`` folder in the
   same directory.

.. _addr_gen_example:

The addr_gen module
^^^^^^^^^^^^^^^^^^^

Since we're just getting started, let's instead begin with :yoscrypt:`hierarchy
-top addr_gen`.  This command declares that the top level module is
``addr_gen``, and everything else can be discarded.

.. literalinclude:: /code_examples/fifo/fifo.v
   :language: Verilog
   :start-at: module addr_gen
   :end-at: endmodule //addr_gen
   :lineno-match:
   :caption: ``addr_gen`` module source
   :name: addr_gen-v

.. note::

   `hierarchy` should always be the first command after the design has been
   read.  By specifying the top module, `hierarchy` will also set the ``(* top
   *)`` attribute on it.  This is used by other commands that need to know which
   module is the top.

.. use doscon for a console-like display that supports the `yosys> [command]` format.

.. literalinclude:: /code_examples/fifo/fifo.out
   :language: doscon
   :start-at: yosys> hierarchy -top addr_gen
   :end-before: yosys> select
   :caption: :yoscrypt:`hierarchy -top addr_gen` output
   :name: hierarchy_output

Our ``addr_gen`` circuit now looks like this:

.. figure:: /_images/code_examples/fifo/addr_gen_hier.*
   :class: width-helper invert-helper
   :name: addr_gen_hier

   ``addr_gen`` module after `hierarchy`

Simple operations like ``addr + 1`` and ``addr == MAX_DATA-1`` can be extracted
from our ``always @`` block in :ref:`addr_gen-v`. This gives us the highlighted
`$add` and `$eq` cells we see. But control logic (like the ``if .. else``) and
memory elements (like the ``addr <= 0``) are not so straightforward.  These get
put into "processes", shown in the schematic as ``PROC``.  Note how the second
line refers to the line numbers of the start/end of the corresponding ``always
@`` block.  In the case of an ``initial`` block, we instead see the ``PROC``
referring to line 0.

To handle these, let us now introduce the next command: :cmd:title:`proc`.
`proc` is a macro command like `synth_ice40`.  Rather than modifying the design
directly, it instead calls a series of other commands.  In the case of `proc`,
these sub-commands work to convert the behavioral logic of processes into
multiplexers and registers.  Let's see what happens when we run it.  For now, we
will call :yoscrypt:`proc -noopt` to prevent some automatic optimizations which
would normally happen.

.. figure:: /_images/code_examples/fifo/addr_gen_proc.*
   :class: width-helper invert-helper
   :name: addr_gen_proc

   ``addr_gen`` module after :yoscrypt:`proc -noopt`

There are now a few new cells from our ``always @``, which have been
highlighted.  The ``if`` statements are now modeled with `$mux` cells, while the
register uses an `$adff` cell.  If we look at the terminal output we can also
see all of the different ``proc_*`` commands being called.  We will look at each
of these in more detail in :doc:`/using_yosys/synthesis/proc`.

Notice how in the top left of :ref:`addr_gen_proc` we have a floating wire,
generated from the initial assignment of 0 to the ``addr`` wire.  However, this
initial assignment is not synthesizable, so this will need to be cleaned up
before we can generate the physical hardware.  We can do this now by calling
`clean`.  We're also going to call `opt_expr` now, which would normally be
called at the end of `proc`.  We can call both commands at the same time by
separating them with a colon and space: :yoscrypt:`opt_expr; clean`.

.. figure:: /_images/code_examples/fifo/addr_gen_clean.*
   :class: width-helper invert-helper
   :name: addr_gen_clean

   ``addr_gen`` module after :yoscrypt:`opt_expr; clean`

You may also notice that the highlighted `$eq` cell input of ``255`` has changed
to ``8'11111111``.  Constant values are presented in the format
``'``, with 32-bit values instead using the decimal number.
This indicates that the constant input has been reduced from 32-bit wide to
8-bit wide.  This is a side-effect of running `opt_expr`, which performs
constant folding and simple expression rewriting.    For more on why this
happens, refer to :doc:`/using_yosys/synthesis/opt` and the :ref:`section on
opt_expr <adv_opt_expr>`.

.. note::

   :cmd:title:`clean` can also be called with two semicolons after any command,
   for example we could have called :yoscrypt:`opt_expr;;` instead of
   :yoscrypt:`opt_expr; clean`.  You may notice some scripts will end each line
   with ``;;``.  It is beneficial to run `clean` before inspecting intermediate
   products to remove disconnected parts of the circuit which have been left
   over, and in some cases can reduce the processing required in subsequent
   commands.

.. todo:: consider a brief glossary for terms like adff

.. seealso:: Advanced usage docs for

   - :doc:`/using_yosys/synthesis/proc`
   - :doc:`/using_yosys/synthesis/opt`

The full example
^^^^^^^^^^^^^^^^

Let's now go back and check on our full design by using :yoscrypt:`hierarchy
-check -top fifo`.  By passing the ``-check`` option there we are also telling
the `hierarchy` command that if the design includes any non-blackbox modules
without an implementation it should return an error.

Note that if we tried to run this command now then we would get an error.  This
is because we already removed all of the modules other than ``addr_gen``.  We
could restart our shell session, but instead let's use two new commands:

- :cmd:title:`design`, and
- :cmd:title:`read_verilog`.

.. literalinclude:: /code_examples/fifo/fifo.out
   :language: doscon
   :start-at: design -reset
   :end-before: yosys> proc
   :caption: reloading :file:`fifo.v` and running :yoscrypt:`hierarchy -check -top fifo`

Notice how this time we didn't see any of those ``$abstract`` modules?  That's
because when we ran ``yosys fifo.v``, the first command Yosys called was
:yoscrypt:`read_verilog -defer fifo.v`.  The ``-defer`` option there tells
`read_verilog` only read the abstract syntax tree and defer actual compilation
to a later `hierarchy` command. This is useful in cases where the default
parameters of modules yield invalid code which is not synthesizable. This is why
Yosys defers compilation automatically and is one of the reasons why hierarchy
should always be the first command after loading the design.  If we know that
our design won't run into this issue, we can skip the ``-defer``.

.. todo:: `hierarchy` failure modes

.. note::

   The number before a command's output increments with each command run.  Don't
   worry if your numbers don't match ours!  The output you are seeing comes from
   the same script that was used to generate the images in this document,
   included in the source as :file:`fifo.ys`. There are extra commands being run
   which you don't see, but feel free to try them yourself, or play around with
   different commands.  You can always start over with a clean slate by calling
   ``exit`` or hitting :kbd:`ctrl+d` (i.e. EOF) and re-launching the Yosys
   interactive terminal.  :kbd:`ctrl+c` (i.e. SIGINT) will also end the terminal
   session but will return an error code rather than exiting gracefully.

We can also run `proc` now to finish off the full :ref:`synth_begin`. Because
the design schematic is quite large, we will be showing just the data path for
the ``rdata`` output.  If you would like to see the entire design for yourself,
you can do so with :cmd:title:`show`.  Note that the `show` command only works
with a single module, so you may need to call it with :yoscrypt:`show fifo`.
:ref:`show_intro` section in :doc:`/getting_started/scripting_intro` has more on
how to use `show`.

.. figure:: /_images/code_examples/fifo/rdata_proc.*
   :class: width-helper invert-helper
   :name: rdata_proc

   ``rdata`` output after `proc`

The highlighted ``fifo_reader`` block contains an instance of the
:ref:`addr_gen_proc` that we looked at earlier.  Notice how the type is shown as
``$paramod\\addr_gen\\MAX_DATA=s32'...``.  This is a "parametric module": an
instance of the ``addr_gen`` module with the ``MAX_DATA`` parameter set to the
given value.

The other highlighted block is a `$memrd` cell.  At this stage of synthesis we
don't yet know what type of memory is going to be implemented, but we *do* know
that ``rdata <= data[raddr];`` could be implemented as a read from memory. Note
that the `$memrd` cell here is asynchronous, with both the clock and enable
signal undefined; shown with the ``1'x`` inputs.

.. seealso:: Advanced usage docs for
   :doc:`/using_yosys/synthesis/proc`

Flattening
~~~~~~~~~~

At this stage of a synthesis flow there are a few other commands we could run.
In `synth_ice40` we get these:

.. literalinclude:: /code_examples/macro_commands/synth_ice40.ys
   :language: yoscrypt
   :start-after: flatten:
   :end-before: coarse:
   :dedent:
   :name: synth_flatten
   :caption: ``flatten`` section

We start by runnning `check`.  This doesn't affect the design, but it can
identify a few obvious problems which will cause errors later.  Calling it here
lets us fail faster rather than wasting time on something we know is impossible.
Next up is `flatten`.  Flattening the design like this can allow for
optimizations between modules which would otherwise be missed.  Let's run
:yoscrypt:`flatten;;` on our design.

.. literalinclude:: /code_examples/fifo/fifo.out
   :language: doscon
   :start-at: yosys> flatten
   :end-before: yosys> select
   :name: flat_clean
   :caption: output of :yoscrypt:`flatten;;`

.. figure:: /_images/code_examples/fifo/rdata_flat.*
   :class: width-helper invert-helper
   :name: rdata_flat

   ``rdata`` output after :yoscrypt:`flatten;;`

.. role:: yoterm(code)
   :language: doscon

The pieces have moved around a bit, but we can see :ref:`addr_gen_proc` from
earlier has replaced the ``fifo_reader`` block in :ref:`rdata_proc`.  We can
also see that the ``addr`` output has been renamed to :file:`fifo_reader.addr`
and merged with the ``raddr`` wire feeding into the `$memrd` cell.  This wire
merging happened during the call to `clean` which we can see in the
:ref:`flat_clean`.

.. note::

   `flatten` and `clean` would normally be combined into a
   single :yoterm:`yosys> flatten;;` output, but they appear separately here as
   a side effect of using `echo` for generating the terminal style
   output.

Depending on the target architecture, this stage of synthesis might also see
commands such as `tribuf` with the ``-logic`` option and `deminout`.  These
remove tristate and inout constructs respectively, replacing them with logic
suitable for mapping to an FPGA.  Since we do not have any such constructs in
our example running these commands does not change our design.

The coarse-grain representation
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

At this stage, the design is in coarse-grain representation.  It still looks
recognizable, and cells are word-level operators with parametrizable width. This
is the stage of synthesis where we do things like const propagation, expression
rewriting, and trimming unused parts of wires.

This is also where we convert our FSMs and hard blocks like DSPs or memories.
Such elements have to be inferred from patterns in the design and there are
special passes for each.  Detection of these patterns can also be affected by
optimizations and other transformations done previously.

.. note::

   While the iCE40 flow had a :ref:`synth_flatten` and put `proc` in the
   :ref:`synth_begin`, some synthesis scripts will instead include these in this
   section.

Part 1
^^^^^^

In the iCE40 flow, we start with the following commands:

.. literalinclude:: /code_examples/macro_commands/synth_ice40.ys
   :language: yoscrypt
   :start-after: coarse:
   :end-before: wreduce
   :dedent:
   :caption: ``coarse`` section (part 1)
   :name: synth_coarse1

We've already come across `opt_expr` and `check`, and `opt_clean` is the same as
`clean` but with more verbose output.  Next up is :yoscrypt:`opt -nodffe
-nosdff` performing a set of simple optimizations on the design.  This command
also ensures that only a specific subset of FF types are included, in
preparation for the next command: :cmd:title:`fsm`.  Both `opt` and `fsm` are
macro commands which are explored in more detail in
:doc:`/using_yosys/synthesis/opt` and :doc:`/using_yosys/synthesis/fsm`
respectively.

Up until now, the data path for ``rdata`` has remained the same since
:ref:`rdata_flat`.  However the next call to `opt` does cause a change.
Specifically, the call to `opt_dff` without the ``-nodffe -nosdff`` options is
able to fold one of the `$mux` cells into the `$adff` to form an `$adffe` cell;
highlighted below:

.. literalinclude:: /code_examples/fifo/fifo.out
   :language: doscon
   :start-at: yosys> opt_dff
   :end-before: yosys> select
   :caption: output of `opt_dff`

.. figure:: /_images/code_examples/fifo/rdata_adffe.*
   :class: width-helper invert-helper
   :name: rdata_adffe

   ``rdata`` output after `opt_dff`

.. seealso:: Advanced usage docs for

   - :doc:`/using_yosys/synthesis/fsm`
   - :doc:`/using_yosys/synthesis/opt`

Part 2
^^^^^^

The next group of commands performs a series of optimizations:

.. literalinclude:: /code_examples/macro_commands/synth_ice40.ys
   :language: yoscrypt
   :start-at: wreduce
   :end-before: macc-only
   :dedent:
   :caption: ``coarse`` section (part 2)
   :name: synth_coarse2

First up is :cmd:title:`wreduce`.  If we run this we get the following:

.. literalinclude:: /code_examples/fifo/fifo.out
   :language: doscon
   :start-at: yosys> wreduce
   :end-before: yosys> select
   :caption: output of `wreduce`

Looking at the data path for ``rdata``, the most relevant of these width
reductions are the ones affecting ``fifo.$flatten\fifo_reader.$add$fifo.v``.
That is the `$add` cell incrementing the fifo_reader address.  We can look at
the schematic and see the output of that cell has now changed.

.. todo:: pending bugfix in `wreduce` and/or `opt_clean`

.. figure:: /_images/code_examples/fifo/rdata_wreduce.*
   :class: width-helper invert-helper
   :name: rdata_wreduce

   ``rdata`` output after `wreduce`

The next two (new) commands are :cmd:title:`peepopt` and :cmd:title:`share`.
Neither of these affect our design, and they're explored in more detail in
:doc:`/using_yosys/synthesis/opt`, so let's skip over them.  :yoscrypt:`techmap
-map +/cmp2lut.v -D LUT_WIDTH=4` optimizes certain comparison operators by
converting them to LUTs instead.  The usage of `techmap` is explored more in
:doc:`/using_yosys/synthesis/techmap_synth`.

Our next command to run is
:cmd:title:`memory_dff`.

.. literalinclude:: /code_examples/fifo/fifo.out
   :language: doscon
   :start-at: yosys> memory_dff
   :end-before: yosys> select
   :caption: output of `memory_dff`

.. figure:: /_images/code_examples/fifo/rdata_memrdv2.*
   :class: width-helper invert-helper
   :name: rdata_memrdv2

   ``rdata`` output after `memory_dff`

As the title suggests, `memory_dff` has merged the output `$dff` into the
`$memrd` cell and converted it to a `$memrd_v2` (highlighted).  This has also
connected the ``CLK`` port to the ``clk`` input as it is now a synchronous
memory read with appropriate enable (``EN=1'1``) and reset (``ARST=1'0`` and
``SRST=1'0``) inputs.

.. seealso:: Advanced usage docs for

   - :doc:`/using_yosys/synthesis/opt`
   - :doc:`/using_yosys/synthesis/techmap_synth`
   - :doc:`/using_yosys/synthesis/memory`

Part 3
^^^^^^

The third part of the `synth_ice40` flow is a series of commands for mapping to
DSPs.  By default, the iCE40 flow will not map to the hardware DSP blocks and
will only be performed if called with the ``-dsp`` flag: :yoscrypt:`synth_ice40
-dsp`.  While our example has nothing that could be mapped to DSPs we can still
take a quick look at the commands here and describe what they do.

.. literalinclude:: /code_examples/macro_commands/synth_ice40.ys
   :language: yoscrypt
   :start-at: macc-only
   :end-at: chtype
   :dedent:
   :caption: ``coarse`` section (part 3)
   :name: synth_coarse3

The first three commands reassociate sums of products.  :yoscrypt:`alumacc
-macc-only` collects each chain of `$mul` and `$add` cells into a single
`$macc_v2` cell, and :yoscrypt:`maccmap -unmap` lowers it straight back to
`$mul` and `$add` cells, but as a chain with the plain addends first, so that
every multiplier has an adder of its own for `ice40_dsp` to absorb.
`opt_clean` then removes the original cells.

:yoscrypt:`wreduce t:$mul` performs width reduction again, this time targetting
only cells of type `$mul`.  :yoscrypt:`techmap -map +/mul2dsp.v -map
+/ice40/dsp_map.v ... -D DSP_NAME=$__MUL16X16` uses `techmap` to map `$mul`
cells to ``$__MUL16X16`` which are, in turn, mapped to the iCE40 ``SB_MAC16``.
Any multipliers which aren't compatible with conversion to ``$__MUL16X16`` are
relabelled to ``$__soft_mul`` before `chtype` changes them back to `$mul`.

During the mul2dsp conversion, some of the intermediate signals are marked with
the attribute ``mul2dsp``.  By calling :yoscrypt:`select a:mul2dsp` we restrict
the following commands to only operate on the cells and wires used for these
signals.  `setattr` removes the now unnecessary ``mul2dsp`` attribute.
`opt_expr` we've already come across for const folding and simple expression
rewriting, the ``-fine`` option just enables more fine-grain optimizations.
Then we perform width reduction a final time and clear the selection.

.. todo:: ``ice40_dsp`` is pmgen

Finally we have `ice40_dsp`: similar to the `memory_dff` command we saw in the
previous section, this merges any surrounding registers into the ``SB_MAC16``
cell.  This includes not just the input/output registers, but also pipeline
registers and even a post-adder where applicable: turning a multiply + add into
a single multiply-accumulate.

.. seealso:: Advanced usage docs for
   :doc:`/using_yosys/synthesis/techmap_synth`

Part 4
^^^^^^

That brings us to the fourth and final part for the iCE40 synthesis flow:

.. literalinclude:: /code_examples/macro_commands/synth_ice40.ys
   :language: yoscrypt
   :start-after: chtype
   :end-before: map_ram:
   :dedent:
   :caption: ``coarse`` section (part 4)
   :name: synth_coarse4

Where before each type of arithmetic operation had its own cell, e.g. `$add`, we
now want to extract these into `$alu` and `$macc_v2` cells which can help identify
opportunities for reusing logic.  We do this by running `alumacc`, which we can
see produce the following changes in our example design:

.. literalinclude:: /code_examples/fifo/fifo.out
   :language: doscon
   :start-at: yosys> alumacc
   :end-before: yosys> select
   :caption: output of `alumacc`

.. figure:: /_images/code_examples/fifo/rdata_alumacc.*
   :class: width-helper invert-helper
   :name: rdata_alumacc

   ``rdata`` output after `alumacc`

Once these cells have been inserted, the call to `opt` can combine cells which
are now identical but may have been missed due to e.g. the difference between
`$add` and `$sub`.

The other new command in this part is :cmd:title:`memory`.  `memory` is another
macro command which we examine in more detail in
:doc:`/using_yosys/synthesis/memory`.  For this document, let us focus just on
the step most relevant to our example: `memory_collect`. Up until this point,
our memory reads and our memory writes have been totally disjoint cells;
operating on the same memory only in the abstract. `memory_collect` combines all
of the reads and writes for a memory block into a single cell.

.. figure:: /_images/code_examples/fifo/rdata_coarse.*
   :class: width-helper invert-helper
   :name: rdata_coarse

   ``rdata`` output after `memory_collect`

Looking at the schematic after running `memory_collect` we see that our
`$memrd_v2` cell has been replaced with a `$mem_v2` cell named ``data``, the
same name that we used in :ref:`fifo-v`. Where before we had a single set of
signals for address and enable, we now have one set for reading (``RD_*``) and
one for writing (``WR_*``), as well as both ``WR_DATA`` input and ``RD_DATA``
output.

.. seealso:: Advanced usage docs for

   - :doc:`/using_yosys/synthesis/opt`
   - :doc:`/using_yosys/synthesis/memory`

Final note
^^^^^^^^^^

Having now reached the end of the the coarse-grain representation, we could also
have gotten here by running :yoscrypt:`synth_ice40 -top fifo -run :map_ram`
after loading the design.  The :yoscrypt:`-run <from_label>:<to_label>` option
with an empty ``<from_label>`` starts from the :ref:`synth_begin`, while the
``<to_label>`` runs up to but including the :ref:`map_ram`.

Hardware mapping
~~~~~~~~~~~~~~~~

The remaining sections each map a different type of hardware and are much more
architecture dependent than the previous sections.  As such we will only be
looking at each section very briefly.

If you skipped calling :yoscrypt:`read_verilog -D ICE40_HX -lib -specify
+/ice40/cells_sim.v` earlier, do it now.

Memory blocks
^^^^^^^^^^^^^

Mapping to hard memory blocks uses a combination of `memory_libmap` and
`techmap`.

.. literalinclude:: /code_examples/macro_commands/synth_ice40.ys
   :language: yoscrypt
   :start-after: map_ram:
   :end-before: map_ffram:
   :dedent:
   :name: map_ram
   :caption: ``map_ram`` section

.. figure:: /_images/code_examples/fifo/rdata_map_ram.*
   :class: width-helper invert-helper
   :name: rdata_map_ram

   ``rdata`` output after :ref:`map_ram`

The :ref:`map_ram` converts the generic `$mem_v2` into the iCE40 ``SB_RAM40_4K``
(highlighted). We can also see the memory address has been remapped, and the
data bits have been reordered (or swizzled).  There is also now a `$mux` cell
controlling the value of ``rdata``.  In :ref:`fifo-v` we wrote our memory as
read-before-write, however the ``SB_RAM40_4K`` has undefined behaviour when
reading from and writing to the same address in the same cycle. As a result,
extra logic is added so that the generated circuit matches the behaviour of the
verilog.  :ref:`no_rw_check` describes how we could change our verilog to match
our hardware instead.

If we run `memory_libmap` under the `debug` command we can see candidates which
were identified for mapping, along with the costs of each and what logic
requires emulation.

.. literalinclude:: /code_examples/fifo/fifo.libmap
   :language: doscon
   :lines: 2, 6-

The ``$__ICE40_RAM4K_`` cell is defined in the file |techlibs/ice40/brams.txt|_,
with the mapping to ``SB_RAM40_4K`` done by `techmap` using
|techlibs/ice40/brams_map.v|_.  Any leftover memory cells are then converted
into flip flops (the ``logic fallback``) with `memory_map`.

.. |techlibs/ice40/brams.txt| replace:: :file:`techlibs/ice40/brams.txt`
.. _techlibs/ice40/brams.txt: https://github.com/YosysHQ/yosys/tree/main/techlibs/ice40/brams.txt
.. |techlibs/ice40/brams_map.v| replace:: :file:`techlibs/ice40/brams_map.v`
.. _techlibs/ice40/brams_map.v: https://github.com/YosysHQ/yosys/tree/main/techlibs/ice40/brams_map.v

.. literalinclude:: /code_examples/macro_commands/synth_ice40.ys
   :language: yoscrypt
   :start-after: map_ffram:
   :end-before: map_gates:
   :dedent:
   :name: map_ffram
   :caption: ``map_ffram`` section

.. figure:: /_images/code_examples/fifo/rdata_map_ffram.*
   :class: width-helper invert-helper
   :name: rdata_map_ffram

   ``rdata`` output after :ref:`map_ffram`

.. note::

   The visual clutter on the ``RDATA`` output port (highlighted) is an
   unfortunate side effect of `opt_clean` on the swizzled data bits. In
   connecting the `$mux` input port directly to ``RDATA`` to reduce the number
   of wires, the ``$techmap579\data.0.0.RDATA`` wire becomes more visually
   complex.

.. seealso:: Advanced usage docs for

   - :doc:`/using_yosys/synthesis/techmap_synth`
   - :doc:`/using_yosys/synthesis/memory`

Arithmetic
^^^^^^^^^^

Uses `techmap` to map basic arithmetic logic to hardware.  This sees somewhat of
an explosion in cells as multi-bit `$mux` and `$adffe` are replaced with
single-bit `$_MUX_` and `$_DFFE_PP0P_` cells, while the `$alu` is replaced with
primitive `$_OR_` and `$_NOT_` gates and a `$lut` cell.

.. literalinclude:: /code_examples/macro_commands/synth_ice40.ys
   :language: yoscrypt
   :start-after: map_gates:
   :end-before: map_ffs:
   :dedent:
   :name: map_gates
   :caption: ``map_gates`` section

.. figure:: /_images/code_examples/fifo/rdata_map_gates.*
   :class: width-helper invert-helper
   :name: rdata_map_gates

   ``rdata`` output after :ref:`map_gates`

.. seealso:: Advanced usage docs for
   :doc:`/using_yosys/synthesis/techmap_synth`

Flip-flops
^^^^^^^^^^

Convert FFs to the types supported in hardware with `dfflegalize`, and then use
`techmap` to map them.  In our example, this converts the `$_DFFE_PP0P_` cells
to ``SB_DFFER``.

We also run `simplemap` here to convert any remaining cells which could not be
mapped to hardware into gate-level primitives.  This includes optimizing
`$_MUX_` cells where one of the inputs is a constant ``1'0``, replacing it
instead with an `$_AND_` cell.

.. literalinclude:: /code_examples/macro_commands/synth_ice40.ys
   :language: yoscrypt
   :start-after: map_ffs:
   :end-before: map_luts:
   :dedent:
   :name: map_ffs
   :caption: ``map_ffs`` section

.. figure:: /_images/code_examples/fifo/rdata_map_ffs.*
   :class: width-helper invert-helper
   :name: rdata_map_ffs

   ``rdata`` output after :ref:`map_ffs`

.. seealso:: Advanced usage docs for
   :doc:`/using_yosys/synthesis/techmap_synth`

LUTs
^^^^

`abc` and `techmap` are used to map LUTs; converting primitive cell types to use
`$lut` and ``SB_CARRY`` cells.  Note that the iCE40 flow uses `abc9` rather than
`abc`. For more on what these do, and what the difference between these two
commands are, refer to :doc:`/using_yosys/synthesis/abc`.

.. literalinclude:: /code_examples/macro_commands/synth_ice40.ys
   :language: yoscrypt
   :start-after: map_luts:
   :end-before: map_cells:
   :dedent:
   :name: map_luts
   :caption: ``map_luts`` section

.. figure:: /_images/code_examples/fifo/rdata_map_luts.*
   :class: width-helper invert-helper
   :name: rdata_map_luts

   ``rdata`` output after :ref:`map_luts`

Finally we use `techmap` to map the generic `$lut` cells to iCE40 ``SB_LUT4``
cells.

.. literalinclude:: /code_examples/macro_commands/synth_ice40.ys
   :language: yoscrypt
   :start-after: map_cells:
   :end-before: check:
   :dedent:
   :name: map_cells
   :caption: ``map_cells`` section

.. figure:: /_images/code_examples/fifo/rdata_map_cells.*
   :class: width-helper invert-helper
   :name: rdata_map_cells

   ``rdata`` output after :ref:`map_cells`

.. seealso:: Advanced usage docs for

   - :doc:`/using_yosys/synthesis/techmap_synth`
   - :doc:`/using_yosys/synthesis/abc`

Other cells
^^^^^^^^^^^

The following commands may also be used for mapping other cells:

`hilomap`
    Some architectures require special driver cells for driving a constant hi or
    lo value. This command replaces simple constants with instances of such
    driver cells.

`iopadmap`
    Top-level input/outputs must usually be implemented using special I/O-pad
    cells. This command inserts such cells to the design.

These commands tend to either be in the :ref:`map_cells` or after the
:ref:`check` depending on the flow.

Final steps
~~~~~~~~~~~~

The next section of the iCE40 synth flow performs some sanity checking and final
tidy up:

.. literalinclude:: /code_examples/macro_commands/synth_ice40.ys
   :language: yoscrypt
   :start-after: check:
   :dedent:
   :name: check
   :caption: ``check`` section

The new commands here are:

- :cmd:title:`autoname`,
- :cmd:title:`stat`, and
- :cmd:title:`blackbox`.

The output from `stat` is useful for checking resource utilization; providing a
list of cells used in the design and the number of each, as well as the number
of other resources used such as wires and processes.  For this design, the final
call to `stat` should look something like the following:

.. literalinclude:: /code_examples/fifo/fifo.stat
   :language: doscon
   :start-at: yosys> stat -top fifo

Note that the :yoscrypt:`-top fifo` here is optional.  `stat` will automatically
use the module with the ``top`` attribute set, which ``fifo`` was when we called
`hierarchy`.  If no module is marked ``top``, then stats will be shown for each
module selected.

The `stat` output is also useful as a kind of sanity-check: Since we have
already run `proc`, we wouldn't expect there to be any processes. We also expect
``data`` to use hard memory; if instead of an ``SB_RAM40_4K`` saw a high number
of flip-flops being used we might suspect something was wrong.

If we instead called `stat` immediately after :yoscrypt:`read_verilog fifo.v` we
would see something very different:

.. literalinclude:: /code_examples/fifo/fifo.stat
   :language: doscon
   :start-at: yosys> stat
   :end-before: yosys> stat -top fifo

Notice how ``fifo`` and ``addr_gen`` are listed separately, and the statistics
for ``fifo`` show 2 ``addr_gen`` modules.  Because this is before the memory has
been mapped, we also see that there is 1 memory with 2048 memory bits; matching
our 8-bit wide ``data`` memory with 256 values (:math:`8*256=2048`).

Synthesis output
^^^^^^^^^^^^^^^^

The iCE40 synthesis flow has the following output modes available:

- `write_blif`,
- `write_edif`, and
- `write_json`.

As an example, if we called :yoscrypt:`synth_ice40 -top fifo -json fifo.json`,
our synthesized ``fifo`` design will be output as :file:`fifo.json`.  We can
then read the design back into Yosys with `read_json`, but make sure you use
:yoscrypt:`design -reset` or open a new interactive terminal first.  The JSON
output we get can also be loaded into `nextpnr`_ to do place and route; but that
is beyond the scope of this documentation.

.. _nextpnr: https://github.com/YosysHQ/nextpnr

.. seealso:: :cmd:title:`synth_ice40`

---

### Source Getting Started Index (`docs/source/getting_started/index.rst`)

Getting started with Yosys
==========================

This section covers how to get started with Yosys, from installation to a guided
walkthrough of synthesizing a design for hardware, and finishing with an
introduction to writing re-usable Yosys scripts.

.. toctree::
   :maxdepth: 3

   installation
   example_synth
   scripting_intro

---

### Source Getting Started Installation (`docs/source/getting_started/installation.rst`)

Installation
------------

This document will guide you through the process of installing Yosys.

CAD suite(s)
~~~~~~~~~~~~

Yosys is part of the `Tabby CAD Suite
<https://www.yosyshq.com/tabby-cad-datasheet>`_ and the `OSS CAD Suite
<https://github.com/YosysHQ/oss-cad-suite-build>`_! The easiest way to use yosys
is to install the binary software suite, which contains all required
dependencies and related tools.

* `Contact YosysHQ <https://www.yosyshq.com/contact>`_ for a `Tabby CAD Suite
  <https://www.yosyshq.com/tabby-cad-datasheet>`_ Evaluation License and
  download link
* OR go to https://github.com/YosysHQ/oss-cad-suite-build/releases to download
  the free OSS CAD Suite
* Follow the `Install Instructions on GitHub
  <https://github.com/YosysHQ/oss-cad-suite-build#installation>`_

Make sure to get a Tabby CAD Suite Evaluation License if you need features such
as industry-grade SystemVerilog and VHDL parsers!

For more information about the difference between Tabby CAD Suite and the OSS
CAD Suite, please visit https://www.yosyshq.com/tabby-cad-datasheet

Many Linux distributions also provide Yosys binaries, some more up to date than
others. Check with your package manager!

Targeted architectures
^^^^^^^^^^^^^^^^^^^^^^

The `OSS CAD Suite`_ releases `nightly builds`_ for the following architectures:

- **linux-x64** - Most personal Linux based computers
- **darwin-x64** - macOS 12 or later with Intel CPU
- **darwin-arm64** - macOS 12 or later with M1/M2 CPU
- **windows-x64** - Targeted for Windows 10 and 11
- **linux-arm64** - Devices such as Raspberry Pi with 64bit OS

For more information about the targeted architectures, and the current build
status, check the `OSS CAD Suite`_ git repository.

.. _OSS CAD Suite: https://github.com/YosysHQ/oss-cad-suite-build
.. _nightly builds: https://github.com/YosysHQ/oss-cad-suite-build/releases/latest

Building from source
~~~~~~~~~~~~~~~~~~~~

The Yosys source files can be obtained from the `YosysHQ/Yosys git repository`_.
`ABC`_ and some of the other libraries used are included as git submodules.  To
clone these submodules at the same time, use e.g.:

.. code:: console

   git clone --recurse-submodules https://github.com/YosysHQ/yosys.git  # ..or..
   git clone https://github.com/YosysHQ/yosys.git
   cd yosys
   git submodule update --init --recursive

.. _YosysHQ/Yosys git repository: https://github.com/yosyshq/yosys/
.. _ABC: https://github.com/berkeley-abc/abc

.. note::

   As of Yosys v0.47, releases include a ``yosys.tar.gz`` file which includes
   all source code and all sub-modules in a single archive.  This can be used as
   an alternative which does not rely on :program:`git`.

Supported platforms
^^^^^^^^^^^^^^^^^^^

The following platforms are supported and regularly tested:

- Linux
- macOS

Other platforms which may work, but instructions may not be up to date and are
not regularly tested:

- FreeBSD
- WSL
- Windows with (e.g.) Cygwin

Build prerequisites
^^^^^^^^^^^^^^^^^^^

A C++ compiler with C++20 support is required as well as some standard tools
such as GNU Flex, GNU Bison (>=3.8), CMake (>=3.28), Make (or other CMake
generator such as Ninja), and Python (>=3.11). Some additional tools: readline,
libffi, Tcl and zlib; will be used if available but are optional. Graphviz and
Xdot are used by the `show` command to display schematics.

Installing all prerequisites:

.. tab:: Ubuntu 22.04

   .. code:: console

      sudo apt-get install gawk git make python3 lld bison clang flex \
         libffi-dev libfl-dev libreadline-dev pkg-config tcl-dev zlib1g-dev \
         graphviz xdot
      sudo snap install cmake --classic

.. tab:: Ubuntu 24.04

   .. code:: console

      sudo apt-get install gawk git cmake make python3 lld bison clang flex \
         libffi-dev libfl-dev libreadline-dev pkg-config tcl-dev zlib1g-dev \
         graphviz xdot

.. tab:: macOS 13 (with Homebrew)

   .. code:: console

      brew tap Homebrew/bundle && brew bundle

.. tab:: MacPorts

   .. code:: console

      sudo port install bison cmake flex readline gawk libffi graphviz \
         pkgconfig python311 zlib tcl

.. tab:: FreeBSD

   .. code:: console

      pkg install bison cmake-core flex readline gawk libffi graphviz \
         pkgconf python311 tcl-wrapper

.. tab:: Cygwin

   Use the following command to install all prerequisites, or select these
   additional packages:

   .. code:: console

      setup-x86_64.exe -q --packages=bison,flex,gcc-core,gcc-g++,git,libffi-devel,libreadline-devel,cmake,make,pkg-config,python3,tcl-devel,zlib-devel

   .. warning::

      As of this writing, Cygwin only supports up to Python 3.9.16 while the
      minimum required version of Python is 3.11.  This means that Cygwin is not
      compatible with many of the Python-based frontends.  While this does not
      currently prevent Yosys itself from working, no guarantees are made for
      continued support.  You may also need to specify ``CXXSTD=gnu++20`` to
      resolve missing ``strdup`` function when using gcc.  It is instead
      recommended to use Windows Subsystem for Linux (WSL) and follow the
      instructions for Ubuntu.

..
   tab:: MSYS2 (MINGW64)

   .. code:: console

      pacman -S bison flex mingw-w64-x86_64-gcc git libffi-devel libreadline-devel make pkg-config python3 tcl-devel zlib-devel

   Not that I can get this to work; it's failing during ld with what looks like
   math library issues: ``multiple definition of `tanh'`` and
   ``undefined reference to `__imp_acosh'``, as well as issues in `aiger2` with
   ``seekg`` et al not being available.

   .. note::

      The ``config-msys2-64`` target uses the ``mingw-w64-x86_64-`` prefixed
      compiler in order to allow compiled exe files to be run without an MSYS2
      shell.

Build configuration
^^^^^^^^^^^^^^^^^^^

The Yosys build is configured via CMake, and uses a number of variables which
influence the build process.  When setting one-off variables, CMake provides the
``-D <var>=<value>`` command line option. For example, disabling zlib support:

.. code:: console

   cmake -B build . -DYOSYS_WITHOUT_ZLIB=ON

.. warning::

   Yosys does not support in-tree builds. If calling :program:`cmake` from the
   root ``yosys`` directory the ``-B`` option must be provided.

For a more persistent configuration, we recommend creating and using a
``CMakeUserPresets.json`` file in the root ``yosys`` directory. Below is an
example file which has two configurations, one enables ccache and sets the default compiler to clang when
calling ``cmake --preset clang``, and the other disables zlib support when calling ``cmake --preset without_zlib``
This can be used instead of manually specifying ``-DYOSYS_WITHOUT_ZLIB=ON``:

.. code-block:: json
   :caption: CMakeUserPresets.json

   {
      "version": 1,
      "configurePresets": [
         {
			"name": "clang",
			"inherits": "default",
			"generator": "Unix Makefiles",
			"cacheVariables": {
				"CMAKE_C_COMPILER": "clang",
				"CMAKE_CXX_COMPILER": "clang++",
				"YOSYS_COMPILER_LAUNCHER": "ccache"
			}
		},
		{
			"name": "without_zlib",
			"inherits": "clang",
			"cacheVariables": {
				"YOSYS_WITHOUT_ZLIB": "ON"
			}
		}
      ]
   }

Once generated, available build variables can be inspected and modified with
:program:`ccmake` or opening the generated ``build/CMakeCache.txt`` file:

.. code:: console

   ccmake build              #..or..
   vi build/CMakeCache.txt

If you have clang, and (a compatible version of) ``ld.lld`` available in PATH,
it's recommended to speed up incremental builds with lld by enabling LTO with
``CMAKE_INTERPROCEDURAL_OPTIMIZATION=ON``. On macOS, LTO requires using clang
from homebrew rather than clang from xcode. For example:

.. code:: console

   cmake -B build . -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON \
      -DCMAKE_C_COMPILER=$(brew --prefix)/opt/llvm/bin/clang \
      -DCMAKE_CXX_COMPILER=$(brew --prefix)/opt/llvm/bin/clang++

This is also available with a preset:

.. code:: console

   cmake --preset lto

By default, building (and installing) Yosys will build (and install) `ABC`_,
using :program:`yosys-abc` as the executable name.  To use an existing ABC
executable instead, set the :makevar:`YOSYS_ABC_EXECUTABLE` CMake variable to
point to the desired executable.

Running the build system
^^^^^^^^^^^^^^^^^^^^^^^^

To quickly install Yosys with default settings, call the following commands from
the root ``yosys`` directory:

.. code:: console

   cmake --preset release --fresh
   cmake --build build-rel --config Release --parallel $(nproc)
   sudo cmake --install build-rel --strip

To use an existing configuration, use the ``--build`` option, e.g:

.. code:: console

   cmake --preset default
   ccmake build              # modify configuration
   cmake --build build

.. seealso::

   Refer to :doc:`/yosys_internals/extending_yosys/test_suites` for details on
   testing Yosys once compiled.

Source tree and build system
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The Yosys source tree is organized into the following top-level
directories:

``backends/``
   This directory contains a subdirectory for each of the backend modules.

``cmake/``
   Additional ``.cmake`` files used by CMake during build generation.

``docs/``
   Contains the source for this documentation, including images and sample code.

``examples/``
   Contains example code for using Yosys with some other tools including a demo
   of the Yosys Python api, and synthesizing for various toolchains such as
   Intel and Anlogic.

``frontends/``
   This directory contains a subdirectory for each of the frontend modules.

``kernel/``
   This directory contains all the core functionality of Yosys. This includes
   the functions and definitions for working with the RTLIL data structures
   (:file:`rtlil.{h|cc}`), the ``main()`` function (:file:`driver.cc`), the
   internal framework for generating log messages (:file:`log.{h|cc}`), the
   internal framework for registering and calling passes
   (:file:`register.{h|cc}`), some core commands that are not really passes
   (:file:`select.cc`, :file:`show.cc`, โ€ฆ) and a couple of other small utility
   libraries.

``libs/``
   Libraries packaged with Yosys builds are contained in this folder.  See
   :doc:`/appendix/auxlibs`.

``misc/``
   Other miscellany which doesn't fit anywhere else.

``passes/``
   This directory contains a subdirectory for each pass or group of passes. For
   example as of this writing the directory :file:`passes/hierarchy/` contains
   the code for three passes: `hierarchy`, `submod`, and `uniquify`.

``pyosys/``
   Contains the scripts and wrappers necessary for building :doc:`Pyosys
   </using_yosys/pyosys>`.

``techlibs/``
   This directory contains simulation models and standard implementations for
   the cells from the internal cell library.

``tests/``
   This directory contains the suite of unit tests and regression tests used by
   Yosys.  See :doc:`/yosys_internals/extending_yosys/test_suites`.

.. TODO:: CMAKE_TODO

   - ``yosys_<pass|test_pass|frontend|backend>(<name>)`` for each pass

      - see :file:`cmake/YosysComponent.cmake`

   - if using a sub folder, add it to the parent's ``CMakeLists.txt`` with
     ``add_subdirectory(<name>)``

   - previous:

   The Yosys kernel automatically detects all commands linked
   with Yosys. So it is not needed to add additional commands to a central list of
   commands.

   Good starting points for reading example source code to learn how to write
   passes are :file:`passes/opt/dff/opt_dff.cc` and :file:`passes/opt/opt_merge.cc`.

   Users of the Qt Creator IDE can generate a QT Creator project file using make
   qtcreator. Users of the Eclipse IDE can use the "Makefile Project with Existing
   Code" project type in the Eclipse "New Project" dialog (only available after the
   CDT plugin has been installed) to create an Eclipse project in order to
   programming extensions to Yosys or just browse the Yosys code base.

---

### Source Getting Started Scripting Intro (`docs/source/getting_started/scripting_intro.rst`)

Scripting in Yosys
------------------

On the previous page we went through a synthesis script, running each command in
the interactive Yosys shell.  On this page, we will be introducing the script
file format and how you can make your own synthesis scripts.

Yosys script files typically use the :file:`.ys` extension and contain a set of
commands for Yosys to run sequentially.  These commands are the same ones we
were using on the previous page like `read_verilog` and `hierarchy`.

Script parsing
~~~~~~~~~~~~~~

As with the interactive shell, each command consists of the command name, and an
optional whitespace separated list of arguments. Commands are terminated with
the newline character, and anything after a hash sign ``#`` is a comment (i.e.
it is ignored).

It is also possible to terminate commands with a semicolon ``;``.  This is
particularly useful in conjunction with the ``-p <command>`` command line
option, where ``<command>`` can be a string with multiple commands separated by
semicolon. In-line comments can also be made with the colon ``:``, where the end
of the comment is a semicolon ``;`` or a new line.

.. code-block::
   :caption: Using the ``-p`` option

   $ yosys -p 'read_verilog fifo.v; :this is a comment; prep'

.. warning::

   The space after the semicolon is required for correct parsing. ``log a;log
   b;`` for example will display ``a;log b`` instead of ``a`` and ``b`` as might
   be expected.

Another special character that can be used in Yosys scripts is the bang ``!``.
Anything after the bang will be executed as a shell command.  This can only be
terminated with a new line.  Any semicolons, hashes, or other special characters
will be passed to the shell.  If an error code is returned from the shell it
will be raised by Yosys.  `exec` provides a much more flexible way of executing
commands, allowing the output to be logged and more control over when to
generate errors.

.. warning::

   Take care when using the ``yosys -p`` option.  Some shells such as bash will
   perform substitution options inside of a double quoted string, such as ``!``
   for history substitution and ``$`` for variable substitution; single quotes
   should be used instead to pass the string to Yosys without substitution.

The synthesis starter script
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. role:: yoscrypt(code)
   :language: yoscrypt

All of the images and console output used in
:doc:`/getting_started/example_synth` were generated by Yosys, using Yosys
script files found in :file:`docs/source/code_examples/fifo`. If you haven't
already, let's take a look at some of those script files now.

.. literalinclude:: /code_examples/fifo/fifo.ys
   :language: yoscrypt
   :lineno-match:
   :start-at: echo on
   :end-before: design -reset
   :caption: A section of :file:`fifo.ys`, generating the images used for :ref:`addr_gen_example`
   :name: fifo-ys

The first command there, :yoscrypt:`echo on`, uses `echo` to enable command
echoes on.  This is how we generated the code listing for
:ref:`hierarchy_output`.  Turning command echoes on prints the ``yosys>
hierarchy -top addr_gen`` line, making the output look the same as if it were an
interactive terminal.  :yoscrypt:`hierarchy -top addr_gen` is of course the
command we were demonstrating, including the output text and an image of the
design schematic after running it.

We briefly touched on `select` when it came up in `synth_ice40`, but let's look
at it more now.

.. _select_intro:

Selections intro
^^^^^^^^^^^^^^^^

The `select` command is used to modify and view the list of selected objects:

.. literalinclude:: /code_examples/fifo/fifo.out
   :language: doscon
   :start-at: yosys> select
   :end-before: yosys> show

When we call :yoscrypt:`select -module addr_gen` we are changing the currently
active selection from the whole design, to just the ``addr_gen`` module.  Notice
how this changes the ``yosys`` at the start of each command to ``yosys
[addr_gen]``?  This indicates that any commands we run at this point will *only*
operate on the ``addr_gen`` module.  When we then call :yoscrypt:`select -list`
we get a list of all objects in the ``addr_gen`` module, including the module
itself, as well as all of the wires, inputs, outputs, processes, and cells.

Next we perform another selection, :yoscrypt:`select t:*`.  The ``t:`` part
signifies we are matching on the *cell type*, and the ``*`` means to match
anything.  For this (very simple) selection, we are trying to find all of the
cells, regardless of their type.  The active selection is now shown as
``[addr_gen]*``, indicating some sub-selection of the ``addr_gen`` module.  This
gives us the `$add` and `$eq` cells, which we want to highlight for the
:ref:`addr_gen_hier` image.

.. _select_new_cells:

We can assign a name to a selection with :yoscrypt:`select -set`.  In our case
we are using the name ``new_cells``, and telling it to use the current
selection, indicated by the ``%`` symbol.  We can then use this named selection
by referring to it as ``@new_cells``, which we will see later.  Then we clear
the selection so that the following commands can operate on the full design.
While we split that out for this document, we could have done the same thing in
a single line by calling :yoscrypt:`select -set new_cells addr_gen/t:*`.  If we
know we only have the one module in our design, we can even skip the
``addr_gen/`` part.  Looking further down :ref:`the fifo.ys code <fifo-ys>` we
can see this with :yoscrypt:`select -set new_cells t:$mux t:*dff`.  We can also
see in that command that selections don't have to be limited to a single
statement.

Many commands also support an optional ``[selection]`` argument which can be
used to override the currently selected objects.  We could, for example, call
:yoscrypt:`clean addr_gen` to have `clean` operate on *just* the ``addr_gen``
module.

Detailed documentation of the select framework can be found under
:doc:`/using_yosys/more_scripting/selections` or in the command reference at
:cmd:title:`select`.

.. _show_intro:

Displaying schematics
^^^^^^^^^^^^^^^^^^^^^

While the `select` command is very useful, sometimes nothing beats being able to
see a design for yourself.  This is where `show` comes in.  Note that this
document is just an introduction to the `show` command, only covering the
basics.  For more information, including a guide on what the different symbols
represent, see :ref:`interactive_show` and the
:doc:`/using_yosys/more_scripting/interactive_investigation` page.

.. figure:: /_images/code_examples/fifo/addr_gen_show.*
   :class: width-helper invert-helper
   :name: addr_gen_show

   Calling :yoscrypt:`show addr_gen` after `hierarchy`

.. note::

   The `show` command requires a working installation of `GraphViz`_ and `xdot`_
   for displaying the actual circuit diagrams.

.. _GraphViz: http://www.graphviz.org/
.. _xdot: https://github.com/jrfonseca/xdot.py

This is the first :yoscrypt:`show` command we called in :file:`fifo.ys`,
:ref:`as we saw above <fifo-ys>`.  If we look at the log output for this image
we see the following:

.. literalinclude:: /code_examples/fifo/fifo.out
   :language: doscon
   :start-at: -prefix addr_gen_show
   :end-before: yosys> show

Calling `show` with :yoscrypt:`-format dot` tells it we want to output a
:file:`.dot` file rather than opening it for display.  The :yoscrypt:`-prefix
addr_gen_show` option indicates we want the file to be called
:file:`addr_gen_show.{*}`. Remember, we do this in :file:`fifo.ys` because we
need to store the image for displaying in the documentation you're reading.  But
if you just want to display the images locally you can skip these two options.
The ``-format`` option internally calls the ``dot`` command line program from
GraphViz to convert to formats other than :file:`.dot`.  Check `GraphViz output
docs`_ for more on available formats.

.. _GraphViz output docs: https://graphviz.org/docs/outputs/

.. note::

   If you are using a POSIX based version of Yosys (such as for Mac or Linux),
   xdot will be opened in the background and Yosys can continue to be used. If
   it it still open, future calls to :yoscrypt:`show` will use the same xdot
   instance.

The ``addr_gen`` at the end tells it we only want the ``addr_gen`` module, just
like when we called :yoscrypt:`select -module addr_gen` in :ref:`select_intro`.
That last parameter doesn't have to be a module name, it can be any valid
selection string.  Remember when we :ref:`assigned a name to a
selection<select_new_cells>` and called it ``new_cells``?  We saw in the
:yoscrypt:`select -list` output that it contained two cells, an `$add` and an
`$eq`.  We can call `show` on that selection just as easily:

.. figure:: /_images/code_examples/fifo/new_cells_show.*
   :class: width-helper invert-helper
   :name: new_cells_show

   Calling :yoscrypt:`show -notitle @new_cells`

We could have gotten the same output with :yoscrypt:`show -notitle t:$add t:$eq`
if we didn't have the named selection. By adding the :yoscrypt:`-notitle` flag
there we can also get rid of the ``addr_gen`` title that would have been
automatically added.  The last two images were both added for this introduction.
The next image is the first one we saw in :doc:`/getting_started/example_synth`:
showing the full ``addr_gen`` module while also highlighting ``@new_cells`` and
the two ``PROC`` blocks.  To achieve this highlight, we make use of the
:yoscrypt:`-color` option:

.. figure:: /_images/code_examples/fifo/addr_gen_hier.*
   :class: width-helper invert-helper

   Calling :yoscrypt:`show -color maroon3 @new_cells -color cornflowerblue p:* -notitle`

As described in the the `help` output for `show` (or by clicking on the `show`
link), colors are specified as :yoscrypt:`-color <color> <object>`.  Color names
for the ``<color>`` portion can be found on the `GraphViz color docs`_.  Unlike
the final `show` parameter which can have be any selection string, the
``<object>`` part must be a single selection expression or named selection.
That means while we can use ``@new_cells``, we couldn't use ``t:$eq t:$add``.
In general, if a command lists ``[selection]`` as its final parameter it can be
any selection string.  Any selections that are not the final parameter, such as
those used in options, must be a single expression instead.

.. _GraphViz color docs: https://graphviz.org/doc/info/colors

For all of the options available to `show`, check the command reference at
:cmd:title:`show`.

.. seealso:: :ref:`interactive_show` on the
   :doc:`/using_yosys/more_scripting/interactive_investigation` page.

---

### Source Using Yosys Bugpoint (`docs/source/using_yosys/bugpoint.rst`)

Minimizing failing (or bugged) designs
======================================

.. TODO:: pending merge of https://github.com/YosysHQ/yosys/pull/5068

This document is a how-to guide for reducing problematic designs to the bare
minimum needed for reproducing the issue.  This is a Yosys specific alternative
to the Stack Overflow article: `How to create a Minimal, Reproducible Example`_,
and is intended to help when there's something wrong with your design, or with
Yosys itself.

.. _How to create a Minimal, Reproducible Example: https://stackoverflow.com/help/minimal-reproducible-example

.. note::

   This guide assumes a moderate degree of familiarity with Yosys and requires
   some amount of problem solving ability.


Before you start
----------------

The first (and often overlooked) step, is to check for and *read* any error
messages or warnings.  Passing the ``-q`` flag when running Yosys will make it
so that only warnings and error messages are written to the console.  Don't just
read the last message either, there may be warnings that indicate a problem
before it happens.  While some things may only be regarded as warnings, such as
multiple drivers for the same signal or logic loops, these can cause problems in
some synthesis flows but not others.

A Yosys error (one that starts with ``ERROR:``) may give you a line number from
your design, or the name of the object causing issues.  If so, you may already
have enough information to resolve the problem, or at least understand why it's
happening.

.. note::

   If you're not already, try using the latest version from the `Yosys GitHub`_.
   You may find that your issue has already been fixed!  And even if it isn't,
   testing with two different versions is a good way to ensure reproducibility.

.. _Yosys GitHub: https://github.com/YosysHQ/yosys

Another thing to be aware of is that Yosys generally doesn't perform rigorous
checking of input designs to ensure they are valid.  This is especially true for
the `read_verilog` frontend.  It is instead recommended that you try load it
with `iverilog`_ or `verilator`_ first, as an invalid design can often lead to
unexpected issues.

.. _iverilog: https://steveicarus.github.io/iverilog/
.. _verilator: https://www.veripool.org/verilator/

If you're using a custom synthesis script, try take a bit of time to figure out
which command is failing.  Calling ``echo on`` at the start of your script will
`echo` each command executed; the last echo before the error should then be
where the error has come from.  Check the help message for the failing command;
does it indicate limited support, or mention some other command that needs to be
run first?  You can also try to call `check` and/or ``hierarchy -check`` before
the failure to see if they report and errors or warnings.


Minimizing RTLIL designs with bugpoint
--------------------------------------

Yosys provides the `bugpoint` command for reducing a failing design to the
smallest portion of that design which still results in failure.  While initially
developed for Yosys crashes, `bugpoint` can also be used for designs that lead
to non-fatal errors, or even failures in other tools that use the output of a
Yosys script.

.. note::

   Make sure to back up your code (design source and yosys script(s)) before
   making any modifications.  Even if the code itself isn't important, this can
   help avoid "losing" the error while trying to debug it.

Can I use bugpoint?
~~~~~~~~~~~~~~~~~~~

The first thing to be aware of is that `bugpoint` is not available in every
build of Yosys.  Because the command works by invoking external processes, it
requires that Yosys can spawn executables.  Notably this means `bugpoint` is not
able to be used in WebAssembly builds such as that available via YoWASP.  The
easiest way to check your build of Yosys is by running ``yosys -h bugpoint``. If
Yosys displays the help text for `bugpoint` then it is available for use.

.. code-block:: console
   :caption: `bugpoint` is unavailable

   $ yosys -h bugpoint

   -- Running command `help bugpoint' --
   No such command or cell type: bugpoint

Next you need to separate loading the design from the failure point; you should
be aiming to reproduce the failure by running ``yosys -s <load.ys> -s
<failure.ys>``.  If the failure occurs while loading the design, such as during
`read_verilog` you will instead have to minimize the input design yourself.
Check out the instructions for :ref:`using_yosys/bugpoint:minimizing verilog
designs` below.

.. note::

   You should also be able to run the two scripts separately, calling first
   ``yosys -s <load.ys> -p 'write_rtlil design.il'`` and then ``yosys -s
   <failure.ys> design.il``.  If this doesn't work then it may mean that the
   failure isn't reproducible from RTLIL and `bugpoint` won't work either.

When we talk about failure points here, it doesn't just mean crashes or errors
in Yosys.  The ``<failure.ys>`` script can also be a user-defined failure such
as the `select` command with one of the ``-assert-*`` options; an example where
this might be useful is when a pass is supposed to remove a certain kind of
cell, but there is some edge case where the cell is not removed.  Another
use-case would be minimizing a design which fails with the `equiv_opt` command,
suggesting that the optimization in question alters the circuit in some way.

It is even possible to use `bugpoint` with failures *external* to Yosys, by
making use of the `exec` command in ``<failure.ys>``.  This is especially useful
when Yosys is outputting an invalid design, or when some other tool is
incompatible with the design.  Be sure to use the ``exec -expect-*`` options so
that the pass/fail can be detected correctly.  Multiple calls to `exec` can be
made, or even entire shell scripts:

.. code-block:: yoscrypt

   exec -expect-return 1 --bash <script.sh>

Our final failure we can use with `bugpoint` is one returned by a wrapper
process, such as ``valgrind`` or ``timeout``.  In this case you will be calling
something like ``<wrapper> yosys -s <failure.ys> design.il``.  Here, Yosys is
run under a wrapper process which checks for some failure state, like a memory
leak or excessive runtime.


How do I use bugpoint?
~~~~~~~~~~~~~~~~~~~~~~

At this point you should have:

1. either an RTLIL file containing the design to minimize (referred to here as
   ``design.il``), or a Yosys script, ``<load.ys>``, which loads it; and
2. a Yosys script, ``<failure.ys>``, which produces the failure and returns a
   non-zero return status.

Now call ``yosys -qq -s <failure.ys> design.il`` and take note of the error(s)
that get printed.  A template script, ``<bugpoint.ys>``, is provided here which
you can use.  Make sure to configure it with the correct filenames and use only
one of the methods to load the design.  Fill in the ``-grep`` option with the
error message printed just before.  If you are using a wrapper process for your
failure state, add the ``-runner "<wrapper>"`` option to the `bugpoint` call.

.. code-block:: yoscrypt
   :caption: ``<bugpoint.ys>`` template script

   # Load design
   read_rtlil design.il
   ## OR
   script <load.ys>

   # Call bugpoint with failure
   bugpoint -script <failure.ys> -grep "<string>"

   # Save minimized design
   write_rtlil min.il

The ``-grep`` option is used to search the log file generated by the Yosys under
test.  If the error message is generated by something else, such as a wrapper
process or compiler sanitizer, then you should instead use ``-err_grep``.  For
an OS error, like a SEGFAULT, you can also use ``-expect-return`` to check the
error code returned.

.. note::

   Checking the error message or return status is optional, but highly
   recommended.  `bugpoint` can quite easily introduce bugs by creating
   malformed designs that commands were not intended to handle.  By having some
   way to check the error, `bugpoint` can ensure that it is the *right* error
   being reproduced.  This is even more important when ``<failure.ys>`` contains
   more than one command.

By default, `bugpoint` is able to remove any part of the design.  In order to
keep certain parts, for instance because you already know they are related to
the failure, you can use the ``bugpoint_keep`` attribute.  This can be done with
``(* bugpoint_keep *)`` in Verilog, ``attribute \bugpoint_keep 1`` in RTLIL, or
``setattr -set bugpoint_keep 1 [selection]`` from a Yosys script.  It is also
possible to limit `bugpoint` to only removing certain *kinds* of objects, such
as only removing entire modules or cells (instances of modules).  For more about
the options available, check ``help bugpoint`` or :cmd:title:`bugpoint`.

In some situations, it may also be helpful to use `setenv` before `bugpoint` to
set environment variables for the spawned processes.  An example of this is
``setenv UBSAN_OPTIONS halt_on_error=1`` for where you are trying to raise an
error on undefined behaviour but only want the child process to halt on error.

.. note::

   Using `setenv` in this way may or may not affect the current process.  For
   instance the ``UBSAN_OPTIONS halt_on_error`` here only affects child
   processes, as does the :doc:`Yosys environment variable</appendix/env_vars>`
   ``ABC`` because they are only read on start-up.  While others, such as
   ``YOSYS_NOVERIFIC`` and ``HOME``, are evaluated each time they are used.

Once you have finished configuration, you can now run ``yosys <bugpoint.ys>``.
The first thing `bugpoint` will do is test the input design fails.  If it
doesn't, make sure you are using the right ``yosys`` executable; unless the
``-yosys`` option is provided, it will use whatever the shell defaults to, *not*
the current ``yosys``.  If you are using the ``-runner`` option, try replacing
the `bugpoint` command with ``write_rtlil test.il`` and then on a new line,
``!<wrapper> yosys -s <failure.ys> test.il`` to check it works as expected and
returns a non-zero status.

.. seealso::

   For more on script parsing and the use of ``!``, check out
   :ref:`getting_started/scripting_intro:script parsing`.

Depending on the size of your design, and the length of your ``<failure.ys>``,
`bugpoint` may take some time; remember, it will run ``yosys -s <failure.ys>``
on each iteration of the design.  The bigger the design, the more iterations.
The longer the ``<failure.ys>``, the longer each iteration will take.  As the
design shrinks and `bugpoint` converges, each iteration should take less and
less time.  Once all simplifications are exhausted and there are no more objects
that can be removed, the script will continue and the minimized design can be
saved.


What do I do with the minimized design?

First off, check the minimized design still fails. This is especially important
if you're not using write_rtlil to output the minimized design. For example,
if you ran :ref:bugpoint_script below, then calling yosys -s <failure.ys> min.v should still fail in the same way.

.. code-block:: yoscrypt
:caption: example bugpoint minimizer
:name: bugpoint_script

read_verilog design.v
bugpoint -script <failure.ys>
write_verilog min.v

The write_rtlil command is generally more reliable, since bugpoint will have
run that exact code through the failing script. Other write_* commands
convert from the RTLIL and then back again during the read_* which can
result in differences which mean the design no longer fails.

.. note::

Simply calling Yosys with the output of write_*, as in yosys -s <failure.ys> min.v, does not guarantee that the corresponding read_*
will be used. For more about this, refer to
:doc:/using_yosys/more_scripting/load_design, or load the design explicitly
with yosys -p 'read_verilog min.v' -s <failure.ys>.

Once you've verified the failure still happens, check out
:ref:using_yosys/bugpoint:identifying issues for more on what to do next.

Minimizing Verilog designs

.. seealso::

This section is not specific to Yosys, so feel free to use another guide such
as Stack Overflow's How to create a Minimal, Reproducible Example_.

Be sure to check any errors or warnings for messages that might identify source
lines or object names that might be causing the failure, and back up your source
code before modifying it. If you have multiple source files, you should start
by reducing them down to a single file. If a specific file is failing to read,
try removing everything else and just focus on that one. If your source uses
the include directive, replace it with the contents of the file referenced.

Unlike RTLIL designs where we can use bugpoint, Yosys does not provide any
tools for minimizing Verilog designs. Instead, you should use an external tool
like C-Reduce_ (with the --not-c flag) or sv-bugpoint_.

.. _C-Reduce: https://github.com/csmith-project/creduce
.. _sv-bugpoint: https://github.com/antmicro/sv-bugpoint

C-Reduce

text
As a very brief overview for using C-Reduce, you want your failing source design
(``test.v``), and some shell script which checks for the error being
investigated (``test.sh``).  Below is an :ref:`egtest` which uses `logger` and
the ``-expect error "<string>" 1`` option to perform a similar role to
``bugpoint -grep``, along with ``verilator`` to lint the code and make sure it
is still valid.

.. code-block:: bash
   :caption: Example test.sh for C-Reduce
   :name: egtest

   #!/usr/bin/env bash
   verilator --lint-only test.v &&/
   yosys -p 'logger -expect error "unsupported" 1; read_verilog test.v'

.. code-block:: verilog
   :caption: input test.v

   module top(input clk, a, b, c, output x, y, z);
      always @(posedge clk) begin
         if (a == 1'b1)
            $stop;
      end
      assign x = a;
      assign y = a ^ b;
      assign z = c;
   endmodule

In this example ``read_verilog test.v`` is giving an error message that contains
the string "unsupported" because the ``$stop`` system task is only supported in
``initial`` blocks.  By calling ``creduce ./test.sh test.v --not-c`` we can
minimize the design to just the failing code, while still being valid Verilog.

.. code-block:: verilog
   :caption: output test.v

   module a;
   always begin $stop;
   end endmodule


sv-bugpoint

sv-bugpoint works quite similarly to C-Reduce, except it requires an output
directory to be provided and the check script needs to accept the target file as
an input argument: sv-bugpoint outDir/ test.sh test.v

.. code-block:: bash
:caption: Example test.sh for sv-bugpoint

#!/usr/bin/env bash
verilator --lint-only $1 &&/
yosys -p "logger -expect error "unsupported" 1; read_verilog $1"

Notice that the commands for yosys -p are now in double quotes ("), and
the quotes around the error string are escaped (\"). This is necessary for
the $1 argument subsitution to work correctly.

Doing it manually

text
If for some reason you are unable to use a tool to minimize your code, you can
still do it manually.  But it can be a time consuming process and requires a lot
of iteration.  At any point in the process, you can check for anything that is
unused or totally disconnected (ports, wires, etc) and remove them. If a
specific module is causing the problem, try to set that as the top module
instead.  Any parameters should have their default values changed to match the
failing usage.

As a rule of thumb, try to split things roughly in half at each step; similar to
a "binary search".  If you have 10 cells (instances of modules) in your top
module, and have no idea what is causing the issue, split them into two groups
of 5 cells.  For each group of cells, try remove them and see if the failure
still happens.  If the error still occurs with the first group removed, but
disappears when the second group is removed, then the first group can be safely
removed.  If a module has no more instances, remove it entirely.  Repeat this
for each remaining group of cells until each group only has 1 cell in it and no
more cells can be removed without making the error disappear.  You can also
repeat this for each module still in your design.

After minimizing the number of cells, do the same for the process blocks in your
top module.  And again for any generate blocks and combinational blocks.
Remember to check for any ports or signals which are no longer used and remove
those too.  Any signals which are written but never read can also be removed.

.. note::

   Depending on where the design is failing, there are some commands which may
   help in identifying unused objects in the design.  `hierarchy` will identify
   which modules are used and which are not, but check for ``$paramod`` modules
   before removing unused ones. ``debug clean`` will list all unused wires in
   each module, as well as unused cells which were automatically generated
   (giving the line number of the source that generated them).  Adding the
   ``-purge`` flag will also include named wires that would normally be ignored
   by `clean`.  Though when there are large numbers of unused wires it is often
   easier to just delete sections of the code and see what happens.

Next, try to remove or reduce assignments (``a = b``) and operations (``a +
b``).  A good place to start is by checking for any wires/registers which are
read but never written.  Try removing the signal declaration and replacing
references to it with ``'0`` or ``'x``.  Do this with any constants too.  Try to
replace strings with numeric values, and wide signals with smaller ones, then
see if the error persists.

Check if there are any operations that you can simplify, like replacing ``a &
'0`` with ``'0``.  If you have enable or reset logic, try removing it and see if
the error still occurs.  Try reducing ``if .. else`` and ``case`` blocks to a
single case.  Even if that doesn't work, you may still be able to remove some
paths; start with cases that appear to be unreachable and go from there.

.. note::

   When sharing code on the `Yosys GitHub`_, please try to keep things in
   English.  Declarations and strings should stick to the letters a-z and
   numbers 0-9, unless the error is arising because of the names/characters
   used.


Identifying issues
------------------

When identifying issues, it is quite useful to understand the conditions under
which the issue is occurring.  While there are occasionally bugs that affect a
significant number of designs, Yosys changes are tested on a variety of designs
and operating systems which typically catch any such issues before they make it
into the main branch.  So what is is it about your situation that makes it
unusual?

.. note::

   If you have access to a different platform you could also check if your issue
   is reproducible there.  Some issues may be specific to the platform or build
   of Yosys.

Try to match the minimized design back to its original context.  Could you
achieve the same thing a different way, and if so, does this other method have
the same issue?  Try to change the design in small ways and see what happens;
while `bugpoint` can reduce and simplify a design, it doesn't *change* much.
What happens if you change operators, for example a left shift (or `$shl`) to a
right shift (or `$shr`)?  Try to see if the issue is tied to specific
parameters, widths, or values.

Search `the existing issues`_ and see if someone has already made a bug report.
This is where changing the design and finding the limits of what causes the
failure really comes in handy.  If you're more familiar with how the problem can
arise, you may be able to find a related issue more easily.  If an issue already
exists for one case of the problem but you've found other cases, you can comment
on the issue and help get it solved.  If there are no existing or related issues
already, then check out the steps for
:ref:`yosys_internals/extending_yosys/contributing:reporting bugs`.

.. _the existing issues: https://github.com/YosysHQ/yosys/issues

.. warning::

   If you are using a fuzzer to find bugs, follow the instructions for
   :doc:`/yosys_internals/extending_yosys/advanced_bugpoint`.  **Do not** open
   more than one fuzzer generated issue at a time if you can not identify the
   root cause.  If you are found to be doing this, your issues may be closed
   without further investigation.

---

### Source Using Yosys Index (`docs/source/using_yosys/index.rst`)

Using Yosys (advanced)
======================

While much of Yosys is focused around synthesis, there are also a number of
other useful things that can be accomplished with Yosys scripts or in an
interactive shell.  As such this section is broken into two parts:
:doc:`/using_yosys/synthesis/index` expands on the
:doc:`/getting_started/example_synth` and goes into further detail on the major
commands used in synthesis; :doc:`/using_yosys/more_scripting/index` covers the
ways Yosys can interact with designs for a deeper investigation.

.. toctree::
   :maxdepth: 2
   :hidden:

   synthesis/index
   more_scripting/index
   bugpoint
   verilog
   pyosys

---

### Source Using Yosys Pyosys (`docs/source/using_yosys/pyosys.rst`)

Scripting with Pyosys
=====================

.. TODO:: document libyosys sans python

Pyosys is a limited subset of the Yosys C++ API (aka "libyosys") made available
using the Python programming language.

Like ``.ys`` and ``.tcl`` scripts, Pyosys provides an interface to write Yosys
scripts in the Python programming language, giving you the benefits of
a type system, control flow, object-oriented programming, and more; especially
that the other options lack a type system and control flow/OOP in Tcl is
limited.

Though unlike these two, Pyosys goes a bit further, allowing you to use the
Yosys API to implement advanced functionality that would otherwise require
custom passes written in C++.

.. note::

   It is recommended to install :program:`uv` for managing python environments:

   .. code:: console

      curl -LsSf https://astral.sh/uv/install.sh | sh

Getting Pyosys
--------------

Pyosys supports CPython 3.8 or higher. You can access Pyosys using one of two
methods:

1. Compiling Yosys with the CMake flag ``-DYOSYS_WITH_PYTHON=ON``

   This adds the flag ``-y`` to the Yosys binary, which allows you to execute
   Python scripts using an interpreter embedded in Yosys itself:

   ``yosys -y ./my_pyosys_script.py``

   Do note this requires some build-time dependencies to be available to Python,
   namely, ``pybind11`` and ``cxxheaderparser``. :program:`uv` may be used to
   create an ephemeral environment with the correct versions of the tools
   installed if the current python environment doesn't provide them.

2. Installing the Pyosys wheels

   On macOS and GNU/Linux you can install pre-built wheels of Yosys using
   ``pip``:

   ``python3 -m pip install pyosys``

   Which then allows you to run your scripts as follows:

   ``python3 ./my_pyosys_script.py``


Scripting and Database Inspection
---------------------------------

To start with, you have to import libyosys as follows:

.. code-block:: python

   from pyosys import libyosys


As a reminder, Python allows you to alias imported modules and objects, so
this import may be preferable for terseness:

.. code-block:: python

   from pyosys import libyosys as ys


Now, scripting is actually quite similar to ``.ys`` and ``.tcl`` script in that
you can provide mostly text commands. Albeit, you can construct your scripts
to use Python's amenities like conditional execution, loops, and functions:

.. code-block:: python

   do_flatten = True

   ys.run_pass("read_verilog tests/simple/fiedler-cooley.v")
   ys.run_pass("hierarchy -check -auto-top")
   if do_flatten:
      ys.run_pass("flatten")

โ€ฆbut this does not strictly provide anything that Tcl scripts do not provide you
with. The real power of using Pyosys comes from the fact you can manually
instantiate, manage, and interact with the design database.

As an example, here is the same script with a manually instantiated design.

.. literalinclude:: /code_examples/pyosys/simple_database.py
   :start-after: loading design
   :end-before: top module inspection
   :language: python

What's new here is that you can manually inspect the design's database. This
gives you access to a huge chunk of the design database API as declared in
the ``kernel/rtlil.h`` header.

For example, here's how to list the input and output ports of the top module
of your design:

.. literalinclude:: /code_examples/pyosys/simple_database.py
   :start-after: top module inspection
   :end-before: # synth
   :language: python

.. tip::

   C++ data structures in Yosys are bridged to Python such that they have a
   pretty similar API to Python objects, for example:

   - ``std::vector`` supports the same methods as
     `iterables <https://docs.python.org/3/glossary.html#term-iterable>`_ in
     Python.
   - ``std::set`` and hashlib ``pool`` support the same methods as ``set``\s in
     Python. While ``set`` is ordered, ``pool`` is not and modifications may
     cause a complete reordering of the set.
   - ``dict`` supports the same methods as ``dict``\s in Python, albeit it is
     unordered, and modifications may cause a complete reordering of the
     dictionary.
   - ``idict`` uses a custom set of methods because it doesn't map very cleanly
     to an existing Python data structure. See ``pyosys/hashlib.h`` for more
     info.

   For most operations, the Python equivalents are also supported as arguments
   where they will automatically be cast to the right type, so you do not have
   to manually instantiate the right underlying C++ object(s) yourself.

Modifying the Database
----------------------

.. warning::

   Any modifications to the database may invalidate previous references held
   by Python, just as if you were writing C++. Pyosys does not currently attempt
   to keep deleted objects alive if a reference is held by Python.

You are not restricted to inspecting the database either: you have the ability
to modify it, and introduce new elements and/or changes to your design.

As a demonstrative example, let's assume we want to add an enable line to all
flip-flops in our fiedler-cooley design.

First of all, we will run :yoscrypt:`synth` to convert all of the logic to
Yosys's internal cell structure (see :ref:`sec:celllib_gates`):

.. literalinclude:: /code_examples/pyosys/simple_database.py
   :start-after: # synth
   :end-before: adding the enable line
   :language: python

Next, we need to add the new port. The method for this is ``Module::addWire``\.

.. tip::

   IdString is Yosys's internal representation of strings used as identifiers
   within Verilog designs. They are efficient as only integers are stored and
   passed around, but they can be translated to and from normal strings at will.

   Pyosys will automatically cast Python strings to IdStrings for you, but the
   rules around IdStrings apply, namely that *broadly*:

   - Identifiers for internal cells must start with ``$``\.
   - All other identifiers must start with ``\``\.

.. literalinclude:: /code_examples/pyosys/simple_database.py
   :start-after: adding the enable line
   :end-before: hooking the enable line
   :language: python

Notice how we modified the wire then called a method to make Yosys re-process
the ports.

Next, we can iterate over all constituent cells, and if they are of the type
``$_DFF_P_``, we do two things:

1. Change their type to ``$_DFFE_PP_`` to enable hooking up an enable signal.
2. Hooking up the enable signal.

.. literalinclude:: /code_examples/pyosys/simple_database.py
   :start-after: hooking the enable line
   :end-before: run check
   :language: python

To verify that you did everything correctly, it is prudent to call ``.check()``
on the module you're manipulating as follows after you're done with a set of
changes:

.. literalinclude:: /code_examples/pyosys/simple_database.py
   :start-after: run check
   :end-before: write output
   :language: python

And then finally, write your outputs. Here, I choose an intermediate Verilog
file and :yoscrypt:`synth_ice40` to map it to the iCE40 architecture.

.. literalinclude:: /code_examples/pyosys/simple_database.py
   :start-after: write output
   :language: python

And voilร , you will note that in the intermediate output, all ``always @``
statements should have an ``if (enable)``\.

Encapsulating as Passes
-----------------------

Just like when writing C++, you can encapsulate routines in terms of "passes",
which adds your Pass to a global registry of commands accessible using
``run_pass``\.

.. literalinclude:: /code_examples/pyosys/pass.py
   :language: python

In general, abstract classes and virtual methods are not really supported by
Pyosys due to their complexity, but there are two exceptions which are:

- ``Pass`` in ``kernel/register.h``
- ``Monitor`` in ``kernel/rtlil.h``

---

### Source Using Yosys Verilog (`docs/source/using_yosys/verilog.rst`)

Notes on Verilog support in Yosys
=================================

Unsupported Verilog-2005 Features
---------------------------------

The following Verilog-2005 features are not supported by
Yosys and there are currently no plans to add support
for them:

- Non-synthesizable language features as defined in
  IEC 62142(E):2005 / IEEE Std. 1364.1(E):2002

- The ``tri``, ``triand`` and ``trior`` net types

- The ``config`` and ``disable`` keywords and library map files


Verilog Attributes and non-standard features
--------------------------------------------

- The ``full_case`` attribute on case statements is supported (also the
  non-standard ``// synopsys full_case`` directive)

- The ``parallel_case`` attribute on case statements is supported (also the
  non-standard ``// synopsys parallel_case`` directive)

- The ``// synopsys translate_off`` and ``// synopsys translate_on`` directives
  are also supported (but the use of ``` `ifdef .. `endif ``` is strongly
  recommended instead).

- The ``nomem2reg`` attribute on modules or arrays prohibits the automatic early
  conversion of arrays to separate registers. This is potentially dangerous.
  Usually the front-end has good reasons for converting an array to a list of
  registers. Prohibiting this step will likely result in incorrect synthesis
  results.

- The ``mem2reg`` attribute on modules or arrays forces the early conversion of
  arrays to separate registers.

- The ``nomeminit`` attribute on modules or arrays prohibits the creation of
  initialized memories. This effectively puts ``mem2reg`` on all memories that
  are written to in an ``initial`` block and are not ROMs.

- The ``no_rw_check`` attribute on registers indicates that inferred memories
  can have undefined behavior when read and write target the same address.
  See :ref:`the chapter on memory handling <no_rw_check>`.

- The ``nolatches`` attribute on modules or always-blocks prohibits the
  generation of logic-loops for latches. Instead all not explicitly assigned
  values default to x-bits. This does not affect clocked storage elements such
  as flip-flops.

- The ``nosync`` attribute on registers prohibits the generation of a storage
  element. The register itself will always have all bits set to 'x' (undefined).
  The variable may only be used as blocking assigned temporary variable within
  an always block. This is mostly used internally by Yosys to synthesize Verilog
  functions and access arrays.

- The ``nowrshmsk`` attribute on a register prohibits the generation of
  shift-and-mask type circuits for writing to bit slices of that register.

- The ``onehot`` attribute on wires mark them as one-hot state register. This is
  used for example for memory port sharing and set by the fsm_map pass.

- The ``blackbox`` attribute on modules is used to mark empty stub modules that
  have the same ports as the real thing but do not contain information on the
  internal configuration. This modules are only used by the synthesis passes to
  identify input and output ports of cells. The Verilog backend also does not
  output blackbox modules on default. `read_verilog`, unless called with
  ``-noblackbox`` will automatically set the blackbox attribute on any empty
  module it reads.

- The ``noblackbox`` attribute set on an empty module prevents `read_verilog`
  from automatically setting the blackbox attribute on the module.

- The ``whitebox`` attribute on modules triggers the same behavior as
  ``blackbox``, but is for whitebox modules, i.e. library modules that contain a
  behavioral model of the cell type.

- The ``lib_whitebox`` attribute overwrites ``whitebox`` when `read_verilog` is
  run in ``-lib`` mode. Otherwise it's automatically removed.

- The ``dynports`` attribute is used by the Verilog front-end to mark modules
  that have ports with a width that depends on a parameter.

- The ``hdlname`` attribute is used by some passes to document the original
  (HDL) name of a module when renaming a module. It should contain a single
  name, or, when describing a hierarchical name in a flattened design, multiple
  names separated by a single space character.

- The ``keep`` attribute on cells and wires is used to mark objects that should
  never be removed by the optimizer. This is used for example for cells that
  have hidden connections that are not part of the netlist, such as IO pads.
  Setting the ``keep`` attribute on a module has the same effect as setting it
  on all instances of the module.

- The ``keep_hierarchy`` attribute on cells and modules keeps the `flatten`
  command from flattening the indicated cells and modules.

- The ``gate_cost_equivalent`` attribute on a module can be used to specify
  the estimated cost of the module as a number of basic gate instances. See
  the help message of command `keep_hierarchy` which interprets this
  attribute.

- The ``init`` attribute on wires is set by the frontend when a register is
  initialized "FPGA-style" with ``reg foo = val``. It can be used during
  synthesis to add the necessary reset logic.

- The ``top`` attribute on a module marks this module as the top of the design
  hierarchy. The `hierarchy` command sets this attribute when called with
  ``-top``. Other commands, such as `flatten` and various backends use this
  attribute to determine the top module.

- The ``src`` attribute is set on cells and wires created by to the string
  ``<hdl-file-name>:<line-number>`` by the HDL front-end and is then carried
  through the synthesis. When entities are combined, a new \|-separated string
  is created that contains all the strings from the original entities.

- The ``defaultvalue`` attribute is used to store default values for module
  inputs. The attribute is attached to the input wire by the HDL front-end when
  the input is declared with a default value.

- The ``parameter`` and ``localparam`` attributes are used to mark wires that
  represent module parameters or localparams (when the HDL front-end is run in
  ``-pwires`` mode).

- Wires marked with the ``hierconn`` attribute are connected to wires with the
  same name (format ``cell_name.identifier``) when they are imported from
  sub-modules by `flatten`.

- The ``clkbuf_driver`` attribute can be set on an output port of a blackbox
  module to mark it as a clock buffer output, and thus prevent `clkbufmap` from
  inserting another clock buffer on a net driven by such output.

- The ``clkbuf_sink`` attribute can be set on an input port of a module to
  request clock buffer insertion by the `clkbufmap` pass.

- The ``clkbuf_inv`` attribute can be set on an output port of a module with the
  value set to the name of an input port of that module.  When the `clkbufmap`
  would otherwise insert a clock buffer on this output, it will instead try
  inserting the clock buffer on the input port (this is used to implement clock
  inverter cells that clock buffer insertion will "see through").

- The ``clkbuf_inhibit`` is the default attribute to set on a wire to prevent
  automatic clock buffer insertion by `clkbufmap`. This behaviour can be
  overridden by providing a custom selection to `clkbufmap`.

- The ``invertible_pin`` attribute can be set on a port to mark it as invertible
  via a cell parameter.  The name of the inversion parameter is specified as the
  value of this attribute.  The value of the inversion parameter must be of the
  same width as the port, with 1 indicating an inverted bit and 0 indicating a
  non-inverted bit.

- The ``iopad_external_pin`` attribute on a blackbox module's port marks it as
  the external-facing pin of an I/O pad, and prevents `iopadmap` from inserting
  another pad cell on it.

- The module attribute ``abc9_lut`` is an integer attribute indicating to `abc9`
  that this module describes a LUT with an area cost of this value, and
  propagation delays described using ``specify`` statements.

- The module attribute ``abc9_box`` is a boolean specifying a black/white-box
  definition, with propagation delays described using ``specify`` statements,
  for use by `abc9`.

- The port attribute ``abc9_carry`` marks the carry-in (if an input port) and
  carry-out (if output port) ports of a box. This information is necessary for
  `abc9` to preserve the integrity of carry-chains. Specifying this attribute
  onto a bus port will affect only its most significant bit.

- The module attribute ``abc9_flop`` is a boolean marking the module as a
  flip-flop. This allows `abc9` to analyse its contents in order to perform
  sequential synthesis.

- The frontend sets attributes ``always_comb``, ``always_latch`` and
  ``always_ff`` on processes derived from SystemVerilog style always blocks
  according to the type of the always. These are checked for correctness in
  ``proc_dlatch``. Latches inferred from ``always_latch`` processes are exempt
  from the ``proc -latches `` reporting policy, and the
  generated latch cells carry the ``always_latch`` attribute, which also
  exempts them from `check` ``-nolatches``.

- The cell attribute ``wildcard_port_conns`` represents wildcard port
  connections (SystemVerilog ``.*``). These are resolved to concrete connections
  to matching wires in `hierarchy`.

- In addition to the ``(* ... *)`` attribute syntax, Yosys supports the
  non-standard ``{* ... *}`` attribute syntax to set default attributes for
  everything that comes after the ``{* ... *}`` statement. (Reset by adding an
  empty ``{* *}`` statement.)

- In module parameter and port declarations, and cell port and parameter lists,
  a trailing comma is ignored. This simplifies writing Verilog code generators a
  bit in some cases.

- Modules can be declared with ``module mod_name(...);`` (with three dots
  instead of a list of module ports). With this syntax it is sufficient to
  simply declare a module port as 'input' or 'output' in the module body.

- When defining a macro with ``\`define``, all text between triple double quotes
  is interpreted as macro body, even if it contains unescaped newlines. The
  triple double quotes are removed from the macro body. For example:

.. code-block:: verilog

      `define MY_MACRO(a, b) """
         assign a = 23;
         assign b = 42;
      """

- The attribute ``via_celltype`` can be used to implement a Verilog task or
  function by instantiating the specified cell type. The value is the name of
  the cell type to use. For functions the name of the output port can be
  specified by appending it to the cell type separated by a whitespace. The body
  of the task or function is unused in this case and can be used to specify a
  behavioral model of the cell type for simulation. For example:

.. code-block:: verilog

      module my_add3(A, B, C, Y);
        parameter WIDTH = 8;
        input [WIDTH-1:0] A, B, C;
        output [WIDTH-1:0] Y;
        ...
      endmodule

      module top;
        ...
        (* via_celltype = "my_add3 Y" *)
        (* via_celltype_defparam_WIDTH = 32 *)
        function [31:0] add3;
          input [31:0] A, B, C;
          begin
            add3 = A + B + C;
          end
        endfunction
        ...
      endmodule

- The ``wiretype`` attribute is added by the verilog parser for wires of a
  typedef'd type to indicate the type identifier.

- Various ``enum_value_{value}`` attributes are added to wires of an enumerated
  type to give a map of possible enum items to their values.

- The ``enum_base_type`` attribute is added to enum items to indicate which enum
  they belong to (enums -- anonymous and otherwise -- are automatically named
  with an auto-incrementing counter). Note that enums are currently not strongly
  typed.

- A limited subset of DPI-C functions is supported. The plugin mechanism (see
  ``help plugin``) can be used to load .so files with implementations of DPI-C
  routines. As a non-standard extension it is possible to specify a plugin alias
  using the ``<alias>:`` syntax. For example:

.. code-block:: verilog

      module dpitest;
        import "DPI-C" function foo:round = real my_round (real);
        parameter real r = my_round(12.345);
      endmodule

.. code-block::

      $ yosys -p 'plugin -a foo -i /lib/libm.so; read_verilog dpitest.v'

- Sized constants (the syntax ``<size>'s?[bodh]<value>``) support constant
  expressions as ``<size>``. If the expression is not a simple identifier, it
  must be put in parentheses. Examples: ``WIDTH'd42``, ``(4+2)'b101010``

- The system tasks ``$finish``, ``$stop`` and ``$display`` are supported in
  initial blocks in an unconditional context (only if/case statements on
  expressions over parameters and constant values are allowed). The intended use
  for this is synthesis-time DRC.

- There is limited support for converting ``specify`` .. ``endspecify``
  statements to special ``$specify2``, ``$specify3``, and ``$specrule`` cells,
  for use in blackboxes and whiteboxes. Use ``read_verilog -specify`` to enable
  this functionality. (By default these blocks are ignored.)

- The ``reprocess_after`` internal attribute is used by the Verilog frontend to
  mark cells with bindings which might depend on the specified instantiated
  module. Modules with such cells will be reprocessed during the `hierarchy`
  pass once the referenced module definition(s) become available.

- The ``smtlib2_module`` attribute can be set on a blackbox module to specify a
  formal model directly using SMT-LIB 2. For such a module, the
  ``smtlib2_comb_expr`` attribute can be used on output ports to define their
  value using an SMT-LIB 2 expression. For example:

.. code-block:: verilog

      (* blackbox *)
      (* smtlib2_module *)
      module submod(a, b);
        input [7:0] a;
        (* smtlib2_comb_expr = "(bvnot a)" *)
        output [7:0] b;
      endmodule

Non-standard or SystemVerilog features for formal verification
--------------------------------------------------------------

- Support for ``assert``, ``assume``, ``restrict``, and ``cover`` is enabled
  when `read_verilog` is called with ``-formal``.

- The system task ``$initstate`` evaluates to 1 in the initial state and to 0
  otherwise.

- The system function ``$anyconst`` evaluates to any constant value. This is
  equivalent to declaring a reg as ``rand const``, but also works outside of
  checkers. (Yosys also supports ``rand const`` outside checkers.)

- The system function ``$anyseq`` evaluates to any value, possibly a different
  value in each cycle. This is equivalent to declaring a reg as ``rand``, but
  also works outside of checkers. (Yosys also supports ``rand`` variables
  outside checkers.)

- The system functions ``$allconst`` and ``$allseq`` can be used to construct
  formal exist-forall problems. Assumptions only hold if the trace satisfies the
  assumption for all ``$allconst/$allseq`` values. For assertions and cover
  statements it is sufficient if just one ``$allconst/$allseq`` value triggers
  the property (similar to ``$anyconst/$anyseq``).

- Wires/registers declared using the ``anyconst/anyseq/allconst/allseq``
  attribute (for example ``(* anyconst *) reg [7:0] foobar;``) will behave as if
  driven by a ``$anyconst/$anyseq/$allconst/$allseq`` function.

- The SystemVerilog tasks ``$past``, ``$stable``, ``$rose`` and ``$fell`` are
  supported in any clocked block.

- The syntax ``@($global_clock)`` can be used to create FFs that have no
  explicit clock input (``$ff`` cells). The same can be achieved by using
  ``@(posedge <netname>)`` or ``@(negedge <netname>)`` when ``<netname>`` is
  marked with the ``(* gclk *)`` Verilog attribute.


Supported features from SystemVerilog
-------------------------------------

When `read_verilog` is called with ``-sv``, it accepts some language features
from SystemVerilog:

- The ``assert`` statement from SystemVerilog is supported in its most basic
  form. In module context: ``assert property (<expression>);`` and within an
  always block: ``assert(<expression>);``. It is transformed to an ``$assert``
  cell.

- The ``assume``, ``restrict``, and ``cover`` statements from SystemVerilog are
  also supported. The same limitations as with the ``assert`` statement apply.

- The keywords ``always_comb``, ``always_ff`` and ``always_latch``, ``logic``
  and ``bit`` are supported.

- Declaring free variables with ``rand`` and ``rand const`` is supported.

- Checkers without a port list that do not need to be instantiated (but instead
  behave like a named block) are supported.

- SystemVerilog packages are supported. Once a SystemVerilog file is read into a
  design with `read_verilog`, all its packages are available to SystemVerilog
  files being read into the same design afterwards.

  - nested packages are currently not supported (i.e. calling ``import`` inside
    a ``package`` .. ``endpackage`` block)

- typedefs are supported (including inside packages)

  - type casts are currently not supported

- enums are supported (including inside packages)

  - but are currently not strongly typed

- packed structs and unions are supported

  - arrays of packed structs/unions are currently not supported
  - structure literals are currently not supported

- multidimensional arrays are supported

  - array assignment of unpacked arrays is currently not supported
  - array literals are currently not supported

- SystemVerilog interfaces (SVIs), including modports for specifying whether
  ports are inputs or outputs, are partially supported.

  - interfaces must be provided as *named* arguments, not positional arguments.
    i.e. ``foo bar(.intf(intf0), .x(x));`` is supported but ``foo bar(intf0,
    x);`` is not.

- Assignments within expressions are supported.

- The ``unique``, ``unique0``, and ``priority`` SystemVerilog keywords are
  supported on ``if`` and ``case`` conditionals.  (The Verilog frontend
  will process conditionals using these keywords by annotating their
  representation with the appropriate ``full_case`` and/or ``parallel_case``
  attributes, which are described above.)

- SystemVerilog string literals are supported (triple-quoted strings and
  escape sequences such as line continuations and hex escapes).

---

### Source Yosys Internals Hashing (`docs/source/yosys_internals/hashing.rst`)

Hashing and associative data structures in Yosys
------------------------------------------------

Container classes based on hashing

Yosys uses dict<K, T> and pool<T> as main container classes.
dict<K, T> is essentially a replacement for std::unordered_map<K, T>
and pool<T> is a replacement for std::unordered_set<T>.
The main characteristics are:

  • dict<K, T> and pool<T> are about 2x faster than the std containers
    (though this claim hasn't been verified for over 10 years)

  • references to elements in a dict<K, T> or pool<T> are invalidated by
    insert and remove operations (similar to std::vector<T> on push_back()).

  • some iterators are invalidated by erase(). specifically, iterators
    that have not passed the erased element yet are invalidated. (erase()
    itself returns valid iterator to the next element.)

  • no iterators are invalidated by insert(). elements are inserted at
    begin(). i.e. only a new iterator that starts at begin() will see the
    inserted elements.

  • the method .count(key, iterator) is like .count(key) but only
    considers elements that can be reached via the iterator.

  • iterators can be compared. it1 < it2 means that the position of t2
    can be reached via t1 but not vice versa.

  • the method .sort() can be used to sort the elements in the container
    the container stays sorted until elements are added or removed.

  • dict<K, T> and pool<T> will have the same order of iteration across
    all compilers, standard libraries and architectures.

In addition to dict<K, T> and pool<T> there is also an idict<K> that
creates a bijective map from K to incrementing integers. For example:

::

idict<string, 42> si;
log("%d\n", si("hello")); // will print 42
log("%d\n", si("world")); // will print 43
log("%d\n", si.at("world")); // will print 43
log("%d\n", si.at("dummy")); // will throw exception
log("%s\n", si[42])); // will print hello
log("%s\n", si[43])); // will print world
log("%s\n", si[44])); // will throw exception

It is not possible to remove elements from an idict.

Finally mfp<K> implements a merge-find set data structure (aka. disjoint-set
or union-find) over the type K ("mfp" = merge-find-promote).

The hash function

text
The hash function generally used in Yosys is the XOR version of DJB2:

::

   state = ((state << 5) + state) ^ value

This is an old-school hash designed to hash ASCII characters. Yosys doesn't hash
a lot of ASCII text, but it still happens to be a local optimum due to factors
described later.

Hash function quality is multi-faceted and highly dependent on what is being
hashed. Yosys isn't concerned by any cryptographic qualities, instead the goal
is minimizing total hashing collision risk given the data patterns within Yosys.
In general, a good hash function typically folds values into a state accumulator
with a mathematical function that is fast to compute and has some beneficial
properties. One of these is the avalanche property, which demands that a small
change such as flipping a bit or incrementing by one in the input produces a
large, unpredictable change in the output. Additionally, the bit independence
criterion states that any pair of output bits should change independently when
any single input bit is inverted. These properties are important for avoiding
hash collision on data patterns like the hash of a sequence not colliding with
its permutation, not losing from the state the information added by hashing
preceding elements, etc.

DJB2 lacks these properties. Instead, since Yosys hashes large numbers of data
structures composed of incrementing integer IDs, Yosys abuses the predictability
of DJB2 to get lower hash collisions, with regular nature of the hashes
surviving through the interaction with the "modulo prime" operations in the
associative data structures. For example, some most common objects in Yosys are
interned ``IdString``\ s of incrementing indices or ``SigBit``\ s with bit
offsets into wire (represented by its unique ``IdString`` name) as the typical
case. This is what makes DJB2 a local optimum. Additionally, the ADD version of
DJB2 (like above but with addition instead of XOR) is used to this end for some
types, abandoning the general pattern of folding values into a state value.

Making a type hashable

Let's first take a look at the external interface on a simplified level.
Generally, to get the hash for T obj, you would call the utility function
run_hash<T>(const T& obj), corresponding to hash_ops<T>::hash(obj),
the default implementation of which uses hash_ops<T>::hash_into(Hasher(), obj).
Hasher is the class actually implementing the hash function, hiding its
initialized internal state, and passing it out on hash_t yield() with
perhaps some finalization steps.

hash_ops<T> is the star of the show. By default it pulls the Hasher h
through a Hasher T::hash_into(Hasher h) method. That's the method you have to
implement to make a record (class or struct) type easily hashable with Yosys
hashlib associative data structures.

hash_ops<T> is specialized for built-in types like int or bool and
treats pointers the same as integers, so it doesn't dereference pointers. Since
many RTLIL data structures like RTLIL::Wire carry their own unique index
Hasher::hash_t hashidx_;, there are specializations for hash_ops<Wire*>
and others in kernel/hashlib.h that actually dereference the pointers and
call hash_into on the instances pointed to.

hash_ops<T> is also specialized for simple compound types like
std::pair<U> by calling hash_into in sequence on its members. For flexible
size containers like std::vector<U> the size of the container is hashed
first. That is also how implementing hashing for a custom record data type
should be - unless there is strong reason to do otherwise, call h.eat(m) on
the Hasher h you have received for each member in sequence and return h;.

The hash_ops<T>::hash(obj) method is not indended to be called when
context of implementing the hashing for a record or other compound type.
When writing it, you should connect it to hash_ops<T>::hash_into(Hasher h)
as shown below. If you have a strong reason to do so, and you have
to create a special implementation for top-level hashing, look at how
hash_ops<RTLIL::SigBit>::hash(...) is implemented in kernel/rtlil.h.

Porting plugins from the legacy interface

text
Previously, the interface to implement hashing on custom types was just
``unsigned int T::hash() const``. This meant hashes for members were computed
independently and then ad-hoc combined with the hash function with some xorshift
operations thrown in to mix bits together somewhat. A plugin can stay compatible
with both versions prior and after the break by implementing both interfaces
based on the existance and value of ``YS_HASHING_VERSION``.

.. code-block:: cpp
   :caption: Example hash compatibility wrapper
   :name: hash_plugin_compat

   #ifndef YS_HASHING_VERSION
   unsigned int T::hash() const {
      return mkhash(a, b);
   }
   #elif YS_HASHING_VERSION == 1
   Hasher T::hash_into(Hasher h) const {
      h.eat(a);
      h.eat(b);
      return h;
   }
   Hasher T::hash() const {
      Hasher h;
      h.eat(*this);
      return h;
   }
   #else
   #error "Unsupported hashing interface"
   #endif

Feel free to contact Yosys maintainers with related issues.

---

### Source Yosys Internals Idstring (`docs/source/yosys_internals/idstring.rst`)

IdString
--------

Design
~~~~~~

String interning is a practice that deduplicates strings held in memory.
An integer then exactly represents a unique string. This also allows string
comparison to be replaced with integer comparison, which is faster.

For performance, memory efficiency, and future parallelism,
``IdString`` is an index into a per-``Design`` ``TwinePool``, which
deduplicates prefixes.

The killer feature is that it allows you to construct a new ``IdString`` by
appending a suffix to an existing ``IdString`` without copying its contents:

.. code-block:: cpp
   :caption: Example suffix node construction
   :name: idstring_suffix

   Wire *enable = module->addWire(TwineSpec::Suffix{cell->name, "_EN"}, 1);

A ``TwinePool`` holds a slab of ``TwineNode``\ s with free-list
bump allocation by inheriting from ``HashConsPool`` backed by
an ``std::deque``.
``HashConsPool`` provides deduplicating storage indexed by content hash.
``IdString``, being an interned string, is hashed as the underlying string.

``TwineSpec`` models an uninterned temporary twine node,
``TwineNode`` models an interned one.
``IdString`` then is an index into the vector
of ``TwineNode``\ s inside a ``TwinePool``.
More concretely, it is 32-bit, offset, and publicity-tagged.
The offset allows it to represent compilation-time allocated identifiers
in ``kernel/constids.inc``. Tagging implements "publicity", which historically
was determined by the first character being ``$`` or ``\``,
by stealing the top bit of the integer.
User-specified names coming in from design sources are public,
while Yosys-created names are private.

``TwineNode`` uses ``SmallString`` to store small strings inline and larger
ones behind a pointer. This keeps its own size at 24 bytes.
``AutoSuffix`` is a ``TwineSpec`` variant produced by ``NEW_ID``
and ``NEW_ID_SUFFIX`` macros. These are ``TwineSpec``s which skip string hashing
on the constant per-callsite prefix when repeatedly interned
and benefit from the ``SmallString`` implementation greatly to represent
the per-use incremented autoidx integer suffix.

Garbage collection traces a ``Design`` in parallel.

Migration from globally interned IdStrings

C++ core change
^^^^^^^^^^^^^^^

IdString <-> string conversion now requires accessing a per-Design
TwinePool, accessible with design->twines(), module->twines(),
wire->twines(), cell->twines(), memory->twines(),
process->twines()

.. code-block:: diff

-IdString id = "hello";
+IdString id = design->twines().add("\hello");

.. code-block:: diff

-void thing(IdString id) {

  • std::string s = id;
  • log("%s\n", id);

+void thing(Design* design, IdString id) {

  • std::string s = design->twines().str(id);
  • log("%s\n", s);

// ...
}

C++ helpers
^^^^^^^^^^^

When passing an IdString around that should then be stringified/printed or
assigned from string, you can use a PooledName which is effectively this but
with lots of convenient methods:

.. code-block:: cpp

class PooledName { const TwinePool *pool_; IdString id_; }

so that you can

.. code-block:: diff

-void foo(IdString name) {
+void foo(PooledName name) {
log("%s\n", name);
}

for (IdString name : names)

  • foo(name);
  • foo({design, name});

// This then works without a change, since Cell::name
// can magically convert to PooledName
for (Cell* cell : cells)
foo(cell->name);

In name fields on RTLIL objects and in Cell::type, a Design* is
contextually available, so those fields are magically wrapping an IdString for
read access. That means you don't need a change here:

.. code-block:: cpp

log("Cell type %s, cell name %s\n", cell->type, cell->name);

but not for write access, so you still have to do this:

.. code-block:: diff

-cell->type = "\asdfghjk";
+cell->type = design->twines().add("\asdfghjk");

Checking the first character of an IdString for publicity can now get
expensive. Do this instead:

.. code-block:: diff

-if (wire->name[0] == '$')
+if (!wire->name.isPublic())

ID(id) now accepts only names in kernel/constids.inc

.. code-block:: diff

-auto w = miter_module->addWire(ID(asdfghjk));
+auto w = miter_module->addWire("\asdfghjk");

IdString is valid only in its own Design: cross-design use requires
TwinePool::copy_from, TwinePool::find_from, Module::clone(Design *),
RTLIL::copy_attr_dict

RTLIL::sort_by_id_str takes a TwinePool reference. This is a good time
to rethink whether you really want to sort stuff by string contents!

.. code-block:: diff

-modules_.sort(sort_by_id_str());
+modules_.sort(sort_by_id_str(design->twines()));

NEW_ID, NEW_ID_SUFFIX(suffix) change type from IdString to
TwineSpec.

But as long as you use them in the construction of RTLIL objects, magic happens:

.. code-block:: cpp

SigSpec s = module->And(NEW_ID, lhs, rhs);

RTLIL::unescape_id(IdString) and log_id have been removed, together with
other things that have relied on the old design.

If you are experiencing bugs while working multiple Designs,
enable extra checks with the YOSYS_ENABLE_TWINE_PROVENANCE CMake variable.

Attribute and parameter dictionaries copied between objects of different
Designs need to be done via copy_attr_dict to safetly re-intern twines.

Python helpers
^^^^^^^^^^^^^^

pyosys lies to you - PooledName is what you're actually getting when you
get an IdString in Python. This is because we expect Python users to value
convenience and simplicity more than unnecessary bytes here. This is different
from what we need for our core optimization passes in C++.

Strings still work as names in methods of Design, Module, Cell,
Wire, Memory and Process, and as keys of their attributes,
parameters, parameter_default_values, connections_, wires_,
cells_, memories, processes and modules_, since those know their
design.

Elsewhere only static names ("\\A", "$add") convert from strings. You
may otherwise need to get an IdString from the design:

.. code-block:: diff

my_idict = ys.IdstringIdict()
-my_idict("\hello")
-print(my_idict[0])
+my_idict(design.id_add("\hello"))
+print(design.str(my_idict[0]))

Use id_find instead of id_add to only look a name up, it returns
None if absent:

.. code-block:: diff

-sel.selected_module("\top")
+sel.selected_module(design.id_find("\top"))

connections_, wires_, cells_, memories, processes and
modules_ can't be assigned as a whole anymore, use methods instead:

.. code-block:: diff

-cell.connections_ = {"\A": sig}
+cell.setPort("\A", sig)

Using a name after its design was deleted now raises RuntimeError, so
convert it with str() while the design is still alive if you want that.

RTLIL
^^^^^

There is a new twines section in the RTLIL textual format. Older RTLIL
versions can still be read in, but older Yosys versions won't be able to read
this format.

To write out RTLIL in a format compatible with older
Yosys versions, use write_rtlil -readable. This will discards only
prefix node structure, not string content. To remove human-readable comments
to save file size, use write_rtlil -small.


Source Yosys Internals Index (`docs/source/yosys_internals/index.rst`)

.. _chapter:overview:

Yosys internals

.. todo:: less academic

Yosys is an extensible open source hardware synthesis tool. It is aimed at
designers who are looking for an easily accessible, universal, and
vendor-independent synthesis tool, as well as scientists who do research in
electronic design automation (EDA) and are looking for an open synthesis
framework that can be used to test algorithms on complex real-world designs.

Yosys can synthesize a large subset of Verilog 2005 and has been tested with a
wide range of real-world designs, including the OpenRISC 1200 CPU, the
openMSP430 CPU
, the OpenCores I2C master, and the k68 CPU.

.. todo:: add RISC-V core example

.. _OpenRISC 1200 CPU: https://github.com/openrisc/or1200

.. _openMSP430 CPU: http://opencores.org/projects/openmsp430

.. _OpenCores I2C master: http://opencores.org/projects/i2c

.. _k68 CPU: http://opencores.org/projects/k68

Yosys is written in C++, targeting C++20 at minimum. This chapter describes some
of the fundamental Yosys data structures. For the sake of simplicity the C++
type names used in the Yosys implementation are used in this chapter, even
though the chapter only explains the conceptual idea behind it and can be used
as reference to implement a similar system in any language.

.. toctree::
:maxdepth: 3

flow/index
formats/index
extending_yosys/index
techmap
hashing
idstring


Source Yosys Internals Techmap (`docs/source/yosys_internals/techmap.rst`)

Techmap by example

As a quick recap, the techmap command replaces cells in the design with
implementations given as Verilog code (called "map files"). It can replace
Yosys' internal cell types (such as $or) as well as user-defined cell types.

  • Verilog parameters are used extensively to customize the internal cell types.
  • Additional special parameters are used by techmap to communicate meta-data to
    the map files.
  • Special wires are used to instruct techmap how to handle a module in the map
    file.
  • Generate blocks and recursion are powerful tools for writing map files.

Code examples used in this document are included in the Yosys code base under
|code_examples/techmap|_.

.. |code_examples/techmap| replace:: :file:docs/source/code_examples/techmap
.. _code_examples/techmap: https://github.com/YosysHQ/yosys/tree/main/docs/source/code_examples/techmap

Mapping OR3X1

text
.. todo:: add/expand supporting text

.. note::

    This is a simple example for demonstration only.  Techmap shouldn't be used
    to implement basic logic optimization.

.. literalinclude:: /code_examples/techmap/red_or3x1_map.v
   :language: verilog
   :caption: :file:`red_or3x1_map.v`

.. figure:: /_images/code_examples/techmap/red_or3x1.*
    :class: width-helper invert-helper

.. literalinclude:: /code_examples/techmap/red_or3x1_test.ys
   :language: yoscrypt
   :caption: :file:`red_or3x1_test.ys`

.. literalinclude:: /code_examples/techmap/red_or3x1_test.v
   :language: verilog
   :caption: :file:`red_or3x1_test.v`

Conditional techmap
  • In some cases only cells with certain properties should be substituted.

  • The special wire _TECHMAP_FAIL_ can be used to disable a module in the map
    file for a certain set of parameters.

  • The wire _TECHMAP_FAIL_ must be set to a constant value. If it is non-zero
    then the module is disabled for this set of parameters.

  • Example use-cases:

    • coarse-grain cell types that only operate on certain bit widths
    • memory resources for different memory geometries (width, depth, ports,
      etc.)

Example:

.. figure:: /_images/code_examples/techmap/sym_mul.*
:class: width-helper invert-helper

.. literalinclude:: /code_examples/techmap/sym_mul_map.v
:language: verilog
:caption: :file:sym_mul_map.v

.. literalinclude:: /code_examples/techmap/sym_mul_test.v
:language: verilog
:caption: :file:sym_mul_test.v

.. literalinclude:: /code_examples/techmap/sym_mul_test.ys
:language: yoscrypt
:caption: :file:sym_mul_test.ys

Scripting in map modules

text
- The special wires ``_TECHMAP_DO_*`` can be used to run Yosys scripts in the
  context of the replacement module.
- The wire that comes first in alphabetical oder is interpreted as string (must
  be connected to constants) that is executed as script. Then the wire is
  removed. Repeat.
- You can even call techmap recursively!
- Example use-cases:

    - Using always blocks in map module: call `proc`
    - Perform expensive optimizations (such as `freduce`) on cells
      where this is known to work well.
    - Interacting with custom commands.

.. note:: PROTIP:

    Commands such as `shell`, ``show -pause``, and `dump` can be used in the
    ``_TECHMAP_DO_*`` scripts for debugging map modules.

Example:

.. figure:: /_images/code_examples/techmap/mymul.*
    :class: width-helper invert-helper

.. literalinclude:: /code_examples/techmap/mymul_map.v
   :language: verilog
   :caption: :file:`mymul_map.v`

.. literalinclude:: /code_examples/techmap/mymul_test.v
   :language: verilog
   :caption: :file:`mymul_test.v`

.. literalinclude:: /code_examples/techmap/mymul_test.ys
   :language: yoscrypt
   :caption: :file:`mymul_test.ys`

Handling constant inputs
  • The special parameters _TECHMAP_CONSTMSK__ and
    _TECHMAP_CONSTVAL__ can be used to handle constant input values
    to cells.

  • The former contains 1-bits for all constant input bits on the port.

  • The latter contains the constant bits or undef (x) for non-constant bits.

  • Example use-cases:

    • Converting arithmetic (for example multiply to shift).
    • Identify constant addresses or enable bits in memory interfaces.

Example:

.. figure:: /_images/code_examples/techmap/mulshift.*
:class: width-helper invert-helper

.. literalinclude:: /code_examples/techmap/mulshift_map.v
:language: verilog
:caption: :file:mulshift_map.v

.. literalinclude:: /code_examples/techmap/mulshift_test.v
:language: verilog
:caption: :file:mulshift_test.v

.. literalinclude:: /code_examples/techmap/mulshift_test.ys
:language: yoscrypt
:caption: :file:mulshift_test.ys

Handling shorted inputs

text
- The special parameters ``_TECHMAP_BITS_CONNMAP_`` and
  ``_TECHMAP_CONNMAP_<port-name>_`` can be used to handle shorted inputs.
- Each bit of the port correlates to an ``_TECHMAP_BITS_CONNMAP_`` bits wide
  number in ``_TECHMAP_CONNMAP_<port-name>_``.
- Each unique signal bit is assigned its own number. Identical fields in the
  ``_TECHMAP_CONNMAP_<port-name>_`` parameters mean shorted signal bits.
- The numbers 0-3 are reserved for ``0``, ``1``, ``x``, and ``z`` respectively.
- Example use-cases:

    - Detecting shared clock or control signals in memory interfaces.
    - In some cases this can be used for for optimization.

Example:

.. figure:: /_images/code_examples/techmap/addshift.*
    :class: width-helper invert-helper

.. literalinclude:: /code_examples/techmap/addshift_map.v
   :language: verilog
   :caption: :file:`addshift_map.v`

.. literalinclude:: /code_examples/techmap/addshift_test.v
   :language: verilog
   :caption: :file:`addshift_test.v`

.. literalinclude:: /code_examples/techmap/addshift_test.ys
   :language: yoscrypt
   :caption: :file:`addshift_test.ys`

Notes on using techmap
~~~~~~~~~~~~~~~~~~~~~~

- Don't use positional cell parameters in map modules.
- You can use the ``$__``-prefix for internal cell types to avoid collisions
  with the user-namespace. But always use two underscores or the internal
  consistency checker will trigger on these cells.
- Techmap has two major use cases:

    - Creating good logic-level representation of arithmetic functions. This
      also means using dedicated hardware resources such as half- and full-adder
      cells in ASICS or dedicated carry logic in FPGAs.
    - Mapping of coarse-grain resources such as block memory or DSP cells.

---

### Source Using Yosys More Scripting Data Flow Tracking (`docs/source/using_yosys/more_scripting/data_flow_tracking.rst`)

Dataflow tracking
-------------------

Yosys can be used to answer questions such as "can this signal affect this other
signal?" via its *dataflow tracking* support. For this, four special cells,
`$get_tag`, `$set_tag`, `$overwrite_tag` and `$original_tag` are inserted into
the design (e.g. by a custom Yosys pass) and then the `dft_tag` is run, which
converts these cells into ordinary logic. Typically, one would then use `SBY`_
to prove assertions involving these cells.

.. _SBY: https://yosyshq.readthedocs.io/projects/sby

Ordinarily in Yosys, the state of a bit is simply ``0`` or ``1`` (or one of the
special values, ``z`` and ``x``). During dataflow tracking they are augmented
with a set of tags. For example, the state of a bit could be ``0`` and the set
of tags ``"KEY"`` and ``"OVERFLOW"``.

In addition to their usual operations on the logical bits, Yosys operations must
now also process the status of the tags. For this, tags are simply *forwarded*
or *propagated* (i.e. copied) from inputs to outputs, according to the following
general rule:

   A tag is forwarded from an input to an output if the input can affect the
   output, for that particular state of all other inputs.

For example, XOR, AND and OR cells propagate tags as follows:

#. XOR simply forwards all tags from its inputs to its output, because inputs to
   XOR can always affect the output.
#. AND forwards tags on a given input only if the other input is ``1``. Because
   if one input is ``0``, the other input can never affect the output.
#. Similarly, OR forwards tags only if the other input is ``0``.

There are two exceptions to this rule:

#. In general, propagation is only determined approximately. For example, unless
   the ``dft_tag`` code knows about a cell, it simply assumes the worst-case
   behaviour that all inputs can affect all outputs. Further, the code also does
   not consider that, when a signal affects multiple inputs of a cell, the
   resulting simultaneous changes of the inputs can cancel each other out, for
   example ``A ^ A`` or ``A ^ (B ^ A)`` is independent of ``A``, but its tags
   would be propagated nonetheless.
#. If tag groups are used, the rules are modified (see below).

Because of this propagation behaviour, we can answer questions about what
signals are affected by a certain signal, by injecting a tag at that point in
the circuit, and observing where the tag is visible.

Example use cases
~~~~~~~~~~~~~~~~~~

As an example use case, consider a cryptographic processor which is not supposed
to expose its secret keys to the outside world. We can tag all key bits with the
``"KEY"`` tag and use `SBY`_ to formally verify that no external signal ever
carries the ``"KEY"`` tag, meaning that key information is not visible to the
outside. As a caveat, we have to manually clear the ``"KEY"`` tag during
cryptographic operations, as proving that the cryptographic operations
themselves do not leak key information is beyond the ability of Yosys. However
we can still easily detect, if e.g. an engineer forgot to remove debugging code
that allows reading back key data.

As a different use case, we can modify all adders in the design to set the
``"OVERFLOW"`` tag on their output bits, if the addition overflowed, and then
add asserts to all flip-flop inputs and output signals that they do not carry
the ``"OVERFLOW"`` tag, i.e. that the results of overflowed additions never
affect system state. Note that in this particular example we use the ability of
tag insertion to be conditional on logic, in this case the overflow condition of
an adder.

Semantics of dataflow tracking cells

$set_tag has inputs A, SET, CLR, an output Y and a string
parameter TAG. The logic value of A and all tags other than the one
named by the TAG parameter are simply copied to Y. If SET is 1,
then the named tag is added to Y. Otherwise, if CLR is 1, then the
named tag is removed. Otherwise, the tag is unchanged, i.e. it is present in
Y if it is present in A.

$get_tag has an input A and an output Y and a string parameter
TAG. $get_tag inspects A for the presence or absence of a tag of the
given name and sets Y to 1 if the tag is present. The logical value of
A is completely ignored.

$overwrite_tag functions like $set_tag, but lacks the Y output.
Instead of providing a modified version of the input signal, it modifies the
signal A "in-place", i.e. if a signal is input to $overwrite_tag, that
is equivalent to interposing a $set_tag between its driver and all cells it
is connected to. The main purpose of $overwrite_tag is adding tags to
signals produced within a module that cannot or should not be modified itself.

$original_tag functions identically to $get_tag, but ignores
$overwrite_tag, i.e. when converting the $overwrite_tag to $set_tag
as described above, it is equivalent to inserting the $get_tag before the
$set_tag.

Tag groups

text
Tag groups are an advanced feature that modify the propagation rule discussed
above. To use tag groups, simply name tags according to the schema
``"group:name"``. For example, ``"key:0"``, ``"key:a"``, ``"key:b"`` would be
three tags in the ``"key"`` group.

The propagation rule is then amended by

   Inputs cannot block the propagation of each other's tags for tags of the same
   group.

For example, an AND gate will propagate a given tag on one input, if the other
input is either 1 or carries a tag of the same group. So if one input is ``0,
"key:a"`` and the other is ``0, "key:b"`` the result would be ``0, "key:a",
"key:b"``, rather than simply ``0``. Note that if we add an unrelated
``"overflow"`` tag to the first input, it would still not be propagated.

---

### Source Using Yosys More Scripting Index (`docs/source/using_yosys/more_scripting/index.rst`)

More scripting
--------------

.. todo:: brief overview for the more scripting index

.. todo:: troubleshooting document(?)

.. toctree::
   :maxdepth: 3

   load_design
   selections
   interactive_investigation
   model_checking
   data_flow_tracking

.. troubleshooting

---

### Source Using Yosys More Scripting Interactive Investigation (`docs/source/using_yosys/more_scripting/interactive_investigation.rst`)

Interactive design investigation
--------------------------------

.. todo:: interactive design opening text

.. role:: yoscrypt(code)
   :language: yoscrypt

.. _interactive_show:

A look at the show command

.. TODO:: merge into :doc:/getting_started/scripting_intro show section

This section explores the show command and explains the symbols used in the
circuit diagrams generated by it. The code used is included in the Yosys code
base under |code_examples/show|_.

.. |code_examples/show| replace:: :file:docs/source/code_examples/show
.. _code_examples/show: https://github.com/YosysHQ/yosys/tree/main/docs/source/code_examples/show

A simple circuit
^^^^^^^^^^^^^^^^

:ref:example_v below provides the Verilog code for a simple circuit which we
will use to demonstrate the usage of show in a simple setting.

.. literalinclude:: /code_examples/show/example.v
:language: Verilog
:caption: :file:example.v
:name: example_v

The Yosys synthesis script we will be running is included as
:numref:example_ys. Note that show is called with the -pause option,
that halts execution of the Yosys script until the user presses the Enter key.
Using :yoscrypt:show -pause also allows the user to enter an interactive shell
to further investigate the circuit before continuing synthesis.

.. literalinclude:: /code_examples/show/example_show.ys
:language: yoscrypt
:caption: :file:example_show.ys
:name: example_ys

This script, when executed, will show the design after each of the three
synthesis commands. We will now look at each of these diagrams and explain what
is shown.

.. note::

The images uses in this document are generated from the :file:example.ys
file, rather than :file:example_show.ys. :file:example.ys outputs the
schematics as :file:.dot files rather than displaying them directly. You
can view these images yourself by running :file:yosys example.ys and then
xdot example_first.dot etc.

.. figure:: /_images/code_examples/show/example_first.*
:class: width-helper invert-helper

Output of the first show command in :numref:example_ys

The first output shows the design directly after being read by the Verilog
front-end. Input and output ports are displayed as octagonal shapes. Cells are
displayed as rectangles with inputs on the left and outputs on the right side.
The cell labels are two lines long: The first line contains a unique identifier
for the cell and the second line contains the cell type. Internal cell types are
prefixed with a dollar sign. For more details on the internal cell library, see
:doc:/cell_index.

Constants are shown as ellipses with the constant value as label. The syntax
<bit_width>'<bits> is used for constants that are not 32-bit wide and/or
contain bits that are not 0 or 1 (i.e. x or z). Ordinary 32-bit
constants are written using decimal numbers.

Single-bit signals are shown as thin arrows pointing from the driver to the
load. Signals that are multiple bits wide are shown as thick arrows.

Finally processes are shown in boxes with round corners. Processes are Yosys'
internal representation of the decision-trees and synchronization events
modelled in a Verilog always-block. The label reads PROC followed by a
unique identifier in the first line and contains the source code location of the
original always-block in the second line. Note how the multiplexer from the
?:-expression is represented as a $mux cell but the multiplexer from the
if-statement is yet still hidden within the process.

The proc command transforms the process from the first diagram into a
multiplexer and a d-type flip-flop, which brings us to the second diagram:

.. figure:: /_images/code_examples/show/example_second.*
:class: width-helper invert-helper

Output of the second show command in :numref:example_ys

The Rhombus shape to the right is a dangling wire. (Wire nodes are only shown if
they are dangling or have "public" names, for example names assigned from the
Verilog input.) Also note that the design now contains two instances of a
BUF-node. These are artefacts left behind by the proc command. It is quite
usual to see such artefacts after calling commands that perform changes in the
design, as most commands only care about doing the transformation in the least
complicated way, not about cleaning up after them. The next call to clean (or
opt, which includes clean as one of its operations) will clean up these
artefacts. This operation is so common in Yosys scripts that it can simply be
abbreviated with the ;; token, which doubles as separator for commands.
Unless one wants to specifically analyze this artefacts left behind some
operations, it is therefore recommended to always call clean before calling
show.

In this script we directly call opt as the next step, which finally leads us
to the third diagram:

.. figure:: /_images/code_examples/show/example_third.*
:class: width-helper invert-helper
:name: example_out

Output of the third show command in :ref:example_ys

Here we see that the opt command not only has removed the artifacts left
behind by proc, but also determined correctly that it can remove the first
$mux cell without changing the behavior of the circuit.

Break-out boxes for signal vectors
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The code listing below shows a simple circuit which uses a lot of spliced signal
accesses.

.. literalinclude:: /code_examples/show/splice.v
:caption: :file:splice.v
:name: splice_src

Notice how the output for this circuit from the show command
(:numref:splice_dia) appears quite complex. This is an unfortunate side effect
of the way Yosys handles signal vectors (aka. multi-bit wires or buses) as
native objects. While this provides great advantages when analyzing circuits
that operate on wide integers, it also introduces some additional complexity
when the individual bits of of a signal vector are accessed.

.. figure:: /_images/code_examples/show/splice.*
:class: width-helper invert-helper
:name: splice_dia

Output of yosys -p 'prep -top splice_demo; show' splice.v

The key elements in understanding this circuit diagram are of course the boxes
with round corners and rows labeled <MSB_LEFT>:<LSB_LEFT> - <MSB_RIGHT>:<LSB_RIGHT>. Each of these boxes have one signal per row on one
side and a common signal for all rows on the other side. The <MSB>:<LSB>
tuples specify which bits of the signals are broken out and connected. So the
top row of the box connecting the signals a and x indicates that the bit
0 (i.e. the range 0:0) from signal a is connected to bit 1 (i.e. the range
1:1) of signal x.

Lines connecting such boxes together and lines connecting such boxes to cell
ports have a slightly different look to emphasise that they are not actual
signal wires but a necessity of the graphical representation. This distinction
seems like a technicality, until one wants to debug a problem related to the way
Yosys internally represents signal vectors, for example when writing custom
Yosys commands.

Gate level netlists
^^^^^^^^^^^^^^^^^^^

:numref:first_pitfall shows two common pitfalls when working with designs
mapped to a cell library:

.. figure:: /_images/code_examples/show/cmos_00.*
:class: width-helper invert-helper
:name: first_pitfall

A half-adder built from simple CMOS gates, demonstrating common pitfalls when
using show

.. literalinclude:: /code_examples/show/cmos.ys
:language: yoscrypt
:start-after: pitfall
:end-at: cmos_00
:name: pitfall_code
:caption: Generating :numref:first_pitfall

First, Yosys did not have access to the cell library when this diagram was
generated, resulting in all cell ports defaulting to being inputs. This is why
all ports are drawn on the left side the cells are awkwardly arranged in a large
column. Secondly the two-bit vector y requires breakout-boxes for its
individual bits, resulting in an unnecessary complex diagram.

.. figure:: /_images/code_examples/show/cmos_01.*
:class: width-helper invert-helper
:name: second_pitfall

Effects of splitnets command and of providing a cell library on design in
:numref:first_pitfall

.. literalinclude:: /code_examples/show/cmos.ys
:language: yoscrypt
:start-after: fixed
:end-at: cmos_01
:name: pitfall_avoided
:caption: Generating :numref:second_pitfall

For :numref:second_pitfall, Yosys has been given a description of the cell
library as Verilog file containing blackbox modules. There are two ways to load
cell descriptions into Yosys: First the Verilog file for the cell library can be
passed directly to the show command using the -lib <filename> option.
Secondly it is possible to load cell libraries into the design with the
:yoscrypt:read_verilog -lib <filename> command. The second method has the
great advantage that the library only needs to be loaded once and can then be
used in all subsequent calls to the show command.

In addition to that, :numref:second_pitfall was generated after
:yoscrypt:splitnet -ports was run on the design. This command splits all
signal vectors into individual signal bits, which is often desirable when
looking at gate-level circuits. The -ports option is required to also split
module ports. Per default the command only operates on interior signals.

Miscellaneous notes
^^^^^^^^^^^^^^^^^^^

Per default the show command outputs a temporary dot file and launches
xdot to display it. The options -format, -viewer and -prefix can
be used to change format, viewer and filename prefix. Note that the pdf and
ps format are the only formats that support plotting multiple modules in one
run. The dot format can be used to output multiple modules, however
xdot will raise an error when trying to read them.

In densely connected circuits it is sometimes hard to keep track of the
individual signal wires. For these cases it can be useful to call show with
the -colors <integer> argument, which randomly assigns colors to the nets.
The integer (> 0) is used as seed value for the random color assignments.
Sometimes it is necessary it try some values to find an assignment of colors
that looks good.

The command :yoscrypt:help show prints a complete listing of all options
supported by the show command.

Navigating the design

text
Plotting circuit diagrams for entire modules in the design brings us only helps
in simple cases. For complex modules the generated circuit diagrams are just
stupidly big and are no help at all. In such cases one first has to select the
relevant portions of the circuit.

In addition to *what* to display one also needs to carefully decide *when* to
display it, with respect to the synthesis flow. In general it is a good idea to
troubleshoot a circuit in the earliest state in which a problem can be
reproduced. So if, for example, the internal state before calling the `techmap`
command already fails to verify, it is better to troubleshoot the coarse-grain
version of the circuit before `techmap` than the gate-level circuit after
`techmap`.

.. Note::

   It is generally recommended to verify the internal state of a design by
   writing it to a Verilog file using :yoscrypt:`write_verilog -noexpr` and
   using the simulation models from :file:`simlib.v` and :file:`simcells.v` from
   the Yosys data directory (as printed by ``yosys-config --datdir``).

Interactive navigation
^^^^^^^^^^^^^^^^^^^^^^

Once the right state within the synthesis flow for debugging the circuit has
been identified, it is recommended to simply add the `shell` command to the
matching place in the synthesis script. This command will stop the synthesis at
the specified moment and go to shell mode, where the user can interactively
enter commands.

For most cases, the shell will start with the whole design selected (i.e. when
the synthesis script does not already narrow the selection). The command `ls`
can now be used to create a list of all modules. The command `cd` can be used to
switch to one of the modules (type ``cd ..`` to switch back). Now the `ls`
command lists the objects within that module. This is demonstrated below using
:file:`example.v` from `A simple circuit`_:

.. literalinclude:: /code_examples/show/example.out
   :language: doscon
   :start-at: yosys> ls
   :end-before: yosys [example]> dump
   :caption: Output of `ls` and `cd` after running :file:`yosys example.v`
   :name: lscd

When a module is selected using the `cd` command, all commands (with a few
exceptions, such as the ``read_`` and ``write_`` commands) operate only on the
selected module. This can also be useful for synthesis scripts where different
synthesis strategies should be applied to different modules in the design.

We can see that the cell names from :numref:`example_out` are just abbreviations
of the actual cell names, namely the part after the last dollar-sign. Most
auto-generated names (the ones starting with a dollar sign) are rather long and
contains some additional information on the origin of the named object. But in
most cases those names can simply be abbreviated using the last part.

Usually all interactive work is done with one module selected using the `cd`
command. But it is also possible to work from the design-context (``cd ..``). In
this case all object names must be prefixed with ``<module_name>/``. For example
``a*/b*`` would refer to all objects whose names start with ``b`` from all
modules whose names start with ``a``.

The `dump` command can be used to print all information about an object. For
example, calling :yoscrypt:`dump $2` after the :yoscrypt:`cd example` above:

.. literalinclude:: /code_examples/show/example.out
   :language: RTLIL
   :start-after: yosys [example]> dump
   :end-before: yosys [example]> cd
   :dedent:
   :caption: Output of :yoscrypt:`dump $2` after :numref:`lscd`
   :name: dump2

This can for example be useful to determine the names of nets connected to
cells, as the net-names are usually suppressed in the circuit diagram if they
are auto-generated.  Note that the output is in the RTLIL representation,
described in :doc:`/yosys_internals/formats/rtlil_rep`.

Design Investigation
~~~~~~~~~~~~~~~~~~~~

Yosys can also be used to investigate designs (or netlists created from other
tools).

- The selection mechanism, especially patterns such as ``%ci`` and ``%co``, can
  be used to figure out how parts of the design are connected.
- Commands such as `submod`, `expose`, and `splice` can be used to transform the
  design into an equivalent design that is easier to analyse.
- Commands such as `eval` and `sat` can be used to investigate the behavior of
  the circuit.
- :cmd:title:`show`.
- :cmd:title:`dump`.
- :cmd:title:`add` and :cmd:title:`delete` can be used to modify and reorganize
  a design dynamically.

The code used is included in the Yosys code base under
|code_examples/scrambler|_.

.. |code_examples/scrambler| replace:: :file:`docs/source/code_examples/scrambler`
.. _code_examples/scrambler: https://github.com/YosysHQ/yosys/tree/main/docs/source/code_examples/scrambler

Changing design hierarchy
^^^^^^^^^^^^^^^^^^^^^^^^^

Commands such as `flatten` and `submod` can be used to change the design
hierarchy, i.e. flatten the hierarchy or moving parts of a module to a
submodule. This has applications in synthesis scripts as well as in reverse
engineering and analysis.  An example using `submod` is shown below for
reorganizing a module in Yosys and checking the resulting circuit.

.. literalinclude:: /code_examples/scrambler/scrambler.v
   :language: verilog
   :caption: :file:`scrambler.v`

.. literalinclude:: /code_examples/scrambler/scrambler.ys
   :language: yoscrypt
   :caption: :file:`scrambler.ys`
   :end-before: cd ..

.. figure:: /_images/code_examples/scrambler/scrambler_p01.*
    :class: width-helper invert-helper

.. figure:: /_images/code_examples/scrambler/scrambler_p02.*
    :class: width-helper invert-helper

Analyzing the resulting circuit with :cmd:title:`eval`:

.. todo:: replace inline code

.. code:: text

    > cd xorshift32
    > rename n2 in
    > rename n1 out

    > eval -set in 1 -show out
    Eval result: \out = 270369.

    > eval -set in 270369 -show out
    Eval result: \out = 67634689.

    > sat -set out 632435482
    Signal Name                 Dec        Hex                                   Bin
    -------------------- ---------- ---------- -------------------------------------
    \in                   745495504   2c6f5bd0      00101100011011110101101111010000
    \out                  632435482   25b2331a      00100101101100100011001100011010

Behavioral changes
^^^^^^^^^^^^^^^^^^

Commands such as `techmap` can be used to make behavioral changes to the design,
for example changing asynchronous resets to synchronous resets. This has
applications in design space exploration (evaluation of various architectures
for one circuit).

The following techmap map file replaces all positive-edge async reset flip-flops
with positive-edge sync reset flip-flops. The code is taken from the example
Yosys script for ASIC synthesis of the Amber ARMv2 CPU.

.. todo:: replace inline code

.. code:: verilog

    (* techmap_celltype = "$adff" *)
    module adff2dff (CLK, ARST, D, Q);

        parameter WIDTH = 1;
        parameter CLK_POLARITY = 1;
        parameter ARST_POLARITY = 1;
        parameter ARST_VALUE = 0;

        input CLK, ARST;
        input [WIDTH-1:0] D;
        output reg [WIDTH-1:0] Q;

        wire [1023:0] _TECHMAP_DO_ = "proc";

        wire _TECHMAP_FAIL_ = !CLK_POLARITY || !ARST_POLARITY;

        always @(posedge CLK)
            if (ARST)
                Q <= ARST_VALUE;
            else
                Q <= D;

    endmodule

For more on the `techmap` command, see the page on
:doc:`/yosys_internals/techmap`.

Advanced investigation techniques

When working with very large modules, it is often not enough to just select the
interesting part of the module. Instead it can be useful to extract the
interesting part of the circuit into a separate module. This can for example be
useful if one wants to run a series of synthesis commands on the critical part
of the module and wants to carefully read all the debug output created by the
commands in order to spot a problem. This kind of troubleshooting is much easier
if the circuit under investigation is encapsulated in a separate module.

Recall the memdemo design from :ref:advanced_logic_cones:

.. figure:: /_images/code_examples/selections/memdemo_00.*
:class: width-helper invert-helper

memdemo

Because this produces a rather large circuit, it can be useful to split it into
smaller parts for viewing and working with. :numref:submod does exactly that,
utilising the submod command to split the circuit into three sections:
outstage, selstage, and scramble.

.. literalinclude:: /code_examples/selections/submod.ys
:language: yoscrypt
:caption: Using submod to break up the circuit from :file:memdemo.v
:start-after: cd memdemo
:end-before: cd ..
:name: submod

The -name option is used to specify the name of the new module and also the
name of the new cell in the current module. The resulting circuits are shown
below.

.. figure:: /_images/code_examples/selections/submod_02.*
:class: width-helper invert-helper

outstage

.. figure:: /_images/code_examples/selections/submod_03.*
:class: width-helper invert-helper
:name: selstage

selstage

.. figure:: /_images/code_examples/selections/submod_01.*
:class: width-helper invert-helper

scramble

Evaluation of combinatorial circuits
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The eval command can be used to evaluate combinatorial circuits. As an
example, we will use the selstage subnet of memdemo which we found above
and is shown in :numref:selstage.

.. todo:: replace inline code

::

text
yosys [selstage]> eval -set s2,s1 4'b1001 -set d 4'hc -show n2 -show n1

  1. Executing EVAL pass (evaluate the circuit given an input).
  Full command line: eval -set s2,s1 4'b1001 -set d 4'hc -show n2 -show n1
  Eval result: \n2 = 2'10.
  Eval result: \n1 = 2'10.

So the -set option is used to set input values and the -show option is
used to specify the nets to evaluate. If no -show option is specified, all
selected output ports are used per default.

If a necessary input value is not given, an error is produced. The option
-set-undef can be used to instead set all unspecified input nets to undef
(x).

The -table option can be used to create a truth table. For example:

::

text
yosys [selstage]> eval -set-undef -set d[3:1] 0 -table s1,d[0]

  10. Executing EVAL pass (evaluate the circuit given an input).
  Full command line: eval -set-undef -set d[3:1] 0 -table s1,d[0]

    \s1 \d [0] |  \n1  \n2
   ---- ------ | ---- ----
   2'00    1'0 | 2'00 2'00
   2'00    1'1 | 2'xx 2'00
   2'01    1'0 | 2'00 2'00
   2'01    1'1 | 2'xx 2'01
   2'10    1'0 | 2'00 2'00
   2'10    1'1 | 2'xx 2'10
   2'11    1'0 | 2'00 2'00
   2'11    1'1 | 2'xx 2'11

  Assumed undef (x) value for the following signals: \s2

Note that the eval command (as well as the sat command discussed in the next
sections) does only operate on flattened modules. It can not analyze signals
that are passed through design hierarchy levels. So the flatten command must
be used on modules that instantiate other modules before these commands can be
applied.

Solving combinatorial SAT problems
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Often the opposite of the eval command is needed, i.e. the circuits output is
given and we want to find the matching input signals. For small circuits with
only a few input bits this can be accomplished by trying all possible input
combinations, as it is done by the eval -table command. For larger circuits
however, Yosys provides the sat command that uses a SAT_ solver, MiniSAT_,
to solve this kind of problems.

.. _SAT: http://en.wikipedia.org/wiki/Circuit_satisfiability

.. _MiniSAT: http://minisat.se/

.. note::

text
While it is possible to perform model checking directly in Yosys, it
is highly recommended to use SBY or EQY for formal hardware verification.

The sat command works very similar to the eval command. The main difference
is that it is now also possible to set output values and find the corresponding
input values. For Example:

.. todo:: replace inline code

::

text
yosys [selstage]> sat -show s1,s2,d -set s1 s2 -set n2,n1 4'b1001

  11. Executing SAT pass (solving SAT problems in the circuit).
  Full command line: sat -show s1,s2,d -set s1 s2 -set n2,n1 4'b1001

  Setting up SAT problem:
  Import set-constraint: \s1 = \s2
  Import set-constraint: { \n2 \n1 } = 4'1001
  Final constraint equation: { \n2 \n1 \s1 } = { 4'1001 \s2 }
  Imported 3 cells to SAT database.
  Import show expression: { \s1 \s2 \d }

  Solving problem with 81 variables and 207 clauses..
  SAT solving finished - model found:

    Signal Name                 Dec        Hex             Bin
    -------------------- ---------- ---------- ---------------
    \d                            9          9            1001
    \s1                           0          0              00
    \s2                           0          0              00

Note that the sat command supports signal names in both arguments to the
-set option. In the above example we used -set s1 s2 to constraint
s1 and s2 to be equal. When more complex constraints are needed, a
wrapper circuit must be constructed that checks the constraints and signals if
the constraint was met using an extra output port, which then can be forced to a
value using the -set option. (Such a circuit that contains the circuit under
test plus additional constraint checking circuitry is called a miter
circuit.)

.. literalinclude:: /code_examples/primetest.v
:language: verilog
:caption: :file:primetest.v, a simple miter circuit for testing if a number is
prime. But it has a problem.
:name: primetest

:numref:primetest shows a miter circuit that is supposed to be used as a prime
number test. If ok is 1 for all input values a and b for a given
p, then p is prime, or at least that is the idea.

.. todo:: replace inline code

.. code-block::
:caption: Experiments with the miter circuit from :file:primetest.v.
:name: prime_shell

yosys [primetest]> sat -prove ok 1 -set p 31

  1. Executing SAT pass (solving SAT problems in the circuit).
    Full command line: sat -prove ok 1 -set p 31

Setting up SAT problem:
Import set-constraint: \p = 16'0000000000011111
Final constraint equation: \p = 16'0000000000011111
Imported 6 cells to SAT database.
Import proof-constraint: \ok = 1'1
Final proof equation: \ok = 1'1

Solving problem with 2790 variables and 8241 clauses..
SAT proof finished - model found: FAIL!

text
______                   ___       ___       _ _            _ _
 (_____ \                 / __)     / __)     (_) |          | | |
  _____) )___ ___   ___ _| |__    _| |__ _____ _| | _____  __| | |
 |  ____/ ___) _ \ / _ (_   __)  (_   __|____ | | || ___ |/ _  |_|
 | |   | |  | |_| | |_| || |       | |  / ___ | | || ____( (_| |_
 |_|   |_|   \___/ \___/ |_|       |_|  \_____|_|\_)_____)\____|_|


 Signal Name                 Dec        Hex                   Bin
 -------------------- ---------- ---------- ---------------------
 \a                        15029       3ab5      0011101010110101
 \b                         4099       1003      0001000000000011
 \ok                           0          0                     0
 \p                           31         1f      0000000000011111

The Yosys shell session shown in :numref:prime_shell demonstrates that SAT
solvers can even find the unexpected solutions to a problem: Using integer
overflow there actually is a way of "factorizing" 31. The clean solution would
of course be to perform the test in 32 bits, for example by replacing p != a*b in the miter with p != {16'd0,a}b, or by using a temporary variable
for the 32 bit product a*b. But as 31 fits well into 8 bits (and as the
purpose of this document is to show off Yosys features) we can also simply force
the upper 8 bits of a and b to zero for the sat call, as is done
below.

.. todo:: replace inline code

.. code-block::
:caption: Miter circuit from :file:primetest.v, with the upper 8 bits of a
and b constrained to prevent overflow.
:name: prime_fixed

yosys [primetest]> sat -prove ok 1 -set p 31 -set a[15:8],b[15:8] 0

  1. Executing SAT pass (solving SAT problems in the circuit).
    Full command line: sat -prove ok 1 -set p 31 -set a[15:8],b[15:8] 0

Setting up SAT problem:
Import set-constraint: \p = 16'0000000000011111
Import set-constraint: { \a [15:8] \b [15:8] } = 16'0000000000000000
Final constraint equation: { \a [15:8] \b [15:8] \p } = { 16'0000000000000000 16'0000000000011111 }
Imported 6 cells to SAT database.
Import proof-constraint: \ok = 1'1
Final proof equation: \ok = 1'1

Solving problem with 2790 variables and 8257 clauses..
SAT proof finished - no model found: SUCCESS!

text
/$$$$$$      /$$$$$$$$     /$$$$$$$
                /$$__  $$    | $$_____/    | $$__  $$
               | $$  \ $$    | $$          | $$  \ $$
               | $$  | $$    | $$$$$       | $$  | $$
               | $$  | $$    | $$__/       | $$  | $$
               | $$/$$ $$    | $$          | $$  | $$
               |  $$$$$$/ /$$| $$$$$$$$ /$$| $$$$$$$//$$
                \____ $$$|__/|________/|__/|_______/|__/
                      \__/

The -prove option used in :numref:prime_fixed works similar to -set,
but tries to find a case in which the two arguments are not equal. If such a
case is not found, the property is proven to hold for all inputs that satisfy
the other constraints.

It might be worth noting, that SAT solvers are not particularly efficient at
factorizing large numbers. But if a small factorization problem occurs as part
of a larger circuit problem, the Yosys SAT solver is perfectly capable of
solving it.

Solving sequential SAT problems
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The SAT solver functionality in Yosys can not only be used to solve
combinatorial problems, but can also solve sequential problems. Let's consider
the memdemo design from :ref:advanced_logic_cones again, and suppose we
want to know which sequence of input values for d will cause the output y to
produce the sequence 1, 2, 3 from any initial state. Let's use the following
command:

.. todo:: replace inline code?

.. code-block:: yoscrypt

text
sat -seq 6 -show y -show d -set-init-undef \
    -max_undef -set-at 4 y 1 -set-at 5 y 2 -set-at 6 y 3

The -seq 6 option instructs the sat command to solve a sequential problem
in 6 time steps. (Experiments with lower number of steps have show that at least
3 cycles are necessary to bring the circuit in a state from which the sequence
1, 2, 3 can be produced.)

The -set-init-undef option tells the sat command to initialize all
registers to the undef (x) state. The way the x state is treated in
Verilog will ensure that the solution will work for any initial state.

The -max_undef option instructs the sat command to find a solution with a
maximum number of undefs. This way we can see clearly which inputs bits are
relevant to the solution.

Finally the three -set-at options add constraints for the y signal to
play the 1, 2, 3 sequence, starting with time step 4.

This produces the following output:

.. todo:: replace inline code

.. code-block::
:caption: Solving a sequential SAT problem in the memdemo module.
:name: memdemo_sat

yosys [memdemo]> sat -seq 6 -show y -show d -set-init-undef
-max_undef -set-at 4 y 1 -set-at 5 y 2 -set-at 6 y 3

  1. Executing SAT pass (solving SAT problems in the circuit).
    Full command line: sat -seq 6 -show y -show d -set-init-undef
    -max_undef -set-at 4 y 1 -set-at 5 y 2 -set-at 6 y 3

Setting up time step 1:
Final constraint equation: { } = { }
Imported 29 cells to SAT database.

Setting up time step 2:
Final constraint equation: { } = { }
Imported 29 cells to SAT database.

Setting up time step 3:
Final constraint equation: { } = { }
Imported 29 cells to SAT database.

Setting up time step 4:
Import set-constraint for timestep: \y = 4'0001
Final constraint equation: \y = 4'0001
Imported 29 cells to SAT database.

Setting up time step 5:
Import set-constraint for timestep: \y = 4'0010
Final constraint equation: \y = 4'0010
Imported 29 cells to SAT database.

Setting up time step 6:
Import set-constraint for timestep: \y = 4'0011
Final constraint equation: \y = 4'0011
Imported 29 cells to SAT database.

Setting up initial state:
Final constraint equation: { \y \s2 \s1 \mem[3] \mem[2] \mem[1]
\mem[0] } = 24'xxxxxxxxxxxxxxxxxxxxxxxx

Import show expression: \y
Import show expression: \d

Solving problem with 10322 variables and 27881 clauses..
SAT model found. maximizing number of undefs.
SAT solving finished - model found:

text
Time Signal Name                 Dec        Hex             Bin
 ---- -------------------- ---------- ---------- ---------------
 init \mem[0]                      --         --            xxxx
 init \mem[1]                      --         --            xxxx
 init \mem[2]                      --         --            xxxx
 init \mem[3]                      --         --            xxxx
 init \s1                          --         --              xx
 init \s2                          --         --              xx
 init \y                           --         --            xxxx
 ---- -------------------- ---------- ---------- ---------------
    1 \d                            0          0            0000
    1 \y                           --         --            xxxx
 ---- -------------------- ---------- ---------- ---------------
    2 \d                            1          1            0001
    2 \y                           --         --            xxxx
 ---- -------------------- ---------- ---------- ---------------
    3 \d                            2          2            0010
    3 \y                            0          0            0000
 ---- -------------------- ---------- ---------- ---------------
    4 \d                            3          3            0011
    4 \y                            1          1            0001
 ---- -------------------- ---------- ---------- ---------------
    5 \d                           --         --            001x
    5 \y                            2          2            0010
 ---- -------------------- ---------- ---------- ---------------
    6 \d                           --         --            xxxx
    6 \y                            3          3            0011

It is not surprising that the solution sets d = 0 in the first step, as this
is the only way of setting the s1 and s2 registers to a known value. The
input values for the other steps are a bit harder to work out manually, but the
SAT solver finds the correct solution in an instant.

There is much more to write about the sat command. For example, there is a set
of options that can be used to performs sequential proofs using temporal
induction :cite:p:een2003temporal. The command help sat can be used to
print a list of all options with short descriptions of their functions.


Source Using Yosys More Scripting Load Design (`docs/source/using_yosys/more_scripting/load_design.rst`)

Loading a design

.. _input files:

Input files on the command line

text
- guesses frontend based on file extension

  + ``.v`` -> ``read -vlog2k``
  + ``.sv`` -> ``read -sv``
  + ``.vhd`` and ``.vhdl`` -> ``read -vhdl``
  + ``.blif`` and ``.eblif`` -> `read_blif`
  + ``.json`` -> `read_json`
  + ``.il`` -> `read_rtlil` (direct textual representation of Yosys internal
    state)

- command line also supports

  + ``.ys`` -> `script`
  + ``.tcl`` -> `tcl`
  + ``-`` -> reads stdin and treats it as a script

The `read` command
~~~~~~~~~~~~~~~~~~

- standard method of loading designs
- also for defining macros and include directories
- uses `verific` command if available

  + ``-verific`` and ``-noverific`` options to enforce with/without Verific
  + check ``help read`` for more about the options available and the filetypes
    supported
  + elaborate designs with ``verific -import [options] <top>`` (or use
    `hierarchy`)

- fallback to `read_verilog` with ``-defer`` option

  + does not compile design until `hierarchy` command as discussed in
    :doc:`/getting_started/example_synth`
  + more similar to `verific` behaviour

- ``read -define`` et al mapped to `verific` or `verilog_defines`
- similarly, ``read -incdir`` et al mapped to `verific` or `verilog_defaults`

.. note::

   The Verific frontend for Yosys, which provides the :cmd:ref:`verific`
   command, requires Yosys to be built with Verific.  For full functionality,
   custom modifications to the Verific source code from YosysHQ are required,
   but limited useability can be achieved with some stock Verific builds.  Check
   :doc:`/yosys_internals/extending_yosys/build_verific` for more.

.. _Frontend:

Yosys frontends
~~~~~~~~~~~~~~~

- :doc:`/cmd/index_frontends`
- typically start with ``read_``
- built-in support for heredocs

  + in-line code with ``<<EOT``
  + can use any eot marker, but EOT (End-of-Transmission) and EOF
    (End-of-File) are most common

- built-in support for reading multiple files in the same command

  + executed as multiple successive calls to the frontend

- compatible with ``-f`` command line option, e.g. ``yosys -f verilog
  design.txt`` will use the `read_verilog` frontend with the input file
  ``design.txt``

- `verific` and `read` commands are technically not 'Frontends', but their
  behaviour is kept in sync

.. note::

   'Frontend' here means that the command is implemented as a sub-class of
   ``RTLIL::Frontend``, as opposed to the usual ``RTLIL::Pass``.

.. todo:: link note to as-yet non-existent section on ``RTLIL::Pass`` under
          :doc:`/yosys_internals/extending_yosys/index`

The `read_verilog` command
""""""""""""""""""""""""""

- :cmd:title:`read_verilog`; also

  + :cmd:title:`verilog_defaults`,
  + :cmd:title:`verilog_defines`, and
  + :cmd:title:`read_verilog_file_list`

- supports most of Verilog-2005
- limited support for SystemVerilog
- some non-standard features/extensions for enabling formal verification
- please do not rely on `read_verilog` for syntax checking

  + recommend using a simulator (for example Icarus Verilog) or linting with
    another tool (such as verilator) first

.. todo:: figure out this example code block

.. code-block:: yoscrypt

    read_verilog file1.v
    read_verilog -I include_dir -D enable_foo -D WIDTH=12 file2.v
    read_verilog -lib cell_library.v

    verilog_defaults -add -I include_dir
    read_verilog file3.v
    read_verilog file4.v
    verilog_defaults -clear

    verilog_defaults -push
    verilog_defaults -add -I include_dir
    read_verilog file5.v
    read_verilog file6.v
    verilog_defaults -pop

Other built-in ``read_*`` commands
""""""""""""""""""""""""""""""""""

- :cmd:title:`read_rtlil`
- :cmd:title:`read_aiger`
- :cmd:title:`read_blif`
- :cmd:title:`read_json`
- :cmd:title:`read_liberty`

.. TODO:: does `write_file` count?

Externally maintained plugins
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

- `GHDL plugin`_ for VHDL (check ``help ghdl``)
- `yosys-slang plugin`_ for more comprehensive SystemVerilog support (check
  ``help read_slang``)

  + yosys-slang is implemented as a '`Frontend`_,' with all the built-in support
    that entails

.. _GHDL plugin: https://github.com/ghdl/ghdl-yosys-plugin
.. _yosys-slang plugin: https://github.com/povik/yosys-slang

- both plugins above are included in `OSS CAD Suite`_

.. _OSS CAD Suite: https://github.com/YosysHQ/oss-cad-suite-build

- `Synlig`_, which uses `Surelog`_ to provide SystemVerilog support

  + also implemented as a '`Frontend`_'

.. _Synlig: https://github.com/chipsalliance/synlig
.. _Surelog: https://github.com/chipsalliance/Surelog

---

### Source Using Yosys More Scripting Model Checking (`docs/source/using_yosys/more_scripting/model_checking.rst`)

Symbolic model checking
-----------------------

.. todo:: check text context

.. note::

    While it is possible to perform model checking directly in Yosys, it
    is highly recommended to use SBY or EQY for formal hardware verification.

Symbolic Model Checking (SMC) is used to formally prove that a circuit has (or
has not) a given property.

One application is Formal Equivalence Checking: Proving that two circuits are
identical. For example this is a very useful feature when debugging custom
passes in Yosys.

Other applications include checking if a module conforms to interface standards.

The `sat` command in Yosys can be used to perform Symbolic Model Checking.

Checking techmap
~~~~~~~~~~~~~~~~

.. todo:: add/expand supporting text

Let's take a look at an example included in the Yosys code base under
|code_examples/synth_flow|_:

.. |code_examples/synth_flow| replace:: :file:`docs/source/code_examples/synth_flow`
.. _code_examples/synth_flow: https://github.com/YosysHQ/yosys/tree/main/docs/source/code_examples/synth_flow

.. literalinclude:: /code_examples/synth_flow/techmap_01_map.v
   :language: verilog
   :caption: :file:`techmap_01_map.v`

.. literalinclude:: /code_examples/synth_flow/techmap_01.v
   :language: verilog
   :caption: :file:`techmap_01.v`

.. literalinclude:: /code_examples/synth_flow/techmap_01.ys
   :language: yoscrypt
   :caption: :file:`techmap_01.ys`

To see if it is correct we can use the following code:

.. todo:: replace inline code

.. code:: yoscrypt

    # read test design
    read_verilog techmap_01.v
    hierarchy -top test

    # create two version of the design: test_orig and test_mapped
    copy test test_orig
    rename test test_mapped

    # apply the techmap only to test_mapped
    techmap -map techmap_01_map.v test_mapped

    # create a miter circuit to test equivalence
    miter -equiv -make_assert -make_outputs test_orig test_mapped miter
    flatten miter

    # run equivalence check
    sat -verify -prove-asserts -show-inputs -show-outputs miter

Result:

.. code::

    Solving problem with 945 variables and 2505 clauses..
    SAT proof finished - no model found: SUCCESS!

AXI4 Stream Master
~~~~~~~~~~~~~~~~~~

The code used in this section is included in the Yosys code base under
|code_examples/axis|_.

.. |code_examples/axis| replace:: :file:`docs/source/code_examples/axis`
.. _code_examples/axis: https://github.com/YosysHQ/yosys/tree/main/docs/source/code_examples/axis

The following AXI4 Stream Master has a bug. But the bug is not exposed if the
slave keeps ``tready`` asserted all the time. (Something a test bench might do.)

Symbolic Model Checking can be used to expose the bug and find a sequence of
values for ``tready`` that yield the incorrect behavior.

.. todo:: add/expand supporting text

.. literalinclude:: /code_examples/axis/axis_master.v
   :language: verilog
   :caption: :file:`axis_master.v`

.. literalinclude:: /code_examples/axis/axis_test.v
   :language: verilog
   :caption: :file:`axis_test.v`

.. literalinclude:: /code_examples/axis/axis_test.ys
   :language: yoscrypt
   :caption: :file:`test.ys`

Result with unmodified :file:`axis_master.v`:

.. todo:: replace inline code

.. code::

    Solving problem with 159344 variables and 442126 clauses..
    SAT proof finished - model found: FAIL!

Result with fixed :file:`axis_master.v`:

.. code::

    Solving problem with 159144 variables and 441626 clauses..
    SAT proof finished - no model found: SUCCESS!

Witness framework and per-property tracking

When using AIGER-based formal verification flows (such as the abc engine in
SBY), Yosys provides infrastructure for tracking individual formal
properties through the verification pipeline.

The rename -witness pass assigns public names to all cells that participate in
the witness framework:

  • Witness signal cells: $anyconst, $anyseq, $anyinit,
    $allconst, $allseq
  • Formal property cells: $assert, $assume, $cover, $live,
    $fair, $check

These public names allow downstream tools to refer to individual properties by
their hierarchical path rather than by anonymous internal identifiers.

The write_aiger -ywmap option generates a map file for conversion to and from
Yosys witness traces, and also allows for mapping AIGER bad-state properties and
invariant constraints back to individual formal properties by name. This enables
features like per-property pass/fail reporting (e.g. abc pdr with
--keep-going mode).

The write_smt2 backend similarly uses the public witness names when emitting
SMT2 comments. Cells whose hdlname attribute contains the _witness_
marker are treated as having private names for comment purposes, keeping solver
output clean.


Source Using Yosys More Scripting Selections (`docs/source/using_yosys/more_scripting/selections.rst`)

Selections

.. role:: yoscrypt(code)
:language: yoscrypt

The selection framework

text
.. todo:: reduce overlap with :doc:`/getting_started/scripting_intro` select section

The `select` command can be used to create a selection for subsequent commands.
For example:

.. code:: yoscrypt

    select foobar         # select the module foobar
    delete                # delete selected objects

Normally the `select` command overwrites a previous selection. The commands
:yoscrypt:`select -add` and :yoscrypt:`select -del` can be used to add or remove
objects from the current selection.

The command :yoscrypt:`select -clear` can be used to reset the selection to the
default, which is a complete selection of everything in the current module.

This selection framework can also be used directly in many other commands.
Whenever a command has ``[selection]`` as last argument in its usage help, this
means that it will use the engine behind the `select` command to evaluate
additional arguments and use the resulting selection instead of the selection
created by the last `select` command.

For example, the command `delete` will delete everything in the current
selection; while :yoscrypt:`delete foobar` will only delete the module foobar.
If no `select` command has been made, then the "current selection" will be the
whole design.

.. note:: Many of the examples on this page make use of the `show`
   command to visually demonstrate the effect of selections.  For a more
   detailed look at this command, refer to :ref:`interactive_show`.

How to make a selection

Selection by object name
^^^^^^^^^^^^^^^^^^^^^^^^

The easiest way to select objects is by object name. This is usually only done
in synthesis scripts that are hand-tailored for a specific design.

.. code:: yoscrypt

text
select foobar         # select module foobar
select foo*           # select all modules whose names start with foo
select foo*/bar*      # select all objects matching bar* from modules matching foo*
select */clk          # select objects named clk from all modules

Module and design context
^^^^^^^^^^^^^^^^^^^^^^^^^

Commands can be executed in module/ or design/ context. Until now, all
commands have been executed in design context. The cd command can be used to
switch to module context.

In module context, all commands only effect the active module. Objects in the
module are selected without the <module_name>/ prefix. For example:

.. code:: yoscrypt

text
cd foo                # switch to module foo
delete bar            # delete object foo/bar

cd mycpu              # switch to module mycpu
dump reg_*            # print details on all objects whose names start with reg_

cd ..                 # switch back to design

Note: Most synthesis scripts never switch to module context. But it is a very
powerful tool which we explore more in
:doc:/using_yosys/more_scripting/interactive_investigation.

Selecting by object property or type
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Special patterns can be used to select by object property or type. For example:

  • select all wires whose names start with reg_: :yoscrypt:select w:reg_*
  • select all objects with the attribute foobar set: :yoscrypt:select a:foobar
  • select all objects with the attribute foobar set to 42: :yoscrypt:select a:foobar=42
  • select all modules with the attribute blabla set: :yoscrypt:select A:blabla
  • select all $add cells from the module foo: :yoscrypt:select foo/t:$add

A complete list of pattern expressions can be found in :cmd:title:select.

Operations on selections

text
Combining selections
^^^^^^^^^^^^^^^^^^^^

The `select` command is actually much more powerful than it might seem at first
glance. When it is called with multiple arguments, each argument is evaluated
and pushed separately on a stack. After all arguments have been processed it
simply creates the union of all elements on the stack. So :yoscrypt:`select
t:$add a:foo` will select all `$add` cells and all objects with the ``foo``
attribute set:

.. literalinclude:: /code_examples/selections/foobaraddsub.v
   :caption: Test module for operations on selections
   :name: foobaraddsub
   :language: verilog

.. code-block::
   :caption: Output for command ``select t:$add a:foo -list`` on :numref:`foobaraddsub`

   yosys> select t:$add a:foo -list
   foobaraddsub/$add$foobaraddsub.v:6$3
   foobaraddsub/$sub$foobaraddsub.v:5$2
   foobaraddsub/$add$foobaraddsub.v:4$1

In many cases simply adding more and more stuff to the selection is an
ineffective way of selecting the interesting part of the design. Special
arguments can be used to combine the elements on the stack. For example the
``%i`` arguments pops the last two elements from the stack, intersects them, and
pushes the result back on the stack. So :yoscrypt:`select t:$add a:foo %i` will
select all `$add` cells that have the ``foo`` attribute set:

.. code-block::
   :caption: Output for command ``select t:$add a:foo %i -list`` on :numref:`foobaraddsub`

   yosys> select t:$add a:foo %i -list
   foobaraddsub/$add$foobaraddsub.v:4$1

Some of the special ``%``-codes:

- ``%u``: union of top two elements on stack -- pop 2, push 1
- ``%d``: difference of top two elements on stack -- pop 2, push 1
- ``%i``: intersection of top two elements on stack -- pop 2, push 1
- ``%n``: inverse of top element on stack -- pop 1, push 1

See :cmd:title:`select` for the full list.

Expanding selections
^^^^^^^^^^^^^^^^^^^^

:numref:`sumprod` uses the Yosys non-standard ``{... *}`` syntax to set the
attribute ``sumstuff`` on all cells generated by the first assign statement.
(This works on arbitrary large blocks of Verilog code and can be used to mark
portions of code for analysis.)

.. literalinclude:: /code_examples/selections/sumprod.v
   :caption: Another test module for operations on selections
   :name: sumprod
   :language: verilog

Selecting ``a:sumstuff`` in this module will yield the following circuit
diagram:

.. figure:: /_images/code_examples/selections/sumprod_00.*
   :class: width-helper invert-helper
   :name: sumprod_00

   Output of ``show a:sumstuff`` on :numref:`sumprod`

As only the cells themselves are selected, but not the temporary wire ``$1_Y``,
the two adders are shown as two disjunct parts. This can be very useful for
global signals like clock and reset signals: just unselect them using a command
such as :yoscrypt:`select -del clk rst` and each cell using them will get its
own net label.

In this case however we would like to see the cells connected properly. This can
be achieved using the ``%x`` action, that broadens the selection, i.e. for each
selected wire it selects all cells connected to the wire and vice versa. So
:yoscrypt:`show a:sumstuff %x` yields the diagram shown in :numref:`sumprod_01`:

.. figure:: /_images/code_examples/selections/sumprod_01.*
   :class: width-helper invert-helper
   :name: sumprod_01

   Output of ``show a:sumstuff %x`` on :numref:`sumprod`

.. _selecting_logic_cones:

Selecting logic cones
^^^^^^^^^^^^^^^^^^^^^

:numref:`sumprod_01` shows what is called the ``input cone`` of ``sum``, i.e.
all cells and signals that are used to generate the signal ``sum``. The ``%ci``
action can be used to select the input cones of all object in the top selection
in the stack maintained by the `select` command.

As with the ``%x`` action, these commands broaden the selection by one "step".
But this time the operation only works against the direction of data flow. That
means, wires only select cells via output ports and cells only select wires via
input ports.

The following sequence of diagrams demonstrates this step-wise expansion:

.. figure:: /_images/code_examples/selections/sumprod_02.*
   :class: width-helper invert-helper

   Output of :yoscrypt:`show prod` on :numref:`sumprod`

.. figure:: /_images/code_examples/selections/sumprod_03.*
   :class: width-helper invert-helper

   Output of :yoscrypt:`show prod %ci` on :numref:`sumprod`

.. figure:: /_images/code_examples/selections/sumprod_04.*
   :class: width-helper invert-helper

   Output of :yoscrypt:`show prod %ci %ci` on :numref:`sumprod`

.. figure:: /_images/code_examples/selections/sumprod_05.*
   :class: width-helper invert-helper

   Output of :yoscrypt:`show prod %ci %ci %ci` on :numref:`sumprod`

Notice the subtle difference between :yoscrypt:`show prod %ci` and
:yoscrypt:`show prod %ci %ci`.  Both images show the `$mul` cell driven by some
inputs ``$3_Y`` and ``c``.  However it is not until the second image, having
called ``%ci`` the second time, that `show` is able to distinguish between
``$3_Y`` being a wire and ``c`` being an input.  We can see this better with the
`dump` command instead:

.. literalinclude:: /code_examples/selections/sumprod.out
   :language: RTLIL
   :end-at: end
   :caption: Output of :yoscrypt:`dump prod %ci`

.. literalinclude:: /code_examples/selections/sumprod.out
   :language: RTLIL
   :start-after: end
   :caption: Output of :yoscrypt:`dump prod %ci %ci`

When selecting many levels of logic, repeating ``%ci`` over and over again can
be a bit dull. So there is a shortcut for that: the number of iterations can be
appended to the action. So for example the action ``%ci3`` is identical to
performing the ``%ci`` action three times.

The action ``%ci*`` performs the ``%ci`` action over and over again until it has
no effect anymore.

.. _advanced_logic_cones:

Advanced logic cone selection
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

In most cases there are certain cell types and/or ports that should not be
considered for the ``%ci`` action, or we only want to follow certain cell types
and/or ports. This can be achieved using additional patterns that can be
appended to the ``%ci`` action.

Lets consider :numref:`memdemo_src`. It serves no purpose other than being a
non-trivial circuit for demonstrating some of the advanced Yosys features. This
code is available in ``docs/source/code_examples/selections`` of the Yosys
source repository.

.. literalinclude:: /code_examples/selections/memdemo.v
   :caption: :file:`memdemo.v`
   :name: memdemo_src
   :language: verilog

The script :file:`memdemo.ys` is used to generate the images included here.
Let's look at the first section:

.. literalinclude:: /code_examples/selections/memdemo.ys
   :caption: Synthesizing :ref:`memdemo_src`
   :name: memdemo_ys
   :language: yoscrypt
   :end-at: opt

This loads :numref:`memdemo_src` and synthesizes the included module. Note that
this code can be copied and run directly in a Yosys command line session,
provided :file:`memdemo.v` is in the same directory. We can now change to the
``memdemo`` module with ``cd memdemo``, and call `show` to see the diagram in
:numref:`memdemo_00`.

.. figure:: /_images/code_examples/selections/memdemo_00.*
   :class: width-helper invert-helper
   :name: memdemo_00

   Complete circuit diagram for the design shown in :numref:`memdemo_src`

There's a lot going on there, but maybe we are only interested in the tree of
multiplexers that select the output value. Let's start by just showing the
output signal, ``y``, and its immediate predecessors. Remember `Selecting logic
cones`_ from above, we can use :yoscrypt:`show y %ci2`:

.. figure:: /_images/code_examples/selections/memdemo_01.*
   :class: width-helper invert-helper
   :name: memdemo_01

   Output of :yoscrypt:`show y %ci2`

From this we would learn that ``y`` is driven by a `$dff` cell, that ``y`` is
connected to the output port ``Q``, that the ``clk`` signal goes into the
``CLK`` input port of the cell, and that the data comes from an auto-generated
wire into the input ``D`` of the flip-flop cell (indicated by the ``$`` at the
start of the name).  Let's go a bit further now and try :yoscrypt:`show y %ci5`:

.. figure:: /_images/code_examples/selections/memdemo_02.*
   :class: width-helper invert-helper
   :name: memdemo_02

   Output of :yoscrypt:`show y %ci5`

That's starting to get a bit messy, so maybe we want to ignore the mux select
inputs. To add a pattern we add a colon followed by the pattern to the ``%ci``
action. The pattern itself starts with ``-`` or ``+``, indicating if it is an
include or exclude pattern, followed by an optional comma separated list of cell
types, followed by an optional comma separated list of port names in square
brackets.  In this case, we want to exclude the ``S`` port of the `$mux` cell
type with :yoscrypt:`show y %ci5:-$mux[S]`:

.. figure:: /_images/code_examples/selections/memdemo_03.*
   :class: width-helper invert-helper
   :name: memdemo_03

   Output of :yoscrypt:`show y %ci5:-$mux[S]`

We could use a command such as :yoscrypt:`show y %ci2:+$dff[Q,D]
%ci*:-$mux[S]:-$dff` in which the first ``%ci`` jumps over the initial d-type
flip-flop and the 2nd action selects the entire input cone without going over
multiplexer select inputs and flip-flop cells:

.. figure:: /_images/code_examples/selections/memdemo_05.*
   :class: width-helper invert-helper
   :name: memdemo_05

   Output of ``show y %ci2:+$dff[Q,D] %ci*:-$mux[S]:-$dff``

Or we could use :yoscrypt:`show y %ci*:-[CLK,S]:+$dff:+$mux` instead, following
the input cone all the way but only following `$dff` and `$mux` cells, and
ignoring any ports named ``CLK`` or ``S``:

.. TODO:: pending discussion on whether rule ordering is a bug or a feature

.. figure:: /_images/code_examples/selections/memdemo_04.*
   :class: width-helper invert-helper
   :name: memdemo_04

   Output of :yoscrypt:`show y %ci*:-[CLK,S]:+$dff,$mux`

Similar to ``%ci`` exists an action ``%co`` to select output cones that accepts
the same syntax for pattern and repetition. The ``%x`` action mentioned
previously also accepts this advanced syntax.

These actions for traversing the circuit graph, combined with the actions for
boolean operations such as intersection (``%i``) and difference (``%d``) are
powerful tools for extracting the relevant portions of the circuit under
investigation.

Again, see :cmd:title:`select` for full documentation of these expressions.

Incremental selection
^^^^^^^^^^^^^^^^^^^^^

Sometimes a selection can most easily be described by a series of add/delete
operations. As mentioned previously, the commands :yoscrypt:`select -add` and
:yoscrypt:`select -del` respectively add or remove objects from the current
selection instead of overwriting it.

.. code:: yoscrypt

    select -none            # start with an empty selection
    select -add reg_*       # select a bunch of objects
    select -del reg_42      # but not this one
    select -add state %ci   # and add more stuff

Within a select expression the token ``%`` can be used to push the previous
selection on the stack.

.. code:: yoscrypt

    select t:$add t:$sub    # select all $add and $sub cells
    select % %ci % %d       # select only the input wires to those cells

Storing and recalling selections

.. todo:: reflow for not presentation

The current selection can be stored in memory with the command select -set <name>. It can later be recalled using select @<name>. In fact, the
@<name> expression pushes the stored selection on the stack maintained by
the select command. So for example :yoscrypt:select @foo @bar %i will select
the intersection between the stored selections foo and bar.

In larger investigation efforts it is highly recommended to maintain a script
that sets up relevant selections, so they can easily be recalled, for example
when Yosys needs to be re-run after a design or source code change.

The history command can be used to list all recent interactive commands. This
feature can be useful for creating such a script from the commands used in an
interactive session.

Remember that select expressions can also be used directly as arguments to most
commands. Some commands also accept a single select argument to some options. In
those cases selection variables must be used to capture more complex selections.

Example code from |code_examples/selections|_:

.. |code_examples/selections| replace:: :file:docs/source/code_examples/selections
.. _code_examples/selections: https://github.com/YosysHQ/yosys/tree/main/docs/source/code_examples/selections

.. literalinclude:: /code_examples/selections/select.v
:language: verilog
:caption: :file:select.v

.. literalinclude:: /code_examples/selections/select.ys
:language: yoscrypt
:caption: :file:select.ys
:name: select_ys

.. figure:: /_images/code_examples/selections/select.*
:class: width-helper invert-helper

text
Circuit diagram produced by :numref:`select_ys`

Source Using Yosys Synthesis Abc (`docs/source/using_yosys/synthesis/abc.rst`)

The ABC toolbox

.. role:: yoscrypt(code)
:language: yoscrypt

ABC_, from the University of California, Berkeley, is a logic toolbox used for
fine-grained optimisation and LUT mapping.

Yosys has two different commands, which both use this logic toolbox, but use it
in different ways.

The abc pass can be used for both ASIC (e.g. :yoscrypt:abc -liberty) and
FPGA (:yoscrypt:abc -lut) mapping, but this page will focus on FPGA mapping.

The abc9 pass generally provides superior mapping quality due to being aware
of combination boxes and DFF and LUT timings, giving it a more global view of
the mapping problem.

.. _ABC: https://github.com/berkeley-abc/abc

ABC: the unit delay model, simple and efficient

The abc pass uses a highly simplified view of an FPGA:

  • An FPGA is made up of a network of inputs that connect through LUTs to a
    network of outputs. These inputs may actually be I/O pins, D flip-flops,
    memory blocks or DSPs, but ABC is unaware of this.
  • Each LUT has 1 unit of delay between an input and its output, and this applies
    for all inputs of a LUT, and for all sizes of LUT up to the maximum LUT size
    allowed; e.g. the delay between the input of a LUT2 and its output is the same
    as the delay between the input of a LUT6 and its output.
  • A LUT may take up a variable number of area units. This is constant for each
    size of LUT; e.g. a LUT4 may take up 1 unit of area, but a LUT5 may take up 2
    units of area, but this applies for all LUT4s and LUT5s.

This is known as the "unit delay model", because each LUT uses one unit of
delay.

From this view, the problem ABC has to solve is finding a mapping of the network
to LUTs that has the lowest delay, and then optimising the mapping for size
while maintaining this delay.

This approach has advantages:

  • It is simple and easy to implement.
  • Working with unit delays is fast to manipulate.
  • It reflects some FPGA families, for example, the iCE40HX/LP fits the
    assumptions of the unit delay model quite well (almost all synchronous blocks,
    except for adders).

But this approach has drawbacks, too:

  • The network of inputs and outputs with only LUTs means that a lot of
    combinational cells (multipliers and LUTRAM) are invisible to the unit delay
    model, meaning the critical path it optimises for is not necessarily the
    actual critical path.
  • LUTs are implemented as multiplexer trees, so there is a delay caused by the
    result propagating through the remaining multiplexers. This means the
    assumption of delay being equal isn't true in physical hardware, and is
    proportionally larger for larger LUTs.
  • Even synchronous blocks have arrival times (propagation delay between clock
    edge to output changing) and setup times (requirement for input to be stable
    before clock edge) which affect the delay of a path.

ABC9: the generalised delay model, realistic and flexible

ABC9 uses a more detailed and accurate model of an FPGA:

  • An FPGA is made up of a network of inputs that connect through LUTs and
    combinational boxes to a network of outputs. These boxes have specified delays
    between inputs and outputs, and may have an associated network ("white boxes")
    or not ("black boxes"), but must be treated as a whole.
  • Each LUT has a specified delay between an input and its output in arbitrary
    delay units, and this varies for all inputs of a LUT and for all sizes of LUT,
    but each size of LUT has the same associated delay; e.g. the delay between
    input A and output is different between a LUT2 and a LUT6, but is constant for
    all LUT6s.
  • A LUT may take up a variable number of area units. This is constant for each
    size of LUT; e.g. a LUT4 may take up 1 unit of area, but a LUT5 may take up 2
    units of area, but this applies for all LUT4s and LUT5s.

This is known as the "generalised delay model", because it has been generalised
to arbitrary delay units. ABC9 doesn't actually care what units you use here,
but the Yosys convention is picoseconds. Note the introduction of boxes as a
concept. While the generalised delay model does not require boxes, they
naturally fit into it to represent combinational delays. Even synchronous delays
like arrival and setup can be emulated with combinational boxes that act as a
delay. This is further extended to white boxes, where the mapper is able to see
inside a box, and remove orphan boxes with no outputs, such as adders.

Again, ABC9 finds a mapping of the network to LUTs that has the lowest delay,
and then minimises it to find the lowest area, but it has a lot more information
to work with about the network.

The result here is that ABC9 can remove boxes (like adders) to reduce area,
optimise better around those boxes, and also permute inputs to give the critical
path the fastest inputs.

.. todo:: more about logic minimization & register balancing et al with ABC

Setting up a flow for ABC9

Much of the configuration comes from attributes and specify blocks in
Verilog simulation models.

specify syntax

text
Since ``specify`` is a relatively obscure part of the Verilog standard, a quick
guide to the syntax:

.. code-block:: verilog

   specify                           // begins a specify block
     (A => B) = 123;                 // simple combinational path from A to B with a delay of 123.
     (A *> B) = 123;                 // simple combinational path from A to all bits of B with a delay of 123 for all.
     if (FOO) (A => B) = 123;        // paths may apply under specific conditions.
     (posedge CLK => (Q : D)) = 123; // combinational path triggered on the positive edge of CLK; used for clock-to-Q arrival paths.
     $setup(A, posedge CLK, 123);    // setup constraint for an input relative to a clock.
   endspecify                        // ends a specify block

By convention, all delays in ``specify`` blocks are in integer picoseconds.
Files containing ``specify`` blocks should be read with the ``-specify`` option
to `read_verilog` so that they aren't skipped.

LUTs
^^^^

LUTs need to be annotated with an ``(* abc9_lut=N *)`` attribute, where ``N`` is
the relative area of that LUT model. For example, if an architecture can combine
LUTs to produce larger LUTs, then the combined LUTs would have increasingly
larger ``N``. Conversely, if an architecture can split larger LUTs into smaller
LUTs, then the smaller LUTs would have smaller ``N``.

LUTs are generally specified with simple combinational paths from the LUT inputs
to the LUT output.

DFFs
^^^^

DFFs should be annotated with an ``(* abc9_flop *)`` attribute, however ABC9 has
some specific requirements for this to be valid: - the DFF must initialise to
zero (consider using `dfflegalize` to ensure this). - the DFF cannot have any
asynchronous resets/sets (see the simplification idiom and the Boxes section for
what to do here).

It is worth noting that in pure ``abc9`` mode, only the setup and arrival times
are passed to ABC9 (specifically, they are modelled as buffers with the given
delay). In ``abc9 -dff``, the flop itself is passed to ABC9, permitting
sequential optimisations.

Some vendors have universal DFF models which include async sets/resets even when
they're unused. Therefore *the simplification idiom* exists to handle this: by
using a ``techmap`` file to discover flops which have a constant driver to those
asynchronous controls, they can be mapped into an intermediate, simplified flop
which qualifies as an ``(* abc9_flop *)``, ran through `abc9`, and then mapped
back to the original flop. This is used in `synth_intel_alm` and
`synth_quicklogic` for the PolarPro3.

DFFs are usually specified to have setup constraints against the clock on the
input signals, and an arrival time for the ``Q`` output.

Boxes
^^^^^

A "box" is a purely-combinational piece of hard logic. If the logic is exposed
to ABC9, it's a "whitebox", otherwise it's a "blackbox". Carry chains would be
best implemented as whiteboxes, but a DSP would be best implemented as a
blackbox (multipliers are too complex to easily work with). LUT RAMs can be
implemented as whiteboxes too.

Boxes are arguably the biggest advantage that ABC9 has over ABC: by being aware
of carry chains and DSPs, it avoids optimising for a path that isn't the actual
critical path, while the generally-longer paths result in ABC9 being able to
reduce design area by mapping other logic to slower cells with greater logic
density.

---

### Source Using Yosys Synthesis Cell Libs (`docs/source/using_yosys/synthesis/cell_libs.rst`)

Mapping to cell libraries
-------------------------

.. role:: yoscrypt(code)
   :language: yoscrypt

While much of this documentation focuses on the use of Yosys with FPGAs, it is
also possible to map to cell libraries which can be used in designing ASICs.
This section will cover a brief `example project`_, available in the Yosys
source code under :file:`docs/source/code_examples/intro/`.  The project
contains a simple ASIC synthesis script (:file:`counter.ys`), a digital design
written in Verilog (:file:`counter.v`), and a simple CMOS cell library
(:file:`mycells.lib`).  Many of the early steps here are already covered in more
detail in the :doc:`/getting_started/example_synth` document.

.. note::

   The :file:`counter.ys` script includes the commands used to generate the
   images in this document.  Code snippets in this document skip these commands;
   including line numbers to allow the reader to follow along with the source.

   To learn more about these commands, check out :ref:`interactive_show`.

.. _example project: https://github.com/YosysHQ/yosys/tree/main/docs/source/code_examples/intro

A simple counter
~~~~~~~~~~~~~~~~

First, let's quickly look at the design:

.. literalinclude:: /code_examples/intro/counter.v
   :language: Verilog
   :linenos:
   :name: counter-v
   :caption: :file:`counter.v`

This is a simple counter with reset and enable.  If the reset signal, ``rst``,
is high then the counter will reset to 0.  Otherwise, if the enable signal,
``en``, is high then the ``count`` register will increment by 1 each rising edge
of the clock, ``clk``.

Loading the design

.. literalinclude:: /code_examples/intro/counter.ys
:language: yoscrypt
:lines: 1-3
:lineno-match:
:caption: :file:counter.ys - read design

Our circuit now looks like this:

.. figure:: /_images/code_examples/intro/counter_00.*
:class: width-helper invert-helper
:name: counter-hierarchy

counter after hierarchy

Coarse-grain representation

text
.. literalinclude:: /code_examples/intro/counter.ys
   :language: yoscrypt
   :lines: 7-10
   :lineno-match:
   :caption: :file:`counter.ys` - the high-level stuff

.. figure:: /_images/code_examples/intro/counter_01.*
   :class: width-helper invert-helper

   Coarse-grain representation of the ``counter`` module

Logic gate mapping
~~~~~~~~~~~~~~~~~~

.. literalinclude:: /code_examples/intro/counter.ys
   :language: yoscrypt
   :lines: 14-15
   :lineno-match:
   :caption: :file:`counter.ys` - mapping to internal cell library

.. figure:: /_images/code_examples/intro/counter_02.*
   :class: width-helper invert-helper

   ``counter`` after `techmap`

Mapping to hardware
~~~~~~~~~~~~~~~~~~~

For this example, we are using a Liberty file to describe a cell library which
our internal cell library will be mapped to:

.. todo:: find a Liberty pygments style?

.. literalinclude:: /code_examples/intro/mycells.lib
   :language: text
   :linenos:
   :name: mycells-lib
   :caption: :file:`mycells.lib`

Recall that the Yosys built-in logic gate types are `$_NOT_`, `$_AND_`, `$_OR_`,
`$_XOR_`, and `$_MUX_` with an assortment of dff memory types.
:ref:`mycells-lib` defines our target cells as ``BUF``, ``NOT``, ``NAND``,
``NOR``, and ``DFF``.  Mapping between these is performed with the commands
`dfflibmap` and `abc` as follows:

.. literalinclude:: /code_examples/intro/counter.ys
   :language: yoscrypt
   :lines: 20-27
   :lineno-match:
   :caption: :file:`counter.ys` - mapping to hardware

The final version of our ``counter`` module looks like this:

.. figure:: /_images/code_examples/intro/counter_03.*
   :class: width-helper invert-helper

   ``counter`` after hardware cell mapping

Before finally being output as a verilog file with `write_verilog`, which can
then be loaded into another tool:

.. literalinclude:: /code_examples/intro/counter.ys
   :language: yoscrypt
   :lines: 30-31
   :lineno-match:
   :caption: :file:`counter.ys` - write synthesized design

---

### Source Using Yosys Synthesis Extract (`docs/source/using_yosys/synthesis/extract.rst`)

The extract pass
----------------

- Like the `techmap` pass, the `extract` pass is called with a map file. It
  compares the circuits inside the modules of the map file with the design and
  looks for sub-circuits in the design that match any of the modules in the map
  file.
- If a match is found, the `extract` pass will replace the matching subcircuit
  with an instance of the module from the map file.
- In a way the `extract` pass is the inverse of the techmap pass.

.. todo:: add/expand supporting text, also mention custom pattern matching and
   pmgen

Example code can be found in |code_examples/macc|_.

.. |code_examples/macc| replace:: :file:`docs/source/code_examples/macc`
.. _code_examples/macc: https://github.com/YosysHQ/yosys/tree/main/docs/source/code_examples/macc


.. literalinclude:: /code_examples/macc/macc_simple_test.ys
    :language: yoscrypt
    :lines: 1-2

.. figure:: /_images/code_examples/macc/macc_simple_test_00a.*
    :class: width-helper invert-helper

    before `extract`

.. literalinclude:: /code_examples/macc/macc_simple_test.ys
    :language: yoscrypt
    :lines: 6

.. figure:: /_images/code_examples/macc/macc_simple_test_00b.*
    :class: width-helper invert-helper

    after `extract`

.. literalinclude:: /code_examples/macc/macc_simple_test.v
   :language: verilog
   :caption: :file:`macc_simple_test.v`

.. literalinclude:: /code_examples/macc/macc_simple_xmap.v
   :language: verilog
   :caption: :file:`macc_simple_xmap.v`

.. literalinclude:: /code_examples/macc/macc_simple_test_01.v
   :language: verilog
   :caption: :file:`macc_simple_test_01.v`

.. figure:: /_images/code_examples/macc/macc_simple_test_01a.*
    :class: width-helper invert-helper

.. figure:: /_images/code_examples/macc/macc_simple_test_01b.*
    :class: width-helper invert-helper

.. literalinclude:: /code_examples/macc/macc_simple_test_02.v
   :language: verilog
   :caption: :file:`macc_simple_test_02.v`

.. figure:: /_images/code_examples/macc/macc_simple_test_02a.*
    :class: width-helper invert-helper

.. figure:: /_images/code_examples/macc/macc_simple_test_02b.*
    :class: width-helper invert-helper

The wrap-extract-unwrap method

Often a coarse-grain element has a constant bit-width, but can be used to
implement operations with a smaller bit-width. For example, a 18x25-bit
multiplier can also be used to implement 16x20-bit multiplication.

A way of mapping such elements in coarse grain synthesis is the
wrap-extract-unwrap method:

wrap
Identify candidate-cells in the circuit and wrap them in a cell with a
constant wider bit-width using techmap. The wrappers use the same parameters
as the original cell, so the information about the original width of the ports
is preserved. Then use the connwrappers command to connect up the
bit-extended in- and outputs of the wrapper cells.

extract
Now all operations are encoded using the same bit-width as the coarse grain
element. The extract command can be used to replace circuits with cells of
the target architecture.

unwrap
The remaining wrapper cell can be unwrapped using techmap.

Example: DSP48_MACC

text
This section details an example that shows how to map MACC operations of
arbitrary size to MACC cells with a 18x25-bit multiplier and a 48-bit adder
(such as the Xilinx DSP48 cells).

Preconditioning: :file:`macc_xilinx_swap_map.v`

Make sure ``A`` is the smaller port on all multipliers

.. todo:: add/expand supporting text

.. literalinclude:: /code_examples/macc/macc_xilinx_swap_map.v
   :language: verilog
   :caption: :file:`macc_xilinx_swap_map.v`

Wrapping multipliers: :file:`macc_xilinx_wrap_map.v`

.. literalinclude:: /code_examples/macc/macc_xilinx_wrap_map.v
   :language: verilog
   :lines: 1-46
   :caption: :file:`macc_xilinx_wrap_map.v`

Wrapping adders: :file:`macc_xilinx_wrap_map.v`

.. literalinclude:: /code_examples/macc/macc_xilinx_wrap_map.v
   :language: verilog
   :lines: 48-89
   :caption: :file:`macc_xilinx_wrap_map.v`

Extract: :file:`macc_xilinx_xmap.v`

.. literalinclude:: /code_examples/macc/macc_xilinx_xmap.v
   :language: verilog
   :caption: :file:`macc_xilinx_xmap.v`

... simply use the same wrapping commands on this module as on the design to
create a template for the `extract` command.

Unwrapping multipliers: :file:`macc_xilinx_unwrap_map.v`

.. literalinclude:: /code_examples/macc/macc_xilinx_unwrap_map.v
   :language: verilog
   :lines: 1-30
   :caption: ``$__mul_wrapper`` module in :file:`macc_xilinx_unwrap_map.v`

Unwrapping adders: :file:`macc_xilinx_unwrap_map.v`

.. literalinclude:: /code_examples/macc/macc_xilinx_unwrap_map.v
   :language: verilog
   :lines: 32-61
   :caption: ``$__add_wrapper`` module in :file:`macc_xilinx_unwrap_map.v`

.. literalinclude:: /code_examples/macc/macc_xilinx_test.v
   :language: verilog
   :lines: 1-6
   :caption: ``test1`` of :file:`macc_xilinx_test.v`

.. figure:: /_images/code_examples/macc/macc_xilinx_test1a.*
    :class: width-helper invert-helper

.. figure:: /_images/code_examples/macc/macc_xilinx_test1b.*
    :class: width-helper invert-helper

.. literalinclude:: /code_examples/macc/macc_xilinx_test.v
   :language: verilog
   :lines: 8-13
   :caption: ``test2`` of :file:`macc_xilinx_test.v`

.. figure:: /_images/code_examples/macc/macc_xilinx_test2a.*
    :class: width-helper invert-helper

.. figure:: /_images/code_examples/macc/macc_xilinx_test2b.*
    :class: width-helper invert-helper

Wrapping in ``test1``:

.. figure:: /_images/code_examples/macc/macc_xilinx_test1b.*
    :class: width-helper invert-helper

.. literalinclude:: /code_examples/macc/macc_xilinx_test.ys
    :language: yoscrypt
    :start-after: part c
    :end-before: end part c

.. figure:: /_images/code_examples/macc/macc_xilinx_test1c.*
    :class: width-helper invert-helper

Wrapping in ``test2``:

.. figure:: /_images/code_examples/macc/macc_xilinx_test2b.*
    :class: width-helper invert-helper

.. literalinclude:: /code_examples/macc/macc_xilinx_test.ys
    :language: yoscrypt
    :start-after: part c
    :end-before: end part c

.. figure:: /_images/code_examples/macc/macc_xilinx_test2c.*
    :class: width-helper invert-helper

Extract in ``test1``:

.. figure:: /_images/code_examples/macc/macc_xilinx_test1c.*
    :class: width-helper invert-helper

.. literalinclude:: /code_examples/macc/macc_xilinx_test.ys
    :language: yoscrypt
    :start-after: part d
    :end-before: end part d

.. figure:: /_images/code_examples/macc/macc_xilinx_test1d.*
    :class: width-helper invert-helper

Extract in ``test2``:

.. figure:: /_images/code_examples/macc/macc_xilinx_test2c.*
    :class: width-helper invert-helper

.. literalinclude:: /code_examples/macc/macc_xilinx_test.ys
    :language: yoscrypt
    :start-after: part d
    :end-before: end part d

.. figure:: /_images/code_examples/macc/macc_xilinx_test2d.*
    :class: width-helper invert-helper

Unwrap in ``test2``:

.. figure:: /_images/code_examples/macc/macc_xilinx_test2d.*
    :class: width-helper invert-helper

.. literalinclude:: /code_examples/macc/macc_xilinx_test.ys
    :language: yoscrypt
    :start-after: part e
    :end-before: end part e

.. figure:: /_images/code_examples/macc/macc_xilinx_test2e.*
    :class: width-helper invert-helper

---

### Source Using Yosys Synthesis Fsm (`docs/source/using_yosys/synthesis/fsm.rst`)

FSM handling
============

The `fsm` command identifies, extracts, optimizes (re-encodes), and
re-synthesizes finite state machines. It again is a macro that calls a series of
other commands:

.. literalinclude:: /code_examples/macro_commands/fsm.ys
   :language: yoscrypt
   :start-after: #end:
   :caption: Passes called by `fsm`

See also :doc:`/cmd/index_passes_fsm`.

The algorithms used for FSM detection and extraction are influenced by a more
general reported technique :cite:p:`fsmextract`.

FSM detection
~~~~~~~~~~~~~

The `fsm_detect` pass identifies FSM state registers. It sets the
``fsm_encoding = "auto"`` attribute on any (multi-bit) wire that matches the
following description:

-  Does not already have the ``fsm_encoding`` attribute.
-  Is not an output of the containing module.
-  Is driven by single `$dff` or `$adff` cell.
-  The ``D``-Input of this `$dff` or `$adff` cell is driven by a multiplexer
   tree that only has constants or the old state value on its leaves.
-  The state value is only used in the said multiplexer tree or by simple
   relational cells that compare the state value to a constant (usually `$eq`
   cells).

This heuristic has proven to work very well. It is possible to overwrite it by
setting ``fsm_encoding = "auto"`` on registers that should be considered FSM
state registers and setting ``fsm_encoding = "none"`` on registers that match
the above criteria but should not be considered FSM state registers.

Note however that marking state registers with ``fsm_encoding`` that are not
suitable for FSM recoding can cause synthesis to fail or produce invalid
results.

FSM extraction
~~~~~~~~~~~~~~

The `fsm_extract` pass operates on all state signals marked with the
(``fsm_encoding != "none"``) attribute. For each state signal the following
information is determined:

-  The state registers

-  The asynchronous reset state if the state registers use asynchronous reset

-  All states and the control input signals used in the state transition
   functions

-  The control output signals calculated from the state signals and control
   inputs

-  A table of all state transitions and corresponding control inputs- and
   outputs

The state registers (and asynchronous reset state, if applicable) is simply
determined by identifying the driver for the state signal.

From there the `$mux`\ -tree driving the state register inputs is recursively
traversed. All select inputs are control signals and the leaves of the `$mux`\
-tree are the states. The algorithm fails if a non-constant leaf that is not the
state signal itself is found.

The list of control outputs is initialized with the bits from the state signal.
It is then extended by adding all values that are calculated by cells that
compare the state signal with a constant value.

In most cases this will cover all uses of the state register, thus rendering the
state encoding arbitrary. If however a design uses e.g. a single bit of the
state value to drive a control output directly, this bit of the state signal
will be transformed to a control output of the same value.

Finally, a transition table for the FSM is generated. This is done by using the
ConstEval C++ helper class (defined in kernel/consteval.h) that can be used to
evaluate parts of the design. The ConstEval class can be asked to calculate a
given set of result signals using a set of signal-value assignments. It can also
be passed a list of stop-signals that abort the ConstEval algorithm if the value
of a stop-signal is needed in order to calculate the result signals.

The `fsm_extract` pass uses the ConstEval class in the following way to create a
transition table. For each state:

1. Create a ConstEval object for the module containing the FSM
2. Add all control inputs to the list of stop signals
3. Set the state signal to the current state
4. Try to evaluate the next state and control output
5. If step 4 was not successful:

   -  Recursively goto step 4 with the offending stop-signal set to 0.
   -  Recursively goto step 4 with the offending stop-signal set to 1.

6. If step 4 was successful: Emit transition

Finally a `$fsm` cell is created with the generated transition table and added
to the module. This new cell is connected to the control signals and the old
drivers for the control outputs are disconnected.

FSM optimization
~~~~~~~~~~~~~~~~

The `fsm_opt` pass performs basic optimizations on `$fsm` cells (not including
state recoding). The following optimizations are performed (in this order):

-  Unused control outputs are removed from the `$fsm` cell.

-  Control inputs that are connected to the same driver are merged.

-  When a control input is driven by a control output, the control input is
   removed and the transition table altered to give the same performance without
   the external feedback path.

-  Entries in the transition table that yield the same output and only differ in
   the value of a single control input bit are merged and the different bit is
   removed from the sensitivity list (turned into a don't-care bit).

-  Constant inputs are removed and the transition table is altered to give an
   unchanged behaviour.

-  Unused inputs are removed.

FSM recoding
~~~~~~~~~~~~

The `fsm_recode` pass assigns new bit pattern to the states. Usually this also
implies a change in the width of the state signal. At the moment of this writing
only one-hot encoding with all-zero for the reset state is supported.

The `fsm_recode` pass can also write a text file with the changes performed by
it that can be used when verifying designs synthesized by Yosys using Synopsys
Formality.

---

### Source Using Yosys Synthesis Index (`docs/source/using_yosys/synthesis/index.rst`)

Synthesis in detail
-------------------

Synthesis can generally be broken down into coarse-grain synthesis, and
fine-grain synthesis.  We saw this in :doc:`/getting_started/example_synth`
where a design was loaded and elaborated and then went through a series of
coarse-grain optimizations before being mapped to hard blocks and fine-grain
cells.  Most commands in Yosys will target either coarse-grain representation or
fine-grain representation, with only a select few compatible with both states.

Commands such as `proc`, `fsm`, and `memory` rely on the additional information
in the coarse-grain representation, along with a number of optimizations such as
`wreduce`, `share`, and `alumacc`.  `opt` provides optimizations which are
useful in both states, while `techmap` is used to convert coarse-grain cells to
the corresponding fine-grain representation.

Single-bit cells (logic gates, FFs) as well as LUTs, half-adders, and
full-adders make up the bulk of the fine-grain representation and are necessary
for commands such as `abc`\ /`abc9`, `simplemap`, `dfflegalize`, and
`memory_map`.

.. toctree::
   :maxdepth: 3

   synth
   proc
   fsm
   memory
   opt
   techmap_synth
   extract
   abc
   cell_libs

---

### Source Using Yosys Synthesis Memory (`docs/source/using_yosys/synthesis/memory.rst`)

Memory handling
===============

The `memory` command
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

In the RTL netlist, memory reads and writes are individual cells. This makes
consolidating the number of ports for a memory easier. The `memory` pass
transforms memories to an implementation. Per default that is logic for address
decoders and registers. It also is a macro command that calls the other common
``memory_*`` passes in a sensible order:

.. literalinclude:: /code_examples/macro_commands/memory.ys
   :language: yoscrypt
   :start-after: #end:
   :caption: Passes called by `memory`

.. todo:: Make ``memory_*`` notes less quick

Some quick notes:

-  `memory_dff` merges registers into the memory read- and write cells.
-  `memory_collect` collects all read and write cells for a memory and
   transforms them into one multi-port memory cell.
-  `memory_map` takes the multi-port memory cell and transforms it to address
   decoder logic and registers.

For more information about `memory`, such as disabling certain sub commands, see
:doc:`/cmd/index_passes_memory`.

Example
-------

.. todo:: describe ``memory`` images

|code_examples/synth_flow|_.

.. |code_examples/synth_flow| replace:: :file:`docs/source/code_examples/synth_flow`
.. _code_examples/synth_flow: https://github.com/YosysHQ/yosys/tree/main/docs/source/code_examples/synth_flow

.. figure:: /_images/code_examples/synth_flow/memory_01.*
   :class: width-helper invert-helper

.. literalinclude:: /code_examples/synth_flow/memory_01.ys
   :language: yoscrypt
   :caption: :file:`memory_01.ys`

.. literalinclude:: /code_examples/synth_flow/memory_01.v
   :language: verilog
   :caption: :file:`memory_01.v`

.. figure:: /_images/code_examples/synth_flow/memory_02.*
   :class: width-helper invert-helper

.. literalinclude:: /code_examples/synth_flow/memory_02.v
   :language: verilog
   :caption: :file:`memory_02.v`

.. literalinclude:: /code_examples/synth_flow/memory_02.ys
   :language: yoscrypt
   :caption: :file:`memory_02.ys`

.. _memory_map:

Memory mapping
^^^^^^^^^^^^^^

Usually it is preferred to use architecture-specific RAM resources for memory.
For example:

.. code-block:: yoscrypt

    memory -nomap
    memory_libmap -lib my_memory_map.txt
    techmap -map my_memory_map.v
    memory_map

`memory_libmap` attempts to convert memory cells (`$mem_v2` etc) into hardware
supported memory using a provided library (:file:`my_memory_map.txt` in the
example above).  Where necessary, emulation logic is added to ensure functional
equivalence before and after this conversion. :yoscrypt:`techmap -map
my_memory_map.v` then uses `techmap` to map to hardware primitives. Any leftover
memory cells unable to be converted are then picked up by `memory_map` and
mapped to DFFs and address decoders.

.. note::

   More information about what mapping options are available and associated
   costs of each can be found by enabling debug outputs.  This can be done with
   the `debug` command, or by using the ``-g`` flag when calling Yosys to
   globally enable debug messages.

For more on the lib format for `memory_libmap`, see
`passes/memory/memlib.md
<https://github.com/YosysHQ/yosys/blob/main/passes/memory/memlib.md>`_

Supported memory patterns
^^^^^^^^^^^^^^^^^^^^^^^^^

Note that not all supported patterns are included in this document, of
particular note is that combinations of multiple patterns should generally work.
For example, `wbe`_ could be used in conjunction with any of the simple dual
port (SDP) models.  In general if a hardware memory definition does not support
a given configuration, additional logic will be instantiated to guarantee
behaviour is consistent with simulation.

Notes
-----

Memory kind selection

The memory inference code will automatically pick target memory primitive based
on memory geometry and features used. Depending on the target, there can be up
to four memory primitive classes available for selection:

  • FF RAM (aka logic): no hardware primitive used, memory lowered to a bunch of
    FFs and multiplexers

    • Can handle arbitrary number of write ports, as long as all write ports are
      in the same clock domain
    • Can handle arbitrary number and kind of read ports
  • LUT RAM (aka distributed RAM): uses LUT storage as RAM

    • Supported on most FPGAs (with notable exception of ice40)
    • Usually has one synchronous write port, one or more asynchronous read ports
    • Small
    • Will never be used for ROMs (lowering to plain LUTs is always better)
  • Block RAM: dedicated memory tiles

    • Supported on basically all FPGAs
    • Supports only synchronous reads
    • Two ports with separate clocks
    • Usually supports true dual port (with notable exception of ice40 that only
      supports SDP)
    • Usually supports asymmetric memories and per-byte write enables
    • Several kilobits in size
  • Huge RAM:

    • Only supported on several targets:

      • Some Xilinx UltraScale devices (UltraRAM)

        • Two ports, both with mutually exclusive synchronous read and write
        • Single clock
        • Initial data must be all-0
      • Some ice40 devices (SPRAM)

        • Single port with mutually exclusive synchronous read and write
        • Does not support initial data
      • Nexus (large RAM)

        • Two ports, both with mutually exclusive synchronous read and write
        • Single clock
    • Will not be automatically selected by memory inference code, needs explicit
      opt-in via ram_style attribute

In general, you can expect the automatic selection process to work roughly like
this:

  • If any read port is asynchronous, only LUT RAM (or FF RAM) can be used.

  • If there is more than one write port, only block RAM can be used, and this
    needs to be a hardware-supported true dual port pattern

    • โ€ฆ unless all write ports are in the same clock domain, in which case FF RAM
      can also be used, but this is generally not what you want for anything but
      really small memories
  • Otherwise, either FF RAM, LUT RAM, or block RAM will be used, depending on
    memory size

This process can be overridden by attaching a ram_style attribute to the memory:

  • (* ram_style = "logic" *) selects FF RAM
  • (* ram_style = "distributed" *) selects LUT RAM
  • (* ram_style = "block" *) selects block RAM
  • (* ram_style = "huge" *) selects huge RAM

It is an error if this override cannot be realized for the given target.

Many alternate spellings of the attribute are also accepted, for compatibility
with other software.

Initial data

text
Most FPGA targets support initializing all kinds of memory to user-provided
values.  If explicit initialization is not used the initial memory value is
undefined.  Initial data can be provided by either initial statements writing
memory cells one by one of ``$readmemh`` or ``$readmemb`` system tasks.  For an
example pattern, see `sr_init`_.

.. _wbe:

Write port with byte enables
  • Byte enables can be used with any supported pattern
  • To ensure that multiple writes will be merged into one port, they need to have
    disjoint bit ranges, have the same address, and the same clock
  • Any write enable granularity will be accepted (down to per-bit write enables),
    but using smaller granularity than natively supported by the target is very
    likely to be inefficient (eg. using 4-bit bytes on ECP5 will result in either
    padding the bytes with 5 dummy bits to native 9-bit units or splitting the RAM
    into two block RAMs)

.. code:: verilog

text
reg [31 : 0] mem [2**ADDR_WIDTH - 1 : 0];

always @(posedge clk) begin
	if (write_enable[0])
		mem[write_addr][7:0] <= write_data[7:0];
	if (write_enable[1])
		mem[write_addr][15:8] <= write_data[15:8];
	if (write_enable[2])
		mem[write_addr][23:16] <= write_data[23:16];
	if (write_enable[3])
		mem[write_addr][31:24] <= write_data[31:24];
	if (read_enable)
		read_data <= mem[read_addr];
end

Simple dual port (SDP) memory patterns

.. todo:: assorted enables, e.g. cen, wen+ren

Asynchronous-read SDP

text
- This will result in LUT RAM on supported targets

.. code:: verilog

	reg [DATA_WIDTH - 1 : 0] mem [2**ADDR_WIDTH - 1 : 0];
	always @(posedge clk)
		if (write_enable)
			mem[write_addr] <= write_data;
	assign read_data = mem[read_addr];

Synchronous SDP with clock domain crossing
  • Will result in block RAM or LUT RAM depending on size
  • No behavior guarantees in case of simultaneous read and write to the same
    address

.. code:: verilog

text
reg [DATA_WIDTH - 1 : 0] mem [2**ADDR_WIDTH - 1 : 0];

always @(posedge write_clk) begin
	if (write_enable)
		mem[write_addr] <= write_data;
end

always @(posedge read_clk) begin
	if (read_enable)
		read_data <= mem[read_addr];
end

Synchronous SDP read first

text
- The read and write parts can be in the same or different processes.
- Will result in block RAM or LUT RAM depending on size
- As long as the same clock is used for both, yosys will ensure read-first
  behavior.  This may require extra circuitry on some targets for block RAM.  If
  this is not necessary, use one of the patterns below.

.. code:: verilog

	reg [DATA_WIDTH - 1 : 0] mem [2**ADDR_WIDTH - 1 : 0];

	always @(posedge clk) begin
		if (write_enable)
			mem[write_addr] <= write_data;
		if (read_enable)
			read_data <= mem[read_addr];
	end

.. _no_rw_check:

Synchronous SDP with undefined collision behavior
  • Like above, but the read value is undefined when read and write ports target
    the same address in the same cycle

.. code:: verilog

text
reg [DATA_WIDTH - 1 : 0] mem [2**ADDR_WIDTH - 1 : 0];

always @(posedge clk) begin
	if (write_enable)
		mem[write_addr] <= write_data;

	if (read_enable) begin
		read_data <= mem[read_addr];

	if (write_enable && read_addr == write_addr)
		// this if block
		read_data <= 'x;
	end
end
  • Or below, using the no_rw_check attribute

.. code:: verilog

text
(* no_rw_check *)
reg [DATA_WIDTH - 1 : 0] mem [2**ADDR_WIDTH - 1 : 0];

always @(posedge clk) begin
	if (write_enable)
		mem[write_addr] <= write_data;

	if (read_enable)
		read_data <= mem[read_addr];
end

.. _sdp_wf:

Synchronous SDP with write-first behavior

text
- Will result in block RAM or LUT RAM depending on size
- May use additional circuitry for block RAM if write-first is not natively
  supported. Will always use additional circuitry for LUT RAM.

.. code:: verilog

	reg [DATA_WIDTH - 1 : 0] mem [2**ADDR_WIDTH - 1 : 0];

	always @(posedge clk) begin
		if (write_enable)
			mem[write_addr] <= write_data;

		if (read_enable) begin
			read_data <= mem[read_addr];
			if (write_enable && read_addr == write_addr)
				read_data <= write_data;
		end
	end

Synchronous SDP with write-first behavior (alternate pattern)
  • This pattern is supported for compatibility, but is much less flexible than
    the above

.. code:: verilog

text
reg [ADDR_WIDTH - 1 : 0] read_addr_reg;
reg [DATA_WIDTH - 1 : 0] mem [2**ADDR_WIDTH - 1 : 0];

always @(posedge clk) begin
	if (write_enable)
		mem[write_addr] <= write_data;
	read_addr_reg <= read_addr;
end

assign read_data = mem[read_addr_reg];

Single-port RAM memory patterns

Asynchronous-read single-port RAM

text
- Will result in single-port LUT RAM on supported targets

.. code:: verilog

	reg [DATA_WIDTH - 1 : 0] mem [2**ADDR_WIDTH - 1 : 0];
	always @(posedge clk)
		if (write_enable)
			mem[addr] <= write_data;
	assign read_data = mem[addr];

Synchronous single-port RAM with mutually exclusive read/write
  • Will result in single-port block RAM or LUT RAM depending on size
  • This is the correct pattern to infer ice40 SPRAM (with manual ram_style
    selection)
  • On targets that don't support read/write block RAM ports (eg. ice40), will
    result in SDP block RAM instead
  • For block RAM, will use "NO_CHANGE" mode if available

.. code:: verilog

text
reg [DATA_WIDTH - 1 : 0] mem [2**ADDR_WIDTH - 1 : 0];

always @(posedge clk) begin
	if (write_enable)
		mem[addr] <= write_data;
	else if (read_enable)
		read_data <= mem[addr];
end

Synchronous single-port RAM with read-first behavior

text
- Will only result in single-port block RAM when read-first behavior is natively
  supported; otherwise, SDP RAM with additional circuitry will be used
- Many targets (Xilinx, ECP5, โ€ฆ) can only natively support
  read-first/write-first single-port RAM (or TDP RAM) where the write_enable
  signal implies the read_enable signal (ie. can never write without reading).
  The memory inference code will run a simple SAT solver on the control signals
  to determine if this is the case, and insert emulation circuitry if it cannot
  be easily proven.

.. code:: verilog

	reg [DATA_WIDTH - 1 : 0] mem [2**ADDR_WIDTH - 1 : 0];

	always @(posedge clk) begin
		if (write_enable)
			mem[addr] <= write_data;
		if (read_enable)
			read_data <= mem[addr];
	end

Synchronous single-port RAM with write-first behavior
  • Will result in single-port block RAM or LUT RAM when supported
  • Block RAMs will require extra circuitry if write-first behavior not natively
    supported

.. code:: verilog

text
reg [DATA_WIDTH - 1 : 0] mem [2**ADDR_WIDTH - 1 : 0];

always @(posedge clk) begin
	if (write_enable)
		mem[addr] <= write_data;
	if (read_enable)
		if (write_enable)
			read_data <= write_data;
		else
			read_data <= mem[addr];
end

.. _sr_init:

Synchronous read port with initial value

text
- Initial read port values can be combined with any other supported pattern
- If block RAM is used and initial read port values are not natively supported
  by the target, small emulation circuit will be inserted

.. code:: verilog

	reg [DATA_WIDTH - 1 : 0] mem [2**ADDR_WIDTH - 1 : 0];
	reg [DATA_WIDTH - 1 : 0] read_data;
	initial read_data = 'h1234;

	always @(posedge clk) begin
		if (write_enable)
			mem[write_addr] <= write_data;
		if (read_enable)
			read_data <= mem[read_addr];
	end

Read register reset patterns
----------------------------

Resets can be combined with any other supported pattern (except that synchronous
reset and asynchronous reset cannot both be used on a single read port).  If
block RAM is used and the selected reset (synchronous or asynchronous) is used
but not natively supported by the target, small emulation circuitry will be
inserted.

Synchronous reset, reset priority over enable

.. code:: verilog

text
reg [DATA_WIDTH - 1 : 0] mem [2**ADDR_WIDTH - 1 : 0];

always @(posedge clk) begin
	if (write_enable)
		mem[write_addr] <= write_data;

	if (read_reset)
		read_data <= 'h1234;
	else if (read_enable)
		read_data <= mem[read_addr];
end

Synchronous reset, enable priority over reset

text
.. code:: verilog

	reg [DATA_WIDTH - 1 : 0] mem [2**ADDR_WIDTH - 1 : 0];

	always @(posedge clk) begin
		if (write_enable)
			mem[write_addr] <= write_data;
		if (read_enable)
			if (read_reset)
				read_data <= 'h1234;
			else
				read_data <= mem[read_addr];
	end

Synchronous read port with asynchronous reset

.. code:: verilog

text
reg [DATA_WIDTH - 1 : 0] mem [2**ADDR_WIDTH - 1 : 0];

always @(posedge clk) begin
	if (write_enable)
		mem[write_addr] <= write_data;
end

always @(posedge clk, posedge read_reset) begin
	if (read_reset)
		read_data <= 'h1234;
	else if (read_enable)
		read_data <= mem[read_addr];
end

Asymmetric memory patterns

To construct an asymmetric memory (memory with read/write ports of differing
widths):

  • Declare the memory with the width of the narrowest intended port

  • Split all wide ports into multiple narrow ports

  • To ensure the wide ports will be correctly merged:

    • For the address, use a concatenation of actual address in the high bits and
      a constant in the low bits
    • Ensure the actual address is identical for all ports belonging to the wide
      port
    • Ensure that clock is identical
    • For read ports, ensure that enable/reset signals are identical (for write
      ports, the enable signal may vary โ€” this will result in using the byte
      enable functionality)

Asymmetric memory is supported on all targets, but may require emulation
circuitry where not natively supported. Note that when the memory is larger
than the underlying block RAM primitive, hardware asymmetric memory support is
likely not to be used even if present as it is more expensive.

.. _wide_sr:

Wide synchronous read port

text
.. code:: verilog

	reg [7:0] mem [0:255];
	wire [7:0] write_addr;
	wire [5:0] read_addr;
	wire [7:0] write_data;
	reg [31:0] read_data;

	always @(posedge clk) begin
		if (write_enable)
			mem[write_addr] <= write_data;
		if (read_enable) begin
			read_data[7:0] <= mem[{read_addr, 2'b00}];
			read_data[15:8] <= mem[{read_addr, 2'b01}];
			read_data[23:16] <= mem[{read_addr, 2'b10}];
			read_data[31:24] <= mem[{read_addr, 2'b11}];
		end
	end

Wide asynchronous read port
  • Note: the only target natively supporting this pattern is Xilinx UltraScale

.. code:: verilog

text
reg [7:0] mem [0:511];
wire [8:0] write_addr;
wire [5:0] read_addr;
wire [7:0] write_data;
wire [63:0] read_data;

always @(posedge clk) begin
	if (write_enable)
		mem[write_addr] <= write_data;
end

assign read_data[7:0] = mem[{read_addr, 3'b000}];
assign read_data[15:8] = mem[{read_addr, 3'b001}];
assign read_data[23:16] = mem[{read_addr, 3'b010}];
assign read_data[31:24] = mem[{read_addr, 3'b011}];
assign read_data[39:32] = mem[{read_addr, 3'b100}];
assign read_data[47:40] = mem[{read_addr, 3'b101}];
assign read_data[55:48] = mem[{read_addr, 3'b110}];
assign read_data[63:56] = mem[{read_addr, 3'b111}];

Wide write port

text
.. code:: verilog

	reg [7:0] mem [0:255];
	wire [5:0] write_addr;
	wire [7:0] read_addr;
	wire [31:0] write_data;
	reg [7:0] read_data;

	always @(posedge clk) begin
		if (write_enable[0])
			mem[{write_addr, 2'b00}] <= write_data[7:0];
		if (write_enable[1])
			mem[{write_addr, 2'b01}] <= write_data[15:8];
		if (write_enable[2])
			mem[{write_addr, 2'b10}] <= write_data[23:16];
		if (write_enable[3])
			mem[{write_addr, 2'b11}] <= write_data[31:24];
		if (read_enable)
			read_data <= mem[read_addr];
	end

True dual port (TDP) patterns
-----------------------------

- Many different variations of true dual port memory can be created by combining
  two single-port RAM patterns on the same memory
- When TDP memory is used, memory inference code has much less maneuver room to
  create requested semantics compared to individual single-port patterns (which
  can end up lowered to SDP memory where necessary) โ€” supported patterns depend
  strongly on the target
- In particular, when both ports have the same clock, it's likely that
  "undefined collision" mode needs to be manually selected to enable TDP memory
  inference
- The examples below are non-exhaustive โ€” many more combinations of port types
  are possible
- Note: if two write ports are in the same process, this defines a priority
  relation between them (if both ports are active in the same clock, the later
  one wins). On almost all targets, this will result in a bit of extra circuitry
  to ensure the priority semantics. If this is not what you want, put them in
  separate processes.

  - Priority is not supported when using the verific front end and any priority
    semantics are ignored.

TDP with different clocks, exclusive read/write

.. code:: verilog

text
reg [DATA_WIDTH - 1 : 0] mem [2**ADDR_WIDTH - 1 : 0];

always @(posedge clk_a) begin
	if (write_enable_a)
		mem[addr_a] <= write_data_a;
	else if (read_enable_a)
		read_data_a <= mem[addr_a];
end

always @(posedge clk_b) begin
	if (write_enable_b)
		mem[addr_b] <= write_data_b;
	else if (read_enable_b)
		read_data_b <= mem[addr_b];
end

TDP with same clock, read-first behavior

text
- This requires hardware inter-port read-first behavior, and will only work on
  some targets (Xilinx, Nexus)

.. code:: verilog

	reg [DATA_WIDTH - 1 : 0] mem [2**ADDR_WIDTH - 1 : 0];

	always @(posedge clk) begin
		if (write_enable_a)
			mem[addr_a] <= write_data_a;
		if (read_enable_a)
			read_data_a <= mem[addr_a];
	end

	always @(posedge clk) begin
		if (write_enable_b)
			mem[addr_b] <= write_data_b;
		if (read_enable_b)
			read_data_b <= mem[addr_b];
	end

TDP with multiple read ports
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

- The combination of a single write port with an arbitrary amount of read ports
  is supported on all targets โ€” if a multi-read port primitive is available
  (like Xilinx RAM64M), it'll be used as appropriate.  Otherwise, the memory
  will be automatically split into multiple primitives.

.. code:: verilog

	reg [31:0] mem [0:31];

	always @(posedge clk) begin
		if (write_enable)
			mem[write_addr] <= write_data;
	end

	assign read_data_a = mem[read_addr_a];
	assign read_data_b = mem[read_addr_b];
	assign read_data_c = mem[read_addr_c];

Patterns only supported with Verific
------------------------------------

The following patterns are only supported when the design is read in using the
Verific front-end.

Synchronous SDP with write-first behavior via blocking assignments
  • Use sdp_wf_ for compatibility with Yosys
    Verilog frontend.

.. code:: verilog

text
reg [DATA_WIDTH - 1 : 0] mem [2**ADDR_WIDTH - 1 : 0];

always @(posedge clk) begin
	if (write_enable)
		mem[write_addr] = write_data;

	if (read_enable)
		read_data <= mem[read_addr];
end

Asymmetric memories via part selection

text
- Build wide ports out of narrow ports instead (see `wide_sr`_) for
  compatibility with Yosys Verilog frontend.

.. code:: verilog

	reg [31:0] mem [2**ADDR_WIDTH - 1 : 0];

	wire [1:0] byte_lane;
	wire [7:0] write_data;

	always @(posedge clk) begin
		if (write_enable)
			mem[write_addr][byte_lane * 8 +: 8] <= write_data;

		if (read_enable)
			read_data <= mem[read_addr];
	end


Undesired patterns
------------------

Asynchronous writes
~~~~~~~~~~~~~~~~~~~

- Not supported in modern FPGAs
- Not supported in yosys code anyhow

.. code:: verilog

	reg [DATA_WIDTH - 1 : 0] mem [2**ADDR_WIDTH - 1 : 0];

	always @* begin
		if (write_enable)
			mem[write_addr] = write_data;
	end

	assign read_data = mem[read_addr];

---

### Source Using Yosys Synthesis Opt (`docs/source/using_yosys/synthesis/opt.rst`)

Optimization passes
===================

Yosys employs a number of optimizations to generate better and cleaner results.
This chapter outlines these optimizations.

.. todo:: "outlines these optimizations" or "outlines *some*.."?

The `opt` macro command
--------------------------------

The Yosys pass `opt` runs a number of simple optimizations. This includes
removing unused signals and cells and const folding. It is recommended to run
this pass after each major step in the synthesis script.  This macro command
calls the following ``opt_*`` commands:

.. literalinclude:: /code_examples/macro_commands/opt.ys
   :language: yoscrypt
   :start-after: #end:
   :caption: Passes called by `opt`

.. _adv_opt_expr:

Constant folding and simple expression rewriting - `opt_expr`

.. todo:: unsure if this is too much detail and should be in :doc:/yosys_internals/index

This pass performs constant folding on the internal combinational cell types
described in :doc:/cell_index. This means a cell with all
constant inputs is replaced with the constant value this cell drives. In some
cases this pass can also optimize cells with some constant inputs.

.. table:: Const folding rules for $_AND_ cells as used in opt_expr.
:name: tab:opt_expr_and
:align: center

========= ========= ===========
A-Input B-Input Replacement
========= ========= ===========
any 0 0
0 any 0
1 1 1


X/Z X/Z X
1 X/Z X
X/Z 1 X


any X/Z 0
X/Z any 0


:math:a 1 :math:a
1 :math:b :math:b
========= ========= ===========

:numref:Table %s <tab:opt_expr_and> shows the replacement rules used for
optimizing an $_AND_ gate. The first three rules implement the obvious const
folding rules. Note that 'any' might include dynamic values calculated by other
parts of the circuit. The following three lines propagate undef (X) states.
These are the only three cases in which it is allowed to propagate an undef
according to Sec. 5.1.10 of IEEE Std. 1364-2005 :cite:p:Verilog2005.

The next two lines assume the value 0 for undef states. These two rules are only
used if no other substitutions are possible in the current module. If other
substitutions are possible they are performed first, in the hope that the 'any'
will change to an undef value or a 1 and therefore the output can be set to
undef.

The last two lines simply replace an $_AND_ gate with one constant-1 input
with a buffer.

Besides this basic const folding the opt_expr pass can replace 1-bit wide
$eq and $ne cells with buffers or not-gates if one input is constant.
Equality checks may also be reduced in size if there are redundant bits in the
arguments (i.e. bits which are constant on both inputs). This can, for example,
result in a 32-bit wide constant like 255 being reduced to the 8-bit value
of 8'11111111 if the signal being compared is only 8-bit as in
:ref:addr_gen_clean of :doc:/getting_started/example_synth.

The opt_expr pass is very conservative regarding optimizing $mux cells, as
these cells are often used to model decision-trees and breaking these trees can
interfere with other optimizations.

.. literalinclude:: /code_examples/opt/opt_expr.ys
:language: Verilog
:start-after: read_verilog <<EOT
:end-before: EOT
:caption: example verilog for demonstrating opt_expr

.. figure:: /_images/code_examples/opt/opt_expr.*
:class: width-helper invert-helper

Before and after opt_expr

Merging identical cells - opt_merge

text
This pass performs trivial resource sharing. This means that this pass
identifies cells with identical inputs and replaces them with a single instance
of the cell.

The option ``-nomux`` can be used to disable resource sharing for multiplexer
cells (`$mux` and `$pmux`.) This can be useful as it prevents multiplexer trees
to be merged, which might prevent `opt_muxtree` to identify possible
optimizations.

.. literalinclude:: /code_examples/opt/opt_merge.ys
   :language: Verilog
   :start-after: read_verilog <<EOT
   :end-before: EOT
   :caption: example verilog for demonstrating `opt_merge`

.. figure:: /_images/code_examples/opt/opt_merge.*
   :class: width-helper invert-helper

   Before and after `opt_merge`

Removing never-active branches from multiplexer tree - `opt_muxtree`

This pass optimizes trees of multiplexer cells by analyzing the select inputs.
Consider the following simple example:

.. literalinclude:: /code_examples/opt/opt_muxtree.ys
:language: Verilog
:start-after: read_verilog <<EOT
:end-before: EOT
:caption: example verilog for demonstrating opt_muxtree

The output can never be c, as this would require a to be 1 for the outer
multiplexer and 0 for the inner multiplexer. The opt_muxtree pass detects this
contradiction and replaces the inner multiplexer with a constant 1, yielding the
logic for y = a ? b : d.

.. figure:: /_images/code_examples/opt/opt_muxtree.*
:class: width-helper invert-helper

Before and after opt_muxtree

Simplifying large MUXes and AND/OR gates - opt_reduce

text
This is a simple optimization pass that identifies and consolidates identical
input bits to `$reduce_and` and `$reduce_or` cells. It also sorts the input bits
to ease identification of shareable `$reduce_and` and `$reduce_or` cells in
other passes.

This pass also identifies and consolidates identical inputs to multiplexer
cells. In this case the new shared select bit is driven using a `$reduce_or`
cell that combines the original select bits.

Lastly this pass consolidates trees of `$reduce_and` cells and trees of
`$reduce_or` cells to single large `$reduce_and` or `$reduce_or` cells.

These three simple optimizations are performed in a loop until a stable result
is produced.

Merging mutually exclusive cells with shared inputs - `opt_share`

This pass identifies mutually exclusive cells of the same type that:
a. share an input signal, and
b. drive the same $mux, $_MUX_, or $pmux multiplexing cell,

allowing the cell to be merged and the multiplexer to be moved from multiplexing
its output to multiplexing the non-shared input signals.

.. literalinclude:: /code_examples/opt/opt_share.ys
:language: Verilog
:start-after: read_verilog <<EOT
:end-before: EOT
:caption: example verilog for demonstrating opt_share

.. figure:: /_images/code_examples/opt/opt_share.*
:class: width-helper invert-helper

Before and after opt_share

When running opt in full, the original $mux (labeled $3) is optimized
away by opt_expr.

Performing DFF optimizations - opt_dff

text
.. todo:: ``$_DFF_`` isn't a valid cell

This pass identifies single-bit d-type flip-flops (`$_DFF_`, `$dff`, and `$adff`
cells) with a constant data input and replaces them with a constant driver.  It
can also merge clock enables and synchronous reset multiplexers, removing unused
control inputs.

Called with ``-nodffe`` and ``-nosdff``, this pass is used to prepare a design
for :doc:`/using_yosys/synthesis/fsm`.

Hierarchical optimization - `opt_hier` pass

This pass considers the design hierarchy and propagates unused signals, constant
signals, and tied-together signals across module boundaries to facilitate
optimization by other passes.

Removing unused cells and wires - opt_clean pass

text
This pass identifies unused signals and cells and removes them from the design.

When to use `opt` or `clean`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Usually it does not hurt to call `opt` after each regular command in the
synthesis script. But it increases the synthesis time, so it is favourable to
only call `opt` when an improvement can be achieved.

It is generally a good idea to call `opt` before inherently expensive commands
such as `sat` or `freduce`, as the possible gain is much higher in these cases
as the possible loss.

The `clean` command, which is an alias for `opt_clean` with fewer outputs, on
the other hand is very fast and many commands leave a mess (dangling signal
wires, etc). For example, most commands do not remove any wires or cells. They
just change the connections and depend on a later call to clean to get rid of
the now unused objects. So the occasional ``;;``, which itself is an alias for
`clean`, is a good idea in every synthesis script, e.g:

.. code-block:: yoscrypt

   hierarchy; proc; opt; memory; opt_expr;; fsm;;

Other optimizations
-------------------

.. todo:: more on the other optimizations

- Check :doc:`/cmd/index_passes_opt` for more.
- `abc` and `abc9`, see also: :doc:`abc`.

---

### Source Using Yosys Synthesis Proc (`docs/source/using_yosys/synthesis/proc.rst`)

Converting process blocks
~~~~~~~~~~~~~~~~~~~~~~~~~

.. role:: yoscrypt(code)
   :language: yoscrypt

The Verilog frontend converts ``always``-blocks to RTL netlists for the
expressions and "processess" for the control- and memory elements. The `proc`
command then transforms these "processess" to netlists of RTL multiplexer and
register cells. It also is a macro command that calls the other ``proc_*``
commands in a sensible order:

.. literalinclude:: /code_examples/macro_commands/proc.ys
   :language: yoscrypt
   :start-after: #end:
   :caption: Passes called by `proc`

After all the ``proc_*`` commands, `opt_expr` is called. This can be disabled by
calling :yoscrypt:`proc -noopt`.  For more information about `proc`, such as
disabling certain sub commands, see :doc:`/cmd/index_passes_proc`.

Many commands can not operate on modules with "processess" in them. Usually a
call to `proc` is the first command in the actual synthesis procedure after
design elaboration.

Example
^^^^^^^

.. todo:: describe ``proc`` images

|code_examples/synth_flow|_.

.. |code_examples/synth_flow| replace:: :file:`docs/source/code_examples/synth_flow`
.. _code_examples/synth_flow: https://github.com/YosysHQ/yosys/tree/main/docs/source/code_examples/synth_flow

.. literalinclude:: /code_examples/synth_flow/proc_01.v
   :language: verilog
   :caption: :file:`proc_01.v`

.. literalinclude:: /code_examples/synth_flow/proc_01.ys
   :language: yoscrypt
   :caption: :file:`proc_01.ys`

.. figure:: /_images/code_examples/synth_flow/proc_01.*
   :class: width-helper invert-helper

.. figure:: /_images/code_examples/synth_flow/proc_02.*
   :class: width-helper invert-helper

.. literalinclude:: /code_examples/synth_flow/proc_02.v
   :language: verilog
   :caption: :file:`proc_02.v`

.. literalinclude:: /code_examples/synth_flow/proc_02.ys
   :language: yoscrypt
   :caption: :file:`proc_02.ys`

.. figure:: /_images/code_examples/synth_flow/proc_03.*
   :class: width-helper invert-helper

.. literalinclude:: /code_examples/synth_flow/proc_03.ys
   :language: yoscrypt
   :caption: :file:`proc_03.ys`

.. literalinclude:: /code_examples/synth_flow/proc_03.v
   :language: verilog
   :caption: :file:`proc_03.v`

---

### Source Using Yosys Synthesis Synth (`docs/source/using_yosys/synthesis/synth.rst`)

Synth commands
--------------

.. todo:: comment on common ``synth_*`` options, like ``-run``

Packaged ``synth_*`` commands
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

A list of all synth commands included in Yosys for different platforms can be
found under :doc:`/cmd/index_techlibs`.  Each command runs a script of sub
commands specific to the platform being targeted.  Note that not all of these
scripts are actively maintained and may not be up-to-date.

General synthesis
~~~~~~~~~~~~~~~~~

In addition to the above hardware-specific synth commands, there is also
:cmd:title:`prep`.  This command is limited to coarse-grain synthesis, without
getting into any architecture-specific mappings or optimizations.  Among other
things, this is useful for design verification.

The following commands are executed by the `prep` command:

.. literalinclude:: /code_examples/macro_commands/prep.ys
   :start-at: begin:

:doc:`/getting_started/example_synth` covers most of these commands and what
they do.

---

### Source Using Yosys Synthesis Techmap Synth (`docs/source/using_yosys/synthesis/techmap_synth.rst`)

Technology mapping
==================

.. todo:: less academic, check text is coherent

Previous chapters outlined how HDL code is transformed into an RTL netlist. The
RTL netlist is still based on abstract coarse-grain cell types like arbitrary
width adders and even multipliers. This chapter covers how an RTL netlist is
transformed into a functionally equivalent netlist utilizing the cell types
available in the target architecture.

Technology mapping is often performed in two phases. In the first phase RTL
cells are mapped to an internal library of single-bit cells (see
:ref:`sec:celllib_gates`). In the second phase this netlist of internal gate
types is transformed to a netlist of gates from the target technology library.

When the target architecture provides coarse-grain cells (such as block ram or
ALUs), these must be mapped to directly form the RTL netlist, as information on
the coarse-grain structure of the design is lost when it is mapped to bit-width
gate types.

Cell substitution
-----------------

The simplest form of technology mapping is cell substitution, as performed by
the techmap pass. This pass, when provided with a Verilog file that implements
the RTL cell types using simpler cells, simply replaces the RTL cells with the
provided implementation.

When no map file is provided, techmap uses a built-in map file that maps the
Yosys RTL cell types to the internal gate library used by Yosys. The curious
reader may find this map file as :file:`techlibs/common/techmap.v` in the Yosys
source tree.

Additional features have been added to techmap to allow for conditional mapping
of cells (see :doc:`/cmd/index_passes_techmap`). This can for example be useful
if the target architecture supports hardware multipliers for certain bit-widths
but not for others.

A usual synthesis flow would first use the techmap pass to directly map some RTL
cells to coarse-grain cells provided by the target architecture (if any) and
then use techmap with the built-in default file to map the remaining RTL cells
to gate logic.

Subcircuit substitution
-----------------------

Sometimes the target architecture provides cells that are more powerful than the
RTL cells used by Yosys. For example a cell in the target architecture that can
calculate the absolute-difference of two numbers does not match any single RTL
cell type but only combinations of cells.

For these cases Yosys provides the extract pass that can match a given set of
modules against a design and identify the portions of the design that are
identical (i.e. isomorphic subcircuits) to any of the given modules. These
matched subcircuits are then replaced by instances of the given modules.

The extract pass also finds basic variations of the given modules, such as
swapped inputs on commutative cell types.

In addition to this the extract pass also has limited support for frequent
subcircuit mining, i.e. the process of finding recurring subcircuits in the
design. This has a few applications, including the design of new coarse-grain
architectures :cite:p:`intersynthFdlBookChapter`.

The hard algorithmic work done by the extract pass (solving the isomorphic
subcircuit problem and frequent subcircuit mining) is performed using the
SubCircuit library that can also be used stand-alone without Yosys (see
:ref:`sec:SubCircuit`).

.. _sec:techmap_extern:

Gate-level technology mapping
-----------------------------

.. todo:: newer techmap libraries appear to be largely ``.v`` instead of ``.lib``

On the gate-level the target architecture is usually described by a "Liberty
file". The Liberty file format is an industry standard format that can be used
to describe the behaviour and other properties of standard library cells .

Mapping a design utilizing the Yosys internal gate library (e.g. as a result of
mapping it to this representation using the techmap pass) is performed in two
phases.

First the register cells must be mapped to the registers that are available on
the target architectures. The target architecture might not provide all
variations of d-type flip-flops with positive and negative clock edge,
high-active and low-active asynchronous set and/or reset, etc. Therefore the
process of mapping the registers might add additional inverters to the design
and thus it is important to map the register cells first.

Mapping of the register cells may be performed by using the dfflibmap pass. This
pass expects a Liberty file as argument (using the -liberty option) and only
uses the register cells from the Liberty file.

Secondly the combinational logic must be mapped to the target architecture. This
is done using the external program ABC via the abc pass by using the -liberty
option to the pass. Note that in this case only the combinatorial cells are used
from the cell library.

Occasionally Liberty files contain trade secrets (such as sensitive timing
information) that cannot be shared freely. This complicates processes such as
reporting bugs in the tools involved. When the information in the Liberty file
used by Yosys and ABC are not part of the sensitive information, the additional
tool yosys-filterlib (see :ref:`sec:filterlib`) can be used to strip the
sensitive information from the Liberty file.

---

### Source Yosys Internals Extending Yosys Advanced Bugpoint (`docs/source/yosys_internals/extending_yosys/advanced_bugpoint.rst`)

Identifying the root cause of bugs
==================================

This document references Yosys internals and is intended for people interested
in solving or investigating Yosys bugs.  This also applies if you are using a
fuzzing tool; fuzzers have a tendency to find many variations of the same bug,
so identifying the root cause is important for avoiding issue spam.

If you're familiar with C/C++, you might try to have a look at the source code
of the command that's failing.  Even if you can't fix the problem yourself, it
can be very helpful for anyone else investigating if you're able to identify
where the issue is arising.


Finding the failing command
---------------------------

Using the ``-L`` flag can help here, allowing you to specify a file to log to,
such as ``yosys -L out.log -s script.ys``.  Most commands will print a header
message when they begin; something like ``2.48. Executing HIERARCHY pass
(managing design hierarchy).``  The last header message will usually be the
failing command.  There are some commands which don't print a header message, so
you may want to add ``echo on`` to the start of your script.  The `echo` command
echoes each command executed, along with any arguments given to it.  For the
`hierarchy` example above this might be ``yosys> hierarchy -check``.

.. note::

   It may also be helpful to use the `log` command to add messages which you can
   then search for either in the terminal or the logfile.  This can be quite
   useful if your script contains script-passes, like the
   :doc:`/using_yosys/synthesis/synth`, which call many sub-commands and you're
   not sure exactly which script-pass is calling the failing command.


Minimizing scripts
------------------

.. warning::

   This section is intended as **advanced usage**, and generally not necessary
   for normal bug reports.

If you're using a command line prompt, such as ``yosys -p 'synth_xilinx' -o
design.json design.v``, consider converting it to a script.  It's generally much
easier to iterate over changes to a script in a file rather than one on the
command line, as well as being better for sharing with others.

.. code-block:: yoscrypt
   :caption: example script, ``script.ys``, for prompt ``yosys -p 'synth_xilinx' -o design.json design.v``

   read_verilog design.v
   synth_xilinx
   write_json design.json

Next up you want to remove everything *after* the error occurs.  If your final
command calls sub-commands, replace it with its contents first.  In the case of
the :doc:`/using_yosys/synthesis/synth`, as well as certain other script-passes,
you can use the ``-run`` option to simplify this. For example we can replace
``synth -top <top> -lut`` with the :ref:`replace_synth`.  The options ``-top
<top> -lut`` can be provided to each `synth` step, or to just the step(s) where
it is relevant, as done here.

.. code-block:: yoscrypt
   :caption: example replacement script for `synth` command
   :name: replace_synth

   synth -top <top> -run :coarse
   synth -lut -run coarse:fine
   synth -lut -run fine:check
   synth -run check:

Say we ran :ref:`replace_synth` and were able to remove the ``synth -run
check:`` and still got our error, then we check the log and we see the last
thing before the error was ``7.2. Executing MEMORY_MAP pass (converting memories
to logic and flip-flops)``. By checking the output of ``yosys -h synth`` (or the
`synth` help page) we can see that the `memory_map` pass is called in the
``fine`` step.  We can then update our script to the following:

.. code-block:: yoscrypt
   :caption: example replacement script for `synth` when `memory_map` is failing

   synth -top <top> -run :fine
   opt -fast -full
   memory_map

By giving `synth` the option ``-run :fine``, we are telling it to run from the
beginning of the script until the ``fine`` step, where we then give it the exact
commands to run.  There are some cases where the commands given in the help
output are not an exact match for what is being run, but are instead a
simplification.  If you find that replacing the script-pass with its contents
causes the error to disappear, or change, try calling the script-pass with
``echo on`` to see exactly what commands are being called and what options are
used.

.. warning::

   Before continuing further, *back up your code*.  The following steps can
   remove context and lead to over-minimizing scripts, hiding underlying issues.
   Check out :ref:`yosys_internals/extending_yosys/advanced_bugpoint:Why
   context matters` to learn more.

When a problem is occurring many steps into a script, minimizing the design at
the start of the script isn't always enough to identify the cause of the issue.
Each extra step of the script can lead to larger sections of the input design
being needed for the specific problem to be preserved until it causes a crash.
So to find the smallest possible reproducer it can sometimes be helpful to
remove commands prior to the failure point.

The simplest way to do this is by writing out the design, resetting the current
state, and reading back the design:

.. code-block:: yoscrypt

   write_rtlil <design.il>; design -reset; read_rtlil <design.il>;

In most cases, this can be inserted immediately before the failing command while
still producing the error, allowing you to :ref:`minimize your
RTLIL<using_yosys/bugpoint:minimizing rtlil designs with bugpoint>` with the
``<design.il>`` output.  For our previous example with `memory_map`, if
:ref:`map_reset` still gives the same error, then we should now be able to call
``yosys design.il -p 'memory_map'`` to reproduce it.

.. code-block:: yoscrypt
   :caption: resetting the design immediately before failure
   :name: map_reset

   synth -top <top> -run :fine
   opt -fast -full
   write_rtlil design.il; design -reset; read_rtlil design.il;
   memory_map

If that doesn't give the error (or doesn't give the same error), then you should
try to move the write/reset/read earlier in the script until it does.  If you
have no idea where exactly you should put the reset, the best way is to use a
"binary search" type approach, reducing the possible options by half after each
attempt.

.. note::

   By default, `write_rtlil` doesn't include platform specific IP blocks and
   other primitive cell models which are typically loaded with a ``read_verilog
   -lib`` command at the start of the synthesis script.  You may have to
   duplicate these commands *after* the call to ``design -reset``.  It is also
   possible to write out *everything* with ``select =*; write_rtlil -selected
   <design.il>``.

As an example, your script has 16 commands in it before failing on the 17th. If
resetting immediately before the 17th doesn't reproduce the error, try between
the 8th and 9th (8 is half of the total 16).  If that produces the error then
you can remove everything before the `read_rtlil` and try reset again in the
middle of what's left, making sure to use a different name for the output file
so that you don't overwrite what you've already got.  If the error isn't
produced then you need to go earlier still, so in this case you would do between
the 4th and 5th (4 is half of the previous 8).  Repeat this until you can't
reduce the remaining commands any further.

A more conservative, but more involved, method is to remove or comment out
commands prior to the failing command.  Each command, or group of commands, can
be disabled one at a time while checking if the error still occurs, eventually
giving the smallest subset of commands needed to take the original input through
to the error.  The difficulty with this method is that depending on your design,
some commands may be necessary even if they aren't needed to reproduce the
error.  For example, if your design includes ``process`` blocks, many commands
will fail unless you run the `proc` command.  While this approach can do a
better job of maintaining context, it is often easier to *recover* the context
after the design has been minimized for producing the error.  For more on
recovering context, checkout
:ref:`yosys_internals/extending_yosys/advanced_bugpoint:Why context matters`.


Why context matters
-------------------

Sometimes when a command is raising an error, you're seeing a symptom rather
than the underlying issue.  It's possible that an earlier command may be putting
the design in an invalid state, which isn't picked up until the error is raised.
This is particularly true for the pre-packaged
:doc:`/using_yosys/synthesis/synth`, which rely on a combination of generic and
architecture specific passes.  As new features are added to Yosys and more
designs are supported, the types of cells output by a pass can grow and change;
and sometimes this leads to a mismatch in what a pass is intended to handle.

If you minimized your script, and removed commands prior to the failure to get a
smaller reproducer, try to work backwards and find which commands may have
contributed to the design failing.  From the minimized design you should have
some understanding of the cell or cells which are producing the error; but where
did those cells come from?  The name and/or type of the cell can often point you
in the right direction:

.. code-block::

   # internal cell types start with a $
   # lowercase for word-level, uppercase for bit-level
   $and
   $_AND_

   # cell types with $__ are typically intermediate cells used in techmapping
   $__MUL16X16

   # cell types without a $ are either user-defined or architecture specific
   my_module
   SB_MAC16

   # object names might give you the name of the pass that created them
   $procdff$1204
   $memory\rom$rdmux[0][0][0]$a$1550

   # or even the line number in the Yosys source
   $auto$muxcover.cc:557:implement_best_cover$2152
   $auto$alumacc.cc:495:replace_alu$1209

Try running the unminimized script and search the log for the names of the
objects in your minimized design.  In the case of cells you can also search for
the type of the cell.  Remember that calling `stat` will list all the types of
cells currently used in the design, and ``select -list =*`` will list the names
of of all the current objects.  You can add these commands to your script, or
use an interactive terminal to run each command individually.  Adding them to
the script can be more repeatable, but if it takes a long time to run to the
point you're interested in then an interactive shell session can give you more
flexibility once you reach that point.  You can also add a call to the `shell`
command at any point in a script to start an interactive session at a given
point; allowing you to script any preparation steps, then come back once it's
done.

The ``--dump-design`` option
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Yosys provides the ``--dump-design`` option (or ``-P`` for short) for dumping
the design at specific steps of the script based on the log header.  If the last
step before an error is ``7.2. Executing MEMORY_MAP pass (converting memories to
logic and flip-flops)``, then calling Yosys with ``--dump-design 7.2:bad.il``
will save the design *before* this command runs, in the file ``bad.il``.

It is also possible to use this option multiple times, e.g. ``-P2:hierarchy.il
-P7 -P7.2:bad.il``, to get multiple dumps in the same run.  This can make it
easier to follow the design through each step to find where certain cells or
connections are coming from.  ``--dump-design ALL`` is also allowed, writing out
the design at each log header.

A worked example
~~~~~~~~~~~~~~~~

Say you did all the minimization and found that an error in `synth_xilinx`
occurs when a call to ``techmap -map +/xilinx/cells_map.v`` with
``MIN_MUX_INPUTS`` defined parses a `$_MUX16_` with all inputs set to ``1'x``.
You could fix the bug in ``+/xilinx/cells_map.v``, but that might only solve
this one case while leaving other problems that haven't been found yet.  So you
step through the original script, calling `stat` after each step to find when
the `$_MUX16_` is added.

You find that the `$_MUX16_` is introduced by a call to `muxcover`, but all the
inputs are defined, so calling `techmap` now works as expected.  From running
`bugpoint` with the failing techmap you know that the cell with index ``2297``
will fail, so you call ``select top/*$2297`` to limit to just that cell.  This
can then be saved with ``design -save pre_bug`` or ``write_rtlil -selected
pre_bug.il``, so that you don't have to re-run all the earlier steps to get back
here.

Next you step through the remaining commands and call `dump` after each to find
when the inputs are disconnected.  You find that ``opt -full`` has optimized
away portions of the circuit, leading to `opt_expr` setting the undriven mux
inputs to ``x``, but failing to remove the now unnecessary `$_MUX16_`.  Now
you've identified a problem in `opt_expr` that affects all of the wide muxes,
and could happen in any synthesis flow, not just `synth_xilinx`.

.. seealso::

   This example is taken from `YosysHQ/yosys#4590
   <https://github.com/YosysHQ/yosys/issues/4590>`_ and can be reproduced with a
   version of Yosys between 0.45 and 0.51.

---

### Source Yosys Internals Extending Yosys Build Verific (`docs/source/yosys_internals/extending_yosys/build_verific.rst`)

Compiling with Verific library
==============================

The easiest way to get Yosys with Verific support is to `contact YosysHQ`_ for a
`Tabby CAD Suite`_ evaluation license and download link.  The TabbyCAD Suite
includes additional patches and a custom extensions library in order to get the
most out of the Verific parser when using Yosys.

If you already have a license for the Verific parser, in either source or binary
form, you may be able to compile Yosys with partial Verific support yourself.

.. _contact YosysHQ : https://www.yosyshq.com/contact
.. _Tabby CAD Suite: https://www.yosyshq.com/tabby-cad-datasheet

The Yosys-Verific patch
-----------------------

YosysHQ maintains and develops a patch for Verific in order to better integrate
with Yosys and to provide features required by some of the formal verification
front-end tools.  To license this patch for your own Yosys builds, `contact
YosysHQ`_.

.. warning::

   While synthesis from RTL may be possible without this patch, YosysHQ provides
   no guarantees of correctness and is unable to provide support.

We recommend against using unpatched Yosys+Verific builds in conjunction with
the formal verification front-end tools unless you are familiar with their inner
workings. There are cases where the tools will appear to work, while producing
incorrect results.

.. note::

   Some of the formal verification front-end tools may not be fully supported
   without the full TabbyCAD suite.  If you want to use these tools, including
   SBY, make sure to ask us if the Yosys-Verific patch is right for you.

Compile options
---------------

To enable Verific support, set the :makevar:`YOSYS_VERIFIC_DIR` CMake variable
to point to the location where the library is located, e.g.

.. code-block:: console

   cmake -B build . -DYOSYS_VERIFIC_DIR="/usr/local/src/verific_lib"

During building, CMake will attempt to automatically detect available Verific
library components to enable the corresponding compile-time option in Yosys.
This can be overridden by manually setting the :makevar:`YOSYS_VERIFIC_FEATURES`
CMake variable. This variable should contain a semi-colon separated list, e.g.
``-DYOSYS_VERIFIC_FEATURES="systemverilog;hier_tree"``.  The table below lists
the features available to Yosys.

============== =========== ===================================
Feature        Directory   Description
============== =========== ===================================
systemverilog  verilog     SystemVerilog support
vhdl           vhdl        VHDL support
hier_tree      hier_tree   Hierarchy tree support
extensions     extensions  YosysHQ specific extensions support
edif           edif        EDIF support
liberty        synlib      Liberty file support
============== =========== ===================================

.. note::

   The YosysHQ specific extensions are only available with the TabbyCAD suite.

Required Verific features
~~~~~~~~~~~~~~~~~~~~~~~~~

The following features, along with their corresponding Yosys build parameters,
are required for the Yosys-Verific patch:

* RTL elaboration with

  * SystemVerilog with ``systemverilog``, and/or
  * VHDL support with ``vhdl``.

* Hierarchy tree support and static elaboration with ``hier_tree``.

Please be aware that the following Verific configuration build parameter needs
to be enabled in order to create the fully supported build:

::

   database/DBCompileFlags.h:
       DB_PRESERVE_INITIAL_VALUE

.. note::

   Yosys+Verific builds may compile without these features, but we provide no
   guarantees and cannot offer support if they are disabled or the Yosys-Verific
   patch is not used.

Optional Verific features
~~~~~~~~~~~~~~~~~~~~~~~~~

The following Verific features are available with TabbyCAD and will be
automatically enabled in Yosys builds if the listed directory is included in the
:makevar:`YOSYS_VERIFIC_DIR`:

* EDIF support with ``edif`` directory, and
* Liberty file support with ``synlib`` directory.

Partially supported builds
~~~~~~~~~~~~~~~~~~~~~~~~~~

This section describes Yosys+Verific configurations which we have confirmed as
working in the past, however they are not a part of our regular tests so we
cannot guarantee they are still functional.

To be able to compile Yosys with Verific, the Verific library must have support
for at least one HDL language with RTL elaboration enabled.  The following table
lists a series of build configurations which are possible, but only provide a
limited subset of features.  Please note that support is limited without YosysHQ
specific extensions of Verific library.

======================================================================= =================================
Features                                                                :makevar:`YOSYS_VERIFIC_FEATURES`
======================================================================= =================================
SystemVerilog + RTL elaboration                                         systemverilog
VHDL + RTL elaboration                                                  vhdl
SystemVerilog + VHDL + RTL elaboration                                  systemverilog;vhdl
SystemVerilog + RTL elaboration + Static elaboration + Hier tree        systemverilog;vhdl;hier_tree
VHDL + RTL elaboration + Static elaboration + Hier tree                 vhdl;hier_tree
SystemVerilog + VHDL + RTL elaboration + Static elaboration + Hier tree systemverilog;vhdl;hier_tree
======================================================================= =================================

.. note::

   In case your Verific build has EDIF and/or Liberty support, you can enable
   those options. These are not mentioned above for simplification.

---

### Source Yosys Internals Extending Yosys Contributing (`docs/source/yosys_internals/extending_yosys/contributing.rst`)

Contributing to Yosys
=====================

LLM usage
---------

While we develop a complete policy around the usage of LLMs in Yosys, we have an
`Interim YosysHQ LLM Policy
<https://blog.yosyshq.com/p/interim-yosyshq-llm-policy/>`_.  As a general rule:
Please do not file pull requests to our GitHub projects containing LLM generated
code.

Reporting bugs
--------------

We fix well-reported bugs the fastest. A good bug report is an issue on the `issue tracker`_
and includes the following information:

.. _`issue tracker`: https://github.com/YosysHQ/yosys/issues

Title
~~~~~

briefly describe the issue, for example:

   techmap of wide mux with undefined inputs raises error during synth_xilinx

+ tells us what's happening ("raises error")
+ gives the command affected (`techmap`)
+ an overview of the input design ("wide mux with undefined inputs")
+ and some context where it was found ("during `synth_xilinx`")


Reproduction Steps
~~~~~~~~~~~~~~~~~~

The reproduction steps should be a minimal, complete and verifiable
example `MVCE`_.
Providing an MVCE with your bug report drastically increases the likelihood that
someone will be able to help resolve your issue.
Make sure that your report input is free of any problems as reported by the
`check` command.
One way to minimize a design is to use the `bugpoint` command.
You can learn more in the :doc:`how-to guide for bugpoint `.

The reproduction steps are ideally a code-block (starting and ending with
triple backquotes) containing
the minimized design (Verilog or RTLIL), followed by a code-block containing
the minimized yosys script OR a command line call to yosys with
code-formatting (starting and ending with single backquotes).

.. code-block:: markdown

   min.v
   ```verilog
   // minimized Verilog design
   ```

   min.ys
   ```
   read_verilog min.v
   # minimum sequence of commands to reproduce error
   ```

   OR

   `yosys -p ': minimum sequence of commands;' min.v`

Alternatively, you can provide a single code-block which includes the minimized
design as a "here document" followed by the sequence of commands which reproduce
the error:

.. code-block:: markdown

   ```
   read_rtlil <<EOF
   # minimized RTLIL design
   EOF
   # minimum sequence of commands
   ```

.. seealso:: See :doc:`/using_yosys/more_scripting/load_design` for more on heredocs.

Don't forget to mention:

- any important environment variables or command line options
- if the problem occurs for a range of values/designs, what is that range
- if you're using an external tool, such as ``valgrind``, to detect the issue,
  what version of that tool are you using and what options are you giving it

.. warning::

   Please try to avoid the use of any external plugins/tools in the reproduction
   steps if they are not directly related to the issue being raised.  This
   includes frontend plugins such as GHDL or slang; use `write_rtlil` on the
   minimized design instead.  This also includes tools which provide a wrapper
   around Yosys such as OpenLane; you should instead minimize your input and
   reproduction steps to just the Yosys part.

.. _MVCE: https://stackoverflow.com/help/minimal-reproducible-example
.. _how-to guide for bugpoint: https://yosys.readthedocs.io/en/latest/using_yosys/bugpoint.html

Expected Behaviour
~~~~~~~~~~~~~~~~~~

Describe what you'd expect to happen when we follow the reproduction steps
if the bug was fixed.

If you have a similar design/script that doesn't give the error, include it
here as a reference. If the bug is that an error *should* be raised but isn't,
note if there are any other commands with similar error messages.


Actual Behaviour
~~~~~~~~~~~~~~~~

Describe what you actually see when you follow the reproduction steps.

This can include:

* any error messages
* any details relevant to the crash that were found with ``--trace`` or
  ``--debug`` flags
* the part of the source code that triggers the bug

  * if possible, use a permalink to the source on GitHub
  * you can browse the source repository for a certain commit with the failure
    and open the source file, select the relevant lines (click on the line
    number for the first relevant line, then while holding shift click on the
    line number for the last relevant line), click on the ``...`` that appears
    and select "Copy permalink"
  * should look something like
    ``https://github.com/YosysHQ/yosys/blob/<commit_hash>/path/to/file#L139-L147``
  * clicking on "Preview" should reveal a code block containing the lines of
    source specified, with a link to the source file at the given commit


Additional Details
~~~~~~~~~~~~~~~~~~

Anything else you think might be helpful or relevant when verifying or fixing
the bug.

Once you have created the issue, any additional details can be added as a
comment on that issue. You can include any additional context as to what you
were doing when you first encountered the bug.

If this issue discovered through the use of a fuzzer, ALWAYS declare that.
If you've minimized the script, consider including the `bugpoint` script you
used, or the original script, for example:

.. code-block:: markdown

   Minimized with
   ```
   read_verilog design.v
   # original sequence of commands prior to error
   bugpoint -script <failure.ys> -grep "<string>"
   write_rtlil min.il
   ```

   OR

   Minimized from
   `yosys -p ': original sequence of commands to produce error;' design.v`

If possible, it may also help to share the original un-minimized design.
If the design is too big for a comment, consider turning it into a `Gist`_

.. _Gist: https://gist.github.com/

Contributing code
-----------------

Code that matters
~~~~~~~~~~~~~~~~~

If you're adding complex functionality, or modifying core parts of yosys,
we highly recommend discussing your motivation and approach
ahead of time on the `Discourse forum`_. Please, be as explicit and concrete
as possible when explaining the motivation for what you're building.
Additionally, if you do so on the forum first before you starting hacking
away at C++, you might solve your problem without writing a single line
of code!

PRs are considered for relevance, priority, and quality
based on their descriptions first, code second.

Before you build or fix something, also search for existing `issues`_.

We have open `developer 'jour fixe' (Dev JF) meetings`_
where developers from YosysHQ and the
community come together to discuss open issues and PRs.  This is also a good
place to talk to us about how to implement larger PRs.

.. _`developer 'jour fixe' (Dev JF) meetings`: https://docs.google.com/document/d/1SapA6QAsJcsgwsdKJDgnGR2mr97pJjV4eeXg_TVJhRU/edit?usp=sharing
.. _`Discourse forum`: https://yosyshq.discourse.group/
.. _`issues`: https://github.com/YosysHQ/yosys/issues

Making sense
~~~~~~~~~~~~

Given enough effort, the behavior of any code can be figured out to any
desired extent. However, the author of the code is by far in the best
position to make this as easy as possible.

Yosys is a long-standing project and has accumulated a lot of C-style code
that's not written to be read, just written to run. We improve this bit
by bit when opportunities arise, but it is what it is.
New additions are expected to be a lot cleaner.

The purpose and behavior of the code changed should be described clearly.
Your change should contain exactly what it needs to match that description.
This means:

* nothing more than that - no dead code, no undocumented features
* nothing missing - if something is partially built, that's fine,
  but you have to make that clear. For example, some passes
  only support some types of cells

Here are some software engineering approaches that help:

* Use abstraction to model the problem and hide details

  * Maximize the usage of types (structs over loose variables),
    not necessarily in an object-oriented way
  * Use functions, scopes, type aliases

* In new passes, make sure the logic behind how and why it works is actually provided
  in coherent comments, and that variable and type naming is consistent with the terms
  you use in the description.
* The logic of the implementation should be described in mathematical
  or algorithm theory terms. Correctness, termination, computational complexity.
  Make it clear if you're re-implementing a classic data structure for logic synthesis
  or graph traversal etc.

* There's various ways of traversing the design with use-def indices (for getting
  drivers and driven signals) available in Yosys. They have advantages and sometimes
  disadvantages. Prefer not re-implementing these
* Prefer references over pointers, and smart pointers over raw pointers
* Aggressively deduplicate code. Within functions, within passes,
  across passes, even against existing code
* Prefer declaring things ``const``
* Prefer range-based for loops over C-style

Common mistakes
~~~~~~~~~~~~~~~

* Deleting design objects invalidates iterators. Defer deletions or hold a copy
  of the list of pointers to design objects
* Deleting wires can get sketchy and is intended to be done solely by
  the ``opt_clean`` pass so just don't do it
* Iterating over an entire design and checking if things are selected is more
  inefficient than using the ``selected_*`` methods
* Remember to call ``fixup_ports`` at the end if you're modifying module interfaces

Testing your change
~~~~~~~~~~~~~~~~~~~

Untested code can't be maintained. Inevitable codebase-wide changes
are likely to break anything untested. Tests also help reviewers understand
the purpose of the code change in practice.

Your code needs to come with tests. If it's a feature, a test that covers
representative examples of the added behavior. If it's a bug fix, it should
reproduce the original isolated bug. But in some situations, adding a test
isn't viable. If you can't provide a test, explain this decision.

Prefer writing unit tests (:file:`tests/unit`) for isolated tests to
the internals of more serious code changes, like those to the core of yosys,
or more algorithmic ones.

The rest of the test suite is mostly based on running Yosys on various Yosys
and Tcl scripts that manually call Yosys commands.
See :doc:`/yosys_internals/extending_yosys/test_suites` for more information
about how our test suite is structured.
The basic test writing approach is checking
for the presence of some kind of object or pattern with ``-assert-count`` in
:doc:`/using_yosys/more_scripting/selections`.

It's often best to use equivalence checking with ``equiv_opt -assert``
or similar to prove that the changes done to the design by a modified pass
preserve equivalence. But some code isn't meant to preserve equivalence.
Sometimes proving equivalence takes an impractically long time for larger
inputs. Also beware, the ``equiv_`` passes are a bit quirky and might even
have incorrect results in unusual situations.

.. Changes to core parts of Yosys or passes that are included in synthesis flows
.. can change runtime and memory usage - for the better or for worse. This strongly
.. depends on the design involved. Such risky changes should then be benchmarked
.. with various designs.

.. TODO Emil benchmarking

Coding style
~~~~~~~~~~~~

Yosys is written in C++20.

In general Yosys uses ``int`` instead of ``size_t``. To avoid compiler warnings
for implicit type casts, always use ``GetSize(foobar)`` instead of
``foobar.size()``. (``GetSize()`` is defined in :file:`kernel/yosys.h`)

For auto formatting code, a :file:`.clang-format` file is present top-level.
Yosys code is using tabs for indentation. A tab is 8 characters wide,
but prefer not relying on it. A continuation of a statement
in the following line is indented by two additional tabs. Lines are
as long as you want them to be. A good rule of thumb is to break lines
at about column 150. Opening braces can be put on the same or next line
as the statement opening the block (if, switch, for, while, do).
Put the opening brace on its own line for larger blocks, especially
blocks that contains blank lines. Remove trailing whitespace on sight.

Otherwise stick to the `Linux Kernel Coding Style`_.

.. _Linux Kernel Coding Style: https://www.kernel.org/doc/Documentation/process/coding-style.rst

Pull requests (PRs)
~~~~~~~~~~~~~~~~~~~

If you are working on something to add to Yosys, or fix something that isn't
working quite right,
make a `pull request (PR)`_.

An open PR, even as a draft, tells everyone that you're working on it and they
don't have to. It can also be a useful way to solicit feedback on in-progress
changes.

We use `labels`_ to help categorise
issues and PRs.  If a label seems relevant to your work, please do add it; this
also includes the labels beginning with 'status-'.  The 'merge-' labels are used
by maintainers for tracking and communicating which PRs are ready and pending
merge; please do not use these labels if you are not a maintainer.

.. _`pull request (PR)`: https://github.com/YosysHQ/yosys/pulls
.. _`labels`: https://github.com/YosysHQ/yosys/labels

Git style
~~~~~~~~~

We don't have a strict commit message style.

Some style hints:

* Refactor and document existing code if you touch it,
  but in separate commits from your functional changes
* Prefer smaller commits organized by good chunks. Git has a lot of features
  like fixup commits, interactive rebase with autosquash

Reviewing PRs
-------------

Reviewing PRs is a totally valid form of external contributing to the project!

Who's the reviewer?
~~~~~~~~~~~~~~~~~~~

YosysHQ GmbH is a company with a mandate to make decisions for the good
of YosysHQ open source software. It was co-founded by Claire Xenia Wolf,
the original author of Yosys.
Within it, we allocate reviews based on expertise with the topic at hand
as well as member time constraints. However, decisions including reviews
are also contributed by people external to the company.

If you're intimately acquainted with a part of the codebase, we will be happy
to defer to your experience and have you review PRs. The official way we like
is our CODEOWNERS file in the git repository. What we're looking for in code
owners is activity and trust. For activity, if you're only interested in
a yosys pass for example for the time you spend writing a thesis, it might be
better to focus on writing good tests and docs in the PRs you submit rather than
to commit to code ownership and therefore to be responsible for fixing things
and reviewing other people's PRs at various unexpected points later. If you're
prolific in some part of the codebase and not a code owner, we still value your
experience and may tag you in PRs.

As a matter of fact, the purpose of code ownership is to avoid maintainer
burnout by removing orphaned parts of the codebase. If you become a code owner
and stop being responsive, in the future, we might decide to remove such code
if convenient and costly to maintain. It's simply more respectful of the users'
time to explicitly cut something out than let it "bitrot". Larger projects like
LLVM or linux could not survive without such things, but Yosys is far smaller,
and there are implicit expectations of stability we aim to
respect within reason.

.. TODO this deserves its own section elsewhere I think? But it would be distracting elsewhere

Sometimes, multiple maintainers may add review comments. This is considered
healthy collaborative even if it might create disagreement at times. If
somebody is already reviewing a PR, others, even non-maintainers are free to
leave comments with extra observations and alternate perspectives in a
collaborative spirit.

How to review
~~~~~~~~~~~~~

First, read everything above about contributing. Those are the values you
should gently enforce as a reviewer. They're ordered by importance, but
explicitly, descriptions are more important than code, long-form comments
describing the design are more important than piecemeal comments, etc.

If a PR is poorly described, incomplete, tests are broken, or if the
author is not responding, please don't feel pressured to take over their
role by reverse engineering the code or fixing things for them, unless
there are good reasons to do so.

If a PR author submits LLM outputs they haven't understood themselves,
they will not be able to implement feedback. Take this into consideration
as well. We do not ban LLM code from the codebase, we ban bad code.

Reviewers may have diverse styles of communication while reviewing - one
may do one thorough review, another may prefer a back and forth with the
basics out the way before digging into the code. Generally, PRs may have
several requests for modifications and long discussions, but often
they just are good enough to merge as-is.

The CI is required to go green for merging. New contributors need a CI
run to be triggered by a maintainer before their PRs take up computing
resources. It's a single click from the github web interface.
We test on various platforms and compilers. Sanitizer builds are only
tested on the main branch.

---

### Source Yosys Internals Extending Yosys Extensions (`docs/source/yosys_internals/extending_yosys/extensions.rst`)

Writing extensions
==================

.. role:: yoscrypt(code)
   :language: yoscrypt

.. todo:: check text is coherent

.. todo:: update to use :file:`/code_examples/extensions/test*.log`

This chapter contains some bits and pieces of information about programming
yosys extensions. Don't be afraid to ask questions on the YosysHQ Discourse.

.. todo:: mention coding guide

Quick guide
-----------

Code examples from this section are included in the |code_examples/extensions|_
directory of the Yosys source code.

.. |code_examples/extensions| replace:: :file:`docs/source/code_examples/extensions`
.. _code_examples/extensions: https://github.com/YosysHQ/yosys/tree/main/docs/source/code_examples/extensions


Program components and data formats
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

See :doc:`/yosys_internals/formats/rtlil_rep` document for more information
about the internal data storage format used in Yosys and the classes that it
provides.

This document will focus on the much simpler version of RTLIL left after the
commands `proc` and `memory` (or :yoscrypt:`memory -nomap`):

.. figure:: /_images/internals/simplified_rtlil.*
    :class: width-helper invert-helper
    :name: fig:Simplified_RTLIL

    Simplified RTLIL entity-relationship diagram without memories and processes

It is possible to only work on this simpler version:

.. todo:: consider replacing inline code

.. code:: c++

    for (RTLIL::Module *module : design->selected_modules() {
        if (module->has_memories_warn() || module->has_processes_warn())
            continue;
        ....
    }

When trying to understand what a command does, creating a small test case to
look at the output of `dump` and `show` before and after the command has been
executed can be helpful. :doc:`/using_yosys/more_scripting/selections` has more
information on using these commands.

Creating a command
~~~~~~~~~~~~~~~~~~

.. todo:: add/expand supporting text

Let's create a very simple test command which prints the arguments we called it
with, and lists off the current design's modules.

.. literalinclude:: /code_examples/extensions/my_cmd.cc
   :language: c++
   :lines: 1, 4, 6, 7-20
   :caption: Example command :yoscrypt:`my_cmd` from :file:`my_cmd.cc`

Note that we are making a global instance of a class derived from
``Yosys::Pass``, which we get by including :file:`kernel/yosys.h`.

Compiling to a plugin
~~~~~~~~~~~~~~~~~~~~~

Yosys can be extended by adding additional C++ code to the Yosys code base, or
by loading plugins into Yosys.  For maintainability it is generally recommended
to create plugins.

The following command compiles our example :yoscrypt:`my_cmd` to a Yosys plugin:

.. todo:: replace inline code

.. code:: shell

   yosys-config --exec --cxx --cxxflags --ldflags \
   -o my_cmd.so -shared my_cmd.cc --ldlibs

Or shorter:

.. code:: shell

   yosys-config --build my_cmd.so my_cmd.cc

Running Yosys with the ``-m`` option allows the plugin to be used.  Here's a
quick example that also uses the ``-p`` option to run :yoscrypt:`my_cmd foo
bar`.

.. code:: shell-session

   $ yosys -m ./my_cmd.so -p 'my_cmd foo bar'

   -- Running command `my_cmd foo bar' --
   Arguments to my_cmd:
     my_cmd
     foo
     bar
   Modules in current design:

Creating modules from scratch
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Let's create the following module using the RTLIL API:

.. literalinclude:: /code_examples/extensions/absval_ref.v
   :language: Verilog
   :caption: absval_ref.v

We'll do the same as before and format it as a a ``Yosys::Pass``.

.. literalinclude:: /code_examples/extensions/my_cmd.cc
   :language: c++
   :lines: 23-47
   :caption: :yoscrypt:`test1` - creating the absval module, from :file:`my_cmd.cc`

.. code:: shell-session

   $ yosys -m ./my_cmd.so -p 'test1' -Q

   -- Running command `test1' --
   Name of this module: absval

And if we look at the schematic for this new module we see the following:

.. figure:: /_images/code_examples/extensions/test1.*
   :class: width-helper invert-helper

   Output of ``yosys -m ./my_cmd.so -p 'test1; show'``

Modifying modules
~~~~~~~~~~~~~~~~~

Most commands modify existing modules, not create new ones.

When modifying existing modules, stick to the following DOs and DON'Ts:

- Do not remove wires. Simply disconnect them and let a successive `clean`
  command worry about removing it.
- Use ``module->fixup_ports()`` after changing the ``port_*`` properties of
  wires.
- You can safely remove cells or change the ``connections`` property of a cell,
  but be careful when changing the size of the ``SigSpec`` connected to a cell
  port.
- Use the ``SigMap`` helper class (see next section) when you need a unique
  handle for each signal bit.

Using the SigMap helper class
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Consider the following module:

.. literalinclude:: /code_examples/extensions/sigmap_test.v
   :language: Verilog
   :caption: :file:`sigmap_test.v`

In this case ``a``, ``x``, and ``y`` are all different names for the same
signal. However:

.. todo:: use my_cmd.cc literalincludes

.. code:: C++

    RTLIL::SigSpec a(module->wire("\\a")), x(module->wire("\\x")),
                                           y(module->wire("\\y"));
    log("%d %d %d\n", a == x, x == y, y == a); // will print "0 0 0"

The ``SigMap`` helper class can be used to map all such aliasing signals to a
unique signal from the group (usually the wire that is directly driven by a cell
or port).

.. code:: C++

    SigMap sigmap(module);
    log("%d %d %d\n", sigmap(a) == sigmap(x), sigmap(x) == sigmap(y),
                      sigmap(y) == sigmap(a)); // will print "1 1 1"

Printing log messages
~~~~~~~~~~~~~~~~~~~~~

The ``log()`` function is a ``printf()``-like function that can be used to
create log messages.

Use ``log_signal()`` to create a C-string for a SigSpec object:

.. code:: C++

    log("Mapped signal x: %s\n", log_signal(sigmap(x)));

The pointer returned by ``log_signal()`` is automatically freed by the log
framework at a later time.

Use ``log_header()`` and ``log_push()``/\ ``log_pop()`` to structure log
messages:

.. todo:: replace inline code

.. code:: C++

    log_header(design, "Doing important stuff!\n");
    log_push();
    for (int i = 0; i < 10; i++)
        log("Log message #%d.\n", i);
    log_pop();

Error handling
~~~~~~~~~~~~~~

Use ``log_error()`` to report a non-recoverable error:

.. todo:: replace inline code

.. code:: C++

    if (design->modules.count(module->name) != 0)
        log_error("A module with the name %s already exists!\n", module);

Use ``log_cmd_error()`` to report a recoverable error:

.. code:: C++

    if (design->selection().empty())
        log_cmd_error("This command can't operator on an empty selection!\n");

Use ``log_assert()`` and ``log_abort()`` instead of ``assert()`` and ``abort()``.

The "stubnets" example module
------------------------------

The following is the complete code of the "stubnets" example module. It is
included in the Yosys source distribution under |code_examples/stubnets|_.

.. |code_examples/stubnets| replace:: :file:`docs/source/code_examples/stubnets`
.. _code_examples/stubnets: https://github.com/YosysHQ/yosys/tree/main/docs/source/code_examples/stubnets

.. literalinclude:: /code_examples/stubnets/stubnets.cc
    :language: c++
    :linenos:
    :caption: :file:`stubnets.cc`

.. literalinclude:: /code_examples/stubnets/Makefile
    :language: makefile
    :linenos:
    :caption: :file:`Makefile`

.. literalinclude:: /code_examples/stubnets/test.v
    :language: verilog
    :linenos:
    :caption: :file:`test.v`

---

### Source Yosys Internals Extending Yosys Functional Ir (`docs/source/yosys_internals/extending_yosys/functional_ir.rst`)

Writing a new backend using FunctionalIR
========================================

What is FunctionalIR
--------------------

To simplify the writing of backends for functional languages or similar targets,
Yosys provides an alternative intermediate representation called FunctionalIR
which maps more directly on those targets.

FunctionalIR represents the design as a function ``(inputs, current_state) ->
(outputs, next_state)``. This function is broken down into a series of
assignments to variables. Each assignment is a simple operation, such as an
addition. Complex operations are broken up into multiple steps. For example, an
RTLIL addition will be translated into a sign/zero extension of the inputs,
followed by an addition.

Like SSA form, each variable is assigned to exactly once. We can thus treat
variables and assignments as equivalent and, since this is a graph-like
representation, those variables are also called "nodes". Unlike RTLIL's cells
and wires representation, this representation is strictly ordered (topologically
sorted) with definitions preceding their use.

Every node has a "sort" (the FunctionalIR term for what might otherwise be
called a "type"). The sorts available are

- ``bit[n]`` for an ``n``-bit bitvector, and
- ``memory[n,m]`` for an immutable array of ``2**n`` values of sort ``bit[m]``.

In terms of actual code, Yosys provides a class ``Functional::IR`` that
represents a design in FunctionalIR. ``Functional::IR::from_module`` generates
an instance from an RTLIL module. The entire design is stored as a whole in an
internal data structure. To access the design, the ``Functional::Node`` class
provides a reference to a particular node in the design. The ``Functional::IR``
class supports the syntax ``for(auto node : ir)`` to iterate over every node.

``Functional::IR`` also keeps track of inputs, outputs and states. By a "state"
we mean a pair of a "current state" input and a "next state" output. One such
pair is created for every register and for every memory. Every input, output and
state has a name (equal to their name in RTLIL), a sort and a kind. The kind
field usually remains as the default value ``$input``, ``$output`` or
``$state``, however some RTLIL cells such as ``$assert`` or ``$anyseq`` generate
auxiliary inputs/outputs/states that are given a different kind to distinguish
them from ordinary RTLIL inputs/outputs/states.

- To access an individual input/output/state, use ``ir.input(name, kind)``,
  ``ir.output(name, kind)`` or ``ir.state(name, kind)``. ``kind`` defaults to
  the default kind.
- To iterate over all inputs/outputs/states of a certain kind, methods
  ``ir.inputs``, ``ir.outputs``, ``ir.states`` are provided. Their argument
  defaults to the default kinds mentioned.
- To iterate over inputs/outputs/states of any kind, use ``ir.all_inputs``,
  ``ir.all_outputs`` and ``ir.all_states``.
- Outputs have a node that indicate the value of the output, this can be
  retrieved via ``output.value()``.
- States have a node that indicate the next value of the state, this can be
  retrieved via ``state.next_value()``. They also have an initial value that is
  accessed as either ``state.initial_value_signal()`` or
  ``state.initial_value_memory()``, depending on their sort.

Each node has a "function", which defines its operation (for a complete list of
functions and a specification of their operation, see ``functional.h``).
Functions are represented as an enum ``Functional::Fn`` and the function field
can be accessed as ``node.fn()``. Since the most common operation is a switch
over the function that also accesses the arguments, the ``Node`` class provides
a method ``visit`` that implements the visitor pattern. For example, for an
addition node ``node`` with arguments ``n1`` and ``n2``, ``node.visit(visitor)``
would call ``visitor.add(node, n1, n2)``. Thus typically one would implement a
class with a method for every function. Visitors should inherit from either
``Functional::AbstractVisitor<ReturnType>`` or
``Functional::DefaultVisitor<ReturnType>``. The former will produce a compiler
error if a case is unhandled, the latter will call ``default_handler(node)``
instead. Visitor methods should be marked as ``override`` to provide compiler
errors if the arguments are wrong.

Utility classes
~~~~~~~~~~~~~~~

``functional.h`` also provides utility classes that are independent of the main
FunctionalIR representation but are likely to be useful for backends.

``Functional::Writer`` provides a simple formatting class that wraps a
``std::ostream`` and provides the following methods:

- ``writer << value`` wraps ``os << value``.
- ``writer.print(fmt, value0, value1, value2, ...)`` replaces ``{0}``, ``{1}``,
  ``{2}``, etc in the string ``fmt`` with ``value0``, ``value1``, ``value2``,
  resp. Each value is formatted using ``os << value``. It is also possible to
  write ``{}`` to refer to one past the last index, i.e. ``{1} {} {} {7} {}`` is
  equivalent to ``{1} {2} {3} {7} {8}``.
- ``writer.print_with(fn, fmt, value0, value1, value2, ...)`` functions much the
  same as ``print`` but it uses ``os << fn(value)`` to print each value and
  falls back to ``os << value`` if ``fn(value)`` is not legal.

``Functional::Scope`` keeps track of variable names in a target language. It is
used to translate between different sets of legal characters and to avoid
accidentally re-defining identifiers. Users should derive a class from ``Scope``
and supply the following:

- ``Scope<Id>`` takes a template argument that specifies a type that's used to
  uniquely distinguish variables. Typically this would be ``int`` (if variables
  are used for ``Functional::IR`` nodes) or ``IdString``.
- The derived class should provide a constructor that calls ``reserve`` for
  every reserved word in the target language.
- A method ``bool is_character_legal(char c, int index)`` has to be provided
  that returns ``true`` iff ``c`` is legal in an identifier at position
  ``index``.

Given an instance ``scope`` of the derived class, the following methods are then
available:

- ``scope.reserve(std::string name)`` marks the given name as being in-use
- ``scope.unique_name(IdString suggestion)`` generates a previously unused name
  and attempts to make it similar to ``suggestion``.
- ``scope(Id id, IdString suggestion)`` functions similar to ``unique_name``,
  except that multiple calls with the same ``id`` are guaranteed to retrieve the
  same name (independent of ``suggestion``).

``sexpr.h`` provides classes that represent and pretty-print s-expressions.
S-expressions can be constructed with ``SExpr::list``, for example ``SExpr expr
= SExpr::list("add", "x", SExpr::list("mul", "y", "z"))`` represents ``(add x
(mul y z))`` (by adding ``using SExprUtil::list`` to the top of the file,
``list`` can be used as shorthand for ``SExpr::list``). For prettyprinting,
``SExprWriter`` wraps an ``std::ostream`` and provides the following methods:

- ``writer << sexpr`` writes the provided expression to the output, breaking
  long lines and adding appropriate indentation.
- ``writer.open(sexpr)`` is similar to ``writer << sexpr`` but will omit the
  last closing parenthesis. Further arguments can then be added separately with
  ``<<`` or ``open``. This allows for printing large s-expressions without
  needing to construct the whole expression in memory first.
- ``writer.open(sexpr, false)`` is similar to ``writer.open(sexpr)`` but further
  arguments will not be indented. This is used to avoid unlimited indentation on
  structures with unlimited nesting.
- ``writer.close(n = 1)`` closes the last ``n`` open s-expressions.
- ``writer.push()`` and ``writer.pop()`` are used to automatically close
  s-expressions. ``writer.pop()`` closes all s-expressions opened since the last
  call to ``writer.push()``.
- ``writer.comment(string)`` writes a comment on a separate-line.
  ``writer.comment(string, true)`` appends a comment to the last printed
  s-expression.
- ``writer.flush()`` flushes any buffering and should be called before any
  direct access to the underlying ``std::ostream``. It does not close unclosed
  parentheses.
- The destructor calls ``flush`` but also closes all unclosed parentheses.

.. _minimal backend:

Example: A minimal functional backend
-------------------------------------

At its most basic, there are three steps we need to accomplish for a minimal
functional backend.  First, we need to convert our design into FunctionalIR.
This is most easily done by calling the ``Functional::IR::from_module()`` static
method with our top-level module, or iterating over and converting each of the
modules in our design.  Second, we need to handle each of the
``Functional::Node``\ s in our design.  Iterating over the ``Functional::IR``
includes reading the module inputs and current state, but not writing the
results.  So our final step is to handle the outputs and next state.

In order to add an output command to Yosys, we implement the ``Yosys::Backend``
class and provide an instance of it:

.. literalinclude:: /code_examples/functional/dummy.cc
   :language: c++
   :caption: Example source code for a minimal functional backend, ``dummy.cc``

Because we are using the ``Backend`` class, our ``"functional_dummy"`` is
registered as the ``write_functional_dummy`` command.  The ``execute`` method is
the part that runs when the user calls the command, handling any options,
preparing the output file for writing, and iterating over selected modules in
the design.  Since we don't have any options here, we set ``argidx = 1`` and
call the ``extra_args()`` method.  This method will read the command arguments,
raising an error if there are any unexpected ones.  It will also assign the
pointer ``f`` to the output file, or stdout if none is given.

.. note::

   For more on adding new commands to Yosys and how they work, refer to
   :doc:`/yosys_internals/extending_yosys/extensions`.

For this minimal example all we are doing is printing out each node.  The
``node.name()`` method returns an ``RTLIL::IdString``, which we convert for
printing with ``unescape()``.  Then, to print the function of the node, we use
``node.to_string()`` which gives us a string of the form ``function(args)``. The
``function`` part is the result of ``Functional::IR::fn_to_string(node.fn())``;
while ``args`` is the zero or more arguments passed to the function, most
commonly the name of another node.  Behind the scenes, the ``node.to_string()``
method actually wraps ``node.visit(visitor)`` with a private visitor whose
return type is ``std::string``.

Finally we iterate over the module's outputs and states, using
``Functional::IROutput::value()`` and ``Functional::IRState::next_value()``
respectively in order to get the results of the transfer function.

Example: Adapting SMT-LIB backend for Rosette
---------------------------------------------

This section will introduce the SMT-LIB functional backend
(`write_functional_smt2`) and what changes are needed to work with another
s-expression target, `Rosette`_ (`write_functional_rosette`).

.. _Rosette: http://emina.github.io/rosette/

Overview
~~~~~~~~

   Rosette is a solver-aided programming language that extends `Racket`_ with
   language constructs for program synthesis, verification, and more. To verify
   or synthesize code, Rosette compiles it to logical constraints solved with
   off-the-shelf `SMT`_ solvers.

   -- https://emina.github.io/rosette/

.. _Racket: http://racket-lang.org/
.. _SMT: http://smtlib.cs.uiowa.edu/

Rosette, being backed by SMT solvers and written with s-expressions, uses code
very similar to the `write_functional_smt2` output.  As a result, the SMT-LIB
functional backend can be used as a starting point for implementing a Rosette
backend.

Full code listings for the initial SMT-LIB backend and the converted Rosette
backend are included in the Yosys source repository under
:file:`backends/functional` as ``smtlib.cc`` and ``smtlib_rosette.cc``
respectively.  Note that the Rosette language is an extension of the Racket
language; this guide tends to refer to Racket when talking about the underlying
semantics/syntax of the language.

The major changes from the SMT-LIB backend are as follows:

- all of the ``Smt`` prefixes in names are replaced with ``Smtr`` to mean
  ``smtlib_rosette``;
- syntax is adjusted for Racket;
- data structures for input/output/state are changed from using
  ``declare-datatype`` with statically typed fields, to using ``struct`` with no
  static typing;
- the transfer function also loses its static typing;
- sign/zero extension in Rosette use the output width instead of the number of
  extra bits, gaining static typing;
- the single scope is traded for a global scope with local scope for each
  struct;
- initial state is provided as a constant value instead of a set of assertions;
- and the ``-provides`` option is introduced to more easily use generated code
  within Rosette based applications.

Scope
~~~~~

Our first addition to the `minimal backend`_ above is that for both SMT-LIB and
Rosette backends, we are now targetting real languages which bring with them
their own sets of constraints with what we can use as identifiers.  This is
where the ``Functional::Scope`` class described above comes in; by using this
class we can safely rename our identifiers in the generated output without
worrying about collisions or illegal names/characters.

In the SMT-LIB version, the ``SmtScope`` class implements ``Scope``;
provides a constructor that iterates over a list of reserved keywords, calling
``reserve`` on each; and defines the ``is_character_legal`` method to reject any
characters which are not allowed in SMT-LIB variable names to then be replaced
with underscores in the output.  To use this scope we create an instance of it,
and call the ``Scope::unique_name()`` method to generate a unique and legal name
for each of our identifiers.

In the Rosette version we update the list of legal ascii characters in the
``is_character_legal`` method to only those allowed in Racket variable names.

.. literalinclude:: /generated/functional/rosette.diff
   :language: diff
   :caption: diff of ``Scope`` class
   :start-at: -struct SmtScope : public Functional::Scope {
   :end-at: };

For the reserved keywords we trade the SMT-LIB specification for Racket to
prevent parts of our design from accidentally being treated as Racket code. We
also no longer need to reserve ``pair``, ``first``, and ``second``.  In
`write_functional_smt2` these are used for combining the ``(inputs,
current_state)`` and ``(outputs, next_state)`` into a single variable.  Racket
provides this functionality natively with ``cons``, which we will see later.

.. inlined diff for skipping the actual lists
.. code-block:: diff
   :caption: diff of ``reserved_keywords`` list

    const char *reserved_keywords[] = {
   -  // reserved keywords from the smtlib spec
   -  ...
   +  // reserved keywords from the racket spec
   +  ...

      // reserved for our own purposes
   -  "pair", "Pair", "first", "second",
   -  "inputs", "state",
   +  "inputs", "state", "name",
      nullptr
    };

.. note:: We skip over the actual list of reserved keywords from both the smtlib
   and racket specifications to save on space in this document.

Sort
~~~~

Next up in `write_functional_smt2` we see the ``Sort`` class.  This is a wrapper
for the ``Functional::Sort`` class, providing the additional functionality of
mapping variable declarations to s-expressions with the ``to_sexpr()`` method.
The main change from ``SmtSort`` to ``SmtrSort`` is a syntactical one with
signals represented as ``bitvector``\ s, and memories as ``list``\ s of signals.

.. literalinclude:: /generated/functional/rosette.diff
   :language: diff
   :caption: diff of ``Sort`` wrapper
   :start-at: SExpr to_sexpr() const {
   :end-before: };

Struct
~~~~~~

As we saw in the `minimal backend`_ above, the ``Functional::IR`` class tracks
the set of inputs, the set of outputs, and the set of "state" variables.  The
SMT-LIB backend maps each of these sets into its own ``SmtStruct``, with each
variable getting a corresponding field in the struct and a specified `Sort`_.
`write_functional_smt2` then defines each of these structs as a new
``datatype``, with each element being strongly-typed.

In Rosette, rather than defining new datatypes for our structs, we use the
native ``struct``.  We also only declare each field by name because Racket
provides less static typing.  For ease of use, we provide the expected type for
each field as comments.

.. literalinclude:: /generated/functional/rosette.diff
   :language: diff
   :caption: diff of ``write_definition`` method
   :start-at: void write_definition
   :end-before: template<typename Fn> void write_value

Each field is added to the ``SmtStruct`` with the ``insert`` method, which also
reserves a unique name (or accessor) within the `Scope`_.  These accessors
combine the struct name and f