1
0
Fork 0

cxp downconn: fix aligner not work @ 5 & 6.25Gbps

This commit is contained in:
morgan 2024-08-14 17:14:06 +08:00
parent aa128e1467
commit a6b1701de3
1 changed files with 23 additions and 91 deletions

View File

@ -160,7 +160,7 @@ class CXP_DownConn(Module, AutoCSR):
Instance("OBUF", i_I=gtx.cd_cxp_gtx_tx.clk, o_O=debug_sma.n_rx), Instance("OBUF", i_I=gtx.cd_cxp_gtx_tx.clk, o_O=debug_sma.n_rx),
# pmod 0-7 pin # pmod 0-7 pin
Instance("OBUF", i_I=gtx.comma_det.rxinit_done, o_O=pmod_pads[0]), Instance("OBUF", i_I=gtx.comma_det.word_aligned, o_O=pmod_pads[0]),
Instance("OBUF", i_I=gtx.comma_det.restart, o_O=pmod_pads[1]), Instance("OBUF", i_I=gtx.comma_det.restart, o_O=pmod_pads[1]),
Instance("OBUF", i_I=gtx.comma_det.aligner_en_rxclk, o_O=pmod_pads[2]), Instance("OBUF", i_I=gtx.comma_det.aligner_en_rxclk, o_O=pmod_pads[2]),
Instance("OBUF", i_I=gtx.comma_det.check_reset, o_O=pmod_pads[3]), Instance("OBUF", i_I=gtx.comma_det.check_reset, o_O=pmod_pads[3]),
@ -331,7 +331,7 @@ class QPLL(Module):
class Comma_Detector(Module): class Comma_Detector(Module):
def __init__(self, comma, check_period=1_000_000): def __init__(self, comma, check_period=1_000_000):
self.data = Signal(20) self.data = Signal(20)
self.rxinit_done = Signal() self.word_aligned = Signal()
self.aligner_en_rxclk = Signal() self.aligner_en_rxclk = Signal()
self.ready = Signal() self.ready = Signal()
@ -345,39 +345,6 @@ class Comma_Detector(Module):
# - UG476 (v1.12.1) p.228 # - UG476 (v1.12.1) p.228
# The validity of data & comma are checked externally # The validity of data & comma are checked externally
# aligned = Signal()
# valid_data = Signal()
# aligned_rxclk = Signal()
# valid_data_rxclk = Signal()
# rx1cnt = Signal(max=11)
# self.specials += [
# MultiReg(aligned_rxclk, aligned),
# MultiReg(valid_data_rxclk, valid_data),
# ]
# self.submodules.check_reset = check_reset = PulseSynchronizer("sys", "cxp_gtx_rx")
# comma_n = ~comma & 0b1111111111
# self.sync.cxp_gtx_rx += [
# If(check_reset.o,
# aligned_rxclk.eq(0),
# ).Elif((self.data[:10] == comma) | (self.data[:10] == comma_n),
# aligned_rxclk.eq(1),
# ),
# rx1cnt.eq(reduce(add, [self.data[i] for i in range(10)])),
# If(check_reset.o,
# valid_data_rxclk.eq(0),
# ).Elif((rx1cnt == 4) | (rx1cnt == 5) | (rx1cnt == 6),
# valid_data_rxclk.eq(1),
# ),
# ]
# self.aligned = Signal()
# self.valid_data = Signal()
# self.comb +=[
# self.aligned.eq(aligned),
# self.valid_data.eq(valid_data)
# ]
check_counter = Signal(reset=check_period-1, max=check_period) check_counter = Signal(reset=check_period-1, max=check_period)
@ -465,18 +432,31 @@ class Comma_Detector(Module):
self.submodules.rxfsm = rxfsm = ClockDomainsRenamer("cxp_gtx_rx")(FSM(reset_state="ALIGNING")) self.submodules.rxfsm = rxfsm = ClockDomainsRenamer("cxp_gtx_rx")(FSM(reset_state="ALIGNING"))
# the data from gtxe2 is delayed and checking at the output may not reflect the alignment inside the aligner
# thus, failing to alignment on high linerate >5Gbps is common due to the aligner_en being asserted longer than necessary and lead to a lose of lock
# a timer is used to wait till the "aligned" data to arrive and do a system check like the datasheet suggested
self.submodules.timer = timer = ClockDomainsRenamer("cxp_gtx_rx")(WaitTimer(5000))
rxfsm.act("ALIGNING", rxfsm.act("ALIGNING",
self.aligner_en_rxclk.eq(1), self.aligner_en_rxclk.eq(1),
If(comma_aligned & (~has_error), If(self.word_aligned,
check_reset.eq(1), check_reset.eq(1),
NextState("DOUBLE_CHECK"), NextState("WAIT_ALIGNED_DATA"),
) )
) )
rxfsm.act("DOUBLE_CHECK", rxfsm.act("WAIT_ALIGNED_DATA",
timer.wait.eq(1),
If(timer.done,
check_reset.eq(1),
NextState("CHECKING"),
)
)
rxfsm.act("CHECKING",
If(check, If(check,
check_reset.eq(1), check_reset.eq(1),
If(~error_seen, If(comma_seen & (~error_seen),
NextState("READY"), NextState("READY"),
).Else( ).Else(
NextState("ALIGNING") NextState("ALIGNING")
@ -490,62 +470,12 @@ class Comma_Detector(Module):
ready.eq(1), ready.eq(1),
If(check, If(check,
check_reset.eq(1), check_reset.eq(1),
If(~comma_seen, If(~(comma_seen & (~error_seen)),
NextState("ALIGNING"), NextState("ALIGNING"),
) )
) )
) )
# self.submodules.fsm = fsm = FSM(reset_state="WAIT_RXINIT")
# aligner_en = Signal()
# self.specials += MultiReg(aligner_en, self.aligner_en_rxclk, odomain="cxp_gtx_rx")
# fsm.act("WAIT_RXINIT",
# If(self.rxinit_done,
# NextState("WAIT_COMMA_ALIGN"),
# )
# )
# fsm.act("WAIT_COMMA_ALIGN",
# aligner_en.eq(1),
# If(check,
# check_reset.i.eq(1),
# If(aligned,
# NextState("WAIT_VALID_DATA"),
# ).Else(
# self.restart.eq(1),
# NextState("WAIT_RXINIT")
# )
# )
# )
# fsm.act("WAIT_VALID_DATA",
# aligner_en.eq(1),
# If(check,
# check_reset.i.eq(1),
# If(aligned & valid_data,
# NextState("READY"),
# ).Else(
# self.restart.eq(1),
# NextState("WAIT_RXINIT"),
# )
# )
# )
# fsm.act("READY",
# self.ready.eq(1),
# If(check,
# check_reset.i.eq(1),
# If(~(aligned & valid_data),
# self.restart.eq(1),
# NextState("WAIT_RXINIT"),
# )
# )
# )
class GTX(Module): class GTX(Module):
# Settings: # Settings:
@ -609,6 +539,7 @@ class GTX(Module):
txdata = Signal(40) txdata = Signal(40)
rxdata = Signal(40) rxdata = Signal(40)
word_aligned = Signal()
comma_aligner_en = Signal() comma_aligner_en = Signal()
# Note: the following parameters were set after consulting AR45360 # Note: the following parameters were set after consulting AR45360
self.specials += \ self.specials += \
@ -752,6 +683,7 @@ class GTX(Module):
i_RXMCOMMAALIGNEN=comma_aligner_en, i_RXMCOMMAALIGNEN=comma_aligner_en,
i_RXCOMMADETEN=1, i_RXCOMMADETEN=1,
i_RXSLIDE=0, i_RXSLIDE=0,
o_RXBYTEISALIGNED=word_aligned,
# RX 8B/10B Decoder Attributes # RX 8B/10B Decoder Attributes
p_RX_DISPERR_SEQ_MATCH="FALSE", p_RX_DISPERR_SEQ_MATCH="FALSE",
@ -893,7 +825,7 @@ class GTX(Module):
self.submodules.comma_det = comma_det = Comma_Detector(0b0101111100) self.submodules.comma_det = comma_det = Comma_Detector(0b0101111100)
self.comb += [ self.comb += [
comma_det.data.eq(rxdata), comma_det.data.eq(rxdata),
comma_det.rxinit_done.eq(rx_init.done), comma_det.word_aligned.eq(word_aligned),
comma_aligner_en.eq(comma_det.aligner_en_rxclk), comma_aligner_en.eq(comma_det.aligner_en_rxclk),
self.rx_ready.eq(comma_det.ready), self.rx_ready.eq(comma_det.ready),