aboutsummaryrefslogtreecommitdiffstats
path: root/docs/source/CHAPTER_Overview.rst
diff options
context:
space:
mode:
authorKrystalDelusion <93062060+KrystalDelusion@users.noreply.github.com>2022-11-16 00:55:22 +1300
committerGitHub <noreply@github.com>2022-11-15 12:55:22 +0100
commita14dec79ebc85fae807684fa027d8098a16a4d34 (patch)
treef05562ce671f452f6d29a90219cced0b37c1aae4 /docs/source/CHAPTER_Overview.rst
parent853f4bb3c695d9f5183ef5064ec4cf9cdd8b5300 (diff)
downloadyosys-a14dec79ebc85fae807684fa027d8098a16a4d34.tar.gz
yosys-a14dec79ebc85fae807684fa027d8098a16a4d34.tar.bz2
yosys-a14dec79ebc85fae807684fa027d8098a16a4d34.zip
Rst docs conversion (#3496)
Rst docs conversion
Diffstat (limited to 'docs/source/CHAPTER_Overview.rst')
-rw-r--r--docs/source/CHAPTER_Overview.rst571
1 files changed, 571 insertions, 0 deletions
diff --git a/docs/source/CHAPTER_Overview.rst b/docs/source/CHAPTER_Overview.rst
new file mode 100644
index 000000000..10d2ce478
--- /dev/null
+++ b/docs/source/CHAPTER_Overview.rst
@@ -0,0 +1,571 @@
+.. _chapter:overview:
+
+Implementation overview
+=======================
+
+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`_.
+
+.. _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
+
+As of this writing a Yosys VHDL frontend is in development.
+
+Yosys is written in C++ (using some features from the new C++11 standard). 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.
+
+Simplified data flow
+--------------------
+
+:numref:`Figure %s <fig:Overview_flow>` shows the simplified data flow within
+Yosys. Rectangles in the figure represent program modules and ellipses internal
+data structures that are used to exchange design data between the program
+modules.
+
+Design data is read in using one of the frontend modules. The high-level HDL
+frontends for Verilog and VHDL code generate an abstract syntax tree (AST) that
+is then passed to the AST frontend. Note that both HDL frontends use the same
+AST representation that is powerful enough to cover the Verilog HDL and VHDL
+language.
+
+The AST Frontend then compiles the AST to Yosys's main internal data format, the
+RTL Intermediate Language (RTLIL). A more detailed description of this format is
+given in the next section.
+
+There is also a text representation of the RTLIL data structure that can be
+parsed using the RTLIL Frontend.
+
+The design data may then be transformed using a series of passes that all
+operate on the RTLIL representation of the design.
+
+Finally the design in RTLIL representation is converted back to text by one of
+the backends, namely the Verilog Backend for generating Verilog netlists and the
+RTLIL Backend for writing the RTLIL data in the same format that is understood
+by the RTLIL Frontend.
+
+With the exception of the AST Frontend, which is called by the high-level HDL
+frontends and can't be called directly by the user, all program modules are
+called by the user (usually using a synthesis script that contains text commands
+for Yosys).
+
+By combining passes in different ways and/or adding additional passes to Yosys
+it is possible to adapt Yosys to a wide range of applications. For this to be
+possible it is key that (1) all passes operate on the same data structure
+(RTLIL) and (2) that this data structure is powerful enough to represent the
+design in different stages of the synthesis.
+
+.. figure:: ../images/overview_flow.*
+ :class: width-helper
+ :name: fig:Overview_flow
+
+ Yosys simplified data flow (ellipses: data structures, rectangles:
+ program modules)
+
+The RTL Intermediate Language (RTLIL)
+-------------------------------------
+
+All frontends, passes and backends in Yosys operate on a design in RTLIL
+representation. The only exception are the high-level frontends that use the AST
+representation as an intermediate step before generating RTLIL data.
+
+In order to avoid reinventing names for the RTLIL classes, they are simply
+referred to by their full C++ name, i.e. including the RTLIL:: namespace prefix,
+in this document.
+
+:numref:`Figure %s <fig:Overview_RTLIL>` shows a simplified Entity-Relationship
+Diagram (ER Diagram) of RTLIL. In :math:`1:N` relationships the arrow points
+from the :math:`N` side to the :math:`1`. For example one RTLIL::Design contains
+:math:`N` (zero to many) instances of RTLIL::Module. A two-pointed arrow
+indicates a :math:`1:1` relationship.
+
+The RTLIL::Design is the root object of the RTLIL data structure. There is
+always one "current design" in memory which passes operate on, frontends add
+data to and backends convert to exportable formats. But in some cases passes
+internally generate additional RTLIL::Design objects. For example when a pass is
+reading an auxiliary Verilog file such as a cell library, it might create an
+additional RTLIL::Design object and call the Verilog frontend with this other
+object to parse the cell library.
+
+.. figure:: ../images/overview_rtlil.*
+ :class: width-helper
+ :name: fig:Overview_RTLIL
+
+ Simplified RTLIL Entity-Relationship Diagram
+
+There is only one active RTLIL::Design object that is used by all frontends,
+passes and backends called by the user, e.g. using a synthesis script. The
+RTLIL::Design then contains zero to many RTLIL::Module objects. This corresponds
+to modules in Verilog or entities in VHDL. Each module in turn contains objects
+from three different categories:
+
+- RTLIL::Cell and RTLIL::Wire objects represent classical netlist data.
+
+- RTLIL::Process objects represent the decision trees (if-then-else statements,
+ etc.) and synchronization declarations (clock signals and sensitivity) from
+ Verilog always and VHDL process blocks.
+
+- RTLIL::Memory objects represent addressable memories (arrays).
+
+Usually the output of the synthesis procedure is a netlist, i.e. all
+RTLIL::Process and RTLIL::Memory objects must be replaced by RTLIL::Cell and
+RTLIL::Wire objects by synthesis passes.
+
+All features of the HDL that cannot be mapped directly to these RTLIL classes
+must be transformed to an RTLIL-compatible representation by the HDL frontend.
+This includes Verilog-features such as generate-blocks, loops and parameters.
+
+The following sections contain a more detailed description of the different
+parts of RTLIL and rationale behind some of the design decisions.
+
+RTLIL identifiers
+~~~~~~~~~~~~~~~~~
+
+All identifiers in RTLIL (such as module names, port names, signal names, cell
+types, etc.) follow the following naming convention: they must either start with
+a backslash (\) or a dollar sign ($).
+
+Identifiers starting with a backslash are public visible identifiers. Usually
+they originate from one of the HDL input files. For example the signal name
+"\\sig42" is most likely a signal that was declared using the name "sig42" in an
+HDL input file. On the other hand the signal name "$sig42" is an auto-generated
+signal name. The backends convert all identifiers that start with a dollar sign
+to identifiers that do not collide with identifiers that start with a backslash.
+
+This has three advantages:
+
+- First, it is impossible that an auto-generated identifier collides with an
+ identifier that was provided by the user.
+
+- Second, the information about which identifiers were originally provided by
+ the user is always available which can help guide some optimizations. For
+ example the "opt_rmunused" tries to preserve signals with a user-provided
+ name but doesn't hesitate to delete signals that have auto-generated names
+ when they just duplicate other signals.
+
+- Third, the delicate job of finding suitable auto-generated public visible
+ names is deferred to one central location. Internally auto-generated names
+ that may hold important information for Yosys developers can be used without
+ disturbing external tools. For example the Verilog backend assigns names in
+ the form \_integer\_.
+
+Whitespace and control characters (any character with an ASCII code 32 or less)
+are not allowed in RTLIL identifiers; most frontends and backends cannot support
+these characters in identifiers.
+
+In order to avoid programming errors, the RTLIL data structures check if all
+identifiers start with either a backslash or a dollar sign, and contain no
+whitespace or control characters. Violating these rules results in a runtime
+error.
+
+All RTLIL identifiers are case sensitive.
+
+Some transformations, such as flattening, may have to change identifiers
+provided by the user to avoid name collisions. When that happens, attribute
+"hdlname" is attached to the object with the changed identifier. This attribute
+contains one name (if emitted directly by the frontend, or is a result of
+disambiguation) or multiple names separated by spaces (if a result of
+flattening). All names specified in the "hdlname" attribute are public and do
+not include the leading "\".
+
+RTLIL::Design and RTLIL::Module
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The RTLIL::Design object is basically just a container for RTLIL::Module
+objects. In addition to a list of RTLIL::Module objects the RTLIL::Design also
+keeps a list of selected objects, i.e. the objects that passes should operate
+on. In most cases the whole design is selected and therefore passes operate on
+the whole design. But this mechanism can be useful for more complex synthesis
+jobs in which only parts of the design should be affected by certain passes.
+
+Besides the objects shown in the ER diagram in :numref:`Fig. %s
+<fig:Overview_RTLIL>` an RTLIL::Module object contains the following additional
+properties:
+
+- The module name
+- A list of attributes
+- A list of connections between wires
+- An optional frontend callback used to derive parametrized variations of the
+ module
+
+The attributes can be Verilog attributes imported by the Verilog frontend or
+attributes assigned by passes. They can be used to store additional metadata
+about modules or just mark them to be used by certain part of the synthesis
+script but not by others.
+
+Verilog and VHDL both support parametric modules (known as "generic entities" in
+VHDL). The RTLIL format does not support parametric modules itself. Instead each
+module contains a callback function into the AST frontend to generate a
+parametrized variation of the RTLIL::Module as needed. This callback then
+returns the auto-generated name of the parametrized variation of the module. (A
+hash over the parameters and the module name is used to prohibit the same
+parametrized variation from being generated twice. For modules with only a few
+parameters, a name directly containing all parameters is generated instead of a
+hash string.)
+
+.. _sec:rtlil_cell_wire:
+
+RTLIL::Cell and RTLIL::Wire
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+A module contains zero to many RTLIL::Cell and RTLIL::Wire objects. Objects of
+these types are used to model netlists. Usually the goal of all synthesis
+efforts is to convert all modules to a state where the functionality of the
+module is implemented only by cells from a given cell library and wires to
+connect these cells with each other. Note that module ports are just wires with
+a special property.
+
+An RTLIL::Wire object has the following properties:
+
+- The wire name
+- A list of attributes
+- A width (buses are just wires with a width > 1)
+- Bus direction (MSB to LSB or vice versa)
+- Lowest valid bit index (LSB or MSB depending on bus direction)
+- If the wire is a port: port number and direction (input/output/inout)
+
+As with modules, the attributes can be Verilog attributes imported by the
+Verilog frontend or attributes assigned by passes.
+
+In Yosys, busses (signal vectors) are represented using a single wire object
+with a width > 1. So Yosys does not convert signal vectors to individual
+signals. This makes some aspects of RTLIL more complex but enables Yosys to be
+used for coarse grain synthesis where the cells of the target architecture
+operate on entire signal vectors instead of single bit wires.
+
+In Verilog and VHDL, busses may have arbitrary bounds, and LSB can have either
+the lowest or the highest bit index. In RTLIL, bit 0 always corresponds to LSB;
+however, information from the HDL frontend is preserved so that the bus will be
+correctly indexed in error messages, backend output, constraint files, etc.
+
+An RTLIL::Cell object has the following properties:
+
+- The cell name and type
+- A list of attributes
+- A list of parameters (for parametric cells)
+- Cell ports and the connections of ports to wires and constants
+
+The connections of ports to wires are coded by assigning an RTLIL::SigSpec to
+each cell port. The RTLIL::SigSpec data type is described in the next section.
+
+.. _sec:rtlil_sigspec:
+
+RTLIL::SigSpec
+~~~~~~~~~~~~~~
+
+A "signal" is everything that can be applied to a cell port. I.e.
+
+- | Any constant value of arbitrary bit-width
+ | 1em For example: ``1337, 16'b0000010100111001, 1'b1, 1'bx``
+
+- | All bits of a wire or a selection of bits from a wire
+ | 1em For example: ``mywire, mywire[24], mywire[15:8]``
+
+- | Concatenations of the above
+ | 1em For example: ``{16'd1337, mywire[15:8]}``
+
+The RTLIL::SigSpec data type is used to represent signals. The RTLIL::Cell
+object contains one RTLIL::SigSpec for each cell port.
+
+In addition, connections between wires are represented using a pair of
+RTLIL::SigSpec objects. Such pairs are needed in different locations. Therefore
+the type name RTLIL::SigSig was defined for such a pair.
+
+.. _sec:rtlil_process:
+
+RTLIL::Process
+~~~~~~~~~~~~~~
+
+When a high-level HDL frontend processes behavioural code it splits it up into
+data path logic (e.g. the expression a + b is replaced by the output of an adder
+that takes a and b as inputs) and an RTLIL::Process that models the control
+logic of the behavioural code. Let's consider a simple example:
+
+.. code:: verilog
+ :number-lines:
+
+ module ff_with_en_and_async_reset(clock, reset, enable, d, q);
+ input clock, reset, enable, d;
+ output reg q;
+ always @(posedge clock, posedge reset)
+ if (reset)
+ q <= 0;
+ else if (enable)
+ q <= d;
+ endmodule
+
+In this example there is no data path and therefore the RTLIL::Module generated
+by the frontend only contains a few RTLIL::Wire objects and an RTLIL::Process.
+The RTLIL::Process in RTLIL syntax:
+
+.. code:: RTLIL
+ :number-lines:
+
+ process $proc$ff_with_en_and_async_reset.v:4$1
+ assign $0\q[0:0] \q
+ switch \reset
+ case 1'1
+ assign $0\q[0:0] 1'0
+ case
+ switch \enable
+ case 1'1
+ assign $0\q[0:0] \d
+ case
+ end
+ end
+ sync posedge \clock
+ update \q $0\q[0:0]
+ sync posedge \reset
+ update \q $0\q[0:0]
+ end
+
+This RTLIL::Process contains two RTLIL::SyncRule objects, two RTLIL::SwitchRule
+objects and five RTLIL::CaseRule objects. The wire $0\q[0:0] is an automatically
+created wire that holds the next value of \\q. The lines :math:`2 \dots 12`
+describe how $0\q[0:0] should be calculated. The lines :math:`13 \dots 16`
+describe how the value of $0\q[0:0] is used to update \\q.
+
+An RTLIL::Process is a container for zero or more RTLIL::SyncRule objects and
+exactly one RTLIL::CaseRule object, which is called the root case.
+
+An RTLIL::SyncRule object contains an (optional) synchronization condition
+(signal and edge-type), zero or more assignments (RTLIL::SigSig), and zero or
+more memory writes (RTLIL::MemWriteAction). The always synchronization condition
+is used to break combinatorial loops when a latch should be inferred instead.
+
+An RTLIL::CaseRule is a container for zero or more assignments (RTLIL::SigSig)
+and zero or more RTLIL::SwitchRule objects. An RTLIL::SwitchRule objects is a
+container for zero or more RTLIL::CaseRule objects.
+
+In the above example the lines :math:`2 \dots 12` are the root case. Here
+$0\q[0:0] is first assigned the old value \\q as default value (line 2). The
+root case also contains an RTLIL::SwitchRule object (lines :math:`3 \dots 12`).
+Such an object is very similar to the C switch statement as it uses a control
+signal (\\reset in this case) to determine which of its cases should be active.
+The RTLIL::SwitchRule object then contains one RTLIL::CaseRule object per case.
+In this example there is a case [1]_ for \\reset == 1 that causes $0\q[0:0] to
+be set (lines 4 and 5) and a default case that in turn contains a switch that
+sets $0\q[0:0] to the value of \\d if \\enable is active (lines :math:`6 \dots
+11`).
+
+A case can specify zero or more compare values that will determine whether it
+matches. Each of the compare values must be the exact same width as the control
+signal. When more than one compare value is specified, the case matches if any
+of them matches the control signal; when zero compare values are specified, the
+case always matches (i.e. it is the default case).
+
+A switch prioritizes cases from first to last: multiple cases can match, but
+only the first matched case becomes active. This normally synthesizes to a
+priority encoder. The parallel_case attribute allows passes to assume that no
+more than one case will match, and full_case attribute allows passes to assume
+that exactly one case will match; if these invariants are ever dynamically
+violated, the behavior is undefined. These attributes are useful when an
+invariant invisible to the synthesizer causes the control signal to never take
+certain bit patterns.
+
+The lines :math:`13 \dots 16` then cause \\q to be updated whenever there is a
+positive clock edge on \\clock or \\reset.
+
+In order to generate such a representation, the language frontend must be able
+to handle blocking and nonblocking assignments correctly. However, the language
+frontend does not need to identify the correct type of storage element for the
+output signal or generate multiplexers for the decision tree. This is done by
+passes that work on the RTLIL representation. Therefore it is relatively easy to
+substitute these steps with other algorithms that target different target
+architectures or perform optimizations or other transformations on the decision
+trees before further processing them.
+
+One of the first actions performed on a design in RTLIL representation in most
+synthesis scripts is identifying asynchronous resets. This is usually done using
+the proc_arst pass. This pass transforms the above example to the following
+RTLIL::Process:
+
+.. code:: RTLIL
+ :number-lines:
+
+ process $proc$ff_with_en_and_async_reset.v:4$1
+ assign $0\q[0:0] \q
+ switch \enable
+ case 1'1
+ assign $0\q[0:0] \d
+ case
+ end
+ sync posedge \clock
+ update \q $0\q[0:0]
+ sync high \reset
+ update \q 1'0
+ end
+
+This pass has transformed the outer RTLIL::SwitchRule into a modified
+RTLIL::SyncRule object for the \\reset signal. Further processing converts the
+RTLIL::Process into e.g. a d-type flip-flop with asynchronous reset and a
+multiplexer for the enable signal:
+
+.. code:: RTLIL
+ :number-lines:
+
+ cell $adff $procdff$6
+ parameter \ARST_POLARITY 1'1
+ parameter \ARST_VALUE 1'0
+ parameter \CLK_POLARITY 1'1
+ parameter \WIDTH 1
+ connect \ARST \reset
+ connect \CLK \clock
+ connect \D $0\q[0:0]
+ connect \Q \q
+ end
+ cell $mux $procmux$3
+ parameter \WIDTH 1
+ connect \A \q
+ connect \B \d
+ connect \S \enable
+ connect \Y $0\q[0:0]
+ end
+
+Different combinations of passes may yield different results. Note that $adff
+and $mux are internal cell types that still need to be mapped to cell types from
+the target cell library.
+
+Some passes refuse to operate on modules that still contain RTLIL::Process
+objects as the presence of these objects in a module increases the complexity.
+Therefore the passes to translate processes to a netlist of cells are usually
+called early in a synthesis script. The proc pass calls a series of other passes
+that together perform this conversion in a way that is suitable for most
+synthesis tasks.
+
+.. _sec:rtlil_memory:
+
+RTLIL::Memory
+~~~~~~~~~~~~~
+
+For every array (memory) in the HDL code an RTLIL::Memory object is created. A
+memory object has the following properties:
+
+- The memory name
+- A list of attributes
+- The width of an addressable word
+- The size of the memory in number of words
+
+All read accesses to the memory are transformed to $memrd cells and all write
+accesses to $memwr cells by the language frontend. These cells consist of
+independent read- and write-ports to the memory. Memory initialization is
+transformed to $meminit cells by the language frontend. The ``\MEMID`` parameter
+on these cells is used to link them together and to the RTLIL::Memory object
+they belong to.
+
+The rationale behind using separate cells for the individual ports versus
+creating a large multiport memory cell right in the language frontend is that
+the separate $memrd and $memwr cells can be consolidated using resource sharing.
+As resource sharing is a non-trivial optimization problem where different
+synthesis tasks can have different requirements it lends itself to do the
+optimisation in separate passes and merge the RTLIL::Memory objects and $memrd
+and $memwr cells to multiport memory blocks after resource sharing is completed.
+
+The memory pass performs this conversion and can (depending on the options
+passed to it) transform the memories directly to d-type flip-flops and address
+logic or yield multiport memory blocks (represented using $mem cells).
+
+See :numref:`Sec. %s <sec:memcells>` for details about the memory cell types.
+
+Command interface and synthesis scripts
+---------------------------------------
+
+Yosys reads and processes commands from synthesis scripts, command line
+arguments and an interactive command prompt. Yosys commands consist of a command
+name and an optional whitespace separated list of arguments. Commands are
+terminated using the newline character or a semicolon (;). Empty lines and lines
+starting with the hash sign (#) are ignored. See :numref:`Sec. %s
+<sec:typusecase>` for an example synthesis script.
+
+The command help can be used to access the command reference manual.
+
+Most commands can operate not only on the entire design but also specifically on
+selected parts of the design. For example the command dump will print all
+selected objects in the current design while dump foobar will only print the
+module foobar and dump \* will print the entire design regardless of the current
+selection.
+
+.. code:: yoscrypt
+
+ dump */t:$add %x:+[A] \*/w:\* %i
+
+The selection mechanism is very powerful. For example the command above will
+print all wires that are connected to the ``\A`` port of a ``$add`` cell.
+Detailed documentation of the select framework can be found in the command
+reference for the ``select`` command.
+
+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.
+
+- | 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
+ (rtlil.h and rtlil.cc), the main() function (driver.cc), the internal
+ framework for generating log messages (log.h and log.cc), the internal
+ framework for registering and calling passes (register.h and register.cc),
+ some core commands that are not really passes (select.cc, show.cc, …) and a
+ couple of other small utility libraries.
+
+- | passes/
+ | This directory contains a subdirectory for each pass or group of passes.
+ For example as of this writing the directory passes/opt/ contains the code
+ for seven passes: opt, opt_expr, opt_muxtree, opt_reduce, opt_rmdff,
+ opt_rmunused and opt_merge.
+
+- | techlibs/
+ | This directory contains simulation models and standard implementations for
+ the cells from the internal cell library.
+
+- | tests/
+ | This directory contains a couple of test cases. Most of the smaller tests
+ are executed automatically when make test is called. The larger tests must
+ be executed manually. Most of the larger tests require downloading external
+ HDL source code and/or external tools. The tests range from comparing
+ simulation results of the synthesized design to the original sources to
+ logic equivalence checking of entire CPU cores.
+
+The top-level Makefile includes frontends/\*/Makefile.inc,
+passes/\*/Makefile.inc and backends/\*/Makefile.inc. So when extending Yosys it
+is enough to create a new directory in frontends/, passes/ or backends/ with
+your sources and a Makefile.inc. 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 passes/opt/opt_rmdff.cc and passes/opt/opt_merge.cc.
+
+See the top-level README file for a quick Getting Started guide and build
+instructions. The Yosys build is based solely on Makefiles.
+
+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.
+
+.. [1]
+ The syntax 1'1 in the RTLIL code specifies a constant with a length of one
+ bit (the first "1"), and this bit is a one (the second "1").