diff --git a/artiq/gateware/rtio/sed/lane_distributor.py b/artiq/gateware/rtio/sed/lane_distributor.py index f2524d012..d21d40484 100644 --- a/artiq/gateware/rtio/sed/lane_distributor.py +++ b/artiq/gateware/rtio/sed/lane_distributor.py @@ -1,19 +1,12 @@ from migen import * from artiq.gateware.rtio import cri +from artiq.gateware.rtio.sed import layouts __all__ = ["LaneDistributor"] -def layout_lane_io(seqn_width, layout_payload): - return [ - ("we", 1, DIR_M_TO_S), - ("writable", 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]) - ] - # CRI write happens in 3 cycles: # 1. set timestamp @@ -31,7 +24,7 @@ class LaneDistributor(Module): self.cri = cri.Interface() self.minimum_coarse_timestamp = Signal(64-fine_ts_width) - self.lane_io = [Record(layout_lane_io(seqn_width, layout_payload)) + self.lane_io = [Record(layouts.fifo_ingress(seqn_width, layout_payload)) for _ in range(lane_count)] # # # diff --git a/artiq/gateware/rtio/sed/layouts.py b/artiq/gateware/rtio/sed/layouts.py new file mode 100644 index 000000000..4408a5d00 --- /dev/null +++ b/artiq/gateware/rtio/sed/layouts.py @@ -0,0 +1,67 @@ +from migen import * + +from artiq.gateware.rtio import rtlink + + +def fifo_payload(channels): + address_width = max(rtlink.get_address_width(channel.interface) + for channel in channels) + data_width = max(rtlink.get_data_width(channel.interface) + for channel in channels) + + layout = [ + ("channel", bits_for(len(channels)-1)), + ("timestamp", 64) + ] + if address_width: + layout.append(("address", address_width)) + if data_width: + layout.append(("data", data_width)) + + return layout + + +def fifo_ingress(seqn_width, layout_payload): + return [ + ("we", 1, DIR_M_TO_S), + ("writable", 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]) + ] + + +def fifo_egress(seqn_width, layout_payload): + return [ + ("re", 1, DIR_S_TO_M), + ("readable", 1, DIR_M_TO_S), + ("seqn", seqn_width, DIR_M_TO_S), + ("payload", [(a, b, DIR_M_TO_S) for a, b in layout_payload]) + ] + + +def output_network_payload(channels): + fine_ts_width = max(rtlink.get_fine_ts_width(channel.interface) + for channel in channels) + address_width = max(rtlink.get_address_width(channel.interface) + for channel in channels) + data_width = max(rtlink.get_data_width(channel.interface) + for channel in channels) + + layout = [("channel", bits_for(len(channels)-1))] + if fine_ts_width: + layout.append(("fine_ts", fine_ts_width)) + if address_width: + layout.append(("address", address_width)) + if data_width: + layout.append(("data", data_width)) + + return layout + + +def output_network_node(seqn_width, layout_payload): + return [ + ("valid", 1), + ("seqn", seqn_width), + ("replace_occured", 1), + ("payload", layout_payload) + ] diff --git a/artiq/gateware/rtio/sed/output_driver.py b/artiq/gateware/rtio/sed/output_driver.py index 5ee24753e..4edf83d34 100644 --- a/artiq/gateware/rtio/sed/output_driver.py +++ b/artiq/gateware/rtio/sed/output_driver.py @@ -3,7 +3,7 @@ from operator import or_ from migen import * -from artiq.gateware.rtio import rtlink +from artiq.gateware.rtio.sed import layouts from artiq.gateware.rtio.sed.output_network import OutputNetwork @@ -17,21 +17,8 @@ class OutputDriver(Module): self.busy = Signal() self.busy_channel = Signal(max=len(channels)) - fine_ts_width = max(rtlink.get_fine_ts_width(channel.interface) - for channel in channels) - address_width = max(rtlink.get_address_width(channel.interface) - for channel in channels) - data_width = max(rtlink.get_data_width(channel.interface) - for channel in channels) - # output network - layout_on_payload = [("channel", bits_for(len(channels)-1))] - if fine_ts_width: - layout_on_payload.append(("fine_ts", fine_ts_width)) - if address_width: - layout_on_payload.append(("address", address_width)) - if data_width: - layout_on_payload.append(("data", data_width)) + layout_on_payload = layouts.output_network_payload(channels) output_network = OutputNetwork(lane_count, seqn_width, layout_on_payload) self.submodules += output_network self.input = output_network.input diff --git a/artiq/gateware/rtio/sed/output_network.py b/artiq/gateware/rtio/sed/output_network.py index edb875b1c..05797bdcb 100644 --- a/artiq/gateware/rtio/sed/output_network.py +++ b/artiq/gateware/rtio/sed/output_network.py @@ -1,5 +1,7 @@ from migen import * +from artiq.gateware.rtio.sed import layouts + __all__ = ["latency", "OutputNetwork"] @@ -42,28 +44,19 @@ def latency(lane_count): return sum(l for l in range(1, d+1)) -def layout_node_data(seqn_width, layout_payload): - return [ - ("valid", 1), - ("seqn", seqn_width), - ("replace_occured", 1), - ("payload", layout_payload) - ] - - def cmp_wrap(a, b): return Mux(a[-2:] == ~b[-2:], a[0], a[:-2] < b[:-2]) class OutputNetwork(Module): def __init__(self, lane_count, seqn_width, layout_payload): - self.input = [Record(layout_node_data(seqn_width, layout_payload)) + self.input = [Record(layouts.output_network_node(seqn_width, layout_payload)) for _ in range(lane_count)] self.output = None step_input = self.input for step in boms_steps_pairs(lane_count): - step_output = [Record(layout_node_data(seqn_width, layout_payload)) + step_output = [Record(layouts.output_network_node(seqn_width, layout_payload)) for _ in range(lane_count)] for node1, node2 in step: