pyedb 0.50.1__py3-none-any.whl → 0.52.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of pyedb might be problematic. Click here for more details.
- pyedb/__init__.py +1 -1
- pyedb/configuration/cfg_ports_sources.py +79 -239
- pyedb/configuration/configuration.py +213 -340
- pyedb/dotnet/clr_module.py +9 -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 +8 -2
- pyedb/dotnet/database/layout_validation.py +20 -26
- pyedb/dotnet/database/modeler.py +0 -1
- pyedb/dotnet/database/stackup.py +4 -3
- pyedb/dotnet/edb.py +42 -2
- pyedb/generic/design_types.py +183 -62
- pyedb/grpc/database/__init__.py +0 -1
- pyedb/grpc/database/components.py +110 -0
- pyedb/grpc/database/control_file.py +150 -17
- pyedb/grpc/database/definition/materials.py +7 -7
- pyedb/grpc/database/definitions.py +36 -2
- pyedb/grpc/database/hfss.py +15 -0
- pyedb/grpc/database/hierarchy/component.py +10 -2
- pyedb/grpc/database/hierarchy/pin_pair_model.py +1 -1
- pyedb/grpc/database/layout_validation.py +58 -7
- pyedb/grpc/database/net/differential_pair.py +2 -1
- pyedb/grpc/database/nets.py +233 -4
- pyedb/grpc/database/padstacks.py +97 -0
- pyedb/grpc/database/primitive/padstack_instance.py +1 -1
- pyedb/grpc/database/primitive/polygon.py +1 -1
- pyedb/grpc/database/siwave.py +63 -3
- pyedb/grpc/database/source_excitations.py +317 -50
- pyedb/grpc/database/stackup.py +107 -2
- pyedb/grpc/database/terminal/point_terminal.py +2 -2
- pyedb/grpc/database/terminal/terminal.py +1 -1
- pyedb/grpc/edb.py +190 -224
- pyedb/grpc/edb_init.py +54 -5
- {pyedb-0.50.1.dist-info → pyedb-0.52.0.dist-info}/METADATA +4 -4
- {pyedb-0.50.1.dist-info → pyedb-0.52.0.dist-info}/RECORD +37 -37
- {pyedb-0.50.1.dist-info → pyedb-0.52.0.dist-info}/LICENSE +0 -0
- {pyedb-0.50.1.dist-info → pyedb-0.52.0.dist-info}/WHEEL +0 -0
pyedb/grpc/edb.py
CHANGED
|
@@ -178,13 +178,13 @@ class Edb(EdbInit):
|
|
|
178
178
|
|
|
179
179
|
Examples
|
|
180
180
|
--------
|
|
181
|
-
Create new EDB:
|
|
181
|
+
>>> # Create new EDB:
|
|
182
182
|
>>> edb = Edb()
|
|
183
183
|
|
|
184
|
-
Open existing AEDB:
|
|
184
|
+
>>> # Open existing AEDB:
|
|
185
185
|
>>> edb = Edb("myproject.aedb")
|
|
186
186
|
|
|
187
|
-
Import board file:
|
|
187
|
+
>>> # Import board file:
|
|
188
188
|
>>> edb = Edb("my_board.brd")
|
|
189
189
|
"""
|
|
190
190
|
|
|
@@ -378,23 +378,6 @@ class Edb(EdbInit):
|
|
|
378
378
|
except:
|
|
379
379
|
self.logger.info(f"Failed to delete AEDT project-related file {file}.")
|
|
380
380
|
|
|
381
|
-
def _clean_variables(self):
|
|
382
|
-
"""Initialize internal variables and perform garbage collection."""
|
|
383
|
-
self.grpc = True
|
|
384
|
-
self._materials = None
|
|
385
|
-
self._components = None
|
|
386
|
-
self._core_primitives = None
|
|
387
|
-
self._stackup = None
|
|
388
|
-
self._padstack = None
|
|
389
|
-
self._siwave = None
|
|
390
|
-
self._hfss = None
|
|
391
|
-
self._nets = None
|
|
392
|
-
self._layout_instance = None
|
|
393
|
-
self._variables = None
|
|
394
|
-
self._active_cell = None
|
|
395
|
-
self._layout = None
|
|
396
|
-
self._configuration = None
|
|
397
|
-
|
|
398
381
|
def _init_objects(self):
|
|
399
382
|
self._components = Components(self)
|
|
400
383
|
self._stackup = Stackup(self, self.layout.layer_collection)
|
|
@@ -503,7 +486,7 @@ class Edb(EdbInit):
|
|
|
503
486
|
|
|
504
487
|
Returns
|
|
505
488
|
-------
|
|
506
|
-
dict[str,
|
|
489
|
+
dict[str, list[:class:`GapPort` or :class:`WavePort` or :class:`CoaxPort`]]
|
|
507
490
|
Port names and objects.
|
|
508
491
|
"""
|
|
509
492
|
terminals = [term for term in self.layout.terminals if not term.is_reference_terminal]
|
|
@@ -579,19 +562,24 @@ class Edb(EdbInit):
|
|
|
579
562
|
terms = [term for term in self.layout.terminals if term.boundary_type.value == 8]
|
|
580
563
|
return {ter.name: ter for ter in terms}
|
|
581
564
|
|
|
582
|
-
def
|
|
565
|
+
def open(self, restart_rpc_server=False) -> bool:
|
|
583
566
|
"""Open EDB database.
|
|
584
567
|
|
|
585
568
|
Returns
|
|
586
569
|
-------
|
|
587
570
|
bool
|
|
588
571
|
True if successful, False otherwise.
|
|
572
|
+
|
|
573
|
+
Examples
|
|
574
|
+
--------
|
|
575
|
+
>>> # Open an existing EDB database:
|
|
576
|
+
>>> edb = Edb("myproject.aedb")
|
|
589
577
|
"""
|
|
590
578
|
self.standalone = self.standalone
|
|
591
579
|
n_try = 10
|
|
592
580
|
while not self.db and n_try:
|
|
593
581
|
try:
|
|
594
|
-
self.
|
|
582
|
+
self._open(
|
|
595
583
|
self.edbpath,
|
|
596
584
|
self.isreadonly,
|
|
597
585
|
restart_rpc_server=restart_rpc_server,
|
|
@@ -621,7 +609,21 @@ class Edb(EdbInit):
|
|
|
621
609
|
self.logger.error("Builder was not initialized.")
|
|
622
610
|
return True
|
|
623
611
|
|
|
624
|
-
def
|
|
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.
|
|
617
|
+
|
|
618
|
+
Returns
|
|
619
|
+
-------
|
|
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:
|
|
625
627
|
"""Create new EDB database.
|
|
626
628
|
|
|
627
629
|
Returns
|
|
@@ -636,7 +638,7 @@ class Edb(EdbInit):
|
|
|
636
638
|
n_try = 10
|
|
637
639
|
while not self.db and n_try:
|
|
638
640
|
try:
|
|
639
|
-
self.
|
|
641
|
+
self._create(self.edbpath, restart_rpc_server=restart_rpc_server)
|
|
640
642
|
n_try -= 1
|
|
641
643
|
except Exception as e:
|
|
642
644
|
self.logger.error(e.args[0])
|
|
@@ -651,9 +653,22 @@ class Edb(EdbInit):
|
|
|
651
653
|
)
|
|
652
654
|
if self._active_cell:
|
|
653
655
|
self._init_objects()
|
|
654
|
-
return
|
|
656
|
+
return self
|
|
655
657
|
return None
|
|
656
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
|
+
|
|
657
672
|
def import_layout_pcb(
|
|
658
673
|
self,
|
|
659
674
|
input_file,
|
|
@@ -746,6 +761,12 @@ class Edb(EdbInit):
|
|
|
746
761
|
-------
|
|
747
762
|
Full path to the AEDB file : str
|
|
748
763
|
|
|
764
|
+
Examples
|
|
765
|
+
--------
|
|
766
|
+
>>> # Import a BRD file:
|
|
767
|
+
>>> edb.import_layout_file("my_board.brd", r"C:/project")
|
|
768
|
+
>>> # Import a GDS file with control file:
|
|
769
|
+
>>> edb.import_layout_file("layout.gds", control_file="control.xml")
|
|
749
770
|
"""
|
|
750
771
|
self._components = None
|
|
751
772
|
self._core_primitives = None
|
|
@@ -806,6 +827,11 @@ class Edb(EdbInit):
|
|
|
806
827
|
-------
|
|
807
828
|
str or bool
|
|
808
829
|
Output file path if successful, False otherwise.
|
|
830
|
+
|
|
831
|
+
Examples
|
|
832
|
+
--------
|
|
833
|
+
>>> # Export to IPC2581 format:
|
|
834
|
+
>>> edb.export_to_ipc2581("output.xml")
|
|
809
835
|
"""
|
|
810
836
|
if units.lower() not in ["millimeter", "inch", "micron"]: # pragma no cover
|
|
811
837
|
self.logger.warning("The wrong unit is entered. Setting to the default, millimeter.")
|
|
@@ -1182,18 +1208,6 @@ class Edb(EdbInit):
|
|
|
1182
1208
|
else:
|
|
1183
1209
|
return PointData(x, y)
|
|
1184
1210
|
|
|
1185
|
-
@staticmethod
|
|
1186
|
-
def _is_file_existing_and_released(filename) -> bool:
|
|
1187
|
-
if os.path.exists(filename):
|
|
1188
|
-
try:
|
|
1189
|
-
os.rename(filename, filename + "_")
|
|
1190
|
-
os.rename(filename + "_", filename)
|
|
1191
|
-
return True
|
|
1192
|
-
except OSError as e:
|
|
1193
|
-
return False
|
|
1194
|
-
else:
|
|
1195
|
-
return False
|
|
1196
|
-
|
|
1197
1211
|
@staticmethod
|
|
1198
1212
|
def _is_file_existing(filename) -> bool:
|
|
1199
1213
|
if os.path.exists(filename):
|
|
@@ -1201,18 +1215,6 @@ class Edb(EdbInit):
|
|
|
1201
1215
|
else:
|
|
1202
1216
|
return False
|
|
1203
1217
|
|
|
1204
|
-
def _wait_for_file_release(self, timeout=30, file_to_release=None) -> bool:
|
|
1205
|
-
if not file_to_release:
|
|
1206
|
-
file_to_release = os.path.join(self.edbpath)
|
|
1207
|
-
tstart = time.time()
|
|
1208
|
-
while True:
|
|
1209
|
-
if self._is_file_existing_and_released(file_to_release):
|
|
1210
|
-
return True
|
|
1211
|
-
elif time.time() - tstart > timeout:
|
|
1212
|
-
return False
|
|
1213
|
-
else:
|
|
1214
|
-
time.sleep(0.250)
|
|
1215
|
-
|
|
1216
1218
|
def _wait_for_file_exists(self, timeout=30, file_to_release=None, wait_count=4):
|
|
1217
1219
|
if not file_to_release:
|
|
1218
1220
|
file_to_release = os.path.join(self.edbpath)
|
|
@@ -1234,57 +1236,40 @@ class Edb(EdbInit):
|
|
|
1234
1236
|
def close_edb(self) -> bool:
|
|
1235
1237
|
"""Close EDB and clean up resources.
|
|
1236
1238
|
|
|
1239
|
+
..deprecated:: 0.51.0
|
|
1240
|
+
Use :func:`close` instead.
|
|
1241
|
+
|
|
1237
1242
|
Returns
|
|
1238
1243
|
-------
|
|
1239
1244
|
bool
|
|
1240
1245
|
True if successful, False otherwise.
|
|
1246
|
+
|
|
1247
|
+
Examples
|
|
1248
|
+
--------
|
|
1249
|
+
Close the EDB session:
|
|
1250
|
+
>>> edb.close_edb()
|
|
1241
1251
|
"""
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
self._wait_for_file_release()
|
|
1245
|
-
elapsed_time = time.time() - start_time
|
|
1246
|
-
self.logger.info("EDB file release time: {0:.2f}ms".format(elapsed_time * 1000.0))
|
|
1247
|
-
self._clean_variables()
|
|
1248
|
-
return True
|
|
1252
|
+
warnings.warn("Use method close instead.", DeprecationWarning)
|
|
1253
|
+
return self.close()
|
|
1249
1254
|
|
|
1250
1255
|
def save_edb(self) -> bool:
|
|
1251
1256
|
"""Save current EDB database.
|
|
1252
1257
|
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
True if successful, False otherwise.
|
|
1258
|
+
..deprecated:: 0.51.0
|
|
1259
|
+
Use :func:`save` instead.
|
|
1260
|
+
|
|
1257
1261
|
"""
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
self._wait_for_file_release()
|
|
1261
|
-
elapsed_time = time.time() - start_time
|
|
1262
|
-
self.logger.info("EDB file save time: {0:.2f}ms".format(elapsed_time * 1000.0))
|
|
1263
|
-
return True
|
|
1262
|
+
warnings.warn("Use method save instead.", DeprecationWarning)
|
|
1263
|
+
return self.save()
|
|
1264
1264
|
|
|
1265
1265
|
def save_edb_as(self, fname) -> bool:
|
|
1266
1266
|
"""Save EDB database to new location.
|
|
1267
1267
|
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
fname : str
|
|
1271
|
-
New AEDB path.
|
|
1272
|
-
|
|
1273
|
-
Returns
|
|
1274
|
-
-------
|
|
1275
|
-
bool
|
|
1276
|
-
True if successful, False otherwise.
|
|
1268
|
+
..deprecated:: 0.51.0
|
|
1269
|
+
Use :func:`save_as` instead.
|
|
1277
1270
|
"""
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
self._wait_for_file_release()
|
|
1281
|
-
elapsed_time = time.time() - start_time
|
|
1282
|
-
self.logger.info("EDB file save time: {0:.2f}ms".format(elapsed_time * 1000.0))
|
|
1283
|
-
self.edbpath = self.directory
|
|
1284
|
-
self.log_name = os.path.join(
|
|
1285
|
-
os.path.dirname(fname), "pyedb_" + os.path.splitext(os.path.split(fname)[-1])[0] + ".log"
|
|
1286
|
-
)
|
|
1287
|
-
return True
|
|
1271
|
+
warnings.warn("Use method save_as instead.", DeprecationWarning)
|
|
1272
|
+
return self.save_as(fname)
|
|
1288
1273
|
|
|
1289
1274
|
def execute(self, func):
|
|
1290
1275
|
"""Execute EDB utility command (Not implemented in gRPC).
|
|
@@ -1297,8 +1282,12 @@ class Edb(EdbInit):
|
|
|
1297
1282
|
# return self.edb_api.utility.utility.Command.Execute(func)
|
|
1298
1283
|
pass
|
|
1299
1284
|
|
|
1300
|
-
def import_cadence_file(self, inputBrd, WorkDir=None, anstranslator_full_path="", use_ppe=False):
|
|
1301
|
-
"""Import Cadence board file
|
|
1285
|
+
def import_cadence_file(self, inputBrd, WorkDir=None, anstranslator_full_path="", use_ppe=False) -> bool:
|
|
1286
|
+
"""Import Cadence board file.
|
|
1287
|
+
|
|
1288
|
+
.. deprecated:: 0.50
|
|
1289
|
+
Use :func:`import_layout_file` instead.
|
|
1290
|
+
"""
|
|
1302
1291
|
if self.import_layout_pcb(
|
|
1303
1292
|
inputBrd,
|
|
1304
1293
|
working_dir=WorkDir,
|
|
@@ -1694,6 +1683,14 @@ class Edb(EdbInit):
|
|
|
1694
1683
|
-------
|
|
1695
1684
|
list or bool
|
|
1696
1685
|
Cutout boundary points if successful, False otherwise.
|
|
1686
|
+
|
|
1687
|
+
Examples
|
|
1688
|
+
--------
|
|
1689
|
+
>>> # Create a basic cutout:
|
|
1690
|
+
>>> edb.cutout(signal_list=["Net1"], reference_list=["GND"])
|
|
1691
|
+
>>> # Create cutout with custom polygon:
|
|
1692
|
+
>>> custom_poly = [[0,0], [10e-3,0], [10e-3,10e-3], [0,10e-3]]
|
|
1693
|
+
>>> edb.cutout(custom_extent=custom_poly)
|
|
1697
1694
|
"""
|
|
1698
1695
|
if expansion_factor > 0:
|
|
1699
1696
|
expansion_size = self.calculate_initial_extent(expansion_factor)
|
|
@@ -1770,7 +1767,7 @@ class Edb(EdbInit):
|
|
|
1770
1767
|
break
|
|
1771
1768
|
self.close_edb()
|
|
1772
1769
|
self.edbpath = legacy_path
|
|
1773
|
-
self.
|
|
1770
|
+
self.open()
|
|
1774
1771
|
i += 1
|
|
1775
1772
|
expansion = expansion_size * i
|
|
1776
1773
|
if working_cutout:
|
|
@@ -1856,15 +1853,15 @@ class Edb(EdbInit):
|
|
|
1856
1853
|
# _cutout.simulation_setups = self.active_cell.simulation_setups see bug #433 status.
|
|
1857
1854
|
_dbCells = [_cutout]
|
|
1858
1855
|
if output_aedb_path:
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1856
|
+
from ansys.edb.core.database import Database as GrpcDatabase
|
|
1857
|
+
|
|
1858
|
+
db2 = GrpcDatabase.create(output_aedb_path)
|
|
1862
1859
|
db2.copy_cells(_dbCells) # Copies cutout cell/design to db2 project
|
|
1863
|
-
if len(list(db2.
|
|
1864
|
-
for net in db2.
|
|
1860
|
+
if len(list(db2.top_circuit_cells)) > 0:
|
|
1861
|
+
for net in db2.top_circuit_cells[0].layout.nets:
|
|
1865
1862
|
if not net.name in included_nets_list:
|
|
1866
1863
|
net.delete()
|
|
1867
|
-
|
|
1864
|
+
db2.save()
|
|
1868
1865
|
for c in self.active_db.top_circuit_cells:
|
|
1869
1866
|
if c.name == _cutout.name:
|
|
1870
1867
|
c.delete()
|
|
@@ -1890,7 +1887,7 @@ class Edb(EdbInit):
|
|
|
1890
1887
|
for _cmp in _cmps:
|
|
1891
1888
|
_cmp.delete()
|
|
1892
1889
|
except:
|
|
1893
|
-
self.
|
|
1890
|
+
self.logger.error("Failed to remove single pin components.")
|
|
1894
1891
|
db2.close()
|
|
1895
1892
|
source = os.path.join(output_aedb_path, "edb.def.tmp")
|
|
1896
1893
|
target = os.path.join(output_aedb_path, "edb.def")
|
|
@@ -2342,7 +2339,9 @@ class Edb(EdbInit):
|
|
|
2342
2339
|
|
|
2343
2340
|
_dbCells = [_cutout]
|
|
2344
2341
|
if output_aedb_path:
|
|
2345
|
-
|
|
2342
|
+
from ansys.edb.core.database import Database as GrpcDatabase
|
|
2343
|
+
|
|
2344
|
+
db2 = GrpcDatabase.create(output_aedb_path)
|
|
2346
2345
|
db2.save()
|
|
2347
2346
|
cell_copied = db2.copy_cells(_dbCells) # Copies cutout cell/design to db2 project
|
|
2348
2347
|
cell = cell_copied[0]
|
|
@@ -2352,7 +2351,7 @@ class Edb(EdbInit):
|
|
|
2352
2351
|
if c.name == _cutout.name:
|
|
2353
2352
|
c.delete()
|
|
2354
2353
|
if open_cutout_at_end: # pragma: no cover
|
|
2355
|
-
|
|
2354
|
+
db2.save()
|
|
2356
2355
|
self._db = db2
|
|
2357
2356
|
self.edbpath = output_aedb_path
|
|
2358
2357
|
self._active_cell = cell
|
|
@@ -2436,6 +2435,11 @@ class Edb(EdbInit):
|
|
|
2436
2435
|
-------
|
|
2437
2436
|
str
|
|
2438
2437
|
Path to generated AEDT file.
|
|
2438
|
+
|
|
2439
|
+
Examples
|
|
2440
|
+
--------
|
|
2441
|
+
>>> # Export to HFSS project:
|
|
2442
|
+
>>> edb.export_hfss(r"C:/output", net_list=["SignalNet"])
|
|
2439
2443
|
"""
|
|
2440
2444
|
siwave_s = SiwaveSolve(self.edbpath, aedt_installer_path=self.base_path)
|
|
2441
2445
|
return siwave_s.export_3d_cad("HFSS", path_to_output, net_list, num_cores, aedt_file_name, hidden=hidden)
|
|
@@ -2467,6 +2471,11 @@ class Edb(EdbInit):
|
|
|
2467
2471
|
-------
|
|
2468
2472
|
str
|
|
2469
2473
|
Path to generated AEDT file.
|
|
2474
|
+
|
|
2475
|
+
Examples
|
|
2476
|
+
--------
|
|
2477
|
+
>>> # Export to Q3D project:
|
|
2478
|
+
>>> edb.export_q3d(r"C:/output")
|
|
2470
2479
|
"""
|
|
2471
2480
|
siwave_s = SiwaveSolve(self.edbpath, aedt_installer_path=self.base_path)
|
|
2472
2481
|
return siwave_s.export_3d_cad(
|
|
@@ -2505,6 +2514,11 @@ class Edb(EdbInit):
|
|
|
2505
2514
|
-------
|
|
2506
2515
|
str
|
|
2507
2516
|
Path to generated AEDT file.
|
|
2517
|
+
|
|
2518
|
+
Examples
|
|
2519
|
+
--------
|
|
2520
|
+
>>> # Export to Maxwell project:
|
|
2521
|
+
>>> edb.export_maxwell(r"C:/output")
|
|
2508
2522
|
"""
|
|
2509
2523
|
siwave_s = SiwaveSolve(self.edbpath, aedt_installer_path=self.base_path)
|
|
2510
2524
|
return siwave_s.export_3d_cad(
|
|
@@ -2523,6 +2537,11 @@ class Edb(EdbInit):
|
|
|
2523
2537
|
-------
|
|
2524
2538
|
str
|
|
2525
2539
|
Path to SIwave project.
|
|
2540
|
+
|
|
2541
|
+
Examples
|
|
2542
|
+
--------
|
|
2543
|
+
>>> # Solve with SIwave:
|
|
2544
|
+
>>> edb.solve_siwave()
|
|
2526
2545
|
"""
|
|
2527
2546
|
process = SiwaveSolve(self.edbpath, aedt_version=self.edbversion)
|
|
2528
2547
|
try:
|
|
@@ -2721,7 +2740,7 @@ class Edb(EdbInit):
|
|
|
2721
2740
|
Returns
|
|
2722
2741
|
-------
|
|
2723
2742
|
list
|
|
2724
|
-
[[min_x, min_y], [max_x, max_y]] in meters.
|
|
2743
|
+
list[list[min_x, min_y], list[max_x, max_y]] in meters.
|
|
2725
2744
|
"""
|
|
2726
2745
|
lay_inst_polygon_data = [obj_inst.get_bbox() for obj_inst in self.layout_instance.query_layout_obj_instances()]
|
|
2727
2746
|
layout_bbox = GrpcPolygonData.bbox_of_polygons(lay_inst_polygon_data)
|
|
@@ -2761,7 +2780,10 @@ class Edb(EdbInit):
|
|
|
2761
2780
|
return True
|
|
2762
2781
|
self.logger.reset_timer()
|
|
2763
2782
|
if not common_reference:
|
|
2764
|
-
|
|
2783
|
+
ref_terminals = [term for term in all_sources if term.is_reference_terminal]
|
|
2784
|
+
common_reference = list(
|
|
2785
|
+
set([i.reference_terminal.net.name for i in all_sources if i.is_reference_terminal])
|
|
2786
|
+
)
|
|
2765
2787
|
if len(common_reference) > 1:
|
|
2766
2788
|
self.logger.error("More than 1 reference found.")
|
|
2767
2789
|
return False
|
|
@@ -2821,10 +2843,10 @@ class Edb(EdbInit):
|
|
|
2821
2843
|
|
|
2822
2844
|
Returns
|
|
2823
2845
|
-------
|
|
2824
|
-
Dict[str,:
|
|
2825
|
-
Dict[str,:
|
|
2826
|
-
Dict[str,:
|
|
2827
|
-
Dict[str,:
|
|
2846
|
+
Dict[str,:class:`HfssSimulationSetup`] or
|
|
2847
|
+
Dict[str,:class:`SiwaveSimulationSetup`] or
|
|
2848
|
+
Dict[str,:class:`SIWaveDCIRSimulationSetup`] or
|
|
2849
|
+
Dict[str,:class:`RaptorXSimulationSetup`]
|
|
2828
2850
|
|
|
2829
2851
|
"""
|
|
2830
2852
|
self._setups = {}
|
|
@@ -2875,8 +2897,7 @@ class Edb(EdbInit):
|
|
|
2875
2897
|
|
|
2876
2898
|
Returns
|
|
2877
2899
|
-------
|
|
2878
|
-
Dict[str,:class:`SiwaveSimulationSetup
|
|
2879
|
-
<pyedb.grpc.database.simulation_setup.siwave_simulation_setup.SiwaveSimulationSetup>`]
|
|
2900
|
+
Dict[str,:class:`SiwaveSimulationSetup`]
|
|
2880
2901
|
"""
|
|
2881
2902
|
return {name: i for name, i in self.setups.items() if isinstance(i, SiwaveSimulationSetup)}
|
|
2882
2903
|
|
|
@@ -2887,16 +2908,6 @@ class Edb(EdbInit):
|
|
|
2887
2908
|
|
|
2888
2909
|
. deprecated:: pyedb 0.30.0
|
|
2889
2910
|
Use :func:`pyedb.grpc.core.hfss.add_setup` instead.
|
|
2890
|
-
|
|
2891
|
-
Parameters
|
|
2892
|
-
----------
|
|
2893
|
-
name : str, optional
|
|
2894
|
-
Setup name.
|
|
2895
|
-
|
|
2896
|
-
Returns
|
|
2897
|
-
-------
|
|
2898
|
-
:class:`HfssSimulationSetup <legacy.database.edb_data.hfss_simulation_setup_data.HfssSimulationSetup>`
|
|
2899
|
-
|
|
2900
2911
|
"""
|
|
2901
2912
|
warnings.warn(
|
|
2902
2913
|
"`create_hfss_setup` is deprecated and is now located here " "`pyedb.grpc.core.hfss.add_setup` instead.",
|
|
@@ -2920,8 +2931,7 @@ class Edb(EdbInit):
|
|
|
2920
2931
|
|
|
2921
2932
|
Returns
|
|
2922
2933
|
-------
|
|
2923
|
-
:class:`RaptorXSimulationSetup
|
|
2924
|
-
<pyedb.grpc.database.simulation_setup.raptor_x_simulation_setup.RaptorXSimulationSetup>`
|
|
2934
|
+
:class:`RaptorXSimulationSetup`
|
|
2925
2935
|
RaptorX setup or False if unsupported.
|
|
2926
2936
|
"""
|
|
2927
2937
|
from ansys.edb.core.simulation_setup.raptor_x_simulation_setup import (
|
|
@@ -2977,8 +2987,7 @@ class Edb(EdbInit):
|
|
|
2977
2987
|
|
|
2978
2988
|
Returns
|
|
2979
2989
|
-------
|
|
2980
|
-
:class:`SiwaveSimulationSetup
|
|
2981
|
-
<pyedb.grpc.database.simulation_setup.siwave_simulation_setup.SiwaveSimulationSetup>`
|
|
2990
|
+
:class:`SiwaveSimulationSetup`
|
|
2982
2991
|
SYZ analysis setup.
|
|
2983
2992
|
"""
|
|
2984
2993
|
if not name:
|
|
@@ -3006,8 +3015,7 @@ class Edb(EdbInit):
|
|
|
3006
3015
|
|
|
3007
3016
|
Returns
|
|
3008
3017
|
-------
|
|
3009
|
-
:class:`SIWaveDCIRSimulationSetup
|
|
3010
|
-
<pyedb.grpc.database.simulation_setup.siwave_dcir_simulation_setup.SIWaveDCIRSimulationSetup>`
|
|
3018
|
+
:class:`SIWaveDCIRSimulationSetup`
|
|
3011
3019
|
DC analysis setup.
|
|
3012
3020
|
"""
|
|
3013
3021
|
if not name:
|
|
@@ -3036,7 +3044,7 @@ class Edb(EdbInit):
|
|
|
3036
3044
|
for port in self.excitations.values():
|
|
3037
3045
|
nets.append(port.net.name)
|
|
3038
3046
|
for port in self.sources.values():
|
|
3039
|
-
nets.append(port.
|
|
3047
|
+
nets.append(port.net.name)
|
|
3040
3048
|
nets = list(set(nets))
|
|
3041
3049
|
max_width = 0
|
|
3042
3050
|
for net in nets:
|
|
@@ -3051,8 +3059,8 @@ class Edb(EdbInit):
|
|
|
3051
3059
|
self.logger.info(f"The W factor is {expansion_factor}, The initial extent = {max_width}")
|
|
3052
3060
|
return max_width
|
|
3053
3061
|
|
|
3054
|
-
def copy_zones(self, working_directory=None):
|
|
3055
|
-
"""Copy
|
|
3062
|
+
def copy_zones(self, working_directory=None) -> dict[str, tuple[int, GrpcPolygonData]]:
|
|
3063
|
+
"""Copy multi-zone EDB project to one new edb per zone.
|
|
3056
3064
|
|
|
3057
3065
|
Parameters
|
|
3058
3066
|
----------
|
|
@@ -3061,7 +3069,8 @@ class Edb(EdbInit):
|
|
|
3061
3069
|
|
|
3062
3070
|
Returns
|
|
3063
3071
|
-------
|
|
3064
|
-
|
|
3072
|
+
dict[str, tuple[int,:class:`PolygonData <ansys.edb.core.geometry.polygon_data.PolygonData>`]]
|
|
3073
|
+
|
|
3065
3074
|
Return a dictionary with edb path as key and tuple Zone Id as first item and EDB polygon Data defining
|
|
3066
3075
|
the region as second item.
|
|
3067
3076
|
|
|
@@ -3080,7 +3089,7 @@ class Edb(EdbInit):
|
|
|
3080
3089
|
edb_zones = {}
|
|
3081
3090
|
if not self.setups:
|
|
3082
3091
|
self.siwave.add_siwave_syz_analysis()
|
|
3083
|
-
self.
|
|
3092
|
+
self.save()
|
|
3084
3093
|
for zone_primitive in zone_primitives:
|
|
3085
3094
|
if zone_primitive:
|
|
3086
3095
|
edb_zone_path = os.path.join(working_directory, f"{zone_primitive.id}_{os.path.basename(self.edbpath)}")
|
|
@@ -3114,10 +3123,9 @@ class Edb(EdbInit):
|
|
|
3114
3123
|
|
|
3115
3124
|
Returns
|
|
3116
3125
|
-------
|
|
3117
|
-
|
|
3118
|
-
|
|
3119
|
-
|
|
3120
|
-
second is the list of connected port.
|
|
3126
|
+
dict[str: str] or list[str]
|
|
3127
|
+
first dictionary defined_ports with edb name as key and existing port name list as value. Those ports are
|
|
3128
|
+
the ones defined before processing the multizone clipping. the second is the list of connected port.
|
|
3121
3129
|
|
|
3122
3130
|
"""
|
|
3123
3131
|
terminals = {}
|
|
@@ -3236,29 +3244,8 @@ class Edb(EdbInit):
|
|
|
3236
3244
|
"""Create a port.
|
|
3237
3245
|
|
|
3238
3246
|
..deprecated:: 0.51.0
|
|
3239
|
-
Use:
|
|
3247
|
+
Use :func:`create_port` has been moved to source_excitation.create_port.
|
|
3240
3248
|
|
|
3241
|
-
Parameters
|
|
3242
|
-
----------
|
|
3243
|
-
terminal : class:`pyedb.dotnet.database.edb_data.terminals.EdgeTerminal`,
|
|
3244
|
-
class:`pyedb.grpc.database.terminals.PadstackInstanceTerminal`,
|
|
3245
|
-
class:`pyedb.grpc.database.terminals.PointTerminal`,
|
|
3246
|
-
class:`pyedb.grpc.database.terminals.PinGroupTerminal`,
|
|
3247
|
-
Positive terminal of the port.
|
|
3248
|
-
ref_terminal : class:`pyedb.grpc.database.terminals.EdgeTerminal`,
|
|
3249
|
-
class:`pyedb.grpc.database.terminals.PadstackInstanceTerminal`,
|
|
3250
|
-
class:`pyedb.grpc.database.terminals.PointTerminal`,
|
|
3251
|
-
class:`pyedb.grpc.database.terminals.PinGroupTerminal`,
|
|
3252
|
-
optional
|
|
3253
|
-
Negative terminal of the port.
|
|
3254
|
-
is_circuit_port : bool, optional
|
|
3255
|
-
Whether it is a circuit port. The default is ``False``.
|
|
3256
|
-
name: str, optional
|
|
3257
|
-
Name of the created port. The default is None, a random name is generated.
|
|
3258
|
-
Returns
|
|
3259
|
-
-------
|
|
3260
|
-
list: [:class:`GapPort <pyedb.grpc.database.ports.ports.GapPort`>,
|
|
3261
|
-
:class:`WavePort <pyedb.grpc.database.ports.ports.WavePort>`].
|
|
3262
3249
|
"""
|
|
3263
3250
|
|
|
3264
3251
|
warnings.warn("Use create_port from edb.source_excitation.create_port", DeprecationWarning)
|
|
@@ -3268,24 +3255,8 @@ class Edb(EdbInit):
|
|
|
3268
3255
|
"""Create a voltage probe.
|
|
3269
3256
|
|
|
3270
3257
|
..deprecated:: 0.50.0
|
|
3271
|
-
Use:
|
|
3272
|
-
|
|
3273
|
-
Parameters
|
|
3274
|
-
----------
|
|
3275
|
-
terminal : :class:`EdgeTerminal <pyedb.grpc.database.terminals.EdgeTerminal>`,
|
|
3276
|
-
:class:`PadstackInstanceTerminal <pyedb.grpc.database.terminals.PadstackInstanceTerminal>`,
|
|
3277
|
-
:class:`PointTerminal <pyedb.grpc.database.terminals.PointTerminal>`,
|
|
3278
|
-
:class:`PinGroupTerminal <pyedb.grpc.database.terminals.PinGroupTerminal>`,
|
|
3279
|
-
Positive terminal of the port.
|
|
3280
|
-
ref_terminal : :class:`EdgeTerminal <pyedb.grpc.database.terminals.EdgeTerminal>`,
|
|
3281
|
-
:class:`pyedb.grpc.database.terminals.PadstackInstanceTerminal`,
|
|
3282
|
-
:class:`PadstackInstanceTerminal <pyedb.grpc.database.terminals.PointTerminal>`,
|
|
3283
|
-
:class:`PinGroupTerminal <pyedb.grpc.database.terminals.PinGroupTerminal>`,
|
|
3284
|
-
Negative terminal of the probe.
|
|
3258
|
+
Use :func:`create_voltage_probe` has been moved to edb.source_excitation.create_voltage_probe.
|
|
3285
3259
|
|
|
3286
|
-
Returns
|
|
3287
|
-
-------
|
|
3288
|
-
:class:`Terminal <pyedb.dotnet.database.edb_data.terminals.Terminal>`
|
|
3289
3260
|
"""
|
|
3290
3261
|
warnings.warn("Use create_voltage_probe located in edb.source_excitation instead", DeprecationWarning)
|
|
3291
3262
|
return self.source_excitation.create_voltage_probe(terminal, ref_terminal)
|
|
@@ -3294,24 +3265,8 @@ class Edb(EdbInit):
|
|
|
3294
3265
|
"""Create a voltage source.
|
|
3295
3266
|
|
|
3296
3267
|
..deprecated:: 0.50.0
|
|
3297
|
-
Use: func:`create_voltage_source`
|
|
3268
|
+
Use: func:`create_voltage_source` has been moved to edb.source_excitation.create_voltage_source.
|
|
3298
3269
|
|
|
3299
|
-
Parameters
|
|
3300
|
-
----------
|
|
3301
|
-
terminal : :class:`EdgeTerminal <pyedb.grpc.database.terminals.EdgeTerminal>`,
|
|
3302
|
-
:class:`PadstackInstanceTerminal <pyedb.grpc.database.terminals.PadstackInstanceTerminal>`,
|
|
3303
|
-
:class:`PointTerminal <pyedb.grpc.database.terminals.PointTerminal>`,
|
|
3304
|
-
:class:`PinGroupTerminal <pyedb.grpc.database.terminals.PinGroupTerminal>`,
|
|
3305
|
-
Positive terminal of the source.
|
|
3306
|
-
ref_terminal : :class:`EdgeTerminal <pyedb.grpc.database.terminals.EdgeTerminal>`,
|
|
3307
|
-
:class:`pyedb.grpc.database.terminals.PadstackInstanceTerminal`,
|
|
3308
|
-
:class:`PadstackInstanceTerminal <pyedb.grpc.database.terminals.PointTerminal>`,
|
|
3309
|
-
:class:`PinGroupTerminal <pyedb.grpc.database.terminals.PinGroupTerminal>`,
|
|
3310
|
-
Negative terminal of the source.
|
|
3311
|
-
|
|
3312
|
-
Returns
|
|
3313
|
-
-------
|
|
3314
|
-
class:`ExcitationSources <legacy.database.edb_data.ports.ExcitationSources>`
|
|
3315
3270
|
"""
|
|
3316
3271
|
warnings.warn(
|
|
3317
3272
|
"use create_voltage_source located in edb.source_excitation.create_voltage_source instead",
|
|
@@ -3323,24 +3278,8 @@ class Edb(EdbInit):
|
|
|
3323
3278
|
"""Create a current source.
|
|
3324
3279
|
|
|
3325
3280
|
..deprecated:: 0.50.0
|
|
3326
|
-
Use:
|
|
3281
|
+
Use :func:`create_current_source` has been moved to edb.source_excitation.create_current_source.
|
|
3327
3282
|
|
|
3328
|
-
Parameters
|
|
3329
|
-
----------
|
|
3330
|
-
terminal : :class:`EdgeTerminal <pyedb.grpc.database.terminals.EdgeTerminal>`,
|
|
3331
|
-
:class:`PadstackInstanceTerminal <pyedb.grpc.database.terminals.PadstackInstanceTerminal>`,
|
|
3332
|
-
:class:`PointTerminal <pyedb.grpc.database.terminals.PointTerminal>`,
|
|
3333
|
-
:class:`PinGroupTerminal <pyedb.grpc.database.terminals.PinGroupTerminal>`,
|
|
3334
|
-
Positive terminal of the source.
|
|
3335
|
-
ref_terminal : :class:`EdgeTerminal <pyedb.grpc.database.terminals.EdgeTerminal>`,
|
|
3336
|
-
:class:`pyedb.grpc.database.terminals.PadstackInstanceTerminal`,
|
|
3337
|
-
:class:`PadstackInstanceTerminal <pyedb.grpc.database.terminals.PointTerminal>`,
|
|
3338
|
-
:class:`PinGroupTerminal <pyedb.grpc.database.terminals.PinGroupTerminal>`,
|
|
3339
|
-
Negative terminal of the source.
|
|
3340
|
-
|
|
3341
|
-
Returns
|
|
3342
|
-
-------
|
|
3343
|
-
:class:`ExcitationSources <legacy.database.edb_data.ports.ExcitationSources>`
|
|
3344
3283
|
"""
|
|
3345
3284
|
warnings.warn(
|
|
3346
3285
|
"use create_current_source located in edb.source_excitation.create_current_source instead",
|
|
@@ -3352,22 +3291,7 @@ class Edb(EdbInit):
|
|
|
3352
3291
|
"""Place terminal between two points.
|
|
3353
3292
|
|
|
3354
3293
|
..deprecated:: 0.50.0
|
|
3355
|
-
Use: func:`get_point_terminal`
|
|
3356
|
-
|
|
3357
|
-
Parameters
|
|
3358
|
-
----------
|
|
3359
|
-
name : str,
|
|
3360
|
-
Name of the terminal.
|
|
3361
|
-
net_name : str
|
|
3362
|
-
Name of the net.
|
|
3363
|
-
location : list
|
|
3364
|
-
Location of the terminal.
|
|
3365
|
-
layer : str,
|
|
3366
|
-
Layer of the terminal.
|
|
3367
|
-
|
|
3368
|
-
Returns
|
|
3369
|
-
-------
|
|
3370
|
-
:class:`PointTerminal <pyedb.grpc.database.terminal.point_terminal.PointTerminal>`
|
|
3294
|
+
Use: func:`get_point_terminal` has been moved to edb.source_excitation.get_point_terminal.
|
|
3371
3295
|
"""
|
|
3372
3296
|
|
|
3373
3297
|
warnings.warn(
|
|
@@ -3438,10 +3362,18 @@ class Edb(EdbInit):
|
|
|
3438
3362
|
-------
|
|
3439
3363
|
list[str]
|
|
3440
3364
|
Created parameter names.
|
|
3365
|
+
|
|
3366
|
+
Examples
|
|
3367
|
+
--------
|
|
3368
|
+
Parametrize design elements:
|
|
3369
|
+
>>> params = edb.auto_parametrize_design(
|
|
3370
|
+
>>> layers=True,
|
|
3371
|
+
>>> materials=True,
|
|
3372
|
+
>>> trace_net_filter=["Clock"])
|
|
3441
3373
|
"""
|
|
3442
3374
|
edb_original_path = self.edbpath
|
|
3443
3375
|
if output_aedb_path:
|
|
3444
|
-
self.
|
|
3376
|
+
self.save_as(output_aedb_path)
|
|
3445
3377
|
if isinstance(trace_net_filter, str):
|
|
3446
3378
|
trace_net_filter = [trace_net_filter]
|
|
3447
3379
|
parameters = []
|
|
@@ -3629,10 +3561,10 @@ class Edb(EdbInit):
|
|
|
3629
3561
|
void.expand(expand_voids_size, round_corners=False)
|
|
3630
3562
|
|
|
3631
3563
|
if not open_aedb_at_end and self.edbpath != edb_original_path:
|
|
3632
|
-
self.
|
|
3633
|
-
self.
|
|
3564
|
+
self.save()
|
|
3565
|
+
self.close()
|
|
3634
3566
|
self.edbpath = edb_original_path
|
|
3635
|
-
self.
|
|
3567
|
+
self.open()
|
|
3636
3568
|
return parameters
|
|
3637
3569
|
|
|
3638
3570
|
@staticmethod
|
|
@@ -3868,3 +3800,37 @@ class Edb(EdbInit):
|
|
|
3868
3800
|
ET.indent(tree, space="\t", level=0)
|
|
3869
3801
|
tree.write(control_path)
|
|
3870
3802
|
return True if os.path.exists(control_path) else False
|
|
3803
|
+
|
|
3804
|
+
def compare(self, input_file, results=""):
|
|
3805
|
+
"""Compares current open database with another one.
|
|
3806
|
+
|
|
3807
|
+
Parameters
|
|
3808
|
+
----------
|
|
3809
|
+
input_file : str
|
|
3810
|
+
Path to the edb file.
|
|
3811
|
+
results: str, optional
|
|
3812
|
+
Path to directory in which results will be saved. If no path is given, a new "_compare_results"
|
|
3813
|
+
directory will be created with the same naming and path as the .aedb folder.
|
|
3814
|
+
Returns
|
|
3815
|
+
-------
|
|
3816
|
+
bool
|
|
3817
|
+
``True`` when successful, ``False`` when failed.
|
|
3818
|
+
"""
|
|
3819
|
+
self.save()
|
|
3820
|
+
if not results:
|
|
3821
|
+
results = self.edbpath[:-5] + "_compare_results"
|
|
3822
|
+
os.mkdir(results)
|
|
3823
|
+
command = os.path.join(self.base_path, "EDBDiff.exe")
|
|
3824
|
+
if is_linux:
|
|
3825
|
+
mono_path = os.path.join(self.base_path, "common/mono/Linux64/bin/mono")
|
|
3826
|
+
cmd_input = [mono_path, command, input_file, self.edbpath, results]
|
|
3827
|
+
else:
|
|
3828
|
+
cmd_input = [command, input_file, self.edbpath, results]
|
|
3829
|
+
subprocess.run(cmd_input)
|
|
3830
|
+
|
|
3831
|
+
if not os.path.exists(os.path.join(results, "EDBDiff.csv")):
|
|
3832
|
+
self.logger.error("Comparison execution failed")
|
|
3833
|
+
return False
|
|
3834
|
+
else:
|
|
3835
|
+
self.logger.info("Comparison correctly completed")
|
|
3836
|
+
return True
|