--- /dev/null
+import inspect
+import ast
+
+from migen.fhdl.structure import *
+from migen.pytholite import transel
+
+class FinalizeError(Exception):
+ pass
+
+class _AbstractLoad:
+ def __init__(self, target, source):
+ self.target = target
+ self.source = source
+
+class _Register:
+ def __init__(self, name, nbits):
+ self.storage = Signal(BV(nbits), name=name)
+ self.source_encoding = {}
+ self.finalized = False
+
+ def load(self, source):
+ if source not in self.source_encoding:
+ self.source_encoding[source] = len(self.source_encoding) + 1
+ return _AbstractLoad(self, source)
+
+ def finalize(self):
+ if self.finalized:
+ raise FinalizeError
+ self.sel = Signal(BV(bits_for(len(self.source_encoding) + 1)))
+ self.finalized = True
+
+ def get_fragment(self):
+ if not self.finalized:
+ raise FinalizeError
+ # do nothing when sel == 0
+ cases = [(v, self.storage.eq(k)) for k, v in self.source_encoding.items()]
+ sync = [Case(self.sel, *cases)]
+ return Fragment(sync=sync)
+
+class _AnonymousRegister:
+ def __init__(self, nbits):
+ self.nbits = nbits
+
+class _CompileVisitor(ast.NodeVisitor):
+ def __init__(self, symdict, registers):
+ self.symdict = symdict
+ self.registers = registers
+
+ def visit_Assign(self, node):
+ value = self.visit(node.value)
+ if isinstance(value, _AnonymousRegister):
+ if isinstance(node.targets[0], ast.Name):
+ name = node.targets[0].id
+ else:
+ raise NotImplementedError
+ value = _Register(name, value.nbits)
+ self.registers.append(value)
+ for target in node.targets:
+ if isinstance(target, ast.Name):
+ self.symdict[target.id] = value
+ else:
+ raise NotImplementedError
+
+ def visit_Call(self, node):
+ if isinstance(node.func, ast.Name):
+ callee = self.symdict[node.func.id]
+ else:
+ raise NotImplementedError
+ if callee == transel.Register:
+ if len(node.args) != 1:
+ raise TypeError("Register() takes exactly 1 argument")
+ nbits = ast.literal_eval(node.args[0])
+ return _AnonymousRegister(nbits)
+ else:
+ raise NotImplementedError
+
+def make_pytholite(func):
+ tree = ast.parse(inspect.getsource(func))
+ symdict = func.__globals__.copy()
+ registers = []
+
+ cv = _CompileVisitor(symdict, registers)
+ cv.visit(tree)
+
+ print(registers)
+ print(symdict)
+
+ #print(ast.dump(tree))