Using externally generated converter profiles

External device tools are often the source of truth for a converter datapath. pyadi-jif can reuse that information to solve the clocks and FPGA transceiver configuration around the converter, but the import process differs between AD9084 and ADRV9009.

Important

pyadi-jif models and validates clocking and JESD204 constraints. It does not program the converter. Keep the generated device profile with the software or device-tree configuration that loads it into the hardware.

Workflow overview

  1. Generate and validate the device profile in the vendor tool.

  2. Export the profile artifacts.

  3. Transfer the converter sample rates, datapath factors, and JESD204 parameters into pyadi-jif:

    • AD9084 profiles can be imported directly from the full JSON file.

    • ADRV9009 TES profiles must currently be mapped to pyadi-jif parameters.

  4. Configure the FPGA board and any external PLL topology.

  5. Solve the pyadi-jif system.

  6. Compare the solved lane rates, reference clocks, SYSREF, and JESD parameters with the generated profile before building or programming the hardware.

AD9084 Apollo profiles

Use the AD9084 (Apollo) Profile Generator supplied with the Apollo plugin for ACE to create and validate the device configuration. The generator’s output directory contains:

  • a full .json profile;

  • a _summary.json description;

  • a .bin profile for loading into the AD9084.

Pass the full JSON profile to pyadi-jif. Do not pass the summary JSON or binary file. The binary remains the artifact loaded by the device software.

Import and solve

The following example models an AD9084 RX path whose device clock is generated by an ADF4382 and whose SYSREF is generated by an ADF4030:

from pathlib import Path

import adijif

profile_json = Path("profiles/my_ad9084_profile.json")
vcxo = 125_000_000

system = adijif.system(
    "ad9084_rx", "hmc7044", "xilinx", vcxo, solver="CPLEX"
)
system.converter.apply_profile_settings(str(profile_json))
system.fpga.setup_by_dev_kit_name("vcu118")

system.converter.clocking_option = "direct"
system.add_pll_inline("adf4382", vcxo, system.converter)
system.add_pll_sysref("adf4030", vcxo, system.converter, system.fpga)

config = system.solve()

print(f"sample rate: {system.converter.sample_clock / 1e9:.6f} GSPS")
print(f"lane rate: {system.converter.bit_clock / 1e9:.6f} Gb/s")
print(
    "JESD: "
    f"{system.converter.jesd_class}, "
    f"M={system.converter.M}, L={system.converter.L}, "
    f"S={system.converter.S}, Np={system.converter.Np}"
)

Use "ad9084_tx" for a TX-only model or "ad9084" for the combined RX/TX model. Applying a profile to the combined model configures both system.converter.adc and system.converter.dac.

apply_profile_settings() extracts and applies:

  • the AD9084 device clock;

  • RX CDDC and FDDC decimation;

  • TX CDUC and FDUC interpolation;

  • sample rates;

  • JESD204 class and M, L, S, and Np parameters.

The importer currently validates Apollo profile schema version 9.1.0. A different version raises an error before settings are applied. bypass_version_check=True is available for development, but should only be used after confirming that the exported JSON has a schema compatible with the parser; bypassing the check does not translate a changed schema.

Validate the result

Before using the solved configuration, compare these values with the profile generator:

converter = system.converter
converter._check_clock_relations()

assert converter.bit_clock <= converter.bit_clock_max
assert config["clock"]["output_clocks"]

In particular, check the device clock, baseband sample rate, lane rate, JESD204 class, lane count, converter count, samples per frame, and sample width. A mismatch usually means the wrong JSON artifact or converter direction was selected.

A complete repository example is available in examples/ad9084_rx_ebz_profile.py.

ADRV9009 TES profiles

ADRV9009 profiles are commonly generated with the Transceiver Evaluation Software (TES). pyadi-jif can load a TES profile file directly using the apply_profile_settings method.

Since the TES profile contains RF and digital-filter settings but does not explicitly contain the JESD204 link parameters (M, L, S, Np), you must pass the desired JESD configuration parameters as dictionaries (rx_jesd and tx_jesd for combined, or jesd for individual RX/TX components) when loading the profile.

Values mapped from profile

Applying a profile extracts and maps the following values automatically:

Profile information

pyadi-jif setting

RX output rate (rxOutputRate_kHz)

system.converter.adc.sample_clock in Hz

Product of enabled RX decimation stages (rxFirDecimation × rxDec5Decimation × rhb1Decimation)

system.converter.adc.decimation

TX input rate (txInputRate_kHz)

system.converter.dac.sample_clock in Hz

Product of enabled TX interpolation stages (txFirInterpolation × thb1Interpolation × thb2Interpolation × thb3Interpolation × txInt5Interpolation)

system.converter.dac.interpolation

Configure and solve

import adijif

vcxo = 122_880_000
system = adijif.system("adrv9009", "ad9528", "xilinx", vcxo=vcxo)
system.fpga.setup_by_dev_kit_name("zcu102")
system.fpga.force_qpll = True

# Load and configure from external TES profile path
profile_path = "path/to/Tx_BW200_IR245p76_Rx_BW100_OR122p88_ORx_BW200_OR245p76_DC245p76.txt"
system.converter.apply_profile_settings(
    profile_path,
    rx_jesd={"M": 4, "L": 2, "S": 1, "Np": 16},
    tx_jesd={"M": 4, "L": 4, "S": 1, "Np": 16}
)

config = system.solve()

print(f"RX lane rate: {system.converter.adc.bit_clock / 1e9:.6f} Gb/s")
print(f"TX lane rate: {system.converter.dac.bit_clock / 1e9:.6f} Gb/s")

The corresponding repository example, including the mapping from device-tree profile fields to total decimation and interpolation, is examples/adrv9009_pcbz_example.py.

Final consistency checklist

Before carrying the result into HDL, device tree, or board software, verify that the external profile and pyadi-jif agree on:

  • RX and TX sample rates;

  • total decimation and interpolation;

  • JESD204B or JESD204C encoding;

  • M, L, S, and Np for every link;

  • lane rates and FPGA transceiver limits;

  • converter device/reference clocks;

  • FPGA reference clock;

  • SYSREF frequency and topology.

The generated device profile and pyadi-jif solution serve different purposes. The profile configures the converter; the pyadi-jif result configures and validates the surrounding clock tree and FPGA interface. Keep both artifacts under version control so the complete hardware configuration remains reproducible.