forked from M-Labs/artiq
1
0
Fork 0

sayma: introduce WRPLL on RTM

This commit is contained in:
Sebastien Bourdeauducq 2019-12-08 15:30:00 +08:00
parent f35f658bc5
commit 46a776d06e
5 changed files with 84 additions and 35 deletions

View File

@ -1 +1,2 @@
from artiq.gateware.drtio.wrpll.core import WRPLL from artiq.gateware.drtio.wrpll.core import WRPLL
from artiq.gateware.drtio.wrpll.ddmtd import DDMTDSamplerExtFF, DDMTDSamplerGTP

View File

@ -23,19 +23,5 @@ class WRPLL(Module, AutoCSR):
ddmtd_counter = Signal(N) ddmtd_counter = Signal(N)
self.sync.helper += ddmtd_counter.eq(ddmtd_counter + 1) self.sync.helper += ddmtd_counter.eq(ddmtd_counter + 1)
if hasattr(ddmtd_inputs, "rec_clk"): self.submodules.ddmtd_helper = DDMTD(ddmtd_counter, ddmtd_inputs.rec_clk)
ddmtd_input_rec_clk = ddmtd_inputs.rec_clk self.submodules.ddmtd_main = DDMTD(ddmtd_counter, ddmtd_inputs.main_xo)
else:
ddmtd_input_rec_clk = Signal()
self.specials += Instance("IBUFDS",
i_I=ddmtd_inputs.rec_clk_p, i_IB=ddmtd_inputs.rec_clk_n,
o_O=ddmtd_input_rec_clk)
if hasattr(ddmtd_inputs, "main_xo"):
ddmtd_input_main_xo = ddmtd_inputs.main_xo
else:
ddmtd_input_main_xo = Signal()
self.specials += Instance("IBUFDS",
i_I=ddmtd_inputs.main_xo_p, i_IB=ddmtd_inputs.main_xo_n,
o_O=ddmtd_input_main_xo)
self.submodules.ddmtd_helper = DDMTD(ddmtd_counter, ddmtd_input_rec_clk)
self.submodules.ddmtd_main = DDMTD(ddmtd_counter, ddmtd_input_main_xo)

View File

@ -3,6 +3,47 @@ from migen.genlib.cdc import PulseSynchronizer, MultiReg
from misoc.interconnect.csr import * from misoc.interconnect.csr import *
class DDMTDSamplerExtFF(Module):
def __init__(self, ddmtd_inputs):
# TODO: s/h timing at FPGA pads
if hasattr(ddmtd_inputs, "rec_clk"):
self.rec_clk = ddmtd_inputs.rec_clk
else:
self.rec_clk = Signal()
self.specials += Instance("IBUFDS",
i_I=ddmtd_inputs.rec_clk_p, i_IB=ddmtd_inputs.rec_clk_n,
o_O=self.rec_clk)
if hasattr(ddmtd_inputs, "main_xo"):
self.main_xo = ddmtd_inputs.main_xo
else:
self.main_xo = Signal()
self.specials += Instance("IBUFDS",
i_I=ddmtd_inputs.main_xo_p, i_IB=ddmtd_inputs.main_xo_n,
o_O=self.main_xo)
class DDMTDSamplerGTP(Module):
def __init__(self, gtp, main_xo_pads):
self.rec_clk = Signal()
self.main_xo = Signal()
# Getting this signal from IBUFDS_GTE2 is problematic because:
# 1. the clock gets divided by 2
# 2. the transceiver PLL craps out if an improper clock signal is applied,
# so we are disabling the buffer until the clock is stable.
# 3. UG482 says "The O and ODIV2 outputs are not phase matched to each other",
# which may or may not be a problem depending on what it actually means.
main_xo_se = Signal()
self.specials += Instance("IBUFDS",
i_I=main_xo_pads.p, i_IB=main_xo_pads.n,
o_O=main_xo_se)
self.sync.helper += [
self.rec_clk.eq(gtp.cd_rtio_rx0.clk),
self.main_xo.eq(main_xo_se)
]
class DDMTDEdgeDetector(Module): class DDMTDEdgeDetector(Module):
def __init__(self, input_signal): def __init__(self, input_signal):
self.rising = Signal() self.rising = Signal()

View File

@ -19,7 +19,7 @@ from artiq.gateware import jesd204_tools
from artiq.gateware.rtio.phy import ttl_simple, ttl_serdes_ultrascale, sawg from artiq.gateware.rtio.phy import ttl_simple, ttl_serdes_ultrascale, sawg
from artiq.gateware.drtio.transceiver import gth_ultrascale from artiq.gateware.drtio.transceiver import gth_ultrascale
from artiq.gateware.drtio.siphaser import SiPhaser7Series from artiq.gateware.drtio.siphaser import SiPhaser7Series
from artiq.gateware.drtio.wrpll import WRPLL from artiq.gateware.drtio.wrpll import WRPLL, DDMTDSamplerExtFF
from artiq.gateware.drtio.rx_synchronizer import XilinxRXSynchronizer from artiq.gateware.drtio.rx_synchronizer import XilinxRXSynchronizer
from artiq.gateware.drtio import * from artiq.gateware.drtio import *
from artiq.build_soc import * from artiq.build_soc import *
@ -136,11 +136,13 @@ class SatelliteBase(MiniSoC):
platform.request("ddmtd_main_dcxo_oe").eq(1), platform.request("ddmtd_main_dcxo_oe").eq(1),
platform.request("ddmtd_helper_dcxo_oe").eq(1) platform.request("ddmtd_helper_dcxo_oe").eq(1)
] ]
self.submodules.wrpll_sampler = DDMTDSamplerExtFF(
platform.request("ddmtd_inputs"))
self.submodules.wrpll = WRPLL( self.submodules.wrpll = WRPLL(
helper_clk_pads=platform.request("ddmtd_helper_clk"), helper_clk_pads=platform.request("ddmtd_helper_clk"),
main_dcxo_i2c=platform.request("ddmtd_main_dcxo_i2c"), main_dcxo_i2c=platform.request("ddmtd_main_dcxo_i2c"),
helper_dxco_i2c=platform.request("ddmtd_helper_dcxo_i2c"), helper_dxco_i2c=platform.request("ddmtd_helper_dcxo_i2c"),
ddmtd_inputs=platform.request("ddmtd_inputs")) ddmtd_inputs=self.wrpll_sampler)
self.csr_devices.append("wrpll") self.csr_devices.append("wrpll")
else: else:
self.comb += platform.request("filtered_clk_sel").eq(1) self.comb += platform.request("filtered_clk_sel").eq(1)

View File

@ -19,6 +19,7 @@ from artiq.gateware import rtio
from artiq.gateware.rtio.phy import ttl_serdes_7series from artiq.gateware.rtio.phy import ttl_serdes_7series
from artiq.gateware.drtio.transceiver import gtp_7series from artiq.gateware.drtio.transceiver import gtp_7series
from artiq.gateware.drtio.siphaser import SiPhaser7Series from artiq.gateware.drtio.siphaser import SiPhaser7Series
from artiq.gateware.drtio.wrpll import WRPLL, DDMTDSamplerGTP
from artiq.gateware.drtio.rx_synchronizer import XilinxRXSynchronizer from artiq.gateware.drtio.rx_synchronizer import XilinxRXSynchronizer
from artiq.gateware.drtio import * from artiq.gateware.drtio import *
from artiq.build_soc import add_identifier from artiq.build_soc import add_identifier
@ -73,7 +74,7 @@ class _SatelliteBase(BaseSoC):
} }
mem_map.update(BaseSoC.mem_map) mem_map.update(BaseSoC.mem_map)
def __init__(self, rtio_clk_freq, **kwargs): def __init__(self, rtio_clk_freq, *, with_wrpll, **kwargs):
BaseSoC.__init__(self, BaseSoC.__init__(self,
cpu_type="or1k", cpu_type="or1k",
**kwargs) **kwargs)
@ -132,6 +133,22 @@ class _SatelliteBase(BaseSoC):
self.add_memory_group("drtioaux_mem", ["drtioaux0_mem"]) self.add_memory_group("drtioaux_mem", ["drtioaux0_mem"])
self.config["RTIO_FREQUENCY"] = str(rtio_clk_freq/1e6) self.config["RTIO_FREQUENCY"] = str(rtio_clk_freq/1e6)
if with_wrpll:
self.comb += [
platform.request("filtered_clk_sel").eq(0),
platform.request("ddmtd_main_dcxo_oe").eq(1),
platform.request("ddmtd_helper_dcxo_oe").eq(1)
]
self.submodules.wrpll_sampler = DDMTDSamplerGTP(
self.drtio_transceiver,
platform.request("cdr_clk_clean_fabric"))
self.submodules.wrpll = WRPLL(
helper_clk_pads=platform.request("ddmtd_helper_clk"),
main_dcxo_i2c=platform.request("ddmtd_main_dcxo_i2c"),
helper_dxco_i2c=platform.request("ddmtd_helper_dcxo_i2c"),
ddmtd_inputs=self.wrpll_sampler)
self.csr_devices.append("wrpll")
else:
self.comb += platform.request("filtered_clk_sel").eq(1) self.comb += platform.request("filtered_clk_sel").eq(1)
self.submodules.siphaser = SiPhaser7Series( self.submodules.siphaser = SiPhaser7Series(
si5324_clkin=platform.request("si5324_clkin"), si5324_clkin=platform.request("si5324_clkin"),
@ -245,10 +262,12 @@ def main():
soc_sayma_rtm_args(parser) soc_sayma_rtm_args(parser)
parser.add_argument("--rtio-clk-freq", parser.add_argument("--rtio-clk-freq",
default=150, type=int, help="RTIO clock frequency in MHz") default=150, type=int, help="RTIO clock frequency in MHz")
parser.add_argument("--with-wrpll", default=False, action="store_true")
parser.set_defaults(output_dir=os.path.join("artiq_sayma", "rtm")) parser.set_defaults(output_dir=os.path.join("artiq_sayma", "rtm"))
args = parser.parse_args() args = parser.parse_args()
soc = Satellite(rtio_clk_freq=1e6*args.rtio_clk_freq, soc = Satellite(
rtio_clk_freq=1e6*args.rtio_clk_freq, with_wrpll=args.with_wrpll,
**soc_sayma_rtm_argdict(args)) **soc_sayma_rtm_argdict(args))
builder = SatmanSoCBuilder(soc, **builder_argdict(args)) builder = SatmanSoCBuilder(soc, **builder_argdict(args))
try: try: