-
Notifications
You must be signed in to change notification settings - Fork 49
Add signed/fixedpoint properties #140
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 11 commits
Commits
Show all changes
18 commits
Select commit
Hold shift + click to select a range
d630379
declared intwidth, fracwidth, and is_signed UDPs
darsor e8d3a76
fix boolean type name in UDP definition
darsor 09f9155
generate hwif fields with fixedpoint indices
darsor 7ceee2c
make "counter" and "encode" properties mutualy exclusive with signed/…
darsor d10f71f
add signed/unsigned to hwif
darsor c351bbd
improved fixedpoint error messages, added validation tests
darsor 0121926
added fixedpoint tests
darsor 7d9de15
fixedpoint/signed not allowed for signal components
darsor 7c81c6a
added signed/fixedpoint UDP docs
darsor 2eb6e51
handle single-bit fixedpoint numbers
darsor 5ec839c
fix too many positional arguments lint
darsor ec0d457
changed spelling of fixedpoint to fixed-point
darsor 317a402
use "logic" in place of "unsigned logic"
darsor 008c58a
split signed and fixedpoint docs, added examples
darsor 99f11d4
allow enums with is_signed=false
darsor e8e9f67
split signed and fixedpoint implementations
darsor 839d899
assorted nits picked
darsor d43eaaf
updated is_signed validation unit test
darsor File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -83,3 +83,4 @@ Links | |
udps/read_buffering | ||
udps/write_buffering | ||
udps/extended_swacc | ||
udps/fixedpoint |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
.. _fixedpoint: | ||
|
||
Signed and Fixedpoint Fields | ||
darsor marked this conversation as resolved.
Show resolved
Hide resolved
|
||
============================ | ||
|
||
SystemRDL does not natively provide a way to mark fields as signed or unsigned. | ||
The ``is_signed`` user-defined property fills this need. Similarly, the | ||
``fracwidth`` and ``intwidth`` user-defined properties can be used to declare | ||
the fixedpoint representation of a field. | ||
|
||
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 | ||
---------- | ||
The behavior of signed and/or fixedpoint fields is defined using the following | ||
three properties: | ||
|
||
.. literalinclude:: ../../hdl-src/regblock_udps.rdl | ||
:lines: 40-54 | ||
|
||
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:: is_signed | ||
|
||
* Assigned value is a boolean. | ||
* If true, the hardware interface field will have the | ||
``logic signed [width-1:0]`` type. | ||
* If false, the hardware interface field will have the | ||
``logic unsigned [width-1:0]`` type. | ||
* If not defined for a field, the field will have the ``logic [width-1:0]`` | ||
type. | ||
|
||
.. describe:: intwidth | ||
|
||
* The ``intwidth`` property defines the number of integer bits in the | ||
fixedpoint representation (including the sign bit, if present). | ||
* If ``intwidth`` is defined for a field and ``is_signed`` is not, | ||
``is_signed`` is inferred as false (unsigned). | ||
* If ``is_signed`` is true, the fixedpoint representation has a range from | ||
:math:`-2^{\mathrm{intwidth}-1}` to :math:`2^{\mathrm{intwidth}-1} -2^{-\mathrm{fracwidth}}`. | ||
* If ``is_signed`` is false, the fixedpoint representation has a range from | ||
:math:`0` to :math:`2^{\mathrm{intwidth}} - 2^{-\mathrm{fracwidth}}`. | ||
* The type of the field in the ``hwif`` struct is | ||
``logic (un)signed [intwidth-1:-fracwidth]``. | ||
|
||
.. describe:: fracwidth | ||
|
||
* The ``fracwidth`` property defines the number of fractional bits in the | ||
fixedpoint representation. | ||
* The weight of the least significant bit of the field is | ||
:math:`2^{-\mathrm{fracwidth}}`. | ||
* If ``fracwidth`` is defined for a field and ``is_signed`` is not, | ||
``is_signed`` is inferred as false (unsigned). | ||
* The type of the field in the ``hwif`` struct is | ||
``logic (un)signed [intwidth-1:-fracwidth]``. | ||
|
||
Other Rules | ||
^^^^^^^^^^^ | ||
* Only one of ``fracwidth`` or ``intwidth`` need be defined. The other is | ||
inferred from the field bit width. | ||
* The bit width of the field shall be equal to ``fracwidth`` + ``intwidth``. | ||
* 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 | ||
amykyta3 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
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 (with the exception of ``is_signed=false``). | ||
* The properties defined above are mutually exclusive with the ``encode`` | ||
property. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
from typing import Any | ||
|
||
from systemrdl.component import Field | ||
from systemrdl.node import Node, FieldNode | ||
from systemrdl.udp import UDPDefinition | ||
|
||
|
||
class FixedpointWidth(UDPDefinition): | ||
darsor marked this conversation as resolved.
Show resolved
Hide resolved
|
||
valid_components = {Field} | ||
valid_type = int | ||
|
||
def validate(self, node: "Node", value: Any) -> None: | ||
assert isinstance(node, FieldNode) | ||
|
||
intwidth = node.get_property("intwidth") | ||
fracwidth = node.get_property("fracwidth") | ||
assert intwidth is not None | ||
assert fracwidth is not None | ||
prop_ref = node.inst.property_src_ref.get(self.name) | ||
|
||
# incompatible with "counter" fields | ||
if node.get_property("counter"): | ||
self.msg.error( | ||
"Fixedpoint representations are not supported for counter fields.", | ||
prop_ref | ||
) | ||
|
||
# incompatible with "encode" fields | ||
if node.get_property("encode") is not None: | ||
self.msg.error( | ||
"Fixedpoint representations are not supported for fields encoded as an enum.", | ||
prop_ref | ||
) | ||
|
||
# ensure node width = fracwidth + intwidth | ||
if intwidth + fracwidth != node.width: | ||
self.msg.error( | ||
f"Number of integer bits ({intwidth}) plus number of fractional bits ({fracwidth})" | ||
f" must be equal to the width of the component ({node.width}).", | ||
prop_ref | ||
) | ||
|
||
|
||
class IntWidth(FixedpointWidth): | ||
name = "intwidth" | ||
|
||
def get_unassigned_default(self, node: "Node") -> Any: | ||
# if 'fracwidth' is defined, 'intwidth' is inferred from the node width | ||
darsor marked this conversation as resolved.
Show resolved
Hide resolved
|
||
fracwidth = node.get_property("fracwidth", default=None) | ||
if fracwidth is not None: | ||
assert isinstance(node, FieldNode) | ||
darsor marked this conversation as resolved.
Show resolved
Hide resolved
|
||
return node.width - fracwidth | ||
else: | ||
# not a fixedpoint number | ||
return None | ||
|
||
|
||
class FracWidth(FixedpointWidth): | ||
name = "fracwidth" | ||
|
||
def get_unassigned_default(self, node: "Node") -> Any: | ||
# if 'intwidth' is defined, 'fracwidth' is inferred from the node width | ||
intwidth = node.get_property("intwidth", default=None) | ||
if intwidth is not None: | ||
assert isinstance(node, FieldNode) | ||
return node.width - intwidth | ||
else: | ||
# not a fixedpoint number | ||
return None | ||
|
||
|
||
class IsSigned(UDPDefinition): | ||
name = "is_signed" | ||
valid_components = {Field} | ||
valid_type = bool | ||
default_assignment = True | ||
|
||
def validate(self, node: "Node", value: Any) -> None: | ||
# "counter" fields can not be signed | ||
if value and node.get_property("counter"): | ||
self.msg.error( | ||
"The property is_signed=true is not supported for counter fields.", | ||
node.inst.property_src_ref["is_signed"] | ||
) | ||
|
||
# incompatible with "encode" fields | ||
if node.get_property("encode") is not None: | ||
self.msg.error( | ||
"The is_signed property is not supported for fields encoded as an enum.", | ||
node.inst.property_src_ref["is_signed"] | ||
) | ||
|
||
def get_unassigned_default(self, node: "Node") -> Any: | ||
intwidth = node.get_property("intwidth") | ||
darsor marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if intwidth is not None: | ||
# it's a fixedpoint number, default to unsigned | ||
return False | ||
else: | ||
# not a fixedpoint number | ||
return None |
Empty file.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
addrmap top { | ||
default accesswidth = 64; | ||
default regwidth = 64; | ||
reg { | ||
field { | ||
sw = rw; hw = r; | ||
intwidth = 8; | ||
fracwidth = 8; | ||
} f_Q8_8[16] = 0; | ||
field { | ||
sw = r; hw = w; | ||
intwidth = 32; | ||
} f_Q32_n12[20]; | ||
field { | ||
sw = rw; hw = r; | ||
fracwidth = 32; | ||
is_signed; | ||
} f_SQn8_32[24] = 0; | ||
field { | ||
sw = rw; hw = r; | ||
fracwidth = 7; | ||
is_signed; | ||
} f_SQn6_7 = 0; | ||
} r1 @ 0x0; | ||
|
||
reg { | ||
field { | ||
sw = r; hw = w; | ||
is_signed; | ||
} f_signed[16]; | ||
field { | ||
sw = rw; hw = r; | ||
is_signed = false; | ||
} f_unsigned[16] = 0; | ||
field { | ||
sw = r; hw = w; | ||
} f_no_sign[16]; | ||
} r2 @ 0x8; | ||
}; |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.