Created
November 30, 2021 15:04
-
-
Save enjoy-digital/cd9ea52fafaebe016e739a90983eb237 to your computer and use it in GitHub Desktop.
LiteJESD204B integration example on Xilinx 7-Series.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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