Skip to content

Commit 436687f

Browse files
committed
interface/stream_utils: anti stall on Arbiter
1 parent a07a3ce commit 436687f

File tree

1 file changed

+9
-2
lines changed

1 file changed

+9
-2
lines changed

lambdalib/interface/stream_utils.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from amaranth import *
44

55
from . import stream
6+
from ..cores.time.timer import *
67

78

89
__all__ = [
@@ -288,9 +289,10 @@ class Arbiter(Elaboratable):
288289
289290
sinks: a list of streams to arbiter.
290291
"""
291-
def __init__(self, sinks, source):
292+
def __init__(self, sinks, source, timeout=2**16):
292293
self.sinks = sinks
293294
self.source = source
295+
self.timeout = timeout
294296

295297
def elaborate(self, platform):
296298
source = self.source
@@ -311,10 +313,15 @@ def elaborate(self, platform):
311313
with m.If(source.valid & source.ready):
312314
m.d.sync += ongoing.eq(~source.last)
313315

316+
# Prevent a stall if the selected sink stream is no longer valid
317+
# for some time but did not give a `last` signal.
318+
m.submodules.stall = stall = WaitTimer(self.timeout)
319+
m.d.comb += stall.wait.eq(ongoing & ~source.valid & ~run)
320+
314321
# Run the round robin when:
315322
# the current transaction has completed,
316323
# or nothing is currently ongoing or pending.
317-
m.d.comb += run.eq(~(ongoing | pending) | complete)
324+
m.d.comb += run.eq(~(ongoing | pending) | complete | stall.done)
318325

319326
with m.Switch(rr.grant):
320327
for i, sink in enumerate(self.sinks):

0 commit comments

Comments
 (0)