From d84c7c952332da2f5730b33d032a7e1204b60df1 Mon Sep 17 00:00:00 2001 From: morgan Date: Tue, 3 Sep 2024 12:49:30 +0800 Subject: [PATCH] cxp: add trig to upconn & remove tx_command_packet --- src/gateware/cxp.py | 177 ++++++++++---------------------------------- 1 file changed, 38 insertions(+), 139 deletions(-) diff --git a/src/gateware/cxp.py b/src/gateware/cxp.py index 68a491f..cd2856f 100644 --- a/src/gateware/cxp.py +++ b/src/gateware/cxp.py @@ -8,8 +8,6 @@ from cxp_pipeline import * class CXP(Module, AutoCSR): def __init__(self, refclk, downconn_pads, upconn_pads, sys_clk_freq, debug_sma, pmod_pads): - self.submodules.trig = TX_Trigger(cxp_phy_layout()) - self.submodules.upconn = UpConn_Interface(upconn_pads, sys_clk_freq, debug_sma, pmod_pads) self.submodules.downconn = CXP_DownConn(refclk, downconn_pads, sys_clk_freq, debug_sma, pmod_pads) @@ -17,9 +15,6 @@ class CXP(Module, AutoCSR): # TODO: add link layer -# TODO: remove this and put it in upconn_interface -def cxp_phy_layout(): - return [("data", 8), ("k", 1)] class UpConn_Interface(Module, AutoCSR): def __init__(self, upconn_pads, sys_clk_freq, debug_sma, pmod_pads, fifos_depth=64): @@ -31,7 +26,9 @@ class UpConn_Interface(Module, AutoCSR): # # # - self.submodules.upconn_phy = upconn_phy = CXP_UpConn_PHY(upconn_pads, sys_clk_freq, debug_sma, pmod_pads, cxp_phy_layout(), fifos_depth) + layout = [("data", 8), ("k", 1)] + + self.submodules.upconn_phy = upconn_phy = CXP_UpConn_PHY(upconn_pads, sys_clk_freq, debug_sma, pmod_pads, layout, fifos_depth) self.sync += [ upconn_phy.bitrate2x_enable.eq(self.bitrate2x_enable.storage), @@ -45,8 +42,36 @@ class UpConn_Interface(Module, AutoCSR): # Packet FIFOs with transmission priority - # 0: Trigger packet + # NOTE: 0 Trigger packet + self.submodules.trig = trig = TX_Trigger(layout) + # DEBUG: INPUT + self.trig_stb = CSR() + self.trig_delay = CSRStorage(8) + self.linktrigger = CSRStorage(2) + + self.sync += [ + trig.trig_stb.eq(self.trig_stb.re), + trig.delay.eq(self.trig_delay.storage), + trig.linktrig_mode.eq(self.linktrigger.storage), + ] + + # DEBUG: OUTPUT + self.submodules.trig_out = trig_out = stream.SyncFIFO(layout, 64) + self.comb += trig.source.connect(trig_out.sink) + self.trig_inc = CSR() + self.trig_dout_pak = CSRStatus(8) + self.trig_kout_pak = CSRStatus() + self.trig_dout_valid = CSRStatus() + + self.sync += [ + # output + trig_out.source.ack.eq(self.trig_inc.re), + self.trig_dout_pak.status.eq(trig_out.source.data), + self.trig_kout_pak.status.eq(trig_out.source.k), + self.trig_dout_valid.status.eq(trig_out.source.stb), + ] + self.symbol0 = CSR(9) self.sync += [ upconn_phy.tx_fifos.sink[0].stb.eq(self.symbol0.re), @@ -55,9 +80,9 @@ class UpConn_Interface(Module, AutoCSR): ] - # 1: IO acknowledgment for trigger packet + # NOTE: 1 IO acknowledgment for trigger packet - self.submodules.trig_ack = trig_ack = Trigger_ACK(cxp_phy_layout()) + self.submodules.trig_ack = trig_ack = Trigger_ACK(layout) # DEBUG: INPUT self.ack = CSR() @@ -66,7 +91,7 @@ class UpConn_Interface(Module, AutoCSR): ] # DEBUG: OUTPUT - self.submodules.trig_ack_out = trig_ack_out = stream.SyncFIFO(cxp_phy_layout(), 64) + self.submodules.trig_ack_out = trig_ack_out = stream.SyncFIFO(layout, 64) self.comb += trig_ack.source.connect(trig_ack_out.sink) self.trig_ack_inc = CSR() self.trig_ack_dout_pak = CSRStatus(8) @@ -88,7 +113,7 @@ class UpConn_Interface(Module, AutoCSR): upconn_phy.tx_fifos.sink[1].k.eq(self.symbol1.r[8]), ] - # 2: All other packets + # NOTE: 2 All other packets # Control is not timing dependent, all the link layer is done in firmware # Table 54 (CXP-001-2021) @@ -99,11 +124,11 @@ class UpConn_Interface(Module, AutoCSR): # section 9.6.1.2 (CXP-001-2021) # tags implementation is on firmware - self.submodules.command = command = TX_Command_Packet(pmod_pads) + self.submodules.command = command = TX_Command_Packet(layout, pmod_pads) # DEBUG: OUTPUT - self.submodules.command_out = command_out = stream.SyncFIFO(cxp_phy_layout(), 64) + self.submodules.command_out = command_out = stream.SyncFIFO(layout, 64) self.comb += command.source.connect(command_out.sink) self.command_inc = CSR() @@ -138,129 +163,3 @@ class UpConn_Interface(Module, AutoCSR): upconn_phy.tx_fifos.sink[2].data.eq(self.symbol2.r[:8]), upconn_phy.tx_fifos.sink[2].k.eq(self.symbol2.r[8]), ] - -def K(x, y): - return ((y << 5) | x) - -# TODO: move this to cxp_pipeline, since it used K(x, y) :< -class TX_Trigger(Module, AutoCSR): - def __init__(self, layout): - # This module is mostly control by gateware - - self.trig_stb = Signal() - self.delay = Signal(8) # FIXME: use source instead - self.linktrig_mode = Signal(max=4) - - # # # - - - self.submodules.code_src = code_src = Code_Source(layout, counts=3) - self.comb += [ - code_src.stb.eq(self.trig_stb), - code_src.data.eq(self.delay), - code_src.k.eq(0) - ] - - self.submodules.inserter_once = inserter_once = Code_Inserter(layout, counts=1) - self.submodules.inserter_twice = inserter_twice = Code_Inserter(layout, counts=2) - - self.comb += [ - inserter_once.k.eq(1), - inserter_twice.k.eq(1), - If((self.linktrig_mode == 0) | (self.linktrig_mode == 2), - inserter_once.data.eq(K(28, 2)), - inserter_twice.data.eq(K(28, 4)), - ).Else( - inserter_once.data.eq(K(28, 4)), - inserter_twice.data.eq(K(28, 2)), - ) - ] - - self.submodules.buf_out = buf_out = stream.SyncFIFO(layout, 64) - - tx_pipeline = [ code_src, inserter_twice, inserter_once, buf_out] - - for s, d in zip(tx_pipeline, tx_pipeline[1:]): - self.comb += s.source.connect(d.sink) - - self.source = tx_pipeline[-1].source - - - # DEBUG: INPUT - self.stb = CSR() - self.trig_delay = CSRStorage(8) - self.linktrigger = CSRStorage(2) - - self.sync += [ - self.trig_stb.eq(self.stb.re), - self.delay.eq(self.trig_delay.storage), - self.linktrig_mode.eq(self.linktrigger.storage), - ] - - # DEBUG: OUTPUT - self.inc = CSR() - self.dout_pak = CSRStatus(8) - self.kout_pak = CSRStatus() - self.dout_valid = CSRStatus() - - self.sync += [ - # output - buf_out.source.ack.eq(self.inc.re), - self.dout_pak.status.eq(buf_out.source.data), - self.kout_pak.status.eq(buf_out.source.k), - self.dout_valid.status.eq(buf_out.source.stb), - ] - -class TX_Command_Packet(Module, AutoCSR): - def __init__(self, pmod_pads): - self.packet_type = CSRStorage(8) - - self.din_len = CSRStorage(6) - self.din_data = CSR(8) - self.din_k = CSRStorage() - self.din_ready = CSRStatus() - - # # # - - - # a buf is used to simulated a proper endpoint which hold source.stb high as long as data is available - # otherwise, CSR.re only hold when CSR is written to and it cannot act as a proper source - self.submodules.buf_in = buf_in = stream.SyncFIFO(cxp_phy_layout(), 2) - - self.submodules.crc_inserter = crc_inserters = CXPCRC32Inserter(cxp_phy_layout()) - self.submodules.pak_type = pak_type = Code_Inserter(cxp_phy_layout()) - self.submodules.pak_wrp = pak_wrp = Packet_Wrapper(cxp_phy_layout()) - - len = Signal(6, reset=1) - self.sync += [ - self.din_ready.status.eq(buf_in.sink.ack), - buf_in.sink.stb.eq(0), - If(self.din_data.re, - If(len == self.din_len.storage, - len.eq(len.reset), - buf_in.sink.eop.eq(1), - ).Else( - len.eq(len + 1), - buf_in.sink.eop.eq(0), - ), - buf_in.sink.stb.eq(1), - buf_in.sink.data.eq(self.din_data.r), - buf_in.sink.k.eq(self.din_k.storage), - ), - ] - - self.comb += [ - pak_type.data.eq(self.packet_type.storage), - pak_type.k.eq(0), - ] - - tx_pipeline = [ buf_in, crc_inserters, pak_type, pak_wrp] - - for s, d in zip(tx_pipeline, tx_pipeline[1:]): - self.comb += s.source.connect(d.sink) - - self.source = tx_pipeline[-1].source - - - -