litex/migen/fhdl/tools.py

126 lines
3.3 KiB
Python
Raw Normal View History

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
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
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
def list_inst_ios(i, ins, outs, inouts):
2011-12-08 10:35:32 -05:00
if isinstance(i, Fragment):
return list_inst_ios(i.instances, ins, outs, inouts)
2011-12-08 10:35:32 -05:00
else:
l = []
for x in i:
2012-01-20 16:36:17 -05:00
if ins:
l += x.ins.values()
if outs:
l += x.outs.values()
if inouts:
l += x.inouts.values()
2011-12-08 10:35:32 -05:00
return set(l)
def list_mem_ios(m, ins, outs):
if isinstance(m, Fragment):
return list_mem_ios(m.memories, ins, outs)
else:
s = set()
def add(*sigs):
for sig in sigs:
if sig is not None:
s.add(sig)
for x in m:
for p in x.ports:
if ins:
add(p.adr, p.we, p.dat_w, p.re)
if outs:
add(p.dat_r)
return s
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)