1
0
Fork 0

cxp GW: fix read ptr not restarting with rx

cxp GW: express size in bytes instead of bits
This commit is contained in:
morgan 2024-10-10 13:06:46 +08:00
parent aa4594d84a
commit 30cc069a29
1 changed files with 61 additions and 65 deletions

View File

@ -16,29 +16,32 @@ class CXP_PHYS(Module, AutoCSR):
@FullMemoryWE() @FullMemoryWE()
class CXP_Interface(Module, AutoCSR): class CXP_Interface(Module, AutoCSR):
def __init__(self, upconn_phy, downconn_phy, debug_sma, pmod_pads): def __init__(self, upconn_phy, downconn_phy, debug_sma, pmod_pads):
# TODO: move all transceiver csr into a transceiver interface submodule # TODO: add rtio interface io
self.submodules.upconn = UpConn_Interface(upconn_phy, debug_sma, pmod_pads) self.submodules.upconn = UpConn_Interface(upconn_phy, debug_sma, pmod_pads)
self.submodules.downconn = DownConn_Interface(downconn_phy, debug_sma, pmod_pads) self.submodules.downconn = DownConn_Interface(downconn_phy, debug_sma, pmod_pads)
def get_tx_port(self): def get_tx_port(self):
return self.upconn.command.mem.get_port(write_capable=True) return self.upconn.bootstrap.mem.get_port(write_capable=True)
def get_tx_mem_size(self): def get_tx_mem_size(self):
return self.upconn.command.mem.depth*self.upconn.command.mem.width # FIXME: if tx mem size is same as rx, for some reason when rx mem is writen, tx mem cannot be access anymore
# and each time tx mem is read, CPU will return rx mem instead
return self.upconn.bootstrap.mem.depth*self.upconn.bootstrap.mem.width // 8
# return self.downconn.bootstrap.mem.depth*self.downconn.bootstrap.mem.width // 8
def get_rx_port(self): def get_rx_port(self):
return self.downconn.packet_decoder.mem.get_port(write_capable=False) return self.downconn.bootstrap.mem.get_port(write_capable=False)
def get_rx_mem_size(self): def get_rx_mem_size(self):
return self.downconn.packet_decoder.mem.depth*self.downconn.packet_decoder.mem.width return self.downconn.bootstrap.mem.depth*self.downconn.bootstrap.mem.width // 8
def get_loopback_tx_port(self): def get_loopback_tx_port(self):
return self.downconn.command.mem.get_port(write_capable=True) return self.downconn.bootstrap_loopback.mem.get_port(write_capable=True)
def get_loopback_tx_mem_size(self): def get_loopback_tx_mem_size(self):
return self.downconn.command.mem.depth*self.downconn.command.mem.width return self.downconn.bootstrap_loopback.mem.depth*self.downconn.bootstrap_loopback.mem.width // 8
class DownConn_Interface(Module, AutoCSR): class DownConn_Interface(Module, AutoCSR):
def __init__(self, phy, debug_sma, pmod_pads): def __init__(self, phy, debug_sma, pmod_pads):
@ -149,17 +152,17 @@ class DownConn_Interface(Module, AutoCSR):
# DEBUG: Transmission Pipeline # DEBUG: Transmission Pipeline
# #
# test pak ----+ # rtio pak ----+
# from gw | 32 32 # from gw | 32 32
# |---/---> mux -----> packet -----> trigger ack ---/---> PHY # mux---/---> packet -----> trigger ack ---/---> PHY
# | wrapper inserter # | wrapper inserter
# data pak ----+ # data/test ----+
# from fw # pak from fw
#
# DEBUG: TX pipeline # DEBUG: TX pipeline
self.submodules.command = command = TX_Command_Packet() self.submodules.bootstrap_loopback = bootstrap_loopback = TX_Bootstrap()
self.submodules.testseq = testseq = TX_Test_Packet()
self.submodules.mux = mux = stream.Multiplexer(word_layout, 2) self.submodules.mux = mux = stream.Multiplexer(word_layout, 2)
self.submodules.pak_wrp = pak_wrp = Packet_Wrapper() self.submodules.pak_wrp = pak_wrp = Packet_Wrapper()
self.submodules.trig_ack = trig_ack = Trigger_ACK_Inserter() self.submodules.trig_ack = trig_ack = Trigger_ACK_Inserter()
@ -169,8 +172,7 @@ class DownConn_Interface(Module, AutoCSR):
self.sync += trig_ack.stb.eq(self.ack.re), self.sync += trig_ack.stb.eq(self.ack.re),
self.comb += [ self.comb += [
command.source.connect(mux.sink0), bootstrap_loopback.source.connect(mux.sink0),
testseq.source.connect(mux.sink1),
mux.sel.eq(self.mux_sel.storage), mux.sel.eq(self.mux_sel.storage),
] ]
@ -207,36 +209,36 @@ class DownConn_Interface(Module, AutoCSR):
] ]
# Priority level 2 packet - data, test packet # Priority level 2 packet - data, test packet
self.submodules.packet_decoder = packet_decoder = cdr(CXP_Data_Packet_Decode()) self.submodules.bootstrap = bootstrap = cdr(RX_Bootstrap())
self.decoder_error = CSR() self.bootstrap_decoder_err = CSR()
self.test_error = CSR() self.bootstrap_test_err = CSR()
self.buffer_error = CSR() self.boostrap_buffer_err = CSR()
decode_err_ps = PulseSynchronizer("cxp_gtx_rx", "sys") decode_err_ps = PulseSynchronizer("cxp_gtx_rx", "sys")
test_err_ps = PulseSynchronizer("cxp_gtx_rx", "sys") test_err_ps = PulseSynchronizer("cxp_gtx_rx", "sys")
buffer_err_ps = PulseSynchronizer("cxp_gtx_rx", "sys") buffer_err_ps = PulseSynchronizer("cxp_gtx_rx", "sys")
self.submodules += decode_err_ps, test_err_ps, buffer_err_ps self.submodules += decode_err_ps, test_err_ps, buffer_err_ps
self.comb += [ self.comb += [
decode_err_ps.i.eq(packet_decoder.decode_err), decode_err_ps.i.eq(bootstrap.decode_err),
test_err_ps.i.eq(packet_decoder.test_err), test_err_ps.i.eq(bootstrap.test_err),
buffer_err_ps.i.eq(packet_decoder.buffer_err), buffer_err_ps.i.eq(bootstrap.buffer_err),
] ]
self.sync += [ self.sync += [
If(decode_err_ps.o, If(decode_err_ps.o,
self.decoder_error.w.eq(1), self.bootstrap_decoder_err.w.eq(1),
).Elif(self.decoder_error.re, ).Elif(self.bootstrap_decoder_err.re,
self.decoder_error.w.eq(0), self.bootstrap_decoder_err.w.eq(0),
), ),
If(test_err_ps.o, If(test_err_ps.o,
self.test_error.w.eq(1), self.bootstrap_test_err.w.eq(1),
).Elif(self.test_error.re, ).Elif(self.bootstrap_test_err.re,
self.test_error.w.eq(0), self.bootstrap_test_err.w.eq(0),
), ),
If(buffer_err_ps.o, If(buffer_err_ps.o,
self.buffer_error.w.eq(1), self.boostrap_buffer_err.w.eq(1),
).Elif(self.test_error.re, ).Elif(self.bootstrap_test_err.re,
self.buffer_error.w.eq(0), self.boostrap_buffer_err.w.eq(0),
), ),
] ]
@ -247,12 +249,14 @@ class DownConn_Interface(Module, AutoCSR):
self.read_ptr = CSRStatus(log2_int(buffer_count)) self.read_ptr = CSRStatus(log2_int(buffer_count))
self.specials += [ self.specials += [
MultiReg(packet_decoder.packet_type, self.packet_type.status), MultiReg(bootstrap.packet_type, self.packet_type.status),
MultiReg(self.read_ptr.status, packet_decoder.read_ptr_rx, odomain="cxp_gtx_rx"), MultiReg(self.read_ptr.status, bootstrap.read_ptr_rx, odomain="cxp_gtx_rx"),
] ]
self.sync += [ self.sync += [
self.pending_packet.w.eq(self.read_ptr.status != packet_decoder.write_ptr_sys), self.pending_packet.w.eq(self.read_ptr.status != bootstrap.write_ptr_sys),
If(self.pending_packet.re & self.pending_packet.w, If(self.rx_restart.re,
self.read_ptr.status.eq(0),
).Elif(self.pending_packet.re & self.pending_packet.w,
self.read_ptr.status.eq(self.read_ptr.status + 1), self.read_ptr.status.eq(self.read_ptr.status + 1),
) )
] ]
@ -263,8 +267,18 @@ class DownConn_Interface(Module, AutoCSR):
self.submodules += ClockDomainsRenamer({"write": "cxp_gtx_rx", "read": "sys"})(cdc_fifo) self.submodules += ClockDomainsRenamer({"write": "cxp_gtx_rx", "read": "sys"})(cdc_fifo)
self.submodules.debug_out = debug_out = RX_Debug_Buffer() self.submodules.debug_out = debug_out = RX_Debug_Buffer()
self.dmux_sel = CSRStorage()
self.submodules.dmux = dmux = stream.Demultiplexer(word_layout, 2)
rx_pipeline = [phy, trig_ack_checker, packet_decoder, cdc_fifo, debug_out]
self.comb += [
dmux.source0.connect(bootstrap.sink),
dmux.source1.connect(cdc_fifo.sink),
cdc_fifo.source.connect(debug_out.sink),
dmux.sel.eq(self.dmux_sel.storage),
]
rx_pipeline = [phy, trig_ack_checker, dmux]
for s, d in zip(rx_pipeline, rx_pipeline[1:]): for s, d in zip(rx_pipeline, rx_pipeline[1:]):
self.comb += s.source.connect(d.sink) self.comb += s.source.connect(d.sink)
@ -278,14 +292,14 @@ class DownConn_Interface(Module, AutoCSR):
pak_start = Signal() pak_start = Signal()
self.sync += [ self.sync += [
pak_start.eq(packet_decoder.sink.data == 0xFBFBFBFB), pak_start.eq(bootstrap.sink.data == 0xFBFBFBFB),
] ]
self.specials += [ self.specials += [
Instance("OBUF", i_I=phy.gtx.cd_cxp_gtx_rx.clk, o_O=debug_sma.p_tx), Instance("OBUF", i_I=phy.gtx.cd_cxp_gtx_rx.clk, o_O=debug_sma.p_tx),
# Instance("OBUF", i_I=, o_O=debug_sma.p_rx), # Instance("OBUF", i_I=, o_O=debug_sma.p_rx),
# # pmod 0-7 pin # # pmod 0-7 pin
Instance("OBUF", i_I=packet_decoder.test_err, o_O=pmod_pads[0]), Instance("OBUF", i_I=bootstrap.test_err, o_O=pmod_pads[0]),
Instance("OBUF", i_I=pak_start, o_O=pmod_pads[1]), Instance("OBUF", i_I=pak_start, o_O=pmod_pads[1]),
# Instance("OBUF", i_I=fifo_in.source.ack, o_O=pmod_pads[2]), # Instance("OBUF", i_I=fifo_in.source.ack, o_O=pmod_pads[2]),
# Instance("OBUF", i_I=gtx.comma_checker.aligner_en, o_O=pmod_pads[3]), # Instance("OBUF", i_I=gtx.comma_checker.aligner_en, o_O=pmod_pads[3]),
@ -301,11 +315,7 @@ class UpConn_Interface(Module, AutoCSR):
self.clk_reset = CSRStorage(reset=1) self.clk_reset = CSRStorage(reset=1)
self.bitrate2x_enable = CSRStorage() self.bitrate2x_enable = CSRStorage()
self.tx_enable = CSRStorage() self.tx_enable = CSRStorage()
self.tx_mux = CSRStorage()
# TODO: add busy condition
self.tx_busy = CSRStatus()
self.tx_testmode_en = CSRStorage()
# # # # # #
@ -317,13 +327,10 @@ class UpConn_Interface(Module, AutoCSR):
# Transmission Pipeline # Transmission Pipeline
# #
# test pak ----+ # 32 32 8
# from gw | 32 32 8 # ctrl/test ---/---> packet -----> idle word -----> trigger ack ---/--> conv ---/---> trigger -----> PHY
# |---/---> mux -----> packet -----> idle word -----> trigger ack ---/--> conv ---/---> trigger -----> PHY # packet wrapper inserter inserter inserter
# | wrapper inserter inserter inserter
# data pak ----+
# from fw
# #
# Equivalent transmission priority: # Equivalent transmission priority:
# trigger > trigger ack > idle > test/data packet # trigger > trigger ack > idle > test/data packet
@ -362,20 +369,9 @@ class UpConn_Interface(Module, AutoCSR):
# 2: All other packets (data & test packet) # 2: All other packets (data & test packet)
# Control is not timing dependent, all the data packets are handled in firmware # Control is not timing dependent, all the data packets are handled in firmware
self.submodules.bootstrap = bootstrap = TX_Bootstrap()
self.submodules.command = command = TX_Command_Packet()
self.submodules.testseq = testseq = TX_Test_Packet()
self.submodules.mux = mux = stream.Multiplexer(word_layout, 2)
self.comb += [
command.source.connect(mux.sink0),
testseq.source.connect(mux.sink1),
mux.sel.eq(self.tx_testmode_en.storage),
]
self.submodules.pak_wrp = pak_wrp = Packet_Wrapper() self.submodules.pak_wrp = pak_wrp = Packet_Wrapper()
# IDLE Word
self.submodules.idle = idle = Idle_Word_Inserter() self.submodules.idle = idle = Idle_Word_Inserter()
# Section 9.2.5.1 (CXP-001-2021) # Section 9.2.5.1 (CXP-001-2021)
@ -394,6 +390,6 @@ class UpConn_Interface(Module, AutoCSR):
self.submodules.converter = converter = stream.StrideConverter(word_layout, char_layout) self.submodules.converter = converter = stream.StrideConverter(word_layout, char_layout)
tx_pipeline = [mux, pak_wrp, idle, trig_ack, converter, trig, phy] tx_pipeline = [bootstrap, pak_wrp, idle, trig_ack, converter, trig, phy]
for s, d in zip(tx_pipeline, tx_pipeline[1:]): for s, d in zip(tx_pipeline, tx_pipeline[1:]):
self.comb += s.source.connect(d.sink) self.comb += s.source.connect(d.sink)