cxp GW: update

This commit is contained in:
morgan 2025-01-16 12:18:20 +08:00
parent ce32c78212
commit 56b1553bdb

View File

@ -295,7 +295,6 @@ class TX_Pipeline(Module, AutoCSR):
class CXP_Frame_Pipeline(Module, AutoCSR): class CXP_Frame_Pipeline(Module, AutoCSR):
# optimal stream packet size is 2 KiB - Section 9.5.2 (CXP-001-2021) # optimal stream packet size is 2 KiB - Section 9.5.2 (CXP-001-2021)
# largest x/y pixel size supported by frame header are 24 bits
def __init__(self, rx_pipelines, pmod_pads, roi_engine_count=1, res_width=16, count_width=31, packet_size=16384): 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) n_downconn = len(rx_pipelines)
assert n_downconn > 0 assert n_downconn > 0
@ -315,62 +314,63 @@ class CXP_Frame_Pipeline(Module, AutoCSR):
# # # # # #
cdr = ClockDomainsRenamer("cxp_gtx_rx") cdr = ClockDomainsRenamer("cxp_gtx_rx")
debug_out = False
# self.submodules.pixel_pipeline = pixel_pipeline = cdr(Pixel_Pipeline(res_width, count_width)) if not debug_out:
self.submodules.pixel_pipeline = pixel_pipeline = cdr(Pixel_Pipeline(res_width, count_width))
# # RTIO interface # RTIO interface
# n = 0 n = 0
# cfg = pixel_pipeline.roi.cfg cfg = pixel_pipeline.roi.cfg
# for offset, target in enumerate([cfg.x0, cfg.y0, cfg.x1, cfg.y1]): for offset, target in enumerate([cfg.x0, cfg.y0, cfg.x1, cfg.y1]):
# roi_boundary = Signal.like(target) roi_boundary = Signal.like(target)
# self.sync.rio += If(self.config.o.stb & (self.config.o.address == 4*n+offset), self.sync.rio += If(self.config.o.stb & (self.config.o.address == 4*n+offset),
# roi_boundary.eq(self.config.o.data)) roi_boundary.eq(self.config.o.data))
# self.specials += MultiReg(roi_boundary, target, "cxp_gtx_rx") self.specials += MultiReg(roi_boundary, target, "cxp_gtx_rx")
# roi_out = pixel_pipeline.roi.out roi_out = pixel_pipeline.roi.out
# update = Signal() update = Signal()
# self.submodules.ps = ps = PulseSynchronizer("cxp_gtx_rx", "sys") self.submodules.ps = ps = PulseSynchronizer("cxp_gtx_rx", "sys")
# self.sync.cxp_gtx_rx += ps.i.eq(roi_out.update) self.sync.cxp_gtx_rx += ps.i.eq(roi_out.update)
# self.sync += update.eq(ps.o) self.sync += update.eq(ps.o)
# sentinel = 2**count_width sentinel = 2**count_width
# count_sys = Signal.like(roi_out.count) count_sys = Signal.like(roi_out.count)
# # count_rx = Signal.like(roi_out.count) # count_rx = Signal.like(roi_out.count)
# # self.sync.cxp_gtx_rx += count_rx.eq(roi_out.count), # self.sync.cxp_gtx_rx += count_rx.eq(roi_out.count),
# # self.specials += MultiReg(count_rx, count_sys), # self.specials += MultiReg(count_rx, count_sys),
# self.specials += MultiReg(roi_out.count, count_sys), self.specials += MultiReg(roi_out.count, count_sys),
# self.sync.rio += [ self.sync.rio += [
# self.gate_data.i.stb.eq(update), self.gate_data.i.stb.eq(update),
# self.gate_data.i.data.eq(count_sys), self.gate_data.i.data.eq(count_sys),
# ] ]
# DEBUG:
crc_checker = cdr(CXPCRC32_Checker())
# TODO: handle full buffer gracefully else:
# TODO: investigate why there is a heartbeat message in the middle of the frame with k27.7 code too??? # DEBUG:
# NOTE: sometimes there are 0xFBFBFBFB K=0b1111 crc_checker = cdr(CXPCRC32_Checker())
# perhaps the buffer is full overflowing and doing strange stuff
# it should be mem block not "cycle buffer" # TODO: handle full buffer gracefully
# self.submodules.dropper = dropper = cdr(DChar_Dropper()) # TODO: investigate why there is a heartbeat message in the middle of the frame with k27.7 code too???
buffer = cdr(Buffer(word_layout_dchar)) # crcchecker timinig is bad # NOTE: sometimes there are 0xFBFBFBFB K=0b1111
buffer_cdc_fifo = cdr(Buffer(word_layout_dchar)) # to improve timing # perhaps the buffer is full overflowing and doing strange stuff
cdc_fifo = stream.AsyncFIFO(word_layout_dchar, 2**log2_int(packet_size//word_width))
self.submodules += buffer, crc_checker, buffer_cdc_fifo
self.submodules += ClockDomainsRenamer({"write": "cxp_gtx_rx", "read": "sys"})(cdc_fifo)
pipeline = [buffer, crc_checker, buffer_cdc_fifo, cdc_fifo] # it should be mem block not "cycle buffer"
for s, d in zip(pipeline, pipeline[1:]): # self.submodules.dropper = dropper = cdr(DChar_Dropper())
self.comb += s.source.connect(d.sink) buffer = cdr(Buffer(word_layout_dchar)) # crcchecker timinig is bad
buffer_cdc_fifo = cdr(Buffer(word_layout_dchar)) # to improve timing
# # DEBUG: cdc_fifo = stream.AsyncFIFO(word_layout_dchar, 2**log2_int(packet_size//word_width))
self.submodules.debug_out = debug_out = RX_Debug_Buffer(word_layout_dchar, 2**log2_int(packet_size//word_width)) self.submodules += buffer, crc_checker, buffer_cdc_fifo
self.comb += pipeline[-1].source.connect(debug_out.sink) self.submodules += ClockDomainsRenamer({"write": "cxp_gtx_rx", "read": "sys"})(cdc_fifo)
self.submodules.debug_out = debug_out = RX_Debug_Buffer(word_layout_dchar, 2**log2_int(packet_size//word_width))
pipeline = [buffer, crc_checker, buffer_cdc_fifo, cdc_fifo, debug_out]
for s, d in zip(pipeline, pipeline[1:]):
self.comb += s.source.connect(d.sink)
@ -392,9 +392,11 @@ class CXP_Frame_Pipeline(Module, AutoCSR):
self.comb += d.source.connect(arbiter.sinks[i]) self.comb += d.source.connect(arbiter.sinks[i])
self.comb += arbiter.source.connect(broadcaster.sink) self.comb += arbiter.source.connect(broadcaster.sink)
# self.comb += broadcaster.sources[0].connect(pixel_pipeline.sink),
# DEBUG if not debug_out:
self.comb += broadcaster.sources[0].connect(pipeline[0].sink), self.comb += broadcaster.sources[0].connect(pixel_pipeline.sink),
else:
self.comb += broadcaster.sources[0].connect(pipeline[0].sink),
# Control interface # Control interface
# only the simple topology MASTER:ch0, extension:ch1,2,3 is supported right now # only the simple topology MASTER:ch0, extension:ch1,2,3 is supported right now