pyedb 0.56.0__py3-none-any.whl → 0.58.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_data.py +3 -0
- pyedb/configuration/cfg_pin_groups.py +2 -0
- pyedb/configuration/cfg_terminals.py +232 -0
- pyedb/configuration/configuration.py +146 -3
- pyedb/dotnet/clr_module.py +1 -2
- pyedb/dotnet/database/Variables.py +30 -22
- pyedb/dotnet/database/cell/hierarchy/component.py +2 -8
- pyedb/dotnet/database/cell/layout.py +5 -1
- pyedb/dotnet/database/cell/primitive/primitive.py +2 -2
- pyedb/dotnet/database/cell/terminal/bundle_terminal.py +12 -0
- pyedb/dotnet/database/cell/terminal/pingroup_terminal.py +1 -1
- pyedb/dotnet/database/cell/terminal/terminal.py +38 -0
- pyedb/dotnet/database/components.py +15 -19
- pyedb/dotnet/database/dotnet/database.py +1 -0
- pyedb/dotnet/database/edb_data/control_file.py +19 -8
- pyedb/dotnet/database/edb_data/nets_data.py +3 -3
- pyedb/dotnet/database/edb_data/padstacks_data.py +39 -14
- pyedb/dotnet/database/edb_data/ports.py +0 -25
- pyedb/dotnet/database/edb_data/primitives_data.py +3 -3
- pyedb/dotnet/database/edb_data/raptor_x_simulation_setup_data.py +18 -19
- pyedb/dotnet/database/edb_data/simulation_configuration.py +3 -3
- pyedb/dotnet/database/edb_data/sources.py +21 -2
- pyedb/dotnet/database/general.py +1 -6
- pyedb/dotnet/database/hfss.py +9 -8
- pyedb/dotnet/database/layout_validation.py +14 -3
- pyedb/dotnet/database/materials.py +1 -3
- pyedb/dotnet/database/modeler.py +7 -3
- pyedb/dotnet/database/nets.py +27 -19
- pyedb/dotnet/database/padstack.py +4 -2
- pyedb/dotnet/database/sim_setup_data/io/siwave.py +54 -1
- pyedb/dotnet/database/siwave.py +4 -3
- pyedb/dotnet/database/stackup.py +55 -58
- pyedb/dotnet/database/utilities/heatsink.py +0 -1
- pyedb/dotnet/database/utilities/hfss_simulation_setup.py +81 -0
- pyedb/dotnet/database/utilities/simulation_setup.py +7 -5
- pyedb/dotnet/database/utilities/siwave_cpa_simulation_setup.py +1 -0
- pyedb/dotnet/database/utilities/siwave_simulation_setup.py +264 -13
- pyedb/dotnet/edb.py +65 -47
- pyedb/exceptions.py +1 -2
- pyedb/extensions/create_cell_array.py +67 -49
- pyedb/generic/data_handlers.py +13 -23
- pyedb/generic/design_types.py +9 -35
- pyedb/generic/filesystem.py +4 -2
- pyedb/generic/general_methods.py +28 -41
- pyedb/generic/plot.py +8 -23
- pyedb/generic/process.py +78 -10
- pyedb/grpc/database/_typing.py +0 -0
- pyedb/grpc/database/components.py +14 -13
- pyedb/grpc/database/control_file.py +27 -40
- pyedb/grpc/database/definition/materials.py +1 -1
- pyedb/grpc/database/definition/package_def.py +6 -3
- pyedb/grpc/database/definition/padstack_def.py +14 -12
- pyedb/grpc/database/hfss.py +1 -4
- pyedb/grpc/database/hierarchy/component.py +5 -13
- pyedb/grpc/database/hierarchy/pingroup.py +16 -3
- pyedb/grpc/database/layers/layer.py +1 -2
- pyedb/grpc/database/layers/stackup_layer.py +42 -19
- pyedb/grpc/database/layout/layout.py +43 -27
- pyedb/grpc/database/layout/voltage_regulator.py +6 -1
- pyedb/grpc/database/layout_validation.py +5 -2
- pyedb/grpc/database/modeler.py +254 -252
- pyedb/grpc/database/net/differential_pair.py +9 -2
- pyedb/grpc/database/net/extended_net.py +24 -9
- pyedb/grpc/database/net/net.py +14 -5
- pyedb/grpc/database/net/net_class.py +24 -7
- pyedb/grpc/database/nets.py +11 -43
- pyedb/grpc/database/padstacks.py +67 -119
- pyedb/grpc/database/primitive/bondwire.py +3 -67
- pyedb/grpc/database/primitive/circle.py +42 -3
- pyedb/grpc/database/primitive/padstack_instance.py +58 -31
- pyedb/grpc/database/primitive/path.py +160 -11
- pyedb/grpc/database/primitive/polygon.py +73 -7
- pyedb/grpc/database/primitive/primitive.py +2 -2
- pyedb/grpc/database/primitive/rectangle.py +105 -4
- pyedb/grpc/database/simulation_setup/hfss_general_settings.py +0 -2
- pyedb/grpc/database/simulation_setup/hfss_settings_options.py +0 -4
- pyedb/grpc/database/simulation_setup/hfss_simulation_setup.py +79 -0
- pyedb/grpc/database/simulation_setup/siwave_cpa_simulation_setup.py +1 -0
- pyedb/grpc/database/simulation_setup/sweep_data.py +1 -3
- pyedb/grpc/database/siwave.py +6 -13
- pyedb/grpc/database/source_excitations.py +46 -63
- pyedb/grpc/database/stackup.py +55 -60
- pyedb/grpc/database/terminal/bundle_terminal.py +10 -3
- pyedb/grpc/database/terminal/padstack_instance_terminal.py +9 -11
- pyedb/grpc/database/terminal/pingroup_terminal.py +8 -1
- pyedb/grpc/database/terminal/point_terminal.py +30 -0
- pyedb/grpc/database/terminal/terminal.py +35 -10
- pyedb/grpc/database/utility/heat_sink.py +0 -1
- pyedb/grpc/database/utility/hfss_extent_info.py +2 -2
- pyedb/grpc/database/utility/xml_control_file.py +19 -8
- pyedb/grpc/edb.py +63 -32
- pyedb/grpc/edb_init.py +1 -0
- pyedb/ipc2581/ecad/cad_data/layer_feature.py +6 -2
- pyedb/ipc2581/ecad/cad_data/step.py +1 -1
- pyedb/ipc2581/ipc2581.py +8 -7
- pyedb/libraries/common.py +3 -4
- pyedb/libraries/rf_libraries/base_functions.py +7 -16
- pyedb/libraries/rf_libraries/planar_antennas.py +3 -21
- pyedb/misc/aedtlib_personalib_install.py +2 -2
- pyedb/misc/downloads.py +19 -3
- pyedb/misc/misc.py +5 -2
- pyedb/misc/siw_feature_config/emc_rule_checker_settings.py +3 -2
- pyedb/misc/siw_feature_config/xtalk_scan/scan_config.py +0 -1
- pyedb/misc/utilities.py +0 -1
- pyedb/modeler/geometry_operators.py +3 -2
- {pyedb-0.56.0.dist-info → pyedb-0.58.0.dist-info}/METADATA +6 -7
- {pyedb-0.56.0.dist-info → pyedb-0.58.0.dist-info}/RECORD +110 -108
- {pyedb-0.56.0.dist-info → pyedb-0.58.0.dist-info}/WHEEL +0 -0
- {pyedb-0.56.0.dist-info → pyedb-0.58.0.dist-info}/licenses/LICENSE +0 -0
pyedb/generic/process.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import os.path
|
|
2
2
|
from pathlib import Path
|
|
3
|
-
import subprocess
|
|
3
|
+
import subprocess # nosec B404
|
|
4
4
|
|
|
5
5
|
from pyedb.generic.general_methods import is_linux
|
|
6
6
|
|
|
@@ -23,7 +23,63 @@ class SiwaveSolve(object):
|
|
|
23
23
|
full_path = Path(self._pedb.ansys_em_path) / executable
|
|
24
24
|
return str(full_path)
|
|
25
25
|
|
|
26
|
+
def __create_exec(self, type):
|
|
27
|
+
base = os.path.splitext(self._pedb.edbpath)[0]
|
|
28
|
+
txt_path = base + ".txt"
|
|
29
|
+
exec_path = base + ".exec"
|
|
30
|
+
with open(txt_path, "w") as file:
|
|
31
|
+
if type:
|
|
32
|
+
if type == "DCIR":
|
|
33
|
+
file.write("ExecDcSim")
|
|
34
|
+
elif type == "SYZ":
|
|
35
|
+
file.write("ExecSyzSim")
|
|
36
|
+
elif type == "CPA":
|
|
37
|
+
file.write("ExecSentinelCpaSim")
|
|
38
|
+
elif type == "TimeCrosstalk":
|
|
39
|
+
file.write("ExecTimeDomainCrosstalkSim")
|
|
40
|
+
elif type == "FreqCrosstalk":
|
|
41
|
+
file.write("ExecCrosstalkSim")
|
|
42
|
+
elif type == "Impedance":
|
|
43
|
+
file.write("ExecZ0Sim")
|
|
44
|
+
|
|
45
|
+
os.rename(txt_path, exec_path)
|
|
46
|
+
return exec_path
|
|
47
|
+
|
|
48
|
+
def solve_siwave(self, edbpath, analysis_type):
|
|
49
|
+
"""Solve an SIWave setup. Only non-graphical batch mode is supported.
|
|
50
|
+
|
|
51
|
+
Parameters
|
|
52
|
+
----------
|
|
53
|
+
analysis_type: str
|
|
54
|
+
Type of SIWave analysis to perform. Available types are "SYZ", "DCIR", "CPA", "TimeCrosstalk",
|
|
55
|
+
"FreqCrosstalk", "Impedance".
|
|
56
|
+
edbpath: str
|
|
57
|
+
Full path to the .aedb folder, siw or siwz file to be solved.
|
|
58
|
+
siwave_ng: str, optinial
|
|
59
|
+
Path to the siwave_ng. Default is the SIWave installation path.
|
|
60
|
+
"""
|
|
61
|
+
|
|
62
|
+
command = [
|
|
63
|
+
self.__siwave_ng_exe_path,
|
|
64
|
+
edbpath,
|
|
65
|
+
self.__create_exec(type=analysis_type),
|
|
66
|
+
"-formatOutput",
|
|
67
|
+
"-useSubdir",
|
|
68
|
+
]
|
|
69
|
+
try:
|
|
70
|
+
subprocess.run(command, check=True)
|
|
71
|
+
except subprocess.CalledProcessError as e:
|
|
72
|
+
raise RuntimeError(f"An error occurred when launching the solver. Please check input paths") from e
|
|
73
|
+
|
|
26
74
|
def solve(self, num_of_cores=4):
|
|
75
|
+
"""Solve using siwave_ng.exe
|
|
76
|
+
|
|
77
|
+
.. warning::
|
|
78
|
+
Do not execute this function with untrusted function argument, environment
|
|
79
|
+
variables or pyedb global settings.
|
|
80
|
+
See the :ref:`security guide<ref_security_consideration>` for details.
|
|
81
|
+
|
|
82
|
+
"""
|
|
27
83
|
exec_file = os.path.splitext(self._pedb.edbpath)[0] + ".exec"
|
|
28
84
|
if os.path.exists(exec_file):
|
|
29
85
|
with open(exec_file, "r+") as f:
|
|
@@ -39,16 +95,21 @@ class SiwaveSolve(object):
|
|
|
39
95
|
f = open(exec_file, "w")
|
|
40
96
|
f.writelines(content)
|
|
41
97
|
command = [self.__siwave_ng_exe_path, self._pedb.edbpath, exec_file, "-formatOutput -useSubdir"]
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
98
|
+
try:
|
|
99
|
+
subprocess.run(command, check=True) # nosec
|
|
100
|
+
except subprocess.CalledProcessError as e: # nosec
|
|
101
|
+
raise RuntimeError("An error occurred while solving") from e
|
|
46
102
|
|
|
47
103
|
def export_3d_cad(
|
|
48
104
|
self, format_3d="Q3D", output_folder=None, net_list=None, num_cores=4, aedt_file_name=None, hidden=False
|
|
49
105
|
): # pragma: no cover
|
|
50
106
|
"""Export edb to Q3D or HFSS
|
|
51
107
|
|
|
108
|
+
.. warning::
|
|
109
|
+
Do not execute this function with untrusted function argument, environment
|
|
110
|
+
variables or pyedb global settings.
|
|
111
|
+
See the :ref:`security guide<ref_security_consideration>` for details.
|
|
112
|
+
|
|
52
113
|
Parameters
|
|
53
114
|
----------
|
|
54
115
|
format_3d : str, default ``Q3D``
|
|
@@ -97,10 +158,10 @@ class SiwaveSolve(object):
|
|
|
97
158
|
command += ["-RunScriptAndExit", scriptname]
|
|
98
159
|
print(command)
|
|
99
160
|
try:
|
|
100
|
-
result = subprocess.run(command, check=True, capture_output=True)
|
|
161
|
+
result = subprocess.run(command, check=True, capture_output=True) # nosec
|
|
101
162
|
print(result.stdout.decode())
|
|
102
|
-
except subprocess.CalledProcessError as e:
|
|
103
|
-
|
|
163
|
+
except subprocess.CalledProcessError as e: # nosec
|
|
164
|
+
raise RuntimeError("An error occurred while exporting 3D CAD") from e
|
|
104
165
|
return os.path.join(output_folder, aedt_file_name)
|
|
105
166
|
|
|
106
167
|
def export_dc_report(
|
|
@@ -119,6 +180,11 @@ class SiwaveSolve(object):
|
|
|
119
180
|
):
|
|
120
181
|
"""Close EDB and solve it with Siwave.
|
|
121
182
|
|
|
183
|
+
.. warning::
|
|
184
|
+
Do not execute this function with untrusted function argument, environment
|
|
185
|
+
variables or pyedb global settings.
|
|
186
|
+
See the :ref:`security guide<ref_security_consideration>` for details.
|
|
187
|
+
|
|
122
188
|
Parameters
|
|
123
189
|
----------
|
|
124
190
|
siwave_project : str
|
|
@@ -215,6 +281,8 @@ class SiwaveSolve(object):
|
|
|
215
281
|
command.append("-RunScriptAndExit")
|
|
216
282
|
command.append(scriptname)
|
|
217
283
|
print(command)
|
|
218
|
-
|
|
219
|
-
|
|
284
|
+
try:
|
|
285
|
+
subprocess.run(command, check=True) # nosec
|
|
286
|
+
except subprocess.CalledProcessError as e: # nosec
|
|
287
|
+
raise RuntimeError("An error occurred while solving with Siwave") from e
|
|
220
288
|
return output_list
|
|
File without changes
|
|
@@ -20,9 +20,8 @@
|
|
|
20
20
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
21
|
# SOFTWARE.
|
|
22
22
|
|
|
23
|
-
"""This module contains the `Components` class.
|
|
23
|
+
"""This module contains the `Components` class."""
|
|
24
24
|
|
|
25
|
-
"""
|
|
26
25
|
import codecs
|
|
27
26
|
import json
|
|
28
27
|
import math
|
|
@@ -31,8 +30,7 @@ import re
|
|
|
31
30
|
from typing import Any, Dict, List, Optional, Tuple, Union
|
|
32
31
|
import warnings
|
|
33
32
|
|
|
34
|
-
from ansys.edb.core.definition.die_property import DieOrientation as GrpDieOrientation
|
|
35
|
-
from ansys.edb.core.definition.die_property import DieType as GrpcDieType
|
|
33
|
+
from ansys.edb.core.definition.die_property import DieOrientation as GrpDieOrientation, DieType as GrpcDieType
|
|
36
34
|
from ansys.edb.core.definition.solder_ball_property import (
|
|
37
35
|
SolderballShape as GrpcSolderballShape,
|
|
38
36
|
)
|
|
@@ -996,8 +994,7 @@ class Components(object):
|
|
|
996
994
|
"""
|
|
997
995
|
component_definition = ComponentDef.find(self._db, name)
|
|
998
996
|
if component_definition.is_null:
|
|
999
|
-
from ansys.edb.core.layout.cell import Cell as GrpcCell
|
|
1000
|
-
from ansys.edb.core.layout.cell import CellType as GrpcCellType
|
|
997
|
+
from ansys.edb.core.layout.cell import Cell as GrpcCell, CellType as GrpcCellType
|
|
1001
998
|
|
|
1002
999
|
foot_print_cell = GrpcCell.create(self._pedb.active_db, GrpcCellType.FOOTPRINT_CELL, name)
|
|
1003
1000
|
component_definition = ComponentDef.create(self._db, name, fp=foot_print_cell)
|
|
@@ -1013,8 +1010,6 @@ class Components(object):
|
|
|
1013
1010
|
if component_definition_pin.is_null:
|
|
1014
1011
|
self._logger.error(f"Failed to create component definition pin {name}-{pin.name}")
|
|
1015
1012
|
return None
|
|
1016
|
-
else:
|
|
1017
|
-
self._logger.warning("Found existing component definition for footprint {}".format(name))
|
|
1018
1013
|
return component_definition
|
|
1019
1014
|
|
|
1020
1015
|
def create(
|
|
@@ -1077,8 +1072,12 @@ class Components(object):
|
|
|
1077
1072
|
if not compdef:
|
|
1078
1073
|
return False
|
|
1079
1074
|
new_cmp = GrpcComponentGroup.create(self._active_layout, component_name, compdef.name)
|
|
1075
|
+
if new_cmp.is_null:
|
|
1076
|
+
raise ValueError(f"Failed to create component {component_name}.")
|
|
1080
1077
|
if hasattr(pins[0], "component") and pins[0].component:
|
|
1081
|
-
hosting_component_location =
|
|
1078
|
+
hosting_component_location = None
|
|
1079
|
+
if not pins[0].component.is_null:
|
|
1080
|
+
hosting_component_location = pins[0].component.transform
|
|
1082
1081
|
else:
|
|
1083
1082
|
hosting_component_location = None
|
|
1084
1083
|
if not len(pins) == len(compdef.component_pins):
|
|
@@ -1470,13 +1469,15 @@ class Components(object):
|
|
|
1470
1469
|
sball_shape = GrpcSolderballShape.SOLDERBALL_SPHEROID
|
|
1471
1470
|
|
|
1472
1471
|
cmp_property = cmp.component_property
|
|
1473
|
-
if cmp.
|
|
1472
|
+
if cmp.component_type == GrpcComponentType.IC:
|
|
1474
1473
|
ic_die_prop = cmp_property.die_property
|
|
1475
1474
|
ic_die_prop.die_type = GrpcDieType.FLIPCHIP
|
|
1475
|
+
if not cmp.placement_layer == list(self._pedb.stackup.layers.keys())[0]:
|
|
1476
|
+
chip_orientation = "chip_up"
|
|
1476
1477
|
if chip_orientation.lower() == "chip_up":
|
|
1477
|
-
ic_die_prop.
|
|
1478
|
+
ic_die_prop.die_orientation = GrpDieOrientation.CHIP_UP
|
|
1478
1479
|
else:
|
|
1479
|
-
ic_die_prop.
|
|
1480
|
+
ic_die_prop.die_orientation = GrpDieOrientation.CHIP_DOWN
|
|
1480
1481
|
cmp_property.die_property = ic_die_prop
|
|
1481
1482
|
|
|
1482
1483
|
solder_ball_prop = cmp_property.solder_ball_property
|
|
@@ -2228,7 +2229,7 @@ class Components(object):
|
|
|
2228
2229
|
Examples
|
|
2229
2230
|
--------
|
|
2230
2231
|
>>> from pyedb import Edb
|
|
2231
|
-
>>> edb_file = r
|
|
2232
|
+
>>> edb_file = r"C:\my_edb_file.aedb"
|
|
2232
2233
|
>>> edb = Edb(edb_file)
|
|
2233
2234
|
>>> for cmp in list(edb.components.instances.keys()):
|
|
2234
2235
|
>>> edb.components.deactivate_rlc_component(component=cmp, create_circuit_port=False)
|
|
@@ -23,10 +23,12 @@
|
|
|
23
23
|
import copy
|
|
24
24
|
import os
|
|
25
25
|
import re
|
|
26
|
-
import subprocess
|
|
26
|
+
import subprocess # nosec B404
|
|
27
27
|
import sys
|
|
28
28
|
from typing import Any, Dict, List, Optional, Union
|
|
29
29
|
|
|
30
|
+
from defusedxml.ElementTree import parse as defused_parse
|
|
31
|
+
|
|
30
32
|
from pyedb.generic.general_methods import ET, env_path, env_value, is_linux
|
|
31
33
|
from pyedb.generic.settings import settings
|
|
32
34
|
from pyedb.misc.aedtlib_personalib_install import write_pretty_xml
|
|
@@ -36,6 +38,11 @@ from pyedb.misc.misc import list_installed_ansysem
|
|
|
36
38
|
def convert_technology_file(tech_file, edbversion=None, control_file=None):
|
|
37
39
|
"""Convert a technology file to EDB control file (XML).
|
|
38
40
|
|
|
41
|
+
.. warning::
|
|
42
|
+
Do not execute this function with untrusted function argument, environment
|
|
43
|
+
variables or pyedb global settings.
|
|
44
|
+
See the :ref:`security guide<ref_security_consideration>` for details.
|
|
45
|
+
|
|
39
46
|
Parameters
|
|
40
47
|
----------
|
|
41
48
|
tech_file : str
|
|
@@ -58,40 +65,26 @@ def convert_technology_file(tech_file, edbversion=None, control_file=None):
|
|
|
58
65
|
-------
|
|
59
66
|
# Example 1: Converting a technology file to control file
|
|
60
67
|
>>> converted_file = convert_technology_file(
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
>>> control_file="/path/to/output.xml"
|
|
64
|
-
>>> )
|
|
68
|
+
... tech_file="/path/to/tech.t", edbversion="2025.2", control_file="/path/to/output.xml"
|
|
69
|
+
... )
|
|
65
70
|
>>> if converted_file:
|
|
66
71
|
>>> print(f"Converted to: {converted_file}")
|
|
67
72
|
|
|
68
73
|
# Example 2: Creating a material
|
|
69
74
|
>>> from pyedb import ControlFileMaterial
|
|
70
|
-
>>> material = ControlFileMaterial(
|
|
71
|
-
>>> "Copper",
|
|
72
|
-
>>> {"Permittivity": 1.0, "Conductivity": 5.8e7}
|
|
73
|
-
>>> )
|
|
75
|
+
>>> material = ControlFileMaterial("Copper", {"Permittivity": 1.0, "Conductivity": 5.8e7})
|
|
74
76
|
|
|
75
77
|
# Example 3: Creating a dielectric layer
|
|
76
78
|
>>> from pyedb import ControlFileDielectric
|
|
77
|
-
>>> dielectric = ControlFileDielectric(
|
|
78
|
-
>>> "Core",
|
|
79
|
-
>>> {"Thickness": "0.2mm", "Material": "FR4"}
|
|
80
|
-
>>> )
|
|
79
|
+
>>> dielectric = ControlFileDielectric("Core", {"Thickness": "0.2mm", "Material": "FR4"})
|
|
81
80
|
|
|
82
81
|
# Example 4: Creating a signal layer
|
|
83
82
|
>>> from pyedb import ControlFileLayer
|
|
84
|
-
>>> signal_layer = ControlFileLayer(
|
|
85
|
-
>>> "TopLayer",
|
|
86
|
-
>>> {"Type": "signal", "Material": "Copper", "Thickness": "0.035mm"}
|
|
87
|
-
>>> )
|
|
83
|
+
>>> signal_layer = ControlFileLayer("TopLayer", {"Type": "signal", "Material": "Copper", "Thickness": "0.035mm"})
|
|
88
84
|
|
|
89
85
|
# Example 5: Creating a via layer
|
|
90
86
|
>>> from pyedb import ControlFileVia
|
|
91
|
-
>>> via_layer = ControlFileVia(
|
|
92
|
-
>>> "Via1",
|
|
93
|
-
>>> {"StartLayer": "TopLayer", "StopLayer": "BottomLayer"}
|
|
94
|
-
>>> )
|
|
87
|
+
>>> via_layer = ControlFileVia("Via1", {"StartLayer": "TopLayer", "StopLayer": "BottomLayer"})
|
|
95
88
|
>>> via_layer.create_via_group = True
|
|
96
89
|
>>> via_layer.tolerance = "0.1mm"
|
|
97
90
|
|
|
@@ -111,11 +104,7 @@ def convert_technology_file(tech_file, edbversion=None, control_file=None):
|
|
|
111
104
|
|
|
112
105
|
# Example 8: Setting up simulation extents
|
|
113
106
|
>>> from pyedb import ControlExtent
|
|
114
|
-
>>> extent = ControlExtent(
|
|
115
|
-
>>> type="Conforming",
|
|
116
|
-
>>> diel_hactor=0.3,
|
|
117
|
-
>>> airbox_hfactor=0.5
|
|
118
|
-
>>> )
|
|
107
|
+
>>> extent = ControlExtent(type="Conforming", diel_hactor=0.3, airbox_hfactor=0.5)
|
|
119
108
|
|
|
120
109
|
# Example 9: Creating circuit ports
|
|
121
110
|
>>> from pyedb import ControlCircuitPt
|
|
@@ -142,17 +131,11 @@ def convert_technology_file(tech_file, edbversion=None, control_file=None):
|
|
|
142
131
|
|
|
143
132
|
# Example 13: Frequency sweep configuration
|
|
144
133
|
>>> from pyedb import ControlFileSweep
|
|
145
|
-
>>> sweep = ControlFileSweep(
|
|
146
|
-
>>> "Sweep1", "1GHz", "10GHz", "0.1GHz",
|
|
147
|
-
>>> "Interpolating", "LinearStep", True
|
|
148
|
-
>>> )
|
|
134
|
+
>>> sweep = ControlFileSweep("Sweep1", "1GHz", "10GHz", "0.1GHz", "Interpolating", "LinearStep", True)
|
|
149
135
|
|
|
150
136
|
# Example 14: Mesh operation setup
|
|
151
137
|
>>> from pyedb import ControlFileMeshOp
|
|
152
|
-
>>> mesh_op = ControlFileMeshOp(
|
|
153
|
-
>>> "FineMesh", "Region1", "MeshOperationSkinDepth",
|
|
154
|
-
>>> {"Net1": "TopLayer"}
|
|
155
|
-
>>> )
|
|
138
|
+
>>> mesh_op = ControlFileMeshOp("FineMesh", "Region1", "MeshOperationSkinDepth", {"Net1": "TopLayer"})
|
|
156
139
|
>>> mesh_op.skin_depth = "1um"
|
|
157
140
|
|
|
158
141
|
# Example 15: Simulation setup configuration
|
|
@@ -236,10 +219,11 @@ def convert_technology_file(tech_file, edbversion=None, control_file=None):
|
|
|
236
219
|
]
|
|
237
220
|
commands.append(command)
|
|
238
221
|
commands.append(["rm", "-r", vlc_file_name + ".aedb"])
|
|
239
|
-
my_env = os.environ.copy()
|
|
240
222
|
for command in commands:
|
|
241
|
-
|
|
242
|
-
|
|
223
|
+
try:
|
|
224
|
+
subprocess.run(command, check=True) # nosec
|
|
225
|
+
except subprocess.CalledProcessError as e: # nosec
|
|
226
|
+
raise RuntimeError("An error occurred while converting a technology file to edb control file") from e
|
|
243
227
|
if os.path.exists(control_file):
|
|
244
228
|
settings.logger.info("XML file created.")
|
|
245
229
|
return control_file
|
|
@@ -290,8 +274,11 @@ class ControlProperty:
|
|
|
290
274
|
double.text = str(self.value)
|
|
291
275
|
else:
|
|
292
276
|
pass
|
|
293
|
-
except:
|
|
294
|
-
|
|
277
|
+
except Exception as e:
|
|
278
|
+
settings.logger.error(
|
|
279
|
+
f"A(n) {type(e).__name__} error occurred while attempting to create a new sub-element {self.name} "
|
|
280
|
+
f"for element {root}: {str(e)}"
|
|
281
|
+
)
|
|
295
282
|
|
|
296
283
|
|
|
297
284
|
class ControlFileMaterial:
|
|
@@ -1673,7 +1660,7 @@ class ControlFile:
|
|
|
1673
1660
|
bool
|
|
1674
1661
|
``True`` if successful, ``False`` otherwise.
|
|
1675
1662
|
"""
|
|
1676
|
-
tree =
|
|
1663
|
+
tree = defused_parse(xml_input)
|
|
1677
1664
|
root = tree.getroot()
|
|
1678
1665
|
for el in root:
|
|
1679
1666
|
if el.tag == "Stackup":
|
|
@@ -34,9 +34,9 @@ from ansys.edb.core.definition.djordjecvic_sarkar_model import (
|
|
|
34
34
|
DjordjecvicSarkarModel as GrpcDjordjecvicSarkarModel,
|
|
35
35
|
)
|
|
36
36
|
from ansys.edb.core.definition.material_def import (
|
|
37
|
+
MaterialDef as GrpcMaterialDef,
|
|
37
38
|
MaterialProperty as GrpcMaterialProperty,
|
|
38
39
|
)
|
|
39
|
-
from ansys.edb.core.definition.material_def import MaterialDef as GrpcMaterialDef
|
|
40
40
|
from ansys.edb.core.definition.multipole_debye_model import (
|
|
41
41
|
MultipoleDebyeModel as GrpcMultipoleDebyeModel,
|
|
42
42
|
)
|
|
@@ -193,8 +193,11 @@ class PackageDef(GrpcPackageDef):
|
|
|
193
193
|
"""
|
|
194
194
|
try:
|
|
195
195
|
return HeatSink(self._pedb, super().heat_sink)
|
|
196
|
-
except:
|
|
197
|
-
|
|
196
|
+
except Exception as e:
|
|
197
|
+
settings.logger.error(
|
|
198
|
+
f"A(n) {type(e).__name__} error occurred while attempting to access 'heatsink' "
|
|
199
|
+
f"property for object {self}: {str(e)}"
|
|
200
|
+
)
|
|
198
201
|
|
|
199
202
|
@property
|
|
200
203
|
@deprecated_property
|
|
@@ -222,9 +225,9 @@ class PackageDef(GrpcPackageDef):
|
|
|
222
225
|
Fin thickness.
|
|
223
226
|
"""
|
|
224
227
|
from ansys.edb.core.utility.heat_sink import (
|
|
228
|
+
HeatSink as GrpcHeatSink,
|
|
225
229
|
HeatSinkFinOrientation as GrpcHeatSinkFinOrientation,
|
|
226
230
|
)
|
|
227
|
-
from ansys.edb.core.utility.heat_sink import HeatSink as GrpcHeatSink
|
|
228
231
|
|
|
229
232
|
if fin_orientation == "x_oriented":
|
|
230
233
|
fin_orientation = GrpcHeatSinkFinOrientation.X_ORIENTED
|
|
@@ -26,18 +26,16 @@ import warnings
|
|
|
26
26
|
from ansys.edb.core.definition.padstack_def import PadstackDef as GrpcPadstackDef
|
|
27
27
|
from ansys.edb.core.definition.padstack_def_data import (
|
|
28
28
|
PadGeometryType as GrpcPadGeometryType,
|
|
29
|
-
)
|
|
30
|
-
from ansys.edb.core.definition.padstack_def_data import (
|
|
31
29
|
PadstackHoleRange as GrpcPadstackHoleRange,
|
|
30
|
+
PadType as GrpcPadType,
|
|
32
31
|
)
|
|
33
|
-
from ansys.edb.core.definition.padstack_def_data import PadType as GrpcPadType
|
|
34
32
|
import ansys.edb.core.geometry.polygon_data
|
|
35
33
|
from ansys.edb.core.geometry.polygon_data import PolygonData as GrpcPolygonData
|
|
36
|
-
from ansys.edb.core.hierarchy.structure3d import MeshClosure as GrpcMeshClosure
|
|
37
|
-
from ansys.edb.core.hierarchy.structure3d import Structure3D as GrpcStructure3D
|
|
34
|
+
from ansys.edb.core.hierarchy.structure3d import MeshClosure as GrpcMeshClosure, Structure3D as GrpcStructure3D
|
|
38
35
|
from ansys.edb.core.primitive.circle import Circle as GrpcCircle
|
|
39
36
|
|
|
40
37
|
from pyedb.generic.general_methods import generate_unique_name
|
|
38
|
+
from pyedb.grpc.database.primitive.circle import Circle
|
|
41
39
|
from pyedb.grpc.database.utility.value import Value
|
|
42
40
|
|
|
43
41
|
|
|
@@ -127,7 +125,7 @@ class PadProperties:
|
|
|
127
125
|
self._update_pad_parameters_parameters(geom_type=GrpcPadGeometryType.PADGEOMTYPE_POLYGON)
|
|
128
126
|
else:
|
|
129
127
|
raise ValueError(
|
|
130
|
-
f"Unsupported pad shape: {value}. Supported shapes are 'circle',
|
|
128
|
+
f"Unsupported pad shape: {value}. Supported shapes are 'circle', 'rectangle', and 'polygon'."
|
|
131
129
|
)
|
|
132
130
|
|
|
133
131
|
@property
|
|
@@ -297,7 +295,11 @@ class PadstackDef(GrpcPadstackDef):
|
|
|
297
295
|
List[:class:`PadstackInstance <pyedb.grpc.database.primitive.padstack_instance.PadstackInstance>`]
|
|
298
296
|
List of PadstackInstance objects.
|
|
299
297
|
"""
|
|
300
|
-
return [
|
|
298
|
+
return [
|
|
299
|
+
i
|
|
300
|
+
for i in list(self._pedb.padstacks.instances.values())
|
|
301
|
+
if not i.is_null and i.padstack_def.name == self.name
|
|
302
|
+
]
|
|
301
303
|
|
|
302
304
|
@property
|
|
303
305
|
def layers(self) -> list[str]:
|
|
@@ -720,7 +722,7 @@ class PadstackDef(GrpcPadstackDef):
|
|
|
720
722
|
net_name=via.net_name,
|
|
721
723
|
)
|
|
722
724
|
else:
|
|
723
|
-
|
|
725
|
+
Circle(self._pedb).create(
|
|
724
726
|
layout,
|
|
725
727
|
self.start_layer,
|
|
726
728
|
via.net,
|
|
@@ -735,7 +737,7 @@ class PadstackDef(GrpcPadstackDef):
|
|
|
735
737
|
net_name=via.net_name,
|
|
736
738
|
)
|
|
737
739
|
else:
|
|
738
|
-
|
|
740
|
+
Circle(self._pedb).create(
|
|
739
741
|
layout,
|
|
740
742
|
self.stop_layer,
|
|
741
743
|
via.net,
|
|
@@ -748,7 +750,7 @@ class PadstackDef(GrpcPadstackDef):
|
|
|
748
750
|
if layer_name == via.start_layer or started:
|
|
749
751
|
start = layer_name
|
|
750
752
|
stop = layer_names[layer_names.index(layer_name) + 1]
|
|
751
|
-
cloned_circle =
|
|
753
|
+
cloned_circle = Circle(self._pedb).create(
|
|
752
754
|
layout,
|
|
753
755
|
start,
|
|
754
756
|
via.net,
|
|
@@ -756,7 +758,7 @@ class PadstackDef(GrpcPadstackDef):
|
|
|
756
758
|
Value(pos[1]),
|
|
757
759
|
Value(rad1),
|
|
758
760
|
)
|
|
759
|
-
cloned_circle2 =
|
|
761
|
+
cloned_circle2 = Circle(self._pedb).create(
|
|
760
762
|
layout,
|
|
761
763
|
stop,
|
|
762
764
|
via.net,
|
|
@@ -771,7 +773,7 @@ class PadstackDef(GrpcPadstackDef):
|
|
|
771
773
|
s3d.add_member(cloned_circle2)
|
|
772
774
|
if not self.data.material.value:
|
|
773
775
|
self._pedb.logger.warning(
|
|
774
|
-
f"Padstack definution {self.name} has no material defined.
|
|
776
|
+
f"Padstack definution {self.name} has no material defined.Defaulting to copper"
|
|
775
777
|
)
|
|
776
778
|
self.data.material = "copper"
|
|
777
779
|
s3d.set_material(self.data.material.value)
|
pyedb/grpc/database/hfss.py
CHANGED
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
"""
|
|
24
24
|
This module contains the ``EdbHfss`` class.
|
|
25
25
|
"""
|
|
26
|
+
|
|
26
27
|
import math
|
|
27
28
|
import warnings
|
|
28
29
|
|
|
@@ -1259,11 +1260,7 @@ class Hfss(object):
|
|
|
1259
1260
|
)
|
|
1260
1261
|
from ansys.edb.core.simulation_setup.simulation_setup import (
|
|
1261
1262
|
Distribution as GrpcDistribution,
|
|
1262
|
-
)
|
|
1263
|
-
from ansys.edb.core.simulation_setup.simulation_setup import (
|
|
1264
1263
|
FrequencyData as GrpcFrequencyData,
|
|
1265
|
-
)
|
|
1266
|
-
from ansys.edb.core.simulation_setup.simulation_setup import (
|
|
1267
1264
|
SweepData as GrpcSweepData,
|
|
1268
1265
|
)
|
|
1269
1266
|
|
|
@@ -28,14 +28,13 @@ import warnings
|
|
|
28
28
|
from ansys.edb.core.definition.component_model import (
|
|
29
29
|
NPortComponentModel as GrpcNPortComponentModel,
|
|
30
30
|
)
|
|
31
|
-
from ansys.edb.core.definition.die_property import DieOrientation as GrpcDieOrientation
|
|
32
|
-
from ansys.edb.core.definition.die_property import DieType as GrpcDieType
|
|
31
|
+
from ansys.edb.core.definition.die_property import DieOrientation as GrpcDieOrientation, DieType as GrpcDieType
|
|
33
32
|
from ansys.edb.core.definition.solder_ball_property import SolderballShape
|
|
34
33
|
from ansys.edb.core.geometry.polygon_data import PolygonData as GrpcPolygonData
|
|
35
34
|
from ansys.edb.core.hierarchy.component_group import (
|
|
36
35
|
ComponentGroup as GrpcComponentGroup,
|
|
36
|
+
ComponentType as GrpcComponentType,
|
|
37
37
|
)
|
|
38
|
-
from ansys.edb.core.hierarchy.component_group import ComponentType as GrpcComponentType
|
|
39
38
|
from ansys.edb.core.hierarchy.netlist_model import NetlistModel as GrpcNetlistModel
|
|
40
39
|
from ansys.edb.core.hierarchy.pin_pair_model import PinPairModel as GrpcPinPairModel
|
|
41
40
|
from ansys.edb.core.hierarchy.sparameter_model import (
|
|
@@ -49,7 +48,9 @@ from ansys.edb.core.terminal.padstack_instance_terminal import (
|
|
|
49
48
|
PadstackInstanceTerminal as GrpcPadstackInstanceTerminal,
|
|
50
49
|
)
|
|
51
50
|
from ansys.edb.core.utility.rlc import Rlc as GrpcRlc
|
|
51
|
+
import numpy as np
|
|
52
52
|
|
|
53
|
+
from pyedb.generic.general_methods import get_filename_without_extension
|
|
53
54
|
from pyedb.grpc.database.hierarchy.pin_pair_model import PinPairModel
|
|
54
55
|
from pyedb.grpc.database.hierarchy.s_parameter_model import SparamModel
|
|
55
56
|
from pyedb.grpc.database.hierarchy.spice_model import SpiceModel
|
|
@@ -60,15 +61,6 @@ from pyedb.grpc.database.terminal.padstack_instance_terminal import (
|
|
|
60
61
|
)
|
|
61
62
|
from pyedb.grpc.database.utility.value import Value
|
|
62
63
|
|
|
63
|
-
try:
|
|
64
|
-
import numpy as np
|
|
65
|
-
except ImportError:
|
|
66
|
-
warnings.warn(
|
|
67
|
-
"The NumPy module is required to run some functionalities of EDB.\n"
|
|
68
|
-
"Install with \n\npip install numpy\n\nRequires CPython."
|
|
69
|
-
)
|
|
70
|
-
from pyedb.generic.general_methods import get_filename_without_extension
|
|
71
|
-
|
|
72
64
|
|
|
73
65
|
class Component(GrpcComponentGroup):
|
|
74
66
|
"""Manages EDB functionalities for components.
|
|
@@ -1102,7 +1094,7 @@ class Component(GrpcComponentGroup):
|
|
|
1102
1094
|
return False
|
|
1103
1095
|
if not reference_net:
|
|
1104
1096
|
self._pedb.logger.warning(
|
|
1105
|
-
f"No reference net provided for S parameter file {file_path}, net `GND` is
|
|
1097
|
+
f"No reference net provided for S parameter file {file_path}, net `GND` is assigned by default"
|
|
1106
1098
|
)
|
|
1107
1099
|
reference_net = "GND"
|
|
1108
1100
|
n_port_model = GrpcNPortComponentModel.find_by_name(self.component_def, name)
|
|
@@ -20,16 +20,20 @@
|
|
|
20
20
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
21
|
# SOFTWARE.
|
|
22
22
|
|
|
23
|
+
from __future__ import annotations
|
|
23
24
|
|
|
25
|
+
from typing import TYPE_CHECKING
|
|
26
|
+
|
|
27
|
+
if TYPE_CHECKING:
|
|
28
|
+
from pyedb.grpc.database.hierarchy.component import Component
|
|
29
|
+
from pyedb.grpc.database.net.net import Net
|
|
30
|
+
from pyedb.grpc.database.primitive.padstack_instance import PadstackInstance
|
|
24
31
|
from typing import Union
|
|
25
32
|
|
|
26
33
|
from ansys.edb.core.hierarchy.pin_group import PinGroup as GrpcPinGroup
|
|
27
34
|
from ansys.edb.core.terminal.terminal import BoundaryType as GrpcBoundaryType
|
|
28
35
|
|
|
29
36
|
from pyedb.generic.general_methods import generate_unique_name
|
|
30
|
-
from pyedb.grpc.database.hierarchy.component import Component
|
|
31
|
-
from pyedb.grpc.database.net.net import Net
|
|
32
|
-
from pyedb.grpc.database.primitive.padstack_instance import PadstackInstance
|
|
33
37
|
from pyedb.grpc.database.terminal.pingroup_terminal import PinGroupTerminal
|
|
34
38
|
from pyedb.grpc.database.utility.value import Value
|
|
35
39
|
|
|
@@ -63,10 +67,13 @@ class PinGroup(GrpcPinGroup):
|
|
|
63
67
|
:class:`Component <pyedb.grpc.database.hierarchy.component.Component>`
|
|
64
68
|
Pin group component.
|
|
65
69
|
"""
|
|
70
|
+
|
|
66
71
|
return Component(self._pedb, super().component)
|
|
67
72
|
|
|
68
73
|
@component.setter
|
|
69
74
|
def component(self, value):
|
|
75
|
+
from pyedb.grpc.database.hierarchy.component import Component
|
|
76
|
+
|
|
70
77
|
if isinstance(value, Component):
|
|
71
78
|
super(PinGroup, self.__class__).component.__set__(self, value)
|
|
72
79
|
|
|
@@ -78,6 +85,8 @@ class PinGroup(GrpcPinGroup):
|
|
|
78
85
|
-------
|
|
79
86
|
Dict[:class:`PadstackInstance <pyedb.grpc.database.primitive.padstack_instance.PadstackInstance>`].
|
|
80
87
|
"""
|
|
88
|
+
from pyedb.grpc.database.primitive.padstack_instance import PadstackInstance
|
|
89
|
+
|
|
81
90
|
return {i.name: PadstackInstance(self._pedb, i) for i in super().pins}
|
|
82
91
|
|
|
83
92
|
@property
|
|
@@ -88,10 +97,14 @@ class PinGroup(GrpcPinGroup):
|
|
|
88
97
|
-------
|
|
89
98
|
:class:`Net <ansys.edb.core.net.net.Net>`.
|
|
90
99
|
"""
|
|
100
|
+
from pyedb.grpc.database.net.net import Net
|
|
101
|
+
|
|
91
102
|
return Net(self._pedb, super().net)
|
|
92
103
|
|
|
93
104
|
@net.setter
|
|
94
105
|
def net(self, value):
|
|
106
|
+
from pyedb.grpc.database.net.net import Net
|
|
107
|
+
|
|
95
108
|
if isinstance(value, Net):
|
|
96
109
|
super(PinGroup, self.__class__).net.__set__(self, value)
|
|
97
110
|
|
|
@@ -6,8 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
from __future__ import absolute_import
|
|
8
8
|
|
|
9
|
-
from ansys.edb.core.layer.layer import Layer as GrpcLayer
|
|
10
|
-
from ansys.edb.core.layer.layer import LayerType as GrpcLayerType
|
|
9
|
+
from ansys.edb.core.layer.layer import Layer as GrpcLayer, LayerType as GrpcLayerType
|
|
11
10
|
|
|
12
11
|
|
|
13
12
|
class Layer(GrpcLayer):
|