Skip to content

Commit a5e7a63

Browse files
committed
interface/stream_utils: add Gate module
1 parent bd22bcb commit a5e7a63

File tree

1 file changed

+50
-0
lines changed

1 file changed

+50
-0
lines changed

lambdalib/interface/stream_utils.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
"LastInserter",
1414
"LastOnTimeout",
1515
"Arbiter",
16+
"Gate",
1617
]
1718

1819

@@ -378,3 +379,52 @@ def elaborate(self, platform):
378379
m.d.comb += sink.connect(source)
379380

380381
return m
382+
383+
384+
class Gate(Elaboratable):
385+
""" This module enables or disables the data flow between
386+
sink and source streams.
387+
388+
param: drop_when_disabled:
389+
when set, data from the sink is dropped when the gate is closed.
390+
when not set, the data is not consumed from the sink when closed.
391+
392+
param: wait_last:
393+
when set, the gate state will be updated only when receiving
394+
the next `last` to avoid cutting in the middle of a packet.
395+
"""
396+
def __init__(self, layout, drop_when_disabled=False, wait_last=False):
397+
self.drop_when_disabled = drop_when_disabled
398+
self.wait_last = wait_last
399+
400+
self.enable = Signal()
401+
self.sink = stream.Endpoint(layout)
402+
self.source = stream.Endpoint(layout)
403+
404+
def elaborate(self, platform):
405+
sink = self.sink
406+
source = self.source
407+
408+
m = Module()
409+
410+
if self.wait_last:
411+
flowing = Signal()
412+
413+
# Wait for the `last` signal to change the gate state.
414+
with m.If(flowing | self.drop_when_disabled):
415+
with m.If(sink.valid & sink.ready & sink.last):
416+
m.d.sync += flowing.eq(self.enable)
417+
with m.Else():
418+
m.d.sync += flowing.eq(self.enable)
419+
420+
else:
421+
flowing = self.enable
422+
423+
# Connect streams when the gate is open,
424+
# or optionally drop data when closed.
425+
with m.If(flowing):
426+
m.d.comb += sink.connect(source)
427+
with m.Else():
428+
m.d.comb += sink.ready.eq(self.drop_when_disabled)
429+
430+
return m

0 commit comments

Comments
 (0)