pyedb 0.50.0__py3-none-any.whl → 0.51.2__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_ports_sources.py +79 -239
- pyedb/configuration/configuration.py +27 -0
- pyedb/dotnet/clr_module.py +9 -3
- pyedb/dotnet/database/cell/hierarchy/component.py +3 -3
- pyedb/dotnet/database/cell/layout.py +10 -1
- pyedb/dotnet/database/dotnet/database.py +0 -2
- pyedb/dotnet/database/edb_data/padstacks_data.py +13 -0
- pyedb/dotnet/database/layout_validation.py +17 -13
- pyedb/dotnet/database/modeler.py +0 -1
- pyedb/dotnet/edb.py +7 -1
- pyedb/generic/design_types.py +183 -62
- pyedb/grpc/database/components.py +604 -652
- pyedb/grpc/database/control_file.py +597 -155
- pyedb/grpc/database/definition/component_def.py +17 -14
- pyedb/grpc/database/definition/materials.py +27 -27
- pyedb/grpc/database/definition/package_def.py +8 -8
- pyedb/grpc/database/definition/padstack_def.py +31 -33
- pyedb/grpc/database/definitions.py +36 -2
- pyedb/grpc/database/geometry/arc_data.py +5 -5
- pyedb/grpc/database/geometry/point_3d_data.py +3 -3
- pyedb/grpc/database/geometry/polygon_data.py +5 -5
- pyedb/grpc/database/hfss.py +412 -395
- pyedb/grpc/database/hierarchy/component.py +67 -58
- pyedb/grpc/database/hierarchy/pin_pair_model.py +6 -6
- pyedb/grpc/database/hierarchy/pingroup.py +13 -11
- pyedb/grpc/database/hierarchy/s_parameter_model.py +1 -1
- pyedb/grpc/database/hierarchy/spice_model.py +1 -1
- pyedb/grpc/database/layers/layer.py +2 -2
- pyedb/grpc/database/layers/stackup_layer.py +26 -23
- pyedb/grpc/database/layout/layout.py +12 -12
- pyedb/grpc/database/layout/voltage_regulator.py +8 -8
- pyedb/grpc/database/layout_validation.py +58 -7
- pyedb/grpc/database/modeler.py +248 -245
- pyedb/grpc/database/net/differential_pair.py +4 -4
- pyedb/grpc/database/net/extended_net.py +7 -8
- pyedb/grpc/database/net/net.py +57 -46
- pyedb/grpc/database/nets.py +362 -116
- pyedb/grpc/database/padstacks.py +259 -178
- pyedb/grpc/database/ports/ports.py +23 -17
- pyedb/grpc/database/primitive/padstack_instance.py +45 -30
- pyedb/grpc/database/primitive/path.py +6 -6
- pyedb/grpc/database/primitive/polygon.py +9 -9
- pyedb/grpc/database/primitive/primitive.py +21 -21
- pyedb/grpc/database/primitive/rectangle.py +1 -1
- pyedb/grpc/database/simulation_setup/hfss_advanced_settings.py +1 -1
- pyedb/grpc/database/simulation_setup/hfss_general_settings.py +1 -1
- pyedb/grpc/database/simulation_setup/hfss_settings_options.py +1 -1
- pyedb/grpc/database/simulation_setup/hfss_simulation_settings.py +6 -6
- pyedb/grpc/database/simulation_setup/hfss_simulation_setup.py +2 -2
- pyedb/grpc/database/simulation_setup/raptor_x_simulation_settings.py +2 -2
- pyedb/grpc/database/simulation_setup/raptor_x_simulation_setup.py +1 -1
- pyedb/grpc/database/simulation_setup/siwave_simulation_setup.py +3 -3
- pyedb/grpc/database/siwave.py +226 -214
- pyedb/grpc/database/source_excitations.py +307 -40
- pyedb/grpc/database/stackup.py +461 -283
- pyedb/grpc/database/terminal/bundle_terminal.py +12 -12
- pyedb/grpc/database/terminal/edge_terminal.py +6 -5
- pyedb/grpc/database/terminal/padstack_instance_terminal.py +13 -13
- pyedb/grpc/database/terminal/pingroup_terminal.py +12 -12
- pyedb/grpc/database/terminal/point_terminal.py +6 -6
- pyedb/grpc/database/terminal/terminal.py +26 -26
- pyedb/grpc/database/utility/heat_sink.py +5 -5
- pyedb/grpc/database/utility/hfss_extent_info.py +21 -21
- pyedb/grpc/database/utility/layout_statistics.py +13 -13
- pyedb/grpc/database/utility/rlc.py +3 -3
- pyedb/grpc/database/utility/sources.py +1 -1
- pyedb/grpc/database/utility/sweep_data_distribution.py +1 -1
- pyedb/grpc/edb.py +542 -739
- pyedb/grpc/edb_init.py +50 -3
- {pyedb-0.50.0.dist-info → pyedb-0.51.2.dist-info}/METADATA +1 -1
- {pyedb-0.50.0.dist-info → pyedb-0.51.2.dist-info}/RECORD +74 -75
- pyedb/grpc/database/utility/simulation_configuration.py +0 -3305
- {pyedb-0.50.0.dist-info → pyedb-0.51.2.dist-info}/LICENSE +0 -0
- {pyedb-0.50.0.dist-info → pyedb-0.51.2.dist-info}/WHEEL +0 -0
pyedb/grpc/edb.py
CHANGED
|
@@ -20,10 +20,40 @@
|
|
|
20
20
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
21
|
# SOFTWARE.
|
|
22
22
|
|
|
23
|
-
"""
|
|
24
|
-
|
|
25
|
-
This module
|
|
26
|
-
|
|
23
|
+
"""Provides the main interface for interacting with Ansys Electronics Desktop Database (EDB).
|
|
24
|
+
|
|
25
|
+
This module contains the ``Edb`` class which serves as the primary interface for:
|
|
26
|
+
- Creating and managing EDB projects
|
|
27
|
+
- Importing/exporting layout files
|
|
28
|
+
- Configuring stackups, materials, and components
|
|
29
|
+
- Setting up simulations (HFSS, SIwave, RaptorX)
|
|
30
|
+
- Performing cutout operations
|
|
31
|
+
- Generating ports and excitations
|
|
32
|
+
- Parametrizing designs
|
|
33
|
+
- Exporting to various formats (IPC2581, HFSS, Q3D)
|
|
34
|
+
|
|
35
|
+
Key Functionality:
|
|
36
|
+
- Database initialization and management
|
|
37
|
+
- Layout manipulation and cutout generation
|
|
38
|
+
- Material and stackup configuration
|
|
39
|
+
- Net and component management
|
|
40
|
+
- Simulation setup and execution
|
|
41
|
+
- Design parametrization and optimization
|
|
42
|
+
|
|
43
|
+
Examples
|
|
44
|
+
--------
|
|
45
|
+
Basic EDB initialization:
|
|
46
|
+
>>> from pyedb.grpc.edb import Edb
|
|
47
|
+
>>> edb = Edb(edbpath="myproject.aedb")
|
|
48
|
+
|
|
49
|
+
Importing a board file:
|
|
50
|
+
>>> edb.import_layout_file("my_board.brd")
|
|
51
|
+
|
|
52
|
+
Creating a cutout:
|
|
53
|
+
>>> edb.cutout(signal_list=["Net1", "Net2"], reference_list=["GND"])
|
|
54
|
+
|
|
55
|
+
Exporting to HFSS:
|
|
56
|
+
>>> edb.export_hfss(r"C:\output_folder")
|
|
27
57
|
"""
|
|
28
58
|
|
|
29
59
|
from itertools import combinations
|
|
@@ -102,100 +132,60 @@ from pyedb.workflow import Workflow
|
|
|
102
132
|
|
|
103
133
|
|
|
104
134
|
class Edb(EdbInit):
|
|
105
|
-
"""
|
|
135
|
+
"""Main class for interacting with Ansys Electronics Desktop Database (EDB).
|
|
106
136
|
|
|
107
|
-
|
|
137
|
+
Provides comprehensive control over EDB projects including:
|
|
138
|
+
- Project creation/management
|
|
139
|
+
- Layout import/export
|
|
140
|
+
- Material/stackup configuration
|
|
141
|
+
- Component/net management
|
|
142
|
+
- Simulation setup
|
|
143
|
+
- Cutout operations
|
|
144
|
+
- Parameterization
|
|
108
145
|
|
|
109
146
|
Parameters
|
|
110
147
|
----------
|
|
111
|
-
edbpath : str, optional
|
|
112
|
-
Full path to
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
For GDS import, the Ansys control file (also XML) should have the same
|
|
116
|
-
name as the GDS file. Only the file extension differs.
|
|
148
|
+
edbpath : str or Path, optional
|
|
149
|
+
Full path to AEDB folder or layout file to import. Supported formats:
|
|
150
|
+
BRD, MCM, XML (IPC2581), GDS, ODB++ (TGZ/ZIP), DXF.
|
|
151
|
+
Default creates new AEDB in documents folder.
|
|
117
152
|
cellname : str, optional
|
|
118
|
-
|
|
153
|
+
Specific cell to open. Default opens first cell.
|
|
119
154
|
isreadonly : bool, optional
|
|
120
|
-
|
|
121
|
-
owned by HFSS 3D Layout. The default is ``False``.
|
|
155
|
+
Open in read-only mode. Default False.
|
|
122
156
|
edbversion : str, int, float, optional
|
|
123
|
-
|
|
124
|
-
Examples of input values are ``232``, ``23.2``, ``2023.2``, ``"2023.2"``.
|
|
157
|
+
EDB version (e.g., "2023.2", 232, 23.2). Default uses latest.
|
|
125
158
|
isaedtowned : bool, optional
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
Reference to the AEDT project object.
|
|
159
|
+
Launch from HFSS 3D Layout. Default False.
|
|
160
|
+
oproject : object, optional
|
|
161
|
+
Reference to AEDT project object.
|
|
130
162
|
student_version : bool, optional
|
|
131
|
-
|
|
163
|
+
Use student version. Default False.
|
|
164
|
+
use_ppe : bool, optional
|
|
165
|
+
Use PPE license. Default False.
|
|
132
166
|
control_file : str, optional
|
|
133
|
-
|
|
134
|
-
the XML file in the same directory as the board file. To succeed, the XML file and board file
|
|
135
|
-
must have the same name. Only the extension differs.
|
|
167
|
+
XML control file path for import.
|
|
136
168
|
map_file : str, optional
|
|
137
|
-
Layer map
|
|
169
|
+
Layer map file for import.
|
|
138
170
|
technology_file : str, optional
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
171
|
+
Technology file for import (GDS only).
|
|
172
|
+
layer_filter : str, optional
|
|
173
|
+
Layer filter file for import.
|
|
174
|
+
remove_existing_aedt : bool, optional
|
|
175
|
+
Remove existing AEDT project files. Default False.
|
|
143
176
|
restart_rpc_server : bool, optional
|
|
144
|
-
|
|
145
|
-
instance loading all EDB, enabling this option should be used with caution but can be a solution to release
|
|
146
|
-
memory in case the server is draining resources. Default value is ``False``.
|
|
177
|
+
Restart gRPC server. Use with caution. Default False.
|
|
147
178
|
|
|
148
179
|
Examples
|
|
149
180
|
--------
|
|
150
|
-
Create :
|
|
151
|
-
|
|
152
|
-
>>> from pyedb.grpc.edb import Edb as Edb
|
|
153
|
-
>>> app = Edb()
|
|
154
|
-
|
|
155
|
-
Add a new variable named "s1" to the ``Edb`` instance.
|
|
156
|
-
|
|
157
|
-
>>> app['s1'] = "0.25 mm"
|
|
158
|
-
>>> app['s1']
|
|
159
|
-
>>> 0.00025
|
|
160
|
-
|
|
161
|
-
Create an ``Edb`` object and open the specified project.
|
|
162
|
-
|
|
163
|
-
>>> app = Edb(edbpath="myfile.aedb")
|
|
164
|
-
|
|
165
|
-
Create an ``Edb`` object from GDS and control files.
|
|
166
|
-
The XML control file resides in the same directory as the GDS file: (myfile.xml).
|
|
167
|
-
|
|
168
|
-
>>> app = Edb("/path/to/file/myfile.gds")
|
|
169
|
-
|
|
170
|
-
Loading Ansys layout
|
|
171
|
-
|
|
172
|
-
>>> from ansys.aedt.core.generic.general_methods import generate_unique_folder_name
|
|
173
|
-
>>> import pyedb.misc.downloads as downloads
|
|
174
|
-
>>> temp_folder = generate_unique_folder_name()
|
|
175
|
-
>>> targetfile = downloads.download_file("edb/ANSYS-HSD_V1.aedb", destination=temp_folder)
|
|
176
|
-
>>> from pyedb.grpc.edb import Edb as Edb
|
|
177
|
-
>>> edbapp = Edb(edbpath=targetfile)
|
|
178
|
-
|
|
179
|
-
Retrieving signal nets dictionary
|
|
180
|
-
|
|
181
|
-
>>> edbapp.nets.signal
|
|
182
|
-
|
|
183
|
-
Retrieving layers
|
|
184
|
-
|
|
185
|
-
>>> edbapp.stackup.layers
|
|
181
|
+
Create new EDB:
|
|
182
|
+
>>> edb = Edb()
|
|
186
183
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
>>> edbapp.components.instances
|
|
190
|
-
|
|
191
|
-
Retrieving all padstacks definitions
|
|
192
|
-
|
|
193
|
-
>>> edbapp.padstacks.definitions
|
|
194
|
-
|
|
195
|
-
Retrieving component pins
|
|
196
|
-
|
|
197
|
-
>>> edbapp.components["U1"].pins
|
|
184
|
+
Open existing AEDB:
|
|
185
|
+
>>> edb = Edb("myproject.aedb")
|
|
198
186
|
|
|
187
|
+
Import board file:
|
|
188
|
+
>>> edb = Edb("my_board.brd")
|
|
199
189
|
"""
|
|
200
190
|
|
|
201
191
|
def __init__(
|
|
@@ -309,38 +299,39 @@ class Edb(EdbInit):
|
|
|
309
299
|
self._layout_instance = None
|
|
310
300
|
|
|
311
301
|
def __enter__(self):
|
|
302
|
+
"""Context manager entry."""
|
|
312
303
|
return self
|
|
313
304
|
|
|
314
305
|
def __exit__(self, ex_type, ex_value, ex_traceback):
|
|
306
|
+
"""Context manager exit. Closes EDB and cleans up resources."""
|
|
315
307
|
self._signal_handler(ex_type, ex_value)
|
|
316
308
|
|
|
317
309
|
def __getitem__(self, variable_name):
|
|
318
|
-
"""Get
|
|
319
|
-
it can be a design variable, in which case the ``$`` is omitted.
|
|
310
|
+
"""Get project or design variable value.
|
|
320
311
|
|
|
321
312
|
Parameters
|
|
322
313
|
----------
|
|
323
314
|
variable_name : str
|
|
315
|
+
Variable name with '$' for project variables.
|
|
324
316
|
|
|
325
317
|
Returns
|
|
326
318
|
-------
|
|
327
|
-
|
|
328
|
-
|
|
319
|
+
float or None
|
|
320
|
+
Variable value if exists, else None.
|
|
329
321
|
"""
|
|
330
322
|
if self.variable_exists(variable_name):
|
|
331
323
|
return self.variables[variable_name]
|
|
332
324
|
return
|
|
333
325
|
|
|
334
326
|
def __setitem__(self, variable_name, variable_value):
|
|
335
|
-
"""Set
|
|
336
|
-
it can be a design variable, in which case the ``$`` is omitted.
|
|
327
|
+
"""Set project or design variable.
|
|
337
328
|
|
|
338
329
|
Parameters
|
|
339
330
|
----------
|
|
340
331
|
variable_name : str
|
|
341
|
-
|
|
342
|
-
variable_value : str, float, int
|
|
343
|
-
|
|
332
|
+
Variable name (with '$' prefix for project variables).
|
|
333
|
+
variable_value : str, float, int, list/tuple
|
|
334
|
+
Value with units. List/tuple format: [value, description]
|
|
344
335
|
"""
|
|
345
336
|
type_error_message = "Allowed values are str, numeric or two-item list with variable description."
|
|
346
337
|
if type(variable_value) in [
|
|
@@ -387,23 +378,6 @@ class Edb(EdbInit):
|
|
|
387
378
|
except:
|
|
388
379
|
self.logger.info(f"Failed to delete AEDT project-related file {file}.")
|
|
389
380
|
|
|
390
|
-
def _clean_variables(self):
|
|
391
|
-
"""Initialize internal variables and perform garbage collection."""
|
|
392
|
-
self.grpc = True
|
|
393
|
-
self._materials = None
|
|
394
|
-
self._components = None
|
|
395
|
-
self._core_primitives = None
|
|
396
|
-
self._stackup = None
|
|
397
|
-
self._padstack = None
|
|
398
|
-
self._siwave = None
|
|
399
|
-
self._hfss = None
|
|
400
|
-
self._nets = None
|
|
401
|
-
self._layout_instance = None
|
|
402
|
-
self._variables = None
|
|
403
|
-
self._active_cell = None
|
|
404
|
-
self._layout = None
|
|
405
|
-
self._configuration = None
|
|
406
|
-
|
|
407
381
|
def _init_objects(self):
|
|
408
382
|
self._components = Components(self)
|
|
409
383
|
self._stackup = Stackup(self, self.layout.layer_collection)
|
|
@@ -419,53 +393,56 @@ class Edb(EdbInit):
|
|
|
419
393
|
|
|
420
394
|
@property
|
|
421
395
|
def cell_names(self) -> [str]:
|
|
422
|
-
"""
|
|
396
|
+
"""List of all cell names in the database.
|
|
423
397
|
|
|
424
398
|
Returns
|
|
425
399
|
-------
|
|
426
|
-
list
|
|
400
|
+
list[str]
|
|
401
|
+
Names of all circuit cells.
|
|
427
402
|
"""
|
|
428
403
|
return [cell.name for cell in self.active_db.top_circuit_cells]
|
|
429
404
|
|
|
430
405
|
@property
|
|
431
406
|
def design_variables(self) -> dict[str, float]:
|
|
432
|
-
"""
|
|
407
|
+
"""All design variables in active cell.
|
|
433
408
|
|
|
434
409
|
Returns
|
|
435
410
|
-------
|
|
436
|
-
|
|
411
|
+
dict[str, float]
|
|
412
|
+
Variable names and values.
|
|
437
413
|
"""
|
|
438
414
|
return {i: self.active_cell.get_variable_value(i).value for i in self.active_cell.get_all_variable_names()}
|
|
439
415
|
|
|
440
416
|
@property
|
|
441
417
|
def project_variables(self) -> dict[str, float]:
|
|
442
|
-
"""
|
|
418
|
+
"""All project variables in database.
|
|
443
419
|
|
|
444
420
|
Returns
|
|
445
421
|
-------
|
|
446
|
-
|
|
447
|
-
|
|
422
|
+
dict[str, float]
|
|
423
|
+
Variable names and values.
|
|
448
424
|
"""
|
|
449
425
|
return {i: self.active_db.get_variable_value(i).value for i in self.active_db.get_all_variable_names()}
|
|
450
426
|
|
|
451
427
|
@property
|
|
452
428
|
def layout_validation(self) -> LayoutValidation:
|
|
453
|
-
"""
|
|
429
|
+
"""Layout validation utilities.
|
|
454
430
|
|
|
455
431
|
Returns
|
|
456
432
|
-------
|
|
457
433
|
:class:`LayoutValidation <pyedb.grpc.database.layout_validation.LayoutValidation>`
|
|
434
|
+
Tools for design rule checking and layout validation.
|
|
458
435
|
"""
|
|
459
436
|
return LayoutValidation(self)
|
|
460
437
|
|
|
461
438
|
@property
|
|
462
439
|
def variables(self) -> dict[str, float]:
|
|
463
|
-
"""
|
|
440
|
+
"""All variables (project + design) in database.
|
|
464
441
|
|
|
465
442
|
Returns
|
|
466
443
|
-------
|
|
467
|
-
|
|
468
|
-
|
|
444
|
+
dict[str, float]
|
|
445
|
+
Combined dictionary of all variables.
|
|
469
446
|
"""
|
|
470
447
|
all_vars = dict()
|
|
471
448
|
for i, j in self.project_variables.items():
|
|
@@ -476,23 +453,24 @@ class Edb(EdbInit):
|
|
|
476
453
|
|
|
477
454
|
@property
|
|
478
455
|
def terminals(self) -> dict[str, Terminal]:
|
|
479
|
-
"""
|
|
456
|
+
"""Terminals in active layout.
|
|
480
457
|
|
|
481
458
|
Returns
|
|
482
459
|
-------
|
|
483
|
-
|
|
460
|
+
dict[str, :class:`Terminal <pyedb.grpc.database.terminal.terminal.Terminal>`]
|
|
461
|
+
Terminal names and objects.
|
|
484
462
|
"""
|
|
485
463
|
return {i.name: i for i in self.layout.terminals}
|
|
486
464
|
|
|
487
465
|
@property
|
|
488
466
|
def excitations(self) -> dict[str, GapPort]:
|
|
489
|
-
"""
|
|
467
|
+
"""All layout excitations.
|
|
490
468
|
|
|
491
469
|
Returns
|
|
492
470
|
-------
|
|
493
|
-
|
|
471
|
+
dict[str, :class:`GapPort <pyedb.grpc.database.ports.ports.GapPort>`]
|
|
472
|
+
Excitation names and objects.
|
|
494
473
|
"""
|
|
495
|
-
|
|
496
474
|
terms = [term for term in self.layout.terminals if term.boundary_type == "port"]
|
|
497
475
|
temp = {}
|
|
498
476
|
for term in terms:
|
|
@@ -504,13 +482,12 @@ class Edb(EdbInit):
|
|
|
504
482
|
|
|
505
483
|
@property
|
|
506
484
|
def ports(self) -> dict[str, GapPort]:
|
|
507
|
-
"""
|
|
485
|
+
"""All ports in design.
|
|
508
486
|
|
|
509
487
|
Returns
|
|
510
488
|
-------
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
489
|
+
dict[str, Union[:class:`GapPort`, :class:`WavePort`, :class:`CoaxPort`]]
|
|
490
|
+
Port names and objects.
|
|
514
491
|
"""
|
|
515
492
|
terminals = [term for term in self.layout.terminals if not term.is_reference_terminal]
|
|
516
493
|
ports = {}
|
|
@@ -538,34 +515,34 @@ class Edb(EdbInit):
|
|
|
538
515
|
|
|
539
516
|
@property
|
|
540
517
|
def excitations_nets(self) -> [str]:
|
|
541
|
-
"""
|
|
518
|
+
"""Nets with excitations defined.
|
|
542
519
|
|
|
543
520
|
Returns
|
|
544
521
|
-------
|
|
545
|
-
|
|
546
|
-
|
|
522
|
+
list[str]
|
|
523
|
+
Net names with excitations.
|
|
547
524
|
"""
|
|
548
525
|
return list(set([i.net.name for i in self.layout.terminals if not i.is_reference_terminal]))
|
|
549
526
|
|
|
550
527
|
@property
|
|
551
528
|
def sources(self) -> dict[str, Terminal]:
|
|
552
|
-
"""
|
|
529
|
+
"""All layout sources.
|
|
553
530
|
|
|
554
531
|
Returns
|
|
555
532
|
-------
|
|
556
|
-
|
|
533
|
+
dict[str, :class:`Terminal <pyedb.grpc.database.terminal.terminal.Terminal>`]
|
|
534
|
+
Source names and objects.
|
|
557
535
|
"""
|
|
558
536
|
return self.terminals
|
|
559
537
|
|
|
560
538
|
@property
|
|
561
539
|
def voltage_regulator_modules(self):
|
|
562
|
-
"""
|
|
540
|
+
"""Voltage regulator modules in design.
|
|
563
541
|
|
|
564
542
|
Returns
|
|
565
543
|
-------
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
544
|
+
dict[str, :class:`VoltageRegulator <pyedb.grpc.database.layout.voltage_regulator.VoltageRegulator>`]
|
|
545
|
+
VRM names and objects.
|
|
569
546
|
"""
|
|
570
547
|
vrms = self.layout.voltage_regulators
|
|
571
548
|
_vrms = {}
|
|
@@ -575,28 +552,34 @@ class Edb(EdbInit):
|
|
|
575
552
|
|
|
576
553
|
@property
|
|
577
554
|
def probes(self) -> dict[str, Terminal]:
|
|
578
|
-
"""
|
|
555
|
+
"""All layout probes.
|
|
579
556
|
|
|
580
557
|
Returns
|
|
581
558
|
-------
|
|
582
|
-
|
|
583
|
-
|
|
559
|
+
dict[str, :class:`Terminal <pyedb.grpc.database.terminal.terminal.Terminal>`]
|
|
560
|
+
Probe names and objects.
|
|
584
561
|
"""
|
|
585
562
|
terms = [term for term in self.layout.terminals if term.boundary_type.value == 8]
|
|
586
563
|
return {ter.name: ter for ter in terms}
|
|
587
564
|
|
|
588
|
-
def
|
|
589
|
-
"""Open EDB.
|
|
565
|
+
def open(self, restart_rpc_server=False) -> bool:
|
|
566
|
+
"""Open EDB database.
|
|
590
567
|
|
|
591
568
|
Returns
|
|
592
569
|
-------
|
|
593
|
-
bool
|
|
570
|
+
bool
|
|
571
|
+
True if successful, False otherwise.
|
|
572
|
+
|
|
573
|
+
Examples
|
|
574
|
+
--------
|
|
575
|
+
Open an existing EDB database:
|
|
576
|
+
>>> edb = Edb("myproject.aedb")
|
|
594
577
|
"""
|
|
595
578
|
self.standalone = self.standalone
|
|
596
579
|
n_try = 10
|
|
597
580
|
while not self.db and n_try:
|
|
598
581
|
try:
|
|
599
|
-
self.
|
|
582
|
+
self._open(
|
|
600
583
|
self.edbpath,
|
|
601
584
|
self.isreadonly,
|
|
602
585
|
restart_rpc_server=restart_rpc_server,
|
|
@@ -626,12 +609,27 @@ class Edb(EdbInit):
|
|
|
626
609
|
self.logger.error("Builder was not initialized.")
|
|
627
610
|
return True
|
|
628
611
|
|
|
629
|
-
def
|
|
630
|
-
"""
|
|
612
|
+
def open_edb(self, restart_rpc_server=False) -> bool:
|
|
613
|
+
"""Open EDB database.
|
|
614
|
+
|
|
615
|
+
.. deprecated:: 0.50.1
|
|
616
|
+
Use :func:`open` instead.
|
|
631
617
|
|
|
632
618
|
Returns
|
|
633
619
|
-------
|
|
634
|
-
bool
|
|
620
|
+
bool
|
|
621
|
+
True if successful, False otherwise.
|
|
622
|
+
"""
|
|
623
|
+
warnings.warn("`open_edb` is deprecated use `open` instead.", DeprecationWarning)
|
|
624
|
+
return self.open(restart_rpc_server)
|
|
625
|
+
|
|
626
|
+
def create(self, restart_rpc_server=False) -> any:
|
|
627
|
+
"""Create new EDB database.
|
|
628
|
+
|
|
629
|
+
Returns
|
|
630
|
+
-------
|
|
631
|
+
bool
|
|
632
|
+
True if successful, False otherwise.
|
|
635
633
|
"""
|
|
636
634
|
from ansys.edb.core.layout.cell import Cell as GrpcCell
|
|
637
635
|
from ansys.edb.core.layout.cell import CellType as GrpcCellType
|
|
@@ -640,7 +638,7 @@ class Edb(EdbInit):
|
|
|
640
638
|
n_try = 10
|
|
641
639
|
while not self.db and n_try:
|
|
642
640
|
try:
|
|
643
|
-
self.
|
|
641
|
+
self._create(self.edbpath, restart_rpc_server=restart_rpc_server)
|
|
644
642
|
n_try -= 1
|
|
645
643
|
except Exception as e:
|
|
646
644
|
self.logger.error(e.args[0])
|
|
@@ -655,9 +653,22 @@ class Edb(EdbInit):
|
|
|
655
653
|
)
|
|
656
654
|
if self._active_cell:
|
|
657
655
|
self._init_objects()
|
|
658
|
-
return
|
|
656
|
+
return self
|
|
659
657
|
return None
|
|
660
658
|
|
|
659
|
+
def create_edb(self, restart_rpc_server=False) -> bool:
|
|
660
|
+
"""
|
|
661
|
+
.. deprecated:: 0.50.1
|
|
662
|
+
Use :func:`create` instead.
|
|
663
|
+
|
|
664
|
+
Returns
|
|
665
|
+
-------
|
|
666
|
+
bool
|
|
667
|
+
True if successful, False otherwise.
|
|
668
|
+
"""
|
|
669
|
+
warnings.warn("`create_edb` is deprecated use `create` instead.", DeprecationWarning)
|
|
670
|
+
return self.create(restart_rpc_server)
|
|
671
|
+
|
|
661
672
|
def import_layout_pcb(
|
|
662
673
|
self,
|
|
663
674
|
input_file,
|
|
@@ -669,38 +680,33 @@ class Edb(EdbInit):
|
|
|
669
680
|
tech_file=None,
|
|
670
681
|
layer_filter=None,
|
|
671
682
|
):
|
|
672
|
-
"""Import
|
|
673
|
-
|
|
674
|
-
.. deprecated:: 0.42.0
|
|
675
|
-
Use :func:`import_layout_file` method instead.
|
|
683
|
+
"""Import layout file and generate AEDB.
|
|
676
684
|
|
|
677
|
-
|
|
685
|
+
Supported formats: BRD, MCM, XML (IPC2581), GDS, ODB++ (TGZ/ZIP), DXF
|
|
678
686
|
|
|
679
687
|
Parameters
|
|
680
688
|
----------
|
|
681
689
|
input_file : str
|
|
682
|
-
Full path to
|
|
690
|
+
Full path to input file.
|
|
683
691
|
working_dir : str, optional
|
|
684
|
-
|
|
685
|
-
is the same as the name of the board file.
|
|
692
|
+
Output directory for AEDB.
|
|
686
693
|
anstranslator_full_path : str, optional
|
|
687
|
-
|
|
688
|
-
use_ppe : bool
|
|
689
|
-
|
|
694
|
+
Path to Ansys translator executable.
|
|
695
|
+
use_ppe : bool, optional
|
|
696
|
+
Use PPE license. Default False.
|
|
690
697
|
control_file : str, optional
|
|
691
|
-
|
|
692
|
-
the XML file in the same directory as the board file. To succeed, the XML file and board file
|
|
693
|
-
must have the same name. Only the extension differs.
|
|
698
|
+
XML control file path.
|
|
694
699
|
tech_file : str, optional
|
|
695
|
-
Technology file
|
|
700
|
+
Technology file path.
|
|
696
701
|
map_file : str, optional
|
|
697
|
-
Layer map
|
|
698
|
-
layer_filter:str,optional
|
|
699
|
-
Layer filter
|
|
702
|
+
Layer map file path.
|
|
703
|
+
layer_filter : str, optional
|
|
704
|
+
Layer filter file path.
|
|
700
705
|
|
|
701
706
|
Returns
|
|
702
707
|
-------
|
|
703
|
-
|
|
708
|
+
str or bool
|
|
709
|
+
AEDB path if successful, False otherwise.
|
|
704
710
|
"""
|
|
705
711
|
self.logger.warning("import_layout_pcb method is deprecated, use import_layout_file instead.")
|
|
706
712
|
return self.import_layout_file(
|
|
@@ -755,6 +761,13 @@ class Edb(EdbInit):
|
|
|
755
761
|
-------
|
|
756
762
|
Full path to the AEDB file : str
|
|
757
763
|
|
|
764
|
+
Examples
|
|
765
|
+
--------
|
|
766
|
+
Import a BRD file:
|
|
767
|
+
>>> edb.import_layout_file("my_board.brd", r"C:/project")
|
|
768
|
+
|
|
769
|
+
Import a GDS file with control file:
|
|
770
|
+
>>> edb.import_layout_file("layout.gds", control_file="control.xml")
|
|
758
771
|
"""
|
|
759
772
|
self._components = None
|
|
760
773
|
self._core_primitives = None
|
|
@@ -802,29 +815,24 @@ class Edb(EdbInit):
|
|
|
802
815
|
return self.open_edb()
|
|
803
816
|
|
|
804
817
|
def export_to_ipc2581(self, ipc_path=None, units="MILLIMETER") -> str:
|
|
805
|
-
"""
|
|
806
|
-
|
|
807
|
-
.. note::
|
|
808
|
-
The method works only in CPython because of some limitations on Ironpython in XML parsing and
|
|
809
|
-
because it's time-consuming.
|
|
810
|
-
This method is still being tested and may need further debugging.
|
|
811
|
-
Any feedback is welcome. Back drills and custom pads are not supported yet.
|
|
818
|
+
"""Export design to IPC2581 format.
|
|
812
819
|
|
|
813
820
|
Parameters
|
|
814
821
|
----------
|
|
815
822
|
ipc_path : str, optional
|
|
816
|
-
|
|
817
|
-
an attempt is made to find the XML IPC2581 file in the same directory
|
|
818
|
-
as the active EDB. To succeed, the XML IPC2581 file and the active
|
|
819
|
-
EDT must have the same name. Only the extension differs.
|
|
823
|
+
Output XML file path. Default: <edb_path>.xml.
|
|
820
824
|
units : str, optional
|
|
821
|
-
|
|
822
|
-
``"inch"``, and ``"micron"``. The default is ``"millimeter"``.
|
|
825
|
+
Output units ("millimeter", "inch", "micron"). Default millimeter.
|
|
823
826
|
|
|
824
827
|
Returns
|
|
825
828
|
-------
|
|
826
|
-
|
|
829
|
+
str or bool
|
|
830
|
+
Output file path if successful, False otherwise.
|
|
827
831
|
|
|
832
|
+
Examples
|
|
833
|
+
--------
|
|
834
|
+
Export to IPC2581 format:
|
|
835
|
+
>>> edb.export_to_ipc2581("output.xml")
|
|
828
836
|
"""
|
|
829
837
|
if units.lower() not in ["millimeter", "inch", "micron"]: # pragma no cover
|
|
830
838
|
self.logger.warning("The wrong unit is entered. Setting to the default, millimeter.")
|
|
@@ -848,30 +856,26 @@ class Edb(EdbInit):
|
|
|
848
856
|
|
|
849
857
|
@property
|
|
850
858
|
def configuration(self) -> Configuration:
|
|
851
|
-
"""
|
|
859
|
+
"""Project configuration manager.
|
|
852
860
|
|
|
853
861
|
Returns
|
|
854
862
|
-------
|
|
855
|
-
:class:`Configuration <pyedb.configuration.configuration.Configuration
|
|
863
|
+
:class:`Configuration <pyedb.configuration.configuration.Configuration>`
|
|
864
|
+
Configuration file interface.
|
|
856
865
|
"""
|
|
857
866
|
if not self._configuration:
|
|
858
867
|
self._configuration = Configuration(self)
|
|
859
868
|
return self._configuration
|
|
860
869
|
|
|
861
870
|
def edb_exception(self, ex_value, tb_data):
|
|
862
|
-
"""
|
|
871
|
+
"""Log Python exceptions to EDB logger.
|
|
863
872
|
|
|
864
873
|
Parameters
|
|
865
874
|
----------
|
|
866
|
-
ex_value :
|
|
867
|
-
|
|
868
|
-
tb_data :
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
Returns
|
|
872
|
-
-------
|
|
873
|
-
None
|
|
874
|
-
|
|
875
|
+
ex_value : Exception
|
|
876
|
+
Exception value.
|
|
877
|
+
tb_data : traceback
|
|
878
|
+
Traceback object.
|
|
875
879
|
"""
|
|
876
880
|
tb_trace = traceback.format_tb(tb_data)
|
|
877
881
|
tblist = tb_trace[0].split("\n")
|
|
@@ -881,26 +885,40 @@ class Edb(EdbInit):
|
|
|
881
885
|
|
|
882
886
|
@property
|
|
883
887
|
def active_db(self):
|
|
884
|
-
"""
|
|
888
|
+
"""Active database object.
|
|
885
889
|
|
|
886
890
|
Returns
|
|
887
891
|
-------
|
|
888
|
-
:class:`
|
|
892
|
+
:class:`ansys.edb.core.database.Database`
|
|
893
|
+
Current database instance.
|
|
889
894
|
"""
|
|
890
895
|
return self.db
|
|
891
896
|
|
|
892
897
|
@property
|
|
893
898
|
def active_cell(self):
|
|
894
|
-
"""Active cell.
|
|
899
|
+
"""Active cell in the database.
|
|
895
900
|
|
|
896
901
|
Returns
|
|
897
902
|
-------
|
|
898
|
-
:class:`
|
|
903
|
+
:class:`ansys.edb.core.layout.cell.Cell`
|
|
904
|
+
Currently active cell.
|
|
899
905
|
"""
|
|
900
906
|
return self._active_cell
|
|
901
907
|
|
|
902
908
|
@active_cell.setter
|
|
903
909
|
def active_cell(self, value):
|
|
910
|
+
"""Set active cell by name or object.
|
|
911
|
+
|
|
912
|
+
Parameters
|
|
913
|
+
----------
|
|
914
|
+
value : str or ansys.edb.core.layout.cell.Cell
|
|
915
|
+
Cell name or object to set as active.
|
|
916
|
+
|
|
917
|
+
Raises
|
|
918
|
+
------
|
|
919
|
+
ValueError
|
|
920
|
+
If cell not found in database.
|
|
921
|
+
"""
|
|
904
922
|
if isinstance(value, str):
|
|
905
923
|
_cell = [cell for cell in self.circuit_cells if cell.name == value]
|
|
906
924
|
if _cell:
|
|
@@ -918,17 +936,12 @@ class Edb(EdbInit):
|
|
|
918
936
|
|
|
919
937
|
@property
|
|
920
938
|
def components(self) -> Components:
|
|
921
|
-
"""
|
|
939
|
+
"""Component management interface.
|
|
922
940
|
|
|
923
941
|
Returns
|
|
924
942
|
-------
|
|
925
|
-
:class:`Components <pyedb.grpc.database.components.Components
|
|
926
|
-
|
|
927
|
-
Examples
|
|
928
|
-
--------
|
|
929
|
-
>>> from pyedb import Edb
|
|
930
|
-
>>> edbapp = Edb("myproject.aedb")
|
|
931
|
-
>>> comp = edbapp.components.get_component_by_name("J1")
|
|
943
|
+
:class:`Components <pyedb.grpc.database.components.Components>`
|
|
944
|
+
Component manipulation tools.
|
|
932
945
|
"""
|
|
933
946
|
if not self._components and self.active_db:
|
|
934
947
|
self._components = Components(self)
|
|
@@ -936,19 +949,12 @@ class Edb(EdbInit):
|
|
|
936
949
|
|
|
937
950
|
@property
|
|
938
951
|
def stackup(self) -> Stackup:
|
|
939
|
-
"""Stackup
|
|
952
|
+
"""Stackup management interface.
|
|
940
953
|
|
|
941
954
|
Returns
|
|
942
955
|
-------
|
|
943
956
|
:class:`Stackup <pyedb.grpc.database.stackup.Stackup>`
|
|
944
|
-
|
|
945
|
-
Examples
|
|
946
|
-
--------
|
|
947
|
-
>>> from pyedb.grpc.edb import Edb
|
|
948
|
-
>>> edbapp = Edb("myproject.aedb")
|
|
949
|
-
>>> edbapp.stackup.layers["TOP"].thickness = 4e-5
|
|
950
|
-
>>> edbapp.stackup.layers["TOP"].thickness == 4e-05
|
|
951
|
-
>>> edbapp.stackup.add_layer("Diel", "GND", layer_type="dielectric", thickness="0.1mm", material="FR4_epoxy")
|
|
957
|
+
Layer stack configuration tools.
|
|
952
958
|
"""
|
|
953
959
|
if self.active_db:
|
|
954
960
|
self._stackup = Stackup(self, self.active_cell.layout.layer_collection)
|
|
@@ -956,30 +962,24 @@ class Edb(EdbInit):
|
|
|
956
962
|
|
|
957
963
|
@property
|
|
958
964
|
def source_excitation(self) -> SourceExcitation:
|
|
959
|
-
"""
|
|
965
|
+
"""Source excitation management.
|
|
960
966
|
|
|
961
967
|
Returns
|
|
962
968
|
-------
|
|
963
|
-
:class:`SourceExcitation <pyedb.grpc.database.source_excitations.SourceExcitation
|
|
969
|
+
:class:`SourceExcitation <pyedb.grpc.database.source_excitations.SourceExcitation>`
|
|
970
|
+
Source and port creation tools.
|
|
964
971
|
"""
|
|
965
972
|
if self.active_db:
|
|
966
973
|
return self._source_excitation
|
|
967
974
|
|
|
968
975
|
@property
|
|
969
976
|
def materials(self) -> Materials:
|
|
970
|
-
"""Material
|
|
977
|
+
"""Material database interface.
|
|
971
978
|
|
|
972
979
|
Returns
|
|
973
980
|
-------
|
|
974
|
-
:class:`Materials <pyedb.grpc.database.definition.materials.Materials
|
|
975
|
-
|
|
976
|
-
Examples
|
|
977
|
-
--------
|
|
978
|
-
>>> from pyedb import Edb
|
|
979
|
-
>>> edbapp = Edb()
|
|
980
|
-
>>> edbapp.materials.add_material("air", permittivity=1.0)
|
|
981
|
-
>>> edbapp.materials.add_debye_material("debye_mat", 5, 3, 0.02, 0.05, 1e5, 1e9)
|
|
982
|
-
>>> edbapp.materials.add_djordjevicsarkar_material("djord_mat", 3.3, 0.02, 3.3)
|
|
981
|
+
:class:`Materials <pyedb.grpc.database.definition.materials.Materials>`
|
|
982
|
+
Material definition and management.
|
|
983
983
|
"""
|
|
984
984
|
if self.active_db:
|
|
985
985
|
self._materials = Materials(self)
|
|
@@ -987,40 +987,25 @@ class Edb(EdbInit):
|
|
|
987
987
|
|
|
988
988
|
@property
|
|
989
989
|
def padstacks(self) -> Padstacks:
|
|
990
|
-
"""
|
|
991
|
-
|
|
990
|
+
"""Padstack management interface.
|
|
992
991
|
|
|
993
992
|
Returns
|
|
994
993
|
-------
|
|
995
|
-
:class:`Padstacks <pyedb.grpc.database.padstack.Padstacks
|
|
996
|
-
|
|
997
|
-
Examples
|
|
998
|
-
--------
|
|
999
|
-
>>> from pyedb import Edb
|
|
1000
|
-
>>> edbapp = Edb("myproject.aedb")
|
|
1001
|
-
>>> p = edbapp.padstacks.create(padstackname="myVia_bullet", antipad_shape="Bullet")
|
|
1002
|
-
>>> edbapp.padstacks.get_pad_parameters(
|
|
1003
|
-
>>> ... p, "TOP", edbapp.padstacks.pad_type.RegularPad
|
|
1004
|
-
>>> ... )
|
|
994
|
+
:class:`Padstacks <pyedb.grpc.database.padstack.Padstacks>`
|
|
995
|
+
Padstack definition and editing.
|
|
1005
996
|
"""
|
|
1006
|
-
|
|
1007
997
|
if not self._padstack and self.active_db:
|
|
1008
998
|
self._padstack = Padstacks(self)
|
|
1009
999
|
return self._padstack
|
|
1010
1000
|
|
|
1011
1001
|
@property
|
|
1012
1002
|
def siwave(self) -> Siwave:
|
|
1013
|
-
"""
|
|
1003
|
+
"""SIwave simulation interface.
|
|
1014
1004
|
|
|
1015
1005
|
Returns
|
|
1016
1006
|
-------
|
|
1017
|
-
:class:`Siwave <pyedb.grpc.database.siwave.Siwave
|
|
1018
|
-
|
|
1019
|
-
Examples
|
|
1020
|
-
--------
|
|
1021
|
-
>>> from pyedb import Edb
|
|
1022
|
-
>>> edbapp = Edb("myproject.aedb")
|
|
1023
|
-
>>> p2 = edbapp.siwave.create_circuit_port_on_net("U2A5", "V3P3_S0", "U2A5", "GND", 50, "test")
|
|
1007
|
+
:class:`Siwave <pyedb.grpc.database.siwave.Siwave>`
|
|
1008
|
+
SIwave analysis setup tools.
|
|
1024
1009
|
"""
|
|
1025
1010
|
if not self._siwave and self.active_db:
|
|
1026
1011
|
self._siwave = Siwave(self)
|
|
@@ -1028,19 +1013,12 @@ class Edb(EdbInit):
|
|
|
1028
1013
|
|
|
1029
1014
|
@property
|
|
1030
1015
|
def hfss(self) -> Hfss:
|
|
1031
|
-
"""
|
|
1016
|
+
"""HFSS simulation interface.
|
|
1032
1017
|
|
|
1033
1018
|
Returns
|
|
1034
1019
|
-------
|
|
1035
|
-
:class:`Hfss <pyedb.grpc.database.hfss.Hfss
|
|
1036
|
-
|
|
1037
|
-
Examples
|
|
1038
|
-
--------
|
|
1039
|
-
>>> from pyedb import Edb
|
|
1040
|
-
>>> edbapp = Edb("myproject.aedb")
|
|
1041
|
-
>>> sim_config = edbapp.new_simulation_configuration()
|
|
1042
|
-
>>> sim_config.mesh_freq = "10Ghz"
|
|
1043
|
-
>>> edbapp.hfss.configure_hfss_analysis_setup(sim_config)
|
|
1020
|
+
:class:`Hfss <pyedb.grpc.database.hfss.Hfss>`
|
|
1021
|
+
HFSS analysis setup tools.
|
|
1044
1022
|
"""
|
|
1045
1023
|
if not self._hfss and self.active_db:
|
|
1046
1024
|
self._hfss = Hfss(self)
|
|
@@ -1048,74 +1026,50 @@ class Edb(EdbInit):
|
|
|
1048
1026
|
|
|
1049
1027
|
@property
|
|
1050
1028
|
def nets(self) -> Nets:
|
|
1051
|
-
"""
|
|
1029
|
+
"""Net management interface.
|
|
1052
1030
|
|
|
1053
1031
|
Returns
|
|
1054
1032
|
-------
|
|
1055
|
-
:class:`Nets <pyedb.grpc.database.nets.Nets
|
|
1056
|
-
|
|
1057
|
-
Examples
|
|
1058
|
-
--------
|
|
1059
|
-
>>> from pyedb import Edb
|
|
1060
|
-
>>> edbapp = Edb"myproject.aedb")
|
|
1061
|
-
>>> edbapp.nets.find_or_create_net("GND")
|
|
1062
|
-
>>> edbapp.nets.find_and_fix_disjoint_nets("GND", keep_only_main_net=True)
|
|
1033
|
+
:class:`Nets <pyedb.grpc.database.nets.Nets>`
|
|
1034
|
+
Net manipulation tools.
|
|
1063
1035
|
"""
|
|
1064
|
-
|
|
1065
1036
|
if not self._nets and self.active_db:
|
|
1066
1037
|
self._nets = Nets(self)
|
|
1067
1038
|
return self._nets
|
|
1068
1039
|
|
|
1069
1040
|
@property
|
|
1070
1041
|
def net_classes(self) -> NetClass:
|
|
1071
|
-
"""
|
|
1042
|
+
"""Net class management.
|
|
1072
1043
|
|
|
1073
1044
|
Returns
|
|
1074
1045
|
-------
|
|
1075
|
-
:class:`NetClass <pyedb.grpc.database.net.net_class.NetClass
|
|
1076
|
-
|
|
1077
|
-
Examples
|
|
1078
|
-
--------
|
|
1079
|
-
>>> from pyedb import Edb
|
|
1080
|
-
>>> edbapp = Edb("myproject.aedb")
|
|
1081
|
-
>>> edbapp.net_classes
|
|
1046
|
+
dict[str, :class:`NetClass <pyedb.grpc.database.net.net_class.NetClass>`]
|
|
1047
|
+
Net class names and objects.
|
|
1082
1048
|
"""
|
|
1083
|
-
|
|
1084
1049
|
if self.active_db:
|
|
1085
1050
|
return {net.name: NetClass(self, net) for net in self.active_layout.net_classes}
|
|
1086
1051
|
|
|
1087
1052
|
@property
|
|
1088
1053
|
def extended_nets(self) -> ExtendedNets:
|
|
1089
|
-
"""
|
|
1054
|
+
"""Extended net management.
|
|
1090
1055
|
|
|
1091
1056
|
Returns
|
|
1092
1057
|
-------
|
|
1093
|
-
:class:`ExtendedNets <pyedb.grpc.database.net.extended_net.ExtendedNets
|
|
1094
|
-
|
|
1095
|
-
Examples
|
|
1096
|
-
--------
|
|
1097
|
-
>>> from pyedb import Edb
|
|
1098
|
-
>>> edbapp = Edb("myproject.aedb")
|
|
1099
|
-
>>> edbapp.extended_nets
|
|
1058
|
+
:class:`ExtendedNets <pyedb.grpc.database.net.extended_net.ExtendedNets>`
|
|
1059
|
+
Extended net tools.
|
|
1100
1060
|
"""
|
|
1101
|
-
|
|
1102
1061
|
if not self._extended_nets:
|
|
1103
1062
|
self._extended_nets = ExtendedNets(self)
|
|
1104
1063
|
return self._extended_nets
|
|
1105
1064
|
|
|
1106
1065
|
@property
|
|
1107
1066
|
def differential_pairs(self) -> DifferentialPairs:
|
|
1108
|
-
"""
|
|
1067
|
+
"""Differential pair management.
|
|
1109
1068
|
|
|
1110
1069
|
Returns
|
|
1111
1070
|
-------
|
|
1112
|
-
:class:`DifferentialPairs <pyedb.grpc.database.net.differential_par.DifferentialPairs
|
|
1113
|
-
|
|
1114
|
-
Examples
|
|
1115
|
-
--------
|
|
1116
|
-
>>> from pyedb import Edb
|
|
1117
|
-
>>> edbapp = Edb("myproject.aedb")
|
|
1118
|
-
>>> edbapp.differential_pairs
|
|
1071
|
+
:class:`DifferentialPairs <pyedb.grpc.database.net.differential_par.DifferentialPairs>`
|
|
1072
|
+
Differential pair tools.
|
|
1119
1073
|
"""
|
|
1120
1074
|
if not self._differential_pairs and self.active_db:
|
|
1121
1075
|
self._differential_pairs = DifferentialPairs(self)
|
|
@@ -1123,17 +1077,12 @@ class Edb(EdbInit):
|
|
|
1123
1077
|
|
|
1124
1078
|
@property
|
|
1125
1079
|
def modeler(self) -> Modeler:
|
|
1126
|
-
"""
|
|
1080
|
+
"""Geometry modeling interface.
|
|
1127
1081
|
|
|
1128
1082
|
Returns
|
|
1129
1083
|
-------
|
|
1130
|
-
:class:`Modeler <pyedb.grpc.database.modeler.Modeler
|
|
1131
|
-
|
|
1132
|
-
Examples
|
|
1133
|
-
--------
|
|
1134
|
-
>>> from pyedb import Edb
|
|
1135
|
-
>>> edbapp = Edb("myproject.aedb")
|
|
1136
|
-
>>> top_prims = edbapp.modeler.primitives_by_layer["TOP"]
|
|
1084
|
+
:class:`Modeler <pyedb.grpc.database.modeler.Modeler>`
|
|
1085
|
+
Geometry creation and editing.
|
|
1137
1086
|
"""
|
|
1138
1087
|
if not self._modeler and self.active_db:
|
|
1139
1088
|
self._modeler = Modeler(self)
|
|
@@ -1141,46 +1090,51 @@ class Edb(EdbInit):
|
|
|
1141
1090
|
|
|
1142
1091
|
@property
|
|
1143
1092
|
def layout(self) -> Layout:
|
|
1144
|
-
"""
|
|
1093
|
+
"""Layout access interface.
|
|
1145
1094
|
|
|
1146
1095
|
Returns
|
|
1147
1096
|
-------
|
|
1148
|
-
:class:`Layout <pyedb.grpc.database.layout.layout.Layout
|
|
1097
|
+
:class:`Layout <pyedb.grpc.database.layout.layout.Layout>`
|
|
1098
|
+
Layout manipulation tools.
|
|
1149
1099
|
"""
|
|
1150
1100
|
return Layout(self)
|
|
1151
1101
|
|
|
1152
1102
|
@property
|
|
1153
1103
|
def active_layout(self) -> Layout:
|
|
1154
|
-
"""Active layout.
|
|
1104
|
+
"""Active layout access.
|
|
1155
1105
|
|
|
1156
1106
|
Returns
|
|
1157
1107
|
-------
|
|
1158
|
-
:class:`Layout <pyedb.grpc.database.layout.layout.Layout
|
|
1108
|
+
:class:`Layout <pyedb.grpc.database.layout.layout.Layout>`
|
|
1109
|
+
Current layout tools.
|
|
1159
1110
|
"""
|
|
1160
1111
|
return self.layout
|
|
1161
1112
|
|
|
1162
1113
|
@property
|
|
1163
1114
|
def layout_instance(self):
|
|
1164
|
-
"""
|
|
1115
|
+
"""Layout instance object.
|
|
1165
1116
|
|
|
1166
1117
|
Returns
|
|
1167
1118
|
-------
|
|
1168
1119
|
:class:`LayoutInstance <ansys.edb.core.layout_instance.layout_instance.LayoutInstance>`
|
|
1120
|
+
Current layout instance.
|
|
1169
1121
|
"""
|
|
1170
1122
|
if not self._layout_instance:
|
|
1171
1123
|
self._layout_instance = self.layout.layout_instance
|
|
1172
1124
|
return self._layout_instance
|
|
1173
1125
|
|
|
1174
1126
|
def get_connected_objects(self, layout_object_instance):
|
|
1175
|
-
"""
|
|
1127
|
+
"""Get objects connected to a layout object.
|
|
1128
|
+
|
|
1129
|
+
Parameters
|
|
1130
|
+
----------
|
|
1131
|
+
layout_object_instance :
|
|
1132
|
+
Target layout object.
|
|
1176
1133
|
|
|
1177
1134
|
Returns
|
|
1178
1135
|
-------
|
|
1179
|
-
list
|
|
1180
|
-
|
|
1181
|
-
:class:`Rectangle <pyedb.grpc.database.primitive.rectangle.Rectangle>`,
|
|
1182
|
-
:class:`Circle <pyedb.grpc.database.primitive.circle.Circle>`,
|
|
1183
|
-
:class:`Polygon <pyedb.grpc.database.primitive.polygon.Polygon>`]
|
|
1136
|
+
list
|
|
1137
|
+
Connected objects (padstacks, paths, polygons, etc.).
|
|
1184
1138
|
"""
|
|
1185
1139
|
from ansys.edb.core.terminal.padstack_instance_terminal import (
|
|
1186
1140
|
PadstackInstanceTerminal as GrpcPadstackInstanceTerminal,
|
|
@@ -1213,39 +1167,40 @@ class Edb(EdbInit):
|
|
|
1213
1167
|
return temp
|
|
1214
1168
|
|
|
1215
1169
|
def point_3d(self, x, y, z=0.0):
|
|
1216
|
-
"""
|
|
1170
|
+
"""Create 3D point.
|
|
1217
1171
|
|
|
1218
1172
|
Parameters
|
|
1219
1173
|
----------
|
|
1220
|
-
x : float, int
|
|
1221
|
-
X
|
|
1222
|
-
y : float, int
|
|
1223
|
-
Y
|
|
1224
|
-
z : float, int
|
|
1225
|
-
Z
|
|
1174
|
+
x : float, int, str
|
|
1175
|
+
X coordinate.
|
|
1176
|
+
y : float, int, str
|
|
1177
|
+
Y coordinate.
|
|
1178
|
+
z : float, int, str, optional
|
|
1179
|
+
Z coordinate.
|
|
1226
1180
|
|
|
1227
1181
|
Returns
|
|
1228
1182
|
-------
|
|
1229
1183
|
:class:`Point3DData <pyedb.grpc.database.geometry.point_3d_data.Point3DData>`
|
|
1184
|
+
3D point object.
|
|
1230
1185
|
"""
|
|
1231
1186
|
from pyedb.grpc.database.geometry.point_3d_data import Point3DData
|
|
1232
1187
|
|
|
1233
1188
|
return Point3DData(x, y, z)
|
|
1234
1189
|
|
|
1235
1190
|
def point_data(self, x, y=None):
|
|
1236
|
-
"""
|
|
1191
|
+
"""Create 2D point.
|
|
1237
1192
|
|
|
1238
1193
|
Parameters
|
|
1239
1194
|
----------
|
|
1240
|
-
x : float, int or
|
|
1241
|
-
X
|
|
1242
|
-
y : float, int
|
|
1243
|
-
Y
|
|
1244
|
-
|
|
1195
|
+
x : float, int, str or PointData
|
|
1196
|
+
X coordinate or PointData object.
|
|
1197
|
+
y : float, int, str, optional
|
|
1198
|
+
Y coordinate.
|
|
1245
1199
|
|
|
1246
1200
|
Returns
|
|
1247
1201
|
-------
|
|
1248
1202
|
:class:`PointData <pyedb.grpc.database.geometry.point_data.PointData>`
|
|
1203
|
+
2D point object.
|
|
1249
1204
|
"""
|
|
1250
1205
|
from pyedb.grpc.database.geometry.point_data import PointData
|
|
1251
1206
|
|
|
@@ -1254,18 +1209,6 @@ class Edb(EdbInit):
|
|
|
1254
1209
|
else:
|
|
1255
1210
|
return PointData(x, y)
|
|
1256
1211
|
|
|
1257
|
-
@staticmethod
|
|
1258
|
-
def _is_file_existing_and_released(filename) -> bool:
|
|
1259
|
-
if os.path.exists(filename):
|
|
1260
|
-
try:
|
|
1261
|
-
os.rename(filename, filename + "_")
|
|
1262
|
-
os.rename(filename + "_", filename)
|
|
1263
|
-
return True
|
|
1264
|
-
except OSError as e:
|
|
1265
|
-
return False
|
|
1266
|
-
else:
|
|
1267
|
-
return False
|
|
1268
|
-
|
|
1269
1212
|
@staticmethod
|
|
1270
1213
|
def _is_file_existing(filename) -> bool:
|
|
1271
1214
|
if os.path.exists(filename):
|
|
@@ -1273,18 +1216,6 @@ class Edb(EdbInit):
|
|
|
1273
1216
|
else:
|
|
1274
1217
|
return False
|
|
1275
1218
|
|
|
1276
|
-
def _wait_for_file_release(self, timeout=30, file_to_release=None) -> bool:
|
|
1277
|
-
if not file_to_release:
|
|
1278
|
-
file_to_release = os.path.join(self.edbpath)
|
|
1279
|
-
tstart = time.time()
|
|
1280
|
-
while True:
|
|
1281
|
-
if self._is_file_existing_and_released(file_to_release):
|
|
1282
|
-
return True
|
|
1283
|
-
elif time.time() - tstart > timeout:
|
|
1284
|
-
return False
|
|
1285
|
-
else:
|
|
1286
|
-
time.sleep(0.250)
|
|
1287
|
-
|
|
1288
1219
|
def _wait_for_file_exists(self, timeout=30, file_to_release=None, wait_count=4):
|
|
1289
1220
|
if not file_to_release:
|
|
1290
1221
|
file_to_release = os.path.join(self.edbpath)
|
|
@@ -1304,93 +1235,80 @@ class Edb(EdbInit):
|
|
|
1304
1235
|
time.sleep(0.250)
|
|
1305
1236
|
|
|
1306
1237
|
def close_edb(self) -> bool:
|
|
1307
|
-
"""Close EDB and
|
|
1238
|
+
"""Close EDB and clean up resources.
|
|
1239
|
+
|
|
1240
|
+
..deprecated:: 0.51.0
|
|
1241
|
+
Use: func:`close` instead.
|
|
1308
1242
|
|
|
1309
1243
|
Returns
|
|
1310
1244
|
-------
|
|
1311
|
-
bool
|
|
1245
|
+
bool
|
|
1246
|
+
True if successful, False otherwise.
|
|
1247
|
+
|
|
1248
|
+
Examples
|
|
1249
|
+
--------
|
|
1250
|
+
Close the EDB session:
|
|
1251
|
+
>>> edb.close_edb()
|
|
1312
1252
|
"""
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
self._wait_for_file_release()
|
|
1316
|
-
elapsed_time = time.time() - start_time
|
|
1317
|
-
self.logger.info("EDB file release time: {0:.2f}ms".format(elapsed_time * 1000.0))
|
|
1318
|
-
self._clean_variables()
|
|
1319
|
-
return True
|
|
1253
|
+
warnings.warn("Use method close instead.", DeprecationWarning)
|
|
1254
|
+
return self.close()
|
|
1320
1255
|
|
|
1321
1256
|
def save_edb(self) -> bool:
|
|
1322
|
-
"""Save
|
|
1257
|
+
"""Save current EDB database.
|
|
1258
|
+
|
|
1259
|
+
..deprecated:: 0.51.0
|
|
1260
|
+
Use: func:`save` instead.
|
|
1323
1261
|
|
|
1324
1262
|
Returns
|
|
1325
1263
|
-------
|
|
1326
|
-
bool
|
|
1264
|
+
bool
|
|
1265
|
+
True if successful, False otherwise.
|
|
1266
|
+
|
|
1267
|
+
Examples
|
|
1268
|
+
--------
|
|
1269
|
+
Save the current EDB:
|
|
1270
|
+
>>> edb.save_edb()
|
|
1327
1271
|
"""
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
self._wait_for_file_release()
|
|
1331
|
-
elapsed_time = time.time() - start_time
|
|
1332
|
-
self.logger.info("EDB file save time: {0:.2f}ms".format(elapsed_time * 1000.0))
|
|
1333
|
-
return True
|
|
1272
|
+
warnings.warn("Use method save instead.", DeprecationWarning)
|
|
1273
|
+
return self.save()
|
|
1334
1274
|
|
|
1335
1275
|
def save_edb_as(self, fname) -> bool:
|
|
1336
|
-
"""Save
|
|
1276
|
+
"""Save EDB database to new location.
|
|
1277
|
+
|
|
1278
|
+
..deprecated:: 0.51.0
|
|
1279
|
+
Use: func:`save_as` instead.
|
|
1337
1280
|
|
|
1338
1281
|
Parameters
|
|
1339
1282
|
----------
|
|
1340
1283
|
fname : str
|
|
1341
|
-
|
|
1284
|
+
New AEDB path.
|
|
1342
1285
|
|
|
1343
1286
|
Returns
|
|
1344
1287
|
-------
|
|
1345
|
-
bool
|
|
1288
|
+
bool
|
|
1289
|
+
True if successful, False otherwise.
|
|
1290
|
+
|
|
1291
|
+
Examples
|
|
1292
|
+
--------
|
|
1293
|
+
Save EDB to new location:
|
|
1294
|
+
>>> edb.save_edb_as("new_location.aedb")
|
|
1346
1295
|
"""
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
self._wait_for_file_release()
|
|
1350
|
-
elapsed_time = time.time() - start_time
|
|
1351
|
-
self.logger.info("EDB file save time: {0:.2f}ms".format(elapsed_time * 1000.0))
|
|
1352
|
-
self.edbpath = self.directory
|
|
1353
|
-
self.log_name = os.path.join(
|
|
1354
|
-
os.path.dirname(fname), "pyedb_" + os.path.splitext(os.path.split(fname)[-1])[0] + ".log"
|
|
1355
|
-
)
|
|
1356
|
-
return True
|
|
1296
|
+
warnings.warn("Use method save_as instead.", DeprecationWarning)
|
|
1297
|
+
return self.save_as(fname)
|
|
1357
1298
|
|
|
1358
1299
|
def execute(self, func):
|
|
1359
|
-
"""Execute
|
|
1300
|
+
"""Execute EDB utility command (Not implemented in gRPC).
|
|
1360
1301
|
|
|
1361
1302
|
Parameters
|
|
1362
1303
|
----------
|
|
1363
1304
|
func : str
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
Returns
|
|
1368
|
-
-------
|
|
1369
|
-
bool: `True` when successful, `False` when failed.
|
|
1305
|
+
Command to execute.
|
|
1370
1306
|
"""
|
|
1371
1307
|
# return self.edb_api.utility.utility.Command.Execute(func)
|
|
1372
1308
|
pass
|
|
1373
1309
|
|
|
1374
1310
|
def import_cadence_file(self, inputBrd, WorkDir=None, anstranslator_full_path="", use_ppe=False):
|
|
1375
|
-
"""Import
|
|
1376
|
-
|
|
1377
|
-
Parameters
|
|
1378
|
-
----------
|
|
1379
|
-
inputBrd : str
|
|
1380
|
-
Full path to the board file.
|
|
1381
|
-
WorkDir : str, optional
|
|
1382
|
-
Directory in which to create the ``aedb`` folder. The default value is ``None``,
|
|
1383
|
-
in which case the AEDB file is given the same name as the board file. Only
|
|
1384
|
-
the extension differs.
|
|
1385
|
-
anstranslator_full_path : str, optional
|
|
1386
|
-
Full path to the Ansys translator.
|
|
1387
|
-
use_ppe : bool, optional
|
|
1388
|
-
Whether to use the PPE License. The default is ``False``.
|
|
1389
|
-
|
|
1390
|
-
Returns
|
|
1391
|
-
-------
|
|
1392
|
-
bool: `True` when successful, `False` when failed.
|
|
1393
|
-
"""
|
|
1311
|
+
"""Import Cadence board file (Deprecated - use import_layout_file)."""
|
|
1394
1312
|
if self.import_layout_pcb(
|
|
1395
1313
|
inputBrd,
|
|
1396
1314
|
working_dir=WorkDir,
|
|
@@ -1411,32 +1329,24 @@ class Edb(EdbInit):
|
|
|
1411
1329
|
map_file=None,
|
|
1412
1330
|
layer_filter=None,
|
|
1413
1331
|
):
|
|
1414
|
-
"""Import
|
|
1415
|
-
|
|
1416
|
-
..note::
|
|
1417
|
-
ANSYS license is necessary to run the translator.
|
|
1332
|
+
"""Import GDS file.
|
|
1418
1333
|
|
|
1419
1334
|
Parameters
|
|
1420
1335
|
----------
|
|
1421
1336
|
inputGDS : str
|
|
1422
|
-
|
|
1337
|
+
GDS file path.
|
|
1423
1338
|
anstranslator_full_path : str, optional
|
|
1424
|
-
|
|
1339
|
+
Ansys translator path.
|
|
1425
1340
|
use_ppe : bool, optional
|
|
1426
|
-
|
|
1341
|
+
Use PPE license. Default False.
|
|
1427
1342
|
control_file : str, optional
|
|
1428
|
-
|
|
1429
|
-
the XML file in the same directory as the GDS file. To succeed, the XML file and GDS file must
|
|
1430
|
-
have the same name. Only the extension differs.
|
|
1343
|
+
XML control file.
|
|
1431
1344
|
tech_file : str, optional
|
|
1432
|
-
Technology file.
|
|
1433
|
-
the gds. Works on Linux only.
|
|
1434
|
-
For versions>=2024.1 it can directly parse through supported foundry tech files.
|
|
1345
|
+
Technology file.
|
|
1435
1346
|
map_file : str, optional
|
|
1436
1347
|
Layer map file.
|
|
1437
|
-
layer_filter:str,optional
|
|
1348
|
+
layer_filter : str, optional
|
|
1438
1349
|
Layer filter file.
|
|
1439
|
-
|
|
1440
1350
|
"""
|
|
1441
1351
|
control_file_temp = os.path.join(tempfile.gettempdir(), os.path.split(inputGDS)[-1][:-3] + "xml")
|
|
1442
1352
|
if float(self.edbversion) < 2024.1:
|
|
@@ -1737,114 +1647,72 @@ class Edb(EdbInit):
|
|
|
1737
1647
|
keep_lines_as_path=False,
|
|
1738
1648
|
include_voids_in_extents=False,
|
|
1739
1649
|
):
|
|
1740
|
-
"""Create
|
|
1741
|
-
This method replaces all legacy cutout methods in PyAEDT.
|
|
1742
|
-
It does in sequence:
|
|
1743
|
-
- delete all nets not in list,
|
|
1744
|
-
- create a extent of the nets,
|
|
1745
|
-
- check and delete all vias not in the extent,
|
|
1746
|
-
- check and delete all the primitives not in extent,
|
|
1747
|
-
- check and intersect all the primitives that intersect the extent.
|
|
1650
|
+
"""Create layout cutout with various options.
|
|
1748
1651
|
|
|
1749
1652
|
Parameters
|
|
1750
1653
|
----------
|
|
1751
|
-
|
|
1752
|
-
|
|
1654
|
+
signal_list : list, optional
|
|
1655
|
+
Signal nets to include.
|
|
1753
1656
|
reference_list : list, optional
|
|
1754
|
-
|
|
1657
|
+
Reference nets to include.
|
|
1755
1658
|
extent_type : str, optional
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
Expansion size ratio in meters. The default is ``0.002``.
|
|
1659
|
+
Cutout type ("Conforming", "ConvexHull", "Bounding").
|
|
1660
|
+
expansion_size : float, optional
|
|
1661
|
+
Boundary expansion size (meters).
|
|
1760
1662
|
use_round_corner : bool, optional
|
|
1761
|
-
|
|
1663
|
+
Use rounded corners. Default False.
|
|
1762
1664
|
output_aedb_path : str, optional
|
|
1763
|
-
|
|
1665
|
+
Output AEDB path.
|
|
1764
1666
|
open_cutout_at_end : bool, optional
|
|
1765
|
-
|
|
1667
|
+
Open cutout when finished. Default True.
|
|
1766
1668
|
use_pyaedt_cutout : bool, optional
|
|
1767
|
-
|
|
1768
|
-
New method is faster than native API method since it benefits of multithread.
|
|
1669
|
+
Use PyAEDT cutout method. Default True.
|
|
1769
1670
|
number_of_threads : int, optional
|
|
1770
|
-
|
|
1671
|
+
Thread count for PyAEDT cutout.
|
|
1771
1672
|
use_pyaedt_extent_computing : bool, optional
|
|
1772
|
-
|
|
1673
|
+
Use PyAEDT extent computation. Default True.
|
|
1773
1674
|
extent_defeature : float, optional
|
|
1774
|
-
|
|
1775
|
-
It applies only to Conforming bounding box. Default value is ``0`` which disable it.
|
|
1675
|
+
Geometry simplification factor.
|
|
1776
1676
|
remove_single_pin_components : bool, optional
|
|
1777
|
-
Remove
|
|
1778
|
-
custom_extent : list
|
|
1779
|
-
|
|
1780
|
-
custom_extent_units : str
|
|
1781
|
-
Units
|
|
1677
|
+
Remove single-pin components. Default False.
|
|
1678
|
+
custom_extent : list, optional
|
|
1679
|
+
Custom polygon points for cutout.
|
|
1680
|
+
custom_extent_units : str, optional
|
|
1681
|
+
Units for custom_extent points.
|
|
1782
1682
|
include_partial_instances : bool, optional
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
keep_voids : bool
|
|
1787
|
-
Boolean used for keep or not the voids intersecting the polygon used for clipping the layout.
|
|
1788
|
-
Default value is ``True``, ``False`` will remove the voids.Valid only if `custom_extend` is provided.
|
|
1683
|
+
Include partial padstack instances. Default False.
|
|
1684
|
+
keep_voids : bool, optional
|
|
1685
|
+
Preserve voids in cutout. Default True.
|
|
1789
1686
|
check_terminals : bool, optional
|
|
1790
|
-
|
|
1791
|
-
This applies to components which have a model (spice, touchstone or netlist) associated.
|
|
1687
|
+
Verify terminal references. Default False.
|
|
1792
1688
|
include_pingroups : bool, optional
|
|
1793
|
-
|
|
1794
|
-
It requires ``check_terminals``.
|
|
1689
|
+
Include pin groups. Default False.
|
|
1795
1690
|
expansion_factor : int, optional
|
|
1796
|
-
|
|
1797
|
-
the dielectric thickness or trace width multiplied by the expansion_factor factor.
|
|
1798
|
-
The trace width search is limited to nets with ports attached. Works only if `use_pyaedt_cutout`.
|
|
1799
|
-
Default is `0` to disable the search.
|
|
1691
|
+
Auto-expansion factor. Default 0 (disabled).
|
|
1800
1692
|
maximum_iterations : int, optional
|
|
1801
|
-
|
|
1802
|
-
Default is `10`.
|
|
1693
|
+
Max auto-expansion iterations. Default 10.
|
|
1803
1694
|
preserve_components_with_model : bool, optional
|
|
1804
|
-
|
|
1805
|
-
This parameter is applicable only for a PyAEDT cutout (except point list).
|
|
1695
|
+
Keep components with models. Default False.
|
|
1806
1696
|
simple_pad_check : bool, optional
|
|
1807
|
-
|
|
1808
|
-
Second method is much slower and requires to disable multithread on padstack removal.
|
|
1809
|
-
Default is `True`.
|
|
1697
|
+
Use simplified pad checking. Default True.
|
|
1810
1698
|
keep_lines_as_path : bool, optional
|
|
1811
|
-
|
|
1812
|
-
This feature works only in Electronics Desktop (3D Layout).
|
|
1813
|
-
If the flag is set to ``True`` it can cause issues in SiWave once the Edb is imported.
|
|
1814
|
-
Default is ``False`` to generate PolygonData of cut lines.
|
|
1699
|
+
Preserve paths as lines. Default False.
|
|
1815
1700
|
include_voids_in_extents : bool, optional
|
|
1816
|
-
|
|
1817
|
-
It works only with Conforming cutout.
|
|
1818
|
-
Default is ``False`` to generate extent without voids.
|
|
1819
|
-
|
|
1701
|
+
Include voids in extent calculation. Default False.
|
|
1820
1702
|
|
|
1821
1703
|
Returns
|
|
1822
1704
|
-------
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
list.
|
|
1705
|
+
list or bool
|
|
1706
|
+
Cutout boundary points if successful, False otherwise.
|
|
1826
1707
|
|
|
1827
1708
|
Examples
|
|
1828
1709
|
--------
|
|
1829
|
-
|
|
1830
|
-
>>> edb
|
|
1831
|
-
>>> edb.logger.info_timer("Edb Opening")
|
|
1832
|
-
>>> edb.logger.reset_timer()
|
|
1833
|
-
>>> start = time.time()
|
|
1834
|
-
>>> signal_list = []
|
|
1835
|
-
>>> for net in edb.nets.netlist:
|
|
1836
|
-
>>> if "3V3" in net:
|
|
1837
|
-
>>> signal_list.append(net)
|
|
1838
|
-
>>> power_list = ["PGND"]
|
|
1839
|
-
>>> edb.cutout(signal_list=signal_list, reference_list=power_list, extent_type="Conforming")
|
|
1840
|
-
>>> end_time = str((time.time() - start)/60)
|
|
1841
|
-
>>> edb.logger.info("Total legacy cutout time in min %s", end_time)
|
|
1842
|
-
>>> edb.nets.plot(signal_list, None, color_by_net=True)
|
|
1843
|
-
>>> edb.nets.plot(power_list, None, color_by_net=True)
|
|
1844
|
-
>>> edb.save_edb()
|
|
1845
|
-
>>> edb.close_edb()
|
|
1846
|
-
|
|
1710
|
+
Create a basic cutout:
|
|
1711
|
+
>>> edb.cutout(signal_list=["Net1"], reference_list=["GND"])
|
|
1847
1712
|
|
|
1713
|
+
Create cutout with custom polygon:
|
|
1714
|
+
>>> custom_poly = [[0,0], [10e-3,0], [10e-3,10e-3], [0,10e-3]]
|
|
1715
|
+
>>> edb.cutout(custom_extent=custom_poly)
|
|
1848
1716
|
"""
|
|
1849
1717
|
if expansion_factor > 0:
|
|
1850
1718
|
expansion_size = self.calculate_initial_extent(expansion_factor)
|
|
@@ -1921,7 +1789,7 @@ class Edb(EdbInit):
|
|
|
1921
1789
|
break
|
|
1922
1790
|
self.close_edb()
|
|
1923
1791
|
self.edbpath = legacy_path
|
|
1924
|
-
self.
|
|
1792
|
+
self.open()
|
|
1925
1793
|
i += 1
|
|
1926
1794
|
expansion = expansion_size * i
|
|
1927
1795
|
if working_cutout:
|
|
@@ -2007,15 +1875,15 @@ class Edb(EdbInit):
|
|
|
2007
1875
|
# _cutout.simulation_setups = self.active_cell.simulation_setups see bug #433 status.
|
|
2008
1876
|
_dbCells = [_cutout]
|
|
2009
1877
|
if output_aedb_path:
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
1878
|
+
from ansys.edb.core.database import Database as GrpcDatabase
|
|
1879
|
+
|
|
1880
|
+
db2 = GrpcDatabase.create(output_aedb_path)
|
|
2013
1881
|
db2.copy_cells(_dbCells) # Copies cutout cell/design to db2 project
|
|
2014
|
-
if len(list(db2.
|
|
2015
|
-
for net in db2.
|
|
1882
|
+
if len(list(db2.top_circuit_cells)) > 0:
|
|
1883
|
+
for net in db2.top_circuit_cells[0].layout.nets:
|
|
2016
1884
|
if not net.name in included_nets_list:
|
|
2017
1885
|
net.delete()
|
|
2018
|
-
|
|
1886
|
+
db2.save()
|
|
2019
1887
|
for c in self.active_db.top_circuit_cells:
|
|
2020
1888
|
if c.name == _cutout.name:
|
|
2021
1889
|
c.delete()
|
|
@@ -2041,7 +1909,7 @@ class Edb(EdbInit):
|
|
|
2041
1909
|
for _cmp in _cmps:
|
|
2042
1910
|
_cmp.delete()
|
|
2043
1911
|
except:
|
|
2044
|
-
self.
|
|
1912
|
+
self.logger.error("Failed to remove single pin components.")
|
|
2045
1913
|
db2.close()
|
|
2046
1914
|
source = os.path.join(output_aedb_path, "edb.def.tmp")
|
|
2047
1915
|
target = os.path.join(output_aedb_path, "edb.def")
|
|
@@ -2493,7 +2361,9 @@ class Edb(EdbInit):
|
|
|
2493
2361
|
|
|
2494
2362
|
_dbCells = [_cutout]
|
|
2495
2363
|
if output_aedb_path:
|
|
2496
|
-
|
|
2364
|
+
from ansys.edb.core.database import Database as GrpcDatabase
|
|
2365
|
+
|
|
2366
|
+
db2 = GrpcDatabase.create(output_aedb_path)
|
|
2497
2367
|
db2.save()
|
|
2498
2368
|
cell_copied = db2.copy_cells(_dbCells) # Copies cutout cell/design to db2 project
|
|
2499
2369
|
cell = cell_copied[0]
|
|
@@ -2503,7 +2373,7 @@ class Edb(EdbInit):
|
|
|
2503
2373
|
if c.name == _cutout.name:
|
|
2504
2374
|
c.delete()
|
|
2505
2375
|
if open_cutout_at_end: # pragma: no cover
|
|
2506
|
-
|
|
2376
|
+
db2.save()
|
|
2507
2377
|
self._db = db2
|
|
2508
2378
|
self.edbpath = output_aedb_path
|
|
2509
2379
|
self._active_cell = cell
|
|
@@ -2568,37 +2438,30 @@ class Edb(EdbInit):
|
|
|
2568
2438
|
aedt_file_name=None,
|
|
2569
2439
|
hidden=False,
|
|
2570
2440
|
):
|
|
2571
|
-
"""Export
|
|
2441
|
+
"""Export to HFSS project.
|
|
2572
2442
|
|
|
2573
2443
|
Parameters
|
|
2574
2444
|
----------
|
|
2575
2445
|
path_to_output : str
|
|
2576
|
-
|
|
2446
|
+
Output directory.
|
|
2577
2447
|
net_list : list, optional
|
|
2578
|
-
|
|
2579
|
-
The default is ``None``, in which case all nets are eported.
|
|
2448
|
+
Nets to export.
|
|
2580
2449
|
num_cores : int, optional
|
|
2581
|
-
|
|
2450
|
+
Processing cores to use.
|
|
2582
2451
|
aedt_file_name : str, optional
|
|
2583
|
-
|
|
2584
|
-
in which case the default name is used.
|
|
2452
|
+
Custom AEDT filename.
|
|
2585
2453
|
hidden : bool, optional
|
|
2586
|
-
|
|
2454
|
+
Run Siwave in background. Default False.
|
|
2587
2455
|
|
|
2588
2456
|
Returns
|
|
2589
2457
|
-------
|
|
2590
2458
|
str
|
|
2591
|
-
|
|
2459
|
+
Path to generated AEDT file.
|
|
2592
2460
|
|
|
2593
2461
|
Examples
|
|
2594
2462
|
--------
|
|
2595
|
-
|
|
2596
|
-
>>>
|
|
2597
|
-
>>> edb = Edb(edbpath=r"C:\temp\myproject.aedb", edbversion="2023.2")
|
|
2598
|
-
|
|
2599
|
-
>>> options_config = {'UNITE_NETS' : 1, 'LAUNCH_Q3D' : 0}
|
|
2600
|
-
>>> edb.write_export3d_option_config_file(r"C:\temp", options_config)
|
|
2601
|
-
>>> edb.export_hfss(r"C:\temp")
|
|
2463
|
+
Export to HFSS project:
|
|
2464
|
+
>>> edb.export_hfss(r"C:/output", net_list=["SignalNet"])
|
|
2602
2465
|
"""
|
|
2603
2466
|
siwave_s = SiwaveSolve(self.edbpath, aedt_installer_path=self.base_path)
|
|
2604
2467
|
return siwave_s.export_3d_cad("HFSS", path_to_output, net_list, num_cores, aedt_file_name, hidden=hidden)
|
|
@@ -2611,38 +2474,31 @@ class Edb(EdbInit):
|
|
|
2611
2474
|
aedt_file_name=None,
|
|
2612
2475
|
hidden=False,
|
|
2613
2476
|
):
|
|
2614
|
-
"""Export
|
|
2477
|
+
"""Export to Q3D project.
|
|
2615
2478
|
|
|
2616
2479
|
Parameters
|
|
2617
2480
|
----------
|
|
2618
2481
|
path_to_output : str
|
|
2619
|
-
|
|
2482
|
+
Output directory.
|
|
2620
2483
|
net_list : list, optional
|
|
2621
|
-
|
|
2622
|
-
The default is ``None``, in which case all nets are eported.
|
|
2484
|
+
Nets to export.
|
|
2623
2485
|
num_cores : int, optional
|
|
2624
|
-
|
|
2486
|
+
Processing cores to use.
|
|
2625
2487
|
aedt_file_name : str, optional
|
|
2626
|
-
|
|
2627
|
-
in which case the default name is used.
|
|
2488
|
+
Custom AEDT filename.
|
|
2628
2489
|
hidden : bool, optional
|
|
2629
|
-
|
|
2490
|
+
Run Siwave in background. Default False.
|
|
2630
2491
|
|
|
2631
2492
|
Returns
|
|
2632
2493
|
-------
|
|
2633
2494
|
str
|
|
2634
|
-
|
|
2495
|
+
Path to generated AEDT file.
|
|
2635
2496
|
|
|
2636
2497
|
Examples
|
|
2637
2498
|
--------
|
|
2638
|
-
|
|
2639
|
-
>>>
|
|
2640
|
-
>>> edb = Edb(edbpath=r"C:\temp\myproject.aedb", edbversion="2021.2")
|
|
2641
|
-
>>> options_config = {'UNITE_NETS' : 1, 'LAUNCH_Q3D' : 0}
|
|
2642
|
-
>>> edb.write_export3d_option_config_file(r"C:\temp", options_config)
|
|
2643
|
-
>>> edb.export_q3d(r"C:\temp")
|
|
2499
|
+
Export to Q3D project:
|
|
2500
|
+
>>> edb.export_q3d(r"C:/output")
|
|
2644
2501
|
"""
|
|
2645
|
-
|
|
2646
2502
|
siwave_s = SiwaveSolve(self.edbpath, aedt_installer_path=self.base_path)
|
|
2647
2503
|
return siwave_s.export_3d_cad(
|
|
2648
2504
|
"Q3D",
|
|
@@ -2661,38 +2517,30 @@ class Edb(EdbInit):
|
|
|
2661
2517
|
aedt_file_name=None,
|
|
2662
2518
|
hidden=False,
|
|
2663
2519
|
):
|
|
2664
|
-
"""Export
|
|
2520
|
+
"""Export to Maxwell project.
|
|
2665
2521
|
|
|
2666
2522
|
Parameters
|
|
2667
2523
|
----------
|
|
2668
2524
|
path_to_output : str
|
|
2669
|
-
|
|
2525
|
+
Output directory.
|
|
2670
2526
|
net_list : list, optional
|
|
2671
|
-
|
|
2672
|
-
exported. The default is ``None``, in which case all nets are exported.
|
|
2527
|
+
Nets to export.
|
|
2673
2528
|
num_cores : int, optional
|
|
2674
|
-
|
|
2529
|
+
Processing cores to use.
|
|
2675
2530
|
aedt_file_name : str, optional
|
|
2676
|
-
|
|
2677
|
-
in which case the default name is used.
|
|
2531
|
+
Custom AEDT filename.
|
|
2678
2532
|
hidden : bool, optional
|
|
2679
|
-
|
|
2533
|
+
Run Siwave in background. Default False.
|
|
2680
2534
|
|
|
2681
2535
|
Returns
|
|
2682
2536
|
-------
|
|
2683
2537
|
str
|
|
2684
|
-
|
|
2538
|
+
Path to generated AEDT file.
|
|
2685
2539
|
|
|
2686
2540
|
Examples
|
|
2687
2541
|
--------
|
|
2688
|
-
|
|
2689
|
-
>>>
|
|
2690
|
-
|
|
2691
|
-
>>> edb = Edb(edbpath=r"C:\temp\myproject.aedb", edbversion="2021.2")
|
|
2692
|
-
|
|
2693
|
-
>>> options_config = {'UNITE_NETS' : 1, 'LAUNCH_Q3D' : 0}
|
|
2694
|
-
>>> edb.write_export3d_option_config_file(r"C:\temp", options_config)
|
|
2695
|
-
>>> edb.export_maxwell(r"C:\temp")
|
|
2542
|
+
Export to Maxwell project:
|
|
2543
|
+
>>> edb.export_maxwell(r"C:/output")
|
|
2696
2544
|
"""
|
|
2697
2545
|
siwave_s = SiwaveSolve(self.edbpath, aedt_installer_path=self.base_path)
|
|
2698
2546
|
return siwave_s.export_3d_cad(
|
|
@@ -2705,12 +2553,17 @@ class Edb(EdbInit):
|
|
|
2705
2553
|
)
|
|
2706
2554
|
|
|
2707
2555
|
def solve_siwave(self):
|
|
2708
|
-
"""
|
|
2556
|
+
"""Solve with SIwave.
|
|
2709
2557
|
|
|
2710
2558
|
Returns
|
|
2711
2559
|
-------
|
|
2712
2560
|
str
|
|
2713
|
-
|
|
2561
|
+
Path to SIwave project.
|
|
2562
|
+
|
|
2563
|
+
Examples
|
|
2564
|
+
--------
|
|
2565
|
+
Solve with SIwave:
|
|
2566
|
+
>>> edb.solve_siwave()
|
|
2714
2567
|
"""
|
|
2715
2568
|
process = SiwaveSolve(self.edbpath, aedt_version=self.edbversion)
|
|
2716
2569
|
try:
|
|
@@ -2733,35 +2586,35 @@ class Edb(EdbInit):
|
|
|
2733
2586
|
power_tree=True,
|
|
2734
2587
|
loop_res=True,
|
|
2735
2588
|
):
|
|
2736
|
-
"""
|
|
2589
|
+
"""Export SIwave DC results.
|
|
2737
2590
|
|
|
2738
2591
|
Parameters
|
|
2739
2592
|
----------
|
|
2740
2593
|
siwave_project : str
|
|
2741
|
-
|
|
2594
|
+
SIwave project path.
|
|
2742
2595
|
solution_name : str
|
|
2743
|
-
|
|
2596
|
+
DC analysis name.
|
|
2744
2597
|
output_folder : str, optional
|
|
2745
|
-
|
|
2598
|
+
Custom output folder.
|
|
2746
2599
|
html_report : bool, optional
|
|
2747
|
-
|
|
2600
|
+
Generate HTML report. Default True.
|
|
2748
2601
|
vias : bool, optional
|
|
2749
|
-
|
|
2602
|
+
Export vias report. Default True.
|
|
2750
2603
|
voltage_probes : bool, optional
|
|
2751
|
-
|
|
2604
|
+
Export voltage probes. Default True.
|
|
2752
2605
|
current_sources : bool, optional
|
|
2753
|
-
|
|
2606
|
+
Export current sources. Default True.
|
|
2754
2607
|
voltage_sources : bool, optional
|
|
2755
|
-
|
|
2608
|
+
Export voltage sources. Default True.
|
|
2756
2609
|
power_tree : bool, optional
|
|
2757
|
-
|
|
2610
|
+
Export power tree. Default True.
|
|
2758
2611
|
loop_res : bool, optional
|
|
2759
|
-
|
|
2612
|
+
Export loop resistance. Default True.
|
|
2760
2613
|
|
|
2761
2614
|
Returns
|
|
2762
2615
|
-------
|
|
2763
2616
|
list[str]
|
|
2764
|
-
|
|
2617
|
+
Generated report files.
|
|
2765
2618
|
"""
|
|
2766
2619
|
process = SiwaveSolve(self.edbpath, aedt_version=self.edbversion)
|
|
2767
2620
|
try:
|
|
@@ -2783,11 +2636,17 @@ class Edb(EdbInit):
|
|
|
2783
2636
|
)
|
|
2784
2637
|
|
|
2785
2638
|
def variable_exists(self, variable_name):
|
|
2786
|
-
"""Check if
|
|
2639
|
+
"""Check if variable exists.
|
|
2640
|
+
|
|
2641
|
+
Parameters
|
|
2642
|
+
----------
|
|
2643
|
+
variable_name : str
|
|
2644
|
+
Variable name.
|
|
2787
2645
|
|
|
2788
2646
|
Returns
|
|
2789
2647
|
-------
|
|
2790
2648
|
bool
|
|
2649
|
+
True if variable exists.
|
|
2791
2650
|
"""
|
|
2792
2651
|
if "$" in variable_name:
|
|
2793
2652
|
if variable_name.index("$") == 0:
|
|
@@ -2801,15 +2660,17 @@ class Edb(EdbInit):
|
|
|
2801
2660
|
return False
|
|
2802
2661
|
|
|
2803
2662
|
def get_variable(self, variable_name):
|
|
2804
|
-
"""
|
|
2663
|
+
"""Get variable value.
|
|
2805
2664
|
|
|
2806
2665
|
Parameters
|
|
2807
2666
|
----------
|
|
2808
|
-
variable_name
|
|
2667
|
+
variable_name : str
|
|
2668
|
+
Variable name.
|
|
2809
2669
|
|
|
2810
2670
|
Returns
|
|
2811
2671
|
-------
|
|
2812
|
-
float
|
|
2672
|
+
float or bool
|
|
2673
|
+
Variable value if exists, else False.
|
|
2813
2674
|
"""
|
|
2814
2675
|
if self.variable_exists(variable_name):
|
|
2815
2676
|
if "$" in variable_name:
|
|
@@ -2822,30 +2683,21 @@ class Edb(EdbInit):
|
|
|
2822
2683
|
return False
|
|
2823
2684
|
|
|
2824
2685
|
def add_project_variable(self, variable_name, variable_value, description=None) -> bool:
|
|
2825
|
-
"""Add
|
|
2686
|
+
"""Add project variable.
|
|
2826
2687
|
|
|
2827
2688
|
Parameters
|
|
2828
2689
|
----------
|
|
2829
2690
|
variable_name : str
|
|
2830
|
-
|
|
2691
|
+
Variable name (auto-prefixed with '$').
|
|
2831
2692
|
variable_value : str, float
|
|
2832
|
-
|
|
2833
|
-
description : str, optional
|
|
2834
|
-
|
|
2693
|
+
Variable value with units.
|
|
2694
|
+
description : str, optional
|
|
2695
|
+
Variable description.
|
|
2835
2696
|
|
|
2836
2697
|
Returns
|
|
2837
2698
|
-------
|
|
2838
2699
|
bool
|
|
2839
|
-
|
|
2840
|
-
Examples
|
|
2841
|
-
--------
|
|
2842
|
-
|
|
2843
|
-
>>> from pyedb import Edb
|
|
2844
|
-
>>> edb_app = Edb()
|
|
2845
|
-
>>> boolean_1, ant_length = edb_app.add_project_variable("my_local_variable", "1cm")
|
|
2846
|
-
>>> print(edb_app["$my_local_variable"]) #using getitem
|
|
2847
|
-
>>> edb_app["$my_local_variable"] = "1cm" #using setitem
|
|
2848
|
-
|
|
2700
|
+
True if successful, False if variable exists.
|
|
2849
2701
|
"""
|
|
2850
2702
|
if not variable_name.startswith("$"):
|
|
2851
2703
|
variable_name = f"${variable_name}"
|
|
@@ -2859,37 +2711,23 @@ class Edb(EdbInit):
|
|
|
2859
2711
|
return False
|
|
2860
2712
|
|
|
2861
2713
|
def add_design_variable(self, variable_name, variable_value, is_parameter=False, description=None) -> bool:
|
|
2862
|
-
"""Add
|
|
2714
|
+
"""Add design variable.
|
|
2863
2715
|
|
|
2864
2716
|
Parameters
|
|
2865
2717
|
----------
|
|
2866
2718
|
variable_name : str
|
|
2867
|
-
|
|
2868
|
-
must begin with ``$``.
|
|
2719
|
+
Variable name.
|
|
2869
2720
|
variable_value : str, float
|
|
2870
|
-
|
|
2721
|
+
Variable value with units.
|
|
2871
2722
|
is_parameter : bool, optional
|
|
2872
|
-
|
|
2873
|
-
When ``True``, the variable is added as a parameter default.
|
|
2723
|
+
Add as local variable. Default False.
|
|
2874
2724
|
description : str, optional
|
|
2875
|
-
|
|
2725
|
+
Variable description.
|
|
2876
2726
|
|
|
2877
2727
|
Returns
|
|
2878
2728
|
-------
|
|
2879
|
-
bool
|
|
2880
|
-
|
|
2881
|
-
Examples
|
|
2882
|
-
--------
|
|
2883
|
-
|
|
2884
|
-
>>> from pyedb import Edb
|
|
2885
|
-
>>> edb_app = Edb()
|
|
2886
|
-
>>> boolean_1, ant_length = edb_app.add_design_variable("my_local_variable", "1cm")
|
|
2887
|
-
>>> print(edb_app["my_local_variable"]) #using getitem
|
|
2888
|
-
>>> edb_app["my_local_variable"] = "1cm" #using setitem
|
|
2889
|
-
>>> boolean_2, para_length = edb_app.change_design_variable_value("my_parameter", "1m", is_parameter=True
|
|
2890
|
-
>>> boolean_3, project_length = edb_app.change_design_variable_value("$my_project_variable", "1m")
|
|
2891
|
-
|
|
2892
|
-
|
|
2729
|
+
bool
|
|
2730
|
+
True if successful, False if variable exists.
|
|
2893
2731
|
"""
|
|
2894
2732
|
if variable_name.startswith("$"):
|
|
2895
2733
|
variable_name = variable_name[1:]
|
|
@@ -2903,27 +2741,14 @@ class Edb(EdbInit):
|
|
|
2903
2741
|
return False
|
|
2904
2742
|
|
|
2905
2743
|
def change_design_variable_value(self, variable_name, variable_value):
|
|
2906
|
-
"""
|
|
2744
|
+
"""Update variable value.
|
|
2907
2745
|
|
|
2908
2746
|
Parameters
|
|
2909
2747
|
----------
|
|
2910
2748
|
variable_name : str
|
|
2911
|
-
|
|
2749
|
+
Variable name.
|
|
2912
2750
|
variable_value : str, float
|
|
2913
|
-
|
|
2914
|
-
|
|
2915
|
-
Returns
|
|
2916
|
-
-------
|
|
2917
|
-
bool.
|
|
2918
|
-
|
|
2919
|
-
Examples
|
|
2920
|
-
--------
|
|
2921
|
-
|
|
2922
|
-
>>> from pyedb import Edb
|
|
2923
|
-
>>> edb_app = Edb()
|
|
2924
|
-
>>> boolean, ant_length = edb_app.add_design_variable("ant_length", "1cm")
|
|
2925
|
-
>>> boolean, ant_length = edb_app.change_design_variable_value("ant_length", "1m")
|
|
2926
|
-
>>> print(edb_app["ant_length"]) #using getitem
|
|
2751
|
+
New value with units.
|
|
2927
2752
|
"""
|
|
2928
2753
|
if self.variable_exists(variable_name):
|
|
2929
2754
|
if variable_name in self.db.get_all_variable_names():
|
|
@@ -2932,54 +2757,44 @@ class Edb(EdbInit):
|
|
|
2932
2757
|
self.active_cell.set_variable_value(variable_name, GrpcValue(variable_value))
|
|
2933
2758
|
|
|
2934
2759
|
def get_bounding_box(self) -> list[list[float, float], list[float, float]]:
|
|
2935
|
-
"""Get
|
|
2760
|
+
"""Get layout bounding box.
|
|
2936
2761
|
|
|
2937
2762
|
Returns
|
|
2938
2763
|
-------
|
|
2939
|
-
list
|
|
2940
|
-
|
|
2764
|
+
list
|
|
2765
|
+
[[min_x, min_y], [max_x, max_y]] in meters.
|
|
2941
2766
|
"""
|
|
2942
2767
|
lay_inst_polygon_data = [obj_inst.get_bbox() for obj_inst in self.layout_instance.query_layout_obj_instances()]
|
|
2943
2768
|
layout_bbox = GrpcPolygonData.bbox_of_polygons(lay_inst_polygon_data)
|
|
2944
2769
|
return [[layout_bbox[0].x.value, layout_bbox[0].y.value], [layout_bbox[1].x.value, layout_bbox[1].y.value]]
|
|
2945
2770
|
|
|
2946
2771
|
def get_statistics(self, compute_area=False):
|
|
2947
|
-
"""Get
|
|
2772
|
+
"""Get layout statistics.
|
|
2773
|
+
|
|
2774
|
+
Parameters
|
|
2775
|
+
----------
|
|
2776
|
+
compute_area : bool, optional
|
|
2777
|
+
Calculate net areas. Default False.
|
|
2948
2778
|
|
|
2949
2779
|
Returns
|
|
2950
2780
|
-------
|
|
2951
2781
|
:class:`LayoutStatistics <pyedb.grpc.database.utility.layout_statistics.LayoutStatistics>`
|
|
2782
|
+
Layout statistics report.
|
|
2952
2783
|
"""
|
|
2953
2784
|
return self.modeler.get_layout_statistics(evaluate_area=compute_area, net_list=None)
|
|
2954
2785
|
|
|
2955
2786
|
def are_port_reference_terminals_connected(self, common_reference=None):
|
|
2956
|
-
"""Check if
|
|
2957
|
-
If the reference nets are different, there is no hope for the terminal references to be connected.
|
|
2958
|
-
After we have identified a common reference net we need to loop the terminals again to get
|
|
2959
|
-
the correct reference terminals that uses that net.
|
|
2787
|
+
"""Check if port reference terminals are connected.
|
|
2960
2788
|
|
|
2961
2789
|
Parameters
|
|
2962
2790
|
----------
|
|
2963
2791
|
common_reference : str, optional
|
|
2964
|
-
|
|
2965
|
-
If a string is passed then all excitations must have such reference assigned.
|
|
2792
|
+
Reference net name to check.
|
|
2966
2793
|
|
|
2967
2794
|
Returns
|
|
2968
2795
|
-------
|
|
2969
2796
|
bool
|
|
2970
|
-
|
|
2971
|
-
|
|
2972
|
-
Examples
|
|
2973
|
-
--------
|
|
2974
|
-
>>> from pyedb import Edb
|
|
2975
|
-
>>>edb = Edb()
|
|
2976
|
-
>>> edb.hfss.create_edge_port_vertical(prim_1_id, ["-66mm", "-4mm"], "port_ver")
|
|
2977
|
-
>>> edb.hfss.create_edge_port_horizontal(
|
|
2978
|
-
>>> ... prim_1_id, ["-60mm", "-4mm"], prim_2_id, ["-59mm", "-4mm"], "port_hori", 30, "Lower"
|
|
2979
|
-
>>> ... )
|
|
2980
|
-
>>> edb.hfss.create_wave_port(traces[0].id, trace_paths[0][0], "wave_port")
|
|
2981
|
-
>>> edb.cutout(["Net1"])
|
|
2982
|
-
>>> assert edb.are_port_reference_terminals_connected()
|
|
2797
|
+
True if all port references are connected.
|
|
2983
2798
|
"""
|
|
2984
2799
|
all_sources = [i for i in self.excitations.values() if not isinstance(i, (WavePort, GapPort, BundleWavePort))]
|
|
2985
2800
|
all_sources.extend([i for i in self.sources.values()])
|
|
@@ -2987,7 +2802,10 @@ class Edb(EdbInit):
|
|
|
2987
2802
|
return True
|
|
2988
2803
|
self.logger.reset_timer()
|
|
2989
2804
|
if not common_reference:
|
|
2990
|
-
|
|
2805
|
+
ref_terminals = [term for term in all_sources if term.is_reference_terminal]
|
|
2806
|
+
common_reference = list(
|
|
2807
|
+
set([i.reference_terminal.net.name for i in all_sources if i.is_reference_terminal])
|
|
2808
|
+
)
|
|
2991
2809
|
if len(common_reference) > 1:
|
|
2992
2810
|
self.logger.error("More than 1 reference found.")
|
|
2993
2811
|
return False
|
|
@@ -3137,17 +2955,18 @@ class Edb(EdbInit):
|
|
|
3137
2955
|
)
|
|
3138
2956
|
|
|
3139
2957
|
def create_raptorx_setup(self, name=None) -> RaptorXSimulationSetup:
|
|
3140
|
-
"""Create
|
|
2958
|
+
"""Create RaptorX analysis setup (2024R2+ only).
|
|
3141
2959
|
|
|
3142
2960
|
Parameters
|
|
3143
2961
|
----------
|
|
3144
2962
|
name : str, optional
|
|
3145
|
-
Setup name.
|
|
2963
|
+
Setup name. Auto-generated if None.
|
|
3146
2964
|
|
|
3147
2965
|
Returns
|
|
3148
2966
|
-------
|
|
3149
|
-
:class:`RaptorXSimulationSetup
|
|
3150
|
-
|
|
2967
|
+
:class:`RaptorXSimulationSetup
|
|
2968
|
+
<pyedb.grpc.database.simulation_setup.raptor_x_simulation_setup.RaptorXSimulationSetup>`
|
|
2969
|
+
RaptorX setup or False if unsupported.
|
|
3151
2970
|
"""
|
|
3152
2971
|
from ansys.edb.core.simulation_setup.raptor_x_simulation_setup import (
|
|
3153
2972
|
RaptorXSimulationSetup as GrpcRaptorXSimulationSetup,
|
|
@@ -3191,28 +3010,20 @@ class Edb(EdbInit):
|
|
|
3191
3010
|
pass
|
|
3192
3011
|
|
|
3193
3012
|
def create_siwave_syz_setup(self, name=None, **kwargs) -> SiwaveSimulationSetup:
|
|
3194
|
-
"""Create
|
|
3013
|
+
"""Create SIwave SYZ analysis setup.
|
|
3195
3014
|
|
|
3196
3015
|
Parameters
|
|
3197
3016
|
----------
|
|
3198
3017
|
name : str, optional
|
|
3199
|
-
Setup name.
|
|
3018
|
+
Setup name. Auto-generated if None.
|
|
3019
|
+
**kwargs
|
|
3020
|
+
Setup properties to modify.
|
|
3200
3021
|
|
|
3201
3022
|
Returns
|
|
3202
3023
|
-------
|
|
3203
3024
|
:class:`SiwaveSimulationSetup
|
|
3204
3025
|
<pyedb.grpc.database.simulation_setup.siwave_simulation_setup.SiwaveSimulationSetup>`
|
|
3205
|
-
|
|
3206
|
-
Examples
|
|
3207
|
-
--------
|
|
3208
|
-
>>> from pyedb import Edb
|
|
3209
|
-
>>> edbapp = Edb()
|
|
3210
|
-
>>> setup1 = edbapp.create_siwave_syz_setup("setup1")
|
|
3211
|
-
>>> setup1.add_frequency_sweep(frequency_sweep=[
|
|
3212
|
-
... ["linear count", "0", "1kHz", 1],
|
|
3213
|
-
... ["log scale", "1kHz", "0.1GHz", 10],
|
|
3214
|
-
... ["linear scale", "0.1GHz", "10GHz", "0.1GHz"],
|
|
3215
|
-
... ])
|
|
3026
|
+
SYZ analysis setup.
|
|
3216
3027
|
"""
|
|
3217
3028
|
if not name:
|
|
3218
3029
|
name = generate_unique_name("Siwave_SYZ")
|
|
@@ -3228,25 +3039,20 @@ class Edb(EdbInit):
|
|
|
3228
3039
|
return self.setups[name]
|
|
3229
3040
|
|
|
3230
3041
|
def create_siwave_dc_setup(self, name=None, **kwargs) -> GrpcSIWaveDCIRSimulationSetup:
|
|
3231
|
-
"""Create
|
|
3042
|
+
"""Create SIwave DC analysis setup.
|
|
3232
3043
|
|
|
3233
3044
|
Parameters
|
|
3234
3045
|
----------
|
|
3235
3046
|
name : str, optional
|
|
3236
|
-
Setup name.
|
|
3047
|
+
Setup name. Auto-generated if None.
|
|
3048
|
+
**kwargs
|
|
3049
|
+
Setup properties to modify.
|
|
3237
3050
|
|
|
3238
3051
|
Returns
|
|
3239
3052
|
-------
|
|
3240
3053
|
:class:`SIWaveDCIRSimulationSetup
|
|
3241
3054
|
<pyedb.grpc.database.simulation_setup.siwave_dcir_simulation_setup.SIWaveDCIRSimulationSetup>`
|
|
3242
|
-
|
|
3243
|
-
Examples
|
|
3244
|
-
--------
|
|
3245
|
-
>>> from pyedb import Edb
|
|
3246
|
-
>>> edbapp = Edb()
|
|
3247
|
-
>>> setup1 = edbapp.create_siwave_dc_setup("setup1")
|
|
3248
|
-
>>> setup1.mesh_bondwires = True
|
|
3249
|
-
|
|
3055
|
+
DC analysis setup.
|
|
3250
3056
|
"""
|
|
3251
3057
|
if not name:
|
|
3252
3058
|
name = generate_unique_name("Siwave_DC")
|
|
@@ -3274,7 +3080,7 @@ class Edb(EdbInit):
|
|
|
3274
3080
|
for port in self.excitations.values():
|
|
3275
3081
|
nets.append(port.net.name)
|
|
3276
3082
|
for port in self.sources.values():
|
|
3277
|
-
nets.append(port.
|
|
3083
|
+
nets.append(port.net.name)
|
|
3278
3084
|
nets = list(set(nets))
|
|
3279
3085
|
max_width = 0
|
|
3280
3086
|
for net in nets:
|
|
@@ -3633,51 +3439,58 @@ class Edb(EdbInit):
|
|
|
3633
3439
|
expand_voids_size=0,
|
|
3634
3440
|
via_offset=True,
|
|
3635
3441
|
):
|
|
3636
|
-
"""
|
|
3442
|
+
"""Automatically parametrize design elements.
|
|
3637
3443
|
|
|
3638
3444
|
Parameters
|
|
3639
3445
|
----------
|
|
3640
3446
|
layers : bool, optional
|
|
3641
|
-
|
|
3447
|
+
Parametrize layer thicknesses. Default True.
|
|
3642
3448
|
materials : bool, optional
|
|
3643
|
-
|
|
3449
|
+
Parametrize material properties. Default True.
|
|
3644
3450
|
via_holes : bool, optional
|
|
3645
|
-
|
|
3451
|
+
Parametrize via holes. Default True.
|
|
3646
3452
|
pads : bool, optional
|
|
3647
|
-
|
|
3453
|
+
Parametrize pads. Default True.
|
|
3648
3454
|
antipads : bool, optional
|
|
3649
|
-
|
|
3455
|
+
Parametrize antipads. Default True.
|
|
3650
3456
|
traces : bool, optional
|
|
3651
|
-
|
|
3652
|
-
layer_filter :
|
|
3653
|
-
|
|
3654
|
-
material_filter :
|
|
3655
|
-
|
|
3656
|
-
padstack_definition_filter :
|
|
3657
|
-
|
|
3658
|
-
trace_net_filter :
|
|
3659
|
-
|
|
3457
|
+
Parametrize trace widths. Default True.
|
|
3458
|
+
layer_filter : list, optional
|
|
3459
|
+
Layers to include. All if None.
|
|
3460
|
+
material_filter : list, optional
|
|
3461
|
+
Materials to include. All if None.
|
|
3462
|
+
padstack_definition_filter : list, optional
|
|
3463
|
+
Padstacks to include. All if None.
|
|
3464
|
+
trace_net_filter : list, optional
|
|
3465
|
+
Nets to parametrize. All if None.
|
|
3660
3466
|
use_single_variable_for_padstack_definitions : bool, optional
|
|
3661
|
-
|
|
3662
|
-
Default value is ``True``.
|
|
3467
|
+
Single variable per padstack. Default True.
|
|
3663
3468
|
use_relative_variables : bool, optional
|
|
3664
|
-
|
|
3665
|
-
Default value is ``True``.
|
|
3469
|
+
Use delta variables. Default True.
|
|
3666
3470
|
output_aedb_path : str, optional
|
|
3667
|
-
|
|
3471
|
+
Output AEDB path.
|
|
3668
3472
|
open_aedb_at_end : bool, optional
|
|
3669
|
-
|
|
3473
|
+
Open AEDB when finished. Default True.
|
|
3670
3474
|
expand_polygons_size : float, optional
|
|
3671
|
-
|
|
3475
|
+
Polygon expansion size. Default 0.
|
|
3672
3476
|
expand_voids_size : float, optional
|
|
3673
|
-
|
|
3477
|
+
Void expansion size. Default 0.
|
|
3674
3478
|
via_offset : bool, optional
|
|
3675
|
-
|
|
3479
|
+
Parametrize via positions. Default True.
|
|
3676
3480
|
|
|
3677
3481
|
Returns
|
|
3678
3482
|
-------
|
|
3679
|
-
|
|
3680
|
-
|
|
3483
|
+
list[str]
|
|
3484
|
+
Created parameter names.
|
|
3485
|
+
|
|
3486
|
+
Examples
|
|
3487
|
+
--------
|
|
3488
|
+
Parametrize design elements:
|
|
3489
|
+
>>> params = edb.auto_parametrize_design(
|
|
3490
|
+
... layers=True,
|
|
3491
|
+
... materials=True,
|
|
3492
|
+
... trace_net_filter=["Clock"]
|
|
3493
|
+
... )
|
|
3681
3494
|
"""
|
|
3682
3495
|
edb_original_path = self.edbpath
|
|
3683
3496
|
if output_aedb_path:
|
|
@@ -3904,41 +3717,27 @@ class Edb(EdbInit):
|
|
|
3904
3717
|
output_edb=None,
|
|
3905
3718
|
launching_box_thickness="100um",
|
|
3906
3719
|
):
|
|
3907
|
-
"""
|
|
3908
|
-
This model has to be considered as merged onto another one. The current opened design must have voids
|
|
3909
|
-
surrounding the pad-stacks where wave ports terminal will be created. THe open design won't be edited, only
|
|
3910
|
-
primitives like voids and pads-stack definition included in the voids are collected to generate a new design.
|
|
3720
|
+
"""Create simplified model for arbitrary wave port generation.
|
|
3911
3721
|
|
|
3912
3722
|
Parameters
|
|
3913
3723
|
----------
|
|
3914
3724
|
temp_directory : str
|
|
3915
|
-
|
|
3916
|
-
|
|
3917
|
-
|
|
3918
|
-
|
|
3919
|
-
|
|
3920
|
-
|
|
3921
|
-
|
|
3922
|
-
signal_nets : List[str], optional
|
|
3923
|
-
Provides the nets to be included for the model creation. Default value is ``None``. If None is provided,
|
|
3924
|
-
all nets will be included.
|
|
3925
|
-
|
|
3926
|
-
terminal_diameter : float, str, optional
|
|
3927
|
-
When ``None``, the terminal diameter is evaluated at each pads-tack instance found inside the voids. The top
|
|
3928
|
-
or bottom layer pad diameter will be taken, depending on ``mounting_side`` selected. If value is provided,
|
|
3929
|
-
it will overwrite the evaluated diameter.
|
|
3930
|
-
|
|
3725
|
+
Working directory.
|
|
3726
|
+
mounting_side : str, optional
|
|
3727
|
+
Board orientation ("top" or "bottom").
|
|
3728
|
+
signal_nets : list, optional
|
|
3729
|
+
Nets to include. All if None.
|
|
3730
|
+
terminal_diameter : float, optional
|
|
3731
|
+
Custom terminal diameter. Auto-calculated if None.
|
|
3931
3732
|
output_edb : str, optional
|
|
3932
|
-
|
|
3933
|
-
|
|
3934
|
-
|
|
3935
|
-
launching_box_thickness : float, str, optional
|
|
3936
|
-
Launching box thickness used for wave ports. Default value is ``"100um"``.
|
|
3733
|
+
Output AEDB path.
|
|
3734
|
+
launching_box_thickness : str, optional
|
|
3735
|
+
Wave port box thickness.
|
|
3937
3736
|
|
|
3938
3737
|
Returns
|
|
3939
3738
|
-------
|
|
3940
3739
|
bool
|
|
3941
|
-
|
|
3740
|
+
True if successful, False otherwise.
|
|
3942
3741
|
"""
|
|
3943
3742
|
if not temp_directory:
|
|
3944
3743
|
self.logger.error("Temp directory must be provided when creating model foe arbitrary wave port")
|
|
@@ -4059,11 +3858,12 @@ class Edb(EdbInit):
|
|
|
4059
3858
|
|
|
4060
3859
|
@property
|
|
4061
3860
|
def definitions(self):
|
|
4062
|
-
"""
|
|
3861
|
+
"""EDB definitions access.
|
|
4063
3862
|
|
|
4064
3863
|
Returns
|
|
4065
3864
|
-------
|
|
4066
3865
|
:class:`Definitions <pyedb.grpc.database.definitions.Definitions>`
|
|
3866
|
+
Definitions interface.
|
|
4067
3867
|
"""
|
|
4068
3868
|
from pyedb.grpc.database.definitions import Definitions
|
|
4069
3869
|
|
|
@@ -4071,28 +3871,31 @@ class Edb(EdbInit):
|
|
|
4071
3871
|
|
|
4072
3872
|
@property
|
|
4073
3873
|
def workflow(self):
|
|
4074
|
-
"""
|
|
3874
|
+
"""Workflow automation interface.
|
|
4075
3875
|
|
|
4076
3876
|
Returns
|
|
4077
|
-
|
|
3877
|
+
-------
|
|
4078
3878
|
:class:`Workflow <pyedb.workflow.Workflow>`
|
|
3879
|
+
Workflow automation tools.
|
|
4079
3880
|
"""
|
|
4080
3881
|
return Workflow(self)
|
|
4081
3882
|
|
|
4082
3883
|
def export_gds_comp_xml(self, comps_to_export, gds_comps_unit="mm", control_path=None):
|
|
4083
|
-
"""
|
|
3884
|
+
"""Export component data to GDS XML control file.
|
|
3885
|
+
|
|
4084
3886
|
Parameters
|
|
4085
3887
|
----------
|
|
4086
3888
|
comps_to_export : list
|
|
4087
|
-
|
|
3889
|
+
Components to export.
|
|
4088
3890
|
gds_comps_unit : str, optional
|
|
4089
|
-
|
|
3891
|
+
Output units. Default "mm".
|
|
4090
3892
|
control_path : str, optional
|
|
4091
|
-
|
|
3893
|
+
Output XML path.
|
|
3894
|
+
|
|
4092
3895
|
Returns
|
|
4093
3896
|
-------
|
|
4094
3897
|
bool
|
|
4095
|
-
|
|
3898
|
+
True if successful, False otherwise.
|
|
4096
3899
|
"""
|
|
4097
3900
|
from pyedb.generic.general_methods import ET
|
|
4098
3901
|
|