From af847f746283eb16d97b67fccb16aa333f8f3560 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marcin=20Ko=C5=9Bcielnicki?= Date: Tue, 3 Dec 2019 18:33:26 +0100 Subject: [PATCH] hdl.ast: Fix width for unary minus operator on signed argument. MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit To properly represent a negation of a signed X-bit quantity we may, in general, need a signed (X+1)-bit signal — for example, negation of 3-bit -4 is 4, which is not representable in signed 3 bits. --- nmigen/hdl/ast.py | 5 +---- nmigen/test/test_hdl_ast.py | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/nmigen/hdl/ast.py b/nmigen/hdl/ast.py index 15d1d65..34c8e2b 100644 --- a/nmigen/hdl/ast.py +++ b/nmigen/hdl/ast.py @@ -556,10 +556,7 @@ class Operator(Value): if self.operator in ("+", "~"): return Shape(a_width, a_signed) if self.operator == "-": - if not a_signed: - return Shape(a_width + 1, True) - else: - return Shape(a_width, a_signed) + return Shape(a_width + 1, True) if self.operator in ("b", "r|", "r&", "r^"): return Shape(1, False) elif len(op_shapes) == 2: diff --git a/nmigen/test/test_hdl_ast.py b/nmigen/test/test_hdl_ast.py index 84f8184..d5e19f1 100644 --- a/nmigen/test/test_hdl_ast.py +++ b/nmigen/test/test_hdl_ast.py @@ -252,7 +252,7 @@ class OperatorTestCase(FHDLTestCase): self.assertEqual(v1.shape(), signed(5)) v2 = -Const(0, signed(4)) self.assertEqual(repr(v2), "(- (const 4'sd0))") - self.assertEqual(v2.shape(), signed(4)) + self.assertEqual(v2.shape(), signed(5)) def test_add(self): v1 = Const(0, unsigned(4)) + Const(0, unsigned(6)) -- 2.30.2