diff --git a/myhdl/conversion/_analyze.py b/myhdl/conversion/_analyze.py index 8a42360b..f32ef310 100644 --- a/myhdl/conversion/_analyze.py +++ b/myhdl/conversion/_analyze.py @@ -511,6 +511,8 @@ class _AnalyzeVisitor(ast.NodeVisitor, _ConversionMixin): self.access = _access.OUTPUT self.visit(target) self.access = _access.INPUT + # set attribute to detect a top-level rhs + value.isRhs = True if isinstance(target, ast.Name): node.kind = _kind.DECLARATION self.kind = _kind.DECLARATION @@ -550,6 +552,8 @@ class _AnalyzeVisitor(ast.NodeVisitor, _ConversionMixin): self.visit(value) def visit_AugAssign(self, node): + # declare node as an rhs for type inference optimization + node.isRhs = True self.access = _access.INOUT self.visit(node.target) self.access = _access.INPUT diff --git a/myhdl/conversion/_toVHDL.py b/myhdl/conversion/_toVHDL.py index 038d812a..cb0e763d 100644 --- a/myhdl/conversion/_toVHDL.py +++ b/myhdl/conversion/_toVHDL.py @@ -2078,10 +2078,14 @@ class _AnnotateTypesVisitor(ast.NodeVisitor, _ConversionMixin): left.vhd = vhd_unsigned(1) if isinstance(right.vhd, (vhd_boolean, vhd_std_logic)): right.vhd = vhd_unsigned(1) - if maybeNegative(left.vhd) and isinstance(right.vhd, vhd_unsigned): - right.vhd = vhd_signed(right.vhd.size + 1) - if isinstance(left.vhd, vhd_unsigned) and maybeNegative(right.vhd): - left.vhd = vhd_signed(left.vhd.size + 1) + if isinstance(right.vhd, vhd_unsigned): + if maybeNegative(left.vhd) or \ + (isinstance(op, ast.Sub) and not hasattr(node, 'isRhs')): + right.vhd = vhd_signed(right.vhd.size + 1) + if isinstance(left.vhd, vhd_unsigned): + if maybeNegative(right.vhd) or \ + (isinstance(op, ast.Sub) and not hasattr(node, 'isRhs')): + left.vhd = vhd_signed(left.vhd.size + 1) l, r = left.vhd, right.vhd ls, rs = l.size, r.size if isinstance(r, vhd_vector) and isinstance(l, vhd_vector): diff --git a/myhdl/conversion/_toVerilog.py b/myhdl/conversion/_toVerilog.py index 8e3916ae..e7870fb3 100644 --- a/myhdl/conversion/_toVerilog.py +++ b/myhdl/conversion/_toVerilog.py @@ -1420,6 +1420,9 @@ class _AnnotateTypesVisitor(ast.NodeVisitor, _ConversionMixin): self.visit(node.left) self.visit(node.right) node.signed = node.left.signed or node.right.signed + # special treatement of subtraction unless in a top-level rhs + if isinstance(node.op, ast.Sub) and not hasattr(node, 'isRhs'): + node.signed = True def visit_BoolOp(self, node): for n in node.values: diff --git a/myhdl/test/bugs/test_bug_39.py b/myhdl/test/bugs/test_bug_39.py index 9d137d29..ef6c6789 100644 --- a/myhdl/test/bugs/test_bug_39.py +++ b/myhdl/test/bugs/test_bug_39.py @@ -29,7 +29,7 @@ def dut(): return logic, check -def test_tb(): +def test_bug_39(): assert verify(dut) == 0 diff --git a/myhdl/test/bugs/test_bug_aj1s.py b/myhdl/test/bugs/test_bug_aj1s.py new file mode 100644 index 00000000..53aab877 --- /dev/null +++ b/myhdl/test/bugs/test_bug_aj1s.py @@ -0,0 +1,24 @@ +from myhdl import * +from myhdl.conversion import verify + +def dut(): + + count = Signal(intbv(0, min=0, max=98)) + + @instance + def seq(): + count.next = 50 + for i in range(300): + yield delay(10) + print count + if count-1 < 0: + count.next = 97 + else: + count.next = count-1 + + return seq + + +def test_bug_aj1s(): + assert verify(dut) == 0 +