cxp GW: refactor test counter csr

cxp GW: improve timinig of test seq csr

cxp gw: refactor csr

cxp GW: improve timing

cxp GW: clenaup

cxp GW: add proto new 4x router
This commit is contained in:
morgan 2025-01-23 13:13:10 +08:00
parent a363f50357
commit 62c72c11b0

View File

@ -9,6 +9,8 @@ from cxp_upconn import CXP_TXPHYs
from cxp_pipeline import *
from cxp_frame_pipeline import *
import cxp_router
from functools import reduce
from operator import add
from types import SimpleNamespace
@ -153,40 +155,55 @@ class RX_Pipeline(Module, AutoCSR):
),
]
# TODO: rewrite this to follow crc_error_cnt from frameline
# test packet error & packet counters
self.test_error_counter = CSRStatus(len(reader.test_err_cnt))
self.test_packet_counter = CSRStatus(len(reader.test_pak_cnt))
self.test_error_counter = CSRStatus(16)
self.test_packet_counter = CSRStatus(16)
self.test_counts_reset = CSR()
test_reset_ps = PulseSynchronizer("sys", "cxp_gtx_rx")
self.submodules += test_reset_ps
test_err_cnt_sys = Signal.like(self.test_error_counter.status)
test_pak_cnt_sys = Signal.like(self.test_packet_counter.status)
self.sync += [
self.test_error_counter.status.eq(test_err_cnt_sys),
self.test_packet_counter.status.eq(test_pak_cnt_sys),
]
self.submodules.test_reset_ps = test_reset_ps = PulseSynchronizer("sys", "cxp_gtx_rx")
self.sync += test_reset_ps.i.eq(self.test_counts_reset.re),
test_err_cnt_r = Signal.like(reader.test_err_cnt)
test_pak_cnt_r = Signal.like(reader.test_pak_cnt)
test_err_cnt_rx = Signal.like(test_err_cnt_sys)
test_pak_cnt_rx = Signal.like(test_pak_cnt_sys)
test_err_r, test_pak_r = Signal(), Signal()
self.sync.cxp_gtx_rx += [
reader.test_cnt_reset.eq(test_reset_ps.o),
test_err_cnt_r.eq(reader.test_err_cnt),
test_pak_cnt_r.eq(reader.test_pak_cnt),
test_err_r.eq(reader.test_err),
test_pak_r.eq(reader.test_pak),
If(test_reset_ps.o,
test_err_cnt_rx.eq(test_err_cnt_rx.reset),
).Elif(test_err_r,
test_err_cnt_rx.eq(test_err_cnt_rx + 1),
),
If(test_reset_ps.o,
test_pak_cnt_rx.eq(test_pak_cnt_rx.reset),
).Elif(test_pak_r,
test_pak_cnt_rx.eq(test_pak_cnt_rx + 1),
),
]
self.specials += [
MultiReg(test_err_cnt_r, self.test_error_counter.status),
MultiReg(test_pak_cnt_r, self.test_packet_counter.status),
MultiReg(test_err_cnt_rx, test_err_cnt_sys),
MultiReg(test_pak_cnt_rx, test_pak_cnt_sys),
]
# reader cicular memory control interface
self.packet_type = CSRStatus(8)
# reader nslot buffer control interface
self.pending_packet = CSR()
self.read_ptr = CSRStatus(log2_int(nslot))
self.read_ptr = CSRStatus(len(reader.read_ptr))
write_ptr_sys = Signal.like(reader.write_ptr)
self.specials += [
MultiReg(reader.packet_type, self.packet_type.status),
MultiReg(self.read_ptr.status, reader.read_ptr_rx, odomain="cxp_gtx_rx"),
MultiReg(self.read_ptr.status, reader.read_ptr, odomain="cxp_gtx_rx"),
MultiReg(reader.write_ptr, write_ptr_sys)
]
self.sync += [
self.pending_packet.w.eq(self.read_ptr.status != reader.write_ptr_sys),
self.pending_packet.w.eq(self.read_ptr.status != write_ptr_sys),
If(~gtx.rx_ready,
self.read_ptr.status.eq(0),
).Elif(self.pending_packet.re & self.pending_packet.w,
@ -194,6 +211,7 @@ class RX_Pipeline(Module, AutoCSR):
)
]
# TODO: remove this
self.submodules.fifo = fifo = cdr(stream.SyncFIFO(word_layout_dchar, 32, True))
# Drop the K29.7 and mark the EOP for arbiter and crc cheker
@ -483,6 +501,68 @@ class CXP_Frame_Pipeline(Module, AutoCSR):
rx_stb = Signal()
self.sync.cxp_gtx_rx += rx_stb.eq(p.rx.source.stb)
self.specials += [
Instance("OBUF", i_I=rx_stb, o_O=pmod_pads[i]),
# Instance("OBUF", i_I=rx_stb, o_O=pmod_pads[i]),
# Instance("OBUF", i_I=arbiter.sinks[i].stb, o_O=pmod_pads[i]),
]
class NEO_CXP_Frame_pipeline(Module):
# optimal stream packet size is 2 KiB - Section 9.5.2 (CXP-001-2021)
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
# Trigger rtio
nbit_trigdelay = 8
nbit_linktrig = 1
self.trigger = rtlink.Interface(
rtlink.OInterface(nbit_trigdelay + nbit_linktrig),
rtlink.IInterface(word_width, timestamped=False)
)
self.sync.rio += [
If(self.trigger.o.stb,
pipelines[master].tx.trig.delay.eq(self.trigger.o.data[nbit_linktrig:]),
pipelines[master].tx.trig.linktrig_mode.eq(self.trigger.o.data[:nbit_linktrig]),
),
pipelines[master].tx.trig.stb.eq(self.trigger.o.stb),
]
# ROI rtio
# 4 cfg (x0, y0, x1, 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
if debug_out:
pass
#
# downconn pipline -----> router -----> arbiter ------> crc checker ------> 4x converters
#
# Connect pipeline
for i, p in enumerate(pipelines):
broadcaster = cdr(cxp_router.Stream_Router()) # strip the packet id, tag & packet size
crc_checker = cdr(CXPCRC32_Checker())
self.submodules += broadcaster, crc_checker
self.comb += [
p.rx.source.connect(broadcaster.sink),
broadcaster.sources[0].connect(crc_checker),
]