1
0
Fork 0

cxp downconn: add gtx drp

This commit is contained in:
morgan 2024-08-12 16:48:05 +08:00
parent 2cd1da81c1
commit bfc8f065f7
1 changed files with 61 additions and 8 deletions

View File

@ -20,14 +20,10 @@ class CXP_DownConn(Module, AutoCSR):
self.tx_restart = CSR() self.tx_restart = CSR()
self.txenable = CSRStorage() self.txenable = CSRStorage()
self.txinit_phaligndone = CSRStatus() self.txinit_phaligndone = CSRStatus()
self.rxinit_phaligndone = CSRStatus() self.rxinit_phaligndone = CSRStatus()
self.rx_ready = CSRStatus() self.rx_ready = CSRStatus()
self.tx_div = CSRStorage(3)
self.rx_div = CSRStorage(3)
self.qpll_reset = CSR() self.qpll_reset = CSR()
self.qpll_locked = CSRStatus() self.qpll_locked = CSRStatus()
@ -47,7 +43,6 @@ class CXP_DownConn(Module, AutoCSR):
# PLL # PLL
qpll.reset.eq(self.qpll_reset.re), qpll.reset.eq(self.qpll_reset.re),
self.qpll_locked.status.eq(qpll.lock), self.qpll_locked.status.eq(qpll.lock),
# GTX # GTX
self.txinit_phaligndone.status.eq(gtx.tx_init.Xxphaligndone), self.txinit_phaligndone.status.eq(gtx.tx_init.Xxphaligndone),
self.rxinit_phaligndone.status.eq(gtx.rx_init.Xxphaligndone), self.rxinit_phaligndone.status.eq(gtx.rx_init.Xxphaligndone),
@ -58,13 +53,47 @@ class CXP_DownConn(Module, AutoCSR):
gtx.rx_restart.eq(self.rx_restart.re), gtx.rx_restart.eq(self.rx_restart.re),
gtx.tx_init.clk_path_ready.eq(self.tx_start_init.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_init.clk_path_ready.eq(self.rx_start_init.storage),
# gtx.rx_alignment_en.eq(self.rx_data_alignment.storage), ]
# GTX DRP # GTX Channels DRP
self.tx_div = CSRStorage(3)
self.rx_div = CSRStorage(3)
self.gtx_daddr = CSRStorage(9)
self.gtx_dread = CSR()
self.gtx_din_stb = CSR()
self.gtx_din = CSRStorage(16)
self.gtx_dout = CSRStatus(16)
self.gtx_dready = CSR()
self.comb += gtx.dclk.eq(ClockSignal("sys")),
self.sync += [
gtx.tx_rate.eq(self.tx_div.storage), gtx.tx_rate.eq(self.tx_div.storage),
gtx.rx_rate.eq(self.rx_div.storage), gtx.rx_rate.eq(self.rx_div.storage),
gtx.den.eq(0),
gtx.dwen.eq(0),
If(self.gtx_dread.re,
gtx.den.eq(1),
gtx.daddr.eq(self.gtx_daddr.storage),
).Elif(self.gtx_din_stb.re,
gtx.den.eq(1),
gtx.dwen.eq(1),
gtx.daddr.eq(self.gtx_daddr.storage),
gtx.din.eq(self.gtx_din.storage),
),
If(gtx.dready,
self.gtx_dready.w.eq(1),
self.gtx_dout.status.eq(gtx.dout),
),
If(self.gtx_dready.re,
self.gtx_dready.w.eq(0),
),
] ]
# DEBUG: txusrclk PLL DRG # DEBUG: txusrclk PLL DRG
self.txpll_reset = CSRStorage() self.txpll_reset = CSRStorage()
@ -130,7 +159,13 @@ class CXP_DownConn(Module, AutoCSR):
Instance("OBUF", i_I=aligned, o_O=pmod_pads[3]), Instance("OBUF", i_I=aligned, o_O=pmod_pads[3]),
Instance("OBUF", i_I=gtx.comma_det.ready, o_O=pmod_pads[4]), Instance("OBUF", i_I=gtx.comma_det.ready, o_O=pmod_pads[4]),
Instance("OBUF", i_I=valid_data, o_O=pmod_pads[5]), Instance("OBUF", i_I=valid_data, o_O=pmod_pads[5]),
# Instance("OBUF", i_I=, o_O=pmod_pads[6]),
# Instance("OBUF", i_I=, o_O=pmod_pads[7]), # Instance("OBUF", i_I=, o_O=pmod_pads[7]),
# Instance("OBUF", i_I=gtx.dclk, o_O=pmod_pads[0]),
# Instance("OBUF", i_I=gtx.den, o_O=pmod_pads[1]),
# Instance("OBUF", i_I=gtx.dwen, o_O=pmod_pads[2]),
# Instance("OBUF", i_I=gtx.dready, o_O=pmod_pads[3]),
] ]
# DEBUG: datain # DEBUG: datain
@ -282,7 +317,6 @@ class QPLL(Module):
) )
] ]
# Warning: Xilinx transceivers are LSB first, and comma needs to be flipped # Warning: Xilinx transceivers are LSB first, and comma needs to be flipped
# compared to the usual 8b10b binary representation. # compared to the usual 8b10b binary representation.
class Comma_Detector(Module): class Comma_Detector(Module):
@ -409,6 +443,15 @@ class GTX(Module):
self.tx_rate = Signal(3) self.tx_rate = Signal(3)
self.rx_rate = Signal(3) self.rx_rate = Signal(3)
# Dynamic Reconfiguration Ports
self.daddr = Signal(9)
self.dclk = Signal()
self.den = Signal()
self.dwen = Signal()
self.din = Signal(16)
self.dout = Signal(16)
self.dready = Signal()
self.submodules.encoder = ClockDomainsRenamer("cxp_gtx_tx")(Encoder(2, True)) self.submodules.encoder = ClockDomainsRenamer("cxp_gtx_tx")(Encoder(2, True))
self.submodules.decoders = [ClockDomainsRenamer("cxp_gtx_rx")( self.submodules.decoders = [ClockDomainsRenamer("cxp_gtx_rx")(
(Decoder(True))) for _ in range(2)] (Decoder(True))) for _ in range(2)]
@ -624,6 +667,16 @@ class GTX(Module):
o_GTXTXP=pads.txp, o_GTXTXP=pads.txp,
o_GTXTXN=pads.txn, o_GTXTXN=pads.txn,
# Dynamic Reconfiguration Ports
p_IS_DRPCLK_INVERTED=0b0,
i_DRPADDR=self.daddr,
i_DRPCLK=self.dclk,
i_DRPEN=self.den,
i_DRPWE=self.dwen,
i_DRPDI=self.din,
o_DRPDO=self.dout,
o_DRPRDY=self.dready,
# ! loopback for debugging # ! loopback for debugging
i_LOOPBACK = self.loopback_mode, i_LOOPBACK = self.loopback_mode,
p_TX_LOOPBACK_DRIVE_HIZ = "FALSE", p_TX_LOOPBACK_DRIVE_HIZ = "FALSE",