forked from M-Labs/artiq
sayma: add SYSREF sampler gateware
This commit is contained in:
parent
814d0583db
commit
28fb0fd754
107
artiq/gateware/jesd204_tools.py
Normal file
107
artiq/gateware/jesd204_tools.py
Normal file
@ -0,0 +1,107 @@
|
||||
from collections import namedtuple
|
||||
|
||||
from migen import *
|
||||
from migen.genlib.cdc import MultiReg
|
||||
from migen.genlib.resetsync import AsyncResetSynchronizer
|
||||
from misoc.interconnect.csr import *
|
||||
|
||||
from jesd204b.common import (JESD204BTransportSettings,
|
||||
JESD204BPhysicalSettings,
|
||||
JESD204BSettings)
|
||||
from jesd204b.phy.gth import GTHChannelPLL as JESD204BGTHChannelPLL
|
||||
from jesd204b.phy import JESD204BPhyTX
|
||||
from jesd204b.core import JESD204BCoreTX
|
||||
from jesd204b.core import JESD204BCoreTXControl
|
||||
|
||||
|
||||
class UltrascaleCRG(Module, AutoCSR):
|
||||
linerate = int(6e9)
|
||||
refclk_freq = int(150e6)
|
||||
fabric_freq = int(125e6)
|
||||
|
||||
def __init__(self, platform, use_rtio_clock=False):
|
||||
self.jreset = CSRStorage(reset=1)
|
||||
self.jref = Signal()
|
||||
self.refclk = Signal()
|
||||
self.clock_domains.cd_jesd = ClockDomain()
|
||||
|
||||
refclk2 = Signal()
|
||||
refclk_pads = platform.request("dac_refclk", 0)
|
||||
platform.add_period_constraint(refclk_pads.p, 1e9/self.refclk_freq)
|
||||
self.specials += [
|
||||
Instance("IBUFDS_GTE3", i_CEB=self.jreset.storage, p_REFCLK_HROW_CK_SEL=0b00,
|
||||
i_I=refclk_pads.p, i_IB=refclk_pads.n,
|
||||
o_O=self.refclk, o_ODIV2=refclk2),
|
||||
AsyncResetSynchronizer(self.cd_jesd, self.jreset.storage),
|
||||
]
|
||||
|
||||
if use_rtio_clock:
|
||||
self.comb += self.cd_jesd.clk.eq(ClockSignal("rtio"))
|
||||
else:
|
||||
self.specials += Instance("BUFG_GT", i_I=refclk2, o_O=self.cd_jesd.clk)
|
||||
|
||||
jref = platform.request("dac_sysref")
|
||||
jref_se = Signal()
|
||||
self.specials += [
|
||||
Instance("IBUFDS_IBUFDISABLE",
|
||||
p_USE_IBUFDISABLE="TRUE", p_SIM_DEVICE="ULTRASCALE",
|
||||
i_IBUFDISABLE=self.jreset.storage,
|
||||
i_I=jref.p, i_IB=jref.n,
|
||||
o_O=jref_se),
|
||||
# SYSREF normally meets s/h at the FPGA, except during margin
|
||||
# scan. Be paranoid and use a double-register anyway.
|
||||
MultiReg(jref_se, self.jref, "jesd")
|
||||
]
|
||||
|
||||
|
||||
PhyPads = namedtuple("PhyPads", "txp txn")
|
||||
|
||||
|
||||
class UltrascaleTX(Module, AutoCSR):
|
||||
def __init__(self, platform, sys_crg, jesd_crg, dac):
|
||||
ps = JESD204BPhysicalSettings(l=8, m=4, n=16, np=16)
|
||||
ts = JESD204BTransportSettings(f=2, s=2, k=16, cs=0)
|
||||
settings = JESD204BSettings(ps, ts, did=0x5a, bid=0x5)
|
||||
|
||||
jesd_pads = platform.request("dac_jesd", dac)
|
||||
phys = []
|
||||
for i in range(len(jesd_pads.txp)):
|
||||
cpll = JESD204BGTHChannelPLL(
|
||||
jesd_crg.refclk, jesd_crg.refclk_freq, jesd_crg.linerate)
|
||||
self.submodules += cpll
|
||||
phy = JESD204BPhyTX(
|
||||
cpll, PhyPads(jesd_pads.txp[i], jesd_pads.txn[i]),
|
||||
jesd_crg.fabric_freq, transceiver="gth")
|
||||
platform.add_period_constraint(phy.transmitter.cd_tx.clk,
|
||||
40*1e9/jesd_crg.linerate)
|
||||
platform.add_false_path_constraints(
|
||||
sys_crg.cd_sys.clk,
|
||||
jesd_crg.cd_jesd.clk,
|
||||
phy.transmitter.cd_tx.clk)
|
||||
phys.append(phy)
|
||||
|
||||
to_jesd = ClockDomainsRenamer("jesd")
|
||||
self.submodules.core = core = to_jesd(JESD204BCoreTX(
|
||||
phys, settings, converter_data_width=64))
|
||||
self.submodules.control = control = to_jesd(JESD204BCoreTXControl(core))
|
||||
core.register_jsync(platform.request("dac_sync", dac))
|
||||
core.register_jref(jesd_crg.jref)
|
||||
|
||||
|
||||
# This assumes:
|
||||
# * coarse RTIO frequency = 16*SYSREF frequency
|
||||
# * JESD and coarse RTIO clocks are the same
|
||||
# (only reset may differ).
|
||||
# * SYSREF meets setup/hold at the FPGA when sampled
|
||||
# in the JESD/RTIO domain.
|
||||
#
|
||||
# Look at the 4 LSBs of the coarse RTIO timestamp counter
|
||||
# to determine SYSREF phase.
|
||||
|
||||
class SysrefSampler(Module, AutoCSR):
|
||||
def __init__(self, coarse_ts, jref):
|
||||
self.sample_result = CSRStatus()
|
||||
|
||||
sample = Signal()
|
||||
self.sync.rtio += If(coarse_ts[:4] == 0, sample.eq(jref))
|
||||
self.specials += MultiReg(sample, self.sample_result.status)
|
@ -2,11 +2,9 @@
|
||||
|
||||
import argparse
|
||||
import os
|
||||
from collections import namedtuple
|
||||
import warnings
|
||||
|
||||
from migen import *
|
||||
from migen.genlib.resetsync import AsyncResetSynchronizer
|
||||
|
||||
from misoc.cores import gpio
|
||||
from misoc.integration.soc_sdram import soc_sdram_args, soc_sdram_argdict
|
||||
@ -14,18 +12,11 @@ from misoc.integration.builder import builder_args, builder_argdict
|
||||
from misoc.interconnect.csr import *
|
||||
from misoc.targets.sayma_amc import BaseSoC, MiniSoC
|
||||
|
||||
from jesd204b.common import (JESD204BTransportSettings,
|
||||
JESD204BPhysicalSettings,
|
||||
JESD204BSettings)
|
||||
from jesd204b.phy.gth import GTHChannelPLL as JESD204BGTHChannelPLL
|
||||
from jesd204b.phy import JESD204BPhyTX
|
||||
from jesd204b.core import JESD204BCoreTX
|
||||
from jesd204b.core import JESD204BCoreTXControl
|
||||
|
||||
from artiq.gateware.amp import AMPSoC
|
||||
from artiq.gateware import serwb
|
||||
from artiq.gateware import remote_csr
|
||||
from artiq.gateware import rtio
|
||||
from artiq.gateware import jesd204_tools
|
||||
from artiq.gateware.rtio.phy import ttl_simple, sawg
|
||||
from artiq.gateware.drtio.transceiver import gth_ultrascale
|
||||
from artiq.gateware.drtio.siphaser import SiPhaser7Series
|
||||
@ -35,77 +26,10 @@ from artiq.build_soc import build_artiq_soc
|
||||
from artiq import __version__ as artiq_version
|
||||
|
||||
|
||||
PhyPads = namedtuple("PhyPads", "txp txn")
|
||||
to_jesd = ClockDomainsRenamer("jesd")
|
||||
|
||||
|
||||
class AD9154CRG(Module, AutoCSR):
|
||||
linerate = int(6e9)
|
||||
refclk_freq = int(150e6)
|
||||
fabric_freq = int(125e6)
|
||||
|
||||
def __init__(self, platform, use_rtio_clock=False):
|
||||
self.jreset = CSRStorage(reset=1)
|
||||
self.jref = Signal()
|
||||
self.refclk = Signal()
|
||||
self.clock_domains.cd_jesd = ClockDomain()
|
||||
|
||||
refclk2 = Signal()
|
||||
refclk_pads = platform.request("dac_refclk", 0)
|
||||
platform.add_period_constraint(refclk_pads.p, 1e9/self.refclk_freq)
|
||||
self.specials += [
|
||||
Instance("IBUFDS_GTE3", i_CEB=self.jreset.storage, p_REFCLK_HROW_CK_SEL=0b00,
|
||||
i_I=refclk_pads.p, i_IB=refclk_pads.n,
|
||||
o_O=self.refclk, o_ODIV2=refclk2),
|
||||
AsyncResetSynchronizer(self.cd_jesd, self.jreset.storage),
|
||||
]
|
||||
|
||||
if use_rtio_clock:
|
||||
self.comb += self.cd_jesd.clk.eq(ClockSignal("rtio"))
|
||||
else:
|
||||
self.specials += Instance("BUFG_GT", i_I=refclk2, o_O=self.cd_jesd.clk)
|
||||
|
||||
jref = platform.request("dac_sysref")
|
||||
self.specials += Instance("IBUFDS_IBUFDISABLE",
|
||||
p_USE_IBUFDISABLE="TRUE", p_SIM_DEVICE="ULTRASCALE",
|
||||
i_IBUFDISABLE=self.jreset.storage,
|
||||
i_I=jref.p, i_IB=jref.n,
|
||||
o_O=self.jref)
|
||||
|
||||
|
||||
class AD9154JESD(Module, AutoCSR):
|
||||
def __init__(self, platform, sys_crg, jesd_crg, dac):
|
||||
ps = JESD204BPhysicalSettings(l=8, m=4, n=16, np=16)
|
||||
ts = JESD204BTransportSettings(f=2, s=2, k=16, cs=0)
|
||||
settings = JESD204BSettings(ps, ts, did=0x5a, bid=0x5)
|
||||
|
||||
jesd_pads = platform.request("dac_jesd", dac)
|
||||
phys = []
|
||||
for i in range(len(jesd_pads.txp)):
|
||||
cpll = JESD204BGTHChannelPLL(
|
||||
jesd_crg.refclk, jesd_crg.refclk_freq, jesd_crg.linerate)
|
||||
self.submodules += cpll
|
||||
phy = JESD204BPhyTX(
|
||||
cpll, PhyPads(jesd_pads.txp[i], jesd_pads.txn[i]),
|
||||
jesd_crg.fabric_freq, transceiver="gth")
|
||||
platform.add_period_constraint(phy.transmitter.cd_tx.clk,
|
||||
40*1e9/jesd_crg.linerate)
|
||||
platform.add_false_path_constraints(
|
||||
sys_crg.cd_sys.clk,
|
||||
jesd_crg.cd_jesd.clk,
|
||||
phy.transmitter.cd_tx.clk)
|
||||
phys.append(phy)
|
||||
|
||||
self.submodules.core = core = to_jesd(JESD204BCoreTX(
|
||||
phys, settings, converter_data_width=64))
|
||||
self.submodules.control = control = to_jesd(JESD204BCoreTXControl(core))
|
||||
core.register_jsync(platform.request("dac_sync", dac))
|
||||
core.register_jref(jesd_crg.jref)
|
||||
|
||||
|
||||
class AD9154(Module, AutoCSR):
|
||||
def __init__(self, platform, sys_crg, jesd_crg, dac):
|
||||
self.submodules.jesd = AD9154JESD(platform, sys_crg, jesd_crg, dac)
|
||||
self.submodules.jesd = jesd204_tools.UltrascaleTX(
|
||||
platform, sys_crg, jesd_crg, dac)
|
||||
|
||||
self.sawgs = [sawg.Channel(width=16, parallelism=4) for i in range(4)]
|
||||
self.submodules += self.sawgs
|
||||
@ -117,7 +41,8 @@ class AD9154(Module, AutoCSR):
|
||||
|
||||
class AD9154NoSAWG(Module, AutoCSR):
|
||||
def __init__(self, platform, sys_crg, jesd_crg, dac):
|
||||
self.submodules.jesd = AD9154JESD(platform, sys_crg, jesd_crg, dac)
|
||||
self.submodules.jesd = jesd204_tools.UltrascaleTX(
|
||||
platform, sys_crg, jesd_crg, dac)
|
||||
|
||||
self.sawgs = []
|
||||
|
||||
@ -231,7 +156,7 @@ class Standalone(MiniSoC, AMPSoC, RTMCommon):
|
||||
self.submodules += phy
|
||||
rtio_channels.append(rtio.Channel.from_phy(phy))
|
||||
|
||||
self.submodules.ad9154_crg = AD9154CRG(platform)
|
||||
self.submodules.ad9154_crg = jesd204_tools.UltrascaleCRG(platform)
|
||||
if with_sawg:
|
||||
cls = AD9154
|
||||
else:
|
||||
@ -276,6 +201,10 @@ class Standalone(MiniSoC, AMPSoC, RTMCommon):
|
||||
self.get_native_sdram_if())
|
||||
self.csr_devices.append("rtio_analyzer")
|
||||
|
||||
self.submodules.sysref_sampler = jesd204_tools.SysrefSampler(
|
||||
self.rtio_core.coarse_ts, self.ad9154_crg.jref)
|
||||
self.csr_devices.append("sysref_sampler")
|
||||
|
||||
|
||||
class Master(MiniSoC, AMPSoC, RTMCommon):
|
||||
mem_map = {
|
||||
@ -433,7 +362,8 @@ class Satellite(BaseSoC, RTMCommon):
|
||||
self.submodules += phy
|
||||
rtio_channels.append(rtio.Channel.from_phy(phy))
|
||||
|
||||
self.submodules.ad9154_crg = AD9154CRG(platform, use_rtio_clock=True)
|
||||
self.submodules.ad9154_crg = jesd204_tools.UltrascaleCRG(
|
||||
platform, use_rtio_clock=True)
|
||||
if with_sawg:
|
||||
cls = AD9154
|
||||
else:
|
||||
@ -491,6 +421,10 @@ class Satellite(BaseSoC, RTMCommon):
|
||||
self.config["I2C_BUS_COUNT"] = 1
|
||||
self.config["HAS_SI5324"] = None
|
||||
|
||||
self.submodules.sysref_sampler = jesd204_tools.SysrefSampler(
|
||||
self.drtio0.coarse_ts, self.ad9154_crg.jref)
|
||||
self.csr_devices.append("sysref_sampler")
|
||||
|
||||
rtio_clk_period = 1e9/rtio_clk_freq
|
||||
gth = self.drtio_transceiver.gths[0]
|
||||
platform.add_period_constraint(gth.txoutclk, rtio_clk_period)
|
||||
|
Loading…
Reference in New Issue
Block a user