Add signed/fixedpoint properties (#140)
* declared intwidth, fracwidth, and is_signed UDPs * fix boolean type name in UDP definition * generate hwif fields with fixedpoint indices * make "counter" and "encode" properties mutualy exclusive with signed/fixedpoint * add signed/unsigned to hwif * improved fixedpoint error messages, added validation tests * added fixedpoint tests * fixedpoint/signed not allowed for signal components * added signed/fixedpoint UDP docs * handle single-bit fixedpoint numbers * fix too many positional arguments lint * changed spelling of fixedpoint to fixed-point * use "logic" in place of "unsigned logic" * split signed and fixedpoint docs, added examples * allow enums with is_signed=false * split signed and fixedpoint implementations * assorted nits picked * updated is_signed validation unit test
This commit is contained in:
103
docs/udps/fixedpoint.rst
Normal file
103
docs/udps/fixedpoint.rst
Normal file
@@ -0,0 +1,103 @@
|
||||
.. _fixedpoint:
|
||||
|
||||
Fixed-Point Fields
|
||||
==================
|
||||
|
||||
`Fixed-point <https://en.wikipedia.org/wiki/Fixed-point_arithmetic>`_ numbers
|
||||
can be used to efficiently represent real numbers using integers. Fixed-point
|
||||
numbers consist of some combination of integer bits and fractional bits. The
|
||||
number of integer/fractional bits is usually implicitly tracked (not stored)
|
||||
for each number, unlike for floating-point numbers.
|
||||
|
||||
For this SystemVerilog exporter, these properties only affect the signal type in
|
||||
the the ``hwif`` structs. There is no special handling in the internals of
|
||||
the regblock.
|
||||
|
||||
Properties
|
||||
----------
|
||||
Fields can be declared as fixed-point numbers using the following two properties:
|
||||
|
||||
.. literalinclude:: ../../hdl-src/regblock_udps.rdl
|
||||
:lines: 46-54
|
||||
|
||||
The :ref:`is_signed<signed>` property can be used in conjunction with these
|
||||
properties to declare signed fixed-point fields.
|
||||
|
||||
These UDP definitions, along with others supported by PeakRDL-regblock, can be
|
||||
enabled by compiling the following file along with your design:
|
||||
:download:`regblock_udps.rdl <../../hdl-src/regblock_udps.rdl>`.
|
||||
|
||||
.. describe:: intwidth
|
||||
|
||||
* The ``intwidth`` property defines the number of integer bits in the
|
||||
fixed-point representation (including the sign bit, if present).
|
||||
|
||||
.. describe:: fracwidth
|
||||
|
||||
* The ``fracwidth`` property defines the number of fractional bits in the
|
||||
fixed-point representation.
|
||||
|
||||
Representable Numbers
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The range of representable real numbers is summarized in the table below.
|
||||
|
||||
.. list-table:: Representable Numbers
|
||||
:header-rows: 1
|
||||
|
||||
* - Signedness
|
||||
- Minimum Value
|
||||
- Maximum Value
|
||||
- Step Size
|
||||
|
||||
* - Unsigned
|
||||
- :math:`0`
|
||||
- :math:`2^{\mathrm{intwidth}} - 2^{-\mathrm{fracwidth}}`
|
||||
- :math:`2^{-\mathrm{fracwidth}}`
|
||||
|
||||
* - Signed
|
||||
- :math:`-2^{\mathrm{intwidth}-1}`
|
||||
- :math:`2^{\mathrm{intwidth}-1} - 2^{-\mathrm{fracwidth}}`
|
||||
- :math:`2^{-\mathrm{fracwidth}}`
|
||||
|
||||
SystemVerilog Types
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
When either ``intwidth`` or ``fracwidth`` are defined for a field, that field's
|
||||
type in the generated SystemVerilog ``hwif`` struct is
|
||||
``logic (signed) [intwidth-1:-fracwidth]``. The bit at index :math:`i` contributes
|
||||
a weight of :math:`2^i` to the real number represented.
|
||||
|
||||
Other Rules
|
||||
^^^^^^^^^^^
|
||||
* Only one of ``intwidth`` or ``fracwidth`` need be defined. The other is
|
||||
inferred from the field bit width.
|
||||
* The bit width of the field shall be equal to ``intwidth`` + ``fracwidth``.
|
||||
* If both ``intwidth`` and ``fracwidth`` are defined for a field, it is an
|
||||
error if their sum does not equal the bit width of the field.
|
||||
* Either ``fracwidth`` or ``intwidth`` can be a negative integer. Because
|
||||
SystemRDL does not have a signed integer type, the only way to achieve
|
||||
this is to define one of the widths as larger than the bit width of the
|
||||
component so that the other width is inferred as a negative number.
|
||||
* The properties defined above are mutually exclusive with the ``counter``
|
||||
property.
|
||||
* The properties defined above are mutually exclusive with the ``encode``
|
||||
property.
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
A 12-bit signed fixed-point field with 4 integer bits and 8 fractional bits
|
||||
can be declared with
|
||||
|
||||
.. code-block:: systemrdl
|
||||
:emphasize-lines: 3, 4
|
||||
|
||||
field {
|
||||
sw=rw; hw=r;
|
||||
intwidth = 4;
|
||||
is_signed;
|
||||
} fixedpoint_num[11:0] = 0;
|
||||
|
||||
This field can represent values from -8.0 to 7.99609375
|
||||
in steps of 0.00390625.
|
||||
@@ -60,3 +60,26 @@ To enable these UDPs, compile this RDL file prior to the rest of your design:
|
||||
- Enables an output strobe that is asserted on sw writes.
|
||||
|
||||
See: :ref:`extended_swacc`.
|
||||
|
||||
* - is_signed
|
||||
- field
|
||||
- boolean
|
||||
- Defines the signedness of a field.
|
||||
|
||||
See: :ref:`signed`.
|
||||
|
||||
* - intwidth
|
||||
- field
|
||||
- unsigned integer
|
||||
- Defines the number of integer bits in the fixed-point representation
|
||||
of a field.
|
||||
|
||||
See: :ref:`fixedpoint`.
|
||||
|
||||
* - fracwidth
|
||||
- field
|
||||
- unsigned integer
|
||||
- Defines the number of fractional bits in the fixed-point representation
|
||||
of a field.
|
||||
|
||||
See: :ref:`fixedpoint`.
|
||||
|
||||
74
docs/udps/signed.rst
Normal file
74
docs/udps/signed.rst
Normal file
@@ -0,0 +1,74 @@
|
||||
.. _signed:
|
||||
|
||||
Signed Fields
|
||||
=============
|
||||
|
||||
SystemRDL does not natively provide a way to mark fields as signed or unsigned.
|
||||
The ``is_signed`` user-defined property fills this need.
|
||||
|
||||
For this SystemVerilog exporter, marking a field as signed only affects the
|
||||
signal type in the ``hwif`` structs. There is no special handling in the internals
|
||||
of the regblock.
|
||||
|
||||
Properties
|
||||
----------
|
||||
A field can be marked as signed using the following user-defined property:
|
||||
|
||||
.. literalinclude:: ../../hdl-src/regblock_udps.rdl
|
||||
:lines: 40-44
|
||||
|
||||
This UDP definition, along with others supported by PeakRDL-regblock, can be
|
||||
enabled by compiling the following file along with your design:
|
||||
:download:`regblock_udps.rdl <../../hdl-src/regblock_udps.rdl>`.
|
||||
|
||||
.. describe:: is_signed
|
||||
|
||||
* Assigned value is a boolean.
|
||||
* If true, the hardware interface field will have the type
|
||||
``logic signed [width-1:0]``.
|
||||
* If false or not defined for a field, the hardware interface field will
|
||||
have the type ``logic [width-1:0]``, which is unsigned by definition.
|
||||
|
||||
Other Rules
|
||||
^^^^^^^^^^^
|
||||
|
||||
* ``is_signed=true`` is mutually exclusive with the ``counter`` property.
|
||||
* ``is_signed=true`` is mutually exclusive with the ``encode`` property.
|
||||
|
||||
Examples
|
||||
--------
|
||||
Below are some examples of fields with different signedness.
|
||||
|
||||
Signed Fields
|
||||
^^^^^^^^^^^^^
|
||||
.. code-block:: systemrdl
|
||||
:emphasize-lines: 3, 8
|
||||
|
||||
field {
|
||||
sw=rw; hw=r;
|
||||
is_signed;
|
||||
} signed_num[63:0] = 0;
|
||||
|
||||
field {
|
||||
sw=r; hw=w;
|
||||
is_signed = true;
|
||||
} another_signed_num[19:0] = 20'hFFFFF; // -1
|
||||
|
||||
SystemRDL's own integer type is always unsigned. In order to specify a negative
|
||||
reset value, the two's complement value must be used as shown in the second
|
||||
example above.
|
||||
|
||||
Unsigned Fields
|
||||
^^^^^^^^^^^^^^^
|
||||
.. code-block:: systemrdl
|
||||
:emphasize-lines: 3, 8
|
||||
|
||||
field {
|
||||
sw=rw; hw=r;
|
||||
// fields are unsigned by default
|
||||
} unsigned_num[63:0] = 0;
|
||||
|
||||
field {
|
||||
sw=r; hw=w;
|
||||
is_signed = false;
|
||||
} another_unsigned_num[19:0] = 0;
|
||||
Reference in New Issue
Block a user