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
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
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
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
+
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):
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]
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]
]
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