From a427874a3c254d3f639731c1de331df46df2c1e0 Mon Sep 17 00:00:00 2001 From: morgan Date: Thu, 16 Jan 2025 14:40:15 +0800 Subject: [PATCH] cxp GW: remove rtio to frame pipeline --- src/gateware/cxp.py | 60 ++++++++++++++++++++++++++++----------------- 1 file changed, 38 insertions(+), 22 deletions(-) diff --git a/src/gateware/cxp.py b/src/gateware/cxp.py index a67255d..2af1b24 100644 --- a/src/gateware/cxp.py +++ b/src/gateware/cxp.py @@ -14,11 +14,11 @@ from operator import add from types import SimpleNamespace class CXP_PHYS(Module, AutoCSR): - def __init__(self, refclk, upconn_pads, downconn_pads, sys_clk_freq): + def __init__(self, refclk, upconn_pads, downconn_pads, sys_clk_freq, master=0): assert len(upconn_pads) == len(downconn_pads) self.submodules.tx = CXP_TXPHYs(upconn_pads, sys_clk_freq) - self.submodules.rx = CXP_RXPHYs(refclk, downconn_pads, sys_clk_freq) + self.submodules.rx = CXP_RXPHYs(refclk, downconn_pads, sys_clk_freq, master) self.phys = [] for tx, rx in zip(self.tx.phys, self.rx.phys): @@ -54,9 +54,6 @@ class CXP_Core(Module, AutoCSR): # TODO: remove this return self.rx.reader.mem.depth*self.downconn.bootstrap.mem.width // 8 - def get_rx_pipeline(self): - return self.rx - class CXP_Master(CXP_Core): def __init__(self, phy, debug_sma, pmod_pads): CXP_Core.__init__(self, phy) @@ -295,27 +292,46 @@ class TX_Pipeline(Module, AutoCSR): class CXP_Frame_Pipeline(Module, AutoCSR): # optimal stream packet size is 2 KiB - Section 9.5.2 (CXP-001-2021) - def __init__(self, rx_pipelines, pmod_pads, roi_engine_count=1, res_width=16, count_width=31, packet_size=16384): - n_downconn = len(rx_pipelines) - assert n_downconn > 0 + def __init__(self, pipelines, pmod_pads, roi_engine_count=1, res_width=16, count_width=31, master=0, packet_size=16384): + n_channels = len(pipelines) + assert n_channels > 0 assert count_width <= 31 - # 4 cfg (x0, x1, y0, y1) per roi_engine - self.config = rtlink.Interface(rtlink.OInterface(res_width, bits_for(4*roi_engine_count-1))) - - # select which roi engine can output rtio_input signal - self.gate_data = rtlink.Interface( - rtlink.OInterface(roi_engine_count), - # the 32th bits is for sentinel (gate detection) - rtlink.IInterface(count_width+1, timestamped=False) + # Trigger rtio + nbit_trigdelay = 8 + nbit_linktrig = 1 + self.rtlink = rtlink.Interface( + rtlink.OInterface(nbit_trigdelay + nbit_linktrig), + rtlink.IInterface(word_width, timestamped=False) ) + self.sync.rio += [ + If(self.rtlink.o.stb, + pipelines[master].tx.trig.delay.eq(self.rtlink.o.data[nbit_linktrig:]), + pipelines[master].tx.trig.linktrig_mode.eq(self.rtlink.o.data[:nbit_linktrig]), + ), + pipelines[master].tx.trig.stb.eq(self.rtlink.o.stb), + ] + + + # ROI rtio + + # # 4 cfg (x0, x1, y0, y1) per roi_engine + # self.config = rtlink.Interface(rtlink.OInterface(res_width, bits_for(4*roi_engine_count-1))) + + # # select which roi engine can output rtio_input signal + # self.gate_data = rtlink.Interface( + # rtlink.OInterface(roi_engine_count), + # # the 32th bits is for sentinel (gate detection) + # rtlink.IInterface(count_width+1, timestamped=False) + # ) + # # # cdr = ClockDomainsRenamer("cxp_gtx_rx") - debug_out = False + debug_out = True if not debug_out: self.submodules.pixel_pipeline = pixel_pipeline = cdr(Pixel_Pipeline(res_width, count_width)) @@ -383,13 +399,13 @@ class CXP_Frame_Pipeline(Module, AutoCSR): # - self.submodules.arbiter = arbiter = cdr(Stream_Arbiter(n_downconn)) + self.submodules.arbiter = arbiter = cdr(Stream_Arbiter(n_channels)) self.submodules.broadcaster = broadcaster = cdr(Stream_Broadcaster()) # Connect pipeline - for i, d in enumerate(rx_pipelines): + for i, p in enumerate(pipelines): # Assume downconns pipeline already marks the eop - self.comb += d.source.connect(arbiter.sinks[i]) + self.comb += p.rx.source.connect(arbiter.sinks[i]) self.comb += arbiter.source.connect(broadcaster.sink) @@ -400,6 +416,6 @@ class CXP_Frame_Pipeline(Module, AutoCSR): # Control interface # only the simple topology MASTER:ch0, extension:ch1,2,3 is supported right now - active_extensions = Signal(max=n_downconn) - self.sync += active_extensions.eq(reduce(add, [rx.ready.status for rx in rx_pipelines[1:]])) + active_extensions = Signal(max=n_channels) + self.sync += active_extensions.eq(reduce(add, [p.rx.ready.status for p in pipelines[1:]])) self.specials += MultiReg(active_extensions, arbiter.n_ext_active, odomain="cxp_gtx_rx"),