pyedb 0.56.0__py3-none-any.whl → 0.57.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_data.py +3 -0
- pyedb/configuration/cfg_terminals.py +232 -0
- pyedb/configuration/configuration.py +146 -3
- pyedb/dotnet/clr_module.py +1 -2
- pyedb/dotnet/database/Variables.py +30 -22
- pyedb/dotnet/database/cell/layout.py +5 -1
- pyedb/dotnet/database/cell/primitive/primitive.py +2 -2
- pyedb/dotnet/database/cell/terminal/bundle_terminal.py +12 -0
- pyedb/dotnet/database/cell/terminal/pingroup_terminal.py +1 -1
- pyedb/dotnet/database/cell/terminal/terminal.py +38 -0
- pyedb/dotnet/database/components.py +14 -16
- pyedb/dotnet/database/dotnet/database.py +1 -0
- pyedb/dotnet/database/edb_data/control_file.py +6 -3
- pyedb/dotnet/database/edb_data/nets_data.py +3 -3
- pyedb/dotnet/database/edb_data/padstacks_data.py +5 -2
- pyedb/dotnet/database/edb_data/ports.py +0 -25
- pyedb/dotnet/database/edb_data/primitives_data.py +3 -3
- pyedb/dotnet/database/edb_data/raptor_x_simulation_setup_data.py +18 -19
- pyedb/dotnet/database/edb_data/simulation_configuration.py +3 -3
- pyedb/dotnet/database/hfss.py +9 -8
- pyedb/dotnet/database/layout_validation.py +6 -3
- pyedb/dotnet/database/materials.py +1 -3
- pyedb/dotnet/database/modeler.py +7 -3
- pyedb/dotnet/database/nets.py +27 -19
- pyedb/dotnet/database/padstack.py +4 -2
- pyedb/dotnet/database/sim_setup_data/io/siwave.py +1 -1
- pyedb/dotnet/database/siwave.py +4 -3
- pyedb/dotnet/database/stackup.py +50 -26
- pyedb/dotnet/database/utilities/heatsink.py +0 -1
- pyedb/dotnet/database/utilities/simulation_setup.py +7 -5
- pyedb/dotnet/database/utilities/siwave_cpa_simulation_setup.py +1 -0
- pyedb/dotnet/database/utilities/siwave_simulation_setup.py +5 -2
- pyedb/dotnet/edb.py +39 -34
- pyedb/exceptions.py +1 -2
- pyedb/extensions/create_cell_array.py +19 -5
- pyedb/generic/data_handlers.py +13 -23
- pyedb/generic/design_types.py +9 -35
- pyedb/generic/filesystem.py +4 -2
- pyedb/generic/general_methods.py +4 -5
- pyedb/generic/plot.py +2 -2
- pyedb/grpc/database/_typing.py +0 -0
- pyedb/grpc/database/components.py +7 -8
- pyedb/grpc/database/control_file.py +14 -35
- pyedb/grpc/database/definition/materials.py +1 -1
- pyedb/grpc/database/definition/package_def.py +6 -3
- pyedb/grpc/database/definition/padstack_def.py +4 -7
- pyedb/grpc/database/hfss.py +1 -4
- pyedb/grpc/database/hierarchy/component.py +3 -4
- pyedb/grpc/database/hierarchy/pingroup.py +16 -3
- pyedb/grpc/database/layers/layer.py +1 -2
- pyedb/grpc/database/layers/stackup_layer.py +42 -19
- pyedb/grpc/database/layout/layout.py +43 -27
- pyedb/grpc/database/layout/voltage_regulator.py +6 -1
- pyedb/grpc/database/layout_validation.py +5 -2
- pyedb/grpc/database/modeler.py +226 -244
- pyedb/grpc/database/net/differential_pair.py +9 -2
- pyedb/grpc/database/net/extended_net.py +24 -9
- pyedb/grpc/database/net/net.py +14 -5
- pyedb/grpc/database/net/net_class.py +24 -7
- pyedb/grpc/database/nets.py +11 -43
- pyedb/grpc/database/padstacks.py +5 -16
- pyedb/grpc/database/primitive/bondwire.py +3 -67
- pyedb/grpc/database/primitive/circle.py +42 -3
- pyedb/grpc/database/primitive/padstack_instance.py +17 -19
- pyedb/grpc/database/primitive/path.py +154 -5
- pyedb/grpc/database/primitive/polygon.py +73 -7
- pyedb/grpc/database/primitive/primitive.py +2 -2
- pyedb/grpc/database/primitive/rectangle.py +105 -4
- pyedb/grpc/database/simulation_setup/hfss_general_settings.py +0 -2
- pyedb/grpc/database/simulation_setup/hfss_settings_options.py +0 -4
- pyedb/grpc/database/simulation_setup/siwave_cpa_simulation_setup.py +1 -0
- pyedb/grpc/database/simulation_setup/sweep_data.py +1 -3
- pyedb/grpc/database/siwave.py +6 -13
- pyedb/grpc/database/source_excitations.py +39 -56
- pyedb/grpc/database/stackup.py +50 -27
- pyedb/grpc/database/terminal/bundle_terminal.py +10 -3
- pyedb/grpc/database/terminal/pingroup_terminal.py +8 -1
- pyedb/grpc/database/terminal/terminal.py +19 -8
- pyedb/grpc/database/utility/heat_sink.py +0 -1
- pyedb/grpc/database/utility/hfss_extent_info.py +2 -2
- pyedb/grpc/database/utility/xml_control_file.py +6 -3
- pyedb/grpc/edb.py +24 -19
- pyedb/grpc/edb_init.py +1 -0
- pyedb/ipc2581/ecad/cad_data/layer_feature.py +6 -2
- pyedb/ipc2581/ecad/cad_data/step.py +1 -1
- pyedb/ipc2581/ipc2581.py +8 -7
- pyedb/libraries/common.py +3 -4
- pyedb/libraries/rf_libraries/base_functions.py +7 -16
- pyedb/libraries/rf_libraries/planar_antennas.py +3 -21
- pyedb/misc/downloads.py +1 -0
- pyedb/misc/misc.py +5 -2
- pyedb/misc/siw_feature_config/emc_rule_checker_settings.py +1 -1
- pyedb/misc/utilities.py +0 -1
- pyedb/modeler/geometry_operators.py +3 -2
- {pyedb-0.56.0.dist-info → pyedb-0.57.0.dist-info}/METADATA +3 -3
- {pyedb-0.56.0.dist-info → pyedb-0.57.0.dist-info}/RECORD +99 -97
- {pyedb-0.56.0.dist-info → pyedb-0.57.0.dist-info}/WHEEL +0 -0
- {pyedb-0.56.0.dist-info → pyedb-0.57.0.dist-info}/licenses/LICENSE +0 -0
pyedb/dotnet/database/stackup.py
CHANGED
|
@@ -1137,7 +1137,7 @@ class Stackup(LayerCollection):
|
|
|
1137
1137
|
|
|
1138
1138
|
Examples
|
|
1139
1139
|
--------
|
|
1140
|
-
>>> edb = Edb(edbpath=targetfile,
|
|
1140
|
+
>>> edb = Edb(edbpath=targetfile, edbversion="2021.2")
|
|
1141
1141
|
>>> edb.stackup.flip_design()
|
|
1142
1142
|
>>> edb.save()
|
|
1143
1143
|
>>> edb.close_edb()
|
|
@@ -1227,8 +1227,11 @@ class Stackup(LayerCollection):
|
|
|
1227
1227
|
sball_prop = cmp_prop.GetSolderBallProperty().Clone()
|
|
1228
1228
|
sball_prop.SetPlacement(self._pedb.definition.SolderballPlacement.AbovePadstack)
|
|
1229
1229
|
cmp_prop.SetSolderBallProperty(sball_prop)
|
|
1230
|
-
except:
|
|
1231
|
-
|
|
1230
|
+
except Exception as e:
|
|
1231
|
+
self._logger.warning(
|
|
1232
|
+
f"A(n) {type(e).__name__} error occurred while attempting to update "
|
|
1233
|
+
f"SolderBallProperty for component {cmp}: {str(e)}"
|
|
1234
|
+
)
|
|
1232
1235
|
if cmp_type == self._pedb.definition.ComponentType.IC:
|
|
1233
1236
|
die_prop = cmp_prop.GetDieProperty().Clone()
|
|
1234
1237
|
chip_orientation = die_prop.GetOrientation()
|
|
@@ -1356,22 +1359,28 @@ class Stackup(LayerCollection):
|
|
|
1356
1359
|
|
|
1357
1360
|
Examples
|
|
1358
1361
|
--------
|
|
1359
|
-
>>> edb1 = Edb(edbpath=targetfile1,
|
|
1362
|
+
>>> edb1 = Edb(edbpath=targetfile1, edbversion="2021.2")
|
|
1360
1363
|
>>> edb2 = Edb(edbpath=targetfile2, edbversion="2021.2")
|
|
1361
1364
|
|
|
1362
1365
|
>>> hosting_cmp = edb1.components.get_component_by_name("U100")
|
|
1363
1366
|
>>> mounted_cmp = edb2.components.get_component_by_name("BGA")
|
|
1364
1367
|
|
|
1365
1368
|
>>> vector, rotation, solder_ball_height = edb1.components.get_component_placement_vector(
|
|
1366
|
-
...
|
|
1367
|
-
...
|
|
1368
|
-
...
|
|
1369
|
-
...
|
|
1370
|
-
...
|
|
1371
|
-
...
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
...
|
|
1369
|
+
... mounted_component=mounted_cmp,
|
|
1370
|
+
... hosting_component=hosting_cmp,
|
|
1371
|
+
... mounted_component_pin1="A12",
|
|
1372
|
+
... mounted_component_pin2="A14",
|
|
1373
|
+
... hosting_component_pin1="A12",
|
|
1374
|
+
... hosting_component_pin2="A14",
|
|
1375
|
+
... )
|
|
1376
|
+
>>> edb2.stackup.place_in_layout(
|
|
1377
|
+
... edb1.active_cell,
|
|
1378
|
+
... angle=0.0,
|
|
1379
|
+
... offset_x=vector[0],
|
|
1380
|
+
... offset_y=vector[1],
|
|
1381
|
+
... flipped_stackup=False,
|
|
1382
|
+
... place_on_top=True,
|
|
1383
|
+
... )
|
|
1375
1384
|
"""
|
|
1376
1385
|
# if flipped_stackup and place_on_top or (not flipped_stackup and not place_on_top):
|
|
1377
1386
|
self.adjust_solder_dielectrics()
|
|
@@ -1453,13 +1462,18 @@ class Stackup(LayerCollection):
|
|
|
1453
1462
|
|
|
1454
1463
|
Examples
|
|
1455
1464
|
--------
|
|
1456
|
-
>>> edb1 = Edb(edbpath=targetfile1,
|
|
1465
|
+
>>> edb1 = Edb(edbpath=targetfile1, edbversion="2021.2")
|
|
1457
1466
|
>>> edb2 = Edb(edbpath=targetfile2, edbversion="2021.2")
|
|
1458
1467
|
>>> hosting_cmp = edb1.components.get_component_by_name("U100")
|
|
1459
1468
|
>>> mounted_cmp = edb2.components.get_component_by_name("BGA")
|
|
1460
|
-
>>> edb2.stackup.place_in_layout(
|
|
1461
|
-
...
|
|
1462
|
-
...
|
|
1469
|
+
>>> edb2.stackup.place_in_layout(
|
|
1470
|
+
... edb1.active_cell,
|
|
1471
|
+
... angle=0.0,
|
|
1472
|
+
... offset_x="1mm",
|
|
1473
|
+
... offset_y="2mm",
|
|
1474
|
+
... flipped_stackup=False,
|
|
1475
|
+
... place_on_top=True,
|
|
1476
|
+
... )
|
|
1463
1477
|
"""
|
|
1464
1478
|
_angle = angle * math.pi / 180.0
|
|
1465
1479
|
|
|
@@ -1592,13 +1606,18 @@ class Stackup(LayerCollection):
|
|
|
1592
1606
|
|
|
1593
1607
|
Examples
|
|
1594
1608
|
--------
|
|
1595
|
-
>>> edb1 = Edb(edbpath=targetfile1,
|
|
1609
|
+
>>> edb1 = Edb(edbpath=targetfile1, edbversion="2021.2")
|
|
1596
1610
|
>>> edb2 = Edb(edbpath=targetfile2, edbversion="2021.2")
|
|
1597
1611
|
>>> hosting_cmp = edb1.components.get_component_by_name("U100")
|
|
1598
1612
|
>>> mounted_cmp = edb2.components.get_component_by_name("BGA")
|
|
1599
|
-
>>> edb1.stackup.place_instance(
|
|
1600
|
-
...
|
|
1601
|
-
...
|
|
1613
|
+
>>> edb1.stackup.place_instance(
|
|
1614
|
+
... edb2,
|
|
1615
|
+
... angle=0.0,
|
|
1616
|
+
... offset_x="1mm",
|
|
1617
|
+
... offset_y="2mm",
|
|
1618
|
+
... flipped_stackup=False,
|
|
1619
|
+
... place_on_top=True,
|
|
1620
|
+
... )
|
|
1602
1621
|
"""
|
|
1603
1622
|
_angle = angle * math.pi / 180.0
|
|
1604
1623
|
|
|
@@ -1736,11 +1755,16 @@ class Stackup(LayerCollection):
|
|
|
1736
1755
|
|
|
1737
1756
|
Examples
|
|
1738
1757
|
--------
|
|
1739
|
-
>>> edb1 = Edb(edbpath=targetfile1,
|
|
1758
|
+
>>> edb1 = Edb(edbpath=targetfile1, edbversion="2021.2")
|
|
1740
1759
|
>>> a3dcomp_path = "connector.a3dcomp"
|
|
1741
|
-
>>> edb1.stackup.place_a3dcomp_3d_placement(
|
|
1742
|
-
...
|
|
1743
|
-
...
|
|
1760
|
+
>>> edb1.stackup.place_a3dcomp_3d_placement(
|
|
1761
|
+
... a3dcomp_path,
|
|
1762
|
+
... angle=0.0,
|
|
1763
|
+
... offset_x="1mm",
|
|
1764
|
+
... offset_y="2mm",
|
|
1765
|
+
... flipped_stackup=False,
|
|
1766
|
+
... place_on_top=True,
|
|
1767
|
+
... )
|
|
1744
1768
|
"""
|
|
1745
1769
|
zero_data = self._edb_value(0.0)
|
|
1746
1770
|
one_data = self._edb_value(1.0)
|
|
@@ -1795,7 +1819,7 @@ class Stackup(LayerCollection):
|
|
|
1795
1819
|
|
|
1796
1820
|
Examples
|
|
1797
1821
|
--------
|
|
1798
|
-
>>> edb = Edb(edbpath=targetfile1,
|
|
1822
|
+
>>> edb = Edb(edbpath=targetfile1, edbversion="2021.2")
|
|
1799
1823
|
>>> edb.stackup.residual_copper_area_per_layer()
|
|
1800
1824
|
"""
|
|
1801
1825
|
temp_data = {name: 0 for name, _ in self.signal_layers.items()}
|
|
@@ -371,11 +371,13 @@ class SimulationSetup(object):
|
|
|
371
371
|
Examples
|
|
372
372
|
--------
|
|
373
373
|
>>> setup1 = edbapp.create_siwave_syz_setup("setup1")
|
|
374
|
-
>>> setup1.add_frequency_sweep(
|
|
375
|
-
... [
|
|
376
|
-
...
|
|
377
|
-
...
|
|
378
|
-
...
|
|
374
|
+
>>> setup1.add_frequency_sweep(
|
|
375
|
+
... frequency_sweep=[
|
|
376
|
+
... ["linear count", "0", "1kHz", 1],
|
|
377
|
+
... ["log scale", "1kHz", "0.1GHz", 10],
|
|
378
|
+
... ["linear scale", "0.1GHz", "10GHz", "0.1GHz"],
|
|
379
|
+
... ]
|
|
380
|
+
... )
|
|
379
381
|
"""
|
|
380
382
|
warnings.warn("`add_frequency_sweep` is deprecated. Use `add_sweep` method instead.", DeprecationWarning)
|
|
381
383
|
return self.add_sweep(name, frequency_sweep)
|
|
@@ -691,6 +691,7 @@ class SIWaveCPASimulationSetup:
|
|
|
691
691
|
self._pedb = pedb
|
|
692
692
|
self._channel_setup = ChannelSetup(pedb)
|
|
693
693
|
self._solver_options = SolverOptions(pedb)
|
|
694
|
+
self.type = "cpa"
|
|
694
695
|
if isinstance(siwave_cpa_setup_class, SIwaveCpaSetup):
|
|
695
696
|
self._apply_cfg_object(siwave_cpa_setup_class)
|
|
696
697
|
else:
|
|
@@ -15,6 +15,7 @@ from pyedb.dotnet.database.sim_setup_data.io.siwave import (
|
|
|
15
15
|
)
|
|
16
16
|
from pyedb.dotnet.database.utilities.simulation_setup import SimulationSetup
|
|
17
17
|
from pyedb.generic.general_methods import is_linux
|
|
18
|
+
from pyedb.generic.settings import settings
|
|
18
19
|
|
|
19
20
|
|
|
20
21
|
def _parse_value(v):
|
|
@@ -79,8 +80,10 @@ def clone_edb_sim_setup_info(source, target):
|
|
|
79
80
|
except TypeError:
|
|
80
81
|
try:
|
|
81
82
|
setter.__setattr__(k, str(value))
|
|
82
|
-
except:
|
|
83
|
-
|
|
83
|
+
except Exception as e:
|
|
84
|
+
settings.logger.warning(
|
|
85
|
+
f"Failed to update attribute {k} with value {value} - {type(e).__name__}: {str(e)}"
|
|
86
|
+
)
|
|
84
87
|
|
|
85
88
|
|
|
86
89
|
class SiwaveSimulationSetup(SimulationSetup):
|
pyedb/dotnet/edb.py
CHANGED
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
This module is implicitly loaded in HFSS 3D Layout when launched.
|
|
26
26
|
|
|
27
27
|
"""
|
|
28
|
+
|
|
28
29
|
from datetime import datetime
|
|
29
30
|
from itertools import combinations
|
|
30
31
|
import os
|
|
@@ -43,7 +44,6 @@ import rtree
|
|
|
43
44
|
|
|
44
45
|
from pyedb.configuration.configuration import Configuration
|
|
45
46
|
import pyedb.dotnet
|
|
46
|
-
from pyedb.dotnet.database.Variables import decompose_variable_value
|
|
47
47
|
from pyedb.dotnet.database.cell.layout import Layout
|
|
48
48
|
from pyedb.dotnet.database.cell.terminal.terminal import Terminal
|
|
49
49
|
from pyedb.dotnet.database.components import Components
|
|
@@ -92,6 +92,7 @@ from pyedb.dotnet.database.utilities.siwave_simulation_setup import (
|
|
|
92
92
|
SiwaveSimulationSetup,
|
|
93
93
|
)
|
|
94
94
|
from pyedb.dotnet.database.utilities.value import Value
|
|
95
|
+
from pyedb.dotnet.database.Variables import decompose_variable_value
|
|
95
96
|
from pyedb.generic.constants import AEDT_UNITS, SolverType, unit_converter
|
|
96
97
|
from pyedb.generic.general_methods import generate_unique_name, is_linux, is_windows
|
|
97
98
|
from pyedb.generic.process import SiwaveSolve
|
|
@@ -152,19 +153,19 @@ class Edb:
|
|
|
152
153
|
|
|
153
154
|
Add a new variable named "s1" to the ``Edb`` instance.
|
|
154
155
|
|
|
155
|
-
>>> app[
|
|
156
|
-
>>> app[
|
|
156
|
+
>>> app["s1"] = "0.25 mm"
|
|
157
|
+
>>> app["s1"].tofloat
|
|
157
158
|
>>> 0.00025
|
|
158
|
-
>>> app[
|
|
159
|
+
>>> app["s1"].tostring
|
|
159
160
|
>>> "0.25mm"
|
|
160
161
|
|
|
161
162
|
or add a new parameter with description:
|
|
162
163
|
|
|
163
|
-
>>> app[
|
|
164
|
-
>>> app[
|
|
164
|
+
>>> app["s2"] = ["20um", "Spacing between traces"]
|
|
165
|
+
>>> app["s2"].value
|
|
165
166
|
>>> 1.9999999999999998e-05
|
|
166
|
-
>>> app[
|
|
167
|
-
>>>
|
|
167
|
+
>>> app["s2"].description
|
|
168
|
+
>>> "Spacing between traces"
|
|
168
169
|
|
|
169
170
|
Create an ``Edb`` object and open the specified project.
|
|
170
171
|
|
|
@@ -1852,8 +1853,11 @@ class Edb:
|
|
|
1852
1853
|
convert_py_list_to_net_list(list(obj_data)),
|
|
1853
1854
|
convert_py_list_to_net_list(voids_poly),
|
|
1854
1855
|
)
|
|
1855
|
-
except:
|
|
1856
|
-
|
|
1856
|
+
except Exception as e:
|
|
1857
|
+
self.logger.error(
|
|
1858
|
+
f"A(n) {type(e).__name__} error occurred in method _create_conformal of "
|
|
1859
|
+
f"class Edb at iteration {k} for data {i}: {str(e)}"
|
|
1860
|
+
)
|
|
1857
1861
|
finally:
|
|
1858
1862
|
unite_polys.extend(list(obj_data))
|
|
1859
1863
|
_poly_unite = self.core.Geometry.PolygonData.Unite(convert_py_list_to_net_list(unite_polys))
|
|
@@ -2048,7 +2052,7 @@ class Edb:
|
|
|
2048
2052
|
Examples
|
|
2049
2053
|
--------
|
|
2050
2054
|
>>> from pyedb import Edb
|
|
2051
|
-
>>> edb = Edb(r
|
|
2055
|
+
>>> edb = Edb(r"C:\\test.aedb", version="2022.2")
|
|
2052
2056
|
>>> edb.logger.info_timer("Edb Opening")
|
|
2053
2057
|
>>> edb.logger.reset_timer()
|
|
2054
2058
|
>>> start = time.time()
|
|
@@ -2058,7 +2062,7 @@ class Edb:
|
|
|
2058
2062
|
>>> signal_list.append(net)
|
|
2059
2063
|
>>> power_list = ["PGND"]
|
|
2060
2064
|
>>> edb.cutout(signal_list=signal_list, reference_list=power_list, extent_type="Conforming")
|
|
2061
|
-
>>> end_time = str((time.time() - start)/60)
|
|
2065
|
+
>>> end_time = str((time.time() - start) / 60)
|
|
2062
2066
|
>>> edb.logger.info("Total legacy cutout time in min %s", end_time)
|
|
2063
2067
|
>>> edb.nets.plot(signal_list, None, color_by_net=True)
|
|
2064
2068
|
>>> edb.nets.plot(power_list, None, color_by_net=True)
|
|
@@ -2291,8 +2295,8 @@ class Edb:
|
|
|
2291
2295
|
if os.path.exists(source) and not os.path.exists(target):
|
|
2292
2296
|
try:
|
|
2293
2297
|
shutil.copy(source, target)
|
|
2294
|
-
except:
|
|
2295
|
-
|
|
2298
|
+
except Exception as e:
|
|
2299
|
+
self.logger.error(f"Failed to copy {source} to {target} - {type(e).__name__}: {str(e)}")
|
|
2296
2300
|
elif open_cutout_at_end:
|
|
2297
2301
|
self._active_cell = _cutout
|
|
2298
2302
|
self._init_objects()
|
|
@@ -2708,7 +2712,7 @@ class Edb:
|
|
|
2708
2712
|
Examples
|
|
2709
2713
|
--------
|
|
2710
2714
|
>>> from pyedb import Edb
|
|
2711
|
-
>>> edb = Edb(r
|
|
2715
|
+
>>> edb = Edb(r"C:\\test.aedb", version="2022.2")
|
|
2712
2716
|
>>> edb.logger.info_timer("Edb Opening")
|
|
2713
2717
|
>>> edb.logger.reset_timer()
|
|
2714
2718
|
>>> start = time.time()
|
|
@@ -2718,7 +2722,7 @@ class Edb:
|
|
|
2718
2722
|
>>> signal_list.append(net)
|
|
2719
2723
|
>>> power_list = ["PGND"]
|
|
2720
2724
|
>>> edb.create_cutout_multithread(signal_list=signal_list, reference_list=power_list, extent_type="Conforming")
|
|
2721
|
-
>>> end_time = str((time.time() - start)/60)
|
|
2725
|
+
>>> end_time = str((time.time() - start) / 60)
|
|
2722
2726
|
>>> edb.logger.info("Total legacy cutout time in min %s", end_time)
|
|
2723
2727
|
>>> edb.nets.plot(signal_list, None, color_by_net=True)
|
|
2724
2728
|
>>> edb.nets.plot(power_list, None, color_by_net=True)
|
|
@@ -2977,8 +2981,8 @@ class Edb:
|
|
|
2977
2981
|
try:
|
|
2978
2982
|
shutil.copy(source, target)
|
|
2979
2983
|
self.logger.warning("aedb def file manually created.")
|
|
2980
|
-
except:
|
|
2981
|
-
|
|
2984
|
+
except Exception as e:
|
|
2985
|
+
self.logger.error(f"Failed to copy {source} to {target} - {type(e).__name__}: {str(e)}")
|
|
2982
2986
|
return [[pt.X.ToDouble(), pt.Y.ToDouble()] for pt in list(polygonData.GetPolygonWithoutArcs().Points)]
|
|
2983
2987
|
|
|
2984
2988
|
def create_cutout_on_point_list(
|
|
@@ -3107,7 +3111,7 @@ class Edb:
|
|
|
3107
3111
|
>>> from pyedb import Edb
|
|
3108
3112
|
>>> edb = Edb(edbpath="C:\\temp\\myproject.aedb", version="2023.2")
|
|
3109
3113
|
|
|
3110
|
-
>>> options_config = {
|
|
3114
|
+
>>> options_config = {"UNITE_NETS": 1, "LAUNCH_Q3D": 0}
|
|
3111
3115
|
>>> edb.write_export3d_option_config_file(r"C:\\temp", options_config)
|
|
3112
3116
|
>>> edb.export_hfss(r"C:\\temp")
|
|
3113
3117
|
"""
|
|
@@ -3149,7 +3153,7 @@ class Edb:
|
|
|
3149
3153
|
|
|
3150
3154
|
>>> from pyedb import Edb
|
|
3151
3155
|
>>> edb = Edb(edbpath="C:\\temp\\myproject.aedb", version="2021.2")
|
|
3152
|
-
>>> options_config = {
|
|
3156
|
+
>>> options_config = {"UNITE_NETS": 1, "LAUNCH_Q3D": 0}
|
|
3153
3157
|
>>> edb.write_export3d_option_config_file("C:\\temp", options_config)
|
|
3154
3158
|
>>> edb.export_q3d("C:\\temp")
|
|
3155
3159
|
"""
|
|
@@ -3201,7 +3205,7 @@ class Edb:
|
|
|
3201
3205
|
|
|
3202
3206
|
>>> edb = Edb(edbpath="C:\\temp\\myproject.aedb", version="2021.2")
|
|
3203
3207
|
|
|
3204
|
-
>>> options_config = {
|
|
3208
|
+
>>> options_config = {"UNITE_NETS": 1, "LAUNCH_Q3D": 0}
|
|
3205
3209
|
>>> edb.write_export3d_option_config_file("C:\\temp", options_config)
|
|
3206
3210
|
>>> edb.export_maxwell("C:\\temp")
|
|
3207
3211
|
"""
|
|
@@ -3369,8 +3373,8 @@ class Edb:
|
|
|
3369
3373
|
>>> from pyedb import Edb
|
|
3370
3374
|
>>> edb_app = Edb()
|
|
3371
3375
|
>>> boolean_1, ant_length = edb_app.add_project_variable("my_local_variable", "1cm")
|
|
3372
|
-
>>> print(edb_app["$my_local_variable"])
|
|
3373
|
-
>>> edb_app["$my_local_variable"] = "1cm"
|
|
3376
|
+
>>> print(edb_app["$my_local_variable"]) # using getitem
|
|
3377
|
+
>>> edb_app["$my_local_variable"] = "1cm" # using setitem
|
|
3374
3378
|
|
|
3375
3379
|
"""
|
|
3376
3380
|
if not variable_name.startswith("$"):
|
|
@@ -3408,8 +3412,8 @@ class Edb:
|
|
|
3408
3412
|
>>> from pyedb import Edb
|
|
3409
3413
|
>>> edb_app = Edb()
|
|
3410
3414
|
>>> boolean_1, ant_length = edb_app.add_design_variable("my_local_variable", "1cm")
|
|
3411
|
-
>>> print(edb_app["my_local_variable"])
|
|
3412
|
-
>>> edb_app["my_local_variable"] = "1cm"
|
|
3415
|
+
>>> print(edb_app["my_local_variable"]) # using getitem
|
|
3416
|
+
>>> edb_app["my_local_variable"] = "1cm" # using setitem
|
|
3413
3417
|
>>> boolean_2, para_length = edb_app.change_design_variable_value("my_parameter", "1m", is_parameter=True
|
|
3414
3418
|
>>> boolean_3, project_length = edb_app.change_design_variable_value("$my_project_variable", "1m")
|
|
3415
3419
|
|
|
@@ -3449,7 +3453,7 @@ class Edb:
|
|
|
3449
3453
|
>>> edb_app = Edb()
|
|
3450
3454
|
>>> boolean, ant_length = edb_app.add_design_variable("ant_length", "1cm")
|
|
3451
3455
|
>>> boolean, ant_length = edb_app.change_design_variable_value("ant_length", "1m")
|
|
3452
|
-
>>> print(edb_app["ant_length"])
|
|
3456
|
+
>>> print(edb_app["ant_length"]) # using getitem
|
|
3453
3457
|
"""
|
|
3454
3458
|
var_server = self.variable_exists(variable_name)
|
|
3455
3459
|
if var_server[0]:
|
|
@@ -3928,11 +3932,13 @@ class Edb:
|
|
|
3928
3932
|
>>> from pyedb import Edb
|
|
3929
3933
|
>>> edbapp = Edb()
|
|
3930
3934
|
>>> setup1 = edbapp.create_siwave_syz_setup("setup1")
|
|
3931
|
-
>>> setup1.add_frequency_sweep(
|
|
3932
|
-
...
|
|
3933
|
-
...
|
|
3934
|
-
...
|
|
3935
|
-
...
|
|
3935
|
+
>>> setup1.add_frequency_sweep(
|
|
3936
|
+
... frequency_sweep=[
|
|
3937
|
+
... ["linear count", "0", "1kHz", 1],
|
|
3938
|
+
... ["log scale", "1kHz", "0.1GHz", 10],
|
|
3939
|
+
... ["linear scale", "0.1GHz", "10GHz", "0.1GHz"],
|
|
3940
|
+
... ]
|
|
3941
|
+
... )
|
|
3936
3942
|
"""
|
|
3937
3943
|
if not name:
|
|
3938
3944
|
name = generate_unique_name("Siwave_SYZ")
|
|
@@ -4687,8 +4693,7 @@ class Edb:
|
|
|
4687
4693
|
]
|
|
4688
4694
|
if not polys:
|
|
4689
4695
|
raise RuntimeWarning(
|
|
4690
|
-
f"No polygon found with voids on layer {reference_layer} during model creation for "
|
|
4691
|
-
f"arbitrary wave ports"
|
|
4696
|
+
f"No polygon found with voids on layer {reference_layer} during model creation for arbitrary wave ports"
|
|
4692
4697
|
)
|
|
4693
4698
|
void_padstacks = []
|
|
4694
4699
|
for poly in polys:
|
|
@@ -4705,7 +4710,7 @@ class Edb:
|
|
|
4705
4710
|
|
|
4706
4711
|
if not void_padstacks:
|
|
4707
4712
|
raise RuntimeWarning(
|
|
4708
|
-
"No padstack instances found inside evaluated voids during model creation for arbitrary
|
|
4713
|
+
"No padstack instances found inside evaluated voids during model creation for arbitrary waveports"
|
|
4709
4714
|
)
|
|
4710
4715
|
cloned_edb = Edb(edbpath=output_edb)
|
|
4711
4716
|
|
pyedb/exceptions.py
CHANGED
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
"""
|
|
24
24
|
This module contains the array building feature from unit cell.
|
|
25
25
|
"""
|
|
26
|
+
|
|
26
27
|
import itertools
|
|
27
28
|
from typing import Optional, Union
|
|
28
29
|
|
|
@@ -36,8 +37,8 @@ def create_array_from_unit_cell(
|
|
|
36
37
|
edb: Edb,
|
|
37
38
|
x_number: int = 2,
|
|
38
39
|
y_number: int = 2,
|
|
39
|
-
offset_x: Optional[Union[int, float]] = None,
|
|
40
|
-
offset_y: Optional[Union[int, float]] = None,
|
|
40
|
+
offset_x: Optional[Union[int, float, str]] = None,
|
|
41
|
+
offset_y: Optional[Union[int, float, str]] = None,
|
|
41
42
|
) -> bool:
|
|
42
43
|
"""
|
|
43
44
|
Create a 2-D rectangular array from the current EDB unit cell.
|
|
@@ -56,10 +57,10 @@ def create_array_from_unit_cell(
|
|
|
56
57
|
Number of columns (X-direction). Must be > 0. Defaults to 2.
|
|
57
58
|
y_number : int, optional
|
|
58
59
|
Number of rows (Y-direction). Must be > 0. Defaults to 2.
|
|
59
|
-
offset_x : int | float | None, optional
|
|
60
|
+
offset_x : int | float | str, None, optional
|
|
60
61
|
Horizontal pitch (distance between cell origins). When *None* the
|
|
61
62
|
value is derived from the outline geometry.
|
|
62
|
-
offset_y : int | float | None, optional
|
|
63
|
+
offset_y : int | float | str, None, optional
|
|
63
64
|
Vertical pitch (distance between cell origins). When *None* the
|
|
64
65
|
value is derived from the outline geometry.
|
|
65
66
|
|
|
@@ -133,8 +134,12 @@ def __create_array_from_unit_cell_impl(
|
|
|
133
134
|
# ---------- Sanity & auto-pitch detection ----------
|
|
134
135
|
if x_number <= 0 or y_number <= 0:
|
|
135
136
|
raise ValueError("x_number and y_number must be positive integers")
|
|
137
|
+
if offset_x and not offset_y:
|
|
138
|
+
raise ValueError("If offset_x is provided, offset_y must be provided as well")
|
|
139
|
+
if offset_y and not offset_x:
|
|
140
|
+
raise ValueError("If offset_y is provided, offset_x must be provided as well")
|
|
136
141
|
|
|
137
|
-
if offset_x
|
|
142
|
+
if not offset_x and not offset_y:
|
|
138
143
|
edb.logger.info("Auto-detecting outline extents")
|
|
139
144
|
outline_prims = [p for p in edb.modeler.primitives if p.layer_name.lower() == "outline"]
|
|
140
145
|
if not outline_prims:
|
|
@@ -143,6 +148,8 @@ def __create_array_from_unit_cell_impl(
|
|
|
143
148
|
if not adapter.is_supported_outline(outline):
|
|
144
149
|
raise RuntimeError("Outline primitive is not a polygon/rectangle. Provide offset_x / offset_y.")
|
|
145
150
|
offset_x, offset_y = adapter.pitch_from_outline(outline)
|
|
151
|
+
offset_x = edb.value(offset_x)
|
|
152
|
+
offset_y = edb.value(offset_y)
|
|
146
153
|
|
|
147
154
|
# ---------- Collect everything we have to replicate ----------
|
|
148
155
|
primitives = [p for p in edb.modeler.primitives if adapter.is_primitive_to_copy(p)]
|
|
@@ -263,6 +270,9 @@ class _GrpcAdapter(_BaseAdapter):
|
|
|
263
270
|
width=path.width,
|
|
264
271
|
layer_name=path.layer.name,
|
|
265
272
|
net_name=path.net.name,
|
|
273
|
+
corner_style=path.corner_style,
|
|
274
|
+
start_cap_style=path.end_cap1,
|
|
275
|
+
end_cap_style=path.end_cap2,
|
|
266
276
|
)
|
|
267
277
|
|
|
268
278
|
def duplicate_standalone_via(self, via, dx, dy, i, j):
|
|
@@ -357,11 +367,15 @@ class _DotNetAdapter(_BaseAdapter):
|
|
|
357
367
|
moved_path = path._edb_object.GetCenterLine()
|
|
358
368
|
moved_path.Move(vector._edb_object)
|
|
359
369
|
moved_path = [[pt.X.ToDouble(), pt.Y.ToDouble()] for pt in list(moved_path.Points)]
|
|
370
|
+
end_caps = path._edb_object.GetEndCapStyle()
|
|
371
|
+
|
|
360
372
|
self.edb.modeler.create_trace(
|
|
361
373
|
path_list=list(moved_path),
|
|
362
374
|
width=path.width,
|
|
363
375
|
layer_name=path.layer.name,
|
|
364
376
|
net_name=path.net.name,
|
|
377
|
+
start_cap_style=str(end_caps[1]),
|
|
378
|
+
end_cap_style=str(end_caps[2]),
|
|
365
379
|
)
|
|
366
380
|
|
|
367
381
|
def duplicate_standalone_via(self, via, dx, dy, i, j):
|
pyedb/generic/data_handlers.py
CHANGED
|
@@ -72,23 +72,13 @@ def unique_string_list(element_list, only_string=True): # pragma: no cover
|
|
|
72
72
|
-------
|
|
73
73
|
|
|
74
74
|
"""
|
|
75
|
-
if element_list:
|
|
76
|
-
|
|
77
|
-
element_list = set(element_list)
|
|
78
|
-
elif isinstance(element_list, str):
|
|
79
|
-
element_list = [element_list]
|
|
80
|
-
else:
|
|
81
|
-
error_message = "Invalid list data"
|
|
82
|
-
try:
|
|
83
|
-
error_message += " {}".format(element_list)
|
|
84
|
-
except:
|
|
85
|
-
pass
|
|
86
|
-
raise Exception(error_message)
|
|
75
|
+
if isinstance(element_list, str):
|
|
76
|
+
element_list = [element_list]
|
|
87
77
|
|
|
88
|
-
|
|
89
|
-
|
|
78
|
+
if only_string and any(not isinstance(x, str) for x in element_list):
|
|
79
|
+
raise TypeError("Invalid list entries, some elements are not of type string.")
|
|
90
80
|
|
|
91
|
-
return element_list
|
|
81
|
+
return list(set(element_list))
|
|
92
82
|
|
|
93
83
|
|
|
94
84
|
def string_list(element_list): # pragma: no cover
|
|
@@ -142,28 +132,28 @@ def from_rkm(code): # pragma: no cover
|
|
|
142
132
|
|
|
143
133
|
Examples
|
|
144
134
|
--------
|
|
145
|
-
>>> from_rkm(
|
|
135
|
+
>>> from_rkm("R47")
|
|
146
136
|
'0.47'
|
|
147
137
|
|
|
148
|
-
>>> from_rkm(
|
|
138
|
+
>>> from_rkm("4R7")
|
|
149
139
|
'4.7'
|
|
150
140
|
|
|
151
|
-
>>> from_rkm(
|
|
141
|
+
>>> from_rkm("470R")
|
|
152
142
|
'470'
|
|
153
143
|
|
|
154
|
-
>>> from_rkm(
|
|
144
|
+
>>> from_rkm("4K7")
|
|
155
145
|
'4.7k'
|
|
156
146
|
|
|
157
|
-
>>> from_rkm(
|
|
147
|
+
>>> from_rkm("47K")
|
|
158
148
|
'47k'
|
|
159
149
|
|
|
160
|
-
>>> from_rkm(
|
|
150
|
+
>>> from_rkm("47K3")
|
|
161
151
|
'47.3k'
|
|
162
152
|
|
|
163
|
-
>>> from_rkm(
|
|
153
|
+
>>> from_rkm("470K")
|
|
164
154
|
'470k'
|
|
165
155
|
|
|
166
|
-
>>> from_rkm(
|
|
156
|
+
>>> from_rkm("4M7")
|
|
167
157
|
'4.7M'
|
|
168
158
|
|
|
169
159
|
"""
|
pyedb/generic/design_types.py
CHANGED
|
@@ -32,18 +32,15 @@ if TYPE_CHECKING:
|
|
|
32
32
|
|
|
33
33
|
|
|
34
34
|
@overload
|
|
35
|
-
def Edb(*, grpc: Literal[True], **kwargs) -> "EdbGrpc":
|
|
36
|
-
...
|
|
35
|
+
def Edb(*, grpc: Literal[True], **kwargs) -> "EdbGrpc": ...
|
|
37
36
|
|
|
38
37
|
|
|
39
38
|
@overload
|
|
40
|
-
def Edb(*, grpc: Literal[False] = False, **kwargs) -> "EdbDotnet":
|
|
41
|
-
...
|
|
39
|
+
def Edb(*, grpc: Literal[False] = False, **kwargs) -> "EdbDotnet": ...
|
|
42
40
|
|
|
43
41
|
|
|
44
42
|
@overload
|
|
45
|
-
def Edb(*, grpc: bool, **kwargs) -> Union["EdbGrpc", "EdbDotnet"]:
|
|
46
|
-
...
|
|
43
|
+
def Edb(*, grpc: bool, **kwargs) -> Union["EdbGrpc", "EdbDotnet"]: ...
|
|
47
44
|
|
|
48
45
|
|
|
49
46
|
# lazy imports
|
|
@@ -167,17 +164,10 @@ def Edb(
|
|
|
167
164
|
4. Simulation Setup
|
|
168
165
|
|
|
169
166
|
# Create SIwave SYZ setup
|
|
170
|
-
>>> syz_setup = edb.create_siwave_syz_setup(
|
|
171
|
-
>>> name="GHz_Setup",
|
|
172
|
-
>>> start_freq="1GHz",
|
|
173
|
-
>>> stop_freq="10GHz"
|
|
174
|
-
>>> )
|
|
167
|
+
>>> syz_setup = edb.create_siwave_syz_setup(name="GHz_Setup", start_freq="1GHz", stop_freq="10GHz")
|
|
175
168
|
|
|
176
169
|
# Create SIwave DC setup
|
|
177
|
-
>>> dc_setup = edb.create_siwave_dc_setup(
|
|
178
|
-
>>> name="DC_Analysis",
|
|
179
|
-
>>> use_dc_point=True
|
|
180
|
-
>>> )
|
|
170
|
+
>>> dc_setup = edb.create_siwave_dc_setup(name="DC_Analysis", use_dc_point=True)
|
|
181
171
|
|
|
182
172
|
# Solve with SIwave
|
|
183
173
|
>>> edb.solve_siwave()
|
|
@@ -208,17 +198,10 @@ def Edb(
|
|
|
208
198
|
7. Port Creation
|
|
209
199
|
|
|
210
200
|
# Create wave port between two pins
|
|
211
|
-
>>> wave_port = edb.source_excitation.create_port(
|
|
212
|
-
>>> positive_terminal=pin1,
|
|
213
|
-
>>> negative_terminal=pin2,
|
|
214
|
-
>>> port_type="Wave"
|
|
215
|
-
>>> )
|
|
201
|
+
>>> wave_port = edb.source_excitation.create_port(positive_terminal=pin1, negative_terminal=pin2, port_type="Wave")
|
|
216
202
|
|
|
217
203
|
# Create lumped port
|
|
218
|
-
>>> lumped_port = edb.source_excitation.create_port(
|
|
219
|
-
>>> positive_terminal=via_terminal,
|
|
220
|
-
>>> port_type="Lumped"
|
|
221
|
-
>>> )
|
|
204
|
+
>>> lumped_port = edb.source_excitation.create_port(positive_terminal=via_terminal, port_type="Lumped")
|
|
222
205
|
|
|
223
206
|
8. Component Management
|
|
224
207
|
|
|
@@ -231,12 +214,7 @@ def Edb(
|
|
|
231
214
|
9. Parametrization
|
|
232
215
|
|
|
233
216
|
# Auto-parametrize design elements
|
|
234
|
-
>>> params = edb.auto_parametrize_design(
|
|
235
|
-
>>> traces=True,
|
|
236
|
-
>>> pads=True,
|
|
237
|
-
>>> antipads=True,
|
|
238
|
-
>>> use_relative_variables=True
|
|
239
|
-
>>> )
|
|
217
|
+
>>> params = edb.auto_parametrize_design(traces=True, pads=True, antipads=True, use_relative_variables=True)
|
|
240
218
|
>>> print("Created parameters:", params)
|
|
241
219
|
|
|
242
220
|
10. Design Statistics
|
|
@@ -255,11 +233,7 @@ def Edb(
|
|
|
255
233
|
12. Differential Pairs
|
|
256
234
|
|
|
257
235
|
# Create differential pair
|
|
258
|
-
>>> edb.differential_pairs.create(
|
|
259
|
-
>>> positive_net="USB_P",
|
|
260
|
-
>>> negative_net="USB_N",
|
|
261
|
-
>>> name="USB_DP"
|
|
262
|
-
>>> )
|
|
236
|
+
>>> edb.differential_pairs.create(positive_net="USB_P", negative_net="USB_N", name="USB_DP")
|
|
263
237
|
|
|
264
238
|
13. Workflow Automation
|
|
265
239
|
|