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

View File

@ -181,15 +181,15 @@ class TestNotSupported(unittest.TestCase):
## z.next = 2 ** 8 ## z.next = 2 ** 8
## self.check(g, z, a) ## self.check(g, z, a)
def testReturn(self): ## def testReturn(self):
a = Signal(bool()) ## a = Signal(bool())
z = Signal(bool()) ## z = Signal(bool())
def g(z, a): ## def g(z, a):
while 1: ## while 1:
yield a ## yield a
z.next = 1 ## z.next = 1
return ## return
self.check(g, z, a) ## self.check(g, z, a)
def testTryExcept(self): def testTryExcept(self):
a = Signal(bool()) 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()) return Cosimulation(simulate_cmd, **locals())
class TestRandomScramber(TestCase): class TestRandomScrambler(TestCase):
def stimulus(self): def stimulus(self):
input = intbv() input = intbv()

View File

@ -11,55 +11,6 @@ from myhdl._toVerilog import ToVerilogError, _error
ACTIVE_LOW, INACTIVE_HIGH = 0, 1 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): def freeVarTypeError(count, enable, clock, reset, n):
cnt = intbv(0)[8:] cnt = intbv(0)[8:]
@ -166,19 +117,46 @@ def recursion2(count, enable, clock, reset, n):
else: else:
if enable: if enable:
count.next = f2(n) 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" 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 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): if path.exists(objfile):
os.remove(objfile) os.remove(objfile)
os.system(analyze_cmd) os.system(analyze_cmd)
return Cosimulation(simulate_cmd, **locals()) return Cosimulation(simulate_cmd, **locals())
class TestInc(TestCase): class TestErr(TestCase):
def clockGen(self, clock): def clockGen(self, clock):
while 1: while 1:
@ -213,7 +191,7 @@ class TestInc(TestCase):
self.assertEqual(count, expect) self.assertEqual(count, expect)
self.assertEqual(count, count_v) self.assertEqual(count, count_v)
def bench(self, inc): def bench(self, err):
m = 8 m = 8
n = 2 ** m n = 2 ** m
@ -223,28 +201,14 @@ class TestInc(TestCase):
enable = Signal(bool(0)) enable = Signal(bool(0))
clock, reset = [Signal(bool()) for i in range(2)] clock, reset = [Signal(bool()) for i in range(2)]
inc_inst_ref = incRef(count, enable, clock, reset, n=n) err_inst = toVerilog(err, 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)
clk_1 = self.clockGen(clock) clk_1 = self.clockGen(clock)
st_1 = self.stimulus(enable, clock, reset) st_1 = self.stimulus(enable, clock, reset)
ch_1 = self.check(count, count_v, enable, clock, reset, n=n) 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 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): def testInternalSignal(self):
try: try:
@ -309,6 +273,22 @@ class TestInc(TestCase):
self.assertEqual(e.kind, _error.NotSupported) self.assertEqual(e.kind, _error.NotSupported)
else: else:
self.fail() 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__': if __name__ == '__main__':