From b4ba71c7a4a05908ecc0f862accf036034cd8365 Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Fri, 23 Feb 2018 08:37:05 +0100 Subject: [PATCH] drtio/transceiver/gth: implement tx multi lane phase alignment sequence (fix merge issue...) --- .../drtio/transceiver/gth_ultrascale.py | 6 ++-- .../drtio/transceiver/gth_ultrascale_init.py | 30 ++++++++++++++----- 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/artiq/gateware/drtio/transceiver/gth_ultrascale.py b/artiq/gateware/drtio/transceiver/gth_ultrascale.py index cde2b6705..735bfa970 100644 --- a/artiq/gateware/drtio/transceiver/gth_ultrascale.py +++ b/artiq/gateware/drtio/transceiver/gth_ultrascale.py @@ -44,10 +44,10 @@ class GTHSingle(Module): # # # # TX generates RTIO clock, init must be in system domain - tx_init = GTHInit(sys_clk_freq, False) + self.submodules.tx_init = tx_init = GTHInit(sys_clk_freq, False) # RX receives restart commands from RTIO domain rx_init = ClockDomainsRenamer("rtio_tx")(GTHInit(rtio_clk_freq, True)) - self.submodules += tx_init, rx_init + self.submodules += rx_init cpll_reset = Signal() cpll_lock = Signal() @@ -297,7 +297,7 @@ class GTH(Module, TransceiverInterface): mode = "single" else: mode = "master" if i == master else "slave" - gth = GTHSingle(plls[i], tx_pads[i], rx_pads[i], sys_clk_freq, dw, mode) + gth = GTHSingle(refclk, data_pads[i], sys_clk_freq, rtio_clk_freq, dw, mode) if mode == "slave": self.comb += gth.cd_rtio_tx.clk.eq(rtio_tx_clk) else: diff --git a/artiq/gateware/drtio/transceiver/gth_ultrascale_init.py b/artiq/gateware/drtio/transceiver/gth_ultrascale_init.py index 8d188f6c0..2a5799ded 100644 --- a/artiq/gateware/drtio/transceiver/gth_ultrascale_init.py +++ b/artiq/gateware/drtio/transceiver/gth_ultrascale_init.py @@ -9,7 +9,8 @@ __all__ = ["GTHInit"] class GTHInit(Module): - def __init__(self, sys_clk_freq, rx): + def __init__(self, sys_clk_freq, rx, mode="master"): + assert not (rx and mode != "master") self.done = Signal() self.restart = Signal() @@ -24,6 +25,9 @@ class GTHInit(Module): self.Xxsyncdone = Signal() self.Xxuserrdy = Signal() + self.all_ready_for_align = Signal(reset=1) + self.ready_for_align = Signal() + # # # # Double-latch transceiver asynch outputs @@ -98,13 +102,21 @@ class GTHInit(Module): else: startup_fsm.act("RELEASE_GTH_RESET", Xxuserrdy.eq(1), - If(Xxresetdone, NextState("ALIGN")) + If(Xxresetdone, + If(mode == "slave", + NextState("WAIT_ALIGN") + ).Else( + NextState("ALIGN") + ) + ) ) # Start delay alignment (pulse) startup_fsm.act("ALIGN", Xxuserrdy.eq(1), - Xxdlysreset.eq(1), - NextState("WAIT_ALIGN") + If(self.all_ready_for_align, + Xxdlysreset.eq(1), + NextState("WAIT_ALIGN") + ) ) if rx: # Wait for delay alignment @@ -119,7 +131,11 @@ class GTHInit(Module): startup_fsm.act("WAIT_ALIGN", Xxuserrdy.eq(1), If(Xxdlysresetdone, - NextState("WAIT_FIRST_ALIGN_DONE") + If(mode == "slave", + NextState("WAIT_LAST_ALIGN_DONE") + ).Else( + NextState("WAIT_FIRST_ALIGN_DONE") + ) ) ) @@ -127,9 +143,9 @@ class GTHInit(Module): # (from UG576 in TX Buffer Bypass in Single-Lane Auto Mode) startup_fsm.act("WAIT_FIRST_ALIGN_DONE", Xxuserrdy.eq(1), - If(Xxphaligndone_rising, NextState("WAIT_SECOND_ALIGN_DONE")) + If(Xxphaligndone_rising, NextState("WAIT_LAST_ALIGN_DONE")) ) - startup_fsm.act("WAIT_SECOND_ALIGN_DONE", + startup_fsm.act("WAIT_LAST_ALIGN_DONE", Xxuserrdy.eq(1), If(Xxphaligndone_rising, NextState("READY")) )