forked from M-Labs/artiq-zynq
cxp downconn: fix aligner not work @ 5 & 6.25Gbps
This commit is contained in:
parent
aa128e1467
commit
a6b1701de3
|
@ -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),
|
||||
|
||||
# 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.aligner_en_rxclk, o_O=pmod_pads[2]),
|
||||
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):
|
||||
def __init__(self, comma, check_period=1_000_000):
|
||||
self.data = Signal(20)
|
||||
self.rxinit_done = Signal()
|
||||
self.word_aligned = Signal()
|
||||
|
||||
self.aligner_en_rxclk = Signal()
|
||||
self.ready = Signal()
|
||||
|
@ -345,39 +345,6 @@ class Comma_Detector(Module):
|
|||
# - UG476 (v1.12.1) p.228
|
||||
|
||||
# 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)
|
||||
|
@ -465,18 +432,31 @@ class Comma_Detector(Module):
|
|||
|
||||
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",
|
||||
self.aligner_en_rxclk.eq(1),
|
||||
If(comma_aligned & (~has_error),
|
||||
If(self.word_aligned,
|
||||
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,
|
||||
check_reset.eq(1),
|
||||
If(~error_seen,
|
||||
If(comma_seen & (~error_seen),
|
||||
NextState("READY"),
|
||||
).Else(
|
||||
NextState("ALIGNING")
|
||||
|
@ -490,62 +470,12 @@ class Comma_Detector(Module):
|
|||
ready.eq(1),
|
||||
If(check,
|
||||
check_reset.eq(1),
|
||||
If(~comma_seen,
|
||||
If(~(comma_seen & (~error_seen)),
|
||||
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):
|
||||
# Settings:
|
||||
|
@ -609,6 +539,7 @@ class GTX(Module):
|
|||
txdata = Signal(40)
|
||||
rxdata = Signal(40)
|
||||
|
||||
word_aligned = Signal()
|
||||
comma_aligner_en = Signal()
|
||||
# Note: the following parameters were set after consulting AR45360
|
||||
self.specials += \
|
||||
|
@ -752,6 +683,7 @@ class GTX(Module):
|
|||
i_RXMCOMMAALIGNEN=comma_aligner_en,
|
||||
i_RXCOMMADETEN=1,
|
||||
i_RXSLIDE=0,
|
||||
o_RXBYTEISALIGNED=word_aligned,
|
||||
|
||||
# RX 8B/10B Decoder Attributes
|
||||
p_RX_DISPERR_SEQ_MATCH="FALSE",
|
||||
|
@ -893,7 +825,7 @@ class GTX(Module):
|
|||
self.submodules.comma_det = comma_det = Comma_Detector(0b0101111100)
|
||||
self.comb += [
|
||||
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),
|
||||
self.rx_ready.eq(comma_det.ready),
|
||||
|
||||
|
|
Loading…
Reference in New Issue