Skip to content

Instantly share code, notes, and snippets.

@enjoy-digital
Created November 30, 2021 15:04
Show Gist options
  • Save enjoy-digital/cd9ea52fafaebe016e739a90983eb237 to your computer and use it in GitHub Desktop.
Save enjoy-digital/cd9ea52fafaebe016e739a90983eb237 to your computer and use it in GitHub Desktop.
LiteJESD204B integration example on Xilinx 7-Series.
from functools import reduce
from operator import and_
from migen import *
from migen.genlib.resetsync import AsyncResetSynchronizer
from litex.build.io import DifferentialInput
from litex.soc.cores.clock import S7MMCM
from liteiclink.transceiver.gtp_7series import GTPQuadPLL, GTP
from liteiclink.transceiver.gtx_7series import GTXQuadPLL, GTX
from litejesd204b.common import *
from litejesd204b.core import LiteJESD204BCoreTX
from litejesd204b.core import LiteJESD204BCoreRX
from litejesd204b.core import LiteJESD204BCoreControl
# [...]
ad937x_phy = "gtx"
ad937x_phy_tx_order = [0, 1, 2, 3]
ad937x_phy_rx_order = [0, 1, 2, 3]
ad937x_refclk_freq = 122.88e6
ad937x_jesd_linerate = 2.4576e9
# JESD Configuration -----------------------------------------------------------------------
jesd_lanes = len(ad937x_phy_tx_order)
# 2 lanes / 4 converters / (4.9152Gbps linerate : IQ rate 61.44MSPS)
if jesd_lanes == 2:
ps_tx = JESD204BPhysicalSettings(l=2, m=4, n=16, np=16)
ts_tx = JESD204BTransportSettings(f=4, s=1, k=32, cs=0)
settings_tx = JESD204BSettings(ps_tx, ts_tx, did=0x5a, bid=0x5, framing=framing, scrambling=scrambling)
ps_rx = JESD204BPhysicalSettings(l=2, m=4, n=16, np=16)
ts_rx = JESD204BTransportSettings(f=4, s=1, k=32, cs=0)
settings_rx = JESD204BSettings(ps_rx, ts_rx, did=0x5a, bid=0x5, framing=framing, scrambling=scrambling)
# 4 lanes / 4 converters / (2.4576Gbps linerate : IQ rate 122.88MSPS)
elif jesd_lanes == 4:
ps_tx = JESD204BPhysicalSettings(l=4, m=4, n=16, np=16)
ts_tx = JESD204BTransportSettings(f=2, s=1, k=32, cs=0)
settings_tx = JESD204BSettings(ps_tx, ts_tx, did=0x5a, bid=0x5, framing=framing, scrambling=scrambling)
ps_rx = JESD204BPhysicalSettings(l=4, m=4, n=16, np=16)
ts_rx = JESD204BTransportSettings(f=2, s=1, k=32, cs=0)
settings_rx = JESD204BSettings(ps_rx, ts_rx, did=0x5a, bid=0x5, framing=framing, scrambling=scrambling)
else:
raise NotImplementedError
# JESD Clocking (Device) -------------------------------------------------------------------
userclk_freq = ad937x_jesd_linerate/40
self.clock_domains.cd_jesd_122_88 = ClockDomain()
self.clock_domains.cd_jesd_61_44 = ClockDomain()
self.clock_domains.cd_jesd = ClockDomain()
self.clock_domains.cd_clk122_88 = ClockDomain()
refclk_pads = platform.request("ad937x_refclk")
refclk = Signal()
refclk_div2 = Signal()
self.specials += Instance("IBUFDS_GTE2",
i_CEB = 0,
i_I = refclk_pads.p,
i_IB = refclk_pads.n,
o_O = refclk,
o_ODIV2 = refclk_div2)
self.submodules.pll = pll = S7MMCM(speedgrade=-2)
pll.register_clkin(refclk_div2, ad937x_refclk_freq/2)
pll.create_clkout(self.cd_jesd_122_88, userclk_freq, buf=None, with_reset=False)
pll.create_clkout(self.cd_jesd_61_44, userclk_freq/2, buf=None, with_reset=False)
pll.create_clkout(self.cd_clk122_88, 122.88e6, with_reset=False)
self.specials += Instance("BUFGMUX",
i_S = self._speed.storage,
i_I0 = ClockSignal("jesd_122_88"),
i_I1 = ClockSignal("jesd_61_44"),
o_O = ClockSignal("jesd")
)
platform.add_period_constraint(refclk_div2, 1e9/(ad937x_refclk_freq/2))
# JESD Clocking (SYSREF) -------------------------------------------------------------------
self.sysref = sysref = Signal()
sysref_pads = platform.request("ad937x_sysref")
self.specials += DifferentialInput(sysref_pads.p, sysref_pads.n, sysref)
# JESD PHYs --------------------------------------------------------------------------------
jesd_pll_cls = {
"gtx": GTXQuadPLL,
"gtp": GTPQuadPLL,
}[ad937x_phy]
jesd_phy_cls = {
"gtx": GTX,
"gtp": GTP,
}[ad937x_phy]
jesd_phy_data_width = {
"gtx": 20,
"gtp": 20,
}[ad937x_phy]
jesd_pll = jesd_pll_cls(refclk, ad937x_refclk_freq, ad937x_jesd_linerate)
self.submodules += jesd_pll
#print(jesd_pll)
self.jesd_phys = jesd_phys = []
for i in range(jesd_lanes):
jesd_tx_pads = platform.request("ad937x_jesd_tx", i)
jesd_rx_pads = platform.request("ad937x_jesd_rx", i)
jesd_phy = jesd_phy_cls(jesd_pll, jesd_tx_pads, jesd_rx_pads, sys_clk_freq,
data_width = jesd_phy_data_width,
clock_aligner = False,
tx_buffer_enable = True,
rx_buffer_enable = True)
jesd_phy.add_stream_endpoints()
jesd_phy.add_controls(auto_enable=False)
jesd_phy.n = i
setattr(self.submodules, "jesd_phy" + str(i), jesd_phy)
platform.add_period_constraint(jesd_phy.cd_tx.clk, 1e9/jesd_phy.tx_clk_freq)
platform.add_period_constraint(jesd_phy.cd_rx.clk, 1e9/jesd_phy.rx_clk_freq)
platform.add_false_path_constraints(
soc.crg.cd_sys.clk,
self.cd_jesd.clk,
jesd_phy.cd_tx.clk,
jesd_phy.cd_rx.clk)
jesd_phys.append(jesd_phy)
jesd_phys_tx_init_done = reduce(and_, [phy.tx_init.done for phy in jesd_phys])
jesd_phys_rx_init_done = reduce(and_, [phy.rx_init.done for phy in jesd_phys])
self.specials += AsyncResetSynchronizer(self.cd_jesd, ~(jesd_phys_tx_init_done & jesd_phys_rx_init_done))
jesd_phys_tx = [jesd_phys[n] for n in ad937x_phy_tx_order]
jesd_phys_rx = [jesd_phys[n] for n in ad937x_phy_rx_order]
# JESD TX ----------------------------------------------------------------------------------
self.submodules.jesd_tx_core = LiteJESD204BCoreTX(jesd_phys_tx, settings_tx,
converter_data_width = jesd_lanes*8,
scrambling = scrambling,
stpl_random = stpl_random)
self.submodules.jesd_tx_control = LiteJESD204BCoreControl(self.jesd_tx_core, sys_clk_freq)
self.jesd_tx_core.register_jsync(platform.request("ad937x_sync_tx"))
self.jesd_tx_core.register_jref(sysref)
# JESD RX ----------------------------------------------------------------------------------
self.submodules.jesd_rx_core = LiteJESD204BCoreRX(jesd_phys_rx, settings_rx,
converter_data_width = jesd_lanes*8,
scrambling = scrambling,
stpl_random = stpl_random)
self.submodules.jesd_rx_control = LiteJESD204BCoreControl(self.jesd_rx_core, sys_clk_freq)
self.jesd_rx_core.register_jsync(platform.request("ad937x_sync_rx"))
self.jesd_rx_core.register_jref(sysref)
# JESD Link Status ------------------------------------------------------------------------------
self.jesd_link_status = Signal()
self.comb += self.jesd_link_status.eq(
(self.jesd_tx_core.enable & self.jesd_tx_core.jsync) &
(self.jesd_rx_core.enable & self.jesd_rx_core.jsync))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment