1
0
mirror of https://github.com/myhdl/myhdl.git synced 2025-01-24 21:52:56 +08:00

map to case

This commit is contained in:
jand 2004-01-05 21:28:51 +00:00
parent ebfa3be920
commit 4e4451a4d4
3 changed files with 79 additions and 6 deletions

View File

@ -35,9 +35,9 @@ def enum(*args, **kwargs):
encoding = kwargs.get('encoding', 'binary')
argdict = {}
codedict = {}
if encoding == 'binary':
if encoding == "binary":
nrbits = len(bin(len(args)))
elif encoding in ('one_hot', 'one_cold'):
elif encoding in ("one_hot", "one_cold"):
nrbits = len(args)
else:
raise ValueError("Unsupported enum encoding: %s \n Supported encodings:" + \
@ -50,9 +50,9 @@ def enum(*args, **kwargs):
if codedict.has_key(arg):
raise ValueError("enum literals should be unique")
argdict[i] = arg
if encoding == 'binary':
if encoding == "binary":
code = bin(i, nrbits)
elif encoding == 'one_hot':
elif encoding == "one_hot":
code = bin(1<<i, nrbits)
else: # one_cold
code = bin(~(1<<i), nrbits)
@ -66,11 +66,20 @@ def enum(*args, **kwargs):
self._index = index
self._val = codedict[arg]
self._nrbits = nrbits
self._nritems = len(args)
def __repr__(self):
return argdict[self._index]
def __hex__(self):
return hex(int(self._val, 2))
__str__ = __repr__
def _toVerilog(self, dontcare=False):
val = self._val
if dontcare:
if encoding == "one_hot":
val = val.replace('0', '?')
elif encoding == "one_cold":
val = val.replace('1', '?')
return "%d'b%s" % (self._nrbits, val)
class Enum(object):
def __init__(self):

View File

@ -98,6 +98,7 @@ def _analyzeGens(top, genNames):
s = inspect.getsource(f)
s = s.lstrip()
ast = compiler.parse(s)
print ast
ast.sourcefile = inspect.getsourcefile(f)
ast.lineoffset = inspect.getsourcelines(f)[1]-1
ast.symdict = f.f_globals.copy()
@ -377,6 +378,12 @@ class _AnalyzeVisitor(_ToVerilogMixin):
def visitCompare(self, node, *args):
node.obj = bool()
self.visitChildNodes(node)
op, arg = node.ops[0]
if op == '==':
if isinstance(node.expr, astNode.Name) and \
str(type(arg.obj)) == "<class 'myhdl._enum.EnumItem'>":
node.case = (node.expr.name, arg.obj)
def visitConst(self, node, *args):
if isinstance(node.value, int):
@ -425,6 +432,27 @@ class _AnalyzeVisitor(_ToVerilogMixin):
self.refStack.push()
self.visit(node.else_, *args)
self.refStack.pop()
# check whether the if can be mapped to a (parallel) case
node.isCase = node.isFullCase = False
test1 = node.tests[0][0]
if not hasattr(test1, 'case'):
return
name1, item1 = test1.case
choices = Set()
choices.add(item1._index)
for test, suite in node.tests[1:]:
if not hasattr(test, 'case'):
return
name, item = test.case
if name != name1 or type(item) is not type(item1):
return
if item._index in choices:
return
choices.add(item._index)
node.isCase = True
node.caseVar = name1
if (len(choices) == item1._nritems) or (node.else_ is not None):
node.isFullCase = True
def visitName(self, node, access=_access.INPUT, *args):
n = node.name

View File

@ -478,9 +478,45 @@ class _ConvertVisitor(_ToVerilogMixin):
elif str(type(obj)) == "<class 'myhdl._enum.Enum'>":
assert hasattr(obj, node.attrname)
e = getattr(obj, node.attrname)
self.write("%d'b%s" % (obj._nrbits, e._val))
self.write(e._toVerilog())
def visitIf(self, node, *args):
if node.isCase:
self.mapToCase(node, *args)
else:
self.mapToIf(node, *args)
def mapToCase(self, node, *args):
var = node.caseVar
self.write("// synthesis parallel_case")
if node.isFullCase:
self.write(" full_case")
self.writeline()
self.write("casez (%s)" % var)
self.indent()
for test, suite in node.tests:
self.writeline()
item = test.ops[0][1].obj
self.write(item._toVerilog(dontcare=True))
self.write(": begin")
self.indent()
self.visit(suite)
self.dedent()
self.writeline()
self.write("end")
if node.else_:
self.writeline()
self.write("default: begin")
self.indent()
self.visit(node.else_)
self.dedent()
self.writeline()
self.write("end")
self.dedent()
self.writeline()
self.write("endcase")
def mapToIf(self, node, *args):
first = True
for test, suite in node.tests:
if first: