hdl.ast: accept any constant-castable expression in Signal(reset=).

See amaranth-lang/rfcs#4.

This functionality was not explicitly specified in the RFC but it
falls under "anywhere an integer or an enumeration is accepted".
This commit is contained in:
Catherine 2023-03-03 06:20:34 +00:00
parent f77a335abf
commit 0c4fda92fe
4 changed files with 43 additions and 29 deletions

View file

@ -1001,19 +1001,28 @@ class Signal(Value, DUID):
self.width = shape.width
self.signed = shape.signed
if isinstance(reset, Enum):
reset = reset.value
if not isinstance(reset, int):
raise TypeError("Reset value has to be an int or an integral Enum")
reset_width = bits_for(reset, self.signed)
if reset != 0 and reset_width > self.width:
warnings.warn("Reset value {!r} requires {} bits to represent, but the signal "
"only has {} bits"
.format(reset, reset_width, self.width),
SyntaxWarning, stacklevel=2 + src_loc_at)
self.reset = reset
orig_reset = reset
try:
reset = Const.cast(reset)
except TypeError:
raise TypeError("Reset value must be a constant-castable expression, not {!r}"
.format(orig_reset))
if orig_reset not in (0, -1): # Avoid false positives for all-zeroes and all-ones
if reset.shape().signed and not self.signed:
warnings.warn(
message="Reset value {!r} is signed, but the signal shape is {!r}"
.format(orig_reset, shape),
category=SyntaxWarning,
stacklevel=2)
elif (reset.shape().width > self.width or
reset.shape().width == self.width and
self.signed and not reset.shape().signed):
warnings.warn(
message="Reset value {!r} will be truncated to the signal shape {!r}"
.format(orig_reset, shape),
category=SyntaxWarning,
stacklevel=2)
self.reset = reset.value
self.reset_less = bool(reset_less)
self.attrs = OrderedDict(() if attrs is None else attrs)

View file

@ -44,7 +44,7 @@ class EnumMeta(ShapeCastable, py_enum.EnumMeta):
.format(member)) from e
if member_shape.signed and not shape.signed:
warnings.warn(
message="Value of enumeration member {!r} is signed, but enumeration "
message="Value of enumeration member {!r} is signed, but the enumeration "
"shape is {!r}" # the repr will be `unsigned(X)`
.format(member, shape),
category=SyntaxWarning,
@ -54,7 +54,7 @@ class EnumMeta(ShapeCastable, py_enum.EnumMeta):
shape.signed and not member_shape.signed):
warnings.warn(
message="Value of enumeration member {!r} will be truncated to "
"enumeration shape {!r}"
"the enumeration shape {!r}"
.format(member, shape),
category=SyntaxWarning,
stacklevel=2)