pyedb 0.17.0__py3-none-any.whl → 0.19.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 +8 -11
- pyedb/configuration/cfg_nets.py +14 -0
- pyedb/configuration/cfg_pin_groups.py +57 -20
- pyedb/configuration/cfg_ports_sources.py +248 -60
- pyedb/configuration/configuration.py +51 -17
- pyedb/dotnet/edb.py +92 -28
- pyedb/dotnet/edb_core/cell/layout.py +48 -1
- pyedb/dotnet/edb_core/cell/terminal/padstack_instance_terminal.py +10 -0
- pyedb/dotnet/edb_core/cell/terminal/pingroup_terminal.py +5 -0
- pyedb/dotnet/edb_core/cell/terminal/point_terminal.py +0 -11
- pyedb/dotnet/edb_core/cell/terminal/terminal.py +35 -1
- pyedb/dotnet/edb_core/components.py +74 -18
- pyedb/dotnet/edb_core/dotnet/primitive.py +9 -6
- pyedb/dotnet/edb_core/edb_data/padstacks_data.py +8 -4
- pyedb/dotnet/edb_core/edb_data/ports.py +0 -18
- pyedb/dotnet/edb_core/edb_data/primitives_data.py +1 -1
- pyedb/dotnet/edb_core/padstack.py +10 -1
- pyedb/dotnet/edb_core/sim_setup_data/data/sim_setup_info.py +42 -3
- pyedb/dotnet/edb_core/sim_setup_data/data/simulation_settings.py +92 -158
- pyedb/dotnet/edb_core/sim_setup_data/data/siw_dc_ir_settings.py +22 -22
- pyedb/dotnet/edb_core/sim_setup_data/io/siwave.py +76 -76
- pyedb/dotnet/edb_core/utilities/hfss_simulation_setup.py +23 -94
- pyedb/dotnet/edb_core/utilities/simulation_setup.py +40 -38
- pyedb/dotnet/edb_core/utilities/siwave_simulation_setup.py +26 -17
- {pyedb-0.17.0.dist-info → pyedb-0.19.0.dist-info}/METADATA +8 -8
- {pyedb-0.17.0.dist-info → pyedb-0.19.0.dist-info}/RECORD +29 -29
- {pyedb-0.17.0.dist-info → pyedb-0.19.0.dist-info}/LICENSE +0 -0
- {pyedb-0.17.0.dist-info → pyedb-0.19.0.dist-info}/WHEEL +0 -0
|
@@ -766,20 +766,44 @@ class Components(object):
|
|
|
766
766
|
>>> edb.close_edb()
|
|
767
767
|
"""
|
|
768
768
|
|
|
769
|
-
if isinstance(pins, str)
|
|
769
|
+
if isinstance(pins, str):
|
|
770
770
|
pins = [pins]
|
|
771
|
+
elif isinstance(pins, EDBPadstackInstance):
|
|
772
|
+
pins = [pins.name]
|
|
771
773
|
if isinstance(reference_pins, str):
|
|
772
774
|
reference_pins = [reference_pins]
|
|
773
|
-
if isinstance(
|
|
775
|
+
if isinstance(reference_pins, list):
|
|
776
|
+
_temp = []
|
|
777
|
+
for ref_pin in reference_pins:
|
|
778
|
+
if isinstance(ref_pin, int):
|
|
779
|
+
if ref_pin in self._padstack.instances:
|
|
780
|
+
_temp.append(self._padstack.instances[ref_pin])
|
|
781
|
+
elif isinstance(ref_pin, str):
|
|
782
|
+
if ref_pin in self.instances[refdes].pins:
|
|
783
|
+
_temp.append(self.instances[refdes].pins[ref_pin])
|
|
784
|
+
else:
|
|
785
|
+
p = [pp for pp in list(self._padstack.instances.values()) if pp.name == ref_pin]
|
|
786
|
+
if p:
|
|
787
|
+
_temp.append(p)
|
|
788
|
+
elif isinstance(ref_pin, EDBPadstackInstance):
|
|
789
|
+
_temp.append(ref_pin.name)
|
|
790
|
+
reference_pins = _temp
|
|
791
|
+
elif isinstance(reference_pins, int):
|
|
792
|
+
if reference_pins in self._padstack.instances:
|
|
793
|
+
reference_pins = self._padstack.instances[reference_pins]
|
|
794
|
+
if isinstance(refdes, str):
|
|
774
795
|
refdes = self.instances[refdes]
|
|
796
|
+
elif isinstance(refdes, self._pedb._edb.Cell.Hierarchy.Component):
|
|
797
|
+
refdes = EDBComponent(self._pedb, refdes)
|
|
798
|
+
refdes_pins = refdes.pins
|
|
775
799
|
if any(refdes.rlc_values):
|
|
776
800
|
return self.deactivate_rlc_component(component=refdes, create_circuit_port=True)
|
|
777
801
|
if len([pin for pin in pins if isinstance(pin, str)]) == len(pins):
|
|
778
802
|
cmp_pins = []
|
|
779
803
|
for pin_name in pins:
|
|
780
|
-
cmp_pin = [pin for pin in list(
|
|
804
|
+
cmp_pin = [pin for pin in list(refdes_pins.values()) if pin_name == pin.name]
|
|
781
805
|
if not cmp_pin:
|
|
782
|
-
cmp_pin = [pin for pin in list(
|
|
806
|
+
cmp_pin = [pin for pin in list(refdes_pins.values()) if pin_name == pin.name.split("-")[1]]
|
|
783
807
|
if cmp_pin:
|
|
784
808
|
cmp_pins.append(cmp_pin[0])
|
|
785
809
|
if not cmp_pins:
|
|
@@ -793,15 +817,15 @@ class Components(object):
|
|
|
793
817
|
if len([pin for pin in reference_pins if isinstance(pin, str)]) == len(reference_pins):
|
|
794
818
|
ref_cmp_pins = []
|
|
795
819
|
for ref_pin_name in reference_pins:
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
ref_cmp_pins.append(cmp_ref_pin[0])
|
|
820
|
+
if ref_pin_name in refdes_pins:
|
|
821
|
+
ref_cmp_pins.append(refdes_pins[ref_pin_name])
|
|
822
|
+
elif "-" in ref_pin_name and ref_pin_name.split("-")[1] in refdes_pins:
|
|
823
|
+
ref_cmp_pins.append(refdes_pins[ref_pin_name.split("-")[1]])
|
|
801
824
|
if not ref_cmp_pins:
|
|
802
825
|
return
|
|
803
826
|
reference_pins = ref_cmp_pins
|
|
804
|
-
if not
|
|
827
|
+
if not reference_pins:
|
|
828
|
+
self._logger.error("No reference pins found.")
|
|
805
829
|
return
|
|
806
830
|
if len(pins) > 1:
|
|
807
831
|
pec_boundary = False
|
|
@@ -883,7 +907,7 @@ class Components(object):
|
|
|
883
907
|
solder_balls_size : float, optional
|
|
884
908
|
Solder balls diameter. When provided auto evaluation based on padstack size will be disabled.
|
|
885
909
|
solder_balls_mid_size : float, optional
|
|
886
|
-
Solder balls mid
|
|
910
|
+
Solder balls mid-diameter. When provided if value is different than solder balls size, spheroid shape will
|
|
887
911
|
be switched.
|
|
888
912
|
|
|
889
913
|
Returns
|
|
@@ -904,11 +928,11 @@ class Components(object):
|
|
|
904
928
|
if isinstance(component, str):
|
|
905
929
|
component = self.instances[component].edbcomponent
|
|
906
930
|
if not solder_balls_height:
|
|
907
|
-
solder_balls_height = self.
|
|
931
|
+
solder_balls_height = self.instances[component.GetName()].solder_ball_height
|
|
908
932
|
if not solder_balls_size:
|
|
909
|
-
solder_balls_size = self.
|
|
933
|
+
solder_balls_size = self.instances[component.GetName()].solder_ball_diameter[0]
|
|
910
934
|
if not solder_balls_mid_size:
|
|
911
|
-
solder_balls_mid_size = self.
|
|
935
|
+
solder_balls_mid_size = self.instances[component.GetName()].solder_ball_diameter[1]
|
|
912
936
|
if not isinstance(net_list, list):
|
|
913
937
|
net_list = [net_list]
|
|
914
938
|
for net in net_list:
|
|
@@ -934,6 +958,18 @@ class Components(object):
|
|
|
934
958
|
return False
|
|
935
959
|
pin_layers = cmp_pins[0].GetPadstackDef().GetData().GetLayerNames()
|
|
936
960
|
if port_type == SourceType.CoaxPort:
|
|
961
|
+
ref_pins = [
|
|
962
|
+
p
|
|
963
|
+
for p in list(component.LayoutObjs)
|
|
964
|
+
if int(p.GetObjType()) == 1 and p.GetNet().GetName() in reference_net
|
|
965
|
+
]
|
|
966
|
+
if not ref_pins:
|
|
967
|
+
self._logger.error(
|
|
968
|
+
"No reference pins found on component. You might consider"
|
|
969
|
+
"using Circuit port instead since reference pins can be extended"
|
|
970
|
+
"outside the component automatically when not found."
|
|
971
|
+
)
|
|
972
|
+
return False
|
|
937
973
|
pad_params = self._padstack.get_pad_parameters(pin=cmp_pins[0], layername=pin_layers[0], pad_type=0)
|
|
938
974
|
if not pad_params[0] == 7:
|
|
939
975
|
if not solder_balls_size: # pragma no cover
|
|
@@ -981,17 +1017,25 @@ class Components(object):
|
|
|
981
1017
|
for p in ref_pins:
|
|
982
1018
|
if not p.IsLayoutPin():
|
|
983
1019
|
p.SetIsLayoutPin(True)
|
|
984
|
-
if
|
|
985
|
-
self._logger.
|
|
1020
|
+
if not ref_pins:
|
|
1021
|
+
self._logger.warning("No reference pins found on component, the closest pin will be selected.")
|
|
1022
|
+
do_pingroup = False
|
|
986
1023
|
if do_pingroup:
|
|
987
1024
|
if len(ref_pins) == 1:
|
|
1025
|
+
ref_pins.is_pin = True
|
|
988
1026
|
ref_pin_group_term = self._create_terminal(ref_pins[0])
|
|
989
1027
|
else:
|
|
1028
|
+
for pin in ref_pins:
|
|
1029
|
+
pin.is_pin = True
|
|
990
1030
|
ref_pin_group = self.create_pingroup_from_pins(ref_pins)
|
|
991
1031
|
if not ref_pin_group:
|
|
1032
|
+
self._logger.error(f"Failed to create reference pin group on component {component.GetName()}.")
|
|
992
1033
|
return False
|
|
993
|
-
ref_pin_group_term = self._create_pin_group_terminal(ref_pin_group, isref=
|
|
1034
|
+
ref_pin_group_term = self._create_pin_group_terminal(ref_pin_group, isref=False)
|
|
994
1035
|
if not ref_pin_group_term:
|
|
1036
|
+
self._logger.error(
|
|
1037
|
+
f"Failed to create reference pin group terminal on component {component.GetName()}"
|
|
1038
|
+
)
|
|
995
1039
|
return False
|
|
996
1040
|
for net in net_list:
|
|
997
1041
|
pins = [pin for pin in cmp_pins if pin.GetNet().GetName() == net]
|
|
@@ -1013,7 +1057,19 @@ class Components(object):
|
|
|
1013
1057
|
for net in net_list:
|
|
1014
1058
|
pins = [pin for pin in cmp_pins if pin.GetNet().GetName() == net]
|
|
1015
1059
|
for pin in pins:
|
|
1016
|
-
|
|
1060
|
+
if ref_pins:
|
|
1061
|
+
self.create_port_on_pins(component, pin, ref_pins)
|
|
1062
|
+
else:
|
|
1063
|
+
_pin = EDBPadstackInstance(pin, self._pedb)
|
|
1064
|
+
ref_pin = _pin.get_reference_pins(
|
|
1065
|
+
reference_net=reference_net[0], max_limit=1, component_only=False, search_radius=3e-3
|
|
1066
|
+
)
|
|
1067
|
+
if ref_pin:
|
|
1068
|
+
self.create_port_on_pins(
|
|
1069
|
+
component,
|
|
1070
|
+
[EDBPadstackInstance(pin, self._pedb).name],
|
|
1071
|
+
[EDBPadstackInstance(ref_pin[0], self._pedb).id],
|
|
1072
|
+
)
|
|
1017
1073
|
return True
|
|
1018
1074
|
|
|
1019
1075
|
def _create_terminal(self, pin, term_name=None):
|
|
@@ -837,9 +837,8 @@ class PathDotNet(PrimitiveDotNet):
|
|
|
837
837
|
net = net.api_object
|
|
838
838
|
width = self._app.edb_api.utility.value(width)
|
|
839
839
|
if isinstance(points, list):
|
|
840
|
-
points = self._app.
|
|
841
|
-
|
|
842
|
-
)
|
|
840
|
+
points = convert_py_list_to_net_list([self._app.point_data(i[0], i[1]) for i in points])
|
|
841
|
+
points = self._app.edb_api.geometry.polygon_data.dotnetobj(points)
|
|
843
842
|
return PathDotNet(
|
|
844
843
|
self._app, self.api.Path.Create(layout, layer, net, width, end_cap1, end_cap2, corner_style, points)
|
|
845
844
|
)
|
|
@@ -847,11 +846,15 @@ class PathDotNet(PrimitiveDotNet):
|
|
|
847
846
|
@property
|
|
848
847
|
def center_line(self):
|
|
849
848
|
""":class:`PolygonData <ansys.edb.geometry.PolygonData>`: Center line for this Path."""
|
|
850
|
-
|
|
849
|
+
edb_center_line = self.prim_obj.GetCenterLine()
|
|
850
|
+
return [[pt.X.ToDouble(), pt.Y.ToDouble()] for pt in list(edb_center_line.Points)]
|
|
851
851
|
|
|
852
852
|
@center_line.setter
|
|
853
|
-
def center_line(self,
|
|
854
|
-
|
|
853
|
+
def center_line(self, value):
|
|
854
|
+
if isinstance(value, list):
|
|
855
|
+
points = [self._pedb.point_data(i[0], i[1]) for i in value]
|
|
856
|
+
polygon_data = self._edb.geometry.polygon_data.dotnetobj(convert_py_list_to_net_list(points), False)
|
|
857
|
+
self.prim_obj.SetCenterLine(polygon_data)
|
|
855
858
|
|
|
856
859
|
@property
|
|
857
860
|
def end_cap_style(self):
|
|
@@ -1678,11 +1678,9 @@ class EDBPadstackInstance(Primitive):
|
|
|
1678
1678
|
def name(self):
|
|
1679
1679
|
"""Padstack Instance Name. If it is a pin, the syntax will be like in AEDT ComponentName-PinName."""
|
|
1680
1680
|
if self.is_pin:
|
|
1681
|
-
|
|
1682
|
-
pin_name = self._edb_padstackinstance.GetName()
|
|
1683
|
-
return "-".join([comp_name, pin_name])
|
|
1681
|
+
return self.aedt_name
|
|
1684
1682
|
else:
|
|
1685
|
-
return self.
|
|
1683
|
+
return self.component_pin
|
|
1686
1684
|
|
|
1687
1685
|
@name.setter
|
|
1688
1686
|
def name(self, value):
|
|
@@ -1725,6 +1723,12 @@ class EDBPadstackInstance(Primitive):
|
|
|
1725
1723
|
@property
|
|
1726
1724
|
def pin_number(self):
|
|
1727
1725
|
"""Get pin number."""
|
|
1726
|
+
warnings.warn("`pin_number` is deprecated. Use `component_pin` method instead.", DeprecationWarning)
|
|
1727
|
+
return self.component_pin
|
|
1728
|
+
|
|
1729
|
+
@property
|
|
1730
|
+
def component_pin(self):
|
|
1731
|
+
"""Get component pin."""
|
|
1728
1732
|
return self._edb_padstackinstance.GetName()
|
|
1729
1733
|
|
|
1730
1734
|
@property
|
|
@@ -198,24 +198,6 @@ class ExcitationSources(Terminal):
|
|
|
198
198
|
def __init__(self, pedb, edb_terminal):
|
|
199
199
|
Terminal.__init__(self, pedb, edb_terminal)
|
|
200
200
|
|
|
201
|
-
@property
|
|
202
|
-
def magnitude(self):
|
|
203
|
-
"""Get the magnitude of the source."""
|
|
204
|
-
return self._edb_object.GetSourceAmplitude().ToDouble()
|
|
205
|
-
|
|
206
|
-
@magnitude.setter
|
|
207
|
-
def magnitude(self, value):
|
|
208
|
-
self._edb_object.SetSourceAmplitude(self._edb.utility.value(value))
|
|
209
|
-
|
|
210
|
-
@property
|
|
211
|
-
def phase(self):
|
|
212
|
-
"""Get the phase of the source."""
|
|
213
|
-
return self._edb_object.GetSourcePhase().ToDouble()
|
|
214
|
-
|
|
215
|
-
@phase.setter
|
|
216
|
-
def phase(self, value):
|
|
217
|
-
self._edb_object.SetSourcePhase(self._edb.utility.value(value))
|
|
218
|
-
|
|
219
201
|
|
|
220
202
|
class BundleWavePort(BundleTerminal):
|
|
221
203
|
"""Manages bundle wave port properties.
|
|
@@ -631,7 +631,7 @@ class EdbPath(EDBPrimitives, PathDotNet):
|
|
|
631
631
|
float
|
|
632
632
|
Path length in meters.
|
|
633
633
|
"""
|
|
634
|
-
center_line_arcs = list(self.
|
|
634
|
+
center_line_arcs = list(self.api_object.GetCenterLine().GetArcData())
|
|
635
635
|
path_length = 0.0
|
|
636
636
|
for arc in center_line_arcs:
|
|
637
637
|
path_length += arc.GetLength()
|
|
@@ -241,6 +241,15 @@ class EdbPadstacks(object):
|
|
|
241
241
|
)
|
|
242
242
|
return padstack_instances
|
|
243
243
|
|
|
244
|
+
def find_instance_by_id(self, value: int):
|
|
245
|
+
"""Find a padstack instance by database id.
|
|
246
|
+
|
|
247
|
+
Parameters
|
|
248
|
+
----------
|
|
249
|
+
value : int
|
|
250
|
+
"""
|
|
251
|
+
return self._pedb.modeler.find_object_by_id(value)
|
|
252
|
+
|
|
244
253
|
@property
|
|
245
254
|
def pins(self):
|
|
246
255
|
"""Dictionary of all pins instances (belonging to component).
|
|
@@ -1441,7 +1450,7 @@ class EdbPadstacks(object):
|
|
|
1441
1450
|
instances = [inst for inst in instances if inst.component.refdes in refdes]
|
|
1442
1451
|
if component_pin:
|
|
1443
1452
|
component_pin = component_pin if isinstance(component_pin, list) else [component_pin]
|
|
1444
|
-
instances = [inst for inst in instances if inst.
|
|
1453
|
+
instances = [inst for inst in instances if inst.component_pin in component_pin]
|
|
1445
1454
|
return instances
|
|
1446
1455
|
|
|
1447
1456
|
def get_padstack_instance_by_net_name(self, net_name):
|
|
@@ -20,6 +20,9 @@
|
|
|
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 pyedb.dotnet.edb_core.sim_setup_data.data.simulation_settings import ( # HFSSSimulationSettings
|
|
24
|
+
HFSSPISimulationSettings,
|
|
25
|
+
)
|
|
23
26
|
from pyedb.dotnet.edb_core.sim_setup_data.data.sweep_data import SweepData
|
|
24
27
|
|
|
25
28
|
|
|
@@ -58,17 +61,53 @@ class SimSetupInfo:
|
|
|
58
61
|
else:
|
|
59
62
|
self._edb_object = edb_object
|
|
60
63
|
|
|
64
|
+
@property
|
|
65
|
+
def name(self):
|
|
66
|
+
return self._edb_object.Name
|
|
67
|
+
|
|
68
|
+
@name.setter
|
|
69
|
+
def name(self, name):
|
|
70
|
+
self._edb_object.Name = name
|
|
71
|
+
|
|
61
72
|
@property
|
|
62
73
|
def position(self):
|
|
63
74
|
return self._edb_object.Position
|
|
64
75
|
|
|
65
76
|
@property
|
|
66
77
|
def sim_setup_type(self):
|
|
67
|
-
|
|
78
|
+
"""
|
|
79
|
+
"kHFSS": self._pedb.simsetupdata.HFSSSimulationSettings,
|
|
80
|
+
"kPEM": None,
|
|
81
|
+
"kSIwave": self._pedb.simsetupdata.SIwave.SIWSimulationSettings,
|
|
82
|
+
"kLNA": None,
|
|
83
|
+
"kTransient": None,
|
|
84
|
+
"kQEye": None,
|
|
85
|
+
"kVEye": None,
|
|
86
|
+
"kAMI": None,
|
|
87
|
+
"kAnalysisOption": None,
|
|
88
|
+
"kSIwaveDCIR": self._pedb.simsetupdata.SIwave.SIWDCIRSimulationSettings,
|
|
89
|
+
"kSIwaveEMI": None,
|
|
90
|
+
"kHFSSPI": self._pedb.simsetupdata.HFSSPISimulationSettings,
|
|
91
|
+
"kDDRwizard": None,
|
|
92
|
+
"kQ3D": None,
|
|
93
|
+
"kNumSetupTypes": None,
|
|
94
|
+
"""
|
|
95
|
+
|
|
96
|
+
return self._edb_object.SimSetupType.ToString()
|
|
68
97
|
|
|
69
98
|
@property
|
|
70
99
|
def simulation_settings(self):
|
|
71
|
-
|
|
100
|
+
if self.sim_setup_type == "kHFSS":
|
|
101
|
+
return self._edb_object.SimulationSettings
|
|
102
|
+
# todo refactor HFSS
|
|
103
|
+
# return HFSSSimulationSettings(self._pedb, self.sim_setup, self._edb_object.SimulationSettings)
|
|
104
|
+
elif self.sim_setup_type == "kHFSSPI":
|
|
105
|
+
return HFSSPISimulationSettings(self._pedb, self.sim_setup, self._edb_object.SimulationSettings)
|
|
106
|
+
elif self.sim_setup_type == "kSIwave": # todo refactor
|
|
107
|
+
return self._edb_object.SimulationSettings
|
|
108
|
+
|
|
109
|
+
elif self.sim_setup_type == "kSIwaveDCIR": # todo refactor
|
|
110
|
+
return self._edb_object.SimulationSettings
|
|
72
111
|
|
|
73
112
|
@property
|
|
74
113
|
def sweep_data_list(self):
|
|
@@ -77,5 +116,5 @@ class SimSetupInfo:
|
|
|
77
116
|
]
|
|
78
117
|
|
|
79
118
|
def add_sweep_data(self, sweep_data):
|
|
80
|
-
sweep_data.
|
|
119
|
+
sweep_data._sim_setup = self.sim_setup
|
|
81
120
|
self._edb_object.SweepDataList.Add(sweep_data._edb_object)
|