pyedb 0.43.0__py3-none-any.whl → 0.45.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_boundaries.py +21 -15
- pyedb/configuration/cfg_components.py +8 -8
- pyedb/configuration/cfg_general.py +14 -6
- pyedb/configuration/cfg_modeler.py +8 -0
- pyedb/configuration/cfg_operations.py +40 -1
- pyedb/configuration/cfg_package_definition.py +41 -1
- pyedb/configuration/cfg_padstacks.py +611 -256
- pyedb/configuration/cfg_pin_groups.py +1 -1
- pyedb/configuration/cfg_ports_sources.py +234 -66
- pyedb/configuration/cfg_s_parameter_models.py +81 -1
- pyedb/configuration/cfg_setup.py +167 -33
- pyedb/configuration/cfg_stackup.py +44 -0
- pyedb/configuration/configuration.py +13 -3
- pyedb/dotnet/database/cell/primitive/path.py +12 -0
- pyedb/dotnet/database/edb_data/design_options.py +19 -1
- pyedb/dotnet/database/edb_data/padstacks_data.py +9 -4
- pyedb/dotnet/database/geometry/point_data.py +26 -0
- pyedb/dotnet/database/geometry/polygon_data.py +13 -2
- pyedb/dotnet/database/nets.py +13 -3
- pyedb/dotnet/database/padstack.py +6 -2
- pyedb/dotnet/database/utilities/simulation_setup.py +7 -17
- pyedb/dotnet/database/utilities/siwave_simulation_setup.py +30 -0
- pyedb/dotnet/edb.py +41 -18
- pyedb/grpc/database/components.py +2 -3
- pyedb/grpc/database/definition/component_def.py +15 -0
- pyedb/grpc/database/definition/component_pin.py +1 -1
- pyedb/grpc/database/definition/materials.py +27 -0
- pyedb/grpc/database/definition/package_def.py +20 -2
- pyedb/grpc/database/definition/padstack_def.py +5 -2
- pyedb/grpc/database/hfss.py +10 -1
- pyedb/grpc/database/hierarchy/component.py +4 -2
- pyedb/grpc/database/hierarchy/pingroup.py +12 -8
- pyedb/grpc/database/layers/layer.py +28 -0
- pyedb/grpc/database/layers/stackup_layer.py +281 -40
- pyedb/grpc/database/layout/layout.py +12 -6
- pyedb/grpc/database/layout_validation.py +2 -2
- pyedb/grpc/database/modeler.py +8 -8
- pyedb/grpc/database/padstacks.py +15 -9
- pyedb/grpc/database/ports/ports.py +3 -3
- pyedb/grpc/database/primitive/bondwire.py +3 -3
- pyedb/grpc/database/primitive/circle.py +1 -1
- pyedb/grpc/database/primitive/padstack_instance.py +13 -3
- pyedb/grpc/database/primitive/path.py +2 -2
- pyedb/grpc/database/primitive/polygon.py +3 -3
- pyedb/grpc/database/primitive/primitive.py +1 -1
- pyedb/grpc/database/primitive/rectangle.py +2 -2
- pyedb/grpc/database/simulation_setup/hfss_simulation_setup.py +78 -30
- pyedb/grpc/database/simulation_setup/siwave_simulation_setup.py +73 -30
- pyedb/grpc/database/simulation_setup/sweep_data.py +12 -1
- pyedb/grpc/database/siwave.py +10 -1
- pyedb/grpc/database/source_excitations.py +19 -9
- pyedb/grpc/database/stackup.py +26 -10
- pyedb/grpc/database/terminal/bundle_terminal.py +3 -3
- pyedb/grpc/database/terminal/edge_terminal.py +95 -2
- pyedb/grpc/database/terminal/padstack_instance_terminal.py +42 -2
- pyedb/grpc/database/terminal/pingroup_terminal.py +48 -2
- pyedb/grpc/database/terminal/point_terminal.py +10 -1
- pyedb/grpc/database/terminal/terminal.py +4 -4
- pyedb/grpc/database/utility/hfss_extent_info.py +14 -10
- pyedb/grpc/edb.py +21 -17
- pyedb/grpc/edb_init.py +19 -15
- pyedb/grpc/rpc_session.py +11 -8
- pyedb/misc/misc.py +13 -0
- {pyedb-0.43.0.dist-info → pyedb-0.45.0.dist-info}/METADATA +6 -6
- {pyedb-0.43.0.dist-info → pyedb-0.45.0.dist-info}/RECORD +68 -68
- {pyedb-0.43.0.dist-info → pyedb-0.45.0.dist-info}/LICENSE +0 -0
- {pyedb-0.43.0.dist-info → pyedb-0.45.0.dist-info}/WHEEL +0 -0
|
@@ -25,7 +25,7 @@ import math
|
|
|
25
25
|
|
|
26
26
|
from ansys.edb.core.geometry.point_data import PointData as GrpcPointData
|
|
27
27
|
from ansys.edb.core.geometry.polygon_data import PolygonData as GrpcPolygonData
|
|
28
|
-
from ansys.edb.core.primitive.
|
|
28
|
+
from ansys.edb.core.primitive.polygon import Polygon as GrpcPolygon
|
|
29
29
|
from ansys.edb.core.utility.value import Value as GrpcValue
|
|
30
30
|
|
|
31
31
|
from pyedb.grpc.database.primitive.primitive import Primitive
|
|
@@ -64,7 +64,7 @@ class Polygon(GrpcPolygon, Primitive):
|
|
|
64
64
|
|
|
65
65
|
Returns
|
|
66
66
|
-------
|
|
67
|
-
List[:class:`Polygon <ansys.edb.core.primitive.
|
|
67
|
+
List[:class:`Polygon <ansys.edb.core.primitive.polygon.Polygon>`]
|
|
68
68
|
All new polygons created from the removal operation.
|
|
69
69
|
|
|
70
70
|
"""
|
|
@@ -84,7 +84,7 @@ class Polygon(GrpcPolygon, Primitive):
|
|
|
84
84
|
|
|
85
85
|
Returns
|
|
86
86
|
-------
|
|
87
|
-
:class:`Polygon <ansys.edb.core.primitive.
|
|
87
|
+
:class:`Polygon <ansys.edb.core.primitive.polygon.Polygon>`
|
|
88
88
|
Cloned polygon.
|
|
89
89
|
|
|
90
90
|
"""
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
|
|
23
23
|
from ansys.edb.core.database import ProductIdType as GrpcProductIdType
|
|
24
24
|
from ansys.edb.core.geometry.point_data import PointData as GrpcPointData
|
|
25
|
-
from ansys.edb.core.primitive.
|
|
25
|
+
from ansys.edb.core.primitive.circle import Circle as GrpcCircle
|
|
26
26
|
from ansys.edb.core.primitive.primitive import Primitive as GrpcPrimitive
|
|
27
27
|
|
|
28
28
|
from pyedb.misc.utilities import compute_arc_points
|
|
@@ -21,10 +21,10 @@
|
|
|
21
21
|
# SOFTWARE.
|
|
22
22
|
|
|
23
23
|
|
|
24
|
-
from ansys.edb.core.primitive.
|
|
24
|
+
from ansys.edb.core.primitive.rectangle import (
|
|
25
25
|
RectangleRepresentationType as GrpcRectangleRepresentationType,
|
|
26
26
|
)
|
|
27
|
-
from ansys.edb.core.primitive.
|
|
27
|
+
from ansys.edb.core.primitive.rectangle import Rectangle as GrpcRectangle
|
|
28
28
|
from ansys.edb.core.utility.value import Value as GrpcValue
|
|
29
29
|
|
|
30
30
|
from pyedb.grpc.database.primitive.primitive import Primitive
|
|
@@ -293,7 +293,14 @@ class HfssSimulationSetup(GrpcHfssSimulationSetup):
|
|
|
293
293
|
return mesh_operation
|
|
294
294
|
|
|
295
295
|
def add_sweep(
|
|
296
|
-
self,
|
|
296
|
+
self,
|
|
297
|
+
name=None,
|
|
298
|
+
distribution="linear",
|
|
299
|
+
start_freq="0GHz",
|
|
300
|
+
stop_freq="20GHz",
|
|
301
|
+
step="10MHz",
|
|
302
|
+
discrete=False,
|
|
303
|
+
frequency_set=None,
|
|
297
304
|
):
|
|
298
305
|
"""Add a HFSS frequency sweep.
|
|
299
306
|
|
|
@@ -317,39 +324,80 @@ class HfssSimulationSetup(GrpcHfssSimulationSetup):
|
|
|
317
324
|
distribution. Must be integer in that case.
|
|
318
325
|
discrete : bool, optional
|
|
319
326
|
Whether the sweep is discrete. The default is ``False``.
|
|
327
|
+
frequency_set : List, optional
|
|
328
|
+
Frequency set is a list adding one or more frequency sweeps. If ``frequency_set`` is provided, the other
|
|
329
|
+
arguments are ignored except ``discrete``. Default value is ``None``.
|
|
330
|
+
example of frequency_set : [['linear_scale', '50MHz', '200MHz', '10MHz']].
|
|
320
331
|
|
|
321
332
|
Returns
|
|
322
333
|
-------
|
|
323
334
|
bool
|
|
324
335
|
"""
|
|
325
336
|
init_sweep_count = len(self.sweep_data)
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
337
|
+
if frequency_set:
|
|
338
|
+
for sweep in frequency_set:
|
|
339
|
+
if "linear_scale" in sweep:
|
|
340
|
+
distribution = "LIN"
|
|
341
|
+
elif "linear_count" in sweep:
|
|
342
|
+
distribution = "LINC"
|
|
343
|
+
elif "exponential" in sweep:
|
|
344
|
+
distribution = "ESTP"
|
|
345
|
+
elif "log_scale" in sweep:
|
|
346
|
+
distribution = "DEC"
|
|
347
|
+
elif "octave_count" in sweep:
|
|
348
|
+
distribution = "OCT"
|
|
349
|
+
else:
|
|
350
|
+
distribution = "LIN"
|
|
351
|
+
start_freq = self._pedb.number_with_units(sweep[1], "Hz")
|
|
352
|
+
stop_freq = self._pedb.number_with_units(sweep[2], "Hz")
|
|
353
|
+
step = str(sweep[3])
|
|
354
|
+
if not name:
|
|
355
|
+
name = f"sweep_{init_sweep_count + 1}"
|
|
356
|
+
sweep_data = [
|
|
357
|
+
SweepData(
|
|
358
|
+
self._pedb, name=name, distribution=distribution, start_f=start_freq, end_f=stop_freq, step=step
|
|
359
|
+
)
|
|
360
|
+
]
|
|
361
|
+
if discrete:
|
|
362
|
+
sweep_data[0].type = sweep_data[0].type.DISCRETE_SWEEP
|
|
363
|
+
for sweep in self.sweep_data:
|
|
364
|
+
sweep_data.append(sweep)
|
|
365
|
+
self.sweep_data = sweep_data
|
|
339
366
|
else:
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
367
|
+
start_freq = self._pedb.number_with_units(start_freq, "Hz")
|
|
368
|
+
stop_freq = self._pedb.number_with_units(stop_freq, "Hz")
|
|
369
|
+
step = str(step)
|
|
370
|
+
if not distribution in ["LIN", "LINC", "ESTP", "DEC", "OCT"]:
|
|
371
|
+
if distribution.lower() == "linear" or distribution.lower() == "linear scale":
|
|
372
|
+
distribution = "LIN"
|
|
373
|
+
elif distribution.lower() == "linear_count" or distribution.lower() == "linear count":
|
|
374
|
+
distribution = "LINC"
|
|
375
|
+
elif distribution.lower() == "exponential":
|
|
376
|
+
distribution = "ESTP"
|
|
377
|
+
elif (
|
|
378
|
+
distribution.lower() == "decade_count"
|
|
379
|
+
or distribution.lower() == "decade count"
|
|
380
|
+
or distribution.lower()
|
|
381
|
+
) == "log scale":
|
|
382
|
+
distribution = "DEC"
|
|
383
|
+
elif distribution.lower() == "octave_count" or distribution.lower() == "octave count":
|
|
384
|
+
distribution = "OCT"
|
|
385
|
+
else:
|
|
386
|
+
distribution = "LIN"
|
|
387
|
+
if not name:
|
|
388
|
+
name = f"sweep_{init_sweep_count + 1}"
|
|
389
|
+
sweep_data = [
|
|
390
|
+
SweepData(
|
|
391
|
+
self._pedb, name=name, distribution=distribution, start_f=start_freq, end_f=stop_freq, step=step
|
|
392
|
+
)
|
|
393
|
+
]
|
|
394
|
+
if discrete:
|
|
395
|
+
sweep_data[0].type = sweep_data[0].type.DISCRETE_SWEEP
|
|
396
|
+
for sweep in self.sweep_data:
|
|
397
|
+
sweep_data.append(sweep)
|
|
398
|
+
self.sweep_data = sweep_data
|
|
399
|
+
if len(self.sweep_data) == init_sweep_count + 1:
|
|
400
|
+
return self.sweep_data[-1]
|
|
401
|
+
else:
|
|
402
|
+
self._pedb.logger.error("Failed to add frequency sweep data")
|
|
403
|
+
return False
|
|
@@ -57,7 +57,14 @@ class SiwaveSimulationSetup(GrpcSIWaveSimulationSetup):
|
|
|
57
57
|
super(SiwaveSimulationSetup, self.__class__).type.__set__(self, GrpcSimulationSetupType.SI_WAVE_DCIR)
|
|
58
58
|
|
|
59
59
|
def add_sweep(
|
|
60
|
-
self,
|
|
60
|
+
self,
|
|
61
|
+
name=None,
|
|
62
|
+
distribution="linear",
|
|
63
|
+
start_freq="0GHz",
|
|
64
|
+
stop_freq="20GHz",
|
|
65
|
+
step="10MHz",
|
|
66
|
+
discrete=False,
|
|
67
|
+
frequency_set=None,
|
|
61
68
|
):
|
|
62
69
|
"""Add a HFSS frequency sweep.
|
|
63
70
|
|
|
@@ -81,39 +88,75 @@ class SiwaveSimulationSetup(GrpcSIWaveSimulationSetup):
|
|
|
81
88
|
distribution. Must be integer in that case.
|
|
82
89
|
discrete : bool, optional
|
|
83
90
|
Whether the sweep is discrete. The default is ``False``.
|
|
91
|
+
frequency_set : List, optional
|
|
92
|
+
Frequency set is a list adding one or more frequency sweeps. If ``frequency_set`` is provided, the other
|
|
93
|
+
arguments are ignored except ``discrete``. Default value is ``None``.
|
|
94
|
+
example of frequency_set : [['linear_scale', '50MHz', '200MHz', '10MHz']].
|
|
84
95
|
|
|
85
96
|
Returns
|
|
86
97
|
-------
|
|
87
98
|
bool
|
|
88
99
|
"""
|
|
89
100
|
init_sweep_count = len(self.sweep_data)
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
101
|
+
if frequency_set:
|
|
102
|
+
for sweep in frequency_set:
|
|
103
|
+
if "linear_scale" in sweep:
|
|
104
|
+
distribution = "LIN"
|
|
105
|
+
elif "linear_count" in sweep:
|
|
106
|
+
distribution = "LINC"
|
|
107
|
+
elif "exponential" in sweep:
|
|
108
|
+
distribution = "ESTP"
|
|
109
|
+
elif "log_scale" in sweep:
|
|
110
|
+
distribution = "DEC"
|
|
111
|
+
elif "octave_count" in sweep:
|
|
112
|
+
distribution = "OCT"
|
|
113
|
+
else:
|
|
114
|
+
distribution = "LIN"
|
|
115
|
+
start_freq = self._pedb.number_with_units(sweep[1], "Hz")
|
|
116
|
+
stop_freq = self._pedb.number_with_units(sweep[2], "Hz")
|
|
117
|
+
step = str(sweep[3])
|
|
118
|
+
if not name:
|
|
119
|
+
name = f"sweep_{init_sweep_count + 1}"
|
|
120
|
+
sweep_data = [
|
|
121
|
+
SweepData(
|
|
122
|
+
self._pedb, name=name, distribution=distribution, start_f=start_freq, end_f=stop_freq, step=step
|
|
123
|
+
)
|
|
124
|
+
]
|
|
125
|
+
if discrete:
|
|
126
|
+
sweep_data[0].type = sweep_data[0].type.DISCRETE_SWEEP
|
|
127
|
+
for sweep in self.sweep_data:
|
|
128
|
+
sweep_data.append(sweep)
|
|
129
|
+
self.sweep_data = sweep_data
|
|
103
130
|
else:
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
131
|
+
start_freq = self._pedb.number_with_units(start_freq, "Hz")
|
|
132
|
+
stop_freq = self._pedb.number_with_units(stop_freq, "Hz")
|
|
133
|
+
step = str(step)
|
|
134
|
+
if distribution.lower() == "linear":
|
|
135
|
+
distribution = "LIN"
|
|
136
|
+
elif distribution.lower() == "linear_count":
|
|
137
|
+
distribution = "LINC"
|
|
138
|
+
elif distribution.lower() == "exponential":
|
|
139
|
+
distribution = "ESTP"
|
|
140
|
+
elif distribution.lower() == "decade_count":
|
|
141
|
+
distribution = "DEC"
|
|
142
|
+
elif distribution.lower() == "octave_count":
|
|
143
|
+
distribution = "OCT"
|
|
144
|
+
else:
|
|
145
|
+
distribution = "LIN"
|
|
146
|
+
if not name:
|
|
147
|
+
name = f"sweep_{init_sweep_count + 1}"
|
|
148
|
+
sweep_data = [
|
|
149
|
+
SweepData(
|
|
150
|
+
self._pedb, name=name, distribution=distribution, start_f=start_freq, end_f=stop_freq, step=step
|
|
151
|
+
)
|
|
152
|
+
]
|
|
153
|
+
if discrete:
|
|
154
|
+
sweep_data[0].type = sweep_data[0].type.DISCRETE_SWEEP
|
|
155
|
+
for sweep in self.sweep_data:
|
|
156
|
+
sweep_data.append(sweep)
|
|
157
|
+
self.sweep_data = sweep_data
|
|
158
|
+
if len(self.sweep_data) == init_sweep_count + 1:
|
|
159
|
+
return True
|
|
160
|
+
else:
|
|
161
|
+
self._pedb.logger.error("Failed to add frequency sweep data")
|
|
162
|
+
return False
|
|
@@ -20,6 +20,12 @@
|
|
|
20
20
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
21
|
# SOFTWARE.
|
|
22
22
|
|
|
23
|
+
from ansys.edb.core.simulation_setup.simulation_setup import (
|
|
24
|
+
Distribution as GrpcDistribution,
|
|
25
|
+
)
|
|
26
|
+
from ansys.edb.core.simulation_setup.simulation_setup import (
|
|
27
|
+
FrequencyData as GrpcFrequencyData,
|
|
28
|
+
)
|
|
23
29
|
from ansys.edb.core.simulation_setup.simulation_setup import SweepData as GrpcSweepData
|
|
24
30
|
|
|
25
31
|
|
|
@@ -27,6 +33,11 @@ class SweepData(GrpcSweepData):
|
|
|
27
33
|
"""Frequency sweep data class."""
|
|
28
34
|
|
|
29
35
|
def __init__(self, pedb, name, distribution, start_f, end_f, step, edb_object=None):
|
|
30
|
-
super().__init__(
|
|
36
|
+
super().__init__(
|
|
37
|
+
name=name,
|
|
38
|
+
frequency_data=GrpcFrequencyData(
|
|
39
|
+
distribution=GrpcDistribution[distribution], start_f=start_f, end_f=end_f, step=step
|
|
40
|
+
),
|
|
41
|
+
)
|
|
31
42
|
self._edb_object = edb_object
|
|
32
43
|
self._pedb = pedb
|
pyedb/grpc/database/siwave.py
CHANGED
|
@@ -28,6 +28,12 @@ import os
|
|
|
28
28
|
import warnings
|
|
29
29
|
|
|
30
30
|
from ansys.edb.core.database import ProductIdType as GrpcProductIdType
|
|
31
|
+
from ansys.edb.core.simulation_setup.simulation_setup import (
|
|
32
|
+
Distribution as GrpcDistribution,
|
|
33
|
+
)
|
|
34
|
+
from ansys.edb.core.simulation_setup.simulation_setup import (
|
|
35
|
+
FrequencyData as GrpcFrequencyData,
|
|
36
|
+
)
|
|
31
37
|
from ansys.edb.core.simulation_setup.simulation_setup import SweepData as GrpcSweepData
|
|
32
38
|
|
|
33
39
|
from pyedb.misc.siw_feature_config.xtalk_scan.scan_config import SiwaveScanConfig
|
|
@@ -592,7 +598,10 @@ class Siwave(object):
|
|
|
592
598
|
sweep_name = f"sweep_{len(setup.sweep_data) + 1}"
|
|
593
599
|
sweep_data = [
|
|
594
600
|
GrpcSweepData(
|
|
595
|
-
name=sweep_name,
|
|
601
|
+
name=sweep_name,
|
|
602
|
+
frequency_data=GrpcFrequencyData(
|
|
603
|
+
distribution=GrpcDistribution[distribution], start_f=start_freq, end_f=stop_freq, step=step_freq
|
|
604
|
+
),
|
|
596
605
|
)
|
|
597
606
|
]
|
|
598
607
|
if discrete_sweep:
|
|
@@ -20,14 +20,14 @@
|
|
|
20
20
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
21
|
# SOFTWARE.
|
|
22
22
|
|
|
23
|
-
from typing import Union
|
|
23
|
+
from typing import List, Set, Union
|
|
24
24
|
|
|
25
25
|
from ansys.edb.core.database import ProductIdType as GrpcProductIdType
|
|
26
26
|
from ansys.edb.core.geometry.point_data import PointData as GrpcPointData
|
|
27
27
|
from ansys.edb.core.geometry.polygon_data import PolygonData as GrpcPolygonData
|
|
28
|
-
from ansys.edb.core.terminal.
|
|
29
|
-
from ansys.edb.core.terminal.
|
|
30
|
-
from ansys.edb.core.terminal.
|
|
28
|
+
from ansys.edb.core.terminal.edge_terminal import EdgeTerminal as GrpcEdgeTerminal
|
|
29
|
+
from ansys.edb.core.terminal.edge_terminal import PrimitiveEdge as GrpcPrimitiveEdge
|
|
30
|
+
from ansys.edb.core.terminal.terminal import BoundaryType as GrpcBoundaryType
|
|
31
31
|
from ansys.edb.core.utility.rlc import Rlc as GrpcRlc
|
|
32
32
|
from ansys.edb.core.utility.value import Value as GrpcValue
|
|
33
33
|
|
|
@@ -225,7 +225,7 @@ class SourceExcitation:
|
|
|
225
225
|
if refdes and any(refdes.rlc_values):
|
|
226
226
|
return self._pedb.components.deactivate_rlc_component(component=refdes, create_circuit_port=True)
|
|
227
227
|
if not port_name:
|
|
228
|
-
port_name = f"Port_{pins[0].net_name}_{pins[0].name}"
|
|
228
|
+
port_name = f"Port_{pins[0].net_name}_{pins[0].component.name}_{pins[0].name}"
|
|
229
229
|
|
|
230
230
|
if len(pins) > 1 or pingroup_on_single_pin:
|
|
231
231
|
pec_boundary = False
|
|
@@ -267,8 +267,8 @@ class SourceExcitation:
|
|
|
267
267
|
return term or False
|
|
268
268
|
|
|
269
269
|
def _get_pins_for_ports(
|
|
270
|
-
self, pins: Union[int, str, PadstackInstance,
|
|
271
|
-
) ->
|
|
270
|
+
self, pins: Union[int, str, PadstackInstance, List[Union[int, str, PadstackInstance]]], comp: Component
|
|
271
|
+
) -> List[PadstackInstance]:
|
|
272
272
|
if not isinstance(pins, list):
|
|
273
273
|
pins = [pins]
|
|
274
274
|
result = []
|
|
@@ -506,7 +506,7 @@ class SourceExcitation:
|
|
|
506
506
|
return True
|
|
507
507
|
|
|
508
508
|
@staticmethod
|
|
509
|
-
def _normalize_net_list(net_list) ->
|
|
509
|
+
def _normalize_net_list(net_list) -> Set[str]:
|
|
510
510
|
if not isinstance(net_list, list):
|
|
511
511
|
net_list = [net_list]
|
|
512
512
|
nets = set()
|
|
@@ -713,9 +713,19 @@ class SourceExcitation:
|
|
|
713
713
|
-------
|
|
714
714
|
Edb pin group terminal.
|
|
715
715
|
"""
|
|
716
|
+
from ansys.edb.core.hierarchy.pin_group import PinGroup as GrpcPinGroup
|
|
717
|
+
|
|
718
|
+
from pyedb.grpc.database.hierarchy.pingroup import PinGroup
|
|
719
|
+
|
|
716
720
|
if pingroup.is_null:
|
|
717
721
|
self._logger.error(f"{pingroup} is null")
|
|
718
|
-
|
|
722
|
+
if not pingroup.pins:
|
|
723
|
+
self._pedb.logger.error("No pins defined on pingroup.")
|
|
724
|
+
return False
|
|
725
|
+
if isinstance(pingroup, GrpcPinGroup):
|
|
726
|
+
pingroup = PinGroup(self._pedb, pingroup)
|
|
727
|
+
pin = list(pingroup.pins.values())[0]
|
|
728
|
+
pin = PadstackInstance(self._pedb, pin)
|
|
719
729
|
if term_name is None:
|
|
720
730
|
term_name = f"{pin.component.name}.{pin.name}.{pin.net_name}"
|
|
721
731
|
for t in self._pedb.active_layout.terminals:
|
pyedb/grpc/database/stackup.py
CHANGED
|
@@ -138,15 +138,23 @@ class LayerCollection(GrpcLayerCollection):
|
|
|
138
138
|
|
|
139
139
|
"""
|
|
140
140
|
thickness = GrpcValue(0.0)
|
|
141
|
+
layer_type_map = {"dielectric": GrpcLayerType.DIELECTRIC_LAYER, "signal": GrpcLayerType.SIGNAL_LAYER}
|
|
141
142
|
if "thickness" in kwargs:
|
|
142
143
|
thickness = GrpcValue(kwargs["thickness"])
|
|
143
144
|
elevation = GrpcValue(0.0)
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
145
|
+
if "type" in kwargs:
|
|
146
|
+
_layer_type = layer_type_map[kwargs["type"]]
|
|
147
|
+
else:
|
|
148
|
+
_layer_type = layer_type_map[layer_type]
|
|
149
|
+
if "material" in kwargs:
|
|
150
|
+
_material = kwargs["material"]
|
|
151
|
+
else:
|
|
152
|
+
_material = "copper"
|
|
147
153
|
layer = GrpcStackupLayer.create(
|
|
148
|
-
name=name, layer_type=_layer_type, thickness=thickness, material=
|
|
154
|
+
name=name, layer_type=_layer_type, thickness=thickness, material=_material, elevation=elevation
|
|
149
155
|
)
|
|
156
|
+
if "fill_material" in kwargs:
|
|
157
|
+
layer.set_fill_material(kwargs["fill_material"])
|
|
150
158
|
return self._layer_collection.add_layer_bottom(layer)
|
|
151
159
|
|
|
152
160
|
def add_layer_below(self, name, base_layer_name, layer_type="signal", **kwargs):
|
|
@@ -170,11 +178,19 @@ class LayerCollection(GrpcLayerCollection):
|
|
|
170
178
|
if "thickness" in kwargs:
|
|
171
179
|
thickness = GrpcValue(kwargs["thickness"])
|
|
172
180
|
elevation = GrpcValue(0.0)
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
_layer_type =
|
|
181
|
+
if "type" in kwargs:
|
|
182
|
+
_l_map = {"signal": GrpcLayerType.SIGNAL_LAYER, "dielectric": GrpcLayerType.DIELECTRIC_LAYER}
|
|
183
|
+
_layer_type = _l_map[kwargs["type"]]
|
|
184
|
+
else:
|
|
185
|
+
_layer_type = GrpcLayerType.SIGNAL_LAYER
|
|
186
|
+
if layer_type.lower() == "dielectric":
|
|
187
|
+
_layer_type = GrpcLayerType.DIELECTRIC_LAYER
|
|
188
|
+
if "material" in kwargs:
|
|
189
|
+
material = kwargs["material"]
|
|
190
|
+
else:
|
|
191
|
+
material = "copper"
|
|
176
192
|
layer = GrpcStackupLayer.create(
|
|
177
|
-
name=name, layer_type=_layer_type, thickness=thickness, material=
|
|
193
|
+
name=name, layer_type=_layer_type, thickness=thickness, material=material, elevation=elevation
|
|
178
194
|
)
|
|
179
195
|
return self._layer_collection.add_layer_below(layer, base_layer_name)
|
|
180
196
|
|
|
@@ -695,8 +711,8 @@ class Stackup(LayerCollection):
|
|
|
695
711
|
|
|
696
712
|
"""
|
|
697
713
|
new_layer_collection = LayerCollection.create()
|
|
698
|
-
for lyr in self.layers:
|
|
699
|
-
if not (
|
|
714
|
+
for layer_name, lyr in self.layers.items():
|
|
715
|
+
if not (layer_name == name):
|
|
700
716
|
new_layer_collection.add_layer_bottom(lyr)
|
|
701
717
|
|
|
702
718
|
self._pedb.layout.layer_collection = new_layer_collection
|
|
@@ -20,11 +20,11 @@
|
|
|
20
20
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
21
|
# SOFTWARE.
|
|
22
22
|
|
|
23
|
-
from ansys.edb.core.terminal.
|
|
23
|
+
from ansys.edb.core.terminal.bundle_terminal import BundleTerminal as GrpcBundleTerminal
|
|
24
|
+
from ansys.edb.core.terminal.terminal import (
|
|
24
25
|
SourceTermToGroundType as GrpcSourceTermToGroundType,
|
|
25
26
|
)
|
|
26
|
-
from ansys.edb.core.terminal.
|
|
27
|
-
from ansys.edb.core.terminal.terminals import HfssPIType as GrpcHfssPIType
|
|
27
|
+
from ansys.edb.core.terminal.terminal import HfssPIType as GrpcHfssPIType
|
|
28
28
|
from ansys.edb.core.utility.value import Value as GrpcValue
|
|
29
29
|
|
|
30
30
|
from pyedb.grpc.database.hierarchy.component import Component
|
|
@@ -20,8 +20,10 @@
|
|
|
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
|
-
|
|
23
|
+
import re
|
|
24
|
+
|
|
25
|
+
from ansys.edb.core.terminal.bundle_terminal import BundleTerminal as GrpcBundleTerminal
|
|
26
|
+
from ansys.edb.core.terminal.edge_terminal import EdgeTerminal as GrpcEdgeTerminal
|
|
25
27
|
|
|
26
28
|
|
|
27
29
|
class EdgeTerminal(GrpcEdgeTerminal):
|
|
@@ -29,6 +31,65 @@ class EdgeTerminal(GrpcEdgeTerminal):
|
|
|
29
31
|
super().__init__(edb_object.msg)
|
|
30
32
|
self._pedb = pedb
|
|
31
33
|
self._edb_object = edb_object
|
|
34
|
+
self._hfss_type = "Gap"
|
|
35
|
+
|
|
36
|
+
@property
|
|
37
|
+
def _edb_properties(self):
|
|
38
|
+
from ansys.edb.core.database import ProductIdType as GrpcProductIdType
|
|
39
|
+
|
|
40
|
+
try:
|
|
41
|
+
p = self._edb_object.get_product_property(GrpcProductIdType.DESIGNER, 1)
|
|
42
|
+
except:
|
|
43
|
+
p = ""
|
|
44
|
+
return p
|
|
45
|
+
|
|
46
|
+
@_edb_properties.setter
|
|
47
|
+
def _edb_properties(self, value):
|
|
48
|
+
from ansys.edb.core.database import ProductIdType as GrpcProductIdType
|
|
49
|
+
|
|
50
|
+
self._edb_object.set_product_property(GrpcProductIdType.DESIGNER, 1, value)
|
|
51
|
+
|
|
52
|
+
@property
|
|
53
|
+
def is_wave_port(self):
|
|
54
|
+
if self._hfss_port_property:
|
|
55
|
+
return True
|
|
56
|
+
return False
|
|
57
|
+
|
|
58
|
+
@property
|
|
59
|
+
def _hfss_port_property(self):
|
|
60
|
+
"""HFSS port property."""
|
|
61
|
+
hfss_prop = re.search(r"HFSS\(.*?\)", self._edb_properties)
|
|
62
|
+
p = {}
|
|
63
|
+
if hfss_prop:
|
|
64
|
+
hfss_type = re.search(r"'HFSS Type'='([^']+)'", hfss_prop.group())
|
|
65
|
+
orientation = re.search(r"'Orientation'='([^']+)'", hfss_prop.group())
|
|
66
|
+
horizontal_ef = re.search(r"'Horizontal Extent Factor'='([^']+)'", hfss_prop.group())
|
|
67
|
+
vertical_ef = re.search(r"'Vertical Extent Factor'='([^']+)'", hfss_prop.group())
|
|
68
|
+
radial_ef = re.search(r"'Radial Extent Factor'='([^']+)'", hfss_prop.group())
|
|
69
|
+
pec_w = re.search(r"'PEC Launch Width'='([^']+)'", hfss_prop.group())
|
|
70
|
+
|
|
71
|
+
p["HFSS Type"] = hfss_type.group(1) if hfss_type else ""
|
|
72
|
+
p["Orientation"] = orientation.group(1) if orientation else ""
|
|
73
|
+
p["Horizontal Extent Factor"] = float(horizontal_ef.group(1)) if horizontal_ef else ""
|
|
74
|
+
p["Vertical Extent Factor"] = float(vertical_ef.group(1)) if vertical_ef else ""
|
|
75
|
+
p["Radial Extent Factor"] = float(radial_ef.group(1)) if radial_ef else ""
|
|
76
|
+
p["PEC Launch Width"] = pec_w.group(1) if pec_w else ""
|
|
77
|
+
else:
|
|
78
|
+
p["HFSS Type"] = ""
|
|
79
|
+
p["Orientation"] = ""
|
|
80
|
+
p["Horizontal Extent Factor"] = ""
|
|
81
|
+
p["Vertical Extent Factor"] = ""
|
|
82
|
+
p["Radial Extent Factor"] = ""
|
|
83
|
+
p["PEC Launch Width"] = ""
|
|
84
|
+
return p
|
|
85
|
+
|
|
86
|
+
@_hfss_port_property.setter
|
|
87
|
+
def _hfss_port_property(self, value):
|
|
88
|
+
txt = []
|
|
89
|
+
for k, v in value.items():
|
|
90
|
+
txt.append("'{}'='{}'".format(k, v))
|
|
91
|
+
txt = ",".join(txt)
|
|
92
|
+
self._edb_properties = "HFSS({})".format(txt)
|
|
32
93
|
|
|
33
94
|
def couple_ports(self, port):
|
|
34
95
|
"""Create a bundle wave port.
|
|
@@ -49,3 +110,35 @@ class EdgeTerminal(GrpcEdgeTerminal):
|
|
|
49
110
|
temp.extend([i for i in port])
|
|
50
111
|
bundle_terminal = GrpcBundleTerminal.create(temp)
|
|
51
112
|
return self._pedb.ports[bundle_terminal.name]
|
|
113
|
+
|
|
114
|
+
@property
|
|
115
|
+
def is_port(self):
|
|
116
|
+
return True
|
|
117
|
+
|
|
118
|
+
@property
|
|
119
|
+
def ref_terminal(self):
|
|
120
|
+
"""Return refeference terminal.
|
|
121
|
+
|
|
122
|
+
..deprecated:: 0.44.0
|
|
123
|
+
Use: func:`reference_terminal` property instead.
|
|
124
|
+
|
|
125
|
+
"""
|
|
126
|
+
self._pedb.logger.warning("ref_terminal is deprecated, use reference_terminal property instead.")
|
|
127
|
+
return self.reference_terminal
|
|
128
|
+
|
|
129
|
+
@ref_terminal.setter
|
|
130
|
+
def ref_terminal(self, value):
|
|
131
|
+
self._pedb.logger.warning("ref_terminal is deprecated, use reference_terminal property instead.")
|
|
132
|
+
self.reference_terminal = value
|
|
133
|
+
|
|
134
|
+
@property
|
|
135
|
+
def hfss_type(self):
|
|
136
|
+
return self._hfss_type
|
|
137
|
+
|
|
138
|
+
@hfss_type.setter
|
|
139
|
+
def hfss_type(self, value):
|
|
140
|
+
self._hfss_type = value
|
|
141
|
+
|
|
142
|
+
@property
|
|
143
|
+
def terminal_type(self):
|
|
144
|
+
return "EdgeTerminal"
|