pyadi-jif 0.1.0__py2.py3-none-any.whl → 0.1.1__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 +2 -2
- adijif/clocks/ad9523_1_bf.py +3 -3
- adijif/clocks/ad9528_bf.py +1 -1
- adijif/clocks/hmc7044_bf.py +1 -1
- adijif/clocks/ltc6952.py +2 -2
- adijif/clocks/ltc6952_bf.py +1 -1
- adijif/clocks/ltc6953.py +2 -2
- adijif/converters/__init__.py +12 -1
- adijif/converters/ad9081.py +1 -1
- adijif/converters/ad9081_dp.py +2 -0
- adijif/converters/ad9084.py +29 -7
- adijif/converters/ad9084_draw.py +20 -14
- adijif/converters/ad9084_util.py +24 -5
- adijif/converters/ad9088_dp.py +111 -0
- adijif/converters/converter.py +153 -2
- adijif/draw.py +11 -2
- adijif/fpgas/xilinx/__init__.py +4 -2
- adijif/jesd.py +3 -1
- adijif/plls/adf4030.py +6 -1
- adijif/plls/adf4382.py +0 -1
- adijif/solvers.py +5 -4
- adijif/system.py +16 -1
- adijif/tools/explorer/cli.py +36 -0
- adijif/tools/explorer/main.py +41 -0
- adijif/tools/explorer/src/pages/__init__.py +16 -0
- adijif/tools/explorer/src/pages/clockconfigurator.py +193 -0
- adijif/tools/explorer/src/pages/helpers/datapath.py +85 -0
- adijif/tools/explorer/src/pages/helpers/drawers.py +87 -0
- adijif/tools/explorer/src/pages/helpers/jesd.py +140 -0
- adijif/tools/explorer/src/pages/jesdmodeselector.py +209 -0
- adijif/tools/explorer/src/pages/systemconfigurator.py +252 -0
- adijif/tools/explorer/src/state.py +141 -0
- adijif/tools/explorer/src/utils.py +37 -0
- adijif/types.py +23 -4
- {pyadi_jif-0.1.0.dist-info → pyadi_jif-0.1.1.dist-info}/METADATA +36 -12
- {pyadi_jif-0.1.0.dist-info → pyadi_jif-0.1.1.dist-info}/RECORD +41 -30
- pyadi_jif-0.1.1.dist-info/entry_points.txt +2 -0
- adijif/d2/__init__.py +0 -26
- adijif/d2/d2lib.h +0 -81
- {pyadi_jif-0.1.0.dist-info → pyadi_jif-0.1.1.dist-info}/WHEEL +0 -0
- {pyadi_jif-0.1.0.dist-info → pyadi_jif-0.1.1.dist-info}/licenses/AUTHORS.rst +0 -0
- {pyadi_jif-0.1.0.dist-info → pyadi_jif-0.1.1.dist-info}/licenses/LICENSE +0 -0
- {pyadi_jif-0.1.0.dist-info → pyadi_jif-0.1.1.dist-info}/top_level.txt +0 -0
adijif/__init__.py
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
__author__ = """Analog Devices, Inc."""
|
|
4
4
|
__email__ = "travis.collins@analog.com"
|
|
5
|
-
__version__ = "0.1.
|
|
5
|
+
__version__ = "0.1.1"
|
|
6
6
|
|
|
7
7
|
import adijif.solvers
|
|
8
8
|
import adijif.utils
|
|
@@ -20,7 +20,7 @@ from adijif.converters.ad9081 import (
|
|
|
20
20
|
ad9082_rx,
|
|
21
21
|
ad9082_tx,
|
|
22
22
|
)
|
|
23
|
-
from adijif.converters.ad9084 import ad9084_rx
|
|
23
|
+
from adijif.converters.ad9084 import ad9084_rx, ad9088_rx
|
|
24
24
|
from adijif.converters.ad9144 import ad9144
|
|
25
25
|
from adijif.converters.ad9680 import ad9680
|
|
26
26
|
from adijif.converters.adrv9009 import adrv9009, adrv9009_rx, adrv9009_tx
|
adijif/clocks/ad9523_1_bf.py
CHANGED
|
@@ -55,7 +55,7 @@ class ad9523_1_bf(clock):
|
|
|
55
55
|
if (vco / m1) % mod == 0:
|
|
56
56
|
# See if we can use only m1 and not both m1+m2
|
|
57
57
|
rods = (vco / m1) / required_output_rates
|
|
58
|
-
if np.all(np.
|
|
58
|
+
if np.all(np.isin(rods, self.d_available)):
|
|
59
59
|
configs.append(
|
|
60
60
|
{
|
|
61
61
|
"m1": m1,
|
|
@@ -67,10 +67,10 @@ class ad9523_1_bf(clock):
|
|
|
67
67
|
)
|
|
68
68
|
else:
|
|
69
69
|
# Try to use m2 as well to meet required out clocks
|
|
70
|
-
f1 = np.
|
|
70
|
+
f1 = np.isin(rods, self.d_available)
|
|
71
71
|
for m2 in self.m1_available:
|
|
72
72
|
rods2 = (vco / m2) / required_output_rates
|
|
73
|
-
f2 = np.
|
|
73
|
+
f2 = np.isin(rods2, self.d_available)
|
|
74
74
|
if np.logical_or(f1, f2).all():
|
|
75
75
|
configs.append(
|
|
76
76
|
{
|
adijif/clocks/ad9528_bf.py
CHANGED
|
@@ -56,7 +56,7 @@ class ad9528_bf(clock):
|
|
|
56
56
|
and (vco / m1) % mod == 0
|
|
57
57
|
):
|
|
58
58
|
required_output_divs = (vco / m1) / required_output_rates
|
|
59
|
-
if np.all(np.
|
|
59
|
+
if np.all(np.isin(required_output_divs, self.d_available)):
|
|
60
60
|
configs.append(
|
|
61
61
|
{
|
|
62
62
|
"m1": m1,
|
adijif/clocks/hmc7044_bf.py
CHANGED
|
@@ -52,7 +52,7 @@ class hmc7044_bf(clock):
|
|
|
52
52
|
# Check if required dividers for output clocks are in set
|
|
53
53
|
if f % mod == 0:
|
|
54
54
|
d = f / rates
|
|
55
|
-
if np.all(np.
|
|
55
|
+
if np.all(np.isin(d, odivs)) and f not in vcos:
|
|
56
56
|
if f not in vcos:
|
|
57
57
|
vcos.append(f)
|
|
58
58
|
config = {
|
adijif/clocks/ltc6952.py
CHANGED
|
@@ -600,7 +600,7 @@ class ltc6952(ltc6952_bf):
|
|
|
600
600
|
self._clk_names = clk_names
|
|
601
601
|
|
|
602
602
|
# Add requested clocks to output constraints
|
|
603
|
-
for out_freq in out_freqs:
|
|
603
|
+
for out_freq, clk_name in zip(out_freqs, clk_names): # noqa: B905
|
|
604
604
|
if self.solver == "gekko":
|
|
605
605
|
__d = self._d if isinstance(self._d, list) else [self._d]
|
|
606
606
|
if __d.sort() != self.d_available.sort():
|
|
@@ -613,7 +613,7 @@ class ltc6952(ltc6952_bf):
|
|
|
613
613
|
od = self.model.Intermediate(mp * pow(2, nx))
|
|
614
614
|
|
|
615
615
|
elif self.solver == "CPLEX":
|
|
616
|
-
od = self._convert_input(self._d, "d_"
|
|
616
|
+
od = self._convert_input(self._d, f"d_{out_freq}_{clk_name}")
|
|
617
617
|
|
|
618
618
|
self._add_equation(
|
|
619
619
|
[self.vcxo / self.config["r2"] * self.config["n2"] / od == out_freq]
|
adijif/clocks/ltc6952_bf.py
CHANGED
|
@@ -51,7 +51,7 @@ class ltc6952_bf(clock):
|
|
|
51
51
|
# Check if required dividers for output clocks are in set
|
|
52
52
|
if f % mod == 0:
|
|
53
53
|
d = f / rates
|
|
54
|
-
if np.all(np.
|
|
54
|
+
if np.all(np.isin(d, odivs)) and f not in vcos:
|
|
55
55
|
if f not in vcos:
|
|
56
56
|
vcos.append(f)
|
|
57
57
|
config = {
|
adijif/clocks/ltc6953.py
CHANGED
|
@@ -490,7 +490,7 @@ class ltc6953(clock):
|
|
|
490
490
|
self._setup(input_ref)
|
|
491
491
|
|
|
492
492
|
# Add requested clocks to output constraints
|
|
493
|
-
for out_freq in out_freqs:
|
|
493
|
+
for out_freq, clk_name in zip(out_freqs, clk_names): # noqa: B905
|
|
494
494
|
if self.solver == "gekko":
|
|
495
495
|
__m = self._d if isinstance(self.__m, list) else [self.__m]
|
|
496
496
|
if __m.sort() != self.m_available.sort():
|
|
@@ -503,7 +503,7 @@ class ltc6953(clock):
|
|
|
503
503
|
od = self.model.Intermediate(mp * pow(2, nx))
|
|
504
504
|
|
|
505
505
|
elif self.solver == "CPLEX":
|
|
506
|
-
od = self._convert_input(self._m, "m_"
|
|
506
|
+
od = self._convert_input(self._m, f"m_{out_freq}_{clk_name}")
|
|
507
507
|
|
|
508
508
|
self._add_equation([self.input_ref / od == out_freq])
|
|
509
509
|
self.config["out_dividers"].append(od)
|
adijif/converters/__init__.py
CHANGED
|
@@ -1,3 +1,14 @@
|
|
|
1
1
|
"""ADI JIF converter models."""
|
|
2
2
|
|
|
3
|
-
supported_parts = [
|
|
3
|
+
supported_parts = [
|
|
4
|
+
"ad9680",
|
|
5
|
+
"adrv9009_rx",
|
|
6
|
+
"adrv9009_tx",
|
|
7
|
+
"ad9081_rx",
|
|
8
|
+
"ad9081_tx",
|
|
9
|
+
"ad9082_rx",
|
|
10
|
+
"ad9082_tx",
|
|
11
|
+
"ad9144",
|
|
12
|
+
"ad9084_rx",
|
|
13
|
+
"ad9088_rx",
|
|
14
|
+
]
|
adijif/converters/ad9081.py
CHANGED
|
@@ -70,7 +70,7 @@ class ad9081_core(converter, metaclass=ABCMeta):
|
|
|
70
70
|
M_available = [1, 2, 3, 4, 6, 8, 12, 16]
|
|
71
71
|
L_available = [1, 2, 3, 4, 6, 8]
|
|
72
72
|
N_available = [12, 16]
|
|
73
|
-
Np_available = [12, 16, 24]
|
|
73
|
+
Np_available = [8, 12, 16, 24]
|
|
74
74
|
F_available = [1, 2, 3, 4, 6, 8, 12, 16, 24, 32]
|
|
75
75
|
S_available = [1, 2, 4, 8]
|
|
76
76
|
# FIXME
|
adijif/converters/ad9081_dp.py
CHANGED
|
@@ -120,11 +120,13 @@ class ad9081_dp_tx:
|
|
|
120
120
|
|
|
121
121
|
cduc_enabled = [True, True, True, True]
|
|
122
122
|
cduc_interpolation = 1
|
|
123
|
+
cduc_interpolations_available = [1, 2, 4, 6, 8, 12]
|
|
123
124
|
cduc_nco_frequencies = [0, 0, 0, 0]
|
|
124
125
|
cduc_nco_phases = [0, 0, 0, 0]
|
|
125
126
|
|
|
126
127
|
fduc_enabled = [False, False, False, False, False, False, False, False]
|
|
127
128
|
fduc_interpolation = 1
|
|
129
|
+
fduc_interpolations_available = [1, 2, 3, 4, 6, 8]
|
|
128
130
|
fduc_nco_frequencies = [0, 0, 0, 0, 0, 0, 0, 0]
|
|
129
131
|
fduc_nco_phases = [0, 0, 0, 0, 0, 0, 0, 0]
|
|
130
132
|
|
adijif/converters/ad9084.py
CHANGED
|
@@ -8,6 +8,7 @@ from .ad9084_dp import ad9084_dp_rx
|
|
|
8
8
|
from .ad9084_draw import ad9084_draw
|
|
9
9
|
from .ad9084_util import _load_rx_config_modes, apply_settings
|
|
10
10
|
from .ad9084_util import parse_json_config as parse_json_cfg
|
|
11
|
+
from .ad9088_dp import ad9088_dp_rx
|
|
11
12
|
from .adc import adc
|
|
12
13
|
from .converter import converter
|
|
13
14
|
|
|
@@ -132,7 +133,8 @@ class ad9084_core(ad9084_draw, converter, metaclass=ABCMeta):
|
|
|
132
133
|
Returns:
|
|
133
134
|
List[str]: List of strings of clock names in order
|
|
134
135
|
"""
|
|
135
|
-
|
|
136
|
+
name = "AD9084" if "9084" in self.name else "AD9088"
|
|
137
|
+
return [f"{name}_ref_clk", f"{name}_sysref"]
|
|
136
138
|
|
|
137
139
|
@property
|
|
138
140
|
@abstractmethod
|
|
@@ -280,7 +282,7 @@ class ad9084_rx(adc, ad9084_core):
|
|
|
280
282
|
sample_clock_min = 312.5e6 / 16 # FIXME
|
|
281
283
|
sample_clock_max = 20e9
|
|
282
284
|
|
|
283
|
-
quick_configuration_modes = _load_rx_config_modes()
|
|
285
|
+
quick_configuration_modes = _load_rx_config_modes(part="AD9084")
|
|
284
286
|
|
|
285
287
|
datapath = ad9084_dp_rx()
|
|
286
288
|
|
|
@@ -310,11 +312,14 @@ class ad9084_rx(adc, ad9084_core):
|
|
|
310
312
|
*args (Any): Pass through arguments
|
|
311
313
|
**kwargs (Any): Pass through keyword arguments
|
|
312
314
|
"""
|
|
313
|
-
self.sample_clock = int(2.5e9)
|
|
314
|
-
|
|
315
|
-
self.datapath.
|
|
316
|
-
self.datapath.
|
|
317
|
-
self.
|
|
315
|
+
self.sample_clock = int(2.5e9) if "AD9084" in self.name else int(1e9)
|
|
316
|
+
N = 1 if "9084" in self.name else 2
|
|
317
|
+
self.datapath.cddc_decimations = [4] * 4 * N
|
|
318
|
+
self.datapath.fddc_decimations = [2] * 8 * N
|
|
319
|
+
self.datapath.fddc_enabled = [True] * 8 * N
|
|
320
|
+
mode = "47" if "9084" in self.name else "45"
|
|
321
|
+
|
|
322
|
+
self.set_quick_configuration_mode(mode, "jesd204c")
|
|
318
323
|
|
|
319
324
|
super().__init__(*args, **kwargs)
|
|
320
325
|
self._init_diagram()
|
|
@@ -372,6 +377,23 @@ class ad9084_rx(adc, ad9084_core):
|
|
|
372
377
|
# raise Exception("Decimation not valid")
|
|
373
378
|
|
|
374
379
|
|
|
380
|
+
class ad9088_rx(ad9084_rx):
|
|
381
|
+
"""AD9088 Receive model."""
|
|
382
|
+
|
|
383
|
+
converter_type = "adc"
|
|
384
|
+
name = "AD9088_RX"
|
|
385
|
+
|
|
386
|
+
converter_clock_min = 2.9e9
|
|
387
|
+
converter_clock_max = 8e9
|
|
388
|
+
|
|
389
|
+
sample_clock_min = 2.9e9 / (6 * 24) # with max decimation
|
|
390
|
+
sample_clock_max = 8e9
|
|
391
|
+
|
|
392
|
+
datapath = ad9088_dp_rx()
|
|
393
|
+
|
|
394
|
+
quick_configuration_modes = _load_rx_config_modes(part="AD9088")
|
|
395
|
+
|
|
396
|
+
|
|
375
397
|
# class ad9084_tx(dac, ad9084_core):
|
|
376
398
|
# """AD9084 Transmit model."""
|
|
377
399
|
|
adijif/converters/ad9084_draw.py
CHANGED
|
@@ -16,7 +16,10 @@ class ad9084_draw:
|
|
|
16
16
|
self.ic_diagram_node = None
|
|
17
17
|
self._diagram_output_dividers = []
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
name = "AD9084" if "9084" in self.name else "AD9088"
|
|
20
|
+
N = 4 if "9084" in self.name else 8
|
|
21
|
+
|
|
22
|
+
self.ic_diagram_node = Node(name)
|
|
20
23
|
|
|
21
24
|
# External
|
|
22
25
|
# ref_in = Node("REF_IN", ntype="input")
|
|
@@ -28,19 +31,19 @@ class ad9084_draw:
|
|
|
28
31
|
self.ic_diagram_node.add_child(crossbar)
|
|
29
32
|
self.ic_diagram_node.add_child(crossbar_rm)
|
|
30
33
|
|
|
31
|
-
for adc in range(
|
|
34
|
+
for adc in range(N):
|
|
32
35
|
adc_node = Node(f"ADC{adc}", ntype="adc")
|
|
33
36
|
self.ic_diagram_node.add_child(adc_node)
|
|
34
37
|
adc_node.shape = "parallelogram"
|
|
35
38
|
self.ic_diagram_node.add_connection({"from": adc_node, "to": crossbar})
|
|
36
39
|
|
|
37
|
-
for cddc in range(
|
|
40
|
+
for cddc in range(N):
|
|
38
41
|
cddc_node = Node(f"CDDC{cddc}", ntype="ddc")
|
|
39
42
|
self.ic_diagram_node.add_child(cddc_node)
|
|
40
43
|
self.ic_diagram_node.add_connection({"from": crossbar, "to": cddc_node})
|
|
41
44
|
self.ic_diagram_node.add_connection({"from": cddc_node, "to": crossbar_rm})
|
|
42
45
|
|
|
43
|
-
for fddc in range(
|
|
46
|
+
for fddc in range(N * 2):
|
|
44
47
|
fddc_node = Node(f"FDDC{fddc}", ntype="ddc")
|
|
45
48
|
self.ic_diagram_node.add_child(fddc_node)
|
|
46
49
|
self.ic_diagram_node.add_connection({"from": crossbar_rm, "to": fddc_node})
|
|
@@ -48,7 +51,7 @@ class ad9084_draw:
|
|
|
48
51
|
jesd204_framer = Node("JESD204 Framer", ntype="jesd204framer")
|
|
49
52
|
self.ic_diagram_node.add_child(jesd204_framer)
|
|
50
53
|
|
|
51
|
-
for ddc in range(
|
|
54
|
+
for ddc in range(N * 2):
|
|
52
55
|
fddc = self.ic_diagram_node.get_child(f"FDDC{ddc}")
|
|
53
56
|
self.ic_diagram_node.add_connection({"from": fddc, "to": jesd204_framer})
|
|
54
57
|
|
|
@@ -97,8 +100,11 @@ class ad9084_draw:
|
|
|
97
100
|
|
|
98
101
|
system_draw = lo is not None
|
|
99
102
|
|
|
103
|
+
name = "AD9084" if "9084" in self.name else "AD9088"
|
|
104
|
+
N = 4 if "9084" in self.name else 8
|
|
105
|
+
|
|
100
106
|
if not system_draw:
|
|
101
|
-
lo = Layout("
|
|
107
|
+
lo = Layout(f"{name} Example")
|
|
102
108
|
lo.show_rates = self.show_rates
|
|
103
109
|
else:
|
|
104
110
|
# Verify lo is a Layout object
|
|
@@ -109,7 +115,7 @@ class ad9084_draw:
|
|
|
109
115
|
ref_in = Node("REF_IN", ntype="input")
|
|
110
116
|
lo.add_node(ref_in)
|
|
111
117
|
else:
|
|
112
|
-
to_node = lo.get_node("
|
|
118
|
+
to_node = lo.get_node(f"{name}_ref_clk")
|
|
113
119
|
# Locate node connected to this one
|
|
114
120
|
from_node = lo.get_connection(to=to_node.name)
|
|
115
121
|
assert from_node, "No connection found"
|
|
@@ -119,16 +125,16 @@ class ad9084_draw:
|
|
|
119
125
|
# Remove to_node since it is not needed
|
|
120
126
|
lo.remove_node(to_node.name)
|
|
121
127
|
|
|
122
|
-
for i in range(
|
|
128
|
+
for i in range(N):
|
|
123
129
|
adc = self.ic_diagram_node.get_child(f"ADC{i}")
|
|
124
130
|
lo.add_connection(
|
|
125
|
-
{"from": ref_in, "to": adc, "rate": clocks["
|
|
131
|
+
{"from": ref_in, "to": adc, "rate": clocks[f"{name}_ref_clk"]}
|
|
126
132
|
)
|
|
127
133
|
|
|
128
134
|
# Update Node values
|
|
129
135
|
fddc_index = 0
|
|
130
|
-
for cddc in range(
|
|
131
|
-
rate = clocks["
|
|
136
|
+
for cddc in range(N):
|
|
137
|
+
rate = clocks[f"{name}_ref_clk"]
|
|
132
138
|
self.ic_diagram_node.update_connection("MUX0", f"CDDC{cddc}", rate)
|
|
133
139
|
|
|
134
140
|
cddc_node = self.ic_diagram_node.get_child(f"CDDC{cddc}")
|
|
@@ -163,11 +169,11 @@ class ad9084_draw:
|
|
|
163
169
|
{
|
|
164
170
|
"from": sysref_in,
|
|
165
171
|
"to": self.ic_diagram_node.get_child("JESD204 Framer"),
|
|
166
|
-
"rate": clocks["
|
|
172
|
+
"rate": clocks[f"{name}_sysref"],
|
|
167
173
|
}
|
|
168
174
|
)
|
|
169
175
|
else:
|
|
170
|
-
to_node = lo.get_node("
|
|
176
|
+
to_node = lo.get_node(f"{name}_sysref")
|
|
171
177
|
# Locate node connected to this one
|
|
172
178
|
from_node = lo.get_connection(to=to_node.name)
|
|
173
179
|
assert from_node, "No connection found"
|
|
@@ -181,7 +187,7 @@ class ad9084_draw:
|
|
|
181
187
|
{
|
|
182
188
|
"from": sysref_in,
|
|
183
189
|
"to": self.ic_diagram_node.get_child("JESD204 Framer"),
|
|
184
|
-
"rate": clocks["
|
|
190
|
+
"rate": clocks[f"{name}_sysref"],
|
|
185
191
|
}
|
|
186
192
|
)
|
|
187
193
|
|
adijif/converters/ad9084_util.py
CHANGED
|
@@ -41,12 +41,23 @@ def _convert_to_config(
|
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
|
|
44
|
-
def _load_rx_config_modes() -> Dict:
|
|
45
|
-
"""Load RX JESD configuration tables from file.
|
|
46
|
-
|
|
44
|
+
def _load_rx_config_modes(part: str) -> Dict:
|
|
45
|
+
"""Load RX JESD configuration tables from file.
|
|
46
|
+
|
|
47
|
+
Args:
|
|
48
|
+
part (str): Part name, either "AD9084" or "AD9088".
|
|
49
|
+
|
|
50
|
+
Returns:
|
|
51
|
+
Dict: Dictionary of JESD configuration modes.
|
|
52
|
+
|
|
53
|
+
Raises:
|
|
54
|
+
AssertionError: If the part is not supported.
|
|
55
|
+
"""
|
|
56
|
+
assert part in ["AD9084", "AD9088"], f"Unsupported part: {part}"
|
|
57
|
+
return _read_table_xlsx("AD9084_JTX_JRX.xlsx", part)
|
|
47
58
|
|
|
48
59
|
|
|
49
|
-
def _read_table_xlsx(filename: str) -> Dict:
|
|
60
|
+
def _read_table_xlsx(filename: str, part: str) -> Dict:
|
|
50
61
|
loc = os.path.dirname(__file__)
|
|
51
62
|
fn = os.path.join(loc, "resources", filename)
|
|
52
63
|
table = pd.read_excel(open(fn, "rb"), sheet_name="JTX_RxPath")
|
|
@@ -57,7 +68,15 @@ def _read_table_xlsx(filename: str) -> Dict:
|
|
|
57
68
|
jrx_modes_204c = {}
|
|
58
69
|
for prow in table.iterrows():
|
|
59
70
|
row = prow[1].to_dict()
|
|
60
|
-
|
|
71
|
+
|
|
72
|
+
field = "8T8R" if part == "AD9088" else "4T4R"
|
|
73
|
+
data = str(row[field])
|
|
74
|
+
|
|
75
|
+
if "nan" in data:
|
|
76
|
+
continue
|
|
77
|
+
if "Not Supported" in data:
|
|
78
|
+
continue
|
|
79
|
+
|
|
61
80
|
jrx_modes_204c[str(row["Mode"])] = {
|
|
62
81
|
"L": row["L"],
|
|
63
82
|
"M": row["M"],
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
"""AD9088 Datapath Description Class."""
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class ad9088_dp_rx:
|
|
5
|
+
"""AD9088 RX Data Path Configuration."""
|
|
6
|
+
|
|
7
|
+
cddc_enabled = [True, True, True, True]
|
|
8
|
+
cddc_decimations = [1, 1, 1, 1, 1, 1, 1, 1]
|
|
9
|
+
cddc_decimations_available = [1, 2, 3, 4, 6, 12]
|
|
10
|
+
cddc_nco_frequencies = [0, 0, 0, 0, 0, 0, 0, 0]
|
|
11
|
+
cddc_nco_phases = [0, 0, 0, 0, 0, 0, 0, 0]
|
|
12
|
+
|
|
13
|
+
fddc_enabled = [False] * 16
|
|
14
|
+
fddc_decimations = [1] * 16
|
|
15
|
+
fddc_decimations_available = [1, 2, 4, 8, 16, 32, 64]
|
|
16
|
+
fddc_nco_frequencies = [0] * 16
|
|
17
|
+
fddc_nco_phases = [0] * 16
|
|
18
|
+
|
|
19
|
+
fddc_source = [1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8]
|
|
20
|
+
|
|
21
|
+
def get_config(self) -> dict:
|
|
22
|
+
"""Get the datapath configuration for the AD9088 RX.
|
|
23
|
+
|
|
24
|
+
Returns:
|
|
25
|
+
dict: datapath configuration
|
|
26
|
+
"""
|
|
27
|
+
datapath = {}
|
|
28
|
+
datapath["cddc"] = {}
|
|
29
|
+
datapath["cddc"]["enabled"] = self.cddc_enabled
|
|
30
|
+
datapath["cddc"]["decimations"] = self.cddc_decimations
|
|
31
|
+
datapath["cddc"]["nco_frequencies"] = self.cddc_nco_frequencies
|
|
32
|
+
datapath["cddc"]["nco_phases"] = self.cddc_nco_phases
|
|
33
|
+
|
|
34
|
+
datapath["fddc"] = {}
|
|
35
|
+
datapath["fddc"]["enabled"] = self.fddc_enabled
|
|
36
|
+
datapath["fddc"]["decimations"] = self.fddc_decimations
|
|
37
|
+
datapath["fddc"]["nco_frequencies"] = self.fddc_nco_frequencies
|
|
38
|
+
datapath["fddc"]["nco_phases"] = self.fddc_nco_phases
|
|
39
|
+
datapath["fddc"]["source"] = self.fddc_source
|
|
40
|
+
|
|
41
|
+
return datapath
|
|
42
|
+
|
|
43
|
+
@property
|
|
44
|
+
def decimation_overall(self) -> int:
|
|
45
|
+
"""Minimum Overall Decimation factor.
|
|
46
|
+
|
|
47
|
+
Raises:
|
|
48
|
+
Exception: No FDDC or CDDC enabled
|
|
49
|
+
Exception: Enabled FDDC's source CDDC not enabled
|
|
50
|
+
|
|
51
|
+
Returns:
|
|
52
|
+
int: minimum overall decimation factor
|
|
53
|
+
"""
|
|
54
|
+
if (not any(self.fddc_enabled)) and (not any(self.cddc_enabled)):
|
|
55
|
+
raise Exception("No FDDCs or CDDCs enabled")
|
|
56
|
+
|
|
57
|
+
if any(self.fddc_enabled):
|
|
58
|
+
min_dec = -1
|
|
59
|
+
for i, fdec in enumerate(self.fddc_decimations):
|
|
60
|
+
if self.fddc_enabled[i]:
|
|
61
|
+
cddc = self.fddc_source[i]
|
|
62
|
+
if not self.cddc_enabled:
|
|
63
|
+
raise Exception(f"Source CDDC {cddc} not enabled for FDDC {i}")
|
|
64
|
+
cdec = self.cddc_decimations[cddc - 1]
|
|
65
|
+
if (cdec * fdec < min_dec) or min_dec == -1:
|
|
66
|
+
min_dec = cdec * fdec
|
|
67
|
+
else:
|
|
68
|
+
min_dec = -1
|
|
69
|
+
for i, cdec in enumerate(self.cddc_decimations):
|
|
70
|
+
if self.cddc_enabled[i] and (min_dec == -1 or cdec < min_dec):
|
|
71
|
+
min_dec = cdec
|
|
72
|
+
|
|
73
|
+
return min_dec
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
# class ad9088_dp_tx:
|
|
77
|
+
# """AD9088 TX Data Path Configuration."""
|
|
78
|
+
|
|
79
|
+
# cduc_enabled = [True, True, True, True]
|
|
80
|
+
# cduc_interpolation = 1
|
|
81
|
+
# cduc_nco_frequencies = [0, 0, 0, 0]
|
|
82
|
+
# cduc_nco_phases = [0, 0, 0, 0]
|
|
83
|
+
|
|
84
|
+
# fduc_enabled = [False, False, False, False, False, False, False, False]
|
|
85
|
+
# fduc_interpolation = 1
|
|
86
|
+
# fduc_nco_frequencies = [0, 0, 0, 0, 0, 0, 0, 0]
|
|
87
|
+
# fduc_nco_phases = [0, 0, 0, 0, 0, 0, 0, 0]
|
|
88
|
+
|
|
89
|
+
# cduc_sources = [[1], [1], [3], [3]]
|
|
90
|
+
|
|
91
|
+
# def get_config(self) -> dict:
|
|
92
|
+
# """Get the datapath configuration for the AD9088 TX.
|
|
93
|
+
|
|
94
|
+
# Returns:
|
|
95
|
+
# dict: Datapath configuration
|
|
96
|
+
# """
|
|
97
|
+
# datapath = {}
|
|
98
|
+
# datapath["cduc"] = {}
|
|
99
|
+
# datapath["cduc"]["enabled"] = self.cduc_enabled
|
|
100
|
+
# datapath["cduc"]["interpolation"] = self.cduc_interpolation
|
|
101
|
+
# datapath["cduc"]["nco_frequencies"] = self.cduc_nco_frequencies
|
|
102
|
+
# datapath["cduc"]["nco_phases"] = self.cduc_nco_phases
|
|
103
|
+
# datapath["cduc"]["sources"] = self.cduc_sources
|
|
104
|
+
|
|
105
|
+
# datapath["fduc"] = {}
|
|
106
|
+
# datapath["fduc"]["enabled"] = self.fduc_enabled
|
|
107
|
+
# datapath["fduc"]["interpolation"] = self.fduc_interpolation
|
|
108
|
+
# datapath["fduc"]["nco_frequencies"] = self.fduc_nco_frequencies
|
|
109
|
+
# datapath["fduc"]["nco_phases"] = self.fduc_nco_phases
|
|
110
|
+
|
|
111
|
+
# return datapath
|