pyedb 0.7.0__py3-none-any.whl → 0.8.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/dotnet/clr_module.py +1 -1
- pyedb/dotnet/edb.py +7 -7
- pyedb/dotnet/edb_core/cell/hierarchy/model.py +1 -1
- pyedb/dotnet/edb_core/components.py +15 -12
- pyedb/dotnet/edb_core/configuration.py +232 -25
- pyedb/dotnet/edb_core/definition/component_def.py +10 -1
- pyedb/dotnet/edb_core/definition/component_model.py +1 -1
- pyedb/dotnet/edb_core/definition/definition_obj.py +1 -1
- pyedb/dotnet/edb_core/definition/definitions.py +8 -2
- pyedb/dotnet/edb_core/definition/package_def.py +61 -15
- pyedb/dotnet/edb_core/dotnet/database.py +5 -4
- pyedb/dotnet/edb_core/edb_data/components_data.py +3 -2
- pyedb/dotnet/edb_core/edb_data/connectable.py +1 -1
- pyedb/dotnet/edb_core/edb_data/hfss_extent_info.py +14 -13
- pyedb/dotnet/edb_core/edb_data/hfss_simulation_setup_data.py +2 -2
- pyedb/dotnet/edb_core/edb_data/layer_data.py +9 -3
- pyedb/dotnet/edb_core/edb_data/padstacks_data.py +6 -5
- pyedb/dotnet/edb_core/edb_data/primitives_data.py +16 -13
- pyedb/dotnet/edb_core/edb_data/siwave_simulation_setup_data.py +7 -1
- pyedb/dotnet/edb_core/edb_data/sources.py +10 -0
- pyedb/dotnet/edb_core/geometry/__init__.py +0 -0
- pyedb/dotnet/edb_core/{edb_data/obj_base.py → geometry/point_data.py} +12 -26
- pyedb/dotnet/edb_core/geometry/polygon_data.py +77 -0
- pyedb/dotnet/edb_core/layout.py +59 -0
- pyedb/dotnet/edb_core/materials.py +715 -597
- pyedb/dotnet/edb_core/nets.py +3 -3
- pyedb/dotnet/edb_core/obj_base.py +94 -0
- pyedb/dotnet/edb_core/padstack.py +57 -6
- pyedb/dotnet/edb_core/siwave.py +11 -4
- pyedb/dotnet/edb_core/stackup.py +152 -131
- pyedb/dotnet/edb_core/utilities/__init__.py +3 -0
- pyedb/dotnet/edb_core/utilities/heatsink.py +69 -0
- pyedb/dotnet/sim_setup_data/data/siw_dc_ir_settings.py +46 -0
- pyedb/edb_logger.py +15 -1
- pyedb/exceptions.py +6 -0
- pyedb/generic/filesystem.py +7 -3
- pyedb/generic/general_methods.py +4 -0
- pyedb/generic/process.py +4 -1
- pyedb/generic/settings.py +30 -8
- pyedb/siwave.py +50 -1
- {pyedb-0.7.0.dist-info → pyedb-0.8.0.dist-info}/METADATA +31 -53
- {pyedb-0.7.0.dist-info → pyedb-0.8.0.dist-info}/RECORD +46 -39
- /pyedb/dotnet/edb_core/{edb_data → utilities}/simulation_setup.py +0 -0
- {pyedb-0.7.0.dist-info → pyedb-0.8.0.dist-info}/LICENSE +0 -0
- {pyedb-0.7.0.dist-info → pyedb-0.8.0.dist-info}/WHEEL +0 -0
|
@@ -20,8 +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
|
-
from pyedb.dotnet.edb_core.
|
|
24
|
-
from pyedb.dotnet.edb_core.
|
|
23
|
+
from pyedb.dotnet.edb_core.geometry.polygon_data import PolygonData
|
|
24
|
+
from pyedb.dotnet.edb_core.obj_base import ObjBase
|
|
25
25
|
from pyedb.generic.general_methods import pyedb_function_handler
|
|
26
26
|
|
|
27
27
|
|
|
@@ -33,19 +33,24 @@ class PackageDef(ObjBase):
|
|
|
33
33
|
pedb : :class:`pyedb.edb`
|
|
34
34
|
Edb object.
|
|
35
35
|
edb_object : object
|
|
36
|
-
|
|
36
|
+
Edb PackageDef Object
|
|
37
|
+
component_part_name : str, optional
|
|
38
|
+
Part name of the component.
|
|
39
|
+
extent_bounding_box : list, optional
|
|
40
|
+
Bounding box defines the shape of the package. For example, [[0, 0], ["2mm", "2mm"].
|
|
41
|
+
|
|
37
42
|
"""
|
|
38
43
|
|
|
39
|
-
def __init__(self, pedb, edb_object=None, name=None):
|
|
40
|
-
|
|
41
|
-
if
|
|
42
|
-
self._edb_object = self.__create_from_name(name)
|
|
44
|
+
def __init__(self, pedb, edb_object=None, name=None, component_part_name=None, extent_bounding_box=None):
|
|
45
|
+
super().__init__(pedb, edb_object)
|
|
46
|
+
if self._edb_object is None and name is not None:
|
|
47
|
+
self._edb_object = self.__create_from_name(name, component_part_name, extent_bounding_box)
|
|
43
48
|
else:
|
|
44
49
|
self._edb_object = edb_object
|
|
45
50
|
|
|
46
51
|
@pyedb_function_handler
|
|
47
|
-
def __create_from_name(self, name):
|
|
48
|
-
"""Create a package
|
|
52
|
+
def __create_from_name(self, name, component_part_name=None, extent_bounding_box=None):
|
|
53
|
+
"""Create a package definition.
|
|
49
54
|
|
|
50
55
|
Parameters
|
|
51
56
|
----------
|
|
@@ -58,15 +63,34 @@ class PackageDef(ObjBase):
|
|
|
58
63
|
EDB PackageDef Object
|
|
59
64
|
"""
|
|
60
65
|
edb_object = self._pedb.edb_api.definition.PackageDef.Create(self._pedb.active_db, name)
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
66
|
+
if component_part_name:
|
|
67
|
+
x_pt1, y_pt1, x_pt2, y_pt2 = list(
|
|
68
|
+
self._pedb.components.definitions[component_part_name].components.values()
|
|
69
|
+
)[0].bounding_box
|
|
70
|
+
x_mid = (x_pt1 + x_pt2) / 2
|
|
71
|
+
y_mid = (y_pt1 + y_pt2) / 2
|
|
72
|
+
bbox = [[y_pt1 - y_mid, x_pt1 - x_mid], [y_pt2 - y_mid, x_pt2 - x_mid]]
|
|
73
|
+
else:
|
|
74
|
+
bbox = extent_bounding_box
|
|
75
|
+
polygon_data = PolygonData(self._pedb, create_from_bounding_box=True, points=bbox)
|
|
65
76
|
|
|
66
|
-
|
|
67
|
-
edb_object.SetExteriorBoundary(polygon)
|
|
77
|
+
edb_object.SetExteriorBoundary(polygon_data._edb_object)
|
|
68
78
|
return edb_object
|
|
69
79
|
|
|
80
|
+
@pyedb_function_handler
|
|
81
|
+
def delete(self):
|
|
82
|
+
"""Delete a package definition object from the database."""
|
|
83
|
+
return self._edb_object.Delete()
|
|
84
|
+
|
|
85
|
+
@property
|
|
86
|
+
def exterior_boundary(self):
|
|
87
|
+
"""Get the exterior boundary of a package definition."""
|
|
88
|
+
return PolygonData(self._pedb, self._edb_object.GetExteriorBoundary()).points
|
|
89
|
+
|
|
90
|
+
@exterior_boundary.setter
|
|
91
|
+
def exterior_boundary(self, value):
|
|
92
|
+
self._edb_object.SetExteriorBoundary(value._edb_object)
|
|
93
|
+
|
|
70
94
|
@property
|
|
71
95
|
def maximum_power(self):
|
|
72
96
|
"""Maximum power of the package."""
|
|
@@ -116,3 +140,25 @@ class PackageDef(ObjBase):
|
|
|
116
140
|
def height(self, value):
|
|
117
141
|
value = self._pedb.edb_value(value)
|
|
118
142
|
self._edb_object.SetHeight(value)
|
|
143
|
+
|
|
144
|
+
@pyedb_function_handler
|
|
145
|
+
def set_heatsink(self, fin_base_height, fin_height, fin_orientation, fin_spacing, fin_thickness):
|
|
146
|
+
from pyedb.dotnet.edb_core.utilities.heatsink import HeatSink
|
|
147
|
+
|
|
148
|
+
heatsink = HeatSink(self._pedb)
|
|
149
|
+
heatsink.fin_base_height = fin_base_height
|
|
150
|
+
heatsink.fin_height = fin_height
|
|
151
|
+
heatsink.fin_orientation = fin_orientation
|
|
152
|
+
heatsink.fin_spacing = fin_spacing
|
|
153
|
+
heatsink.fin_thickness = fin_thickness
|
|
154
|
+
self._edb_object.SetHeatSink(heatsink._edb_object)
|
|
155
|
+
|
|
156
|
+
@property
|
|
157
|
+
def heatsink(self):
|
|
158
|
+
from pyedb.dotnet.edb_core.utilities.heatsink import HeatSink
|
|
159
|
+
|
|
160
|
+
flag, edb_object = self._edb_object.GetHeatSink()
|
|
161
|
+
if flag:
|
|
162
|
+
return HeatSink(self._pedb, edb_object)
|
|
163
|
+
else:
|
|
164
|
+
return None
|
|
@@ -721,10 +721,11 @@ class EdbDotNet(object):
|
|
|
721
721
|
"""Initialize DLLs."""
|
|
722
722
|
from pyedb.dotnet.clr_module import _clr, edb_initialized
|
|
723
723
|
|
|
724
|
-
if settings.
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
724
|
+
if not settings.use_pyaedt_log:
|
|
725
|
+
if settings.enable_screen_logs:
|
|
726
|
+
self._logger.enable_stdout_log()
|
|
727
|
+
else: # pragma: no cover
|
|
728
|
+
self._logger.disable_stdout_log()
|
|
728
729
|
if not edb_initialized: # pragma: no cover
|
|
729
730
|
self._logger.error("Failed to initialize Dlls.")
|
|
730
731
|
return
|
|
@@ -329,7 +329,7 @@ class EDBComponent(object):
|
|
|
329
329
|
|
|
330
330
|
@solder_ball_height.setter
|
|
331
331
|
def solder_ball_height(self, value):
|
|
332
|
-
if "GetSolderBallProperty" in dir(self.component_property)
|
|
332
|
+
if "GetSolderBallProperty" in dir(self.component_property):
|
|
333
333
|
sball_height = round(self._edb.utility.Value(value).ToDouble(), 9)
|
|
334
334
|
cmp_property = self.component_property
|
|
335
335
|
solder_ball_prop = cmp_property.GetSolderBallProperty().Clone()
|
|
@@ -375,7 +375,7 @@ class EDBComponent(object):
|
|
|
375
375
|
|
|
376
376
|
@property
|
|
377
377
|
def solder_ball_diameter(self):
|
|
378
|
-
"""Solder ball diameter"""
|
|
378
|
+
"""Solder ball diameter."""
|
|
379
379
|
if "GetSolderBallProperty" in dir(self.component_property):
|
|
380
380
|
result = self.component_property.GetSolderBallProperty().GetDiameter()
|
|
381
381
|
succeed = result[0]
|
|
@@ -850,6 +850,7 @@ class EDBComponent(object):
|
|
|
850
850
|
@property
|
|
851
851
|
def is_top_mounted(self):
|
|
852
852
|
"""Check if a component is mounted on top or bottom of the layout.
|
|
853
|
+
|
|
853
854
|
Returns
|
|
854
855
|
-------
|
|
855
856
|
bool
|
|
@@ -20,7 +20,7 @@
|
|
|
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 pyedb.dotnet.edb_core.
|
|
23
|
+
from pyedb.dotnet.edb_core.obj_base import ObjBase
|
|
24
24
|
from pyedb.generic.general_methods import pyedb_function_handler
|
|
25
25
|
|
|
26
26
|
|
|
@@ -39,14 +39,14 @@ class HfssExtentInfo:
|
|
|
39
39
|
self._pedb = pedb
|
|
40
40
|
|
|
41
41
|
self._hfss_extent_info_type = {
|
|
42
|
-
"
|
|
43
|
-
"
|
|
44
|
-
"
|
|
45
|
-
"
|
|
42
|
+
"bounding_box": self._pedb.edb_api.utility.utility.HFSSExtentInfoType.BoundingBox,
|
|
43
|
+
"conforming": self._pedb.edb_api.utility.utility.HFSSExtentInfoType.Conforming,
|
|
44
|
+
"convexHull": self._pedb.edb_api.utility.utility.HFSSExtentInfoType.ConvexHull,
|
|
45
|
+
"polygon": self._pedb.edb_api.utility.utility.HFSSExtentInfoType.Polygon,
|
|
46
46
|
}
|
|
47
47
|
self._open_region_type = {
|
|
48
|
-
"
|
|
49
|
-
"
|
|
48
|
+
"radiation": self._pedb.edb_api.utility.utility.OpenRegionType.Radiation,
|
|
49
|
+
"pml": self._pedb.edb_api.utility.utility.OpenRegionType.PML,
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
@pyedb_function_handler()
|
|
@@ -195,18 +195,19 @@ class HfssExtentInfo:
|
|
|
195
195
|
@property
|
|
196
196
|
def dielectric_extent_type(self):
|
|
197
197
|
"""Dielectric extent type."""
|
|
198
|
-
return self._edb_hfss_extent_info.DielectricExtentType.ToString()
|
|
198
|
+
return self._edb_hfss_extent_info.DielectricExtentType.ToString().lower()
|
|
199
199
|
|
|
200
200
|
@dielectric_extent_type.setter
|
|
201
201
|
def dielectric_extent_type(self, value):
|
|
202
|
+
value = "bounding_box" if value == "BoundingBox" else value
|
|
202
203
|
info = self._edb_hfss_extent_info
|
|
203
|
-
info.DielectricExtentType = self._hfss_extent_info_type[value]
|
|
204
|
+
info.DielectricExtentType = self._hfss_extent_info_type[value.lower()]
|
|
204
205
|
self._update_hfss_extent_info(info)
|
|
205
206
|
|
|
206
207
|
@property
|
|
207
208
|
def extent_type(self):
|
|
208
209
|
"""Extent type."""
|
|
209
|
-
return self._edb_hfss_extent_info.ExtentType.ToString()
|
|
210
|
+
return self._edb_hfss_extent_info.ExtentType.ToString().lower()
|
|
210
211
|
|
|
211
212
|
@extent_type.setter
|
|
212
213
|
def extent_type(self, value):
|
|
@@ -239,17 +240,17 @@ class HfssExtentInfo:
|
|
|
239
240
|
@property
|
|
240
241
|
def open_region_type(self):
|
|
241
242
|
"""Open region type."""
|
|
242
|
-
return self._edb_hfss_extent_info.OpenRegionType.ToString()
|
|
243
|
+
return self._edb_hfss_extent_info.OpenRegionType.ToString().lower()
|
|
243
244
|
|
|
244
245
|
@open_region_type.setter
|
|
245
246
|
def open_region_type(self, value):
|
|
246
247
|
info = self._edb_hfss_extent_info
|
|
247
|
-
info.OpenRegionType = self._open_region_type[value]
|
|
248
|
+
info.OpenRegionType = self._open_region_type[value.lower()]
|
|
248
249
|
self._update_hfss_extent_info(info)
|
|
249
250
|
|
|
250
251
|
@property
|
|
251
252
|
def operating_freq(self):
|
|
252
|
-
"""Operating frequency.
|
|
253
|
+
"""PML Operating frequency.
|
|
253
254
|
|
|
254
255
|
Returns
|
|
255
256
|
-------
|
|
@@ -266,7 +267,7 @@ class HfssExtentInfo:
|
|
|
266
267
|
|
|
267
268
|
@property
|
|
268
269
|
def radiation_level(self):
|
|
269
|
-
"""Radiation level."""
|
|
270
|
+
"""PML Radiation level to calculate the thickness of boundary."""
|
|
270
271
|
return EdbValue(self._edb_hfss_extent_info.RadiationLevel)
|
|
271
272
|
|
|
272
273
|
@radiation_level.setter
|
|
@@ -21,11 +21,11 @@
|
|
|
21
21
|
# SOFTWARE.
|
|
22
22
|
|
|
23
23
|
from pyedb.dotnet.clr_module import Tuple
|
|
24
|
-
from pyedb.dotnet.edb_core.
|
|
24
|
+
from pyedb.dotnet.edb_core.general import convert_py_list_to_net_list
|
|
25
|
+
from pyedb.dotnet.edb_core.utilities.simulation_setup import (
|
|
25
26
|
BaseSimulationSetup,
|
|
26
27
|
EdbFrequencySweep,
|
|
27
28
|
)
|
|
28
|
-
from pyedb.dotnet.edb_core.general import convert_py_list_to_net_list
|
|
29
29
|
from pyedb.generic.general_methods import generate_unique_name, pyedb_function_handler
|
|
30
30
|
|
|
31
31
|
|
|
@@ -553,6 +553,7 @@ class StackupLayerEdbClass(LayerEdbClass):
|
|
|
553
553
|
dict_out[k[1:]] = v
|
|
554
554
|
return dict_out
|
|
555
555
|
|
|
556
|
+
# TODO: This method might need some refactoring
|
|
556
557
|
def _load_layer(self, layer):
|
|
557
558
|
if layer:
|
|
558
559
|
self.color = layer["color"]
|
|
@@ -560,13 +561,18 @@ class StackupLayerEdbClass(LayerEdbClass):
|
|
|
560
561
|
if isinstance(layer["material"], str):
|
|
561
562
|
self.material = layer["material"]
|
|
562
563
|
else:
|
|
563
|
-
|
|
564
|
-
|
|
564
|
+
material_data = layer["material"]
|
|
565
|
+
if material_data is not None:
|
|
566
|
+
material_name = layer["material"]["name"]
|
|
567
|
+
self._pclass._pedb.materials.add_material(material_name, **material_data)
|
|
568
|
+
self.material = material_name
|
|
565
569
|
if layer["dielectric_fill"]:
|
|
566
570
|
if isinstance(layer["dielectric_fill"], str):
|
|
567
571
|
self.dielectric_fill = layer["dielectric_fill"]
|
|
568
572
|
else:
|
|
569
|
-
|
|
573
|
+
dielectric_data = layer["dielectric_fill"]
|
|
574
|
+
if dielectric_data is not None:
|
|
575
|
+
self._pclass._pedb.materials.add_material(**dielectric_data)
|
|
570
576
|
self.dielectric_fill = layer["dielectric_fill"]["name"]
|
|
571
577
|
self.thickness = layer["thickness"]
|
|
572
578
|
self.etch_factor = layer["etch_factor"]
|
|
@@ -688,6 +688,7 @@ class EDBPadstack(object):
|
|
|
688
688
|
float
|
|
689
689
|
Thickness of the hole plating if present.
|
|
690
690
|
"""
|
|
691
|
+
value = self._get_edb_value(value).ToDouble()
|
|
691
692
|
hr = 200 * float(value) / float(self.hole_properties[0])
|
|
692
693
|
self.hole_plating_ratio = hr
|
|
693
694
|
|
|
@@ -808,13 +809,13 @@ class EDBPadstack(object):
|
|
|
808
809
|
if convert_only_signal_vias:
|
|
809
810
|
signal_nets = [i for i in list(self._ppadstack._pedb.nets.signal_nets.keys())]
|
|
810
811
|
topl, topz, bottoml, bottomz = self._ppadstack._pedb.stackup.stackup_limits(True)
|
|
811
|
-
|
|
812
|
+
if self.via_start_layer in layers:
|
|
812
813
|
start_elevation = layers[self.via_start_layer].lower_elevation
|
|
813
|
-
|
|
814
|
+
else:
|
|
814
815
|
start_elevation = layers[self.instances[0].start_layer].lower_elevation
|
|
815
|
-
|
|
816
|
-
stop_elevation = layers[self.
|
|
817
|
-
|
|
816
|
+
if self.via_stop_layer in layers:
|
|
817
|
+
stop_elevation = layers[self.via_stop_layer].upper_elevation
|
|
818
|
+
else:
|
|
818
819
|
stop_elevation = layers[self.instances[0].stop_layer].upper_elevation
|
|
819
820
|
|
|
820
821
|
diel_thick = abs(start_elevation - stop_elevation)
|
|
@@ -142,7 +142,7 @@ class EDBPrimitivesMain(Connectable):
|
|
|
142
142
|
try:
|
|
143
143
|
layer_name = self.primitive_object.GetLayer().GetName()
|
|
144
144
|
return self._pedb.stackup.layers[layer_name]
|
|
145
|
-
except AttributeError: # pragma: no cover
|
|
145
|
+
except (KeyError, AttributeError): # pragma: no cover
|
|
146
146
|
return None
|
|
147
147
|
|
|
148
148
|
@property
|
|
@@ -155,18 +155,19 @@ class EDBPrimitivesMain(Connectable):
|
|
|
155
155
|
"""
|
|
156
156
|
try:
|
|
157
157
|
return self.layer.name
|
|
158
|
-
except AttributeError: # pragma: no cover
|
|
158
|
+
except (KeyError, AttributeError): # pragma: no cover
|
|
159
159
|
return None
|
|
160
160
|
|
|
161
161
|
@layer_name.setter
|
|
162
162
|
def layer_name(self, val):
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
163
|
+
layer_list = list(self._core_stackup.layers.keys())
|
|
164
|
+
if isinstance(val, str) and val in layer_list:
|
|
165
|
+
layer = self._core_stackup.layers[val]._edb_layer
|
|
166
|
+
if layer:
|
|
167
|
+
self.primitive_object.SetLayer(layer)
|
|
167
168
|
else:
|
|
168
|
-
raise AttributeError("Layer {} not found
|
|
169
|
-
elif isinstance(val, type(self._core_stackup.layers[
|
|
169
|
+
raise AttributeError("Layer {} not found.".format(val))
|
|
170
|
+
elif isinstance(val, type(self._core_stackup.layers[layer_list[0]])):
|
|
170
171
|
try:
|
|
171
172
|
self.primitive_object.SetLayer(val._edb_layer)
|
|
172
173
|
except:
|
|
@@ -887,7 +888,7 @@ class EdbPath(EDBPrimitives, PathDotNet):
|
|
|
887
888
|
return self._app.hfss.create_edge_port_vertical(self.id, pos, name, 50, reference_layer)
|
|
888
889
|
|
|
889
890
|
@pyedb_function_handler()
|
|
890
|
-
def create_via_fence(self, distance, gap, padstack_name):
|
|
891
|
+
def create_via_fence(self, distance, gap, padstack_name, net_name="GND"):
|
|
891
892
|
"""Create via fences on both sides of the trace.
|
|
892
893
|
|
|
893
894
|
Parameters
|
|
@@ -898,6 +899,8 @@ class EdbPath(EDBPrimitives, PathDotNet):
|
|
|
898
899
|
Gap between vias.
|
|
899
900
|
padstack_name: str
|
|
900
901
|
Name of the via padstack.
|
|
902
|
+
net_name: str, optional
|
|
903
|
+
Name of the net.
|
|
901
904
|
|
|
902
905
|
Returns
|
|
903
906
|
-------
|
|
@@ -989,7 +992,7 @@ class EdbPath(EDBPrimitives, PathDotNet):
|
|
|
989
992
|
center_line = self.get_center_line()
|
|
990
993
|
leftline, rightline = getParalletLines(center_line, distance)
|
|
991
994
|
for x, y in getLocations(rightline, gap) + getLocations(leftline, gap):
|
|
992
|
-
self._pedb.padstacks.place([x, y], padstack_name)
|
|
995
|
+
self._pedb.padstacks.place([x, y], padstack_name, net_name=net_name)
|
|
993
996
|
|
|
994
997
|
|
|
995
998
|
class EdbRectangle(EDBPrimitives, RectangleDotNet):
|
|
@@ -1301,7 +1304,7 @@ class EDBArcs(object):
|
|
|
1301
1304
|
|
|
1302
1305
|
Examples
|
|
1303
1306
|
--------
|
|
1304
|
-
>>> appedb = Edb(fpath, edbversion="
|
|
1307
|
+
>>> appedb = Edb(fpath, edbversion="2024.1")
|
|
1305
1308
|
>>> start_coordinate = appedb.nets["V1P0_S0"].primitives[0].arcs[0].start
|
|
1306
1309
|
>>> print(start_coordinate)
|
|
1307
1310
|
[x_value, y_value]
|
|
@@ -1320,7 +1323,7 @@ class EDBArcs(object):
|
|
|
1320
1323
|
|
|
1321
1324
|
Examples
|
|
1322
1325
|
--------
|
|
1323
|
-
>>> appedb = Edb(fpath, edbversion="
|
|
1326
|
+
>>> appedb = Edb(fpath, edbversion="2024.1")
|
|
1324
1327
|
>>> end_coordinate = appedb.nets["V1P0_S0"].primitives[0].arcs[0].end
|
|
1325
1328
|
"""
|
|
1326
1329
|
point = self.arc_object.End
|
|
@@ -1338,7 +1341,7 @@ class EDBArcs(object):
|
|
|
1338
1341
|
|
|
1339
1342
|
Examples
|
|
1340
1343
|
--------
|
|
1341
|
-
>>> appedb = Edb(fpath, edbversion="
|
|
1344
|
+
>>> appedb = Edb(fpath, edbversion="2024.1")
|
|
1342
1345
|
>>> arc_height = appedb.nets["V1P0_S0"].primitives[0].arcs[0].height
|
|
1343
1346
|
"""
|
|
1344
1347
|
return self.arc_object.Height
|
|
@@ -22,11 +22,12 @@
|
|
|
22
22
|
|
|
23
23
|
import warnings
|
|
24
24
|
|
|
25
|
-
from pyedb.dotnet.edb_core.edb_data.simulation_setup import BaseSimulationSetup
|
|
26
25
|
from pyedb.dotnet.edb_core.general import (
|
|
27
26
|
convert_netdict_to_pydict,
|
|
28
27
|
convert_pydict_to_netdict,
|
|
29
28
|
)
|
|
29
|
+
from pyedb.dotnet.edb_core.utilities.simulation_setup import BaseSimulationSetup
|
|
30
|
+
from pyedb.dotnet.sim_setup_data.data.siw_dc_ir_settings import SiwaveDCIRSettings
|
|
30
31
|
from pyedb.generic.general_methods import is_linux, pyedb_function_handler
|
|
31
32
|
|
|
32
33
|
|
|
@@ -1144,6 +1145,11 @@ class SiwaveDCSimulationSetup(SiwaveSYZSimulationSetup):
|
|
|
1144
1145
|
self.set_dc_slider(1)
|
|
1145
1146
|
return self
|
|
1146
1147
|
|
|
1148
|
+
@property
|
|
1149
|
+
def dc_ir_settings(self):
|
|
1150
|
+
"""DC IR settings."""
|
|
1151
|
+
return SiwaveDCIRSettings(self)
|
|
1152
|
+
|
|
1147
1153
|
@pyedb_function_handler
|
|
1148
1154
|
def get_configurations(self):
|
|
1149
1155
|
"""Get SIwave DC simulation settings.
|
|
@@ -20,6 +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
|
+
import warnings
|
|
24
|
+
|
|
23
25
|
from pyedb.generic.constants import NodeType, SourceType
|
|
24
26
|
from pyedb.generic.general_methods import generate_unique_name, pyedb_function_handler
|
|
25
27
|
|
|
@@ -274,9 +276,17 @@ class PinGroup(object):
|
|
|
274
276
|
def component(self, value):
|
|
275
277
|
self._component = value
|
|
276
278
|
|
|
279
|
+
@property
|
|
280
|
+
def pins(self):
|
|
281
|
+
"""Gets the pins belong to this pin group."""
|
|
282
|
+
from pyedb.dotnet.edb_core.edb_data.padstacks_data import EDBPadstackInstance
|
|
283
|
+
|
|
284
|
+
return {i.GetName(): EDBPadstackInstance(i, self._pedb) for i in list(self._edb_object.GetPins())}
|
|
285
|
+
|
|
277
286
|
@property
|
|
278
287
|
def node_pins(self):
|
|
279
288
|
"""Node pins."""
|
|
289
|
+
warnings.warn("`node_pins` is deprecated. Use `pins` method instead.", DeprecationWarning)
|
|
280
290
|
return self._node_pins
|
|
281
291
|
|
|
282
292
|
@node_pins.setter
|
|
File without changes
|
|
@@ -21,31 +21,17 @@
|
|
|
21
21
|
# SOFTWARE.
|
|
22
22
|
|
|
23
23
|
|
|
24
|
-
class
|
|
25
|
-
"""
|
|
24
|
+
class PointData:
|
|
25
|
+
"""Point Data."""
|
|
26
26
|
|
|
27
|
-
def __init__(self, pedb, edb_object):
|
|
27
|
+
def __init__(self, pedb, edb_object=None, x=None, y=None):
|
|
28
28
|
self._pedb = pedb
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
"""Type of the edb object."""
|
|
39
|
-
try:
|
|
40
|
-
return self._edb_object.GetType()
|
|
41
|
-
except AttributeError: # pragma: no cover
|
|
42
|
-
return None
|
|
43
|
-
|
|
44
|
-
@property
|
|
45
|
-
def name(self):
|
|
46
|
-
"""Name of the definition."""
|
|
47
|
-
return self._edb_object.GetName()
|
|
48
|
-
|
|
49
|
-
@name.setter
|
|
50
|
-
def name(self, value):
|
|
51
|
-
self._edb_object.SetName(value)
|
|
29
|
+
if edb_object:
|
|
30
|
+
self._edb_object = edb_object
|
|
31
|
+
else:
|
|
32
|
+
x = x if x else 0
|
|
33
|
+
y = y if y else 0
|
|
34
|
+
self._edb_object = self._pedb.edb_api.geometry.point_data(
|
|
35
|
+
self._pedb.edb_value(x),
|
|
36
|
+
self._pedb.edb_value(y),
|
|
37
|
+
)
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# Copyright (C) 2023 - 2024 ANSYS, Inc. and/or its affiliates.
|
|
2
|
+
# SPDX-License-Identifier: MIT
|
|
3
|
+
#
|
|
4
|
+
#
|
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
# furnished to do so, subject to the following conditions:
|
|
11
|
+
#
|
|
12
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
# copies or substantial portions of the Software.
|
|
14
|
+
#
|
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
# SOFTWARE.
|
|
22
|
+
|
|
23
|
+
from pyedb.dotnet.edb_core.geometry.point_data import PointData
|
|
24
|
+
from pyedb.dotnet.edb_core.obj_base import BBox
|
|
25
|
+
from pyedb.generic.general_methods import pyedb_function_handler
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class PolygonData:
|
|
29
|
+
"""Polygon Data."""
|
|
30
|
+
|
|
31
|
+
def __init__(
|
|
32
|
+
self,
|
|
33
|
+
pedb,
|
|
34
|
+
edb_object=None,
|
|
35
|
+
create_from_points=None,
|
|
36
|
+
create_from_circle=None,
|
|
37
|
+
create_from_rectangle=None,
|
|
38
|
+
create_from_bounding_box=None,
|
|
39
|
+
**kwargs,
|
|
40
|
+
):
|
|
41
|
+
self._pedb = pedb
|
|
42
|
+
|
|
43
|
+
if create_from_points:
|
|
44
|
+
self._edb_object = self.create_from_points(**kwargs)
|
|
45
|
+
elif create_from_circle:
|
|
46
|
+
x_center, y_center, radius = kwargs
|
|
47
|
+
elif create_from_rectangle:
|
|
48
|
+
x_lower_left, y_lower_left, x_upper_right, y_upper_right = kwargs
|
|
49
|
+
elif create_from_bounding_box:
|
|
50
|
+
self._edb_object = self.create_from_bounding_box(**kwargs)
|
|
51
|
+
else: # pragma: no cover
|
|
52
|
+
self._edb_object = edb_object
|
|
53
|
+
|
|
54
|
+
@property
|
|
55
|
+
def points(self):
|
|
56
|
+
"""Get all points in polygon.
|
|
57
|
+
|
|
58
|
+
Returns
|
|
59
|
+
-------
|
|
60
|
+
list[list[float]]
|
|
61
|
+
"""
|
|
62
|
+
return [
|
|
63
|
+
[self._pedb.edb_value(i.X).ToDouble(), self._pedb.edb_value(i.Y).ToDouble()]
|
|
64
|
+
for i in list(self._edb_object.Points)
|
|
65
|
+
]
|
|
66
|
+
|
|
67
|
+
@pyedb_function_handler
|
|
68
|
+
def create_from_points(self, points, closed=True):
|
|
69
|
+
list_of_point_data = []
|
|
70
|
+
for pt in points:
|
|
71
|
+
list_of_point_data.append(PointData(self._pedb, x=pt[0], y=pt[1]))
|
|
72
|
+
return self._pedb.edb_api.geometry.api_class.PolygonData(list_of_point_data, closed)
|
|
73
|
+
|
|
74
|
+
@pyedb_function_handler
|
|
75
|
+
def create_from_bounding_box(self, points):
|
|
76
|
+
bbox = BBox(self._pedb, point_1=points[0], point_2=points[1])
|
|
77
|
+
return self._pedb.edb_api.geometry.api_class.PolygonData.CreateFromBBox(bbox._edb_object)
|
pyedb/dotnet/edb_core/layout.py
CHANGED
|
@@ -240,6 +240,65 @@ class EdbLayout(object):
|
|
|
240
240
|
objinst.append(el)
|
|
241
241
|
return objinst
|
|
242
242
|
|
|
243
|
+
@pyedb_function_handler()
|
|
244
|
+
def get_primitive_by_layer_and_point(self, point=None, layer=None, nets=None):
|
|
245
|
+
"""Return primitive given coordinate point [x, y], layer name and nets.
|
|
246
|
+
|
|
247
|
+
Parameters
|
|
248
|
+
----------
|
|
249
|
+
point : list
|
|
250
|
+
Coordinate [x, y]
|
|
251
|
+
|
|
252
|
+
layer : list or str, optional
|
|
253
|
+
list of layer name or layer name applied on filter.
|
|
254
|
+
|
|
255
|
+
nets : list or str, optional
|
|
256
|
+
list of net name or single net name applied on filter
|
|
257
|
+
|
|
258
|
+
Returns
|
|
259
|
+
-------
|
|
260
|
+
list of :class:`pyedb.dotnet.edb_core.edb_data.primitives_data.EDBPrimitives`
|
|
261
|
+
List of primitives, polygons, paths and rectangles.
|
|
262
|
+
"""
|
|
263
|
+
if isinstance(layer, str) and layer not in list(self._pedb.stackup.signal_layers.keys()):
|
|
264
|
+
layer = None
|
|
265
|
+
if not isinstance(point, list) and len(point) == 2:
|
|
266
|
+
self._logger.error("Provided point must be a list of two values")
|
|
267
|
+
return False
|
|
268
|
+
pt = self._edb.geometry.point_data(point[0], point[1])
|
|
269
|
+
if isinstance(nets, str):
|
|
270
|
+
nets = [nets]
|
|
271
|
+
elif nets and not isinstance(nets, list) and len(nets) == len([net for net in nets if isinstance(net, str)]):
|
|
272
|
+
_nets = []
|
|
273
|
+
for net in nets:
|
|
274
|
+
if net not in self._pedb.nets:
|
|
275
|
+
self._logger.error(
|
|
276
|
+
f"Net {net} used to find primitive from layer point and net not found, skipping it."
|
|
277
|
+
)
|
|
278
|
+
else:
|
|
279
|
+
_nets.append(self._pedb.nets[net].net_obj)
|
|
280
|
+
if _nets:
|
|
281
|
+
nets = _nets
|
|
282
|
+
_obj_instances = list(self._pedb.layout_instance.FindLayoutObjInstance(pt, None, nets).Items)
|
|
283
|
+
returned_obj = []
|
|
284
|
+
if layer:
|
|
285
|
+
selected_obj = [obj for obj in _obj_instances if layer in [lay.GetName() for lay in list(obj.GetLayers())]]
|
|
286
|
+
for obj in selected_obj:
|
|
287
|
+
prim = obj.GetLayoutObj()
|
|
288
|
+
obj_id = prim.GetId()
|
|
289
|
+
prim_type = str(prim.GetPrimitiveType())
|
|
290
|
+
if prim_type == "Polygon":
|
|
291
|
+
[returned_obj.append(p) for p in [poly for poly in self.polygons if poly.id == obj_id]]
|
|
292
|
+
elif prim_type == "Path":
|
|
293
|
+
[returned_obj.append(p) for p in [t for t in self.paths if t.id == obj_id]]
|
|
294
|
+
elif prim_type == "Rectangle":
|
|
295
|
+
[returned_obj.append(p) for p in [t for t in self.rectangles if t.id == obj_id]]
|
|
296
|
+
else:
|
|
297
|
+
for obj in _obj_instances:
|
|
298
|
+
obj_id = obj.GetLayoutObj().GetId()
|
|
299
|
+
[returned_obj.append(p) for p in [obj for obj in self.primitives if obj.id == obj_id]]
|
|
300
|
+
return returned_obj
|
|
301
|
+
|
|
243
302
|
@pyedb_function_handler()
|
|
244
303
|
def get_polygon_bounding_box(self, polygon):
|
|
245
304
|
"""Retrieve a polygon bounding box.
|