1
0
mirror of https://github.com/myhdl/myhdl.git synced 2025-01-24 21:52:56 +08:00

augmented assigns

This commit is contained in:
jand 2006-11-07 11:57:26 +00:00
parent 172ff071b4
commit 39a2603d92
5 changed files with 141 additions and 113 deletions

View File

@ -1,4 +1,4 @@
Release 0.6dev2 Release 0.6dev3
--------------- ---------------
Release 0.5.1 1-May-2006 Release 0.5.1 1-May-2006

View File

@ -1,4 +1,4 @@
MyHDL Release 0.6dev2 MyHDL Release 0.6dev3
===================== =====================
OVERVIEW OVERVIEW

View File

@ -300,6 +300,14 @@ def _convertGens(genlist, vfile):
print >> vfile print >> vfile
vfile.write(blockBuf.getvalue()); blockBuf.close() vfile.write(blockBuf.getvalue()); blockBuf.close()
class _Cast(object):
__slots__ = ["pre", "suf"]
def __init__(self):
self.pre = ""
self.suf = ""
class _ConvertVisitor(_ConversionMixin): class _ConvertVisitor(_ConversionMixin):
def __init__(self, ast, buf): def __init__(self, ast, buf):
@ -400,37 +408,46 @@ class _ConvertVisitor(_ConversionMixin):
def binaryOp(self, node, op=None): def binaryOp(self, node, op=None):
n, o, l, r = node.vhd, node.vhdOri, node.left.vhd, node.right.vhd 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 context = None
self.write(n.pre) self.write(nc.pre)
self.write("(") self.write("(")
self.write(l.pre) self.write(lc.pre)
self.visit(node.left, context) self.visit(node.left, context)
self.write(l.suf) self.write(lc.suf)
self.write(" %s " % op) self.write(" %s " % op)
self.write(r.pre) self.write(rc.pre)
self.visit(node.right, context) self.visit(node.right, context)
self.write(r.suf) self.write(rc.suf)
self.write(")") self.write(")")
self.write(n.suf) self.write(nc.suf)
def inferBinaryOpCasts(self, node, n, o, l, r, op): def inferBinaryOpCasts(self, node, n, o, l, r, op):
ns, os, ls, rs = n.size, o.size, l.size, r.size ns, os, ls, rs = n.size, o.size, l.size, r.size
ds = ns - os 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(o, vhd_int):
if isinstance(n, vhd_unsigned): 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): 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): elif isinstance(n, vhd_int):
pass pass
else: else:
self.raiseError(node, "Not implemented") self.raiseError(node, "Not implemented")
elif isinstance(l, vhd_unsigned) and isinstance(r, (vhd_int, vhd_unsigned)): elif isinstance(l, vhd_unsigned) and isinstance(r, (vhd_int, vhd_unsigned)):
if ds > 0: if ds < 0:
l.pre, l.suf = "resize(", ", %s)" % ns nc.pre, nc.suf = "resize(", ", %s)" % ns
elif ds < 0: elif ds > 0:
n.pre, n.suf = "resize(", ", %s)" % ns 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): def visitAdd(self, node, *args):
@ -453,43 +470,42 @@ class _ConvertVisitor(_ConversionMixin):
def shiftOp(self, node, op=None): def shiftOp(self, node, op=None):
pre, suf = "", "" n, l, r = node.vhd, node.left.vhd, node.right.vhd
prel, sufl = "", "" nc, lc, rc = self.inferShiftOpCasts(node, n, l, r, op)
prer, sufr = "", "" self.write(nc.pre)
if isinstance(node.vhd, vhd_type): self.write("%s(" % op)
ts = node.vhd.size self.write(lc.pre)
if isinstance(node.left.vhd, vhd_int): self.visit(node.left)
if isinstance(node.vhd, vhd_unsigned): self.write(lc.suf)
pre, suf = "to_unsigned(", ", %s)" % ts self.write(", ")
elif isinstance(node.vhd, vhd_signed): self.write(rc.pre)
pre, suf = "to_signed(", ", %s)" % ts 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: else:
raise NotImplementedError raise NotImplementedError
elif isinstance(node.left.vhd, vhd_unsigned): elif isinstance(l, vhd_unsigned):
ns = node.left.vhd.size ds = ns - ls
ds = ts - ns if isinstance(n, vhd_unsigned):
if isinstance(node.vhd, vhd_unsigned):
if ds > 0: if ds > 0:
prel, sufl = "resize(", ", %s)" % ts lc.pre, lc.suf = "resize(", ", %s)" % ns
elif ds < 0: elif ds < 0:
pre, suf = "resize(", ", %s)" % ts nc.pre, nc.suf = "resize(", ", %s)" % ns
else: else:
raise NotImplementedError raise NotImplementedError
else: else:
assert NotImplementedError assert NotImplementedError
self.write(pre) return nc, lc, rc
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)
def visitLeftShift(self, node, *args): def visitLeftShift(self, node, *args):
@ -649,60 +665,72 @@ class _ConvertVisitor(_ConversionMixin):
"%=" : "mod", "%=" : "mod",
"**=" : "**", "**=" : "**",
"|=" : "or", "|=" : "or",
">>=" : ">>>", ">>=" : "shift_right",
"<<=" : "<<", "<<=" : "shift_left",
"&=" : "and", "&=" : "and",
"^=" : "xor" "^=" : "xor"
} }
if node.op not in opmap: if node.op not in opmap:
self.raiseError(node, _error.NotSupported, self.raiseError(node, _error.NotSupported,
"augmented assignment %s" % node.op) "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] 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.visit(node.node)
self.write(" := ") self.write(" := ")
self.write(n.pre) self.write(nc.pre)
self.write(l.pre) if isFunc:
self.write("%s(" % op)
self.write(lc.pre)
self.visit(node.node) self.visit(node.node)
self.write(l.suf) self.write(lc.suf)
self.write(" %s " % op) if isFunc:
self.write(r.pre) self.write(", ")
else:
self.write(" %s " % op)
self.write(rc.pre)
self.visit(node.expr) self.visit(node.expr)
self.write(r.suf) self.write(rc.suf)
self.write(n.suf) if isFunc:
self.write(")")
self.write(nc.suf)
self.write(";") self.write(";")
def bitOpAugAssign(self, node, *args): ## def bitOpAugAssign(self, node, *args):
opmap = {"|=" : "or", ## opmap = {"|=" : "or",
"&=" : "and", ## "&=" : "and",
"^=" : "xor" ## "^=" : "xor"
} ## }
op = opmap[node.op] ## op = opmap[node.op]
prer, sufr = "", "" ## prer, sufr = "", ""
n, r = node.vhd, node.expr.vhd ## n, r = node.vhd, node.expr.vhd
ns, rs = n.size, r.size ## ns, rs = n.size, r.size
if isinstance(n, vhd_unsigned): ## if isinstance(n, vhd_unsigned):
if isinstance(r, vhd_int): ## if isinstance(r, vhd_int):
prer, sufr = "to_unsigned(", ", %s)" % ns ## prer, sufr = "to_unsigned(", ", %s)" % ns
elif isinstance(r, vhd_unsigned): ## elif isinstance(r, vhd_unsigned):
if ns != rs: ## if ns != rs:
prer, sufr = "resize(", ", %s)" % ns ## prer, sufr = "resize(", ", %s)" % ns
else: ## else:
self.raiseError(node, "Not implemeted") ## self.raiseError(node, "Not implemeted")
else: ## else:
self.raiseError(node, "Not implemeted") ## self.raiseError(node, "Not implemeted")
self.visit(node.node) ## self.visit(node.node)
self.write(" := ") ## self.write(" := ")
self.visit(node.node) ## self.visit(node.node)
self.write(" %s " % op) ## self.write(" %s " % op)
self.write(prer) ## self.write(prer)
self.visit(node.expr) ## self.visit(node.expr)
self.write(sufr) ## self.write(sufr)
self.write(";") ## self.write(";")
@ -1480,8 +1508,6 @@ class _ConvertTaskVisitor(_ConvertVisitor):
class vhd_type(object): class vhd_type(object):
def __init__(self, size=0): def __init__(self, size=0):
self.size = size self.size = size
self.pre = ""
self.suf = ""
class vhd_std_logic(vhd_type): class vhd_std_logic(vhd_type):
def __init__(self, size=0): def __init__(self, size=0):
@ -1569,7 +1595,11 @@ class _AnnotateTypesVisitor(_ConversionMixin):
self.visit(node.expr) self.visit(node.expr)
if node.op in ("|=", "&=", "^="): if node.op in ("|=", "&=", "^="):
node.expr.vhd = node.node.vhd 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: else:
r, l = node.node.vhd, node.expr.vhd r, l = node.node.vhd, node.expr.vhd
self.inferBinaryOpType(node, l, r, node.op) 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 isinstance(r, vhd_vector) and isinstance(l, vhd_vector):
if op in ('+', '-', '+=', '-='): if op in ('+', '-', '+=', '-='):
s = max(ls, rs) s = max(ls, rs)
elif op in ('%' '%='): elif op in ('%', '%='):
s = rs s = rs
elif op in ('/', '//='): elif op in ('/', '//='):
s = ls s = ls

View File

@ -325,8 +325,9 @@ def augmOps( Bitand,
Sub, Sub,
Sum, Sum,
left, right): 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):] var = intbv(0)[len(left) + len(right):]
var2 = intbv(0)[64:]
while True: while True:
yield left, right yield left, right
var[:] = left var[:] = left
@ -341,6 +342,7 @@ def augmOps( Bitand,
if right != 0: if right != 0:
var[:] = left var[:] = left
var //= right var //= right
FloorDiv.next = var
if left >= right: if left >= right:
var[:] = left var[:] = left
var -= right var -= right
@ -348,24 +350,20 @@ def augmOps( Bitand,
var[:] = left var[:] = left
var += right var += right
Sum.next = var Sum.next = var
if left < 256 and right < 26:
# FloorDiv.next = var var2[:] = left
var2 <<= right
## if left < 256 and right < 40: LeftShift.next = var2
## var[:] = left if right != 0:
## var <<= right var[:] = left
## LeftShift.next = var var %= right
Modulo.next = var
## if right != 0:
## var[:] = left
## var %= right
## Modulo.next = var
var[:] = left var[:] = left
#var *= right var *= right
#Mul.next = var Mul.next = var
## var[:] = left var[:] = left
## var >>= right var >>= right
## RightShift.next = var RightShift.next = var
@ -424,11 +422,11 @@ def augmBench(m, n):
print Bitxor print Bitxor
print Sub print Sub
print Sum print Sum
# print FloorDiv print FloorDiv
## print LeftShift print LeftShift
# print Modulo print Modulo
#print Mul print Mul
## print RightShift print RightShift
return augmops, stimulus(), check() return augmops, stimulus(), check()

View File

@ -32,7 +32,7 @@ Topic :: Scientific/Engineering :: Electronic Design Automation (EDA)
setup(name="myhdl", setup(name="myhdl",
version="0.6dev2", version="0.6dev3",
description="Python as a Hardware Description Language", description="Python as a Hardware Description Language",
long_description = "See home page.", long_description = "See home page.",
author="Jan Decaluwe", author="Jan Decaluwe",