diff --git a/myhdl/_toVerilog.py b/myhdl/_toVerilog.py index 6eb5b8ca..497104d5 100644 --- a/myhdl/_toVerilog.py +++ b/myhdl/_toVerilog.py @@ -1243,12 +1243,14 @@ class _ConvertFunctionVisitor(_ConvertVisitor): self.indent() self.writeInputDeclarations() self.writeDeclarations() + self.dedent() self.writeline() self.write("begin: %s" % self.returnLabel) + self.indent() self.visit(node.code) + self.dedent() self.writeline() self.write("end") - self.dedent() self.writeline() self.write("endfunction") self.writeline(2) @@ -1268,6 +1270,7 @@ class _ConvertTaskVisitor(_ConvertVisitor): self.argnames = ast.argnames self.inputs = ast.inputs self.outputs = ast.outputs + self.returnLabel = Label("RETURN") def writeInterfaceDeclarations(self): @@ -1292,12 +1295,14 @@ class _ConvertTaskVisitor(_ConvertVisitor): self.indent() self.writeInterfaceDeclarations() self.writeDeclarations() + self.dedent() self.writeline() self.write("begin") + self.indent() self.visit(node.code) + self.dedent() self.writeline() self.write("end") - self.dedent() self.writeline() self.write("endtask") self.writeline(2) diff --git a/myhdl/test/toVerilog/test_loops.py b/myhdl/test/toVerilog/test_loops.py index cb6e76e2..41d4723d 100644 --- a/myhdl/test/toVerilog/test_loops.py +++ b/myhdl/test/toVerilog/test_loops.py @@ -74,6 +74,34 @@ def NestedForLoop2(a, out): break break +def ReturnFromFunction(a): + for i in downrange(len(a)): + if a[i] == 1: + return i + return 0 + +def FunctionCall(a, out): + while 1: + yield a + out.next = ReturnFromFunction(a) + +# During the following check, I noticed that non-blocking assignments +# are not scheduled when a task is disabled in Icarus. Apparently +# this is one of the many vague areas in the Verilog standard. +def ReturnFromTask(a, out): + for i in downrange(len(a)): + if a[i] == 1: + out[:] = i + return + out[:] = 23 # to notice it + +def TaskCall(a, out): + var = intbv()[8:] + while 1: + yield a + ReturnFromTask(a, var) + out.next = var + def WhileLoop(a, out): while 1: yield a @@ -138,7 +166,7 @@ class TestLoops(unittest.TestCase): def bench(self, LoopTest): - a = Signal(intbv(0)[16:]) + a = Signal(intbv(-1)[16:]) out_v = Signal(intbv(0)[16:]) out = Signal(intbv(0)[16:]) @@ -150,50 +178,62 @@ class TestLoops(unittest.TestCase): for i in range(100): a.next = randrange(2**min(i, 16)) yield delay(10) - print "%s %s" % (out, out_v) + # print "%s %s" % (out, out_v) self.assertEqual(out, out_v) return stimulus(), looptest_inst, looptest_v_inst -## def testForLoop(self): -## sim = self.bench(ForLoop) -## Simulation(sim).run() + def testForLoop(self): + sim = self.bench(ForLoop) + Simulation(sim).run() -## def testForContinueLoop(self): -## sim = self.bench(ForContinueLoop) -## Simulation(sim).run() + def testForContinueLoop(self): + sim = self.bench(ForContinueLoop) + Simulation(sim).run() -## def testForBreakLoop(self): -## sim = self.bench(ForBreakLoop) -## Simulation(sim).run() + def testForBreakLoop(self): + sim = self.bench(ForBreakLoop) + Simulation(sim).run() -## def testForBreakContinueLoop(self): -## sim = self.bench(ForBreakContinueLoop) -## Simulation(sim).run() + def testForBreakContinueLoop(self): + sim = self.bench(ForBreakContinueLoop) + Simulation(sim).run() -## def testNestedForLoop1(self): -## sim = self.bench(NestedForLoop1) -## Simulation(sim).run() + def testNestedForLoop1(self): + sim = self.bench(NestedForLoop1) + Simulation(sim).run() def testNestedForLoop2(self): sim = self.bench(NestedForLoop2) Simulation(sim).run() -## def testWhileLoop(self): -## sim = self.bench(WhileLoop) -## Simulation(sim).run() + def testNestedForLoop2(self): + sim = self.bench(NestedForLoop2) + Simulation(sim).run() -## def testWhileContinueLoop(self): -## sim = self.bench(WhileContinueLoop) -## Simulation(sim).run() - -## def testWhileBreakLoop(self): -## sim = self.bench(WhileBreakLoop) -## Simulation(sim).run() + def testFunctionCall(self): + sim = self.bench(FunctionCall) + Simulation(sim).run() -## def testWhileBreakContinueLoop(self): -## sim = self.bench(WhileBreakContinueLoop) -## Simulation(sim).run() + def testTaskCall(self): + sim = self.bench(TaskCall) + Simulation(sim).run() + + def testWhileLoop(self): + sim = self.bench(WhileLoop) + Simulation(sim).run() + + def testWhileContinueLoop(self): + sim = self.bench(WhileContinueLoop) + Simulation(sim).run() + + def testWhileBreakLoop(self): + sim = self.bench(WhileBreakLoop) + Simulation(sim).run() + + def testWhileBreakContinueLoop(self): + sim = self.bench(WhileBreakContinueLoop) + Simulation(sim).run() if __name__ == '__main__':