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
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
"""AD9081 Datapath Description Class."""
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class ad9081_dp_rx:
|
|
5
|
+
"""AD9081 RX Data Path Configuration."""
|
|
6
|
+
|
|
7
|
+
cddc_enabled = [True, True, True, True]
|
|
8
|
+
cddc_decimations = [1, 1, 1, 1]
|
|
9
|
+
cddc_decimations_available = [1, 2, 3, 4, 6]
|
|
10
|
+
cddc_nco_frequencies = [0, 0, 0, 0]
|
|
11
|
+
cddc_nco_phases = [0, 0, 0, 0]
|
|
12
|
+
|
|
13
|
+
fddc_enabled = [False, False, False, False, False, False, False, False]
|
|
14
|
+
fddc_decimations = [1, 1, 1, 1, 1, 1, 1, 1]
|
|
15
|
+
fddc_decimations_available = [1, 2, 3, 4, 6, 8, 12, 16, 24]
|
|
16
|
+
fddc_nco_frequencies = [0, 0, 0, 0, 0, 0, 0, 0]
|
|
17
|
+
fddc_nco_phases = [0, 0, 0, 0, 0, 0, 0, 0]
|
|
18
|
+
fddc_source = [1, 1, 2, 2, 3, 3, 4, 4]
|
|
19
|
+
|
|
20
|
+
__isfrozen = False
|
|
21
|
+
|
|
22
|
+
def __init__(self) -> None:
|
|
23
|
+
"""Initialize the AD9081 RX datapath."""
|
|
24
|
+
self._freeze()
|
|
25
|
+
|
|
26
|
+
def __setattr__(self, key: str, value: any) -> None:
|
|
27
|
+
"""Set attribute intercept.
|
|
28
|
+
|
|
29
|
+
Only allow setting of attributes that already exist.
|
|
30
|
+
|
|
31
|
+
Args:
|
|
32
|
+
key (str): attribute name
|
|
33
|
+
value (any): attribute value
|
|
34
|
+
|
|
35
|
+
Raises:
|
|
36
|
+
TypeError: if attribute does not exist
|
|
37
|
+
"""
|
|
38
|
+
if self.__isfrozen and not hasattr(self, key):
|
|
39
|
+
raise TypeError("Property %r does not exist" % key)
|
|
40
|
+
|
|
41
|
+
if key in ["cddc_decimations", "fddc_decimations"]:
|
|
42
|
+
# Error if decimations are not a list
|
|
43
|
+
if not isinstance(value, list):
|
|
44
|
+
raise TypeError("Decimations must be a list")
|
|
45
|
+
if key == "cddc_decimations":
|
|
46
|
+
if len(value) != 4:
|
|
47
|
+
raise TypeError("CDDC Decimations must be a list of length 4")
|
|
48
|
+
for v in value:
|
|
49
|
+
if v not in [1, 2, 3, 4, 6]:
|
|
50
|
+
raise TypeError("CDDC Decimations must be 1, 2, 3, 4, or 6")
|
|
51
|
+
if key == "fddc_decimations":
|
|
52
|
+
if len(value) != 8:
|
|
53
|
+
raise TypeError("FDDC Decimations must be a list of length 8")
|
|
54
|
+
for v in value:
|
|
55
|
+
if v not in [1, 2, 3, 4, 6, 8, 12, 16, 24]:
|
|
56
|
+
raise TypeError(
|
|
57
|
+
"FDDC Decimations must be 1, 2, 4, 6, 8, 12, 16, or 24"
|
|
58
|
+
)
|
|
59
|
+
object.__setattr__(self, key, value)
|
|
60
|
+
|
|
61
|
+
def _freeze(self) -> None:
|
|
62
|
+
self.__isfrozen = True
|
|
63
|
+
|
|
64
|
+
def get_config(self) -> dict:
|
|
65
|
+
"""Get the datapath configuration for the AD9081 RX.
|
|
66
|
+
|
|
67
|
+
Returns:
|
|
68
|
+
dict: datapath configuration
|
|
69
|
+
"""
|
|
70
|
+
datapath = {}
|
|
71
|
+
datapath["cddc"] = {}
|
|
72
|
+
datapath["cddc"]["enabled"] = self.cddc_enabled
|
|
73
|
+
datapath["cddc"]["decimations"] = self.cddc_decimations
|
|
74
|
+
datapath["cddc"]["nco_frequencies"] = self.cddc_nco_frequencies
|
|
75
|
+
datapath["cddc"]["nco_phases"] = self.cddc_nco_phases
|
|
76
|
+
|
|
77
|
+
datapath["fddc"] = {}
|
|
78
|
+
datapath["fddc"]["enabled"] = self.fddc_enabled
|
|
79
|
+
datapath["fddc"]["decimations"] = self.fddc_decimations
|
|
80
|
+
datapath["fddc"]["nco_frequencies"] = self.fddc_nco_frequencies
|
|
81
|
+
datapath["fddc"]["nco_phases"] = self.fddc_nco_phases
|
|
82
|
+
datapath["fddc"]["source"] = self.fddc_source
|
|
83
|
+
|
|
84
|
+
return datapath
|
|
85
|
+
|
|
86
|
+
@property
|
|
87
|
+
def decimation_overall(self) -> int:
|
|
88
|
+
"""Minimum Overall Decimation factor.
|
|
89
|
+
|
|
90
|
+
Raises:
|
|
91
|
+
Exception: No FDDC or CDDC enabled
|
|
92
|
+
Exception: Enabled FDDC's source CDDC not enabled
|
|
93
|
+
|
|
94
|
+
Returns:
|
|
95
|
+
int: minimum overall decimation factor
|
|
96
|
+
"""
|
|
97
|
+
if (not any(self.fddc_enabled)) and (not any(self.cddc_enabled)):
|
|
98
|
+
raise Exception("No FDDCs or CDDCs enabled")
|
|
99
|
+
|
|
100
|
+
min_dec = -1
|
|
101
|
+
if any(self.fddc_enabled):
|
|
102
|
+
for i, fdec in enumerate(self.fddc_decimations):
|
|
103
|
+
if self.fddc_enabled[i]:
|
|
104
|
+
cddc = self.fddc_source[i] - 1
|
|
105
|
+
if not self.cddc_enabled:
|
|
106
|
+
raise Exception(f"Source CDDC {cddc} not enabled for FDDC {i}")
|
|
107
|
+
cdec = self.cddc_decimations[cddc]
|
|
108
|
+
if (cdec * fdec < min_dec) or min_dec == -1:
|
|
109
|
+
min_dec = cdec * fdec
|
|
110
|
+
else:
|
|
111
|
+
for i, cdec in enumerate(self.cddc_decimations):
|
|
112
|
+
if self.cddc_enabled[i] and (min_dec == -1 or cdec < min_dec):
|
|
113
|
+
min_dec = cdec
|
|
114
|
+
|
|
115
|
+
return min_dec
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
class ad9081_dp_tx:
|
|
119
|
+
"""AD9081 TX Data Path Configuration."""
|
|
120
|
+
|
|
121
|
+
cduc_enabled = [True, True, True, True]
|
|
122
|
+
cduc_interpolation = 1
|
|
123
|
+
cduc_nco_frequencies = [0, 0, 0, 0]
|
|
124
|
+
cduc_nco_phases = [0, 0, 0, 0]
|
|
125
|
+
|
|
126
|
+
fduc_enabled = [False, False, False, False, False, False, False, False]
|
|
127
|
+
fduc_interpolation = 1
|
|
128
|
+
fduc_nco_frequencies = [0, 0, 0, 0, 0, 0, 0, 0]
|
|
129
|
+
fduc_nco_phases = [0, 0, 0, 0, 0, 0, 0, 0]
|
|
130
|
+
|
|
131
|
+
cduc_sources = [[1], [1], [3], [3]]
|
|
132
|
+
|
|
133
|
+
__isfrozen = False
|
|
134
|
+
|
|
135
|
+
def __init__(self) -> None:
|
|
136
|
+
"""Initialize the AD9081 TX datapath."""
|
|
137
|
+
self._freeze()
|
|
138
|
+
|
|
139
|
+
def __setattr__(self, key: str, value: any) -> None:
|
|
140
|
+
"""Set attribute intercept.
|
|
141
|
+
|
|
142
|
+
Only allow setting of attributes that already exist.
|
|
143
|
+
|
|
144
|
+
Args:
|
|
145
|
+
key (str): attribute name
|
|
146
|
+
value (any): attribute value
|
|
147
|
+
|
|
148
|
+
Raises:
|
|
149
|
+
TypeError: if attribute does not exist
|
|
150
|
+
"""
|
|
151
|
+
if self.__isfrozen and not hasattr(self, key):
|
|
152
|
+
raise TypeError("Property %r does not exist" % key)
|
|
153
|
+
|
|
154
|
+
if key in ["cduc_interpolation", "fduc_interpolation"]:
|
|
155
|
+
# Error if interpolation is a list
|
|
156
|
+
if isinstance(value, list):
|
|
157
|
+
raise TypeError("Interpolation must be an integer, not a list")
|
|
158
|
+
if key == "cduc_interpolation" and value not in [1, 2, 4, 6, 8, 12]:
|
|
159
|
+
raise TypeError("CDUC Interpolation must be 1, 2, 4, 6, 8, or 12")
|
|
160
|
+
if key == "fduc_interpolation" and value not in [1, 2, 3, 4, 6, 8]:
|
|
161
|
+
raise TypeError("FDUC Interpolation must be 1, 2, 3, 4, 6, or 8")
|
|
162
|
+
object.__setattr__(self, key, value)
|
|
163
|
+
|
|
164
|
+
def _freeze(self) -> None:
|
|
165
|
+
self.__isfrozen = True
|
|
166
|
+
|
|
167
|
+
def get_config(self) -> dict:
|
|
168
|
+
"""Get the datapath configuration for the AD9081 TX.
|
|
169
|
+
|
|
170
|
+
Returns:
|
|
171
|
+
dict: Datapath configuration
|
|
172
|
+
"""
|
|
173
|
+
datapath = {}
|
|
174
|
+
datapath["cduc"] = {}
|
|
175
|
+
datapath["cduc"]["enabled"] = self.cduc_enabled
|
|
176
|
+
datapath["cduc"]["interpolation"] = self.cduc_interpolation
|
|
177
|
+
datapath["cduc"]["nco_frequencies"] = self.cduc_nco_frequencies
|
|
178
|
+
datapath["cduc"]["nco_phases"] = self.cduc_nco_phases
|
|
179
|
+
datapath["cduc"]["sources"] = self.cduc_sources
|
|
180
|
+
|
|
181
|
+
datapath["fduc"] = {}
|
|
182
|
+
datapath["fduc"]["enabled"] = self.fduc_enabled
|
|
183
|
+
datapath["fduc"]["interpolation"] = self.fduc_interpolation
|
|
184
|
+
datapath["fduc"]["nco_frequencies"] = self.fduc_nco_frequencies
|
|
185
|
+
datapath["fduc"]["nco_phases"] = self.fduc_nco_phases
|
|
186
|
+
|
|
187
|
+
return datapath
|
|
188
|
+
|
|
189
|
+
@property
|
|
190
|
+
def interpolation_overall(self) -> int:
|
|
191
|
+
"""Minimum Overall Interpolation factor.
|
|
192
|
+
|
|
193
|
+
Raises:
|
|
194
|
+
Exception: No FDDC or CDDC enabled
|
|
195
|
+
Exception: Enabled FDDC's source CDDC not enabled
|
|
196
|
+
|
|
197
|
+
Returns:
|
|
198
|
+
int: minimum overall interpolation factor
|
|
199
|
+
"""
|
|
200
|
+
if (not any(self.fduc_enabled)) and (not any(self.cduc_enabled)):
|
|
201
|
+
raise Exception("No FDUCs or CDUCs enabled")
|
|
202
|
+
|
|
203
|
+
if any(self.fduc_enabled):
|
|
204
|
+
return self.fduc_interpolation * self.cduc_interpolation
|
|
205
|
+
else:
|
|
206
|
+
return self.cduc_interpolation
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
"""AD9081 MxFE Utility Functions."""
|
|
2
|
+
|
|
3
|
+
import csv
|
|
4
|
+
import os
|
|
5
|
+
from typing import Dict, Union
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def _convert_to_config(
|
|
9
|
+
mode: str,
|
|
10
|
+
L: Union[int, float],
|
|
11
|
+
M: Union[int, float],
|
|
12
|
+
F: Union[int, float],
|
|
13
|
+
S: Union[int, float],
|
|
14
|
+
HD: Union[int, float],
|
|
15
|
+
K: Union[int, float],
|
|
16
|
+
N: Union[int, float],
|
|
17
|
+
Np: Union[int, float],
|
|
18
|
+
CS: Union[int, float],
|
|
19
|
+
E: Union[int, float],
|
|
20
|
+
global_index: Union[int, float],
|
|
21
|
+
jesd_class: str,
|
|
22
|
+
) -> Dict:
|
|
23
|
+
return {
|
|
24
|
+
"L": L,
|
|
25
|
+
"M": M,
|
|
26
|
+
"F": F,
|
|
27
|
+
"S": S,
|
|
28
|
+
# "HD": 1 if F == 1 else 0,
|
|
29
|
+
"Np": Np,
|
|
30
|
+
"K": K,
|
|
31
|
+
"HD": HD,
|
|
32
|
+
"CS": CS,
|
|
33
|
+
"E": E,
|
|
34
|
+
"jesd_class": jesd_class,
|
|
35
|
+
"global_index": global_index,
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def _load_rx_config_modes() -> Dict:
|
|
40
|
+
"""Load RX JESD configuration tables from file."""
|
|
41
|
+
return {
|
|
42
|
+
"jesd204b": _read_table("ad9081_JTx_204B.csv", True),
|
|
43
|
+
"jesd204c": _read_table("ad9081_JTx_204C.csv", False),
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def _load_tx_config_modes() -> Dict:
|
|
48
|
+
"""Load TX JESD configuration tables from file."""
|
|
49
|
+
return {
|
|
50
|
+
"jesd204b": _read_table("ad9081_JRx_204B.csv", True),
|
|
51
|
+
"jesd204c": _read_table("ad9081_JRx_204C.csv", False),
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def _read_table(fn: str, jesd204b: bool, qcm: Union[Dict, None] = None) -> Dict:
|
|
56
|
+
loc = os.path.dirname(__file__)
|
|
57
|
+
fn = os.path.join(loc, "resources", fn)
|
|
58
|
+
with open(fn) as f:
|
|
59
|
+
records = csv.DictReader(f)
|
|
60
|
+
if qcm:
|
|
61
|
+
quick_configuration_modes = qcm
|
|
62
|
+
else:
|
|
63
|
+
quick_configuration_modes = {}
|
|
64
|
+
for row in records:
|
|
65
|
+
d = dict(row)
|
|
66
|
+
if "_JTx_" in fn:
|
|
67
|
+
HD = int(float(d["HD"]))
|
|
68
|
+
conv_min = float(d["FADC Min (GSPS)"])
|
|
69
|
+
conv_max = float(d["FADC Max (GSPS)"])
|
|
70
|
+
lane_min = float(d["Lane Rate Min (GSPS)"])
|
|
71
|
+
lane_max = float(d["Lane Rate Max (GSPS)"])
|
|
72
|
+
else:
|
|
73
|
+
HD = 0
|
|
74
|
+
conv_min = -1
|
|
75
|
+
conv_max = -1
|
|
76
|
+
lane_min = -1
|
|
77
|
+
lane_max = -1
|
|
78
|
+
if jesd204b:
|
|
79
|
+
k = "JESD204B Mode Number"
|
|
80
|
+
jmode = "jesd204b"
|
|
81
|
+
E = 0
|
|
82
|
+
else:
|
|
83
|
+
k = "JESD204C Mode Number"
|
|
84
|
+
jmode = "jesd204c"
|
|
85
|
+
E = int(float(d["E"]))
|
|
86
|
+
mode = d[k]
|
|
87
|
+
del d[k]
|
|
88
|
+
if not mode:
|
|
89
|
+
continue
|
|
90
|
+
gi = int(float(d["global_index"]))
|
|
91
|
+
decs = {
|
|
92
|
+
"coarse": int(float(d["Coarse"])),
|
|
93
|
+
"fine": int(float(d["Fine"])),
|
|
94
|
+
"conv_min": conv_min,
|
|
95
|
+
"conv_max": conv_max,
|
|
96
|
+
"lane_min": lane_min,
|
|
97
|
+
"lane_max": lane_max,
|
|
98
|
+
}
|
|
99
|
+
cfg = _convert_to_config(
|
|
100
|
+
mode=mode,
|
|
101
|
+
L=int(float(d["L"])),
|
|
102
|
+
M=int(float(d["M"])),
|
|
103
|
+
F=int(float(d["F"])),
|
|
104
|
+
S=int(float(d["S"])),
|
|
105
|
+
N=int(float(d["NP"])),
|
|
106
|
+
Np=int(float(d["NP"])),
|
|
107
|
+
CS=int(0),
|
|
108
|
+
HD=HD,
|
|
109
|
+
K=int(float(d["K"])),
|
|
110
|
+
E=E,
|
|
111
|
+
global_index=gi,
|
|
112
|
+
jesd_class=jmode,
|
|
113
|
+
)
|
|
114
|
+
if mode not in quick_configuration_modes:
|
|
115
|
+
quick_configuration_modes[mode] = cfg
|
|
116
|
+
quick_configuration_modes[mode]["decimations"] = [decs]
|
|
117
|
+
else:
|
|
118
|
+
quick_configuration_modes[mode]["decimations"].append(decs)
|
|
119
|
+
return quick_configuration_modes
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
if __name__ == "__main__":
|
|
123
|
+
_load_rx_config_modes()
|
|
124
|
+
_load_tx_config_modes()
|