Permalink
Browse files

pytholite/io: support token pull

  • Loading branch information...
1 parent 748741b commit eb156af20ccc3c4f46274bfb3a4b535ca25461b1 @sbourdeauducq sbourdeauducq committed Nov 16, 2012
Showing with 52 additions and 6 deletions.
  1. +2 −2 migen/pytholite/compiler.py
  2. +11 −0 migen/pytholite/expr.py
  3. +39 −4 migen/pytholite/io.py
@@ -154,7 +154,7 @@ def visit_io_pattern(self, sa, targets, model, args, statements):
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 @@ def visit_expr_statement(self, sa, node):
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
@@ -19,6 +19,10 @@ def visit_expr(self, node):
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 @@ def visit_expr_name(self, node):
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
@@ -4,6 +4,7 @@
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

0 comments on commit eb156af

Please sign in to comment.