forked from M-Labs/artiq
drtio/gth_ultrascale: generate multiplied RTIO clock from BUFG_GT (#792)
This commit is contained in:
parent
77126ce5b3
commit
175f8b8ccc
|
@ -14,7 +14,7 @@ from artiq.gateware.drtio.transceiver.gth_ultrascale_init import *
|
||||||
|
|
||||||
|
|
||||||
class GTHSingle(Module):
|
class GTHSingle(Module):
|
||||||
def __init__(self, refclk, pads, sys_clk_freq, rtio_clk_freq, dw, mode):
|
def __init__(self, refclk, pads, sys_clk_freq, rtio_clk_freq, rtiox_mul, dw, mode):
|
||||||
assert (dw == 20) or (dw == 40)
|
assert (dw == 20) or (dw == 40)
|
||||||
assert mode in ["single", "master", "slave"]
|
assert mode in ["single", "master", "slave"]
|
||||||
self.mode = mode
|
self.mode = mode
|
||||||
|
@ -441,7 +441,7 @@ class GTHSingle(Module):
|
||||||
p_TX_PMADATA_OPT =0b0,
|
p_TX_PMADATA_OPT =0b0,
|
||||||
p_TX_PMA_POWER_SAVE =0b0,
|
p_TX_PMA_POWER_SAVE =0b0,
|
||||||
p_TX_PROGCLK_SEL ="PREPI",
|
p_TX_PROGCLK_SEL ="PREPI",
|
||||||
p_TX_PROGDIV_CFG =0.0,
|
p_TX_PROGDIV_CFG =dw/rtiox_mul,
|
||||||
p_TX_QPI_STATUS_EN =0b0,
|
p_TX_QPI_STATUS_EN =0b0,
|
||||||
p_TX_RXDETECT_CFG =0b00000000110010,
|
p_TX_RXDETECT_CFG =0b00000000110010,
|
||||||
p_TX_RXDETECT_REF =0b100,
|
p_TX_RXDETECT_REF =0b100,
|
||||||
|
@ -469,7 +469,7 @@ class GTHSingle(Module):
|
||||||
o_TXOUTCLK=self.txoutclk,
|
o_TXOUTCLK=self.txoutclk,
|
||||||
i_TXSYSCLKSEL=0b00,
|
i_TXSYSCLKSEL=0b00,
|
||||||
i_TXPLLCLKSEL=0b00,
|
i_TXPLLCLKSEL=0b00,
|
||||||
i_TXOUTCLKSEL=0b11,
|
i_TXOUTCLKSEL=0b101,
|
||||||
|
|
||||||
# TX Startup/Reset
|
# TX Startup/Reset
|
||||||
i_GTTXRESET=tx_init.gtXxreset,
|
i_GTTXRESET=tx_init.gtXxreset,
|
||||||
|
@ -558,9 +558,12 @@ class GTHSingle(Module):
|
||||||
tx_reset_deglitched.attr.add("no_retiming")
|
tx_reset_deglitched.attr.add("no_retiming")
|
||||||
self.sync += tx_reset_deglitched.eq(~tx_init.done)
|
self.sync += tx_reset_deglitched.eq(~tx_init.done)
|
||||||
self.clock_domains.cd_rtio_tx = ClockDomain()
|
self.clock_domains.cd_rtio_tx = ClockDomain()
|
||||||
|
self.clock_domains.cd_rtiox_tx = ClockDomain()
|
||||||
if mode == "master" or mode == "single":
|
if mode == "master" or mode == "single":
|
||||||
self.specials += \
|
self.specials += [
|
||||||
Instance("BUFG_GT", i_I=self.txoutclk, o_O=self.cd_rtio_tx.clk, i_DIV=0)
|
Instance("BUFG_GT", i_I=self.txoutclk, o_O=self.cd_rtiox_tx.clk, i_DIV=0),
|
||||||
|
Instance("BUFG_GT", i_I=self.txoutclk, o_O=self.cd_rtio_tx.clk, i_DIV=rtiox_mul-1)
|
||||||
|
]
|
||||||
self.specials += AsyncResetSynchronizer(self.cd_rtio_tx, tx_reset_deglitched)
|
self.specials += AsyncResetSynchronizer(self.cd_rtio_tx, tx_reset_deglitched)
|
||||||
|
|
||||||
# rx clocking
|
# rx clocking
|
||||||
|
@ -630,7 +633,7 @@ class GTHTXPhaseAlignement(Module):
|
||||||
|
|
||||||
|
|
||||||
class GTH(Module, TransceiverInterface):
|
class GTH(Module, TransceiverInterface):
|
||||||
def __init__(self, clock_pads, data_pads, sys_clk_freq, rtio_clk_freq, dw=20, master=0):
|
def __init__(self, clock_pads, data_pads, sys_clk_freq, rtio_clk_freq, rtiox_mul=2, dw=20, master=0):
|
||||||
self.nchannels = nchannels = len(data_pads)
|
self.nchannels = nchannels = len(data_pads)
|
||||||
self.gths = []
|
self.gths = []
|
||||||
|
|
||||||
|
@ -655,7 +658,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(refclk, data_pads[i], sys_clk_freq, rtio_clk_freq, dw, mode)
|
gth = GTHSingle(refclk, data_pads[i], sys_clk_freq, rtio_clk_freq, rtiox_mul, dw, mode)
|
||||||
if mode == "master":
|
if mode == "master":
|
||||||
self.comb += rtio_tx_clk.eq(gth.cd_rtio_tx.clk)
|
self.comb += rtio_tx_clk.eq(gth.cd_rtio_tx.clk)
|
||||||
elif mode == "slave":
|
elif mode == "slave":
|
||||||
|
@ -669,6 +672,7 @@ class GTH(Module, TransceiverInterface):
|
||||||
self.submodules.tx_phase_alignment = GTHTXPhaseAlignement(self.gths)
|
self.submodules.tx_phase_alignment = GTHTXPhaseAlignement(self.gths)
|
||||||
|
|
||||||
TransceiverInterface.__init__(self, channel_interfaces)
|
TransceiverInterface.__init__(self, channel_interfaces)
|
||||||
|
self.cd_rtiox = ClockDomain(reset_less=True)
|
||||||
if create_buf:
|
if create_buf:
|
||||||
# GTH PLLs recover on their own from an interrupted clock input,
|
# GTH PLLs recover on their own from an interrupted clock input,
|
||||||
# but be paranoid about HMC7043 noise.
|
# but be paranoid about HMC7043 noise.
|
||||||
|
@ -677,6 +681,7 @@ class GTH(Module, TransceiverInterface):
|
||||||
|
|
||||||
self.comb += [
|
self.comb += [
|
||||||
self.cd_rtio.clk.eq(self.gths[master].cd_rtio_tx.clk),
|
self.cd_rtio.clk.eq(self.gths[master].cd_rtio_tx.clk),
|
||||||
|
self.cd_rtiox.clk.eq(self.gths[master].cd_rtiox_tx.clk),
|
||||||
self.cd_rtio.rst.eq(reduce(or_, [gth.cd_rtio_tx.rst for gth in self.gths]))
|
self.cd_rtio.rst.eq(reduce(or_, [gth.cd_rtio_tx.rst for gth in self.gths]))
|
||||||
]
|
]
|
||||||
for i in range(nchannels):
|
for i in range(nchannels):
|
||||||
|
|
|
@ -321,7 +321,7 @@ class MasterDAC(MiniSoC, AMPSoC, RTMCommon):
|
||||||
|
|
||||||
rtio_clk_period = 1e9/rtio_clk_freq
|
rtio_clk_period = 1e9/rtio_clk_freq
|
||||||
gth = self.drtio_transceiver.gths[0]
|
gth = self.drtio_transceiver.gths[0]
|
||||||
platform.add_period_constraint(gth.txoutclk, rtio_clk_period)
|
platform.add_period_constraint(gth.txoutclk, rtio_clk_period/2)
|
||||||
platform.add_period_constraint(gth.rxoutclk, rtio_clk_period)
|
platform.add_period_constraint(gth.rxoutclk, rtio_clk_period)
|
||||||
platform.add_false_path_constraints(
|
platform.add_false_path_constraints(
|
||||||
self.crg.cd_sys.clk,
|
self.crg.cd_sys.clk,
|
||||||
|
@ -480,7 +480,7 @@ class Master(MiniSoC, AMPSoC):
|
||||||
|
|
||||||
rtio_clk_period = 1e9/rtio_clk_freq
|
rtio_clk_period = 1e9/rtio_clk_freq
|
||||||
gth = self.drtio_transceiver.gths[0]
|
gth = self.drtio_transceiver.gths[0]
|
||||||
platform.add_period_constraint(gth.txoutclk, rtio_clk_period)
|
platform.add_period_constraint(gth.txoutclk, rtio_clk_period/2)
|
||||||
platform.add_period_constraint(gth.rxoutclk, rtio_clk_period)
|
platform.add_period_constraint(gth.rxoutclk, rtio_clk_period)
|
||||||
platform.add_false_path_constraints(
|
platform.add_false_path_constraints(
|
||||||
self.crg.cd_sys.clk,
|
self.crg.cd_sys.clk,
|
||||||
|
@ -661,7 +661,7 @@ class Satellite(BaseSoC, RTMCommon):
|
||||||
|
|
||||||
rtio_clk_period = 1e9/rtio_clk_freq
|
rtio_clk_period = 1e9/rtio_clk_freq
|
||||||
gth = self.drtio_transceiver.gths[0]
|
gth = self.drtio_transceiver.gths[0]
|
||||||
platform.add_period_constraint(gth.txoutclk, rtio_clk_period)
|
platform.add_period_constraint(gth.txoutclk, rtio_clk_period/2)
|
||||||
platform.add_period_constraint(gth.rxoutclk, rtio_clk_period)
|
platform.add_period_constraint(gth.rxoutclk, rtio_clk_period)
|
||||||
platform.add_false_path_constraints(
|
platform.add_false_path_constraints(
|
||||||
self.crg.cd_sys.clk,
|
self.crg.cd_sys.clk,
|
||||||
|
|
Loading…
Reference in New Issue