diff --git a/src/gateware/cxp.py b/src/gateware/cxp.py index 7a8f0d8..3b44ee0 100644 --- a/src/gateware/cxp.py +++ b/src/gateware/cxp.py @@ -8,25 +8,20 @@ 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.txtrig = TX_Trigger() - self.submodules.upconn = UpConn_Packets(upconn_pads, sys_clk_freq, debug_sma, pmod_pads) + 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) # TODO: support the option high speed upconn # TODO: add link layer +# TODO: remove this and put it in upconn_interface +def cxp_phy_layout(): + return [("data", 8), ("k", 1)] -class UpConn_Packets(Module, AutoCSR): +class UpConn_Interface(Module, AutoCSR): def __init__(self, upconn_pads, sys_clk_freq, debug_sma, pmod_pads, fifos_depth=64): - - # increment after ack - # for CXP 2.0 or latest, command packet need to includet tags - # section 9.6.1.2 (CXP-001-2021) - self.tag_counts = Signal(max=0xFF) - self.use_tag = Signal() - self.clk_reset = CSRStorage(reset=1) self.bitrate2x_enable = CSRStorage() self.tx_enable = CSRStorage() @@ -50,6 +45,7 @@ class UpConn_Packets(Module, AutoCSR): # Packet FIFOs with transmission priority # 0: Trigger packet + self.symbol0 = CSR(9) self.sync += [ upconn_phy.tx_fifos.sink[0].stb.eq(self.symbol0.re), @@ -59,6 +55,31 @@ class UpConn_Packets(Module, AutoCSR): # 1: IO acknowledgment for trigger packet + + self.submodules.trig_ack = trig_ack = Trigger_ACK(cxp_phy_layout()) + + # DEBUG: INPUT + self.ack = CSR() + self.sync += [ + trig_ack.ack.eq(self.ack.re), + ] + + # DEBUG: OUTPUT + self.submodules.trig_ack_out = trig_ack_out = stream.SyncFIFO(cxp_phy_layout(), 64) + self.comb += trig_ack.source.connect(trig_ack_out.sink) + self.trig_ack_inc = CSR() + self.trig_ack_dout_pak = CSRStatus(8) + self.trig_ack_kout_pak = CSRStatus() + self.trig_ack_dout_valid = CSRStatus() + + self.sync += [ + # output + trig_ack_out.source.ack.eq(self.trig_ack_inc.re), + self.trig_ack_dout_pak.status.eq(trig_ack_out.source.data), + self.trig_ack_kout_pak.status.eq(trig_ack_out.source.k), + self.trig_ack_dout_valid.status.eq(trig_ack_out.source.stb), + ] + self.symbol1 = CSR(9) self.sync += [ upconn_phy.tx_fifos.sink[1].stb.eq(self.symbol1.re), @@ -72,36 +93,41 @@ class UpConn_Packets(Module, AutoCSR): # Table 54 (CXP-001-2021) # Largest CXP register is 8 byte - self.submodules.tx_command = tx_command = TX_Command_Packet(pmod_pads) + # increment after ack + # for CXP 2.0 or latest, command packet need to includet tags + # section 9.6.1.2 (CXP-001-2021) + # tags implementation is on firmware + + self.submodules.command = command = TX_Command_Packet(pmod_pads) # DEBUG: OUTPUT - self.submodules.buf_out = buf_out = stream.SyncFIFO(cxp_phy_layout(), 64) - self.comb += tx_command.source.connect(buf_out.sink) + self.submodules.command_out = command_out = stream.SyncFIFO(cxp_phy_layout(), 64) + self.comb += command.source.connect(command_out.sink) - self.inc = CSR() - self.dout_pak = CSRStatus(8) - self.kout_pak = CSRStatus() - self.dout_valid = CSRStatus() + self.command_inc = CSR() + self.command_dout_pak = CSRStatus(8) + self.command_kout_pak = CSRStatus() + self.command_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), + command_out.source.ack.eq(self.command_inc.re), + self.command_dout_pak.status.eq(command_out.source.data), + self.command_kout_pak.status.eq(command_out.source.k), + self.command_dout_valid.status.eq(command_out.source.stb), ] self.specials += [ # pmod 0-7 pin - Instance("OBUF", i_I=tx_command.buf_in.sink.stb, o_O=pmod_pads[0]), - Instance("OBUF", i_I=tx_command.buf_in.sink.ack, o_O=pmod_pads[1]), - Instance("OBUF", i_I=tx_command.buf_in.source.stb, o_O=pmod_pads[2]), - Instance("OBUF", i_I=tx_command.buf_in.source.ack, o_O=pmod_pads[3]), - Instance("OBUF", i_I=buf_out.sink.stb, o_O=pmod_pads[4]), - Instance("OBUF", i_I=buf_out.sink.ack, o_O=pmod_pads[5]), - Instance("OBUF", i_I=buf_out.source.stb, o_O=pmod_pads[6]), - Instance("OBUF", i_I=buf_out.source.ack, o_O=pmod_pads[7]), + Instance("OBUF", i_I=command.buf_in.sink.stb, o_O=pmod_pads[0]), + Instance("OBUF", i_I=command.buf_in.sink.ack, o_O=pmod_pads[1]), + Instance("OBUF", i_I=command.buf_in.source.stb, o_O=pmod_pads[2]), + Instance("OBUF", i_I=command.buf_in.source.ack, o_O=pmod_pads[3]), + Instance("OBUF", i_I=command_out.sink.stb, o_O=pmod_pads[4]), + Instance("OBUF", i_I=command_out.sink.ack, o_O=pmod_pads[5]), + Instance("OBUF", i_I=command_out.source.stb, o_O=pmod_pads[6]), + Instance("OBUF", i_I=command_out.source.ack, o_O=pmod_pads[7]), ] @@ -112,15 +138,14 @@ class UpConn_Packets(Module, AutoCSR): upconn_phy.tx_fifos.sink[2].k.eq(self.symbol2.r[8]), ] -# TODO: put these stuff properly instead of declaring everytime - -def cxp_phy_layout(): - return [("data", 8), ("k", 1)] - class TX_Trigger(Module, AutoCSR): def __init__(self): # This module is mostly control by gateware + self.trig_stb = Signal() + self.delay = Signal(max=240) + + self.ack = Signal() # # #