diff --git a/RELEASE_NOTES.rst b/RELEASE_NOTES.rst index e4901d2c6..d0edd2a60 100644 --- a/RELEASE_NOTES.rst +++ b/RELEASE_NOTES.rst @@ -28,6 +28,7 @@ Highlights: clock, to facilitate implementation of local processing on DRTIO satellites, and to slightly reduce RTIO latency. * Support for DRTIO-over-EEM, used with Shuttler. +* Enabled event spreading on DRTIO satellites, using high watermark for lane switching. * Added channel names to RTIO error messages. * GUI: - Implemented Applet Request Interfaces which allow applets to modify datasets and set the diff --git a/artiq/gateware/drtio/core.py b/artiq/gateware/drtio/core.py index c6db5d9af..8928f833e 100644 --- a/artiq/gateware/drtio/core.py +++ b/artiq/gateware/drtio/core.py @@ -61,8 +61,8 @@ class SyncRTIO(Module): self.submodules.outputs = ClockDomainsRenamer("rio")( SED(channels, tsc.glbl_fine_ts_width, lane_count=lane_count, fifo_depth=fifo_depth, - enable_spread=False, report_buffer_space=True, - interface=self.cri)) + enable_spread=True, fifo_high_watermark=0.75, + report_buffer_space=True, interface=self.cri)) self.comb += self.outputs.coarse_timestamp.eq(tsc.coarse_ts) self.sync += self.outputs.minimum_coarse_timestamp.eq(tsc.coarse_ts + 16) diff --git a/artiq/gateware/rtio/sed/core.py b/artiq/gateware/rtio/sed/core.py index 8953ff9d2..32ed90996 100644 --- a/artiq/gateware/rtio/sed/core.py +++ b/artiq/gateware/rtio/sed/core.py @@ -12,10 +12,13 @@ __all__ = ["SED"] class SED(Module): def __init__(self, channels, glbl_fine_ts_width, - lane_count=8, fifo_depth=128, enable_spread=True, + lane_count=8, fifo_depth=128, fifo_high_watermark=1.0, enable_spread=True, quash_channels=[], report_buffer_space=False, interface=None): seqn_width = layouts.seqn_width(lane_count, fifo_depth) + fifo_high_watermark = int(fifo_high_watermark * fifo_depth) + assert fifo_depth >= fifo_high_watermark + self.submodules.lane_dist = LaneDistributor(lane_count, seqn_width, layouts.fifo_payload(channels), [channel.interface.o.delay for channel in channels], @@ -23,7 +26,7 @@ class SED(Module): enable_spread=enable_spread, quash_channels=quash_channels, interface=interface) - self.submodules.fifos = FIFOs(lane_count, fifo_depth, + self.submodules.fifos = FIFOs(lane_count, fifo_depth, fifo_high_watermark, layouts.fifo_payload(channels), report_buffer_space) self.submodules.gates = Gates(lane_count, seqn_width, layouts.fifo_payload(channels), diff --git a/artiq/gateware/rtio/sed/fifos.py b/artiq/gateware/rtio/sed/fifos.py index 3bf1bfc5a..81a260678 100644 --- a/artiq/gateware/rtio/sed/fifos.py +++ b/artiq/gateware/rtio/sed/fifos.py @@ -11,7 +11,7 @@ __all__ = ["FIFOs"] class FIFOs(Module): - def __init__(self, lane_count, fifo_depth, layout_payload, report_buffer_space=False): + def __init__(self, lane_count, fifo_depth, high_watermark, layout_payload, report_buffer_space=False): seqn_width = layouts.seqn_width(lane_count, fifo_depth) self.input = [Record(layouts.fifo_ingress(seqn_width, layout_payload)) for _ in range(lane_count)] @@ -33,6 +33,7 @@ class FIFOs(Module): fifo.din.eq(Cat(input.seqn, input.payload.raw_bits())), fifo.we.eq(input.we), input.writable.eq(fifo.writable), + input.high_watermark.eq(fifo.level >= high_watermark), Cat(output.seqn, output.payload.raw_bits()).eq(fifo.dout), output.readable.eq(fifo.readable), diff --git a/artiq/gateware/rtio/sed/lane_distributor.py b/artiq/gateware/rtio/sed/lane_distributor.py index 08a3fa716..f14010362 100644 --- a/artiq/gateware/rtio/sed/lane_distributor.py +++ b/artiq/gateware/rtio/sed/lane_distributor.py @@ -154,8 +154,10 @@ class LaneDistributor(Module): self.comb += lio.payload.timestamp.eq(compensated_timestamp) # cycle #3, read status + current_lane_high_watermark = Signal() current_lane_writable = Signal() self.comb += [ + current_lane_high_watermark.eq(Array(lio.high_watermark for lio in self.output)[current_lane]), current_lane_writable.eq(Array(lio.writable for lio in self.output)[current_lane]), o_status_wait.eq(~current_lane_writable) ] @@ -170,12 +172,10 @@ class LaneDistributor(Module): self.sequence_error_channel.eq(self.cri.chan_sel[:16]) ] - # current lane has been full, spread events by switching to the next. + # current lane has reached high watermark, spread events by switching to the next. if enable_spread: - current_lane_writable_r = Signal(reset=1) self.sync += [ - current_lane_writable_r.eq(current_lane_writable), - If(~current_lane_writable_r & current_lane_writable, + If(current_lane_high_watermark | ~current_lane_writable, force_laneB.eq(1) ), If(do_write, diff --git a/artiq/gateware/rtio/sed/layouts.py b/artiq/gateware/rtio/sed/layouts.py index 1fbb8f6ec..c3b69d64b 100644 --- a/artiq/gateware/rtio/sed/layouts.py +++ b/artiq/gateware/rtio/sed/layouts.py @@ -31,6 +31,7 @@ def fifo_ingress(seqn_width, layout_payload): return [ ("we", 1, DIR_M_TO_S), ("writable", 1, DIR_S_TO_M), + ("high_watermark", 1, DIR_S_TO_M), ("seqn", seqn_width, DIR_M_TO_S), ("payload", [(a, b, DIR_M_TO_S) for a, b in layout_payload]) ]