Implement RFC 46: Change Shape.cast(range(1))
to unsigned(0)
.
This commit is contained in:
parent
1fe7bd010f
commit
089213e19f
|
@ -93,8 +93,8 @@ class Shape:
|
||||||
|
|
||||||
* a :class:`Shape`, where the result is itself;
|
* a :class:`Shape`, where the result is itself;
|
||||||
* an :class:`int`, where the result is :func:`unsigned(obj) <unsigned>`;
|
* an :class:`int`, where the result is :func:`unsigned(obj) <unsigned>`;
|
||||||
* a :class:`range`, where the result is wide enough to represent any element of the range,
|
* a :class:`range`, where the result has minimal width required to represent all elements
|
||||||
and is signed if any element of the range is signed;
|
of the range, and is signed if any element of the range is signed;
|
||||||
* an :class:`enum.Enum` whose members are all :ref:`constant-castable <lang-constcasting>`
|
* an :class:`enum.Enum` whose members are all :ref:`constant-castable <lang-constcasting>`
|
||||||
or :class:`enum.IntEnum`, where the result is wide enough to represent any member of
|
or :class:`enum.IntEnum`, where the result is wide enough to represent any member of
|
||||||
the enumeration, and is signed if any member of the enumeration is signed;
|
the enumeration, and is signed if any member of the enumeration is signed;
|
||||||
|
@ -121,6 +121,8 @@ class Shape:
|
||||||
signed = obj[0] < 0 or obj[-1] < 0
|
signed = obj[0] < 0 or obj[-1] < 0
|
||||||
width = max(bits_for(obj[0], signed),
|
width = max(bits_for(obj[0], signed),
|
||||||
bits_for(obj[-1], signed))
|
bits_for(obj[-1], signed))
|
||||||
|
if obj[0] == obj[-1] == 0:
|
||||||
|
width = 0
|
||||||
return Shape(width, signed)
|
return Shape(width, signed)
|
||||||
elif isinstance(obj, type) and issubclass(obj, Enum):
|
elif isinstance(obj, type) and issubclass(obj, Enum):
|
||||||
# For compatibility with third party enumerations, handle them as if they were
|
# For compatibility with third party enumerations, handle them as if they were
|
||||||
|
|
|
@ -36,9 +36,11 @@ Implemented RFCs
|
||||||
|
|
||||||
.. _RFC 17: https://amaranth-lang.org/rfcs/0017-remove-log2-int.html
|
.. _RFC 17: https://amaranth-lang.org/rfcs/0017-remove-log2-int.html
|
||||||
.. _RFC 39: https://amaranth-lang.org/rfcs/0039-empty-case.html
|
.. _RFC 39: https://amaranth-lang.org/rfcs/0039-empty-case.html
|
||||||
|
.. _RFC 46: https://amaranth-lang.org/rfcs/0046-shape-range-1.html
|
||||||
|
|
||||||
* `RFC 17`_: Remove ``log2_int``
|
* `RFC 17`_: Remove ``log2_int``
|
||||||
* `RFC 39`_: Change semantics of no-argument ``m.Case()``
|
* `RFC 39`_: Change semantics of no-argument ``m.Case()``
|
||||||
|
* `RFC 46`_: Change ``Shape.cast(range(1))`` to ``unsigned(0)``
|
||||||
|
|
||||||
|
|
||||||
Language changes
|
Language changes
|
||||||
|
@ -52,6 +54,7 @@ Language changes
|
||||||
* Changed: ``Value.matches()`` with no patterns is ``Const(0)`` instead of ``Const(1)``. (`RFC 39`_)
|
* Changed: ``Value.matches()`` with no patterns is ``Const(0)`` instead of ``Const(1)``. (`RFC 39`_)
|
||||||
* Changed: ``Signal(range(stop), reset=stop)`` warning has been changed into a hard error and made to trigger on any out-of range value.
|
* Changed: ``Signal(range(stop), reset=stop)`` warning has been changed into a hard error and made to trigger on any out-of range value.
|
||||||
* Changed: ``Signal(range(0))`` is now valid without a warning.
|
* Changed: ``Signal(range(0))`` is now valid without a warning.
|
||||||
|
* Changed: ``Shape.cast(range(1))`` is now ``unsigned(0)``. (`RFC 46`_)
|
||||||
* Deprecated: :func:`amaranth.utils.log2_int`. (`RFC 17`_)
|
* Deprecated: :func:`amaranth.utils.log2_int`. (`RFC 17`_)
|
||||||
* Removed: (deprecated in 0.4) :meth:`Const.normalize`. (`RFC 5`_)
|
* Removed: (deprecated in 0.4) :meth:`Const.normalize`. (`RFC 5`_)
|
||||||
* Removed: (deprecated in 0.4) :class:`Repl`. (`RFC 10`_)
|
* Removed: (deprecated in 0.4) :class:`Repl`. (`RFC 10`_)
|
||||||
|
|
|
@ -115,7 +115,7 @@ class ShapeTestCase(FHDLTestCase):
|
||||||
self.assertEqual(s3.width, 4)
|
self.assertEqual(s3.width, 4)
|
||||||
self.assertEqual(s3.signed, True)
|
self.assertEqual(s3.signed, True)
|
||||||
s4 = Shape.cast(range(0, 1))
|
s4 = Shape.cast(range(0, 1))
|
||||||
self.assertEqual(s4.width, 1)
|
self.assertEqual(s4.width, 0)
|
||||||
self.assertEqual(s4.signed, False)
|
self.assertEqual(s4.signed, False)
|
||||||
s5 = Shape.cast(range(-1, 0))
|
s5 = Shape.cast(range(-1, 0))
|
||||||
self.assertEqual(s5.width, 1)
|
self.assertEqual(s5.width, 1)
|
||||||
|
@ -129,6 +129,9 @@ class ShapeTestCase(FHDLTestCase):
|
||||||
s8 = Shape.cast(range(0, 10, 3))
|
s8 = Shape.cast(range(0, 10, 3))
|
||||||
self.assertEqual(s8.width, 4)
|
self.assertEqual(s8.width, 4)
|
||||||
self.assertEqual(s8.signed, False)
|
self.assertEqual(s8.signed, False)
|
||||||
|
s9 = Shape.cast(range(0, 3, 3))
|
||||||
|
self.assertEqual(s9.width, 0)
|
||||||
|
self.assertEqual(s9.signed, False)
|
||||||
|
|
||||||
def test_cast_enum(self):
|
def test_cast_enum(self):
|
||||||
s1 = Shape.cast(UnsignedEnum)
|
s1 = Shape.cast(UnsignedEnum)
|
||||||
|
@ -1088,7 +1091,7 @@ class SignalTestCase(FHDLTestCase):
|
||||||
s10 = Signal(range(0))
|
s10 = Signal(range(0))
|
||||||
self.assertEqual(s10.shape(), unsigned(0))
|
self.assertEqual(s10.shape(), unsigned(0))
|
||||||
s11 = Signal(range(1))
|
s11 = Signal(range(1))
|
||||||
self.assertEqual(s11.shape(), unsigned(1))
|
self.assertEqual(s11.shape(), unsigned(0))
|
||||||
|
|
||||||
def test_shape_wrong(self):
|
def test_shape_wrong(self):
|
||||||
with self.assertRaisesRegex(TypeError,
|
with self.assertRaisesRegex(TypeError,
|
||||||
|
|
Loading…
Reference in a new issue