2011-12-16 15:30:14 -05:00
|
|
|
from migen.fhdl.structure import *
|
2011-12-21 16:57:07 -05:00
|
|
|
from migen.fhdl.structure import _Operator, _Slice, _Assign, _StatementList
|
2011-12-04 16:41:50 -05:00
|
|
|
|
|
|
|
class Namespace:
|
|
|
|
def __init__(self):
|
|
|
|
self.counts = {}
|
|
|
|
self.sigs = {}
|
|
|
|
|
2011-12-16 10:02:55 -05:00
|
|
|
def get_name(self, sig):
|
2011-12-04 16:41:50 -05:00
|
|
|
try:
|
|
|
|
n = self.sigs[sig]
|
|
|
|
if n:
|
|
|
|
return sig.name + "_" + str(n)
|
|
|
|
else:
|
|
|
|
return sig.name
|
|
|
|
except KeyError:
|
|
|
|
try:
|
|
|
|
n = self.counts[sig.name]
|
|
|
|
except KeyError:
|
|
|
|
n = 0
|
|
|
|
self.sigs[sig] = n
|
|
|
|
self.counts[sig.name] = n + 1
|
|
|
|
if n:
|
|
|
|
return sig.name + "_" + str(n)
|
|
|
|
else:
|
|
|
|
return sig.name
|
|
|
|
|
2011-12-16 10:02:55 -05:00
|
|
|
def list_signals(node):
|
2012-01-15 11:45:54 -05:00
|
|
|
if node is None:
|
|
|
|
return set()
|
|
|
|
elif isinstance(node, Constant):
|
2011-12-04 16:41:50 -05:00
|
|
|
return set()
|
|
|
|
elif isinstance(node, Signal):
|
|
|
|
return {node}
|
2011-12-16 15:30:14 -05:00
|
|
|
elif isinstance(node, _Operator):
|
2011-12-16 10:02:55 -05:00
|
|
|
l = list(map(list_signals, node.operands))
|
2011-12-04 16:41:50 -05:00
|
|
|
return set().union(*l)
|
2011-12-21 16:57:07 -05:00
|
|
|
elif isinstance(node, _Slice):
|
2011-12-16 10:02:55 -05:00
|
|
|
return list_signals(node.value)
|
2011-12-04 16:41:50 -05:00
|
|
|
elif isinstance(node, Cat):
|
2011-12-16 10:02:55 -05:00
|
|
|
l = list(map(list_signals, node.l))
|
2011-12-04 16:41:50 -05:00
|
|
|
return set().union(*l)
|
2011-12-09 07:11:34 -05:00
|
|
|
elif isinstance(node, Replicate):
|
2011-12-16 10:02:55 -05:00
|
|
|
return list_signals(node.v)
|
2011-12-21 16:57:07 -05:00
|
|
|
elif isinstance(node, _Assign):
|
2011-12-16 10:02:55 -05:00
|
|
|
return list_signals(node.l) | list_signals(node.r)
|
2011-12-21 16:57:07 -05:00
|
|
|
elif isinstance(node, _StatementList):
|
2011-12-16 10:02:55 -05:00
|
|
|
l = list(map(list_signals, node.l))
|
2011-12-04 16:41:50 -05:00
|
|
|
return set().union(*l)
|
|
|
|
elif isinstance(node, If):
|
2011-12-16 10:02:55 -05:00
|
|
|
return list_signals(node.cond) | list_signals(node.t) | list_signals(node.f)
|
2011-12-05 11:43:56 -05:00
|
|
|
elif isinstance(node, Case):
|
2011-12-16 10:02:55 -05:00
|
|
|
l = list(map(lambda x: list_signals(x[1]), node.cases))
|
|
|
|
return list_signals(node.test).union(*l).union(list_signals(node.default))
|
2011-12-04 16:41:50 -05:00
|
|
|
elif isinstance(node, Fragment):
|
2011-12-16 10:02:55 -05:00
|
|
|
return list_signals(node.comb) | list_signals(node.sync)
|
2011-12-04 16:41:50 -05:00
|
|
|
else:
|
|
|
|
raise TypeError
|
|
|
|
|
2011-12-16 10:02:55 -05:00
|
|
|
def list_targets(node):
|
2012-01-15 11:45:54 -05:00
|
|
|
if node is None:
|
|
|
|
return set()
|
|
|
|
elif isinstance(node, Signal):
|
2011-12-04 16:41:50 -05:00
|
|
|
return {node}
|
2011-12-21 16:57:07 -05:00
|
|
|
elif isinstance(node, _Slice):
|
2011-12-16 10:02:55 -05:00
|
|
|
return list_targets(node.value)
|
2011-12-04 16:41:50 -05:00
|
|
|
elif isinstance(node, Cat):
|
2011-12-16 10:02:55 -05:00
|
|
|
l = list(map(list_targets, node.l))
|
2011-12-04 16:41:50 -05:00
|
|
|
return set().union(*l)
|
2011-12-21 16:57:07 -05:00
|
|
|
elif isinstance(node, _Assign):
|
2011-12-16 10:02:55 -05:00
|
|
|
return list_targets(node.l)
|
2011-12-21 16:57:07 -05:00
|
|
|
elif isinstance(node, _StatementList):
|
2011-12-16 10:02:55 -05:00
|
|
|
l = list(map(list_targets, node.l))
|
2011-12-04 16:41:50 -05:00
|
|
|
return set().union(*l)
|
|
|
|
elif isinstance(node, If):
|
2011-12-16 10:02:55 -05:00
|
|
|
return list_targets(node.t) | list_targets(node.f)
|
2011-12-05 11:43:56 -05:00
|
|
|
elif isinstance(node, Case):
|
2011-12-16 10:02:55 -05:00
|
|
|
l = list(map(lambda x: list_targets(x[1]), node.cases))
|
|
|
|
return list_targets(node.default).union(*l)
|
2011-12-08 10:35:32 -05:00
|
|
|
elif isinstance(node, Fragment):
|
2011-12-16 10:02:55 -05:00
|
|
|
return list_targets(node.comb) | list_targets(node.sync)
|
2011-12-04 16:41:50 -05:00
|
|
|
else:
|
|
|
|
raise TypeError
|
|
|
|
|
2012-01-07 06:19:06 -05:00
|
|
|
def group_by_targets(sl):
|
|
|
|
groups = []
|
|
|
|
for statement in sl.l:
|
|
|
|
targets = list_targets(statement)
|
|
|
|
processed = False
|
|
|
|
for g in groups:
|
|
|
|
if not targets.isdisjoint(g[0]):
|
|
|
|
g[0].update(targets)
|
|
|
|
g[1].append(statement)
|
|
|
|
processed = True
|
|
|
|
break
|
|
|
|
if not processed:
|
|
|
|
groups.append((targets, [statement]))
|
|
|
|
return groups
|
|
|
|
|
2011-12-16 10:02:55 -05:00
|
|
|
def list_inst_outs(i):
|
2011-12-08 10:35:32 -05:00
|
|
|
if isinstance(i, Fragment):
|
2011-12-16 10:02:55 -05:00
|
|
|
return list_inst_outs(i.instances)
|
2011-12-08 10:35:32 -05:00
|
|
|
else:
|
|
|
|
l = []
|
|
|
|
for x in i:
|
|
|
|
l += list(map(lambda x: x[1], list(x.outs.items())))
|
|
|
|
return set(l)
|
|
|
|
|
2011-12-16 10:02:55 -05:00
|
|
|
def is_variable(node):
|
2011-12-05 16:00:06 -05:00
|
|
|
if isinstance(node, Signal):
|
|
|
|
return node.variable
|
2011-12-21 16:57:07 -05:00
|
|
|
elif isinstance(node, _Slice):
|
2011-12-16 10:02:55 -05:00
|
|
|
return is_variable(node.value)
|
2011-12-05 16:00:06 -05:00
|
|
|
elif isinstance(node, Cat):
|
2011-12-16 10:02:55 -05:00
|
|
|
arevars = list(map(is_variable, node.l))
|
2011-12-05 16:00:06 -05:00
|
|
|
r = arevars[0]
|
|
|
|
for x in arevars:
|
|
|
|
if x != r:
|
|
|
|
raise TypeError
|
|
|
|
return r
|
|
|
|
else:
|
|
|
|
raise TypeError
|
|
|
|
|
2011-12-16 10:02:55 -05:00
|
|
|
def insert_reset(rst, sl):
|
|
|
|
targets = list_targets(sl)
|
2011-12-16 15:30:14 -05:00
|
|
|
resetcode = [t.eq(t.reset) for t in targets]
|
|
|
|
return If(rst, *resetcode).Else(*sl.l)
|