forked from M-Labs/artiq
drtio: signal stable clock input to transceiver
This commit is contained in:
parent
c87636ed2b
commit
83abdd283a
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
|
@ -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(
|
||||||
|
|
Loading…
Reference in New Issue