drtio: signal stable clock input to transceiver

This commit is contained in:
Sebastien Bourdeauducq 2018-02-18 22:29:30 +08:00
parent c87636ed2b
commit 83abdd283a
7 changed files with 26 additions and 8 deletions

View File

@ -41,6 +41,9 @@ pub mod drtio {
use drtioaux; use drtioaux;
pub fn startup(io: &Io) { pub fn startup(io: &Io) {
unsafe {
csr::drtio_transceiver::stable_clkin_write(1);
}
io.spawn(4096, link_thread); io.spawn(4096, link_thread);
} }

View File

@ -206,6 +206,9 @@ fn startup() {
hmc830_7043::init().expect("cannot initialize HMC830/7043"); hmc830_7043::init().expect("cannot initialize HMC830/7043");
i2c::init(); i2c::init();
si5324::setup(&SI5324_SETTINGS).expect("cannot initialize Si5324"); si5324::setup(&SI5324_SETTINGS).expect("cannot initialize Si5324");
unsafe {
csr::drtio_transceiver::stable_clkin_write(1);
}
loop { loop {
while !drtio_link_is_up() { while !drtio_link_is_up() {

View File

@ -2,6 +2,7 @@ from types import SimpleNamespace
from migen import * from migen import *
from migen.genlib.cdc import ElasticBuffer from migen.genlib.cdc import ElasticBuffer
from misoc.interconnect.csr import *
from artiq.gateware.rtio.sed.core import * from artiq.gateware.rtio.sed.core import *
from artiq.gateware.rtio.input_collector import * from artiq.gateware.rtio.input_collector import *
@ -17,8 +18,9 @@ class ChannelInterface:
self.decoders = decoders self.decoders = decoders
class TransceiverInterface: class TransceiverInterface(AutoCSR):
def __init__(self, channel_interfaces): def __init__(self, channel_interfaces):
self.stable_clkin = CSRStorage()
self.clock_domains.cd_rtio = ClockDomain() self.clock_domains.cd_rtio = ClockDomain()
for i in range(len(channel_interfaces)): for i in range(len(channel_interfaces)):
name = "rtio_rx" + str(i) name = "rtio_rx" + str(i)

View File

@ -251,6 +251,8 @@ class GTH(Module, TransceiverInterface):
channel_interfaces.append(channel_interface) channel_interfaces.append(channel_interface)
TransceiverInterface.__init__(self, channel_interfaces) TransceiverInterface.__init__(self, channel_interfaces)
# GTH PLLs recover on their own from an interrupted clock input.
# stable_clkin can be ignored.
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),

View File

@ -15,6 +15,8 @@ class GTPSingle(Module):
def __init__(self, qpll_channel, pads, sys_clk_freq, rtio_clk_freq, mode): def __init__(self, qpll_channel, pads, sys_clk_freq, rtio_clk_freq, mode):
if mode != "master": if mode != "master":
raise NotImplementedError raise NotImplementedError
self.stable_clkin = Signal()
self.submodules.encoder = encoder = ClockDomainsRenamer("rtio_tx")( self.submodules.encoder = encoder = ClockDomainsRenamer("rtio_tx")(
Encoder(2, True)) Encoder(2, True))
self.submodules.decoders = decoders = [ClockDomainsRenamer("rtio_rx")( self.submodules.decoders = decoders = [ClockDomainsRenamer("rtio_rx")(
@ -35,6 +37,7 @@ class GTPSingle(Module):
self.submodules += tx_init, rx_init self.submodules += tx_init, rx_init
self.comb += [ self.comb += [
tx_init.stable_clkin.eq(self.stable_clkin),
qpll_channel.reset.eq(tx_init.pllreset), qpll_channel.reset.eq(tx_init.pllreset),
tx_init.plllock.eq(qpll_channel.lock), tx_init.plllock.eq(qpll_channel.lock),
rx_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) channel_interfaces.append(channel_interface)
TransceiverInterface.__init__(self, channel_interfaces) TransceiverInterface.__init__(self, channel_interfaces)
for gtp in self.gtps:
self.comb += gtp.stable_clkin.eq(self.stable_clkin.storage)
self.comb += [ self.comb += [
self.cd_rtio.clk.eq(self.gtps[master].cd_rtio_tx.clk), self.cd_rtio.clk.eq(self.gtps[master].cd_rtio_tx.clk),

View File

@ -10,6 +10,7 @@ __all__ = ["GTPTXInit", "GTPRXInit"]
class GTPTXInit(Module): class GTPTXInit(Module):
def __init__(self, sys_clk_freq): def __init__(self, sys_clk_freq):
self.stable_clkin = Signal()
self.done = Signal() self.done = Signal()
self.restart = Signal() self.restart = Signal()
@ -82,7 +83,7 @@ class GTPTXInit(Module):
startup_fsm.act("PLL_RESET", startup_fsm.act("PLL_RESET",
self.pllreset.eq(1), self.pllreset.eq(1),
pll_reset_timer.wait.eq(1), pll_reset_timer.wait.eq(1),
If(pll_reset_timer.done, If(pll_reset_timer.done & self.stable_clkin,
NextState("GTP_RESET") NextState("GTP_RESET")
) )
) )

View File

@ -327,14 +327,15 @@ class Master(MiniSoC, AMPSoC):
self.config["RTIO_FREQUENCY"] = str(rtio_clk_freq/1e6) self.config["RTIO_FREQUENCY"] = str(rtio_clk_freq/1e6)
self.comb += platform.request("sfp_ctl", 2).tx_disable.eq(0) 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, qpll_channel=self.drtio_qpll_channel,
data_pads=[platform.request("sfp", 2)], data_pads=[platform.request("sfp", 2)],
sys_clk_freq=self.clk_freq, sys_clk_freq=self.clk_freq,
rtio_clk_freq=rtio_clk_freq) rtio_clk_freq=rtio_clk_freq)
self.csr_devices.append("drtio_transceiver")
self.submodules.drtio0 = ClockDomainsRenamer({"rtio_rx": "rtio_rx0"})( 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.csr_devices.append("drtio0")
self.add_wb_slave(self.mem_map["drtio_aux"], 0x800, self.add_wb_slave(self.mem_map["drtio_aux"], 0x800,
self.drtio0.aux_controller.bus) self.drtio0.aux_controller.bus)
@ -344,7 +345,7 @@ class Master(MiniSoC, AMPSoC):
self.add_memory_group("drtio_aux", ["drtio0_aux"]) self.add_memory_group("drtio_aux", ["drtio0_aux"])
rtio_clk_period = 1e9/rtio_clk_freq 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.txoutclk, rtio_clk_period)
platform.add_period_constraint(gtp.rxoutclk, rtio_clk_period) platform.add_period_constraint(gtp.rxoutclk, rtio_clk_period)
platform.add_false_path_constraints( platform.add_false_path_constraints(
@ -447,14 +448,15 @@ class Satellite(BaseSoC):
self.submodules += qpll self.submodules += qpll
self.comb += platform.request("sfp_ctl", 0).tx_disable.eq(0) 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], qpll_channel=qpll.channels[0],
data_pads=[platform.request("sfp", 0)], data_pads=[platform.request("sfp", 0)],
sys_clk_freq=self.clk_freq, sys_clk_freq=self.clk_freq,
rtio_clk_freq=rtio_clk_freq) rtio_clk_freq=rtio_clk_freq)
self.csr_devices.append("drtio_transceiver")
rx0 = ClockDomainsRenamer({"rtio_rx": "rtio_rx0"}) rx0 = ClockDomainsRenamer({"rtio_rx": "rtio_rx0"})
self.submodules.drtio0 = rx0(DRTIOSatellite( self.submodules.drtio0 = rx0(DRTIOSatellite(
self.transceiver.channels[0], rtio_channels)) self.drtio_transceiver.channels[0], rtio_channels))
self.csr_devices.append("drtio0") self.csr_devices.append("drtio0")
self.add_wb_slave(self.mem_map["drtio_aux"], 0x800, self.add_wb_slave(self.mem_map["drtio_aux"], 0x800,
self.drtio0.aux_controller.bus) self.drtio0.aux_controller.bus)
@ -478,7 +480,7 @@ class Satellite(BaseSoC):
self.config["SI5324_SOFT_RESET"] = None self.config["SI5324_SOFT_RESET"] = None
rtio_clk_period = 1e9/rtio_clk_freq 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.txoutclk, rtio_clk_period)
platform.add_period_constraint(gtp.rxoutclk, rtio_clk_period) platform.add_period_constraint(gtp.rxoutclk, rtio_clk_period)
platform.add_false_path_constraints( platform.add_false_path_constraints(