Repository: amaranth-lang/amaranth
Pull request #1008 (2023-12-30 11:13:17)

hdl.ast: fix `Const.cast(Cat(...))`  handling for signed numbers.

codecov[bot]: ## [Codecov](https://app.codecov.io/gh/amaranth-lang/amaranth/pull/1008?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=amaranth-lang) Report
All modified and coverable lines are covered by tests :white_check_mark:
> Comparison is base [(`82d35fb`)](https://app.codecov.io/gh/amaranth-lang/amaranth/commit/82d35fb93243aa8bdc50bf13be0f4cba472d037d?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=amaranth-lang) 86.58% compared to head [(`13e351f`)](https://app.codecov.io/gh/amaranth-lang/amaranth/pull/1008?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=amaranth-lang) 86.46%.


<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##             main    #1008      +/-   ##
==========================================
- Coverage   86.58%   86.46%   -0.12%     
==========================================
  Files          41       41              
  Lines        7035     7036       +1     
  Branches     1675     1531     -144     
==========================================
- Hits         6091     6084       -7     
- Misses        782      786       +4     
- Partials      162      166       +4     
```



</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/amaranth-lang/amaranth/pull/1008?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=amaranth-lang).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=amaranth-lang).


Patch:
diff --git a/amaranth/hdl/ast.py b/amaranth/hdl/ast.py
index 2ed8801..e0a0c4f 100644
--- a/amaranth/hdl/ast.py
+++ b/amaranth/hdl/ast.py
@@ -727,7 +727,8 @@ class Const(Value):
             width = 0
             for part in obj.parts:
                 const  = Const.cast(part)
-                value |= const.value << width
+                part_value = Const(const.value, unsigned(const.width)).value
+                value |= part_value << width
                 width += len(const)
             return Const(value, width)
         else:


Test patch:
diff --git a/tests/test_hdl_ast.py b/tests/test_hdl_ast.py
index 625e0e8..be28c7a 100644
--- a/tests/test_hdl_ast.py
+++ b/tests/test_hdl_ast.py
@@ -935,6 +935,16 @@ class CatTestCase(FHDLTestCase):
                 r"specify the width explicitly using C\(2, 2\)$"):
             Cat(2)
 
+    def test_const(self):
+        a = Const.cast(Cat(Const(1, 1), Const(0, 1), Const(3, 2), Const(2, 2)))
+        self.assertEqual(a.value, 0x2d)
+        self.assertEqual(a.width, 6)
+        self.assertEqual(a.signed, False)
+        a = Const.cast(Cat(Const(-4, 8), Const(-3, 8)))
+        self.assertEqual(a.value, 0xfdfc)
+        self.assertEqual(a.width, 16)
+        self.assertEqual(a.signed, False)
+
 
 class ReplTestCase(FHDLTestCase):
     @_ignore_deprecated