pytholite/compiler: create FSM
This commit is contained in:
parent
7744655ef2
commit
a645e0b24e
|
@ -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
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue