pytholite/io: support token pull
This commit is contained in:
parent
748741b49a
commit
eb156af20c
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue