pyedb 0.54.0__py3-none-any.whl → 0.56.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 -8
- pyedb/configuration/cfg_boundaries.py +69 -151
- pyedb/configuration/cfg_components.py +201 -460
- pyedb/configuration/cfg_data.py +4 -2
- pyedb/configuration/cfg_general.py +13 -36
- pyedb/configuration/cfg_modeler.py +2 -1
- pyedb/configuration/cfg_nets.py +21 -35
- pyedb/configuration/cfg_operations.py +22 -151
- pyedb/configuration/cfg_package_definition.py +56 -112
- pyedb/configuration/cfg_padstacks.py +292 -688
- pyedb/configuration/cfg_pin_groups.py +32 -79
- pyedb/configuration/cfg_ports_sources.py +19 -6
- pyedb/configuration/cfg_s_parameter_models.py +67 -172
- pyedb/configuration/cfg_setup.py +102 -295
- pyedb/configuration/configuration.py +64 -5
- pyedb/dotnet/database/Variables.py +26 -19
- pyedb/dotnet/database/cell/connectable.py +38 -9
- pyedb/dotnet/database/cell/hierarchy/component.py +28 -28
- pyedb/dotnet/database/cell/hierarchy/model.py +1 -1
- pyedb/dotnet/database/cell/layout.py +63 -2
- pyedb/dotnet/database/cell/layout_obj.py +2 -2
- pyedb/dotnet/database/cell/primitive/path.py +6 -8
- pyedb/dotnet/database/cell/primitive/primitive.py +3 -24
- pyedb/dotnet/database/cell/terminal/edge_terminal.py +2 -2
- pyedb/dotnet/database/cell/terminal/padstack_instance_terminal.py +1 -1
- pyedb/dotnet/database/cell/terminal/pingroup_terminal.py +1 -1
- pyedb/dotnet/database/cell/terminal/point_terminal.py +1 -1
- pyedb/dotnet/database/cell/terminal/terminal.py +24 -24
- pyedb/dotnet/database/cell/voltage_regulator.py +0 -21
- pyedb/dotnet/database/components.py +137 -124
- pyedb/dotnet/database/definition/component_def.py +4 -4
- pyedb/dotnet/database/definition/component_model.py +1 -1
- pyedb/dotnet/database/definition/package_def.py +2 -3
- pyedb/dotnet/database/dotnet/database.py +3 -199
- pyedb/dotnet/database/dotnet/primitive.py +3 -3
- pyedb/dotnet/database/edb_data/control_file.py +5 -5
- pyedb/dotnet/database/edb_data/hfss_extent_info.py +6 -6
- pyedb/dotnet/database/edb_data/layer_data.py +23 -23
- pyedb/dotnet/database/edb_data/padstacks_data.py +63 -88
- pyedb/dotnet/database/edb_data/primitives_data.py +5 -5
- pyedb/dotnet/database/edb_data/sources.py +6 -6
- pyedb/dotnet/database/edb_data/variables.py +1 -1
- pyedb/dotnet/database/geometry/point_data.py +14 -10
- pyedb/dotnet/database/geometry/polygon_data.py +3 -3
- pyedb/dotnet/database/hfss.py +46 -48
- pyedb/dotnet/database/layout_validation.py +14 -11
- pyedb/dotnet/database/materials.py +10 -11
- pyedb/dotnet/database/modeler.py +97 -91
- pyedb/dotnet/database/nets.py +19 -22
- pyedb/dotnet/database/padstack.py +171 -83
- pyedb/dotnet/database/siwave.py +42 -42
- pyedb/dotnet/database/stackup.py +140 -72
- pyedb/dotnet/database/utilities/heatsink.py +4 -4
- pyedb/dotnet/database/utilities/obj_base.py +2 -2
- pyedb/dotnet/database/utilities/simulation_setup.py +2 -2
- pyedb/dotnet/database/utilities/value.py +16 -16
- pyedb/dotnet/edb.py +230 -152
- pyedb/edb_logger.py +12 -27
- pyedb/extensions/create_cell_array.py +394 -0
- pyedb/extensions/via_design_backend.py +6 -3
- pyedb/generic/data_handlers.py +6 -7
- pyedb/generic/design_types.py +81 -30
- pyedb/generic/filesystem.py +5 -2
- pyedb/generic/general_methods.py +2 -122
- pyedb/generic/process.py +44 -108
- pyedb/generic/settings.py +79 -19
- pyedb/grpc/database/components.py +26 -4
- pyedb/grpc/database/control_file.py +5 -5
- pyedb/grpc/database/definition/materials.py +1 -1
- pyedb/grpc/database/definition/package_def.py +3 -3
- pyedb/grpc/database/definition/padstack_def.py +53 -0
- pyedb/grpc/database/geometry/polygon_data.py +1 -1
- pyedb/grpc/database/layout/layout.py +81 -5
- pyedb/grpc/database/layout_validation.py +5 -5
- pyedb/grpc/database/modeler.py +24 -16
- pyedb/grpc/database/net/net.py +15 -14
- pyedb/grpc/database/nets.py +70 -0
- pyedb/grpc/database/padstacks.py +122 -17
- pyedb/grpc/database/primitive/padstack_instance.py +175 -7
- pyedb/grpc/database/primitive/polygon.py +2 -2
- pyedb/grpc/database/simulation_setup/siwave_cpa_simulation_setup.py +3 -2
- pyedb/grpc/database/siwave.py +1 -1
- pyedb/grpc/database/source_excitations.py +12 -5
- pyedb/grpc/database/stackup.py +1 -1
- pyedb/grpc/database/terminal/bundle_terminal.py +1 -1
- pyedb/grpc/database/terminal/padstack_instance_terminal.py +1 -1
- pyedb/grpc/database/terminal/pingroup_terminal.py +1 -1
- pyedb/grpc/database/utility/value.py +1 -0
- pyedb/grpc/database/utility/xml_control_file.py +5 -5
- pyedb/grpc/edb.py +80 -30
- pyedb/grpc/edb_init.py +3 -3
- pyedb/grpc/rpc_session.py +14 -13
- pyedb/libraries/common.py +366 -0
- pyedb/libraries/rf_libraries/base_functions.py +1358 -0
- pyedb/libraries/rf_libraries/planar_antennas.py +628 -0
- pyedb/misc/decorators.py +61 -0
- pyedb/misc/misc.py +0 -13
- pyedb/modeler/geometry_operators.py +6 -6
- pyedb/siwave.py +6 -8
- pyedb/siwave_core/__init__.py +0 -0
- pyedb/siwave_core/cpa/__init__.py +0 -0
- {pyedb-0.54.0.dist-info → pyedb-0.56.0.dist-info}/METADATA +1 -2
- {pyedb-0.54.0.dist-info → pyedb-0.56.0.dist-info}/RECORD +105 -98
- {pyedb-0.54.0.dist-info → pyedb-0.56.0.dist-info}/WHEEL +0 -0
- {pyedb-0.54.0.dist-info → pyedb-0.56.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -19,7 +19,6 @@
|
|
|
19
19
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
20
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
21
|
# SOFTWARE.
|
|
22
|
-
import os
|
|
23
22
|
|
|
24
23
|
from pyedb.configuration.cfg_common import CfgBase
|
|
25
24
|
from pyedb.dotnet.database.general import (
|
|
@@ -33,20 +32,20 @@ class CfgPadstacks:
|
|
|
33
32
|
"""Padstack data class."""
|
|
34
33
|
|
|
35
34
|
def __init__(self, pedb, padstack_dict=None):
|
|
36
|
-
self.
|
|
35
|
+
self._pedb = pedb
|
|
37
36
|
self.definitions = []
|
|
38
37
|
self.instances = []
|
|
39
38
|
|
|
40
39
|
if padstack_dict:
|
|
41
|
-
padstack_defs_layout = self.
|
|
40
|
+
padstack_defs_layout = self._pedb.padstacks.definitions
|
|
42
41
|
for pdef in padstack_dict.get("definitions", []):
|
|
43
42
|
obj = padstack_defs_layout[pdef["name"]]
|
|
44
|
-
self.definitions.append(CfgPadstackDefinition(self.
|
|
43
|
+
self.definitions.append(CfgPadstackDefinition(self._pedb, obj, **pdef))
|
|
45
44
|
|
|
46
|
-
inst_from_layout = self.
|
|
45
|
+
inst_from_layout = self._pedb.padstacks.instances_by_name
|
|
47
46
|
for inst in padstack_dict.get("instances", []):
|
|
48
47
|
obj = inst_from_layout[inst["name"]]
|
|
49
|
-
self.instances.append(CfgPadstackInstance(self.
|
|
48
|
+
self.instances.append(CfgPadstackInstance(self._pedb, obj, **inst))
|
|
50
49
|
|
|
51
50
|
def clean(self):
|
|
52
51
|
self.definitions = []
|
|
@@ -56,562 +55,277 @@ class CfgPadstacks:
|
|
|
56
55
|
"""Apply padstack definition and instances on layout."""
|
|
57
56
|
if self.definitions:
|
|
58
57
|
for pdef in self.definitions:
|
|
59
|
-
pdef.
|
|
58
|
+
pdef.set_parameters_to_edb()
|
|
60
59
|
if self.instances:
|
|
61
60
|
for inst in self.instances:
|
|
62
|
-
inst.
|
|
61
|
+
inst.set_parameters_to_edb()
|
|
63
62
|
|
|
64
63
|
def retrieve_parameters_from_edb(self):
|
|
65
64
|
self.clean()
|
|
66
|
-
for name, obj in self.
|
|
65
|
+
for name, obj in self._pedb.padstacks.definitions.items():
|
|
67
66
|
if name.lower() == "symbol":
|
|
68
67
|
continue
|
|
69
|
-
pdef = CfgPadstackDefinition(self.
|
|
70
|
-
pdef.
|
|
68
|
+
pdef = CfgPadstackDefinition(self._pedb, obj)
|
|
69
|
+
pdef.retrieve_parameters_from_edb()
|
|
71
70
|
self.definitions.append(pdef)
|
|
72
71
|
|
|
73
|
-
for obj in self.
|
|
74
|
-
inst = CfgPadstackInstance(self.
|
|
75
|
-
inst.
|
|
72
|
+
for obj in self._pedb.layout.padstack_instances:
|
|
73
|
+
inst = CfgPadstackInstance(self._pedb, obj)
|
|
74
|
+
inst.retrieve_parameters_from_edb()
|
|
76
75
|
self.instances.append(inst)
|
|
77
76
|
|
|
78
77
|
|
|
79
78
|
class CfgPadstackDefinition(CfgBase):
|
|
80
79
|
"""Padstack definition data class."""
|
|
81
80
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
81
|
+
PAD_SHAPE_PARAMETERS = {
|
|
82
|
+
"circle": ["diameter"],
|
|
83
|
+
"square": ["size"],
|
|
84
|
+
"rectangle": ["x_size", "y_size"],
|
|
85
|
+
"oval": ["x_size", "y_size", "corner_radius"],
|
|
86
|
+
"bullet": ["x_size", "y_size", "corner_radius"],
|
|
87
|
+
"round45": ["inner", "channel_width", "isolation_gap"],
|
|
88
|
+
"round90": ["inner", "channel_width", "isolation_gap"],
|
|
89
|
+
"no_geometry": [],
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
def get_solder_ball_definition(self):
|
|
93
|
+
definition = self._pedb._edb.Definition
|
|
94
|
+
self._solder_shape_type = {
|
|
95
|
+
"no_solder_ball": definition.SolderballShape.NoSolderball,
|
|
96
|
+
"cylinder": definition.SolderballShape.Cylinder,
|
|
97
|
+
"spheroid": definition.SolderballShape.Spheroid,
|
|
98
|
+
}
|
|
99
|
+
self._solder_placement = {
|
|
100
|
+
"above_padstack": definition.SolderballPlacement.AbovePadstack,
|
|
101
|
+
"below_padstack": definition.SolderballPlacement.BelowPadstack,
|
|
92
102
|
}
|
|
93
103
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
104
|
+
def set_hole_parameters_to_edb(self, params):
|
|
105
|
+
original_params = self.hole_parameters
|
|
106
|
+
pdef_data = self.pyedb_obj._padstack_def_data
|
|
107
|
+
|
|
108
|
+
temp_param = []
|
|
109
|
+
shape = params["shape"]
|
|
110
|
+
if shape == "no_geometry":
|
|
111
|
+
return # .net api doesn't tell how to set no_geometry shape.
|
|
112
|
+
for i in self.PAD_SHAPE_PARAMETERS[shape]:
|
|
113
|
+
temp_param.append(params[i])
|
|
114
|
+
pedb_shape = getattr(self._pedb._edb.Definition.PadGeometryType, snake_to_pascal(shape))
|
|
115
|
+
|
|
116
|
+
pdef_data.SetHoleParameters(
|
|
117
|
+
pedb_shape,
|
|
118
|
+
convert_py_list_to_net_list([self._pedb.edb_value(i) for i in temp_param]),
|
|
119
|
+
self._pedb.edb_value(params.get("offset_x", original_params.get("offset_x", 0))),
|
|
120
|
+
self._pedb.edb_value(params.get("offset_y", original_params.get("offset_y", 0))),
|
|
121
|
+
self._pedb.edb_value(params.get("rotation", original_params.get("rotation", 0))),
|
|
122
|
+
)
|
|
123
|
+
self.pyedb_obj._padstack_def_data = pdef_data
|
|
124
|
+
|
|
125
|
+
def set_solder_parameters_to_edb(self, parameters):
|
|
126
|
+
pdef_data = self.pyedb_obj._padstack_def_data
|
|
127
|
+
|
|
128
|
+
shape = parameters.get("shape", "no_solder_ball")
|
|
129
|
+
diameter = parameters.get("diameter", "0.4mm")
|
|
130
|
+
mid_diameter = parameters.get("mid_diameter", diameter)
|
|
131
|
+
placement = parameters.get("placement", "above_padstack")
|
|
132
|
+
material = parameters.get("material", None)
|
|
133
|
+
|
|
134
|
+
pdef_data.SetSolderBallShape(self._solder_shape_type[shape])
|
|
135
|
+
if not shape == "no_solder_ball":
|
|
136
|
+
pdef_data.SetSolderBallParameter(self._pedb.edb_value(diameter), self._pedb.edb_value(mid_diameter))
|
|
137
|
+
pdef_data.SetSolderBallPlacement(self._solder_placement[placement])
|
|
138
|
+
|
|
139
|
+
if material:
|
|
140
|
+
pdef_data.SetSolderBallMaterial(material)
|
|
141
|
+
self.pyedb_obj._padstack_def_data = pdef_data
|
|
142
|
+
|
|
143
|
+
def get_solder_parameters_from_edb(self):
|
|
144
|
+
pdef_data = self.pyedb_obj._padstack_def_data
|
|
145
|
+
shape = pdef_data.GetSolderBallShape()
|
|
146
|
+
_, diameter, mid_diameter = pdef_data.GetSolderBallParameterValue()
|
|
147
|
+
placement = pdef_data.GetSolderBallPlacement()
|
|
148
|
+
material = pdef_data.GetSolderBallMaterial()
|
|
149
|
+
|
|
150
|
+
parameters = {
|
|
151
|
+
"shape": [i for i, j in self._solder_shape_type.items() if j == shape][0],
|
|
152
|
+
"diameter": self._pedb.edb_value(diameter).ToString(),
|
|
153
|
+
"mid_diameter": self._pedb.edb_value(mid_diameter).ToString(),
|
|
154
|
+
"placement": [i for i, j in self._solder_placement.items() if j == placement][0],
|
|
155
|
+
"material": material,
|
|
156
|
+
}
|
|
157
|
+
return parameters
|
|
158
|
+
|
|
159
|
+
def get_pad_parameters_from_edb(self):
|
|
160
|
+
"""Pad parameters.
|
|
161
|
+
|
|
162
|
+
Returns
|
|
163
|
+
-------
|
|
164
|
+
dict
|
|
165
|
+
params = {
|
|
166
|
+
'regular_pad': [
|
|
167
|
+
{'layer_name': '1_Top', 'shape': 'circle', 'offset_x': '0.1mm', 'offset_y': '0',
|
|
168
|
+
'rotation': '0', 'diameter': '0.5mm'}
|
|
169
|
+
],
|
|
170
|
+
'anti_pad': [
|
|
171
|
+
{'layer_name': '1_Top', 'shape': 'circle', 'offset_x': '0', 'offset_y': '0', 'rotation': '0',
|
|
172
|
+
'diameter': '1mm'}
|
|
173
|
+
],
|
|
174
|
+
'thermal_pad': [
|
|
175
|
+
{'layer_name': '1_Top', 'shape': 'round90', 'offset_x': '0', 'offset_y': '0', 'rotation': '0',
|
|
176
|
+
'inner': '1mm', 'channel_width': '0.2mm', 'isolation_gap': '0.3mm'},
|
|
177
|
+
],
|
|
178
|
+
'hole': [
|
|
179
|
+
{'layer_name': '1_Top', 'shape': 'circle', 'offset_x': '0', 'offset_y': '0', 'rotation': '0',
|
|
180
|
+
'diameter': '0.1499997mm'},
|
|
181
|
+
]
|
|
182
|
+
}
|
|
183
|
+
"""
|
|
184
|
+
pdef_data = self.pyedb_obj._padstack_def_data
|
|
185
|
+
pad_type_list = [
|
|
186
|
+
self._pedb._edb.Definition.PadType.RegularPad,
|
|
187
|
+
self._pedb._edb.Definition.PadType.AntiPad,
|
|
188
|
+
self._pedb._edb.Definition.PadType.ThermalPad,
|
|
189
|
+
# self._ppadstack._pedb._edb.Definition.PadType.Hole,
|
|
190
|
+
# This property doesn't appear in UI. It is unclear what it is used for.
|
|
191
|
+
# Suppressing this property for now.
|
|
192
|
+
]
|
|
193
|
+
data = {}
|
|
194
|
+
for pad_type in pad_type_list:
|
|
195
|
+
pad_type_name = pascal_to_snake(pad_type.ToString())
|
|
196
|
+
temp_list = []
|
|
197
|
+
for lyr_name in list(pdef_data.GetLayerNames()):
|
|
198
|
+
result = pdef_data.GetPadParametersValue(lyr_name, pad_type)
|
|
199
|
+
_, pad_shape, params, offset_x, offset_y, rotation = result
|
|
200
|
+
pad_shape = pascal_to_snake(pad_shape.ToString())
|
|
201
|
+
|
|
202
|
+
pad_params = {}
|
|
203
|
+
pad_params["layer_name"] = lyr_name
|
|
204
|
+
pad_params["shape"] = pad_shape
|
|
205
|
+
pad_params["offset_x"] = offset_x.ToString()
|
|
206
|
+
pad_params["offset_y"] = offset_y.ToString()
|
|
207
|
+
pad_params["rotation"] = rotation.ToString()
|
|
208
|
+
|
|
209
|
+
for idx, i in enumerate(self.PAD_SHAPE_PARAMETERS[pad_shape]):
|
|
210
|
+
pad_params[i] = params[idx].ToString()
|
|
211
|
+
temp_list.append(pad_params)
|
|
212
|
+
data[pad_type_name] = temp_list
|
|
213
|
+
return data
|
|
214
|
+
|
|
215
|
+
def set_pad_parameters_to_edb(self, param):
|
|
216
|
+
pdef_data = self.pyedb_obj._padstack_def_data
|
|
217
|
+
|
|
218
|
+
pad_type_list = [
|
|
219
|
+
self._pedb._edb.Definition.PadType.RegularPad,
|
|
220
|
+
self._pedb._edb.Definition.PadType.AntiPad,
|
|
221
|
+
self._pedb._edb.Definition.PadType.ThermalPad,
|
|
222
|
+
self._pedb._edb.Definition.PadType.Hole,
|
|
223
|
+
]
|
|
224
|
+
for pad_type in pad_type_list:
|
|
225
|
+
pad_type_name = pascal_to_snake(pad_type.ToString())
|
|
226
|
+
rpp = param.get(pad_type_name, [])
|
|
227
|
+
for idx, layer_data in enumerate(rpp):
|
|
228
|
+
# Get geometry type from kwargs
|
|
229
|
+
p = layer_data.get("shape")
|
|
139
230
|
temp_param = []
|
|
140
|
-
shape = params["shape"]
|
|
141
|
-
for idx, i in enumerate(self.parent.PAD_SHAPE_PARAMETERS[shape]):
|
|
142
|
-
temp_param.append(params[i])
|
|
143
|
-
|
|
144
|
-
pdef_data.set_hole_parameters(
|
|
145
|
-
offset_x=GrpcValue(params.get("offset_x", original_params.get("offset_x", 0))),
|
|
146
|
-
offset_y=GrpcValue(params.get("offset_y", original_params.get("offset_y", 0))),
|
|
147
|
-
rotation=GrpcValue(params.get("rotation", original_params.get("rotation", 0))),
|
|
148
|
-
type_geom=pad_geometry_type[shape],
|
|
149
|
-
sizes=[GrpcValue(i) for i in temp_param],
|
|
150
|
-
)
|
|
151
|
-
self.parent.pyedb_obj.data = pdef_data
|
|
152
|
-
|
|
153
|
-
def set_solder_parameters_to_edb(self, parameters):
|
|
154
|
-
from ansys.edb.core.utility.value import Value as GrpcValue
|
|
155
|
-
|
|
156
|
-
pdef_data = self.parent.pyedb_obj.data
|
|
157
|
-
|
|
158
|
-
shape = parameters.get("shape", "no_solder_ball")
|
|
159
|
-
diameter = parameters.get("diameter", "0.4mm")
|
|
160
|
-
mid_diameter = parameters.get("mid_diameter", diameter)
|
|
161
|
-
placement = parameters.get("placement", "above_padstack")
|
|
162
|
-
material = parameters.get("material", None)
|
|
163
|
-
|
|
164
|
-
pdef_data.solder_ball_shape = self.parent._solder_shape_type[shape]
|
|
165
|
-
if not shape == "no_solder_ball":
|
|
166
|
-
pdef_data.solder_ball_param = (GrpcValue(diameter), GrpcValue(mid_diameter))
|
|
167
|
-
pdef_data.solder_ball_placement = self.parent._solder_placement[placement]
|
|
168
231
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
"
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
]
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
]
|
|
220
|
-
}
|
|
221
|
-
"""
|
|
222
|
-
from ansys.edb.core.definition.padstack_def_data import (
|
|
223
|
-
PadType as GrpcPadType,
|
|
224
|
-
)
|
|
225
|
-
|
|
226
|
-
pdef_data = self.parent.pyedb_obj.data
|
|
227
|
-
pad_type_list = [GrpcPadType.REGULAR_PAD, GrpcPadType.ANTI_PAD, GrpcPadType.THERMAL_PAD]
|
|
228
|
-
data = {}
|
|
229
|
-
for pad_type in pad_type_list:
|
|
230
|
-
pad_type_name = pad_type.name.lower()
|
|
231
|
-
temp_list = []
|
|
232
|
-
for lyr_name in pdef_data.layer_names:
|
|
233
|
-
try:
|
|
234
|
-
result = pdef_data.get_pad_parameters(lyr_name, pad_type)
|
|
235
|
-
if len(result) == 4:
|
|
236
|
-
# polygon based pad
|
|
237
|
-
pass
|
|
238
|
-
elif len(result) == 5:
|
|
239
|
-
pad_shape, params, offset_x, offset_y, rotation = result
|
|
240
|
-
pad_shape = pad_shape.name.lower().split("_")[-1]
|
|
241
|
-
pad_params = {
|
|
242
|
-
"layer_name": lyr_name,
|
|
243
|
-
"shape": pad_shape,
|
|
244
|
-
"offset_x": str(offset_x),
|
|
245
|
-
"offset_y": str(offset_y),
|
|
246
|
-
"rotation": str(rotation),
|
|
247
|
-
}
|
|
248
|
-
for idx, i in enumerate(self.parent.PAD_SHAPE_PARAMETERS[pad_shape]):
|
|
249
|
-
pad_params[i] = str(params[idx])
|
|
250
|
-
temp_list.append(pad_params)
|
|
251
|
-
except:
|
|
252
|
-
pass
|
|
253
|
-
data[pad_type_name] = temp_list
|
|
254
|
-
return data
|
|
255
|
-
|
|
256
|
-
def set_pad_parameters_to_edb(self, param):
|
|
257
|
-
from ansys.edb.core.definition.padstack_def_data import (
|
|
258
|
-
PadGeometryType as GrpcPadGeometryType,
|
|
259
|
-
)
|
|
260
|
-
from ansys.edb.core.definition.padstack_def_data import (
|
|
261
|
-
PadType as GrpcPadType,
|
|
262
|
-
)
|
|
263
|
-
from ansys.edb.core.utility.value import Value as GrpcValue
|
|
264
|
-
|
|
265
|
-
pdef_data = self.parent.pyedb_obj.data
|
|
266
|
-
|
|
267
|
-
pad_type_list = [GrpcPadType.REGULAR_PAD, GrpcPadType.ANTI_PAD, GrpcPadType.THERMAL_PAD]
|
|
268
|
-
for pad_type in pad_type_list:
|
|
269
|
-
pad_type_name = pad_type.name.lower()
|
|
270
|
-
rpp = param.get(pad_type_name, [])
|
|
271
|
-
for idx, layer_data in enumerate(rpp):
|
|
272
|
-
# Get geometry type from kwargs
|
|
273
|
-
p = layer_data.get("shape")
|
|
274
|
-
temp_param = []
|
|
275
|
-
pad_shape = None
|
|
276
|
-
# Handle Circle geometry type
|
|
277
|
-
if p == "circle":
|
|
278
|
-
temp_param.append(layer_data["diameter"])
|
|
279
|
-
pad_shape = GrpcPadGeometryType.PADGEOMTYPE_CIRCLE
|
|
280
|
-
|
|
281
|
-
# Handle Square geometry type
|
|
282
|
-
elif p == "square":
|
|
283
|
-
temp_param.append(layer_data["size"])
|
|
284
|
-
pad_shape = GrpcPadGeometryType.PADGEOMTYPE_SQUARE
|
|
285
|
-
|
|
286
|
-
elif p == "rectangle":
|
|
287
|
-
temp_param.append(layer_data["x_size"])
|
|
288
|
-
temp_param.append(layer_data["y_size"])
|
|
289
|
-
pad_shape = GrpcPadGeometryType.PADGEOMTYPE_RECTANGLE
|
|
290
|
-
|
|
291
|
-
# Handle Oval geometry type
|
|
292
|
-
elif p == "oval":
|
|
293
|
-
temp_param.append(layer_data["x_size"])
|
|
294
|
-
temp_param.append(layer_data["y_size"])
|
|
295
|
-
temp_param.append(layer_data["corner_radius"])
|
|
296
|
-
pad_shape = GrpcPadGeometryType.PADGEOMTYPE_OVAL
|
|
297
|
-
|
|
298
|
-
# Handle Bullet geometry type
|
|
299
|
-
elif p == "bullet":
|
|
300
|
-
temp_param.append(layer_data["x_size"])
|
|
301
|
-
temp_param.append(layer_data["y_size"])
|
|
302
|
-
temp_param.append(layer_data["corner_radius"])
|
|
303
|
-
pad_shape = GrpcPadGeometryType.PADGEOMTYPE_BULLET
|
|
304
|
-
|
|
305
|
-
# Handle Round45 geometry type
|
|
306
|
-
elif p == "round45":
|
|
307
|
-
temp_param.append(layer_data["inner"])
|
|
308
|
-
temp_param.append(layer_data["channel_width"])
|
|
309
|
-
temp_param.append(layer_data["isolation_gap"])
|
|
310
|
-
pad_shape = GrpcPadGeometryType.PADGEOMTYPE_ROUND45
|
|
311
|
-
|
|
312
|
-
# Handle Round90 geometry type
|
|
313
|
-
elif p == "round90":
|
|
314
|
-
temp_param.append(layer_data["inner"])
|
|
315
|
-
temp_param.append(layer_data["channel_width"])
|
|
316
|
-
temp_param.append(layer_data["isolation_gap"])
|
|
317
|
-
pad_shape = GrpcPadGeometryType.PADGEOMTYPE_ROUND90
|
|
318
|
-
elif p == "no_geometry":
|
|
319
|
-
continue
|
|
320
|
-
|
|
321
|
-
# Set pad parameters for the current layer
|
|
322
|
-
if pad_shape:
|
|
323
|
-
pdef_data.set_pad_parameters(
|
|
324
|
-
layer=layer_data["layer_name"],
|
|
325
|
-
pad_type=pad_type,
|
|
326
|
-
offset_x=GrpcValue(layer_data.get("offset_x", 0)),
|
|
327
|
-
offset_y=GrpcValue(layer_data.get("offset_y", 0)),
|
|
328
|
-
rotation=GrpcValue(layer_data.get("rotation", 0)),
|
|
329
|
-
type_geom=pad_shape,
|
|
330
|
-
sizes=[GrpcValue(i) for i in temp_param],
|
|
331
|
-
)
|
|
332
|
-
self.parent.pyedb_obj.data = pdef_data
|
|
333
|
-
|
|
334
|
-
def get_hole_parameters_from_edb(self):
|
|
335
|
-
pdef_data = self.parent.pyedb_obj.data
|
|
336
|
-
try:
|
|
337
|
-
hole_shape, params, offset_x, offset_y, rotation = pdef_data.get_hole_parameters()
|
|
338
|
-
hole_shape = hole_shape.name.lower().split("_")[-1]
|
|
339
|
-
|
|
340
|
-
hole_params = {"shape": hole_shape}
|
|
341
|
-
for idx, i in enumerate(self.parent.PAD_SHAPE_PARAMETERS[hole_shape]):
|
|
342
|
-
hole_params[i] = str(params[idx])
|
|
343
|
-
hole_params["offset_x"] = str(offset_x)
|
|
344
|
-
hole_params["offset_y"] = str(offset_y)
|
|
345
|
-
hole_params["rotation"] = str(rotation)
|
|
346
|
-
return hole_params
|
|
347
|
-
except:
|
|
348
|
-
return None
|
|
349
|
-
|
|
350
|
-
class DotNet(Grpc):
|
|
351
|
-
def __init__(self, parent):
|
|
352
|
-
super().__init__(parent)
|
|
353
|
-
|
|
354
|
-
def get_solder_ball_definition(self):
|
|
355
|
-
definition = self._pedb._edb.Definition
|
|
356
|
-
self.parent._solder_shape_type = {
|
|
357
|
-
"no_solder_ball": definition.SolderballShape.NoSolderball,
|
|
358
|
-
"cylinder": definition.SolderballShape.Cylinder,
|
|
359
|
-
"spheroid": definition.SolderballShape.Spheroid,
|
|
360
|
-
}
|
|
361
|
-
self.parent._solder_placement = {
|
|
362
|
-
"above_padstack": definition.SolderballPlacement.AbovePadstack,
|
|
363
|
-
"below_padstack": definition.SolderballPlacement.BelowPadstack,
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
def set_hole_parameters_to_edb(self, params):
|
|
367
|
-
original_params = self.parent.parent.hole_parameters
|
|
368
|
-
pdef_data = self.parent.pyedb_obj._padstack_def_data
|
|
369
|
-
|
|
370
|
-
temp_param = []
|
|
371
|
-
shape = params["shape"]
|
|
372
|
-
if shape == "no_geometry":
|
|
373
|
-
return # .net api doesn't tell how to set no_geometry shape.
|
|
374
|
-
for idx, i in enumerate(self.parent.PAD_SHAPE_PARAMETERS[shape]):
|
|
375
|
-
temp_param.append(params[i])
|
|
376
|
-
pedb_shape = getattr(self._pedb._edb.Definition.PadGeometryType, snake_to_pascal(shape))
|
|
377
|
-
|
|
378
|
-
pdef_data.SetHoleParameters(
|
|
379
|
-
pedb_shape,
|
|
232
|
+
# Handle Circle geometry type
|
|
233
|
+
if p == pascal_to_snake(self._pedb._edb.Definition.PadGeometryType.Circle.ToString()):
|
|
234
|
+
temp_param.append(layer_data["diameter"])
|
|
235
|
+
pad_shape = self._pedb._edb.Definition.PadGeometryType.Circle
|
|
236
|
+
|
|
237
|
+
# Handle Square geometry type
|
|
238
|
+
elif p == pascal_to_snake(self._pedb._edb.Definition.PadGeometryType.Square.ToString()):
|
|
239
|
+
temp_param.append(layer_data["size"])
|
|
240
|
+
pad_shape = self._pedb._edb.Definition.PadGeometryType.Square
|
|
241
|
+
|
|
242
|
+
elif p == pascal_to_snake(self._pedb._edb.Definition.PadGeometryType.Rectangle.ToString()):
|
|
243
|
+
temp_param.append(layer_data["x_size"])
|
|
244
|
+
temp_param.append(layer_data["y_size"])
|
|
245
|
+
pad_shape = self._pedb._edb.Definition.PadGeometryType.Rectangle
|
|
246
|
+
|
|
247
|
+
# Handle Oval geometry type
|
|
248
|
+
elif p == pascal_to_snake(self._pedb._edb.Definition.PadGeometryType.Oval.ToString()):
|
|
249
|
+
temp_param.append(layer_data["x_size"])
|
|
250
|
+
temp_param.append(layer_data["y_size"])
|
|
251
|
+
temp_param.append(layer_data["corner_radius"])
|
|
252
|
+
pad_shape = self._pedb._edb.Definition.PadGeometryType.Oval
|
|
253
|
+
|
|
254
|
+
# Handle Bullet geometry type
|
|
255
|
+
elif p == pascal_to_snake(self._pedb._edb.Definition.PadGeometryType.Bullet.ToString()):
|
|
256
|
+
temp_param.append(layer_data["x_size"])
|
|
257
|
+
temp_param.append(layer_data["y_size"])
|
|
258
|
+
temp_param.append(layer_data["corner_radius"])
|
|
259
|
+
pad_shape = self._pedb._edb.Definition.PadGeometryType.Bullet
|
|
260
|
+
|
|
261
|
+
# Handle Round45 geometry type
|
|
262
|
+
elif p == pascal_to_snake(self._pedb._edb.Definition.PadGeometryType.Round45.ToString()):
|
|
263
|
+
temp_param.append(layer_data["inner"])
|
|
264
|
+
temp_param.append(layer_data["channel_width"])
|
|
265
|
+
temp_param.append(layer_data["isolation_gap"])
|
|
266
|
+
pad_shape = self._pedb._edb.Definition.PadGeometryType.Round45
|
|
267
|
+
|
|
268
|
+
# Handle Round90 geometry type
|
|
269
|
+
elif p == pascal_to_snake(self._pedb._edb.Definition.PadGeometryType.Round90.ToString()):
|
|
270
|
+
temp_param.append(layer_data["inner"])
|
|
271
|
+
temp_param.append(layer_data["channel_width"])
|
|
272
|
+
temp_param.append(layer_data["isolation_gap"])
|
|
273
|
+
pad_shape = self._pedb._edb.Definition.PadGeometryType.Round90
|
|
274
|
+
elif p == pascal_to_snake(self._pedb._edb.Definition.PadGeometryType.NoGeometry.ToString()):
|
|
275
|
+
continue
|
|
276
|
+
|
|
277
|
+
# Set pad parameters for the current layer
|
|
278
|
+
pdef_data.SetPadParameters(
|
|
279
|
+
layer_data["layer_name"],
|
|
280
|
+
pad_type,
|
|
281
|
+
pad_shape,
|
|
380
282
|
convert_py_list_to_net_list([self._pedb.edb_value(i) for i in temp_param]),
|
|
381
|
-
self._pedb.edb_value(
|
|
382
|
-
self._pedb.edb_value(
|
|
383
|
-
self._pedb.edb_value(
|
|
283
|
+
self._pedb.edb_value(layer_data.get("offset_x", 0)),
|
|
284
|
+
self._pedb.edb_value(layer_data.get("offset_y", 0)),
|
|
285
|
+
self._pedb.edb_value(layer_data.get("rotation", 0)),
|
|
384
286
|
)
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
Returns
|
|
425
|
-
-------
|
|
426
|
-
dict
|
|
427
|
-
params = {
|
|
428
|
-
'regular_pad': [
|
|
429
|
-
{'layer_name': '1_Top', 'shape': 'circle', 'offset_x': '0.1mm', 'offset_y': '0',
|
|
430
|
-
'rotation': '0', 'diameter': '0.5mm'}
|
|
431
|
-
],
|
|
432
|
-
'anti_pad': [
|
|
433
|
-
{'layer_name': '1_Top', 'shape': 'circle', 'offset_x': '0', 'offset_y': '0', 'rotation': '0',
|
|
434
|
-
'diameter': '1mm'}
|
|
435
|
-
],
|
|
436
|
-
'thermal_pad': [
|
|
437
|
-
{'layer_name': '1_Top', 'shape': 'round90', 'offset_x': '0', 'offset_y': '0', 'rotation': '0',
|
|
438
|
-
'inner': '1mm', 'channel_width': '0.2mm', 'isolation_gap': '0.3mm'},
|
|
439
|
-
],
|
|
440
|
-
'hole': [
|
|
441
|
-
{'layer_name': '1_Top', 'shape': 'circle', 'offset_x': '0', 'offset_y': '0', 'rotation': '0',
|
|
442
|
-
'diameter': '0.1499997mm'},
|
|
443
|
-
]
|
|
444
|
-
}
|
|
445
|
-
"""
|
|
446
|
-
pdef_data = self.parent.pyedb_obj._padstack_def_data
|
|
447
|
-
pad_type_list = [
|
|
448
|
-
self._pedb._edb.Definition.PadType.RegularPad,
|
|
449
|
-
self._pedb._edb.Definition.PadType.AntiPad,
|
|
450
|
-
self._pedb._edb.Definition.PadType.ThermalPad,
|
|
451
|
-
# self._ppadstack._pedb._edb.Definition.PadType.Hole,
|
|
452
|
-
# This property doesn't appear in UI. It is unclear what it is used for.
|
|
453
|
-
# Suppressing this property for now.
|
|
454
|
-
]
|
|
455
|
-
data = {}
|
|
456
|
-
for pad_type in pad_type_list:
|
|
457
|
-
pad_type_name = pascal_to_snake(pad_type.ToString())
|
|
458
|
-
temp_list = []
|
|
459
|
-
for lyr_name in list(pdef_data.GetLayerNames()):
|
|
460
|
-
result = pdef_data.GetPadParametersValue(lyr_name, pad_type)
|
|
461
|
-
_, pad_shape, params, offset_x, offset_y, rotation = result
|
|
462
|
-
pad_shape = pascal_to_snake(pad_shape.ToString())
|
|
463
|
-
|
|
464
|
-
pad_params = {}
|
|
465
|
-
pad_params["layer_name"] = lyr_name
|
|
466
|
-
pad_params["shape"] = pad_shape
|
|
467
|
-
pad_params["offset_x"] = offset_x.ToString()
|
|
468
|
-
pad_params["offset_y"] = offset_y.ToString()
|
|
469
|
-
pad_params["rotation"] = rotation.ToString()
|
|
470
|
-
|
|
471
|
-
for idx, i in enumerate(self.parent.PAD_SHAPE_PARAMETERS[pad_shape]):
|
|
472
|
-
pad_params[i] = params[idx].ToString()
|
|
473
|
-
temp_list.append(pad_params)
|
|
474
|
-
data[pad_type_name] = temp_list
|
|
475
|
-
return data
|
|
476
|
-
|
|
477
|
-
def set_pad_parameters_to_edb(self, param):
|
|
478
|
-
pdef_data = self.parent.pyedb_obj._padstack_def_data
|
|
479
|
-
|
|
480
|
-
pad_type_list = [
|
|
481
|
-
self._pedb._edb.Definition.PadType.RegularPad,
|
|
482
|
-
self._pedb._edb.Definition.PadType.AntiPad,
|
|
483
|
-
self._pedb._edb.Definition.PadType.ThermalPad,
|
|
484
|
-
self._pedb._edb.Definition.PadType.Hole,
|
|
485
|
-
]
|
|
486
|
-
for pad_type in pad_type_list:
|
|
487
|
-
pad_type_name = pascal_to_snake(pad_type.ToString())
|
|
488
|
-
rpp = param.get(pad_type_name, [])
|
|
489
|
-
for idx, layer_data in enumerate(rpp):
|
|
490
|
-
# Get geometry type from kwargs
|
|
491
|
-
p = layer_data.get("shape")
|
|
492
|
-
temp_param = []
|
|
493
|
-
|
|
494
|
-
# Handle Circle geometry type
|
|
495
|
-
if p == pascal_to_snake(self._pedb._edb.Definition.PadGeometryType.Circle.ToString()):
|
|
496
|
-
temp_param.append(layer_data["diameter"])
|
|
497
|
-
pad_shape = self._pedb._edb.Definition.PadGeometryType.Circle
|
|
498
|
-
|
|
499
|
-
# Handle Square geometry type
|
|
500
|
-
elif p == pascal_to_snake(self._pedb._edb.Definition.PadGeometryType.Square.ToString()):
|
|
501
|
-
temp_param.append(layer_data["size"])
|
|
502
|
-
pad_shape = self._pedb._edb.Definition.PadGeometryType.Square
|
|
503
|
-
|
|
504
|
-
elif p == pascal_to_snake(self._pedb._edb.Definition.PadGeometryType.Rectangle.ToString()):
|
|
505
|
-
temp_param.append(layer_data["x_size"])
|
|
506
|
-
temp_param.append(layer_data["y_size"])
|
|
507
|
-
pad_shape = self._pedb._edb.Definition.PadGeometryType.Rectangle
|
|
508
|
-
|
|
509
|
-
# Handle Oval geometry type
|
|
510
|
-
elif p == pascal_to_snake(self._pedb._edb.Definition.PadGeometryType.Oval.ToString()):
|
|
511
|
-
temp_param.append(layer_data["x_size"])
|
|
512
|
-
temp_param.append(layer_data["y_size"])
|
|
513
|
-
temp_param.append(layer_data["corner_radius"])
|
|
514
|
-
pad_shape = self._pedb._edb.Definition.PadGeometryType.Oval
|
|
515
|
-
|
|
516
|
-
# Handle Bullet geometry type
|
|
517
|
-
elif p == pascal_to_snake(self._pedb._edb.Definition.PadGeometryType.Bullet.ToString()):
|
|
518
|
-
temp_param.append(layer_data["x_size"])
|
|
519
|
-
temp_param.append(layer_data["y_size"])
|
|
520
|
-
temp_param.append(layer_data["corner_radius"])
|
|
521
|
-
pad_shape = self._pedb._edb.Definition.PadGeometryType.Bullet
|
|
522
|
-
|
|
523
|
-
# Handle Round45 geometry type
|
|
524
|
-
elif p == pascal_to_snake(self._pedb._edb.Definition.PadGeometryType.Round45.ToString()):
|
|
525
|
-
temp_param.append(layer_data["inner"])
|
|
526
|
-
temp_param.append(layer_data["channel_width"])
|
|
527
|
-
temp_param.append(layer_data["isolation_gap"])
|
|
528
|
-
pad_shape = self._pedb._edb.Definition.PadGeometryType.Round45
|
|
529
|
-
|
|
530
|
-
# Handle Round90 geometry type
|
|
531
|
-
elif p == pascal_to_snake(self._pedb._edb.Definition.PadGeometryType.Round90.ToString()):
|
|
532
|
-
temp_param.append(layer_data["inner"])
|
|
533
|
-
temp_param.append(layer_data["channel_width"])
|
|
534
|
-
temp_param.append(layer_data["isolation_gap"])
|
|
535
|
-
pad_shape = self._pedb._edb.Definition.PadGeometryType.Round90
|
|
536
|
-
elif p == pascal_to_snake(self._pedb._edb.Definition.PadGeometryType.NoGeometry.ToString()):
|
|
537
|
-
continue
|
|
538
|
-
|
|
539
|
-
# Set pad parameters for the current layer
|
|
540
|
-
pdef_data.SetPadParameters(
|
|
541
|
-
layer_data["layer_name"],
|
|
542
|
-
pad_type,
|
|
543
|
-
pad_shape,
|
|
544
|
-
convert_py_list_to_net_list([self._pedb.edb_value(i) for i in temp_param]),
|
|
545
|
-
self._pedb.edb_value(layer_data.get("offset_x", 0)),
|
|
546
|
-
self._pedb.edb_value(layer_data.get("offset_y", 0)),
|
|
547
|
-
self._pedb.edb_value(layer_data.get("rotation", 0)),
|
|
548
|
-
)
|
|
549
|
-
self.parent.pyedb_obj._padstack_def_data = pdef_data
|
|
550
|
-
|
|
551
|
-
def get_hole_parameters_from_edb(self):
|
|
552
|
-
pdef_data = self.parent.pyedb_obj._padstack_def_data
|
|
553
|
-
_, hole_shape, params, offset_x, offset_y, rotation = pdef_data.GetHoleParametersValue()
|
|
554
|
-
hole_shape = pascal_to_snake(hole_shape.ToString())
|
|
555
|
-
|
|
556
|
-
hole_params = {}
|
|
557
|
-
hole_params["shape"] = hole_shape
|
|
558
|
-
for idx, i in enumerate(self.parent.PAD_SHAPE_PARAMETERS[hole_shape]):
|
|
559
|
-
hole_params[i] = params[idx].ToString()
|
|
560
|
-
hole_params["offset_x"] = offset_x.ToString()
|
|
561
|
-
hole_params["offset_y"] = offset_y.ToString()
|
|
562
|
-
hole_params["rotation"] = rotation.ToString()
|
|
563
|
-
return hole_params
|
|
564
|
-
|
|
565
|
-
def __init__(self, parent):
|
|
566
|
-
self.parent = parent
|
|
567
|
-
self._pedb = parent.pedb
|
|
568
|
-
if self._pedb.grpc:
|
|
569
|
-
self.api = self.Grpc(self)
|
|
570
|
-
else:
|
|
571
|
-
self.api = self.DotNet(self)
|
|
572
|
-
|
|
573
|
-
self._solder_shape_type = None
|
|
574
|
-
self._solder_placement = None
|
|
575
|
-
self.api.get_solder_ball_definition()
|
|
576
|
-
|
|
577
|
-
def set_parameters_to_edb(self):
|
|
578
|
-
if self.parent.hole_parameters:
|
|
579
|
-
self.api.set_hole_parameters_to_edb(self.parent.hole_parameters)
|
|
580
|
-
if self.parent.hole_range:
|
|
581
|
-
self.pyedb_obj.hole_range = self.parent.hole_range
|
|
582
|
-
if self.parent.hole_plating_thickness:
|
|
583
|
-
self.pyedb_obj.hole_plating_thickness = self.parent.hole_plating_thickness
|
|
584
|
-
if self.parent.material:
|
|
585
|
-
self.pyedb_obj.material = self.parent.material
|
|
586
|
-
if self.parent.pad_parameters:
|
|
587
|
-
self.api.set_pad_parameters_to_edb(self.parent.pad_parameters)
|
|
588
|
-
if self.parent.solder_ball_parameters:
|
|
589
|
-
self.api.set_solder_parameters_to_edb(self.parent.solder_ball_parameters)
|
|
590
|
-
|
|
591
|
-
def retrieve_parameters_from_edb(self):
|
|
592
|
-
self.parent.name = self.pyedb_obj.name
|
|
593
|
-
self.parent.hole_plating_thickness = self.pyedb_obj.hole_plating_thickness
|
|
594
|
-
self.parent.material = self.pyedb_obj.material
|
|
595
|
-
self.parent.hole_range = self.pyedb_obj.hole_range
|
|
596
|
-
self.parent.pad_parameters = self.api.get_pad_parameters_from_edb()
|
|
597
|
-
self.parent.hole_parameters = self.api.get_hole_parameters_from_edb()
|
|
598
|
-
self.parent.solder_ball_parameters = self.api.get_solder_parameters_from_edb()
|
|
599
|
-
|
|
600
|
-
class Grpc(Common):
|
|
601
|
-
def __init__(self, parent):
|
|
602
|
-
super().__init__(parent)
|
|
603
|
-
|
|
604
|
-
class DotNet(Grpc):
|
|
605
|
-
def __init__(self, parent):
|
|
606
|
-
super().__init__(parent)
|
|
287
|
+
self.pyedb_obj._padstack_def_data = pdef_data
|
|
288
|
+
|
|
289
|
+
def get_hole_parameters_from_edb(self):
|
|
290
|
+
pdef_data = self.pyedb_obj._padstack_def_data
|
|
291
|
+
_, hole_shape, params, offset_x, offset_y, rotation = pdef_data.GetHoleParametersValue()
|
|
292
|
+
hole_shape = pascal_to_snake(hole_shape.ToString())
|
|
293
|
+
|
|
294
|
+
hole_params = {}
|
|
295
|
+
hole_params["shape"] = hole_shape
|
|
296
|
+
for idx, i in enumerate(self.PAD_SHAPE_PARAMETERS[hole_shape]):
|
|
297
|
+
hole_params[i] = params[idx].ToString()
|
|
298
|
+
hole_params["offset_x"] = offset_x.ToString()
|
|
299
|
+
hole_params["offset_y"] = offset_y.ToString()
|
|
300
|
+
hole_params["rotation"] = rotation.ToString()
|
|
301
|
+
return hole_params
|
|
302
|
+
|
|
303
|
+
def set_parameters_to_edb(self):
|
|
304
|
+
if self.hole_parameters:
|
|
305
|
+
self.set_hole_parameters_to_edb(self.hole_parameters)
|
|
306
|
+
if self.hole_range:
|
|
307
|
+
self.pyedb_obj.hole_range = self.hole_range
|
|
308
|
+
if self.hole_plating_thickness:
|
|
309
|
+
self.pyedb_obj.hole_plating_thickness = self.hole_plating_thickness
|
|
310
|
+
if self.material:
|
|
311
|
+
self.pyedb_obj.material = self.material
|
|
312
|
+
if self.pad_parameters:
|
|
313
|
+
self.set_pad_parameters_to_edb(self.pad_parameters)
|
|
314
|
+
if self.solder_ball_parameters:
|
|
315
|
+
self.set_solder_parameters_to_edb(self.solder_ball_parameters)
|
|
316
|
+
|
|
317
|
+
def retrieve_parameters_from_edb(self):
|
|
318
|
+
self.name = self.pyedb_obj.name
|
|
319
|
+
self.hole_plating_thickness = self.pyedb_obj.hole_plating_thickness
|
|
320
|
+
self.material = self.pyedb_obj.material
|
|
321
|
+
self.hole_range = self.pyedb_obj.hole_range
|
|
322
|
+
self.pad_parameters = self.get_pad_parameters_from_edb()
|
|
323
|
+
self.hole_parameters = self.get_hole_parameters_from_edb()
|
|
324
|
+
self.solder_ball_parameters = self.get_solder_parameters_from_edb()
|
|
607
325
|
|
|
608
326
|
def __init__(self, pedb, pedb_object, **kwargs):
|
|
609
|
-
self.
|
|
327
|
+
self._pedb = pedb
|
|
610
328
|
self.pyedb_obj = pedb_object
|
|
611
|
-
if os.environ["PYEDB_USE_DOTNET"] == "0":
|
|
612
|
-
self.api = self.Grpc(self)
|
|
613
|
-
else:
|
|
614
|
-
self.api = self.DotNet(self)
|
|
615
329
|
|
|
616
330
|
self.name = kwargs.get("name", None)
|
|
617
331
|
self.hole_plating_thickness = kwargs.get("hole_plating_thickness", None)
|
|
@@ -621,164 +335,54 @@ class CfgPadstackDefinition(CfgBase):
|
|
|
621
335
|
self.hole_parameters = kwargs.get("hole_parameters", None)
|
|
622
336
|
self.solder_ball_parameters = kwargs.get("solder_ball_parameters", None)
|
|
623
337
|
|
|
338
|
+
self._solder_shape_type = None
|
|
339
|
+
self._solder_placement = None
|
|
340
|
+
self.get_solder_ball_definition()
|
|
341
|
+
|
|
624
342
|
|
|
625
343
|
class CfgPadstackInstance(CfgBase):
|
|
626
344
|
"""Instance data class."""
|
|
627
345
|
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
).name
|
|
648
|
-
if self.parent.parent.layer_range[0] is not None:
|
|
649
|
-
self.parent.pyedb_obj.start_layer = self.parent.parent.layer_range[0]
|
|
650
|
-
if self.parent.parent.layer_range[1] is not None:
|
|
651
|
-
self.parent.pyedb_obj.stop_layer = self.parent.parent.layer_range[1]
|
|
652
|
-
if self.parent.parent.backdrill_parameters:
|
|
653
|
-
self.parent.pyedb_obj.backdrill_parameters = self.parent.parent.backdrill_parameters
|
|
654
|
-
if self.parent.parent.solder_ball_layer:
|
|
655
|
-
self.parent.pyedb_obj.solderball_layer = self._pedb.stackup.layers[
|
|
656
|
-
self.parent.parent.solder_ball_layer
|
|
657
|
-
]
|
|
658
|
-
|
|
659
|
-
hole_override_enabled, hole_override_diam = self.parent.pyedb_obj.get_hole_overrides()
|
|
660
|
-
hole_override_enabled = (
|
|
661
|
-
self.parent.parent.hole_override_enabled
|
|
662
|
-
if self.parent.parent.hole_override_enabled
|
|
663
|
-
else hole_override_enabled
|
|
664
|
-
)
|
|
665
|
-
hole_override_diam = (
|
|
666
|
-
self.parent.parent.hole_override_diameter
|
|
667
|
-
if self.parent.parent.hole_override_diameter
|
|
668
|
-
else hole_override_diam
|
|
669
|
-
)
|
|
670
|
-
self.parent.pyedb_obj.set_hole_overrides(hole_override_enabled, GrpcValue(hole_override_diam))
|
|
671
|
-
|
|
672
|
-
def retrieve_parameters_from_edb(self):
|
|
673
|
-
self.parent.parent.name = self.parent.pyedb_obj.aedt_name
|
|
674
|
-
self.parent.parent.is_pin = self.parent.pyedb_obj.is_pin
|
|
675
|
-
self.parent.parent.definition = self.parent.pyedb_obj.padstack_definition
|
|
676
|
-
backdrill_type = self.parent.pyedb_obj.get_backdrill_type()
|
|
677
|
-
if backdrill_type == "no_drill":
|
|
678
|
-
self.parent.parent.backdrill_parameters = None
|
|
679
|
-
elif backdrill_type == "layer_drill":
|
|
680
|
-
self.parent.parent.backdrill_parameters = self.parent.pyedb_obj.get_back_drill_by_layer()
|
|
681
|
-
elif backdrill_type == "depth_drill":
|
|
682
|
-
self.parent.parent.backdrill_parameters = self.parent.pyedb_obj.get_back_drill_by_depth
|
|
683
|
-
position_x, position_y, rotation = self.parent.pyedb_obj.get_position_and_rotation()
|
|
684
|
-
self.parent.parent.position = [str(position_x), str(position_y)]
|
|
685
|
-
self.parent.parent.rotation = str(rotation)
|
|
686
|
-
self.parent.parent._id = self.parent.pyedb_obj.id
|
|
687
|
-
(
|
|
688
|
-
self.parent.parent.hole_override_enabled,
|
|
689
|
-
hole_override_diameter,
|
|
690
|
-
) = self.parent.pyedb_obj.get_hole_overrides()
|
|
691
|
-
self.parent.hole_override_diameter = str(hole_override_diameter)
|
|
692
|
-
try:
|
|
693
|
-
self.parent.parent.solder_ball_layer = self.parent.pyedb_obj.solderball_layer.name
|
|
694
|
-
except:
|
|
695
|
-
self.parent.parent.solder_ball_layer = ""
|
|
696
|
-
self.parent.parent.layer_range = [self.parent.pyedb_obj.start_layer, self.parent.pyedb_obj.stop_layer]
|
|
697
|
-
|
|
698
|
-
class DotNet(Grpc):
|
|
699
|
-
def __init__(self, parent):
|
|
700
|
-
super().__init__(parent)
|
|
701
|
-
|
|
702
|
-
def set_parameters_to_edb(self):
|
|
703
|
-
if self.parent.parent.name is not None:
|
|
704
|
-
self.parent.pyedb_obj.aedt_name = self.parent.parent.name
|
|
705
|
-
self.parent.pyedb_obj.is_pin = self.parent.parent.is_pin
|
|
706
|
-
if self.parent.parent.net_name is not None:
|
|
707
|
-
self.parent.pyedb_obj.net_name = self._pedb.nets.find_or_create_net(
|
|
708
|
-
self.parent.parent.net_name
|
|
709
|
-
).name
|
|
710
|
-
if self.parent.parent.layer_range[0] is not None:
|
|
711
|
-
self.parent.pyedb_obj.start_layer = self.parent.parent.layer_range[0]
|
|
712
|
-
if self.parent.parent.layer_range[1] is not None:
|
|
713
|
-
self.parent.pyedb_obj.stop_layer = self.parent.parent.layer_range[1]
|
|
714
|
-
if self.parent.parent.backdrill_parameters:
|
|
715
|
-
self.parent.pyedb_obj.backdrill_parameters = self.parent.parent.backdrill_parameters
|
|
716
|
-
if self.parent.parent.solder_ball_layer:
|
|
717
|
-
self.parent.pyedb_obj._edb_object.SetSolderBallLayer(
|
|
718
|
-
self._pedb.stackup[self.parent.parent.solder_ball_layer]._edb_object
|
|
719
|
-
)
|
|
720
|
-
|
|
721
|
-
hole_override_enabled, hole_override_diam = self.parent.pyedb_obj._edb_object.GetHoleOverrideValue()
|
|
722
|
-
hole_override_enabled = (
|
|
723
|
-
self.parent.parent.hole_override_enabled
|
|
724
|
-
if self.parent.parent.hole_override_enabled
|
|
725
|
-
else hole_override_enabled
|
|
726
|
-
)
|
|
727
|
-
hole_override_diam = (
|
|
728
|
-
self.parent.parent.hole_override_diameter
|
|
729
|
-
if self.parent.parent.hole_override_diameter
|
|
730
|
-
else hole_override_diam
|
|
731
|
-
)
|
|
732
|
-
self.parent.pyedb_obj._edb_object.SetHoleOverride(
|
|
733
|
-
hole_override_enabled, self._pedb.edb_value(hole_override_diam)
|
|
734
|
-
)
|
|
346
|
+
def set_parameters_to_edb(self):
|
|
347
|
+
if self.name is not None:
|
|
348
|
+
self.pyedb_obj.aedt_name = self.name
|
|
349
|
+
self.pyedb_obj.is_pin = self.is_pin
|
|
350
|
+
if self.net_name is not None:
|
|
351
|
+
self.pyedb_obj.net_name = self._pedb.nets.find_or_create_net(self.net_name).name
|
|
352
|
+
if self.layer_range[0] is not None:
|
|
353
|
+
self.pyedb_obj.start_layer = self.layer_range[0]
|
|
354
|
+
if self.layer_range[1] is not None:
|
|
355
|
+
self.pyedb_obj.stop_layer = self.layer_range[1]
|
|
356
|
+
if self.backdrill_parameters:
|
|
357
|
+
self.pyedb_obj.backdrill_parameters = self.backdrill_parameters
|
|
358
|
+
if self.solder_ball_layer:
|
|
359
|
+
self.pyedb_obj._edb_object.SetSolderBallLayer(self._pedb.stackup[self.solder_ball_layer]._edb_object)
|
|
360
|
+
|
|
361
|
+
hole_override_enabled, hole_override_diam = self.pyedb_obj._edb_object.GetHoleOverrideValue()
|
|
362
|
+
hole_override_enabled = self.hole_override_enabled if self.hole_override_enabled else hole_override_enabled
|
|
363
|
+
hole_override_diam = self.hole_override_diameter if self.hole_override_diameter else hole_override_diam
|
|
364
|
+
self.pyedb_obj._edb_object.SetHoleOverride(hole_override_enabled, self._pedb.edb_value(hole_override_diam))
|
|
735
365
|
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
def __init__(self, parent):
|
|
754
|
-
self.parent = parent
|
|
755
|
-
self._pedb = parent.pedb
|
|
756
|
-
if self._pedb.grpc:
|
|
757
|
-
self.api = self.Grpc(self)
|
|
758
|
-
else:
|
|
759
|
-
self.api = self.DotNet(self)
|
|
760
|
-
|
|
761
|
-
def set_parameters_to_edb(self):
|
|
762
|
-
self.api.set_parameters_to_edb()
|
|
763
|
-
|
|
764
|
-
def retrieve_parameters_from_edb(self):
|
|
765
|
-
self.api.retrieve_parameters_from_edb()
|
|
766
|
-
|
|
767
|
-
class Grpc(Common):
|
|
768
|
-
def __init__(self, parent):
|
|
769
|
-
super().__init__(parent)
|
|
770
|
-
|
|
771
|
-
class DotNet(Grpc):
|
|
772
|
-
def __init__(self, parent):
|
|
773
|
-
super().__init__(parent)
|
|
366
|
+
def retrieve_parameters_from_edb(self):
|
|
367
|
+
self.name = self.pyedb_obj.aedt_name
|
|
368
|
+
self.is_pin = self.pyedb_obj.is_pin
|
|
369
|
+
self.definition = self.pyedb_obj.padstack_definition
|
|
370
|
+
self.backdrill_parameters = self.pyedb_obj.backdrill_parameters
|
|
371
|
+
_, position, rotation = self.pyedb_obj._edb_object.GetPositionAndRotationValue()
|
|
372
|
+
self.position = [position.X.ToString(), position.Y.ToString()]
|
|
373
|
+
self.rotation = rotation.ToString()
|
|
374
|
+
self._id = self.pyedb_obj.id
|
|
375
|
+
(
|
|
376
|
+
self.hole_override_enabled,
|
|
377
|
+
hole_override_diameter,
|
|
378
|
+
) = self.pyedb_obj._edb_object.GetHoleOverrideValue()
|
|
379
|
+
self.hole_override_diameter = hole_override_diameter.ToString()
|
|
380
|
+
self.solder_ball_layer = self.pyedb_obj._edb_object.GetSolderBallLayer().GetName()
|
|
381
|
+
self.layer_range = [self.pyedb_obj.start_layer, self.pyedb_obj.stop_layer]
|
|
774
382
|
|
|
775
383
|
def __init__(self, pedb, pyedb_obj, **kwargs):
|
|
776
|
-
self.
|
|
384
|
+
self._pedb = pedb
|
|
777
385
|
self.pyedb_obj = pyedb_obj
|
|
778
|
-
if self.pedb.grpc:
|
|
779
|
-
self.api = self.Grpc(self)
|
|
780
|
-
else:
|
|
781
|
-
self.api = self.DotNet(self)
|
|
782
386
|
|
|
783
387
|
self.name = kwargs.get("name", None)
|
|
784
388
|
self.is_pin = kwargs.get("is_pin", False)
|