pyadi-jif 0.1.0__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- adijif/__init__.py +32 -0
- adijif/adijif.py +1 -0
- adijif/cli.py +21 -0
- adijif/clocks/__init__.py +10 -0
- adijif/clocks/ad9523.py +321 -0
- adijif/clocks/ad9523_1_bf.py +91 -0
- adijif/clocks/ad9528.py +444 -0
- adijif/clocks/ad9528_bf.py +70 -0
- adijif/clocks/ad9545.py +553 -0
- adijif/clocks/clock.py +153 -0
- adijif/clocks/hmc7044.py +558 -0
- adijif/clocks/hmc7044_bf.py +68 -0
- adijif/clocks/ltc6952.py +624 -0
- adijif/clocks/ltc6952_bf.py +67 -0
- adijif/clocks/ltc6953.py +509 -0
- adijif/common.py +70 -0
- adijif/converters/__init__.py +3 -0
- adijif/converters/ad9081.py +679 -0
- adijif/converters/ad9081_dp.py +206 -0
- adijif/converters/ad9081_util.py +124 -0
- adijif/converters/ad9084.py +588 -0
- adijif/converters/ad9084_dp.py +111 -0
- adijif/converters/ad9084_draw.py +203 -0
- adijif/converters/ad9084_util.py +365 -0
- adijif/converters/ad9144.py +316 -0
- adijif/converters/ad9144_bf.py +44 -0
- adijif/converters/ad9680.py +201 -0
- adijif/converters/ad9680_bf.py +43 -0
- adijif/converters/ad9680_draw.py +184 -0
- adijif/converters/adc.py +83 -0
- adijif/converters/adrv9009.py +426 -0
- adijif/converters/adrv9009_bf.py +43 -0
- adijif/converters/adrv9009_util.py +89 -0
- adijif/converters/converter.py +399 -0
- adijif/converters/dac.py +85 -0
- adijif/converters/resources/AD9084_JTX_JRX.xlsx +0 -0
- adijif/converters/resources/ad9081_JRx_204B.csv +180 -0
- adijif/converters/resources/ad9081_JRx_204C.csv +411 -0
- adijif/converters/resources/ad9081_JTx_204B.csv +1488 -0
- adijif/converters/resources/ad9081_JTx_204C.csv +1064 -0
- adijif/converters/resources/full_rx_mode_table_ad9081.csv +1904 -0
- adijif/converters/resources/full_tx_mode_table_ad9081.csv +994 -0
- adijif/d2/__init__.py +26 -0
- adijif/d2/d2lib.h +81 -0
- adijif/draw.py +498 -0
- adijif/fpgas/__init__.py +1 -0
- adijif/fpgas/fpga.py +64 -0
- adijif/fpgas/xilinx/__init__.py +1143 -0
- adijif/fpgas/xilinx/bf.py +101 -0
- adijif/fpgas/xilinx/pll.py +232 -0
- adijif/fpgas/xilinx/sevenseries.py +531 -0
- adijif/fpgas/xilinx/ultrascaleplus.py +485 -0
- adijif/fpgas/xilinx/xilinx_draw.py +516 -0
- adijif/gekko_trans.py +295 -0
- adijif/jesd.py +760 -0
- adijif/plls/__init__.py +3 -0
- adijif/plls/adf4030.py +259 -0
- adijif/plls/adf4371.py +419 -0
- adijif/plls/adf4382.py +581 -0
- adijif/plls/pll.py +103 -0
- adijif/solvers.py +54 -0
- adijif/sys/__init__.py +1 -0
- adijif/sys/s_plls.py +185 -0
- adijif/system.py +567 -0
- adijif/system_draw.py +65 -0
- adijif/types.py +151 -0
- adijif/utils.py +191 -0
- pyadi_jif-0.1.0.dist-info/METADATA +62 -0
- pyadi_jif-0.1.0.dist-info/RECORD +73 -0
- pyadi_jif-0.1.0.dist-info/WHEEL +6 -0
- pyadi_jif-0.1.0.dist-info/licenses/AUTHORS.rst +13 -0
- pyadi_jif-0.1.0.dist-info/licenses/LICENSE +277 -0
- pyadi_jif-0.1.0.dist-info/top_level.txt +1 -0
adijif/solvers.py
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# flake8: noqa
|
|
2
|
+
# pytype: skip-file
|
|
3
|
+
"""Common solver API management layer."""
|
|
4
|
+
|
|
5
|
+
from typing import Union
|
|
6
|
+
|
|
7
|
+
try:
|
|
8
|
+
from docplex.cp.expression import CpoExpr # type: ignore
|
|
9
|
+
from docplex.cp.expression import CpoFunctionCall # type: ignore
|
|
10
|
+
from docplex.cp.expression import CpoIntVar # type: ignore
|
|
11
|
+
from docplex.cp.model import binary_var # type: ignore
|
|
12
|
+
from docplex.cp.model import CpoModel, integer_var, interval_var # type: ignore
|
|
13
|
+
from docplex.cp.solution import CpoSolveResult # type: ignore
|
|
14
|
+
|
|
15
|
+
cplex_solver = True
|
|
16
|
+
except ImportError:
|
|
17
|
+
cplex_solver = False
|
|
18
|
+
CpoExpr = None
|
|
19
|
+
CpoFunctionCall = None
|
|
20
|
+
binary_var = None
|
|
21
|
+
integer_var = None
|
|
22
|
+
continuous_var = None
|
|
23
|
+
interval_var = None
|
|
24
|
+
|
|
25
|
+
try:
|
|
26
|
+
import gekko # type: ignore
|
|
27
|
+
from gekko import GEKKO # type: ignore
|
|
28
|
+
from gekko.gk_operators import GK_Intermediate # type: ignore
|
|
29
|
+
from gekko.gk_operators import GK_Operators # type: ignore
|
|
30
|
+
from gekko.gk_variable import GKVariable # type: ignore
|
|
31
|
+
|
|
32
|
+
gekko_solver = True
|
|
33
|
+
except ImportError:
|
|
34
|
+
gekko_solver = False
|
|
35
|
+
gekko = None
|
|
36
|
+
GEKKO = None
|
|
37
|
+
GK_Intermediate = None
|
|
38
|
+
GK_Operators = None
|
|
39
|
+
GKVariable = None
|
|
40
|
+
|
|
41
|
+
if not cplex_solver and not gekko_solver:
|
|
42
|
+
raise ImportError(
|
|
43
|
+
"No solver found. gekko or docplex/cplex must be installed."
|
|
44
|
+
+ "\n-> Use `pip install pyadi-jif[cplex]` or `pip install pyadi-jif[gekko]`"
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def tround(value: float, tol: float = 1e-4) -> Union[float, int]:
|
|
49
|
+
"""Round if expected to have computational noise."""
|
|
50
|
+
if value.is_integer():
|
|
51
|
+
return int(value)
|
|
52
|
+
if abs(value - round(value)) < tol:
|
|
53
|
+
return round(value)
|
|
54
|
+
return value
|
adijif/sys/__init__.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Helper methods for system level models."""
|
adijif/sys/s_plls.py
ADDED
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
"""Cross part connector methods for system models."""
|
|
2
|
+
|
|
3
|
+
from typing import List, Tuple, Union
|
|
4
|
+
|
|
5
|
+
import adijif # noqa: F401
|
|
6
|
+
from adijif.clocks.clock import clock as clockc
|
|
7
|
+
from adijif.converters.converter import converter as convc
|
|
8
|
+
from adijif.fpgas.fpga import fpga as fpgac
|
|
9
|
+
from adijif.plls.pll import pll as pllc
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class SystemPLL:
|
|
13
|
+
"""PLL helper methods for System models."""
|
|
14
|
+
|
|
15
|
+
_plls_sysref = []
|
|
16
|
+
|
|
17
|
+
@property
|
|
18
|
+
def plls_sysref(self) -> List[pllc]:
|
|
19
|
+
"""External PLLs used as SYSREF sources for converters and FPGA.
|
|
20
|
+
|
|
21
|
+
Returns:
|
|
22
|
+
List: List of PLL objects
|
|
23
|
+
"""
|
|
24
|
+
return self._plls_sysref
|
|
25
|
+
|
|
26
|
+
def add_pll_sysref(
|
|
27
|
+
self, pll_name: str, clk: clockc, cnv: convc = None, fpga: fpgac = None
|
|
28
|
+
) -> None:
|
|
29
|
+
"""Add External PLL to system between clock chip, converter and FPGA.
|
|
30
|
+
|
|
31
|
+
Args:
|
|
32
|
+
pll_name (str): Name of PLL class
|
|
33
|
+
clk (clockc): Clock chip reference
|
|
34
|
+
cnv (convc): Converter to be driven by PLL
|
|
35
|
+
fpga (fpgac): FPGA to be driven by PLL
|
|
36
|
+
"""
|
|
37
|
+
pll = eval(f"adijif.{pll_name}(self.model,solver=self.solver)") # noqa: S307
|
|
38
|
+
self._plls_sysref.append(pll)
|
|
39
|
+
pll._connected_to_output = []
|
|
40
|
+
pll._ref = clk
|
|
41
|
+
assert cnv or fpga, "Converter or FPGA must be connected to PLL"
|
|
42
|
+
if cnv:
|
|
43
|
+
if hasattr(cnv, "_nested") and cnv._nested:
|
|
44
|
+
# If the converter has nested references (like MxFE)
|
|
45
|
+
# we need to ensure all nested names are connected
|
|
46
|
+
names = cnv._nested
|
|
47
|
+
for name in names:
|
|
48
|
+
pll._connected_to_output.append(name)
|
|
49
|
+
else:
|
|
50
|
+
pll._connected_to_output.append(cnv.name)
|
|
51
|
+
if fpga:
|
|
52
|
+
pll._connected_to_output.append(fpga.name)
|
|
53
|
+
|
|
54
|
+
def _get_ref_clock(
|
|
55
|
+
self, conv: convc, config: dict, clock_names: List[str]
|
|
56
|
+
) -> Tuple[dict, List[str]]:
|
|
57
|
+
config[f"{conv.name}_ref_clk"] = self.clock._get_clock_constraint(
|
|
58
|
+
f"{conv.name}_ref_clk"
|
|
59
|
+
)
|
|
60
|
+
clock_names.append(f"{conv.name}_ref_clk")
|
|
61
|
+
return config, clock_names
|
|
62
|
+
|
|
63
|
+
def _get_ref_clock_fpga(
|
|
64
|
+
self,
|
|
65
|
+
conv: convc,
|
|
66
|
+
config: dict,
|
|
67
|
+
clock_names: List[str],
|
|
68
|
+
need_separate_link_clock: bool,
|
|
69
|
+
) -> Tuple[dict, List[str]]:
|
|
70
|
+
if conv._nested:
|
|
71
|
+
names = conv._nested
|
|
72
|
+
for name in names:
|
|
73
|
+
config[f"{name}_fpga_ref_clk"] = self.clock._get_clock_constraint(
|
|
74
|
+
f"{self.fpga.name}_{name}_ref_clk"
|
|
75
|
+
)
|
|
76
|
+
clock_names.append(f"{name}_fpga_ref_clk")
|
|
77
|
+
# sys_refs.append(config[name + "_fpga_ref_clk"])
|
|
78
|
+
|
|
79
|
+
if need_separate_link_clock:
|
|
80
|
+
config[f"{name}_fpga_device_clk"] = (
|
|
81
|
+
self.clock._get_clock_constraint(
|
|
82
|
+
f"{self.fpga.name}_{name}_device_clk"
|
|
83
|
+
)
|
|
84
|
+
)
|
|
85
|
+
clock_names.append(f"{name}_fpga_device_clk")
|
|
86
|
+
|
|
87
|
+
else:
|
|
88
|
+
config[f"{conv.name}_fpga_ref_clk"] = self.clock._get_clock_constraint(
|
|
89
|
+
f"{self.fpga.name}_{conv.name}_ref_clk"
|
|
90
|
+
)
|
|
91
|
+
clock_names.append(f"{conv.name}_fpga_ref_clk")
|
|
92
|
+
# sys_refs.append(config[f"{conv.name}_fpga_ref_clk"])
|
|
93
|
+
|
|
94
|
+
if need_separate_link_clock:
|
|
95
|
+
config[f"{conv.name}_fpga_device_clk"] = (
|
|
96
|
+
self.clock._get_clock_constraint(
|
|
97
|
+
f"{self.fpga.name}_{conv.name}_device_clk"
|
|
98
|
+
)
|
|
99
|
+
)
|
|
100
|
+
clock_names.append(f"{conv.name}_fpga_device_clk")
|
|
101
|
+
|
|
102
|
+
return config, clock_names
|
|
103
|
+
|
|
104
|
+
def _get_ext_sysref_clock(
|
|
105
|
+
self, name: str, config: dict, clock_names: List[str]
|
|
106
|
+
) -> Tuple[bool, dict, List[str]]:
|
|
107
|
+
found = False
|
|
108
|
+
if self._plls_sysref:
|
|
109
|
+
for pll in self._plls_sysref:
|
|
110
|
+
if name in pll._connected_to_output:
|
|
111
|
+
config[f"{name}_sysref"] = pll._get_clock_constraint(
|
|
112
|
+
f"{name}_sysref"
|
|
113
|
+
)
|
|
114
|
+
clock_names.append(f"{name}_sysref")
|
|
115
|
+
found = True
|
|
116
|
+
break
|
|
117
|
+
return found, config, clock_names
|
|
118
|
+
|
|
119
|
+
def _get_sysref_clock(
|
|
120
|
+
self, conv: convc, config: dict, clock_names: List[str]
|
|
121
|
+
) -> Tuple[dict, List[str]]:
|
|
122
|
+
if conv._nested: # MxFE, Transceivers
|
|
123
|
+
assert isinstance(conv._nested, list)
|
|
124
|
+
names = conv._nested
|
|
125
|
+
for name in names:
|
|
126
|
+
# Check if we want to use external PLL for SYSREF
|
|
127
|
+
found, config, clock_names = self._get_ext_sysref_clock(
|
|
128
|
+
name, config, clock_names
|
|
129
|
+
)
|
|
130
|
+
if not found:
|
|
131
|
+
# Use clock chip for SYSREF
|
|
132
|
+
config[f"{name}_sysref"] = self.clock._get_clock_constraint(
|
|
133
|
+
f"{name}_sysref"
|
|
134
|
+
)
|
|
135
|
+
clock_names.append(f"{name}_sysref")
|
|
136
|
+
else:
|
|
137
|
+
found, config, clock_names = self._get_ext_sysref_clock(
|
|
138
|
+
conv.name, config, clock_names
|
|
139
|
+
)
|
|
140
|
+
if not found:
|
|
141
|
+
# Use clock chip for SYSREF
|
|
142
|
+
config[f"{conv.name}_sysref"] = self.clock._get_clock_constraint(
|
|
143
|
+
f"{conv.name}_sysref"
|
|
144
|
+
)
|
|
145
|
+
clock_names.append(f"{conv.name}_sysref")
|
|
146
|
+
return config, clock_names
|
|
147
|
+
|
|
148
|
+
def __apply_ext_sysref_constraint(
|
|
149
|
+
self, name: str, clks: List[str], config: dict, sys_refs: List[str]
|
|
150
|
+
) -> Tuple[bool, List[str]]:
|
|
151
|
+
found = False
|
|
152
|
+
if self._plls_sysref:
|
|
153
|
+
for pll in self._plls_sysref:
|
|
154
|
+
if name in pll._connected_to_output:
|
|
155
|
+
self.clock._add_equation(config[f"{name}_sysref"] == clks[1])
|
|
156
|
+
sys_refs.append(config[f"{name}_sysref"])
|
|
157
|
+
found = True
|
|
158
|
+
break
|
|
159
|
+
return found, sys_refs
|
|
160
|
+
|
|
161
|
+
def _apply_sysref_constraint(
|
|
162
|
+
self,
|
|
163
|
+
device: Union[convc, fpgac],
|
|
164
|
+
clks: List[str],
|
|
165
|
+
config: str,
|
|
166
|
+
sys_refs: List[str],
|
|
167
|
+
) -> List[str]:
|
|
168
|
+
if device._nested:
|
|
169
|
+
names = device._nested
|
|
170
|
+
for i, name in enumerate(names):
|
|
171
|
+
found, sys_refs = self.__apply_ext_sysref_constraint(
|
|
172
|
+
name, clks, config, sys_refs
|
|
173
|
+
)
|
|
174
|
+
if not found:
|
|
175
|
+
self.clock._add_equation(config[f"{name}_sysref"] == clks[i + 1])
|
|
176
|
+
sys_refs.append(config[f"{name}_sysref"])
|
|
177
|
+
else:
|
|
178
|
+
found, sys_refs = self.__apply_ext_sysref_constraint(
|
|
179
|
+
device.name, clks, config, sys_refs
|
|
180
|
+
)
|
|
181
|
+
if not found:
|
|
182
|
+
self.clock._add_equation(config[f"{device.name}_sysref"] == clks[1])
|
|
183
|
+
sys_refs.append(config[f"{device.name}_sysref"])
|
|
184
|
+
|
|
185
|
+
return sys_refs
|