mirror of
https://github.com/YosysHQ/yosys
synced 2025-08-11 13:40:53 +00:00
Merge pull request #5139 from YosysHQ/docs-preview-bugpoint
Docs: Add bugpoint guide
This commit is contained in:
commit
700ba982e8
13 changed files with 994 additions and 36 deletions
|
@ -19,14 +19,14 @@ much easier for someone to respond and help.
|
||||||
|
|
||||||
### Bug reports
|
### Bug reports
|
||||||
|
|
||||||
Before you submit an issue, please have a search of the existing issues in case
|
Before you submit an issue, please check out the [how-to guide for
|
||||||
one already exists. Making sure that you have a minimal, complete and
|
`bugpoint`](https://yosys.readthedocs.io/en/latest/using_yosys/bugpoint.html).
|
||||||
verifiable example (MVCE) is a great way to quickly check an existing issue
|
This guide will take you through the process of using the [`bugpoint`
|
||||||
against a new one. Stack overflow has a guide on [how to create an
|
command](https://yosys.readthedocs.io/en/latest/cmd/bugpoint.html) in Yosys to
|
||||||
MVCE](https://stackoverflow.com/help/minimal-reproducible-example). The
|
produce a [minimal, complete and verifiable
|
||||||
[`bugpoint`
|
example](https://stackoverflow.com/help/minimal-reproducible-example) (MVCE).
|
||||||
command](https://yosyshq.readthedocs.io/projects/yosys/en/latest/cmd/bugpoint.html)
|
Providing an MVCE with your bug report drastically increases the likelihood that
|
||||||
in Yosys can be helpful for this process.
|
someone will be able to help resolve your issue.
|
||||||
|
|
||||||
|
|
||||||
# Using pull requests
|
# Using pull requests
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
.. _cmd_ref:
|
|
||||||
|
|
||||||
================================================================================
|
================================================================================
|
||||||
Command line reference
|
Command line reference
|
||||||
================================================================================
|
================================================================================
|
||||||
|
|
|
@ -64,7 +64,6 @@ if os.getenv("READTHEDOCS"):
|
||||||
|
|
||||||
# Ensure that autosectionlabel will produce unique names
|
# Ensure that autosectionlabel will produce unique names
|
||||||
autosectionlabel_prefix_document = True
|
autosectionlabel_prefix_document = True
|
||||||
autosectionlabel_maxdepth = 1
|
|
||||||
|
|
||||||
# include todos for previews
|
# include todos for previews
|
||||||
extensions.append('sphinx.ext.todo')
|
extensions.append('sphinx.ext.todo')
|
||||||
|
|
|
@ -26,7 +26,7 @@ of the comment is a semicolon ``;`` or a new line.
|
||||||
.. code-block::
|
.. code-block::
|
||||||
:caption: Using the ``-p`` option
|
:caption: Using the ``-p`` option
|
||||||
|
|
||||||
$ yosys -p "read_verilog fifo.v; :this is a comment; prep"
|
$ yosys -p 'read_verilog fifo.v; :this is a comment; prep'
|
||||||
|
|
||||||
.. warning::
|
.. warning::
|
||||||
|
|
||||||
|
@ -42,6 +42,13 @@ will be raised by Yosys. `exec` provides a much more flexible way of executing
|
||||||
commands, allowing the output to be logged and more control over when to
|
commands, allowing the output to be logged and more control over when to
|
||||||
generate errors.
|
generate errors.
|
||||||
|
|
||||||
|
.. warning::
|
||||||
|
|
||||||
|
Take care when using the ``yosys -p`` option. Some shells such as bash will
|
||||||
|
perform substitution options inside of a double quoted string, such as ``!``
|
||||||
|
for history substitution and ``$`` for variable substitution; single quotes
|
||||||
|
should be used instead to pass the string to Yosys without substitution.
|
||||||
|
|
||||||
The synthesis starter script
|
The synthesis starter script
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
446
docs/source/using_yosys/bugpoint.rst
Normal file
446
docs/source/using_yosys/bugpoint.rst
Normal file
|
@ -0,0 +1,446 @@
|
||||||
|
Minimizing failing (or bugged) designs
|
||||||
|
======================================
|
||||||
|
|
||||||
|
.. TODO:: pending merge of https://github.com/YosysHQ/yosys/pull/5068
|
||||||
|
|
||||||
|
This document is a how-to guide for reducing problematic designs to the bare
|
||||||
|
minimum needed for reproducing the issue. This is a Yosys specific alternative
|
||||||
|
to the Stack Overflow article: `How to create a Minimal, Reproducible Example`_,
|
||||||
|
and is intended to help when there's something wrong with your design, or with
|
||||||
|
Yosys itself.
|
||||||
|
|
||||||
|
.. _How to create a Minimal, Reproducible Example: https://stackoverflow.com/help/minimal-reproducible-example
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
This guide assumes a moderate degree of familiarity with Yosys and requires
|
||||||
|
some amount of problem solving ability.
|
||||||
|
|
||||||
|
|
||||||
|
Before you start
|
||||||
|
----------------
|
||||||
|
|
||||||
|
The first (and often overlooked) step, is to check for and *read* any error
|
||||||
|
messages or warnings. Passing the ``-q`` flag when running Yosys will make it
|
||||||
|
so that only warnings and error messages are written to the console. Don't just
|
||||||
|
read the last message either, there may be warnings that indicate a problem
|
||||||
|
before it happens. While some things may only be regarded as warnings, such as
|
||||||
|
multiple drivers for the same signal or logic loops, these can cause problems in
|
||||||
|
some synthesis flows but not others.
|
||||||
|
|
||||||
|
A Yosys error (one that starts with ``ERROR:``) may give you a line number from
|
||||||
|
your design, or the name of the object causing issues. If so, you may already
|
||||||
|
have enough information to resolve the problem, or at least understand why it's
|
||||||
|
happening.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
If you're not already, try using the latest version from the `Yosys GitHub`_.
|
||||||
|
You may find that your issue has already been fixed! And even if it isn't,
|
||||||
|
testing with two different versions is a good way to ensure reproducibility.
|
||||||
|
|
||||||
|
.. _Yosys GitHub: https://github.com/YosysHQ/yosys
|
||||||
|
|
||||||
|
Another thing to be aware of is that Yosys generally doesn't perform rigorous
|
||||||
|
checking of input designs to ensure they are valid. This is especially true for
|
||||||
|
the `read_verilog` frontend. It is instead recommended that you try load it
|
||||||
|
with `iverilog`_ or `verilator`_ first, as an invalid design can often lead to
|
||||||
|
unexpected issues.
|
||||||
|
|
||||||
|
.. _iverilog: https://steveicarus.github.io/iverilog/
|
||||||
|
.. _verilator: https://www.veripool.org/verilator/
|
||||||
|
|
||||||
|
If you're using a custom synthesis script, try take a bit of time to figure out
|
||||||
|
which command is failing. Calling ``echo on`` at the start of your script will
|
||||||
|
`echo` each command executed; the last echo before the error should then be
|
||||||
|
where the error has come from. Check the help message for the failing command;
|
||||||
|
does it indicate limited support, or mention some other command that needs to be
|
||||||
|
run first? You can also try to call `check` and/or ``hierarchy -check`` before
|
||||||
|
the failure to see if they report and errors or warnings.
|
||||||
|
|
||||||
|
|
||||||
|
Minimizing RTLIL designs with bugpoint
|
||||||
|
--------------------------------------
|
||||||
|
|
||||||
|
Yosys provides the `bugpoint` command for reducing a failing design to the
|
||||||
|
smallest portion of that design which still results in failure. While initially
|
||||||
|
developed for Yosys crashes, `bugpoint` can also be used for designs that lead
|
||||||
|
to non-fatal errors, or even failures in other tools that use the output of a
|
||||||
|
Yosys script.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
Make sure to back up your code (design source and yosys script(s)) before
|
||||||
|
making any modifications. Even if the code itself isn't important, this can
|
||||||
|
help avoid "losing" the error while trying to debug it.
|
||||||
|
|
||||||
|
Can I use bugpoint?
|
||||||
|
~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
The first thing to be aware of is that `bugpoint` is not available in every
|
||||||
|
build of Yosys. Because the command works by invoking external processes, it
|
||||||
|
requires that Yosys can spawn executables. Notably this means `bugpoint` is not
|
||||||
|
able to be used in WebAssembly builds such as that available via YoWASP. The
|
||||||
|
easiest way to check your build of Yosys is by running ``yosys -h bugpoint``. If
|
||||||
|
Yosys displays the help text for `bugpoint` then it is available for use.
|
||||||
|
|
||||||
|
.. code-block:: console
|
||||||
|
:caption: `bugpoint` is unavailable
|
||||||
|
|
||||||
|
$ yosys -h bugpoint
|
||||||
|
|
||||||
|
-- Running command `help bugpoint' --
|
||||||
|
No such command or cell type: bugpoint
|
||||||
|
|
||||||
|
Next you need to separate loading the design from the failure point; you should
|
||||||
|
be aiming to reproduce the failure by running ``yosys -s <load.ys> -s
|
||||||
|
<failure.ys>``. If the failure occurs while loading the design, such as during
|
||||||
|
`read_verilog` you will instead have to minimize the input design yourself.
|
||||||
|
Check out the instructions for :ref:`using_yosys/bugpoint:minimizing verilog
|
||||||
|
designs` below.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
You should also be able to run the two scripts separately, calling first
|
||||||
|
``yosys -s <load.ys> -p 'write_rtlil design.il'`` and then ``yosys -s
|
||||||
|
<failure.ys> design.il``. If this doesn't work then it may mean that the
|
||||||
|
failure isn't reproducible from RTLIL and `bugpoint` won't work either.
|
||||||
|
|
||||||
|
When we talk about failure points here, it doesn't just mean crashes or errors
|
||||||
|
in Yosys. The ``<failure.ys>`` script can also be a user-defined failure such
|
||||||
|
as the `select` command with one of the ``-assert-*`` options; an example where
|
||||||
|
this might be useful is when a pass is supposed to remove a certain kind of
|
||||||
|
cell, but there is some edge case where the cell is not removed. Another
|
||||||
|
use-case would be minimizing a design which fails with the `equiv_opt` command,
|
||||||
|
suggesting that the optimization in question alters the circuit in some way.
|
||||||
|
|
||||||
|
It is even possible to use `bugpoint` with failures *external* to Yosys, by
|
||||||
|
making use of the `exec` command in ``<failure.ys>``. This is especially useful
|
||||||
|
when Yosys is outputting an invalid design, or when some other tool is
|
||||||
|
incompatible with the design. Be sure to use the ``exec -expect-*`` options so
|
||||||
|
that the pass/fail can be detected correctly. Multiple calls to `exec` can be
|
||||||
|
made, or even entire shell scripts:
|
||||||
|
|
||||||
|
.. code-block:: yoscrypt
|
||||||
|
|
||||||
|
exec -expect-return 1 --bash <script.sh>
|
||||||
|
|
||||||
|
Our final failure we can use with `bugpoint` is one returned by a wrapper
|
||||||
|
process, such as ``valgrind`` or ``timeout``. In this case you will be calling
|
||||||
|
something like ``<wrapper> yosys -s <failure.ys> design.il``. Here, Yosys is
|
||||||
|
run under a wrapper process which checks for some failure state, like a memory
|
||||||
|
leak or excessive runtime.
|
||||||
|
|
||||||
|
|
||||||
|
How do I use bugpoint?
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
At this point you should have:
|
||||||
|
|
||||||
|
1. either an RTLIL file containing the design to minimize (referred to here as
|
||||||
|
``design.il``), or a Yosys script, ``<load.ys>``, which loads it; and
|
||||||
|
2. a Yosys script, ``<failure.ys>``, which produces the failure and returns a
|
||||||
|
non-zero return status.
|
||||||
|
|
||||||
|
Now call ``yosys -qq -s <failure.ys> design.il`` and take note of the error(s)
|
||||||
|
that get printed. A template script, ``<bugpoint.ys>``, is provided here which
|
||||||
|
you can use. Make sure to configure it with the correct filenames and use only
|
||||||
|
one of the methods to load the design. Fill in the ``-grep`` option with the
|
||||||
|
error message printed just before. If you are using a wrapper process for your
|
||||||
|
failure state, add the ``-runner "<wrapper>"`` option to the `bugpoint` call.
|
||||||
|
|
||||||
|
.. code-block:: yoscrypt
|
||||||
|
:caption: ``<bugpoint.ys>`` template script
|
||||||
|
|
||||||
|
# Load design
|
||||||
|
read_rtlil design.il
|
||||||
|
## OR
|
||||||
|
script <load.ys>
|
||||||
|
|
||||||
|
# Call bugpoint with failure
|
||||||
|
bugpoint -script <failure.ys> -grep "<string>"
|
||||||
|
|
||||||
|
# Save minimized design
|
||||||
|
write_rtlil min.il
|
||||||
|
|
||||||
|
The ``-grep`` option is used to search the log file generated by the Yosys under
|
||||||
|
test. If the error message is generated by something else, such as a wrapper
|
||||||
|
process or compiler sanitizer, then you should instead use ``-err_grep``. For
|
||||||
|
an OS error, like a SEGFAULT, you can also use ``-expect-return`` to check the
|
||||||
|
error code returned.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
Checking the error message or return status is optional, but highly
|
||||||
|
recommended. `bugpoint` can quite easily introduce bugs by creating
|
||||||
|
malformed designs that commands were not intended to handle. By having some
|
||||||
|
way to check the error, `bugpoint` can ensure that it is the *right* error
|
||||||
|
being reproduced. This is even more important when ``<failure.ys>`` contains
|
||||||
|
more than one command.
|
||||||
|
|
||||||
|
By default, `bugpoint` is able to remove any part of the design. In order to
|
||||||
|
keep certain parts, for instance because you already know they are related to
|
||||||
|
the failure, you can use the ``bugpoint_keep`` attribute. This can be done with
|
||||||
|
``(* bugpoint_keep *)`` in Verilog, ``attribute \bugpoint_keep 1`` in RTLIL, or
|
||||||
|
``setattr -set bugpoint_keep 1 [selection]`` from a Yosys script. It is also
|
||||||
|
possible to limit `bugpoint` to only removing certain *kinds* of objects, such
|
||||||
|
as only removing entire modules or cells (instances of modules). For more about
|
||||||
|
the options available, check ``help bugpoint`` or :doc:`/cmd/bugpoint`.
|
||||||
|
|
||||||
|
In some situations, it may also be helpful to use `setenv` before `bugpoint` to
|
||||||
|
set environment variables for the spawned processes. An example of this is
|
||||||
|
``setenv UBSAN_OPTIONS halt_on_error=1`` for where you are trying to raise an
|
||||||
|
error on undefined behaviour but only want the child process to halt on error.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
Using `setenv` in this way may or may not affect the current process. For
|
||||||
|
instance the ``UBSAN_OPTIONS halt_on_error`` here only affects child
|
||||||
|
processes, as does the :doc:`Yosys environment variable</appendix/env_vars>`
|
||||||
|
``ABC`` because they are only read on start-up. While others, such as
|
||||||
|
``YOSYS_NOVERIFIC`` and ``HOME``, are evaluated each time they are used.
|
||||||
|
|
||||||
|
Once you have finished configuration, you can now run ``yosys <bugpoint.ys>``.
|
||||||
|
The first thing `bugpoint` will do is test the input design fails. If it
|
||||||
|
doesn't, make sure you are using the right ``yosys`` executable; unless the
|
||||||
|
``-yosys`` option is provided, it will use whatever the shell defaults to, *not*
|
||||||
|
the current ``yosys``. If you are using the ``-runner`` option, try replacing
|
||||||
|
the `bugpoint` command with ``write_rtlil test.il`` and then on a new line,
|
||||||
|
``!<wrapper> yosys -s <failure.ys> test.il`` to check it works as expected and
|
||||||
|
returns a non-zero status.
|
||||||
|
|
||||||
|
.. seealso::
|
||||||
|
|
||||||
|
For more on script parsing and the use of ``!``, check out
|
||||||
|
:ref:`getting_started/scripting_intro:script parsing`.
|
||||||
|
|
||||||
|
Depending on the size of your design, and the length of your ``<failure.ys>``,
|
||||||
|
`bugpoint` may take some time; remember, it will run ``yosys -s <failure.ys>``
|
||||||
|
on each iteration of the design. The bigger the design, the more iterations.
|
||||||
|
The longer the ``<failure.ys>``, the longer each iteration will take. As the
|
||||||
|
design shrinks and `bugpoint` converges, each iteration should take less and
|
||||||
|
less time. Once all simplifications are exhausted and there are no more objects
|
||||||
|
that can be removed, the script will continue and the minimized design can be
|
||||||
|
saved.
|
||||||
|
|
||||||
|
|
||||||
|
What do I do with the minimized design?
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
First off, check the minimized design still fails. This is especially important
|
||||||
|
if you're not using `write_rtlil` to output the minimized design. For example,
|
||||||
|
if you ran :ref:`bugpoint_script` below, then calling ``yosys -s <failure.ys>
|
||||||
|
min.v`` should still fail in the same way.
|
||||||
|
|
||||||
|
.. code-block:: yoscrypt
|
||||||
|
:caption: example `bugpoint` minimizer
|
||||||
|
:name: bugpoint_script
|
||||||
|
|
||||||
|
read_verilog design.v
|
||||||
|
bugpoint -script <failure.ys>
|
||||||
|
write_verilog min.v
|
||||||
|
|
||||||
|
The `write_rtlil` command is generally more reliable, since `bugpoint` will have
|
||||||
|
run that exact code through the failing script. Other ``write_*`` commands
|
||||||
|
convert from the RTLIL and then back again during the ``read_*`` which can
|
||||||
|
result in differences which mean the design no longer fails.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
Simply calling Yosys with the output of ``write_*``, as in ``yosys -s
|
||||||
|
<failure.ys> min.v``, does not guarantee that the corresponding ``read_*``
|
||||||
|
will be used. For more about this, refer to
|
||||||
|
:doc:`/using_yosys/more_scripting/load_design`, or load the design explicitly
|
||||||
|
with ``yosys -p 'read_verilog min.v' -s <failure.ys>``.
|
||||||
|
|
||||||
|
Once you've verified the failure still happens, check out
|
||||||
|
:ref:`using_yosys/bugpoint:identifying issues` for more on what to do next.
|
||||||
|
|
||||||
|
|
||||||
|
Minimizing Verilog designs
|
||||||
|
--------------------------
|
||||||
|
|
||||||
|
.. seealso::
|
||||||
|
|
||||||
|
This section is not specific to Yosys, so feel free to use another guide such
|
||||||
|
as Stack Overflow's `How to create a Minimal, Reproducible Example`_.
|
||||||
|
|
||||||
|
Be sure to check any errors or warnings for messages that might identify source
|
||||||
|
lines or object names that might be causing the failure, and back up your source
|
||||||
|
code before modifying it. If you have multiple source files, you should start
|
||||||
|
by reducing them down to a single file. If a specific file is failing to read,
|
||||||
|
try removing everything else and just focus on that one. If your source uses
|
||||||
|
the ``include`` directive, replace it with the contents of the file referenced.
|
||||||
|
|
||||||
|
Unlike RTLIL designs where we can use `bugpoint`, Yosys does not provide any
|
||||||
|
tools for minimizing Verilog designs. Instead, you should use an external tool
|
||||||
|
like `C-Reduce`_ (with the ``--not-c`` flag) or `sv-bugpoint`_.
|
||||||
|
|
||||||
|
.. _C-Reduce: https://github.com/csmith-project/creduce
|
||||||
|
.. _sv-bugpoint: https://github.com/antmicro/sv-bugpoint
|
||||||
|
|
||||||
|
C-Reduce
|
||||||
|
~~~~~~~~
|
||||||
|
|
||||||
|
As a very brief overview for using C-Reduce, you want your failing source design
|
||||||
|
(``test.v``), and some shell script which checks for the error being
|
||||||
|
investigated (``test.sh``). Below is an :ref:`egtest` which uses `logger` and
|
||||||
|
the ``-expect error "<string>" 1`` option to perform a similar role to
|
||||||
|
``bugpoint -grep``, along with ``verilator`` to lint the code and make sure it
|
||||||
|
is still valid.
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
:caption: Example test.sh for C-Reduce
|
||||||
|
:name: egtest
|
||||||
|
|
||||||
|
#!/bin/bash
|
||||||
|
verilator --lint-only test.v &&/
|
||||||
|
yosys -p 'logger -expect error "unsupported" 1; read_verilog test.v'
|
||||||
|
|
||||||
|
.. code-block:: verilog
|
||||||
|
:caption: input test.v
|
||||||
|
|
||||||
|
module top(input clk, a, b, c, output x, y, z);
|
||||||
|
always @(posedge clk) begin
|
||||||
|
if (a == 1'b1)
|
||||||
|
$stop;
|
||||||
|
end
|
||||||
|
assign x = a;
|
||||||
|
assign y = a ^ b;
|
||||||
|
assign z = c;
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
In this example ``read_verilog test.v`` is giving an error message that contains
|
||||||
|
the string "unsupported" because the ``$stop`` system task is only supported in
|
||||||
|
``initial`` blocks. By calling ``creduce ./test.sh test.v --not-c`` we can
|
||||||
|
minimize the design to just the failing code, while still being valid Verilog.
|
||||||
|
|
||||||
|
.. code-block:: verilog
|
||||||
|
:caption: output test.v
|
||||||
|
|
||||||
|
module a;
|
||||||
|
always begin $stop;
|
||||||
|
end endmodule
|
||||||
|
|
||||||
|
|
||||||
|
sv-bugpoint
|
||||||
|
~~~~~~~~~~~
|
||||||
|
|
||||||
|
sv-bugpoint works quite similarly to C-Reduce, except it requires an output
|
||||||
|
directory to be provided and the check script needs to accept the target file as
|
||||||
|
an input argument: ``sv-bugpoint outDir/ test.sh test.v``
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
:caption: Example test.sh for sv-bugpoint
|
||||||
|
|
||||||
|
#!/bin/bash
|
||||||
|
verilator --lint-only $1 &&/
|
||||||
|
yosys -p "logger -expect error \"unsupported\" 1; read_verilog $1"
|
||||||
|
|
||||||
|
Notice that the commands for ``yosys -p`` are now in double quotes (``"``), and
|
||||||
|
the quotes around the error string are escaped (``\"``). This is necessary for
|
||||||
|
the ``$1`` argument subsitution to work correctly.
|
||||||
|
|
||||||
|
|
||||||
|
Doing it manually
|
||||||
|
~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
If for some reason you are unable to use a tool to minimize your code, you can
|
||||||
|
still do it manually. But it can be a time consuming process and requires a lot
|
||||||
|
of iteration. At any point in the process, you can check for anything that is
|
||||||
|
unused or totally disconnected (ports, wires, etc) and remove them. If a
|
||||||
|
specific module is causing the problem, try to set that as the top module
|
||||||
|
instead. Any parameters should have their default values changed to match the
|
||||||
|
failing usage.
|
||||||
|
|
||||||
|
As a rule of thumb, try to split things roughly in half at each step; similar to
|
||||||
|
a "binary search". If you have 10 cells (instances of modules) in your top
|
||||||
|
module, and have no idea what is causing the issue, split them into two groups
|
||||||
|
of 5 cells. For each group of cells, try remove them and see if the failure
|
||||||
|
still happens. If the error still occurs with the first group removed, but
|
||||||
|
disappears when the second group is removed, then the first group can be safely
|
||||||
|
removed. If a module has no more instances, remove it entirely. Repeat this
|
||||||
|
for each remaining group of cells until each group only has 1 cell in it and no
|
||||||
|
more cells can be removed without making the error disappear. You can also
|
||||||
|
repeat this for each module still in your design.
|
||||||
|
|
||||||
|
After minimizing the number of cells, do the same for the process blocks in your
|
||||||
|
top module. And again for any generate blocks and combinational blocks.
|
||||||
|
Remember to check for any ports or signals which are no longer used and remove
|
||||||
|
those too. Any signals which are written but never read can also be removed.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
Depending on where the design is failing, there are some commands which may
|
||||||
|
help in identifying unused objects in the design. `hierarchy` will identify
|
||||||
|
which modules are used and which are not, but check for ``$paramod`` modules
|
||||||
|
before removing unused ones. ``debug clean`` will list all unused wires in
|
||||||
|
each module, as well as unused cells which were automatically generated
|
||||||
|
(giving the line number of the source that generated them). Adding the
|
||||||
|
``-purge`` flag will also include named wires that would normally be ignored
|
||||||
|
by `clean`. Though when there are large numbers of unused wires it is often
|
||||||
|
easier to just delete sections of the code and see what happens.
|
||||||
|
|
||||||
|
Next, try to remove or reduce assignments (``a = b``) and operations (``a +
|
||||||
|
b``). A good place to start is by checking for any wires/registers which are
|
||||||
|
read but never written. Try removing the signal declaration and replacing
|
||||||
|
references to it with ``'0`` or ``'x``. Do this with any constants too. Try to
|
||||||
|
replace strings with numeric values, and wide signals with smaller ones, then
|
||||||
|
see if the error persists.
|
||||||
|
|
||||||
|
Check if there are any operations that you can simplify, like replacing ``a &
|
||||||
|
'0`` with ``'0``. If you have enable or reset logic, try removing it and see if
|
||||||
|
the error still occurs. Try reducing ``if .. else`` and ``case`` blocks to a
|
||||||
|
single case. Even if that doesn't work, you may still be able to remove some
|
||||||
|
paths; start with cases that appear to be unreachable and go from there.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
When sharing code on the `Yosys GitHub`_, please try to keep things in
|
||||||
|
English. Declarations and strings should stick to the letters a-z and
|
||||||
|
numbers 0-9, unless the error is arising because of the names/characters
|
||||||
|
used.
|
||||||
|
|
||||||
|
|
||||||
|
Identifying issues
|
||||||
|
------------------
|
||||||
|
|
||||||
|
When identifying issues, it is quite useful to understand the conditions under
|
||||||
|
which the issue is occurring. While there are occasionally bugs that affect a
|
||||||
|
significant number of designs, Yosys changes are tested on a variety of designs
|
||||||
|
and operating systems which typically catch any such issues before they make it
|
||||||
|
into the main branch. So what is is it about your situation that makes it
|
||||||
|
unusual?
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
If you have access to a different platform you could also check if your issue
|
||||||
|
is reproducible there. Some issues may be specific to the platform or build
|
||||||
|
of Yosys.
|
||||||
|
|
||||||
|
Try to match the minimized design back to its original context. Could you
|
||||||
|
achieve the same thing a different way, and if so, does this other method have
|
||||||
|
the same issue? Try to change the design in small ways and see what happens;
|
||||||
|
while `bugpoint` can reduce and simplify a design, it doesn't *change* much.
|
||||||
|
What happens if you change operators, for example a left shift (or `$shl`) to a
|
||||||
|
right shift (or `$shr`)? Try to see if the issue is tied to specific
|
||||||
|
parameters, widths, or values.
|
||||||
|
|
||||||
|
Search `the existing issues`_ and see if someone has already made a bug report.
|
||||||
|
This is where changing the design and finding the limits of what causes the
|
||||||
|
failure really comes in handy. If you're more familiar with how the problem can
|
||||||
|
arise, you may be able to find a related issue more easily. If an issue already
|
||||||
|
exists for one case of the problem but you've found other cases, you can comment
|
||||||
|
on the issue and help get it solved. If there are no existing or related issues
|
||||||
|
already, then check out the steps for
|
||||||
|
:ref:`yosys_internals/extending_yosys/contributing:reporting bugs`.
|
||||||
|
|
||||||
|
.. _the existing issues: https://github.com/YosysHQ/yosys/issues
|
||||||
|
|
||||||
|
.. warning::
|
||||||
|
|
||||||
|
If you are using a fuzzer to find bugs, follow the instructions for
|
||||||
|
:doc:`/yosys_internals/extending_yosys/advanced_bugpoint`. **Do not** open
|
||||||
|
more than one fuzzer generated issue at a time if you can not identify the
|
||||||
|
root cause. If you are found to be doing this, your issues may be closed
|
||||||
|
without further investigation.
|
|
@ -15,3 +15,5 @@ ways Yosys can interact with designs for a deeper investigation.
|
||||||
|
|
||||||
synthesis/index
|
synthesis/index
|
||||||
more_scripting/index
|
more_scripting/index
|
||||||
|
bugpoint
|
||||||
|
verilog
|
||||||
|
|
|
@ -311,8 +311,8 @@ cells, as the net-names are usually suppressed in the circuit diagram if they
|
||||||
are auto-generated. Note that the output is in the RTLIL representation,
|
are auto-generated. Note that the output is in the RTLIL representation,
|
||||||
described in :doc:`/yosys_internals/formats/rtlil_rep`.
|
described in :doc:`/yosys_internals/formats/rtlil_rep`.
|
||||||
|
|
||||||
Interactive Design Investigation
|
Design Investigation
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
Yosys can also be used to investigate designs (or netlists created from other
|
Yosys can also be used to investigate designs (or netlists created from other
|
||||||
tools).
|
tools).
|
||||||
|
|
|
@ -1,11 +1,101 @@
|
||||||
Loading a design
|
Loading a design
|
||||||
~~~~~~~~~~~~~~~~
|
----------------
|
||||||
|
|
||||||
keyword: Frontends
|
.. _input files:
|
||||||
|
|
||||||
|
Input files on the command line
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
- guesses frontend based on file extension
|
||||||
|
|
||||||
|
+ ``.v`` -> ``read -vlog2k``
|
||||||
|
+ ``.sv`` -> ``read -sv``
|
||||||
|
+ ``.vhd`` and ``.vhdl`` -> ``read -vhdl``
|
||||||
|
+ ``.blif`` and ``.eblif`` -> `read_blif`
|
||||||
|
+ ``.json`` -> `read_json`
|
||||||
|
+ ``.il`` -> `read_rtlil` (direct textual representation of Yosys internal
|
||||||
|
state)
|
||||||
|
|
||||||
|
- command line also supports
|
||||||
|
|
||||||
|
+ ``.ys`` -> `script`
|
||||||
|
+ ``.tcl`` -> `tcl`
|
||||||
|
+ ``-`` -> reads stdin and treats it as a script
|
||||||
|
|
||||||
|
The `read` command
|
||||||
|
~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
- standard method of loading designs
|
||||||
|
- also for defining macros and include directories
|
||||||
|
- uses `verific` command if available
|
||||||
|
|
||||||
|
+ ``-verific`` and ``-noverific`` options to enforce with/without Verific
|
||||||
|
+ check ``help read`` for more about the options available and the filetypes
|
||||||
|
supported
|
||||||
|
+ elaborate designs with ``verific -import [options] <top>`` (or use
|
||||||
|
`hierarchy`)
|
||||||
|
|
||||||
|
- fallback to `read_verilog` with ``-defer`` option
|
||||||
|
|
||||||
|
+ does not compile design until `hierarchy` command as discussed in
|
||||||
|
:doc:`/getting_started/example_synth`
|
||||||
|
+ more similar to `verific` behaviour
|
||||||
|
|
||||||
|
- ``read -define`` et al mapped to `verific` or `verilog_defines`
|
||||||
|
- similarly, ``read -incdir`` et al mapped to `verific` or `verilog_defaults`
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
The Verific frontend for Yosys, which provides the :cmd:ref:`verific`
|
||||||
|
command, requires Yosys to be built with Verific. For full functionality,
|
||||||
|
custom modifications to the Verific source code from YosysHQ are required,
|
||||||
|
but limited useability can be achieved with some stock Verific builds. Check
|
||||||
|
:doc:`/yosys_internals/extending_yosys/build_verific` for more.
|
||||||
|
|
||||||
|
.. _Frontend:
|
||||||
|
|
||||||
|
Yosys frontends
|
||||||
|
~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
- typically start with ``read_``
|
||||||
|
- built-in support for heredocs
|
||||||
|
|
||||||
|
+ in-line code with ``<<EOT``
|
||||||
|
+ can use any eot marker, but EOT (End-of-Transmission) and EOF
|
||||||
|
(End-of-File) are most common
|
||||||
|
|
||||||
|
- built-in support for reading multiple files in the same command
|
||||||
|
|
||||||
|
+ executed as multiple successive calls to the frontend
|
||||||
|
|
||||||
|
- compatible with ``-f`` command line option, e.g. ``yosys -f verilog
|
||||||
|
design.txt`` will use the `read_verilog` frontend with the input file
|
||||||
|
``design.txt``
|
||||||
|
|
||||||
|
- `verific` and `read` commands are technically not 'Frontends', but their
|
||||||
|
behaviour is kept in sync
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
'Frontend' here means that the command is implemented as a sub-class of
|
||||||
|
``RTLIL::Frontend``, as opposed to the usual ``RTLIL::Pass``.
|
||||||
|
|
||||||
|
.. todo:: link note to as-yet non-existent section on ``RTLIL::Pass`` under
|
||||||
|
:doc:`/yosys_internals/extending_yosys/index`
|
||||||
|
|
||||||
|
The `read_verilog` command
|
||||||
|
""""""""""""""""""""""""""
|
||||||
|
|
||||||
- :doc:`/cmd/read_verilog`
|
- :doc:`/cmd/read_verilog`
|
||||||
|
- supports most of Verilog-2005
|
||||||
|
- limited support for SystemVerilog
|
||||||
|
- some non-standard features/extensions for enabling formal verification
|
||||||
|
- please do not rely on `read_verilog` for syntax checking
|
||||||
|
|
||||||
.. todo:: include ``read_verilog <<EOF``, also other methods of loading designs
|
+ recommend using a simulator (for example Icarus Verilog) or linting with
|
||||||
|
another tool (such as verilator) first
|
||||||
|
|
||||||
|
.. todo:: figure out this example code block
|
||||||
|
|
||||||
.. code-block:: yoscrypt
|
.. code-block:: yoscrypt
|
||||||
|
|
||||||
|
@ -24,25 +114,38 @@ keyword: Frontends
|
||||||
read_verilog file6.v
|
read_verilog file6.v
|
||||||
verilog_defaults -pop
|
verilog_defaults -pop
|
||||||
|
|
||||||
.. todo:: more info on other ``read_*`` commands, also is this the first time we
|
Other built-in ``read_*`` commands
|
||||||
mention verific?
|
""""""""""""""""""""""""""""""""""
|
||||||
|
|
||||||
.. note::
|
- :doc:`/cmd/read_rtlil`
|
||||||
|
|
||||||
The Verific frontend for Yosys, which provides the :cmd:ref:`verific`
|
|
||||||
command, requires Yosys to be built with Verific. For full functionality,
|
|
||||||
custom modifications to the Verific source code from YosysHQ are required,
|
|
||||||
but limited useability can be achieved with some stock Verific builds. Check
|
|
||||||
:doc:`/yosys_internals/extending_yosys/build_verific` for more.
|
|
||||||
|
|
||||||
Others:
|
|
||||||
|
|
||||||
- :doc:`/cmd/read`
|
|
||||||
- `GHDL plugin`_ for VHDL
|
|
||||||
- :doc:`/cmd/read_rtlil` (direct textual representation of Yosys internal state)
|
|
||||||
- :doc:`/cmd/read_aiger`
|
- :doc:`/cmd/read_aiger`
|
||||||
- :doc:`/cmd/read_blif`
|
- :doc:`/cmd/read_blif`
|
||||||
- :doc:`/cmd/read_json`
|
- :doc:`/cmd/read_json`
|
||||||
- :doc:`/cmd/read_liberty`
|
- :doc:`/cmd/read_liberty`
|
||||||
|
- :doc:`/cmd/read_xaiger2`
|
||||||
|
|
||||||
|
.. TODO:: does `write_file` count?
|
||||||
|
|
||||||
|
Externally maintained plugins
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
- `GHDL plugin`_ for VHDL (check ``help ghdl``)
|
||||||
|
- `yosys-slang plugin`_ for more comprehensive SystemVerilog support (check
|
||||||
|
``help read_slang``)
|
||||||
|
|
||||||
|
+ yosys-slang is implemented as a '`Frontend`_,' with all the built-in support
|
||||||
|
that entails
|
||||||
|
|
||||||
.. _GHDL plugin: https://github.com/ghdl/ghdl-yosys-plugin
|
.. _GHDL plugin: https://github.com/ghdl/ghdl-yosys-plugin
|
||||||
|
.. _yosys-slang plugin: https://github.com/povik/yosys-slang
|
||||||
|
|
||||||
|
- both plugins above are included in `OSS CAD Suite`_
|
||||||
|
|
||||||
|
.. _OSS CAD Suite: https://github.com/YosysHQ/oss-cad-suite-build
|
||||||
|
|
||||||
|
- `Synlig`_, which uses `Surelog`_ to provide SystemVerilog support
|
||||||
|
|
||||||
|
+ also implemented as a '`Frontend`_'
|
||||||
|
|
||||||
|
.. _Synlig: https://github.com/chipsalliance/synlig
|
||||||
|
.. _Surelog: https://github.com/chipsalliance/Surelog
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
Notes on Verilog support in Yosys
|
Notes on Verilog support in Yosys
|
||||||
=================================
|
=================================
|
||||||
|
|
||||||
.. TODO:: how much of this is specific to the read_verilog and should be in :doc:`/yosys_internals/flow/verilog_frontend`?
|
|
||||||
|
|
||||||
Unsupported Verilog-2005 Features
|
Unsupported Verilog-2005 Features
|
||||||
---------------------------------
|
---------------------------------
|
||||||
|
|
|
@ -0,0 +1,271 @@
|
||||||
|
Identifying the root cause of bugs
|
||||||
|
==================================
|
||||||
|
|
||||||
|
This document references Yosys internals and is intended for people interested
|
||||||
|
in solving or investigating Yosys bugs. This also applies if you are using a
|
||||||
|
fuzzing tool; fuzzers have a tendency to find many variations of the same bug,
|
||||||
|
so identifying the root cause is important for avoiding issue spam.
|
||||||
|
|
||||||
|
If you're familiar with C/C++, you might try to have a look at the source code
|
||||||
|
of the command that's failing. Even if you can't fix the problem yourself, it
|
||||||
|
can be very helpful for anyone else investigating if you're able to identify
|
||||||
|
where the issue is arising.
|
||||||
|
|
||||||
|
|
||||||
|
Finding the failing command
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
Using the ``-L`` flag can help here, allowing you to specify a file to log to,
|
||||||
|
such as ``yosys -L out.log -s script.ys``. Most commands will print a header
|
||||||
|
message when they begin; something like ``2.48. Executing HIERARCHY pass
|
||||||
|
(managing design hierarchy).`` The last header message will usually be the
|
||||||
|
failing command. There are some commands which don't print a header message, so
|
||||||
|
you may want to add ``echo on`` to the start of your script. The `echo` command
|
||||||
|
echoes each command executed, along with any arguments given to it. For the
|
||||||
|
`hierarchy` example above this might be ``yosys> hierarchy -check``.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
It may also be helpful to use the `log` command to add messages which you can
|
||||||
|
then search for either in the terminal or the logfile. This can be quite
|
||||||
|
useful if your script contains script-passes, like the
|
||||||
|
:doc:`/using_yosys/synthesis/synth`, which call many sub-commands and you're
|
||||||
|
not sure exactly which script-pass is calling the failing command.
|
||||||
|
|
||||||
|
|
||||||
|
Minimizing scripts
|
||||||
|
------------------
|
||||||
|
|
||||||
|
.. warning::
|
||||||
|
|
||||||
|
This section is intended as **advanced usage**, and generally not necessary
|
||||||
|
for normal bug reports.
|
||||||
|
|
||||||
|
If you're using a command line prompt, such as ``yosys -p 'synth_xilinx' -o
|
||||||
|
design.json design.v``, consider converting it to a script. It's generally much
|
||||||
|
easier to iterate over changes to a script in a file rather than one on the
|
||||||
|
command line, as well as being better for sharing with others.
|
||||||
|
|
||||||
|
.. code-block:: yoscrypt
|
||||||
|
:caption: example script, ``script.ys``, for prompt ``yosys -p 'synth_xilinx' -o design.json design.v``
|
||||||
|
|
||||||
|
read_verilog design.v
|
||||||
|
synth_xilinx
|
||||||
|
write_json design.json
|
||||||
|
|
||||||
|
Next up you want to remove everything *after* the error occurs. If your final
|
||||||
|
command calls sub-commands, replace it with its contents first. In the case of
|
||||||
|
the :doc:`/using_yosys/synthesis/synth`, as well as certain other script-passes,
|
||||||
|
you can use the ``-run`` option to simplify this. For example we can replace
|
||||||
|
``synth -top <top> -lut`` with the :ref:`replace_synth`. The options ``-top
|
||||||
|
<top> -lut`` can be provided to each `synth` step, or to just the step(s) where
|
||||||
|
it is relevant, as done here.
|
||||||
|
|
||||||
|
.. code-block:: yoscrypt
|
||||||
|
:caption: example replacement script for `synth` command
|
||||||
|
:name: replace_synth
|
||||||
|
|
||||||
|
synth -top <top> -run :coarse
|
||||||
|
synth -lut -run coarse:fine
|
||||||
|
synth -lut -run fine:check
|
||||||
|
synth -run check:
|
||||||
|
|
||||||
|
Say we ran :ref:`replace_synth` and were able to remove the ``synth -run
|
||||||
|
check:`` and still got our error, then we check the log and we see the last
|
||||||
|
thing before the error was ``7.2. Executing MEMORY_MAP pass (converting memories
|
||||||
|
to logic and flip-flops)``. By checking the output of ``yosys -h synth`` (or the
|
||||||
|
`synth` help page) we can see that the `memory_map` pass is called in the
|
||||||
|
``fine`` step. We can then update our script to the following:
|
||||||
|
|
||||||
|
.. code-block:: yoscrypt
|
||||||
|
:caption: example replacement script for `synth` when `memory_map` is failing
|
||||||
|
|
||||||
|
synth -top <top> -run :fine
|
||||||
|
opt -fast -full
|
||||||
|
memory_map
|
||||||
|
|
||||||
|
By giving `synth` the option ``-run :fine``, we are telling it to run from the
|
||||||
|
beginning of the script until the ``fine`` step, where we then give it the exact
|
||||||
|
commands to run. There are some cases where the commands given in the help
|
||||||
|
output are not an exact match for what is being run, but are instead a
|
||||||
|
simplification. If you find that replacing the script-pass with its contents
|
||||||
|
causes the error to disappear, or change, try calling the script-pass with
|
||||||
|
``echo on`` to see exactly what commands are being called and what options are
|
||||||
|
used.
|
||||||
|
|
||||||
|
.. warning::
|
||||||
|
|
||||||
|
Before continuing further, *back up your code*. The following steps can
|
||||||
|
remove context and lead to over-minimizing scripts, hiding underlying issues.
|
||||||
|
Check out :ref:`yosys_internals/extending_yosys/advanced_bugpoint:Why
|
||||||
|
context matters` to learn more.
|
||||||
|
|
||||||
|
When a problem is occurring many steps into a script, minimizing the design at
|
||||||
|
the start of the script isn't always enough to identify the cause of the issue.
|
||||||
|
Each extra step of the script can lead to larger sections of the input design
|
||||||
|
being needed for the specific problem to be preserved until it causes a crash.
|
||||||
|
So to find the smallest possible reproducer it can sometimes be helpful to
|
||||||
|
remove commands prior to the failure point.
|
||||||
|
|
||||||
|
The simplest way to do this is by writing out the design, resetting the current
|
||||||
|
state, and reading back the design:
|
||||||
|
|
||||||
|
.. code-block:: yoscrypt
|
||||||
|
|
||||||
|
write_rtlil <design.il>; design -reset; read_rtlil <design.il>;
|
||||||
|
|
||||||
|
In most cases, this can be inserted immediately before the failing command while
|
||||||
|
still producing the error, allowing you to :ref:`minimize your
|
||||||
|
RTLIL<using_yosys/bugpoint:minimizing rtlil designs with bugpoint>` with the
|
||||||
|
``<design.il>`` output. For our previous example with `memory_map`, if
|
||||||
|
:ref:`map_reset` still gives the same error, then we should now be able to call
|
||||||
|
``yosys design.il -p 'memory_map'`` to reproduce it.
|
||||||
|
|
||||||
|
.. code-block:: yoscrypt
|
||||||
|
:caption: resetting the design immediately before failure
|
||||||
|
:name: map_reset
|
||||||
|
|
||||||
|
synth -top <top> -run :fine
|
||||||
|
opt -fast -full
|
||||||
|
write_rtlil design.il; design -reset; read_rtlil design.il;
|
||||||
|
memory_map
|
||||||
|
|
||||||
|
If that doesn't give the error (or doesn't give the same error), then you should
|
||||||
|
try to move the write/reset/read earlier in the script until it does. If you
|
||||||
|
have no idea where exactly you should put the reset, the best way is to use a
|
||||||
|
"binary search" type approach, reducing the possible options by half after each
|
||||||
|
attempt.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
By default, `write_rtlil` doesn't include platform specific IP blocks and
|
||||||
|
other primitive cell models which are typically loaded with a ``read_verilog
|
||||||
|
-lib`` command at the start of the synthesis script. You may have to
|
||||||
|
duplicate these commands *after* the call to ``design -reset``. It is also
|
||||||
|
possible to write out *everything* with ``select =*; write_rtlil -selected
|
||||||
|
<design.il>``.
|
||||||
|
|
||||||
|
As an example, your script has 16 commands in it before failing on the 17th. If
|
||||||
|
resetting immediately before the 17th doesn't reproduce the error, try between
|
||||||
|
the 8th and 9th (8 is half of the total 16). If that produces the error then
|
||||||
|
you can remove everything before the `read_rtlil` and try reset again in the
|
||||||
|
middle of what's left, making sure to use a different name for the output file
|
||||||
|
so that you don't overwrite what you've already got. If the error isn't
|
||||||
|
produced then you need to go earlier still, so in this case you would do between
|
||||||
|
the 4th and 5th (4 is half of the previous 8). Repeat this until you can't
|
||||||
|
reduce the remaining commands any further.
|
||||||
|
|
||||||
|
A more conservative, but more involved, method is to remove or comment out
|
||||||
|
commands prior to the failing command. Each command, or group of commands, can
|
||||||
|
be disabled one at a time while checking if the error still occurs, eventually
|
||||||
|
giving the smallest subset of commands needed to take the original input through
|
||||||
|
to the error. The difficulty with this method is that depending on your design,
|
||||||
|
some commands may be necessary even if they aren't needed to reproduce the
|
||||||
|
error. For example, if your design includes ``process`` blocks, many commands
|
||||||
|
will fail unless you run the `proc` command. While this approach can do a
|
||||||
|
better job of maintaining context, it is often easier to *recover* the context
|
||||||
|
after the design has been minimized for producing the error. For more on
|
||||||
|
recovering context, checkout
|
||||||
|
:ref:`yosys_internals/extending_yosys/advanced_bugpoint:Why context matters`.
|
||||||
|
|
||||||
|
|
||||||
|
Why context matters
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
Sometimes when a command is raising an error, you're seeing a symptom rather
|
||||||
|
than the underlying issue. It's possible that an earlier command may be putting
|
||||||
|
the design in an invalid state, which isn't picked up until the error is raised.
|
||||||
|
This is particularly true for the pre-packaged
|
||||||
|
:doc:`/using_yosys/synthesis/synth`, which rely on a combination of generic and
|
||||||
|
architecture specific passes. As new features are added to Yosys and more
|
||||||
|
designs are supported, the types of cells output by a pass can grow and change;
|
||||||
|
and sometimes this leads to a mismatch in what a pass is intended to handle.
|
||||||
|
|
||||||
|
If you minimized your script, and removed commands prior to the failure to get a
|
||||||
|
smaller reproducer, try to work backwards and find which commands may have
|
||||||
|
contributed to the design failing. From the minimized design you should have
|
||||||
|
some understanding of the cell or cells which are producing the error; but where
|
||||||
|
did those cells come from? The name and/or type of the cell can often point you
|
||||||
|
in the right direction:
|
||||||
|
|
||||||
|
.. code-block::
|
||||||
|
|
||||||
|
# internal cell types start with a $
|
||||||
|
# lowercase for word-level, uppercase for bit-level
|
||||||
|
$and
|
||||||
|
$_AND_
|
||||||
|
|
||||||
|
# cell types with $__ are typically intermediate cells used in techmapping
|
||||||
|
$__MUL16X16
|
||||||
|
|
||||||
|
# cell types without a $ are either user-defined or architecture specific
|
||||||
|
my_module
|
||||||
|
SB_MAC16
|
||||||
|
|
||||||
|
# object names might give you the name of the pass that created them
|
||||||
|
$procdff$1204
|
||||||
|
$memory\rom$rdmux[0][0][0]$a$1550
|
||||||
|
|
||||||
|
# or even the line number in the Yosys source
|
||||||
|
$auto$muxcover.cc:557:implement_best_cover$2152
|
||||||
|
$auto$alumacc.cc:495:replace_alu$1209
|
||||||
|
|
||||||
|
Try running the unminimized script and search the log for the names of the
|
||||||
|
objects in your minimized design. In the case of cells you can also search for
|
||||||
|
the type of the cell. Remember that calling `stat` will list all the types of
|
||||||
|
cells currently used in the design, and ``select -list =*`` will list the names
|
||||||
|
of of all the current objects. You can add these commands to your script, or
|
||||||
|
use an interactive terminal to run each command individually. Adding them to
|
||||||
|
the script can be more repeatable, but if it takes a long time to run to the
|
||||||
|
point you're interested in then an interactive shell session can give you more
|
||||||
|
flexibility once you reach that point. You can also add a call to the `shell`
|
||||||
|
command at any point in a script to start an interactive session at a given
|
||||||
|
point; allowing you to script any preparation steps, then come back once it's
|
||||||
|
done.
|
||||||
|
|
||||||
|
The ``--dump-design`` option
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Yosys provides the ``--dump-design`` option (or ``-P`` for short) for dumping
|
||||||
|
the design at specific steps of the script based on the log header. If the last
|
||||||
|
step before an error is ``7.2. Executing MEMORY_MAP pass (converting memories to
|
||||||
|
logic and flip-flops)``, then calling Yosys with ``--dump-design 7.2:bad.il``
|
||||||
|
will save the design *before* this command runs, in the file ``bad.il``.
|
||||||
|
|
||||||
|
It is also possible to use this option multiple times, e.g. ``-P2:hierarchy.il
|
||||||
|
-P7 -P7.2:bad.il``, to get multiple dumps in the same run. This can make it
|
||||||
|
easier to follow the design through each step to find where certain cells or
|
||||||
|
connections are coming from. ``--dump-design ALL`` is also allowed, writing out
|
||||||
|
the design at each log header.
|
||||||
|
|
||||||
|
A worked example
|
||||||
|
~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Say you did all the minimization and found that an error in `synth_xilinx`
|
||||||
|
occurs when a call to ``techmap -map +/xilinx/cells_map.v`` with
|
||||||
|
``MIN_MUX_INPUTS`` defined parses a `$_MUX16_` with all inputs set to ``1'x``.
|
||||||
|
You could fix the bug in ``+/xilinx/cells_map.v``, but that might only solve
|
||||||
|
this one case while leaving other problems that haven't been found yet. So you
|
||||||
|
step through the original script, calling `stat` after each step to find when
|
||||||
|
the `$_MUX16_` is added.
|
||||||
|
|
||||||
|
You find that the `$_MUX16_` is introduced by a call to `muxcover`, but all the
|
||||||
|
inputs are defined, so calling `techmap` now works as expected. From running
|
||||||
|
`bugpoint` with the failing techmap you know that the cell with index ``2297``
|
||||||
|
will fail, so you call ``select top/*$2297`` to limit to just that cell. This
|
||||||
|
can then be saved with ``design -save pre_bug`` or ``write_rtlil -selected
|
||||||
|
pre_bug.il``, so that you don't have to re-run all the earlier steps to get back
|
||||||
|
here.
|
||||||
|
|
||||||
|
Next you step through the remaining commands and call `dump` after each to find
|
||||||
|
when the inputs are disconnected. You find that ``opt -full`` has optimized
|
||||||
|
away portions of the circuit, leading to `opt_expr` setting the undriven mux
|
||||||
|
inputs to ``x``, but failing to remove the now unnecessary `$_MUX16_`. Now
|
||||||
|
you've identified a problem in `opt_expr` that affects all of the wide muxes,
|
||||||
|
and could happen in any synthesis flow, not just `synth_xilinx`.
|
||||||
|
|
||||||
|
.. seealso::
|
||||||
|
|
||||||
|
This example is taken from `YosysHQ/yosys#4590
|
||||||
|
<https://github.com/YosysHQ/yosys/issues/4590>`_ and can be reproduced with a
|
||||||
|
version of Yosys between 0.45 and 0.51.
|
|
@ -7,7 +7,7 @@ Contributing to Yosys
|
||||||
|CONTRIBUTING|_ file.
|
|CONTRIBUTING|_ file.
|
||||||
|
|
||||||
.. |CONTRIBUTING| replace:: :file:`CONTRIBUTING.md`
|
.. |CONTRIBUTING| replace:: :file:`CONTRIBUTING.md`
|
||||||
.. _CONTRIBUTING: https://github.com/YosysHQ/yosys/CONTRIBUTING.md
|
.. _CONTRIBUTING: https://github.com/YosysHQ/yosys/blob/main/CONTRIBUTING.md
|
||||||
|
|
||||||
Coding Style
|
Coding Style
|
||||||
------------
|
------------
|
||||||
|
@ -42,3 +42,137 @@ for implicit type casts, always use ``GetSize(foobar)`` instead of
|
||||||
``foobar.size()``. (``GetSize()`` is defined in :file:`kernel/yosys.h`)
|
``foobar.size()``. (``GetSize()`` is defined in :file:`kernel/yosys.h`)
|
||||||
|
|
||||||
Use range-based for loops whenever applicable.
|
Use range-based for loops whenever applicable.
|
||||||
|
|
||||||
|
|
||||||
|
Reporting bugs
|
||||||
|
--------------
|
||||||
|
|
||||||
|
- use the `bug report template`_
|
||||||
|
|
||||||
|
.. _bug report template: https://github.com/YosysHQ/yosys/issues/new?template=bug_report.yml
|
||||||
|
|
||||||
|
- short title briefly describing the issue, e.g.
|
||||||
|
|
||||||
|
techmap of wide mux with undefined inputs raises error during synth_xilinx
|
||||||
|
|
||||||
|
+ tells us what's happening ("raises error")
|
||||||
|
+ gives the command affected (`techmap`)
|
||||||
|
+ an overview of the input design ("wide mux with undefined inputs")
|
||||||
|
+ and some context where it was found ("during `synth_xilinx`")
|
||||||
|
|
||||||
|
|
||||||
|
Reproduction Steps
|
||||||
|
~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
- ideally a code-block (starting and ending with triple backquotes) containing
|
||||||
|
the minimized design (Verilog or RTLIL), followed by a code-block containing
|
||||||
|
the minimized yosys script OR a command line call to yosys with
|
||||||
|
code-formatting (starting and ending with single backquotes)
|
||||||
|
|
||||||
|
.. code-block:: markdown
|
||||||
|
|
||||||
|
min.v
|
||||||
|
```verilog
|
||||||
|
// minimized Verilog design
|
||||||
|
```
|
||||||
|
|
||||||
|
min.ys
|
||||||
|
```
|
||||||
|
read_verilog min.v
|
||||||
|
# minimum sequence of commands to reproduce error
|
||||||
|
```
|
||||||
|
|
||||||
|
OR
|
||||||
|
|
||||||
|
`yosys -p ': minimum sequence of commands;' min.v`
|
||||||
|
|
||||||
|
- alternatively can provide a single code-block which includes the minimized
|
||||||
|
design as a "here document" followed by the sequence of commands which
|
||||||
|
reproduce the error
|
||||||
|
|
||||||
|
+ see :doc:`/using_yosys/more_scripting/load_design` for more on heredocs.
|
||||||
|
|
||||||
|
.. code-block:: markdown
|
||||||
|
|
||||||
|
```
|
||||||
|
read_rtlil <<EOF
|
||||||
|
# minimized RTLIL design
|
||||||
|
EOF
|
||||||
|
# minimum sequence of commands
|
||||||
|
```
|
||||||
|
|
||||||
|
- any environment variables or command line options should also be mentioned
|
||||||
|
- if the problem occurs for a range of values/designs, what is that range
|
||||||
|
- if you're using an external tool, such as ``valgrind``, to detect the issue,
|
||||||
|
what version of that tool are you using and what options are you giving it
|
||||||
|
|
||||||
|
.. warning::
|
||||||
|
|
||||||
|
Please try to avoid the use of any external plugins/tools in the reproduction
|
||||||
|
steps if they are not directly related to the issue being raised. This
|
||||||
|
includes frontend plugins such as GHDL or slang; use `write_rtlil` on the
|
||||||
|
minimized design instead. This also includes tools which provide a wrapper
|
||||||
|
around Yosys such as OpenLane; you should instead minimize your input and
|
||||||
|
reproduction steps to just the Yosys part.
|
||||||
|
|
||||||
|
"Expected Behaviour"
|
||||||
|
~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
- if you have a similar design/script that doesn't give the error, include it
|
||||||
|
here as a reference
|
||||||
|
- if the bug is that an error *should* be raised but isn't, are there any other
|
||||||
|
commands with similar error messages
|
||||||
|
|
||||||
|
|
||||||
|
"Actual Behaviour"
|
||||||
|
~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
- any error messages go here
|
||||||
|
- any details relevant to the crash that were found with ``--trace`` or
|
||||||
|
``--debug`` flags
|
||||||
|
- if you identified the point of failure in the source code, you could mention
|
||||||
|
it here, or as a comment below
|
||||||
|
|
||||||
|
+ if possible, use a permalink to the source on GitHub
|
||||||
|
+ you can browse the source repository for a certain commit with the failure
|
||||||
|
and open the source file, select the relevant lines (click on the line
|
||||||
|
number for the first relevant line, then while holding shift click on the
|
||||||
|
line number for the last relevant line), click on the ``...`` that appears
|
||||||
|
and select "Copy permalink"
|
||||||
|
+ should look something like
|
||||||
|
``https://github.com/YosysHQ/yosys/blob/<commit_hash>/path/to/file#L139-L147``
|
||||||
|
+ clicking on "Preview" should reveal a code block containing the lines of
|
||||||
|
source specified, with a link to the source file at the given commit
|
||||||
|
|
||||||
|
|
||||||
|
Additional details
|
||||||
|
~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
- once you have created the issue, any additional details can be added as a
|
||||||
|
comment on that issue
|
||||||
|
- could include any additional context as to what you were doing when you first
|
||||||
|
encountered the bug
|
||||||
|
- was this issue discovered through the use of a fuzzer
|
||||||
|
- if you've minimized the script, consider including the `bugpoint` script you
|
||||||
|
used, or the original script, e.g.
|
||||||
|
|
||||||
|
.. code-block:: markdown
|
||||||
|
|
||||||
|
Minimized with
|
||||||
|
```
|
||||||
|
read_verilog design.v
|
||||||
|
# original sequence of commands prior to error
|
||||||
|
bugpoint -script <failure.ys> -grep "<string>"
|
||||||
|
write_rtlil min.il
|
||||||
|
```
|
||||||
|
|
||||||
|
OR
|
||||||
|
|
||||||
|
Minimized from
|
||||||
|
`yosys -p ': original sequence of commands to produce error;' design.v`
|
||||||
|
|
||||||
|
- if you're able to, it may also help to share the original un-minimized design
|
||||||
|
|
||||||
|
+ if the design is too big for a comment, consider turning it into a `Gist`_
|
||||||
|
|
||||||
|
.. _Gist: https://gist.github.com/
|
||||||
|
|
|
@ -11,6 +11,7 @@ of interest for developers looking to customise Yosys builds.
|
||||||
extensions
|
extensions
|
||||||
build_verific
|
build_verific
|
||||||
functional_ir
|
functional_ir
|
||||||
|
advanced_bugpoint
|
||||||
contributing
|
contributing
|
||||||
test_suites
|
test_suites
|
||||||
|
|
||||||
|
|
|
@ -38,5 +38,4 @@ as reference to implement a similar system in any language.
|
||||||
formats/index
|
formats/index
|
||||||
extending_yosys/index
|
extending_yosys/index
|
||||||
techmap
|
techmap
|
||||||
verilog
|
|
||||||
hashing
|
hashing
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue