pyedb 0.9.0__py3-none-any.whl → 0.10.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/__init__.py +0 -0
- pyedb/configuration/cfg_data.py +45 -0
- pyedb/configuration/cfg_ports.py +149 -0
- pyedb/{dotnet/edb_core → configuration}/configuration.py +68 -32
- pyedb/dotnet/edb.py +4 -3
- pyedb/dotnet/edb_core/components.py +19 -8
- pyedb/dotnet/edb_core/edb_data/hfss_simulation_setup_data.py +4 -0
- pyedb/dotnet/edb_core/edb_data/layer_data.py +164 -62
- pyedb/dotnet/edb_core/edb_data/simulation_configuration.py +49 -0
- pyedb/dotnet/edb_core/hfss.py +29 -11
- pyedb/dotnet/edb_core/materials.py +73 -81
- pyedb/dotnet/edb_core/stackup.py +289 -84
- {pyedb-0.9.0.dist-info → pyedb-0.10.0.dist-info}/METADATA +5 -5
- {pyedb-0.9.0.dist-info → pyedb-0.10.0.dist-info}/RECORD +17 -14
- {pyedb-0.9.0.dist-info → pyedb-0.10.0.dist-info}/LICENSE +0 -0
- {pyedb-0.9.0.dist-info → pyedb-0.10.0.dist-info}/WHEEL +0 -0
pyedb/__init__.py
CHANGED
|
File without changes
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Copyright (C) 2023 - 2024 ANSYS, Inc. and/or its affiliates.
|
|
2
|
+
# SPDX-License-Identifier: MIT
|
|
3
|
+
#
|
|
4
|
+
#
|
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
# furnished to do so, subject to the following conditions:
|
|
11
|
+
#
|
|
12
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
# copies or substantial portions of the Software.
|
|
14
|
+
#
|
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
# SOFTWARE.
|
|
22
|
+
|
|
23
|
+
from pyedb.configuration.cfg_ports import CfgPort
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class CfgData(object):
|
|
27
|
+
"""Manages configure data."""
|
|
28
|
+
|
|
29
|
+
def __init__(self, pedb, **kwargs):
|
|
30
|
+
self.pedb = pedb
|
|
31
|
+
self.edb_comps = self.pedb.components.components
|
|
32
|
+
|
|
33
|
+
self.cfg_general = None
|
|
34
|
+
self.cfg_boundaries = None
|
|
35
|
+
self.cfg_nets = None
|
|
36
|
+
self.cfg_components = None
|
|
37
|
+
self.cfg_padstacks = None
|
|
38
|
+
self.cfg_pin_groups = None
|
|
39
|
+
self.cfg_ports = [CfgPort(self, **port) for port in kwargs.get("ports", [])]
|
|
40
|
+
self.cfg_setups = None
|
|
41
|
+
self.cfg_stackup = None
|
|
42
|
+
self.cfg_s_parameters = None
|
|
43
|
+
self.cfg_spice_models = None
|
|
44
|
+
self.cfg_package_definition = None
|
|
45
|
+
self.cfg_operations = None
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
# Copyright (C) 2023 - 2024 ANSYS, Inc. and/or its affiliates.
|
|
2
|
+
# SPDX-License-Identifier: MIT
|
|
3
|
+
#
|
|
4
|
+
#
|
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
# furnished to do so, subject to the following conditions:
|
|
11
|
+
#
|
|
12
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
# copies or substantial portions of the Software.
|
|
14
|
+
#
|
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
# SOFTWARE.
|
|
22
|
+
|
|
23
|
+
from enum import Enum
|
|
24
|
+
|
|
25
|
+
from pyedb.dotnet.edb_core.edb_data.padstacks_data import EDBPadstackInstance
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class CfgNegTerm:
|
|
29
|
+
"""Manage negative terminal."""
|
|
30
|
+
|
|
31
|
+
class CfgTermType(Enum):
|
|
32
|
+
"""Terminal types."""
|
|
33
|
+
|
|
34
|
+
pin = [list, str]
|
|
35
|
+
net = [str]
|
|
36
|
+
pin_group = [str]
|
|
37
|
+
|
|
38
|
+
@property
|
|
39
|
+
def pedb(self):
|
|
40
|
+
"""Edb."""
|
|
41
|
+
return self.pport.pedb
|
|
42
|
+
|
|
43
|
+
def __init__(self, pport, **kwargs):
|
|
44
|
+
self.pport = pport
|
|
45
|
+
self.type = kwargs.get("type", None)
|
|
46
|
+
self.value = kwargs.get("value", None)
|
|
47
|
+
|
|
48
|
+
def _get_candidates(self, distributed):
|
|
49
|
+
"""Get list of objects."""
|
|
50
|
+
|
|
51
|
+
def get_pin_obj(pin_name):
|
|
52
|
+
port_name = "{}_{}".format(self.pport.reference_designator, pin_name)
|
|
53
|
+
return {port_name: self.pport.pdata.edb_comps[self.pport.reference_designator].pins[pin_name]}
|
|
54
|
+
|
|
55
|
+
def get_pin_group_obj(pin_group_name):
|
|
56
|
+
pin_group_obj = self.pedb.siwave.pin_groups[pin_group_name]
|
|
57
|
+
return {pin_group_obj.name: pin_group_obj}
|
|
58
|
+
|
|
59
|
+
term_objs = dict()
|
|
60
|
+
if self.type in "pin":
|
|
61
|
+
term_objs.update(get_pin_obj(self.value))
|
|
62
|
+
elif self.type == "pin_group":
|
|
63
|
+
term_objs.update(get_pin_group_obj(self.value))
|
|
64
|
+
elif self.type == "net":
|
|
65
|
+
pins = self.pport.pdata.pedb.components.get_pin_from_component(self.pport.reference_designator, self.value)
|
|
66
|
+
pins = [EDBPadstackInstance(p, self.pedb) for p in pins]
|
|
67
|
+
|
|
68
|
+
pin_objs = {f"{self.value}_{p.GetName()}": p for p in pins}
|
|
69
|
+
if distributed:
|
|
70
|
+
term_objs.update(pin_objs)
|
|
71
|
+
else:
|
|
72
|
+
pg_name = f"pg_{self.pport.reference_designator}_{self.value}"
|
|
73
|
+
pin_objs = {p.GetName(): p for p in pin_objs.values()}
|
|
74
|
+
if self.pport.type == "coax":
|
|
75
|
+
term_objs.update(get_pin_obj(pins[0].GetName()))
|
|
76
|
+
else:
|
|
77
|
+
temp = self.pport.pdata.pedb.siwave.create_pin_group(
|
|
78
|
+
self.pport.reference_designator, list(pin_objs.keys()), pg_name
|
|
79
|
+
)
|
|
80
|
+
term_objs.update({temp[0]: temp[1]})
|
|
81
|
+
return term_objs
|
|
82
|
+
|
|
83
|
+
def get_candidates(self):
|
|
84
|
+
"""Get list of objects."""
|
|
85
|
+
return self._get_candidates(False)
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
class CfgPosTerm(CfgNegTerm):
|
|
89
|
+
"""Manage positive terminal."""
|
|
90
|
+
|
|
91
|
+
def __init__(self, pport, **kwargs):
|
|
92
|
+
super().__init__(pport, **kwargs)
|
|
93
|
+
|
|
94
|
+
def get_candidates(self):
|
|
95
|
+
"""Get list of objects."""
|
|
96
|
+
return self._get_candidates(self.pport.distributed)
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
class CfgPort:
|
|
100
|
+
"""Manage port."""
|
|
101
|
+
|
|
102
|
+
class CfgPortType(Enum):
|
|
103
|
+
"""Port type."""
|
|
104
|
+
|
|
105
|
+
circuit = [str]
|
|
106
|
+
coax = [str]
|
|
107
|
+
|
|
108
|
+
@property
|
|
109
|
+
def pedb(self):
|
|
110
|
+
"""Edb."""
|
|
111
|
+
return self.pdata.pedb
|
|
112
|
+
|
|
113
|
+
def __init__(self, pdata, **kwargs):
|
|
114
|
+
self.pdata = pdata
|
|
115
|
+
self.name = kwargs.get("name", None)
|
|
116
|
+
self.type = kwargs.get("type", None)
|
|
117
|
+
self.reference_designator = kwargs.get("reference_designator", None)
|
|
118
|
+
pos_term = kwargs.get("positive_terminal", None)
|
|
119
|
+
neg_term = kwargs.get("negative_terminal", None)
|
|
120
|
+
if pos_term:
|
|
121
|
+
self.positive_terminal = CfgPosTerm(
|
|
122
|
+
pport=self, type=list(pos_term.keys())[0], value=list(pos_term.values())[0]
|
|
123
|
+
)
|
|
124
|
+
if neg_term:
|
|
125
|
+
self.negative_terminal = CfgPosTerm(
|
|
126
|
+
pport=self, type=list(neg_term.keys())[0], value=list(neg_term.values())[0]
|
|
127
|
+
)
|
|
128
|
+
self.distributed = kwargs.get("distributed", False)
|
|
129
|
+
|
|
130
|
+
self._port_name = None
|
|
131
|
+
|
|
132
|
+
def create(self):
|
|
133
|
+
"""Create port."""
|
|
134
|
+
if self.type == "circuit":
|
|
135
|
+
candidates = [i for i in self.negative_terminal.get_candidates().values()][0]
|
|
136
|
+
neg_term = candidates.get_terminal(create_new_terminal=True)
|
|
137
|
+
else:
|
|
138
|
+
neg_term = None
|
|
139
|
+
ports = []
|
|
140
|
+
for name, p in self.positive_terminal.get_candidates().items():
|
|
141
|
+
if self.distributed:
|
|
142
|
+
port_name = f"{self.name}_{name}" if self.name else name
|
|
143
|
+
else:
|
|
144
|
+
port_name = self.name if self.name else name
|
|
145
|
+
pos_term = p.get_terminal(port_name, create_new_terminal=True)
|
|
146
|
+
is_circuit_port = True if self.type == "circuit" else False
|
|
147
|
+
port = self.pedb.create_port(pos_term, neg_term, is_circuit_port)
|
|
148
|
+
ports.append(port)
|
|
149
|
+
return ports
|
|
@@ -26,6 +26,7 @@ from pathlib import Path
|
|
|
26
26
|
|
|
27
27
|
import toml
|
|
28
28
|
|
|
29
|
+
from pyedb.configuration.cfg_data import CfgData
|
|
29
30
|
from pyedb.dotnet.edb_core.definition.package_def import PackageDef
|
|
30
31
|
from pyedb.generic.general_methods import pyedb_function_handler
|
|
31
32
|
|
|
@@ -39,6 +40,7 @@ class Configuration:
|
|
|
39
40
|
self.data = {}
|
|
40
41
|
self._s_parameter_library = ""
|
|
41
42
|
self._spice_model_library = ""
|
|
43
|
+
self.cfg_data = None
|
|
42
44
|
|
|
43
45
|
@pyedb_function_handler
|
|
44
46
|
def load(self, config_file, append=True, apply_file=False, output_file=None, open_at_the_end=True):
|
|
@@ -86,6 +88,9 @@ class Configuration:
|
|
|
86
88
|
self.data[k] = v
|
|
87
89
|
else:
|
|
88
90
|
self.data[k] = v
|
|
91
|
+
|
|
92
|
+
self.cfg_data = CfgData(self._pedb, **data)
|
|
93
|
+
|
|
89
94
|
if apply_file:
|
|
90
95
|
original_file = self._pedb.edbpath
|
|
91
96
|
if output_file:
|
|
@@ -132,8 +137,8 @@ class Configuration:
|
|
|
132
137
|
self._load_pin_groups()
|
|
133
138
|
|
|
134
139
|
# Configure ports
|
|
135
|
-
|
|
136
|
-
|
|
140
|
+
for port in self.cfg_data.cfg_ports:
|
|
141
|
+
port.create()
|
|
137
142
|
|
|
138
143
|
# Configure sources
|
|
139
144
|
if "sources" in self.data:
|
|
@@ -275,6 +280,7 @@ class Configuration:
|
|
|
275
280
|
@pyedb_function_handler
|
|
276
281
|
def _load_ports(self):
|
|
277
282
|
"""Imports port information from json."""
|
|
283
|
+
|
|
278
284
|
for port in self.data["ports"]:
|
|
279
285
|
port_type = port["type"]
|
|
280
286
|
|
|
@@ -315,7 +321,7 @@ class Configuration:
|
|
|
315
321
|
pin_name = negative_terminal_json["pin"]
|
|
316
322
|
port_name = "{}_{}_ref".format(ref_designator, pin_name)
|
|
317
323
|
neg_terminal = comp_layout.pins[pin_name].get_terminal(port_name, True)
|
|
318
|
-
|
|
324
|
+
elif "net" in negative_terminal_json:
|
|
319
325
|
net_name = negative_terminal_json["net"]
|
|
320
326
|
port_name = "{}_{}_ref".format(ref_designator, net_name)
|
|
321
327
|
pg_name = "pg_{}".format(port_name)
|
|
@@ -476,35 +482,65 @@ class Configuration:
|
|
|
476
482
|
def _load_stackup(self):
|
|
477
483
|
"""Imports stackup information from json."""
|
|
478
484
|
data = self.data["stackup"]
|
|
479
|
-
materials = data
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
485
|
+
materials = data.get("materials")
|
|
486
|
+
|
|
487
|
+
if materials:
|
|
488
|
+
edb_materials = {i.lower(): i for i, _ in self._pedb.materials.materials.items()}
|
|
489
|
+
for mat in materials:
|
|
490
|
+
name = mat["name"].lower()
|
|
491
|
+
if name in edb_materials:
|
|
492
|
+
self._pedb.materials.delete_material(edb_materials[name])
|
|
493
|
+
for mat in materials:
|
|
494
|
+
self._pedb.materials.add_material(**mat)
|
|
495
|
+
|
|
496
|
+
layers = data.get("layers")
|
|
497
|
+
|
|
498
|
+
if layers:
|
|
499
|
+
lc = self._pedb.stackup
|
|
500
|
+
input_signal_layers = [i for i in layers if i["type"].lower() == "signal"]
|
|
501
|
+
if not len(input_signal_layers) == len(lc.signal_layers):
|
|
502
|
+
self._pedb.logger.error("Input signal layer count do not match.")
|
|
503
|
+
return False
|
|
504
|
+
|
|
505
|
+
layer_clones = []
|
|
506
|
+
doc_layer_clones = []
|
|
507
|
+
for name, obj in lc.layers.items():
|
|
508
|
+
if obj.is_stackup_layer:
|
|
509
|
+
if obj.type == "signal": # keep signal layers
|
|
510
|
+
layer_clones.append(obj)
|
|
511
|
+
else:
|
|
512
|
+
doc_layer_clones.append(obj)
|
|
513
|
+
lc.remove_layer(name)
|
|
514
|
+
|
|
515
|
+
signal_layer_ids = {}
|
|
516
|
+
top_layer_clone = None
|
|
517
|
+
|
|
518
|
+
# add all signal layers
|
|
519
|
+
for l in layers:
|
|
520
|
+
if l["type"] == "signal":
|
|
521
|
+
clone = layer_clones.pop(0)
|
|
522
|
+
clone.update(**l)
|
|
523
|
+
lc.add_layer_bottom(name=clone.name, layer_clone=clone)
|
|
524
|
+
signal_layer_ids[clone.name] = clone.id
|
|
525
|
+
|
|
526
|
+
# add all document layers at bottom
|
|
527
|
+
for l in doc_layer_clones:
|
|
528
|
+
doc_layer = lc.add_document_layer(name=l.name, layer_clone=l)
|
|
529
|
+
first_doc_layer_name = doc_layer.name
|
|
530
|
+
|
|
531
|
+
# add all dielectric layers. Dielectric layers must be added last. Otherwise,
|
|
532
|
+
# dielectric layer will occupy signal and document layer id.
|
|
533
|
+
prev_layer_clone = None
|
|
534
|
+
l = layers.pop(0)
|
|
535
|
+
if l["type"] == "signal":
|
|
536
|
+
prev_layer_clone = lc.layers[l["name"]]
|
|
537
|
+
else:
|
|
538
|
+
prev_layer_clone = lc.add_layer_top(**l)
|
|
539
|
+
for idx, l in enumerate(layers):
|
|
540
|
+
if l["type"] == "dielectric":
|
|
541
|
+
prev_layer_clone = lc.add_layer_below(base_layer_name=prev_layer_clone.name, **l)
|
|
542
|
+
else:
|
|
543
|
+
prev_layer_clone = lc.layers[l["name"]]
|
|
508
544
|
|
|
509
545
|
@pyedb_function_handler
|
|
510
546
|
def _load_s_parameter(self):
|
pyedb/dotnet/edb.py
CHANGED
|
@@ -35,9 +35,9 @@ import time
|
|
|
35
35
|
import traceback
|
|
36
36
|
import warnings
|
|
37
37
|
|
|
38
|
+
from pyedb.configuration.configuration import Configuration
|
|
38
39
|
from pyedb.dotnet.application.Variables import decompose_variable_value
|
|
39
40
|
from pyedb.dotnet.edb_core.components import Components
|
|
40
|
-
from pyedb.dotnet.edb_core.configuration import Configuration
|
|
41
41
|
from pyedb.dotnet.edb_core.dotnet.database import Database
|
|
42
42
|
from pyedb.dotnet.edb_core.dotnet.layout import LayoutDotNet
|
|
43
43
|
from pyedb.dotnet.edb_core.edb_data.control_file import (
|
|
@@ -342,7 +342,7 @@ class Edb(Database):
|
|
|
342
342
|
@pyedb_function_handler()
|
|
343
343
|
def _init_objects(self):
|
|
344
344
|
self._components = Components(self)
|
|
345
|
-
self._stackup = Stackup(self)
|
|
345
|
+
self._stackup = Stackup(self, self.layout.layer_collection)
|
|
346
346
|
self._padstack = EdbPadstacks(self)
|
|
347
347
|
self._siwave = EdbSiwave(self)
|
|
348
348
|
self._hfss = EdbHfss(self)
|
|
@@ -845,7 +845,7 @@ class Edb(Database):
|
|
|
845
845
|
>>> edbapp.stackup.add_layer("Diel", "GND", layer_type="dielectric", thickness="0.1mm", material="FR4_epoxy")
|
|
846
846
|
"""
|
|
847
847
|
if not self._stackup2 and self.active_db:
|
|
848
|
-
self._stackup2 = Stackup(self)
|
|
848
|
+
self._stackup2 = Stackup(self, self.layout.layer_collection)
|
|
849
849
|
return self._stackup2
|
|
850
850
|
|
|
851
851
|
@property
|
|
@@ -3655,6 +3655,7 @@ class Edb(Database):
|
|
|
3655
3655
|
elif not name:
|
|
3656
3656
|
name = generate_unique_name("setup")
|
|
3657
3657
|
setup = HfssSimulationSetup(self).create(name)
|
|
3658
|
+
setup.set_solution_single_frequency("1GΗz")
|
|
3658
3659
|
return setup
|
|
3659
3660
|
|
|
3660
3661
|
def create_raptorx_setup(self, name=None):
|
|
@@ -915,6 +915,12 @@ class Components(object):
|
|
|
915
915
|
"""
|
|
916
916
|
if isinstance(component, str):
|
|
917
917
|
component = self.instances[component].edbcomponent
|
|
918
|
+
if not solder_balls_height:
|
|
919
|
+
solder_balls_height = self.components[component.GetName()].solder_ball_height
|
|
920
|
+
if not solder_balls_size:
|
|
921
|
+
solder_balls_size = self.components[component.GetName()].solder_ball_diameter[0]
|
|
922
|
+
if not solder_balls_mid_size:
|
|
923
|
+
solder_balls_mid_size = self.components[component.GetName()].solder_ball_diameter[1]
|
|
918
924
|
if not isinstance(net_list, list):
|
|
919
925
|
net_list = [net_list]
|
|
920
926
|
for net in net_list:
|
|
@@ -2402,20 +2408,20 @@ class Components(object):
|
|
|
2402
2408
|
return [pin_xy.X.ToDouble(), pin_xy.Y.ToDouble()]
|
|
2403
2409
|
|
|
2404
2410
|
@pyedb_function_handler()
|
|
2405
|
-
def get_pins_name_from_net(self,
|
|
2411
|
+
def get_pins_name_from_net(self, net_name, pin_list=None):
|
|
2406
2412
|
"""Retrieve pins belonging to a net.
|
|
2407
2413
|
|
|
2408
2414
|
Parameters
|
|
2409
2415
|
----------
|
|
2410
|
-
pin_list : list
|
|
2411
|
-
List of pins to check.
|
|
2416
|
+
pin_list : list of EDBPadstackInstance, optional
|
|
2417
|
+
List of pins to check. The default is ``None``, in which case all pins are checked
|
|
2412
2418
|
net_name : str
|
|
2413
2419
|
Name of the net.
|
|
2414
2420
|
|
|
2415
2421
|
Returns
|
|
2416
2422
|
-------
|
|
2417
|
-
list
|
|
2418
|
-
|
|
2423
|
+
list of str names:
|
|
2424
|
+
Pins belonging to the net.
|
|
2419
2425
|
|
|
2420
2426
|
Examples
|
|
2421
2427
|
--------
|
|
@@ -2425,11 +2431,16 @@ class Components(object):
|
|
|
2425
2431
|
>>> edbapp.components.get_pins_name_from_net(pin_list, net_name)
|
|
2426
2432
|
|
|
2427
2433
|
"""
|
|
2428
|
-
|
|
2434
|
+
pin_names = []
|
|
2435
|
+
if not pin_list:
|
|
2436
|
+
pin_list = []
|
|
2437
|
+
for i in [*self.components.values()]:
|
|
2438
|
+
for j in [*i.pins.values()]:
|
|
2439
|
+
pin_list.append(j)
|
|
2429
2440
|
for pin in pin_list:
|
|
2430
2441
|
if pin.GetNet().GetName() == net_name:
|
|
2431
|
-
|
|
2432
|
-
return
|
|
2442
|
+
pin_names.append(self.get_aedt_pin_name(pin))
|
|
2443
|
+
return pin_names
|
|
2433
2444
|
|
|
2434
2445
|
@pyedb_function_handler()
|
|
2435
2446
|
def get_nets_from_pin_list(self, PinList):
|
|
@@ -29,6 +29,10 @@ from pyedb.dotnet.edb_core.utilities.simulation_setup import (
|
|
|
29
29
|
from pyedb.generic.general_methods import generate_unique_name, pyedb_function_handler
|
|
30
30
|
|
|
31
31
|
|
|
32
|
+
class AdaptiveType(object):
|
|
33
|
+
(SingleFrequency, MultiFrequency, BroadBand) = range(0, 3)
|
|
34
|
+
|
|
35
|
+
|
|
32
36
|
class MeshOperation(object):
|
|
33
37
|
"""Mesh Operation Class."""
|
|
34
38
|
|