mirror of
https://github.com/YosysHQ/yosys
synced 2025-06-12 09:03:27 +00:00
Reorganising documentation
Also changing to furo theme.
This commit is contained in:
parent
4f1cd66829
commit
045c04096e
40 changed files with 661 additions and 1282 deletions
1022
docs/source/yosys_internals/formats/cell_library.rst
Normal file
1022
docs/source/yosys_internals/formats/cell_library.rst
Normal file
File diff suppressed because it is too large
Load diff
11
docs/source/yosys_internals/formats/index.rst
Normal file
11
docs/source/yosys_internals/formats/index.rst
Normal file
|
@ -0,0 +1,11 @@
|
|||
Internal formats
|
||||
================
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
overview
|
||||
rtlil
|
||||
rtlil_text
|
||||
cell_library
|
||||
|
53
docs/source/yosys_internals/formats/overview.rst
Normal file
53
docs/source/yosys_internals/formats/overview.rst
Normal file
|
@ -0,0 +1,53 @@
|
|||
Format overview
|
||||
===============
|
||||
|
||||
Yosys uses two different internal formats. The first is used to store an
|
||||
abstract syntax tree (AST) of a Verilog input file. This format is simply called
|
||||
AST and is generated by the Verilog Frontend. This data structure is consumed by
|
||||
a subsystem called AST Frontend [1]_. This AST Frontend then generates a design
|
||||
in Yosys' main internal format, the
|
||||
Register-Transfer-Level-Intermediate-Language (RTLIL) representation. It does
|
||||
that by first performing a number of simplifications within the AST
|
||||
representation and then generating RTLIL from the simplified AST data structure.
|
||||
|
||||
The RTLIL representation is used by all passes as input and outputs. This has
|
||||
the following advantages over using different representational formats between
|
||||
different passes:
|
||||
|
||||
- The passes can be rearranged in a different order and passes can be removed
|
||||
or inserted.
|
||||
|
||||
- Passes can simply pass-thru the parts of the design they don't change without
|
||||
the need to convert between formats. In fact Yosys passes output the same
|
||||
data structure they received as input and performs all changes in place.
|
||||
|
||||
- All passes use the same interface, thus reducing the effort required to
|
||||
understand a pass when reading the Yosys source code, e.g. when adding
|
||||
additional features.
|
||||
|
||||
The RTLIL representation is basically a netlist representation with the
|
||||
following additional features:
|
||||
|
||||
- An internal cell library with fixed-function cells to represent RTL datapath
|
||||
and register cells as well as logical gate-level cells (single-bit gates and
|
||||
registers).
|
||||
|
||||
- Support for multi-bit values that can use individual bits from wires as well
|
||||
as constant bits to represent coarse-grain netlists.
|
||||
|
||||
- Support for basic behavioural constructs (if-then-else structures and
|
||||
multi-case switches with a sensitivity list for updating the outputs).
|
||||
|
||||
- Support for multi-port memories.
|
||||
|
||||
The use of RTLIL also has the disadvantage of having a very powerful format
|
||||
between all passes, even when doing gate-level synthesis where the more advanced
|
||||
features are not needed. In order to reduce complexity for passes that operate
|
||||
on a low-level representation, these passes check the features used in the input
|
||||
RTLIL and fail to run when unsupported high-level constructs are used. In such
|
||||
cases a pass that transforms the higher-level constructs to lower-level
|
||||
constructs must be called from the synthesis script first.
|
||||
|
||||
.. [1]
|
||||
In Yosys the term pass is only used to refer to commands that operate on the
|
||||
RTLIL data structure.
|
408
docs/source/yosys_internals/formats/rtlil.rst
Normal file
408
docs/source/yosys_internals/formats/rtlil.rst
Normal file
|
@ -0,0 +1,408 @@
|
|||
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 :ref:`sec:memcells` for details about the memory cell types.
|
||||
|
||||
.. [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").
|
297
docs/source/yosys_internals/formats/rtlil_text.rst
Normal file
297
docs/source/yosys_internals/formats/rtlil_text.rst
Normal file
|
@ -0,0 +1,297 @@
|
|||
.. _chapter:textrtlil:
|
||||
|
||||
RTLIL text representation
|
||||
-------------------------
|
||||
|
||||
This appendix documents the text representation of RTLIL in extended Backus-Naur
|
||||
form (EBNF).
|
||||
|
||||
The grammar is not meant to represent semantic limitations. That is, the grammar
|
||||
is "permissive", and later stages of processing perform more rigorous checks.
|
||||
|
||||
The grammar is also not meant to represent the exact grammar used in the RTLIL
|
||||
frontend, since that grammar is specific to processing by lex and yacc, is even
|
||||
more permissive, and is somewhat less understandable than simple EBNF notation.
|
||||
|
||||
Finally, note that all statements (rules ending in ``-stmt``) terminate in an
|
||||
end-of-line. Because of this, a statement cannot be broken into multiple lines.
|
||||
|
||||
Lexical elements
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
Characters
|
||||
^^^^^^^^^^
|
||||
|
||||
An RTLIL file is a stream of bytes. Strictly speaking, a "character" in an RTLIL
|
||||
file is a single byte. The lexer treats multi-byte encoded characters as
|
||||
consecutive single-byte characters. While other encodings *may* work, UTF-8 is
|
||||
known to be safe to use. Byte order marks at the beginning of the file will
|
||||
cause an error.
|
||||
|
||||
ASCII spaces (32) and tabs (9) separate lexer tokens.
|
||||
|
||||
A ``nonws`` character, used in identifiers, is any character whose encoding
|
||||
consists solely of bytes above ASCII space (32).
|
||||
|
||||
An ``eol`` is one or more consecutive ASCII newlines (10) and carriage returns
|
||||
(13).
|
||||
|
||||
Identifiers
|
||||
^^^^^^^^^^^
|
||||
|
||||
There are two types of identifiers in RTLIL:
|
||||
|
||||
- Publically visible identifiers
|
||||
- Auto-generated identifiers
|
||||
|
||||
.. code:: BNF
|
||||
|
||||
<id> ::= <public-id> | <autogen-id>
|
||||
<public-id> ::= \ <nonws>+
|
||||
<autogen-id> ::= $ <nonws>+
|
||||
|
||||
Values
|
||||
^^^^^^
|
||||
|
||||
A *value* consists of a width in bits and a bit representation, most
|
||||
significant bit first. Bits may be any of:
|
||||
|
||||
- ``0``: A logic zero value
|
||||
- ``1``: A logic one value
|
||||
- ``x``: An unknown logic value (or don't care in case patterns)
|
||||
- ``z``: A high-impedance value (or don't care in case patterns)
|
||||
- ``m``: A marked bit (internal use only)
|
||||
- ``-``: A don't care value
|
||||
|
||||
An *integer* is simply a signed integer value in decimal format. **Warning:**
|
||||
Integer constants are limited to 32 bits. That is, they may only be in the range
|
||||
:math:`[-2147483648, 2147483648)`. Integers outside this range will result in an
|
||||
error.
|
||||
|
||||
.. code:: BNF
|
||||
|
||||
<value> ::= <decimal-digit>+ ' <binary-digit>*
|
||||
<decimal-digit> ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
|
||||
<binary-digit> ::= 0 | 1 | x | z | m | -
|
||||
<integer> ::= -? <decimal-digit>+
|
||||
|
||||
Strings
|
||||
^^^^^^^
|
||||
|
||||
A string is a series of characters delimited by double-quote characters. Within
|
||||
a string, any character except ASCII NUL (0) may be used. In addition, certain
|
||||
escapes can be used:
|
||||
|
||||
- ``\n``: A newline
|
||||
- ``\t``: A tab
|
||||
- ``\ooo``: A character specified as a one, two, or three digit octal value
|
||||
|
||||
All other characters may be escaped by a backslash, and become the following
|
||||
character. Thus:
|
||||
|
||||
- ``\\``: A backslash
|
||||
- ``\"``: A double-quote
|
||||
- ``\r``: An 'r' character
|
||||
|
||||
Comments
|
||||
^^^^^^^^
|
||||
|
||||
A comment starts with a ``#`` character and proceeds to the end of the line. All
|
||||
comments are ignored.
|
||||
|
||||
File
|
||||
~~~~
|
||||
|
||||
A file consists of an optional autoindex statement followed by zero or more
|
||||
modules.
|
||||
|
||||
.. code:: BNF
|
||||
|
||||
<file> ::= <autoidx-stmt>? <module>*
|
||||
|
||||
Autoindex statements
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The autoindex statement sets the global autoindex value used by Yosys when it
|
||||
needs to generate a unique name, e.g. ``flattenN``. The N part is filled with
|
||||
the value of the global autoindex value, which is subsequently incremented. This
|
||||
global has to be dumped into RTLIL, otherwise e.g. dumping and running a pass
|
||||
would have different properties than just running a pass on a warm design.
|
||||
|
||||
.. code:: BNF
|
||||
|
||||
<autoidx-stmt> ::= autoidx <integer> <eol>
|
||||
|
||||
Modules
|
||||
^^^^^^^
|
||||
|
||||
Declares a module, with zero or more attributes, consisting of zero or more
|
||||
wires, memories, cells, processes, and connections.
|
||||
|
||||
.. code:: BNF
|
||||
|
||||
<module> ::= <attr-stmt>* <module-stmt> <module-body> <module-end-stmt>
|
||||
<module-stmt> ::= module <id> <eol>
|
||||
<module-body> ::= (<param-stmt>
|
||||
| <wire>
|
||||
| <memory>
|
||||
| <cell>
|
||||
| <process>)*
|
||||
<param-stmt> ::= parameter <id> <constant>? <eol>
|
||||
<constant> ::= <value> | <integer> | <string>
|
||||
<module-end-stmt> ::= end <eol>
|
||||
|
||||
Attribute statements
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Declares an attribute with the given identifier and value.
|
||||
|
||||
.. code:: BNF
|
||||
|
||||
<attr-stmt> ::= attribute <id> <constant> <eol>
|
||||
|
||||
Signal specifications
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
A signal is anything that can be applied to a cell port, i.e. a constant value,
|
||||
all bits or a selection of bits from a wire, or concatenations of those.
|
||||
|
||||
**Warning:** When an integer constant is a sigspec, it is always 32 bits wide,
|
||||
2's complement. For example, a constant of :math:`-1` is the same as
|
||||
``32'11111111111111111111111111111111``, while a constant of :math:`1` is the
|
||||
same as ``32'1``.
|
||||
|
||||
See :ref:`sec:rtlil_sigspec` for an overview of signal specifications.
|
||||
|
||||
.. code:: BNF
|
||||
|
||||
<sigspec> ::= <constant>
|
||||
| <wire-id>
|
||||
| <sigspec> [ <integer> (:<integer>)? ]
|
||||
| { <sigspec>* }
|
||||
|
||||
Connections
|
||||
^^^^^^^^^^^
|
||||
|
||||
Declares a connection between the given signals.
|
||||
|
||||
.. code:: BNF
|
||||
|
||||
<conn-stmt> ::= connect <sigspec> <sigspec> <eol>
|
||||
|
||||
Wires
|
||||
^^^^^
|
||||
|
||||
Declares a wire, with zero or more attributes, with the given identifier and
|
||||
options in the enclosing module.
|
||||
|
||||
See :ref:`sec:rtlil_cell_wire` for an overview of wires.
|
||||
|
||||
.. code:: BNF
|
||||
|
||||
<wire> ::= <attr-stmt>* <wire-stmt>
|
||||
<wire-stmt> ::= wire <wire-option>* <wire-id> <eol>
|
||||
<wire-id> ::= <id>
|
||||
<wire-option> ::= width <integer>
|
||||
| offset <integer>
|
||||
| input <integer>
|
||||
| output <integer>
|
||||
| inout <integer>
|
||||
| upto
|
||||
| signed
|
||||
|
||||
Memories
|
||||
^^^^^^^^
|
||||
|
||||
Declares a memory, with zero or more attributes, with the given identifier and
|
||||
options in the enclosing module.
|
||||
|
||||
See :ref:`sec:rtlil_memory` for an overview of memory cells, and
|
||||
:ref:`sec:memcells` for details about memory cell types.
|
||||
|
||||
.. code:: BNF
|
||||
|
||||
<memory> ::= <attr-stmt>* <memory-stmt>
|
||||
<memory-stmt> ::= memory <memory-option>* <id> <eol>
|
||||
<memory-option> ::= width <integer>
|
||||
| size <integer>
|
||||
| offset <integer>
|
||||
|
||||
Cells
|
||||
^^^^^
|
||||
|
||||
Declares a cell, with zero or more attributes, with the given identifier and
|
||||
type in the enclosing module.
|
||||
|
||||
Cells perform functions on input signals. See :ref:`chapter:celllib` for a
|
||||
detailed list of cell types.
|
||||
|
||||
.. code:: BNF
|
||||
|
||||
<cell> ::= <attr-stmt>* <cell-stmt> <cell-body-stmt>* <cell-end-stmt>
|
||||
<cell-stmt> ::= cell <cell-type> <cell-id> <eol>
|
||||
<cell-id> ::= <id>
|
||||
<cell-type> ::= <id>
|
||||
<cell-body-stmt> ::= parameter (signed | real)? <id> <constant> <eol>
|
||||
| connect <id> <sigspec> <eol>
|
||||
<cell-end-stmt> ::= end <eol>
|
||||
|
||||
|
||||
Processes
|
||||
^^^^^^^^^
|
||||
|
||||
Declares a process, with zero or more attributes, with the given identifier in
|
||||
the enclosing module. The body of a process consists of zero or more
|
||||
assignments, exactly one switch, and zero or more syncs.
|
||||
|
||||
See :ref:`sec:rtlil_process` for an overview of processes.
|
||||
|
||||
.. code:: BNF
|
||||
|
||||
<process> ::= <attr-stmt>* <proc-stmt> <process-body> <proc-end-stmt>
|
||||
<proc-stmt> ::= process <id> <eol>
|
||||
<process-body> ::= <assign-stmt>* <switch>? <assign-stmt>* <sync>*
|
||||
<assign-stmt> ::= assign <dest-sigspec> <src-sigspec> <eol>
|
||||
<dest-sigspec> ::= <sigspec>
|
||||
<src-sigspec> ::= <sigspec>
|
||||
<proc-end-stmt> ::= end <eol>
|
||||
|
||||
Switches
|
||||
^^^^^^^^
|
||||
|
||||
Switches test a signal for equality against a list of cases. Each case specifies
|
||||
a comma-separated list of signals to check against. If there are no signals in
|
||||
the list, then the case is the default case. The body of a case consists of zero
|
||||
or more switches and assignments. Both switches and cases may have zero or more
|
||||
attributes.
|
||||
|
||||
.. code:: BNF
|
||||
|
||||
<switch> ::= <switch-stmt> <case>* <switch-end-stmt>
|
||||
<switch-stmt> := <attr-stmt>* switch <sigspec> <eol>
|
||||
<case> ::= <attr-stmt>* <case-stmt> <case-body>
|
||||
<case-stmt> ::= case <compare>? <eol>
|
||||
<compare> ::= <sigspec> (, <sigspec>)*
|
||||
<case-body> ::= (<switch> | <assign-stmt>)*
|
||||
<switch-end-stmt> ::= end <eol>
|
||||
|
||||
Syncs
|
||||
^^^^^
|
||||
|
||||
Syncs update signals with other signals when an event happens. Such an event may
|
||||
be:
|
||||
|
||||
- An edge or level on a signal
|
||||
- Global clock ticks
|
||||
- Initialization
|
||||
- Always
|
||||
|
||||
.. code:: BNF
|
||||
|
||||
<sync> ::= <sync-stmt> <update-stmt>*
|
||||
<sync-stmt> ::= sync <sync-type> <sigspec> <eol>
|
||||
| sync global <eol>
|
||||
| sync init <eol>
|
||||
| sync always <eol>
|
||||
<sync-type> ::= low | high | posedge | negedge | edge
|
||||
<update-stmt> ::= update <dest-sigspec> <src-sigspec> <eol>
|
Loading…
Add table
Add a link
Reference in a new issue