From 83abdd283a93f968947753acd6672f0172b1eab8 Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Sun, 18 Feb 2018 22:29:30 +0800 Subject: [PATCH] drtio: signal stable clock input to transceiver --- artiq/firmware/runtime/rtio_mgt.rs | 3 +++ artiq/firmware/satman/main.rs | 3 +++ artiq/gateware/drtio/core.py | 4 +++- artiq/gateware/drtio/transceiver/gth_ultrascale.py | 2 ++ artiq/gateware/drtio/transceiver/gtp_7series.py | 5 +++++ .../gateware/drtio/transceiver/gtp_7series_init.py | 3 ++- artiq/gateware/targets/kasli.py | 14 ++++++++------ 7 files changed, 26 insertions(+), 8 deletions(-) diff --git a/artiq/firmware/runtime/rtio_mgt.rs b/artiq/firmware/runtime/rtio_mgt.rs index cc63b86e2..f481b04ad 100644 --- a/artiq/firmware/runtime/rtio_mgt.rs +++ b/artiq/firmware/runtime/rtio_mgt.rs @@ -41,6 +41,9 @@ pub mod drtio { use drtioaux; pub fn startup(io: &Io) { + unsafe { + csr::drtio_transceiver::stable_clkin_write(1); + } io.spawn(4096, link_thread); } diff --git a/artiq/firmware/satman/main.rs b/artiq/firmware/satman/main.rs index cdaebff47..a2c155085 100644 --- a/artiq/firmware/satman/main.rs +++ b/artiq/firmware/satman/main.rs @@ -206,6 +206,9 @@ fn startup() { hmc830_7043::init().expect("cannot initialize HMC830/7043"); i2c::init(); si5324::setup(&SI5324_SETTINGS).expect("cannot initialize Si5324"); + unsafe { + csr::drtio_transceiver::stable_clkin_write(1); + } loop { while !drtio_link_is_up() { diff --git a/artiq/gateware/drtio/core.py b/artiq/gateware/drtio/core.py index 0bda7ad38..12b12b1ab 100644 --- a/artiq/gateware/drtio/core.py +++ b/artiq/gateware/drtio/core.py @@ -2,6 +2,7 @@ from types import SimpleNamespace from migen import * from migen.genlib.cdc import ElasticBuffer +from misoc.interconnect.csr import * from artiq.gateware.rtio.sed.core import * from artiq.gateware.rtio.input_collector import * @@ -17,8 +18,9 @@ class ChannelInterface: self.decoders = decoders -class TransceiverInterface: +class TransceiverInterface(AutoCSR): def __init__(self, channel_interfaces): + self.stable_clkin = CSRStorage() self.clock_domains.cd_rtio = ClockDomain() for i in range(len(channel_interfaces)): name = "rtio_rx" + str(i) diff --git a/artiq/gateware/drtio/transceiver/gth_ultrascale.py b/artiq/gateware/drtio/transceiver/gth_ultrascale.py index a6a098b19..1e1a5a9e6 100644 --- a/artiq/gateware/drtio/transceiver/gth_ultrascale.py +++ b/artiq/gateware/drtio/transceiver/gth_ultrascale.py @@ -251,6 +251,8 @@ class GTH(Module, TransceiverInterface): channel_interfaces.append(channel_interface) TransceiverInterface.__init__(self, channel_interfaces) + # GTH PLLs recover on their own from an interrupted clock input. + # stable_clkin can be ignored. self.comb += [ self.cd_rtio.clk.eq(self.gths[master].cd_rtio_tx.clk), diff --git a/artiq/gateware/drtio/transceiver/gtp_7series.py b/artiq/gateware/drtio/transceiver/gtp_7series.py index 6ea82de9c..4ed906391 100644 --- a/artiq/gateware/drtio/transceiver/gtp_7series.py +++ b/artiq/gateware/drtio/transceiver/gtp_7series.py @@ -15,6 +15,8 @@ class GTPSingle(Module): def __init__(self, qpll_channel, pads, sys_clk_freq, rtio_clk_freq, mode): if mode != "master": raise NotImplementedError + + self.stable_clkin = Signal() self.submodules.encoder = encoder = ClockDomainsRenamer("rtio_tx")( Encoder(2, True)) self.submodules.decoders = decoders = [ClockDomainsRenamer("rtio_rx")( @@ -35,6 +37,7 @@ class GTPSingle(Module): self.submodules += tx_init, rx_init self.comb += [ + tx_init.stable_clkin.eq(self.stable_clkin), qpll_channel.reset.eq(tx_init.pllreset), tx_init.plllock.eq(qpll_channel.lock), rx_init.plllock.eq(qpll_channel.lock), @@ -721,6 +724,8 @@ class GTP(Module, TransceiverInterface): channel_interfaces.append(channel_interface) TransceiverInterface.__init__(self, channel_interfaces) + for gtp in self.gtps: + self.comb += gtp.stable_clkin.eq(self.stable_clkin.storage) self.comb += [ self.cd_rtio.clk.eq(self.gtps[master].cd_rtio_tx.clk), diff --git a/artiq/gateware/drtio/transceiver/gtp_7series_init.py b/artiq/gateware/drtio/transceiver/gtp_7series_init.py index e544a90b2..8e742d342 100644 --- a/artiq/gateware/drtio/transceiver/gtp_7series_init.py +++ b/artiq/gateware/drtio/transceiver/gtp_7series_init.py @@ -10,6 +10,7 @@ __all__ = ["GTPTXInit", "GTPRXInit"] class GTPTXInit(Module): def __init__(self, sys_clk_freq): + self.stable_clkin = Signal() self.done = Signal() self.restart = Signal() @@ -82,7 +83,7 @@ class GTPTXInit(Module): startup_fsm.act("PLL_RESET", self.pllreset.eq(1), pll_reset_timer.wait.eq(1), - If(pll_reset_timer.done, + If(pll_reset_timer.done & self.stable_clkin, NextState("GTP_RESET") ) ) diff --git a/artiq/gateware/targets/kasli.py b/artiq/gateware/targets/kasli.py index 6ef5c610e..43d8b6031 100755 --- a/artiq/gateware/targets/kasli.py +++ b/artiq/gateware/targets/kasli.py @@ -327,14 +327,15 @@ class Master(MiniSoC, AMPSoC): self.config["RTIO_FREQUENCY"] = str(rtio_clk_freq/1e6) self.comb += platform.request("sfp_ctl", 2).tx_disable.eq(0) - self.submodules.transceiver = gtp_7series.GTP( + self.submodules.drtio_transceiver = gtp_7series.GTP( qpll_channel=self.drtio_qpll_channel, data_pads=[platform.request("sfp", 2)], sys_clk_freq=self.clk_freq, rtio_clk_freq=rtio_clk_freq) + self.csr_devices.append("drtio_transceiver") self.submodules.drtio0 = ClockDomainsRenamer({"rtio_rx": "rtio_rx0"})( - DRTIOMaster(self.transceiver.channels[0])) + DRTIOMaster(self.drtio_transceiver.channels[0])) self.csr_devices.append("drtio0") self.add_wb_slave(self.mem_map["drtio_aux"], 0x800, self.drtio0.aux_controller.bus) @@ -344,7 +345,7 @@ class Master(MiniSoC, AMPSoC): self.add_memory_group("drtio_aux", ["drtio0_aux"]) rtio_clk_period = 1e9/rtio_clk_freq - for gtp in self.transceiver.gtps: + for gtp in self.drtio_transceiver.gtps: platform.add_period_constraint(gtp.txoutclk, rtio_clk_period) platform.add_period_constraint(gtp.rxoutclk, rtio_clk_period) platform.add_false_path_constraints( @@ -447,14 +448,15 @@ class Satellite(BaseSoC): self.submodules += qpll self.comb += platform.request("sfp_ctl", 0).tx_disable.eq(0) - self.submodules.transceiver = gtp_7series.GTP( + self.submodules.drtio_transceiver = gtp_7series.GTP( qpll_channel=qpll.channels[0], data_pads=[platform.request("sfp", 0)], sys_clk_freq=self.clk_freq, rtio_clk_freq=rtio_clk_freq) + self.csr_devices.append("drtio_transceiver") rx0 = ClockDomainsRenamer({"rtio_rx": "rtio_rx0"}) self.submodules.drtio0 = rx0(DRTIOSatellite( - self.transceiver.channels[0], rtio_channels)) + self.drtio_transceiver.channels[0], rtio_channels)) self.csr_devices.append("drtio0") self.add_wb_slave(self.mem_map["drtio_aux"], 0x800, self.drtio0.aux_controller.bus) @@ -478,7 +480,7 @@ class Satellite(BaseSoC): self.config["SI5324_SOFT_RESET"] = None rtio_clk_period = 1e9/rtio_clk_freq - gtp = self.transceiver.gtps[0] + gtp = self.drtio_transceiver.gtps[0] platform.add_period_constraint(gtp.txoutclk, rtio_clk_period) platform.add_period_constraint(gtp.rxoutclk, rtio_clk_period) platform.add_false_path_constraints(