sayma: add SYSREF sampler gateware

This commit is contained in:
Sebastien Bourdeauducq 2018-06-20 17:42:04 +08:00
parent 814d0583db
commit 28fb0fd754
2 changed files with 123 additions and 82 deletions

View 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)

View File

@ -2,11 +2,9 @@
import argparse import argparse
import os import os
from collections import namedtuple
import warnings import warnings
from migen import * from migen import *
from migen.genlib.resetsync import AsyncResetSynchronizer
from misoc.cores import gpio from misoc.cores import gpio
from misoc.integration.soc_sdram import soc_sdram_args, soc_sdram_argdict 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.interconnect.csr import *
from misoc.targets.sayma_amc import BaseSoC, MiniSoC 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.amp import AMPSoC
from artiq.gateware import serwb from artiq.gateware import serwb
from artiq.gateware import remote_csr from artiq.gateware import remote_csr
from artiq.gateware import rtio from artiq.gateware import rtio
from artiq.gateware import jesd204_tools
from artiq.gateware.rtio.phy import ttl_simple, sawg from artiq.gateware.rtio.phy import ttl_simple, 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
@ -35,77 +26,10 @@ from artiq.build_soc import build_artiq_soc
from artiq import __version__ as artiq_version 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): class AD9154(Module, AutoCSR):
def __init__(self, platform, sys_crg, jesd_crg, dac): 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.sawgs = [sawg.Channel(width=16, parallelism=4) for i in range(4)]
self.submodules += self.sawgs self.submodules += self.sawgs
@ -117,7 +41,8 @@ class AD9154(Module, AutoCSR):
class AD9154NoSAWG(Module, AutoCSR): class AD9154NoSAWG(Module, AutoCSR):
def __init__(self, platform, sys_crg, jesd_crg, dac): 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 = [] self.sawgs = []
@ -231,7 +156,7 @@ class Standalone(MiniSoC, AMPSoC, RTMCommon):
self.submodules += phy self.submodules += phy
rtio_channels.append(rtio.Channel.from_phy(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: if with_sawg:
cls = AD9154 cls = AD9154
else: else:
@ -276,6 +201,10 @@ class Standalone(MiniSoC, AMPSoC, RTMCommon):
self.get_native_sdram_if()) self.get_native_sdram_if())
self.csr_devices.append("rtio_analyzer") 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): class Master(MiniSoC, AMPSoC, RTMCommon):
mem_map = { mem_map = {
@ -433,7 +362,8 @@ class Satellite(BaseSoC, RTMCommon):
self.submodules += phy self.submodules += phy
rtio_channels.append(rtio.Channel.from_phy(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: if with_sawg:
cls = AD9154 cls = AD9154
else: else:
@ -491,6 +421,10 @@ class Satellite(BaseSoC, RTMCommon):
self.config["I2C_BUS_COUNT"] = 1 self.config["I2C_BUS_COUNT"] = 1
self.config["HAS_SI5324"] = None 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 rtio_clk_period = 1e9/rtio_clk_freq
gth = self.drtio_transceiver.gths[0] gth = self.drtio_transceiver.gths[0]
platform.add_period_constraint(gth.txoutclk, rtio_clk_period) platform.add_period_constraint(gth.txoutclk, rtio_clk_period)