forked from M-Labs/artiq
sayma: use QPLL for 1GSPS JESD204B TX
* requires jesd204b changes as in https://github.com/HarryMakes/jesd204b/tree/gth
This commit is contained in:
parent
b5405dfad6
commit
400af2c582
@ -87,7 +87,7 @@ const JESD_SETTINGS: JESDSettings = JESDSettings {
|
||||
np: 16,
|
||||
f: 2,
|
||||
s: 2,
|
||||
k: 16,
|
||||
k: 32,
|
||||
cs: 0,
|
||||
|
||||
subclassv: 1,
|
||||
@ -349,6 +349,28 @@ pub fn setup(dacno: u8, linerate: u64) -> Result<(), &'static str> {
|
||||
write(ad9154_reg::GENERAL_JRX_CTRL_0,
|
||||
0x1*ad9154_reg::LINK_EN | 0*ad9154_reg::LINK_PAGE |
|
||||
0*ad9154_reg::LINK_MODE | 0*ad9154_reg::CHECKSUM_MODE);
|
||||
|
||||
// JESD Checks
|
||||
let jesd_checks = read(ad9154_reg::JESD_CHECKS);
|
||||
if jesd_checks & ad9154_reg::ERR_DLYOVER == ad9154_reg::ERR_DLYOVER {
|
||||
error!("LMFC_Delay > JESD_K Parameter")
|
||||
}
|
||||
if jesd_checks & ad9154_reg::ERR_WINLIMIT == ad9154_reg::ERR_WINLIMIT {
|
||||
error!("Unsupported Window Limit")
|
||||
}
|
||||
if jesd_checks & ad9154_reg::ERR_JESDBAD == ad9154_reg::ERR_JESDBAD {
|
||||
error!("Unsupported M/L/S/F Selection")
|
||||
}
|
||||
if jesd_checks & ad9154_reg::ERR_KUNSUPP == ad9154_reg::ERR_KUNSUPP {
|
||||
error!("Unsupported K Values")
|
||||
}
|
||||
if jesd_checks & ad9154_reg::ERR_SUBCLASS == ad9154_reg::ERR_SUBCLASS {
|
||||
error!("Unsupported SUBCLASSV Value")
|
||||
}
|
||||
if jesd_checks & ad9154_reg::ERR_INTSUPP == ad9154_reg::ERR_INTSUPP {
|
||||
error!("Unsupported Interpolation Factor")
|
||||
}
|
||||
|
||||
info!(" ...done");
|
||||
Ok(())
|
||||
}
|
||||
|
@ -8,7 +8,11 @@ from misoc.interconnect.csr import *
|
||||
from jesd204b.common import (JESD204BTransportSettings,
|
||||
JESD204BPhysicalSettings,
|
||||
JESD204BSettings)
|
||||
from jesd204b.phy.gth import GTHChannelPLL as JESD204BGTHChannelPLL
|
||||
from jesd204b.phy.gth import (GTHChannelPLL as JESD204BGTHChannelPLL,
|
||||
GTHQuadPLL as JESD204BGTHQuadPLL,
|
||||
GTHTransmitter as JESD204BGTHTransmitter,
|
||||
GTHInit as JESD204BGTHInit,
|
||||
GTHTransmitterInterconnect as JESD204BGTHTransmitterInterconnect)
|
||||
from jesd204b.phy import JESD204BPhyTX
|
||||
from jesd204b.core import JESD204BCoreTX
|
||||
from jesd204b.core import JESD204BCoreTXControl
|
||||
@ -16,6 +20,7 @@ from jesd204b.core import JESD204BCoreTXControl
|
||||
|
||||
class UltrascaleCRG(Module, AutoCSR):
|
||||
linerate = int(10e9) # linerate = 20*data_rate*4/8 = data_rate*10
|
||||
# data_rate = dac_rate/interp_factor
|
||||
refclk_freq = int(250e6)
|
||||
fabric_freq = int(125e6)
|
||||
|
||||
@ -41,30 +46,99 @@ PhyPads = namedtuple("PhyPads", "txp txn")
|
||||
|
||||
|
||||
class UltrascaleTX(Module, AutoCSR):
|
||||
def __init__(self, platform, sys_crg, jesd_crg, dac):
|
||||
def __init__(self, platform, sys_crg, jesd_crg, dac, pll_type="cpll", tx_half=False):
|
||||
# Note: In general, the choice between channel and quad PLLs can be made based on the "nominal operating ranges", which are (see UG576, Ch.2):
|
||||
# CPLL: 2.0 - 6.25 GHz
|
||||
# QPLL0: 9.8 - 16.375 GHz
|
||||
# QPLL1: 8.0 - 13.0 GHz
|
||||
# However, the exact frequency and/or linerate range should be checked according to the model and speed grade from their corresponding datasheets.
|
||||
pll_cls = {
|
||||
"cpll": JESD204BGTHChannelPLL,
|
||||
"qpll": JESD204BGTHQuadPLL
|
||||
}[pll_type]
|
||||
ps = JESD204BPhysicalSettings(l=8, m=4, n=16, np=16)
|
||||
ts = JESD204BTransportSettings(f=2, s=2, k=16, cs=0)
|
||||
ts = JESD204BTransportSettings(f=2, s=2, k=32, cs=0)
|
||||
settings = JESD204BSettings(ps, ts, did=0x5a, bid=0x5)
|
||||
|
||||
jesd_pads = platform.request("dac_jesd", dac)
|
||||
plls = []
|
||||
phys = []
|
||||
for i in range(len(jesd_pads.txp)):
|
||||
cpll = JESD204BGTHChannelPLL(
|
||||
jesd_crg.refclk, jesd_crg.refclk_freq, jesd_crg.linerate)
|
||||
self.submodules += cpll
|
||||
pll = pll_cls(
|
||||
jesd_crg.refclk, jesd_crg.refclk_freq, jesd_crg.linerate)
|
||||
self.submodules += pll
|
||||
plls.append(pll)
|
||||
# QPLL quads
|
||||
if pll_type == "qpll":
|
||||
gthe3_common_cfgs = []
|
||||
for i in range(0, len(plls), 4):
|
||||
# GTHE3_COMMON common signals
|
||||
qpll_clk = Signal()
|
||||
qpll_refclk = Signal()
|
||||
qpll_reset = Signal()
|
||||
qpll_lock = Signal()
|
||||
# GTHE3_COMMON
|
||||
self.specials += pll_cls.get_gthe3_common(
|
||||
jesd_crg.refclk, jesd_crg.refclk_freq, jesd_crg.linerate,
|
||||
qpll_clk, qpll_refclk, qpll_reset, qpll_lock)
|
||||
gthe3_common_cfgs.append({
|
||||
"clk": qpll_clk,
|
||||
"refclk": qpll_refclk,
|
||||
"reset": qpll_reset,
|
||||
"lock": qpll_lock
|
||||
})
|
||||
# Per-channel PLL phys
|
||||
for i, pll in enumerate(plls):
|
||||
# PhyTX
|
||||
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)
|
||||
pll, jesd_crg.refclk, PhyPads(jesd_pads.txp[i], jesd_pads.txn[i]),
|
||||
jesd_crg.fabric_freq, transceiver="gth", tx_half=tx_half)
|
||||
phys.append(phy)
|
||||
if tx_half:
|
||||
platform.add_period_constraint(phy.transmitter.cd_tx_half.clk,
|
||||
80*1e9/jesd_crg.linerate)
|
||||
platform.add_false_path_constraints(
|
||||
sys_crg.cd_sys.clk,
|
||||
jesd_crg.cd_jesd.clk,
|
||||
phy.transmitter.cd_tx_half.clk)
|
||||
else:
|
||||
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)
|
||||
# CHANNEL & init interconnects
|
||||
for i, (pll, phy) in enumerate(zip(plls, phys)):
|
||||
# CPLLs: 1 init per channel
|
||||
if pll_type == "cpll":
|
||||
phy_channel_cfg = {}
|
||||
# Connect reset/lock to init
|
||||
pll_reset = pll.reset
|
||||
pll_lock = pll.lock
|
||||
self.submodules += JESD204BGTHTransmitterInterconnect(
|
||||
pll_reset, pll_lock, phy.transmitter, phy.transmitter.init)
|
||||
# QPLL: 4 inits and 4 channels per quad
|
||||
elif pll_type == "qpll":
|
||||
# Connect clk/refclk to CHANNEL
|
||||
phy_cfg = gthe3_common_cfgs[int(i//4)]
|
||||
phy_channel_cfg = {
|
||||
"qpll_clk": phy_cfg["clk"],
|
||||
"qpll_refclk": phy_cfg["refclk"]
|
||||
}
|
||||
# Connect reset/lock to init
|
||||
pll_reset = phy_cfg["reset"]
|
||||
pll_lock = phy_cfg["lock"]
|
||||
if i % 4 == 0:
|
||||
self.submodules += JESD204BGTHTransmitterInterconnect(
|
||||
pll_reset, pll_lock, phy.transmitter,
|
||||
[phys[j].transmitter.init for j in range(i, min(len(phys), i+4))])
|
||||
# GTHE3_CHANNEL
|
||||
self.specials += JESD204BGTHTransmitter.get_gthe3_channel(
|
||||
pll, phy.transmitter, **phy_channel_cfg)
|
||||
|
||||
self.submodules.core = JESD204BCoreTX(
|
||||
phys, settings, converter_data_width=128)
|
||||
phys, settings, converter_data_width=128, tx_half=tx_half)
|
||||
self.submodules.control = JESD204BCoreTXControl(self.core)
|
||||
self.core.register_jsync(platform.request("dac_sync", dac))
|
||||
|
||||
@ -111,7 +185,7 @@ class DDMTD(Module, AutoCSR):
|
||||
i_RST=self.reset.storage,
|
||||
o_LOCKED=helper_locked,
|
||||
|
||||
# VCO at 1200MHz with 150MHz RTIO frequency
|
||||
# VCO at 1000MHz/1200MHz with 125MHz/150MHz RTIO frequency
|
||||
p_CLKFBOUT_MULT_F=8.0,
|
||||
p_DIVCLK_DIVIDE=1,
|
||||
|
||||
|
@ -190,8 +190,10 @@ class SatelliteBase(MiniSoC):
|
||||
# JESD204 DAC Channel Group
|
||||
class JDCGSAWG(Module, AutoCSR):
|
||||
def __init__(self, platform, sys_crg, jesd_crg, dac):
|
||||
# Kintex Ultrascale GTH, speed grade -1C:
|
||||
# QPLL0 linerate (D=1): 9.8 - 12.5 Gb/s
|
||||
self.submodules.jesd = jesd204_tools.UltrascaleTX(
|
||||
platform, sys_crg, jesd_crg, dac)
|
||||
platform, sys_crg, jesd_crg, dac, pll_type="qpll", tx_half=True)
|
||||
|
||||
self.submodules.sawgs = [sawg.Channel(width=16, parallelism=8) for i in range(4)]
|
||||
|
||||
@ -203,7 +205,7 @@ class JDCGSAWG(Module, AutoCSR):
|
||||
class JDCGPattern(Module, AutoCSR):
|
||||
def __init__(self, platform, sys_crg, jesd_crg, dac):
|
||||
self.submodules.jesd = jesd204_tools.UltrascaleTX(
|
||||
platform, sys_crg, jesd_crg, dac)
|
||||
platform, sys_crg, jesd_crg, dac, pll_type="qpll", tx_half=True)
|
||||
|
||||
self.sawgs = []
|
||||
|
||||
@ -243,7 +245,7 @@ class JDCGPattern(Module, AutoCSR):
|
||||
class JDCGSyncDDS(Module, AutoCSR):
|
||||
def __init__(self, platform, sys_crg, jesd_crg, dac):
|
||||
self.submodules.jesd = jesd204_tools.UltrascaleTX(
|
||||
platform, sys_crg, jesd_crg, dac)
|
||||
platform, sys_crg, jesd_crg, dac, pll_type="qpll", tx_half=True)
|
||||
self.coarse_ts = Signal(32)
|
||||
|
||||
self.sawgs = []
|
||||
|
Loading…
Reference in New Issue
Block a user