1
0
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:
jand 2003-12-07 16:12:52 +00:00
parent beaca96d74
commit 24c8fbe188
3 changed files with 146 additions and 23 deletions

View File

@ -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)):

View File

@ -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

View File

@ -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__':