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,67 @@
|
|
|
1
|
+
# flake8: noqa
|
|
2
|
+
import numpy as np
|
|
3
|
+
|
|
4
|
+
from adijif.clocks.clock import clock
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class ltc6952_bf(clock):
|
|
8
|
+
"""Brute force methods for calculating clocks
|
|
9
|
+
|
|
10
|
+
These are currently meant for debug to compare against
|
|
11
|
+
the solver solutions
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
def list_available_references(self, divider_set):
|
|
15
|
+
"""list_available_references: Based on config list possible
|
|
16
|
+
references that can be generated based on VCO and output
|
|
17
|
+
dividers
|
|
18
|
+
"""
|
|
19
|
+
# Check input
|
|
20
|
+
ref = {
|
|
21
|
+
"n2": 2,
|
|
22
|
+
"vco": 3000000000,
|
|
23
|
+
"r2": 24,
|
|
24
|
+
"required_output_divs": np.array([1.0]),
|
|
25
|
+
}
|
|
26
|
+
for key in ref:
|
|
27
|
+
if key not in divider_set:
|
|
28
|
+
raise Exception(
|
|
29
|
+
"Input must be of type dict with fields: " + str(ref.keys())
|
|
30
|
+
)
|
|
31
|
+
return [divider_set["vco"] / div for div in self.d_available]
|
|
32
|
+
|
|
33
|
+
def find_dividers(self, vcxo, rates, find=3):
|
|
34
|
+
v = []
|
|
35
|
+
for mp in range(0, 32):
|
|
36
|
+
for nx in range(0, 8):
|
|
37
|
+
val = (mp + 1) * pow(2, nx)
|
|
38
|
+
v.append(val)
|
|
39
|
+
|
|
40
|
+
odivs = np.unique(v)
|
|
41
|
+
|
|
42
|
+
mod = np.gcd.reduce(np.array(rates, dtype=int))
|
|
43
|
+
vcos = []
|
|
44
|
+
configs = []
|
|
45
|
+
|
|
46
|
+
for n in range(self.n2_divider_min, self.n2_divider_max):
|
|
47
|
+
for r in range(self.r2_divider_min, self.r2_divider_max):
|
|
48
|
+
# Check VCO in range and output clock a multiple of required reference
|
|
49
|
+
f = vcxo * n / r
|
|
50
|
+
if f >= self.vco_min and f <= self.vco_max:
|
|
51
|
+
# Check if required dividers for output clocks are in set
|
|
52
|
+
if f % mod == 0:
|
|
53
|
+
d = f / rates
|
|
54
|
+
if np.all(np.in1d(d, odivs)) and f not in vcos:
|
|
55
|
+
if f not in vcos:
|
|
56
|
+
vcos.append(f)
|
|
57
|
+
config = {
|
|
58
|
+
"n2": n,
|
|
59
|
+
"r2": r,
|
|
60
|
+
"vco": f,
|
|
61
|
+
"required_output_divs": d,
|
|
62
|
+
}
|
|
63
|
+
configs.append(config)
|
|
64
|
+
if len(configs) >= find:
|
|
65
|
+
return configs
|
|
66
|
+
|
|
67
|
+
return configs
|
adijif/clocks/ltc6953.py
ADDED
|
@@ -0,0 +1,509 @@
|
|
|
1
|
+
"""LTC6953 clock chip model."""
|
|
2
|
+
|
|
3
|
+
from typing import Dict, List, Union
|
|
4
|
+
|
|
5
|
+
from docplex.cp.solution import CpoSolveResult # type: ignore
|
|
6
|
+
|
|
7
|
+
from adijif.clocks.clock import clock
|
|
8
|
+
from adijif.solvers import CpoExpr, GK_Intermediate
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class ltc6953(clock):
|
|
12
|
+
"""LTC6953 clock chip model.
|
|
13
|
+
|
|
14
|
+
This model currently supports all divider configurations
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
name = "LTC6953"
|
|
18
|
+
|
|
19
|
+
input_ref = 1000000000
|
|
20
|
+
|
|
21
|
+
# Ranges
|
|
22
|
+
m_divider_min = 1
|
|
23
|
+
m_divider_max = 1023
|
|
24
|
+
m_available = [
|
|
25
|
+
1,
|
|
26
|
+
2,
|
|
27
|
+
3,
|
|
28
|
+
4,
|
|
29
|
+
5,
|
|
30
|
+
6,
|
|
31
|
+
7,
|
|
32
|
+
8,
|
|
33
|
+
9,
|
|
34
|
+
10,
|
|
35
|
+
11,
|
|
36
|
+
12,
|
|
37
|
+
13,
|
|
38
|
+
14,
|
|
39
|
+
15,
|
|
40
|
+
16,
|
|
41
|
+
17,
|
|
42
|
+
18,
|
|
43
|
+
19,
|
|
44
|
+
20,
|
|
45
|
+
21,
|
|
46
|
+
22,
|
|
47
|
+
23,
|
|
48
|
+
24,
|
|
49
|
+
25,
|
|
50
|
+
26,
|
|
51
|
+
27,
|
|
52
|
+
28,
|
|
53
|
+
29,
|
|
54
|
+
30,
|
|
55
|
+
31,
|
|
56
|
+
32,
|
|
57
|
+
34,
|
|
58
|
+
36,
|
|
59
|
+
38,
|
|
60
|
+
40,
|
|
61
|
+
42,
|
|
62
|
+
44,
|
|
63
|
+
46,
|
|
64
|
+
48,
|
|
65
|
+
50,
|
|
66
|
+
52,
|
|
67
|
+
54,
|
|
68
|
+
56,
|
|
69
|
+
58,
|
|
70
|
+
60,
|
|
71
|
+
62,
|
|
72
|
+
64,
|
|
73
|
+
68,
|
|
74
|
+
72,
|
|
75
|
+
76,
|
|
76
|
+
80,
|
|
77
|
+
84,
|
|
78
|
+
88,
|
|
79
|
+
92,
|
|
80
|
+
96,
|
|
81
|
+
100,
|
|
82
|
+
104,
|
|
83
|
+
108,
|
|
84
|
+
112,
|
|
85
|
+
116,
|
|
86
|
+
120,
|
|
87
|
+
124,
|
|
88
|
+
128,
|
|
89
|
+
136,
|
|
90
|
+
144,
|
|
91
|
+
152,
|
|
92
|
+
160,
|
|
93
|
+
168,
|
|
94
|
+
176,
|
|
95
|
+
184,
|
|
96
|
+
192,
|
|
97
|
+
200,
|
|
98
|
+
208,
|
|
99
|
+
216,
|
|
100
|
+
224,
|
|
101
|
+
232,
|
|
102
|
+
240,
|
|
103
|
+
248,
|
|
104
|
+
256,
|
|
105
|
+
272,
|
|
106
|
+
288,
|
|
107
|
+
304,
|
|
108
|
+
320,
|
|
109
|
+
336,
|
|
110
|
+
352,
|
|
111
|
+
368,
|
|
112
|
+
384,
|
|
113
|
+
400,
|
|
114
|
+
416,
|
|
115
|
+
432,
|
|
116
|
+
448,
|
|
117
|
+
464,
|
|
118
|
+
480,
|
|
119
|
+
496,
|
|
120
|
+
512,
|
|
121
|
+
544,
|
|
122
|
+
576,
|
|
123
|
+
608,
|
|
124
|
+
640,
|
|
125
|
+
672,
|
|
126
|
+
704,
|
|
127
|
+
736,
|
|
128
|
+
768,
|
|
129
|
+
800,
|
|
130
|
+
832,
|
|
131
|
+
864,
|
|
132
|
+
896,
|
|
133
|
+
928,
|
|
134
|
+
960,
|
|
135
|
+
992,
|
|
136
|
+
1024,
|
|
137
|
+
1088,
|
|
138
|
+
1152,
|
|
139
|
+
1216,
|
|
140
|
+
1280,
|
|
141
|
+
1344,
|
|
142
|
+
1408,
|
|
143
|
+
1472,
|
|
144
|
+
1536,
|
|
145
|
+
1600,
|
|
146
|
+
1664,
|
|
147
|
+
1728,
|
|
148
|
+
1792,
|
|
149
|
+
1856,
|
|
150
|
+
1920,
|
|
151
|
+
1984,
|
|
152
|
+
2048,
|
|
153
|
+
2176,
|
|
154
|
+
2304,
|
|
155
|
+
2432,
|
|
156
|
+
2560,
|
|
157
|
+
2688,
|
|
158
|
+
2816,
|
|
159
|
+
2944,
|
|
160
|
+
3072,
|
|
161
|
+
3200,
|
|
162
|
+
3328,
|
|
163
|
+
3456,
|
|
164
|
+
3584,
|
|
165
|
+
3712,
|
|
166
|
+
3840,
|
|
167
|
+
3968,
|
|
168
|
+
4096,
|
|
169
|
+
]
|
|
170
|
+
|
|
171
|
+
""" Output dividers """
|
|
172
|
+
|
|
173
|
+
# Defaults
|
|
174
|
+
_m: Union[int, List[int]] = [
|
|
175
|
+
1,
|
|
176
|
+
2,
|
|
177
|
+
3,
|
|
178
|
+
4,
|
|
179
|
+
5,
|
|
180
|
+
6,
|
|
181
|
+
7,
|
|
182
|
+
8,
|
|
183
|
+
9,
|
|
184
|
+
10,
|
|
185
|
+
11,
|
|
186
|
+
12,
|
|
187
|
+
13,
|
|
188
|
+
14,
|
|
189
|
+
15,
|
|
190
|
+
16,
|
|
191
|
+
17,
|
|
192
|
+
18,
|
|
193
|
+
19,
|
|
194
|
+
20,
|
|
195
|
+
21,
|
|
196
|
+
22,
|
|
197
|
+
23,
|
|
198
|
+
24,
|
|
199
|
+
25,
|
|
200
|
+
26,
|
|
201
|
+
27,
|
|
202
|
+
28,
|
|
203
|
+
29,
|
|
204
|
+
30,
|
|
205
|
+
31,
|
|
206
|
+
32,
|
|
207
|
+
34,
|
|
208
|
+
36,
|
|
209
|
+
38,
|
|
210
|
+
40,
|
|
211
|
+
42,
|
|
212
|
+
44,
|
|
213
|
+
46,
|
|
214
|
+
48,
|
|
215
|
+
50,
|
|
216
|
+
52,
|
|
217
|
+
54,
|
|
218
|
+
56,
|
|
219
|
+
58,
|
|
220
|
+
60,
|
|
221
|
+
62,
|
|
222
|
+
64,
|
|
223
|
+
68,
|
|
224
|
+
72,
|
|
225
|
+
76,
|
|
226
|
+
80,
|
|
227
|
+
84,
|
|
228
|
+
88,
|
|
229
|
+
92,
|
|
230
|
+
96,
|
|
231
|
+
100,
|
|
232
|
+
104,
|
|
233
|
+
108,
|
|
234
|
+
112,
|
|
235
|
+
116,
|
|
236
|
+
120,
|
|
237
|
+
124,
|
|
238
|
+
128,
|
|
239
|
+
136,
|
|
240
|
+
144,
|
|
241
|
+
152,
|
|
242
|
+
160,
|
|
243
|
+
168,
|
|
244
|
+
176,
|
|
245
|
+
184,
|
|
246
|
+
192,
|
|
247
|
+
200,
|
|
248
|
+
208,
|
|
249
|
+
216,
|
|
250
|
+
224,
|
|
251
|
+
232,
|
|
252
|
+
240,
|
|
253
|
+
248,
|
|
254
|
+
256,
|
|
255
|
+
272,
|
|
256
|
+
288,
|
|
257
|
+
304,
|
|
258
|
+
320,
|
|
259
|
+
336,
|
|
260
|
+
352,
|
|
261
|
+
368,
|
|
262
|
+
384,
|
|
263
|
+
400,
|
|
264
|
+
416,
|
|
265
|
+
432,
|
|
266
|
+
448,
|
|
267
|
+
464,
|
|
268
|
+
480,
|
|
269
|
+
496,
|
|
270
|
+
512,
|
|
271
|
+
544,
|
|
272
|
+
576,
|
|
273
|
+
608,
|
|
274
|
+
640,
|
|
275
|
+
672,
|
|
276
|
+
704,
|
|
277
|
+
736,
|
|
278
|
+
768,
|
|
279
|
+
800,
|
|
280
|
+
832,
|
|
281
|
+
864,
|
|
282
|
+
896,
|
|
283
|
+
928,
|
|
284
|
+
960,
|
|
285
|
+
992,
|
|
286
|
+
1024,
|
|
287
|
+
1088,
|
|
288
|
+
1152,
|
|
289
|
+
1216,
|
|
290
|
+
1280,
|
|
291
|
+
1344,
|
|
292
|
+
1408,
|
|
293
|
+
1472,
|
|
294
|
+
1536,
|
|
295
|
+
1600,
|
|
296
|
+
1664,
|
|
297
|
+
1728,
|
|
298
|
+
1792,
|
|
299
|
+
1856,
|
|
300
|
+
1920,
|
|
301
|
+
1984,
|
|
302
|
+
2048,
|
|
303
|
+
2176,
|
|
304
|
+
2304,
|
|
305
|
+
2432,
|
|
306
|
+
2560,
|
|
307
|
+
2688,
|
|
308
|
+
2816,
|
|
309
|
+
2944,
|
|
310
|
+
3072,
|
|
311
|
+
3200,
|
|
312
|
+
3328,
|
|
313
|
+
3456,
|
|
314
|
+
3584,
|
|
315
|
+
3712,
|
|
316
|
+
3840,
|
|
317
|
+
3968,
|
|
318
|
+
4096,
|
|
319
|
+
]
|
|
320
|
+
|
|
321
|
+
# Limits
|
|
322
|
+
""" Internal limits """
|
|
323
|
+
input_freq_max = 4.5e9
|
|
324
|
+
|
|
325
|
+
# State management
|
|
326
|
+
_clk_names: List[str] = []
|
|
327
|
+
|
|
328
|
+
@property
|
|
329
|
+
def m(self) -> Union[int, List[int]]:
|
|
330
|
+
"""Output dividers.
|
|
331
|
+
|
|
332
|
+
Valid dividers are 1,2,3,4,5,6..32->(even)->4096
|
|
333
|
+
|
|
334
|
+
Returns:
|
|
335
|
+
int: Current allowable dividers
|
|
336
|
+
"""
|
|
337
|
+
return self._d
|
|
338
|
+
|
|
339
|
+
@m.setter
|
|
340
|
+
def m(self, value: Union[int, List[int]]) -> None:
|
|
341
|
+
"""Output dividers.
|
|
342
|
+
|
|
343
|
+
Valid dividers are 1,2,3,4,5,6..32->(even)->4096
|
|
344
|
+
|
|
345
|
+
Args:
|
|
346
|
+
value (int, list[int]): Allowable values for divider
|
|
347
|
+
|
|
348
|
+
"""
|
|
349
|
+
self._check_in_range(value, self.m_available, "d")
|
|
350
|
+
self._d = value
|
|
351
|
+
|
|
352
|
+
def find_dividers(self) -> Dict:
|
|
353
|
+
"""Find the best dividers for the current configuration.
|
|
354
|
+
|
|
355
|
+
NOT IMPLEMENTED YET
|
|
356
|
+
|
|
357
|
+
Raises:
|
|
358
|
+
NotImplementedError: Not implemented yet
|
|
359
|
+
"""
|
|
360
|
+
raise NotImplementedError("find_dividers not implemented")
|
|
361
|
+
|
|
362
|
+
def list_available_references(self) -> List[int]:
|
|
363
|
+
"""List the available reference frequencies.
|
|
364
|
+
|
|
365
|
+
NOT IMPLEMENTED YET
|
|
366
|
+
|
|
367
|
+
Raises:
|
|
368
|
+
NotImplementedError: Not implemented yet
|
|
369
|
+
"""
|
|
370
|
+
raise NotImplementedError("list_available_references not implemented")
|
|
371
|
+
|
|
372
|
+
def get_config(self, solution: CpoSolveResult = None) -> Dict:
|
|
373
|
+
"""Extract configurations from solver results.
|
|
374
|
+
|
|
375
|
+
Collect internal clock chip configuration and output clock definitions
|
|
376
|
+
leading to connected devices (converters, FPGAs)
|
|
377
|
+
|
|
378
|
+
Args:
|
|
379
|
+
solution (CpoSolveResult): CPlex solution. Only needed for CPlex solver
|
|
380
|
+
|
|
381
|
+
Returns:
|
|
382
|
+
Dict: Dictionary of clocking rates and dividers for configuration
|
|
383
|
+
|
|
384
|
+
Raises:
|
|
385
|
+
Exception: If solver is not called first
|
|
386
|
+
"""
|
|
387
|
+
if not self._clk_names:
|
|
388
|
+
raise Exception("set_requested_clocks must be called before get_config")
|
|
389
|
+
|
|
390
|
+
if solution:
|
|
391
|
+
self.solution = solution
|
|
392
|
+
|
|
393
|
+
out_dividers = [self._get_val(x) for x in self.config["out_dividers"]]
|
|
394
|
+
|
|
395
|
+
config: Dict = {
|
|
396
|
+
"out_dividers": out_dividers,
|
|
397
|
+
"output_clocks": [],
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
config["input_ref"] = self._get_val(
|
|
401
|
+
self.input_ref
|
|
402
|
+
) # pytype: disable=attribute-error
|
|
403
|
+
|
|
404
|
+
output_cfg = {}
|
|
405
|
+
for i, div in enumerate(out_dividers):
|
|
406
|
+
rate = config["input_ref"] / div # type: ignore # noqa: B950
|
|
407
|
+
output_cfg[self._clk_names[i]] = {"rate": rate, "divider": div}
|
|
408
|
+
|
|
409
|
+
config["output_clocks"] = output_cfg
|
|
410
|
+
|
|
411
|
+
self._saved_solution = config
|
|
412
|
+
|
|
413
|
+
return config
|
|
414
|
+
|
|
415
|
+
def _setup_solver_constraints(self, input_ref: int) -> None:
|
|
416
|
+
"""Apply constraints to solver model.
|
|
417
|
+
|
|
418
|
+
Args:
|
|
419
|
+
input_ref (int): Input reference frequency in hertz
|
|
420
|
+
"""
|
|
421
|
+
self.config = {}
|
|
422
|
+
if not isinstance(input_ref, (int, float)):
|
|
423
|
+
self.config["input_ref_set"] = input_ref(self.model) # type: ignore
|
|
424
|
+
input_ref = self.config["input_ref_set"]["range"]
|
|
425
|
+
self.input_ref = input_ref
|
|
426
|
+
|
|
427
|
+
self._add_equation(
|
|
428
|
+
[
|
|
429
|
+
input_ref <= self.input_freq_max,
|
|
430
|
+
]
|
|
431
|
+
)
|
|
432
|
+
|
|
433
|
+
def _setup(self, input_ref: int) -> None:
|
|
434
|
+
if isinstance(input_ref, (float, int)):
|
|
435
|
+
assert self.input_freq_max >= input_ref >= 0, "Input frequency out of range"
|
|
436
|
+
|
|
437
|
+
# Setup clock chip internal constraints
|
|
438
|
+
self._setup_solver_constraints(input_ref)
|
|
439
|
+
|
|
440
|
+
# Add requested clocks to output constraints
|
|
441
|
+
self.config["out_dividers"] = []
|
|
442
|
+
|
|
443
|
+
def _get_clock_constraint(
|
|
444
|
+
self, clk_name: List[str]
|
|
445
|
+
) -> Union[int, float, CpoExpr, GK_Intermediate]:
|
|
446
|
+
"""Get abstract clock output.
|
|
447
|
+
|
|
448
|
+
Args:
|
|
449
|
+
clk_name (str): String of clock name
|
|
450
|
+
|
|
451
|
+
Returns:
|
|
452
|
+
(int or float or CpoExpr or GK_Intermediate): Abstract
|
|
453
|
+
or concrete clock reference
|
|
454
|
+
|
|
455
|
+
Raises:
|
|
456
|
+
Exception: Invalid solver
|
|
457
|
+
"""
|
|
458
|
+
if self.solver == "gekko":
|
|
459
|
+
__m = self._m if isinstance(self._m, list) else [self._m]
|
|
460
|
+
if __m.sort() != self.m_available.sort():
|
|
461
|
+
raise Exception("For solver gekko d is not configurable for LTC6952")
|
|
462
|
+
mp = self.model.Var(integer=True, lb=1, ub=32)
|
|
463
|
+
nx = self.model.Var(integer=True, lb=0, ub=7)
|
|
464
|
+
od = self.model.Intermediate(mp * pow(2, nx))
|
|
465
|
+
elif self.solver == "CPLEX":
|
|
466
|
+
od = self._convert_input(self._m, f"m_{clk_name}")
|
|
467
|
+
else:
|
|
468
|
+
raise Exception("Unknown solver {}".format(self.solver))
|
|
469
|
+
self.config["out_dividers"].append(od)
|
|
470
|
+
return self.input_ref / od
|
|
471
|
+
|
|
472
|
+
def set_requested_clocks(
|
|
473
|
+
self, input_ref: int, out_freqs: List, clk_names: List[str]
|
|
474
|
+
) -> None:
|
|
475
|
+
"""Define necessary clocks to be generated in model.
|
|
476
|
+
|
|
477
|
+
Args:
|
|
478
|
+
input_ref (int): Input reference frequency in hertz
|
|
479
|
+
out_freqs (List): list of required clocks to be output
|
|
480
|
+
clk_names (List[str]): list of strings of clock names
|
|
481
|
+
|
|
482
|
+
Raises:
|
|
483
|
+
Exception: If len(out_freqs) != len(clk_names)
|
|
484
|
+
"""
|
|
485
|
+
if len(clk_names) != len(out_freqs):
|
|
486
|
+
raise Exception("clk_names is not the same size as out_freqs")
|
|
487
|
+
self._clk_names = clk_names
|
|
488
|
+
|
|
489
|
+
# Setup clock chip internal constraints
|
|
490
|
+
self._setup(input_ref)
|
|
491
|
+
|
|
492
|
+
# Add requested clocks to output constraints
|
|
493
|
+
for out_freq in out_freqs:
|
|
494
|
+
if self.solver == "gekko":
|
|
495
|
+
__m = self._d if isinstance(self.__m, list) else [self.__m]
|
|
496
|
+
if __m.sort() != self.m_available.sort():
|
|
497
|
+
raise Exception(
|
|
498
|
+
"For solver gekko m is not configurable for LTC6953"
|
|
499
|
+
)
|
|
500
|
+
|
|
501
|
+
mp = self.model.Var(integer=True, lb=1, ub=32)
|
|
502
|
+
nx = self.model.Var(integer=True, lb=0, ub=7)
|
|
503
|
+
od = self.model.Intermediate(mp * pow(2, nx))
|
|
504
|
+
|
|
505
|
+
elif self.solver == "CPLEX":
|
|
506
|
+
od = self._convert_input(self._m, "m_" + str(out_freq))
|
|
507
|
+
|
|
508
|
+
self._add_equation([self.input_ref / od == out_freq])
|
|
509
|
+
self.config["out_dividers"].append(od)
|
adijif/common.py
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"""Common class for all JIF components."""
|
|
2
|
+
|
|
3
|
+
from typing import List, Union
|
|
4
|
+
|
|
5
|
+
from adijif.solvers import CpoModel # noqa: BLK100
|
|
6
|
+
from adijif.solvers import GK_Operators # noqa: BLK100
|
|
7
|
+
from adijif.solvers import GEKKO, CpoExpr, GK_Intermediate, GKVariable
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class core:
|
|
11
|
+
"""Common class for all JIF components.
|
|
12
|
+
|
|
13
|
+
This is the central point for all classes in module
|
|
14
|
+
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
solver = "CPLEX" # "CPLEX"
|
|
18
|
+
|
|
19
|
+
_objectives = []
|
|
20
|
+
|
|
21
|
+
def _add_objective(
|
|
22
|
+
self,
|
|
23
|
+
objective: List[Union[GKVariable, GK_Intermediate, GK_Operators, CpoExpr]],
|
|
24
|
+
) -> None:
|
|
25
|
+
if isinstance(objective, list):
|
|
26
|
+
self._objectives += objective
|
|
27
|
+
else:
|
|
28
|
+
self._objectives.append(objective)
|
|
29
|
+
|
|
30
|
+
def __init__(
|
|
31
|
+
self, model: Union[GEKKO, CpoModel] = None, solver: str = None
|
|
32
|
+
) -> None:
|
|
33
|
+
"""Initalize clocking model.
|
|
34
|
+
|
|
35
|
+
When usings the clocking models standalone, typically for
|
|
36
|
+
validation flows, a solver model is created internally.
|
|
37
|
+
For system level work, a shared model is passed.
|
|
38
|
+
|
|
39
|
+
Args:
|
|
40
|
+
model (GEKKO,CpoModel): Solver model
|
|
41
|
+
solver (str): Solver name (gekko or CPLEX)
|
|
42
|
+
|
|
43
|
+
Raises:
|
|
44
|
+
Exception: If solver is not valid
|
|
45
|
+
"""
|
|
46
|
+
self._saved_solution = None
|
|
47
|
+
self._objectives = []
|
|
48
|
+
self._solution = None
|
|
49
|
+
self.configs = [] # type: List[dict]
|
|
50
|
+
if hasattr(self, "_init_diagram"):
|
|
51
|
+
self._init_diagram()
|
|
52
|
+
if solver:
|
|
53
|
+
self.solver = solver
|
|
54
|
+
if self.solver == "gekko":
|
|
55
|
+
if model:
|
|
56
|
+
assert isinstance(
|
|
57
|
+
model, GEKKO
|
|
58
|
+
), "Input model must be of type gekko.GEKKO"
|
|
59
|
+
else:
|
|
60
|
+
model = GEKKO(remote=False)
|
|
61
|
+
elif self.solver == "CPLEX":
|
|
62
|
+
if model:
|
|
63
|
+
assert isinstance(
|
|
64
|
+
model, CpoModel
|
|
65
|
+
), "Input model must be of type docplex.cp.model.CpoModel"
|
|
66
|
+
else:
|
|
67
|
+
model = CpoModel()
|
|
68
|
+
else:
|
|
69
|
+
raise Exception(f"Unknown solver {self.solver}")
|
|
70
|
+
self.model = model
|