pytholite/io: support token pull

This commit is contained in:
Sebastien Bourdeauducq 2012-11-16 23:48:41 +01:00
parent 748741b49a
commit eb156af20c
3 changed files with 52 additions and 6 deletions

View File

@ -154,7 +154,7 @@ class _Compiler:
raise NotImplementedError
from_model.append((tregs, fstatement.value))
states, exit_states = gen_io(self, model, args, from_model)
states, exit_states = gen_io(self, modelname, model, args, from_model)
sa.assemble(states, exit_states)
return fstatement
@ -222,7 +222,7 @@ class _Compiler:
if not isinstance(yvalue, ast.Call) or not isinstance(yvalue.func, ast.Name):
raise NotImplementedError("Unrecognized I/O pattern")
callee = self.symdict[yvalue.func.id]
states, exit_states = gen_io(self, callee, yvalue.args, [])
states, exit_states = gen_io(self, None, callee, yvalue.args, [])
sa.assemble(states, exit_states)
else:
raise NotImplementedError

View File

@ -19,6 +19,10 @@ class ExprCompiler:
return self.visit_expr_name(node)
elif isinstance(node, ast.Num):
return self.visit_expr_num(node)
elif isinstance(node, ast.Attribute):
return self.visit_expr_attribute(node)
elif isinstance(node, ast.Subscript):
return self.visit_expr_subscript(node)
else:
raise NotImplementedError
@ -102,3 +106,10 @@ class ExprCompiler:
def visit_expr_num(self, node):
return Constant(node.n)
def visit_expr_attribute(self, node):
raise NotImplementedError
def visit_expr_subscript(self, node):
raise NotImplementedError

View File

@ -4,6 +4,7 @@ from migen.fhdl.structure import *
from migen.flow.actor import *
from migen.actorlib.sim import *
from migen.pytholite.fsm import *
from migen.pytholite.expr import ExprCompiler
class Pytholite:
def get_fragment(self):
@ -18,7 +19,28 @@ def make_io_object(dataflow=None):
else:
return DFPytholite(*dataflow)
def gen_df_io(compiler, to_model, from_model):
class _TokenPullExprCompiler(ExprCompiler):
def __init__(self, symdict, modelname, ep):
super().__init__(symdict)
self.modelname = modelname
self.ep = ep
def visit_expr_subscript(self, node):
# check that we are subscripting <modelname>.value
if not isinstance(node.value, ast.Attribute) \
or node.value.attr != "value" \
or not isinstance(node.value.value, ast.Name) \
or node.value.value.id != self.modelname:
raise NotImplementedError
if not isinstance(node.slice, ast.Index):
raise NotImplementedError
field = ast.literal_eval(node.slice.value)
signal = getattr(self.ep.token, field)
return signal
def gen_df_io(compiler, modelname, to_model, from_model):
if len(to_model) == 1 or len(to_model) == 2:
epname = ast.literal_eval(to_model[0])
ep = compiler.ioo.endpoints[epname]
@ -27,9 +49,22 @@ def gen_df_io(compiler, to_model, from_model):
if len(to_model) == 1:
# token pull from sink
raise NotImplementedError # TODO
if not isinstance(ep, Sink):
raise TypeError("Attempted to pull from source")
ec = _TokenPullExprCompiler(compiler.symdict, modelname, ep)
state = []
for target_regs, expr in from_model:
cexpr = ec.visit_expr(expr)
state += [reg.load(cexpr) for reg in target_regs]
state += [
ep.ack.eq(1),
If(~ep.stb, AbstractNextState(state))
]
return [state], [state]
else:
# token push to source
if not isinstance(ep, Source):
raise TypeError("Attempted to push to sink")
if from_model:
raise TypeError("Attempted to read from pushed token")
d = to_model[1]
@ -46,8 +81,8 @@ def gen_df_io(compiler, to_model, from_model):
]
return [state], [state]
def gen_io(compiler, model, to_model, from_model):
def gen_io(compiler, modelname, model, to_model, from_model):
if model == Token:
return gen_df_io(compiler, to_model, from_model)
return gen_df_io(compiler, modelname, to_model, from_model)
else:
raise NotImplementedError