diff --git a/adijif/clocks/ad9528.py b/adijif/clocks/ad9528.py index 1da6b80..304d203 100644 --- a/adijif/clocks/ad9528.py +++ b/adijif/clocks/ad9528.py @@ -223,7 +223,12 @@ def b(self, value: Union[int, List[int]]) -> None: self._b = value @property - def vco(self): + def vco(self) -> float: + """VCO Frequency in Hz. + + Returns: + float: computed VCO frequency + """ r1 = self._get_val(self.config["r1"]) m1 = self._get_val(self.config["m1"]) n2 = self._get_val(self.config["n2"]) @@ -231,11 +236,11 @@ def vco(self): return self.vcxo / r1 * m1 * n2 @property - def sysref(self): - """SYSREF Frequency + def sysref(self) -> int: + """SYSREF Frequency in Hz. Returns: - float: computed sysref frequency + int: computed sysref frequency """ r1 = self._get_val(self.config["r1"]) k = self._get_val(self.config["k"]) @@ -248,7 +253,12 @@ def sysref(self): return sysref_src / (2 * k) @sysref.setter - def sysref(self, value: Union[int, float]): + def sysref(self, value: Union[int, float]) -> None: + """Set sysref frequency. + + Args: + value (int, float): Frequency + """ self._sysref = int(value) def get_config(self, solution: CpoSolveResult = None) -> Dict: @@ -385,7 +395,10 @@ def _get_clock_constraint( return self.vcxo / self.config["r1"] * self.config["n2"] / od def set_requested_clocks( - self, vcxo: int, out_freqs: List, clk_names: List[str], + self, + vcxo: int, + out_freqs: List, + clk_names: List[str], ) -> None: """Define necessary clocks to be generated in model. @@ -410,12 +423,10 @@ def set_requested_clocks( else: sysref_src = self.vcxo / self.config["r1"] - self._add_equation( - [sysref_src / (2 * self.config["k"]) == self._sysref] - ) + self._add_equation([sysref_src / (2 * self.config["k"]) == self._sysref]) # Add requested clocks to output constraints - for out_freq, name in zip(out_freqs, clk_names): + for out_freq, name in zip(out_freqs, clk_names): # noqa: B905 # od = self.model.Var(integer=True, lb=1, ub=256, value=1) od = self._convert_input(self._d, f"d_{name}_{out_freq}") # od = self.model.sos1([n*n for n in range(1,9)]) diff --git a/adijif/converters/ad9081.py b/adijif/converters/ad9081.py index d734117..d6a8889 100644 --- a/adijif/converters/ad9081.py +++ b/adijif/converters/ad9081.py @@ -349,13 +349,10 @@ def __init__( self.set_quick_configuration_mode("3.01", "jesd204b") def _converter_clock_config(self) -> None: - """RX specific configuration of internall PLL config. + """RX specific configuration of internal PLL config. This method will update the config struct to include the RX clocking constraints - - Raises: - Exception: If solver is not valid """ adc_clk = self.decimation * self.sample_clock self.config["l"] = self._convert_input([1, 2, 3, 4], "l") @@ -470,15 +467,10 @@ def _converter_clock_config(self) -> None: This method will update the config struct to include the TX clocking constraints - - Raises: - Exception: If solver is not valid """ dac_clk = self.interpolation * self.sample_clock self.config["dac_clk"] = self._convert_input(dac_clk) - self.config["converter_clk"] = self._add_intermediate( - self.config["dac_clk"] - ) + self.config["converter_clk"] = self._add_intermediate(self.config["dac_clk"]) class ad9081(ad9081_core): @@ -550,9 +542,7 @@ def _converter_clock_config(self) -> None: self.config["dac_clk"] = self._convert_input(dac_clk) self.config["adc_clk"] = self._convert_input(adc_clk) - self.config["converter_clk"] = self._add_intermediate( - self.config["dac_clk"] - ) + self.config["converter_clk"] = self._add_intermediate(self.config["dac_clk"]) # Add single PLL constraint # JESD204B/C transmitter is a power of 2 divisor of the lane rate of @@ -578,9 +568,6 @@ def get_required_clocks(self) -> List: Returns: List: List of solver variables, equations, and constants - - Raises: - Exception: If direct clocking is used. Not yet implemented """ # SYSREF self.config = {} diff --git a/adijif/converters/adrv9009.py b/adijif/converters/adrv9009.py index c506173..0e27eb6 100644 --- a/adijif/converters/adrv9009.py +++ b/adijif/converters/adrv9009.py @@ -4,9 +4,7 @@ import numpy as np -from adijif.common import core from adijif.converters.adrv9009_bf import adrv9009_bf -from adijif.gekko_trans import gekko_translation from ..solvers import CpoModel # type: ignore # noqa: I202,BLK100 from ..solvers import GEKKO, CpoSolveResult @@ -38,14 +36,14 @@ class adrv9009_core(converter, metaclass=ABCMeta): name = "ADRV9009" # JESD configurations - quick_configuration_modes = None # FIXME + quick_configuration_modes = None # FIXME available_jesd_modes = ["jesd204b"] M_available = [1, 2, 4] L_available = [1, 2, 3, 4, 6, 8] N_available = [12, 16] Np_available = [12, 16, 24] F_available = [1, 2, 3, 4, 8] - S_available = [1] # FIXME? + S_available = [1] # FIXME? K_available = [*np.arange(1, 32 + 1)] CS_available = [0] CF_available = [0] @@ -105,6 +103,7 @@ def get_config(self, solution: CpoSolveResult = None) -> Dict: self.solution = solution return {} + class adrv9009_clock_common(adrv9009_core, adrv9009_bf): """ADRV9009 class managing common singleton (Rx,Tx) methods.""" @@ -358,5 +357,8 @@ def get_required_clocks(self) -> List[Dict]: ] ) - return [self.config["device_clock"], self.config["sysref_adc"], - self.config["sysref_dac"]] + return [ + self.config["device_clock"], + self.config["sysref_adc"], + self.config["sysref_dac"], + ] diff --git a/adijif/jesd.py b/adijif/jesd.py index 794919a..8f0cb68 100644 --- a/adijif/jesd.py +++ b/adijif/jesd.py @@ -81,13 +81,13 @@ def validate_clocks(self) -> None: for name in ["bit", "sample"]: clk = getattr(self, name + "_clock") lim = getattr(self, name + "_clock_max") - assert ( - clk <= lim - ), name + f" clock too fast for device {clk} (limit: {lim})" + assert clk <= lim, ( + name + f" clock too fast for device {clk} (limit: {lim})" + ) lim = getattr(self, name + "_clock_min") - assert ( - clk >= lim - ), name + f" clock too slow for device {clk} (limit: {lim})" + assert clk >= lim, ( + name + f" clock too slow for device {clk} (limit: {lim})" + ) @property def bit_clock_min(self) -> Union[int, float]: diff --git a/adijif/system.py b/adijif/system.py index d4e6e07..d3a4ce3 100644 --- a/adijif/system.py +++ b/adijif/system.py @@ -318,7 +318,6 @@ def solve(self) -> Dict: sys_refs = [] for conv in convs: - if conv._nested: # MxFE, Transceivers for name in conv._nested: serdes_used += getattr(conv, name).L diff --git a/tests/test_bf.py b/tests/test_bf.py index 76e3962..98e7d4b 100644 --- a/tests/test_bf.py +++ b/tests/test_bf.py @@ -534,21 +534,21 @@ def test_system_daq2_rx_ad9528(): "Converter": np.array(1000000000), "ClockChip": [ { - 'm1': 4, - 'vco': 4000000000.0, - 'n2': 8, - 'r1': 1, - 'required_output_divs': 1.0, - 'fpga_pll_config': { - 'vco': 10000000000.0, - 'band': 1, - 'd': 1, - 'm': 1, - 'n': 20, - 'qty4_full_rate': 0, - 'type': 'QPLL', + "m1": 4, + "vco": 4000000000.0, + "n2": 8, + "r1": 1, + "required_output_divs": 1.0, + "fpga_pll_config": { + "vco": 10000000000.0, + "band": 1, + "d": 1, + "m": 1, + "n": 20, + "qty4_full_rate": 0, + "type": "QPLL", }, - 'sysref_rate': 7812500.0, + "sysref_rate": 7812500.0, }, { "m1": 4, diff --git a/tests/test_clocks.py b/tests/test_clocks.py index 8d6e56f..2502355 100644 --- a/tests/test_clocks.py +++ b/tests/test_clocks.py @@ -91,7 +91,6 @@ def test_ad9545_fail_no_solver(): @pytest.mark.parametrize("solver", ["gekko", "CPLEX"]) def test_ad9523_1_daq2_validate(solver): - vcxo = 125000000 n2 = 24 @@ -249,7 +248,6 @@ def test_ltc6953_validate(): @pytest.mark.parametrize("solver", ["gekko", "CPLEX"]) def test_ad9528_validate(solver): - n2 = 10 vcxo = 122.88e6 @@ -280,14 +278,13 @@ def test_ad9528_validate(solver): @pytest.mark.parametrize("solver", ["gekko", "CPLEX"]) def test_ad9528_sysref(solver): - n2 = 10 vcxo = 122.88e6 clk = adijif.ad9528(solver=solver) clk.n2 = n2 - clk.k = [*range(500, 600)] # FIXME gekko fails to find a solution without this. + clk.k = [*range(500, 600)] # FIXME gekko fails to find a solution without this. clk.use_vcxo_double = False clk.sysref = 120e3 diff --git a/tests/test_system.py b/tests/test_system.py index 01aec1d..939b318 100644 --- a/tests/test_system.py +++ b/tests/test_system.py @@ -1,3 +1,5 @@ +# flake8: noqa + import pytest import adijif @@ -67,7 +69,7 @@ def test_nested_converter_lane_count_exceeds_fpga_lane_count(): sys = adijif.system("adrv9009", "ad9528", "xilinx", 122.88e6) sys.fpga.setup_by_dev_kit_name("zcu102") - sys.fpga.max_serdes_lanes = fpga_L # Force it to break + sys.fpga.max_serdes_lanes = fpga_L # Force it to break sys.converter.adc.sample_clock = 122.88e6 sys.converter.dac.sample_clock = 122.88e6 @@ -80,5 +82,7 @@ def test_nested_converter_lane_count_exceeds_fpga_lane_count(): sys.converter.adc.set_quick_configuration_mode(mode_rx, "jesd204b") sys.converter.dac.set_quick_configuration_mode(mode_tx, "jesd204b") - with pytest.raises(Exception, match=f"Max SERDES lanes exceeded. {fpga_L} only available"): + with pytest.raises( + Exception, match=f"Max SERDES lanes exceeded. {fpga_L} only available" + ): cfg = sys.solve()