pyedb 0.39.1__py3-none-any.whl → 0.41.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/common/nets.py +11 -2
- pyedb/configuration/cfg_components.py +2 -0
- pyedb/configuration/cfg_padstacks.py +1 -1
- pyedb/configuration/cfg_ports_sources.py +63 -11
- pyedb/configuration/cfg_stackup.py +22 -1
- pyedb/dotnet/database/cell/terminal/edge_terminal.py +55 -0
- pyedb/dotnet/database/components.py +14 -12
- pyedb/dotnet/database/edb_data/padstacks_data.py +80 -3
- pyedb/dotnet/database/edb_data/ports.py +0 -55
- pyedb/dotnet/database/materials.py +40 -11
- pyedb/dotnet/database/modeler.py +11 -4
- pyedb/dotnet/edb.py +18 -0
- pyedb/grpc/database/components.py +24 -72
- pyedb/grpc/database/definition/materials.py +16 -1
- pyedb/grpc/database/layout/layout.py +43 -4
- pyedb/grpc/database/layout_validation.py +164 -143
- pyedb/grpc/database/net/net.py +5 -8
- pyedb/grpc/database/padstacks.py +184 -31
- pyedb/grpc/database/primitive/padstack_instance.py +1 -1
- pyedb/grpc/database/source_excitations.py +83 -105
- pyedb/grpc/edb.py +59 -198
- {pyedb-0.39.1.dist-info → pyedb-0.41.0.dist-info}/METADATA +2 -1
- {pyedb-0.39.1.dist-info → pyedb-0.41.0.dist-info}/RECORD +26 -26
- {pyedb-0.39.1.dist-info → pyedb-0.41.0.dist-info}/LICENSE +0 -0
- {pyedb-0.39.1.dist-info → pyedb-0.41.0.dist-info}/WHEEL +0 -0
pyedb/dotnet/database/modeler.py
CHANGED
|
@@ -307,9 +307,13 @@ class Modeler(object):
|
|
|
307
307
|
_obj_instances = list(self._pedb.layout_instance.FindLayoutObjInstance(pt, None, nets).Items)
|
|
308
308
|
returned_obj = []
|
|
309
309
|
if layer:
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
310
|
+
selected_prim = [
|
|
311
|
+
obj.GetLayoutObj()
|
|
312
|
+
for obj in _obj_instances
|
|
313
|
+
if layer in [lay.GetName() for lay in list(obj.GetLayers())]
|
|
314
|
+
and "Terminal" not in str(obj.GetLayoutObj())
|
|
315
|
+
]
|
|
316
|
+
for prim in selected_prim:
|
|
313
317
|
obj_id = prim.GetId()
|
|
314
318
|
prim_type = str(prim.GetPrimitiveType())
|
|
315
319
|
if prim_type == "Polygon":
|
|
@@ -321,7 +325,10 @@ class Modeler(object):
|
|
|
321
325
|
else:
|
|
322
326
|
for obj in _obj_instances:
|
|
323
327
|
obj_id = obj.GetLayoutObj().GetId()
|
|
324
|
-
[
|
|
328
|
+
[
|
|
329
|
+
returned_obj.append(Primitive(p, self._pedb))
|
|
330
|
+
for p in [obj for obj in self.primitives if obj.id == obj_id]
|
|
331
|
+
]
|
|
325
332
|
return returned_obj
|
|
326
333
|
|
|
327
334
|
def get_polygon_bounding_box(self, polygon):
|
pyedb/dotnet/edb.py
CHANGED
|
@@ -46,6 +46,7 @@ from pyedb.dotnet.database.Variables import decompose_variable_value
|
|
|
46
46
|
from pyedb.dotnet.database.cell.layout import Layout
|
|
47
47
|
from pyedb.dotnet.database.cell.terminal.terminal import Terminal
|
|
48
48
|
from pyedb.dotnet.database.components import Components
|
|
49
|
+
import pyedb.dotnet.database.dotnet.database
|
|
49
50
|
from pyedb.dotnet.database.dotnet.database import Database
|
|
50
51
|
from pyedb.dotnet.database.edb_data.control_file import (
|
|
51
52
|
ControlFile,
|
|
@@ -761,6 +762,23 @@ class Edb(Database):
|
|
|
761
762
|
"""Active cell."""
|
|
762
763
|
return self._active_cell
|
|
763
764
|
|
|
765
|
+
@active_cell.setter
|
|
766
|
+
def active_cell(self, value):
|
|
767
|
+
if isinstance(value, str):
|
|
768
|
+
_cell = [cell for cell in self.circuit_cells if cell.GetName() == value]
|
|
769
|
+
if _cell:
|
|
770
|
+
self._active_cell = _cell[0]
|
|
771
|
+
self._init_objects()
|
|
772
|
+
self.logger.info(f"Cell {value} set as active")
|
|
773
|
+
else:
|
|
774
|
+
raise f"Design {value} not found in database."
|
|
775
|
+
elif isinstance(value, pyedb.dotnet.database.dotnet.database.CellClassDotNet):
|
|
776
|
+
self._active_cell = value
|
|
777
|
+
self._init_objects()
|
|
778
|
+
self.logger.info(f"Cell {value.GetName()} set as active")
|
|
779
|
+
else:
|
|
780
|
+
raise "No valid design."
|
|
781
|
+
|
|
764
782
|
@property
|
|
765
783
|
def core_components(self): # pragma: no cover
|
|
766
784
|
"""Edb Components methods and properties.
|
|
@@ -54,6 +54,7 @@ from pyedb.grpc.database.definition.component_pin import ComponentPin
|
|
|
54
54
|
from pyedb.grpc.database.hierarchy.component import Component
|
|
55
55
|
from pyedb.grpc.database.hierarchy.pin_pair_model import PinPairModel
|
|
56
56
|
from pyedb.grpc.database.hierarchy.pingroup import PinGroup
|
|
57
|
+
from pyedb.grpc.database.padstacks import Padstacks
|
|
57
58
|
from pyedb.grpc.database.utility.sources import SourceType
|
|
58
59
|
from pyedb.modeler.geometry_operators import GeometryOperators
|
|
59
60
|
|
|
@@ -119,17 +120,10 @@ class Components(object):
|
|
|
119
120
|
|
|
120
121
|
def __init__(self, p_edb):
|
|
121
122
|
self._pedb = p_edb
|
|
122
|
-
self.
|
|
123
|
-
self._res = {}
|
|
124
|
-
self._cap = {}
|
|
125
|
-
self._ind = {}
|
|
126
|
-
self._ios = {}
|
|
127
|
-
self._ics = {}
|
|
128
|
-
self._others = {}
|
|
123
|
+
self.refresh_components()
|
|
129
124
|
self._pins = {}
|
|
130
125
|
self._comps_by_part = {}
|
|
131
|
-
self.
|
|
132
|
-
# self._padstack = Padstacks(self._pedb)
|
|
126
|
+
self._padstack = Padstacks(self._pedb)
|
|
133
127
|
# self._excitations = self._pedb.excitations
|
|
134
128
|
|
|
135
129
|
@property
|
|
@@ -137,16 +131,6 @@ class Components(object):
|
|
|
137
131
|
"""Logger."""
|
|
138
132
|
return self._pedb.logger
|
|
139
133
|
|
|
140
|
-
def _init_parts(self):
|
|
141
|
-
a = self.instances
|
|
142
|
-
a = self.resistors
|
|
143
|
-
a = self.ICs
|
|
144
|
-
a = self.Others
|
|
145
|
-
a = self.inductors
|
|
146
|
-
a = self.IOs
|
|
147
|
-
a = self.components_by_partname
|
|
148
|
-
return True
|
|
149
|
-
|
|
150
134
|
@property
|
|
151
135
|
def _active_layout(self):
|
|
152
136
|
return self._pedb.active_layout
|
|
@@ -180,8 +164,6 @@ class Components(object):
|
|
|
180
164
|
>>> edbapp.components.instances
|
|
181
165
|
|
|
182
166
|
"""
|
|
183
|
-
if not self._cmp:
|
|
184
|
-
self.refresh_components()
|
|
185
167
|
return self._cmp
|
|
186
168
|
|
|
187
169
|
@property
|
|
@@ -287,10 +269,28 @@ class Components(object):
|
|
|
287
269
|
"""Refresh the component dictionary."""
|
|
288
270
|
self._logger.info("Refreshing the Components dictionary.")
|
|
289
271
|
self._cmp = {}
|
|
272
|
+
self._res = {}
|
|
273
|
+
self._ind = {}
|
|
274
|
+
self._cap = {}
|
|
275
|
+
self._ics = {}
|
|
276
|
+
self._ios = {}
|
|
277
|
+
self._others = {}
|
|
290
278
|
for i in self._pedb.layout.groups:
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
279
|
+
self._cmp[i.name] = i
|
|
280
|
+
if i.type == "resistor":
|
|
281
|
+
self._res[i.name] = i
|
|
282
|
+
elif i.type == "capacitor":
|
|
283
|
+
self._cap[i.name] = i
|
|
284
|
+
elif i.type == "inductor":
|
|
285
|
+
self._ind[i.name] = i
|
|
286
|
+
elif i.type == "ic":
|
|
287
|
+
self._ics[i.name] = i
|
|
288
|
+
elif i.type == "io":
|
|
289
|
+
self._ios[i.name] = i
|
|
290
|
+
elif i.type == "other":
|
|
291
|
+
self._others[i.name] = i
|
|
292
|
+
else:
|
|
293
|
+
self._logger.warning(f"Unknown component type {i.name} found while refreshing components, will ignore")
|
|
294
294
|
return True
|
|
295
295
|
|
|
296
296
|
@property
|
|
@@ -309,14 +309,6 @@ class Components(object):
|
|
|
309
309
|
>>> edbapp = Edb("myaedbfolder")
|
|
310
310
|
>>> edbapp.components.resistors
|
|
311
311
|
"""
|
|
312
|
-
self._res = {}
|
|
313
|
-
for el, val in self.instances.items():
|
|
314
|
-
if not val.is_null:
|
|
315
|
-
try:
|
|
316
|
-
if val.type == "resistor":
|
|
317
|
-
self._res[el] = val
|
|
318
|
-
except:
|
|
319
|
-
pass
|
|
320
312
|
return self._res
|
|
321
313
|
|
|
322
314
|
@property
|
|
@@ -335,14 +327,6 @@ class Components(object):
|
|
|
335
327
|
>>> edbapp = Edb("myaedbfolder")
|
|
336
328
|
>>> edbapp.components.capacitors
|
|
337
329
|
"""
|
|
338
|
-
self._cap = {}
|
|
339
|
-
for el, val in self.instances.items():
|
|
340
|
-
if not val.is_null:
|
|
341
|
-
try:
|
|
342
|
-
if val.type == "capacitor":
|
|
343
|
-
self._cap[el] = val
|
|
344
|
-
except:
|
|
345
|
-
pass
|
|
346
330
|
return self._cap
|
|
347
331
|
|
|
348
332
|
@property
|
|
@@ -362,14 +346,6 @@ class Components(object):
|
|
|
362
346
|
>>> edbapp.components.inductors
|
|
363
347
|
|
|
364
348
|
"""
|
|
365
|
-
self._ind = {}
|
|
366
|
-
for el, val in self.instances.items():
|
|
367
|
-
if not val.is_null:
|
|
368
|
-
try:
|
|
369
|
-
if val.type == "inductor":
|
|
370
|
-
self._ind[el] = val
|
|
371
|
-
except:
|
|
372
|
-
pass
|
|
373
349
|
return self._ind
|
|
374
350
|
|
|
375
351
|
@property
|
|
@@ -389,14 +365,6 @@ class Components(object):
|
|
|
389
365
|
>>> edbapp.components.ICs
|
|
390
366
|
|
|
391
367
|
"""
|
|
392
|
-
self._ics = {}
|
|
393
|
-
for el, val in self.instances.items():
|
|
394
|
-
if not val.is_null:
|
|
395
|
-
try:
|
|
396
|
-
if val.type == "ic":
|
|
397
|
-
self._ics[el] = val
|
|
398
|
-
except:
|
|
399
|
-
pass
|
|
400
368
|
return self._ics
|
|
401
369
|
|
|
402
370
|
@property
|
|
@@ -416,14 +384,6 @@ class Components(object):
|
|
|
416
384
|
>>> edbapp.components.IOs
|
|
417
385
|
|
|
418
386
|
"""
|
|
419
|
-
self._ios = {}
|
|
420
|
-
for el, val in self.instances.items():
|
|
421
|
-
if not val.is_null:
|
|
422
|
-
try:
|
|
423
|
-
if val.type == "io":
|
|
424
|
-
self._ios[el] = val
|
|
425
|
-
except:
|
|
426
|
-
pass
|
|
427
387
|
return self._ios
|
|
428
388
|
|
|
429
389
|
@property
|
|
@@ -443,14 +403,6 @@ class Components(object):
|
|
|
443
403
|
>>> edbapp.components.others
|
|
444
404
|
|
|
445
405
|
"""
|
|
446
|
-
self._others = {}
|
|
447
|
-
for el, val in self.instances.items():
|
|
448
|
-
if not val.is_null:
|
|
449
|
-
try:
|
|
450
|
-
if val.type == "other":
|
|
451
|
-
self._others[el] = val
|
|
452
|
-
except:
|
|
453
|
-
pass
|
|
454
406
|
return self._others
|
|
455
407
|
|
|
456
408
|
@property
|
|
@@ -26,7 +26,7 @@ import difflib
|
|
|
26
26
|
import logging
|
|
27
27
|
import os
|
|
28
28
|
import re
|
|
29
|
-
from typing import Optional
|
|
29
|
+
from typing import Optional, Union
|
|
30
30
|
import warnings
|
|
31
31
|
|
|
32
32
|
from ansys.edb.core.definition.debye_model import DebyeModel as GrpcDebyeModel
|
|
@@ -1205,3 +1205,18 @@ class Materials(object):
|
|
|
1205
1205
|
|
|
1206
1206
|
self.__edb.logger.error(f"Material {material_name} does not exist in syslib AMAT file.")
|
|
1207
1207
|
return res
|
|
1208
|
+
|
|
1209
|
+
def update_materials_from_sys_library(self, update_all: bool = True, material_name: Union[str, list] = None):
|
|
1210
|
+
"""Update material properties from syslib AMAT file."""
|
|
1211
|
+
amat_file = os.path.join(self.__edb.base_path, "syslib", "Materials.amat")
|
|
1212
|
+
materials_dict = self.read_materials(amat_file)
|
|
1213
|
+
if update_all:
|
|
1214
|
+
for name, obj in self.materials.items():
|
|
1215
|
+
if name in materials_dict:
|
|
1216
|
+
obj.update(materials_dict[name])
|
|
1217
|
+
self.__edb.logger.info(f"Material {name} is updated from syslibrary.")
|
|
1218
|
+
else:
|
|
1219
|
+
material_names = material_name if isinstance(material_name, list) else [material_name]
|
|
1220
|
+
for name in material_names:
|
|
1221
|
+
self.materials[name].update(materials_dict[name])
|
|
1222
|
+
self.__edb.logger.info(f"Material {name} is updated from syslibrary.")
|
|
@@ -26,6 +26,7 @@ This module contains these classes: `EdbLayout` and `Shape`.
|
|
|
26
26
|
from typing import Union
|
|
27
27
|
|
|
28
28
|
from ansys.edb.core.layout.layout import Layout as GrpcLayout
|
|
29
|
+
import ansys.edb.core.primitive.primitive
|
|
29
30
|
|
|
30
31
|
from pyedb.grpc.database.hierarchy.component import Component
|
|
31
32
|
from pyedb.grpc.database.hierarchy.pingroup import PinGroup
|
|
@@ -34,7 +35,12 @@ from pyedb.grpc.database.net.differential_pair import DifferentialPair
|
|
|
34
35
|
from pyedb.grpc.database.net.extended_net import ExtendedNet
|
|
35
36
|
from pyedb.grpc.database.net.net import Net
|
|
36
37
|
from pyedb.grpc.database.net.net_class import NetClass
|
|
38
|
+
from pyedb.grpc.database.primitive.bondwire import Bondwire
|
|
39
|
+
from pyedb.grpc.database.primitive.circle import Circle
|
|
37
40
|
from pyedb.grpc.database.primitive.padstack_instance import PadstackInstance
|
|
41
|
+
from pyedb.grpc.database.primitive.path import Path
|
|
42
|
+
from pyedb.grpc.database.primitive.polygon import Polygon
|
|
43
|
+
from pyedb.grpc.database.primitive.rectangle import Rectangle
|
|
38
44
|
from pyedb.grpc.database.terminal.bundle_terminal import BundleTerminal
|
|
39
45
|
from pyedb.grpc.database.terminal.edge_terminal import EdgeTerminal
|
|
40
46
|
from pyedb.grpc.database.terminal.padstack_instance_terminal import (
|
|
@@ -59,6 +65,24 @@ class Layout(GrpcLayout):
|
|
|
59
65
|
"""
|
|
60
66
|
return self._pedb._active_cell
|
|
61
67
|
|
|
68
|
+
@property
|
|
69
|
+
def primitives(self):
|
|
70
|
+
prims = []
|
|
71
|
+
for prim in super().primitives:
|
|
72
|
+
if isinstance(prim, ansys.edb.core.primitive.primitive.Path):
|
|
73
|
+
prims.append(Path(self._pedb, prim))
|
|
74
|
+
elif isinstance(prim, ansys.edb.core.primitive.primitive.Polygon):
|
|
75
|
+
prims.append(Polygon(self._pedb, prim))
|
|
76
|
+
elif isinstance(prim, ansys.edb.core.primitive.primitive.PadstackInstance):
|
|
77
|
+
prims.append(PadstackInstance(self._pedb, prim))
|
|
78
|
+
elif isinstance(prim, ansys.edb.core.primitive.primitive.Rectangle):
|
|
79
|
+
prims.append(Rectangle(self._pedb, prim))
|
|
80
|
+
elif isinstance(prim, ansys.edb.core.primitive.primitive.Circle):
|
|
81
|
+
prims.append(Circle(self._pedb, prim))
|
|
82
|
+
elif isinstance(prim, ansys.edb.core.primitive.primitive.Bondwire):
|
|
83
|
+
prims.append(Bondwire(self._pedb, prim))
|
|
84
|
+
return prims
|
|
85
|
+
|
|
62
86
|
@property
|
|
63
87
|
def terminals(self):
|
|
64
88
|
"""Get terminals belonging to active layout.
|
|
@@ -180,17 +204,32 @@ class Layout(GrpcLayout):
|
|
|
180
204
|
"""
|
|
181
205
|
return [VoltageRegulator(self._pedb, i) for i in self._pedb.active_cell.layout.voltage_regulators]
|
|
182
206
|
|
|
183
|
-
def find_primitive(
|
|
207
|
+
def find_primitive(
|
|
208
|
+
self, layer_name: Union[str, list] = None, name: Union[str, list] = None, net_name: Union[str, list] = None
|
|
209
|
+
) -> list:
|
|
184
210
|
"""Find a primitive objects by layer name.
|
|
185
|
-
|
|
186
211
|
Parameters
|
|
187
212
|
----------
|
|
188
213
|
layer_name : str, list
|
|
214
|
+
layer_name : str, list, optional
|
|
189
215
|
Name of the layer.
|
|
216
|
+
name : str, list, optional
|
|
217
|
+
Name of the primitive
|
|
218
|
+
net_name : str, list, optional
|
|
219
|
+
Name of the primitive
|
|
190
220
|
Returns
|
|
191
221
|
-------
|
|
192
222
|
List[:class:`Primitive <pyedb.grpc.database.primitive.primitive.Primitive`].
|
|
193
223
|
List of Primitive.
|
|
194
224
|
"""
|
|
195
|
-
|
|
196
|
-
|
|
225
|
+
if layer_name:
|
|
226
|
+
layer_name = layer_name if isinstance(layer_name, list) else [layer_name]
|
|
227
|
+
if name:
|
|
228
|
+
name = name if isinstance(name, list) else [name]
|
|
229
|
+
if net_name:
|
|
230
|
+
net_name = net_name if isinstance(net_name, list) else [net_name]
|
|
231
|
+
prims = self.primitives
|
|
232
|
+
prims = [i for i in prims if i.aedt_name in name] if name is not None else prims
|
|
233
|
+
prims = [i for i in prims if i.layer_name in layer_name] if layer_name is not None else prims
|
|
234
|
+
prims = [i for i in prims if i.net_name in net_name] if net_name is not None else prims
|
|
235
|
+
return prims
|