Files
PeakRDL-BusDecoder/docs/faq.rst
2025-10-10 22:30:59 -07:00

132 lines
5.7 KiB
ReStructuredText

Frequently Asked Questions
==========================
Why isn't there an option for a flat non-struct hardware interface?
-------------------------------------------------------------------
SystemRDL is inherently a very hierarchical language.
For small register blocks, flattening the hardware interface may be acceptable,
but this ends up scaling very poorly as the design becomes larger and has more
complex hierarchy.
Using struct compositions for the hardware interface has the benefit of
preserving conceptual hierarchy and arrays exactly as defined in the original
SystemRDL.
How do I know I connected everything? Structs are harder to review
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Initially this can be daunting, but fortunately the tool has an option to generate a
flattened hardware interface report upon export. Try using the ``--hwif-report``
command line option when exporting. This is the easiest way to quickly
understand the structure of the hardware interface.
Why does the tool generate un-packed structs? I prefer packed structs.
----------------------------------------------------------------------
Packed structs are great when describing vectors that have bit-level structure.
In this tool, the use of un-packed structs is intentional since the hardware
interface is not something that is meant to be bit-accessible. In the case of
the hardware interface structs, using a packed struct is semantically inappropriate.
... Then how can I initialize the struct?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
We get this request most often because designers want to initialize the ``hwif_in``
struct with a simple assignment:
.. code:: systemverilog
always_comb begin
hwif_in = '0;
end
Of course since the struct actually is **unpacked**, this will result in a
compile error which usually leads to the inappropriate assumption that it ought
to be packed. (See this amusing blog post about `X/Y problems <https://xyproblem.info>`_)
If your goal is to initialize the packed struct, fortunately SystemVerilog already
has syntax to do this:
.. code:: systemverilog
always_comb begin
hwif_in = '{default: '0};
end
This is lesser-known syntax, but still very well supported by synthesis
tools, and is the recommended way to handle this.
... What if I want to assign it to a bit-vector?
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Assigning the hwif struct to a bit-vector is strongly discouraged. This tool makes
no guarantees regarding the field ordering of the hwif structure, so doing so
should be considered functionally dangerous.
That said, if you still need to do this, it is still trivially possible to
without requiring packed structs. Instead, use the SystemVerilog streaming operator:
.. code:: systemverilog
my_packed_vector = {<<{hwif_out}};
... Why are unpacked structs preferred?
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
In the case of the hardware interface ports, unpacked structs help prevent
mistakes that are very easy to make.
Consider the following situation - a designer has a field that sets the following
properties: ``sw=rw; hw=rw; we;``, and wants to assign the hardware input value,
so they erroneously do the following assignment in Verilog:
.. code:: systemverilog
assign hwif_in.my_register.my_field = <some value>;
This is actually a bug since the ``my_field`` member is actually a struct that
has two members: ``we`` and ``next``. If this were a packed struct, this would
silently compile and you would potentially have a bug that may not be noticed
(depending on how thorough the test campaign is).
With an unpacked struct, this gets flagged immediately as a compile error since
the assignment is invalid.
The designer may have simply forgotten that the field is an aggregate of multiple
members and intended to do the following:
.. code:: systemverilog
assign hwif.my_register.my_field.next = <some value>;
assign hwif.my_register.my_field.we = <some control signal>;
The generated output does not match our organization's coding style
-------------------------------------------------------------------
SystemVerilog coding styles vary wildly, and unfortunately there is little
consensus on this topic within the digital design community.
The output generated by PeakRDL-busdecoder strives to be as human-readable as possible,
and follow consistent indentation and styling. We do our best to use the most
widely accepted coding style, but since this is a very opinionated space, it is
impossible to satisfy everyone.
In general, we strive to follow the
`SystemVerilog style guide by lowRISC <https://github.com/lowRISC/style-guides/blob/master/VerilogCodingStyle.md>`_,
but may deviate in some areas if not practical or would impose excessive complexity on the code generator.
The lint tool I am using is flagging violations in generated code
-----------------------------------------------------------------
Code linting tools are a great way to check for user-error, flag inconsistencies,
and enforce best-practices within an organization. In many cases, linter tools
may be configured to also enforce stylistic preferences.
Unfortunately just like coding styles, lint rules can often be more
opinionated than practical.
In general, we will not address lint violations unless they flag actual
structural issues or semantically dangerous code.
Stylistic violations that pose no actual danger to the correctness of the design
will rarely be addressed, especially if the change would add unreasonable
complexity to the tool.
If you encounter a lint violation, please carefully review and consider waiving
it if it does not pose an actual danger. If you still believe it is a problem,
please let us know by `submitting an issue <https://github.com/SystemRDL/PeakRDL-busdecoder/issues>`_
that describes the problem.