3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2025-06-13 01:16:16 +00:00

advanced_bugpoint.rst: Paragraphing

This commit is contained in:
Krystine Sherwin 2025-05-17 11:49:41 +12:00
parent 1b3566af42
commit a9d4579765
No known key found for this signature in database

View file

@ -6,27 +6,40 @@ 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, 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. so identifying the root cause is important for avoiding issue spam.
- if the failing command was part of a larger script, such as one of the If you're familiar with C/C++, you might try to have a look at the source code
:doc:`/using_yosys/synthesis/synth`, you could try to follow the design of the command that's failing. Even if you can't fix the problem yourself, it
through the script can be very helpful for anyone else investigating if you're able to identify
where the issue is arising.
+ sometimes when a command is raising an error, you're seeing a symptom rather
than the underlying issue
+ an earlier command may be putting the design in an invalid state which isn't
picked up until the error is raised
+ check out :ref:`yosys_internals/extending_yosys/advanced_bugpoint:why context matters`
- if you're familiar with C/C++ you might try to have a look at the source Finding the failing command
code of the command that's failing ---------------------------
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.
+ 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 exactly the
issue is
Minimizing scripts Minimizing scripts
------------------ ------------------
.. TODO:: disclaimer this is intended as advanced usage, and generally not necessary for bug reports .. 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 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 design.json design.v``, consider converting it to a script. It's generally much
@ -40,28 +53,10 @@ command line, as well as being better for sharing with others.
synth_xilinx synth_xilinx
write_json design.json write_json design.json
Next up you want to remove everything *after* the error occurs. Using the Next up you want to remove everything *after* the error occurs. If your final
``-L`` flag can help here, allowing you to specify a file to log to, such as command calls sub-commands, replace it with its contents first. In the case of
``yosys -L out.log -s script.ys``. Most commands will print a header message the :doc:`/using_yosys/synthesis/synth`, as well as certain other script-passes,
when they begin; something like ``2.48. Executing HIERARCHY pass (managing you can use the ``-run`` option to simplify this. For example we can replace
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.
If your final command calls sub-commands, replace it with its contents and
repeat the previous step. 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 ``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 <top> -lut`` can be provided to each `synth` step, or to just the step(s) where
it is relevant, as done here. it is relevant, as done here.
@ -177,32 +172,85 @@ recovering context, checkout
Why context matters Why context matters
------------------- -------------------
- if you did minimized your script, and removed commands prior to the failure Sometimes when a command is raising an error, you're seeing a symptom rather
to get a smaller design, try to work backwards and find which commands may than the underlying issue. It's possible that an earlier command may be putting
have contributed to the design failing the design in an invalid state, which isn't picked up until the error is raised.
- especially important when the bug is happening inside of a ``synth_*`` script This is particularly true for the pre-packaged
- example (#4590) :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.
A worked example
~~~~~~~~~~~~~~~~
+ say you did all the minimization and found that the error occurs when a call Say you did all the minimization and found that an error in `synth_xilinx`
to ``techmap -map +/xilinx/cells_map.v`` with ``MIN_MUX_INPUTS`` defined occurs when a call to ``techmap -map +/xilinx/cells_map.v`` with
parses a `$_MUX16_` with all inputs set to ``1'x`` ``MIN_MUX_INPUTS`` defined parses a `$_MUX16_` with all inputs set to ``1'x``.
+ step through the original script, calling `stat` after each step to find You could fix the bug in ``+/xilinx/cells_map.v``, but that might only solve
when the `$_MUX16_` is added this one case while leaving other problems that haven't been found yet. So you
+ find that the `$_MUX16_` is introduced by a call to `muxcover`, but all the step through the original script, calling `stat` after each step to find when
inputs are defined, so calling `techmap` now works as expected the `$_MUX16_` is added.
* and from running `bugpoint` with the failing techmap you know that the You find that the `$_MUX16_` is introduced by a call to `muxcover`, but all the
cell with index ``2297`` will fail, so you can now call ``select inputs are defined, so calling `techmap` now works as expected. From running
top/*$2297`` to limit to just that cell, and optionally call ``design `bugpoint` with the failing techmap you know that the cell with index ``2297``
-save pre_bug`` or ``write_rtlil -selected pre_bug.il`` to save this state 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 Next you step through the remaining commands and call `dump` after each to find
find when the inputs are disconnected when the inputs are disconnected. You find that ``opt -full`` has optimized
+ find that ``opt -full`` has optimized away portions of the circuit, leading away portions of the circuit, leading to `opt_expr` setting the undriven mux
to `opt_expr` setting the undriven mux inputs to ``x``, but failing to inputs to ``x``, but failing to remove the now unnecessary `$_MUX16_`. Now
remove the now unnecessary `$_MUX16_` 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`.
- in this example, you might've stopped with the minimal reproducer, fixed the .. seealso::
bug in ``+/xilinx/cells_map.v``, and carried on
- but by following the failure back you've managed to identify a problem with This example is taken from `YosysHQ/yosys#4590
`opt_expr` that could be causing other problems either now or in the future <https://github.com/YosysHQ/yosys/issues/4590>`_ and can be reproduced with a
version of Yosys between 0.45 and 0.51.