mirror of
https://github.com/enjoy-digital/litex.git
synced 2025-01-04 09:52:26 -05:00
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 <lars@metafoo.de>
This commit is contained in:
parent
72579a6129
commit
dea4674922
1 changed files with 25 additions and 18 deletions
|
@ -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):
|
||||
if s.rd(ep.ack) and s.rd(ep.stb):
|
||||
token.value = s.multiread(ep.token)
|
||||
completed.add(token)
|
||||
s.wr(ep.ack, 0)
|
||||
else:
|
||||
s.wr(ep.ack, 1)
|
||||
elif isinstance(ep, Source):
|
||||
if s.rd(ep.stb):
|
||||
if s.rd(ep.ack):
|
||||
if s.rd(ep.ack) and s.rd(ep.stb):
|
||||
completed.add(token)
|
||||
s.wr(ep.stb, 0)
|
||||
else:
|
||||
s.wr(ep.stb, 1)
|
||||
s.multiwrite(ep.token, token.value)
|
||||
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)
|
||||
|
@ -65,10 +69,13 @@ class TokenExchanger(PureSimulable):
|
|||
|
||||
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):
|
||||
|
|
Loading…
Reference in a new issue