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

function / task check

This commit is contained in:
jand 2004-01-21 22:31:44 +00:00
parent 5d1e8fe952
commit 530e65c559
4 changed files with 82 additions and 86 deletions

View File

@ -373,6 +373,7 @@ class _AnalyzeVisitor(_ToVerilogMixin):
s = inspect.getsource(f)
s = s.lstrip()
ast = compiler.parse(s)
print ast
fname = f.__name__
ast.name = _Label(fname)
ast.sourcefile = inspect.getsourcefile(f)
@ -403,8 +404,6 @@ class _AnalyzeVisitor(_ToVerilogMixin):
self.visit(arg, _access.OUTPUT)
if n in ast.inputs:
self.visit(arg, _access.INPUT)
if ast.isGen:
self.raiseError(node, _error.NotSupported, "Generator function call")
elif type(f) is MethodType:
self.raiseError(node,_error.NotSupported, "method call: '%s'" % f.__name__)
else:
@ -610,7 +609,12 @@ class _AnalyzeBlockVisitor(_AnalyzeVisitor):
def visitReturn(self, node, *args):
### value should be None
self.raiseError(node, _error.NotSupported, "return statement")
if isinstance(node.value, astNode.Const) and node.value.value is None:
obj = None
elif isinstance(node.value, astNode.Name) and node.value.name == 'None':
obj = None
else:
self.raiseError(node, _error.NotSupported, "return value other than None")
class _AnalyzeAlwaysCombVisitor(_AnalyzeBlockVisitor):
@ -653,17 +657,29 @@ class _AnalyzeFuncVisitor(_AnalyzeVisitor):
self.ast.sigdict[n] = v
self.visit(node.code)
self.refStack.pop()
if self.ast.isGen:
self.raiseError(node, _error.NotSupported,
"call to a generator function")
if self.ast.kind == _kind.TASK:
if self.ast.returnObj is not None:
self.raiseError(node, _error.NotSupported,
"function with side effects and return value")
else:
if self.ast.returnObj is None:
self.raiseError(node, _error.NotSupported,
"pure function without return value")
def visitReturn(self, node, *args):
self.visit(node.value, _access.INPUT, _kind.DECLARATION, *args)
if isinstance(node.value, astNode.Const) and node.value.value is None:
obj = None
elif isinstance(node.value, astNode.Name) and node.value.name is None:
elif isinstance(node.value, astNode.Name) and node.value.name == 'None':
obj = None
elif node.value.obj is not None:
obj = node.value.obj
else:
self.raiseError(node, error._ReturnTypeInfer)
self.raiseError(node, _error.ReturnTypeInfer)
if isinstance(obj, intbv) and len(obj) == 0:
self.raiseError(node, _error.ReturnIntbvBitWidth)
if self.ast.hasReturn:

View File

@ -181,15 +181,15 @@ class TestNotSupported(unittest.TestCase):
## z.next = 2 ** 8
## self.check(g, z, a)
def testReturn(self):
a = Signal(bool())
z = Signal(bool())
def g(z, a):
while 1:
yield a
z.next = 1
return
self.check(g, z, a)
## def testReturn(self):
## a = Signal(bool())
## z = Signal(bool())
## def g(z, a):
## while 1:
## yield a
## z.next = 1
## return
## self.check(g, z, a)
def testTryExcept(self):
a = Signal(bool())

View File

@ -84,7 +84,7 @@ def RandomScrambler_v(o7, o6, o5, o4, o3, o2, o1, o0,
return Cosimulation(simulate_cmd, **locals())
class TestRandomScramber(TestCase):
class TestRandomScrambler(TestCase):
def stimulus(self):
input = intbv()

View File

@ -11,55 +11,6 @@ from myhdl._toVerilog import ToVerilogError, _error
ACTIVE_LOW, INACTIVE_HIGH = 0, 1
def incRef(count, enable, clock, reset, n):
""" Incrementer with enable.
count -- output
enable -- control input, increment when 1
clock -- clock input
reset -- asynchronous reset input
n -- counter max value
"""
while 1:
yield posedge(clock), negedge(reset)
if reset == ACTIVE_LOW:
count.next = 0
else:
if enable:
count.next = (count + 1) % n
## def incTaskFunc(count, count_in, enable, clock, reset, n):
## if enable:
## count.next = (count_in + 1) % n
## def incTask(count, enable, clock, reset, n):
## while 1:
## yield posedge(clock), negedge(reset)
## if reset == ACTIVE_LOW:
## count.next = 0
## else:
## incTaskFunc(count, count, enable, clock, reset, n)
## def incTask(count, enable, clock, reset, n):
## def incTaskFunc(cnt, enable, reset, n):
## if enable:
## cnt[:] = (cnt + 1) % n
## def incTaskGen():
## cnt = intbv(0)[8:]
## while 1:
## yield posedge(clock), negedge(reset)
## if reset == ACTIVE_LOW:
## cnt[:] = 0
## count.next = 0
## else:
## # print count
## incTaskFunc(cnt, enable, reset, n)
## count.next = cnt
## return incTaskGen()
def freeVarTypeError(count, enable, clock, reset, n):
cnt = intbv(0)[8:]
@ -167,18 +118,45 @@ def recursion2(count, enable, clock, reset, n):
if enable:
count.next = f2(n)
def h1(n):
return None
def functionNoReturnVal(count, enable, clock, reset, n):
while 1:
yield posedge(clock), negedge(reset)
if reset == ACTIVE_LOW:
count.next = 0
else:
if enable:
count.next = h1(n)
def h2(cnt):
cnt[:] = cnt + 1
return 1
def taskReturnVal(count, enable, clock, reset, n):
cnt = intbv()[8:]
while 1:
yield posedge(clock), negedge(reset)
if reset == ACTIVE_LOW:
count.next = 0
else:
if enable:
h2(cnt)
count.next = count + 1
objfile = "inc_inst.o"
analyze_cmd = "iverilog -o %s inc_inst.v tb_inc_inst.v" % objfile
analyze_cmd = "iverilog -o %s err_inst.v tb_err_inst.v" % objfile
simulate_cmd = "vvp -m ../../../cosimulation/icarus/myhdl.vpi %s" % objfile
def inc_v(count, enable, clock, reset):
def err_v(count, enable, clock, reset):
if path.exists(objfile):
os.remove(objfile)
os.system(analyze_cmd)
return Cosimulation(simulate_cmd, **locals())
class TestInc(TestCase):
class TestErr(TestCase):
def clockGen(self, clock):
while 1:
@ -213,7 +191,7 @@ class TestInc(TestCase):
self.assertEqual(count, expect)
self.assertEqual(count, count_v)
def bench(self, inc):
def bench(self, err):
m = 8
n = 2 ** m
@ -223,28 +201,14 @@ class TestInc(TestCase):
enable = Signal(bool(0))
clock, reset = [Signal(bool()) for i in range(2)]
inc_inst_ref = incRef(count, enable, clock, reset, n=n)
inc_inst = toVerilog(inc, count, enable, clock, reset, n=n)
inc_inst_v = inc_v(count_v, enable, clock, reset)
err_inst = toVerilog(err, count, enable, clock, reset, n=n)
clk_1 = self.clockGen(clock)
st_1 = self.stimulus(enable, clock, reset)
ch_1 = self.check(count, count_v, enable, clock, reset, n=n)
sim = Simulation(inc_inst_ref, inc_inst_v, clk_1, st_1, ch_1)
sim = Simulation(err_inst, clk_1, st_1, ch_1)
return sim
## def testIncRef(self):
## """ Check increment operation """
## sim = self.bench(incRef)
## sim.run(quiet=1)
## def testIncTask(self):
## sim = self.bench(incTask)
## sim.run(quiet=1)
## def testIncTaskFreeVar(self):
## sim = self.bench(incTaskFreeVar)
## sim.run(quiet=1)
def testInternalSignal(self):
try:
@ -310,6 +274,22 @@ class TestInc(TestCase):
else:
self.fail()
def testFunctionNoReturnVal(self):
try:
self.bench(functionNoReturnVal)
except ToVerilogError, e:
self.assertEqual(e.kind, _error.NotSupported)
else:
self.fail()
def testTaskReturnVal(self):
try:
self.bench(taskReturnVal)
except ToVerilogError, e:
self.assertEqual(e.kind, _error.NotSupported)
else:
self.fail()
if __name__ == '__main__':
unittest.main()