pyedb 0.2.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 +17 -0
- pyedb/dotnet/__init__.py +0 -0
- pyedb/dotnet/application/Variables.py +2261 -0
- pyedb/dotnet/application/__init__.py +0 -0
- pyedb/dotnet/clr_module.py +103 -0
- pyedb/dotnet/edb.py +4237 -0
- pyedb/dotnet/edb_core/__init__.py +1 -0
- pyedb/dotnet/edb_core/cell/__init__.py +0 -0
- pyedb/dotnet/edb_core/cell/hierarchy/__init__.py +0 -0
- pyedb/dotnet/edb_core/cell/hierarchy/model.py +66 -0
- pyedb/dotnet/edb_core/components.py +2669 -0
- pyedb/dotnet/edb_core/configuration.py +423 -0
- pyedb/dotnet/edb_core/definition/__init__.py +0 -0
- pyedb/dotnet/edb_core/definition/component_def.py +166 -0
- pyedb/dotnet/edb_core/definition/component_model.py +30 -0
- pyedb/dotnet/edb_core/definition/definition_obj.py +18 -0
- pyedb/dotnet/edb_core/definition/definitions.py +12 -0
- pyedb/dotnet/edb_core/dotnet/__init__.py +0 -0
- pyedb/dotnet/edb_core/dotnet/database.py +1218 -0
- pyedb/dotnet/edb_core/dotnet/layout.py +238 -0
- pyedb/dotnet/edb_core/dotnet/primitive.py +1517 -0
- pyedb/dotnet/edb_core/edb_data/__init__.py +0 -0
- pyedb/dotnet/edb_core/edb_data/components_data.py +938 -0
- pyedb/dotnet/edb_core/edb_data/connectable.py +113 -0
- pyedb/dotnet/edb_core/edb_data/control_file.py +1268 -0
- pyedb/dotnet/edb_core/edb_data/design_options.py +35 -0
- pyedb/dotnet/edb_core/edb_data/edbvalue.py +45 -0
- pyedb/dotnet/edb_core/edb_data/hfss_extent_info.py +330 -0
- pyedb/dotnet/edb_core/edb_data/hfss_simulation_setup_data.py +1607 -0
- pyedb/dotnet/edb_core/edb_data/layer_data.py +576 -0
- pyedb/dotnet/edb_core/edb_data/nets_data.py +281 -0
- pyedb/dotnet/edb_core/edb_data/obj_base.py +19 -0
- pyedb/dotnet/edb_core/edb_data/padstacks_data.py +2080 -0
- pyedb/dotnet/edb_core/edb_data/ports.py +287 -0
- pyedb/dotnet/edb_core/edb_data/primitives_data.py +1397 -0
- pyedb/dotnet/edb_core/edb_data/simulation_configuration.py +2914 -0
- pyedb/dotnet/edb_core/edb_data/simulation_setup.py +716 -0
- pyedb/dotnet/edb_core/edb_data/siwave_simulation_setup_data.py +1205 -0
- pyedb/dotnet/edb_core/edb_data/sources.py +514 -0
- pyedb/dotnet/edb_core/edb_data/terminals.py +632 -0
- pyedb/dotnet/edb_core/edb_data/utilities.py +148 -0
- pyedb/dotnet/edb_core/edb_data/variables.py +91 -0
- pyedb/dotnet/edb_core/general.py +181 -0
- pyedb/dotnet/edb_core/hfss.py +1646 -0
- pyedb/dotnet/edb_core/layout.py +1244 -0
- pyedb/dotnet/edb_core/layout_validation.py +272 -0
- pyedb/dotnet/edb_core/materials.py +939 -0
- pyedb/dotnet/edb_core/net_class.py +335 -0
- pyedb/dotnet/edb_core/nets.py +1215 -0
- pyedb/dotnet/edb_core/padstack.py +1389 -0
- pyedb/dotnet/edb_core/siwave.py +1427 -0
- pyedb/dotnet/edb_core/stackup.py +2703 -0
- pyedb/edb_logger.py +396 -0
- pyedb/generic/__init__.py +0 -0
- pyedb/generic/constants.py +1063 -0
- pyedb/generic/data_handlers.py +320 -0
- pyedb/generic/design_types.py +104 -0
- pyedb/generic/filesystem.py +150 -0
- pyedb/generic/general_methods.py +1535 -0
- pyedb/generic/plot.py +1840 -0
- pyedb/generic/process.py +285 -0
- pyedb/generic/settings.py +224 -0
- pyedb/ipc2581/__init__.py +0 -0
- pyedb/ipc2581/bom/__init__.py +0 -0
- pyedb/ipc2581/bom/bom.py +21 -0
- pyedb/ipc2581/bom/bom_item.py +32 -0
- pyedb/ipc2581/bom/characteristics.py +37 -0
- pyedb/ipc2581/bom/refdes.py +16 -0
- pyedb/ipc2581/content/__init__.py +0 -0
- pyedb/ipc2581/content/color.py +38 -0
- pyedb/ipc2581/content/content.py +55 -0
- pyedb/ipc2581/content/dictionary_color.py +29 -0
- pyedb/ipc2581/content/dictionary_fill.py +28 -0
- pyedb/ipc2581/content/dictionary_line.py +30 -0
- pyedb/ipc2581/content/entry_color.py +13 -0
- pyedb/ipc2581/content/entry_line.py +14 -0
- pyedb/ipc2581/content/fill.py +15 -0
- pyedb/ipc2581/content/layer_ref.py +10 -0
- pyedb/ipc2581/content/standard_geometries_dictionary.py +72 -0
- pyedb/ipc2581/ecad/__init__.py +0 -0
- pyedb/ipc2581/ecad/cad_data/__init__.py +0 -0
- pyedb/ipc2581/ecad/cad_data/assembly_drawing.py +26 -0
- pyedb/ipc2581/ecad/cad_data/cad_data.py +37 -0
- pyedb/ipc2581/ecad/cad_data/component.py +41 -0
- pyedb/ipc2581/ecad/cad_data/drill.py +30 -0
- pyedb/ipc2581/ecad/cad_data/feature.py +54 -0
- pyedb/ipc2581/ecad/cad_data/layer.py +41 -0
- pyedb/ipc2581/ecad/cad_data/layer_feature.py +151 -0
- pyedb/ipc2581/ecad/cad_data/logical_net.py +32 -0
- pyedb/ipc2581/ecad/cad_data/outline.py +25 -0
- pyedb/ipc2581/ecad/cad_data/package.py +104 -0
- pyedb/ipc2581/ecad/cad_data/padstack_def.py +38 -0
- pyedb/ipc2581/ecad/cad_data/padstack_hole_def.py +24 -0
- pyedb/ipc2581/ecad/cad_data/padstack_instance.py +62 -0
- pyedb/ipc2581/ecad/cad_data/padstack_pad_def.py +26 -0
- pyedb/ipc2581/ecad/cad_data/path.py +89 -0
- pyedb/ipc2581/ecad/cad_data/phy_net.py +80 -0
- pyedb/ipc2581/ecad/cad_data/pin.py +31 -0
- pyedb/ipc2581/ecad/cad_data/polygon.py +169 -0
- pyedb/ipc2581/ecad/cad_data/profile.py +40 -0
- pyedb/ipc2581/ecad/cad_data/stackup.py +31 -0
- pyedb/ipc2581/ecad/cad_data/stackup_group.py +42 -0
- pyedb/ipc2581/ecad/cad_data/stackup_layer.py +21 -0
- pyedb/ipc2581/ecad/cad_data/step.py +275 -0
- pyedb/ipc2581/ecad/cad_header.py +33 -0
- pyedb/ipc2581/ecad/ecad.py +19 -0
- pyedb/ipc2581/ecad/spec.py +46 -0
- pyedb/ipc2581/history_record.py +37 -0
- pyedb/ipc2581/ipc2581.py +387 -0
- pyedb/ipc2581/logistic_header.py +25 -0
- pyedb/misc/__init__.py +0 -0
- pyedb/misc/aedtlib_personalib_install.py +14 -0
- pyedb/misc/downloads.py +322 -0
- pyedb/misc/misc.py +67 -0
- pyedb/misc/pyedb.runtimeconfig.json +13 -0
- pyedb/misc/siw_feature_config/__init__.py +0 -0
- pyedb/misc/siw_feature_config/emc/__init__.py +0 -0
- pyedb/misc/siw_feature_config/emc/component_tags.py +46 -0
- pyedb/misc/siw_feature_config/emc/net_tags.py +37 -0
- pyedb/misc/siw_feature_config/emc/tag_library.py +62 -0
- pyedb/misc/siw_feature_config/emc/xml_generic.py +78 -0
- pyedb/misc/siw_feature_config/emc_rule_checker_settings.py +179 -0
- pyedb/misc/utilities.py +27 -0
- pyedb/modeler/geometry_operators.py +2082 -0
- pyedb-0.2.0.dist-info/LICENSE +21 -0
- pyedb-0.2.0.dist-info/METADATA +208 -0
- pyedb-0.2.0.dist-info/RECORD +128 -0
- pyedb-0.2.0.dist-info/WHEEL +4 -0
|
@@ -0,0 +1,632 @@
|
|
|
1
|
+
import re
|
|
2
|
+
|
|
3
|
+
from pyedb.dotnet.edb_core.edb_data.connectable import Connectable
|
|
4
|
+
from pyedb.dotnet.edb_core.edb_data.padstacks_data import EDBPadstackInstance
|
|
5
|
+
from pyedb.dotnet.edb_core.edb_data.primitives_data import cast
|
|
6
|
+
from pyedb.dotnet.edb_core.general import convert_py_list_to_net_list
|
|
7
|
+
from pyedb.generic.general_methods import generate_unique_name, pyedb_function_handler
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class Terminal(Connectable):
|
|
11
|
+
def __init__(self, pedb, edb_object=None):
|
|
12
|
+
super().__init__(pedb, edb_object)
|
|
13
|
+
self._reference_object = None
|
|
14
|
+
|
|
15
|
+
self._boundary_type_mapping = {
|
|
16
|
+
"InvalidBoundary": self._pedb.edb_api.cell.terminal.BoundaryType.InvalidBoundary,
|
|
17
|
+
"PortBoundary": self._pedb.edb_api.cell.terminal.BoundaryType.PortBoundary,
|
|
18
|
+
"PecBoundary": self._pedb.edb_api.cell.terminal.BoundaryType.PecBoundary,
|
|
19
|
+
"RlcBoundary": self._pedb.edb_api.cell.terminal.BoundaryType.RlcBoundary,
|
|
20
|
+
"kCurrentSource": self._pedb.edb_api.cell.terminal.BoundaryType.kCurrentSource,
|
|
21
|
+
"kVoltageSource": self._pedb.edb_api.cell.terminal.BoundaryType.kVoltageSource,
|
|
22
|
+
"kNexximGround": self._pedb.edb_api.cell.terminal.BoundaryType.kNexximGround,
|
|
23
|
+
"kNexximPort": self._pedb.edb_api.cell.terminal.BoundaryType.kNexximPort,
|
|
24
|
+
"kDcTerminal": self._pedb.edb_api.cell.terminal.BoundaryType.kDcTerminal,
|
|
25
|
+
"kVoltageProbe": self._pedb.edb_api.cell.terminal.BoundaryType.kVoltageProbe,
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
self._terminal_type_mapping = {
|
|
29
|
+
"InvalidTerminal": self._pedb.edb_api.cell.terminal.TerminalType.InvalidTerminal,
|
|
30
|
+
"EdgeTerminal": self._pedb.edb_api.cell.terminal.TerminalType.EdgeTerminal,
|
|
31
|
+
"PointTerminal": self._pedb.edb_api.cell.terminal.TerminalType.PointTerminal,
|
|
32
|
+
"TerminalInstanceTerminal": self._pedb.edb_api.cell.terminal.TerminalType.TerminalInstanceTerminal,
|
|
33
|
+
"PadstackInstanceTerminal": self._pedb.edb_api.cell.terminal.TerminalType.PadstackInstanceTerminal,
|
|
34
|
+
"BundleTerminal": self._pedb.edb_api.cell.terminal.TerminalType.BundleTerminal,
|
|
35
|
+
"PinGroupTerminal": self._pedb.edb_api.cell.terminal.TerminalType.PinGroupTerminal,
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
self._terminal_mapping = {
|
|
39
|
+
"EdgeTerminal": EdgeTerminal,
|
|
40
|
+
"PointTerminal": PointTerminal,
|
|
41
|
+
"PadstackInstanceTerminal": PadstackInstanceTerminal,
|
|
42
|
+
"BundleTerminal": BundleTerminal,
|
|
43
|
+
"PinGroupTerminal": PinGroupTerminal,
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
@property
|
|
47
|
+
def _hfss_port_property(self):
|
|
48
|
+
"""HFSS port property."""
|
|
49
|
+
hfss_prop = re.search(r"HFSS\(.*?\)", self._edb_properties)
|
|
50
|
+
p = {}
|
|
51
|
+
if hfss_prop:
|
|
52
|
+
hfss_type = re.search(r"'HFSS Type'='([^']+)'", hfss_prop.group())
|
|
53
|
+
orientation = re.search(r"'Orientation'='([^']+)'", hfss_prop.group())
|
|
54
|
+
horizontal_ef = re.search(r"'Horizontal Extent Factor'='([^']+)'", hfss_prop.group())
|
|
55
|
+
vertical_ef = re.search(r"'Vertical Extent Factor'='([^']+)'", hfss_prop.group())
|
|
56
|
+
radial_ef = re.search(r"'Radial Extent Factor'='([^']+)'", hfss_prop.group())
|
|
57
|
+
pec_w = re.search(r"'PEC Launch Width'='([^']+)'", hfss_prop.group())
|
|
58
|
+
|
|
59
|
+
p["HFSS Type"] = hfss_type.group(1) if hfss_type else ""
|
|
60
|
+
p["Orientation"] = orientation.group(1) if orientation else ""
|
|
61
|
+
p["Horizontal Extent Factor"] = float(horizontal_ef.group(1)) if horizontal_ef else ""
|
|
62
|
+
p["Vertical Extent Factor"] = float(vertical_ef.group(1)) if vertical_ef else ""
|
|
63
|
+
p["Radial Extent Factor"] = float(radial_ef.group(1)) if radial_ef else ""
|
|
64
|
+
p["PEC Launch Width"] = pec_w.group(1) if pec_w else ""
|
|
65
|
+
else:
|
|
66
|
+
p["HFSS Type"] = ""
|
|
67
|
+
p["Orientation"] = ""
|
|
68
|
+
p["Horizontal Extent Factor"] = ""
|
|
69
|
+
p["Vertical Extent Factor"] = ""
|
|
70
|
+
p["Radial Extent Factor"] = ""
|
|
71
|
+
p["PEC Launch Width"] = ""
|
|
72
|
+
return p
|
|
73
|
+
|
|
74
|
+
@_hfss_port_property.setter
|
|
75
|
+
def _hfss_port_property(self, value):
|
|
76
|
+
txt = []
|
|
77
|
+
for k, v in value.items():
|
|
78
|
+
txt.append("'{}'='{}'".format(k, v))
|
|
79
|
+
txt = ",".join(txt)
|
|
80
|
+
self._edb_properties = "HFSS({})".format(txt)
|
|
81
|
+
|
|
82
|
+
@property
|
|
83
|
+
def hfss_type(self):
|
|
84
|
+
"""HFSS port type."""
|
|
85
|
+
return self._hfss_port_property["HFSS Type"]
|
|
86
|
+
|
|
87
|
+
@hfss_type.setter
|
|
88
|
+
def hfss_type(self, value):
|
|
89
|
+
p = self._hfss_port_property
|
|
90
|
+
p["HFSS Type"] = value
|
|
91
|
+
self._hfss_port_property = p
|
|
92
|
+
|
|
93
|
+
@property
|
|
94
|
+
def is_circuit_port(self):
|
|
95
|
+
"""Whether it is a circuit port."""
|
|
96
|
+
return self._edb_object.GetIsCircuitPort()
|
|
97
|
+
|
|
98
|
+
@is_circuit_port.setter
|
|
99
|
+
def is_circuit_port(self, value):
|
|
100
|
+
self._edb_object.SetIsCircuitPort(value)
|
|
101
|
+
|
|
102
|
+
@property
|
|
103
|
+
def _port_post_processing_prop(self):
|
|
104
|
+
"""Get port post processing properties."""
|
|
105
|
+
return self._edb_object.GetPortPostProcessingProp()
|
|
106
|
+
|
|
107
|
+
@_port_post_processing_prop.setter
|
|
108
|
+
def _port_post_processing_prop(self, value):
|
|
109
|
+
self._edb_object.SetPortPostProcessingProp(value)
|
|
110
|
+
|
|
111
|
+
@property
|
|
112
|
+
def do_renormalize(self):
|
|
113
|
+
"""Determine whether port renormalization is enabled."""
|
|
114
|
+
return self._port_post_processing_prop.DoRenormalize
|
|
115
|
+
|
|
116
|
+
@do_renormalize.setter
|
|
117
|
+
def do_renormalize(self, value):
|
|
118
|
+
ppp = self._port_post_processing_prop
|
|
119
|
+
ppp.DoRenormalize = value
|
|
120
|
+
self._port_post_processing_prop = ppp
|
|
121
|
+
|
|
122
|
+
@property
|
|
123
|
+
def name(self):
|
|
124
|
+
"""Port Name.
|
|
125
|
+
|
|
126
|
+
Returns
|
|
127
|
+
-------
|
|
128
|
+
str
|
|
129
|
+
"""
|
|
130
|
+
return self._edb_object.GetName()
|
|
131
|
+
|
|
132
|
+
@name.setter
|
|
133
|
+
def name(self, value):
|
|
134
|
+
if isinstance(value, str):
|
|
135
|
+
if not any(port for port in list(self._pedb.excitations.keys()) if port == value):
|
|
136
|
+
self._edb_object.SetName(value)
|
|
137
|
+
else:
|
|
138
|
+
self._pedb.logger.warning("An existing port already has this same name. A port name must be unique.")
|
|
139
|
+
|
|
140
|
+
@property
|
|
141
|
+
def net_name(self):
|
|
142
|
+
"""Net name.
|
|
143
|
+
|
|
144
|
+
Returns
|
|
145
|
+
-------
|
|
146
|
+
str
|
|
147
|
+
"""
|
|
148
|
+
return self.net.name
|
|
149
|
+
|
|
150
|
+
@property
|
|
151
|
+
def terminal_type(self):
|
|
152
|
+
"""Terminal Type.
|
|
153
|
+
|
|
154
|
+
Returns
|
|
155
|
+
-------
|
|
156
|
+
int
|
|
157
|
+
"""
|
|
158
|
+
return self._edb_object.GetTerminalType().ToString()
|
|
159
|
+
|
|
160
|
+
@terminal_type.setter
|
|
161
|
+
def terminal_type(self, value):
|
|
162
|
+
self._edb_object.GetTerminalType(self._terminal_type_mapping[value])
|
|
163
|
+
|
|
164
|
+
@property
|
|
165
|
+
def boundary_type(self):
|
|
166
|
+
"""Boundary type.
|
|
167
|
+
|
|
168
|
+
Returns
|
|
169
|
+
-------
|
|
170
|
+
str
|
|
171
|
+
InvalidBoundary, PortBoundary, PecBoundary, RlcBoundary, kCurrentSource, kVoltageSource, kNexximGround,
|
|
172
|
+
kNexximPort, kDcTerminal, kVoltageProbe
|
|
173
|
+
"""
|
|
174
|
+
return self._edb_object.GetBoundaryType().ToString()
|
|
175
|
+
|
|
176
|
+
@boundary_type.setter
|
|
177
|
+
def boundary_type(self, value):
|
|
178
|
+
self._edb_object.SetBoundaryType(self._boundary_type_mapping[value])
|
|
179
|
+
|
|
180
|
+
@property
|
|
181
|
+
def impedance(self):
|
|
182
|
+
"""Impedance of the port."""
|
|
183
|
+
return self._edb_object.GetImpedance().ToDouble()
|
|
184
|
+
|
|
185
|
+
@impedance.setter
|
|
186
|
+
def impedance(self, value):
|
|
187
|
+
self._edb_object.SetImpedance(self._pedb.edb_value(value))
|
|
188
|
+
|
|
189
|
+
@property
|
|
190
|
+
def is_reference_terminal(self):
|
|
191
|
+
"""Whether it is a reference terminal."""
|
|
192
|
+
return self._edb_object.IsReferenceTerminal()
|
|
193
|
+
|
|
194
|
+
@property
|
|
195
|
+
def ref_terminal(self):
|
|
196
|
+
"""Get reference terminal."""
|
|
197
|
+
|
|
198
|
+
terminal = Terminal(self._pedb, self._edb_object.GetReferenceTerminal())
|
|
199
|
+
if not terminal.is_null:
|
|
200
|
+
return self._terminal_mapping[terminal.terminal_type](self._pedb, terminal._edb_object)
|
|
201
|
+
|
|
202
|
+
@ref_terminal.setter
|
|
203
|
+
def ref_terminal(self, value):
|
|
204
|
+
self._edb_object.SetReferenceTerminal(value._edb_object)
|
|
205
|
+
|
|
206
|
+
@property
|
|
207
|
+
def reference_object(self): # pragma : no cover
|
|
208
|
+
"""This returns the object assigned as reference. It can be a primitive or a padstack instance.
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
Returns
|
|
212
|
+
-------
|
|
213
|
+
:class:`dotnet.edb_core.edb_data.padstacks_data.EDBPadstackInstance` or
|
|
214
|
+
:class:`pyedb.dotnet.edb_core.edb_data.primitives_data.EDBPrimitives`
|
|
215
|
+
"""
|
|
216
|
+
if not self._reference_object:
|
|
217
|
+
term = self._edb_object
|
|
218
|
+
|
|
219
|
+
if self.terminal_type == self._pedb.edb_api.cell.terminal.TerminalType.EdgeTerminal:
|
|
220
|
+
edges = self._edb_object.GetEdges()
|
|
221
|
+
edgeType = edges[0].GetEdgeType()
|
|
222
|
+
if edgeType == self._pedb.edb_api.cell.terminal.EdgeType.PadEdge:
|
|
223
|
+
self._reference_object = self.get_pad_edge_terminal_reference_pin()
|
|
224
|
+
else:
|
|
225
|
+
self._reference_object = self.get_edge_terminal_reference_primitive()
|
|
226
|
+
elif self.terminal_type == "PinGroupTerminal":
|
|
227
|
+
self._reference_object = self.get_pin_group_terminal_reference_pin()
|
|
228
|
+
elif self.terminal_type == "PointTerminal":
|
|
229
|
+
self._reference_object = self.get_point_terminal_reference_primitive()
|
|
230
|
+
elif self.terminal_type == "PadstackInstanceTerminal":
|
|
231
|
+
self._reference_object = self.get_padstack_terminal_reference_pin()
|
|
232
|
+
else:
|
|
233
|
+
self._pedb.logger.warning("Invalid Terminal Type={}".format(term.GetTerminalType()))
|
|
234
|
+
|
|
235
|
+
return self._reference_object
|
|
236
|
+
|
|
237
|
+
@property
|
|
238
|
+
def reference_net_name(self):
|
|
239
|
+
"""Net name to which reference_object belongs."""
|
|
240
|
+
ref_obj = self._reference_object if self._reference_object else self.reference_object
|
|
241
|
+
if ref_obj:
|
|
242
|
+
return ref_obj.net_name
|
|
243
|
+
|
|
244
|
+
return ""
|
|
245
|
+
|
|
246
|
+
@pyedb_function_handler()
|
|
247
|
+
def get_padstack_terminal_reference_pin(self, gnd_net_name_preference=None): # pragma : no cover
|
|
248
|
+
"""Get a list of pad stacks instances and serves Coax wave ports,
|
|
249
|
+
pingroup terminals, PadEdge terminals.
|
|
250
|
+
|
|
251
|
+
Parameters
|
|
252
|
+
----------
|
|
253
|
+
gnd_net_name_preference : str, optional
|
|
254
|
+
Preferred reference net name.
|
|
255
|
+
|
|
256
|
+
Returns
|
|
257
|
+
-------
|
|
258
|
+
:class:`dotnet.edb_core.edb_data.padstack_data.EDBPadstackInstance`
|
|
259
|
+
"""
|
|
260
|
+
|
|
261
|
+
if self._edb_object.GetIsCircuitPort():
|
|
262
|
+
return self.get_pin_group_terminal_reference_pin()
|
|
263
|
+
_, padStackInstance, _ = self._edb_object.GetParameters()
|
|
264
|
+
|
|
265
|
+
# Get the pastack instance of the terminal
|
|
266
|
+
compInst = self._edb_object.GetComponent()
|
|
267
|
+
pins = self._pedb.components.get_pin_from_component(compInst.GetName())
|
|
268
|
+
return self._get_closest_pin(padStackInstance, pins, gnd_net_name_preference)
|
|
269
|
+
|
|
270
|
+
@pyedb_function_handler()
|
|
271
|
+
def get_pin_group_terminal_reference_pin(self, gnd_net_name_preference=None): # pragma : no cover
|
|
272
|
+
"""Return a list of pins and serves terminals connected to pingroups.
|
|
273
|
+
|
|
274
|
+
Parameters
|
|
275
|
+
----------
|
|
276
|
+
gnd_net_name_preference : str, optional
|
|
277
|
+
Preferred reference net name.
|
|
278
|
+
|
|
279
|
+
Returns
|
|
280
|
+
-------
|
|
281
|
+
:class:`dotnet.edb_core.edb_data.padstack_data.EDBPadstackInstance`
|
|
282
|
+
"""
|
|
283
|
+
|
|
284
|
+
refTerm = self._edb_object.GetReferenceTerminal()
|
|
285
|
+
if self._edb_object.GetTerminalType() == self._pedb.edb_api.cell.terminal.TerminalType.PinGroupTerminal:
|
|
286
|
+
padStackInstance = self._edb_object.GetPinGroup().GetPins()[0]
|
|
287
|
+
pingroup = refTerm.GetPinGroup()
|
|
288
|
+
refPinList = pingroup.GetPins()
|
|
289
|
+
return self._get_closest_pin(padStackInstance, refPinList, gnd_net_name_preference)
|
|
290
|
+
elif (
|
|
291
|
+
self._edb_object.GetTerminalType() == self._pedb.edb_api.cell.terminal.TerminalType.PadstackInstanceTerminal
|
|
292
|
+
):
|
|
293
|
+
_, padStackInstance, _ = self._edb_object.GetParameters()
|
|
294
|
+
if refTerm.GetTerminalType() == self._pedb.edb_api.cell.terminal.TerminalType.PinGroupTerminal:
|
|
295
|
+
pingroup = refTerm.GetPinGroup()
|
|
296
|
+
refPinList = pingroup.GetPins()
|
|
297
|
+
return self._get_closest_pin(padStackInstance, refPinList, gnd_net_name_preference)
|
|
298
|
+
else:
|
|
299
|
+
try:
|
|
300
|
+
_, refTermPSI, _ = refTerm.GetParameters()
|
|
301
|
+
return EDBPadstackInstance(refTermPSI, self._pedb)
|
|
302
|
+
except AttributeError:
|
|
303
|
+
return None
|
|
304
|
+
return None
|
|
305
|
+
|
|
306
|
+
@pyedb_function_handler()
|
|
307
|
+
def get_edge_terminal_reference_primitive(self): # pragma : no cover
|
|
308
|
+
"""Check and return a primitive instance that serves Edge ports,
|
|
309
|
+
wave ports and coupled edge ports that are directly connedted to primitives.
|
|
310
|
+
|
|
311
|
+
Returns
|
|
312
|
+
-------
|
|
313
|
+
:class:`pyedb.dotnet.edb_core.edb_data.primitives_data.EDBPrimitives`
|
|
314
|
+
"""
|
|
315
|
+
|
|
316
|
+
ref_layer = self._edb_object.GetReferenceLayer()
|
|
317
|
+
edges = self._edb_object.GetEdges()
|
|
318
|
+
_, _, point_data = edges[0].GetParameters()
|
|
319
|
+
X = point_data.X
|
|
320
|
+
Y = point_data.Y
|
|
321
|
+
shape_pd = self._pedb.edb_api.geometry.point_data(X, Y)
|
|
322
|
+
layer_name = ref_layer.GetName()
|
|
323
|
+
for primitive in self._pedb.layout.primitives:
|
|
324
|
+
if primitive.GetLayer().GetName() == layer_name or not layer_name:
|
|
325
|
+
prim_shape_data = primitive.GetPolygonData()
|
|
326
|
+
if prim_shape_data.PointInPolygon(shape_pd):
|
|
327
|
+
return cast(primitive, self._pedb)
|
|
328
|
+
return None # pragma: no cover
|
|
329
|
+
|
|
330
|
+
@pyedb_function_handler()
|
|
331
|
+
def get_point_terminal_reference_primitive(self): # pragma : no cover
|
|
332
|
+
"""Find and return the primitive reference for the point terminal or the padstack instance.
|
|
333
|
+
|
|
334
|
+
Returns
|
|
335
|
+
-------
|
|
336
|
+
:class:`dotnet.edb_core.edb_data.padstacks_data.EDBPadstackInstance` or
|
|
337
|
+
:class:`pyedb.dotnet.edb_core.edb_data.primitives_data.EDBPrimitives`
|
|
338
|
+
"""
|
|
339
|
+
|
|
340
|
+
ref_term = self._edb_object.GetReferenceTerminal() # return value is type terminal
|
|
341
|
+
_, point_data, layer = ref_term.GetParameters()
|
|
342
|
+
X = point_data.X
|
|
343
|
+
Y = point_data.Y
|
|
344
|
+
shape_pd = self._pedb.edb_api.geometry.point_data(X, Y)
|
|
345
|
+
layer_name = layer.GetName()
|
|
346
|
+
for primitive in self._pedb.layout.primitives:
|
|
347
|
+
if primitive.GetLayer().GetName() == layer_name:
|
|
348
|
+
prim_shape_data = primitive.GetPolygonData()
|
|
349
|
+
if prim_shape_data.PointInPolygon(shape_pd):
|
|
350
|
+
return cast(primitive, self._pedb)
|
|
351
|
+
for vias in self._pedb.padstacks.instances.values():
|
|
352
|
+
if layer_name in vias.layer_range_names:
|
|
353
|
+
plane = self._pedb.modeler.Shape(
|
|
354
|
+
"rectangle", pointA=vias.position, pointB=vias.padstack_definition.bounding_box[1]
|
|
355
|
+
)
|
|
356
|
+
rectangle_data = vias._pedb.modeler.shape_to_polygon_data(plane)
|
|
357
|
+
if rectangle_data.PointInPolygon(shape_pd):
|
|
358
|
+
return vias
|
|
359
|
+
return None
|
|
360
|
+
|
|
361
|
+
@pyedb_function_handler()
|
|
362
|
+
def get_pad_edge_terminal_reference_pin(self, gnd_net_name_preference=None):
|
|
363
|
+
"""Get the closest pin padstack instances and serves any edge terminal connected to a pad.
|
|
364
|
+
|
|
365
|
+
Parameters
|
|
366
|
+
----------
|
|
367
|
+
gnd_net_name_preference : str, optional
|
|
368
|
+
Preferred reference net name. Optianal, default is `None` which will auto compute the gnd name.
|
|
369
|
+
|
|
370
|
+
Returns
|
|
371
|
+
-------
|
|
372
|
+
:class:`pyedb.dotnet.edb_core.edb_data.padstacks_data.EDBPadstackInstance`
|
|
373
|
+
"""
|
|
374
|
+
comp_inst = self._edb_object.GetComponent()
|
|
375
|
+
pins = self._pedb.components.get_pin_from_component(comp_inst.GetName())
|
|
376
|
+
try:
|
|
377
|
+
edges = self._edb_object.GetEdges()
|
|
378
|
+
except AttributeError:
|
|
379
|
+
return None
|
|
380
|
+
_, pad_edge_pstack_inst, _, _ = edges[0].GetParameters()
|
|
381
|
+
return self._get_closest_pin(pad_edge_pstack_inst, pins, gnd_net_name_preference)
|
|
382
|
+
|
|
383
|
+
@pyedb_function_handler()
|
|
384
|
+
def _get_closest_pin(self, ref_pin, pin_list, gnd_net=None):
|
|
385
|
+
_, pad_stack_inst_point, _ = ref_pin.GetPositionAndRotation() # get the xy of the padstack
|
|
386
|
+
if gnd_net is not None:
|
|
387
|
+
power_ground_net_names = [gnd_net]
|
|
388
|
+
else:
|
|
389
|
+
power_ground_net_names = [net for net in self._pedb.nets.power_nets.keys()]
|
|
390
|
+
comp_ref_pins = [i for i in pin_list if i.GetNet().GetName() in power_ground_net_names]
|
|
391
|
+
if len(comp_ref_pins) == 0: # pragma: no cover
|
|
392
|
+
self._pedb.logger.error(
|
|
393
|
+
"Terminal with PadStack Instance Name {} component has no reference pins.".format(ref_pin.GetName())
|
|
394
|
+
)
|
|
395
|
+
return None
|
|
396
|
+
closest_pin_distance = None
|
|
397
|
+
pin_obj = None
|
|
398
|
+
for pin in comp_ref_pins: # find the distance to all the pins to the terminal pin
|
|
399
|
+
if pin.GetName() == ref_pin.GetName(): # skip the reference psi
|
|
400
|
+
continue # pragma: no cover
|
|
401
|
+
_, pin_point, _ = pin.GetPositionAndRotation()
|
|
402
|
+
distance = pad_stack_inst_point.Distance(pin_point)
|
|
403
|
+
if closest_pin_distance is None:
|
|
404
|
+
closest_pin_distance = distance
|
|
405
|
+
pin_obj = pin
|
|
406
|
+
elif closest_pin_distance < distance:
|
|
407
|
+
continue
|
|
408
|
+
else:
|
|
409
|
+
closest_pin_distance = distance
|
|
410
|
+
pin_obj = pin
|
|
411
|
+
if pin_obj:
|
|
412
|
+
return EDBPadstackInstance(pin_obj, self._pedb)
|
|
413
|
+
|
|
414
|
+
|
|
415
|
+
class EdgeTerminal(Terminal):
|
|
416
|
+
def __init__(self, pedb, edb_object):
|
|
417
|
+
super().__init__(pedb, edb_object)
|
|
418
|
+
|
|
419
|
+
@pyedb_function_handler()
|
|
420
|
+
def couple_ports(self, port):
|
|
421
|
+
"""Create a bundle wave port.
|
|
422
|
+
|
|
423
|
+
Parameters
|
|
424
|
+
----------
|
|
425
|
+
port : :class:`dotnet.edb_core.ports.WavePort`, :class:`dotnet.edb_core.ports.GapPort`, list, optional
|
|
426
|
+
Ports to be added.
|
|
427
|
+
|
|
428
|
+
Returns
|
|
429
|
+
-------
|
|
430
|
+
:class:`dotnet.edb_core.ports.BundleWavePort`
|
|
431
|
+
|
|
432
|
+
"""
|
|
433
|
+
if not isinstance(port, (list, tuple)):
|
|
434
|
+
port = [port]
|
|
435
|
+
temp = [self._edb_object]
|
|
436
|
+
temp.extend([i._edb_object for i in port])
|
|
437
|
+
edb_list = convert_py_list_to_net_list(temp, self._edb.cell.terminal.Terminal)
|
|
438
|
+
_edb_bundle_terminal = self._edb.cell.terminal.BundleTerminal.Create(edb_list)
|
|
439
|
+
return self._pedb.ports[self.name]
|
|
440
|
+
|
|
441
|
+
|
|
442
|
+
class BundleTerminal(Terminal):
|
|
443
|
+
"""Manages bundle terminal properties.
|
|
444
|
+
|
|
445
|
+
Parameters
|
|
446
|
+
----------
|
|
447
|
+
pedb : pyedb.edb.Edb
|
|
448
|
+
EDB object from the ``Edblib`` library.
|
|
449
|
+
edb_object : Ansys.Ansoft.Edb.Cell.Terminal.BundleTerminal
|
|
450
|
+
BundleTerminal instance from EDB.
|
|
451
|
+
"""
|
|
452
|
+
|
|
453
|
+
def __init__(self, pedb, edb_object):
|
|
454
|
+
super().__init__(pedb, edb_object)
|
|
455
|
+
|
|
456
|
+
@property
|
|
457
|
+
def terminals(self):
|
|
458
|
+
"""Get terminals belonging to this excitation."""
|
|
459
|
+
return [EdgeTerminal(self._pedb, i) for i in list(self._edb_object.GetTerminals())]
|
|
460
|
+
|
|
461
|
+
@property
|
|
462
|
+
def name(self):
|
|
463
|
+
return self.terminals[0].name
|
|
464
|
+
|
|
465
|
+
@pyedb_function_handler()
|
|
466
|
+
def decouple(self):
|
|
467
|
+
"""Ungroup a bundle of terminals."""
|
|
468
|
+
return self._edb_object.Ungroup()
|
|
469
|
+
|
|
470
|
+
|
|
471
|
+
class PadstackInstanceTerminal(Terminal):
|
|
472
|
+
"""Manages bundle terminal properties."""
|
|
473
|
+
|
|
474
|
+
def __init__(self, pedb, edb_object):
|
|
475
|
+
super().__init__(pedb, edb_object)
|
|
476
|
+
|
|
477
|
+
@property
|
|
478
|
+
def position(self):
|
|
479
|
+
"""Return terminal position.
|
|
480
|
+
Returns
|
|
481
|
+
-------
|
|
482
|
+
Position [x,y] : [float, float]
|
|
483
|
+
"""
|
|
484
|
+
edb_padstack_instance = self._edb_object.GetParameters()
|
|
485
|
+
if edb_padstack_instance[0]:
|
|
486
|
+
return EDBPadstackInstance(edb_padstack_instance[1], self._pedb).position
|
|
487
|
+
return False
|
|
488
|
+
|
|
489
|
+
def create(self, padstack_instance, name=None, layer=None, is_ref=False):
|
|
490
|
+
"""Create an edge terminal.
|
|
491
|
+
|
|
492
|
+
Parameters
|
|
493
|
+
----------
|
|
494
|
+
prim_id : int
|
|
495
|
+
Primitive ID.
|
|
496
|
+
point_on_edge : list
|
|
497
|
+
Coordinate of the point to define the edge terminal.
|
|
498
|
+
The point must be on the target edge but not on the two
|
|
499
|
+
ends of the edge.
|
|
500
|
+
terminal_name : str, optional
|
|
501
|
+
Name of the terminal. The default is ``None``, in which case the
|
|
502
|
+
default name is assigned.
|
|
503
|
+
is_ref : bool, optional
|
|
504
|
+
Whether it is a reference terminal. The default is ``False``.
|
|
505
|
+
|
|
506
|
+
Returns
|
|
507
|
+
-------
|
|
508
|
+
Edb.Cell.Terminal.EdgeTerminal
|
|
509
|
+
"""
|
|
510
|
+
if not name:
|
|
511
|
+
pin_name = padstack_instance._edb_object.GetName()
|
|
512
|
+
refdes = padstack_instance.component.refdes
|
|
513
|
+
name = "{}_{}".format(refdes, pin_name)
|
|
514
|
+
name = generate_unique_name(name)
|
|
515
|
+
|
|
516
|
+
if not layer:
|
|
517
|
+
layer = padstack_instance.start_layer
|
|
518
|
+
|
|
519
|
+
layer_obj = self._pedb.stackup.signal_layers[layer]
|
|
520
|
+
|
|
521
|
+
terminal = self._edb.cell.terminal.PadstackInstanceTerminal.Create(
|
|
522
|
+
self._pedb.active_layout,
|
|
523
|
+
self.net.net_object,
|
|
524
|
+
name,
|
|
525
|
+
padstack_instance._edb_object,
|
|
526
|
+
layer_obj._edb_layer,
|
|
527
|
+
isRef=is_ref,
|
|
528
|
+
)
|
|
529
|
+
terminal = PadstackInstanceTerminal(self._pedb, terminal)
|
|
530
|
+
|
|
531
|
+
return terminal if not terminal.is_null else False
|
|
532
|
+
|
|
533
|
+
|
|
534
|
+
class PointTerminal(Terminal):
|
|
535
|
+
"""Manages point terminal properties."""
|
|
536
|
+
|
|
537
|
+
def __init__(self, pedb, edb_object=None):
|
|
538
|
+
super().__init__(pedb, edb_object)
|
|
539
|
+
|
|
540
|
+
@pyedb_function_handler
|
|
541
|
+
def create(self, name, net, location, layer, is_ref=False):
|
|
542
|
+
"""Create a point terminal.
|
|
543
|
+
|
|
544
|
+
Parameters
|
|
545
|
+
----------
|
|
546
|
+
name : str
|
|
547
|
+
Name of the terminal.
|
|
548
|
+
net : str
|
|
549
|
+
Name of the net.
|
|
550
|
+
location : list
|
|
551
|
+
Location of the terminal.
|
|
552
|
+
layer : str
|
|
553
|
+
Name of the layer.
|
|
554
|
+
is_ref : bool, optional
|
|
555
|
+
Whether it is a reference terminal.
|
|
556
|
+
|
|
557
|
+
Returns
|
|
558
|
+
-------
|
|
559
|
+
:class:`pyedb.dotnet.edb_core.edb_data.terminals.PointTerminal`
|
|
560
|
+
"""
|
|
561
|
+
terminal = self._pedb.edb_api.cell.terminal.PointTerminal.Create(
|
|
562
|
+
self._pedb.active_layout,
|
|
563
|
+
self._pedb.nets[net].net_object,
|
|
564
|
+
name,
|
|
565
|
+
self._pedb.point_data(*location),
|
|
566
|
+
self._pedb.stackup[layer]._edb_layer,
|
|
567
|
+
is_ref,
|
|
568
|
+
)
|
|
569
|
+
terminal = PointTerminal(self._pedb, terminal)
|
|
570
|
+
return terminal if not terminal.is_null else False
|
|
571
|
+
|
|
572
|
+
@property
|
|
573
|
+
def location(self):
|
|
574
|
+
"""Location of the terminal."""
|
|
575
|
+
layer = list(self._pedb.stackup.layers.values())[0]._edb_layer
|
|
576
|
+
_, point_data, _ = self._edb_object.GetParameters(None, layer)
|
|
577
|
+
return [point_data.X.ToDouble(), point_data.Y.ToDouble()]
|
|
578
|
+
|
|
579
|
+
@location.setter
|
|
580
|
+
def location(self, value):
|
|
581
|
+
layer = self.layer
|
|
582
|
+
self._edb_object.SetParameters(self._pedb.point_data(*value), layer)
|
|
583
|
+
|
|
584
|
+
@property
|
|
585
|
+
def layer(self):
|
|
586
|
+
"""Get layer of the terminal."""
|
|
587
|
+
point_data = self._pedb.point_data(0, 0)
|
|
588
|
+
layer = list(self._pedb.stackup.layers.values())[0]._edb_layer
|
|
589
|
+
if self._edb_object.GetParameters(point_data, layer):
|
|
590
|
+
return layer
|
|
591
|
+
|
|
592
|
+
@layer.setter
|
|
593
|
+
def layer(self, value):
|
|
594
|
+
layer = self._pedb.stackup.layers[value]._edb_layer
|
|
595
|
+
point_data = self._pedb.point_data(*self.location)
|
|
596
|
+
self._edb_object.SetParameters(point_data, layer)
|
|
597
|
+
|
|
598
|
+
|
|
599
|
+
class PinGroupTerminal(Terminal):
|
|
600
|
+
"""Manages pin group terminal properties."""
|
|
601
|
+
|
|
602
|
+
def __init__(self, pedb, edb_object=None):
|
|
603
|
+
super().__init__(pedb, edb_object)
|
|
604
|
+
|
|
605
|
+
@pyedb_function_handler
|
|
606
|
+
def create(self, name, net_name, pin_group_name, is_ref=False):
|
|
607
|
+
"""Create a pin group terminal.
|
|
608
|
+
|
|
609
|
+
Parameters
|
|
610
|
+
----------
|
|
611
|
+
name : str
|
|
612
|
+
Name of the terminal.
|
|
613
|
+
net_name : str
|
|
614
|
+
Name of the net.
|
|
615
|
+
pin_group_name : str,
|
|
616
|
+
Name of the pin group.
|
|
617
|
+
is_ref : bool, optional
|
|
618
|
+
Whether it is a reference terminal. The default is ``False``.
|
|
619
|
+
|
|
620
|
+
Returns
|
|
621
|
+
-------
|
|
622
|
+
:class:`pyedb.dotnet.edb_core.edb_data.terminals.PinGroupTerminal`
|
|
623
|
+
"""
|
|
624
|
+
term = self._pedb.edb_api.cell.terminal.PinGroupTerminal.Create(
|
|
625
|
+
self._pedb.active_layout,
|
|
626
|
+
self._pedb.nets[net_name].net_object,
|
|
627
|
+
name,
|
|
628
|
+
self._pedb.siwave.pin_groups[pin_group_name]._edb_object,
|
|
629
|
+
is_ref,
|
|
630
|
+
)
|
|
631
|
+
term = PinGroupTerminal(self._pedb, term)
|
|
632
|
+
return term if not term.is_null else False
|