forked from M-Labs/artiq
drtio/transceiver/gth: implement tx multi lane phase alignment sequence (fix merge issue...)
This commit is contained in:
parent
820c834251
commit
b4ba71c7a4
|
@ -44,10 +44,10 @@ class GTHSingle(Module):
|
||||||
# # #
|
# # #
|
||||||
|
|
||||||
# TX generates RTIO clock, init must be in system domain
|
# 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 receives restart commands from RTIO domain
|
||||||
rx_init = ClockDomainsRenamer("rtio_tx")(GTHInit(rtio_clk_freq, True))
|
rx_init = ClockDomainsRenamer("rtio_tx")(GTHInit(rtio_clk_freq, True))
|
||||||
self.submodules += tx_init, rx_init
|
self.submodules += rx_init
|
||||||
|
|
||||||
cpll_reset = Signal()
|
cpll_reset = Signal()
|
||||||
cpll_lock = Signal()
|
cpll_lock = Signal()
|
||||||
|
@ -297,7 +297,7 @@ class GTH(Module, TransceiverInterface):
|
||||||
mode = "single"
|
mode = "single"
|
||||||
else:
|
else:
|
||||||
mode = "master" if i == master else "slave"
|
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":
|
if mode == "slave":
|
||||||
self.comb += gth.cd_rtio_tx.clk.eq(rtio_tx_clk)
|
self.comb += gth.cd_rtio_tx.clk.eq(rtio_tx_clk)
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -9,7 +9,8 @@ __all__ = ["GTHInit"]
|
||||||
|
|
||||||
|
|
||||||
class GTHInit(Module):
|
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.done = Signal()
|
||||||
self.restart = Signal()
|
self.restart = Signal()
|
||||||
|
|
||||||
|
@ -24,6 +25,9 @@ class GTHInit(Module):
|
||||||
self.Xxsyncdone = Signal()
|
self.Xxsyncdone = Signal()
|
||||||
self.Xxuserrdy = Signal()
|
self.Xxuserrdy = Signal()
|
||||||
|
|
||||||
|
self.all_ready_for_align = Signal(reset=1)
|
||||||
|
self.ready_for_align = Signal()
|
||||||
|
|
||||||
# # #
|
# # #
|
||||||
|
|
||||||
# Double-latch transceiver asynch outputs
|
# Double-latch transceiver asynch outputs
|
||||||
|
@ -98,14 +102,22 @@ class GTHInit(Module):
|
||||||
else:
|
else:
|
||||||
startup_fsm.act("RELEASE_GTH_RESET",
|
startup_fsm.act("RELEASE_GTH_RESET",
|
||||||
Xxuserrdy.eq(1),
|
Xxuserrdy.eq(1),
|
||||||
If(Xxresetdone, NextState("ALIGN"))
|
If(Xxresetdone,
|
||||||
|
If(mode == "slave",
|
||||||
|
NextState("WAIT_ALIGN")
|
||||||
|
).Else(
|
||||||
|
NextState("ALIGN")
|
||||||
|
)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
# Start delay alignment (pulse)
|
# Start delay alignment (pulse)
|
||||||
startup_fsm.act("ALIGN",
|
startup_fsm.act("ALIGN",
|
||||||
Xxuserrdy.eq(1),
|
Xxuserrdy.eq(1),
|
||||||
|
If(self.all_ready_for_align,
|
||||||
Xxdlysreset.eq(1),
|
Xxdlysreset.eq(1),
|
||||||
NextState("WAIT_ALIGN")
|
NextState("WAIT_ALIGN")
|
||||||
)
|
)
|
||||||
|
)
|
||||||
if rx:
|
if rx:
|
||||||
# Wait for delay alignment
|
# Wait for delay alignment
|
||||||
startup_fsm.act("WAIT_ALIGN",
|
startup_fsm.act("WAIT_ALIGN",
|
||||||
|
@ -119,17 +131,21 @@ class GTHInit(Module):
|
||||||
startup_fsm.act("WAIT_ALIGN",
|
startup_fsm.act("WAIT_ALIGN",
|
||||||
Xxuserrdy.eq(1),
|
Xxuserrdy.eq(1),
|
||||||
If(Xxdlysresetdone,
|
If(Xxdlysresetdone,
|
||||||
|
If(mode == "slave",
|
||||||
|
NextState("WAIT_LAST_ALIGN_DONE")
|
||||||
|
).Else(
|
||||||
NextState("WAIT_FIRST_ALIGN_DONE")
|
NextState("WAIT_FIRST_ALIGN_DONE")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
)
|
||||||
|
|
||||||
# Wait 2 rising edges of Xxphaligndone
|
# Wait 2 rising edges of Xxphaligndone
|
||||||
# (from UG576 in TX Buffer Bypass in Single-Lane Auto Mode)
|
# (from UG576 in TX Buffer Bypass in Single-Lane Auto Mode)
|
||||||
startup_fsm.act("WAIT_FIRST_ALIGN_DONE",
|
startup_fsm.act("WAIT_FIRST_ALIGN_DONE",
|
||||||
Xxuserrdy.eq(1),
|
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),
|
Xxuserrdy.eq(1),
|
||||||
If(Xxphaligndone_rising, NextState("READY"))
|
If(Xxphaligndone_rising, NextState("READY"))
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue