litex/migen/fhdl/visit.py

211 lines
5.4 KiB
Python
Raw Normal View History

2012-11-28 11:50:55 -05:00
from copy import copy
2012-11-09 10:00:11 -05:00
from migen.fhdl.structure import *
2013-07-25 12:52:54 -04:00
from migen.fhdl.structure import _Operator, _Slice, _Assign, _ArrayProxy, _Fragment
2012-11-09 10:00:11 -05:00
class NodeVisitor:
def visit(self, node):
2012-11-28 17:18:43 -05:00
if isinstance(node, (int, bool)):
self.visit_constant(node)
2012-11-09 10:00:11 -05:00
elif isinstance(node, Signal):
self.visit_Signal(node)
elif isinstance(node, ClockSignal):
self.visit_ClockSignal(node)
elif isinstance(node, ResetSignal):
self.visit_ResetSignal(node)
2012-11-09 10:00:11 -05:00
elif isinstance(node, _Operator):
self.visit_Operator(node)
elif isinstance(node, _Slice):
self.visit_Slice(node)
elif isinstance(node, Cat):
self.visit_Cat(node)
elif isinstance(node, Replicate):
self.visit_Replicate(node)
elif isinstance(node, _Assign):
self.visit_Assign(node)
elif isinstance(node, If):
self.visit_If(node)
elif isinstance(node, Case):
self.visit_Case(node)
2013-07-25 12:52:54 -04:00
elif isinstance(node, _Fragment):
2012-11-09 10:00:11 -05:00
self.visit_Fragment(node)
2013-01-05 08:18:15 -05:00
elif isinstance(node, (list, tuple)):
2012-11-09 10:00:11 -05:00
self.visit_statements(node)
elif isinstance(node, dict):
self.visit_clock_domains(node)
elif isinstance(node, _ArrayProxy):
self.visit_ArrayProxy(node)
elif node is not None:
self.visit_unknown(node)
2014-10-17 05:08:37 -04:00
2012-11-28 17:18:43 -05:00
def visit_constant(self, node):
2012-11-09 10:00:11 -05:00
pass
2014-10-17 05:08:37 -04:00
2012-11-09 11:37:24 -05:00
def visit_Signal(self, node):
2012-11-09 10:00:11 -05:00
pass
def visit_ClockSignal(self, node):
pass
def visit_ResetSignal(self, node):
pass
2014-10-17 05:08:37 -04:00
2012-11-09 11:37:24 -05:00
def visit_Operator(self, node):
2012-11-09 10:00:11 -05:00
for o in node.operands:
self.visit(o)
2014-10-17 05:08:37 -04:00
2012-11-09 11:37:24 -05:00
def visit_Slice(self, node):
2012-11-09 10:00:11 -05:00
self.visit(node.value)
2014-10-17 05:08:37 -04:00
2012-11-09 11:37:24 -05:00
def visit_Cat(self, node):
2012-11-09 10:00:11 -05:00
for e in node.l:
self.visit(e)
2014-10-17 05:08:37 -04:00
2012-11-09 11:37:24 -05:00
def visit_Replicate(self, node):
2012-11-09 10:00:11 -05:00
self.visit(node.v)
2014-10-17 05:08:37 -04:00
2012-11-09 11:37:24 -05:00
def visit_Assign(self, node):
2012-11-09 10:00:11 -05:00
self.visit(node.l)
self.visit(node.r)
2014-10-17 05:08:37 -04:00
2012-11-09 11:37:24 -05:00
def visit_If(self, node):
2012-11-09 10:00:11 -05:00
self.visit(node.cond)
self.visit(node.t)
self.visit(node.f)
2014-10-17 05:08:37 -04:00
2012-11-09 11:37:24 -05:00
def visit_Case(self, node):
2012-11-09 10:00:11 -05:00
self.visit(node.test)
2012-11-28 19:11:15 -05:00
for v, statements in node.cases.items():
2012-11-09 10:00:11 -05:00
self.visit(statements)
2014-10-17 05:08:37 -04:00
2012-11-09 11:37:24 -05:00
def visit_Fragment(self, node):
2012-11-09 10:00:11 -05:00
self.visit(node.comb)
self.visit(node.sync)
2014-10-17 05:08:37 -04:00
2012-11-09 11:37:24 -05:00
def visit_statements(self, node):
2012-11-09 10:00:11 -05:00
for statement in node:
self.visit(statement)
2014-10-17 05:08:37 -04:00
2012-11-09 11:37:24 -05:00
def visit_clock_domains(self, node):
2012-11-09 10:00:11 -05:00
for clockname, statements in node.items():
self.visit(statements)
2014-10-17 05:08:37 -04:00
2012-11-09 11:37:24 -05:00
def visit_ArrayProxy(self, node):
2012-11-09 10:00:11 -05:00
for choice in node.choices:
self.visit(choice)
self.visit(node.key)
2014-10-17 05:08:37 -04:00
2012-11-09 11:37:24 -05:00
def visit_unknown(self, node):
2012-11-09 10:00:11 -05:00
pass
2012-11-28 11:50:55 -05:00
# Default methods always copy the node, except for:
# - Signals, ClockSignals and ResetSignals
2012-11-28 11:50:55 -05:00
# - Unknown objects
# - All fragment fields except comb and sync
# In those cases, the original node is returned unchanged.
2012-11-09 10:00:11 -05:00
class NodeTransformer:
def visit(self, node):
2012-11-28 17:18:43 -05:00
if isinstance(node, (int, bool)):
return self.visit_constant(node)
2012-11-09 10:00:11 -05:00
elif isinstance(node, Signal):
return self.visit_Signal(node)
elif isinstance(node, ClockSignal):
return self.visit_ClockSignal(node)
elif isinstance(node, ResetSignal):
return self.visit_ResetSignal(node)
2012-11-09 10:00:11 -05:00
elif isinstance(node, _Operator):
return self.visit_Operator(node)
elif isinstance(node, _Slice):
return self.visit_Slice(node)
elif isinstance(node, Cat):
return self.visit_Cat(node)
elif isinstance(node, Replicate):
return self.visit_Replicate(node)
elif isinstance(node, _Assign):
return self.visit_Assign(node)
elif isinstance(node, If):
return self.visit_If(node)
elif isinstance(node, Case):
return self.visit_Case(node)
2013-07-25 12:52:54 -04:00
elif isinstance(node, _Fragment):
2012-11-09 10:00:11 -05:00
return self.visit_Fragment(node)
2013-01-05 08:18:15 -05:00
elif isinstance(node, (list, tuple)):
2012-11-09 10:00:11 -05:00
return self.visit_statements(node)
elif isinstance(node, dict):
return self.visit_clock_domains(node)
elif isinstance(node, _ArrayProxy):
return self.visit_ArrayProxy(node)
elif node is not None:
return self.visit_unknown(node)
else:
return None
2014-10-17 05:08:37 -04:00
2012-11-28 17:18:43 -05:00
def visit_constant(self, node):
2012-11-09 10:00:11 -05:00
return node
2014-10-17 05:08:37 -04:00
2012-11-09 11:37:24 -05:00
def visit_Signal(self, node):
2012-11-09 10:00:11 -05:00
return node
2014-10-17 05:08:37 -04:00
def visit_ClockSignal(self, node):
return node
def visit_ResetSignal(self, node):
return node
2012-11-09 11:37:24 -05:00
def visit_Operator(self, node):
2012-11-28 11:50:55 -05:00
return _Operator(node.op, [self.visit(o) for o in node.operands])
2014-10-17 05:08:37 -04:00
2012-11-09 11:37:24 -05:00
def visit_Slice(self, node):
2012-11-28 11:50:55 -05:00
return _Slice(self.visit(node.value), node.start, node.stop)
2014-10-17 05:08:37 -04:00
2012-11-09 11:37:24 -05:00
def visit_Cat(self, node):
2012-11-28 11:50:55 -05:00
return Cat(*[self.visit(e) for e in node.l])
2014-10-17 05:08:37 -04:00
2012-11-09 11:37:24 -05:00
def visit_Replicate(self, node):
2012-11-28 11:50:55 -05:00
return Replicate(self.visit(node.v), node.n)
2014-10-17 05:08:37 -04:00
2012-11-09 11:37:24 -05:00
def visit_Assign(self, node):
2012-11-28 11:50:55 -05:00
return _Assign(self.visit(node.l), self.visit(node.r))
2014-10-17 05:08:37 -04:00
2012-11-09 11:37:24 -05:00
def visit_If(self, node):
2012-11-28 11:50:55 -05:00
r = If(self.visit(node.cond))
r.t = self.visit(node.t)
r.f = self.visit(node.f)
return r
2014-10-17 05:08:37 -04:00
2012-11-09 11:37:24 -05:00
def visit_Case(self, node):
2012-11-28 19:11:15 -05:00
cases = dict((v, self.visit(statements)) for v, statements in node.cases.items())
r = Case(self.visit(node.test), cases)
2012-11-28 11:50:55 -05:00
return r
2014-10-17 05:08:37 -04:00
2012-11-09 11:37:24 -05:00
def visit_Fragment(self, node):
2012-11-28 11:50:55 -05:00
r = copy(node)
r.comb = self.visit(node.comb)
r.sync = self.visit(node.sync)
return r
2014-10-17 05:08:37 -04:00
2013-01-05 08:18:15 -05:00
# NOTE: this will always return a list, even if node is a tuple
2012-11-09 11:37:24 -05:00
def visit_statements(self, node):
2012-11-09 10:00:11 -05:00
return [self.visit(statement) for statement in node]
2014-10-17 05:08:37 -04:00
2012-11-09 11:37:24 -05:00
def visit_clock_domains(self, node):
2012-11-09 10:00:11 -05:00
return dict((clockname, self.visit(statements)) for clockname, statements in node.items())
2014-10-17 05:08:37 -04:00
2012-11-09 11:37:24 -05:00
def visit_ArrayProxy(self, node):
2012-11-28 11:50:55 -05:00
return _ArrayProxy([self.visit(choice) for choice in node.choices],
self.visit(node.key))
2014-10-17 05:08:37 -04:00
2012-11-09 11:37:24 -05:00
def visit_unknown(self, node):
2012-11-09 10:00:11 -05:00
return node
2013-04-10 17:42:14 -04:00
class TransformModule:
def __init__(self, transform, module):
self.transform = transform
self.module = module
2015-03-14 12:45:11 -04:00
self.get_fragment_called = False
2013-04-10 17:42:14 -04:00
def get_fragment(self):
2015-03-14 12:45:11 -04:00
assert(not self.get_fragment_called)
self.get_fragment_called = True
2013-04-10 17:42:14 -04:00
return self.transform(self.module.get_fragment())