diff --git a/amaranth/hdl/ast.py b/amaranth/hdl/ast.py index e1ee694..3fdb031 100644 --- a/amaranth/hdl/ast.py +++ b/amaranth/hdl/ast.py @@ -860,9 +860,14 @@ class Part(Value): if not isinstance(stride, int) or stride <= 0: raise TypeError("Part stride must be a positive integer, not {!r}".format(stride)) + value = Value.cast(value) + offset = Value.cast(offset) + if offset.shape().signed: + raise TypeError("Part offset must be unsigned") + super().__init__(src_loc_at=src_loc_at) - self.value = Value.cast(value) - self.offset = Value.cast(offset) + self.value = value + self.offset = offset self.width = width self.stride = stride diff --git a/tests/test_hdl_ast.py b/tests/test_hdl_ast.py index 0cb8865..760744c 100644 --- a/tests/test_hdl_ast.py +++ b/tests/test_hdl_ast.py @@ -785,6 +785,11 @@ class BitSelectTestCase(FHDLTestCase): s = self.c.bit_select(self.s, 2) self.assertEqual(repr(s), "(part (const 8'd0) (sig s) 2 1)") + def test_offset_wrong(self): + with self.assertRaisesRegex(TypeError, + r"^Part offset must be unsigned$"): + self.c.bit_select(self.s.as_signed(), 1) + class WordSelectTestCase(FHDLTestCase): def setUp(self): @@ -817,6 +822,11 @@ class WordSelectTestCase(FHDLTestCase): s = self.c.word_select(self.s, 2) self.assertEqual(repr(s), "(part (const 8'd0) (sig s) 2 2)") + def test_offset_wrong(self): + with self.assertRaisesRegex(TypeError, + r"^Part offset must be unsigned$"): + self.c.word_select(self.s.as_signed(), 1) + class CatTestCase(FHDLTestCase): def test_shape(self):