Repository: amaranth-lang/amaranth (python)

Issue:
`Layout.const` doesn't properly mask signed values
```
from amaranth.lib import data
from amaranth import *

class Abc(data.Struct):
    a: signed(8)
    b: signed(8)
    c: signed(8)

print(hex(Abc.const({
    'a': 1,
    'c': 1,
    'b': -1,
}).value))

print(hex(Abc.const({
    'a': 1,
    'b': -1,
    'c': 1,
}).value))
```

Result:

```
0xffff01
0x1ff01
```

Pull request description:
lib.data: fix `Layout.const` masking for signed fields.
Fixes #846.

Patch:
diff --git a/amaranth/lib/data.py b/amaranth/lib/data.py
index 237cc93..605b1fc 100644
--- a/amaranth/lib/data.py
+++ b/amaranth/lib/data.py
@@ -240,8 +240,9 @@ class Layout(ShapeCastable, metaclass=ABCMeta):
                                              key_value.shape()))
             elif not isinstance(key_value, Const):
                 key_value = Const(key_value, cast_field_shape)
-            int_value &= ~(((1 << cast_field_shape.width) - 1) << field.offset)
-            int_value |= key_value.value << field.offset
+            mask = ((1 << cast_field_shape.width) - 1) << field.offset
+            int_value &= ~mask
+            int_value |= (key_value.value << field.offset) & mask
         return Const(int_value, self.as_shape())
 
 


Test patch:
diff --git a/tests/test_lib_data.py b/tests/test_lib_data.py
index 845d240..2dd1928 100644
--- a/tests/test_lib_data.py
+++ b/tests/test_lib_data.py
@@ -398,6 +398,12 @@ class LayoutTestCase(FHDLTestCase):
         self.assertRepr(fl.const({"b": 0b10}), "(const 2'd2)")
         self.assertRepr(fl.const({"a": 0b1, "b": 0b10}), "(const 2'd2)")
 
+        sls = StructLayout({
+            "a": signed(4),
+            "b": signed(4)
+        })
+        self.assertRepr(sls.const({"b": 0, "a": -1}), "(const 8'd15)")
+
     def test_const_wrong(self):
         sl = StructLayout({"f": unsigned(1)})
         with self.assertRaisesRegex(TypeError,