From 72579a612960c4c97f159da110249abd38c95d28 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 12 Mar 2013 21:34:36 +0100 Subject: [PATCH 1/2] Add support for negative slice indices In python a negative indices usually mean start counting from the right side. I.e. if the index is negative is acutal index used is len(l) + i. E.g. l[-2] equals l[len(l)-2]. Being able to specify an index this way also comes in handy for migen slices in some cases. E.g. the following snippet can be implement to shift an abitrary length register n bits to the right: reg.eq(Cat(Replicate(0, n), reg[-n:]) Signed-off-by: Lars-Peter Clausen --- migen/fhdl/structure.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/migen/fhdl/structure.py b/migen/fhdl/structure.py index 8052fdffb..350670fc5 100644 --- a/migen/fhdl/structure.py +++ b/migen/fhdl/structure.py @@ -89,10 +89,16 @@ class Value(HUID): def __getitem__(self, key): if isinstance(key, int): + if (key < 0): + key += len(self) return _Slice(self, key, key+1) elif isinstance(key, slice): start = key.start or 0 stop = key.stop or len(self) + if (start < 0): + start += len(self) + if (stop < 0): + stop += len(self) if stop > len(self): stop = len(self) if key.step != None: From dea46749220fb78154b9cb3355b87275b4339707 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 12 Mar 2013 22:27:19 +0100 Subject: [PATCH 2/2] Allow SimActors to produce/consume a constant stream of tokens Currently a SimActor requires one clock period to recover from consuming or producing a token. ack/stb are deasserted in the cycle where the token is consumed/produced and only re-asserted in the next cycle. This patch updates the code to keep the control signals asserted if the actor is able to produce or consume a token in the next cycle. The patch also sets 'initialize' attribute on the simulation method, this will make sure that the control and data signals will be ready right on the first clock cycle. Signed-off-by: Lars-Peter Clausen --- migen/actorlib/sim.py | 43 +++++++++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/migen/actorlib/sim.py b/migen/actorlib/sim.py index de11f1c97..18a7bfc9b 100644 --- a/migen/actorlib/sim.py +++ b/migen/actorlib/sim.py @@ -22,27 +22,31 @@ class TokenExchanger(PureSimulable): for token in self.active: ep = self.actor.endpoints[token.endpoint] if isinstance(ep, Sink): - if s.rd(ep.ack): - if s.rd(ep.stb): - token.value = s.multiread(ep.token) - completed.add(token) - s.wr(ep.ack, 0) - else: - s.wr(ep.ack, 1) + if s.rd(ep.ack) and s.rd(ep.stb): + token.value = s.multiread(ep.token) + completed.add(token) + s.wr(ep.ack, 0) elif isinstance(ep, Source): - if s.rd(ep.stb): - if s.rd(ep.ack): - completed.add(token) - s.wr(ep.stb, 0) - else: - s.wr(ep.stb, 1) - s.multiwrite(ep.token, token.value) + if s.rd(ep.ack) and s.rd(ep.stb): + completed.add(token) + s.wr(ep.stb, 0) else: raise TypeError self.active -= completed if not self.active: self.busy = True - + + def _update_control_signals(self, s): + for token in self.active: + ep = self.actor.endpoints[token.endpoint] + if isinstance(ep, Sink): + s.wr(ep.ack, 1) + elif isinstance(ep, Source): + s.multiwrite(ep.token, token.value) + s.wr(ep.stb, 1) + else: + raise TypeError + def _next_transactions(self): try: transactions = next(self.generator) @@ -62,13 +66,16 @@ class TokenExchanger(PureSimulable): raise TypeError if self.active and all(transaction.idle_wait for transaction in self.active): self.busy = False - + def do_simulation(self, s): if not self.done: - if not self.active: - self._next_transactions() if self.active: self._process_transactions(s) + if not self.active: + self._next_transactions() + self._update_control_signals(s) + + do_simulation.initialize = True class SimActor(Actor): def __init__(self, generator, *endpoint_descriptions, **misc):