From 39a2603d92e37198be12ee30fc552dee96090cff Mon Sep 17 00:00:00 2001 From: jand Date: Tue, 7 Nov 2006 11:57:26 +0000 Subject: [PATCH] augmented assigns --- CHANGES.txt | 2 +- README.txt | 2 +- myhdl/conversion/_toVHDL.py | 204 +++++++++++++++++++--------------- myhdl/test/toVHDL/test_ops.py | 44 ++++---- setup.py | 2 +- 5 files changed, 141 insertions(+), 113 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index eeea8541..e74c5107 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,4 @@ -Release 0.6dev2 +Release 0.6dev3 --------------- Release 0.5.1 1-May-2006 diff --git a/README.txt b/README.txt index d8fbe49b..a1d8ca53 100644 --- a/README.txt +++ b/README.txt @@ -1,4 +1,4 @@ -MyHDL Release 0.6dev2 +MyHDL Release 0.6dev3 ===================== OVERVIEW diff --git a/myhdl/conversion/_toVHDL.py b/myhdl/conversion/_toVHDL.py index 548f2385..8d51eeac 100644 --- a/myhdl/conversion/_toVHDL.py +++ b/myhdl/conversion/_toVHDL.py @@ -300,6 +300,14 @@ def _convertGens(genlist, vfile): print >> vfile vfile.write(blockBuf.getvalue()); blockBuf.close() + +class _Cast(object): + __slots__ = ["pre", "suf"] + def __init__(self): + self.pre = "" + self.suf = "" + + class _ConvertVisitor(_ConversionMixin): def __init__(self, ast, buf): @@ -400,37 +408,46 @@ class _ConvertVisitor(_ConversionMixin): def binaryOp(self, node, op=None): n, o, l, r = node.vhd, node.vhdOri, node.left.vhd, node.right.vhd - self.inferBinaryOpCasts(node, n, o, l, r, op) + nc, rc, lc = self.inferBinaryOpCasts(node, n, o, l, r, op) context = None - self.write(n.pre) + self.write(nc.pre) self.write("(") - self.write(l.pre) + self.write(lc.pre) self.visit(node.left, context) - self.write(l.suf) + self.write(lc.suf) self.write(" %s " % op) - self.write(r.pre) + self.write(rc.pre) self.visit(node.right, context) - self.write(r.suf) + self.write(rc.suf) self.write(")") - self.write(n.suf) + self.write(nc.suf) def inferBinaryOpCasts(self, node, n, o, l, r, op): ns, os, ls, rs = n.size, o.size, l.size, r.size ds = ns - os + # print op, ns, os, ls, rs + nc, lc, rc = [_Cast() for i in range(3)] if isinstance(o, vhd_int): if isinstance(n, vhd_unsigned): - n.pre, n.suf = "to_unsigned(", ", %s)" % node.vhd.size + nc.pre, nc.suf = "to_unsigned(", ", %s)" % node.vhd.size elif isinstance(n, vhd_signed): - n.pre, n.suf = "to_signed(", ", %s)" % node.vhd.size + nc.pre, nc.suf = "to_signed(", ", %s)" % node.vhd.size elif isinstance(n, vhd_int): pass else: self.raiseError(node, "Not implemented") elif isinstance(l, vhd_unsigned) and isinstance(r, (vhd_int, vhd_unsigned)): - if ds > 0: - l.pre, l.suf = "resize(", ", %s)" % ns - elif ds < 0: - n.pre, n.suf = "resize(", ", %s)" % ns + if ds < 0: + nc.pre, nc.suf = "resize(", ", %s)" % ns + elif ds > 0: + if op in ('+', '-', '/'): + lc.pre, lc.suf = "resize(", ", %s)" % ns + elif op in ('mod'): + nc.pre, nc.suf = "resize(", ", %s)" % ns + else: + self.raiseError(node, "Not implemented") + + return nc, lc, rc def visitAdd(self, node, *args): @@ -453,43 +470,42 @@ class _ConvertVisitor(_ConversionMixin): def shiftOp(self, node, op=None): - pre, suf = "", "" - prel, sufl = "", "" - prer, sufr = "", "" - if isinstance(node.vhd, vhd_type): - ts = node.vhd.size - if isinstance(node.left.vhd, vhd_int): - if isinstance(node.vhd, vhd_unsigned): - pre, suf = "to_unsigned(", ", %s)" % ts - elif isinstance(node.vhd, vhd_signed): - pre, suf = "to_signed(", ", %s)" % ts + n, l, r = node.vhd, node.left.vhd, node.right.vhd + nc, lc, rc = self.inferShiftOpCasts(node, n, l, r, op) + self.write(nc.pre) + self.write("%s(" % op) + self.write(lc.pre) + self.visit(node.left) + self.write(lc.suf) + self.write(", ") + self.write(rc.pre) + self.visit(node.right) + self.write(rc.suf) + self.write(")") + self.write(nc.suf) + + def inferShiftOpCasts(self, node, n, l, r, op): + ns, ls, rs = n.size, l.size, r.size + nc, lc, rc = [_Cast() for i in range(3)] + if isinstance(l, vhd_int): + if isinstance(n, vhd_unsigned): + nc.pre, nc.suf = "to_unsigned(", ", %s)" % ns + elif isinstance(n, vhd_signed): + nc.pre, nc.suf = "to_signed(", ", %s)" % ns else: raise NotImplementedError - elif isinstance(node.left.vhd, vhd_unsigned): - ns = node.left.vhd.size - ds = ts - ns - if isinstance(node.vhd, vhd_unsigned): + elif isinstance(l, vhd_unsigned): + ds = ns - ls + if isinstance(n, vhd_unsigned): if ds > 0: - prel, sufl = "resize(", ", %s)" % ts + lc.pre, lc.suf = "resize(", ", %s)" % ns elif ds < 0: - pre, suf = "resize(", ", %s)" % ts + nc.pre, nc.suf = "resize(", ", %s)" % ns else: raise NotImplementedError else: assert NotImplementedError - self.write(pre) - self.write("%s(" % op) - self.write(prel) - self.visit(node.left) - self.write(sufl) - self.write(", ") - self.write(prer) - self.visit(node.right) - self.write(sufr) - self.write(")") - self.write(suf) - - + return nc, lc, rc def visitLeftShift(self, node, *args): @@ -649,60 +665,72 @@ class _ConvertVisitor(_ConversionMixin): "%=" : "mod", "**=" : "**", "|=" : "or", - ">>=" : ">>>", - "<<=" : "<<", + ">>=" : "shift_right", + "<<=" : "shift_left", "&=" : "and", "^=" : "xor" } if node.op not in opmap: self.raiseError(node, _error.NotSupported, "augmented assignment %s" % node.op) - # XXX apparently no signed context required for augmented assigns - n, l, r, = node.vhd, node.vhd, node.expr.vhd - if node.op[:-1] in ('+', '-', '*' '%', '//'): - o = node.vhdOri - self.inferBinaryOpCasts(node, n, o, l, r, node.op[:-1]) op = opmap[node.op] + # XXX apparently no signed context required for augmented assigns + n, l, r, = node.vhd, node.node.vhd, node.expr.vhd + nc, lc, rc = [_Cast() for i in range(3)] + isFunc = False + if op in ('+', '-', '*', 'mod', '/'): + o = node.vhdOri + nc, lc, rc = self.inferBinaryOpCasts(node, n, o, l, r, op) + elif op in ("shift_left", "shift_right"): + isFunc = True + nc, lc, rc = self.inferShiftOpCasts(node, n, l, r, op) self.visit(node.node) self.write(" := ") - self.write(n.pre) - self.write(l.pre) + self.write(nc.pre) + if isFunc: + self.write("%s(" % op) + self.write(lc.pre) self.visit(node.node) - self.write(l.suf) - self.write(" %s " % op) - self.write(r.pre) + self.write(lc.suf) + if isFunc: + self.write(", ") + else: + self.write(" %s " % op) + self.write(rc.pre) self.visit(node.expr) - self.write(r.suf) - self.write(n.suf) + self.write(rc.suf) + if isFunc: + self.write(")") + self.write(nc.suf) self.write(";") - def bitOpAugAssign(self, node, *args): - opmap = {"|=" : "or", - "&=" : "and", - "^=" : "xor" - } - op = opmap[node.op] - prer, sufr = "", "" - n, r = node.vhd, node.expr.vhd - ns, rs = n.size, r.size - if isinstance(n, vhd_unsigned): - if isinstance(r, vhd_int): - prer, sufr = "to_unsigned(", ", %s)" % ns - elif isinstance(r, vhd_unsigned): - if ns != rs: - prer, sufr = "resize(", ", %s)" % ns - else: - self.raiseError(node, "Not implemeted") - else: - self.raiseError(node, "Not implemeted") - self.visit(node.node) - self.write(" := ") - self.visit(node.node) - self.write(" %s " % op) - self.write(prer) - self.visit(node.expr) - self.write(sufr) - self.write(";") +## def bitOpAugAssign(self, node, *args): +## opmap = {"|=" : "or", +## "&=" : "and", +## "^=" : "xor" +## } +## op = opmap[node.op] +## prer, sufr = "", "" +## n, r = node.vhd, node.expr.vhd +## ns, rs = n.size, r.size +## if isinstance(n, vhd_unsigned): +## if isinstance(r, vhd_int): +## prer, sufr = "to_unsigned(", ", %s)" % ns +## elif isinstance(r, vhd_unsigned): +## if ns != rs: +## prer, sufr = "resize(", ", %s)" % ns +## else: +## self.raiseError(node, "Not implemeted") +## else: +## self.raiseError(node, "Not implemeted") +## self.visit(node.node) +## self.write(" := ") +## self.visit(node.node) +## self.write(" %s " % op) +## self.write(prer) +## self.visit(node.expr) +## self.write(sufr) +## self.write(";") @@ -1480,8 +1508,6 @@ class _ConvertTaskVisitor(_ConvertVisitor): class vhd_type(object): def __init__(self, size=0): self.size = size - self.pre = "" - self.suf = "" class vhd_std_logic(vhd_type): def __init__(self, size=0): @@ -1569,7 +1595,11 @@ class _AnnotateTypesVisitor(_ConversionMixin): self.visit(node.expr) if node.op in ("|=", "&=", "^="): node.expr.vhd = node.node.vhd - node.vhdlOri = node.node.vhd + node.vhdOri = node.node.vhd + elif node.op in ("<<=", ">>="): + node.vhd = node.node.vhd + node.expr.vhd = vhd_int() + node.vhdOri = node.vhd else: r, l = node.node.vhd, node.expr.vhd self.inferBinaryOpType(node, l, r, node.op) @@ -1647,7 +1677,7 @@ class _AnnotateTypesVisitor(_ConversionMixin): if isinstance(r, vhd_vector) and isinstance(l, vhd_vector): if op in ('+', '-', '+=', '-='): s = max(ls, rs) - elif op in ('%' '%='): + elif op in ('%', '%='): s = rs elif op in ('/', '//='): s = ls diff --git a/myhdl/test/toVHDL/test_ops.py b/myhdl/test/toVHDL/test_ops.py index 709b2b8c..ceb79da0 100644 --- a/myhdl/test/toVHDL/test_ops.py +++ b/myhdl/test/toVHDL/test_ops.py @@ -325,8 +325,9 @@ def augmOps( Bitand, Sub, Sum, left, right): -## var = intbv(0)[min(64, len(left) + len(right)):] + # var = intbv(0)[min(64, len(left) + len(right)):] var = intbv(0)[len(left) + len(right):] + var2 = intbv(0)[64:] while True: yield left, right var[:] = left @@ -341,6 +342,7 @@ def augmOps( Bitand, if right != 0: var[:] = left var //= right + FloorDiv.next = var if left >= right: var[:] = left var -= right @@ -348,24 +350,20 @@ def augmOps( Bitand, var[:] = left var += right Sum.next = var - -# FloorDiv.next = var - -## if left < 256 and right < 40: -## var[:] = left -## var <<= right -## LeftShift.next = var - -## if right != 0: -## var[:] = left -## var %= right -## Modulo.next = var + if left < 256 and right < 26: + var2[:] = left + var2 <<= right + LeftShift.next = var2 + if right != 0: + var[:] = left + var %= right + Modulo.next = var var[:] = left - #var *= right - #Mul.next = var -## var[:] = left -## var >>= right -## RightShift.next = var + var *= right + Mul.next = var + var[:] = left + var >>= right + RightShift.next = var @@ -424,11 +422,11 @@ def augmBench(m, n): print Bitxor print Sub print Sum -# print FloorDiv -## print LeftShift -# print Modulo - #print Mul -## print RightShift + print FloorDiv + print LeftShift + print Modulo + print Mul + print RightShift return augmops, stimulus(), check() diff --git a/setup.py b/setup.py index 6da930eb..15d2faab 100644 --- a/setup.py +++ b/setup.py @@ -32,7 +32,7 @@ Topic :: Scientific/Engineering :: Electronic Design Automation (EDA) setup(name="myhdl", - version="0.6dev2", + version="0.6dev3", description="Python as a Hardware Description Language", long_description = "See home page.", author="Jan Decaluwe",