diff --git a/artiq/gateware/rtio/sed/fifo.py b/artiq/gateware/rtio/sed/fifo.py new file mode 100644 index 000000000..1f908a0c1 --- /dev/null +++ b/artiq/gateware/rtio/sed/fifo.py @@ -0,0 +1,37 @@ +from migen import * +from migen.genlib.fifo import * + +from artiq.gateware.rtio.sed import layouts + + +__all__ = ["FIFO"] + + +class FIFO(Module): + def __init__(self, lane_count, mode, fifo_depth, layout_payload): + seqn_width = layouts.seqn_width(lane_count, fifo_width) + self.input = [layouts.fifo_ingress(seqn_width, layout_payload) + for _ in range(lane_count)] + self.output = [layouts.fifo_egress(seqn_width, layout_payload) + for _ in range(lane_count)] + + if mode == "sync": + fifo_cls = fifo.SyncFIFOBuffered + elif mode == "async": + fifo_cls = fifo.AsyncFIFO + else: + raise ValueError + + for input, output in zip(self.input, self.output): + fifo = fifo_cls(layout_len(layout_payload), fifo_depth) + self.submodules += fifo + + self.comb += [ + fifo.din.eq(input.payload.raw_bits()), + fifo.we.eq(input.we), + input.writable.eq(fifo.writable), + + output.payload.raw_bits().eq(fifo.dout), + output.readable.eq(fifo.readable), + fifo.re.eq(output.re) + ] diff --git a/artiq/gateware/rtio/sed/lane_distributor.py b/artiq/gateware/rtio/sed/lane_distributor.py index d21d40484..c58dfeb6d 100644 --- a/artiq/gateware/rtio/sed/lane_distributor.py +++ b/artiq/gateware/rtio/sed/lane_distributor.py @@ -14,14 +14,10 @@ __all__ = ["LaneDistributor"] # 3. check status class LaneDistributor(Module): - def __init__(self, lane_count, fifo_size, layout_payload, fine_ts_width, enable_spread=True): + def __init__(self, lane_count, seqn_width, layout_payload, fine_ts_width, enable_spread=True): if lane_count & (lane_count - 1): raise NotImplementedError("lane count must be a power of 2") - # There must be a unique sequence number for every possible event in every FIFO. - # Plus 2 bits to detect and handle wraparounds. - seqn_width = bits_for(lane_count*fifo_size-1) + 2 - self.cri = cri.Interface() self.minimum_coarse_timestamp = Signal(64-fine_ts_width) self.lane_io = [Record(layouts.fifo_ingress(seqn_width, layout_payload)) diff --git a/artiq/gateware/rtio/sed/layouts.py b/artiq/gateware/rtio/sed/layouts.py index 4408a5d00..5feac13b2 100644 --- a/artiq/gateware/rtio/sed/layouts.py +++ b/artiq/gateware/rtio/sed/layouts.py @@ -21,6 +21,12 @@ def fifo_payload(channels): return layout +def seqn_width(lane_count, fifo_width): + # There must be a unique sequence number for every possible event in every FIFO. + # Plus 2 bits to detect and handle wraparounds. + return bits_for(lane_count*fifo_size-1) + 2 + + def fifo_ingress(seqn_width, layout_payload): return [ ("we", 1, DIR_M_TO_S), diff --git a/artiq/gateware/test/rtio/test_sed_lane_distributor.py b/artiq/gateware/test/rtio/test_sed_lane_distributor.py index c9f883db4..f7c4efa28 100644 --- a/artiq/gateware/test/rtio/test_sed_lane_distributor.py +++ b/artiq/gateware/test/rtio/test_sed_lane_distributor.py @@ -10,7 +10,7 @@ LANE_COUNT = 8 def simulate(input_events, wait=True): - dut = lane_distributor.LaneDistributor(LANE_COUNT, 16, [("channel", 8), ("timestamp", 32)], 3) + dut = lane_distributor.LaneDistributor(LANE_COUNT, 8, [("channel", 8), ("timestamp", 32)], 3) output = [] access_results = []