mirror of
https://github.com/YosysHQ/yosys
synced 2026-02-14 04:41:48 +00:00
377 lines
15 KiB
ReStructuredText
377 lines
15 KiB
ReStructuredText
Contributing to Yosys
|
|
=====================
|
|
|
|
Reporting bugs
|
|
--------------
|
|
|
|
A good bug report includes the following information:
|
|
|
|
|
|
Title
|
|
~~~~~
|
|
|
|
briefly describe the issue, for example:
|
|
|
|
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
|
|
~~~~~~~~~~~~~~~~~~
|
|
|
|
The reproduction steps should be a minimal, complete and verifiable
|
|
example `MVCE`_.
|
|
Providing an MVCE with your bug report drastically increases the likelihood that
|
|
someone will be able to help resolve your issue.
|
|
One way to minimize a design is to use the `bugpoint_` command.
|
|
You can learn more in the `how-to guide for bugpoint_`.
|
|
|
|
The reproduction steps are 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, you 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
|
|
```
|
|
|
|
Don't forget to mention:
|
|
|
|
- any important environment variables or command line options
|
|
- 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.
|
|
|
|
.. _MVCE: https://stackoverflow.com/help/minimal-reproducible-example
|
|
.. _bugpoint: https://yosys.readthedocs.io/en/latest/cmd/bugpoint.html
|
|
.. _how-to guide for bugpoint: https://yosys.readthedocs.io/en/latest/using_yosys/bugpoint.html
|
|
|
|
Expected Behaviour
|
|
~~~~~~~~~~~~~~~~~~
|
|
|
|
Describe what you'd expect to happen when we follow the reproduction steps
|
|
if the bug was fixed.
|
|
|
|
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,
|
|
note if there are any other commands with similar error messages.
|
|
|
|
|
|
Actual Behaviour
|
|
~~~~~~~~~~~~~~~~
|
|
|
|
Describe what you actually see when you follow the reproduction steps.
|
|
|
|
This can include:
|
|
|
|
* any error messages
|
|
* any details relevant to the crash that were found with ``--trace`` or
|
|
``--debug`` flags
|
|
* the part of the source code that triggers the bug
|
|
|
|
* 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
|
|
~~~~~~~~~~~~~~~~~~
|
|
|
|
Anything else you think might be helpful or relevant when verifying or fixing
|
|
the bug.
|
|
|
|
Once you have created the issue, any additional details can be added as a
|
|
comment on that issue. You can include any additional context as to what you
|
|
were doing when you first encountered the bug.
|
|
|
|
If this issue discovered through the use of a fuzzer, ALWAYS declare that.
|
|
If you've minimized the script, consider including the `bugpoint` script you
|
|
used, or the original script, for example:
|
|
|
|
.. 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 possible, 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/
|
|
|
|
Contributing code
|
|
-----------------
|
|
|
|
Code that matters
|
|
~~~~~~~~~~~~~~~~~
|
|
|
|
If you're adding complex functionality, or modifying core parts of yosys,
|
|
we highly recommend discussing your motivation and approach
|
|
ahead of time on the `Discourse forum`_. Please, be as explicit and concrete
|
|
as possible when explaining the motivation for what you're building.
|
|
Additionally, if you do so on the forum first before you starting hacking
|
|
away at C++, you might solve your problem without writing a single line
|
|
of code!
|
|
|
|
PRs are considered for relevance, priority, and quality
|
|
based on their descriptions first, code second.
|
|
|
|
Before you build or fix something, also search for existing `issues`_.
|
|
|
|
.. _`Discourse forum`: https://yosyshq.discourse.group/
|
|
.. _`issues`: https://github.com/YosysHQ/yosys/issues
|
|
|
|
Making sense
|
|
~~~~~~~~~~~~
|
|
|
|
Given enough effort, the behavior of any code can be figured out to any
|
|
desired extent. However, the author of the code is by far in the best
|
|
position to make this as easy as possible.
|
|
|
|
Yosys is a long-standing project and has accumulated a lot of C-style code
|
|
that's not written to be read, just written to run. We improve this bit
|
|
by bit when opportunities arise, but it is what it is.
|
|
New additions are expected to be a lot cleaner.
|
|
|
|
The purpose and behavior of the code changed should be described clearly.
|
|
Your change should contain exactly what it needs to match that description.
|
|
This means:
|
|
|
|
* nothing more than that - no dead code, no undocumented features
|
|
* nothing missing - if something is partially built, that's fine,
|
|
but you have to make that clear. For example, some passes
|
|
only support some types of cells
|
|
|
|
Here are some software engineering approaches that help:
|
|
|
|
* Use abstraction to model the problem and hide details
|
|
|
|
* Maximize the usage of types (structs over loose variables),
|
|
not necessarily in an object-oriented way
|
|
* Use functions, scopes, type aliases
|
|
|
|
* In new passes, make sure the logic behind how and why it works is actually provided
|
|
in coherent comments, and that variable and type naming is consistent with the terms
|
|
you use in the description.
|
|
* The logic of the implementation should be described in mathematical
|
|
or algorithm theory terms. Correctness, termination, computational complexity.
|
|
Make it clear if you're re-implementing a classic data structure for logic synthesis
|
|
or graph traversal etc.
|
|
|
|
* There's various ways of traversing the design with use-def indices (for getting
|
|
drivers and driven signals) available in Yosys. They have advantages and sometimes
|
|
disadvantages. Prefer not re-implementing these
|
|
* Prefer references over pointers, and smart pointers over raw pointers
|
|
* Aggressively deduplicate code. Within functions, within passes,
|
|
across passes, even against existing code
|
|
* Prefer declaring things ``const``
|
|
* Prefer range-based for loops over C-style
|
|
|
|
Common mistakes
|
|
~~~~~~~~~~~~~~~
|
|
|
|
* Deleting design objects invalidates iterators. Defer deletions or hold a copy
|
|
of the list of pointers to design objects
|
|
* Deleting wires can get sketchy and is intended to be done solely by
|
|
the ``opt_clean`` pass so just don't do it
|
|
* Iterating over an entire design and checking if things are selected is more
|
|
inefficient than using the ``selected_*`` methods
|
|
* Remember to call ``fixup_ports`` at the end if you're modifying module interfaces
|
|
|
|
Testing your change
|
|
~~~~~~~~~~~~~~~~~~~
|
|
|
|
Untested code can't be maintained. Inevitable codebase-wide changes
|
|
are likely to break anything untested. Tests also help reviewers understand
|
|
the purpose of the code change in practice.
|
|
|
|
Your code needs to come with tests. If it's a feature, a test that covers
|
|
representative examples of the added behavior. If it's a bug fix, it should
|
|
reproduce the original isolated bug. But in some situations, adding a test
|
|
isn't viable. If you can't provide a test, explain this decision.
|
|
|
|
Prefer writing unit tests (:file:`tests/unit`) for isolated tests to
|
|
the internals of more serious code changes, like those to the core of yosys,
|
|
or more algorithmic ones.
|
|
|
|
The rest of the test suite is mostly based on running Yosys on various Yosys
|
|
and Tcl scripts that manually call Yosys commands.
|
|
See :doc:`/yosys_internals/extending_yosys/test_suites` for more information
|
|
about how our test suite is structured.
|
|
The basic test writing approach is checking
|
|
for the presence of some kind of object or pattern with ``-assert-count`` in
|
|
:doc:`/using_yosys/more_scripting/selections`.
|
|
|
|
It's often best to use equivalence checking with ``equiv_opt -assert``
|
|
or similar to prove that the changes done to the design by a modified pass
|
|
preserve equivalence. But some code isn't meant to preserve equivalence.
|
|
Sometimes proving equivalence takes an impractically long time for larger
|
|
inputs. Also beware, the ``equiv_`` passes are a bit quirky and might even
|
|
have incorrect results in unusual situations.
|
|
|
|
.. Changes to core parts of Yosys or passes that are included in synthesis flows
|
|
.. can change runtime and memory usage - for the better or for worse. This strongly
|
|
.. depends on the design involved. Such risky changes should then be benchmarked
|
|
.. with various designs.
|
|
|
|
.. TODO Emil benchmarking
|
|
|
|
Coding style
|
|
~~~~~~~~~~~~
|
|
|
|
Yosys is written in C++17.
|
|
|
|
In general Yosys uses ``int`` instead of ``size_t``. To avoid compiler warnings
|
|
for implicit type casts, always use ``GetSize(foobar)`` instead of
|
|
``foobar.size()``. (``GetSize()`` is defined in :file:`kernel/yosys.h`)
|
|
|
|
For auto formatting code, a :file:`.clang-format` file is present top-level.
|
|
Yosys code is using tabs for indentation. A tab is 8 characters wide,
|
|
but prefer not relying on it. A continuation of a statement
|
|
in the following line is indented by two additional tabs. Lines are
|
|
as long as you want them to be. A good rule of thumb is to break lines
|
|
at about column 150. Opening braces can be put on the same or next line
|
|
as the statement opening the block (if, switch, for, while, do).
|
|
Put the opening brace on its own line for larger blocks, especially
|
|
blocks that contains blank lines. Remove trailing whitespace on sight.
|
|
|
|
Otherwise stick to the `Linux Kernel Coding Style`_.
|
|
|
|
.. _Linux Kernel Coding Style: https://www.kernel.org/doc/Documentation/process/coding-style.rst
|
|
|
|
Git style
|
|
~~~~~~~~~
|
|
|
|
We don't have a strict commit message style.
|
|
|
|
Some style hints:
|
|
|
|
* Refactor and document existing code if you touch it,
|
|
but in separate commits from your functional changes
|
|
* Prefer smaller commits organized by good chunks. Git has a lot of features
|
|
like fixup commits, interactive rebase with autosquash
|
|
|
|
Reviewing PRs
|
|
-------------
|
|
|
|
Reviewing PRs is a totally valid form of external contributing to the project!
|
|
|
|
Who's the reviewer?
|
|
~~~~~~~~~~~~~~~~~~~
|
|
|
|
Yosys HQ is a company with the inherited mandate to make decisions on behalf
|
|
of the open source project. As such, we at HQ are collectively the maintainers.
|
|
Within HQ, we allocate reviews based on expertise with the topic at hand
|
|
as well as member time constraints.
|
|
|
|
If you're intimately acquainted with a part of the codebase, we will be happy
|
|
to defer to your experience and have you review PRs. The official way we like
|
|
is our CODEOWNERS file in the git repository. What we're looking for in code
|
|
owners is activity and trust. For activity, if you're only interested in
|
|
a yosys pass for example for the time you spend writing a thesis, it might be
|
|
better to focus on writing good tests and docs in the PRs you submit rather than
|
|
to commit to code ownership and therefore to be responsible for fixing things
|
|
and reviewing other people's PRs at various unexpected points later. If you're
|
|
prolific in some part of the codebase and not a code owner, we still value your
|
|
experience and may tag you in PRs.
|
|
|
|
As a matter of fact, the purpose of code ownership is to avoid maintainer
|
|
burnout by removing orphaned parts of the codebase. If you become a code owner
|
|
and stop being responsive, in the future, we might decide to remove such code
|
|
if convenient and costly to maintain. It's simply more respectful of the users'
|
|
time to explicitly cut something out than let it "bitrot". Larger projects like
|
|
LLVM or linux could not survive without such things, but Yosys is far smaller,
|
|
and there are expectations
|
|
|
|
.. TODO this deserves its own section elsewhere I think? But it would be distracting elsewhere
|
|
|
|
Sometimes, multiple maintainers may add review comments. This is considered
|
|
healthy collaborative even if it might create disagreement at times. If
|
|
somebody is already reviewing a PR, others, even non-maintainers are free to
|
|
leave comments with extra observations and alternate perspectives in a
|
|
collaborative spirit.
|
|
|
|
How to review
|
|
~~~~~~~~~~~~~
|
|
|
|
First, read everything above about contributing. Those are the values you
|
|
should gently enforce as a reviewer. They're ordered by importance, but
|
|
explicitly, descriptions are more important than code, long-form comments
|
|
describing the design are more important than piecemeal comments, etc.
|
|
|
|
If a PR is poorly described, incomplete, tests are broken, or if the
|
|
author is not responding, please don't feel pressured to take over their
|
|
role by reverse engineering the code or fixing things for them, unless
|
|
there are good reasons to do so.
|
|
|
|
If a PR author submits LLM outputs they haven't understood themselves,
|
|
they will not be able to implement feedback. Take this into consideration
|
|
as well. We do not ban LLM code from the codebase, we ban bad code.
|
|
|
|
Reviewers may have diverse styles of communication while reviewing - one
|
|
may do one thorough review, another may prefer a back and forth with the
|
|
basics out the way before digging into the code. Generally, PRs may have
|
|
several requests for modifications and long discussions, but often
|
|
they just are good enough to merge as-is.
|
|
|
|
The CI is required to go green for merging. New contributors need a CI
|
|
run to be triggered by a maintainer before their PRs take up computing
|
|
resources. It's a single click from the github web interface.
|