Commit a67f483f authored by Sebastien Bourdeauducq's avatar Sebastien Bourdeauducq
Browse files

Token: support idle_wait

parent 6f992415
...@@ -29,7 +29,7 @@ def adrgen_gen(): ...@@ -29,7 +29,7 @@ def adrgen_gen():
def dumper_gen(): def dumper_gen():
while True: while True:
t = Token("data") t = Token("data", idle_wait=True)
yield t yield t
print("Received: " + str(t.value["d"])) print("Received: " + str(t.value["d"]))
......
...@@ -14,6 +14,7 @@ class TokenExchanger(PureSimulable): ...@@ -14,6 +14,7 @@ class TokenExchanger(PureSimulable):
self.generator = generator self.generator = generator
self.actor = actor self.actor = actor
self.active = set() self.active = set()
self.busy = True
self.done = False self.done = False
def _process_transactions(self, s): def _process_transactions(self, s):
...@@ -39,12 +40,15 @@ class TokenExchanger(PureSimulable): ...@@ -39,12 +40,15 @@ class TokenExchanger(PureSimulable):
else: else:
raise TypeError raise TypeError
self.active -= completed self.active -= completed
if not self.active:
self.busy = True
def _next_transactions(self): def _next_transactions(self):
try: try:
transactions = next(self.generator) transactions = next(self.generator)
except StopIteration: except StopIteration:
self.done = True self.done = True
self.busy = False
transactions = None transactions = None
if isinstance(transactions, Token): if isinstance(transactions, Token):
self.active = {transactions} self.active = {transactions}
...@@ -56,6 +60,8 @@ class TokenExchanger(PureSimulable): ...@@ -56,6 +60,8 @@ class TokenExchanger(PureSimulable):
self.active = set() self.active = set()
else: else:
raise TypeError raise TypeError
if all(transaction.idle_wait for transaction in self.active):
self.busy = False
def do_simulation(self, s): def do_simulation(self, s):
if not self.done: if not self.done:
...@@ -70,7 +76,7 @@ class SimActor(Actor): ...@@ -70,7 +76,7 @@ class SimActor(Actor):
self.token_exchanger = TokenExchanger(generator, self) self.token_exchanger = TokenExchanger(generator, self)
def update_busy(self, s): 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): def get_fragment(self):
return self.token_exchanger.get_fragment() + Fragment(sim=[self.update_busy]) return self.token_exchanger.get_fragment() + Fragment(sim=[self.update_busy])
......
class Token: class Token:
def __init__(self, endpoint, value=None): def __init__(self, endpoint, value=None, idle_wait=False):
self.endpoint = endpoint self.endpoint = endpoint
self.value = value self.value = value
self.idle_wait = idle_wait
...@@ -13,6 +13,8 @@ from migen.pytholite.expr import ExprCompiler ...@@ -13,6 +13,8 @@ from migen.pytholite.expr import ExprCompiler
class Pytholite(UnifiedIOObject): class Pytholite(UnifiedIOObject):
def __init__(self, dataflow=None, buses={}): def __init__(self, dataflow=None, buses={}):
super().__init__(dataflow, 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)) self.memory_ports = dict((mem, mem.get_port(write_capable=True, we_granularity=8))
for mem in self._memories) for mem in self._memories)
...@@ -43,14 +45,18 @@ class _TokenPullExprCompiler(ExprCompiler): ...@@ -43,14 +45,18 @@ class _TokenPullExprCompiler(ExprCompiler):
def _gen_df_io(compiler, modelname, to_model, from_model): def _gen_df_io(compiler, modelname, to_model, from_model):
epname = ast.literal_eval(to_model["endpoint"]) epname = ast.literal_eval(to_model["endpoint"])
values = to_model["value"] values = to_model["value"]
idle_wait = ast.literal_eval(to_model["idle_wait"])
ep = compiler.ioo.endpoints[epname] 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": if isinstance(values, ast.Name) and values.id == "None":
# token pull from sink # token pull from sink
if not isinstance(ep, Sink): if not isinstance(ep, Sink):
raise TypeError("Attempted to pull from source") raise TypeError("Attempted to pull from source")
ec = _TokenPullExprCompiler(compiler.symdict, modelname, ep) ec = _TokenPullExprCompiler(compiler.symdict, modelname, ep)
state = []
for target_regs, expr in from_model: for target_regs, expr in from_model:
cexpr = ec.visit_expr(expr) cexpr = ec.visit_expr(expr)
state += [reg.load(cexpr) for reg in target_regs] state += [reg.load(cexpr) for reg in target_regs]
...@@ -67,7 +73,6 @@ def _gen_df_io(compiler, modelname, to_model, from_model): ...@@ -67,7 +73,6 @@ def _gen_df_io(compiler, modelname, to_model, from_model):
raise TypeError("Attempted to read from pushed token") raise TypeError("Attempted to read from pushed token")
if not isinstance(values, ast.Dict): if not isinstance(values, ast.Dict):
raise NotImplementedError raise NotImplementedError
state = []
for akey, value in zip(values.keys, values.values): for akey, value in zip(values.keys, values.values):
key = ast.literal_eval(akey) key = ast.literal_eval(akey)
signal = getattr(ep.token, key) signal = getattr(ep.token, key)
...@@ -190,6 +195,7 @@ def gen_io(compiler, modelname, model, to_model, to_model_kw, from_model): ...@@ -190,6 +195,7 @@ def gen_io(compiler, modelname, model, to_model, to_model_kw, from_model):
desc = [ desc = [
"endpoint", "endpoint",
("value", ast.Name("None", ast.Load())), ("value", ast.Name("None", ast.Load())),
("idle_wait", ast.Name("False", ast.Load()))
] ]
args = _decode_args(desc, to_model, to_model_kw) args = _decode_args(desc, to_model, to_model_kw)
return _gen_df_io(compiler, modelname, args, from_model) return _gen_df_io(compiler, modelname, args, from_model)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment