diff --git a/.gitignore b/.gitignore index 387b4fc9..267af9a0 100644 --- a/.gitignore +++ b/.gitignore @@ -36,3 +36,4 @@ myhdl/**/*.vhd # Pycharm ide junk .idea/ +/.pytest_cache/ diff --git a/myhdl/_misc.py b/myhdl/_misc.py index cec70727..ae2ad787 100644 --- a/myhdl/_misc.py +++ b/myhdl/_misc.py @@ -29,6 +29,7 @@ import inspect from myhdl._Cosimulation import Cosimulation from myhdl._instance import _Instantiator + def _isGenSeq(obj): from myhdl._block import _Block if isinstance(obj, (Cosimulation, _Instantiator, _Block)): diff --git a/myhdl/conversion/_analyze.py b/myhdl/conversion/_analyze.py index 9ad11117..35af88ca 100644 --- a/myhdl/conversion/_analyze.py +++ b/myhdl/conversion/_analyze.py @@ -682,19 +682,42 @@ class _AnalyzeVisitor(ast.NodeVisitor, _ConversionMixin): elif v == 1: node.edge = sig.posedge - def visit_Num(self, node): - n = node.n - # assign to value attribute for backwards compatibility - node.value = n - if n in (0, 1): - node.obj = bool(n) - elif isinstance(n, int): - node.obj = n - else: - node.obj = None + if sys.version_info >= (3, 9, 0): - def visit_Str(self, node): - node.obj = node.s + def visit_Constant(self, node): + node.obj = None # safeguarding? + # ToDo check for tuples? + if isinstance(node.value, int): + # Num + if node.value in (0, 1): + node.obj = bool(node.value) + else: + node.obj = node.value + elif node.value in (True, False, None): + # NameConstant + node.obj = node.value + elif isinstance(node.value, str): + # Str + node.obj = node.value + + else: + + def visit_Num(self, node): + n = node.n + # assign to value attribute for backwards compatibility + node.value = n + if n in (0, 1): + node.obj = bool(n) + elif isinstance(n, int): + node.obj = n + else: + node.obj = None + + def visit_Str(self, node): + node.obj = node.s + + def visit_NameConstant(self, node): + node.obj = node.value def visit_Continue(self, node): self.labelStack[-1].isActive = True @@ -787,9 +810,6 @@ class _AnalyzeVisitor(ast.NodeVisitor, _ConversionMixin): self.raiseError(node, _error.UnsupportedListComp) mem.depth = cf.args[0].obj - def visit_NameConstant(self, node): - node.obj = node.value - def visit_Name(self, node): if isinstance(node.ctx, ast.Store): self.setName(node) @@ -976,7 +996,11 @@ class _AnalyzeVisitor(ast.NodeVisitor, _ConversionMixin): def accessIndex(self, node): self.visit(node.value) self.access = _access.INPUT - self.visit(node.slice.value) + if sys.version_info >= (3, 9, 0): # Python 3.9+: no ast.Index wrapper + self.visit(node.slice) + else: + self.visit(node.slice.value) + if isinstance(node.value.obj, _Ram): if isinstance(node.ctx, ast.Store): self.raiseError(node, _error.ListElementAssign) diff --git a/myhdl/conversion/_toVHDL.py b/myhdl/conversion/_toVHDL.py index 7942963a..19f5b881 100644 --- a/myhdl/conversion/_toVHDL.py +++ b/myhdl/conversion/_toVHDL.py @@ -986,8 +986,8 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin): rhs = node.value # shortcut for expansion of ROM in case statement if isinstance(node.value, ast.Subscript) and \ - isinstance(node.value.slice, ast.Index) and \ - isinstance(node.value.value.obj, _Rom): + not isinstance(node.value.slice, ast.Slice) and \ + isinstance(node.value.value.obj, _Rom): rom = node.value.value.obj.rom self.write("case ") self.visit(node.value.slice) @@ -1189,36 +1189,85 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin): self.visit(right) self.write(suf) - def visit_Num(self, node): - n = node.n - if isinstance(node.vhd, vhd_std_logic): - self.write("'%s'" % n) - elif isinstance(node.vhd, vhd_boolean): - self.write("%s" % bool(n)) - # elif isinstance(node.vhd, (vhd_unsigned, vhd_signed)): - # self.write('"%s"' % tobin(n, node.vhd.size)) - elif isinstance(node.vhd, vhd_unsigned): - if abs(n) < 2 ** 31: - self.write("to_unsigned(%s, %s)" % (n, node.vhd.size)) - else: - self.write('unsigned\'("%s")' % tobin(n, node.vhd.size)) - elif isinstance(node.vhd, vhd_signed): - if abs(n) < 2 ** 31: - self.write("to_signed(%s, %s)" % (n, node.vhd.size)) - else: - self.write('signed\'("%s")' % tobin(n, node.vhd.size)) - else: - if n < 0: - self.write("(") - self.write(n) - if n < 0: - self.write(")") + if sys.version_info >= (3, 9, 0): - def visit_Str(self, node): - typemark = 'string' - if isinstance(node.vhd, vhd_unsigned): - typemark = 'unsigned' - self.write("%s'(\"%s\")" % (typemark, node.s)) + def visit_Constant(self, node): + if node.value is None: + # NameConstant + node.id = str(node.value) + self.getName(node) + elif isinstance(node.value, bool): + # NameConstant + node.id = str(node.value) + self.getName(node) + elif isinstance(node.value, int): + # Num + n = node.value + if isinstance(node.vhd, vhd_std_logic): + self.write("'%s'" % n) + elif isinstance(node.vhd, vhd_boolean): + self.write("%s" % bool(n)) + # elif isinstance(node.vhd, (vhd_unsigned, vhd_signed)): + # self.write('"%s"' % tobin(n, node.vhd.size)) + elif isinstance(node.vhd, vhd_unsigned): + if abs(n) < 2 ** 31: + self.write("to_unsigned(%s, %s)" % (n, node.vhd.size)) + else: + self.write('unsigned\'("%s")' % tobin(n, node.vhd.size)) + elif isinstance(node.vhd, vhd_signed): + if abs(n) < 2 ** 31: + self.write("to_signed(%s, %s)" % (n, node.vhd.size)) + else: + self.write('signed\'("%s")' % tobin(n, node.vhd.size)) + else: + if n < 0: + self.write("(") + self.write(n) + if n < 0: + self.write(")") + elif isinstance(node.value, str): + # Str + typemark = 'string' + if isinstance(node.vhd, vhd_unsigned): + typemark = 'unsigned' + self.write("%s'(\"%s\")" % (typemark, node.value)) + + else: + + def visit_Num(self, node): + n = node.n + if isinstance(node.vhd, vhd_std_logic): + self.write("'%s'" % n) + elif isinstance(node.vhd, vhd_boolean): + self.write("%s" % bool(n)) + # elif isinstance(node.vhd, (vhd_unsigned, vhd_signed)): + # self.write('"%s"' % tobin(n, node.vhd.size)) + elif isinstance(node.vhd, vhd_unsigned): + if abs(n) < 2 ** 31: + self.write("to_unsigned(%s, %s)" % (n, node.vhd.size)) + else: + self.write('unsigned\'("%s")' % tobin(n, node.vhd.size)) + elif isinstance(node.vhd, vhd_signed): + if abs(n) < 2 ** 31: + self.write("to_signed(%s, %s)" % (n, node.vhd.size)) + else: + self.write('signed\'("%s")' % tobin(n, node.vhd.size)) + else: + if n < 0: + self.write("(") + self.write(n) + if n < 0: + self.write(")") + + def visit_Str(self, node): + typemark = 'string' + if isinstance(node.vhd, vhd_unsigned): + typemark = 'unsigned' + self.write("%s'(\"%s\")" % (typemark, node.s)) + + def visit_NameConstant(self, node): + node.id = str(node.value) + self.getName(node) def visit_Continue(self, node, *args): self.write("next;") @@ -1399,10 +1448,6 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin): for stmt in node.body: self.visit(stmt) - def visit_NameConstant(self, node): - node.id = str(node.value) - self.getName(node) - def visit_Name(self, node): if isinstance(node.ctx, ast.Store): self.setName(node) @@ -1470,6 +1515,8 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin): s = "to_signed(%s, %s)" % (obj, node.vhd.size) else: s = 'signed\'("%s")' % tobin(obj, node.vhd.size) + elif isinstance(obj, tuple): # Python3.9+ ast.Index replacement serves a tuple + s = n elif isinstance(obj, _Signal): s = str(obj) ori = inferVhdlObj(obj) @@ -1583,7 +1630,10 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin): self.visit(node.value) self.write("(") # assert len(node.subs) == 1 - self.visit(node.slice.value) + if sys.version_info >= (3, 9, 0): # Python 3.9+: no ast.Index wrapper + self.visit(node.slice) + else: + self.visit(node.slice.value) self.write(")") self.write(suf) @@ -2244,16 +2294,42 @@ class _AnnotateTypesVisitor(ast.NodeVisitor, _ConversionMixin): right.vhd = vhd_signed(right.vhd.size + 1) node.vhdOri = copy(node.vhd) - def visit_Str(self, node): - node.vhd = vhd_string() - node.vhdOri = copy(node.vhd) + if sys.version_info >= (3, 9, 0): - def visit_Num(self, node): - if node.n < 0: - node.vhd = vhd_int() - else: - node.vhd = vhd_nat() - node.vhdOri = copy(node.vhd) + def visit_Constant(self, node): + if node.value is None: + # NameConstant + node.vhd = inferVhdlObj(node.value) + elif isinstance(node.value, bool): + # NameConstant + node.vhd = inferVhdlObj(node.value) + elif isinstance(node.value, int): + # Num + if node.value < 0: + node.vhd = vhd_int() + else: + node.vhd = vhd_nat() + elif isinstance(node.value, str): + # Str + node.vhd = vhd_string() + node.vhdOri = copy(node.vhd) + + else: + + def visit_Str(self, node): + node.vhd = vhd_string() + node.vhdOri = copy(node.vhd) + + def visit_Num(self, node): + if node.n < 0: + node.vhd = vhd_int() + else: + node.vhd = vhd_nat() + node.vhdOri = copy(node.vhd) + + def visit_NameConstant(self, node): + node.vhd = inferVhdlObj(node.value) + node.vhdOri = copy(node.vhd) def visit_For(self, node): var = node.target.id @@ -2261,10 +2337,6 @@ class _AnnotateTypesVisitor(ast.NodeVisitor, _ConversionMixin): self.tree.vardict[var] = _loopInt(-1) self.generic_visit(node) - def visit_NameConstant(self, node): - node.vhd = inferVhdlObj(node.value) - node.vhdOri = copy(node.vhd) - def visit_Name(self, node): if node.id in self.tree.vardict: node.obj = self.tree.vardict[node.id] @@ -2391,7 +2463,10 @@ class _AnnotateTypesVisitor(ast.NodeVisitor, _ConversionMixin): def accessIndex(self, node): self.generic_visit(node) node.vhd = vhd_std_logic() # XXX default - node.slice.value.vhd = vhd_int() + if sys.version_info >= (3, 9, 0): # Python 3.9+: no ast.Index wrapper + node.slice.vhd = vhd_int() + else: + node.slice.value.vhd = vhd_int() obj = node.value.obj if isinstance(obj, list): assert len(obj) diff --git a/myhdl/conversion/_toVerilog.py b/myhdl/conversion/_toVerilog.py index 2f07fc8e..ffe2e800 100644 --- a/myhdl/conversion/_toVerilog.py +++ b/myhdl/conversion/_toVerilog.py @@ -471,6 +471,7 @@ def _getSignString(s): else: return '' + def _intRepr(n, radix=''): # write size for large integers (beyond 32 bits signed) # with some safety margin @@ -478,18 +479,19 @@ def _intRepr(n, radix=''): p = abs(n) size = '' num = str(p).rstrip('L') - if radix == "hex" or p >= 2**30: + if radix == "hex" or p >= 2 ** 30: radix = "'h" num = hex(p)[2:].rstrip('L') - if p >= 2**30: - size = int(math.ceil(math.log(p+1,2))) + 1 # sign bit! + if p >= 2 ** 30: + size = int(math.ceil(math.log(p + 1, 2))) + 1 # sign bit! # if not radix: # radix = "'d" r = "%s%s%s" % (size, radix, num) - if n < 0: # add brackets and sign on negative numbers + if n < 0: # add brackets and sign on negative numbers r = "(-%s)" % r return r + def _convertGens(genlist, vfile): blockBuf = StringIO() funcBuf = StringIO() @@ -750,8 +752,8 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin): def visit_Assign(self, node): # shortcut for expansion of ROM in case statement if isinstance(node.value, ast.Subscript) and \ - isinstance(node.value.slice, ast.Index) and\ - isinstance(node.value.value.obj, _Rom): + not isinstance(node.value.slice, ast.Slice) and \ + isinstance(node.value.value.obj, _Rom): rom = node.value.value.obj.rom # self.write("// synthesis parallel_case full_case") # self.writeline() @@ -886,20 +888,49 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin): self.write(")") self.context = None - def visit_Num(self, node): - if self.context == _context.PRINT: - self.write('"%s"' % node.n) - else: - self.write(self.IntRepr(node.n)) + if sys.version_info >= (3, 9, 0): - def visit_Str(self, node): - s = node.s - if self.context == _context.PRINT: - self.write('"%s"' % s) - elif len(s) == s.count('0') + s.count('1'): - self.write("%s'b%s" % (len(s), s)) - else: - self.write(s) + def visit_Constant(self, node): + if node.value is None: + # NameConstant + self.write(nameconstant_map[node.obj]) + elif isinstance(node.value, bool): + self.write(nameconstant_map[node.obj]) + elif isinstance(node.value, int): + # Num + if self.context == _context.PRINT: + self.write('"%s"' % node.value) + else: + self.write(self.IntRepr(node.value)) + elif isinstance(node.value, str): + # Str + s = node.value + if self.context == _context.PRINT: + self.write('"%s"' % s) + elif len(s) == s.count('0') + s.count('1'): + self.write("%s'b%s" % (len(s), s)) + else: + self.write(s) + + else: + + def visit_Num(self, node): + if self.context == _context.PRINT: + self.write('"%s"' % node.n) + else: + self.write(self.IntRepr(node.n)) + + def visit_Str(self, node): + s = node.s + if self.context == _context.PRINT: + self.write('"%s"' % s) + elif len(s) == s.count('0') + s.count('1'): + self.write("%s'b%s" % (len(s), s)) + else: + self.write(s) + + def visit_NameConstant(self, node): + self.write(nameconstant_map[node.obj]) def visit_Continue(self, node): self.write("disable %s;" % self.labelStack[-1]) @@ -1074,9 +1105,6 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin): def visit_ListComp(self, node): pass # do nothing - def visit_NameConstant(self, node): - self.write(nameconstant_map[node.obj]) - def visit_Name(self, node): if isinstance(node.ctx, ast.Store): self.setName(node) @@ -1103,6 +1131,8 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin): s = "1'b%s" % int(obj) elif isinstance(obj, int): s = self.IntRepr(obj) + elif isinstance(obj, tuple): # Python3.9+ ast.Index replacement serves a tuple + s = n elif isinstance(obj, _Signal): addSignBit = isMixedExpr s = str(obj) @@ -1115,7 +1145,7 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin): elif (type(obj) in (type,)) and issubclass(obj, Exception): s = n else: - self.raiseError(node, _error.UnsupportedType, "%s, %s" % (n, type(obj))) + self.raiseError(node, _error.UnsupportedType, "%s, %s %s" % (n, type(obj), obj)) else: raise AssertionError("name ref: %s" % n) if addSignBit: @@ -1170,7 +1200,6 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin): self.writeline() self.write("endcase") else: - print (type(obj), type(a)) self.write('$write("%s", ' % fs) self.visit(a) self.write(');') @@ -1215,7 +1244,7 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin): self.visit(lower.right) self.write("]") return - + self.write("[") if lower is None: self.write("%s" % node.obj._nrbits) @@ -1240,7 +1269,10 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin): self.visit(node.value) self.write("[") # assert len(node.subs) == 1 - self.visit(node.slice.value) + if sys.version_info >= (3, 9, 0): # Python 3.9+: no ast.Index wrapper + self.visit(node.slice) + else: + self.visit(node.slice.value) self.write("]") if addSignBit: self.write("})") @@ -1406,7 +1438,7 @@ def _convertInitVal(reg, init): if tipe is bool: v = '1' if init else '0' elif tipe is intbv: - init = int(init) # int representation + init = int(init) # int representation v = "%s" % init if init is not None else "'bz" else: assert isinstance(init, EnumItemType) @@ -1609,11 +1641,18 @@ class _AnnotateTypesVisitor(ast.NodeVisitor, _ConversionMixin): return self.generic_visit(node) - def visit_Num(self, node): - node.signed = False + if sys.version_info >= (3, 9, 0): - def visit_Str(self, node): - node.signed = False + def visit_Constant(self, node): + node.signed = False + + else: + + def visit_Num(self, node): + node.signed = False + + def visit_Str(self, node): + node.signed = False def visit_Name(self, node): if isinstance(node.ctx, ast.Store): diff --git a/myhdl/test/conversion/general/test_loops.py b/myhdl/test/conversion/general/test_loops.py index 05d7033b..cf137a22 100644 --- a/myhdl/test/conversion/general/test_loops.py +++ b/myhdl/test/conversion/general/test_loops.py @@ -2,15 +2,16 @@ 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: @@ -20,10 +21,13 @@ def ForLoopError1(a, out): if a[i] == 1: var += 1 out.next = var + return logic - + + @block def ForLoopError2(a, out): + @instance def logic(): while 1: @@ -33,10 +37,13 @@ def ForLoopError2(a, out): if a[i] == 1: var += 1 out.next = var + return logic + @block def ForLoop1(a, out): + @instance def logic(): while 1: @@ -46,10 +53,13 @@ def ForLoop1(a, out): if a[i] == 1: var += 1 out.next = var + return logic + @block def ForLoop2(a, out): + @instance def logic(): while 1: @@ -59,10 +69,13 @@ def ForLoop2(a, out): if a[i] == 1: var += 1 out.next = var + return logic + @block def ForLoop3(a, out): + @instance def logic(): while 1: @@ -72,10 +85,13 @@ def ForLoop3(a, out): if a[i] == 1: var += 1 out.next = var + return logic - + + @block def ForLoop4(a, out): + @instance def logic(): while 1: @@ -85,10 +101,13 @@ def ForLoop4(a, out): if a[i] == 1: var += 1 out.next = var + return logic + @block def ForLoop5(a, out): + @instance def logic(): while 1: @@ -98,10 +117,13 @@ def ForLoop5(a, out): if a[i] == 1: var += 1 out.next = var + return logic + @block def ForLoop6(a, out): + @instance def logic(): while 1: @@ -111,10 +133,13 @@ def ForLoop6(a, out): if a[i] == 1: var += 1 out.next = var + return logic + @block def ForContinueLoop(a, out): + @instance def logic(): while 1: @@ -125,10 +150,13 @@ def ForContinueLoop(a, out): continue var += 1 out.next = var + return logic + @block def ForBreakLoop(a, out): + @instance def logic(): while 1: @@ -138,10 +166,13 @@ def ForBreakLoop(a, out): if a[i] == 1: out.next = i break + return logic + @block def ForBreakContinueLoop(a, out): + @instance def logic(): while 1: @@ -152,10 +183,13 @@ def ForBreakContinueLoop(a, out): continue out.next = i break + return logic + @block def NestedForLoop1(a, out): + @instance def logic(): while 1: @@ -167,13 +201,16 @@ def NestedForLoop1(a, out): else: for j in downrange(i): if a[j] == 0: - var +=1 + var += 1 break out.next = var + return logic + @block def NestedForLoop2(a, out): + @instance def logic(): while 1: @@ -184,30 +221,36 @@ def NestedForLoop2(a, out): if a[i] == 0: continue else: - for j in downrange(i-1): + 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. @@ -216,10 +259,12 @@ def ReturnFromTask(a, out): if a[i] == 1: out[:] = i return - out[:] = 23 # to notice it + out[:] = 23 # to notice it + @block def TaskCall(a, out): + @instance def logic(): var = intbv(0)[8:] @@ -227,31 +272,37 @@ def TaskCall(a, out): yield a ReturnFromTask(a, var) out.next = var + return logic + @block def WhileLoop(a, out): + @instance def logic(): while 1: yield a var = 0 - i = len(a)-1 + 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 + i = len(a) - 1 while i >= 0: if a[i] == 0: i -= 1 @@ -259,41 +310,49 @@ def WhileContinueLoop(a, out): 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 + 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 + i = len(a) - 1 out.next = 0 while i >= 0: if a[i] == 0: - i -= 1 - continue + i -= 1 + continue out.next = i break + return logic - + + @block def LoopBench(LoopTest): @@ -301,7 +360,7 @@ def LoopBench(LoopTest): z = Signal(intbv(0)[16:]) looptest_inst = LoopTest(a, z) - data = tuple([randrange(2**min(i, 16)) for i in range(100)]) + data = tuple([randrange(2 ** min(i, 16)) for i in range(100)]) @instance def stimulus(): @@ -320,7 +379,8 @@ def testForLoopError1(): assert e.kind == _error.Requirement else: assert False - + + def testForLoopError2(): try: analyze(LoopBench(ForLoopError2)) @@ -329,47 +389,64 @@ def testForLoopError2(): 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 + assert verify(LoopBench(ForBreakContinueLoop)) == 0 + def testNestedForLoop1(): assert verify(LoopBench(NestedForLoop1)) == 0 + def testNestedForLoop2(): assert verify(LoopBench(NestedForLoop2)) == 0 -def testWhileLoop(): + +def testFunctionCall(): assert verify(LoopBench(FunctionCall)) == 0 -## def testTaskCall(self): -## sim = self.bench(TaskCall) -## Simulation(sim).run() +# # def testTaskCall(self): +# # sim = self.bench(TaskCall) +# # 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 diff --git a/myhdl/test/conversion/toVerilog/test_fsm.py b/myhdl/test/conversion/toVerilog/test_fsm.py index 25260d48..ee88f5bb 100644 --- a/myhdl/test/conversion/toVerilog/test_fsm.py +++ b/myhdl/test/conversion/toVerilog/test_fsm.py @@ -3,8 +3,7 @@ path = os.path import unittest from unittest import TestCase -import myhdl -from myhdl import * +from myhdl import enum, block, Signal, intbv, always, instance, delay, StopSimulation from .util import setupCosimulation @@ -15,6 +14,7 @@ t_State_b = enum('SEARCH', 'CONFIRM', 'SYNC') t_State_oh = enum('SEARCH', 'CONFIRM', 'SYNC', encoding="one_hot") t_State_oc = enum('SEARCH', 'CONFIRM', 'SYNC', encoding="one_cold") + @block def FramerCtrl(SOF, state, syncFlag, clk, reset_n, t_State): @@ -28,7 +28,7 @@ def FramerCtrl(SOF, state, syncFlag, clk, reset_n, t_State): """ - index = Signal(intbv(0)[8:]) # position in frame + index = Signal(intbv(0)[8:]) # position in frame @always(clk.posedge, reset_n.negedge) def FSM(): @@ -53,12 +53,13 @@ def FramerCtrl(SOF, state, syncFlag, clk, reset_n, t_State): if index == 0: if not syncFlag: state.next = t_State.SEARCH - SOF.next = (index == FRAME_SIZE-1) + SOF.next = (index == FRAME_SIZE - 1) else: raise ValueError("Undefined state") return FSM + @block def FramerCtrl_alt(SOF, state, syncFlag, clk, reset_n, t_State): @@ -72,10 +73,9 @@ def FramerCtrl_alt(SOF, state, syncFlag, clk, reset_n, t_State): """ - @instance def FSM(): - index = intbv(0)[8:] # position in frame + index = intbv(0)[8:] # position in frame state_var = t_State.SEARCH while 1: yield clk.posedge, reset_n.negedge @@ -100,15 +100,16 @@ def FramerCtrl_alt(SOF, state, syncFlag, clk, reset_n, t_State): if index == 0: if not syncFlag: state_var = t_State.SEARCH - SOF_var = (index == FRAME_SIZE-1) + SOF_var = (index == FRAME_SIZE - 1) else: raise ValueError("Undefined state") - index[:]= (index + 1) % FRAME_SIZE + index[:] = (index + 1) % FRAME_SIZE SOF.next = SOF_var state.next = state_var return FSM + @block def FramerCtrl_ref(SOF, state, syncFlag, clk, reset_n, t_State): @@ -124,7 +125,7 @@ def FramerCtrl_ref(SOF, state, syncFlag, clk, reset_n, t_State): @instance def logic(): - index = intbv(0, min=0, max=8) # position in frame + index = intbv(0, min=0, max=8) # position in frame while 1: yield clk.posedge, reset_n.negedge if reset_n == ACTIVE_LOW: @@ -147,10 +148,10 @@ def FramerCtrl_ref(SOF, state, syncFlag, clk, reset_n, t_State): if index == 0: if not syncFlag: state.next = t_State.SEARCH - SOF.next = (index == FRAME_SIZE-1) + SOF.next = (index == FRAME_SIZE - 1) else: raise ValueError("Undefined state") - index[:]= (index + 1) % FRAME_SIZE + index[:] = (index + 1) % FRAME_SIZE return logic @@ -192,13 +193,13 @@ class FramerCtrlTest(TestCase): @instance def stimulus(): - for i in range(3): + for __ in range(3): yield clk.posedge for n in (12, 8, 8, 4, 11, 8, 8, 7, 6, 8, 8): syncFlag.next = 1 yield clk.posedge syncFlag.next = 0 - for i in range(n-1): + for __ in range(n - 1): yield clk.posedge raise StopSimulation @@ -213,7 +214,6 @@ class FramerCtrlTest(TestCase): return framerctrl_ref_inst, framerctrl_v_inst, clkgen, stimulus, check - def testRef(self): for t_State in (t_State_b, t_State_oc, t_State_oh): tb_fsm = self.bench(FramerCtrl_ref, t_State)