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$"
|
__revision__ = "$Revision$"
|
||||||
__date__ = "$Date$"
|
__date__ = "$Date$"
|
||||||
|
|
||||||
__version__ = "0.5dev2"
|
__version__ = "0.5dev3"
|
||||||
|
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
|
@ -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):
|
||||||
|
@ -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):
|
||||||
|
@ -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:
|
||||||
|
@ -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, '+')
|
||||||
@ -341,12 +341,23 @@ class _ConvertVisitor(_ToVerilogMixin):
|
|||||||
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, '~')
|
||||||
@ -669,25 +681,39 @@ class _ConvertVisitor(_ToVerilogMixin):
|
|||||||
for stmt in node.node.nodes:
|
for stmt in node.node.nodes:
|
||||||
self.visit(stmt)
|
self.visit(stmt)
|
||||||
|
|
||||||
def visitName(self, node, *args):
|
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, 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
|
||||||
|
@ -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()
|
||||||
|
@ -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()
|
||||||
|
@ -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
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -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,20 +155,21 @@ class TestBinaryOps(TestCase):
|
|||||||
Mul_v,
|
Mul_v,
|
||||||
## Pow_v,
|
## Pow_v,
|
||||||
## RightShift_v,
|
## RightShift_v,
|
||||||
## Sub_v,
|
Sub_v,
|
||||||
Sum_v,
|
Sum_v, Sum1_v, Sum2_v, Sum3_v,
|
||||||
## EQ_v,
|
EQ_v,
|
||||||
## NE_v,
|
NE_v,
|
||||||
## LT_v,
|
LT_v,
|
||||||
## GT_v,
|
GT_v,
|
||||||
## LE_v,
|
LE_v,
|
||||||
## GE_v,
|
GE_v,
|
||||||
## And_v,
|
And_v,
|
||||||
## Or_v,
|
Or_v,
|
||||||
left, right)
|
left, right, bit)
|
||||||
|
|
||||||
def stimulus():
|
def stimulus():
|
||||||
for i in range(100):
|
for i in range(100):
|
||||||
|
bit.next = False
|
||||||
left.next = randrange(Ll, Ml)
|
left.next = randrange(Ll, Ml)
|
||||||
right.next = randrange(Lr, Mr)
|
right.next = randrange(Lr, Mr)
|
||||||
yield delay(10)
|
yield delay(10)
|
||||||
@ -176,13 +181,24 @@ class TestBinaryOps(TestCase):
|
|||||||
def check():
|
def check():
|
||||||
while 1:
|
while 1:
|
||||||
yield left, right
|
yield left, right
|
||||||
|
bit.next = not bit
|
||||||
yield delay(1)
|
yield delay(1)
|
||||||
|
|
||||||
#print "%s %s %s %s" % (left, right, Mul, Mul_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, bin(Mul), bin(Mul_v))
|
||||||
#print "%s %s %s %s" % (left, right, Sum, Sum_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, bin(Sum), bin(Sum_v))
|
||||||
## self.assertEqual(Bitand, Bitand_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(Bitor, Bitor_v)
|
||||||
## self.assertEqual(Bitxor, Bitxor_v)
|
## self.assertEqual(Bitxor, Bitxor_v)
|
||||||
## self.assertEqual(FloorDiv, FloorDiv_v)
|
## self.assertEqual(FloorDiv, FloorDiv_v)
|
||||||
@ -191,16 +207,19 @@ class TestBinaryOps(TestCase):
|
|||||||
self.assertEqual(Mul, Mul_v)
|
self.assertEqual(Mul, Mul_v)
|
||||||
# self.assertEqual(Pow, Pow_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(Sum1, Sum1_v)
|
||||||
## self.assertEqual(NE, NE_v)
|
self.assertEqual(Sum2, Sum2_v)
|
||||||
## self.assertEqual(LT, LT_v)
|
self.assertEqual(Sum3, Sum3_v)
|
||||||
## self.assertEqual(GT, GT_v)
|
self.assertEqual(EQ, EQ_v)
|
||||||
## self.assertEqual(LE, LE_v)
|
self.assertEqual(NE, NE_v)
|
||||||
## self.assertEqual(GE, GE_v)
|
self.assertEqual(LT, LT_v)
|
||||||
## self.assertEqual(And, And_v)
|
self.assertEqual(GT, GT_v)
|
||||||
## self.assertEqual(Or, Or_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 binops, binops_v, stimulus(), check()
|
||||||
|
|
||||||
@ -217,6 +236,253 @@ class TestBinaryOps(TestCase):
|
|||||||
Simulation(sim).run()
|
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,
|
||||||
|
left, right)
|
||||||
|
|
||||||
|
def stimulus():
|
||||||
|
for i in range(100):
|
||||||
|
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
|
||||||
|
yield delay(1)
|
||||||
|
# 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)
|
||||||
|
## self.assertEqual(FloorDiv, FloorDiv_v)
|
||||||
|
## self.assertEqual(LeftShift, LeftShift_v)
|
||||||
|
## self.assertEqual(Mod, Mod_v)
|
||||||
|
self.assertEqual(Mul, Mul_v)
|
||||||
|
## self.assertEqual(RightShift, RightShift_v)
|
||||||
|
self.assertEqual(Sub, Sub_v)
|
||||||
|
self.assertEqual(Sum, Sum_v)
|
||||||
|
|
||||||
|
return augmops, augmops_v, stimulus(), check()
|
||||||
|
|
||||||
|
|
||||||
|
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.augmBench(Ll, Ml, Lr, Mr)
|
||||||
|
Simulation(sim).run()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
||||||
|
2
setup.py
2
setup.py
@ -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",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user