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

signed arithmetic

This commit is contained in:
jand 2005-11-04 09:07:13 +00:00
parent 0dd0b8a8a9
commit acc510f5ba
11 changed files with 419 additions and 117 deletions

View File

@ -48,7 +48,7 @@ __author__ = "Jan Decaluwe <jan@jandecaluwe.com>"
__revision__ = "$Revision$" __revision__ = "$Revision$"
__date__ = "$Date$" __date__ = "$Date$"
__version__ = "0.5dev2" __version__ = "0.5dev3"
import warnings import warnings

View File

@ -123,7 +123,7 @@ class intbv(object):
i = key i = key
if self._val is None: if self._val is None:
return intbv(None, _nrbits=1) return intbv(None, _nrbits=1)
res = intbv((self._val >> i) & 0x1, _nrbits=1) res = bool((self._val >> i) & 0x1)
return res return res
elif isinstance(key, slice): elif isinstance(key, slice):
i, j = key.start, key.stop i, j = key.start, key.stop
@ -271,7 +271,7 @@ class intbv(object):
def __and__(self, other): def __and__(self, other):
if isinstance(other, intbv): if isinstance(other, intbv):
return intbv(self._val & other._val, _nrbits=max(self._nrbits, other._nrbits)) return intbv(self._val & other._val)
else: else:
return intbv(self._val & other) return intbv(self._val & other)
def __rand__(self, other): def __rand__(self, other):
@ -279,7 +279,7 @@ class intbv(object):
def __or__(self, other): def __or__(self, other):
if isinstance(other, intbv): if isinstance(other, intbv):
return intbv(self._val | other._val, _nrbits=max(self._nrbits, other._nrbits)) return intbv(self._val | other._val)
else: else:
return intbv(self._val | other) return intbv(self._val | other)
def __ror__(self, other): def __ror__(self, other):
@ -287,7 +287,7 @@ class intbv(object):
def __xor__(self, other): def __xor__(self, other):
if isinstance(other, intbv): if isinstance(other, intbv):
return intbv(self._val ^ other._val, _nrbits=max(self._nrbits, other._nrbits)) return intbv(self._val ^ other._val)
else: else:
return intbv(self._val ^ other) return intbv(self._val ^ other)
def __rxor__(self, other): def __rxor__(self, other):

View File

@ -71,7 +71,7 @@ _error.ListElementNotUnique = "List contains Signals that are not unique to it"
_access = enum("INPUT", "OUTPUT", "INOUT", "UNKNOWN") _access = enum("INPUT", "OUTPUT", "INOUT", "UNKNOWN")
_kind = enum("NORMAL", "DECLARATION", "ALWAYS", "INITIAL", "ALWAYS_COMB", "SIMPLE_ALWAYS_COMB", "ALWAYS_DECO", "TASK", "REG") _kind = enum("NORMAL", "DECLARATION", "ALWAYS", "INITIAL", "ALWAYS_COMB", "SIMPLE_ALWAYS_COMB", "ALWAYS_DECO", "TASK", "REG")
_context = enum("BOOLEAN", "YIELD", "PRINT", "UNKNOWN") _context = enum("BOOLEAN", "YIELD", "PRINT" ,"EXPR", "UNKNOWN")
class _ToVerilogMixin(object): class _ToVerilogMixin(object):

View File

@ -160,7 +160,7 @@ def _analyzeGens(top, absnames):
s = re.sub(r"@.*", "", s) s = re.sub(r"@.*", "", s)
s = s.lstrip() s = s.lstrip()
ast = compiler.parse(s) ast = compiler.parse(s)
#print ast # print ast
ast.sourcefile = inspect.getsourcefile(f) ast.sourcefile = inspect.getsourcefile(f)
ast.lineoffset = inspect.getsourcelines(f)[1]-1 ast.lineoffset = inspect.getsourcelines(f)[1]-1
ast.symdict = f.f_globals.copy() ast.symdict = f.f_globals.copy()
@ -609,11 +609,13 @@ class _AnalyzeVisitor(_ToVerilogMixin):
def visitName(self, node, access=_access.INPUT, *args): def visitName(self, node, access=_access.INPUT, *args):
n = node.name n = node.name
node.obj = None
if n not in self.refStack: if n not in self.refStack:
if n in self.ast.vardict: if n in self.ast.vardict:
self.raiseError(node, _error.UnboundLocal, n) self.raiseError(node, _error.UnboundLocal, n)
self.globalRefs.add(n) self.globalRefs.add(n)
if n in self.ast.sigdict: if n in self.ast.sigdict:
node.obj = self.ast.sigdict[n]
if access == _access.INPUT: if access == _access.INPUT:
self.ast.inputs.add(n) self.ast.inputs.add(n)
elif access == _access.OUTPUT: elif access == _access.OUTPUT:
@ -625,7 +627,6 @@ class _AnalyzeVisitor(_ToVerilogMixin):
pass pass
else: else:
raise AssertionError raise AssertionError
node.obj = None
if n in self.ast.vardict: if n in self.ast.vardict:
node.obj = self.ast.vardict[n] node.obj = self.ast.vardict[n]
elif n in self.ast.symdict: elif n in self.ast.symdict:

View File

@ -315,9 +315,9 @@ class _ConvertVisitor(_ToVerilogMixin):
def binaryOp(self, node, op=None): def binaryOp(self, node, op=None):
self.write("(") self.write("(")
self.visit(node.left) self.visit(node.left, _context.EXPR)
self.write(" %s " % op) self.write(" %s " % op)
self.visit(node.right) self.visit(node.right, _context.EXPR)
self.write(")") self.write(")")
def visitAdd(self, node, *args): def visitAdd(self, node, *args):
self.binaryOp(node, '+') self.binaryOp(node, '+')
@ -340,13 +340,24 @@ class _ConvertVisitor(_ToVerilogMixin):
self.binaryOp(node, "-") self.binaryOp(node, "-")
def visitRightShift(self, node, *args): def visitRightShift(self, node, *args):
self.binaryOp(node, '>>') self.binaryOp(node, '>>')
def checkOpWithNegIntbv(self, node, op):
if op in ("+", "-", "*", "&&", "||", "!"):
return
if isinstance(node, astNode.Name):
o = node.obj
if isinstance(o, (Signal, intbv)) and o.min is not None and o.min < 0:
self.raiseError(node, _error.NotSupported,
"negative intbv with operator %s" % op)
def multiOp(self, node, op): def multiOp(self, node, op):
for n in node.nodes:
self.checkOpWithNegIntbv(n, op)
self.write("(") self.write("(")
self.visit(node.nodes[0]) self.visit(node.nodes[0])
for node in node.nodes[1:]: for n in node.nodes[1:]:
self.write(" %s " % op) self.write(" %s " % op)
self.visit(node) self.visit(n, _context.EXPR)
self.write(")") self.write(")")
def visitAnd(self, node, *args): def visitAnd(self, node, *args):
self.multiOp(node, '&&') self.multiOp(node, '&&')
@ -360,8 +371,9 @@ class _ConvertVisitor(_ToVerilogMixin):
self.multiOp(node, '||') self.multiOp(node, '||')
def unaryOp(self, node, op): def unaryOp(self, node, op):
self.checkOpWithNegIntbv(node.expr, op)
self.write("(%s" % op) self.write("(%s" % op)
self.visit(node.expr) self.visit(node.expr, _context.EXPR)
self.write(")") self.write(")")
def visitInvert(self, node, *args): def visitInvert(self, node, *args):
self.unaryOp(node, '~') self.unaryOp(node, '~')
@ -668,26 +680,40 @@ class _ConvertVisitor(_ToVerilogMixin):
def visitModule(self, node, *args): def visitModule(self, node, *args):
for stmt in node.node.nodes: for stmt in node.node.nodes:
self.visit(stmt) self.visit(stmt)
def writeName(self, name, context, isBool):
addSignBit = isBool and _isSigned() and context == _context.EXPR
if addSignBit:
self.write("$signed({1'b0, ")
self.write(name)
if addSignBit:
self.write("})")
def visitName(self, node, *args): def visitName(self, node, context=None, *args):
n = node.name n = node.name
if n == 'False': if n == 'False':
self.write("1'b0") self.write("0")
elif n == 'True': elif n == 'True':
self.write("1'b1") self.write("1")
elif n in self.ast.vardict: elif n in self.ast.vardict:
self.write(n) obj = self.ast.vardict[n]
isBool = isinstance(obj, bool)
self.writeName(n, context, isBool)
elif n in self.ast.argnames: elif n in self.ast.argnames:
self.write(n) assert n in self.ast.symdict
elif node.name in self.ast.symdict: obj = self.ast.symdict[n]
isBool = isinstance(obj, bool) or (isinstance(obj, Signal) and obj._type is bool)
self.writeName(n, context, isBool)
elif n in self.ast.symdict:
obj = self.ast.symdict[n] obj = self.ast.symdict[n]
if isinstance(obj, bool): if isinstance(obj, bool):
self.write("1'b%s" % int(obj)) self.write("%s" % int(obj))
elif isinstance(obj, int): elif isinstance(obj, int):
self.write(str(obj)) self.write(str(obj))
elif type(obj) is Signal: elif isinstance(obj, Signal):
isBool = obj._type is bool
assert obj._name assert obj._name
self.write(obj._name) self.writeName(obj._name, context, isBool)
elif _isMem(obj): elif _isMem(obj):
m = _getMemInfo(obj) m = _getMemInfo(obj)
assert m.name assert m.name
@ -738,6 +764,8 @@ class _ConvertVisitor(_ToVerilogMixin):
self.write("%s'h" % c._nrbits) self.write("%s'h" % c._nrbits)
self.write("%x" % c._val) self.write("%x" % c._val)
return return
if node.flags == 'OP_APPLY' and _isSigned():
self.write("$signed({1'b0, ")
self.visit(node.expr) self.visit(node.expr)
# special shortcut case for [:] slice # special shortcut case for [:] slice
if node.lower is None and node.upper is None: if node.lower is None and node.upper is None:
@ -753,6 +781,8 @@ class _ConvertVisitor(_ToVerilogMixin):
else: else:
self.visit(node.upper) self.visit(node.upper)
self.write("]") self.write("]")
if node.flags == 'OP_APPLY' and _isSigned():
self.write("})")
def visitStmt(self, node, *args): def visitStmt(self, node, *args):
for stmt in node.nodes: for stmt in node.nodes:
@ -763,11 +793,15 @@ class _ConvertVisitor(_ToVerilogMixin):
self.write(';') self.write(';')
def visitSubscript(self, node, *args): def visitSubscript(self, node, *args):
if node.flags == 'OP_APPLY' and _isSigned():
self.write("$signed({1'b0, ")
self.visit(node.expr) self.visit(node.expr)
self.write("[") self.write("[")
assert len(node.subs) == 1 assert len(node.subs) == 1
self.visit(node.subs[0]) self.visit(node.subs[0])
self.write("]") self.write("]")
if node.flags == 'OP_APPLY' and _isSigned():
self.write("})")
def visitTuple(self, node, context=None, *args): def visitTuple(self, node, context=None, *args):
assert context != None assert context != None

View File

@ -506,9 +506,9 @@ class TestSignalIntBvIndexing(TestCase):
res = sbv[i] res = sbv[i]
resi = sbvi[i] resi = sbvi[i]
self.assertEqual(res, ref) self.assertEqual(res, ref)
self.assertEqual(type(res), intbv) self.assertEqual(type(res), bool)
self.assertEqual(resi, ref^1) self.assertEqual(resi, ref^1)
self.assertEqual(type(resi), intbv) self.assertEqual(type(resi), bool)
def testGetSlice(self): def testGetSlice(self):
self.seqsSetup() self.seqsSetup()

View File

@ -108,9 +108,9 @@ class TestIntBvIndexing(TestCase):
res = bv[i] res = bv[i]
resi = bvi[i] resi = bvi[i]
self.assertEqual(res, ref) self.assertEqual(res, ref)
self.assertEqual(type(res), intbv) self.assertEqual(type(res), bool)
self.assertEqual(resi, ref^1) self.assertEqual(resi, ref^1)
self.assertEqual(type(resi), intbv) self.assertEqual(type(resi), bool)
def testGetSlice(self): def testGetSlice(self):
self.seqsSetup() self.seqsSetup()

View File

@ -29,13 +29,13 @@ import unittest
import test_bin2gray, test_inc, test_fsm, test_ops, test_NotSupported, \ import test_bin2gray, test_inc, test_fsm, test_ops, test_NotSupported, \
test_inc_initial, test_hec, test_loops, test_infer, test_errors, \ test_inc_initial, test_hec, test_loops, test_infer, test_errors, \
test_RandomScrambler, test_beh, test_GrayInc, test_misc, \ test_RandomScrambler, test_beh, test_GrayInc, test_misc, \
test_ram, test_rom, test_always_comb, test_dec test_ram, test_rom, test_always_comb, test_dec, test_signed
modules = (test_bin2gray, test_inc, test_fsm, test_ops, test_NotSupported, \ modules = (test_bin2gray, test_inc, test_fsm, test_ops, test_NotSupported, \
test_inc_initial, test_hec, test_loops, test_infer, test_errors, \ test_inc_initial, test_hec, test_loops, test_infer, test_errors, \
test_RandomScrambler, test_beh, test_GrayInc, test_misc, \ test_RandomScrambler, test_beh, test_GrayInc, test_misc, \
test_ram, test_rom, test_always_comb, test_dec test_ram, test_rom, test_always_comb, test_dec, test_signed
) )

View File

@ -381,6 +381,7 @@ class TestUnaryOps(TestCase):
def check(): def check():
while 1: while 1:
yield arg yield arg
yield delay(1)
self.assertEqual(Not, Not_v) self.assertEqual(Not, Not_v)
self.assertEqual(Invert, Invert_v) self.assertEqual(Invert, Invert_v)
self.assertEqual(UnaryAdd, UnaryAdd_v) self.assertEqual(UnaryAdd, UnaryAdd_v)

View File

@ -10,30 +10,32 @@ from myhdl import *
from util import setupCosimulation from util import setupCosimulation
def binaryOps( def binaryOps(
## Bitand, ## Bitand,
## Bitor, ## Bitor,
## Bitxor, ## Bitxor,
## FloorDiv, ## FloorDiv,
## LeftShift, ## LeftShift,
## Mod, ## Mod,
Mul, Mul,
## Pow, ## Pow,
## RightShift, ## RightShift,
## Sub, Sub,
Sum, Sum, Sum1, Sum2, Sum3,
## EQ, EQ,
## NE, NE,
## LT, LT,
## GT, GT,
## LE, LE,
## GE, GE,
## And, And,
## Or, Or,
left, right): left, right, bit):
while 1: while 1:
yield left, right yield left, right
## Bitand.next = left & right ## Bitand.next = left & right
## Bitor.next = left | right ## Bitor.next = left | right
## Bitxor.next = left ^ right ## Bitxor.next = left ^ right
## if right != 0: ## if right != 0:
@ -48,22 +50,24 @@ def binaryOps(
## # Pow.next = left ** right ## # Pow.next = left ** right
## Pow.next = 0 ## Pow.next = 0
## RightShift.next = left >> right ## RightShift.next = left >> right
## if left >= right: Sub.next = left - right
## Sub.next = left - right
Sum.next = left + right Sum.next = left + right
## EQ.next = left == right Sum1.next = left + right[2:]
## NE.next = left != right Sum2.next = left + right[1]
## LT.next = left < right Sum3.next = left + bit
## GT.next = left > right EQ.next = left == right
## LE.next = left <= right NE.next = left != right
## GE.next = left >= right LT.next = left < right
## And.next = bool(left and right) GT.next = left > right
## Or.next = bool(left or right) LE.next = left <= right
GE.next = left >= right
And.next = bool(left and right)
Or.next = bool(left or right)
def binaryOps_v(name, def binaryOps_v(name,
## Bitand, ## Bitand,
## Bitor, ## Bitor,
## Bitxor, ## Bitxor,
## FloorDiv, ## FloorDiv,
@ -72,27 +76,29 @@ def binaryOps_v(name,
Mul, Mul,
## Pow, ## Pow,
## RightShift, ## RightShift,
## Sub, Sub,
Sum, Sum, Sum1, Sum2, Sum3,
## EQ, EQ,
## NE, NE,
## LT, LT,
## GT, GT,
## LE, LE,
## GE, GE,
## And, And,
## Or, Or,
left, right): left, right, bit):
return setupCosimulation(**locals()) return setupCosimulation(**locals())
class TestBinaryOps(TestCase): class TestBinaryOps(TestCase):
def binaryBench(self, Ll, Ml, Lr, Mr): def binaryBench(self, Ll, Ml, Lr, Mr):
bit = Signal(bool(0))
left = Signal(intbv(min=Ll, max=Ml)) left = Signal(intbv(min=Ll, max=Ml))
right = Signal(intbv(min=Lr, max=Mr)) right = Signal(intbv(min=Lr, max=Mr))
## Bitand = Signal(intbv(0)[max(m, n):]) M = 2**14
## Bitand_v = Signal(intbv(0)[max(m, n):]) ## Bitand = Signal(intbv(0, min=-2**17, max=2**17))
## Bitand_v = Signal(intbv(0, min=-2**17, max=2**17))
## Bitor = Signal(intbv(0)[max(m, n):]) ## Bitor = Signal(intbv(0)[max(m, n):])
## Bitor_v = Signal(intbv(0)[max(m, n):]) ## Bitor_v = Signal(intbv(0)[max(m, n):])
## Bitxor = Signal(intbv(0)[max(m, n):]) ## Bitxor = Signal(intbv(0)[max(m, n):])
@ -109,16 +115,14 @@ class TestBinaryOps(TestCase):
## Pow_v = Signal(intbv(0)[64:]) ## Pow_v = Signal(intbv(0)[64:])
## RightShift = Signal(intbv(0)[m:]) ## RightShift = Signal(intbv(0)[m:])
## RightShift_v = Signal(intbv(0)[m:]) ## RightShift_v = Signal(intbv(0)[m:])
## Sub = Signal(intbv(0)[max(m, n):]) Sub, Sub1, Sub2, Sub3 = [Signal(intbv(min=-M, max=M)) for i in range(4)]
## Sub_v = Signal(intbv(0)[max(m, n):]) Sub_v, Sub1_v, Sub2_v, Sub3_v = [Signal(intbv(min=-M, max=M)) for i in range(4)]
Sum = Signal(intbv(min=Ll+Lr, max=Ml+Mr-1)) Sum, Sum1, Sum2, Sum3 = [Signal(intbv(min=-M, max=M)) for i in range(4)]
Sum_v = Signal(intbv(min=Ll+Lr, max=Ml+Mr-1)) Sum_v, Sum1_v, Sum2_v, Sum3_v = [Signal(intbv(min=-M, max=M)) for i in range(4)]
Sum = Signal(intbv(min=-2**14, max=2**14)) EQ, NE, LT, GT, LE, GE = [Signal(bool()) for i in range(6)]
Sum_v = Signal(intbv(min=-2**14, max=2**14)) EQ_v, NE_v, LT_v, GT_v, LE_v, GE_v = [Signal(bool()) for i in range(6)]
## EQ, NE, LT, GT, LE, GE = [Signal(bool()) for i in range(6)] And, Or = [Signal(bool()) for i in range(2)]
## EQ_v, NE_v, LT_v, GT_v, LE_v, GE_v = [Signal(bool()) for i in range(6)] And_v, Or_v, = [Signal(bool()) for i in range(2)]
## And, Or = [Signal(bool()) for i in range(2)]
## And_v, Or_v, = [Signal(bool()) for i in range(2)]
binops = toVerilog(binaryOps, binops = toVerilog(binaryOps,
## Bitand, ## Bitand,
@ -130,17 +134,17 @@ class TestBinaryOps(TestCase):
Mul, Mul,
## Pow, ## Pow,
## RightShift, ## RightShift,
## Sub, Sub,
Sum, Sum, Sum1, Sum2, Sum3,
## EQ, EQ,
## NE, NE,
## LT, LT,
## GT, GT,
## LE, LE,
## GE, GE,
## And, And,
## Or, Or,
left, right) left, right, bit)
binops_v = binaryOps_v(binaryOps.func_name, binops_v = binaryOps_v(binaryOps.func_name,
## Bitand_v, ## Bitand_v,
## Bitor_v, ## Bitor_v,
@ -151,16 +155,290 @@ class TestBinaryOps(TestCase):
Mul_v, Mul_v,
## Pow_v, ## Pow_v,
## RightShift_v, ## RightShift_v,
## Sub_v, Sub_v,
Sum_v, Sum1_v, Sum2_v, Sum3_v,
EQ_v,
NE_v,
LT_v,
GT_v,
LE_v,
GE_v,
And_v,
Or_v,
left, right, bit)
def stimulus():
for i in range(100):
bit.next = False
left.next = randrange(Ll, Ml)
right.next = randrange(Lr, Mr)
yield delay(10)
for j, k in ((Ll, Lr), (Ml-1, Mr-1), (Ll, Mr-1), (Ml-1, Lr)):
left.next = j
right.next = k
yield delay(10)
def check():
while 1:
yield left, right
bit.next = not bit
yield delay(1)
#print "%s %s %s %s" % (left, right, Mul, Mul_v)
#print "%s %s %s %s" % (left, right, bin(Mul), bin(Mul_v))
#print "%s %s %s %s" % (left, right, Sum, Sum_v)
#print "%s %s %s %s" % (left, right, bin(Sum), bin(Sum_v))
## print left
## print right
## print bin(left)
## print bin(right)
## print bin(Bitand)
## print bin(Bitand_v)
## print Bitand
## print Bitand_v
## self.assertEqual(Bitand, Bitand_v)
#w = len(Bitand)
#self.assertEqual(bin(Bitand, w), bin(Bitand_v,w ))
## self.assertEqual(Bitor, Bitor_v)
## self.assertEqual(Bitxor, Bitxor_v)
## self.assertEqual(FloorDiv, FloorDiv_v)
## self.assertEqual(LeftShift, LeftShift_v)
## self.assertEqual(Mod, Mod_v)
self.assertEqual(Mul, Mul_v)
# self.assertEqual(Pow, Pow_v)
## self.assertEqual(RightShift, RightShift_v)
self.assertEqual(Sub, Sub_v)
self.assertEqual(Sum, Sum_v)
self.assertEqual(Sum1, Sum1_v)
self.assertEqual(Sum2, Sum2_v)
self.assertEqual(Sum3, Sum3_v)
self.assertEqual(EQ, EQ_v)
self.assertEqual(NE, NE_v)
self.assertEqual(LT, LT_v)
self.assertEqual(GT, GT_v)
self.assertEqual(LE, LE_v)
self.assertEqual(GE, GE_v)
self.assertEqual(And, And_v)
self.assertEqual(Or, Or_v)
return binops, binops_v, stimulus(), check()
def testBinaryOps(self):
for Ll, Ml, Lr, Mr in ( (-128, 128, -128, 128),
(-53, 25, -23, 123),
(-23, 145, -66, 12),
(23, 34, -34, -16),
(-54, -20, 45, 73),
(-25, -12, -123, -66),
):
sim = self.binaryBench(Ll, Ml, Lr, Mr)
Simulation(sim).run()
def unaryOps(
Not,
Invert,
UnaryAdd,
UnarySub,
arg):
while 1:
yield arg
Not.next = not arg
# Invert.next = ~arg
UnaryAdd.next = +arg
UnarySub.next = --arg
def unaryOps_v(name,
Not,
Invert,
UnaryAdd,
UnarySub,
arg):
return setupCosimulation(**locals())
class TestUnaryOps(TestCase):
def unaryBench(self, m):
M = 2**m
arg = Signal(intbv(0, min=-M, max=+M))
Not = Signal(bool(0))
Not_v = Signal(bool(0))
Invert = Signal(intbv(0, min=-M, max=+M))
Invert_v = Signal(intbv(0, min=-M, max=+M))
UnaryAdd = Signal(intbv(0, min=-M, max=+M))
UnaryAdd_v = Signal(intbv(0, min=-M, max=+M))
UnarySub = Signal(intbv(0, min=-M, max=+M))
UnarySub_v = Signal(intbv(0, min=-M, max=+M))
unaryops = toVerilog(unaryOps,
Not,
Invert,
UnaryAdd,
UnarySub,
arg)
unaryops_v = unaryOps_v(unaryOps.func_name,
Not_v,
Invert_v,
UnaryAdd_v,
UnarySub_v,
arg)
def stimulus():
for i in range(-M, M):
arg.next = intbv(i)
yield delay(10)
for i in range(100):
arg.next = randrange(-M, M)
yield delay(10)
raise StopSimulation
def check():
while 1:
yield arg
yield delay(1)
self.assertEqual(Not, Not_v)
#self.assertEqual(Invert, Invert_v)
self.assertEqual(UnaryAdd, UnaryAdd_v)
self.assertEqual(UnarySub, UnarySub_v)
return unaryops, unaryops_v, stimulus(), check()
def testUnaryOps(self):
for m in (4, 7):
sim = self.unaryBench(m)
Simulation(sim).run()
def augmOps(
## Bitand,
## Bitor,
## Bitxor,
## FloorDiv,
## LeftShift,
## Mod,
Mul,
## RightShift,
Sub,
Sum,
left, right):
var = intbv(0, min=-2**17, max=+2**17)
while 1:
yield left, right
## var[:] = left
## var &= right
## Bitand.next = var
## var[:] = left
## var |= right
## Bitor.next = var
## var[:] = left
## var ^= left
## Bitxor.next = var
## if right != 0:
## var[:] = left
## var //= right
## FloorDiv.next = var
## if left < 256 and right < 40:
## var[:] = left
## var <<= right
## LeftShift.next = var
## if right != 0:
## var[:] = left
## var %= right
## Mod.next = var
var[:] = left
var *= right
Mul.next = var
## var[:] = left
## var >>= right
## RightShift.next = var
var[:] = left
var -= right
Sub.next = var
var[:] = left
var += right
Sum.next = var
def augmOps_v( name,
## Bitand,
## Bitor,
## Bitxor,
## FloorDiv,
## LeftShift,
## Mod,
Mul,
## RightShift,
Sub,
Sum,
left, right):
return setupCosimulation(**locals())
class TestAugmOps(TestCase):
def augmBench(self, Ll, Ml, Lr, Mr):
left = Signal(intbv(min=Ll, max=Ml))
right = Signal(intbv(min=Lr, max=Mr))
M = 2**17
## Bitand = Signal(intbv(0)[max(m, n):])
## Bitand_v = Signal(intbv(0)[max(m, n):])
## Bitor = Signal(intbv(0)[max(m, n):])
## Bitor_v = Signal(intbv(0)[max(m, n):])
## Bitxor = Signal(intbv(0)[max(m, n):])
## Bitxor_v = Signal(intbv(0)[max(m, n):])
## FloorDiv = Signal(intbv(0)[m:])
## FloorDiv_v = Signal(intbv(0)[m:])
## LeftShift = Signal(intbv(0)[64:])
## LeftShift_v = Signal(intbv(0)[64:])
## Mod = Signal(intbv(0)[m:])
## Mod_v = Signal(intbv(0)[m:])
Mul = Signal(intbv(0, min=-M, max=+M))
Mul_v = Signal(intbv(0, min=-M, max=+M))
## RightShift = Signal(intbv(0)[m:])
## RightShift_v = Signal(intbv(0)[m:])
Sub = Signal(intbv(0, min=-M, max=+M))
Sub_v = Signal(intbv(0, min=-M, max=+M))
Sum = Signal(intbv(0, min=-M, max=+M))
Sum_v = Signal(intbv(0, min=-M, max=+M))
augmops = toVerilog(augmOps,
## Bitand,
## Bitor,
## Bitxor,
## FloorDiv,
## LeftShift,
## Mod,
Mul,
## RightShift,
Sub,
Sum,
left, right)
augmops_v = augmOps_v( augmOps.func_name,
## Bitand_v,
## Bitor_v,
## Bitxor_v,
## FloorDiv_v,
## LeftShift_v,
## Mod_v,
Mul_v,
## RightShift_v,
Sub_v,
Sum_v, Sum_v,
## EQ_v,
## NE_v,
## LT_v,
## GT_v,
## LE_v,
## GE_v,
## And_v,
## Or_v,
left, right) left, right)
def stimulus(): def stimulus():
@ -177,11 +455,7 @@ class TestBinaryOps(TestCase):
while 1: while 1:
yield left, right yield left, right
yield delay(1) yield delay(1)
# print "%s %s %s %s" % (left, right, Or, Or_v)
#print "%s %s %s %s" % (left, right, Mul, Mul_v)
#print "%s %s %s %s" % (left, right, bin(Mul), bin(Mul_v))
#print "%s %s %s %s" % (left, right, Sum, Sum_v)
#print "%s %s %s %s" % (left, right, bin(Sum), bin(Sum_v))
## self.assertEqual(Bitand, Bitand_v) ## self.assertEqual(Bitand, Bitand_v)
## self.assertEqual(Bitor, Bitor_v) ## self.assertEqual(Bitor, Bitor_v)
## self.assertEqual(Bitxor, Bitxor_v) ## self.assertEqual(Bitxor, Bitxor_v)
@ -189,33 +463,25 @@ class TestBinaryOps(TestCase):
## self.assertEqual(LeftShift, LeftShift_v) ## self.assertEqual(LeftShift, LeftShift_v)
## self.assertEqual(Mod, Mod_v) ## self.assertEqual(Mod, Mod_v)
self.assertEqual(Mul, Mul_v) self.assertEqual(Mul, Mul_v)
# self.assertEqual(Pow, Pow_v)
## self.assertEqual(RightShift, RightShift_v) ## self.assertEqual(RightShift, RightShift_v)
## self.assertEqual(Sub, Sub_v) self.assertEqual(Sub, Sub_v)
self.assertEqual(Sum, Sum_v) self.assertEqual(Sum, Sum_v)
## self.assertEqual(EQ, EQ_v)
## self.assertEqual(NE, NE_v)
## self.assertEqual(LT, LT_v)
## self.assertEqual(GT, GT_v)
## self.assertEqual(LE, LE_v)
## self.assertEqual(GE, GE_v)
## self.assertEqual(And, And_v)
## self.assertEqual(Or, Or_v)
return binops, binops_v, stimulus(), check() return augmops, augmops_v, stimulus(), check()
def testBinaryOps(self): def testAugmOps(self):
for Ll, Ml, Lr, Mr in ( (-128, 128, -128, 128), for Ll, Ml, Lr, Mr in ( (-128, 128, -128, 128),
(-53, 25, -23, 123), (-53, 25, -23, 123),
(-23, 145, -66, 12), (-23, 145, -66, 12),
(23, 34, -34, -16), (23, 34, -34, -16),
(-54, -20, 45, 73), (-54, -20, 45, 73),
(-25, -12, -123, -66), (-25, -12, -123, -66),
): ):
sim = self.binaryBench(Ll, Ml, Lr, Mr) sim = self.augmBench(Ll, Ml, Lr, Mr)
Simulation(sim).run() Simulation(sim).run()
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()

View File

@ -29,7 +29,7 @@ Topic :: Scientific/Engineering :: Electronic Design Automation (EDA)
setup(name="myhdl", setup(name="myhdl",
version="0.5dev2", version="0.5dev3",
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",