mirror of
https://github.com/myhdl/myhdl.git
synced 2025-01-24 21:52:56 +08:00
signed arithmetic
This commit is contained in:
parent
0dd0b8a8a9
commit
acc510f5ba
@ -48,7 +48,7 @@ __author__ = "Jan Decaluwe <jan@jandecaluwe.com>"
|
||||
__revision__ = "$Revision$"
|
||||
__date__ = "$Date$"
|
||||
|
||||
__version__ = "0.5dev2"
|
||||
__version__ = "0.5dev3"
|
||||
|
||||
import warnings
|
||||
|
||||
|
@ -123,7 +123,7 @@ class intbv(object):
|
||||
i = key
|
||||
if self._val is None:
|
||||
return intbv(None, _nrbits=1)
|
||||
res = intbv((self._val >> i) & 0x1, _nrbits=1)
|
||||
res = bool((self._val >> i) & 0x1)
|
||||
return res
|
||||
elif isinstance(key, slice):
|
||||
i, j = key.start, key.stop
|
||||
@ -271,7 +271,7 @@ class intbv(object):
|
||||
|
||||
def __and__(self, other):
|
||||
if isinstance(other, intbv):
|
||||
return intbv(self._val & other._val, _nrbits=max(self._nrbits, other._nrbits))
|
||||
return intbv(self._val & other._val)
|
||||
else:
|
||||
return intbv(self._val & other)
|
||||
def __rand__(self, other):
|
||||
@ -279,7 +279,7 @@ class intbv(object):
|
||||
|
||||
def __or__(self, other):
|
||||
if isinstance(other, intbv):
|
||||
return intbv(self._val | other._val, _nrbits=max(self._nrbits, other._nrbits))
|
||||
return intbv(self._val | other._val)
|
||||
else:
|
||||
return intbv(self._val | other)
|
||||
def __ror__(self, other):
|
||||
@ -287,7 +287,7 @@ class intbv(object):
|
||||
|
||||
def __xor__(self, other):
|
||||
if isinstance(other, intbv):
|
||||
return intbv(self._val ^ other._val, _nrbits=max(self._nrbits, other._nrbits))
|
||||
return intbv(self._val ^ other._val)
|
||||
else:
|
||||
return intbv(self._val ^ other)
|
||||
def __rxor__(self, other):
|
||||
|
@ -71,7 +71,7 @@ _error.ListElementNotUnique = "List contains Signals that are not unique to it"
|
||||
|
||||
_access = enum("INPUT", "OUTPUT", "INOUT", "UNKNOWN")
|
||||
_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):
|
||||
|
@ -160,7 +160,7 @@ def _analyzeGens(top, absnames):
|
||||
s = re.sub(r"@.*", "", s)
|
||||
s = s.lstrip()
|
||||
ast = compiler.parse(s)
|
||||
#print ast
|
||||
# print ast
|
||||
ast.sourcefile = inspect.getsourcefile(f)
|
||||
ast.lineoffset = inspect.getsourcelines(f)[1]-1
|
||||
ast.symdict = f.f_globals.copy()
|
||||
@ -609,11 +609,13 @@ class _AnalyzeVisitor(_ToVerilogMixin):
|
||||
|
||||
def visitName(self, node, access=_access.INPUT, *args):
|
||||
n = node.name
|
||||
node.obj = None
|
||||
if n not in self.refStack:
|
||||
if n in self.ast.vardict:
|
||||
self.raiseError(node, _error.UnboundLocal, n)
|
||||
self.globalRefs.add(n)
|
||||
if n in self.ast.sigdict:
|
||||
node.obj = self.ast.sigdict[n]
|
||||
if access == _access.INPUT:
|
||||
self.ast.inputs.add(n)
|
||||
elif access == _access.OUTPUT:
|
||||
@ -625,7 +627,6 @@ class _AnalyzeVisitor(_ToVerilogMixin):
|
||||
pass
|
||||
else:
|
||||
raise AssertionError
|
||||
node.obj = None
|
||||
if n in self.ast.vardict:
|
||||
node.obj = self.ast.vardict[n]
|
||||
elif n in self.ast.symdict:
|
||||
|
@ -315,9 +315,9 @@ class _ConvertVisitor(_ToVerilogMixin):
|
||||
|
||||
def binaryOp(self, node, op=None):
|
||||
self.write("(")
|
||||
self.visit(node.left)
|
||||
self.visit(node.left, _context.EXPR)
|
||||
self.write(" %s " % op)
|
||||
self.visit(node.right)
|
||||
self.visit(node.right, _context.EXPR)
|
||||
self.write(")")
|
||||
def visitAdd(self, node, *args):
|
||||
self.binaryOp(node, '+')
|
||||
@ -340,13 +340,24 @@ class _ConvertVisitor(_ToVerilogMixin):
|
||||
self.binaryOp(node, "-")
|
||||
def visitRightShift(self, node, *args):
|
||||
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):
|
||||
for n in node.nodes:
|
||||
self.checkOpWithNegIntbv(n, op)
|
||||
self.write("(")
|
||||
self.visit(node.nodes[0])
|
||||
for node in node.nodes[1:]:
|
||||
for n in node.nodes[1:]:
|
||||
self.write(" %s " % op)
|
||||
self.visit(node)
|
||||
self.visit(n, _context.EXPR)
|
||||
self.write(")")
|
||||
def visitAnd(self, node, *args):
|
||||
self.multiOp(node, '&&')
|
||||
@ -360,8 +371,9 @@ class _ConvertVisitor(_ToVerilogMixin):
|
||||
self.multiOp(node, '||')
|
||||
|
||||
def unaryOp(self, node, op):
|
||||
self.checkOpWithNegIntbv(node.expr, op)
|
||||
self.write("(%s" % op)
|
||||
self.visit(node.expr)
|
||||
self.visit(node.expr, _context.EXPR)
|
||||
self.write(")")
|
||||
def visitInvert(self, node, *args):
|
||||
self.unaryOp(node, '~')
|
||||
@ -668,26 +680,40 @@ class _ConvertVisitor(_ToVerilogMixin):
|
||||
def visitModule(self, node, *args):
|
||||
for stmt in node.node.nodes:
|
||||
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
|
||||
if n == 'False':
|
||||
self.write("1'b0")
|
||||
self.write("0")
|
||||
elif n == 'True':
|
||||
self.write("1'b1")
|
||||
self.write("1")
|
||||
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:
|
||||
self.write(n)
|
||||
elif node.name in self.ast.symdict:
|
||||
assert n 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]
|
||||
if isinstance(obj, bool):
|
||||
self.write("1'b%s" % int(obj))
|
||||
self.write("%s" % int(obj))
|
||||
elif isinstance(obj, int):
|
||||
self.write(str(obj))
|
||||
elif type(obj) is Signal:
|
||||
elif isinstance(obj, Signal):
|
||||
isBool = obj._type is bool
|
||||
assert obj._name
|
||||
self.write(obj._name)
|
||||
self.writeName(obj._name, context, isBool)
|
||||
elif _isMem(obj):
|
||||
m = _getMemInfo(obj)
|
||||
assert m.name
|
||||
@ -738,6 +764,8 @@ class _ConvertVisitor(_ToVerilogMixin):
|
||||
self.write("%s'h" % c._nrbits)
|
||||
self.write("%x" % c._val)
|
||||
return
|
||||
if node.flags == 'OP_APPLY' and _isSigned():
|
||||
self.write("$signed({1'b0, ")
|
||||
self.visit(node.expr)
|
||||
# special shortcut case for [:] slice
|
||||
if node.lower is None and node.upper is None:
|
||||
@ -753,6 +781,8 @@ class _ConvertVisitor(_ToVerilogMixin):
|
||||
else:
|
||||
self.visit(node.upper)
|
||||
self.write("]")
|
||||
if node.flags == 'OP_APPLY' and _isSigned():
|
||||
self.write("})")
|
||||
|
||||
def visitStmt(self, node, *args):
|
||||
for stmt in node.nodes:
|
||||
@ -763,11 +793,15 @@ class _ConvertVisitor(_ToVerilogMixin):
|
||||
self.write(';')
|
||||
|
||||
def visitSubscript(self, node, *args):
|
||||
if node.flags == 'OP_APPLY' and _isSigned():
|
||||
self.write("$signed({1'b0, ")
|
||||
self.visit(node.expr)
|
||||
self.write("[")
|
||||
assert len(node.subs) == 1
|
||||
self.visit(node.subs[0])
|
||||
self.write("]")
|
||||
if node.flags == 'OP_APPLY' and _isSigned():
|
||||
self.write("})")
|
||||
|
||||
def visitTuple(self, node, context=None, *args):
|
||||
assert context != None
|
||||
|
@ -506,9 +506,9 @@ class TestSignalIntBvIndexing(TestCase):
|
||||
res = sbv[i]
|
||||
resi = sbvi[i]
|
||||
self.assertEqual(res, ref)
|
||||
self.assertEqual(type(res), intbv)
|
||||
self.assertEqual(type(res), bool)
|
||||
self.assertEqual(resi, ref^1)
|
||||
self.assertEqual(type(resi), intbv)
|
||||
self.assertEqual(type(resi), bool)
|
||||
|
||||
def testGetSlice(self):
|
||||
self.seqsSetup()
|
||||
|
@ -108,9 +108,9 @@ class TestIntBvIndexing(TestCase):
|
||||
res = bv[i]
|
||||
resi = bvi[i]
|
||||
self.assertEqual(res, ref)
|
||||
self.assertEqual(type(res), intbv)
|
||||
self.assertEqual(type(res), bool)
|
||||
self.assertEqual(resi, ref^1)
|
||||
self.assertEqual(type(resi), intbv)
|
||||
self.assertEqual(type(resi), bool)
|
||||
|
||||
def testGetSlice(self):
|
||||
self.seqsSetup()
|
||||
|
@ -29,13 +29,13 @@ import unittest
|
||||
import test_bin2gray, test_inc, test_fsm, test_ops, test_NotSupported, \
|
||||
test_inc_initial, test_hec, test_loops, test_infer, test_errors, \
|
||||
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, \
|
||||
test_inc_initial, test_hec, test_loops, test_infer, test_errors, \
|
||||
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
|
||||
)
|
||||
|
||||
|
||||
|
@ -381,6 +381,7 @@ class TestUnaryOps(TestCase):
|
||||
def check():
|
||||
while 1:
|
||||
yield arg
|
||||
yield delay(1)
|
||||
self.assertEqual(Not, Not_v)
|
||||
self.assertEqual(Invert, Invert_v)
|
||||
self.assertEqual(UnaryAdd, UnaryAdd_v)
|
||||
|
@ -10,30 +10,32 @@ from myhdl import *
|
||||
|
||||
from util import setupCosimulation
|
||||
|
||||
|
||||
def binaryOps(
|
||||
## Bitand,
|
||||
## Bitand,
|
||||
## Bitor,
|
||||
## Bitxor,
|
||||
## FloorDiv,
|
||||
## LeftShift,
|
||||
## Mod,
|
||||
Mul,
|
||||
Mul,
|
||||
## Pow,
|
||||
## RightShift,
|
||||
## Sub,
|
||||
Sum,
|
||||
## EQ,
|
||||
## NE,
|
||||
## LT,
|
||||
## GT,
|
||||
## LE,
|
||||
## GE,
|
||||
## And,
|
||||
## Or,
|
||||
left, right):
|
||||
Sub,
|
||||
Sum, Sum1, Sum2, Sum3,
|
||||
EQ,
|
||||
NE,
|
||||
LT,
|
||||
GT,
|
||||
LE,
|
||||
GE,
|
||||
And,
|
||||
Or,
|
||||
left, right, bit):
|
||||
|
||||
while 1:
|
||||
yield left, right
|
||||
## Bitand.next = left & right
|
||||
## Bitand.next = left & right
|
||||
## Bitor.next = left | right
|
||||
## Bitxor.next = left ^ right
|
||||
## if right != 0:
|
||||
@ -48,22 +50,24 @@ def binaryOps(
|
||||
## # Pow.next = left ** right
|
||||
## Pow.next = 0
|
||||
## RightShift.next = left >> right
|
||||
## if left >= right:
|
||||
## Sub.next = left - right
|
||||
Sub.next = left - right
|
||||
Sum.next = left + right
|
||||
## EQ.next = left == right
|
||||
## NE.next = left != right
|
||||
## LT.next = left < right
|
||||
## GT.next = left > right
|
||||
## LE.next = left <= right
|
||||
## GE.next = left >= right
|
||||
## And.next = bool(left and right)
|
||||
## Or.next = bool(left or right)
|
||||
Sum1.next = left + right[2:]
|
||||
Sum2.next = left + right[1]
|
||||
Sum3.next = left + bit
|
||||
EQ.next = left == right
|
||||
NE.next = left != right
|
||||
LT.next = left < right
|
||||
GT.next = left > 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,
|
||||
## Bitand,
|
||||
## Bitand,
|
||||
## Bitor,
|
||||
## Bitxor,
|
||||
## FloorDiv,
|
||||
@ -72,27 +76,29 @@ def binaryOps_v(name,
|
||||
Mul,
|
||||
## Pow,
|
||||
## RightShift,
|
||||
## Sub,
|
||||
Sum,
|
||||
## EQ,
|
||||
## NE,
|
||||
## LT,
|
||||
## GT,
|
||||
## LE,
|
||||
## GE,
|
||||
## And,
|
||||
## Or,
|
||||
left, right):
|
||||
Sub,
|
||||
Sum, Sum1, Sum2, Sum3,
|
||||
EQ,
|
||||
NE,
|
||||
LT,
|
||||
GT,
|
||||
LE,
|
||||
GE,
|
||||
And,
|
||||
Or,
|
||||
left, right, bit):
|
||||
return setupCosimulation(**locals())
|
||||
|
||||
class TestBinaryOps(TestCase):
|
||||
|
||||
def binaryBench(self, Ll, Ml, Lr, Mr):
|
||||
|
||||
bit = Signal(bool(0))
|
||||
left = Signal(intbv(min=Ll, max=Ml))
|
||||
right = Signal(intbv(min=Lr, max=Mr))
|
||||
## Bitand = Signal(intbv(0)[max(m, n):])
|
||||
## Bitand_v = Signal(intbv(0)[max(m, n):])
|
||||
M = 2**14
|
||||
## 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_v = 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:])
|
||||
## RightShift = Signal(intbv(0)[m:])
|
||||
## RightShift_v = Signal(intbv(0)[m:])
|
||||
## Sub = Signal(intbv(0)[max(m, n):])
|
||||
## Sub_v = Signal(intbv(0)[max(m, n):])
|
||||
Sum = Signal(intbv(min=Ll+Lr, max=Ml+Mr-1))
|
||||
Sum_v = Signal(intbv(min=Ll+Lr, max=Ml+Mr-1))
|
||||
Sum = Signal(intbv(min=-2**14, max=2**14))
|
||||
Sum_v = Signal(intbv(min=-2**14, max=2**14))
|
||||
## EQ, NE, LT, GT, LE, GE = [Signal(bool()) for i in range(6)]
|
||||
## EQ_v, NE_v, LT_v, GT_v, LE_v, GE_v = [Signal(bool()) for i in range(6)]
|
||||
## And, Or = [Signal(bool()) for i in range(2)]
|
||||
## And_v, Or_v, = [Signal(bool()) for i in range(2)]
|
||||
Sub, Sub1, Sub2, Sub3 = [Signal(intbv(min=-M, max=M)) for i in range(4)]
|
||||
Sub_v, Sub1_v, Sub2_v, Sub3_v = [Signal(intbv(min=-M, max=M)) for i in range(4)]
|
||||
Sum, Sum1, Sum2, Sum3 = [Signal(intbv(min=-M, max=M)) for i in range(4)]
|
||||
Sum_v, Sum1_v, Sum2_v, Sum3_v = [Signal(intbv(min=-M, max=M)) for i in range(4)]
|
||||
EQ, NE, LT, GT, LE, GE = [Signal(bool()) for i in range(6)]
|
||||
EQ_v, NE_v, LT_v, GT_v, LE_v, GE_v = [Signal(bool()) for i in range(6)]
|
||||
And, Or = [Signal(bool()) for i in range(2)]
|
||||
And_v, Or_v, = [Signal(bool()) for i in range(2)]
|
||||
|
||||
binops = toVerilog(binaryOps,
|
||||
## Bitand,
|
||||
@ -130,17 +134,17 @@ class TestBinaryOps(TestCase):
|
||||
Mul,
|
||||
## Pow,
|
||||
## RightShift,
|
||||
## Sub,
|
||||
Sum,
|
||||
## EQ,
|
||||
## NE,
|
||||
## LT,
|
||||
## GT,
|
||||
## LE,
|
||||
## GE,
|
||||
## And,
|
||||
## Or,
|
||||
left, right)
|
||||
Sub,
|
||||
Sum, Sum1, Sum2, Sum3,
|
||||
EQ,
|
||||
NE,
|
||||
LT,
|
||||
GT,
|
||||
LE,
|
||||
GE,
|
||||
And,
|
||||
Or,
|
||||
left, right, bit)
|
||||
binops_v = binaryOps_v(binaryOps.func_name,
|
||||
## Bitand_v,
|
||||
## Bitor_v,
|
||||
@ -151,16 +155,290 @@ class TestBinaryOps(TestCase):
|
||||
Mul_v,
|
||||
## Pow_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,
|
||||
## EQ_v,
|
||||
## NE_v,
|
||||
## LT_v,
|
||||
## GT_v,
|
||||
## LE_v,
|
||||
## GE_v,
|
||||
## And_v,
|
||||
## Or_v,
|
||||
left, right)
|
||||
|
||||
def stimulus():
|
||||
@ -177,11 +455,7 @@ class TestBinaryOps(TestCase):
|
||||
while 1:
|
||||
yield left, right
|
||||
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 "%s %s %s %s" % (left, right, Or, Or_v)
|
||||
## self.assertEqual(Bitand, Bitand_v)
|
||||
## self.assertEqual(Bitor, Bitor_v)
|
||||
## self.assertEqual(Bitxor, Bitxor_v)
|
||||
@ -189,33 +463,25 @@ class TestBinaryOps(TestCase):
|
||||
## 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(Sub, Sub_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):
|
||||
for Ll, Ml, Lr, Mr in ( (-128, 128, -128, 128),
|
||||
def testAugmOps(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)
|
||||
sim = self.augmBench(Ll, Ml, Lr, Mr)
|
||||
Simulation(sim).run()
|
||||
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
Loading…
x
Reference in New Issue
Block a user