pytholite/compiler: create FSM

This commit is contained in:
Sebastien Bourdeauducq 2012-11-09 17:37:42 +01:00
parent 7744655ef2
commit a645e0b24e
1 changed files with 36 additions and 8 deletions

View File

@ -1,7 +1,10 @@
import inspect import inspect
import ast import ast
from operator import itemgetter
from migen.fhdl.structure import * from migen.fhdl.structure import *
from migen.fhdl import visit as fhdl
from migen.corelogic.fsm import FSM
from migen.pytholite import transel from migen.pytholite import transel
class FinalizeError(Exception): class FinalizeError(Exception):
@ -12,6 +15,18 @@ class _AbstractLoad:
self.target = target self.target = target
self.source = source self.source = source
def lower(self):
if not self.target.finalized:
raise FinalizeError
return self.target.sel.eq(self.target.source_encoding[self.source])
class _LowerAbstractLoad(fhdl.NodeTransformer):
def visit_unknown(self, node):
if isinstance(node, _AbstractLoad):
return node.lower()
else:
return node
class _Register: class _Register:
def __init__(self, name, nbits): def __init__(self, name, nbits):
self.storage = Signal(BV(nbits), name=name) self.storage = Signal(BV(nbits), name=name)
@ -26,15 +41,16 @@ class _Register:
def finalize(self): def finalize(self):
if self.finalized: if self.finalized:
raise FinalizeError raise FinalizeError
self.sel = Signal(BV(bits_for(len(self.source_encoding) + 1))) self.sel = Signal(BV(bits_for(len(self.source_encoding) + 1)), name="pl_regsel")
self.finalized = True self.finalized = True
def get_fragment(self): def get_fragment(self):
if not self.finalized: if not self.finalized:
raise FinalizeError raise FinalizeError
# do nothing when sel == 0 # do nothing when sel == 0
items = sorted(self.source_encoding.items(), key=itemgetter(1))
cases = [(Constant(v, self.sel.bv), cases = [(Constant(v, self.sel.bv),
self.storage.eq(k)) for k, v in self.source_encoding.items()] self.storage.eq(k)) for k, v in items]
sync = [Case(self.sel, *cases)] sync = [Case(self.sel, *cases)]
return Fragment(sync=sync) return Fragment(sync=sync)
@ -153,6 +169,18 @@ class _Compiler:
def visit_expr_num(self, node): def visit_expr_num(self, node):
return node.n return node.n
def _create_fsm(states):
stnames = ["S" + str(i) for i in range(len(states))]
fsm = FSM(*stnames)
for i, state in enumerate(states):
if i == len(states) - 1:
actions = []
else:
actions = [fsm.next_state(getattr(fsm, stnames[i+1]))]
actions += state
fsm.act(getattr(fsm, stnames[i]), *actions)
return fsm
def make_pytholite(func): def make_pytholite(func):
tree = ast.parse(inspect.getsource(func)) tree = ast.parse(inspect.getsource(func))
symdict = func.__globals__.copy() symdict = func.__globals__.copy()
@ -163,11 +191,6 @@ def make_pytholite(func):
print("compilation result:") print("compilation result:")
print(states) print(states)
print("registers:")
print(registers)
#print("symdict:")
#print(symdict)
print("ast:") print("ast:")
print(ast.dump(tree)) print(ast.dump(tree))
@ -175,4 +198,9 @@ def make_pytholite(func):
for register in registers: for register in registers:
register.finalize() register.finalize()
regf += register.get_fragment() regf += register.get_fragment()
return regf
fsm = _create_fsm(states)
fsmf = _LowerAbstractLoad().visit(fsm.get_fragment())
return regf + fsmf