From 6e155a9b4646d6926018d511420c9a79ea65f395 Mon Sep 17 00:00:00 2001 From: Wanda Date: Thu, 11 Apr 2024 01:49:31 +0200 Subject: [PATCH] hdl._ast: make `Signal.like` work properly with `ShapeCastable`s. Fixes #1285. --- amaranth/hdl/_ast.py | 17 +++++++++++------ tests/test_lib_data.py | 9 +++++++++ 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/amaranth/hdl/_ast.py b/amaranth/hdl/_ast.py index 88055cc6f..77b3a05bb 100644 --- a/amaranth/hdl/_ast.py +++ b/amaranth/hdl/_ast.py @@ -2177,13 +2177,14 @@ def like(cls, other, *, name=None, name_suffix=None, init=None, reset=None, src_ Parameters ---------- - other : Value + other : ValueLike Object to base this Signal on. """ + cast_other = Value.cast(other) if name is not None: new_name = str(name) elif name_suffix is not None: - new_name = other.name + str(name_suffix) + new_name = cast_other.name + str(name_suffix) else: new_name = tracer.get_var_name(depth=2 + src_loc_at, default="$like") # TODO(amaranth-0.7): remove @@ -2196,11 +2197,15 @@ def like(cls, other, *, name=None, name_suffix=None, init=None, reset=None, src_ if isinstance(other, ValueCastable): shape = other.shape() else: - shape = Value.cast(other).shape() + shape = cast_other.shape() kw = dict(shape=shape, name=new_name) - if isinstance(other, Signal): - kw.update(init=other.init, reset_less=other.reset_less, - attrs=other.attrs, decoder=other.decoder) + if isinstance(cast_other, Signal): + if isinstance(shape, ShapeCastable): + other_init = shape.from_bits(cast_other.init) + else: + other_init = cast_other.init + kw.update(init=other_init, reset_less=cast_other.reset_less, + attrs=cast_other.attrs, decoder=cast_other.decoder) kw.update(kwargs) if init is not None: kw["init"] = init diff --git a/tests/test_lib_data.py b/tests/test_lib_data.py index 1dd439927..6618eea4c 100644 --- a/tests/test_lib_data.py +++ b/tests/test_lib_data.py @@ -641,6 +641,15 @@ def test_signal_like(self): s1 = Signal(data.StructLayout({"a": unsigned(1)})) s2 = Signal.like(s1) self.assertEqual(s2.shape(), data.StructLayout({"a": unsigned(1)})) + s3 = Signal.like(s1, name_suffix="a") + self.assertEqual(s3.as_value().name, "s1a") + + s4 = Signal(data.StructLayout({"a": unsigned(2), "b": unsigned(3)}), init={"a": 1}, reset_less=True, attrs={"x": "y"}) + s5 = Signal.like(s4) + self.assertEqual(s5.as_value().init, 0b00001) + self.assertEqual(s5.as_value().reset_less, True) + self.assertEqual(s5.as_value().attrs, {"x": "y"}) + def test_bug_837_array_layout_getitem_str(self): with self.assertRaisesRegex(TypeError,