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.

Files changed (42) hide show
  1. pyedb/__init__.py +1 -1
  2. pyedb/configuration/cfg_common.py +1 -3
  3. pyedb/configuration/cfg_components.py +49 -5
  4. pyedb/configuration/cfg_data.py +3 -6
  5. pyedb/configuration/cfg_package_definition.py +3 -5
  6. pyedb/configuration/cfg_setup.py +214 -176
  7. pyedb/configuration/cfg_stackup.py +4 -4
  8. pyedb/configuration/configuration.py +9 -5
  9. pyedb/dotnet/edb.py +64 -44
  10. pyedb/dotnet/edb_core/cell/__init__.py +0 -0
  11. pyedb/dotnet/edb_core/cell/hierarchy/component.py +12 -17
  12. pyedb/dotnet/edb_core/cell/hierarchy/hierarchy_obj.py +50 -0
  13. pyedb/dotnet/edb_core/cell/layout.py +0 -6
  14. pyedb/dotnet/edb_core/cell/voltage_regulator.py +143 -0
  15. pyedb/dotnet/edb_core/components.py +2 -2
  16. pyedb/dotnet/edb_core/dotnet/primitive.py +129 -3
  17. pyedb/dotnet/edb_core/edb_data/hfss_pi_simulation_setup_data.py +0 -460
  18. pyedb/dotnet/edb_core/edb_data/primitives_data.py +38 -38
  19. pyedb/dotnet/edb_core/edb_data/raptor_x_simulation_setup_data.py +1 -1
  20. pyedb/dotnet/edb_core/layout.py +25 -1
  21. pyedb/dotnet/edb_core/layout_validation.py +26 -0
  22. pyedb/dotnet/edb_core/nets.py +1 -1
  23. pyedb/dotnet/edb_core/sim_setup_data/data/mesh_operation.py +63 -49
  24. pyedb/dotnet/edb_core/sim_setup_data/data/settings.py +1 -1
  25. pyedb/dotnet/edb_core/sim_setup_data/data/sim_setup_info.py +81 -0
  26. pyedb/dotnet/edb_core/sim_setup_data/data/simulation_settings.py +424 -0
  27. pyedb/dotnet/edb_core/sim_setup_data/data/sweep_data.py +131 -96
  28. pyedb/dotnet/edb_core/siwave.py +63 -0
  29. pyedb/dotnet/edb_core/utilities/hfss_simulation_setup.py +469 -0
  30. pyedb/dotnet/edb_core/utilities/simulation_setup.py +112 -773
  31. pyedb/dotnet/edb_core/utilities/siwave_simulation_setup.py +369 -0
  32. pyedb/misc/siw_feature_config/xtalk_scan/fd_xtalk_scan_config.py +91 -0
  33. pyedb/misc/siw_feature_config/xtalk_scan/impedance_scan_config.py +70 -0
  34. pyedb/misc/siw_feature_config/xtalk_scan/net.py +69 -0
  35. pyedb/misc/siw_feature_config/xtalk_scan/pins.py +60 -0
  36. pyedb/misc/siw_feature_config/xtalk_scan/scan_config.py +88 -0
  37. pyedb/misc/siw_feature_config/xtalk_scan/td_xtalk_config.py +104 -0
  38. pyedb/workflow.py +32 -0
  39. {pyedb-0.15.dev0.dist-info → pyedb-0.17.0.dist-info}/METADATA +1 -1
  40. {pyedb-0.15.dev0.dist-info → pyedb-0.17.0.dist-info}/RECORD +42 -28
  41. {pyedb-0.15.dev0.dist-info → pyedb-0.17.0.dist-info}/LICENSE +0 -0
  42. {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))