diff --git a/src/gateware/cxp_downconn.py b/src/gateware/cxp_downconn.py index 1c601b2..d5d92af 100644 --- a/src/gateware/cxp_downconn.py +++ b/src/gateware/cxp_downconn.py @@ -58,7 +58,7 @@ class Receiver(Module): data_valid = Signal() self.sync.cxp_gtx_rx += [ - data_valid.eq(gtx.comma_checker.rxfsm.ongoing("READY")), + data_valid.eq(gtx.comma_aligner.rxfsm.ongoing("READY")), self.source.stb.eq(0), If(data_valid & self.source.ack & ~((gtx.decoders[0].d == 0xBC) & (gtx.decoders[0].k == 1)), @@ -218,9 +218,33 @@ class QPLL(Module, AutoCSR): ), ] + +class RX_Resetter(Module): + def __init__(self, reset_period=10_000_000): + self.rx_ready = Signal() + self.rx_reset = Signal() + + # # # + + # periodically reset rx until rx is connected and receiving valid data + # as after connecting RXP/RXN, the whole RX need to be reset + + reset_counter = Signal(reset=reset_period-1, max=reset_period) + self.sync += [ + self.rx_reset.eq(0), + If(~self.rx_ready, + If(reset_counter == 0, + reset_counter.eq(reset_counter.reset), + self.rx_reset.eq(1), + ).Else( + reset_counter.eq(reset_counter - 1), + ) + ) + ] + # Warning: Xilinx transceivers are LSB first, and comma needs to be flipped # compared to the usual 8b10b binary representation. -class Comma_Checker(Module): +class Comma_Aligner(Module): def __init__(self, comma, reset_period=10_000_000): self.data = Signal(20) self.comma_aligned = Signal() @@ -229,28 +253,9 @@ class Comma_Checker(Module): self.aligner_en = Signal() self.ready_sys = Signal() - self.restart_sys = Signal() # # # - - # periodically reset rx until rx is connected and receiving valid data - # as after connecting RXP/RXN, the whole RX need to be reset - - reset_counter = Signal(reset=reset_period-1, max=reset_period) - self.sync += [ - self.restart_sys.eq(0), - If(~self.ready_sys, - If(reset_counter == 0, - reset_counter.eq(reset_counter.reset), - self.restart_sys.eq(1), - ).Else( - reset_counter.eq(reset_counter - 1), - ) - ) - ] - - # Data and comma checker # From UG476 (v1.12.1) p.228 # The built-in RXBYTEISALIGNED can be falsely asserted at linerate higher than 5Gbps @@ -694,14 +699,29 @@ class GTX(Module): Instance("BUFG", i_I=txpll_clkout, o_O=self.cd_cxp_gtx_tx.clk), AsyncResetSynchronizer(self.cd_cxp_gtx_tx, ~self.txpll_locked & ~tx_init.done) ] + self.comb += tx_init.restart.eq(self.tx_restart) # RX clocking # the CDR matches the required frequency for RXUSRCLK, no need for PLL - self.clock_domains.cd_cxp_gtx_rx = ClockDomain() - self.specials += [ - Instance("BUFG", i_I=self.rxoutclk, o_O=self.cd_cxp_gtx_rx.clk), - AsyncResetSynchronizer(self.cd_cxp_gtx_rx, ~rx_init.done) - ] + + # Slave Rx will use cxp_gtx_rx instead + if rx_mode == "single" or rx_mode == "master": + self.clock_domains.cd_cxp_gtx_rx = ClockDomain() + self.specials += [ + Instance("BUFG", i_I=self.rxoutclk, o_O=self.cd_cxp_gtx_rx.clk), + AsyncResetSynchronizer(self.cd_cxp_gtx_rx, ~rx_init.done) + ] + self.submodules.rx_resetter = rx_resetter = RX_Resetter() + self.comb += [ + rx_resetter.rx_ready.eq(self.rx_ready), + rx_init.restart.eq(self.rx_restart | rx_resetter.rx_reset), + ] + else: + self.comb += rx_init.restart.eq(self.rx_restart), + + + + # 8b10b Encoder/Decoder self.comb += [ txdata.eq(Cat(self.encoder.output[0], self.encoder.output[1], self.encoder.output[2], self.encoder.output[3])), @@ -711,16 +731,12 @@ class GTX(Module): self.decoders[3].input.eq(rxdata[30:]), ] - - self.submodules.comma_checker = comma_checker = Comma_Checker(0b0101111100) + self.submodules.comma_aligner = comma_aligner = Comma_Aligner(0b0101111100) self.comb += [ - comma_checker.data.eq(rxdata), - comma_checker.comma_aligned.eq(comma_aligned), - comma_checker.comma_realigned.eq(comma_realigned), - comma_checker.comma_det.eq(comma_det), - comma_aligner_en.eq(comma_checker.aligner_en), - self.rx_ready.eq(comma_checker.ready_sys), - - rx_init.restart.eq(self.rx_restart | comma_checker.restart_sys), - tx_init.restart.eq(self.tx_restart), + comma_aligner.data.eq(rxdata), + comma_aligner.comma_aligned.eq(comma_aligned), + comma_aligner.comma_realigned.eq(comma_realigned), + comma_aligner.comma_det.eq(comma_det), + comma_aligner_en.eq(comma_aligner.aligner_en), + self.rx_ready.eq(comma_aligner.ready_sys), ]