mirror of
https://github.com/YosysHQ/yosys
synced 2025-04-29 11:55:52 +00:00
How to guide for using bugpoint, minimizing yosys scripts, and minimizing verilog code. AKA how to MVCE.
210 lines
8 KiB
ReStructuredText
210 lines
8 KiB
ReStructuredText
Minimizing failing (or bugged) designs
|
|
======================================
|
|
|
|
- how to guide
|
|
- assumes knowledge and familiarity with Yosys
|
|
- something is wrong with your design OR something is wrong with Yosys
|
|
|
|
+ how to work out which
|
|
|
|
- *read* the error message
|
|
- is it a Yosys error? (starts with ERROR:)
|
|
|
|
+ does it give you a line number from your design
|
|
|
|
- is it a runtime error, e.g. SEGFAULT
|
|
- are you using the latest release of Yosys
|
|
|
|
+ has your problem already been fixed
|
|
|
|
- is your input design valid?
|
|
|
|
+ if you're using Verilog, try load it with `iverilog`_ or `verilator`_
|
|
|
|
.. _iverilog: https://steveicarus.github.io/iverilog/
|
|
.. _verilator: https://www.veripool.org/verilator/
|
|
|
|
- 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
|
|
|
|
|
|
.. _minimize your RTLIL:
|
|
|
|
Minimizing RTLIL designs with bugpoint
|
|
--------------------------------------
|
|
|
|
- `bugpoint`, only usable on platforms where Yosys can spawn executables
|
|
|
|
+ unavailable on emscripten and wasm
|
|
+ can test by running e.g. ``yosys -qqp '!echo test'``
|
|
|
|
* the ``-qq`` prevents Yosys from outputting non-error messages to the
|
|
console, so this will either display the text ``test``, or an error
|
|
message about ``Shell`` being unavailable
|
|
* be careful about using ``!`` in bash as it will perform a history
|
|
substitution if not escaped with single quotes (double quotes will not
|
|
escape it)
|
|
* ``!`` does not need to be escaped in *Yosys* scripts or when called within
|
|
the interactive Yosys shell, *only* when called on the command line with
|
|
``-p``
|
|
|
|
- single command (``yosys -p "<command>" design.il``)
|
|
- *or* multiple commands in a separate script file
|
|
|
|
+ script shouldn't load the design
|
|
+ ``yosys -s <failure.ys> design.il``
|
|
+ `minimize your script`_ to reduce the time needed by `bugpoint`
|
|
|
|
- doesn't require design to be in RTLIL format
|
|
|
|
+ can e.g. ``read_verilog <design.v>; prep -top <top>;`` before `bugpoint`
|
|
+ this method may be more useful if you are trying to find a bug in your
|
|
design rather than Yosys
|
|
+ but, `bugpoint` itself calls the command/script with an RTLIL dump, so if it
|
|
isn't reproducible from RTLIL then `bugpoint` won't work
|
|
|
|
- follow `bugpoint` instructions
|
|
|
|
+ output design after `bugpoint` with `write_rtlil`
|
|
+ use ``-grep "<string>"`` to only accept a minimized design that crashes
|
|
with the ``<string>`` in the log file
|
|
+ ``-modules``, ``-ports``, ``-cells``, and ``-processes`` will enable those
|
|
parts of the design to be removed
|
|
|
|
* use the ``bugpoint_keep`` attribute on objects you don't want to be
|
|
removed, usually because you already know they are related to the failure
|
|
* ``(* bugpoint_keep *)`` in Verilog, ``attribute \bugpoint_keep 1`` in
|
|
RTLIL, or ``setattr -set bugpoint_keep 1 [selection]`` from script
|
|
|
|
+ ``-runner "<prefix>"`` can allow running ``yosys`` wrapped by another
|
|
command
|
|
+ can also use `setenv` before `bugpoint` to set environment variables for
|
|
the spawned processes (e.g. ``setenv UBSAN_OPTIONS halt_on_error=1``)
|
|
|
|
.. note::
|
|
|
|
Using `setenv` in this way **does not affect the current process**. Only
|
|
child processes will respect the assigned ``halt_on_error``.
|
|
|
|
|
|
.. _minimize your script:
|
|
|
|
Minimizing scripts
|
|
------------------
|
|
|
|
- reminder to back up original code before modifying it
|
|
- if you're using command line, convert it to a script
|
|
- if you're using one of the :doc:`/using_yosys/synthesis/synth`, replace it
|
|
with its contents
|
|
- remove everything *after* the error occurs
|
|
- can use `log` command to print messages to help locate the failure point
|
|
- `echo` can also help (``echo on``)
|
|
- try ``write_rtlil <design.il>; design -reset; read_rtlil <design.il>;`` before
|
|
the failure point
|
|
|
|
+ ideally you now have a single command that is producing an error and can
|
|
`minimize your RTLIL`_ with the ``<design.il>`` output
|
|
+ if not, try to move the write/reset/read earlier in the script until you can
|
|
reproduce the error
|
|
+ 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
|
|
|
|
* for 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
|
|
|
|
.. TODO:: is it possible to dump scratchpad?
|
|
|
|
is there anything else in the yosys/design state that doesn't get included in
|
|
`write_rtlil`?
|
|
|
|
- you can also try to remove or comment out commands prior to the failing
|
|
command; just because the first and last commands are needed doesn't mean that
|
|
every command between them is
|
|
|
|
|
|
Minimizing Verilog designs
|
|
--------------------------
|
|
|
|
- manual process
|
|
- made easier if the error message is able to identify the source line or name
|
|
of the object
|
|
- reminder to back up original code before modifying it
|
|
- if a specific module is causing the problem, try to set that as the top
|
|
module, you can then remove
|
|
|
|
+ if the problem is parameter specific you may be able to change the default
|
|
parameters so that they match the problematic configuration
|
|
|
|
- as with `minimize your script`_, if you have no idea what is or is not
|
|
relevant, try to follow a "binary search" type approach where you remove (or
|
|
comment out) roughly half of what's left at a time
|
|
- focusing on one type of object at a time simplifies the process, removing as
|
|
many as you can until the error disappears if any of the remaining objects are
|
|
removed
|
|
- periodically check if anything is totally disconnected (ports, wires, etc), if
|
|
it is then it can be removed too
|
|
- start by removing cells (instances of modules)
|
|
|
|
+ if a module has no more instances, remove it entirely
|
|
|
|
- then processes
|
|
- try to remove or reduce assignments and operations
|
|
|
|
+ are there any wires/registers which get read but never written?
|
|
|
|
* try removing the signal declaration and replacing references to it with
|
|
``'0`` or ``'x``
|
|
* try this with constants too
|
|
|
|
+ can you replace strings with numeric values?
|
|
+ are you able to simplify any operations? like replacing ``a & '0`` with
|
|
``'0``
|
|
+ if you have enable or reset logic, does the error still happen without that?
|
|
+ can you reduce an ``if .. else`` to a single case?
|
|
|
|
- if you're planning to share the minimized code:
|
|
|
|
+ make sure there is no sensitive or proprietary data in the design
|
|
+ instead of a long string of numbers and letters that had some meaning (or
|
|
were randomly or sequentially generated), can you give it a single character
|
|
name like ``a`` or ``x``
|
|
+ please try to keep things in English, using the letters a-z and numbers 0-9
|
|
(unless the error is arising because of the names used)
|
|
|
|
|
|
Creating an issue on GitHub
|
|
---------------------------
|
|
|
|
- "Reproduction Steps" is ideally a single code-block (starting and ending with
|
|
triple backquotes), containing the minimized yosys script file, which includes
|
|
the minimized design as a "here document" followed by the sequence of commands
|
|
which reproduce the error
|
|
|
|
.. TODO:: https://tldp.org/LDP/abs/html/here-docs.html
|
|
|
|
Actually fill out :doc:`/using_yosys/more_scripting/load_design` with here
|
|
docs info and then link to it from here
|
|
|
|
.. code-block:: markdown
|
|
|
|
```
|
|
read_rtlil <<EOF
|
|
# minimized RTLIL design
|
|
EOF
|
|
# minimum sequence of commands to reproduce error
|
|
```
|
|
|
|
- any environment variables or command line options should also be mentioned in
|
|
the "Reproduction Steps"
|