From 530e65c5596f50e2d988296b3a8be504a2cd9968 Mon Sep 17 00:00:00 2001 From: jand Date: Wed, 21 Jan 2004 22:31:44 +0000 Subject: [PATCH] function / task check --- myhdl/_toVerilog/_analyze.py | 28 ++++- myhdl/test/toVerilog/test_NotSupported.py | 18 +-- myhdl/test/toVerilog/test_RandomScrambler.py | 2 +- myhdl/test/toVerilog/test_errors.py | 120 ++++++++----------- 4 files changed, 82 insertions(+), 86 deletions(-) diff --git a/myhdl/_toVerilog/_analyze.py b/myhdl/_toVerilog/_analyze.py index a6b40397..abfc1bf5 100644 --- a/myhdl/_toVerilog/_analyze.py +++ b/myhdl/_toVerilog/_analyze.py @@ -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,8 +609,13 @@ 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: diff --git a/myhdl/test/toVerilog/test_NotSupported.py b/myhdl/test/toVerilog/test_NotSupported.py index 9f225b52..7de5959d 100644 --- a/myhdl/test/toVerilog/test_NotSupported.py +++ b/myhdl/test/toVerilog/test_NotSupported.py @@ -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()) diff --git a/myhdl/test/toVerilog/test_RandomScrambler.py b/myhdl/test/toVerilog/test_RandomScrambler.py index a65038d5..185b0b87 100644 --- a/myhdl/test/toVerilog/test_RandomScrambler.py +++ b/myhdl/test/toVerilog/test_RandomScrambler.py @@ -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() diff --git a/myhdl/test/toVerilog/test_errors.py b/myhdl/test/toVerilog/test_errors.py index 46afaf90..3362d2c2 100644 --- a/myhdl/test/toVerilog/test_errors.py +++ b/myhdl/test/toVerilog/test_errors.py @@ -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:] @@ -166,19 +117,46 @@ def recursion2(count, enable, clock, reset, n): else: 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: @@ -309,6 +273,22 @@ class TestInc(TestCase): self.assertEqual(e.kind, _error.NotSupported) 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__':