mirror of
https://github.com/myhdl/myhdl.git
synced 2025-01-24 21:52:56 +08:00
type inference and tests
This commit is contained in:
parent
beaca96d74
commit
24c8fbe188
@ -59,11 +59,16 @@ _error.SigMultipleDriven = "Signal has multiple drivers"
|
||||
_error.UndefinedBitWidth = "Signal has undefined bit width"
|
||||
_error.UndrivenSignal = "Signal is not driven"
|
||||
_error.Requirement = "Requirement violation"
|
||||
_error.UnboundLocal="Local variable may be referenced before assignment"
|
||||
_error.TypeMismatch="Type mismatch with earlier assignment"
|
||||
_error.NrBitsMismatch="Nr of bits mismatch with earlier assignment"
|
||||
_error.ReturnTypeMismatch="Return type mismatch"
|
||||
_error.ReutrnNrBitsMismatch="Returned nr of bits mismatch"
|
||||
_error.UnboundLocal = "Local variable may be referenced before assignment"
|
||||
_error.TypeMismatch = "Type mismatch with earlier assignment"
|
||||
_error.NrBitsMismatch = "Nr of bits mismatch with earlier assignment"
|
||||
_error.IntbvBitWidth = "intbv instance should have bit width"
|
||||
_error.TypeInfer = "Can't infer type"
|
||||
_error.ReturnTypeMismatch = "Return type mismatch"
|
||||
_error.ReturnNrBitsMismatch = "Returned nr of bits mismatch"
|
||||
_error.ReturnIntbvBitWidth = "Returned intbv instance should have bit width"
|
||||
_error.ReturnTypeInfer = "Can't infer return type"
|
||||
|
||||
|
||||
def _checkArgs(arglist):
|
||||
for arg in arglist:
|
||||
@ -349,9 +354,53 @@ class _AnalyzeVisitor(_ToVerilogMixin):
|
||||
self.visit(node.left)
|
||||
self.visit(node.right)
|
||||
node.obj = int()
|
||||
|
||||
visitAdd = binaryOp
|
||||
visitFloorDiv = binaryOp
|
||||
visitLeftShift = binaryOp
|
||||
visitMul = binaryOp
|
||||
visitPow = binaryOp
|
||||
visitMod = binaryOp
|
||||
visitRightShift = binaryOp
|
||||
visitSub = binaryOp
|
||||
|
||||
def multiBitOp(self, node, *args):
|
||||
for n in node.nodes:
|
||||
self.visit(n)
|
||||
node.obj = None
|
||||
for n in node.nodes:
|
||||
if node.obj is None:
|
||||
node.obj = n.obj
|
||||
elif isinstance(node.obj, type(n.obj)):
|
||||
node.obj = n.obj
|
||||
def visitBitand(self, node, *args):
|
||||
self.multiBitOp(node, *args)
|
||||
def visitBitor(self, node, *args):
|
||||
self.multiBitOp(node, *args)
|
||||
def visitBitxor(self, node, *args):
|
||||
self.multiBitOp(node, *args)
|
||||
def multiLogicalOp(self, node, *args):
|
||||
for n in node.nodes:
|
||||
self.visit(n, *args)
|
||||
node.obj = None
|
||||
def visitAnd(self, node, *args):
|
||||
self.multiLogicalOp(node, *args)
|
||||
def visitOr(self, node, *args):
|
||||
self.multiLogicalOp(node, *args)
|
||||
|
||||
# unaryOp's
|
||||
def visitInvert(self, node, *args):
|
||||
self.visit(node.expr)
|
||||
node.obj = node.expr.obj
|
||||
def visitNot(self, node, *args):
|
||||
self.visit(node.expr)
|
||||
node.obj = bool()
|
||||
def visitUnaryAdd(self, node, *args):
|
||||
self.visit(node.expr)
|
||||
node.obj = int()
|
||||
def visitUnarySub(self, node, *args):
|
||||
self.visit(node.expr)
|
||||
node.obj = int()
|
||||
|
||||
|
||||
def visitAssAttr(self, node, access=OUTPUT, *args):
|
||||
self.visit(node.expr, OUTPUT)
|
||||
@ -365,7 +414,9 @@ class _AnalyzeVisitor(_ToVerilogMixin):
|
||||
n = target.name
|
||||
obj = self.getObj(expr)
|
||||
if obj is None:
|
||||
self.raiseError(node, "Cannot infer type or bit width of %s" % n)
|
||||
self.raiseError(node, _error.TypeInfer, n)
|
||||
if isinstance(obj, intbv) and len(obj) == 0:
|
||||
self.raiseError(node, _error.IntbvBitWidth, n)
|
||||
if n in self.vardict:
|
||||
curObj = self.vardict[n]
|
||||
if isinstance(obj, type(curObj)):
|
||||
@ -528,7 +579,7 @@ class _AnalyzeVisitor(_ToVerilogMixin):
|
||||
pass
|
||||
|
||||
def visitReturn(self, node, *args):
|
||||
self.visit(node.value)
|
||||
self.visit(node.value, *args)
|
||||
|
||||
def visitSlice(self, node, access=INPUT, kind=NORMAL, *args):
|
||||
self.visit(node.expr, access)
|
||||
@ -641,7 +692,7 @@ class _AnalyzeFuncVisitor(_AnalyzeVisitor):
|
||||
self.refStack.pop()
|
||||
|
||||
def visitReturn(self, node, *args):
|
||||
self.visit(node.value)
|
||||
self.visit(node.value, INPUT, DECLARATION, *args)
|
||||
if isinstance(node.value, ast.Const) and node.value.value is None:
|
||||
obj = None
|
||||
elif isinstance(node.value, ast.Name) and node.value.name is None:
|
||||
@ -649,7 +700,9 @@ class _AnalyzeFuncVisitor(_AnalyzeVisitor):
|
||||
elif node.value.obj is not None:
|
||||
obj = node.value.obj
|
||||
else:
|
||||
self.raiseError(node, "Can't derive return type")
|
||||
self.raiseError(node, error._ReturnTypeInfer)
|
||||
if isinstance(obj, intbv) and len(obj) == 0:
|
||||
self.raiseError(node, _error.ReturnIntbvBitWidth)
|
||||
if self.hasReturn:
|
||||
returnObj = self.returnObj
|
||||
if isinstance(obj, type(returnObj)):
|
||||
|
@ -17,17 +17,17 @@
|
||||
# License along with this library; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
""" Run all myhdl unit tests. """
|
||||
""" Run all myhdl toVerilog unit tests. """
|
||||
|
||||
__author__ = "Jan Decaluwe <jan@jandecaluwe.com>"
|
||||
__revision__ = "$Revision$"
|
||||
__date__ = "$Date$"
|
||||
|
||||
import test_bin2gray, test_inc, test_fsm, test_ops, test_NotSupported, \
|
||||
test_inc_initial, test_hec, test_loops
|
||||
test_inc_initial, test_hec, test_loops, test_infer
|
||||
|
||||
modules = (test_bin2gray, test_inc, test_fsm, test_ops, test_NotSupported, \
|
||||
test_inc_initial, test_hec, test_loops
|
||||
test_inc_initial, test_hec, test_loops, test_infer
|
||||
)
|
||||
|
||||
import unittest
|
||||
|
@ -59,6 +59,41 @@ def InferError3(a, out):
|
||||
d = 4
|
||||
out.next = b
|
||||
|
||||
def InferError4(a, out):
|
||||
h = intbv(0)
|
||||
yield a
|
||||
out.next = h
|
||||
|
||||
def InferError5Func(a):
|
||||
h = intbv(0)[5:]
|
||||
if a:
|
||||
return h
|
||||
else:
|
||||
return 1
|
||||
|
||||
def InferError5(a, out):
|
||||
yield a
|
||||
out.next = InferError5Func(a)
|
||||
|
||||
def InferError6Func(a):
|
||||
if a:
|
||||
return intbv(0)
|
||||
else:
|
||||
return intbv(1)
|
||||
|
||||
def InferError6(a, out):
|
||||
yield a
|
||||
out.next = InferError6Func(a)
|
||||
|
||||
def InferError7Func(a):
|
||||
if a:
|
||||
return intbv(0)[5:]
|
||||
else:
|
||||
return intbv(0xff)[7:2]
|
||||
|
||||
def InferError7(a, out):
|
||||
yield a
|
||||
out.next = InferError7Func(a)
|
||||
|
||||
|
||||
class TestErrors(unittest.TestCase):
|
||||
@ -114,6 +149,17 @@ class TestErrors(unittest.TestCase):
|
||||
def testInferError3(self):
|
||||
sim = self.check(InferError3, _error.TypeMismatch)
|
||||
|
||||
def testInferError4(self):
|
||||
sim = self.check(InferError4, _error.IntbvBitWidth)
|
||||
|
||||
def testInferError5(self):
|
||||
sim = self.check(InferError5, _error.ReturnTypeMismatch)
|
||||
|
||||
def testInferError6(self):
|
||||
sim = self.check(InferError6, _error.ReturnIntbvBitWidth)
|
||||
|
||||
def testInferError7(self):
|
||||
sim = self.nocheck(InferError7, _error.ReturnIntbvBitWidth)
|
||||
|
||||
|
||||
|
||||
@ -123,6 +169,7 @@ def Infer1(a, out):
|
||||
c = a < 4
|
||||
c = bool(0)
|
||||
c = False
|
||||
c = not a
|
||||
c = True
|
||||
out.next = c
|
||||
|
||||
@ -131,6 +178,7 @@ def Infer2(a, out):
|
||||
c = a < 4
|
||||
c = bool(0)
|
||||
c = False
|
||||
c = not a
|
||||
c = True
|
||||
c = 5
|
||||
out.next = c
|
||||
@ -155,6 +203,25 @@ def Infer4(a, out):
|
||||
yield a
|
||||
out.next = Infer4Func(a)
|
||||
|
||||
def Infer5(a, out):
|
||||
yield a
|
||||
c = a + 1
|
||||
c = a - 1
|
||||
c = a * 3
|
||||
c = a // 2
|
||||
c = a << 2
|
||||
c = a >> 2
|
||||
c = a % 16
|
||||
c = + a
|
||||
c = -( - a)
|
||||
c = ~(-3)
|
||||
c = not a
|
||||
c = 5 & 4
|
||||
c = 5 | 2
|
||||
c = 6 ^ 3
|
||||
c = bool(a and 1)
|
||||
out.next = c
|
||||
|
||||
|
||||
|
||||
objfile = "infertest.o"
|
||||
@ -187,22 +254,25 @@ class TestInfer(unittest.TestCase):
|
||||
|
||||
return stimulus(), infertest_inst, infertest_v_inst
|
||||
|
||||
## def testInfer1(self):
|
||||
## sim = self.bench(Infer1)
|
||||
## Simulation(sim).run()
|
||||
def testInfer1(self):
|
||||
sim = self.bench(Infer1)
|
||||
Simulation(sim).run()
|
||||
|
||||
## def testInfer2(self):
|
||||
## sim = self.bench(Infer2)
|
||||
## Simulation(sim).run()
|
||||
def testInfer2(self):
|
||||
sim = self.bench(Infer2)
|
||||
Simulation(sim).run()
|
||||
|
||||
## def testInfer3(self):
|
||||
## sim = self.bench(Infer3)
|
||||
## Simulation(sim).run()
|
||||
def testInfer3(self):
|
||||
sim = self.bench(Infer3)
|
||||
Simulation(sim).run()
|
||||
|
||||
def testInfer4(self):
|
||||
sim = self.bench(Infer4)
|
||||
Simulation(sim).run()
|
||||
|
||||
|
||||
def testInfer5(self):
|
||||
sim = self.bench(Infer5)
|
||||
Simulation(sim).run()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
Loading…
x
Reference in New Issue
Block a user