pyedb 0.15.dev0__py3-none-any.whl → 0.17.0__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.
Potentially problematic release.
This version of pyedb might be problematic. Click here for more details.
- pyedb/__init__.py +1 -1
- pyedb/configuration/cfg_common.py +1 -3
- pyedb/configuration/cfg_components.py +49 -5
- pyedb/configuration/cfg_data.py +3 -6
- pyedb/configuration/cfg_package_definition.py +3 -5
- pyedb/configuration/cfg_setup.py +214 -176
- pyedb/configuration/cfg_stackup.py +4 -4
- pyedb/configuration/configuration.py +9 -5
- pyedb/dotnet/edb.py +64 -44
- pyedb/dotnet/edb_core/cell/__init__.py +0 -0
- pyedb/dotnet/edb_core/cell/hierarchy/component.py +12 -17
- pyedb/dotnet/edb_core/cell/hierarchy/hierarchy_obj.py +50 -0
- pyedb/dotnet/edb_core/cell/layout.py +0 -6
- pyedb/dotnet/edb_core/cell/voltage_regulator.py +143 -0
- pyedb/dotnet/edb_core/components.py +2 -2
- pyedb/dotnet/edb_core/dotnet/primitive.py +129 -3
- pyedb/dotnet/edb_core/edb_data/hfss_pi_simulation_setup_data.py +0 -460
- pyedb/dotnet/edb_core/edb_data/primitives_data.py +38 -38
- pyedb/dotnet/edb_core/edb_data/raptor_x_simulation_setup_data.py +1 -1
- pyedb/dotnet/edb_core/layout.py +25 -1
- pyedb/dotnet/edb_core/layout_validation.py +26 -0
- pyedb/dotnet/edb_core/nets.py +1 -1
- pyedb/dotnet/edb_core/sim_setup_data/data/mesh_operation.py +63 -49
- pyedb/dotnet/edb_core/sim_setup_data/data/settings.py +1 -1
- pyedb/dotnet/edb_core/sim_setup_data/data/sim_setup_info.py +81 -0
- pyedb/dotnet/edb_core/sim_setup_data/data/simulation_settings.py +424 -0
- pyedb/dotnet/edb_core/sim_setup_data/data/sweep_data.py +131 -96
- pyedb/dotnet/edb_core/siwave.py +63 -0
- pyedb/dotnet/edb_core/utilities/hfss_simulation_setup.py +469 -0
- pyedb/dotnet/edb_core/utilities/simulation_setup.py +112 -773
- pyedb/dotnet/edb_core/utilities/siwave_simulation_setup.py +369 -0
- pyedb/misc/siw_feature_config/xtalk_scan/fd_xtalk_scan_config.py +91 -0
- pyedb/misc/siw_feature_config/xtalk_scan/impedance_scan_config.py +70 -0
- pyedb/misc/siw_feature_config/xtalk_scan/net.py +69 -0
- pyedb/misc/siw_feature_config/xtalk_scan/pins.py +60 -0
- pyedb/misc/siw_feature_config/xtalk_scan/scan_config.py +88 -0
- pyedb/misc/siw_feature_config/xtalk_scan/td_xtalk_config.py +104 -0
- pyedb/workflow.py +32 -0
- {pyedb-0.15.dev0.dist-info → pyedb-0.17.0.dist-info}/METADATA +1 -1
- {pyedb-0.15.dev0.dist-info → pyedb-0.17.0.dist-info}/RECORD +42 -28
- {pyedb-0.15.dev0.dist-info → pyedb-0.17.0.dist-info}/LICENSE +0 -0
- {pyedb-0.15.dev0.dist-info → pyedb-0.17.0.dist-info}/WHEEL +0 -0
|
@@ -0,0 +1,369 @@
|
|
|
1
|
+
import warnings
|
|
2
|
+
|
|
3
|
+
from pyedb.dotnet.edb_core.general import (
|
|
4
|
+
convert_netdict_to_pydict,
|
|
5
|
+
convert_pydict_to_netdict,
|
|
6
|
+
)
|
|
7
|
+
from pyedb.dotnet.edb_core.sim_setup_data.data.sim_setup_info import SimSetupInfo
|
|
8
|
+
from pyedb.dotnet.edb_core.sim_setup_data.data.siw_dc_ir_settings import (
|
|
9
|
+
SiwaveDCIRSettings,
|
|
10
|
+
)
|
|
11
|
+
from pyedb.dotnet.edb_core.sim_setup_data.io.siwave import (
|
|
12
|
+
AdvancedSettings,
|
|
13
|
+
DCAdvancedSettings,
|
|
14
|
+
DCSettings,
|
|
15
|
+
)
|
|
16
|
+
from pyedb.dotnet.edb_core.utilities.simulation_setup import SimulationSetup
|
|
17
|
+
from pyedb.generic.general_methods import is_linux
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def _parse_value(v):
|
|
21
|
+
"""Parse value in C sharp format."""
|
|
22
|
+
# duck typing parse of the value 'v'
|
|
23
|
+
if v is None or v == "":
|
|
24
|
+
pv = v
|
|
25
|
+
elif v == "true":
|
|
26
|
+
pv = True
|
|
27
|
+
elif v == "false":
|
|
28
|
+
pv = False
|
|
29
|
+
else:
|
|
30
|
+
try:
|
|
31
|
+
pv = int(v)
|
|
32
|
+
except ValueError:
|
|
33
|
+
try:
|
|
34
|
+
pv = float(v)
|
|
35
|
+
except ValueError:
|
|
36
|
+
if isinstance(v, str) and v[0] == v[-1] == "'":
|
|
37
|
+
pv = v[1:-1]
|
|
38
|
+
else:
|
|
39
|
+
pv = v
|
|
40
|
+
return pv
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def clone_edb_sim_setup_info(source, target):
|
|
44
|
+
string = source.ToString().replace("\t", "").split("\r\n")
|
|
45
|
+
if is_linux:
|
|
46
|
+
string = string[0].split("\n")
|
|
47
|
+
keys = [i.split("=")[0] for i in string if len(i.split("=")) == 2 and "SourceTermsToGround" not in i]
|
|
48
|
+
values = [i.split("=")[1] for i in string if len(i.split("=")) == 2 and "SourceTermsToGround" not in i]
|
|
49
|
+
for val in string:
|
|
50
|
+
if "SourceTermsToGround()" in val:
|
|
51
|
+
break
|
|
52
|
+
elif "SourceTermsToGround" in val:
|
|
53
|
+
sources = {}
|
|
54
|
+
val = val.replace("SourceTermsToGround(", "").replace(")", "").split(",")
|
|
55
|
+
for v in val:
|
|
56
|
+
source = v.split("=")
|
|
57
|
+
sources[source[0]] = int(source[1].replace("'", ""))
|
|
58
|
+
target.SimulationSettings.DCIRSettings.SourceTermsToGround = convert_pydict_to_netdict(sources)
|
|
59
|
+
break
|
|
60
|
+
for k in keys:
|
|
61
|
+
value = _parse_value(values[keys.index(k)])
|
|
62
|
+
setter = None
|
|
63
|
+
if k in dir(target.SimulationSettings):
|
|
64
|
+
setter = target.SimulationSettings
|
|
65
|
+
elif k in dir(target.SimulationSettings.AdvancedSettings):
|
|
66
|
+
setter = target.SimulationSettings.AdvancedSettings
|
|
67
|
+
|
|
68
|
+
elif k in dir(target.SimulationSettings.DCAdvancedSettings):
|
|
69
|
+
setter = target.SimulationSettings.DCAdvancedSettings
|
|
70
|
+
elif "DCIRSettings" in dir(target.SimulationSettings) and k in dir(target.SimulationSettings.DCIRSettings):
|
|
71
|
+
setter = target.SimulationSettings.DCIRSettings
|
|
72
|
+
elif k in dir(target.SimulationSettings.DCSettings):
|
|
73
|
+
setter = target.SimulationSettings.DCSettings
|
|
74
|
+
elif k in dir(target.SimulationSettings.AdvancedSettings):
|
|
75
|
+
setter = target.SimulationSettings.AdvancedSettings
|
|
76
|
+
if setter:
|
|
77
|
+
try:
|
|
78
|
+
setter.__setattr__(k, value)
|
|
79
|
+
except TypeError:
|
|
80
|
+
try:
|
|
81
|
+
setter.__setattr__(k, str(value))
|
|
82
|
+
except:
|
|
83
|
+
pass
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
class SiwaveSimulationSetup(SimulationSetup):
|
|
87
|
+
"""Manages EDB methods for SIwave simulation setup."""
|
|
88
|
+
|
|
89
|
+
def __init__(self, pedb, edb_object=None, name: str = None):
|
|
90
|
+
super().__init__(pedb, edb_object)
|
|
91
|
+
self._simulation_setup_builder = self._pedb._edb.Utility.SIWaveSimulationSetup
|
|
92
|
+
if edb_object is None:
|
|
93
|
+
self._name = name
|
|
94
|
+
sim_setup_info = SimSetupInfo(self._pedb, sim_setup=self, setup_type="kSIwave", name=name)
|
|
95
|
+
self._edb_object = self._simulation_setup_builder(sim_setup_info._edb_object)
|
|
96
|
+
self._update_setup()
|
|
97
|
+
|
|
98
|
+
def create(self, name=None):
|
|
99
|
+
"""Create a SIwave SYZ setup.
|
|
100
|
+
|
|
101
|
+
Returns
|
|
102
|
+
-------
|
|
103
|
+
:class:`SiwaveDCSimulationSetup`
|
|
104
|
+
"""
|
|
105
|
+
self._name = name
|
|
106
|
+
self._create(name, simulation_setup_type="kSIwave")
|
|
107
|
+
self.si_slider_position = 1
|
|
108
|
+
|
|
109
|
+
return self
|
|
110
|
+
|
|
111
|
+
def get_configurations(self):
|
|
112
|
+
"""Get SIwave SYZ simulation settings.
|
|
113
|
+
|
|
114
|
+
Returns
|
|
115
|
+
-------
|
|
116
|
+
dict
|
|
117
|
+
Dictionary of SIwave SYZ simulation settings.
|
|
118
|
+
"""
|
|
119
|
+
return {
|
|
120
|
+
"pi_slider_position": self.pi_slider_position,
|
|
121
|
+
"si_slider_position": self.si_slider_position,
|
|
122
|
+
"use_custom_settings": self.use_si_settings,
|
|
123
|
+
"use_si_settings": self.use_si_settings,
|
|
124
|
+
"advanced_settings": self.advanced_settings.get_configurations(),
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
@property
|
|
128
|
+
def advanced_settings(self):
|
|
129
|
+
"""SIwave advanced settings."""
|
|
130
|
+
return AdvancedSettings(self)
|
|
131
|
+
|
|
132
|
+
@property
|
|
133
|
+
def sim_setup_info(self):
|
|
134
|
+
"""Overrides the default sim_setup_info object."""
|
|
135
|
+
return SimSetupInfo(self._pedb, sim_setup=self, edb_object=self.get_sim_setup_info)
|
|
136
|
+
|
|
137
|
+
@sim_setup_info.setter
|
|
138
|
+
def sim_setup_info(self, sim_setup_info):
|
|
139
|
+
self._edb_object = self._simulation_setup_builder(sim_setup_info._edb_object)
|
|
140
|
+
|
|
141
|
+
@property
|
|
142
|
+
def get_sim_setup_info(self):
|
|
143
|
+
"""Get simulation information from the setup."""
|
|
144
|
+
|
|
145
|
+
sim_setup_info = SimSetupInfo(self._pedb, sim_setup=self, setup_type="kSIwave", name=self._edb_object.GetName())
|
|
146
|
+
clone_edb_sim_setup_info(source=self._edb_object, target=sim_setup_info._edb_object)
|
|
147
|
+
return sim_setup_info._edb_object
|
|
148
|
+
|
|
149
|
+
def set_pi_slider(self, value):
|
|
150
|
+
"""Set SIwave PI simulation accuracy level.
|
|
151
|
+
Options are:
|
|
152
|
+
- ``0``: Optimal speed
|
|
153
|
+
- ``1``: Balanced
|
|
154
|
+
- ``2``: Optimal accuracy
|
|
155
|
+
|
|
156
|
+
.. deprecated:: 0.7.5
|
|
157
|
+
Use :property:`pi_slider_position` property instead.
|
|
158
|
+
|
|
159
|
+
"""
|
|
160
|
+
warnings.warn("`set_pi_slider` is deprecated. Use `pi_slider_position` property instead.", DeprecationWarning)
|
|
161
|
+
self.pi_slider_position = value
|
|
162
|
+
|
|
163
|
+
def set_si_slider(self, value):
|
|
164
|
+
"""Set SIwave SI simulation accuracy level.
|
|
165
|
+
|
|
166
|
+
Options are:
|
|
167
|
+
- ``0``: Optimal speed;
|
|
168
|
+
- ``1``: Balanced;
|
|
169
|
+
- ``2``: Optimal accuracy```.
|
|
170
|
+
"""
|
|
171
|
+
self.use_si_settings = True
|
|
172
|
+
self.use_custom_settings = False
|
|
173
|
+
self.si_slider_position = value
|
|
174
|
+
self.advanced_settings.set_si_slider(value)
|
|
175
|
+
|
|
176
|
+
@property
|
|
177
|
+
def pi_slider_position(self):
|
|
178
|
+
"""PI solider position. Values are from ``1`` to ``3``."""
|
|
179
|
+
return self.get_sim_setup_info.SimulationSettings.PISliderPos
|
|
180
|
+
|
|
181
|
+
@pi_slider_position.setter
|
|
182
|
+
def pi_slider_position(self, value):
|
|
183
|
+
edb_setup_info = self.get_sim_setup_info
|
|
184
|
+
edb_setup_info.SimulationSettings.PISliderPos = value
|
|
185
|
+
self._edb_object = self._set_edb_setup_info(edb_setup_info)
|
|
186
|
+
self._update_setup()
|
|
187
|
+
|
|
188
|
+
self.use_si_settings = False
|
|
189
|
+
self.use_custom_settings = False
|
|
190
|
+
self.advanced_settings.set_pi_slider(value)
|
|
191
|
+
|
|
192
|
+
@property
|
|
193
|
+
def si_slider_position(self):
|
|
194
|
+
"""SI slider position. Values are from ``1`` to ``3``."""
|
|
195
|
+
return self.get_sim_setup_info.SimulationSettings.SISliderPos
|
|
196
|
+
|
|
197
|
+
@si_slider_position.setter
|
|
198
|
+
def si_slider_position(self, value):
|
|
199
|
+
edb_setup_info = self.get_sim_setup_info
|
|
200
|
+
edb_setup_info.SimulationSettings.SISliderPos = value
|
|
201
|
+
self._edb_object = self._set_edb_setup_info(edb_setup_info)
|
|
202
|
+
self._update_setup()
|
|
203
|
+
|
|
204
|
+
self.use_si_settings = True
|
|
205
|
+
self.use_custom_settings = False
|
|
206
|
+
self.advanced_settings.set_si_slider(value)
|
|
207
|
+
|
|
208
|
+
@property
|
|
209
|
+
def use_custom_settings(self):
|
|
210
|
+
"""Custom settings to use.
|
|
211
|
+
|
|
212
|
+
Returns
|
|
213
|
+
-------
|
|
214
|
+
bool
|
|
215
|
+
"""
|
|
216
|
+
return self.get_sim_setup_info.SimulationSettings.UseCustomSettings
|
|
217
|
+
|
|
218
|
+
@use_custom_settings.setter
|
|
219
|
+
def use_custom_settings(self, value):
|
|
220
|
+
edb_setup_info = self.get_sim_setup_info
|
|
221
|
+
edb_setup_info.SimulationSettings.UseCustomSettings = value
|
|
222
|
+
self._edb_object = self._set_edb_setup_info(edb_setup_info)
|
|
223
|
+
self._update_setup()
|
|
224
|
+
|
|
225
|
+
@property
|
|
226
|
+
def use_si_settings(self):
|
|
227
|
+
"""Whether to use SI Settings.
|
|
228
|
+
|
|
229
|
+
Returns
|
|
230
|
+
-------
|
|
231
|
+
bool
|
|
232
|
+
"""
|
|
233
|
+
return self.get_sim_setup_info.SimulationSettings.UseSISettings
|
|
234
|
+
|
|
235
|
+
@use_si_settings.setter
|
|
236
|
+
def use_si_settings(self, value):
|
|
237
|
+
edb_setup_info = self.get_sim_setup_info
|
|
238
|
+
edb_setup_info.SimulationSettings.UseSISettings = value
|
|
239
|
+
self._edb_object = self._set_edb_setup_info(edb_setup_info)
|
|
240
|
+
self._update_setup()
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
class SiwaveDCSimulationSetup(SimulationSetup):
|
|
244
|
+
"""Manages EDB methods for SIwave DC simulation setup."""
|
|
245
|
+
|
|
246
|
+
def __init__(self, pedb, edb_object=None, name: str = None):
|
|
247
|
+
super().__init__(pedb, edb_object)
|
|
248
|
+
self._simulation_setup_builder = self._pedb._edb.Utility.SIWaveDCIRSimulationSetup
|
|
249
|
+
self._mesh_operations = {}
|
|
250
|
+
if edb_object is None:
|
|
251
|
+
self._name = name
|
|
252
|
+
sim_setup_info = SimSetupInfo(self._pedb, sim_setup=self, setup_type="kSIwaveDCIR", name=name)
|
|
253
|
+
self._edb_object = self._simulation_setup_builder(sim_setup_info._edb_object)
|
|
254
|
+
self._update_setup()
|
|
255
|
+
|
|
256
|
+
def create(self, name=None):
|
|
257
|
+
"""Create a SIwave DCIR setup.
|
|
258
|
+
|
|
259
|
+
Returns
|
|
260
|
+
-------
|
|
261
|
+
:class:`SiwaveDCSimulationSetup`
|
|
262
|
+
"""
|
|
263
|
+
self._name = name
|
|
264
|
+
self._create(name)
|
|
265
|
+
self.set_dc_slider(1)
|
|
266
|
+
return self
|
|
267
|
+
|
|
268
|
+
@property
|
|
269
|
+
def sim_setup_info(self):
|
|
270
|
+
"""Overrides the default sim_setup_info object."""
|
|
271
|
+
return SimSetupInfo(self._pedb, sim_setup=self, edb_object=self.get_sim_setup_info)
|
|
272
|
+
|
|
273
|
+
@sim_setup_info.setter
|
|
274
|
+
def sim_setup_info(self, sim_setup_info):
|
|
275
|
+
self._edb_object = self._simulation_setup_builder(sim_setup_info._edb_object)
|
|
276
|
+
|
|
277
|
+
@property
|
|
278
|
+
def get_sim_setup_info(self):
|
|
279
|
+
"""Get simulation information from the setup."""
|
|
280
|
+
|
|
281
|
+
sim_setup_info = SimSetupInfo(
|
|
282
|
+
self._pedb, sim_setup=self, setup_type="kSIwaveDCIR", name=self._edb_object.GetName()
|
|
283
|
+
)
|
|
284
|
+
clone_edb_sim_setup_info(source=self._edb_object, target=sim_setup_info._edb_object)
|
|
285
|
+
return sim_setup_info._edb_object
|
|
286
|
+
|
|
287
|
+
@property
|
|
288
|
+
def dc_ir_settings(self):
|
|
289
|
+
"""DC IR settings."""
|
|
290
|
+
return SiwaveDCIRSettings(self)
|
|
291
|
+
|
|
292
|
+
def get_configurations(self):
|
|
293
|
+
"""Get SIwave DC simulation settings.
|
|
294
|
+
|
|
295
|
+
Returns
|
|
296
|
+
-------
|
|
297
|
+
dict
|
|
298
|
+
Dictionary of SIwave DC simulation settings.
|
|
299
|
+
"""
|
|
300
|
+
return {
|
|
301
|
+
"dc_settings": self.dc_settings.get_configurations(),
|
|
302
|
+
"dc_advanced_settings": self.dc_advanced_settings.get_configurations(),
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
def set_dc_slider(self, value):
|
|
306
|
+
"""Set DC simulation accuracy level.
|
|
307
|
+
|
|
308
|
+
Options are:
|
|
309
|
+
|
|
310
|
+
- ``0``: Optimal speed
|
|
311
|
+
- ``1``: Balanced
|
|
312
|
+
- ``2``: Optimal accuracy
|
|
313
|
+
"""
|
|
314
|
+
self.use_custom_settings = False
|
|
315
|
+
self.dc_settings.dc_slider_position = value
|
|
316
|
+
self.dc_advanced_settings.set_dc_slider(value)
|
|
317
|
+
|
|
318
|
+
@property
|
|
319
|
+
def dc_settings(self):
|
|
320
|
+
"""SIwave DC setting."""
|
|
321
|
+
return DCSettings(self)
|
|
322
|
+
|
|
323
|
+
@property
|
|
324
|
+
def dc_advanced_settings(self):
|
|
325
|
+
"""Siwave DC advanced settings.
|
|
326
|
+
|
|
327
|
+
Returns
|
|
328
|
+
-------
|
|
329
|
+
:class:`pyedb.dotnet.edb_core.edb_data.siwave_simulation_setup_data.SiwaveDCAdvancedSettings`
|
|
330
|
+
"""
|
|
331
|
+
return DCAdvancedSettings(self)
|
|
332
|
+
|
|
333
|
+
@property
|
|
334
|
+
def source_terms_to_ground(self):
|
|
335
|
+
"""Dictionary of grounded terminals.
|
|
336
|
+
|
|
337
|
+
Returns
|
|
338
|
+
-------
|
|
339
|
+
Dictionary
|
|
340
|
+
{str, int}, keys is source name, value int 0 unspecified, 1 negative node, 2 positive one.
|
|
341
|
+
|
|
342
|
+
"""
|
|
343
|
+
return convert_netdict_to_pydict(self.get_sim_setup_info.SimulationSettings.DCIRSettings.SourceTermsToGround)
|
|
344
|
+
|
|
345
|
+
def add_source_terminal_to_ground(self, source_name, terminal=0):
|
|
346
|
+
"""Add a source terminal to ground.
|
|
347
|
+
|
|
348
|
+
Parameters
|
|
349
|
+
----------
|
|
350
|
+
source_name : str,
|
|
351
|
+
Source name.
|
|
352
|
+
terminal : int, optional
|
|
353
|
+
Terminal to assign. Options are:
|
|
354
|
+
|
|
355
|
+
- 0=Unspecified
|
|
356
|
+
- 1=Negative node
|
|
357
|
+
- 2=Positive none
|
|
358
|
+
|
|
359
|
+
Returns
|
|
360
|
+
-------
|
|
361
|
+
bool
|
|
362
|
+
|
|
363
|
+
"""
|
|
364
|
+
terminals = self.source_terms_to_ground
|
|
365
|
+
terminals[source_name] = terminal
|
|
366
|
+
self.get_sim_setup_info.SimulationSettings.DCIRSettings.SourceTermsToGround = convert_pydict_to_netdict(
|
|
367
|
+
terminals
|
|
368
|
+
)
|
|
369
|
+
return self._update_setup()
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# Copyright (C) 2023 - 2024 ANSYS, Inc. and/or its affiliates.
|
|
2
|
+
# SPDX-License-Identifier: MIT
|
|
3
|
+
#
|
|
4
|
+
#
|
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
# furnished to do so, subject to the following conditions:
|
|
11
|
+
#
|
|
12
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
# copies or substantial portions of the Software.
|
|
14
|
+
#
|
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
# SOFTWARE.
|
|
22
|
+
|
|
23
|
+
from pyedb.generic.general_methods import ET
|
|
24
|
+
from pyedb.misc.siw_feature_config.xtalk_scan.net import SingleEndedNet
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class CrosstalkFrequency:
|
|
28
|
+
"""Siwave frequency domain crosstalk configuration handler."""
|
|
29
|
+
|
|
30
|
+
def __init__(self, pedb):
|
|
31
|
+
self._pedb = pedb
|
|
32
|
+
self.min_transmission_line_segment_length = "0.25mm"
|
|
33
|
+
self.frequency = "2e9Hz"
|
|
34
|
+
self.nets = {}
|
|
35
|
+
|
|
36
|
+
def extend_xml(self, parent):
|
|
37
|
+
"""Write class xml section.
|
|
38
|
+
|
|
39
|
+
Parameters
|
|
40
|
+
----------
|
|
41
|
+
parent : :class xml.etree.cElementTree object
|
|
42
|
+
Parent object.
|
|
43
|
+
|
|
44
|
+
"""
|
|
45
|
+
freq_scan = ET.SubElement(parent, "FdXtalkConfig")
|
|
46
|
+
freq_scan.set("MinTlineSegmentLength", self.min_transmission_line_segment_length)
|
|
47
|
+
freq_scan.set("XtalkFrequency", self.frequency)
|
|
48
|
+
nets = ET.SubElement(freq_scan, "SingleEndedNets")
|
|
49
|
+
for net in list(self.nets.values()):
|
|
50
|
+
net.extend_xml(nets)
|
|
51
|
+
|
|
52
|
+
def add_single_ended_net(
|
|
53
|
+
self,
|
|
54
|
+
name,
|
|
55
|
+
next_warning_threshold=5.0,
|
|
56
|
+
next_violation_threshold=10.0,
|
|
57
|
+
fext_warning_threshold_warning=5.0,
|
|
58
|
+
fext_violation_threshold=5.0,
|
|
59
|
+
):
|
|
60
|
+
"""Add single ended net.
|
|
61
|
+
|
|
62
|
+
Parameters
|
|
63
|
+
----------
|
|
64
|
+
name : str
|
|
65
|
+
Net name.
|
|
66
|
+
next_warning_threshold : flot or str
|
|
67
|
+
Near end crosstalk warning threshold value. Default value is ``5.0``.
|
|
68
|
+
next_violation_threshold : float, str
|
|
69
|
+
Near end crosstalk violation threshold value. Default value is ``10.0
|
|
70
|
+
|
|
71
|
+
fext_violation_threshold : float, str
|
|
72
|
+
Far end crosstalk violation threshold value, Default value is ``5.0``
|
|
73
|
+
fext_warning_threshold_warning : float, str
|
|
74
|
+
Far end crosstalk warning threshold value, Default value is ``5.0``
|
|
75
|
+
|
|
76
|
+
Returns
|
|
77
|
+
-------
|
|
78
|
+
bool
|
|
79
|
+
"""
|
|
80
|
+
if name and name not in self.nets:
|
|
81
|
+
net = SingleEndedNet()
|
|
82
|
+
net.name = name
|
|
83
|
+
net.next_warning_threshold = next_warning_threshold
|
|
84
|
+
net.next_violation_threshold = next_violation_threshold
|
|
85
|
+
net.fext_warning_threshold = fext_warning_threshold_warning
|
|
86
|
+
net.fext_violation_threshold = fext_violation_threshold
|
|
87
|
+
self.nets[name] = net
|
|
88
|
+
return True
|
|
89
|
+
else:
|
|
90
|
+
self._pedb.logger.error(f"Net {name} already assigned.")
|
|
91
|
+
return False
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# Copyright (C) 2023 - 2024 ANSYS, Inc. and/or its affiliates.
|
|
2
|
+
# SPDX-License-Identifier: MIT
|
|
3
|
+
#
|
|
4
|
+
#
|
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
# furnished to do so, subject to the following conditions:
|
|
11
|
+
#
|
|
12
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
# copies or substantial portions of the Software.
|
|
14
|
+
#
|
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
# SOFTWARE.
|
|
22
|
+
|
|
23
|
+
from pyedb.generic.general_methods import ET
|
|
24
|
+
from pyedb.misc.siw_feature_config.xtalk_scan.net import SingleEndedNet
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class ImpedanceScan:
|
|
28
|
+
def __init__(self, pedb):
|
|
29
|
+
self._pedb = pedb
|
|
30
|
+
self.min_transmission_line_segment_length = "0.25mm"
|
|
31
|
+
self.frequency = "2e9Hz"
|
|
32
|
+
self.nets = {}
|
|
33
|
+
|
|
34
|
+
def extend_xml(self, parent):
|
|
35
|
+
"""Write object wml section"""
|
|
36
|
+
z_scan = ET.SubElement(parent, "Z0ScanConfig")
|
|
37
|
+
z_scan.set("MinTlineSegmentLength", self.min_transmission_line_segment_length)
|
|
38
|
+
z_scan.set("Z0Frequency", self.frequency)
|
|
39
|
+
single_ended_nets = ET.SubElement(z_scan, "SingleEndedNets")
|
|
40
|
+
for net in list(self.nets.values()):
|
|
41
|
+
net.extend_xml(single_ended_nets)
|
|
42
|
+
|
|
43
|
+
def add_single_ended_net(self, name, nominal_impedance=50.0, warning_threshold=17.0, violation_threshold=32.0):
|
|
44
|
+
"""Add single ended net.
|
|
45
|
+
|
|
46
|
+
Parameters
|
|
47
|
+
----------
|
|
48
|
+
name : str
|
|
49
|
+
Net name.
|
|
50
|
+
nominal_impedance : flot or str
|
|
51
|
+
nominal impedance in ohm. Default value is ``50,0``..
|
|
52
|
+
warning_threshold : float, str
|
|
53
|
+
Warning threshold value. Default value is ``17.0
|
|
54
|
+
violation_threshold : float, str
|
|
55
|
+
Violation threshold value, Default value is ``5.0``
|
|
56
|
+
|
|
57
|
+
Returns
|
|
58
|
+
-------
|
|
59
|
+
bool
|
|
60
|
+
"""
|
|
61
|
+
if name and name not in self.nets:
|
|
62
|
+
net = SingleEndedNet()
|
|
63
|
+
net.name = name
|
|
64
|
+
net.nominal_impedance = nominal_impedance
|
|
65
|
+
net.warning_threshold = warning_threshold
|
|
66
|
+
net.violation_threshold = violation_threshold
|
|
67
|
+
self.nets[name] = net
|
|
68
|
+
else:
|
|
69
|
+
self._pedb.logger.error(f"Net {name} already assigned")
|
|
70
|
+
return False
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# Copyright (C) 2023 - 2024 ANSYS, Inc. and/or its affiliates.
|
|
2
|
+
# SPDX-License-Identifier: MIT
|
|
3
|
+
#
|
|
4
|
+
#
|
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
# furnished to do so, subject to the following conditions:
|
|
11
|
+
#
|
|
12
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
# copies or substantial portions of the Software.
|
|
14
|
+
#
|
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
# SOFTWARE.
|
|
22
|
+
|
|
23
|
+
from pyedb.generic.general_methods import ET
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class SingleEndedNet:
|
|
27
|
+
"""Single ended net class handler."""
|
|
28
|
+
|
|
29
|
+
def __init__(self):
|
|
30
|
+
self.name = None
|
|
31
|
+
self.nominal_impedance = None
|
|
32
|
+
self.warning_threshold = None
|
|
33
|
+
self.violation_threshold = None
|
|
34
|
+
self.fext_warning_threshold = None
|
|
35
|
+
self.fext_violation_threshold = None
|
|
36
|
+
self.next_warning_threshold = None
|
|
37
|
+
self.next_violation_threshold = None
|
|
38
|
+
self.driver_rise_time = None
|
|
39
|
+
self.voltage = None
|
|
40
|
+
self.driver_impedance = None
|
|
41
|
+
self.termination_impedance = None
|
|
42
|
+
|
|
43
|
+
def extend_xml(self, parent):
|
|
44
|
+
"""Write XMl object section."""
|
|
45
|
+
net = ET.SubElement(parent, "Net")
|
|
46
|
+
if self.name is not None:
|
|
47
|
+
net.set("Name", self.name)
|
|
48
|
+
if self.nominal_impedance is not None:
|
|
49
|
+
net.set("NominalZ0", str(self.nominal_impedance))
|
|
50
|
+
if self.warning_threshold is not None:
|
|
51
|
+
net.set("WarningThreshold", str(self.warning_threshold))
|
|
52
|
+
if self.violation_threshold is not None:
|
|
53
|
+
net.set("ViolationThreshold", str(self.violation_threshold))
|
|
54
|
+
if self.fext_warning_threshold is not None:
|
|
55
|
+
net.set("FEXTWarningThreshold", str(self.fext_warning_threshold))
|
|
56
|
+
if self.fext_violation_threshold is not None:
|
|
57
|
+
net.set("FEXTViolationThreshold", str(self.fext_violation_threshold))
|
|
58
|
+
if self.next_warning_threshold is not None:
|
|
59
|
+
net.set("NEXTWarningThreshold", str(self.next_warning_threshold))
|
|
60
|
+
if self.next_violation_threshold is not None:
|
|
61
|
+
net.set("NEXTViolationThreshold", str(self.next_violation_threshold))
|
|
62
|
+
if self.driver_rise_time is not None:
|
|
63
|
+
net.set("DriverRiseTime", str(self.driver_rise_time))
|
|
64
|
+
if self.voltage is not None:
|
|
65
|
+
net.set("Voltage", str(self.voltage))
|
|
66
|
+
if self.driver_impedance is not None:
|
|
67
|
+
net.set("DriverImpedance", str(self.driver_impedance))
|
|
68
|
+
if self.termination_impedance is not None:
|
|
69
|
+
net.set("TerminationImpedance", str(self.termination_impedance))
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Copyright (C) 2023 - 2024 ANSYS, Inc. and/or its affiliates.
|
|
2
|
+
# SPDX-License-Identifier: MIT
|
|
3
|
+
#
|
|
4
|
+
#
|
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
# furnished to do so, subject to the following conditions:
|
|
11
|
+
#
|
|
12
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
# copies or substantial portions of the Software.
|
|
14
|
+
#
|
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
# SOFTWARE.
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
from pyedb.generic.general_methods import ET
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class DriverPin:
|
|
28
|
+
"""Driver pin class handler."""
|
|
29
|
+
|
|
30
|
+
def __init__(self):
|
|
31
|
+
self.name = None
|
|
32
|
+
self.ref_des = None
|
|
33
|
+
self.driver_rise_time = None
|
|
34
|
+
self.voltage = None
|
|
35
|
+
self.driver_impedance = None
|
|
36
|
+
|
|
37
|
+
def extend_xml(self, parent):
|
|
38
|
+
"""Write object to xml section."""
|
|
39
|
+
pin = ET.SubElement(parent, "Pin")
|
|
40
|
+
pin.set("Name", self.name)
|
|
41
|
+
pin.set("RefDes", self.ref_des)
|
|
42
|
+
pin.set("DriverRiseTime", str(self.driver_rise_time))
|
|
43
|
+
pin.set("Voltage", str(self.voltage))
|
|
44
|
+
pin.set("DriverImpedance", str(self.driver_impedance))
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class ReceiverPin:
|
|
48
|
+
"""Receiver pin class handler."""
|
|
49
|
+
|
|
50
|
+
def __init__(self):
|
|
51
|
+
self.name = None
|
|
52
|
+
self.ref_des = None
|
|
53
|
+
self.receiver_impedance = None
|
|
54
|
+
|
|
55
|
+
def extend_xml(self, parent):
|
|
56
|
+
"""Write object to xml section."""
|
|
57
|
+
pin = ET.SubElement(parent, "Pin")
|
|
58
|
+
pin.set("Name", self.name)
|
|
59
|
+
pin.set("Name", self.name)
|
|
60
|
+
pin.set("ReceiverImpedance", str(self.receiver_impedance))
|