pyedb 0.54.0__py3-none-any.whl → 0.55.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 -8
- pyedb/configuration/cfg_boundaries.py +69 -151
- pyedb/configuration/cfg_components.py +201 -460
- pyedb/configuration/cfg_data.py +4 -2
- pyedb/configuration/cfg_general.py +13 -36
- pyedb/configuration/cfg_modeler.py +2 -1
- pyedb/configuration/cfg_nets.py +21 -35
- pyedb/configuration/cfg_operations.py +22 -151
- pyedb/configuration/cfg_package_definition.py +56 -112
- pyedb/configuration/cfg_padstacks.py +292 -688
- pyedb/configuration/cfg_pin_groups.py +32 -79
- pyedb/configuration/cfg_ports_sources.py +19 -6
- pyedb/configuration/cfg_s_parameter_models.py +67 -172
- pyedb/configuration/cfg_setup.py +102 -295
- pyedb/configuration/configuration.py +64 -5
- pyedb/dotnet/database/cell/connectable.py +38 -9
- pyedb/dotnet/database/cell/hierarchy/component.py +28 -28
- pyedb/dotnet/database/cell/hierarchy/model.py +1 -1
- pyedb/dotnet/database/cell/layout.py +63 -2
- pyedb/dotnet/database/cell/layout_obj.py +2 -2
- pyedb/dotnet/database/cell/primitive/path.py +6 -8
- pyedb/dotnet/database/cell/primitive/primitive.py +3 -24
- pyedb/dotnet/database/cell/terminal/edge_terminal.py +2 -2
- pyedb/dotnet/database/cell/terminal/padstack_instance_terminal.py +1 -1
- pyedb/dotnet/database/cell/terminal/pingroup_terminal.py +1 -1
- pyedb/dotnet/database/cell/terminal/point_terminal.py +1 -1
- pyedb/dotnet/database/cell/terminal/terminal.py +24 -24
- pyedb/dotnet/database/cell/voltage_regulator.py +0 -21
- pyedb/dotnet/database/components.py +96 -88
- pyedb/dotnet/database/definition/component_def.py +4 -4
- pyedb/dotnet/database/definition/component_model.py +1 -1
- pyedb/dotnet/database/definition/package_def.py +2 -3
- pyedb/dotnet/database/dotnet/database.py +3 -199
- pyedb/dotnet/database/dotnet/primitive.py +3 -3
- pyedb/dotnet/database/edb_data/control_file.py +5 -5
- pyedb/dotnet/database/edb_data/hfss_extent_info.py +6 -6
- pyedb/dotnet/database/edb_data/layer_data.py +23 -23
- pyedb/dotnet/database/edb_data/padstacks_data.py +63 -88
- pyedb/dotnet/database/edb_data/primitives_data.py +5 -5
- pyedb/dotnet/database/edb_data/sources.py +6 -6
- pyedb/dotnet/database/edb_data/variables.py +1 -1
- pyedb/dotnet/database/geometry/point_data.py +14 -10
- pyedb/dotnet/database/geometry/polygon_data.py +3 -3
- pyedb/dotnet/database/hfss.py +46 -48
- pyedb/dotnet/database/layout_validation.py +14 -11
- pyedb/dotnet/database/materials.py +10 -11
- pyedb/dotnet/database/modeler.py +97 -91
- pyedb/dotnet/database/nets.py +19 -22
- pyedb/dotnet/database/padstack.py +84 -83
- pyedb/dotnet/database/siwave.py +42 -42
- pyedb/dotnet/database/stackup.py +140 -72
- pyedb/dotnet/database/utilities/heatsink.py +4 -4
- pyedb/dotnet/database/utilities/obj_base.py +2 -2
- pyedb/dotnet/database/utilities/simulation_setup.py +2 -2
- pyedb/dotnet/database/utilities/value.py +16 -16
- pyedb/dotnet/edb.py +228 -150
- pyedb/edb_logger.py +12 -27
- pyedb/extensions/via_design_backend.py +6 -3
- pyedb/generic/design_types.py +67 -29
- pyedb/generic/general_methods.py +0 -120
- pyedb/generic/process.py +44 -108
- pyedb/generic/settings.py +75 -19
- pyedb/grpc/database/components.py +2 -0
- pyedb/grpc/database/control_file.py +5 -5
- pyedb/grpc/database/definition/materials.py +1 -1
- pyedb/grpc/database/definition/package_def.py +3 -3
- pyedb/grpc/database/definition/padstack_def.py +53 -0
- pyedb/grpc/database/geometry/polygon_data.py +1 -1
- pyedb/grpc/database/layout/layout.py +8 -5
- pyedb/grpc/database/layout_validation.py +3 -3
- pyedb/grpc/database/modeler.py +9 -4
- pyedb/grpc/database/net/net.py +15 -14
- pyedb/grpc/database/nets.py +70 -0
- pyedb/grpc/database/padstacks.py +35 -17
- pyedb/grpc/database/primitive/padstack_instance.py +175 -7
- pyedb/grpc/database/siwave.py +1 -1
- pyedb/grpc/database/source_excitations.py +2 -4
- pyedb/grpc/database/stackup.py +1 -1
- pyedb/grpc/database/terminal/bundle_terminal.py +1 -1
- pyedb/grpc/database/terminal/padstack_instance_terminal.py +1 -1
- pyedb/grpc/database/terminal/pingroup_terminal.py +1 -1
- pyedb/grpc/database/utility/xml_control_file.py +5 -5
- pyedb/grpc/edb.py +73 -27
- pyedb/grpc/edb_init.py +3 -3
- pyedb/grpc/rpc_session.py +10 -10
- pyedb/libraries/common.py +366 -0
- pyedb/libraries/rf_libraries/base_functions.py +1358 -0
- pyedb/libraries/rf_libraries/planar_antennas.py +628 -0
- pyedb/misc/decorators.py +61 -0
- pyedb/misc/misc.py +0 -13
- pyedb/siwave.py +2 -2
- {pyedb-0.54.0.dist-info → pyedb-0.55.0.dist-info}/METADATA +1 -2
- {pyedb-0.54.0.dist-info → pyedb-0.55.0.dist-info}/RECORD +95 -91
- {pyedb-0.54.0.dist-info → pyedb-0.55.0.dist-info}/WHEEL +0 -0
- {pyedb-0.54.0.dist-info → pyedb-0.55.0.dist-info}/licenses/LICENSE +0 -0
pyedb/generic/settings.py
CHANGED
|
@@ -21,12 +21,24 @@
|
|
|
21
21
|
# SOFTWARE.
|
|
22
22
|
|
|
23
23
|
import os
|
|
24
|
+
import re
|
|
25
|
+
import sys
|
|
24
26
|
import time
|
|
27
|
+
import warnings
|
|
25
28
|
|
|
26
29
|
|
|
27
30
|
class Settings(object):
|
|
28
31
|
"""Manages all PyEDB environment variables and global settings."""
|
|
29
32
|
|
|
33
|
+
INSTALLED_VERSIONS = None
|
|
34
|
+
INSTALLED_STUDENT_VERSIONS = None
|
|
35
|
+
INSTALLED_CLIENT_VERSIONS = None
|
|
36
|
+
LATEST_VERSION = None
|
|
37
|
+
LATEST_STUDENT_VERSION = None
|
|
38
|
+
|
|
39
|
+
specified_version = None
|
|
40
|
+
is_student_version = False
|
|
41
|
+
|
|
30
42
|
def __init__(self):
|
|
31
43
|
self.remote_rpc_session = False
|
|
32
44
|
self._enable_screen_logs = True
|
|
@@ -58,26 +70,12 @@ class Settings(object):
|
|
|
58
70
|
self._global_log_file_size = 10
|
|
59
71
|
self._lsf_queue = None
|
|
60
72
|
self._edb_environment_variables = {}
|
|
61
|
-
self.
|
|
62
|
-
self.
|
|
63
|
-
|
|
64
|
-
@property
|
|
65
|
-
def logger(self):
|
|
66
|
-
"""Active logger."""
|
|
67
|
-
return self._logger
|
|
68
|
-
|
|
69
|
-
@logger.setter
|
|
70
|
-
def logger(self, val):
|
|
71
|
-
self._logger = val
|
|
73
|
+
self.logger = None
|
|
74
|
+
self.log_file = None
|
|
75
|
+
self._aedt_version = None
|
|
72
76
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
"""Flag that disable Edb log when PyAEDT is used."""
|
|
76
|
-
return self._use_pyaedt_log
|
|
77
|
-
|
|
78
|
-
@use_pyaedt_log.setter
|
|
79
|
-
def use_pyaedt_log(self, value):
|
|
80
|
-
self._use_pyaedt_log = value
|
|
77
|
+
self.__get_version_information()
|
|
78
|
+
self.__init_logger()
|
|
81
79
|
|
|
82
80
|
@property
|
|
83
81
|
def edb_environment_variables(self):
|
|
@@ -261,5 +259,63 @@ class Settings(object):
|
|
|
261
259
|
def retry_n_times_time_interval(self, value):
|
|
262
260
|
self._retry_n_times_time_interval = float(value)
|
|
263
261
|
|
|
262
|
+
def __get_version_information(self):
|
|
263
|
+
"""Get the installed AEDT versions.
|
|
264
|
+
|
|
265
|
+
This method returns a dictionary, with the version as the key and the installation path
|
|
266
|
+
as the value."""
|
|
267
|
+
version_pattern = re.compile(r"^(ANSYSEM_ROOT|ANSYSEM_PY_CLIENT_ROOT|ANSYSEMSV_ROOT)\d{3}$")
|
|
268
|
+
env_list = sorted([x for x in os.environ if version_pattern.match(x)], reverse=True)
|
|
269
|
+
if not env_list: # pragma: no cover
|
|
270
|
+
warnings.warn("No installed versions of AEDT are found in the system environment variables.")
|
|
271
|
+
return
|
|
272
|
+
|
|
273
|
+
aedt_system_env_variables = {i: os.environ[i] for i in env_list}
|
|
274
|
+
|
|
275
|
+
standard_versions = {}
|
|
276
|
+
client_versions = {}
|
|
277
|
+
student_versions = {}
|
|
278
|
+
# version_list is ordered: first normal versions, then client versions, finally student versions
|
|
279
|
+
for var_name, aedt_path in aedt_system_env_variables.items():
|
|
280
|
+
version_id = var_name[-3:]
|
|
281
|
+
version, release = version_id[0:2], version_id[2]
|
|
282
|
+
version_name = f"20{version}.{release}"
|
|
283
|
+
if "ANSYSEM_ROOT" in var_name:
|
|
284
|
+
standard_versions[version_name] = aedt_path
|
|
285
|
+
elif "ANSYSEM_PY_CLIENT_ROOT" in var_name:
|
|
286
|
+
client_versions[version_name] = aedt_path
|
|
287
|
+
else:
|
|
288
|
+
student_versions[version_name] = aedt_path
|
|
289
|
+
self.INSTALLED_VERSIONS = standard_versions
|
|
290
|
+
self.INSTALLED_STUDENT_VERSIONS = student_versions
|
|
291
|
+
self.INSTALLED_CLIENT_VERSIONS = client_versions
|
|
292
|
+
|
|
293
|
+
if len(self.INSTALLED_VERSIONS):
|
|
294
|
+
self.LATEST_VERSION = max(standard_versions.keys(), key=lambda x: tuple(map(int, x.split("."))))
|
|
295
|
+
if len(self.INSTALLED_STUDENT_VERSIONS):
|
|
296
|
+
self.LATEST_STUDENT_VERSION = max(student_versions.keys(), key=lambda x: tuple(map(int, x.split("."))))
|
|
297
|
+
|
|
298
|
+
@property
|
|
299
|
+
def aedt_installation_path(self):
|
|
300
|
+
if self.edb_dll_path:
|
|
301
|
+
return self.edb_dll_path
|
|
302
|
+
elif self.is_student_version:
|
|
303
|
+
return self.INSTALLED_STUDENT_VERSIONS[self.specified_version]
|
|
304
|
+
elif self.specified_version in self.INSTALLED_VERSIONS.keys():
|
|
305
|
+
return self.INSTALLED_VERSIONS[self.specified_version]
|
|
306
|
+
elif os.name == "posix":
|
|
307
|
+
main = sys.modules["__main__"]
|
|
308
|
+
if "oDesktop" in dir(main):
|
|
309
|
+
return main.oDesktop.GetExeDir()
|
|
310
|
+
else:
|
|
311
|
+
raise RuntimeError(f"Version {self.specified_version} is not installed on the system. ")
|
|
312
|
+
else:
|
|
313
|
+
raise RuntimeError(f"Version {self.specified_version} is not installed on the system. ")
|
|
314
|
+
|
|
315
|
+
def __init_logger(self):
|
|
316
|
+
from pyedb.edb_logger import EdbLogger
|
|
317
|
+
|
|
318
|
+
self.logger = EdbLogger(to_stdout=self.enable_screen_logs, settings=self)
|
|
319
|
+
|
|
264
320
|
|
|
265
321
|
settings = Settings()
|
|
@@ -57,6 +57,7 @@ from pyedb.grpc.database.hierarchy.pingroup import PinGroup
|
|
|
57
57
|
from pyedb.grpc.database.padstacks import Padstacks
|
|
58
58
|
from pyedb.grpc.database.utility.sources import SourceType
|
|
59
59
|
from pyedb.grpc.database.utility.value import Value
|
|
60
|
+
from pyedb.misc.decorators import deprecate_argument_name
|
|
60
61
|
from pyedb.modeler.geometry_operators import GeometryOperators
|
|
61
62
|
|
|
62
63
|
|
|
@@ -500,6 +501,7 @@ class Components(object):
|
|
|
500
501
|
"""
|
|
501
502
|
return self.instances[name]
|
|
502
503
|
|
|
504
|
+
@deprecate_argument_name({"pinName": "pin_name"})
|
|
503
505
|
def get_pin_from_component(
|
|
504
506
|
self,
|
|
505
507
|
component: Union[str, Component],
|
|
@@ -27,8 +27,8 @@ import subprocess
|
|
|
27
27
|
import sys
|
|
28
28
|
from typing import Any, Dict, List, Optional, Union
|
|
29
29
|
|
|
30
|
-
from pyedb.edb_logger import pyedb_logger
|
|
31
30
|
from pyedb.generic.general_methods import ET, env_path, env_value, is_linux
|
|
31
|
+
from pyedb.generic.settings import settings
|
|
32
32
|
from pyedb.misc.aedtlib_personalib_install import write_pretty_xml
|
|
33
33
|
from pyedb.misc.misc import list_installed_ansysem
|
|
34
34
|
|
|
@@ -194,7 +194,7 @@ def convert_technology_file(tech_file, edbversion=None, control_file=None):
|
|
|
194
194
|
base_path = env_path(edbversion)
|
|
195
195
|
sys.path.append(base_path)
|
|
196
196
|
else:
|
|
197
|
-
|
|
197
|
+
settings.logger.error("No EDB installation found. Check environment variables")
|
|
198
198
|
return False
|
|
199
199
|
os.environ["HELIC_ROOT"] = os.path.join(base_path, "helic")
|
|
200
200
|
if os.getenv("ANSYSLMD_LICENCE_FILE", None) is None:
|
|
@@ -207,7 +207,7 @@ def convert_technology_file(tech_file, edbversion=None, control_file=None):
|
|
|
207
207
|
os.environ["ANSYSLMD_LICENSE_FILE"] = line.split("=")[1]
|
|
208
208
|
break
|
|
209
209
|
else:
|
|
210
|
-
|
|
210
|
+
settings.logger.error("ANSYSLMD_LICENSE_FILE is not defined.")
|
|
211
211
|
vlc_file_name = os.path.splitext(tech_file)[0]
|
|
212
212
|
if not control_file:
|
|
213
213
|
control_file = vlc_file_name + ".xml"
|
|
@@ -241,9 +241,9 @@ def convert_technology_file(tech_file, edbversion=None, control_file=None):
|
|
|
241
241
|
p = subprocess.Popen(command, env=my_env)
|
|
242
242
|
p.wait()
|
|
243
243
|
if os.path.exists(control_file):
|
|
244
|
-
|
|
244
|
+
settings.logger.info("XML file created.")
|
|
245
245
|
return control_file
|
|
246
|
-
|
|
246
|
+
settings.logger.error("Technology files are supported only in Linux. Use control file instead.")
|
|
247
247
|
return False
|
|
248
248
|
|
|
249
249
|
|
|
@@ -378,7 +378,7 @@ class Material(GrpcMaterialDef):
|
|
|
378
378
|
"Use property dielectric_loss_tangent instead.",
|
|
379
379
|
DeprecationWarning,
|
|
380
380
|
)
|
|
381
|
-
self.dielectric_loss_tangent
|
|
381
|
+
self.dielectric_loss_tangent = value
|
|
382
382
|
|
|
383
383
|
@dielectric_loss_tangent.setter
|
|
384
384
|
def dielectric_loss_tangent(self, value):
|
|
@@ -23,10 +23,10 @@
|
|
|
23
23
|
from ansys.edb.core.definition.package_def import PackageDef as GrpcPackageDef
|
|
24
24
|
from ansys.edb.core.geometry.polygon_data import PolygonData as GrpcPolygonData
|
|
25
25
|
|
|
26
|
-
from pyedb.
|
|
26
|
+
from pyedb.generic.settings import settings
|
|
27
27
|
from pyedb.grpc.database.utility.heat_sink import HeatSink
|
|
28
28
|
from pyedb.grpc.database.utility.value import Value
|
|
29
|
-
from pyedb.misc.
|
|
29
|
+
from pyedb.misc.decorators import deprecated_property
|
|
30
30
|
|
|
31
31
|
|
|
32
32
|
class PackageDef(GrpcPackageDef):
|
|
@@ -82,7 +82,7 @@ class PackageDef(GrpcPackageDef):
|
|
|
82
82
|
else:
|
|
83
83
|
bbox = extent_bounding_box
|
|
84
84
|
if bbox is None:
|
|
85
|
-
|
|
85
|
+
settings.logger.warning(
|
|
86
86
|
"Package creation uses bounding box but it cannot be inferred. "
|
|
87
87
|
"Please set argument 'component_part_name' or 'extent_bounding_box'."
|
|
88
88
|
)
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
# SOFTWARE.
|
|
22
22
|
|
|
23
23
|
import math
|
|
24
|
+
import warnings
|
|
24
25
|
|
|
25
26
|
from ansys.edb.core.definition.padstack_def import PadstackDef as GrpcPadstackDef
|
|
26
27
|
from ansys.edb.core.definition.padstack_def_data import (
|
|
@@ -109,6 +110,26 @@ class PadProperties:
|
|
|
109
110
|
"""
|
|
110
111
|
return self._pad_parameter_value[0].name.split("_")[-1].lower()
|
|
111
112
|
|
|
113
|
+
@shape.setter
|
|
114
|
+
def shape(self, value: str):
|
|
115
|
+
"""Set pad shape.
|
|
116
|
+
|
|
117
|
+
Parameters
|
|
118
|
+
----------
|
|
119
|
+
value : str
|
|
120
|
+
Pad shape.
|
|
121
|
+
"""
|
|
122
|
+
if value.lower() == "circle":
|
|
123
|
+
self._update_pad_parameters_parameters(geom_type=GrpcPadGeometryType.PADGEOMTYPE_CIRCLE)
|
|
124
|
+
elif value.lower() == "rectangle":
|
|
125
|
+
self._update_pad_parameters_parameters(geom_type=GrpcPadGeometryType.PADGEOMTYPE_RECTANGLE)
|
|
126
|
+
elif value.lower() == "polygon":
|
|
127
|
+
self._update_pad_parameters_parameters(geom_type=GrpcPadGeometryType.PADGEOMTYPE_POLYGON)
|
|
128
|
+
else:
|
|
129
|
+
raise ValueError(
|
|
130
|
+
f"Unsupported pad shape: {value}. Supported shapes are 'circle', " f"'rectangle', and 'polygon'."
|
|
131
|
+
)
|
|
132
|
+
|
|
112
133
|
@property
|
|
113
134
|
def parameters_values(self):
|
|
114
135
|
"""Parameters.
|
|
@@ -300,6 +321,22 @@ class PadstackDef(GrpcPadstackDef):
|
|
|
300
321
|
"""
|
|
301
322
|
return self.layers[0]
|
|
302
323
|
|
|
324
|
+
@property
|
|
325
|
+
def via_start_layer(self):
|
|
326
|
+
"""Via starting layer.
|
|
327
|
+
|
|
328
|
+
.deprecated
|
|
329
|
+
Use: :method:`start_layer <pyedb.grpc.database.definition.padstack_def.PadstackDef.start_layer>`
|
|
330
|
+
instead.
|
|
331
|
+
|
|
332
|
+
Returns
|
|
333
|
+
-------
|
|
334
|
+
str
|
|
335
|
+
Name of the via starting layer.
|
|
336
|
+
"""
|
|
337
|
+
warnings.warn("via_start_layer is deprecated. Use start_layer instead.", DeprecationWarning)
|
|
338
|
+
return self.start_layer
|
|
339
|
+
|
|
303
340
|
@property
|
|
304
341
|
def stop_layer(self):
|
|
305
342
|
"""Stopping layer.
|
|
@@ -311,6 +348,22 @@ class PadstackDef(GrpcPadstackDef):
|
|
|
311
348
|
"""
|
|
312
349
|
return self.layers[-1]
|
|
313
350
|
|
|
351
|
+
@property
|
|
352
|
+
def via_stop_layer(self):
|
|
353
|
+
"""Via stop layer.
|
|
354
|
+
|
|
355
|
+
.deprecated
|
|
356
|
+
Use :method:`stop_layer <pyedb.grpc.database.definition.padstack_def.PadstackDef.stop_layer>`
|
|
357
|
+
instead.
|
|
358
|
+
|
|
359
|
+
Returns
|
|
360
|
+
-------
|
|
361
|
+
str
|
|
362
|
+
Name of the via stop layer.
|
|
363
|
+
"""
|
|
364
|
+
warnings.warn("via_stop_layer is deprecated. Use stop_layer instead.", DeprecationWarning)
|
|
365
|
+
return self.stop_layer
|
|
366
|
+
|
|
314
367
|
@property
|
|
315
368
|
def hole_diameter(self) -> float:
|
|
316
369
|
"""Hole diameter.
|
|
@@ -127,7 +127,7 @@ class PolygonData(GrpcPolygonData):
|
|
|
127
127
|
bool
|
|
128
128
|
|
|
129
129
|
"""
|
|
130
|
-
new_poly =
|
|
130
|
+
new_poly = super().expand(offset, tolerance, round_corners, maximum_corner_extension)
|
|
131
131
|
if not new_poly[0].points:
|
|
132
132
|
return False
|
|
133
133
|
self._edb_object = new_poly[0]
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"""
|
|
24
24
|
This module contains these classes: `EdbLayout` and `Shape`.
|
|
25
25
|
"""
|
|
26
|
-
from typing import Union
|
|
26
|
+
from typing import Dict, Union
|
|
27
27
|
|
|
28
28
|
from ansys.edb.core.layout.layout import Layout as GrpcLayout
|
|
29
29
|
import ansys.edb.core.primitive.bondwire
|
|
@@ -63,6 +63,7 @@ class Layout(GrpcLayout):
|
|
|
63
63
|
super().__init__(pedb.active_cell._Cell__stub.GetLayout(pedb.active_cell.msg))
|
|
64
64
|
self._pedb = pedb
|
|
65
65
|
self.__primitives = []
|
|
66
|
+
self.__padstack_instances = {}
|
|
66
67
|
|
|
67
68
|
@property
|
|
68
69
|
def cell(self):
|
|
@@ -74,8 +75,9 @@ class Layout(GrpcLayout):
|
|
|
74
75
|
|
|
75
76
|
@property
|
|
76
77
|
def primitives(self) -> list[any]:
|
|
78
|
+
primitives = super().primitives
|
|
77
79
|
self.__primitives = []
|
|
78
|
-
for prim in
|
|
80
|
+
for prim in primitives:
|
|
79
81
|
if isinstance(prim, ansys.edb.core.primitive.path.Path):
|
|
80
82
|
self.__primitives.append(Path(self._pedb, prim))
|
|
81
83
|
elif isinstance(prim, ansys.edb.core.primitive.polygon.Polygon):
|
|
@@ -196,11 +198,12 @@ class Layout(GrpcLayout):
|
|
|
196
198
|
return [DifferentialPair(self._pedb, i) for i in self._pedb.active_cell.layout.differential_pairs]
|
|
197
199
|
|
|
198
200
|
@property
|
|
199
|
-
def padstack_instances(self) ->
|
|
201
|
+
def padstack_instances(self) -> Dict[int, PadstackInstance]:
|
|
200
202
|
"""Get all padstack instances in a list."""
|
|
201
|
-
|
|
203
|
+
pad_stack_inst = super().padstack_instances
|
|
204
|
+
self.__padstack_instances = {i.edb_uid: PadstackInstance(self._pedb, i) for i in pad_stack_inst}
|
|
205
|
+
return self.__padstack_instances
|
|
202
206
|
|
|
203
|
-
#
|
|
204
207
|
@property
|
|
205
208
|
def voltage_regulators(self) -> list[VoltageRegulator]:
|
|
206
209
|
"""Voltage regulators.
|
|
@@ -334,7 +334,7 @@ class LayoutValidation:
|
|
|
334
334
|
new_name = re.sub(pattern, "_", net)
|
|
335
335
|
val.name = new_name
|
|
336
336
|
|
|
337
|
-
self._pedb.
|
|
337
|
+
self._pedb.logger.info("Found {} illegal net names.".format(len(renamed_nets)))
|
|
338
338
|
return
|
|
339
339
|
|
|
340
340
|
def illegal_rlc_values(self, fix: bool = False) -> List[str]:
|
|
@@ -358,7 +358,7 @@ class LayoutValidation:
|
|
|
358
358
|
temp.append(k)
|
|
359
359
|
if fix:
|
|
360
360
|
v.rlc_values = [0, 1, 0]
|
|
361
|
-
self._pedb.
|
|
361
|
+
self._pedb.logger.info(f"Found {len(temp)} inductors have no value.")
|
|
362
362
|
return temp
|
|
363
363
|
|
|
364
364
|
def padstacks_no_name(self, fix: bool = False) -> None:
|
|
@@ -389,4 +389,4 @@ class LayoutValidation:
|
|
|
389
389
|
obj.set_product_property(
|
|
390
390
|
GrpcProductIdType.DESIGNER, 11, f"{obj.component.name}-{obj.component_pin}"
|
|
391
391
|
)
|
|
392
|
-
self._pedb.
|
|
392
|
+
self._pedb.logger.info(f"Found {counts}/{len(pds)} padstacks have no name.")
|
pyedb/grpc/database/modeler.py
CHANGED
|
@@ -92,7 +92,8 @@ class Modeler(object):
|
|
|
92
92
|
def __init__(self, p_edb) -> None:
|
|
93
93
|
"""Initialize Modeler instance."""
|
|
94
94
|
self._pedb = p_edb
|
|
95
|
-
self.
|
|
95
|
+
self.__primitives = []
|
|
96
|
+
self.__primitives_by_layer = {}
|
|
96
97
|
|
|
97
98
|
@property
|
|
98
99
|
def _edb(self) -> Any:
|
|
@@ -267,7 +268,7 @@ class Modeler(object):
|
|
|
267
268
|
try:
|
|
268
269
|
lay = i.layer.name
|
|
269
270
|
if lay in _primitives_by_layer:
|
|
270
|
-
_primitives_by_layer[lay].append(
|
|
271
|
+
_primitives_by_layer[lay].append(i)
|
|
271
272
|
except (InvalidArgumentException, AttributeError):
|
|
272
273
|
pass
|
|
273
274
|
return _primitives_by_layer
|
|
@@ -1114,7 +1115,7 @@ class Modeler(object):
|
|
|
1114
1115
|
# return None
|
|
1115
1116
|
# pointA = GrpcPointData(pointA[0]), self._get_edb_value(shape.pointA[1])
|
|
1116
1117
|
# )
|
|
1117
|
-
# pointB = self._edb.
|
|
1118
|
+
# pointB = self._edb.Geometry.PointData(
|
|
1118
1119
|
# self._get_edb_value(shape.pointB[0]), self._get_edb_value(shape.pointB[1])
|
|
1119
1120
|
# )
|
|
1120
1121
|
# return self._edb.geometry.polygon_data.create_from_bbox((pointA, pointB))
|
|
@@ -1475,7 +1476,11 @@ class Modeler(object):
|
|
|
1475
1476
|
if isinstance(pins_by_name, str):
|
|
1476
1477
|
pins_by_name = [pins_by_name]
|
|
1477
1478
|
p_inst = self._pedb.layout.padstack_instances
|
|
1478
|
-
_pins = {
|
|
1479
|
+
_pins = {
|
|
1480
|
+
pin_id: pin
|
|
1481
|
+
for pin_id, pin in p_inst.items()
|
|
1482
|
+
if pin.aedt_name in pins_by_aedt_name or pin.name in pins_by_name
|
|
1483
|
+
}
|
|
1479
1484
|
if not pins:
|
|
1480
1485
|
pins = _pins
|
|
1481
1486
|
else:
|
pyedb/grpc/database/net/net.py
CHANGED
|
@@ -60,7 +60,7 @@ class Net(GrpcNet):
|
|
|
60
60
|
self._pedb = pedb
|
|
61
61
|
self._core_components = pedb.components
|
|
62
62
|
self._core_primitive = pedb.modeler
|
|
63
|
-
self.
|
|
63
|
+
self.__primitives = []
|
|
64
64
|
|
|
65
65
|
@property
|
|
66
66
|
def primitives(self) -> list[Union[Path, Polygon, Circle, Rectangle, Bondwire]]:
|
|
@@ -76,19 +76,20 @@ class Net(GrpcNet):
|
|
|
76
76
|
- :class:`Rectangle <pyedb.grpc.database.primitive.rectangle.Rectangle>`
|
|
77
77
|
- :class:`Bondwire <pyedb.grpc.database.primitive.bondwire.Bondwire>`
|
|
78
78
|
"""
|
|
79
|
-
primitives =
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
79
|
+
primitives = super().primitives
|
|
80
|
+
if not len(self.__primitives) == len(primitives):
|
|
81
|
+
for primitive in primitives:
|
|
82
|
+
if primitive.primitive_type == GrpcPrimitiveType.PATH:
|
|
83
|
+
self.__primitives.append(Path(self._pedb, primitive))
|
|
84
|
+
elif primitive.primitive_type == GrpcPrimitiveType.POLYGON:
|
|
85
|
+
self.__primitives.append(Polygon(self._pedb, primitive))
|
|
86
|
+
elif primitive.primitive_type == GrpcPrimitiveType.CIRCLE:
|
|
87
|
+
self.__primitives.append(Circle(self._pedb, primitive))
|
|
88
|
+
elif primitive.primitive_type == GrpcPrimitiveType.RECTANGLE:
|
|
89
|
+
self.__primitives.append(Rectangle(self._pedb, primitive))
|
|
90
|
+
elif primitive.primitive_type == GrpcPrimitiveType.BONDWIRE:
|
|
91
|
+
self.__primitives.append(Bondwire(self._pedb, primitive))
|
|
92
|
+
return self.__primitives
|
|
92
93
|
|
|
93
94
|
@property
|
|
94
95
|
def padstack_instances(self) -> list[PadstackInstance]:
|
pyedb/grpc/database/nets.py
CHANGED
|
@@ -25,9 +25,12 @@ from __future__ import absolute_import # noreorder
|
|
|
25
25
|
from typing import Any, Dict, List, Optional, Set, Tuple, Union
|
|
26
26
|
import warnings
|
|
27
27
|
|
|
28
|
+
from ansys.edb.core.net.net_class import NetClass as GrpcNetClass
|
|
29
|
+
|
|
28
30
|
from pyedb.common.nets import CommonNets
|
|
29
31
|
from pyedb.generic.general_methods import generate_unique_name
|
|
30
32
|
from pyedb.grpc.database.net.net import Net
|
|
33
|
+
from pyedb.grpc.database.net.net_class import NetClass
|
|
31
34
|
from pyedb.grpc.database.primitive.bondwire import Bondwire
|
|
32
35
|
from pyedb.grpc.database.primitive.path import Path
|
|
33
36
|
from pyedb.grpc.database.primitive.polygon import Polygon
|
|
@@ -888,3 +891,70 @@ class Nets(CommonNets):
|
|
|
888
891
|
if isinstance(net_names_list, str):
|
|
889
892
|
net_names_list = [net_names_list]
|
|
890
893
|
return self._pedb.modeler.unite_polygons_on_layer(net_names_list=net_names_list)
|
|
894
|
+
|
|
895
|
+
|
|
896
|
+
class NetClasses:
|
|
897
|
+
"""Net classes management.
|
|
898
|
+
|
|
899
|
+
This class provides access to net classes in the EDB layout.
|
|
900
|
+
It allows for operations like retrieving nets, adding/removing nets,
|
|
901
|
+
and checking if a net is part of a net class.
|
|
902
|
+
|
|
903
|
+
Examples
|
|
904
|
+
--------
|
|
905
|
+
>>> from pyedb import Edb
|
|
906
|
+
>>> edb = Edb(myedb, edbversion="2025.1")
|
|
907
|
+
>>> net_classes = edb.net_classes
|
|
908
|
+
"""
|
|
909
|
+
|
|
910
|
+
def __init__(self, pedb):
|
|
911
|
+
self._pedb = pedb
|
|
912
|
+
self._net_classes = pedb.active_layout.net_classes
|
|
913
|
+
|
|
914
|
+
def __getitem__(self, name: str) -> NetClass:
|
|
915
|
+
"""Get a net by name.
|
|
916
|
+
|
|
917
|
+
Parameters
|
|
918
|
+
----------
|
|
919
|
+
name : str
|
|
920
|
+
Name of the net to retrieve.
|
|
921
|
+
|
|
922
|
+
"""
|
|
923
|
+
return self.items[name]
|
|
924
|
+
|
|
925
|
+
@property
|
|
926
|
+
def items(self) -> Dict[str, NetClass]:
|
|
927
|
+
"""Extended nets.
|
|
928
|
+
|
|
929
|
+
Returns
|
|
930
|
+
-------
|
|
931
|
+
Dict[str, :class:`pyedb.grpc.database.nets.nets_class.NetClass`]
|
|
932
|
+
Dictionary of extended nets.
|
|
933
|
+
"""
|
|
934
|
+
return {i.name: i for i in self._pedb.layout.net_classes}
|
|
935
|
+
|
|
936
|
+
def create(self, name, net) -> Union[bool, NetClass]:
|
|
937
|
+
"""Create a new net class.
|
|
938
|
+
|
|
939
|
+
Parameters
|
|
940
|
+
----------
|
|
941
|
+
name : str
|
|
942
|
+
Name of the net class.
|
|
943
|
+
net : str, list
|
|
944
|
+
Name of the nets to be added into this net class.
|
|
945
|
+
|
|
946
|
+
Returns
|
|
947
|
+
-------
|
|
948
|
+
:class:`pyedb.dotnet.database.edb_data.nets_data.EDBNetClassData` `False` if net name already exists.
|
|
949
|
+
"""
|
|
950
|
+
if name in self.items:
|
|
951
|
+
self._pedb.logger.error("{} already exists.".format(name))
|
|
952
|
+
return False
|
|
953
|
+
grpc_net_class = GrpcNetClass.create(self._pedb.active_layout, name)
|
|
954
|
+
if isinstance(net, str):
|
|
955
|
+
net = [net]
|
|
956
|
+
for i in net:
|
|
957
|
+
grpc_net_class.add_net(self._pedb.nets[i])
|
|
958
|
+
net_class = NetClass(self._pedb, grpc_net_class)
|
|
959
|
+
self.items[name] = net_class
|
|
960
|
+
return net_class
|
pyedb/grpc/database/padstacks.py
CHANGED
|
@@ -93,8 +93,7 @@ class Padstacks(object):
|
|
|
93
93
|
|
|
94
94
|
def __init__(self, p_edb: Any) -> None:
|
|
95
95
|
self._pedb = p_edb
|
|
96
|
-
self.
|
|
97
|
-
self._definitions: Dict[str, Any] = {}
|
|
96
|
+
self.__definitions: Dict[str, Any] = {}
|
|
98
97
|
|
|
99
98
|
@property
|
|
100
99
|
def _active_layout(self) -> Any:
|
|
@@ -211,13 +210,12 @@ class Padstacks(object):
|
|
|
211
210
|
>>> for name, definition in all_definitions.items():
|
|
212
211
|
... print(f"Padstack: {name}")
|
|
213
212
|
"""
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
for padstack_def in self._pedb.db.padstack_defs:
|
|
213
|
+
padstack_defs = self._pedb.db.padstack_defs
|
|
214
|
+
self.__definitions = {}
|
|
215
|
+
for padstack_def in padstack_defs:
|
|
218
216
|
if len(padstack_def.data.layer_names) >= 1:
|
|
219
|
-
self.
|
|
220
|
-
return self.
|
|
217
|
+
self.__definitions[padstack_def.name] = PadstackDef(self._pedb, padstack_def)
|
|
218
|
+
return self.__definitions
|
|
221
219
|
|
|
222
220
|
@property
|
|
223
221
|
def instances(self) -> Dict[int, PadstackInstance]:
|
|
@@ -230,15 +228,11 @@ class Padstacks(object):
|
|
|
230
228
|
|
|
231
229
|
Examples
|
|
232
230
|
--------
|
|
233
|
-
>>> all_instances =
|
|
231
|
+
>>> all_instances = edb.padstacks.instances
|
|
234
232
|
>>> for id, instance in all_instances.items():
|
|
235
233
|
... print(f"Instance {id}: {instance.name}")
|
|
236
234
|
"""
|
|
237
|
-
|
|
238
|
-
if len(self._instances) == len(pad_stack_inst):
|
|
239
|
-
return self._instances
|
|
240
|
-
self._instances = {i.edb_uid: PadstackInstance(self._pedb, i) for i in pad_stack_inst}
|
|
241
|
-
return self._instances
|
|
235
|
+
return self._pedb.layout.padstack_instances
|
|
242
236
|
|
|
243
237
|
@property
|
|
244
238
|
def instances_by_name(self) -> Dict[str, PadstackInstance]:
|
|
@@ -348,6 +342,7 @@ class Padstacks(object):
|
|
|
348
342
|
@property
|
|
349
343
|
def pad_type(self) -> GrpcPadType:
|
|
350
344
|
"""Return a PadType Enumerator."""
|
|
345
|
+
return GrpcPadType
|
|
351
346
|
|
|
352
347
|
def create_circular_padstack(
|
|
353
348
|
self,
|
|
@@ -800,7 +795,7 @@ class Padstacks(object):
|
|
|
800
795
|
if net_list and not isinstance(net_list, list):
|
|
801
796
|
net_list = [net_list]
|
|
802
797
|
via_list = []
|
|
803
|
-
for inst in self._layout.padstack_instances:
|
|
798
|
+
for inst_id, inst in self._layout.padstack_instances.items():
|
|
804
799
|
pad_layers_name = inst.padstack_def.data.layer_names
|
|
805
800
|
if len(pad_layers_name) > 1:
|
|
806
801
|
if not net_list:
|
|
@@ -1150,7 +1145,7 @@ class Padstacks(object):
|
|
|
1150
1145
|
padstack_instance.is_layout_pin = is_pin
|
|
1151
1146
|
return PadstackInstance(self._pedb, padstack_instance)
|
|
1152
1147
|
else:
|
|
1153
|
-
|
|
1148
|
+
raise RuntimeError("Place padstack failed")
|
|
1154
1149
|
|
|
1155
1150
|
def remove_pads_from_padstack(self, padstack_name: str, layer_name: Optional[str] = None):
|
|
1156
1151
|
"""Remove pads from a padstack definition on specified layers.
|
|
@@ -1287,6 +1282,29 @@ class Padstacks(object):
|
|
|
1287
1282
|
self.definitions[padstack_name].data = new_padstack_def
|
|
1288
1283
|
return True
|
|
1289
1284
|
|
|
1285
|
+
def get_padstack_instance_by_net_name(self, net: str):
|
|
1286
|
+
"""Get padstack instances by net name.
|
|
1287
|
+
|
|
1288
|
+
.. deprecated:: 0.55.0
|
|
1289
|
+
Use: :func:`get_instances` with `net_name` parameter instead.
|
|
1290
|
+
|
|
1291
|
+
Parameters
|
|
1292
|
+
----------
|
|
1293
|
+
net : str
|
|
1294
|
+
Net name to filter padstack instances.
|
|
1295
|
+
|
|
1296
|
+
Returns
|
|
1297
|
+
-------
|
|
1298
|
+
list[:class:`pyedb.grpc.database.primitive.padstack_instance.PadstackInstance`]
|
|
1299
|
+
List of padstack instances associated with the specified net.
|
|
1300
|
+
"""
|
|
1301
|
+
warnings.warn(
|
|
1302
|
+
"`get_padstack_instance_by_net_name` is deprecated, use `get_instances` with `net_name` "
|
|
1303
|
+
"parameter instead.",
|
|
1304
|
+
DeprecationWarning,
|
|
1305
|
+
)
|
|
1306
|
+
return self.get_instances(net_name=net)
|
|
1307
|
+
|
|
1290
1308
|
def get_instances(
|
|
1291
1309
|
self,
|
|
1292
1310
|
name: Optional[str] = None,
|
|
@@ -1322,7 +1340,7 @@ class Padstacks(object):
|
|
|
1322
1340
|
if pid:
|
|
1323
1341
|
return instances_by_id[pid]
|
|
1324
1342
|
elif name:
|
|
1325
|
-
instances = [inst for inst in list(self.instances.values()) if inst.
|
|
1343
|
+
instances = [inst for inst in list(self.instances.values()) if inst.aedt_name == name]
|
|
1326
1344
|
if instances:
|
|
1327
1345
|
return instances
|
|
1328
1346
|
else:
|