cxp GW: remove rtio to frame pipeline

This commit is contained in:
morgan 2025-01-16 14:40:15 +08:00
parent 61183d1c6d
commit a427874a3c

View File

@ -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"),