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
|
@@ -22,11 +22,14 @@
|
|
|
22
22
|
|
|
23
23
|
import math
|
|
24
24
|
import re
|
|
25
|
+
import warnings
|
|
25
26
|
|
|
26
27
|
from ansys.edb.core.database import ProductIdType as GrpcProductIdType
|
|
27
28
|
from ansys.edb.core.geometry.point_data import PointData as GrpcPointData
|
|
28
29
|
from ansys.edb.core.geometry.polygon_data import PolygonData as GrpcPolygonData
|
|
29
30
|
from ansys.edb.core.hierarchy.pin_group import PinGroup as GrpcPinGroup
|
|
31
|
+
from ansys.edb.core.hierarchy.structure3d import MeshClosure as GrpcMeshClosure
|
|
32
|
+
from ansys.edb.core.hierarchy.structure3d import Structure3D as GrpcStructure3D
|
|
30
33
|
from ansys.edb.core.primitive.padstack_instance import (
|
|
31
34
|
PadstackInstance as GrpcPadstackInstance,
|
|
32
35
|
)
|
|
@@ -34,7 +37,9 @@ from ansys.edb.core.terminal.pin_group_terminal import (
|
|
|
34
37
|
PinGroupTerminal as GrpcPinGroupTerminal,
|
|
35
38
|
)
|
|
36
39
|
|
|
40
|
+
from pyedb.generic.general_methods import generate_unique_name
|
|
37
41
|
from pyedb.grpc.database.definition.padstack_def import PadstackDef
|
|
42
|
+
from pyedb.grpc.database.modeler import Circle
|
|
38
43
|
from pyedb.grpc.database.terminal.padstack_instance_terminal import (
|
|
39
44
|
PadstackInstanceTerminal,
|
|
40
45
|
)
|
|
@@ -67,6 +72,16 @@ class PadstackInstance(GrpcPadstackInstance):
|
|
|
67
72
|
self._pedb = pedb
|
|
68
73
|
self._object_instance = None
|
|
69
74
|
|
|
75
|
+
@property
|
|
76
|
+
def is_pin(self):
|
|
77
|
+
"""Property added for backward compatibility with earlier versions of pyEDB."""
|
|
78
|
+
return self.is_layout_pin
|
|
79
|
+
|
|
80
|
+
@is_pin.setter
|
|
81
|
+
def is_pin(self, value):
|
|
82
|
+
"""Property added for backward compatibility with earlier versions of pyEDB."""
|
|
83
|
+
self.is_layout_pin = value
|
|
84
|
+
|
|
70
85
|
@property
|
|
71
86
|
def definition(self) -> PadstackDef:
|
|
72
87
|
"""Padstack definition.
|
|
@@ -108,6 +123,77 @@ class PadstackInstance(GrpcPadstackInstance):
|
|
|
108
123
|
term = PadstackInstanceTerminal(self._pedb, term)
|
|
109
124
|
return term if not term.is_null else None
|
|
110
125
|
|
|
126
|
+
def set_backdrill_top(self, drill_depth, drill_diameter, offset=0.0):
|
|
127
|
+
"""Set backdrill from top.
|
|
128
|
+
|
|
129
|
+
.deprecated:: 0.55.0
|
|
130
|
+
Use :method:`set_back_drill_by_depth` instead.
|
|
131
|
+
|
|
132
|
+
Parameters
|
|
133
|
+
----------
|
|
134
|
+
drill_depth : str
|
|
135
|
+
Name of the drill to layer.
|
|
136
|
+
drill_diameter : float, str
|
|
137
|
+
Diameter of backdrill size.
|
|
138
|
+
offset : str, optional.
|
|
139
|
+
offset with respect to the layer to drill to.
|
|
140
|
+
|
|
141
|
+
Returns
|
|
142
|
+
-------
|
|
143
|
+
bool
|
|
144
|
+
True if success, False otherwise.
|
|
145
|
+
"""
|
|
146
|
+
warnings.warn(
|
|
147
|
+
"`set_backdrill_top` is deprecated. Use `set_back_drill_by_depth` or " "`set_back_drill_by_layer` instead.",
|
|
148
|
+
DeprecationWarning,
|
|
149
|
+
)
|
|
150
|
+
if isinstance(drill_depth, str):
|
|
151
|
+
if drill_depth in self._pedb.stackup.layers:
|
|
152
|
+
return self.set_back_drill_by_layer(
|
|
153
|
+
drill_to_layer=self._pedb.stackup.layers[drill_depth],
|
|
154
|
+
offset=Value(offset),
|
|
155
|
+
diameter=Value(drill_diameter),
|
|
156
|
+
from_bottom=False,
|
|
157
|
+
)
|
|
158
|
+
else:
|
|
159
|
+
return self.set_back_drill_by_depth(Value(drill_depth), Value(drill_diameter), from_bottom=False)
|
|
160
|
+
|
|
161
|
+
def set_backdrill_bottom(self, drill_depth, drill_diameter, offset=0.0):
|
|
162
|
+
"""Set backdrill from bottom.
|
|
163
|
+
|
|
164
|
+
.deprecated: 0.55.0
|
|
165
|
+
Use: method:`set_back_drill_by_depth` instead.
|
|
166
|
+
|
|
167
|
+
Parameters
|
|
168
|
+
----------
|
|
169
|
+
drill_depth : str
|
|
170
|
+
Name of the drill to layer.
|
|
171
|
+
drill_diameter : float, str
|
|
172
|
+
Diameter of backdrill size.
|
|
173
|
+
offset : str, optional.
|
|
174
|
+
offset with respect to the layer to drill to.
|
|
175
|
+
|
|
176
|
+
Returns
|
|
177
|
+
-------
|
|
178
|
+
bool
|
|
179
|
+
True if success, False otherwise.
|
|
180
|
+
"""
|
|
181
|
+
warnings.warn(
|
|
182
|
+
"`set_backdrill_bottom` is deprecated. Use `set_back_drill_by_depth` or "
|
|
183
|
+
"`set_back_drill_by_layer` instead.",
|
|
184
|
+
DeprecationWarning,
|
|
185
|
+
)
|
|
186
|
+
if isinstance(drill_depth, str):
|
|
187
|
+
if drill_depth in self._pedb.stackup.layers:
|
|
188
|
+
return self.set_back_drill_by_layer(
|
|
189
|
+
drill_to_layer=self._pedb.stackup.layers[drill_depth],
|
|
190
|
+
offset=Value(offset),
|
|
191
|
+
diameter=Value(drill_diameter),
|
|
192
|
+
from_bottom=True,
|
|
193
|
+
)
|
|
194
|
+
else:
|
|
195
|
+
return self.set_back_drill_by_depth(Value(drill_depth), Value(drill_diameter), from_bottom=True)
|
|
196
|
+
|
|
111
197
|
def create_terminal(self, name=None) -> PadstackInstanceTerminal:
|
|
112
198
|
"""Create a padstack instance terminal.
|
|
113
199
|
|
|
@@ -500,13 +586,16 @@ class PadstackInstance(GrpcPadstackInstance):
|
|
|
500
586
|
list
|
|
501
587
|
List of ``[x, y]`` coordinates for the padstack instance position.
|
|
502
588
|
"""
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
589
|
+
try:
|
|
590
|
+
position = self.get_position_and_rotation()
|
|
591
|
+
if self.component:
|
|
592
|
+
out2 = self.component.transform.transform_point(GrpcPointData(position[:2]))
|
|
593
|
+
self._position = [Value(out2[0]), Value(out2[1])]
|
|
594
|
+
else:
|
|
595
|
+
self._position = [Value(pt) for pt in position[:2]]
|
|
596
|
+
return self._position
|
|
597
|
+
except Exception:
|
|
598
|
+
return False
|
|
510
599
|
|
|
511
600
|
@position.setter
|
|
512
601
|
def position(self, value):
|
|
@@ -684,6 +773,85 @@ class PadstackInstance(GrpcPadstackInstance):
|
|
|
684
773
|
def side_number(self, value):
|
|
685
774
|
self._side_number = self.set_product_property(GrpcProductIdType.HFSS_3D_LAYOUT, 21, value)
|
|
686
775
|
|
|
776
|
+
def split(self) -> list:
|
|
777
|
+
"""Split padstack instance into multiple instances. The new instances only connect adjacent layers."""
|
|
778
|
+
pdef_name = self.padstack_definition
|
|
779
|
+
position = self.position
|
|
780
|
+
net_name = self.net_name
|
|
781
|
+
name = self.name
|
|
782
|
+
stackup_layer_range = list(self._pedb.stackup.signal_layers.keys())
|
|
783
|
+
start_idx = stackup_layer_range.index(self.start_layer)
|
|
784
|
+
stop_idx = stackup_layer_range.index(self.stop_layer)
|
|
785
|
+
temp = []
|
|
786
|
+
for idx, (l1, l2) in enumerate(
|
|
787
|
+
list(zip(stackup_layer_range[start_idx:stop_idx], stackup_layer_range[start_idx + 1 : stop_idx + 1]))
|
|
788
|
+
):
|
|
789
|
+
pd_inst = self._pedb.padstacks.place(
|
|
790
|
+
position, pdef_name, net_name, f"{name}_{idx}", fromlayer=l1, tolayer=l2
|
|
791
|
+
)
|
|
792
|
+
temp.append(pd_inst)
|
|
793
|
+
self.delete()
|
|
794
|
+
return temp
|
|
795
|
+
|
|
796
|
+
def convert_hole_to_conical_shape(self, angle=75):
|
|
797
|
+
"""Convert actual padstack instance to microvias 3D Objects with a given aspect ratio.
|
|
798
|
+
|
|
799
|
+
Parameters
|
|
800
|
+
----------
|
|
801
|
+
angle : float, optional
|
|
802
|
+
Angle of laser penetration in degrees. The angle defines the lowest hole diameter with this formula:
|
|
803
|
+
HoleDiameter -2*tan(laser_angle* Hole depth). Hole depth is the height of the via (dielectric thickness).
|
|
804
|
+
The default is ``75``.
|
|
805
|
+
The lowest hole is ``0.75*HoleDepth/HoleDiam``.
|
|
806
|
+
|
|
807
|
+
Returns
|
|
808
|
+
-------
|
|
809
|
+
"""
|
|
810
|
+
stackup_layers = self._pedb.stackup.stackup_layers
|
|
811
|
+
signal_layers = self._pedb.stackup.signal_layers
|
|
812
|
+
layer_idx = list(signal_layers.keys()).index(self.start_layer)
|
|
813
|
+
|
|
814
|
+
_layer_idx = list(stackup_layers.keys()).index(self.start_layer)
|
|
815
|
+
diel_layer_idx = list(stackup_layers.keys())[_layer_idx + 1]
|
|
816
|
+
diel_thickness = stackup_layers[diel_layer_idx].thickness
|
|
817
|
+
|
|
818
|
+
rad_large = self.definition.hole_diameter / 2
|
|
819
|
+
rad_small = rad_large - diel_thickness * 1 / math.tan(math.radians(angle))
|
|
820
|
+
|
|
821
|
+
if layer_idx + 1 < len(signal_layers) / 2: # upper half of stack
|
|
822
|
+
rad_u = rad_large
|
|
823
|
+
rad_l = rad_small
|
|
824
|
+
else:
|
|
825
|
+
rad_u = rad_small
|
|
826
|
+
rad_l = rad_large
|
|
827
|
+
|
|
828
|
+
layout = self._pedb.active_layout
|
|
829
|
+
cloned_circle = Circle.create(
|
|
830
|
+
layout,
|
|
831
|
+
self.start_layer,
|
|
832
|
+
self.net,
|
|
833
|
+
Value(self.position[0]),
|
|
834
|
+
Value(self.position[1]),
|
|
835
|
+
Value(rad_u),
|
|
836
|
+
)
|
|
837
|
+
cloned_circle2 = Circle.create(
|
|
838
|
+
layout,
|
|
839
|
+
self.stop_layer,
|
|
840
|
+
self.net,
|
|
841
|
+
Value(self.position[0]),
|
|
842
|
+
Value(self.position[1]),
|
|
843
|
+
Value(rad_l),
|
|
844
|
+
)
|
|
845
|
+
|
|
846
|
+
s3d = GrpcStructure3D.create(layout, generate_unique_name("via3d_" + self.aedt_name.replace("via_", ""), n=3))
|
|
847
|
+
s3d.add_member(cloned_circle)
|
|
848
|
+
s3d.add_member(cloned_circle2)
|
|
849
|
+
s3d.set_material(self.definition.material)
|
|
850
|
+
s3d.mesh_closure = GrpcMeshClosure.ENDS_CLOSED
|
|
851
|
+
hole_override_enabled = True
|
|
852
|
+
hole_override_diam = 0
|
|
853
|
+
self.set_hole_overrides(hole_override_enabled, Value(hole_override_diam))
|
|
854
|
+
|
|
687
855
|
def get_backdrill_type(self, from_bottom=True):
|
|
688
856
|
"""Return backdrill type
|
|
689
857
|
Parameters
|
pyedb/grpc/database/siwave.py
CHANGED
|
@@ -589,7 +589,7 @@ class Siwave(object):
|
|
|
589
589
|
f.write('ExportTouchstone "{}"\n'.format(touchstone_file_path))
|
|
590
590
|
f.write("SaveSiw\n")
|
|
591
591
|
|
|
592
|
-
return
|
|
592
|
+
return file_name
|
|
593
593
|
|
|
594
594
|
def add_cpa_analysis(self, name=None, siwave_cpa_setup_class=None):
|
|
595
595
|
if not name:
|
|
@@ -431,12 +431,10 @@ class SourceExcitation:
|
|
|
431
431
|
refdes = Component(self._pedb, refdes)
|
|
432
432
|
pins = self._get_pins_for_ports(pins, refdes)
|
|
433
433
|
if not pins:
|
|
434
|
-
|
|
435
|
-
return False
|
|
434
|
+
raise RuntimeWarning("No pins found during port creation. Port is not defined.")
|
|
436
435
|
reference_pins = self._get_pins_for_ports(reference_pins, refdes)
|
|
437
436
|
if not reference_pins:
|
|
438
|
-
|
|
439
|
-
return False
|
|
437
|
+
raise RuntimeWarning("No reference pins found during port creation. Port is not defined.")
|
|
440
438
|
if refdes and any(refdes.rlc_values):
|
|
441
439
|
return self._pedb.components.deactivate_rlc_component(component=refdes, create_circuit_port=True)
|
|
442
440
|
if not port_name:
|
pyedb/grpc/database/stackup.py
CHANGED
|
@@ -1355,7 +1355,7 @@ class Stackup(LayerCollection):
|
|
|
1355
1355
|
_offset_y = Value(offset_y)
|
|
1356
1356
|
|
|
1357
1357
|
if edb_cell.name not in self._pedb.cell_names:
|
|
1358
|
-
list_cells = self._pedb.copy_cells([edb_cell
|
|
1358
|
+
list_cells = self._pedb.copy_cells([edb_cell])
|
|
1359
1359
|
edb_cell = list_cells[0]
|
|
1360
1360
|
self._pedb.layout.cell.is_blackbox = True
|
|
1361
1361
|
cell_inst2 = GrpcCellInstance.create(
|
|
@@ -152,7 +152,7 @@ class BundleTerminal(GrpcBundleTerminal):
|
|
|
152
152
|
-------
|
|
153
153
|
:class:`Terminal <pyedb.grpc.database.terminal.terminal.Terminal>`
|
|
154
154
|
"""
|
|
155
|
-
return Terminal(self._pedb,
|
|
155
|
+
return Terminal(self._pedb, super().reference_terminal)
|
|
156
156
|
|
|
157
157
|
@reference_terminal.setter
|
|
158
158
|
def reference_terminal(self, value):
|
|
@@ -26,7 +26,7 @@ from ansys.edb.core.terminal.padstack_instance_terminal import (
|
|
|
26
26
|
from ansys.edb.core.terminal.terminal import BoundaryType as GrpcBoundaryType
|
|
27
27
|
|
|
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 PadstackInstanceTerminal(GrpcPadstackInstanceTerminal):
|
|
@@ -27,7 +27,7 @@ from ansys.edb.core.terminal.terminal import BoundaryType as GrpcBoundaryType
|
|
|
27
27
|
|
|
28
28
|
from pyedb.grpc.database.net.net import Net
|
|
29
29
|
from pyedb.grpc.database.utility.value import Value
|
|
30
|
-
from pyedb.misc.
|
|
30
|
+
from pyedb.misc.decorators import deprecated_property
|
|
31
31
|
|
|
32
32
|
|
|
33
33
|
class PinGroupTerminal(GrpcPinGroupTerminal):
|
|
@@ -26,8 +26,8 @@ import re
|
|
|
26
26
|
import subprocess
|
|
27
27
|
import sys
|
|
28
28
|
|
|
29
|
-
from pyedb.edb_logger import pyedb_logger
|
|
30
29
|
from pyedb.generic.general_methods import ET, env_path, env_value, is_linux
|
|
30
|
+
from pyedb.generic.settings import settings
|
|
31
31
|
from pyedb.misc.aedtlib_personalib_install import write_pretty_xml
|
|
32
32
|
from pyedb.misc.misc import list_installed_ansysem
|
|
33
33
|
|
|
@@ -56,7 +56,7 @@ def convert_technology_file(tech_file, edbversion=None, control_file=None):
|
|
|
56
56
|
base_path = env_path(edbversion)
|
|
57
57
|
sys.path.append(base_path)
|
|
58
58
|
else:
|
|
59
|
-
|
|
59
|
+
settings.logger.error("No Edb installation found. Check environment variables")
|
|
60
60
|
return False
|
|
61
61
|
os.environ["HELIC_ROOT"] = os.path.join(base_path, "helic")
|
|
62
62
|
if os.getenv("ANSYSLMD_LICENCE_FILE", None) is None:
|
|
@@ -69,7 +69,7 @@ def convert_technology_file(tech_file, edbversion=None, control_file=None):
|
|
|
69
69
|
os.environ["ANSYSLMD_LICENSE_FILE"] = line.split("=")[1]
|
|
70
70
|
break
|
|
71
71
|
else:
|
|
72
|
-
|
|
72
|
+
settings.logger.error("ANSYSLMD_LICENSE_FILE is not defined.")
|
|
73
73
|
vlc_file_name = os.path.splitext(tech_file)[0]
|
|
74
74
|
if not control_file:
|
|
75
75
|
control_file = vlc_file_name + ".xml"
|
|
@@ -103,9 +103,9 @@ def convert_technology_file(tech_file, edbversion=None, control_file=None):
|
|
|
103
103
|
p = subprocess.Popen(command, env=my_env)
|
|
104
104
|
p.wait()
|
|
105
105
|
if os.path.exists(control_file):
|
|
106
|
-
|
|
106
|
+
settings.logger.info("Xml file created.")
|
|
107
107
|
return control_file
|
|
108
|
-
|
|
108
|
+
settings.logger.error("Technology files are supported only in Linux. Use control file instead.")
|
|
109
109
|
return False
|
|
110
110
|
|
|
111
111
|
|
pyedb/grpc/edb.py
CHANGED
|
@@ -65,7 +65,7 @@ import sys
|
|
|
65
65
|
import tempfile
|
|
66
66
|
import time
|
|
67
67
|
import traceback
|
|
68
|
-
from typing import Union
|
|
68
|
+
from typing import Dict, List, Union
|
|
69
69
|
import warnings
|
|
70
70
|
from zipfile import ZipFile as zpf
|
|
71
71
|
|
|
@@ -99,8 +99,7 @@ from pyedb.grpc.database.layout_validation import LayoutValidation
|
|
|
99
99
|
from pyedb.grpc.database.modeler import Modeler
|
|
100
100
|
from pyedb.grpc.database.net.differential_pair import DifferentialPairs
|
|
101
101
|
from pyedb.grpc.database.net.extended_net import ExtendedNets
|
|
102
|
-
from pyedb.grpc.database.
|
|
103
|
-
from pyedb.grpc.database.nets import Nets
|
|
102
|
+
from pyedb.grpc.database.nets import NetClasses, Nets
|
|
104
103
|
from pyedb.grpc.database.padstacks import Padstacks
|
|
105
104
|
from pyedb.grpc.database.ports.ports import BundleWavePort, CoaxPort, GapPort, WavePort
|
|
106
105
|
from pyedb.grpc.database.primitive.circle import Circle
|
|
@@ -137,6 +136,8 @@ from pyedb.ipc2581.ipc2581 import Ipc2581
|
|
|
137
136
|
from pyedb.modeler.geometry_operators import GeometryOperators
|
|
138
137
|
from pyedb.workflow import Workflow
|
|
139
138
|
|
|
139
|
+
os.environ["no_proxy"] = "localhost,127.0.0.1"
|
|
140
|
+
|
|
140
141
|
|
|
141
142
|
class Edb(EdbInit):
|
|
142
143
|
"""Main class for interacting with Ansys Electronics Desktop Database (EDB).
|
|
@@ -209,7 +210,6 @@ class Edb(EdbInit):
|
|
|
209
210
|
technology_file: str = None,
|
|
210
211
|
layer_filter: str = None,
|
|
211
212
|
restart_rpc_server=False,
|
|
212
|
-
**kwargs,
|
|
213
213
|
):
|
|
214
214
|
edbversion = get_string_version(edbversion)
|
|
215
215
|
self._clean_variables()
|
|
@@ -402,7 +402,7 @@ class Edb(EdbInit):
|
|
|
402
402
|
self._differential_pairs = DifferentialPairs(self)
|
|
403
403
|
self._extended_nets = ExtendedNets(self)
|
|
404
404
|
|
|
405
|
-
def value(self, val):
|
|
405
|
+
def value(self, val) -> float:
|
|
406
406
|
"""Convert a value into a pyedb value."""
|
|
407
407
|
if isinstance(val, GrpcValue):
|
|
408
408
|
return Value(val)
|
|
@@ -411,7 +411,7 @@ class Edb(EdbInit):
|
|
|
411
411
|
return Value(GrpcValue(val, context), context)
|
|
412
412
|
|
|
413
413
|
@property
|
|
414
|
-
def cell_names(self) -> [str]:
|
|
414
|
+
def cell_names(self) -> List[str]:
|
|
415
415
|
"""List of all cell names in the database.
|
|
416
416
|
|
|
417
417
|
Returns
|
|
@@ -422,7 +422,7 @@ class Edb(EdbInit):
|
|
|
422
422
|
return [cell.name for cell in self.active_db.top_circuit_cells]
|
|
423
423
|
|
|
424
424
|
@property
|
|
425
|
-
def design_variables(self) ->
|
|
425
|
+
def design_variables(self) -> Dict[str, float]:
|
|
426
426
|
"""All design variables in active cell.
|
|
427
427
|
|
|
428
428
|
Returns
|
|
@@ -433,7 +433,7 @@ class Edb(EdbInit):
|
|
|
433
433
|
return {i: Value(self.active_cell.get_variable_value(i)) for i in self.active_cell.get_all_variable_names()}
|
|
434
434
|
|
|
435
435
|
@property
|
|
436
|
-
def project_variables(self) ->
|
|
436
|
+
def project_variables(self) -> Dict[str, float]:
|
|
437
437
|
"""All project variables in database.
|
|
438
438
|
|
|
439
439
|
Returns
|
|
@@ -455,7 +455,7 @@ class Edb(EdbInit):
|
|
|
455
455
|
return LayoutValidation(self)
|
|
456
456
|
|
|
457
457
|
@property
|
|
458
|
-
def variables(self) ->
|
|
458
|
+
def variables(self) -> Dict[str, float]:
|
|
459
459
|
"""All variables (project + design) in database.
|
|
460
460
|
|
|
461
461
|
Returns
|
|
@@ -471,7 +471,7 @@ class Edb(EdbInit):
|
|
|
471
471
|
return all_vars
|
|
472
472
|
|
|
473
473
|
@property
|
|
474
|
-
def terminals(self) ->
|
|
474
|
+
def terminals(self) -> Dict[str, Terminal]:
|
|
475
475
|
"""Terminals in active layout.
|
|
476
476
|
|
|
477
477
|
Returns
|
|
@@ -482,7 +482,7 @@ class Edb(EdbInit):
|
|
|
482
482
|
return {i.name: i for i in self.layout.terminals}
|
|
483
483
|
|
|
484
484
|
@property
|
|
485
|
-
def excitations(self) ->
|
|
485
|
+
def excitations(self) -> Dict[str, GapPort]:
|
|
486
486
|
"""All layout excitations.
|
|
487
487
|
|
|
488
488
|
Returns
|
|
@@ -500,7 +500,7 @@ class Edb(EdbInit):
|
|
|
500
500
|
return temp
|
|
501
501
|
|
|
502
502
|
@property
|
|
503
|
-
def ports(self) ->
|
|
503
|
+
def ports(self) -> Dict[str, GapPort]:
|
|
504
504
|
"""All ports in design.
|
|
505
505
|
|
|
506
506
|
Returns
|
|
@@ -533,7 +533,7 @@ class Edb(EdbInit):
|
|
|
533
533
|
return ports
|
|
534
534
|
|
|
535
535
|
@property
|
|
536
|
-
def excitations_nets(self) -> [str]:
|
|
536
|
+
def excitations_nets(self) -> List[str]:
|
|
537
537
|
"""Nets with excitations defined.
|
|
538
538
|
|
|
539
539
|
Returns
|
|
@@ -544,7 +544,7 @@ class Edb(EdbInit):
|
|
|
544
544
|
return list(set([i.net.name for i in self.layout.terminals if not i.is_reference_terminal]))
|
|
545
545
|
|
|
546
546
|
@property
|
|
547
|
-
def sources(self) ->
|
|
547
|
+
def sources(self) -> Dict[str, Terminal]:
|
|
548
548
|
"""All layout sources.
|
|
549
549
|
|
|
550
550
|
Returns
|
|
@@ -574,7 +574,7 @@ class Edb(EdbInit):
|
|
|
574
574
|
return _vrms
|
|
575
575
|
|
|
576
576
|
@property
|
|
577
|
-
def probes(self) ->
|
|
577
|
+
def probes(self) -> Dict[str, Terminal]:
|
|
578
578
|
"""All layout probes.
|
|
579
579
|
|
|
580
580
|
Returns
|
|
@@ -941,6 +941,7 @@ class Edb(EdbInit):
|
|
|
941
941
|
ValueError
|
|
942
942
|
If cell not found in database.
|
|
943
943
|
"""
|
|
944
|
+
self._layout = None
|
|
944
945
|
if isinstance(value, str):
|
|
945
946
|
_cell = [cell for cell in self.circuit_cells if cell.name == value]
|
|
946
947
|
if _cell:
|
|
@@ -1060,16 +1061,16 @@ class Edb(EdbInit):
|
|
|
1060
1061
|
return self._nets
|
|
1061
1062
|
|
|
1062
1063
|
@property
|
|
1063
|
-
def net_classes(self) ->
|
|
1064
|
+
def net_classes(self) -> NetClasses:
|
|
1064
1065
|
"""Net class management.
|
|
1065
1066
|
|
|
1066
1067
|
Returns
|
|
1067
1068
|
-------
|
|
1068
|
-
|
|
1069
|
-
Net
|
|
1069
|
+
:class:`NetClass <pyedb.grpc.database.nets.NetClasses>`
|
|
1070
|
+
Net classes objects.
|
|
1070
1071
|
"""
|
|
1071
1072
|
if self.active_db:
|
|
1072
|
-
return
|
|
1073
|
+
return NetClasses(self)
|
|
1073
1074
|
|
|
1074
1075
|
@property
|
|
1075
1076
|
def extended_nets(self) -> ExtendedNets:
|
|
@@ -1119,7 +1120,10 @@ class Edb(EdbInit):
|
|
|
1119
1120
|
:class:`Layout <pyedb.grpc.database.layout.layout.Layout>`
|
|
1120
1121
|
Layout manipulation tools.
|
|
1121
1122
|
"""
|
|
1122
|
-
|
|
1123
|
+
if self._layout:
|
|
1124
|
+
return self._layout
|
|
1125
|
+
self._layout = Layout(self)
|
|
1126
|
+
return self._layout
|
|
1123
1127
|
|
|
1124
1128
|
@property
|
|
1125
1129
|
def active_layout(self) -> Layout:
|
|
@@ -1401,7 +1405,7 @@ class Edb(EdbInit):
|
|
|
1401
1405
|
print(command)
|
|
1402
1406
|
temp_inputGDS = inputGDS.split(".gds")[0]
|
|
1403
1407
|
self.edbpath = temp_inputGDS + ".aedb"
|
|
1404
|
-
return self.
|
|
1408
|
+
return self.open()
|
|
1405
1409
|
|
|
1406
1410
|
def _create_extent(
|
|
1407
1411
|
self,
|
|
@@ -1420,6 +1424,7 @@ class Edb(EdbInit):
|
|
|
1420
1424
|
|
|
1421
1425
|
if extent_type in [
|
|
1422
1426
|
"Conforming",
|
|
1427
|
+
"Conformal",
|
|
1423
1428
|
GrpcExtentType.CONFORMING,
|
|
1424
1429
|
1,
|
|
1425
1430
|
]:
|
|
@@ -1521,13 +1526,26 @@ class Edb(EdbInit):
|
|
|
1521
1526
|
unite_polys = []
|
|
1522
1527
|
for i in _polys:
|
|
1523
1528
|
if "PolygonData" not in str(i):
|
|
1524
|
-
obj_data = i.polygon_data.expand(
|
|
1529
|
+
obj_data = i.polygon_data.expand(
|
|
1530
|
+
expansion_size,
|
|
1531
|
+
round_corner,
|
|
1532
|
+
round_extension,
|
|
1533
|
+
tolerance,
|
|
1534
|
+
)
|
|
1525
1535
|
else:
|
|
1526
|
-
obj_data = i.expand(
|
|
1536
|
+
obj_data = i.expand(
|
|
1537
|
+
expansion_size,
|
|
1538
|
+
round_corner,
|
|
1539
|
+
round_extension,
|
|
1540
|
+
tolerance,
|
|
1541
|
+
)
|
|
1527
1542
|
if inlcude_voids_in_extents and "PolygonData" not in str(i) and i.has_voids and obj_data:
|
|
1528
1543
|
for void in i.voids:
|
|
1529
1544
|
void_data = void.polygon_data.expand(
|
|
1530
|
-
-1 * expansion_size,
|
|
1545
|
+
-1 * expansion_size,
|
|
1546
|
+
round_corner,
|
|
1547
|
+
round_extension,
|
|
1548
|
+
tolerance,
|
|
1531
1549
|
)
|
|
1532
1550
|
if void_data:
|
|
1533
1551
|
for v in list(void_data):
|
|
@@ -1992,11 +2010,15 @@ class Edb(EdbInit):
|
|
|
1992
2010
|
if isinstance(term, PadstackInstanceTerminal):
|
|
1993
2011
|
if term.net.name in reference_list:
|
|
1994
2012
|
pins_to_preserve.append(term.edb_uid)
|
|
2013
|
+
delete_list = []
|
|
1995
2014
|
|
|
1996
2015
|
for i in self.nets.nets.values():
|
|
1997
2016
|
name = i.name
|
|
1998
2017
|
if name not in all_list and name not in nets_to_preserve:
|
|
1999
|
-
|
|
2018
|
+
delete_list.append(i)
|
|
2019
|
+
# i.delete()
|
|
2020
|
+
for i in delete_list:
|
|
2021
|
+
i.delete()
|
|
2000
2022
|
reference_pinsts = []
|
|
2001
2023
|
reference_prims = []
|
|
2002
2024
|
reference_paths = []
|
|
@@ -2468,7 +2490,7 @@ class Edb(EdbInit):
|
|
|
2468
2490
|
>>> # Export to HFSS project:
|
|
2469
2491
|
>>> edb.export_hfss(r"C:/output", net_list=["SignalNet"])
|
|
2470
2492
|
"""
|
|
2471
|
-
siwave_s = SiwaveSolve(self.edbpath
|
|
2493
|
+
siwave_s = SiwaveSolve(self.edbpath)
|
|
2472
2494
|
return siwave_s.export_3d_cad("HFSS", path_to_output, net_list, num_cores, aedt_file_name, hidden=hidden)
|
|
2473
2495
|
|
|
2474
2496
|
def export_q3d(
|
|
@@ -2570,7 +2592,7 @@ class Edb(EdbInit):
|
|
|
2570
2592
|
>>> # Solve with SIwave:
|
|
2571
2593
|
>>> edb.solve_siwave()
|
|
2572
2594
|
"""
|
|
2573
|
-
process = SiwaveSolve(self.edbpath
|
|
2595
|
+
process = SiwaveSolve(self.edbpath)
|
|
2574
2596
|
try:
|
|
2575
2597
|
self.close()
|
|
2576
2598
|
except:
|
|
@@ -2687,6 +2709,30 @@ class Edb(EdbInit):
|
|
|
2687
2709
|
self.logger.info(f"Variable {variable_name} doesn't exists.")
|
|
2688
2710
|
return False
|
|
2689
2711
|
|
|
2712
|
+
def get_variable_value(self, variable_name):
|
|
2713
|
+
"""
|
|
2714
|
+
Deprecated method to get the value of a variable.
|
|
2715
|
+
|
|
2716
|
+
.. deprecated:: pyedb 0.55.0
|
|
2717
|
+
Use :func:`get_variable` instead.
|
|
2718
|
+
"""
|
|
2719
|
+
warnings.warn(
|
|
2720
|
+
"`get_variable_value` is deprecated use `get_variable` instead.",
|
|
2721
|
+
DeprecationWarning,
|
|
2722
|
+
)
|
|
2723
|
+
return self.get_variable(variable_name)
|
|
2724
|
+
|
|
2725
|
+
def get_all_variable_names(self) -> List[str]:
|
|
2726
|
+
"""Method added for compatibility with grpc.
|
|
2727
|
+
|
|
2728
|
+
Returns
|
|
2729
|
+
-------
|
|
2730
|
+
List[str]
|
|
2731
|
+
List of variable names.
|
|
2732
|
+
|
|
2733
|
+
"""
|
|
2734
|
+
return list(self.active_cell.get_all_variable_names())
|
|
2735
|
+
|
|
2690
2736
|
def add_project_variable(self, variable_name, variable_value, description=None) -> bool:
|
|
2691
2737
|
"""Add project variable.
|
|
2692
2738
|
|
pyedb/grpc/edb_init.py
CHANGED
|
@@ -31,8 +31,8 @@ import time
|
|
|
31
31
|
import ansys.edb.core.database as database
|
|
32
32
|
|
|
33
33
|
from pyedb import __version__
|
|
34
|
-
from pyedb.edb_logger import pyedb_logger
|
|
35
34
|
from pyedb.generic.general_methods import env_path, env_value, is_linux
|
|
35
|
+
from pyedb.generic.settings import settings
|
|
36
36
|
from pyedb.grpc.rpc_session import RpcSession
|
|
37
37
|
|
|
38
38
|
|
|
@@ -40,7 +40,7 @@ class EdbInit(object):
|
|
|
40
40
|
"""Edb Dot Net Class."""
|
|
41
41
|
|
|
42
42
|
def __init__(self, edbversion):
|
|
43
|
-
self.logger =
|
|
43
|
+
self.logger = settings.logger
|
|
44
44
|
self._db = None
|
|
45
45
|
self.edbversion = edbversion
|
|
46
46
|
self.logger.info("Logger is initialized in EDB.")
|
|
@@ -72,7 +72,7 @@ class EdbInit(object):
|
|
|
72
72
|
|
|
73
73
|
@staticmethod
|
|
74
74
|
def _signal_handler(signum=None, frame=None):
|
|
75
|
-
RpcSession.
|
|
75
|
+
RpcSession.kill_all_instances()
|
|
76
76
|
|
|
77
77
|
@property
|
|
78
78
|
def db(self):
|