diff --git a/src/gateware/cxp.py b/src/gateware/cxp.py index ec5bfa3..053c169 100644 --- a/src/gateware/cxp.py +++ b/src/gateware/cxp.py @@ -2,148 +2,20 @@ from migen import * from misoc.interconnect.csr import * from misoc.cores.liteeth_mini.mac.crc import LiteEthMACCRCEngine -from artiq.gateware.drtio.core import ChannelInterface - from cxp_downconn import CXP_DownConn from cxp_upconn import CXP_UpConn class CXP(Module, AutoCSR): def __init__(self, refclk, pads, sys_clk_freq, debug_sma, pmod_pads): - nchannels = len(pads) - self.rx_start_init = CSRStorage() - self.rx_restart = CSRStorage() - self.rx_data_alignment = CSRStorage() - - self.tx_start_init = CSRStorage() - self.tx_restart = CSRStorage() - - self.loopback_mode = CSRStorage(3) - - self.txinit_phaligndone = CSRStatus() - self.rxinit_phaligndone = CSRStatus() - self.rx_ready = CSRStatus() - - self.data_0 = CSRStorage(8) - self.data_1 = CSRStorage(8) - self.data_2 = CSRStorage(8) - self.data_3 = CSRStorage(8) - self.control_bit_0 = CSRStorage() - self.control_bit_1 = CSRStorage() - self.control_bit_2 = CSRStorage() - self.control_bit_3 = CSRStorage() - self.encoded_0 = CSRStatus(10) - self.encoded_1 = CSRStatus(10) - - self.rxdata_0 = CSRStatus(10) - self.rxdata_1 = CSRStatus(10) - self.decoded_data_0 = CSRStatus(8) - self.decoded_data_1 = CSRStatus(8) - self.decoded_k_0 = CSRStatus() - self.decoded_k_1 = CSRStatus() - - # # # - self.submodules.crc = CXP_CRC(8) - # FIFOs with transmission priority # 0: Trigger packet # 1: IO acknowledgment for trigger packet # 2: All other packets - self.submodules.upconn = CXP_UpConn(debug_sma, sys_clk_freq, pmod_pads) - - # single & master tx_mode can lock with rx in loopback - self.submodules.gtx = gtx = CXP_DownConn(refclk, pads, sys_clk_freq, tx_mode="single", rx_mode="single") - - # DEBUG:loopback - self.sync += gtx.loopback_mode.eq(self.loopback_mode.storage) + self.submodules.downconn = CXP_DownConn(refclk, pads, sys_clk_freq, debug_sma, pmod_pads) - # DEBUG:SMA - self.specials += [ - Instance("OBUF", i_I=gtx.rxoutclk, o_O=debug_sma.p_tx), - Instance("OBUF", i_I=gtx.cd_cxp_gtx_tx.clk, o_O=debug_sma.n_rx) - ] - - self.comb += [ - self.txinit_phaligndone.status.eq(self.gtx.tx_init.Xxphaligndone), - # self.rxinit_phaligndone.status.eq(self.gtx.rx_init.Xxphaligndone), - self.rx_ready.status.eq(self.gtx.rx_ready), - ] - - - counter_max = 4 - counter = Signal(max=counter_max) - - self.sync.cxp_gtx_tx += [ - If(counter == 0, - self.gtx.encoder.d[0].eq(self.data_0.storage), - self.gtx.encoder.k[0].eq(self.control_bit_0.storage), - self.gtx.encoder.d[1].eq(self.data_1.storage), - self.gtx.encoder.k[1].eq(self.control_bit_1.storage), - counter.eq(counter+1), - ).Elif(counter == 1, - self.gtx.encoder.d[0].eq(self.data_2.storage), - self.gtx.encoder.k[0].eq(self.control_bit_2.storage), - self.gtx.encoder.d[1].eq(self.data_3.storage), - self.gtx.encoder.k[1].eq(self.control_bit_3.storage), - counter.eq(0), - ), - self.encoded_0.status.eq(self.gtx.encoder.output[0]), - self.encoded_1.status.eq(self.gtx.encoder.output[1]), - ] - self.sync.cxp_gtx_rx += [ - self.rxdata_0.status.eq(self.gtx.decoders[0].input), - self.decoded_data_0.status.eq(self.gtx.decoders[0].d), - self.decoded_k_0.status.eq(self.gtx.decoders[0].k), - - self.rxdata_1.status.eq(self.gtx.decoders[1].input), - self.decoded_data_1.status.eq(self.gtx.decoders[1].d), - self.decoded_k_1.status.eq(self.gtx.decoders[1].k), - ] - - # TODO: rip encoder & rx clockalignment out of CXP_GTX - - # TODO: use expose encoder & decoder from CXP - # encoder.k = 1 if sending control bit, different calculation - # encoder.d = data 8 bit - - - - channel_interface = ChannelInterface(gtx.encoder, gtx.decoders) - self.comb += channel_interface.rx_ready.eq(gtx.rx_ready) - channel_interfaces = [] - channel_interfaces.append(channel_interface) - - # TransceiverInterface, just adding cxp_rx_ - self.stable_clkin = CSRStorage() - self.txenable = CSRStorage(len(channel_interfaces)) - for i in range(len(channel_interfaces)): - name = "cxp_gtx_rx" + str(i) - setattr(self.clock_domains, "cd_"+name, ClockDomain(name=name)) - self.channels = channel_interfaces - - - # TODO: add tx_phase_alignment for multi CXP - # The TX phase alignment will fail with a wrong TXUSRCLK frequency - - - self.comb += [ - gtx.txenable.eq(self.txenable.storage[0]), - gtx.tx_restart.eq(self.tx_restart.storage), - gtx.rx_restart.eq(self.rx_restart.storage), - gtx.tx_init.clk_path_ready.eq(self.tx_start_init.storage), - gtx.rx_init.clk_path_ready.eq(self.rx_start_init.storage), - gtx.rx_alignment_en.eq(self.rx_data_alignment.storage), - ] - - # TODO: Connect multilane cxp_tx - - # TODO: Connect slave i's `cxp_gtx_rx` clock to `cxp_gtx_rxi` clock - self.comb += [ - getattr(self, "cd_cxp_gtx_rx" + str(0)).clk.eq(self.gtx.cd_cxp_gtx_rx.clk), - getattr(self, "cd_cxp_gtx_rx" + str(0)).rst.eq(self.gtx.cd_cxp_gtx_rx.rst) - ] class CXP_CRC(Module, AutoCSR): width = 32