mirror of https://github.com/YosysHQ/yosys.git
Docs: Reflow line length
This commit is contained in:
parent
829e02ec5b
commit
40ba92e956
|
@ -2,13 +2,12 @@ Synthesis starter
|
|||
-----------------
|
||||
|
||||
This page will be a guided walkthrough of the prepackaged iCE40 FPGA synthesis
|
||||
script - `synth_ice40`. We will take a simple design through each
|
||||
step, looking at the commands being called and what they do to the design. While
|
||||
`synth_ice40` is specific to the iCE40 platform, most of the operations
|
||||
we will be discussing are common across the majority of FPGA synthesis scripts.
|
||||
Thus, this document will provide a good foundational understanding of how
|
||||
synthesis in Yosys is performed, regardless of the actual architecture being
|
||||
used.
|
||||
script - `synth_ice40`. We will take a simple design through each step, looking
|
||||
at the commands being called and what they do to the design. While `synth_ice40`
|
||||
is specific to the iCE40 platform, most of the operations we will be discussing
|
||||
are common across the majority of FPGA synthesis scripts. Thus, this document
|
||||
will provide a good foundational understanding of how synthesis in Yosys is
|
||||
performed, regardless of the actual architecture being used.
|
||||
|
||||
.. seealso:: Advanced usage docs for
|
||||
:doc:`/using_yosys/synthesis/synth`
|
||||
|
@ -105,10 +104,10 @@ Since we're just getting started, let's instead begin with :yoscrypt:`hierarchy
|
|||
|
||||
.. note::
|
||||
|
||||
`hierarchy` should always be the first command after the design has
|
||||
been read. By specifying the top module, `hierarchy` will also set
|
||||
the ``(* top *)`` attribute on it. This is used by other commands that need
|
||||
to know which module is the top.
|
||||
`hierarchy` should always be the first command after the design has been
|
||||
read. By specifying the top module, `hierarchy` will also set the ``(* top
|
||||
*)`` attribute on it. This is used by other commands that need to know which
|
||||
module is the top.
|
||||
|
||||
.. use doscon for a console-like display that supports the `yosys> [command]` format.
|
||||
|
||||
|
@ -129,20 +128,20 @@ Our ``addr_gen`` circuit now looks like this:
|
|||
|
||||
Simple operations like ``addr + 1`` and ``addr == MAX_DATA-1`` can be extracted
|
||||
from our ``always @`` block in :ref:`addr_gen-v`. This gives us the highlighted
|
||||
`$add` and `$eq` cells we see. But control logic (like the ``if .. else``)
|
||||
and memory elements (like the ``addr <= 0``) are not so straightforward. These
|
||||
get put into "processes", shown in the schematic as ``PROC``. Note how the
|
||||
second line refers to the line numbers of the start/end of the corresponding
|
||||
``always @`` block. In the case of an ``initial`` block, we instead see the
|
||||
``PROC`` referring to line 0.
|
||||
`$add` and `$eq` cells we see. But control logic (like the ``if .. else``) and
|
||||
memory elements (like the ``addr <= 0``) are not so straightforward. These get
|
||||
put into "processes", shown in the schematic as ``PROC``. Note how the second
|
||||
line refers to the line numbers of the start/end of the corresponding ``always
|
||||
@`` block. In the case of an ``initial`` block, we instead see the ``PROC``
|
||||
referring to line 0.
|
||||
|
||||
To handle these, let us now introduce the next command: :doc:`/cmd/proc`.
|
||||
`proc` is a macro command like `synth_ice40`. Rather than
|
||||
modifying the design directly, it instead calls a series of other commands. In
|
||||
the case of `proc`, these sub-commands work to convert the behavioral
|
||||
logic of processes into multiplexers and registers. Let's see what happens when
|
||||
we run it. For now, we will call :yoscrypt:`proc -noopt` to prevent some
|
||||
automatic optimizations which would normally happen.
|
||||
To handle these, let us now introduce the next command: :doc:`/cmd/proc`. `proc`
|
||||
is a macro command like `synth_ice40`. Rather than modifying the design
|
||||
directly, it instead calls a series of other commands. In the case of `proc`,
|
||||
these sub-commands work to convert the behavioral logic of processes into
|
||||
multiplexers and registers. Let's see what happens when we run it. For now, we
|
||||
will call :yoscrypt:`proc -noopt` to prevent some automatic optimizations which
|
||||
would normally happen.
|
||||
|
||||
.. figure:: /_images/code_examples/fifo/addr_gen_proc.*
|
||||
:class: width-helper invert-helper
|
||||
|
@ -151,19 +150,18 @@ automatic optimizations which would normally happen.
|
|||
``addr_gen`` module after :yoscrypt:`proc -noopt`
|
||||
|
||||
There are now a few new cells from our ``always @``, which have been
|
||||
highlighted. The ``if`` statements are now modeled with `$mux` cells, while
|
||||
the register uses an `$adff` cell. If we look at the terminal output we can
|
||||
also see all of the different ``proc_*`` commands being called. We will look at
|
||||
each of these in more detail in :doc:`/using_yosys/synthesis/proc`.
|
||||
highlighted. The ``if`` statements are now modeled with `$mux` cells, while the
|
||||
register uses an `$adff` cell. If we look at the terminal output we can also
|
||||
see all of the different ``proc_*`` commands being called. We will look at each
|
||||
of these in more detail in :doc:`/using_yosys/synthesis/proc`.
|
||||
|
||||
Notice how in the top left of :ref:`addr_gen_proc` we have a floating wire,
|
||||
generated from the initial assignment of 0 to the ``addr`` wire. However, this
|
||||
initial assignment is not synthesizable, so this will need to be cleaned up
|
||||
before we can generate the physical hardware. We can do this now by calling
|
||||
`clean`. We're also going to call `opt_expr` now, which would
|
||||
normally be called at the end of `proc`. We can call both commands at
|
||||
the same time by separating them with a colon and space: :yoscrypt:`opt_expr;
|
||||
clean`.
|
||||
`clean`. We're also going to call `opt_expr` now, which would normally be
|
||||
called at the end of `proc`. We can call both commands at the same time by
|
||||
separating them with a colon and space: :yoscrypt:`opt_expr; clean`.
|
||||
|
||||
.. figure:: /_images/code_examples/fifo/addr_gen_clean.*
|
||||
:class: width-helper invert-helper
|
||||
|
@ -171,24 +169,24 @@ clean`.
|
|||
|
||||
``addr_gen`` module after :yoscrypt:`opt_expr; clean`
|
||||
|
||||
You may also notice that the highlighted `$eq` cell input of ``255`` has
|
||||
changed to ``8'11111111``. Constant values are presented in the format
|
||||
You may also notice that the highlighted `$eq` cell input of ``255`` has changed
|
||||
to ``8'11111111``. Constant values are presented in the format
|
||||
``<bit_width>'<bits>``, with 32-bit values instead using the decimal number.
|
||||
This indicates that the constant input has been reduced from 32-bit wide to
|
||||
8-bit wide. This is a side-effect of running `opt_expr`, which
|
||||
performs constant folding and simple expression rewriting. For more on why
|
||||
this happens, refer to :doc:`/using_yosys/synthesis/opt` and the :ref:`section
|
||||
on opt_expr <adv_opt_expr>`.
|
||||
8-bit wide. This is a side-effect of running `opt_expr`, which performs
|
||||
constant folding and simple expression rewriting. For more on why this
|
||||
happens, refer to :doc:`/using_yosys/synthesis/opt` and the :ref:`section on
|
||||
opt_expr <adv_opt_expr>`.
|
||||
|
||||
.. note::
|
||||
|
||||
:doc:`/cmd/clean` can also be called with two semicolons after any command,
|
||||
for example we could have called :yoscrypt:`opt_expr;;` instead of
|
||||
:yoscrypt:`opt_expr; clean`. You may notice some scripts will end each line
|
||||
with ``;;``. It is beneficial to run `clean` before inspecting
|
||||
intermediate products to remove disconnected parts of the circuit which have
|
||||
been left over, and in some cases can reduce the processing required in
|
||||
subsequent commands.
|
||||
with ``;;``. It is beneficial to run `clean` before inspecting intermediate
|
||||
products to remove disconnected parts of the circuit which have been left
|
||||
over, and in some cases can reduce the processing required in subsequent
|
||||
commands.
|
||||
|
||||
.. todo:: consider a brief glossary for terms like adff
|
||||
|
||||
|
@ -202,8 +200,8 @@ The full example
|
|||
|
||||
Let's now go back and check on our full design by using :yoscrypt:`hierarchy
|
||||
-check -top fifo`. By passing the ``-check`` option there we are also telling
|
||||
the `hierarchy` command that if the design includes any non-blackbox
|
||||
modules without an implementation it should return an error.
|
||||
the `hierarchy` command that if the design includes any non-blackbox modules
|
||||
without an implementation it should return an error.
|
||||
|
||||
Note that if we tried to run this command now then we would get an error. This
|
||||
is because we already removed all of the modules other than ``addr_gen``. We
|
||||
|
@ -221,13 +219,12 @@ could restart our shell session, but instead let's use two new commands:
|
|||
Notice how this time we didn't see any of those ``$abstract`` modules? That's
|
||||
because when we ran ``yosys fifo.v``, the first command Yosys called was
|
||||
:yoscrypt:`read_verilog -defer fifo.v`. The ``-defer`` option there tells
|
||||
`read_verilog` only read the abstract syntax tree and defer actual
|
||||
compilation to a later `hierarchy` command. This is useful in cases
|
||||
where the default parameters of modules yield invalid code which is not
|
||||
synthesizable. This is why Yosys defers compilation automatically and is one of
|
||||
the reasons why hierarchy should always be the first command after loading the
|
||||
design. If we know that our design won't run into this issue, we can skip the
|
||||
``-defer``.
|
||||
`read_verilog` only read the abstract syntax tree and defer actual compilation
|
||||
to a later `hierarchy` command. This is useful in cases where the default
|
||||
parameters of modules yield invalid code which is not synthesizable. This is why
|
||||
Yosys defers compilation automatically and is one of the reasons why hierarchy
|
||||
should always be the first command after loading the design. If we know that
|
||||
our design won't run into this issue, we can skip the ``-defer``.
|
||||
|
||||
.. todo:: `hierarchy` failure modes
|
||||
|
||||
|
@ -243,13 +240,13 @@ design. If we know that our design won't run into this issue, we can skip the
|
|||
interactive terminal. :kbd:`ctrl+c` (i.e. SIGINT) will also end the terminal
|
||||
session but will return an error code rather than exiting gracefully.
|
||||
|
||||
We can also run `proc` now to finish off the full :ref:`synth_begin`.
|
||||
Because the design schematic is quite large, we will be showing just the data
|
||||
path for the ``rdata`` output. If you would like to see the entire design for
|
||||
yourself, you can do so with :doc:`/cmd/show`. Note that the `show`
|
||||
command only works with a single module, so you may need to call it with
|
||||
:yoscrypt:`show fifo`. :ref:`show_intro` section in
|
||||
:doc:`/getting_started/scripting_intro` has more on how to use `show`.
|
||||
We can also run `proc` now to finish off the full :ref:`synth_begin`. Because
|
||||
the design schematic is quite large, we will be showing just the data path for
|
||||
the ``rdata`` output. If you would like to see the entire design for yourself,
|
||||
you can do so with :doc:`/cmd/show`. Note that the `show` command only works
|
||||
with a single module, so you may need to call it with :yoscrypt:`show fifo`.
|
||||
:ref:`show_intro` section in :doc:`/getting_started/scripting_intro` has more on
|
||||
how to use `show`.
|
||||
|
||||
.. figure:: /_images/code_examples/fifo/rdata_proc.*
|
||||
:class: width-helper invert-helper
|
||||
|
@ -321,11 +318,10 @@ merging happened during the call to `clean` which we can see in the
|
|||
output.
|
||||
|
||||
Depending on the target architecture, this stage of synthesis might also see
|
||||
commands such as `tribuf` with the ``-logic`` option and
|
||||
`deminout`. These remove tristate and inout constructs respectively,
|
||||
replacing them with logic suitable for mapping to an FPGA. Since we do not have
|
||||
any such constructs in our example running these commands does not change our
|
||||
design.
|
||||
commands such as `tribuf` with the ``-logic`` option and `deminout`. These
|
||||
remove tristate and inout constructs respectively, replacing them with logic
|
||||
suitable for mapping to an FPGA. Since we do not have any such constructs in
|
||||
our example running these commands does not change our design.
|
||||
|
||||
The coarse-grain representation
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
@ -342,9 +338,9 @@ optimizations and other transformations done previously.
|
|||
|
||||
.. note::
|
||||
|
||||
While the iCE40 flow had a :ref:`synth_flatten` and put `proc` in
|
||||
the :ref:`synth_begin`, some synthesis scripts will instead include these in
|
||||
this section.
|
||||
While the iCE40 flow had a :ref:`synth_flatten` and put `proc` in the
|
||||
:ref:`synth_begin`, some synthesis scripts will instead include these in this
|
||||
section.
|
||||
|
||||
Part 1
|
||||
^^^^^^
|
||||
|
@ -359,24 +355,23 @@ In the iCE40 flow, we start with the following commands:
|
|||
:caption: ``coarse`` section (part 1)
|
||||
:name: synth_coarse1
|
||||
|
||||
We've already come across `opt_expr`, and `opt_clean` is the
|
||||
same as `clean` but with more verbose output. The `check`
|
||||
pass identifies a few obvious problems which will cause errors later. Calling
|
||||
it here lets us fail faster rather than wasting time on something we know is
|
||||
impossible.
|
||||
We've already come across `opt_expr`, and `opt_clean` is the same as `clean` but
|
||||
with more verbose output. The `check` pass identifies a few obvious problems
|
||||
which will cause errors later. Calling it here lets us fail faster rather than
|
||||
wasting time on something we know is impossible.
|
||||
|
||||
Next up is :yoscrypt:`opt -nodffe -nosdff` performing a set of simple
|
||||
optimizations on the design. This command also ensures that only a specific
|
||||
subset of FF types are included, in preparation for the next command:
|
||||
:doc:`/cmd/fsm`. Both `opt` and `fsm` are macro commands
|
||||
which are explored in more detail in :doc:`/using_yosys/synthesis/opt` and
|
||||
:doc:`/cmd/fsm`. Both `opt` and `fsm` are macro commands which are explored in
|
||||
more detail in :doc:`/using_yosys/synthesis/opt` and
|
||||
:doc:`/using_yosys/synthesis/fsm` respectively.
|
||||
|
||||
Up until now, the data path for ``rdata`` has remained the same since
|
||||
:ref:`rdata_flat`. However the next call to `opt` does cause a change.
|
||||
Specifically, the call to `opt_dff` without the ``-nodffe -nosdff``
|
||||
options is able to fold one of the `$mux` cells into the `$adff` to form an
|
||||
`$adffe` cell; highlighted below:
|
||||
Specifically, the call to `opt_dff` without the ``-nodffe -nosdff`` options is
|
||||
able to fold one of the `$mux` cells into the `$adff` to form an `$adffe` cell;
|
||||
highlighted below:
|
||||
|
||||
.. literalinclude:: /code_examples/fifo/fifo.out
|
||||
:language: doscon
|
||||
|
@ -433,8 +428,8 @@ The next two (new) commands are :doc:`/cmd/peepopt` and :doc:`/cmd/share`.
|
|||
Neither of these affect our design, and they're explored in more detail in
|
||||
:doc:`/using_yosys/synthesis/opt`, so let's skip over them. :yoscrypt:`techmap
|
||||
-map +/cmp2lut.v -D LUT_WIDTH=4` optimizes certain comparison operators by
|
||||
converting them to LUTs instead. The usage of `techmap` is explored
|
||||
more in :doc:`/using_yosys/synthesis/techmap_synth`.
|
||||
converting them to LUTs instead. The usage of `techmap` is explored more in
|
||||
:doc:`/using_yosys/synthesis/techmap_synth`.
|
||||
|
||||
Our next command to run is
|
||||
:doc:`/cmd/memory_dff`.
|
||||
|
@ -451,9 +446,9 @@ Our next command to run is
|
|||
|
||||
``rdata`` output after `memory_dff`
|
||||
|
||||
As the title suggests, `memory_dff` has merged the output `$dff` into
|
||||
the `$memrd` cell and converted it to a `$memrd_v2` (highlighted). This has
|
||||
also connected the ``CLK`` port to the ``clk`` input as it is now a synchronous
|
||||
As the title suggests, `memory_dff` has merged the output `$dff` into the
|
||||
`$memrd` cell and converted it to a `$memrd_v2` (highlighted). This has also
|
||||
connected the ``CLK`` port to the ``clk`` input as it is now a synchronous
|
||||
memory read with appropriate enable (``EN=1'1``) and reset (``ARST=1'0`` and
|
||||
``SRST=1'0``) inputs.
|
||||
|
||||
|
@ -466,12 +461,11 @@ memory read with appropriate enable (``EN=1'1``) and reset (``ARST=1'0`` and
|
|||
Part 3
|
||||
^^^^^^
|
||||
|
||||
The third part of the `synth_ice40` flow is a series of commands for
|
||||
mapping to DSPs. By default, the iCE40 flow will not map to the hardware DSP
|
||||
blocks and will only be performed if called with the ``-dsp`` flag:
|
||||
:yoscrypt:`synth_ice40 -dsp`. While our example has nothing that could be
|
||||
mapped to DSPs we can still take a quick look at the commands here and describe
|
||||
what they do.
|
||||
The third part of the `synth_ice40` flow is a series of commands for mapping to
|
||||
DSPs. By default, the iCE40 flow will not map to the hardware DSP blocks and
|
||||
will only be performed if called with the ``-dsp`` flag: :yoscrypt:`synth_ice40
|
||||
-dsp`. While our example has nothing that could be mapped to DSPs we can still
|
||||
take a quick look at the commands here and describe what they do.
|
||||
|
||||
.. literalinclude:: /cmd/synth_ice40.rst
|
||||
:language: yoscrypt
|
||||
|
@ -483,28 +477,26 @@ what they do.
|
|||
|
||||
:yoscrypt:`wreduce t:$mul` performs width reduction again, this time targetting
|
||||
only cells of type `$mul`. :yoscrypt:`techmap -map +/mul2dsp.v -map
|
||||
+/ice40/dsp_map.v ... -D DSP_NAME=$__MUL16X16` uses `techmap` to map
|
||||
`$mul` cells to ``$__MUL16X16`` which are, in turn, mapped to the iCE40
|
||||
``SB_MAC16``. Any multipliers which aren't compatible with conversion to
|
||||
``$__MUL16X16`` are relabelled to ``$__soft_mul`` before `chtype`
|
||||
changes them back to `$mul`.
|
||||
+/ice40/dsp_map.v ... -D DSP_NAME=$__MUL16X16` uses `techmap` to map `$mul`
|
||||
cells to ``$__MUL16X16`` which are, in turn, mapped to the iCE40 ``SB_MAC16``.
|
||||
Any multipliers which aren't compatible with conversion to ``$__MUL16X16`` are
|
||||
relabelled to ``$__soft_mul`` before `chtype` changes them back to `$mul`.
|
||||
|
||||
During the mul2dsp conversion, some of the intermediate signals are marked with
|
||||
the attribute ``mul2dsp``. By calling :yoscrypt:`select a:mul2dsp` we restrict
|
||||
the following commands to only operate on the cells and wires used for these
|
||||
signals. `setattr` removes the now unnecessary ``mul2dsp`` attribute.
|
||||
`opt_expr` we've already come across for const folding and simple
|
||||
expression rewriting, the ``-fine`` option just enables more fine-grain
|
||||
optimizations. Then we perform width reduction a final time and clear the
|
||||
selection.
|
||||
`opt_expr` we've already come across for const folding and simple expression
|
||||
rewriting, the ``-fine`` option just enables more fine-grain optimizations.
|
||||
Then we perform width reduction a final time and clear the selection.
|
||||
|
||||
.. todo:: ``ice40_dsp`` is pmgen
|
||||
|
||||
Finally we have `ice40_dsp`: similar to the `memory_dff`
|
||||
command we saw in the previous section, this merges any surrounding registers
|
||||
into the ``SB_MAC16`` cell. This includes not just the input/output registers,
|
||||
but also pipeline registers and even a post-adder where applicable: turning a
|
||||
multiply + add into a single multiply-accumulate.
|
||||
Finally we have `ice40_dsp`: similar to the `memory_dff` command we saw in the
|
||||
previous section, this merges any surrounding registers into the ``SB_MAC16``
|
||||
cell. This includes not just the input/output registers, but also pipeline
|
||||
registers and even a post-adder where applicable: turning a multiply + add into
|
||||
a single multiply-accumulate.
|
||||
|
||||
.. seealso:: Advanced usage docs for
|
||||
:doc:`/using_yosys/synthesis/techmap_synth`
|
||||
|
@ -522,11 +514,10 @@ That brings us to the fourth and final part for the iCE40 synthesis flow:
|
|||
:caption: ``coarse`` section (part 4)
|
||||
:name: synth_coarse4
|
||||
|
||||
Where before each type of arithmetic operation had its own cell, e.g. `$add`,
|
||||
we now want to extract these into `$alu` and `$macc` cells which can help
|
||||
identify opportunities for reusing logic. We do this by running
|
||||
`alumacc`, which we can see produce the following changes in our
|
||||
example design:
|
||||
Where before each type of arithmetic operation had its own cell, e.g. `$add`, we
|
||||
now want to extract these into `$alu` and `$macc` cells which can help identify
|
||||
opportunities for reusing logic. We do this by running `alumacc`, which we can
|
||||
see produce the following changes in our example design:
|
||||
|
||||
.. literalinclude:: /code_examples/fifo/fifo.out
|
||||
:language: doscon
|
||||
|
@ -540,17 +531,17 @@ example design:
|
|||
|
||||
``rdata`` output after `alumacc`
|
||||
|
||||
Once these cells have been inserted, the call to `opt` can combine
|
||||
cells which are now identical but may have been missed due to e.g. the
|
||||
difference between `$add` and `$sub`.
|
||||
Once these cells have been inserted, the call to `opt` can combine cells which
|
||||
are now identical but may have been missed due to e.g. the difference between
|
||||
`$add` and `$sub`.
|
||||
|
||||
The other new command in this part is :doc:`/cmd/memory`. `memory` is
|
||||
another macro command which we examine in more detail in
|
||||
The other new command in this part is :doc:`/cmd/memory`. `memory` is another
|
||||
macro command which we examine in more detail in
|
||||
:doc:`/using_yosys/synthesis/memory`. For this document, let us focus just on
|
||||
the step most relevant to our example: `memory_collect`. Up until this
|
||||
point, our memory reads and our memory writes have been totally disjoint cells;
|
||||
operating on the same memory only in the abstract. `memory_collect`
|
||||
combines all of the reads and writes for a memory block into a single cell.
|
||||
the step most relevant to our example: `memory_collect`. Up until this point,
|
||||
our memory reads and our memory writes have been totally disjoint cells;
|
||||
operating on the same memory only in the abstract. `memory_collect` combines all
|
||||
of the reads and writes for a memory block into a single cell.
|
||||
|
||||
.. figure:: /_images/code_examples/fifo/rdata_coarse.*
|
||||
:class: width-helper invert-helper
|
||||
|
@ -609,19 +600,19 @@ Mapping to hard memory blocks uses a combination of `memory_libmap` and
|
|||
|
||||
``rdata`` output after :ref:`map_ram`
|
||||
|
||||
The :ref:`map_ram` converts the generic `$mem_v2` into the iCE40
|
||||
``SB_RAM40_4K`` (highlighted). We can also see the memory address has been
|
||||
remapped, and the data bits have been reordered (or swizzled). There is also
|
||||
now a `$mux` cell controlling the value of ``rdata``. In :ref:`fifo-v` we
|
||||
wrote our memory as read-before-write, however the ``SB_RAM40_4K`` has undefined
|
||||
behaviour when reading from and writing to the same address in the same cycle.
|
||||
As a result, extra logic is added so that the generated circuit matches the
|
||||
behaviour of the verilog. :ref:`no_rw_check` describes how we could change our
|
||||
verilog to match our hardware instead.
|
||||
The :ref:`map_ram` converts the generic `$mem_v2` into the iCE40 ``SB_RAM40_4K``
|
||||
(highlighted). We can also see the memory address has been remapped, and the
|
||||
data bits have been reordered (or swizzled). There is also now a `$mux` cell
|
||||
controlling the value of ``rdata``. In :ref:`fifo-v` we wrote our memory as
|
||||
read-before-write, however the ``SB_RAM40_4K`` has undefined behaviour when
|
||||
reading from and writing to the same address in the same cycle. As a result,
|
||||
extra logic is added so that the generated circuit matches the behaviour of the
|
||||
verilog. :ref:`no_rw_check` describes how we could change our verilog to match
|
||||
our hardware instead.
|
||||
|
||||
If we run `memory_libmap` under the `debug` command we can see
|
||||
candidates which were identified for mapping, along with the costs of each and
|
||||
what logic requires emulation.
|
||||
If we run `memory_libmap` under the `debug` command we can see candidates which
|
||||
were identified for mapping, along with the costs of each and what logic
|
||||
requires emulation.
|
||||
|
||||
.. literalinclude:: /code_examples/fifo/fifo.libmap
|
||||
:language: doscon
|
||||
|
@ -667,11 +658,10 @@ into flip flops (the ``logic fallback``) with `memory_map`.
|
|||
Arithmetic
|
||||
^^^^^^^^^^
|
||||
|
||||
Uses `techmap` to map basic arithmetic logic to hardware. This sees
|
||||
somewhat of an explosion in cells as multi-bit :cell:ref:`$mux` and `$adffe` are
|
||||
replaced with single-bit `$_MUX_` and `$_DFFE_PP0P_` cells, while the
|
||||
:cell:ref:`$alu` is replaced with primitive `$_OR_` and `$_NOT_` gates and a
|
||||
`$lut` cell.
|
||||
Uses `techmap` to map basic arithmetic logic to hardware. This sees somewhat of
|
||||
an explosion in cells as multi-bit `$mux` and `$adffe` are replaced with
|
||||
single-bit `$_MUX_` and `$_DFFE_PP0P_` cells, while the `$alu` is replaced with
|
||||
primitive `$_OR_` and `$_NOT_` gates and a `$lut` cell.
|
||||
|
||||
.. literalinclude:: /cmd/synth_ice40.rst
|
||||
:language: yoscrypt
|
||||
|
@ -693,12 +683,12 @@ replaced with single-bit `$_MUX_` and `$_DFFE_PP0P_` cells, while the
|
|||
Flip-flops
|
||||
^^^^^^^^^^
|
||||
|
||||
Convert FFs to the types supported in hardware with `dfflegalize`, and
|
||||
then use `techmap` to map them. In our example, this converts the
|
||||
`$_DFFE_PP0P_` cells to ``SB_DFFER``.
|
||||
Convert FFs to the types supported in hardware with `dfflegalize`, and then use
|
||||
`techmap` to map them. In our example, this converts the `$_DFFE_PP0P_` cells
|
||||
to ``SB_DFFER``.
|
||||
|
||||
We also run `simplemap` here to convert any remaining cells which could
|
||||
not be mapped to hardware into gate-level primitives. This includes optimizing
|
||||
We also run `simplemap` here to convert any remaining cells which could not be
|
||||
mapped to hardware into gate-level primitives. This includes optimizing
|
||||
`$_MUX_` cells where one of the inputs is a constant ``1'0``, replacing it
|
||||
instead with an `$_AND_` cell.
|
||||
|
||||
|
@ -722,11 +712,10 @@ instead with an `$_AND_` cell.
|
|||
LUTs
|
||||
^^^^
|
||||
|
||||
`abc` and `techmap` are used to map LUTs; converting primitive
|
||||
cell types to use `$lut` and ``SB_CARRY`` cells. Note that the iCE40 flow
|
||||
uses `abc9` rather than `abc`. For more on what these do, and
|
||||
what the difference between these two commands are, refer to
|
||||
:doc:`/using_yosys/synthesis/abc`.
|
||||
`abc` and `techmap` are used to map LUTs; converting primitive cell types to use
|
||||
`$lut` and ``SB_CARRY`` cells. Note that the iCE40 flow uses `abc9` rather than
|
||||
`abc`. For more on what these do, and what the difference between these two
|
||||
commands are, refer to :doc:`/using_yosys/synthesis/abc`.
|
||||
|
||||
.. literalinclude:: /cmd/synth_ice40.rst
|
||||
:language: yoscrypt
|
||||
|
@ -742,8 +731,8 @@ what the difference between these two commands are, refer to
|
|||
|
||||
``rdata`` output after :ref:`map_luts`
|
||||
|
||||
Finally we use `techmap` to map the generic `$lut` cells to iCE40
|
||||
``SB_LUT4`` cells.
|
||||
Finally we use `techmap` to map the generic `$lut` cells to iCE40 ``SB_LUT4``
|
||||
cells.
|
||||
|
||||
.. literalinclude:: /cmd/synth_ice40.rst
|
||||
:language: yoscrypt
|
||||
|
@ -801,28 +790,27 @@ The new commands here are:
|
|||
- :doc:`/cmd/stat`, and
|
||||
- :doc:`/cmd/blackbox`.
|
||||
|
||||
The output from `stat` is useful for checking resource utilization;
|
||||
providing a list of cells used in the design and the number of each, as well as
|
||||
the number of other resources used such as wires and processes. For this
|
||||
design, the final call to `stat` should look something like the
|
||||
following:
|
||||
The output from `stat` is useful for checking resource utilization; providing a
|
||||
list of cells used in the design and the number of each, as well as the number
|
||||
of other resources used such as wires and processes. For this design, the final
|
||||
call to `stat` should look something like the following:
|
||||
|
||||
.. literalinclude:: /code_examples/fifo/fifo.stat
|
||||
:language: doscon
|
||||
:start-at: yosys> stat -top fifo
|
||||
|
||||
Note that the :yoscrypt:`-top fifo` here is optional. `stat` will
|
||||
automatically use the module with the ``top`` attribute set, which ``fifo`` was
|
||||
when we called `hierarchy`. If no module is marked ``top``, then stats
|
||||
will be shown for each module selected.
|
||||
Note that the :yoscrypt:`-top fifo` here is optional. `stat` will automatically
|
||||
use the module with the ``top`` attribute set, which ``fifo`` was when we called
|
||||
`hierarchy`. If no module is marked ``top``, then stats will be shown for each
|
||||
module selected.
|
||||
|
||||
The `stat` output is also useful as a kind of sanity-check: Since we
|
||||
have already run `proc`, we wouldn't expect there to be any processes.
|
||||
We also expect ``data`` to use hard memory; if instead of an ``SB_RAM40_4K`` saw
|
||||
a high number of flip-flops being used we might suspect something was wrong.
|
||||
The `stat` output is also useful as a kind of sanity-check: Since we have
|
||||
already run `proc`, we wouldn't expect there to be any processes. We also expect
|
||||
``data`` to use hard memory; if instead of an ``SB_RAM40_4K`` saw a high number
|
||||
of flip-flops being used we might suspect something was wrong.
|
||||
|
||||
If we instead called `stat` immediately after :yoscrypt:`read_verilog
|
||||
fifo.v` we would see something very different:
|
||||
If we instead called `stat` immediately after :yoscrypt:`read_verilog fifo.v` we
|
||||
would see something very different:
|
||||
|
||||
.. literalinclude:: /code_examples/fifo/fifo.stat
|
||||
:language: doscon
|
||||
|
@ -845,10 +833,10 @@ The iCE40 synthesis flow has the following output modes available:
|
|||
|
||||
As an example, if we called :yoscrypt:`synth_ice40 -top fifo -json fifo.json`,
|
||||
our synthesized ``fifo`` design will be output as :file:`fifo.json`. We can
|
||||
then read the design back into Yosys with `read_json`, but make sure
|
||||
you use :yoscrypt:`design -reset` or open a new interactive terminal first. The
|
||||
JSON output we get can also be loaded into `nextpnr`_ to do place and route; but
|
||||
that is beyond the scope of this documentation.
|
||||
then read the design back into Yosys with `read_json`, but make sure you use
|
||||
:yoscrypt:`design -reset` or open a new interactive terminal first. The JSON
|
||||
output we get can also be loaded into `nextpnr`_ to do place and route; but that
|
||||
is beyond the scope of this documentation.
|
||||
|
||||
.. _nextpnr: https://github.com/YosysHQ/nextpnr
|
||||
|
||||
|
|
|
@ -184,9 +184,8 @@ directories:
|
|||
|
||||
``passes/``
|
||||
This directory contains a subdirectory for each pass or group of passes. For
|
||||
example as of this writing the directory :file:`passes/hierarchy/` contains the
|
||||
code for three passes: `hierarchy`, `submod`, and
|
||||
`uniquify`.
|
||||
example as of this writing the directory :file:`passes/hierarchy/` contains
|
||||
the code for three passes: `hierarchy`, `submod`, and `uniquify`.
|
||||
|
||||
``techlibs/``
|
||||
This directory contains simulation models and standard implementations for
|
||||
|
|
|
@ -61,24 +61,23 @@ already, let's take a look at some of those script files now.
|
|||
:caption: A section of :file:`fifo.ys`, generating the images used for :ref:`addr_gen_example`
|
||||
:name: fifo-ys
|
||||
|
||||
The first command there, :yoscrypt:`echo on`, uses `echo` to enable
|
||||
command echoes on. This is how we generated the code listing for
|
||||
The first command there, :yoscrypt:`echo on`, uses `echo` to enable command
|
||||
echoes on. This is how we generated the code listing for
|
||||
:ref:`hierarchy_output`. Turning command echoes on prints the ``yosys>
|
||||
hierarchy -top addr_gen`` line, making the output look the same as if it were an
|
||||
interactive terminal. :yoscrypt:`hierarchy -top addr_gen` is of course the
|
||||
command we were demonstrating, including the output text and an image of the
|
||||
design schematic after running it.
|
||||
|
||||
We briefly touched on `select` when it came up in
|
||||
`synth_ice40`, but let's look at it more now.
|
||||
We briefly touched on `select` when it came up in `synth_ice40`, but let's look
|
||||
at it more now.
|
||||
|
||||
.. _select_intro:
|
||||
|
||||
Selections intro
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
The `select` command is used to modify and view the list of selected
|
||||
objects:
|
||||
The `select` command is used to modify and view the list of selected objects:
|
||||
|
||||
.. literalinclude:: /code_examples/fifo/fifo.out
|
||||
:language: doscon
|
||||
|
@ -118,8 +117,8 @@ statement.
|
|||
|
||||
Many commands also support an optional ``[selection]`` argument which can be
|
||||
used to override the currently selected objects. We could, for example, call
|
||||
:yoscrypt:`clean addr_gen` to have `clean` operate on *just* the
|
||||
``addr_gen`` module.
|
||||
:yoscrypt:`clean addr_gen` to have `clean` operate on *just* the ``addr_gen``
|
||||
module.
|
||||
|
||||
Detailed documentation of the select framework can be found under
|
||||
:doc:`/using_yosys/more_scripting/selections` or in the command reference at
|
||||
|
@ -130,11 +129,11 @@ Detailed documentation of the select framework can be found under
|
|||
Displaying schematics
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
While the `select` command is very useful, sometimes nothing beats
|
||||
being able to see a design for yourself. This is where `show` comes
|
||||
in. Note that this document is just an introduction to the `show`
|
||||
command, only covering the basics. For more information, including a guide on
|
||||
what the different symbols represent, see :ref:`interactive_show` and the
|
||||
While the `select` command is very useful, sometimes nothing beats being able to
|
||||
see a design for yourself. This is where `show` comes in. Note that this
|
||||
document is just an introduction to the `show` command, only covering the
|
||||
basics. For more information, including a guide on what the different symbols
|
||||
represent, see :ref:`interactive_show` and the
|
||||
:doc:`/using_yosys/more_scripting/interactive_investigation` page.
|
||||
|
||||
.. figure:: /_images/code_examples/fifo/addr_gen_show.*
|
||||
|
@ -145,8 +144,8 @@ what the different symbols represent, see :ref:`interactive_show` and the
|
|||
|
||||
.. note::
|
||||
|
||||
The `show` command requires a working installation of `GraphViz`_
|
||||
and `xdot`_ for displaying the actual circuit diagrams.
|
||||
The `show` command requires a working installation of `GraphViz`_ and `xdot`_
|
||||
for displaying the actual circuit diagrams.
|
||||
|
||||
.. _GraphViz: http://www.graphviz.org/
|
||||
.. _xdot: https://github.com/jrfonseca/xdot.py
|
||||
|
@ -160,8 +159,8 @@ we see the following:
|
|||
:start-at: -prefix addr_gen_show
|
||||
:end-before: yosys> show
|
||||
|
||||
Calling `show` with :yoscrypt:`-format dot` tells it we want to output
|
||||
a :file:`.dot` file rather than opening it for display. The :yoscrypt:`-prefix
|
||||
Calling `show` with :yoscrypt:`-format dot` tells it we want to output a
|
||||
:file:`.dot` file rather than opening it for display. The :yoscrypt:`-prefix
|
||||
addr_gen_show` option indicates we want the file to be called
|
||||
:file:`addr_gen_show.{*}`. Remember, we do this in :file:`fifo.ys` because we
|
||||
need to store the image for displaying in the documentation you're reading. But
|
||||
|
@ -207,21 +206,20 @@ the two ``PROC`` blocks. To achieve this highlight, we make use of the
|
|||
|
||||
Calling :yoscrypt:`show -color maroon3 @new_cells -color cornflowerblue p:* -notitle`
|
||||
|
||||
As described in the the `help` output for `show` (or by
|
||||
clicking on the `show` link), colors are specified as :yoscrypt:`-color
|
||||
<color> <object>`. Color names for the ``<color>`` portion can be found on the
|
||||
`GraphViz color docs`_. Unlike the final `show` parameter which can
|
||||
have be any selection string, the ``<object>`` part must be a single selection
|
||||
expression or named selection. That means while we can use ``@new_cells``, we
|
||||
couldn't use ``t:$eq t:$add``. In general, if a command lists ``[selection]``
|
||||
as its final parameter it can be any selection string. Any selections that are
|
||||
not the final parameter, such as those used in options, must be a single
|
||||
expression instead.
|
||||
As described in the the `help` output for `show` (or by clicking on the `show`
|
||||
link), colors are specified as :yoscrypt:`-color <color> <object>`. Color names
|
||||
for the ``<color>`` portion can be found on the `GraphViz color docs`_. Unlike
|
||||
the final `show` parameter which can have be any selection string, the
|
||||
``<object>`` part must be a single selection expression or named selection.
|
||||
That means while we can use ``@new_cells``, we couldn't use ``t:$eq t:$add``.
|
||||
In general, if a command lists ``[selection]`` as its final parameter it can be
|
||||
any selection string. Any selections that are not the final parameter, such as
|
||||
those used in options, must be a single expression instead.
|
||||
|
||||
.. _GraphViz color docs: https://graphviz.org/doc/info/colors
|
||||
|
||||
For all of the options available to `show`, check the command reference
|
||||
at :doc:`/cmd/show`.
|
||||
For all of the options available to `show`, check the command reference at
|
||||
:doc:`/cmd/show`.
|
||||
|
||||
.. seealso:: :ref:`interactive_show` on the
|
||||
:doc:`/using_yosys/more_scripting/interactive_investigation` page.
|
||||
|
|
|
@ -161,9 +161,9 @@ Benefits of open source HDL synthesis
|
|||
|
||||
- Cost (also applies to ``free as in free beer`` solutions):
|
||||
|
||||
Today the cost for a mask set in 180nm technology is far less than
|
||||
the cost for the design tools needed to design the mask layouts. Open Source
|
||||
ASIC flows are an important enabler for ASIC-level Open Source Hardware.
|
||||
Today the cost for a mask set in 180nm technology is far less than the cost
|
||||
for the design tools needed to design the mask layouts. Open Source ASIC flows
|
||||
are an important enabler for ASIC-level Open Source Hardware.
|
||||
|
||||
- Availability and Reproducibility:
|
||||
|
||||
|
@ -171,21 +171,23 @@ Benefits of open source HDL synthesis
|
|||
else can also use. Even if most universities have access to all major
|
||||
commercial tools, you usually do not have easy access to the version that was
|
||||
used in a research project a couple of years ago. With Open Source tools you
|
||||
can even release the source code of the tool you have used alongside your data.
|
||||
can even release the source code of the tool you have used alongside your
|
||||
data.
|
||||
|
||||
- Framework:
|
||||
|
||||
Yosys is not only a tool. It is a framework that can be used as basis for other
|
||||
developments, so researchers and hackers alike do not need to re-invent the
|
||||
basic functionality. Extensibility was one of Yosys' design goals.
|
||||
Yosys is not only a tool. It is a framework that can be used as basis for
|
||||
other developments, so researchers and hackers alike do not need to re-invent
|
||||
the basic functionality. Extensibility was one of Yosys' design goals.
|
||||
|
||||
- All-in-one:
|
||||
|
||||
Because of the framework characteristics of Yosys, an increasing number of features
|
||||
become available in one tool. Yosys not only can be used for circuit synthesis but
|
||||
also for formal equivalence checking, SAT solving, and for circuit analysis, to
|
||||
name just a few other application domains. With proprietary software one needs to
|
||||
learn a new tool for each of these applications.
|
||||
Because of the framework characteristics of Yosys, an increasing number of
|
||||
features become available in one tool. Yosys not only can be used for circuit
|
||||
synthesis but also for formal equivalence checking, SAT solving, and for
|
||||
circuit analysis, to name just a few other application domains. With
|
||||
proprietary software one needs to learn a new tool for each of these
|
||||
applications.
|
||||
|
||||
- Educational Tool:
|
||||
|
||||
|
|
|
@ -13,9 +13,9 @@ A look at the show command
|
|||
|
||||
.. TODO:: merge into :doc:`/getting_started/scripting_intro` show section
|
||||
|
||||
This section explores the `show` command and explains the symbols used
|
||||
in the circuit diagrams generated by it. The code used is included in the Yosys
|
||||
code base under |code_examples/show|_.
|
||||
This section explores the `show` command and explains the symbols used in the
|
||||
circuit diagrams generated by it. The code used is included in the Yosys code
|
||||
base under |code_examples/show|_.
|
||||
|
||||
.. |code_examples/show| replace:: :file:`docs/source/code_examples/show`
|
||||
.. _code_examples/show: https://github.com/YosysHQ/yosys/tree/main/docs/source/code_examples/show
|
||||
|
@ -32,11 +32,10 @@ will use to demonstrate the usage of `show` in a simple setting.
|
|||
:name: example_v
|
||||
|
||||
The Yosys synthesis script we will be running is included as
|
||||
:numref:`example_ys`. Note that `show` is called with the ``-pause``
|
||||
option, that halts execution of the Yosys script until the user presses the
|
||||
Enter key. Using :yoscrypt:`show -pause` also allows the user to enter an
|
||||
interactive shell to further investigate the circuit before continuing
|
||||
synthesis.
|
||||
:numref:`example_ys`. Note that `show` is called with the ``-pause`` option,
|
||||
that halts execution of the Yosys script until the user presses the Enter key.
|
||||
Using :yoscrypt:`show -pause` also allows the user to enter an interactive shell
|
||||
to further investigate the circuit before continuing synthesis.
|
||||
|
||||
.. literalinclude:: /code_examples/show/example_show.ys
|
||||
:language: yoscrypt
|
||||
|
@ -95,19 +94,19 @@ multiplexer and a d-type flip-flop, which brings us to the second diagram:
|
|||
The Rhombus shape to the right is a dangling wire. (Wire nodes are only shown if
|
||||
they are dangling or have "public" names, for example names assigned from the
|
||||
Verilog input.) Also note that the design now contains two instances of a
|
||||
``BUF``-node. These are artefacts left behind by the `proc` command. It
|
||||
is quite usual to see such artefacts after calling commands that perform changes
|
||||
in the design, as most commands only care about doing the transformation in the
|
||||
least complicated way, not about cleaning up after them. The next call to
|
||||
`clean` (or `opt`, which includes `clean` as one of
|
||||
its operations) will clean up these artefacts. This operation is so common in
|
||||
Yosys scripts that it can simply be abbreviated with the ``;;`` token, which
|
||||
doubles as separator for commands. Unless one wants to specifically analyze this
|
||||
artefacts left behind some operations, it is therefore recommended to always
|
||||
call `clean` before calling `show`.
|
||||
``BUF``-node. These are artefacts left behind by the `proc` command. It is quite
|
||||
usual to see such artefacts after calling commands that perform changes in the
|
||||
design, as most commands only care about doing the transformation in the least
|
||||
complicated way, not about cleaning up after them. The next call to `clean` (or
|
||||
`opt`, which includes `clean` as one of its operations) will clean up these
|
||||
artefacts. This operation is so common in Yosys scripts that it can simply be
|
||||
abbreviated with the ``;;`` token, which doubles as separator for commands.
|
||||
Unless one wants to specifically analyze this artefacts left behind some
|
||||
operations, it is therefore recommended to always call `clean` before calling
|
||||
`show`.
|
||||
|
||||
In this script we directly call `opt` as the next step, which finally
|
||||
leads us to the third diagram:
|
||||
In this script we directly call `opt` as the next step, which finally leads us
|
||||
to the third diagram:
|
||||
|
||||
.. figure:: /_images/code_examples/show/example_third.*
|
||||
:class: width-helper invert-helper
|
||||
|
@ -115,9 +114,9 @@ leads us to the third diagram:
|
|||
|
||||
Output of the third `show` command in :ref:`example_ys`
|
||||
|
||||
Here we see that the `opt` command not only has removed the artifacts
|
||||
left behind by `proc`, but also determined correctly that it can remove
|
||||
the first `$mux` cell without changing the behavior of the circuit.
|
||||
Here we see that the `opt` command not only has removed the artifacts left
|
||||
behind by `proc`, but also determined correctly that it can remove the first
|
||||
`$mux` cell without changing the behavior of the circuit.
|
||||
|
||||
Break-out boxes for signal vectors
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -188,8 +187,8 @@ individual bits, resulting in an unnecessary complex diagram.
|
|||
:class: width-helper invert-helper
|
||||
:name: second_pitfall
|
||||
|
||||
Effects of `splitnets` command and of providing a cell library on
|
||||
design in :numref:`first_pitfall`
|
||||
Effects of `splitnets` command and of providing a cell library on design in
|
||||
:numref:`first_pitfall`
|
||||
|
||||
.. literalinclude:: /code_examples/show/cmos.ys
|
||||
:language: yoscrypt
|
||||
|
@ -201,8 +200,8 @@ individual bits, resulting in an unnecessary complex diagram.
|
|||
For :numref:`second_pitfall`, Yosys has been given a description of the cell
|
||||
library as Verilog file containing blackbox modules. There are two ways to load
|
||||
cell descriptions into Yosys: First the Verilog file for the cell library can be
|
||||
passed directly to the `show` command using the ``-lib <filename>``
|
||||
option. Secondly it is possible to load cell libraries into the design with the
|
||||
passed directly to the `show` command using the ``-lib <filename>`` option.
|
||||
Secondly it is possible to load cell libraries into the design with the
|
||||
:yoscrypt:`read_verilog -lib <filename>` command. The second method has the
|
||||
great advantage that the library only needs to be loaded once and can then be
|
||||
used in all subsequent calls to the `show` command.
|
||||
|
@ -216,19 +215,19 @@ module ports. Per default the command only operates on interior signals.
|
|||
Miscellaneous notes
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Per default the `show` command outputs a temporary dot file and
|
||||
launches ``xdot`` to display it. The options ``-format``, ``-viewer`` and
|
||||
``-prefix`` can be used to change format, viewer and filename prefix. Note that
|
||||
the ``pdf`` and ``ps`` format are the only formats that support plotting
|
||||
multiple modules in one run. The ``dot`` format can be used to output multiple
|
||||
modules, however ``xdot`` will raise an error when trying to read them.
|
||||
Per default the `show` command outputs a temporary dot file and launches
|
||||
``xdot`` to display it. The options ``-format``, ``-viewer`` and ``-prefix`` can
|
||||
be used to change format, viewer and filename prefix. Note that the ``pdf`` and
|
||||
``ps`` format are the only formats that support plotting multiple modules in one
|
||||
run. The ``dot`` format can be used to output multiple modules, however
|
||||
``xdot`` will raise an error when trying to read them.
|
||||
|
||||
In densely connected circuits it is sometimes hard to keep track of the
|
||||
individual signal wires. For these cases it can be useful to call
|
||||
`show` with the ``-colors <integer>`` argument, which randomly assigns
|
||||
colors to the nets. The integer (> 0) is used as seed value for the random color
|
||||
assignments. Sometimes it is necessary it try some values to find an assignment
|
||||
of colors that looks good.
|
||||
individual signal wires. For these cases it can be useful to call `show` with
|
||||
the ``-colors <integer>`` argument, which randomly assigns colors to the nets.
|
||||
The integer (> 0) is used as seed value for the random color assignments.
|
||||
Sometimes it is necessary it try some values to find an assignment of colors
|
||||
that looks good.
|
||||
|
||||
The command :yoscrypt:`help show` prints a complete listing of all options
|
||||
supported by the `show` command.
|
||||
|
@ -244,10 +243,10 @@ relevant portions of the circuit.
|
|||
In addition to *what* to display one also needs to carefully decide *when* to
|
||||
display it, with respect to the synthesis flow. In general it is a good idea to
|
||||
troubleshoot a circuit in the earliest state in which a problem can be
|
||||
reproduced. So if, for example, the internal state before calling the
|
||||
`techmap` command already fails to verify, it is better to troubleshoot
|
||||
the coarse-grain version of the circuit before `techmap` than the
|
||||
gate-level circuit after `techmap`.
|
||||
reproduced. So if, for example, the internal state before calling the `techmap`
|
||||
command already fails to verify, it is better to troubleshoot the coarse-grain
|
||||
version of the circuit before `techmap` than the gate-level circuit after
|
||||
`techmap`.
|
||||
|
||||
.. Note::
|
||||
|
||||
|
@ -260,18 +259,17 @@ Interactive navigation
|
|||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Once the right state within the synthesis flow for debugging the circuit has
|
||||
been identified, it is recommended to simply add the `shell` command to
|
||||
the matching place in the synthesis script. This command will stop the synthesis
|
||||
at the specified moment and go to shell mode, where the user can interactively
|
||||
been identified, it is recommended to simply add the `shell` command to the
|
||||
matching place in the synthesis script. This command will stop the synthesis at
|
||||
the specified moment and go to shell mode, where the user can interactively
|
||||
enter commands.
|
||||
|
||||
For most cases, the shell will start with the whole design selected (i.e. when
|
||||
the synthesis script does not already narrow the selection). The command
|
||||
`ls` can now be used to create a list of all modules. The command
|
||||
`cd` can be used to switch to one of the modules (type ``cd ..`` to
|
||||
switch back). Now the `ls` command lists the objects within that
|
||||
module. This is demonstrated below using :file:`example.v` from `A simple
|
||||
circuit`_:
|
||||
the synthesis script does not already narrow the selection). The command `ls`
|
||||
can now be used to create a list of all modules. The command `cd` can be used to
|
||||
switch to one of the modules (type ``cd ..`` to switch back). Now the `ls`
|
||||
command lists the objects within that module. This is demonstrated below using
|
||||
:file:`example.v` from `A simple circuit`_:
|
||||
|
||||
.. literalinclude:: /code_examples/show/example.out
|
||||
:language: doscon
|
||||
|
@ -280,11 +278,10 @@ circuit`_:
|
|||
:caption: Output of `ls` and `cd` after running :file:`yosys example.v`
|
||||
:name: lscd
|
||||
|
||||
When a module is selected using the `cd` command, all commands (with a
|
||||
few exceptions, such as the ``read_`` and ``write_`` commands) operate only on
|
||||
the selected module. This can also be useful for synthesis scripts where
|
||||
different synthesis strategies should be applied to different modules in the
|
||||
design.
|
||||
When a module is selected using the `cd` command, all commands (with a few
|
||||
exceptions, such as the ``read_`` and ``write_`` commands) operate only on the
|
||||
selected module. This can also be useful for synthesis scripts where different
|
||||
synthesis strategies should be applied to different modules in the design.
|
||||
|
||||
We can see that the cell names from :numref:`example_out` are just abbreviations
|
||||
of the actual cell names, namely the part after the last dollar-sign. Most
|
||||
|
@ -292,15 +289,14 @@ auto-generated names (the ones starting with a dollar sign) are rather long and
|
|||
contains some additional information on the origin of the named object. But in
|
||||
most cases those names can simply be abbreviated using the last part.
|
||||
|
||||
Usually all interactive work is done with one module selected using the
|
||||
`cd` command. But it is also possible to work from the design-context
|
||||
(``cd ..``). In this case all object names must be prefixed with
|
||||
``<module_name>/``. For example ``a*/b*`` would refer to all objects whose names
|
||||
start with ``b`` from all modules whose names start with ``a``.
|
||||
Usually all interactive work is done with one module selected using the `cd`
|
||||
command. But it is also possible to work from the design-context (``cd ..``). In
|
||||
this case all object names must be prefixed with ``<module_name>/``. For example
|
||||
``a*/b*`` would refer to all objects whose names start with ``b`` from all
|
||||
modules whose names start with ``a``.
|
||||
|
||||
The `dump` command can be used to print all information about an
|
||||
object. For example, calling :yoscrypt:`dump $2` after the :yoscrypt:`cd
|
||||
example` above:
|
||||
The `dump` command can be used to print all information about an object. For
|
||||
example, calling :yoscrypt:`dump $2` after the :yoscrypt:`cd example` above:
|
||||
|
||||
.. literalinclude:: /code_examples/show/example.out
|
||||
:language: RTLIL
|
||||
|
@ -323,11 +319,10 @@ tools).
|
|||
|
||||
- The selection mechanism, especially patterns such as ``%ci`` and ``%co``, can
|
||||
be used to figure out how parts of the design are connected.
|
||||
- Commands such as `submod`, `expose`, and `splice`
|
||||
can be used to transform the design into an equivalent design that is easier
|
||||
to analyse.
|
||||
- Commands such as `eval` and `sat` can be used to investigate
|
||||
the behavior of the circuit.
|
||||
- Commands such as `submod`, `expose`, and `splice` can be used to transform the
|
||||
design into an equivalent design that is easier to analyse.
|
||||
- Commands such as `eval` and `sat` can be used to investigate the behavior of
|
||||
the circuit.
|
||||
- :doc:`/cmd/show`.
|
||||
- :doc:`/cmd/dump`.
|
||||
- :doc:`/cmd/add` and :doc:`/cmd/delete` can be used to modify and reorganize a
|
||||
|
@ -342,9 +337,9 @@ The code used is included in the Yosys code base under
|
|||
Changing design hierarchy
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Commands such as `flatten` and `submod` can be used to change
|
||||
the design hierarchy, i.e. flatten the hierarchy or moving parts of a module to
|
||||
a submodule. This has applications in synthesis scripts as well as in reverse
|
||||
Commands such as `flatten` and `submod` can be used to change the design
|
||||
hierarchy, i.e. flatten the hierarchy or moving parts of a module to a
|
||||
submodule. This has applications in synthesis scripts as well as in reverse
|
||||
engineering and analysis. An example using `submod` is shown below for
|
||||
reorganizing a module in Yosys and checking the resulting circuit.
|
||||
|
||||
|
@ -388,10 +383,10 @@ Analyzing the resulting circuit with :doc:`/cmd/eval`:
|
|||
Behavioral changes
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Commands such as `techmap` can be used to make behavioral changes to
|
||||
the design, for example changing asynchronous resets to synchronous resets. This
|
||||
has applications in design space exploration (evaluation of various
|
||||
architectures for one circuit).
|
||||
Commands such as `techmap` can be used to make behavioral changes to the design,
|
||||
for example changing asynchronous resets to synchronous resets. This has
|
||||
applications in design space exploration (evaluation of various architectures
|
||||
for one circuit).
|
||||
|
||||
The following techmap map file replaces all positive-edge async reset flip-flops
|
||||
with positive-edge sync reset flip-flops. The code is taken from the example
|
||||
|
@ -448,8 +443,8 @@ Recall the ``memdemo`` design from :ref:`advanced_logic_cones`:
|
|||
|
||||
Because this produces a rather large circuit, it can be useful to split it into
|
||||
smaller parts for viewing and working with. :numref:`submod` does exactly that,
|
||||
utilising the `submod` command to split the circuit into three
|
||||
sections: ``outstage``, ``selstage``, and ``scramble``.
|
||||
utilising the `submod` command to split the circuit into three sections:
|
||||
``outstage``, ``selstage``, and ``scramble``.
|
||||
|
||||
.. literalinclude:: /code_examples/selections/submod.ys
|
||||
:language: yoscrypt
|
||||
|
@ -481,9 +476,9 @@ below.
|
|||
Evaluation of combinatorial circuits
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The `eval` command can be used to evaluate combinatorial circuits. As
|
||||
an example, we will use the ``selstage`` subnet of ``memdemo`` which we found
|
||||
above and is shown in :numref:`selstage`.
|
||||
The `eval` command can be used to evaluate combinatorial circuits. As an
|
||||
example, we will use the ``selstage`` subnet of ``memdemo`` which we found above
|
||||
and is shown in :numref:`selstage`.
|
||||
|
||||
.. todo:: replace inline code
|
||||
|
||||
|
@ -526,21 +521,21 @@ The ``-table`` option can be used to create a truth table. For example:
|
|||
|
||||
Assumed undef (x) value for the following signals: \s2
|
||||
|
||||
Note that the `eval` command (as well as the `sat` command
|
||||
discussed in the next sections) does only operate on flattened modules. It can
|
||||
not analyze signals that are passed through design hierarchy levels. So the
|
||||
`flatten` command must be used on modules that instantiate other
|
||||
modules before these commands can be applied.
|
||||
Note that the `eval` command (as well as the `sat` command discussed in the next
|
||||
sections) does only operate on flattened modules. It can not analyze signals
|
||||
that are passed through design hierarchy levels. So the `flatten` command must
|
||||
be used on modules that instantiate other modules before these commands can be
|
||||
applied.
|
||||
|
||||
Solving combinatorial SAT problems
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Often the opposite of the `eval` command is needed, i.e. the circuits
|
||||
output is given and we want to find the matching input signals. For small
|
||||
circuits with only a few input bits this can be accomplished by trying all
|
||||
possible input combinations, as it is done by the ``eval -table`` command. For
|
||||
larger circuits however, Yosys provides the `sat` command that uses a
|
||||
`SAT`_ solver, `MiniSAT`_, to solve this kind of problems.
|
||||
Often the opposite of the `eval` command is needed, i.e. the circuits output is
|
||||
given and we want to find the matching input signals. For small circuits with
|
||||
only a few input bits this can be accomplished by trying all possible input
|
||||
combinations, as it is done by the ``eval -table`` command. For larger circuits
|
||||
however, Yosys provides the `sat` command that uses a `SAT`_ solver, `MiniSAT`_,
|
||||
to solve this kind of problems.
|
||||
|
||||
.. _SAT: http://en.wikipedia.org/wiki/Circuit_satisfiability
|
||||
|
||||
|
@ -551,9 +546,9 @@ larger circuits however, Yosys provides the `sat` command that uses a
|
|||
While it is possible to perform model checking directly in Yosys, it
|
||||
is highly recommended to use SBY or EQY for formal hardware verification.
|
||||
|
||||
The `sat` command works very similar to the `eval` command.
|
||||
The main difference is that it is now also possible to set output values and
|
||||
find the corresponding input values. For Example:
|
||||
The `sat` command works very similar to the `eval` command. The main difference
|
||||
is that it is now also possible to set output values and find the corresponding
|
||||
input values. For Example:
|
||||
|
||||
.. todo:: replace inline code
|
||||
|
||||
|
@ -580,8 +575,8 @@ find the corresponding input values. For Example:
|
|||
\s1 0 0 00
|
||||
\s2 0 0 00
|
||||
|
||||
Note that the `sat` command supports signal names in both arguments to
|
||||
the ``-set`` option. In the above example we used ``-set s1 s2`` to constraint
|
||||
Note that the `sat` command supports signal names in both arguments to the
|
||||
``-set`` option. In the above example we used ``-set s1 s2`` to constraint
|
||||
``s1`` and ``s2`` to be equal. When more complex constraints are needed, a
|
||||
wrapper circuit must be constructed that checks the constraints and signals if
|
||||
the constraint was met using an extra output port, which then can be forced to a
|
||||
|
@ -642,8 +637,8 @@ of course be to perform the test in 32 bits, for example by replacing ``p !=
|
|||
a*b`` in the miter with ``p != {16'd0,a}b``, or by using a temporary variable
|
||||
for the 32 bit product ``a*b``. But as 31 fits well into 8 bits (and as the
|
||||
purpose of this document is to show off Yosys features) we can also simply force
|
||||
the upper 8 bits of ``a`` and ``b`` to zero for the `sat` call, as is
|
||||
done below.
|
||||
the upper 8 bits of ``a`` and ``b`` to zero for the `sat` call, as is done
|
||||
below.
|
||||
|
||||
.. todo:: replace inline code
|
||||
|
||||
|
@ -705,18 +700,18 @@ command:
|
|||
sat -seq 6 -show y -show d -set-init-undef \
|
||||
-max_undef -set-at 4 y 1 -set-at 5 y 2 -set-at 6 y 3
|
||||
|
||||
The ``-seq 6`` option instructs the `sat` command to solve a sequential
|
||||
problem in 6 time steps. (Experiments with lower number of steps have show that
|
||||
at least 3 cycles are necessary to bring the circuit in a state from which the
|
||||
sequence 1, 2, 3 can be produced.)
|
||||
The ``-seq 6`` option instructs the `sat` command to solve a sequential problem
|
||||
in 6 time steps. (Experiments with lower number of steps have show that at least
|
||||
3 cycles are necessary to bring the circuit in a state from which the sequence
|
||||
1, 2, 3 can be produced.)
|
||||
|
||||
The ``-set-init-undef`` option tells the `sat` command to initialize
|
||||
all registers to the undef (``x``) state. The way the ``x`` state is treated in
|
||||
The ``-set-init-undef`` option tells the `sat` command to initialize all
|
||||
registers to the undef (``x``) state. The way the ``x`` state is treated in
|
||||
Verilog will ensure that the solution will work for any initial state.
|
||||
|
||||
The ``-max_undef`` option instructs the `sat` command to find a
|
||||
solution with a maximum number of undefs. This way we can see clearly which
|
||||
inputs bits are relevant to the solution.
|
||||
The ``-max_undef`` option instructs the `sat` command to find a solution with a
|
||||
maximum number of undefs. This way we can see clearly which inputs bits are
|
||||
relevant to the solution.
|
||||
|
||||
Finally the three ``-set-at`` options add constraints for the ``y`` signal to
|
||||
play the 1, 2, 3 sequence, starting with time step 4.
|
||||
|
@ -807,7 +802,7 @@ is the only way of setting the ``s1`` and ``s2`` registers to a known value. The
|
|||
input values for the other steps are a bit harder to work out manually, but the
|
||||
SAT solver finds the correct solution in an instant.
|
||||
|
||||
There is much more to write about the `sat` command. For example, there
|
||||
is a set of options that can be used to performs sequential proofs using
|
||||
temporal induction :cite:p:`een2003temporal`. The command ``help sat`` can be
|
||||
used to print a list of all options with short descriptions of their functions.
|
||||
There is much more to write about the `sat` command. For example, there is a set
|
||||
of options that can be used to performs sequential proofs using temporal
|
||||
induction :cite:p:`een2003temporal`. The command ``help sat`` can be used to
|
||||
print a list of all options with short descriptions of their functions.
|
||||
|
|
|
@ -17,8 +17,7 @@ passes in Yosys.
|
|||
|
||||
Other applications include checking if a module conforms to interface standards.
|
||||
|
||||
The `sat` command in Yosys can be used to perform Symbolic Model
|
||||
Checking.
|
||||
The `sat` command in Yosys can be used to perform Symbolic Model Checking.
|
||||
|
||||
Checking techmap
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
|
|
@ -9,31 +9,31 @@ The selection framework
|
|||
|
||||
.. todo:: reduce overlap with :doc:`/getting_started/scripting_intro` select section
|
||||
|
||||
The `select` command can be used to create a selection for subsequent
|
||||
commands. For example:
|
||||
The `select` command can be used to create a selection for subsequent commands.
|
||||
For example:
|
||||
|
||||
.. code:: yoscrypt
|
||||
|
||||
select foobar # select the module foobar
|
||||
delete # delete selected objects
|
||||
|
||||
Normally the `select` command overwrites a previous selection. The
|
||||
commands :yoscrypt:`select -add` and :yoscrypt:`select -del` can be used to add
|
||||
or remove objects from the current selection.
|
||||
Normally the `select` command overwrites a previous selection. The commands
|
||||
:yoscrypt:`select -add` and :yoscrypt:`select -del` can be used to add or remove
|
||||
objects from the current selection.
|
||||
|
||||
The command :yoscrypt:`select -clear` can be used to reset the selection to the
|
||||
default, which is a complete selection of everything in the current module.
|
||||
|
||||
This selection framework can also be used directly in many other commands.
|
||||
Whenever a command has ``[selection]`` as last argument in its usage help, this
|
||||
means that it will use the engine behind the `select` command to
|
||||
evaluate additional arguments and use the resulting selection instead of the
|
||||
selection created by the last `select` command.
|
||||
means that it will use the engine behind the `select` command to evaluate
|
||||
additional arguments and use the resulting selection instead of the selection
|
||||
created by the last `select` command.
|
||||
|
||||
For example, the command `delete` will delete everything in the current
|
||||
selection; while :yoscrypt:`delete foobar` will only delete the module foobar.
|
||||
If no `select` command has been made, then the "current selection" will
|
||||
be the whole design.
|
||||
If no `select` command has been made, then the "current selection" will be the
|
||||
whole design.
|
||||
|
||||
.. note:: Many of the examples on this page make use of the `show`
|
||||
command to visually demonstrate the effect of selections. For a more
|
||||
|
@ -59,8 +59,8 @@ Module and design context
|
|||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Commands can be executed in *module/* or *design/* context. Until now, all
|
||||
commands have been executed in design context. The `cd` command can be
|
||||
used to switch to module context.
|
||||
commands have been executed in design context. The `cd` command can be used to
|
||||
switch to module context.
|
||||
|
||||
In module context, all commands only effect the active module. Objects in the
|
||||
module are selected without the ``<module_name>/`` prefix. For example:
|
||||
|
@ -91,7 +91,7 @@ Special patterns can be used to select by object property or type. For example:
|
|||
a:foobar=42`
|
||||
- select all modules with the attribute ``blabla`` set: :yoscrypt:`select
|
||||
A:blabla`
|
||||
- select all $add cells from the module foo: :yoscrypt:`select foo/t:$add`
|
||||
- select all `$add` cells from the module foo: :yoscrypt:`select foo/t:$add`
|
||||
|
||||
A complete list of pattern expressions can be found in :doc:`/cmd/select`.
|
||||
|
||||
|
@ -101,12 +101,12 @@ Operations on selections
|
|||
Combining selections
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The `select` command is actually much more powerful than it might seem
|
||||
at first glance. When it is called with multiple arguments, each argument is
|
||||
evaluated and pushed separately on a stack. After all arguments have been
|
||||
processed it simply creates the union of all elements on the stack. So
|
||||
:yoscrypt:`select t:$add a:foo` will select all `$add` cells and all objects
|
||||
with the ``foo`` attribute set:
|
||||
The `select` command is actually much more powerful than it might seem at first
|
||||
glance. When it is called with multiple arguments, each argument is evaluated
|
||||
and pushed separately on a stack. After all arguments have been processed it
|
||||
simply creates the union of all elements on the stack. So :yoscrypt:`select
|
||||
t:$add a:foo` will select all `$add` cells and all objects with the ``foo``
|
||||
attribute set:
|
||||
|
||||
.. literalinclude:: /code_examples/selections/foobaraddsub.v
|
||||
:caption: Test module for operations on selections
|
||||
|
@ -220,11 +220,11 @@ The following sequence of diagrams demonstrates this step-wise expansion:
|
|||
Output of :yoscrypt:`show prod %ci %ci %ci` on :numref:`sumprod`
|
||||
|
||||
Notice the subtle difference between :yoscrypt:`show prod %ci` and
|
||||
:yoscrypt:`show prod %ci %ci`. Both images show the `$mul` cell driven by
|
||||
some inputs ``$3_Y`` and ``c``. However it is not until the second image,
|
||||
having called ``%ci`` the second time, that `show` is able to
|
||||
distinguish between ``$3_Y`` being a wire and ``c`` being an input. We can see
|
||||
this better with the `dump` command instead:
|
||||
:yoscrypt:`show prod %ci %ci`. Both images show the `$mul` cell driven by some
|
||||
inputs ``$3_Y`` and ``c``. However it is not until the second image, having
|
||||
called ``%ci`` the second time, that `show` is able to distinguish between
|
||||
``$3_Y`` being a wire and ``c`` being an input. We can see this better with the
|
||||
`dump` command instead:
|
||||
|
||||
.. literalinclude:: /code_examples/selections/sumprod.out
|
||||
:language: RTLIL
|
||||
|
@ -241,8 +241,8 @@ be a bit dull. So there is a shortcut for that: the number of iterations can be
|
|||
appended to the action. So for example the action ``%ci3`` is identical to
|
||||
performing the ``%ci`` action three times.
|
||||
|
||||
The action ``%ci*`` performs the ``%ci`` action over and over again until it
|
||||
has no effect anymore.
|
||||
The action ``%ci*`` performs the ``%ci`` action over and over again until it has
|
||||
no effect anymore.
|
||||
|
||||
.. _advanced_logic_cones:
|
||||
|
||||
|
@ -264,8 +264,8 @@ source repository.
|
|||
:name: memdemo_src
|
||||
:language: verilog
|
||||
|
||||
The script :file:`memdemo.ys` is used to generate the images included here. Let's
|
||||
look at the first section:
|
||||
The script :file:`memdemo.ys` is used to generate the images included here.
|
||||
Let's look at the first section:
|
||||
|
||||
.. literalinclude:: /code_examples/selections/memdemo.ys
|
||||
:caption: Synthesizing :ref:`memdemo_src`
|
||||
|
@ -276,8 +276,8 @@ look at the first section:
|
|||
This loads :numref:`memdemo_src` and synthesizes the included module. Note that
|
||||
this code can be copied and run directly in a Yosys command line session,
|
||||
provided :file:`memdemo.v` is in the same directory. We can now change to the
|
||||
``memdemo`` module with ``cd memdemo``, and call `show` to see the
|
||||
diagram in :numref:`memdemo_00`.
|
||||
``memdemo`` module with ``cd memdemo``, and call `show` to see the diagram in
|
||||
:numref:`memdemo_00`.
|
||||
|
||||
.. figure:: /_images/code_examples/selections/memdemo_00.*
|
||||
:class: width-helper invert-helper
|
||||
|
@ -371,8 +371,8 @@ selection instead of overwriting it.
|
|||
select -del reg_42 # but not this one
|
||||
select -add state %ci # and add more stuff
|
||||
|
||||
Within a select expression the token ``%`` can be used to push the previous selection
|
||||
on the stack.
|
||||
Within a select expression the token ``%`` can be used to push the previous
|
||||
selection on the stack.
|
||||
|
||||
.. code:: yoscrypt
|
||||
|
||||
|
@ -387,16 +387,16 @@ Storing and recalling selections
|
|||
The current selection can be stored in memory with the command ``select -set
|
||||
<name>``. It can later be recalled using ``select @<name>``. In fact, the
|
||||
``@<name>`` expression pushes the stored selection on the stack maintained by
|
||||
the `select` command. So for example :yoscrypt:`select @foo @bar %i`
|
||||
will select the intersection between the stored selections ``foo`` and ``bar``.
|
||||
the `select` command. So for example :yoscrypt:`select @foo @bar %i` will select
|
||||
the intersection between the stored selections ``foo`` and ``bar``.
|
||||
|
||||
In larger investigation efforts it is highly recommended to maintain a script
|
||||
that sets up relevant selections, so they can easily be recalled, for example
|
||||
when Yosys needs to be re-run after a design or source code change.
|
||||
|
||||
The `history` command can be used to list all recent interactive
|
||||
commands. This feature can be useful for creating such a script from the
|
||||
commands used in an interactive session.
|
||||
The `history` command can be used to list all recent interactive commands. This
|
||||
feature can be useful for creating such a script from the commands used in an
|
||||
interactive session.
|
||||
|
||||
Remember that select expressions can also be used directly as arguments to most
|
||||
commands. Some commands also accept a single select argument to some options. In
|
||||
|
|
|
@ -10,13 +10,12 @@ fine-grained optimisation and LUT mapping.
|
|||
Yosys has two different commands, which both use this logic toolbox, but use it
|
||||
in different ways.
|
||||
|
||||
The `abc` pass can be used for both ASIC (e.g. :yoscrypt:`abc
|
||||
-liberty`) and FPGA (:yoscrypt:`abc -lut`) mapping, but this page will focus on
|
||||
FPGA mapping.
|
||||
The `abc` pass can be used for both ASIC (e.g. :yoscrypt:`abc -liberty`) and
|
||||
FPGA (:yoscrypt:`abc -lut`) mapping, but this page will focus on FPGA mapping.
|
||||
|
||||
The `abc9` pass generally provides superior mapping quality due to
|
||||
being aware of combination boxes and DFF and LUT timings, giving it a more
|
||||
global view of the mapping problem.
|
||||
The `abc9` pass generally provides superior mapping quality due to being aware
|
||||
of combination boxes and DFF and LUT timings, giving it a more global view of
|
||||
the mapping problem.
|
||||
|
||||
.. _ABC: https://github.com/berkeley-abc/abc
|
||||
|
||||
|
|
|
@ -98,8 +98,8 @@ our internal cell library will be mapped to:
|
|||
:name: mycells-lib
|
||||
:caption: :file:`mycells.lib`
|
||||
|
||||
Recall that the Yosys built-in logic gate types are `$_NOT_`, `$_AND_`,
|
||||
`$_OR_`, `$_XOR_`, and `$_MUX_` with an assortment of dff memory types.
|
||||
Recall that the Yosys built-in logic gate types are `$_NOT_`, `$_AND_`, `$_OR_`,
|
||||
`$_XOR_`, and `$_MUX_` with an assortment of dff memory types.
|
||||
:ref:`mycells-lib` defines our target cells as ``BUF``, ``NOT``, ``NAND``,
|
||||
``NOR``, and ``DFF``. Mapping between these is performed with the commands
|
||||
`dfflibmap` and `abc` as follows:
|
||||
|
@ -117,8 +117,8 @@ The final version of our ``counter`` module looks like this:
|
|||
|
||||
``counter`` after hardware cell mapping
|
||||
|
||||
Before finally being output as a verilog file with `write_verilog`,
|
||||
which can then be loaded into another tool:
|
||||
Before finally being output as a verilog file with `write_verilog`, which can
|
||||
then be loaded into another tool:
|
||||
|
||||
.. literalinclude:: /code_examples/intro/counter.ys
|
||||
:language: yoscrypt
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
The extract pass
|
||||
----------------
|
||||
|
||||
- Like the `techmap` pass, the `extract` pass is called with a
|
||||
map file. It compares the circuits inside the modules of the map file with the
|
||||
design and looks for sub-circuits in the design that match any of the modules
|
||||
in the map file.
|
||||
- If a match is found, the `extract` pass will replace the matching
|
||||
subcircuit with an instance of the module from the map file.
|
||||
- Like the `techmap` pass, the `extract` pass is called with a map file. It
|
||||
compares the circuits inside the modules of the map file with the design and
|
||||
looks for sub-circuits in the design that match any of the modules in the map
|
||||
file.
|
||||
- If a match is found, the `extract` pass will replace the matching subcircuit
|
||||
with an instance of the module from the map file.
|
||||
- In a way the `extract` pass is the inverse of the techmap pass.
|
||||
|
||||
.. todo:: add/expand supporting text, also mention custom pattern matching and
|
||||
|
@ -68,23 +68,23 @@ The wrap-extract-unwrap method
|
|||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Often a coarse-grain element has a constant bit-width, but can be used to
|
||||
implement operations with a smaller bit-width. For example, a 18x25-bit multiplier
|
||||
can also be used to implement 16x20-bit multiplication.
|
||||
implement operations with a smaller bit-width. For example, a 18x25-bit
|
||||
multiplier can also be used to implement 16x20-bit multiplication.
|
||||
|
||||
A way of mapping such elements in coarse grain synthesis is the
|
||||
wrap-extract-unwrap method:
|
||||
|
||||
wrap
|
||||
Identify candidate-cells in the circuit and wrap them in a cell with a
|
||||
constant wider bit-width using `techmap`. The wrappers use the same
|
||||
parameters as the original cell, so the information about the original width
|
||||
of the ports is preserved. Then use the `connwrappers` command to
|
||||
connect up the bit-extended in- and outputs of the wrapper cells.
|
||||
constant wider bit-width using `techmap`. The wrappers use the same parameters
|
||||
as the original cell, so the information about the original width of the ports
|
||||
is preserved. Then use the `connwrappers` command to connect up the
|
||||
bit-extended in- and outputs of the wrapper cells.
|
||||
|
||||
extract
|
||||
Now all operations are encoded using the same bit-width as the coarse grain
|
||||
element. The `extract` command can be used to replace circuits with
|
||||
cells of the target architecture.
|
||||
element. The `extract` command can be used to replace circuits with cells of
|
||||
the target architecture.
|
||||
|
||||
unwrap
|
||||
The remaining wrapper cell can be unwrapped using `techmap`.
|
||||
|
|
|
@ -25,9 +25,8 @@ following description:
|
|||
- Does not already have the ``\fsm_encoding`` attribute.
|
||||
- Is not an output of the containing module.
|
||||
- Is driven by single `$dff` or `$adff` cell.
|
||||
- The ``\D``-Input of this `$dff` or `$adff` cell is driven by a
|
||||
multiplexer tree that only has constants or the old state value on its
|
||||
leaves.
|
||||
- The ``\D``-Input of this `$dff` or `$adff` cell is driven by a multiplexer
|
||||
tree that only has constants or the old state value on its leaves.
|
||||
- The state value is only used in the said multiplexer tree or by simple
|
||||
relational cells that compare the state value to a constant (usually `$eq`
|
||||
cells).
|
||||
|
@ -87,8 +86,8 @@ given set of result signals using a set of signal-value assignments. It can also
|
|||
be passed a list of stop-signals that abort the ConstEval algorithm if the value
|
||||
of a stop-signal is needed in order to calculate the result signals.
|
||||
|
||||
The `fsm_extract` pass uses the ConstEval class in the following way to
|
||||
create a transition table. For each state:
|
||||
The `fsm_extract` pass uses the ConstEval class in the following way to create a
|
||||
transition table. For each state:
|
||||
|
||||
1. Create a ConstEval object for the module containing the FSM
|
||||
2. Add all control inputs to the list of stop signals
|
||||
|
@ -108,13 +107,12 @@ drivers for the control outputs are disconnected.
|
|||
FSM optimization
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
The `fsm_opt` pass performs basic optimizations on `$fsm` cells (not
|
||||
including state recoding). The following optimizations are performed (in this
|
||||
order):
|
||||
The `fsm_opt` pass performs basic optimizations on `$fsm` cells (not including
|
||||
state recoding). The following optimizations are performed (in this order):
|
||||
|
||||
- Unused control outputs are removed from the `$fsm` cell. The attribute
|
||||
``\unused_bits`` (that is usually set by the `opt_clean` pass) is
|
||||
used to determine which control outputs are unused.
|
||||
``\unused_bits`` (that is usually set by the `opt_clean` pass) is used to
|
||||
determine which control outputs are unused.
|
||||
|
||||
- Control inputs that are connected to the same driver are merged.
|
||||
|
||||
|
@ -134,11 +132,10 @@ order):
|
|||
FSM recoding
|
||||
~~~~~~~~~~~~
|
||||
|
||||
The `fsm_recode` pass assigns new bit pattern to the states. Usually
|
||||
this also implies a change in the width of the state signal. At the moment of
|
||||
this writing only one-hot encoding with all-zero for the reset state is
|
||||
supported.
|
||||
The `fsm_recode` pass assigns new bit pattern to the states. Usually this also
|
||||
implies a change in the width of the state signal. At the moment of this writing
|
||||
only one-hot encoding with all-zero for the reset state is supported.
|
||||
|
||||
The `fsm_recode` pass can also write a text file with the changes
|
||||
performed by it that can be used when verifying designs synthesized by Yosys
|
||||
using Synopsys Formality.
|
||||
The `fsm_recode` pass can also write a text file with the changes performed by
|
||||
it that can be used when verifying designs synthesized by Yosys using Synopsys
|
||||
Formality.
|
||||
|
|
|
@ -8,17 +8,16 @@ coarse-grain optimizations before being mapped to hard blocks and fine-grain
|
|||
cells. Most commands in Yosys will target either coarse-grain representation or
|
||||
fine-grain representation, with only a select few compatible with both states.
|
||||
|
||||
Commands such as `proc`, `fsm`, and `memory` rely on
|
||||
the additional information in the coarse-grain representation, along with a
|
||||
number of optimizations such as `wreduce`, `share`, and
|
||||
`alumacc`. `opt` provides optimizations which are useful in
|
||||
both states, while `techmap` is used to convert coarse-grain cells
|
||||
to the corresponding fine-grain representation.
|
||||
Commands such as `proc`, `fsm`, and `memory` rely on the additional information
|
||||
in the coarse-grain representation, along with a number of optimizations such as
|
||||
`wreduce`, `share`, and `alumacc`. `opt` provides optimizations which are
|
||||
useful in both states, while `techmap` is used to convert coarse-grain cells to
|
||||
the corresponding fine-grain representation.
|
||||
|
||||
Single-bit cells (logic gates, FFs) as well as LUTs, half-adders, and
|
||||
full-adders make up the bulk of the fine-grain representation and are necessary
|
||||
for commands such as `abc`\ /`abc9`, `simplemap`,
|
||||
`dfflegalize`, and `memory_map`.
|
||||
for commands such as `abc`\ /`abc9`, `simplemap`, `dfflegalize`, and
|
||||
`memory_map`.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 3
|
||||
|
|
|
@ -5,10 +5,10 @@ The `memory` command
|
|||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
In the RTL netlist, memory reads and writes are individual cells. This makes
|
||||
consolidating the number of ports for a memory easier. The `memory`
|
||||
pass transforms memories to an implementation. Per default that is logic for
|
||||
address decoders and registers. It also is a macro command that calls the other
|
||||
common ``memory_*`` passes in a sensible order:
|
||||
consolidating the number of ports for a memory easier. The `memory` pass
|
||||
transforms memories to an implementation. Per default that is logic for address
|
||||
decoders and registers. It also is a macro command that calls the other common
|
||||
``memory_*`` passes in a sensible order:
|
||||
|
||||
.. literalinclude:: /code_examples/macro_commands/memory.ys
|
||||
:language: yoscrypt
|
||||
|
@ -22,11 +22,11 @@ Some quick notes:
|
|||
- `memory_dff` merges registers into the memory read- and write cells.
|
||||
- `memory_collect` collects all read and write cells for a memory and
|
||||
transforms them into one multi-port memory cell.
|
||||
- `memory_map` takes the multi-port memory cell and transforms it to
|
||||
address decoder logic and registers.
|
||||
- `memory_map` takes the multi-port memory cell and transforms it to address
|
||||
decoder logic and registers.
|
||||
|
||||
For more information about `memory`, such as disabling certain sub
|
||||
commands, see :doc:`/cmd/memory`.
|
||||
For more information about `memory`, such as disabling certain sub commands, see
|
||||
:doc:`/cmd/memory`.
|
||||
|
||||
Example
|
||||
-------
|
||||
|
@ -75,20 +75,20 @@ For example:
|
|||
techmap -map my_memory_map.v
|
||||
memory_map
|
||||
|
||||
`memory_libmap` attempts to convert memory cells (`$mem_v2` etc) into
|
||||
hardware supported memory using a provided library (:file:`my_memory_map.txt` in the
|
||||
`memory_libmap` attempts to convert memory cells (`$mem_v2` etc) into hardware
|
||||
supported memory using a provided library (:file:`my_memory_map.txt` in the
|
||||
example above). Where necessary, emulation logic is added to ensure functional
|
||||
equivalence before and after this conversion. :yoscrypt:`techmap -map
|
||||
my_memory_map.v` then uses `techmap` to map to hardware primitives. Any
|
||||
leftover memory cells unable to be converted are then picked up by
|
||||
`memory_map` and mapped to DFFs and address decoders.
|
||||
my_memory_map.v` then uses `techmap` to map to hardware primitives. Any leftover
|
||||
memory cells unable to be converted are then picked up by `memory_map` and
|
||||
mapped to DFFs and address decoders.
|
||||
|
||||
.. note::
|
||||
|
||||
More information about what mapping options are available and associated
|
||||
costs of each can be found by enabling debug outputs. This can be done with
|
||||
the `debug` command, or by using the ``-g`` flag when calling Yosys
|
||||
to globally enable debug messages.
|
||||
the `debug` command, or by using the ``-g`` flag when calling Yosys to
|
||||
globally enable debug messages.
|
||||
|
||||
For more on the lib format for `memory_libmap`, see
|
||||
`passes/memory/memlib.md
|
||||
|
@ -110,13 +110,15 @@ Notes
|
|||
Memory kind selection
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The memory inference code will automatically pick target memory primitive based on memory geometry
|
||||
and features used. Depending on the target, there can be up to four memory primitive classes
|
||||
available for selection:
|
||||
The memory inference code will automatically pick target memory primitive based
|
||||
on memory geometry and features used. Depending on the target, there can be up
|
||||
to four memory primitive classes available for selection:
|
||||
|
||||
- FF RAM (aka logic): no hardware primitive used, memory lowered to a bunch of FFs and multiplexers
|
||||
- FF RAM (aka logic): no hardware primitive used, memory lowered to a bunch of
|
||||
FFs and multiplexers
|
||||
|
||||
- Can handle arbitrary number of write ports, as long as all write ports are in the same clock domain
|
||||
- Can handle arbitrary number of write ports, as long as all write ports are
|
||||
in the same clock domain
|
||||
- Can handle arbitrary number and kind of read ports
|
||||
|
||||
- LUT RAM (aka distributed RAM): uses LUT storage as RAM
|
||||
|
@ -131,7 +133,8 @@ available for selection:
|
|||
- Supported on basically all FPGAs
|
||||
- Supports only synchronous reads
|
||||
- Two ports with separate clocks
|
||||
- Usually supports true dual port (with notable exception of ice40 that only supports SDP)
|
||||
- Usually supports true dual port (with notable exception of ice40 that only
|
||||
supports SDP)
|
||||
- Usually supports asymmetric memories and per-byte write enables
|
||||
- Several kilobits in size
|
||||
|
||||
|
@ -155,19 +158,22 @@ available for selection:
|
|||
- Two ports, both with mutually exclusive synchronous read and write
|
||||
- Single clock
|
||||
|
||||
- Will not be automatically selected by memory inference code, needs explicit opt-in via
|
||||
ram_style attribute
|
||||
- Will not be automatically selected by memory inference code, needs explicit
|
||||
opt-in via ram_style attribute
|
||||
|
||||
In general, you can expect the automatic selection process to work roughly like this:
|
||||
In general, you can expect the automatic selection process to work roughly like
|
||||
this:
|
||||
|
||||
- If any read port is asynchronous, only LUT RAM (or FF RAM) can be used.
|
||||
- If there is more than one write port, only block RAM can be used, and this needs to be a
|
||||
hardware-supported true dual port pattern
|
||||
- If there is more than one write port, only block RAM can be used, and this
|
||||
needs to be a hardware-supported true dual port pattern
|
||||
|
||||
- … unless all write ports are in the same clock domain, in which case FF RAM can also be used,
|
||||
but this is generally not what you want for anything but really small memories
|
||||
- … unless all write ports are in the same clock domain, in which case FF RAM
|
||||
can also be used, but this is generally not what you want for anything but
|
||||
really small memories
|
||||
|
||||
- Otherwise, either FF RAM, LUT RAM, or block RAM will be used, depending on memory size
|
||||
- Otherwise, either FF RAM, LUT RAM, or block RAM will be used, depending on
|
||||
memory size
|
||||
|
||||
This process can be overridden by attaching a ram_style attribute to the memory:
|
||||
|
||||
|
@ -178,15 +184,17 @@ This process can be overridden by attaching a ram_style attribute to the memory:
|
|||
|
||||
It is an error if this override cannot be realized for the given target.
|
||||
|
||||
Many alternate spellings of the attribute are also accepted, for compatibility with other software.
|
||||
Many alternate spellings of the attribute are also accepted, for compatibility
|
||||
with other software.
|
||||
|
||||
Initial data
|
||||
~~~~~~~~~~~~
|
||||
|
||||
Most FPGA targets support initializing all kinds of memory to user-provided values. If explicit
|
||||
initialization is not used the initial memory value is undefined. Initial data can be provided by
|
||||
either initial statements writing memory cells one by one of ``$readmemh`` or ``$readmemb`` system
|
||||
tasks. For an example pattern, see `sr_init`_.
|
||||
Most FPGA targets support initializing all kinds of memory to user-provided
|
||||
values. If explicit initialization is not used the initial memory value is
|
||||
undefined. Initial data can be provided by either initial statements writing
|
||||
memory cells one by one of ``$readmemh`` or ``$readmemb`` system tasks. For an
|
||||
example pattern, see `sr_init`_.
|
||||
|
||||
.. _wbe:
|
||||
|
||||
|
@ -194,12 +202,13 @@ Write port with byte enables
|
|||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- Byte enables can be used with any supported pattern
|
||||
- To ensure that multiple writes will be merged into one port, they need to have disjoint bit
|
||||
ranges, have the same address, and the same clock
|
||||
- Any write enable granularity will be accepted (down to per-bit write enables), but using smaller
|
||||
granularity than natively supported by the target is very likely to be inefficient (eg. using
|
||||
4-bit bytes on ECP5 will result in either padding the bytes with 5 dummy bits to native 9-bit
|
||||
units or splitting the RAM into two block RAMs)
|
||||
- To ensure that multiple writes will be merged into one port, they need to have
|
||||
disjoint bit ranges, have the same address, and the same clock
|
||||
- Any write enable granularity will be accepted (down to per-bit write enables),
|
||||
but using smaller granularity than natively supported by the target is very
|
||||
likely to be inefficient (eg. using 4-bit bytes on ECP5 will result in either
|
||||
padding the bytes with 5 dummy bits to native 9-bit units or splitting the RAM
|
||||
into two block RAMs)
|
||||
|
||||
.. code:: verilog
|
||||
|
||||
|
@ -240,7 +249,8 @@ Synchronous SDP with clock domain crossing
|
|||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- Will result in block RAM or LUT RAM depending on size
|
||||
- No behavior guarantees in case of simultaneous read and write to the same address
|
||||
- No behavior guarantees in case of simultaneous read and write to the same
|
||||
address
|
||||
|
||||
.. code:: verilog
|
||||
|
||||
|
@ -261,9 +271,9 @@ Synchronous SDP read first
|
|||
|
||||
- The read and write parts can be in the same or different processes.
|
||||
- Will result in block RAM or LUT RAM depending on size
|
||||
- As long as the same clock is used for both, yosys will ensure read-first behavior. This may
|
||||
require extra circuitry on some targets for block RAM. If this is not necessary, use one of the
|
||||
patterns below.
|
||||
- As long as the same clock is used for both, yosys will ensure read-first
|
||||
behavior. This may require extra circuitry on some targets for block RAM. If
|
||||
this is not necessary, use one of the patterns below.
|
||||
|
||||
.. code:: verilog
|
||||
|
||||
|
@ -281,8 +291,8 @@ Synchronous SDP read first
|
|||
Synchronous SDP with undefined collision behavior
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- Like above, but the read value is undefined when read and write ports target the same address in
|
||||
the same cycle
|
||||
- Like above, but the read value is undefined when read and write ports target
|
||||
the same address in the same cycle
|
||||
|
||||
.. code:: verilog
|
||||
|
||||
|
@ -322,8 +332,8 @@ Synchronous SDP with write-first behavior
|
|||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- Will result in block RAM or LUT RAM depending on size
|
||||
- May use additional circuitry for block RAM if write-first is not natively supported. Will always
|
||||
use additional circuitry for LUT RAM.
|
||||
- May use additional circuitry for block RAM if write-first is not natively
|
||||
supported. Will always use additional circuitry for LUT RAM.
|
||||
|
||||
.. code:: verilog
|
||||
|
||||
|
@ -343,7 +353,8 @@ Synchronous SDP with write-first behavior
|
|||
Synchronous SDP with write-first behavior (alternate pattern)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- This pattern is supported for compatibility, but is much less flexible than the above
|
||||
- This pattern is supported for compatibility, but is much less flexible than
|
||||
the above
|
||||
|
||||
.. code:: verilog
|
||||
|
||||
|
@ -378,8 +389,10 @@ Synchronous single-port RAM with mutually exclusive read/write
|
|||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- Will result in single-port block RAM or LUT RAM depending on size
|
||||
- This is the correct pattern to infer ice40 SPRAM (with manual ram_style selection)
|
||||
- On targets that don't support read/write block RAM ports (eg. ice40), will result in SDP block RAM instead
|
||||
- This is the correct pattern to infer ice40 SPRAM (with manual ram_style
|
||||
selection)
|
||||
- On targets that don't support read/write block RAM ports (eg. ice40), will
|
||||
result in SDP block RAM instead
|
||||
- For block RAM, will use "NO_CHANGE" mode if available
|
||||
|
||||
.. code:: verilog
|
||||
|
@ -396,12 +409,14 @@ Synchronous single-port RAM with mutually exclusive read/write
|
|||
Synchronous single-port RAM with read-first behavior
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- Will only result in single-port block RAM when read-first behavior is natively supported;
|
||||
otherwise, SDP RAM with additional circuitry will be used
|
||||
- Many targets (Xilinx, ECP5, …) can only natively support read-first/write-first single-port RAM
|
||||
(or TDP RAM) where the write_enable signal implies the read_enable signal (ie. can never write
|
||||
without reading). The memory inference code will run a simple SAT solver on the control signals to
|
||||
determine if this is the case, and insert emulation circuitry if it cannot be easily proven.
|
||||
- Will only result in single-port block RAM when read-first behavior is natively
|
||||
supported; otherwise, SDP RAM with additional circuitry will be used
|
||||
- Many targets (Xilinx, ECP5, …) can only natively support
|
||||
read-first/write-first single-port RAM (or TDP RAM) where the write_enable
|
||||
signal implies the read_enable signal (ie. can never write without reading).
|
||||
The memory inference code will run a simple SAT solver on the control signals
|
||||
to determine if this is the case, and insert emulation circuitry if it cannot
|
||||
be easily proven.
|
||||
|
||||
.. code:: verilog
|
||||
|
||||
|
@ -418,7 +433,8 @@ Synchronous single-port RAM with write-first behavior
|
|||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- Will result in single-port block RAM or LUT RAM when supported
|
||||
- Block RAMs will require extra circuitry if write-first behavior not natively supported
|
||||
- Block RAMs will require extra circuitry if write-first behavior not natively
|
||||
supported
|
||||
|
||||
.. code:: verilog
|
||||
|
||||
|
@ -440,8 +456,8 @@ Synchronous read port with initial value
|
|||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- Initial read port values can be combined with any other supported pattern
|
||||
- If block RAM is used and initial read port values are not natively supported by the target, small
|
||||
emulation circuit will be inserted
|
||||
- If block RAM is used and initial read port values are not natively supported
|
||||
by the target, small emulation circuit will be inserted
|
||||
|
||||
.. code:: verilog
|
||||
|
||||
|
@ -459,10 +475,11 @@ Synchronous read port with initial value
|
|||
Read register reset patterns
|
||||
----------------------------
|
||||
|
||||
Resets can be combined with any other supported pattern (except that synchronous reset and
|
||||
asynchronous reset cannot both be used on a single read port). If block RAM is used and the
|
||||
selected reset (synchronous or asynchronous) is used but not natively supported by the target, small
|
||||
emulation circuitry will be inserted.
|
||||
Resets can be combined with any other supported pattern (except that synchronous
|
||||
reset and asynchronous reset cannot both be used on a single read port). If
|
||||
block RAM is used and the selected reset (synchronous or asynchronous) is used
|
||||
but not natively supported by the target, small emulation circuitry will be
|
||||
inserted.
|
||||
|
||||
Synchronous reset, reset priority over enable
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
@ -520,22 +537,26 @@ Synchronous read port with asynchronous reset
|
|||
Asymmetric memory patterns
|
||||
--------------------------
|
||||
|
||||
To construct an asymmetric memory (memory with read/write ports of differing widths):
|
||||
To construct an asymmetric memory (memory with read/write ports of differing
|
||||
widths):
|
||||
|
||||
- Declare the memory with the width of the narrowest intended port
|
||||
- Split all wide ports into multiple narrow ports
|
||||
- To ensure the wide ports will be correctly merged:
|
||||
|
||||
- For the address, use a concatenation of actual address in the high bits and a constant in the
|
||||
low bits
|
||||
- Ensure the actual address is identical for all ports belonging to the wide port
|
||||
- For the address, use a concatenation of actual address in the high bits and
|
||||
a constant in the low bits
|
||||
- Ensure the actual address is identical for all ports belonging to the wide
|
||||
port
|
||||
- Ensure that clock is identical
|
||||
- For read ports, ensure that enable/reset signals are identical (for write ports, the enable
|
||||
signal may vary — this will result in using the byte enable functionality)
|
||||
- For read ports, ensure that enable/reset signals are identical (for write
|
||||
ports, the enable signal may vary — this will result in using the byte
|
||||
enable functionality)
|
||||
|
||||
Asymmetric memory is supported on all targets, but may require emulation circuitry where not
|
||||
natively supported. Note that when the memory is larger than the underlying block RAM primitive,
|
||||
hardware asymmetric memory support is likely not to be used even if present as it is more expensive.
|
||||
Asymmetric memory is supported on all targets, but may require emulation
|
||||
circuitry where not natively supported. Note that when the memory is larger
|
||||
than the underlying block RAM primitive, hardware asymmetric memory support is
|
||||
likely not to be used even if present as it is more expensive.
|
||||
|
||||
.. _wide_sr:
|
||||
|
||||
|
@ -615,20 +636,25 @@ Wide write port
|
|||
True dual port (TDP) patterns
|
||||
-----------------------------
|
||||
|
||||
- Many different variations of true dual port memory can be created by combining two single-port RAM
|
||||
patterns on the same memory
|
||||
- When TDP memory is used, memory inference code has much less maneuver room to create requested
|
||||
semantics compared to individual single-port patterns (which can end up lowered to SDP memory
|
||||
where necessary) — supported patterns depend strongly on the target
|
||||
- In particular, when both ports have the same clock, it's likely that "undefined collision" mode
|
||||
needs to be manually selected to enable TDP memory inference
|
||||
- The examples below are non-exhaustive — many more combinations of port types are possible
|
||||
- Note: if two write ports are in the same process, this defines a priority relation between them
|
||||
(if both ports are active in the same clock, the later one wins). On almost all targets, this will
|
||||
result in a bit of extra circuitry to ensure the priority semantics. If this is not what you want,
|
||||
put them in separate processes.
|
||||
- Many different variations of true dual port memory can be created by combining
|
||||
two single-port RAM patterns on the same memory
|
||||
- When TDP memory is used, memory inference code has much less maneuver room to
|
||||
create requested semantics compared to individual single-port patterns (which
|
||||
can end up lowered to SDP memory where necessary) — supported patterns depend
|
||||
strongly on the target
|
||||
- In particular, when both ports have the same clock, it's likely that
|
||||
"undefined collision" mode needs to be manually selected to enable TDP memory
|
||||
inference
|
||||
- The examples below are non-exhaustive — many more combinations of port types
|
||||
are possible
|
||||
- Note: if two write ports are in the same process, this defines a priority
|
||||
relation between them (if both ports are active in the same clock, the later
|
||||
one wins). On almost all targets, this will result in a bit of extra circuitry
|
||||
to ensure the priority semantics. If this is not what you want, put them in
|
||||
separate processes.
|
||||
|
||||
- Priority is not supported when using the verific front end and any priority semantics are ignored.
|
||||
- Priority is not supported when using the verific front end and any priority
|
||||
semantics are ignored.
|
||||
|
||||
TDP with different clocks, exclusive read/write
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
@ -654,7 +680,8 @@ TDP with different clocks, exclusive read/write
|
|||
TDP with same clock, read-first behavior
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- This requires hardware inter-port read-first behavior, and will only work on some targets (Xilinx, Nexus)
|
||||
- This requires hardware inter-port read-first behavior, and will only work on
|
||||
some targets (Xilinx, Nexus)
|
||||
|
||||
.. code:: verilog
|
||||
|
||||
|
@ -677,9 +704,10 @@ TDP with same clock, read-first behavior
|
|||
TDP with multiple read ports
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- The combination of a single write port with an arbitrary amount of read ports is supported on all
|
||||
targets — if a multi-read port primitive is available (like Xilinx RAM64M), it'll be used as
|
||||
appropriate. Otherwise, the memory will be automatically split into multiple primitives.
|
||||
- The combination of a single write port with an arbitrary amount of read ports
|
||||
is supported on all targets — if a multi-read port primitive is available
|
||||
(like Xilinx RAM64M), it'll be used as appropriate. Otherwise, the memory
|
||||
will be automatically split into multiple primitives.
|
||||
|
||||
.. code:: verilog
|
||||
|
||||
|
|
|
@ -9,9 +9,9 @@ This chapter outlines these optimizations.
|
|||
The `opt` macro command
|
||||
--------------------------------
|
||||
|
||||
The Yosys pass `opt` runs a number of simple optimizations. This
|
||||
includes removing unused signals and cells and const folding. It is recommended
|
||||
to run this pass after each major step in the synthesis script. As listed in
|
||||
The Yosys pass `opt` runs a number of simple optimizations. This includes
|
||||
removing unused signals and cells and const folding. It is recommended to run
|
||||
this pass after each major step in the synthesis script. As listed in
|
||||
:doc:`/cmd/opt`, this macro command calls the following ``opt_*`` commands:
|
||||
|
||||
.. literalinclude:: /code_examples/macro_commands/opt.ys
|
||||
|
@ -69,17 +69,17 @@ undef.
|
|||
The last two lines simply replace an `$_AND_` gate with one constant-1 input
|
||||
with a buffer.
|
||||
|
||||
Besides this basic const folding the `opt_expr` pass can replace 1-bit
|
||||
wide `$eq` and `$ne` cells with buffers or not-gates if one input is
|
||||
constant. Equality checks may also be reduced in size if there are redundant
|
||||
bits in the arguments (i.e. bits which are constant on both inputs). This can,
|
||||
for example, result in a 32-bit wide constant like ``255`` being reduced to the
|
||||
8-bit value of ``8'11111111`` if the signal being compared is only 8-bit as in
|
||||
Besides this basic const folding the `opt_expr` pass can replace 1-bit wide
|
||||
`$eq` and `$ne` cells with buffers or not-gates if one input is constant.
|
||||
Equality checks may also be reduced in size if there are redundant bits in the
|
||||
arguments (i.e. bits which are constant on both inputs). This can, for example,
|
||||
result in a 32-bit wide constant like ``255`` being reduced to the 8-bit value
|
||||
of ``8'11111111`` if the signal being compared is only 8-bit as in
|
||||
:ref:`addr_gen_clean` of :doc:`/getting_started/example_synth`.
|
||||
|
||||
The `opt_expr` pass is very conservative regarding optimizing `$mux`
|
||||
cells, as these cells are often used to model decision-trees and breaking these
|
||||
trees can interfere with other optimizations.
|
||||
The `opt_expr` pass is very conservative regarding optimizing `$mux` cells, as
|
||||
these cells are often used to model decision-trees and breaking these trees can
|
||||
interfere with other optimizations.
|
||||
|
||||
.. literalinclude:: /code_examples/opt/opt_expr.ys
|
||||
:language: Verilog
|
||||
|
@ -100,9 +100,9 @@ identifies cells with identical inputs and replaces them with a single instance
|
|||
of the cell.
|
||||
|
||||
The option ``-nomux`` can be used to disable resource sharing for multiplexer
|
||||
cells (`$mux` and `$pmux`.) This can be useful as it prevents multiplexer
|
||||
trees to be merged, which might prevent `opt_muxtree` to identify
|
||||
possible optimizations.
|
||||
cells (`$mux` and `$pmux`.) This can be useful as it prevents multiplexer trees
|
||||
to be merged, which might prevent `opt_muxtree` to identify possible
|
||||
optimizations.
|
||||
|
||||
.. literalinclude:: /code_examples/opt/opt_merge.ys
|
||||
:language: Verilog
|
||||
|
@ -128,9 +128,9 @@ Consider the following simple example:
|
|||
:caption: example verilog for demonstrating `opt_muxtree`
|
||||
|
||||
The output can never be ``c``, as this would require ``a`` to be 1 for the outer
|
||||
multiplexer and 0 for the inner multiplexer. The `opt_muxtree` pass
|
||||
detects this contradiction and replaces the inner multiplexer with a constant 1,
|
||||
yielding the logic for ``y = a ? b : d``.
|
||||
multiplexer and 0 for the inner multiplexer. The `opt_muxtree` pass detects this
|
||||
contradiction and replaces the inner multiplexer with a constant 1, yielding the
|
||||
logic for ``y = a ? b : d``.
|
||||
|
||||
.. figure:: /_images/code_examples/opt/opt_muxtree.*
|
||||
:class: width-helper invert-helper
|
||||
|
@ -141,9 +141,9 @@ Simplifying large MUXes and AND/OR gates - `opt_reduce`
|
|||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
This is a simple optimization pass that identifies and consolidates identical
|
||||
input bits to `$reduce_and` and `$reduce_or` cells. It also sorts the input
|
||||
bits to ease identification of shareable `$reduce_and` and `$reduce_or`
|
||||
cells in other passes.
|
||||
input bits to `$reduce_and` and `$reduce_or` cells. It also sorts the input bits
|
||||
to ease identification of shareable `$reduce_and` and `$reduce_or` cells in
|
||||
other passes.
|
||||
|
||||
This pass also identifies and consolidates identical inputs to multiplexer
|
||||
cells. In this case the new shared select bit is driven using a `$reduce_or`
|
||||
|
@ -162,8 +162,8 @@ This pass identifies mutually exclusive cells of the same type that:
|
|||
a. share an input signal, and
|
||||
b. drive the same `$mux`, `$_MUX_`, or `$pmux` multiplexing cell,
|
||||
|
||||
allowing the cell to be merged and the multiplexer to be moved from
|
||||
multiplexing its output to multiplexing the non-shared input signals.
|
||||
allowing the cell to be merged and the multiplexer to be moved from multiplexing
|
||||
its output to multiplexing the non-shared input signals.
|
||||
|
||||
.. literalinclude:: /code_examples/opt/opt_share.ys
|
||||
:language: Verilog
|
||||
|
@ -176,16 +176,16 @@ multiplexing its output to multiplexing the non-shared input signals.
|
|||
|
||||
Before and after `opt_share`
|
||||
|
||||
When running `opt` in full, the original `$mux` (labeled ``$3``) is
|
||||
optimized away by `opt_expr`.
|
||||
When running `opt` in full, the original `$mux` (labeled ``$3``) is optimized
|
||||
away by `opt_expr`.
|
||||
|
||||
Performing DFF optimizations - `opt_dff`
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
This pass identifies single-bit d-type flip-flops (`$_DFF_`, `$dff`, and
|
||||
`$adff` cells) with a constant data input and replaces them with a constant
|
||||
driver. It can also merge clock enables and synchronous reset multiplexers,
|
||||
removing unused control inputs.
|
||||
This pass identifies single-bit d-type flip-flops (`$_DFF_`, `$dff`, and `$adff`
|
||||
cells) with a constant data input and replaces them with a constant driver. It
|
||||
can also merge clock enables and synchronous reset multiplexers, removing unused
|
||||
control inputs.
|
||||
|
||||
Called with ``-nodffe`` and ``-nosdff``, this pass is used to prepare a design
|
||||
for :doc:`/using_yosys/synthesis/fsm`.
|
||||
|
@ -200,20 +200,20 @@ attribute can be used for debugging or by other optimization passes.
|
|||
When to use `opt` or `clean`
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Usually it does not hurt to call `opt` after each regular command in
|
||||
the synthesis script. But it increases the synthesis time, so it is favourable
|
||||
to only call `opt` when an improvement can be achieved.
|
||||
Usually it does not hurt to call `opt` after each regular command in the
|
||||
synthesis script. But it increases the synthesis time, so it is favourable to
|
||||
only call `opt` when an improvement can be achieved.
|
||||
|
||||
It is generally a good idea to call `opt` before inherently expensive
|
||||
commands such as `sat` or `freduce`, as the possible gain is
|
||||
much higher in these cases as the possible loss.
|
||||
It is generally a good idea to call `opt` before inherently expensive commands
|
||||
such as `sat` or `freduce`, as the possible gain is much higher in these cases
|
||||
as the possible loss.
|
||||
|
||||
The `clean` command, which is an alias for `opt_clean` with
|
||||
fewer outputs, on the other hand is very fast and many commands leave a mess
|
||||
(dangling signal wires, etc). For example, most commands do not remove any wires
|
||||
or cells. They just change the connections and depend on a later call to clean
|
||||
to get rid of the now unused objects. So the occasional ``;;``, which itself is
|
||||
an alias for `clean`, is a good idea in every synthesis script, e.g:
|
||||
The `clean` command, which is an alias for `opt_clean` with fewer outputs, on
|
||||
the other hand is very fast and many commands leave a mess (dangling signal
|
||||
wires, etc). For example, most commands do not remove any wires or cells. They
|
||||
just change the connections and depend on a later call to clean to get rid of
|
||||
the now unused objects. So the occasional ``;;``, which itself is an alias for
|
||||
`clean`, is a good idea in every synthesis script, e.g:
|
||||
|
||||
.. code-block:: yoscrypt
|
||||
|
||||
|
|
|
@ -5,23 +5,23 @@ Converting process blocks
|
|||
:language: yoscrypt
|
||||
|
||||
The Verilog frontend converts ``always``-blocks to RTL netlists for the
|
||||
expressions and "processess" for the control- and memory elements. The
|
||||
`proc` command then transforms these "processess" to netlists of RTL
|
||||
multiplexer and register cells. It also is a macro command that calls the other
|
||||
``proc_*`` commands in a sensible order:
|
||||
expressions and "processess" for the control- and memory elements. The `proc`
|
||||
command then transforms these "processess" to netlists of RTL multiplexer and
|
||||
register cells. It also is a macro command that calls the other ``proc_*``
|
||||
commands in a sensible order:
|
||||
|
||||
.. literalinclude:: /code_examples/macro_commands/proc.ys
|
||||
:language: yoscrypt
|
||||
:start-after: #end:
|
||||
:caption: Passes called by `proc`
|
||||
|
||||
After all the ``proc_*`` commands, `opt_expr` is called. This can be
|
||||
disabled by calling :yoscrypt:`proc -noopt`. For more information about
|
||||
`proc`, such as disabling certain sub commands, see :doc:`/cmd/proc`.
|
||||
After all the ``proc_*`` commands, `opt_expr` is called. This can be disabled by
|
||||
calling :yoscrypt:`proc -noopt`. For more information about `proc`, such as
|
||||
disabling certain sub commands, see :doc:`/cmd/proc`.
|
||||
|
||||
Many commands can not operate on modules with "processess" in them. Usually a
|
||||
call to `proc` is the first command in the actual synthesis procedure
|
||||
after design elaboration.
|
||||
call to `proc` is the first command in the actual synthesis procedure after
|
||||
design elaboration.
|
||||
|
||||
Example
|
||||
^^^^^^^
|
||||
|
|
|
@ -20,8 +20,8 @@ CodingStyle may be of interest.
|
|||
Quick guide
|
||||
-----------
|
||||
|
||||
Code examples from this section are included in the
|
||||
|code_examples/extensions|_ directory of the Yosys source code.
|
||||
Code examples from this section are included in the |code_examples/extensions|_
|
||||
directory of the Yosys source code.
|
||||
|
||||
.. |code_examples/extensions| replace:: :file:`docs/source/code_examples/extensions`
|
||||
.. _code_examples/extensions: https://github.com/YosysHQ/yosys/tree/main/docs/source/code_examples/extensions
|
||||
|
@ -56,10 +56,9 @@ It is possible to only work on this simpler version:
|
|||
}
|
||||
|
||||
When trying to understand what a command does, creating a small test case to
|
||||
look at the output of `dump` and `show` before and after the
|
||||
command has been executed can be helpful.
|
||||
:doc:`/using_yosys/more_scripting/selections` has more information on using
|
||||
these commands.
|
||||
look at the output of `dump` and `show` before and after the command has been
|
||||
executed can be helpful. :doc:`/using_yosys/more_scripting/selections` has more
|
||||
information on using these commands.
|
||||
|
||||
Creating a command
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
@ -151,8 +150,8 @@ Most commands modify existing modules, not create new ones.
|
|||
|
||||
When modifying existing modules, stick to the following DOs and DON'Ts:
|
||||
|
||||
- Do not remove wires. Simply disconnect them and let a successive
|
||||
`clean` command worry about removing it.
|
||||
- Do not remove wires. Simply disconnect them and let a successive `clean`
|
||||
command worry about removing it.
|
||||
- Use ``module->fixup_ports()`` after changing the ``port_*`` properties of
|
||||
wires.
|
||||
- You can safely remove cells or change the ``connections`` property of a cell,
|
||||
|
|
|
@ -599,14 +599,14 @@ The proc pass
|
|||
|
||||
The ProcessGenerator converts a behavioural model in AST representation to a
|
||||
behavioural model in ``RTLIL::Process`` representation. The actual conversion
|
||||
from a behavioural model to an RTL representation is performed by the
|
||||
`proc` pass and the passes it launches:
|
||||
from a behavioural model to an RTL representation is performed by the `proc`
|
||||
pass and the passes it launches:
|
||||
|
||||
- | `proc_clean` and `proc_rmdead`
|
||||
| These two passes just clean up the ``RTLIL::Process`` structure. The
|
||||
`proc_clean` pass removes empty parts (eg. empty assignments) from
|
||||
the process and `proc_rmdead` detects and removes unreachable
|
||||
branches from the process's decision trees.
|
||||
`proc_clean` pass removes empty parts (eg. empty assignments) from the
|
||||
process and `proc_rmdead` detects and removes unreachable branches from the
|
||||
process's decision trees.
|
||||
|
||||
- | `proc_arst`
|
||||
| This pass detects processes that describe d-type flip-flops with
|
||||
|
@ -617,10 +617,10 @@ from a behavioural model to an RTL representation is performed by the
|
|||
and the top-level ``RTLIL::SwitchRule`` has been removed.
|
||||
|
||||
- | `proc_mux`
|
||||
| This pass converts the ``RTLIL::CaseRule``/\ ``RTLIL::SwitchRule``-tree to a
|
||||
tree of multiplexers per written signal. After this, the ``RTLIL::Process``
|
||||
structure only contains the ``RTLIL::SyncRule`` s that describe the output
|
||||
registers.
|
||||
| This pass converts the ``RTLIL::CaseRule``/\ ``RTLIL::SwitchRule``-tree to
|
||||
a tree of multiplexers per written signal. After this, the
|
||||
``RTLIL::Process`` structure only contains the ``RTLIL::SyncRule`` s that
|
||||
describe the output registers.
|
||||
|
||||
- | `proc_dff`
|
||||
| This pass replaces the ``RTLIL::SyncRule``\ s to d-type flip-flops (with
|
||||
|
@ -630,8 +630,8 @@ from a behavioural model to an RTL representation is performed by the
|
|||
| This pass replaces the ``RTLIL::MemWriteAction``\ s with `$memwr` cells.
|
||||
|
||||
- | `proc_clean`
|
||||
| A final call to `proc_clean` removes the now empty
|
||||
``RTLIL::Process`` 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 Verilog
|
||||
frontend has two important benefits:
|
||||
|
@ -646,8 +646,8 @@ to extend the actual Verilog frontend.
|
|||
|
||||
.. todo:: Synthesizing Verilog arrays
|
||||
|
||||
Add some information on the generation of `$memrd` and `$memwr` cells and
|
||||
how they are processed in the memory pass.
|
||||
Add some information on the generation of `$memrd` and `$memwr` cells and how
|
||||
they are processed in the memory pass.
|
||||
|
||||
|
||||
.. todo:: Synthesizing parametric designs
|
||||
|
|
|
@ -73,16 +73,16 @@ also have the following parameters:
|
|||
:verilog:`Y = !A` $logic_not
|
||||
================== ============
|
||||
|
||||
For the unary cells that output a logical value (`$reduce_and`,
|
||||
`$reduce_or`, `$reduce_xor`, `$reduce_xnor`, `$reduce_bool`,
|
||||
`$logic_not`), when the ``\Y_WIDTH`` parameter is greater than 1, the output
|
||||
is zero-extended, and only the least significant bit varies.
|
||||
For the unary cells that output a logical value (`$reduce_and`, `$reduce_or`,
|
||||
`$reduce_xor`, `$reduce_xnor`, `$reduce_bool`, `$logic_not`), when the
|
||||
``\Y_WIDTH`` parameter is greater than 1, the output is zero-extended, and only
|
||||
the least significant bit varies.
|
||||
|
||||
Note that `$reduce_or` and `$reduce_bool` actually represent the same logic
|
||||
function. But the HDL frontends generate them in different situations. A
|
||||
`$reduce_or` cell is generated when the prefix ``|`` operator is being used. A
|
||||
`$reduce_bool` cell is generated when a bit vector is used as a condition in
|
||||
an ``if``-statement or ``?:``-expression.
|
||||
`$reduce_bool` cell is generated when a bit vector is used as a condition in an
|
||||
``if``-statement or ``?:``-expression.
|
||||
|
||||
Binary operators
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
@ -91,15 +91,15 @@ All binary RTL cells have two input ports ``\A`` and ``\B`` and one output port
|
|||
``\Y``. They also have the following parameters:
|
||||
|
||||
``\A_SIGNED``
|
||||
Set to a non-zero value if the input ``\A`` is signed and therefore
|
||||
should be sign-extended when needed.
|
||||
Set to a non-zero value if the input ``\A`` is signed and therefore should be
|
||||
sign-extended when needed.
|
||||
|
||||
``\A_WIDTH``
|
||||
The width of the input port ``\A``.
|
||||
|
||||
``\B_SIGNED``
|
||||
Set to a non-zero value if the input ``\B`` is signed and therefore
|
||||
should be sign-extended when needed.
|
||||
Set to a non-zero value if the input ``\B`` is signed and therefore should be
|
||||
sign-extended when needed.
|
||||
|
||||
``\B_WIDTH``
|
||||
The width of the input port ``\B``.
|
||||
|
@ -130,29 +130,28 @@ All binary RTL cells have two input ports ``\A`` and ``\B`` and one output port
|
|||
:verilog:`Y = A ** B` $pow ``N/A`` $modfloor
|
||||
======================= ============= ======================= =========
|
||||
|
||||
The `$shl` and `$shr` cells implement logical shifts, whereas the `$sshl`
|
||||
and `$sshr` cells implement arithmetic shifts. The `$shl` and `$sshl`
|
||||
cells implement the same operation. All four of these cells interpret the second
|
||||
The `$shl` and `$shr` cells implement logical shifts, whereas the `$sshl` and
|
||||
`$sshr` cells implement arithmetic shifts. The `$shl` and `$sshl` cells
|
||||
implement the same operation. All four of these cells interpret the second
|
||||
operand as unsigned, and require ``\B_SIGNED`` to be zero.
|
||||
|
||||
Two additional shift operator cells are available that do not directly
|
||||
correspond to any operator in Verilog, `$shift` and `$shiftx`. The
|
||||
`$shift` cell performs a right logical shift if the second operand is positive
|
||||
(or unsigned), and a left logical shift if it is negative. The `$shiftx` cell
|
||||
performs the same operation as the `$shift` cell, but the vacated bit
|
||||
positions are filled with undef (x) bits, and corresponds to the Verilog indexed
|
||||
part-select expression.
|
||||
correspond to any operator in Verilog, `$shift` and `$shiftx`. The `$shift` cell
|
||||
performs a right logical shift if the second operand is positive (or unsigned),
|
||||
and a left logical shift if it is negative. The `$shiftx` cell performs the same
|
||||
operation as the `$shift` cell, but the vacated bit positions are filled with
|
||||
undef (x) bits, and corresponds to the Verilog indexed part-select expression.
|
||||
|
||||
For the binary cells that output a logical value (`$logic_and`, `$logic_or`,
|
||||
`$eqx`, `$nex`, `$lt`, `$le`, `$eq`, `$ne`, `$ge`, `$gt`), when
|
||||
the ``\Y_WIDTH`` parameter is greater than 1, the output is zero-extended, and
|
||||
only the least significant bit varies.
|
||||
`$eqx`, `$nex`, `$lt`, `$le`, `$eq`, `$ne`, `$ge`, `$gt`), when the ``\Y_WIDTH``
|
||||
parameter is greater than 1, the output is zero-extended, and only the least
|
||||
significant bit varies.
|
||||
|
||||
Division and modulo cells are available in two rounding modes. The original
|
||||
`$div` and `$mod` cells are based on truncating division, and correspond to
|
||||
the semantics of the verilog ``/`` and ``%`` operators. The `$divfloor` and
|
||||
`$modfloor` cells represent flooring division and flooring modulo, the latter
|
||||
of which is also known as "remainder" in several languages. See
|
||||
`$div` and `$mod` cells are based on truncating division, and correspond to the
|
||||
semantics of the verilog ``/`` and ``%`` operators. The `$divfloor` and
|
||||
`$modfloor` cells represent flooring division and flooring modulo, the latter of
|
||||
which is also known as "remainder" in several languages. See
|
||||
:numref:`tab:CellLib_divmod` for a side-by-side comparison between the different
|
||||
semantics.
|
||||
|
||||
|
@ -187,9 +186,9 @@ all of the specified width. This cell also has a single bit control input
|
|||
it is 1 the value from the ``\B`` input is sent to the output. So the `$mux`
|
||||
cell implements the function :verilog:`Y = S ? B : A`.
|
||||
|
||||
The `$pmux` cell is used to multiplex between many inputs using a one-hot
|
||||
select signal. Cells of this type have a ``\WIDTH`` and a ``\S_WIDTH`` parameter
|
||||
and inputs ``\A``, ``\B``, and ``\S`` and an output ``\Y``. The ``\S`` input is
|
||||
The `$pmux` cell is used to multiplex between many inputs using a one-hot select
|
||||
signal. Cells of this type have a ``\WIDTH`` and a ``\S_WIDTH`` parameter and
|
||||
inputs ``\A``, ``\B``, and ``\S`` and an output ``\Y``. The ``\S`` input is
|
||||
``\S_WIDTH`` bits wide. The ``\A`` input and the output are both ``\WIDTH`` bits
|
||||
wide and the ``\B`` input is ``\WIDTH*\S_WIDTH`` bits wide. When all bits of
|
||||
``\S`` are zero, the value from ``\A`` input is sent to the output. If the
|
||||
|
@ -199,8 +198,8 @@ from ``\S`` is set the output is undefined. Cells of this type are used to model
|
|||
"parallel cases" (defined by using the ``parallel_case`` attribute or detected
|
||||
by an optimization).
|
||||
|
||||
The `$tribuf` cell is used to implement tristate logic. Cells of this type
|
||||
have a ``\WIDTH`` parameter and inputs ``\A`` and ``\EN`` and an output ``\Y``. The
|
||||
The `$tribuf` cell is used to implement tristate logic. Cells of this type have
|
||||
a ``\WIDTH`` parameter and inputs ``\A`` and ``\EN`` and an output ``\Y``. The
|
||||
``\A`` input and ``\Y`` output are ``\WIDTH`` bits wide, and the ``\EN`` input
|
||||
is one bit wide. When ``\EN`` is 0, the output is not driven. When ``\EN`` is 1,
|
||||
the value from ``\A`` input is sent to the ``\Y`` output. Therefore, the
|
||||
|
@ -224,27 +223,27 @@ parameters:
|
|||
The width of inputs ``\SET`` and ``\CLR`` and output ``\Q``.
|
||||
|
||||
``\SET_POLARITY``
|
||||
The set input bits are active-high if this parameter has the value
|
||||
``1'b1`` and active-low if this parameter is ``1'b0``.
|
||||
The set input bits are active-high if this parameter has the value ``1'b1``
|
||||
and active-low if this parameter is ``1'b0``.
|
||||
|
||||
``\CLR_POLARITY``
|
||||
The reset input bits are active-high if this parameter has the value
|
||||
``1'b1`` and active-low if this parameter is ``1'b0``.
|
||||
The reset input bits are active-high if this parameter has the value ``1'b1``
|
||||
and active-low if this parameter is ``1'b0``.
|
||||
|
||||
Both set and reset inputs have separate bits for every output bit. When both the
|
||||
set and reset inputs of an `$sr` cell are active for a given bit index, the
|
||||
reset input takes precedence.
|
||||
|
||||
D-type flip-flops are represented by `$dff` cells. These cells have a clock
|
||||
port ``\CLK``, an input port ``\D`` and an output port ``\Q``. The following
|
||||
D-type flip-flops are represented by `$dff` cells. These cells have a clock port
|
||||
``\CLK``, an input port ``\D`` and an output port ``\Q``. The following
|
||||
parameters are available for `$dff` cells:
|
||||
|
||||
``\WIDTH``
|
||||
The width of input ``\D`` and output ``\Q``.
|
||||
|
||||
``\CLK_POLARITY``
|
||||
Clock is active on the positive edge if this parameter has the value
|
||||
``1'b1`` and on the negative edge if this parameter is ``1'b0``.
|
||||
Clock is active on the positive edge if this parameter has the value ``1'b1``
|
||||
and on the negative edge if this parameter is ``1'b0``.
|
||||
|
||||
D-type flip-flops with asynchronous reset are represented by `$adff` cells. As
|
||||
the `$dff` cells they have ``\CLK``, ``\D`` and ``\Q`` ports. In addition they
|
||||
|
@ -258,8 +257,8 @@ additional two parameters:
|
|||
``\ARST_VALUE``
|
||||
The state of ``\Q`` will be set to this value when the reset is active.
|
||||
|
||||
Usually these cells are generated by the `proc` pass using the
|
||||
information in the designs RTLIL::Process objects.
|
||||
Usually these cells are generated by the `proc` pass using the information in
|
||||
the designs RTLIL::Process objects.
|
||||
|
||||
D-type flip-flops with synchronous reset are represented by `$sdff` cells. As
|
||||
the `$dff` cells they have ``\CLK``, ``\D`` and ``\Q`` ports. In addition they
|
||||
|
@ -267,14 +266,14 @@ also have a single-bit ``\SRST`` input port for the reset pin and the following
|
|||
additional two parameters:
|
||||
|
||||
``\SRST_POLARITY``
|
||||
The synchronous reset is active-high if this parameter has the value
|
||||
``1'b1`` and active-low if this parameter is ``1'b0``.
|
||||
The synchronous reset is active-high if this parameter has the value ``1'b1``
|
||||
and active-low if this parameter is ``1'b0``.
|
||||
|
||||
``\SRST_VALUE``
|
||||
The state of ``\Q`` will be set to this value when the reset is active.
|
||||
|
||||
Note that the `$adff` and `$sdff` cells can only be used when the reset
|
||||
value is constant.
|
||||
Note that the `$adff` and `$sdff` cells can only be used when the reset value is
|
||||
constant.
|
||||
|
||||
D-type flip-flops with asynchronous load are represented by `$aldff` cells. As
|
||||
the `$dff` cells they have ``\CLK``, ``\D`` and ``\Q`` ports. In addition they
|
||||
|
@ -283,25 +282,24 @@ also have a single-bit ``\ALOAD`` input port for the async load enable pin, a
|
|||
following additional parameter:
|
||||
|
||||
``\ALOAD_POLARITY``
|
||||
The asynchronous load is active-high if this parameter has the value
|
||||
``1'b1`` and active-low if this parameter is ``1'b0``.
|
||||
The asynchronous load is active-high if this parameter has the value ``1'b1``
|
||||
and active-low if this parameter is ``1'b0``.
|
||||
|
||||
D-type flip-flops with asynchronous set and reset are represented by `$dffsr`
|
||||
cells. As the `$dff` cells they have ``\CLK``, ``\D`` and ``\Q`` ports. In
|
||||
addition they also have multi-bit ``\SET`` and ``\CLR`` input ports and the
|
||||
corresponding polarity parameters, like `$sr` cells.
|
||||
|
||||
D-type flip-flops with enable are represented by `$dffe`, `$adffe`,
|
||||
`$aldffe`, `$dffsre`, `$sdffe`, and `$sdffce` cells, which are enhanced
|
||||
variants of `$dff`, `$adff`, `$aldff`, `$dffsr`, `$sdff` (with reset
|
||||
over enable) and `$sdff` (with enable over reset) cells, respectively. They
|
||||
have the same ports and parameters as their base cell. In addition they also
|
||||
have a single-bit ``\EN`` input port for the enable pin and the following
|
||||
parameter:
|
||||
D-type flip-flops with enable are represented by `$dffe`, `$adffe`, `$aldffe`,
|
||||
`$dffsre`, `$sdffe`, and `$sdffce` cells, which are enhanced variants of `$dff`,
|
||||
`$adff`, `$aldff`, `$dffsr`, `$sdff` (with reset over enable) and `$sdff` (with
|
||||
enable over reset) cells, respectively. They have the same ports and parameters
|
||||
as their base cell. In addition they also have a single-bit ``\EN`` input port
|
||||
for the enable pin and the following parameter:
|
||||
|
||||
``\EN_POLARITY``
|
||||
The enable input is active-high if this parameter has the value ``1'b1``
|
||||
and active-low if this parameter is ``1'b0``.
|
||||
The enable input is active-high if this parameter has the value ``1'b1`` and
|
||||
active-low if this parameter is ``1'b0``.
|
||||
|
||||
D-type latches are represented by `$dlatch` cells. These cells have an enable
|
||||
port ``\EN``, an input port ``\D``, and an output port ``\Q``. The following
|
||||
|
@ -311,14 +309,14 @@ parameters are available for `$dlatch` cells:
|
|||
The width of input ``\D`` and output ``\Q``.
|
||||
|
||||
``\EN_POLARITY``
|
||||
The enable input is active-high if this parameter has the value ``1'b1``
|
||||
and active-low if this parameter is ``1'b0``.
|
||||
The enable input is active-high if this parameter has the value ``1'b1`` and
|
||||
active-low if this parameter is ``1'b0``.
|
||||
|
||||
The latch is transparent when the ``\EN`` input is active.
|
||||
|
||||
D-type latches with reset are represented by `$adlatch` cells. In addition to
|
||||
`$dlatch` ports and parameters, they also have a single-bit ``\ARST`` input
|
||||
port for the reset pin and the following additional parameters:
|
||||
`$dlatch` ports and parameters, they also have a single-bit ``\ARST`` input port
|
||||
for the reset pin and the following additional parameters:
|
||||
|
||||
``\ARST_POLARITY``
|
||||
The asynchronous reset is active-high if this parameter has the value
|
||||
|
@ -363,56 +361,53 @@ parameters:
|
|||
The number of address bits (width of the ``\ADDR`` input port).
|
||||
|
||||
``\WIDTH``
|
||||
The number of data bits (width of the ``\DATA`` output port). Note that
|
||||
this may be a power-of-two multiple of the underlying memory's width --
|
||||
such ports are called wide ports and access an aligned group of cells at
|
||||
once. In this case, the corresponding low bits of ``\ADDR`` must be
|
||||
tied to 0.
|
||||
The number of data bits (width of the ``\DATA`` output port). Note that this
|
||||
may be a power-of-two multiple of the underlying memory's width -- such ports
|
||||
are called wide ports and access an aligned group of cells at once. In this
|
||||
case, the corresponding low bits of ``\ADDR`` must be tied to 0.
|
||||
|
||||
``\CLK_ENABLE``
|
||||
When this parameter is non-zero, the clock is used. Otherwise this read
|
||||
port is asynchronous and the ``\CLK`` input is not used.
|
||||
When this parameter is non-zero, the clock is used. Otherwise this read port
|
||||
is asynchronous and the ``\CLK`` input is not used.
|
||||
|
||||
``\CLK_POLARITY``
|
||||
Clock is active on the positive edge if this parameter has the value
|
||||
``1'b1`` and on the negative edge if this parameter is ``1'b0``.
|
||||
Clock is active on the positive edge if this parameter has the value ``1'b1``
|
||||
and on the negative edge if this parameter is ``1'b0``.
|
||||
|
||||
``\TRANSPARENCY_MASK``
|
||||
This parameter is a bitmask of write ports that this read port is
|
||||
transparent with. The bits of this parameter are indexed by the write
|
||||
port's ``\PORTID`` parameter. Transparency can only be enabled between
|
||||
synchronous ports sharing a clock domain. When transparency is enabled
|
||||
for a given port pair, a read and write to the same address in the same
|
||||
cycle will return the new value. Otherwise the old value is returned.
|
||||
This parameter is a bitmask of write ports that this read port is transparent
|
||||
with. The bits of this parameter are indexed by the write port's ``\PORTID``
|
||||
parameter. Transparency can only be enabled between synchronous ports sharing
|
||||
a clock domain. When transparency is enabled for a given port pair, a read
|
||||
and write to the same address in the same cycle will return the new value.
|
||||
Otherwise the old value is returned.
|
||||
|
||||
``\COLLISION_X_MASK``
|
||||
This parameter is a bitmask of write ports that have undefined collision
|
||||
behavior with this port. The bits of this parameter are indexed by the
|
||||
write port's ``\PORTID`` parameter. This behavior can only be enabled
|
||||
between synchronous ports sharing a clock domain. When undefined
|
||||
collision is enabled for a given port pair, a read and write to the same
|
||||
address in the same cycle will return the undefined (all-X) value.This
|
||||
option is exclusive (for a given port pair) with the transparency
|
||||
option.
|
||||
behavior with this port. The bits of this parameter are indexed by the write
|
||||
port's ``\PORTID`` parameter. This behavior can only be enabled between
|
||||
synchronous ports sharing a clock domain. When undefined collision is enabled
|
||||
for a given port pair, a read and write to the same address in the same cycle
|
||||
will return the undefined (all-X) value.This option is exclusive (for a given
|
||||
port pair) with the transparency option.
|
||||
|
||||
``\ARST_VALUE``
|
||||
Whenever the ``\ARST`` input is asserted, the data output will be reset
|
||||
to this value. Only used for synchronous ports.
|
||||
Whenever the ``\ARST`` input is asserted, the data output will be reset to
|
||||
this value. Only used for synchronous ports.
|
||||
|
||||
``\SRST_VALUE``
|
||||
Whenever the ``\SRST`` input is synchronously asserted, the data output
|
||||
will be reset to this value. Only used for synchronous ports.
|
||||
Whenever the ``\SRST`` input is synchronously asserted, the data output will
|
||||
be reset to this value. Only used for synchronous ports.
|
||||
|
||||
``\INIT_VALUE``
|
||||
The initial value of the data output, for synchronous ports.
|
||||
|
||||
``\CE_OVER_SRST``
|
||||
If this parameter is non-zero, the ``\SRST`` input is only recognized
|
||||
when ``\EN`` is true. Otherwise, ``\SRST`` is recognized regardless of
|
||||
``\EN``.
|
||||
If this parameter is non-zero, the ``\SRST`` input is only recognized when
|
||||
``\EN`` is true. Otherwise, ``\SRST`` is recognized regardless of ``\EN``.
|
||||
|
||||
The `$memwr_v2` cells have a clock input ``\CLK``, an enable input ``\EN``
|
||||
(one enable bit for each data bit), an address input ``\ADDR`` and a data input
|
||||
The `$memwr_v2` cells have a clock input ``\CLK``, an enable input ``\EN`` (one
|
||||
enable bit for each data bit), an address input ``\ADDR`` and a data input
|
||||
``\DATA``. They also have the following parameters:
|
||||
|
||||
``\MEMID``
|
||||
|
@ -424,16 +419,16 @@ The `$memwr_v2` cells have a clock input ``\CLK``, an enable input ``\EN``
|
|||
|
||||
``\WIDTH``
|
||||
The number of data bits (width of the ``\DATA`` output port). Like with
|
||||
`$memrd_v2` cells, the width is allowed to be any power-of-two
|
||||
multiple of memory width, with the corresponding restriction on address.
|
||||
`$memrd_v2` cells, the width is allowed to be any power-of-two multiple of
|
||||
memory width, with the corresponding restriction on address.
|
||||
|
||||
``\CLK_ENABLE``
|
||||
When this parameter is non-zero, the clock is used. Otherwise this write
|
||||
port is asynchronous and the ``\CLK`` input is not used.
|
||||
When this parameter is non-zero, the clock is used. Otherwise this write port
|
||||
is asynchronous and the ``\CLK`` input is not used.
|
||||
|
||||
``\CLK_POLARITY``
|
||||
Clock is active on positive edge if this parameter has the value
|
||||
``1'b1`` and on the negative edge if this parameter is ``1'b0``.
|
||||
Clock is active on positive edge if this parameter has the value ``1'b1`` and
|
||||
on the negative edge if this parameter is ``1'b0``.
|
||||
|
||||
``\PORTID``
|
||||
An identifier for this write port, used to index write port bit mask
|
||||
|
@ -442,16 +437,16 @@ The `$memwr_v2` cells have a clock input ``\CLK``, an enable input ``\EN``
|
|||
``\PRIORITY_MASK``
|
||||
This parameter is a bitmask of write ports that this write port has priority
|
||||
over in case of writing to the same address. The bits of this parameter are
|
||||
indexed by the other write port's ``\PORTID`` parameter. Write ports can
|
||||
only have priority over write ports with lower port ID. When two ports write
|
||||
to the same address and neither has priority over the other, the result is
|
||||
indexed by the other write port's ``\PORTID`` parameter. Write ports can only
|
||||
have priority over write ports with lower port ID. When two ports write to
|
||||
the same address and neither has priority over the other, the result is
|
||||
undefined. Priority can only be set between two synchronous ports sharing
|
||||
the same clock domain.
|
||||
|
||||
The `$meminit_v2` cells have an address input ``\ADDR``, a data input
|
||||
``\DATA``, with the width of the ``\DATA`` port equal to ``\WIDTH`` parameter
|
||||
times ``\WORDS`` parameter, and a bit enable mask input ``\EN`` with width equal
|
||||
to ``\WIDTH`` parameter. All three of the inputs must resolve to a constant for
|
||||
The `$meminit_v2` cells have an address input ``\ADDR``, a data input ``\DATA``,
|
||||
with the width of the ``\DATA`` port equal to ``\WIDTH`` parameter times
|
||||
``\WORDS`` parameter, and a bit enable mask input ``\EN`` with width equal to
|
||||
``\WIDTH`` parameter. All three of the inputs must resolve to a constant for
|
||||
synthesis to succeed.
|
||||
|
||||
``\MEMID``
|
||||
|
@ -472,19 +467,18 @@ synthesis to succeed.
|
|||
initialization conflict.
|
||||
|
||||
The HDL frontend models a memory using ``RTLIL::Memory`` objects and
|
||||
asynchronous `$memrd_v2` and `$memwr_v2` cells. The `memory` pass
|
||||
(i.e. its various sub-passes) migrates `$dff` cells into the `$memrd_v2` and
|
||||
`$memwr_v2` cells making them synchronous, then converts them to a single
|
||||
`$mem_v2` cell and (optionally) maps this cell type to `$dff` cells for the
|
||||
individual words and multiplexer-based address decoders for the read and write
|
||||
interfaces. When the last step is disabled or not possible, a `$mem_v2` cell
|
||||
is left in the design.
|
||||
asynchronous `$memrd_v2` and `$memwr_v2` cells. The `memory` pass (i.e. its
|
||||
various sub-passes) migrates `$dff` cells into the `$memrd_v2` and `$memwr_v2`
|
||||
cells making them synchronous, then converts them to a single `$mem_v2` cell and
|
||||
(optionally) maps this cell type to `$dff` cells for the individual words and
|
||||
multiplexer-based address decoders for the read and write interfaces. When the
|
||||
last step is disabled or not possible, a `$mem_v2` cell is left in the design.
|
||||
|
||||
The `$mem_v2` cell provides the following parameters:
|
||||
|
||||
``\MEMID``
|
||||
The name of the original ``RTLIL::Memory`` object that became this
|
||||
`$mem_v2` cell.
|
||||
The name of the original ``RTLIL::Memory`` object that became this `$mem_v2`
|
||||
cell.
|
||||
|
||||
``\SIZE``
|
||||
The number of words in the memory.
|
||||
|
@ -502,19 +496,19 @@ The `$mem_v2` cell provides the following parameters:
|
|||
The number of read ports on this memory cell.
|
||||
|
||||
``\RD_WIDE_CONTINUATION``
|
||||
This parameter is ``\RD_PORTS`` bits wide, containing a bitmask of
|
||||
"wide continuation" read ports. Such ports are used to represent the
|
||||
extra data bits of wide ports in the combined cell, and must have all
|
||||
control signals identical with the preceding port, except for address,
|
||||
which must have the proper sub-cell address encoded in the low bits.
|
||||
This parameter is ``\RD_PORTS`` bits wide, containing a bitmask of "wide
|
||||
continuation" read ports. Such ports are used to represent the extra data
|
||||
bits of wide ports in the combined cell, and must have all control signals
|
||||
identical with the preceding port, except for address, which must have the
|
||||
proper sub-cell address encoded in the low bits.
|
||||
|
||||
``\RD_CLK_ENABLE``
|
||||
This parameter is ``\RD_PORTS`` bits wide, containing a clock enable bit
|
||||
for each read port.
|
||||
This parameter is ``\RD_PORTS`` bits wide, containing a clock enable bit for
|
||||
each read port.
|
||||
|
||||
``\RD_CLK_POLARITY``
|
||||
This parameter is ``\RD_PORTS`` bits wide, containing a clock polarity
|
||||
bit for each read port.
|
||||
This parameter is ``\RD_PORTS`` bits wide, containing a clock polarity bit
|
||||
for each read port.
|
||||
|
||||
``\RD_TRANSPARENCY_MASK``
|
||||
This parameter is ``\RD_PORTS*\WR_PORTS`` bits wide, containing a
|
||||
|
@ -523,62 +517,62 @@ The `$mem_v2` cell provides the following parameters:
|
|||
|
||||
``\RD_COLLISION_X_MASK``
|
||||
This parameter is ``\RD_PORTS*\WR_PORTS`` bits wide, containing a
|
||||
concatenation of all ``\COLLISION_X_MASK`` values of the original
|
||||
`$memrd_v2` cells.
|
||||
concatenation of all ``\COLLISION_X_MASK`` values of the original `$memrd_v2`
|
||||
cells.
|
||||
|
||||
``\RD_CE_OVER_SRST``
|
||||
This parameter is ``\RD_PORTS`` bits wide, determining relative
|
||||
synchronous reset and enable priority for each read port.
|
||||
This parameter is ``\RD_PORTS`` bits wide, determining relative synchronous
|
||||
reset and enable priority for each read port.
|
||||
|
||||
``\RD_INIT_VALUE``
|
||||
This parameter is ``\RD_PORTS*\WIDTH`` bits wide, containing the initial
|
||||
value for each synchronous read port.
|
||||
|
||||
``\RD_ARST_VALUE``
|
||||
This parameter is ``\RD_PORTS*\WIDTH`` bits wide, containing the
|
||||
asynchronous reset value for each synchronous read port.
|
||||
This parameter is ``\RD_PORTS*\WIDTH`` bits wide, containing the asynchronous
|
||||
reset value for each synchronous read port.
|
||||
|
||||
``\RD_SRST_VALUE``
|
||||
This parameter is ``\RD_PORTS*\WIDTH`` bits wide, containing the
|
||||
synchronous reset value for each synchronous read port.
|
||||
This parameter is ``\RD_PORTS*\WIDTH`` bits wide, containing the synchronous
|
||||
reset value for each synchronous read port.
|
||||
|
||||
``\WR_PORTS``
|
||||
The number of write ports on this memory cell.
|
||||
|
||||
``\WR_WIDE_CONTINUATION``
|
||||
This parameter is ``\WR_PORTS`` bits wide, containing a bitmask of
|
||||
"wide continuation" write ports.
|
||||
This parameter is ``\WR_PORTS`` bits wide, containing a bitmask of "wide
|
||||
continuation" write ports.
|
||||
|
||||
``\WR_CLK_ENABLE``
|
||||
This parameter is ``\WR_PORTS`` bits wide, containing a clock enable bit
|
||||
for each write port.
|
||||
This parameter is ``\WR_PORTS`` bits wide, containing a clock enable bit for
|
||||
each write port.
|
||||
|
||||
``\WR_CLK_POLARITY``
|
||||
This parameter is ``\WR_PORTS`` bits wide, containing a clock polarity
|
||||
bit for each write port.
|
||||
This parameter is ``\WR_PORTS`` bits wide, containing a clock polarity bit
|
||||
for each write port.
|
||||
|
||||
``\WR_PRIORITY_MASK``
|
||||
This parameter is ``\WR_PORTS*\WR_PORTS`` bits wide, containing a
|
||||
concatenation of all ``\PRIORITY_MASK`` values of the original
|
||||
`$memwr_v2` cells.
|
||||
concatenation of all ``\PRIORITY_MASK`` values of the original `$memwr_v2`
|
||||
cells.
|
||||
|
||||
The `$mem_v2` cell has the following ports:
|
||||
|
||||
``\RD_CLK``
|
||||
This input is ``\RD_PORTS`` bits wide, containing all clock signals for
|
||||
the read ports.
|
||||
This input is ``\RD_PORTS`` bits wide, containing all clock signals for the
|
||||
read ports.
|
||||
|
||||
``\RD_EN``
|
||||
This input is ``\RD_PORTS`` bits wide, containing all enable signals for
|
||||
the read ports.
|
||||
This input is ``\RD_PORTS`` bits wide, containing all enable signals for the
|
||||
read ports.
|
||||
|
||||
``\RD_ADDR``
|
||||
This input is ``\RD_PORTS*\ABITS`` bits wide, containing all address
|
||||
signals for the read ports.
|
||||
This input is ``\RD_PORTS*\ABITS`` bits wide, containing all address signals
|
||||
for the read ports.
|
||||
|
||||
``\RD_DATA``
|
||||
This output is ``\RD_PORTS*\WIDTH`` bits wide, containing all data
|
||||
signals for the read ports.
|
||||
This output is ``\RD_PORTS*\WIDTH`` bits wide, containing all data signals
|
||||
for the read ports.
|
||||
|
||||
``\RD_ARST``
|
||||
This input is ``\RD_PORTS`` bits wide, containing all asynchronous reset
|
||||
|
@ -593,26 +587,25 @@ The `$mem_v2` cell has the following ports:
|
|||
the write ports.
|
||||
|
||||
``\WR_EN``
|
||||
This input is ``\WR_PORTS*\WIDTH`` bits wide, containing all enable
|
||||
signals for the write ports.
|
||||
This input is ``\WR_PORTS*\WIDTH`` bits wide, containing all enable signals
|
||||
for the write ports.
|
||||
|
||||
``\WR_ADDR``
|
||||
This input is ``\WR_PORTS*\ABITS`` bits wide, containing all address
|
||||
signals for the write ports.
|
||||
This input is ``\WR_PORTS*\ABITS`` bits wide, containing all address signals
|
||||
for the write ports.
|
||||
|
||||
``\WR_DATA``
|
||||
This input is ``\WR_PORTS*\WIDTH`` bits wide, containing all data
|
||||
signals for the write ports.
|
||||
This input is ``\WR_PORTS*\WIDTH`` bits wide, containing all data signals for
|
||||
the write ports.
|
||||
|
||||
The `memory_collect` pass can be used to convert discrete
|
||||
`$memrd_v2`, `$memwr_v2`, and `$meminit_v2` cells belonging to the same
|
||||
memory to a single `$mem_v2` cell, whereas the `memory_unpack` pass
|
||||
performs the inverse operation. The `memory_dff` pass can combine
|
||||
asynchronous memory ports that are fed by or feeding registers into synchronous
|
||||
memory ports. The `memory_bram` pass can be used to recognize
|
||||
`$mem_v2` cells that can be implemented with a block RAM resource on an FPGA.
|
||||
The `memory_map` pass can be used to implement `$mem_v2` cells as
|
||||
basic logic: word-wide DFFs and address decoders.
|
||||
The `memory_collect` pass can be used to convert discrete `$memrd_v2`,
|
||||
`$memwr_v2`, and `$meminit_v2` cells belonging to the same memory to a single
|
||||
`$mem_v2` cell, whereas the `memory_unpack` pass performs the inverse operation.
|
||||
The `memory_dff` pass can combine asynchronous memory ports that are fed by or
|
||||
feeding registers into synchronous memory ports. The `memory_bram` pass can be
|
||||
used to recognize `$mem_v2` cells that can be implemented with a block RAM
|
||||
resource on an FPGA. The `memory_map` pass can be used to implement `$mem_v2`
|
||||
cells as basic logic: word-wide DFFs and address decoders.
|
||||
|
||||
Finite state machines
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
@ -622,15 +615,17 @@ Add a brief description of the `$fsm` cell type.
|
|||
Coarse arithmetics
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The `$macc` cell type represents a generalized multiply and accumulate operation. The cell is purely combinational. It outputs the result of summing up a sequence of products and other injected summands.
|
||||
The `$macc` cell type represents a generalized multiply and accumulate
|
||||
operation. The cell is purely combinational. It outputs the result of summing up
|
||||
a sequence of products and other injected summands.
|
||||
|
||||
.. code-block::
|
||||
|
||||
Y = 0 +- a0factor1 * a0factor2 +- a1factor1 * a1factor2 +- ...
|
||||
+ B[0] + B[1] + ...
|
||||
|
||||
The A port consists of concatenated pairs of multiplier inputs ("factors").
|
||||
A zero length factor2 acts as a constant 1, turning factor1 into a simple summand.
|
||||
The A port consists of concatenated pairs of multiplier inputs ("factors"). A
|
||||
zero length factor2 acts as a constant 1, turning factor1 into a simple summand.
|
||||
|
||||
In this pseudocode, ``u(foo)`` means an unsigned int that's foo bits long.
|
||||
|
||||
|
@ -644,8 +639,8 @@ In this pseudocode, ``u(foo)`` means an unsigned int that's foo bits long.
|
|||
...
|
||||
};
|
||||
|
||||
The cell's ``CONFIG`` parameter determines the layout of cell port ``A``.
|
||||
The CONFIG parameter carries the following information:
|
||||
The cell's ``CONFIG`` parameter determines the layout of cell port ``A``. The
|
||||
CONFIG parameter carries the following information:
|
||||
|
||||
.. code-block::
|
||||
|
||||
|
@ -714,8 +709,8 @@ Formal verification cells
|
|||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Add information about `$check`, `$assert`, `$assume`, `$live`, `$fair`,
|
||||
`$cover`, `$equiv`, `$initstate`, `$anyconst`, `$anyseq`,
|
||||
`$anyinit`, `$allconst`, `$allseq` cells.
|
||||
`$cover`, `$equiv`, `$initstate`, `$anyconst`, `$anyseq`, `$anyinit`,
|
||||
`$allconst`, `$allseq` cells.
|
||||
|
||||
Add information about `$ff` and `$_FF_` cells.
|
||||
|
||||
|
@ -733,8 +728,8 @@ has the following parameters:
|
|||
The width (in bits) of the signal on the ``\ARGS`` port.
|
||||
|
||||
``\TRG_ENABLE``
|
||||
True if triggered on specific signals defined in ``\TRG``; false if
|
||||
triggered whenever ``\ARGS`` or ``\EN`` change and ``\EN`` is 1.
|
||||
True if triggered on specific signals defined in ``\TRG``; false if triggered
|
||||
whenever ``\ARGS`` or ``\EN`` change and ``\EN`` is 1.
|
||||
|
||||
If ``\TRG_ENABLE`` is true, the following parameters also apply:
|
||||
|
||||
|
@ -792,12 +787,13 @@ width\ *?*
|
|||
(optional) The number of characters wide to pad to.
|
||||
|
||||
base
|
||||
* ``b`` for base-2 integers (binary)
|
||||
* ``o`` for base-8 integers (octal)
|
||||
* ``d`` for base-10 integers (decimal)
|
||||
* ``h`` for base-16 integers (hexadecimal)
|
||||
* ``c`` for ASCII characters/strings
|
||||
* ``t`` and ``r`` for simulation time (corresponding to :verilog:`$time` and :verilog:`$realtime`)
|
||||
* ``b`` for base-2 integers (binary)
|
||||
* ``o`` for base-8 integers (octal)
|
||||
* ``d`` for base-10 integers (decimal)
|
||||
* ``h`` for base-16 integers (hexadecimal)
|
||||
* ``c`` for ASCII characters/strings
|
||||
* ``t`` and ``r`` for simulation time (corresponding to :verilog:`$time` and
|
||||
:verilog:`$realtime`)
|
||||
|
||||
For integers, this item may follow:
|
||||
|
||||
|
@ -1042,14 +1038,13 @@ Tables :numref:`%s <tab:CellLib_gates>`, :numref:`%s <tab:CellLib_gates_dffe>`,
|
|||
:numref:`%s <tab:CellLib_gates_adlatch>`, :numref:`%s
|
||||
<tab:CellLib_gates_dlatchsr>` and :numref:`%s <tab:CellLib_gates_sr>` list all
|
||||
cell types used for gate level logic. The cell types `$_BUF_`, `$_NOT_`,
|
||||
`$_AND_`, `$_NAND_`, `$_ANDNOT_`, `$_OR_`, `$_NOR_`, `$_ORNOT_`,
|
||||
`$_XOR_`, `$_XNOR_`, `$_AOI3_`, `$_OAI3_`, `$_AOI4_`, `$_OAI4_`,
|
||||
`$_MUX_`, `$_MUX4_`, `$_MUX8_`, `$_MUX16_` and `$_NMUX_` are used to
|
||||
model combinatorial logic. The cell type `$_TBUF_` is used to model tristate
|
||||
logic.
|
||||
`$_AND_`, `$_NAND_`, `$_ANDNOT_`, `$_OR_`, `$_NOR_`, `$_ORNOT_`, `$_XOR_`,
|
||||
`$_XNOR_`, `$_AOI3_`, `$_OAI3_`, `$_AOI4_`, `$_OAI4_`, `$_MUX_`, `$_MUX4_`,
|
||||
`$_MUX8_`, `$_MUX16_` and `$_NMUX_` are used to model combinatorial logic. The
|
||||
cell type `$_TBUF_` is used to model tristate logic.
|
||||
|
||||
The `$_MUX4_`, `$_MUX8_` and `$_MUX16_` cells are used to model wide
|
||||
muxes, and correspond to the following Verilog code:
|
||||
The `$_MUX4_`, `$_MUX8_` and `$_MUX16_` cells are used to model wide muxes, and
|
||||
correspond to the following Verilog code:
|
||||
|
||||
.. code-block:: verilog
|
||||
:force:
|
||||
|
@ -1114,8 +1109,8 @@ following Verilog code template:
|
|||
|
||||
The cell types ``$_DFFE_[NP][NP][01][NP]_`` implement d-type flip-flops with
|
||||
asynchronous reset and enable. The values in the table for these cell types
|
||||
relate to the following Verilog code template, where ``RST_EDGE`` is
|
||||
``posedge`` if ``RST_LVL`` if ``1``, and ``negedge`` otherwise.
|
||||
relate to the following Verilog code template, where ``RST_EDGE`` is ``posedge``
|
||||
if ``RST_LVL`` if ``1``, and ``negedge`` otherwise.
|
||||
|
||||
.. code-block:: verilog
|
||||
:force:
|
||||
|
@ -1156,8 +1151,8 @@ in the table for these cell types relate to the following Verilog code template:
|
|||
The cell types ``$_DFFSR_[NP][NP][NP]_`` implement d-type flip-flops with
|
||||
asynchronous set and reset. The values in the table for these cell types relate
|
||||
to the following Verilog code template, where ``RST_EDGE`` is ``posedge`` if
|
||||
``RST_LVL`` if ``1``, ``negedge`` otherwise, and ``SET_EDGE`` is ``posedge``
|
||||
if ``SET_LVL`` if ``1``, ``negedge`` otherwise.
|
||||
``RST_LVL`` if ``1``, ``negedge`` otherwise, and ``SET_EDGE`` is ``posedge`` if
|
||||
``SET_LVL`` if ``1``, ``negedge`` otherwise.
|
||||
|
||||
.. code-block:: verilog
|
||||
:force:
|
||||
|
@ -1173,8 +1168,8 @@ if ``SET_LVL`` if ``1``, ``negedge`` otherwise.
|
|||
The cell types ``$_DFFSRE_[NP][NP][NP][NP]_`` implement d-type flip-flops with
|
||||
asynchronous set and reset and enable. The values in the table for these cell
|
||||
types relate to the following Verilog code template, where ``RST_EDGE`` is
|
||||
``posedge`` if ``RST_LVL`` if ``1``, ``negedge`` otherwise, and ``SET_EDGE``
|
||||
is ``posedge`` if ``SET_LVL`` if ``1``, ``negedge`` otherwise.
|
||||
``posedge`` if ``RST_LVL`` if ``1``, ``negedge`` otherwise, and ``SET_EDGE`` is
|
||||
``posedge`` if ``SET_LVL`` if ``1``, ``negedge`` otherwise.
|
||||
|
||||
.. code-block:: verilog
|
||||
:force:
|
||||
|
|
|
@ -76,11 +76,10 @@ This has three advantages:
|
|||
|
||||
- Second, the information about which identifiers were originally provided by
|
||||
the user is always available which can help guide some optimizations. For
|
||||
example, `opt_clean` 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. Note that this can be overridden
|
||||
with the ``-purge`` option to also delete internal nets with user-provided
|
||||
names.
|
||||
example, `opt_clean` 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. Note that this can be overridden with the
|
||||
``-purge`` option to also delete internal nets with user-provided names.
|
||||
|
||||
- Third, the delicate job of finding suitable auto-generated public visible
|
||||
names is deferred to one central location. Internally auto-generated names
|
||||
|
@ -204,8 +203,8 @@ A "signal" is everything that can be applied to a cell port. I.e.
|
|||
- | 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.
|
||||
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.
|
||||
|
@ -234,9 +233,9 @@ control logic of the behavioural code. Let's consider a simple example:
|
|||
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:
|
||||
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:
|
||||
|
@ -320,8 +319,8 @@ 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``:
|
||||
the `proc_arst` pass. This pass transforms the above example to the following
|
||||
``RTLIL::Process``:
|
||||
|
||||
.. code:: RTLIL
|
||||
:number-lines:
|
||||
|
@ -340,9 +339,9 @@ following ``RTLIL::Process``:
|
|||
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:
|
||||
``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:
|
||||
|
@ -365,9 +364,9 @@ multiplexer for the enable signal:
|
|||
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.
|
||||
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.
|
||||
|
@ -389,9 +388,9 @@ A memory object has the following properties:
|
|||
- 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
|
||||
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.
|
||||
|
@ -402,8 +401,8 @@ 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.
|
||||
`$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
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
Techmap by example
|
||||
------------------
|
||||
|
||||
As a quick recap, the `techmap` command replaces cells in the design
|
||||
with implementations given as Verilog code (called "map files"). It can replace
|
||||
As a quick recap, the `techmap` command replaces cells in the design with
|
||||
implementations given as Verilog code (called "map files"). It can replace
|
||||
Yosys' internal cell types (such as `$or`) as well as user-defined cell types.
|
||||
|
||||
- Verilog parameters are used extensively to customize the internal cell types.
|
||||
|
@ -94,8 +94,8 @@ Scripting in map modules
|
|||
|
||||
.. note:: PROTIP:
|
||||
|
||||
Commands such as `shell`, ``show -pause``, and `dump` can
|
||||
be used in the ``_TECHMAP_DO_*`` scripts for debugging map modules.
|
||||
Commands such as `shell`, ``show -pause``, and `dump` can be used in the
|
||||
``_TECHMAP_DO_*`` scripts for debugging map modules.
|
||||
|
||||
Example:
|
||||
|
||||
|
|
Loading…
Reference in New Issue