```import os
path = os.path
from random import randrange

import myhdl
from myhdl import *
from myhdl.conversion import verify, analyze
from myhdl import ConversionError
from myhdl.conversion._misc import _error

@block
def ForLoopError1(a, out):
@instance
def logic():
while 1:
yield a
var = 0
for i in (1, 2, 3):
if a[i] == 1:
var += 1
out.next = var
return logic

@block
def ForLoopError2(a, out):
@instance
def logic():
while 1:
yield a
var = 0
for i in list((1, 2, 3)):
if a[i] == 1:
var += 1
out.next = var
return logic

@block
def ForLoop1(a, out):
@instance
def logic():
while 1:
yield a
var = 0
for i in downrange(len(a)):
if a[i] == 1:
var += 1
out.next = var
return logic

@block
def ForLoop2(a, out):
@instance
def logic():
while 1:
yield a
var = 0
for i in downrange(len(a), 5):
if a[i] == 1:
var += 1
out.next = var
return logic

@block
def ForLoop3(a, out):
@instance
def logic():
while 1:
yield a
var = 0
for i in downrange(len(a), 3, 2):
if a[i] == 1:
var += 1
out.next = var
return logic

@block
def ForLoop4(a, out):
@instance
def logic():
while 1:
yield a
var = 0
for i in range(len(a)):
if a[i] == 1:
var += 1
out.next = var
return logic

@block
def ForLoop5(a, out):
@instance
def logic():
while 1:
yield a
var = 0
for i in range(6, len(a)):
if a[i] == 1:
var += 1
out.next = var
return logic

@block
def ForLoop6(a, out):
@instance
def logic():
while 1:
yield a
var = 0
for i in range(5, len(a), 3):
if a[i] == 1:
var += 1
out.next = var
return logic

@block
def ForContinueLoop(a, out):
@instance
def logic():
while 1:
yield a
var = 0
for i in downrange(len(a)):
if a[i] == 0:
continue
var += 1
out.next = var
return logic

@block
def ForBreakLoop(a, out):
@instance
def logic():
while 1:
yield a
out.next = 0
for i in downrange(len(a)):
if a[i] == 1:
out.next = i
break
return logic

@block
def ForBreakContinueLoop(a, out):
@instance
def logic():
while 1:
yield a
out.next = 0
for i in downrange(len(a)):
if a[i] == 0:
continue
out.next = i
break
return logic

@block
def NestedForLoop1(a, out):
@instance
def logic():
while 1:
yield a
var = 0
for i in downrange(len(a)):
if a[i] == 0:
continue
else:
for j in downrange(i):
if a[j] == 0:
var +=1
break
out.next = var
return logic

@block
def NestedForLoop2(a, out):
@instance
def logic():
while 1:
yield a
var = 0
out.next = 0
for i in downrange(len(a)):
if a[i] == 0:
continue
else:
for j in downrange(i-1):
if a[j] == 0:
pass
else:
out.next = j
break
break
return logic

def ReturnFromFunction(a):
for i in downrange(len(a)):
if a[i] == 1:
return i
return 0

@block
def FunctionCall(a, out):
@instance
def logic():
while 1:
yield a
out.next = ReturnFromFunction(a)
return logic

# 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.
for i in downrange(len(a)):
if a[i] == 1:
out[:] = i
return
out[:] = 23 # to notice it

@block
@instance
def logic():
var = intbv(0)[8:]
while 1:
yield a
out.next = var
return logic

@block
def WhileLoop(a, out):
@instance
def logic():
while 1:
yield a
var = 0
i = len(a)-1
while i >= 0:
if a[i] == 1:
var += 1
i -= 1
out.next = var
return logic

@block
def WhileContinueLoop(a, out):
@instance
def logic():
while 1:
yield a
var = 0
i = len(a)-1
while i >= 0:
if a[i] == 0:
i -= 1
continue
var += 1
i -= 1
out.next = var
return logic

@block
def WhileBreakLoop(a, out):
@instance
def logic():
while 1:
yield a
var = 0
i = len(a)-1
out.next = 0
while i >= 0:
if a[i] == 1:
out.next = i
break
i -= 1
return logic

@block
def WhileBreakContinueLoop(a, out):
@instance
def logic():
while 1:
yield a
var = 0
i = len(a)-1
out.next = 0
while i >= 0:
if a[i] == 0:
i -= 1
continue
out.next = i
break
return logic

@block
def LoopBench(LoopTest):

a = Signal(intbv(-1)[16:])
z = Signal(intbv(0)[16:])

looptest_inst = LoopTest(a, z)
data = tuple([randrange(2**min(i, 16)) for i in range(100)])

@instance
def stimulus():
for i in range(100):
a.next = data[i]
yield delay(10)
print(z)

return stimulus, looptest_inst

def testForLoopError1():
try:
analyze(LoopBench(ForLoopError1))
except ConversionError as e:
assert e.kind == _error.Requirement
else:
assert False

def testForLoopError2():
try:
analyze(LoopBench(ForLoopError2))
except ConversionError as e:
assert e.kind == _error.Requirement
else:
assert False

def testForLoop1():
assert verify(LoopBench(ForLoop1)) == 0
def testForLoop2():
assert verify(LoopBench(ForLoop2)) == 0
def testForLoop4():
assert verify(LoopBench(ForLoop4)) == 0
def testForLoop5():
assert verify(LoopBench(ForLoop5)) == 0

# for loop 3 and 6 can't work in vhdl

def testForContinueLoop():
assert verify(LoopBench(ForContinueLoop)) == 0

def testForBreakLoop():
assert verify(LoopBench(ForBreakLoop)) == 0

def testForBreakContinueLoop():
assert verify(LoopBench(ForBreakContinueLoop))== 0

def testNestedForLoop1():
assert verify(LoopBench(NestedForLoop1)) == 0

def testNestedForLoop2():
assert verify(LoopBench(NestedForLoop2)) == 0

def testWhileLoop():
assert verify(LoopBench(FunctionCall)) == 0

##     Simulation(sim).run()

def testWhileLoop():
assert verify(LoopBench(WhileLoop)) == 0

def testWhileContinueLoop():
assert verify(LoopBench(WhileContinueLoop)) == 0

def testWhileBreakLoop():
assert verify(LoopBench(WhileBreakLoop)) == 0

def testWhileBreakContinueLoop():
assert verify(LoopBench(WhileBreakContinueLoop)) == 0
```