hdl.ast: fix shape calculation for *.
authorwhitequark <cz@m-labs.hk>
Sat, 26 Jan 2019 00:54:02 +0000 (00:54 +0000)
committerwhitequark <cz@m-labs.hk>
Sat, 26 Jan 2019 00:56:40 +0000 (00:56 +0000)
This was carried over from Migen, and is wrong there too.
Counterexample: 1'sd-1 * 4'sd-4 = 4'sd-4 (but should be 5'sd4).

nmigen/hdl/ast.py
nmigen/test/test_hdl_ast.py

index 6e2155e7d178fb7a73249fce35625792519e9047..79b6ed758ec63b522ff91787b2f0392573d27284 100644 (file)
@@ -333,14 +333,7 @@ class Operator(Value):
                 bits, sign = self._bitwise_binary_shape(*op_shapes)
                 return bits + 1, sign
             if self.op == "*":
-                if not a_sign and not b_sign:
-                    # both operands unsigned
-                    return a_bits + b_bits, False
-                if a_sign and b_sign:
-                    # both operands signed
-                    return a_bits + b_bits - 1, True
-                # one operand signed, the other unsigned (add sign bit)
-                return a_bits + b_bits + 1 - 1, True
+                return a_bits + b_bits, a_sign or b_sign
             if self.op == "%":
                 return a_bits, a_sign
             if self.op in ("<", "<=", "==", "!=", ">", ">=", "b"):
index d1c5bb52a134e7c6d4e980c96880012485e16c59..9f20d1728032c3eeb3287a0b26939bffe5266d2e 100644 (file)
@@ -137,7 +137,7 @@ class OperatorTestCase(FHDLTestCase):
         self.assertEqual(repr(v1), "(* (const 4'd0) (const 6'd0))")
         self.assertEqual(v1.shape(), (10, False))
         v2 = Const(0, (4, True)) * Const(0, (6, True))
-        self.assertEqual(v2.shape(), (9, True))
+        self.assertEqual(v2.shape(), (10, True))
         v3 = Const(0, (4, True)) * Const(0, (4, False))
         self.assertEqual(v3.shape(), (8, True))
         v5 = 10 * Const(0, 4)