Token: support idle_wait
authorSebastien Bourdeauducq <sebastien@milkymist.org>
Fri, 14 Dec 2012 18:16:22 +0000 (19:16 +0100)
committerSebastien Bourdeauducq <sebastien@milkymist.org>
Fri, 14 Dec 2012 18:16:22 +0000 (19:16 +0100)
examples/dataflow/dma.py
migen/actorlib/sim.py
migen/flow/transactions.py
migen/pytholite/io.py

index dad3d47a7f606311caad732fc10e69cf035bc531..98a3a2e185228c8a84a8c120605ee7b3d9682c7f 100644 (file)
@@ -29,7 +29,7 @@ def adrgen_gen():
 
 def dumper_gen():
        while True:
-               t = Token("data")
+               t = Token("data", idle_wait=True)
                yield t
                print("Received: " + str(t.value["d"]))
 
index 153dbe13f84d246d5437f678270e6408b43bc451..67f8689eb83a29bde7e7ecf3fc0e7eff5363fe88 100644 (file)
@@ -14,6 +14,7 @@ class TokenExchanger(PureSimulable):
                self.generator = generator
                self.actor = actor
                self.active = set()
+               self.busy = True
                self.done = False
 
        def _process_transactions(self, s):
@@ -39,12 +40,15 @@ class TokenExchanger(PureSimulable):
                        else:
                                raise TypeError
                self.active -= completed
+               if not self.active:
+                       self.busy = True
        
        def _next_transactions(self):
                try:
                        transactions = next(self.generator)
                except StopIteration:
                        self.done = True
+                       self.busy = False
                        transactions = None
                if isinstance(transactions, Token):
                        self.active = {transactions}
@@ -56,6 +60,8 @@ class TokenExchanger(PureSimulable):
                        self.active = set()
                else:
                        raise TypeError
+               if all(transaction.idle_wait for transaction in self.active):
+                       self.busy = False
        
        def do_simulation(self, s):
                if not self.done:
@@ -70,7 +76,7 @@ class SimActor(Actor):
                self.token_exchanger = TokenExchanger(generator, self)
        
        def update_busy(self, s):
-               s.wr(self.busy, not self.token_exchanger.done)
+               s.wr(self.busy, self.token_exchanger.busy)
        
        def get_fragment(self):
                return self.token_exchanger.get_fragment() + Fragment(sim=[self.update_busy])
index 5c3ceab8b2b5e17f63528910e723201bcf25a624..b9c1bc1d7dac3a2d0dfcbae2e70da7e9f5e83109 100644 (file)
@@ -1,5 +1,5 @@
 class Token:
-       def __init__(self, endpoint, value=None):
+       def __init__(self, endpoint, value=None, idle_wait=False):
                self.endpoint = endpoint
                self.value = value
+               self.idle_wait = idle_wait
index 66efa6e2310e1aca89f61588730659d11835f3bf..dbaa5613e0df55653ae6e90b7de2fb9430ee27e5 100644 (file)
@@ -13,6 +13,8 @@ from migen.pytholite.expr import ExprCompiler
 class Pytholite(UnifiedIOObject):
        def __init__(self, dataflow=None, buses={}):
                super().__init__(dataflow, buses)
+               if dataflow is not None:
+                       self.busy.reset = 1
                self.memory_ports = dict((mem, mem.get_port(write_capable=True, we_granularity=8))
                        for mem in self._memories)
        
@@ -43,14 +45,18 @@ class _TokenPullExprCompiler(ExprCompiler):
 def _gen_df_io(compiler, modelname, to_model, from_model):
        epname = ast.literal_eval(to_model["endpoint"])
        values = to_model["value"]
+       idle_wait = ast.literal_eval(to_model["idle_wait"])
        ep = compiler.ioo.endpoints[epname]
+       if idle_wait:
+               state = [compiler.ioo.busy.eq(0)]
+       else:
+               state = []
        
        if isinstance(values, ast.Name) and values.id == "None":
                # token pull from sink
                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]
@@ -67,7 +73,6 @@ def _gen_df_io(compiler, modelname, to_model, from_model):
                        raise TypeError("Attempted to read from pushed token")
                if not isinstance(values, ast.Dict):
                        raise NotImplementedError
-               state = []
                for akey, value in zip(values.keys, values.values):
                        key = ast.literal_eval(akey)
                        signal = getattr(ep.token, key)
@@ -190,6 +195,7 @@ def gen_io(compiler, modelname, model, to_model, to_model_kw, from_model):
                desc = [
                        "endpoint",
                        ("value", ast.Name("None", ast.Load())),
+                       ("idle_wait", ast.Name("False", ast.Load()))
                ]
                args = _decode_args(desc, to_model, to_model_kw)
                return _gen_df_io(compiler, modelname, args, from_model)