Tidy/reflow some things

This commit is contained in:
Krystine Sherwin 2023-08-03 10:23:39 +12:00
parent 2c75b103d6
commit 4b40372446
No known key found for this signature in database
10 changed files with 433 additions and 443 deletions

View File

@ -189,13 +189,13 @@ 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 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. 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 (Note that there is no problem if this coding techniques are used to model ROM,
model ROM, where the register is initialized using this syntax but is where the register is initialized using this syntax but is never updated
never updated otherwise.) otherwise.)
:numref:`amber23.ys` shows the synthesis script for the Amber23 core. In line 17 :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 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 ``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 design hierarchy and then all module instantiations are altered so that this new
signal is connected throughout the whole design hierarchy. signal is connected throughout the whole design hierarchy.
@ -235,18 +235,18 @@ signal is connected throughout the whole design hierarchy.
endmodule endmodule
In line 18 the proc command is called. But in this script the signal In line 18 the ``proc`` command is called. But in this script the signal name
name globrst is passed to the command as a global reset signal for globrst is passed to the command as a global reset signal for resetting the
resetting the registers to their assigned initial values. registers to their assigned initial values.
Finally in line 19 the techmap command is used to replace all instances of 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 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 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 ``techmap_celltype`` attribute is used in line 1 to tell the techmap command
cells to replace in the design, how the \_TECHMAP_FAIL\_ wire in lines 15 and 16 which cells to replace in the design, how the ``_TECHMAP_FAIL_`` wire in lines
(which evaluates to a constant value) determines if the parameter set is 15 and 16 (which evaluates to a constant value) determines if the parameter set
compatible with this replacement circuit, and how the \_TECHMAP_DO\_ wire in is compatible with this replacement circuit, and how the ``_TECHMAP_DO_`` wire
line 13 provides a mini synthesis-script to be used to process this cell. in line 13 provides a mini synthesis-script to be used to process this cell.
.. code-block:: c .. code-block:: c
:caption: Test program for the Amber23 CPU (Sieve of Eratosthenes). Compiled :caption: Test program for the Amber23 CPU (Sieve of Eratosthenes). Compiled
@ -298,39 +298,36 @@ format as well.
.. _ABC: https://github.com/berkeley-abc/abc .. _ABC: https://github.com/berkeley-abc/abc
The only thing left to write about the simulation itself is that it The only thing left to write about the simulation itself is that it probably was
probably was one of the most energy inefficient and time consuming ways one of the most energy inefficient and time consuming ways of successfully
of successfully calculating the first 31 primes the author has ever calculating the first 31 primes the author has ever conducted.
conducted.
Limitations Limitations
=========== ===========
At the time of this writing Yosys does not support multi-dimensional At the time of this writing Yosys does not support multi-dimensional memories,
memories, does not support writing to individual bits of array elements, does not support writing to individual bits of array elements, does not support
does not support initialization of arrays with $readmemb and $readmemh, initialization of arrays with ``$readmemb`` and ``$readmemh``, and has only
and has only limited support for tristate logic, to name just a few limited support for tristate logic, to name just a few limitations.
limitations.
That being said, Yosys can synthesize an overwhelming majority of That being said, Yosys can synthesize an overwhelming majority of real-world
real-world Verilog RTL code. The remaining cases can usually be modified Verilog RTL code. The remaining cases can usually be modified to be compatible
to be compatible with Yosys quite easily. with Yosys quite easily.
The various designs in yosys-bigsim are a good place to look for The various designs in yosys-bigsim are a good place to look for examples of
examples of what is within the capabilities of Yosys. what is within the capabilities of Yosys.
Conclusion Conclusion
========== ==========
Yosys is a feature-rich Verilog-2005 synthesis tool. It has many uses, Yosys is a feature-rich Verilog-2005 synthesis tool. It has many uses, but one
but one is to provide an easy gateway from high-level Verilog code to is to provide an easy gateway from high-level Verilog code to low-level logic
low-level logic circuits. circuits.
The command line option -S can be used to quickly synthesize Verilog The command line option ``-S`` can be used to quickly synthesize Verilog code to
code to BLIF files without a hassle. BLIF files without a hassle.
With custom synthesis scripts it becomes possible to easily perform With custom synthesis scripts it becomes possible to easily perform high-level
high-level optimizations, such as re-encoding FSMs. In some extreme optimizations, such as re-encoding FSMs. In some extreme cases, such as the
cases, such as the Amber23 ARMv2 CPU, the more advanced Yosys features Amber23 ARMv2 CPU, the more advanced Yosys features can be used to change a
can be used to change a design to fit a certain need without actually design to fit a certain need without actually touching the RTL code.
touching the RTL code.

View File

@ -315,7 +315,7 @@ simply be abbreviated using the last part.
Usually all interactive work is done with one module selected using the ``cd`` 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 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 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 ``a*/b*`` would refer to all objects whose names start with ``b`` from all
modules whose names start with ``a``. modules whose names start with ``a``.
The ``dump`` command can be used to print all information about an object. For The ``dump`` command can be used to print all information about an object. For
@ -416,7 +416,7 @@ will select all ``$add ``cells that have the ``foo`` attribute set:
select t:$add a:foo %i select t:$add a:foo %i
The listing in :numref:`sumprod` uses the Yosys non-standard ``{... \*}`` syntax The listing in :numref:`sumprod` uses the Yosys non-standard ``{... *}`` syntax
to set the attribute ``sumstuff`` on all cells generated by the first assign to set the attribute ``sumstuff`` on all cells generated by the first assign
statement. (This works on arbitrary large blocks of Verilog code an can be used statement. (This works on arbitrary large blocks of Verilog code an can be used
to mark portions of code for analysis.) to mark portions of code for analysis.)
@ -467,7 +467,7 @@ 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 appended to the action. So for example the action ``%ci3`` is identical to
performing the ``%ci`` action three times. performing the ``%ci`` action three times.
The action ``%ci\*`` performs the ``%ci`` action over and over again until it The action ``%ci*`` performs the ``%ci`` action over and over again until it
has no effect anymore. has no effect anymore.
.. figure:: ../../images/011/select_prod.* .. figure:: ../../images/011/select_prod.*

View File

@ -43,15 +43,15 @@ directories:
simulation results of the synthesized design to the original sources to simulation results of the synthesized design to the original sources to
logic equivalence checking of entire CPU cores. logic equivalence checking of entire CPU cores.
The top-level Makefile includes frontends/\*/Makefile.inc, The top-level Makefile includes ``frontends/*/Makefile.inc``,
passes/\*/Makefile.inc and backends/\*/Makefile.inc. So when extending Yosys it ``passes/*/Makefile.inc`` and ``backends/*/Makefile.inc``. So when extending
is enough to create a new directory in frontends/, passes/ or backends/ with Yosys it is enough to create a new directory in ``frontends/``, ``passes/`` or
your sources and a Makefile.inc. The Yosys kernel automatically detects all ``backends/`` with your sources and a ``Makefile.inc``. The Yosys kernel
commands linked with Yosys. So it is not needed to add additional commands to a automatically detects all commands linked with Yosys. So it is not needed to add
central list of commands. additional commands to a central list of commands.
Good starting points for reading example source code to learn how to write 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. 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 See the top-level README file for a quick Getting Started guide and build
instructions. The Yosys build is based solely on Makefiles. instructions. The Yosys build is based solely on Makefiles.

View File

@ -99,14 +99,14 @@ Selections intro
~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~
Most commands can operate not only on the entire design but also specifically on 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 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 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 module ``foobar`` and ``dump *`` will print the entire design regardless of the
selection. current selection.
.. code:: yoscrypt .. code:: yoscrypt
dump */t:$add %x:+[A] \*/w:\* %i dump */t:$add %x:+[A] */w:* %i
The selection mechanism is very powerful. For example the command above will 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. print all wires that are connected to the ``\A`` port of a ``$add`` cell.

View File

@ -50,15 +50,6 @@ What you can do with Yosys
- Perform all kinds of operations on netlist (RTL, Logic, Gate) - Perform all kinds of operations on netlist (RTL, Logic, Gate)
- Perform logic optimizations and gate mapping with ABC - Perform logic optimizations and gate mapping with ABC
Things you can't do
~~~~~~~~~~~~~~~~~~~
- Process high-level languages such as C/C++/SystemC
- Create physical layouts (place&route)
+ Check out `nextpnr`_ for that
.. _nextpnr: https://github.com/YosysHQ/nextpnr
Typical applications for Yosys Typical applications for Yosys
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -71,12 +62,21 @@ Typical applications for Yosys
- Framework for building custom flows (Not limited to synthesis but also formal - Framework for building custom flows (Not limited to synthesis but also formal
verification, reverse engineering, ...) 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
.. _nextpnr: https://github.com/YosysHQ/nextpnr
Benefits of open source HDL synthesis Benefits of open source HDL synthesis
------------------------------------- -------------------------------------
- Cost (also applies to ``free as in free beer`` solutions): - Cost (also applies to ``free as in free beer`` solutions):
Today the cost for a mask set in $\unit[180]{nm}$ technology is far less than 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 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. ASIC flows are an important enabler for ASIC-level Open Source Hardware.

View File

@ -143,7 +143,7 @@ identifies cells with identical inputs and replaces them with a single instance
of the cell. of the cell.
The option ``-nomux`` can be used to disable resource sharing for multiplexer The option ``-nomux`` can be used to disable resource sharing for multiplexer
cells (``$mux`` and ``$pmux.`` This can be useful as it prevents 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 trees to be merged, which might prevent ``opt_muxtree`` to identify possible
optimizations. optimizations.

View File

@ -19,54 +19,53 @@ Transforming Verilog to AST
--------------------------- ---------------------------
The Verilog frontend converts the Verilog sources to an internal AST The Verilog frontend converts the Verilog sources to an internal AST
representation that closely resembles the structure of the original representation that closely resembles the structure of the original Verilog
Verilog code. The Verilog frontend consists of three components, the code. The Verilog frontend consists of three components, the Preprocessor, the
Preprocessor, the Lexer and the Parser. Lexer and the Parser.
The source code to the Verilog frontend can be found in The source code to the Verilog frontend can be found in ``frontends/verilog/``
frontends/verilog/ in the Yosys source tree. in the Yosys source tree.
The Verilog preprocessor The Verilog preprocessor
~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~
The Verilog preprocessor scans over the Verilog source code and The Verilog preprocessor scans over the Verilog source code and interprets some
interprets some of the Verilog compiler directives such as of the Verilog compiler directives such as :literal:`\`include`,
:literal:`\`include`, :literal:`\`define` and :literal:`\`ifdef`. :literal:`\`define` and :literal:`\`ifdef`.
It is implemented as a C++ function that is passed a file descriptor as It is implemented as a C++ function that is passed a file descriptor as input
input and returns the pre-processed Verilog code as a ``std::string``. and returns the pre-processed Verilog code as a ``std::string``.
The source code to the Verilog Preprocessor can be found in The source code to the Verilog Preprocessor can be found in
frontends/verilog/preproc.cc in the Yosys source tree. ``frontends/verilog/preproc.cc`` in the Yosys source tree.
The Verilog lexer The Verilog lexer
~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~
The Verilog Lexer is written using the lexer generator flex . Its source The Verilog Lexer is written using the lexer generator flex. Its source code
code can be found in frontends/verilog/verilog_lexer.l in the Yosys can be found in ``frontends/verilog/verilog_lexer.l`` in the Yosys source tree.
source tree. The lexer does little more than identifying all keywords The lexer does little more than identifying all keywords and literals recognised
and literals recognised by the Yosys Verilog frontend. by the Yosys Verilog frontend.
The lexer keeps track of the current location in the Verilog source code The lexer keeps track of the current location in the Verilog source code
using some global variables. These variables are used by the constructor using some global variables. These variables are used by the constructor
of AST nodes to annotate each node with the source code location it of AST nodes to annotate each node with the source code location it
originated from. originated from.
Finally the lexer identifies and handles special comments such as Finally the lexer identifies and handles special comments such as "``// synopsys
"``// synopsys translate_off``" and "``// synopsys full_case``". (It is translate_off``" and "``// synopsys full_case``". (It is recommended to use
recommended to use :literal:`\`ifdef` constructs instead of the :literal:`\`ifdef` constructs instead of the Synsopsys translate_on/off comments
Synsopsys translate_on/off comments and attributes such as and attributes such as ``(* full_case *)`` over "``// synopsys full_case``"
``(* full_case *)`` over "``// synopsys full_case``" whenever possible.) whenever possible.)
The Verilog parser The Verilog parser
~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~
The Verilog Parser is written using the parser generator bison . Its The Verilog Parser is written using the parser generator bison. Its source code
source code can be found in frontends/verilog/verilog_parser.y in the can be found in ``frontends/verilog/verilog_parser.y`` in the Yosys source tree.
Yosys source tree.
It generates an AST using the ``AST::AstNode`` data structure defined in It generates an AST using the ``AST::AstNode`` data structure defined in
frontends/ast/ast.h. An ``AST::AstNode`` object has the following ``frontends/ast/ast.h``. An ``AST::AstNode`` object has the following
properties: properties:
.. list-table:: AST node types with their corresponding Verilog constructs. .. list-table:: AST node types with their corresponding Verilog constructs.
@ -152,35 +151,32 @@ properties:
- | The node type - | The node type
| This enum (``AST::AstNodeType``) specifies the role of the node. | This enum (``AST::AstNodeType``) specifies the role of the node.
:numref:`Table %s <tab:Verilog_AstNodeType>` :numref:`Table %s <tab:Verilog_AstNodeType>` contains a list of all node
contains a list of all node types. types.
- | The child nodes - | The child nodes
| This is a list of pointers to all children in the abstract syntax | This is a list of pointers to all children in the abstract syntax tree.
tree.
- | Attributes - | Attributes
| As almost every AST node might have Verilog attributes assigned to | As almost every AST node might have Verilog attributes assigned to it, the
it, the ``AST::AstNode`` has direct support for attributes. Note ``AST::AstNode`` has direct support for attributes. Note that the attribute
that the attribute values are again AST nodes. values are again AST nodes.
- | Node content - | Node content
| Each node might have additional content data. A series of member | Each node might have additional content data. A series of member variables
variables exist to hold such data. For example the member exist to hold such data. For example the member ``std::string str`` can
``std::string str`` can hold a string value and is used e.g. in the hold a string value and is used e.g. in the ``AST_IDENTIFIER`` node type to
AST_IDENTIFIER node type to store the identifier name. store the identifier name.
- | Source code location - | Source code location
| Each ``AST::AstNode`` is automatically annotated with the current | Each ``AST::AstNode`` is automatically annotated with the current source
source code location by the ``AST::AstNode`` constructor. It is code location by the ``AST::AstNode`` constructor. It is stored in the
stored in the ``std::string filename`` and ``int linenum`` member ``std::string filename`` and ``int linenum`` member variables.
variables.
The ``AST::AstNode`` constructor can be called with up to two child The ``AST::AstNode`` constructor can be called with up to two child nodes that
nodes that are automatically added to the list of child nodes for the are automatically added to the list of child nodes for the new object. This
new object. This simplifies the creation of AST nodes for simple simplifies the creation of AST nodes for simple expressions a bit. For example
expressions a bit. For example the bison code for parsing the bison code for parsing multiplications:
multiplications:
.. code:: none .. code:: none
:number-lines: :number-lines:
@ -190,49 +186,50 @@ multiplications:
append_attr($$, $3); append_attr($$, $3);
} | } |
The generated AST data structure is then passed directly to the AST The generated AST data structure is then passed directly to the AST frontend
frontend that performs the actual conversion to RTLIL. that performs the actual conversion to RTLIL.
Note that the Yosys command ``read_verilog`` provides the options ``-yydebug`` Note that the Yosys command ``read_verilog`` provides the options ``-yydebug``
and ``-dump_ast`` that can be used to print the parse tree or abstract and ``-dump_ast`` that can be used to print the parse tree or abstract syntax
syntax tree respectively. tree respectively.
Transforming AST to RTLIL Transforming AST to RTLIL
------------------------- -------------------------
The AST Frontend converts a set of modules in AST representation to The AST Frontend converts a set of modules in AST representation to modules in
modules in RTLIL representation and adds them to the current design. RTLIL representation and adds them to the current design. This is done in two
This is done in two steps: simplification and RTLIL generation. steps: simplification and RTLIL generation.
The source code to the AST frontend can be found in ``frontends/ast/`` in The source code to the AST frontend can be found in ``frontends/ast/`` in the
the Yosys source tree. Yosys source tree.
AST simplification AST simplification
~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~
A full-featured AST is too complex to be transformed into RTLIL A full-featured AST is too complex to be transformed into RTLIL directly.
directly. Therefore it must first be brought into a simpler form. This Therefore it must first be brought into a simpler form. This is done by calling
is done by calling the ``AST::AstNode::simplify()`` method of all the ``AST::AstNode::simplify()`` method of all ``AST_MODULE`` nodes in the AST.
AST_MODULE nodes in the AST. This initiates a recursive process that This initiates a recursive process that performs the following transformations
performs the following transformations on the AST data structure: on the AST data structure:
- Inline all task and function calls. - Inline all task and function calls.
- Evaluate all ``generate``-statements and unroll all ``for``-loops. - Evaluate all ``generate``-statements and unroll all ``for``-loops.
- Perform const folding where it is necessary (e.g. in the value part - Perform const folding where it is necessary (e.g. in the value part of
of AST_PARAMETER, AST_LOCALPARAM, AST_PARASET and AST_RANGE nodes). ``AST_PARAMETER``, ``AST_LOCALPARAM``, ``AST_PARASET`` and ``AST_RANGE``
nodes).
- Replace AST_PRIMITIVE nodes with appropriate AST_ASSIGN nodes. - Replace ``AST_PRIMITIVE`` nodes with appropriate ``AST_ASSIGN`` nodes.
- Replace dynamic bit ranges in the left-hand-side of assignments with - Replace dynamic bit ranges in the left-hand-side of assignments with
AST_CASE nodes with AST_COND children for each possible case. ``AST_CASE`` nodes with ``AST_COND`` children for each possible case.
- Detect array access patterns that are too complicated for the - Detect array access patterns that are too complicated for the
RTLIL::Memory abstraction and replace them with a set of signals and ``RTLIL::Memory`` abstraction and replace them with a set of signals and
cases for all reads and/or writes. cases for all reads and/or writes.
- Otherwise replace array accesses with AST_MEMRD and AST_MEMWR nodes. - Otherwise replace array accesses with ``AST_MEMRD`` and ``AST_MEMWR`` nodes.
In addition to these transformations, the simplifier also annotates the In addition to these transformations, the simplifier also annotates the
AST with additional information that is needed for the RTLIL generator, AST with additional information that is needed for the RTLIL generator,
@ -242,70 +239,66 @@ namely:
folded but (when a constant value is found) are also written to folded but (when a constant value is found) are also written to
member variables in the AST_RANGE node. member variables in the AST_RANGE node.
- All identifiers are resolved and all AST_IDENTIFIER nodes are - All identifiers are resolved and all ``AST_IDENTIFIER`` nodes are annotated
annotated with a pointer to the AST node that contains the with a pointer to the AST node that contains the declaration of the
declaration of the identifier. If no declaration has been found, an identifier. If no declaration has been found, an ``AST_AUTOWIRE`` node is
AST_AUTOWIRE node is created and used for the annotation. created and used for the annotation.
This produces an AST that is fairly easy to convert to the RTLIL format. This produces an AST that is fairly easy to convert to the RTLIL format.
Generating RTLIL Generating RTLIL
~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~
After AST simplification, the ``AST::AstNode::genRTLIL()`` method of After AST simplification, the ``AST::AstNode::genRTLIL()`` method of each
each AST_MODULE node in the AST is called. This initiates a recursive ``AST_MODULE`` node in the AST is called. This initiates a recursive process
process that generates equivalent RTLIL data for the AST data. that generates equivalent RTLIL data for the AST data.
The ``AST::AstNode::genRTLIL()`` method returns an ``RTLIL::SigSpec`` The ``AST::AstNode::genRTLIL()`` method returns an ``RTLIL::SigSpec`` structure.
structure. For nodes that represent expressions (operators, constants, For nodes that represent expressions (operators, constants, signals, etc.), the
signals, etc.), the cells needed to implement the calculation described cells needed to implement the calculation described by the expression are
by the expression are created and the resulting signal is returned. That created and the resulting signal is returned. That way it is easy to generate
way it is easy to generate the circuits for large expressions using the circuits for large expressions using depth-first recursion. For nodes that
depth-first recursion. For nodes that do not represent an expression do not represent an expression (such as ``AST_CELL``), the corresponding circuit
(such as AST_CELL), the corresponding circuit is generated and an empty is generated and an empty ``RTLIL::SigSpec`` is returned.
``RTLIL::SigSpec`` is returned.
Synthesizing Verilog always blocks Synthesizing Verilog always blocks
-------------------------------------- --------------------------------------
For behavioural Verilog code (code utilizing ``always``- and For behavioural Verilog code (code utilizing ``always``- and ``initial``-blocks)
``initial``-blocks) it is necessary to also generate ``RTLIL::Process`` it is necessary to also generate ``RTLIL::Process`` objects. This is done in the
objects. This is done in the following way: following way:
Whenever ``AST::AstNode::genRTLIL()`` encounters an ``always``- or Whenever ``AST::AstNode::genRTLIL()`` encounters an ``always``- or
``initial``-block, it creates an instance of ``initial``-block, it creates an instance of ``AST_INTERNAL::ProcessGenerator``.
``AST_INTERNAL::ProcessGenerator``. This object then generates the This object then generates the ``RTLIL::Process`` object for the block. It also
``RTLIL::Process`` object for the block. It also calls calls ``AST::AstNode::genRTLIL()`` for all right-hand-side expressions contained
``AST::AstNode::genRTLIL()`` for all right-hand-side expressions within the block.
contained within the block.
First the ``AST_INTERNAL::ProcessGenerator`` creates a list of all First the ``AST_INTERNAL::ProcessGenerator`` creates a list of all signals
signals assigned within the block. It then creates a set of temporary assigned within the block. It then creates a set of temporary signals using the
signals using the naming scheme $\ <number> \\\ <original_name> for each naming scheme ``$ <number> \ <original_name>`` for each of the assigned signals.
of the assigned signals.
Then an ``RTLIL::Process`` is created that assigns all intermediate Then an ``RTLIL::Process`` is created that assigns all intermediate values for
values for each left-hand-side signal to the temporary signal in its each left-hand-side signal to the temporary signal in its
``RTLIL::CaseRule``/``RTLIL::SwitchRule`` tree. ``RTLIL::CaseRule``/``RTLIL::SwitchRule`` tree.
Finally a ``RTLIL::SyncRule`` is created for the ``RTLIL::Process`` that Finally a ``RTLIL::SyncRule`` is created for the ``RTLIL::Process`` that assigns
assigns the temporary signals for the final values to the actual the temporary signals for the final values to the actual signals.
signals.
A process may also contain memory writes. A ``RTLIL::MemWriteAction`` is A process may also contain memory writes. A ``RTLIL::MemWriteAction`` is created
created for each of them. for each of them.
Calls to ``AST::AstNode::genRTLIL()`` are generated for right hand sides Calls to ``AST::AstNode::genRTLIL()`` are generated for right hand sides as
as needed. When blocking assignments are used, needed. When blocking assignments are used, ``AST::AstNode::genRTLIL()`` is
``AST::AstNode::genRTLIL()`` is configured using global variables to use configured using global variables to use the temporary signals that hold the
the temporary signals that hold the correct intermediate values whenever correct intermediate values whenever one of the previously assigned signals is
one of the previously assigned signals is used in an expression. used in an expression.
Unfortunately the generation of a correct Unfortunately the generation of a correct
``RTLIL::CaseRule``/``RTLIL::SwitchRule`` tree for behavioural code is a ``RTLIL::CaseRule``/``RTLIL::SwitchRule`` tree for behavioural code is a
non-trivial task. The AST frontend solves the problem using the approach non-trivial task. The AST frontend solves the problem using the approach
described on the following pages. The following example illustrates what described on the following pages. The following example illustrates what the
the algorithm is supposed to do. Consider the following Verilog code: algorithm is supposed to do. Consider the following Verilog code:
.. code:: verilog .. code:: verilog
:number-lines: :number-lines:
@ -325,9 +318,8 @@ the algorithm is supposed to do. Consider the following Verilog code:
out1 = out1 ^ out2; out1 = out1 ^ out2;
end end
This is translated by the Verilog and AST frontends into the following This is translated by the Verilog and AST frontends into the following RTLIL
RTLIL code (attributes, cell parameters and wire declarations not code (attributes, cell parameters and wire declarations not included):
included):
.. code:: RTLIL .. code:: RTLIL
:number-lines: :number-lines:
@ -372,47 +364,47 @@ included):
update \out3 $0\out3[0:0] update \out3 $0\out3[0:0]
end end
Note that the two operators are translated into separate cells outside Note that the two operators are translated into separate cells outside the
the generated process. The signal ``out1`` is assigned using blocking generated process. The signal ``out1`` is assigned using blocking assignments
assignments and therefore ``out1`` has been replaced with a different and therefore ``out1`` has been replaced with a different signal in all
signal in all expressions after the initial assignment. The signal expressions after the initial assignment. The signal ``out2`` is assigned using
``out2`` is assigned using nonblocking assignments and therefore is not nonblocking assignments and therefore is not substituted on the right-hand-side
substituted on the right-hand-side expressions. expressions.
The ``RTLIL::CaseRule``/``RTLIL::SwitchRule`` tree must be interpreted The ``RTLIL::CaseRule``/``RTLIL::SwitchRule`` tree must be interpreted the
the following way: following way:
- On each case level (the body of the process is the root case), first - On each case level (the body of the process is the root case), first the
the actions on this level are evaluated and then the switches within actions on this level are evaluated and then the switches within the case are
the case are evaluated. (Note that the last assignment on line 13 of evaluated. (Note that the last assignment on line 13 of the Verilog code has
the Verilog code has been moved to the beginning of the RTLIL process been moved to the beginning of the RTLIL process to line 13 of the RTLIL
to line 13 of the RTLIL listing.) listing.)
I.e. the special cases deeper in the switch hierarchy override the I.e. the special cases deeper in the switch hierarchy override the defaults
defaults on the upper levels. The assignments in lines 12 and 22 of on the upper levels. The assignments in lines 12 and 22 of the RTLIL code
the RTLIL code serve as an example for this. serve as an example for this.
Note that in contrast to this, the order within the Note that in contrast to this, the order within the ``RTLIL::SwitchRule``
``RTLIL::SwitchRule`` objects within a ``RTLIL::CaseRule`` is objects within a ``RTLIL::CaseRule`` is preserved with respect to the
preserved with respect to the original AST and Verilog code. original AST and Verilog code.
- The whole ``RTLIL::CaseRule``/``RTLIL::SwitchRule`` tree describes an - The whole ``RTLIL::CaseRule``/``RTLIL::SwitchRule`` tree describes an
asynchronous circuit. I.e. the decision tree formed by the switches asynchronous circuit. I.e. the decision tree formed by the switches can be
can be seen independently for each assigned signal. Whenever one seen independently for each assigned signal. Whenever one assigned signal
assigned signal changes, all signals that depend on the changed changes, all signals that depend on the changed signals are to be updated.
signals are to be updated. For example the assignments in lines 16 For example the assignments in lines 16 and 18 in the RTLIL code in fact
and 18 in the RTLIL code in fact influence the assignment in line 12, influence the assignment in line 12, even though they are in the "wrong
even though they are in the "wrong order". order".
The only synchronous part of the process is in the ``RTLIL::SyncRule`` The only synchronous part of the process is in the ``RTLIL::SyncRule`` object
object generated at line 35 in the RTLIL code. The sync rule is the only generated at line 35 in the RTLIL code. The sync rule is the only part of the
part of the process where the original signals are assigned. The process where the original signals are assigned. The synchronization event from
synchronization event from the original Verilog code has been translated the original Verilog code has been translated into the synchronization type
into the synchronization type (posedge) and signal (\\clock) for the (posedge) and signal (``\clock``) for the ``RTLIL::SyncRule`` object. In the
``RTLIL::SyncRule`` object. In the case of this simple example the case of this simple example the ``RTLIL::SyncRule`` object is later simply
``RTLIL::SyncRule`` object is later simply transformed into a set of transformed into a set of d-type flip-flops and the
d-type flip-flops and the ``RTLIL::CaseRule``/``RTLIL::SwitchRule`` tree ``RTLIL::CaseRule``/``RTLIL::SwitchRule`` tree to a decision tree using
to a decision tree using multiplexers. multiplexers.
In more complex examples (e.g. asynchronous resets) the part of the In more complex examples (e.g. asynchronous resets) the part of the
``RTLIL::CaseRule``/``RTLIL::SwitchRule`` tree that describes the ``RTLIL::CaseRule``/``RTLIL::SwitchRule`` tree that describes the
@ -426,64 +418,62 @@ The ``AST_INTERNAL::ProcessGenerator`` uses the following internal state
variables: variables:
- | ``subst_rvalue_from`` and ``subst_rvalue_to`` - | ``subst_rvalue_from`` and ``subst_rvalue_to``
| These two variables hold the replacement pattern that should be | These two variables hold the replacement pattern that should be used by
used by ``AST::AstNode::genRTLIL()`` for signals with blocking ``AST::AstNode::genRTLIL()`` for signals with blocking assignments. After
assignments. After initialization of initialization of ``AST_INTERNAL::ProcessGenerator`` these two variables are
``AST_INTERNAL::ProcessGenerator`` these two variables are empty. empty.
- | ``subst_lvalue_from`` and ``subst_lvalue_to`` - | ``subst_lvalue_from`` and ``subst_lvalue_to``
| These two variables contain the mapping from left-hand-side signals | These two variables contain the mapping from left-hand-side signals (``\
(\\\ <name>) to the current temporary signal for the same thing <name>``) to the current temporary signal for the same thing (initially
(initially $0\\\ <name>). ``$0\ <name>``).
- | ``current_case`` - | ``current_case``
| A pointer to a ``RTLIL::CaseRule`` object. Initially this is the | A pointer to a ``RTLIL::CaseRule`` object. Initially this is the root case
root case of the generated ``RTLIL::Process``. of the generated ``RTLIL::Process``.
As the algorithm runs these variables are continuously modified as well As the algorithm runs these variables are continuously modified as well as
as pushed to the stack and later restored to their earlier values by pushed to the stack and later restored to their earlier values by popping from
popping from the stack. the stack.
On startup the ProcessGenerator generates a new ``RTLIL::Process`` On startup the ProcessGenerator generates a new ``RTLIL::Process`` object with
object with an empty root case and initializes its state variables as an empty root case and initializes its state variables as described above. Then
described above. Then the ``RTLIL::SyncRule`` objects are created using the ``RTLIL::SyncRule`` objects are created using the synchronization events
the synchronization events from the AST_ALWAYS node and the initial from the AST_ALWAYS node and the initial values of ``subst_lvalue_from`` and
values of ``subst_lvalue_from`` and ``subst_lvalue_to``. Then the AST ``subst_lvalue_to``. Then the AST for this process is evaluated recursively.
for this process is evaluated recursively.
During this recursive evaluation, three different relevant types of AST During this recursive evaluation, three different relevant types of AST nodes
nodes can be discovered: AST_ASSIGN_LE (nonblocking assignments), can be discovered: ``AST_ASSIGN_LE`` (nonblocking assignments),
AST_ASSIGN_EQ (blocking assignments) and AST_CASE (``if`` or ``case`` ``AST_ASSIGN_EQ`` (blocking assignments) and ``AST_CASE`` (``if`` or ``case``
statement). statement).
Handling of nonblocking assignments Handling of nonblocking assignments
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
When an AST_ASSIGN_LE node is discovered, the following actions are When an ``AST_ASSIGN_LE`` node is discovered, the following actions are
performed by the ProcessGenerator: performed by the ProcessGenerator:
- The left-hand-side is evaluated using ``AST::AstNode::genRTLIL()`` - The left-hand-side is evaluated using ``AST::AstNode::genRTLIL()`` and mapped
and mapped to a temporary signal name using ``subst_lvalue_from`` and to a temporary signal name using ``subst_lvalue_from`` and
``subst_lvalue_to``. ``subst_lvalue_to``.
- The right-hand-side is evaluated using ``AST::AstNode::genRTLIL()``. - The right-hand-side is evaluated using ``AST::AstNode::genRTLIL()``. For this
For this call, the values of ``subst_rvalue_from`` and call, the values of ``subst_rvalue_from`` and ``subst_rvalue_to`` are used to
``subst_rvalue_to`` are used to map blocking-assigned signals map blocking-assigned signals correctly.
correctly.
- Remove all assignments to the same left-hand-side as this assignment - Remove all assignments to the same left-hand-side as this assignment from the
from the ``current_case`` and all cases within it. ``current_case`` and all cases within it.
- Add the new assignment to the ``current_case``. - Add the new assignment to the ``current_case``.
Handling of blocking assignments Handling of blocking assignments
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
When an AST_ASSIGN_EQ node is discovered, the following actions are When an ``AST_ASSIGN_EQ`` node is discovered, the following actions are
performed by the ProcessGenerator: performed by the ProcessGenerator:
- Perform all the steps that would be performed for a nonblocking - Perform all the steps that would be performed for a nonblocking assignment
assignment (see above). (see above).
- Remove the found left-hand-side (before lvalue mapping) from - Remove the found left-hand-side (before lvalue mapping) from
``subst_rvalue_from`` and also remove the respective bits from ``subst_rvalue_from`` and also remove the respective bits from
@ -496,36 +486,33 @@ performed by the ProcessGenerator:
Handling of cases and if-statements Handling of cases and if-statements
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
When an AST_CASE node is discovered, the following actions are performed When an ``AST_CASE`` node is discovered, the following actions are performed by
by the ProcessGenerator: the ProcessGenerator:
- The values of ``subst_rvalue_from``, ``subst_rvalue_to``, - The values of ``subst_rvalue_from``, ``subst_rvalue_to``,
``subst_lvalue_from`` and ``subst_lvalue_to`` are pushed to the ``subst_lvalue_from`` and ``subst_lvalue_to`` are pushed to the stack.
stack.
- A new ``RTLIL::SwitchRule`` object is generated, the selection - A new ``RTLIL::SwitchRule`` object is generated, the selection expression is
expression is evaluated using ``AST::AstNode::genRTLIL()`` (with the evaluated using ``AST::AstNode::genRTLIL()`` (with the use of
use of ``subst_rvalue_from`` and ``subst_rvalue_to``) and added to ``subst_rvalue_from`` and ``subst_rvalue_to``) and added to the
the ``RTLIL::SwitchRule`` object and the object is added to the ``RTLIL::SwitchRule`` object and the object is added to the ``current_case``.
``current_case``.
- All lvalues assigned to within the AST_CASE node using blocking - All lvalues assigned to within the ``AST_CASE`` node using blocking
assignments are collected and saved in the local variable assignments are collected and saved in the local variable
``this_case_eq_lvalue``. ``this_case_eq_lvalue``.
- New temporary signals are generated for all signals in - New temporary signals are generated for all signals in
``this_case_eq_lvalue`` and stored in ``this_case_eq_ltemp``. ``this_case_eq_lvalue`` and stored in ``this_case_eq_ltemp``.
- The signals in ``this_case_eq_lvalue`` are mapped using - The signals in ``this_case_eq_lvalue`` are mapped using ``subst_rvalue_from``
``subst_rvalue_from`` and ``subst_rvalue_to`` and the resulting set and ``subst_rvalue_to`` and the resulting set of signals is stored in
of signals is stored in ``this_case_eq_rvalue``. ``this_case_eq_rvalue``.
Then the following steps are performed for each AST_COND node within the Then the following steps are performed for each ``AST_COND`` node within the
AST_CASE node: ``AST_CASE`` node:
- Set ``subst_rvalue_from``, ``subst_rvalue_to``, ``subst_lvalue_from`` - Set ``subst_rvalue_from``, ``subst_rvalue_to``, ``subst_lvalue_from`` and
and ``subst_lvalue_to`` to the values that have been pushed to the ``subst_lvalue_to`` to the values that have been pushed to the stack.
stack.
- Remove ``this_case_eq_lvalue`` from - Remove ``this_case_eq_lvalue`` from
``subst_lvalue_from``/``subst_lvalue_to``. ``subst_lvalue_from``/``subst_lvalue_to``.
@ -535,33 +522,30 @@ AST_CASE node:
- Push the value of ``current_case``. - Push the value of ``current_case``.
- Create a new ``RTLIL::CaseRule``. Set ``current_case`` to the new - Create a new ``RTLIL::CaseRule``. Set ``current_case`` to the new object and
object and add the new object to the ``RTLIL::SwitchRule`` created add the new object to the ``RTLIL::SwitchRule`` created above.
above.
- Add an assignment from ``this_case_eq_rvalue`` to - Add an assignment from ``this_case_eq_rvalue`` to ``this_case_eq_ltemp`` to
``this_case_eq_ltemp`` to the new ``current_case``. the new ``current_case``.
- Evaluate the compare value for this case using - Evaluate the compare value for this case using
``AST::AstNode::genRTLIL()`` (with the use of ``subst_rvalue_from`` ``AST::AstNode::genRTLIL()`` (with the use of ``subst_rvalue_from``
and ``subst_rvalue_to``) modify the new ``current_case`` accordingly. and ``subst_rvalue_to``) modify the new ``current_case`` accordingly.
- Recursion into the children of the AST_COND node. - Recursion into the children of the ``AST_COND`` node.
- Restore ``current_case`` by popping the old value from the stack. - Restore ``current_case`` by popping the old value from the stack.
Finally the following steps are performed: Finally the following steps are performed:
- The values of ``subst_rvalue_from``, ``subst_rvalue_to``, - The values of ``subst_rvalue_from``, ``subst_rvalue_to``,
``subst_lvalue_from`` and ``subst_lvalue_to`` are popped from the ``subst_lvalue_from`` and ``subst_lvalue_to`` are popped from the stack.
stack.
- The signals from ``this_case_eq_lvalue`` are removed from the - The signals from ``this_case_eq_lvalue`` are removed from the
``subst_rvalue_from``/``subst_rvalue_to``-pair. ``subst_rvalue_from``/``subst_rvalue_to``-pair.
- The value of ``this_case_eq_lvalue`` is appended to - The value of ``this_case_eq_lvalue`` is appended to ``subst_rvalue_from`` and
``subst_rvalue_from`` and the value of ``this_case_eq_ltemp`` is the value of ``this_case_eq_ltemp`` is appended to ``subst_rvalue_to``.
appended to ``subst_rvalue_to``.
- Map the signals in ``this_case_eq_lvalue`` using - Map the signals in ``this_case_eq_lvalue`` using
``subst_lvalue_from``/``subst_lvalue_to``. ``subst_lvalue_from``/``subst_lvalue_to``.
@ -569,37 +553,35 @@ Finally the following steps are performed:
- Remove all assignments to signals in ``this_case_eq_lvalue`` in - Remove all assignments to signals in ``this_case_eq_lvalue`` in
``current_case`` and all cases within it. ``current_case`` and all cases within it.
- Add an assignment from ``this_case_eq_ltemp`` to - Add an assignment from ``this_case_eq_ltemp`` to ``this_case_eq_lvalue`` to
``this_case_eq_lvalue`` to ``current_case``. ``current_case``.
Further analysis of the algorithm for cases and if-statements Further analysis of the algorithm for cases and if-statements
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
With respect to nonblocking assignments the algorithm is easy: later With respect to nonblocking assignments the algorithm is easy: later assignments
assignments invalidate earlier assignments. For each signal assigned invalidate earlier assignments. For each signal assigned using nonblocking
using nonblocking assignments exactly one temporary variable is assignments exactly one temporary variable is generated (with the ``$0``-prefix)
generated (with the $0-prefix) and this variable is used for all and this variable is used for all assignments of the variable.
assignments of the variable.
Note how all the ``_eq_``-variables become empty when no blocking Note how all the ``_eq_``-variables become empty when no blocking assignments
assignments are used and many of the steps in the algorithm can then be are used and many of the steps in the algorithm can then be ignored as a result
ignored as a result of this. of this.
For a variable with blocking assignments the algorithm shows the For a variable with blocking assignments the algorithm shows the following
following behaviour: First a new temporary variable is created. This new behaviour: First a new temporary variable is created. This new temporary
temporary variable is then registered as the assignment target for all variable is then registered as the assignment target for all assignments for
assignments for this variable within the cases for this AST_CASE node. this variable within the cases for this ``AST_CASE`` node. Then for each case
Then for each case the new temporary variable is first assigned the old the new temporary variable is first assigned the old temporary variable. This
temporary variable. This assignment is overwritten if the variable is assignment is overwritten if the variable is actually assigned in this case and
actually assigned in this case and is kept as a default value otherwise. is kept as a default value otherwise.
This yields an ``RTLIL::CaseRule`` that assigns the new temporary This yields an ``RTLIL::CaseRule`` that assigns the new temporary variable in
variable in all branches. So when all cases have been processed a final all branches. So when all cases have been processed a final assignment is added
assignment is added to the containing block that assigns the new to the containing block that assigns the new temporary variable to the old one.
temporary variable to the old one. Note how this step always overrides a Note how this step always overrides a previous assignment to the old temporary
previous assignment to the old temporary variable. Other than variable. Other than nonblocking assignments, the old assignment could still
nonblocking assignments, the old assignment could still have an effect have an effect somewhere in the design, as there have been calls to
somewhere in the design, as there have been calls to
``AST::AstNode::genRTLIL()`` with a ``AST::AstNode::genRTLIL()`` with a
``subst_rvalue_from``/ ``subst_rvalue_to``-tuple that contained the ``subst_rvalue_from``/ ``subst_rvalue_to``-tuple that contained the
right-hand-side of the old assignment. right-hand-side of the old assignment.
@ -607,60 +589,63 @@ right-hand-side of the old assignment.
The proc pass The proc pass
~~~~~~~~~~~~~ ~~~~~~~~~~~~~
The ProcessGenerator converts a behavioural model in AST representation The ProcessGenerator converts a behavioural model in AST representation to a
to a behavioural model in ``RTLIL::Process`` representation. The actual behavioural model in ``RTLIL::Process`` representation. The actual conversion
conversion from a behavioural model to an RTL representation is from a behavioural model to an RTL representation is performed by the ``proc``
performed by the proc pass and the passes it launches: pass and the passes it launches:
- | proc_clean and proc_rmdead - | proc_clean and proc_rmdead
| These two passes just clean up the ``RTLIL::Process`` structure. | These two passes just clean up the ``RTLIL::Process`` structure. The
The proc_clean pass removes empty parts (eg. empty assignments) ``proc_clean`` pass removes empty parts (eg. empty assignments) from the
from the process and proc_rmdead detects and removes unreachable process and ``proc_rmdead`` detects and removes unreachable branches from
branches from the process's decision trees. the process's decision trees.
- | proc_arst - | proc_arst
| This pass detects processes that describe d-type flip-flops with | This pass detects processes that describe d-type flip-flops with
asynchronous resets and rewrites the process to better reflect what asynchronous resets and rewrites the process to better reflect what they
they are modelling: Before this pass, an asynchronous reset has two are modelling: Before this pass, an asynchronous reset has two
edge-sensitive sync rules and one top-level for the reset path. edge-sensitive sync rules and one top-level ``RTLIL::SwitchRule`` for the
After this pass the sync rule for the reset is level-sensitive and reset path. After this pass the sync rule for the reset is level-sensitive
the top-level has been removed. and the top-level ``RTLIL::SwitchRule`` has been removed.
- | proc_mux - | proc_mux
| This pass converts the /-tree to a tree of multiplexers per written | This pass converts the ``RTLIL::CaseRule``/ ``RTLIL::SwitchRule``-tree to a
signal. After this, the structure only contains the s that describe tree of multiplexers per written signal. After this, the ``RTLIL::Process``
the output registers. structure only contains the ``RTLIL::SyncRule`` s that describe the output
registers.
- | proc_dff - | proc_dff
| This pass replaces the s to d-type flip-flops (with asynchronous | This pass replaces the ``RTLIL::SyncRule`` s to d-type flip-flops (with
resets if necessary). asynchronous resets if necessary).
- | proc_dff - | proc_dff
| This pass replaces the s with $memwr cells. | This pass replaces the ``RTLIL::MemWriteAction`` s with ``$memwr`` cells.
- | proc_clean - | proc_clean
| A final call to proc_clean removes the now empty objects. | A final call to ``proc_clean`` removes the now empty ``RTLIL::Process``
objects.
Performing these last processing steps in passes instead of in the Performing these last processing steps in passes instead of in the Verilog
Verilog frontend has two important benefits: frontend has two important benefits:
First it improves the transparency of the process. Everything that First it improves the transparency of the process. Everything that happens in a
happens in a separate pass is easier to debug, as the RTLIL data separate pass is easier to debug, as the RTLIL data structures can be easily
structures can be easily investigated before and after each of the investigated before and after each of the steps.
steps.
Second it improves flexibility. This scheme can easily be extended to Second it improves flexibility. This scheme can easily be extended to support
support other types of storage-elements, such as sr-latches or other types of storage-elements, such as sr-latches or d-latches, without having
d-latches, without having to extend the actual Verilog frontend. to extend the actual Verilog frontend.
Synthesizing Verilog arrays Synthesizing Verilog arrays
--------------------------- ---------------------------
Add some information on the generation of $memrd and $memwr cells and .. TODO: these
Add some information on the generation of ``$memrd`` and ``$memwr`` cells and
how they are processed in the memory pass. how they are processed in the memory pass.
Synthesizing parametric designs Synthesizing parametric designs
------------------------------- -------------------------------
Add some information on the ``RTLIL::Module::derive()`` method and how Add some information on the ``RTLIL::Module::derive()`` method and how it is
it is used to synthesize parametric modules via the hierarchy pass. used to synthesize parametric modules via the hierarchy pass.

View File

@ -816,17 +816,17 @@ techlibs/common/simcells.v in the Yosys source tree.
============== ============== ========= ============== ============== =========
Tables \ :numref:`%s <tab:CellLib_gates>`, :numref:`%s Tables :numref:`%s <tab:CellLib_gates>`, :numref:`%s <tab:CellLib_gates_dffe>`,
<tab:CellLib_gates_dffe>`, :numref:`%s <tab:CellLib_gates_adff>`, :numref:`%s :numref:`%s <tab:CellLib_gates_adff>`, :numref:`%s <tab:CellLib_gates_adffe>`,
<tab:CellLib_gates_adffe>`, :numref:`%s <tab:CellLib_gates_dffsr>`, :numref:`%s :numref:`%s <tab:CellLib_gates_dffsr>`, :numref:`%s <tab:CellLib_gates_dffsre>`,
<tab:CellLib_gates_dffsre>`, :numref:`%s <tab:CellLib_gates_adlatch>`, :numref:`%s <tab:CellLib_gates_adlatch>`, :numref:`%s
:numref:`%s <tab:CellLib_gates_dlatchsr>` and :numref:`%s <tab:CellLib_gates_dlatchsr>` and :numref:`%s <tab:CellLib_gates_sr>` list all
<tab:CellLib_gates_sr>` list all cell types used for gate level logic. The cell cell types used for gate level logic. The cell types ``$_BUF_``, ``$_NOT_``,
types ``$_BUF_``, ``$_NOT_``, ``$_AND_``, ``$_NAND_``, ``$_ANDNOT_``, ``$_OR_``, ``$_AND_``, ``$_NAND_``, ``$_ANDNOT_``, ``$_OR_``, ``$_NOR_``, ``$_ORNOT_``,
``$_NOR_``, ``$_ORNOT_``, ``$_XOR_``, ``$_XNOR_``, ``$_AOI3_``, ``$_OAI3_``, ``$_XOR_``, ``$_XNOR_``, ``$_AOI3_``, ``$_OAI3_``, ``$_AOI4_``, ``$_OAI4_``,
``$_AOI4_``, ``$_OAI4_``, ``$_MUX_``, ``$_MUX4_``, ``$_MUX8_``, ``$_MUX16_`` and ``$_MUX_``, ``$_MUX4_``, ``$_MUX8_``, ``$_MUX16_`` and ``$_NMUX_`` are used to
``$_NMUX_`` are used to model combinatorial logic. The cell type ``$_TBUF_`` is model combinatorial logic. The cell type ``$_TBUF_`` is used to model tristate
used to model tristate logic. logic.
The ``$_MUX4_``, ``$_MUX8_`` and ``$_MUX16_`` cells are used to model wide The ``$_MUX4_``, ``$_MUX8_`` and ``$_MUX16_`` cells are used to model wide
muxes, and correspond to the following Verilog code: muxes, and correspond to the following Verilog code:

View File

@ -6,21 +6,21 @@ representation. The only exception are the high-level frontends that use the AST
representation as an intermediate step before generating RTLIL data. representation as an intermediate step before generating RTLIL data.
In order to avoid reinventing names for the RTLIL classes, they are simply 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, referred to by their full C++ name, i.e. including the ``RTLIL::`` namespace prefix,
in this document. in this document.
:numref:`Figure %s <fig:Overview_RTLIL>` shows a simplified Entity-Relationship :numref:`Figure %s <fig:Overview_RTLIL>` shows a simplified Entity-Relationship
Diagram (ER Diagram) of RTLIL. In :math:`1:N` relationships the arrow points 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 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 :math:`N` (zero to many) instances of ``RTLIL::Module`` . A two-pointed arrow
indicates a :math:`1:1` relationship. indicates a :math:`1:1` relationship.
The RTLIL::Design is the root object of the RTLIL data structure. There is 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 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 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 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 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 additional ``RTLIL::Design`` object and call the Verilog frontend with this other
object to parse the cell library. object to parse the cell library.
.. figure:: ../../../images/overview_rtlil.* .. figure:: ../../../images/overview_rtlil.*
@ -29,23 +29,23 @@ object to parse the cell library.
Simplified RTLIL Entity-Relationship Diagram Simplified RTLIL Entity-Relationship Diagram
There is only one active RTLIL::Design object that is used by all frontends, 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 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 ``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 to modules in Verilog or entities in VHDL. Each module in turn contains objects
from three different categories: from three different categories:
- RTLIL::Cell and RTLIL::Wire objects represent classical netlist data. - ``RTLIL::Cell`` and ``RTLIL::Wire`` objects represent classical netlist data.
- RTLIL::Process objects represent the decision trees (if-then-else statements, - ``RTLIL::Process`` objects represent the decision trees (if-then-else statements,
etc.) and synchronization declarations (clock signals and sensitivity) from etc.) and synchronization declarations (clock signals and sensitivity) from
Verilog always and VHDL process blocks. Verilog always and VHDL process blocks.
- RTLIL::Memory objects represent addressable memories (arrays). - ``RTLIL::Memory`` objects represent addressable memories (arrays).
Usually the output of the synthesis procedure is a netlist, i.e. all 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::Process`` and ``RTLIL::Memory`` objects must be replaced by ``RTLIL::Cell`` and
RTLIL::Wire objects by synthesis passes. ``RTLIL::Wire`` objects by synthesis passes.
All features of the HDL that cannot be mapped directly to these RTLIL classes 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. must be transformed to an RTLIL-compatible representation by the HDL frontend.
@ -63,19 +63,22 @@ a backslash (\) or a dollar sign ($).
Identifiers starting with a backslash are public visible identifiers. Usually Identifiers starting with a backslash are public visible identifiers. Usually
they originate from one of the HDL input files. For example the signal name 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 ``\sig42`` is most likely a signal that was declared using the name ``sig42`` in
HDL input file. On the other hand the signal name "$sig42" is an auto-generated an HDL input file. On the other hand the signal name ``$sig42`` is an
signal name. The backends convert all identifiers that start with a dollar sign auto-generated signal name. The backends convert all identifiers that start with
to identifiers that do not collide with identifiers that start with a backslash. a dollar sign to identifiers that do not collide with identifiers that start
with a backslash.
This has three advantages: This has three advantages:
- First, it is impossible that an auto-generated identifier collides with an - First, it is impossible that an auto-generated identifier collides with an
identifier that was provided by the user. identifier that was provided by the user.
.. TODO: does opt_rmunused (still?) exist?
- Second, the information about which identifiers were originally provided by - Second, the information about which identifiers were originally provided by
the user is always available which can help guide some optimizations. For the user is always available which can help guide some optimizations. For
example the "opt_rmunused" tries to preserve signals with a user-provided 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 name but doesn't hesitate to delete signals that have auto-generated names
when they just duplicate other signals. when they just duplicate other signals.
@ -98,25 +101,25 @@ All RTLIL identifiers are case sensitive.
Some transformations, such as flattening, may have to change identifiers Some transformations, such as flattening, may have to change identifiers
provided by the user to avoid name collisions. When that happens, attribute provided by the user to avoid name collisions. When that happens, attribute
"hdlname" is attached to the object with the changed identifier. This attribute ``hdlname`` is attached to the object with the changed identifier. This
contains one name (if emitted directly by the frontend, or is a result of attribute contains one name (if emitted directly by the frontend, or is a result
disambiguation) or multiple names separated by spaces (if a result of of disambiguation) or multiple names separated by spaces (if a result of
flattening). All names specified in the "hdlname" attribute are public and do flattening). All names specified in the ``hdlname`` attribute are public and do
not include the leading "\". not include the leading ``\``.
RTLIL::Design and RTLIL::Module RTLIL::Design and RTLIL::Module
------------------------------- -------------------------------
The RTLIL::Design object is basically just a container for 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 objects. In addition to a list of ``RTLIL::Module`` objects the
keeps a list of selected objects, i.e. the objects that passes should operate ``RTLIL::Design`` also keeps a list of selected objects, i.e. the objects that
on. In most cases the whole design is selected and therefore passes operate on passes should operate on. In most cases the whole design is selected and
the whole design. But this mechanism can be useful for more complex synthesis therefore passes operate on the whole design. But this mechanism can be useful
jobs in which only parts of the design should be affected by certain passes. 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 Besides the objects shown in the :ref:`ER diagram <fig:Overview_RTLIL>` above,
<fig:Overview_RTLIL>` an RTLIL::Module object contains the following additional an ``RTLIL::Module`` object contains the following additional properties:
properties:
- The module name - The module name
- A list of attributes - A list of attributes
@ -132,7 +135,7 @@ script but not by others.
Verilog and VHDL both support parametric modules (known as "generic entities" in Verilog and VHDL both support parametric modules (known as "generic entities" in
VHDL). The RTLIL format does not support parametric modules itself. Instead each VHDL). The RTLIL format does not support parametric modules itself. Instead each
module contains a callback function into the AST frontend to generate a module contains a callback function into the AST frontend to generate a
parametrized variation of the RTLIL::Module as needed. This callback then parametrized variation of the ``RTLIL::Module`` as needed. This callback then
returns the auto-generated name of the parametrized variation of the module. (A 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 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 parametrized variation from being generated twice. For modules with only a few
@ -144,14 +147,14 @@ hash string.)
RTLIL::Cell and RTLIL::Wire RTLIL::Cell and RTLIL::Wire
--------------------------- ---------------------------
A module contains zero to many RTLIL::Cell and RTLIL::Wire objects. Objects of A module contains zero to many ``RTLIL::Cell`` and ``RTLIL::Wire`` objects.
these types are used to model netlists. Usually the goal of all synthesis Objects of these types are used to model netlists. Usually the goal of all
efforts is to convert all modules to a state where the functionality of the synthesis efforts is to convert all modules to a state where the functionality
module is implemented only by cells from a given cell library and wires to of the module is implemented only by cells from a given cell library and wires
connect these cells with each other. Note that module ports are just wires with to connect these cells with each other. Note that module ports are just wires
a special property. with a special property.
An RTLIL::Wire object has the following properties: An ``RTLIL::Wire`` object has the following properties:
- The wire name - The wire name
- A list of attributes - A list of attributes
@ -174,15 +177,16 @@ 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 however, information from the HDL frontend is preserved so that the bus will be
correctly indexed in error messages, backend output, constraint files, etc. correctly indexed in error messages, backend output, constraint files, etc.
An RTLIL::Cell object has the following properties: An ``RTLIL::Cell`` object has the following properties:
- The cell name and type - The cell name and type
- A list of attributes - A list of attributes
- A list of parameters (for parametric cells) - A list of parameters (for parametric cells)
- Cell ports and the connections of ports to wires and constants - 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 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. each cell port. The ``RTLIL::SigSpec`` data type is described in the next
section.
.. _sec:rtlil_sigspec: .. _sec:rtlil_sigspec:
@ -200,12 +204,12 @@ A "signal" is everything that can be applied to a cell port. I.e.
- | Concatenations of the above - | Concatenations of the above
| 1em For example: ``{16'd1337, mywire[15:8]}`` | 1em For example: ``{16'd1337, mywire[15:8]}``
The RTLIL::SigSpec data type is used to represent signals. The RTLIL::Cell The ``RTLIL::SigSpec`` data type is used to represent signals. The ``RTLIL::Cell``
object contains one RTLIL::SigSpec for each cell port. object contains one ``RTLIL::SigSpec`` for each cell port.
In addition, connections between wires are represented using a pair of In addition, connections between wires are represented using a pair of
RTLIL::SigSpec objects. Such pairs are needed in different locations. Therefore ``RTLIL::SigSpec`` objects. Such pairs are needed in different locations.
the type name RTLIL::SigSig was defined for such a pair. Therefore the type name ``RTLIL::SigSig`` was defined for such a pair.
.. _sec:rtlil_process: .. _sec:rtlil_process:
@ -213,9 +217,9 @@ RTLIL::Process
-------------- --------------
When a high-level HDL frontend processes behavioural code it splits it up into 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 data path logic (e.g. the expression ``a + b`` is replaced by the output of an
that takes a and b as inputs) and an RTLIL::Process that models the control adder that takes a and b as inputs) and an ``RTLIL::Process`` that models the
logic of the behavioural code. Let's consider a simple example: control logic of the behavioural code. Let's consider a simple example:
.. code:: verilog .. code:: verilog
:number-lines: :number-lines:
@ -230,9 +234,9 @@ logic of the behavioural code. Let's consider a simple example:
q <= d; q <= d;
endmodule endmodule
In this example there is no data path and therefore the RTLIL::Module generated 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. by the frontend only contains a few ``RTLIL::Wire`` objects and an ``RTLIL::Process`` .
The RTLIL::Process in RTLIL syntax: The ``RTLIL::Process`` in RTLIL syntax:
.. code:: RTLIL .. code:: RTLIL
:number-lines: :number-lines:
@ -255,34 +259,37 @@ The RTLIL::Process in RTLIL syntax:
update \q $0\q[0:0] update \q $0\q[0:0]
end end
This RTLIL::Process contains two RTLIL::SyncRule objects, two RTLIL::SwitchRule This ``RTLIL::Process`` contains two ``RTLIL::SyncRule`` objects, two
objects and five RTLIL::CaseRule objects. The wire $0\q[0:0] is an automatically ``RTLIL::SwitchRule`` objects and five ``RTLIL::CaseRule`` objects. The wire
created wire that holds the next value of \\q. The lines :math:`2 \dots 12` ``$0\q[0:0]`` is an automatically created wire that holds the next value of
describe how $0\q[0:0] should be calculated. The lines :math:`13 \dots 16` ``\q``. The lines 2..12 describe how ``$0\q[0:0]`` should be calculated. The
describe how the value of $0\q[0:0] is used to update \\q. lines 13..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 An ``RTLIL::Process`` is a container for zero or more ``RTLIL::SyncRule``
exactly one RTLIL::CaseRule object, which is called the root case. objects and exactly one ``RTLIL::CaseRule`` object, which is called the root
case.
An RTLIL::SyncRule object contains an (optional) synchronization condition An ``RTLIL::SyncRule`` object contains an (optional) synchronization condition
(signal and edge-type), zero or more assignments (RTLIL::SigSig), and zero or (signal and edge-type), zero or more assignments (``RTLIL::SigSig``), and zero
more memory writes (RTLIL::MemWriteAction). The always synchronization condition or more memory writes (``RTLIL::MemWriteAction``). The always synchronization
is used to break combinatorial loops when a latch should be inferred instead. 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) An ``RTLIL::CaseRule`` is a container for zero or more assignments
and zero or more RTLIL::SwitchRule objects. An RTLIL::SwitchRule objects is a (``RTLIL::SigSig``) and zero or more ``RTLIL::SwitchRule`` objects. An
container for zero or more RTLIL::CaseRule objects. ``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 In the above example the lines 2..12 are the root case. Here ``$0\q[0:0]`` is
$0\q[0:0] is first assigned the old value \\q as default value (line 2). The first assigned the old value ``\q`` as default value (line 2). The root case
root case also contains an RTLIL::SwitchRule object (lines :math:`3 \dots 12`). also contains an ``RTLIL::SwitchRule`` object (lines 3..12). Such an object is
Such an object is very similar to the C switch statement as it uses a control very similar to the C switch statement as it uses a control signal (``\reset``
signal (\\reset in this case) to determine which of its cases should be active. in this case) to determine which of its cases should be active. The
The RTLIL::SwitchRule object then contains one RTLIL::CaseRule object per case. ``RTLIL::SwitchRule`` object then contains one ``RTLIL::CaseRule`` object per
In this example there is a case [1]_ for \\reset == 1 that causes $0\q[0:0] to case. In this example there is a case [1]_ for ``\reset == 1`` that causes
be set (lines 4 and 5) and a default case that in turn contains a switch that ``$0\q[0:0]`` to be set (lines 4 and 5) and a default case that in turn contains
sets $0\q[0:0] to the value of \\d if \\enable is active (lines :math:`6 \dots a switch that sets ``$0\q[0:0]`` to the value of ``\d`` if ``\enable`` is active
11`). (lines 6..11).
A case can specify zero or more compare values that will determine whether it 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 matches. Each of the compare values must be the exact same width as the control
@ -299,8 +306,8 @@ violated, the behavior is undefined. These attributes are useful when an
invariant invisible to the synthesizer causes the control signal to never take invariant invisible to the synthesizer causes the control signal to never take
certain bit patterns. certain bit patterns.
The lines :math:`13 \dots 16` then cause \\q to be updated whenever there is a The lines 13..16 then cause ``\q`` to be updated whenever there is a positive
positive clock edge on \\clock or \\reset. clock edge on ``\clock`` or ``\reset``.
In order to generate such a representation, the language frontend must be able In order to generate such a representation, the language frontend must be able
to handle blocking and nonblocking assignments correctly. However, the language to handle blocking and nonblocking assignments correctly. However, the language
@ -313,8 +320,8 @@ trees before further processing them.
One of the first actions performed on a design in RTLIL representation in most 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 synthesis scripts is identifying asynchronous resets. This is usually done using
the proc_arst pass. This pass transforms the above example to the following the ``proc_arst`` pass. This pass transforms the above example to the following
RTLIL::Process: ``RTLIL::Process``:
.. code:: RTLIL .. code:: RTLIL
:number-lines: :number-lines:
@ -332,9 +339,9 @@ RTLIL::Process:
update \q 1'0 update \q 1'0
end end
This pass has transformed the outer RTLIL::SwitchRule into a modified This pass has transformed the outer ``RTLIL::SwitchRule`` into a modified
RTLIL::SyncRule object for the \\reset signal. Further processing converts the ``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 ``RTLIL::Process`` into e.g. a d-type flip-flop with asynchronous reset and a
multiplexer for the enable signal: multiplexer for the enable signal:
.. code:: RTLIL .. code:: RTLIL
@ -358,11 +365,11 @@ multiplexer for the enable signal:
connect \Y $0\q[0:0] connect \Y $0\q[0:0]
end end
Different combinations of passes may yield different results. Note that $adff Different combinations of passes may yield different results. Note that
and $mux are internal cell types that still need to be mapped to cell types from ``$adff`` and ``$mux`` are internal cell types that still need to be mapped to
the target cell library. cell types from the target cell library.
Some passes refuse to operate on modules that still contain RTLIL::Process 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. 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 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 called early in a synthesis script. The proc pass calls a series of other passes
@ -374,7 +381,7 @@ synthesis tasks.
RTLIL::Memory RTLIL::Memory
------------- -------------
For every array (memory) in the HDL code an RTLIL::Memory object is created. A For every array (memory) in the HDL code an ``RTLIL::Memory`` object is created. A
memory object has the following properties: memory object has the following properties:
- The memory name - The memory name
@ -382,27 +389,28 @@ memory object has the following properties:
- The width of an addressable word - The width of an addressable word
- The size of the memory in number of words - The size of the memory in number of words
All read accesses to the memory are transformed to $memrd cells and all write All read accesses to the memory are transformed to ``$memrd`` cells and all
accesses to $memwr cells by the language frontend. These cells consist of write accesses to ``$memwr`` cells by the language frontend. These cells consist
independent read- and write-ports to the memory. Memory initialization is of independent read- and write-ports to the memory. Memory initialization is
transformed to $meminit cells by the language frontend. The ``\MEMID`` parameter transformed to ``$meminit`` cells by the language frontend. The ``\MEMID``
on these cells is used to link them together and to the RTLIL::Memory object parameter on these cells is used to link them together and to the
they belong to. ``RTLIL::Memory`` object they belong to.
The rationale behind using separate cells for the individual ports versus The rationale behind using separate cells for the individual ports versus
creating a large multiport memory cell right in the language frontend is that 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. the separate ``$memrd`` and ``$memwr`` cells can be consolidated using resource
As resource sharing is a non-trivial optimization problem where different sharing. As resource sharing is a non-trivial optimization problem where
synthesis tasks can have different requirements it lends itself to do the different synthesis tasks can have different requirements it lends itself to do
optimisation in separate passes and merge the RTLIL::Memory objects and $memrd the optimisation in separate passes and merge the ``RTLIL::Memory`` objects and
and $memwr cells to multiport memory blocks after resource sharing is completed. ``$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 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 passed to it) transform the memories directly to d-type flip-flops and address
logic or yield multiport memory blocks (represented using $mem cells). logic or yield multiport memory blocks (represented using ``$mem`` cells).
See :ref:`sec:memcells` for details about the memory cell types. See :ref:`sec:memcells` for details about the memory cell types.
.. [1] .. [1]
The syntax 1'1 in the RTLIL code specifies a constant with a length of one The syntax ``1'1`` in the RTLIL code specifies a constant with a length of
bit (the first "1"), and this bit is a one (the second "1"). one bit (the first ``1``), and this bit is a one (the second ``1``).