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.
Files changed (73) hide show
  1. adijif/__init__.py +32 -0
  2. adijif/adijif.py +1 -0
  3. adijif/cli.py +21 -0
  4. adijif/clocks/__init__.py +10 -0
  5. adijif/clocks/ad9523.py +321 -0
  6. adijif/clocks/ad9523_1_bf.py +91 -0
  7. adijif/clocks/ad9528.py +444 -0
  8. adijif/clocks/ad9528_bf.py +70 -0
  9. adijif/clocks/ad9545.py +553 -0
  10. adijif/clocks/clock.py +153 -0
  11. adijif/clocks/hmc7044.py +558 -0
  12. adijif/clocks/hmc7044_bf.py +68 -0
  13. adijif/clocks/ltc6952.py +624 -0
  14. adijif/clocks/ltc6952_bf.py +67 -0
  15. adijif/clocks/ltc6953.py +509 -0
  16. adijif/common.py +70 -0
  17. adijif/converters/__init__.py +3 -0
  18. adijif/converters/ad9081.py +679 -0
  19. adijif/converters/ad9081_dp.py +206 -0
  20. adijif/converters/ad9081_util.py +124 -0
  21. adijif/converters/ad9084.py +588 -0
  22. adijif/converters/ad9084_dp.py +111 -0
  23. adijif/converters/ad9084_draw.py +203 -0
  24. adijif/converters/ad9084_util.py +365 -0
  25. adijif/converters/ad9144.py +316 -0
  26. adijif/converters/ad9144_bf.py +44 -0
  27. adijif/converters/ad9680.py +201 -0
  28. adijif/converters/ad9680_bf.py +43 -0
  29. adijif/converters/ad9680_draw.py +184 -0
  30. adijif/converters/adc.py +83 -0
  31. adijif/converters/adrv9009.py +426 -0
  32. adijif/converters/adrv9009_bf.py +43 -0
  33. adijif/converters/adrv9009_util.py +89 -0
  34. adijif/converters/converter.py +399 -0
  35. adijif/converters/dac.py +85 -0
  36. adijif/converters/resources/AD9084_JTX_JRX.xlsx +0 -0
  37. adijif/converters/resources/ad9081_JRx_204B.csv +180 -0
  38. adijif/converters/resources/ad9081_JRx_204C.csv +411 -0
  39. adijif/converters/resources/ad9081_JTx_204B.csv +1488 -0
  40. adijif/converters/resources/ad9081_JTx_204C.csv +1064 -0
  41. adijif/converters/resources/full_rx_mode_table_ad9081.csv +1904 -0
  42. adijif/converters/resources/full_tx_mode_table_ad9081.csv +994 -0
  43. adijif/d2/__init__.py +26 -0
  44. adijif/d2/d2lib.h +81 -0
  45. adijif/draw.py +498 -0
  46. adijif/fpgas/__init__.py +1 -0
  47. adijif/fpgas/fpga.py +64 -0
  48. adijif/fpgas/xilinx/__init__.py +1143 -0
  49. adijif/fpgas/xilinx/bf.py +101 -0
  50. adijif/fpgas/xilinx/pll.py +232 -0
  51. adijif/fpgas/xilinx/sevenseries.py +531 -0
  52. adijif/fpgas/xilinx/ultrascaleplus.py +485 -0
  53. adijif/fpgas/xilinx/xilinx_draw.py +516 -0
  54. adijif/gekko_trans.py +295 -0
  55. adijif/jesd.py +760 -0
  56. adijif/plls/__init__.py +3 -0
  57. adijif/plls/adf4030.py +259 -0
  58. adijif/plls/adf4371.py +419 -0
  59. adijif/plls/adf4382.py +581 -0
  60. adijif/plls/pll.py +103 -0
  61. adijif/solvers.py +54 -0
  62. adijif/sys/__init__.py +1 -0
  63. adijif/sys/s_plls.py +185 -0
  64. adijif/system.py +567 -0
  65. adijif/system_draw.py +65 -0
  66. adijif/types.py +151 -0
  67. adijif/utils.py +191 -0
  68. pyadi_jif-0.1.0.dist-info/METADATA +62 -0
  69. pyadi_jif-0.1.0.dist-info/RECORD +73 -0
  70. pyadi_jif-0.1.0.dist-info/WHEEL +6 -0
  71. pyadi_jif-0.1.0.dist-info/licenses/AUTHORS.rst +13 -0
  72. pyadi_jif-0.1.0.dist-info/licenses/LICENSE +277 -0
  73. 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