1
0
mirror of https://github.com/myhdl/myhdl.git synced 2024-12-14 07:44:38 +08:00

Merge pull request #358 from josyb/Python3_9

Fixing issue #350
This commit is contained in:
Keerthan Jaic 2021-03-18 22:35:03 +00:00 committed by GitHub
commit 7b17942abb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 350 additions and 133 deletions

1
.gitignore vendored
View File

@ -36,3 +36,4 @@ myhdl/**/*.vhd
# Pycharm ide junk
.idea/
/.pytest_cache/

View File

@ -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)):

View File

@ -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)

View File

@ -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)

View File

@ -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(');')
@ -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):

View File

@ -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():
@ -321,6 +380,7 @@ def testForLoopError1():
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

View File

@ -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)