pyedb 0.42.0__py3-none-any.whl → 0.44.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of pyedb might be problematic. Click here for more details.
- pyedb/__init__.py +1 -1
- pyedb/configuration/cfg_boundaries.py +155 -72
- pyedb/configuration/cfg_components.py +1 -1
- pyedb/configuration/cfg_general.py +34 -16
- pyedb/configuration/cfg_modeler.py +162 -67
- pyedb/configuration/cfg_nets.py +33 -17
- pyedb/configuration/cfg_operations.py +63 -31
- pyedb/configuration/cfg_package_definition.py +113 -52
- pyedb/configuration/cfg_padstacks.py +611 -256
- pyedb/configuration/cfg_pin_groups.py +75 -33
- pyedb/configuration/cfg_ports_sources.py +75 -15
- pyedb/configuration/cfg_s_parameter_models.py +125 -70
- pyedb/configuration/cfg_setup.py +301 -257
- pyedb/configuration/cfg_stackup.py +166 -90
- pyedb/configuration/configuration.py +342 -209
- pyedb/dotnet/database/edb_data/design_options.py +19 -1
- pyedb/dotnet/database/edb_data/padstacks_data.py +16 -6
- pyedb/dotnet/database/geometry/polygon_data.py +4 -2
- pyedb/dotnet/database/padstack.py +6 -2
- pyedb/dotnet/database/sim_setup_data/data/sweep_data.py +63 -10
- pyedb/dotnet/database/utilities/simulation_setup.py +14 -30
- pyedb/dotnet/database/utilities/siwave_simulation_setup.py +30 -0
- pyedb/dotnet/edb.py +75 -105
- pyedb/grpc/database/components.py +1 -1
- pyedb/grpc/database/definition/component_def.py +15 -0
- pyedb/grpc/database/definition/component_pin.py +1 -1
- pyedb/grpc/database/definition/materials.py +27 -0
- pyedb/grpc/database/definition/package_def.py +20 -2
- pyedb/grpc/database/definition/padstack_def.py +5 -2
- pyedb/grpc/database/hierarchy/component.py +4 -2
- pyedb/grpc/database/hierarchy/pingroup.py +12 -8
- pyedb/grpc/database/layers/layer.py +28 -0
- pyedb/grpc/database/layers/stackup_layer.py +281 -40
- pyedb/grpc/database/layout/layout.py +12 -6
- pyedb/grpc/database/modeler.py +8 -8
- pyedb/grpc/database/primitive/bondwire.py +3 -3
- pyedb/grpc/database/primitive/circle.py +1 -1
- pyedb/grpc/database/primitive/padstack_instance.py +13 -3
- pyedb/grpc/database/primitive/path.py +2 -2
- pyedb/grpc/database/primitive/polygon.py +3 -3
- pyedb/grpc/database/primitive/primitive.py +1 -1
- pyedb/grpc/database/primitive/rectangle.py +2 -2
- pyedb/grpc/database/simulation_setup/hfss_simulation_setup.py +73 -30
- pyedb/grpc/database/source_excitations.py +7 -7
- pyedb/grpc/database/stackup.py +14 -6
- pyedb/grpc/database/terminal/bundle_terminal.py +3 -3
- pyedb/grpc/database/terminal/edge_terminal.py +2 -2
- pyedb/grpc/database/terminal/padstack_instance_terminal.py +42 -2
- pyedb/grpc/database/terminal/pingroup_terminal.py +35 -2
- pyedb/grpc/database/terminal/point_terminal.py +10 -1
- pyedb/grpc/database/terminal/terminal.py +4 -4
- pyedb/grpc/database/utility/hfss_extent_info.py +14 -10
- pyedb/grpc/edb.py +8 -8
- pyedb/misc/misc.py +13 -0
- {pyedb-0.42.0.dist-info → pyedb-0.44.0.dist-info}/METADATA +1 -1
- {pyedb-0.42.0.dist-info → pyedb-0.44.0.dist-info}/RECORD +58 -58
- {pyedb-0.42.0.dist-info → pyedb-0.44.0.dist-info}/LICENSE +0 -0
- {pyedb-0.42.0.dist-info → pyedb-0.44.0.dist-info}/WHEEL +0 -0
|
@@ -95,24 +95,488 @@ class CfgPadstackDefinition(CfgBase):
|
|
|
95
95
|
def pyedb_obj(self):
|
|
96
96
|
return self.parent.pyedb_obj
|
|
97
97
|
|
|
98
|
+
class Grpc:
|
|
99
|
+
def __init__(self, parent):
|
|
100
|
+
self.parent = parent
|
|
101
|
+
self._pedb = parent._pedb
|
|
102
|
+
|
|
103
|
+
def get_solder_ball_definition(self):
|
|
104
|
+
from ansys.edb.core.definition.solder_ball_property import (
|
|
105
|
+
SolderballPlacement as GrpcSolderballPlacement,
|
|
106
|
+
)
|
|
107
|
+
from ansys.edb.core.definition.solder_ball_property import (
|
|
108
|
+
SolderballShape as GrpcSolderballShape,
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
self.parent._solder_shape_type = {
|
|
112
|
+
"no_solder_ball": GrpcSolderballShape.NO_SOLDERBALL,
|
|
113
|
+
"cylinder": GrpcSolderballShape.SOLDERBALL_CYLINDER,
|
|
114
|
+
"spheroid": GrpcSolderballShape.SOLDERBALL_SPHEROID,
|
|
115
|
+
}
|
|
116
|
+
self.parent._solder_placement = {
|
|
117
|
+
"above_padstack": GrpcSolderballPlacement.ABOVE_PADSTACK,
|
|
118
|
+
"below_padstack": GrpcSolderballPlacement.BELOW_PADSTACK,
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
def set_hole_parameters_to_edb(self, params):
|
|
122
|
+
from ansys.edb.core.definition.padstack_def_data import (
|
|
123
|
+
PadGeometryType as GrpcPadGeometryType,
|
|
124
|
+
)
|
|
125
|
+
from ansys.edb.core.utility.value import Value as GrpcValue
|
|
126
|
+
|
|
127
|
+
pad_geometry_type = {
|
|
128
|
+
"circle": GrpcPadGeometryType.PADGEOMTYPE_CIRCLE,
|
|
129
|
+
"polygon": GrpcPadGeometryType.PADGEOMTYPE_POLYGON,
|
|
130
|
+
"rectangle": GrpcPadGeometryType.PADGEOMTYPE_RECTANGLE,
|
|
131
|
+
"oval": GrpcPadGeometryType.PADGEOMTYPE_OVAL,
|
|
132
|
+
"square": GrpcPadGeometryType.PADGEOMTYPE_SQUARE,
|
|
133
|
+
"no_geometry": GrpcPadGeometryType.PADGEOMTYPE_NO_GEOMETRY,
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
original_params = self.parent.parent.hole_parameters
|
|
137
|
+
pdef_data = self.parent.pyedb_obj.data
|
|
138
|
+
|
|
139
|
+
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
|
+
|
|
169
|
+
if material:
|
|
170
|
+
pdef_data.solder_ball_material = material
|
|
171
|
+
self.parent.pyedb_obj.data = pdef_data
|
|
172
|
+
|
|
173
|
+
def get_solder_parameters_from_edb(self):
|
|
174
|
+
from ansys.edb.core.definition.solder_ball_property import (
|
|
175
|
+
SolderballPlacement as GrpcSolderballPlacement,
|
|
176
|
+
)
|
|
177
|
+
from ansys.edb.core.utility.value import Value as GrpcValue
|
|
178
|
+
|
|
179
|
+
pdef_data = self.parent.pyedb_obj.data
|
|
180
|
+
shape = pdef_data.solder_ball_shape
|
|
181
|
+
diameter, mid_diameter = pdef_data.solder_ball_param
|
|
182
|
+
try:
|
|
183
|
+
placement = pdef_data.solder_ball_placement.name.lower()
|
|
184
|
+
except:
|
|
185
|
+
placement = GrpcSolderballPlacement.ABOVE_PADSTACK.name.lower()
|
|
186
|
+
material = pdef_data.solder_ball_material.value
|
|
187
|
+
|
|
188
|
+
parameters = {
|
|
189
|
+
"shape": [i for i, j in self.parent._solder_shape_type.items() if j == shape][0],
|
|
190
|
+
"diameter": str(GrpcValue(diameter)),
|
|
191
|
+
"mid_diameter": str(GrpcValue(mid_diameter)),
|
|
192
|
+
"placement": placement,
|
|
193
|
+
"material": material,
|
|
194
|
+
}
|
|
195
|
+
return parameters
|
|
196
|
+
|
|
197
|
+
def get_pad_parameters_from_edb(self):
|
|
198
|
+
"""Pad parameters.
|
|
199
|
+
|
|
200
|
+
Returns
|
|
201
|
+
-------
|
|
202
|
+
dict
|
|
203
|
+
params = {
|
|
204
|
+
'regular_pad': [
|
|
205
|
+
{'layer_name': '1_Top', 'shape': 'circle', 'offset_x': '0.1mm', 'offset_y': '0',
|
|
206
|
+
'rotation': '0', 'diameter': '0.5mm'}
|
|
207
|
+
],
|
|
208
|
+
'anti_pad': [
|
|
209
|
+
{'layer_name': '1_Top', 'shape': 'circle', 'offset_x': '0', 'offset_y': '0', 'rotation': '0',
|
|
210
|
+
'diameter': '1mm'}
|
|
211
|
+
],
|
|
212
|
+
'thermal_pad': [
|
|
213
|
+
{'layer_name': '1_Top', 'shape': 'round90', 'offset_x': '0', 'offset_y': '0', 'rotation': '0',
|
|
214
|
+
'inner': '1mm', 'channel_width': '0.2mm', 'isolation_gap': '0.3mm'},
|
|
215
|
+
],
|
|
216
|
+
'hole': [
|
|
217
|
+
{'layer_name': '1_Top', 'shape': 'circle', 'offset_x': '0', 'offset_y': '0', 'rotation': '0',
|
|
218
|
+
'diameter': '0.1499997mm'},
|
|
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,
|
|
380
|
+
convert_py_list_to_net_list([self._pedb.edb_value(i) for i in temp_param]),
|
|
381
|
+
self._pedb.edb_value(params.get("offset_x", original_params.get("offset_x", 0))),
|
|
382
|
+
self._pedb.edb_value(params.get("offset_y", original_params.get("offset_y", 0))),
|
|
383
|
+
self._pedb.edb_value(params.get("rotation", original_params.get("rotation", 0))),
|
|
384
|
+
)
|
|
385
|
+
self.parent.pyedb_obj._padstack_def_data = pdef_data
|
|
386
|
+
|
|
387
|
+
def set_solder_parameters_to_edb(self, parameters):
|
|
388
|
+
pdef_data = self.parent.pyedb_obj._padstack_def_data
|
|
389
|
+
|
|
390
|
+
shape = parameters.get("shape", "no_solder_ball")
|
|
391
|
+
diameter = parameters.get("diameter", "0.4mm")
|
|
392
|
+
mid_diameter = parameters.get("mid_diameter", diameter)
|
|
393
|
+
placement = parameters.get("placement", "above_padstack")
|
|
394
|
+
material = parameters.get("material", None)
|
|
395
|
+
|
|
396
|
+
pdef_data.SetSolderBallShape(self.parent._solder_shape_type[shape])
|
|
397
|
+
if not shape == "no_solder_ball":
|
|
398
|
+
pdef_data.SetSolderBallParameter(self._pedb.edb_value(diameter), self._pedb.edb_value(mid_diameter))
|
|
399
|
+
pdef_data.SetSolderBallPlacement(self.parent._solder_placement[placement])
|
|
400
|
+
|
|
401
|
+
if material:
|
|
402
|
+
pdef_data.SetSolderBallMaterial(material)
|
|
403
|
+
self.parent.pyedb_obj._padstack_def_data = pdef_data
|
|
404
|
+
|
|
405
|
+
def get_solder_parameters_from_edb(self):
|
|
406
|
+
pdef_data = self.parent.pyedb_obj._padstack_def_data
|
|
407
|
+
shape = pdef_data.GetSolderBallShape()
|
|
408
|
+
_, diameter, mid_diameter = pdef_data.GetSolderBallParameterValue()
|
|
409
|
+
placement = pdef_data.GetSolderBallPlacement()
|
|
410
|
+
material = pdef_data.GetSolderBallMaterial()
|
|
411
|
+
|
|
412
|
+
parameters = {
|
|
413
|
+
"shape": [i for i, j in self.parent._solder_shape_type.items() if j == shape][0],
|
|
414
|
+
"diameter": self._pedb.edb_value(diameter).ToString(),
|
|
415
|
+
"mid_diameter": self._pedb.edb_value(mid_diameter).ToString(),
|
|
416
|
+
"placement": [i for i, j in self.parent._solder_placement.items() if j == placement][0],
|
|
417
|
+
"material": material,
|
|
418
|
+
}
|
|
419
|
+
return parameters
|
|
420
|
+
|
|
421
|
+
def get_pad_parameters_from_edb(self):
|
|
422
|
+
"""Pad parameters.
|
|
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
|
+
|
|
98
565
|
def __init__(self, parent):
|
|
99
566
|
self.parent = parent
|
|
100
|
-
self.
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
self.
|
|
109
|
-
"above_padstack": definition.SolderballPlacement.AbovePadstack,
|
|
110
|
-
"below_padstack": definition.SolderballPlacement.BelowPadstack,
|
|
111
|
-
}
|
|
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()
|
|
112
576
|
|
|
113
577
|
def set_parameters_to_edb(self):
|
|
114
578
|
if self.parent.hole_parameters:
|
|
115
|
-
self.
|
|
579
|
+
self.api.set_hole_parameters_to_edb(self.parent.hole_parameters)
|
|
116
580
|
if self.parent.hole_range:
|
|
117
581
|
self.pyedb_obj.hole_range = self.parent.hole_range
|
|
118
582
|
if self.parent.hole_plating_thickness:
|
|
@@ -120,217 +584,18 @@ class CfgPadstackDefinition(CfgBase):
|
|
|
120
584
|
if self.parent.material:
|
|
121
585
|
self.pyedb_obj.material = self.parent.material
|
|
122
586
|
if self.parent.pad_parameters:
|
|
123
|
-
self.
|
|
587
|
+
self.api.set_pad_parameters_to_edb(self.parent.pad_parameters)
|
|
124
588
|
if self.parent.solder_ball_parameters:
|
|
125
|
-
self.
|
|
589
|
+
self.api.set_solder_parameters_to_edb(self.parent.solder_ball_parameters)
|
|
126
590
|
|
|
127
591
|
def retrieve_parameters_from_edb(self):
|
|
128
592
|
self.parent.name = self.pyedb_obj.name
|
|
129
593
|
self.parent.hole_plating_thickness = self.pyedb_obj.hole_plating_thickness
|
|
130
594
|
self.parent.material = self.pyedb_obj.material
|
|
131
595
|
self.parent.hole_range = self.pyedb_obj.hole_range
|
|
132
|
-
self.parent.pad_parameters = self.
|
|
133
|
-
self.parent.hole_parameters = self.
|
|
134
|
-
self.parent.solder_ball_parameters = self.
|
|
135
|
-
|
|
136
|
-
def _set_solder_parameters_to_edb(self, parameters):
|
|
137
|
-
pdef_data = self.pyedb_obj._padstack_def_data
|
|
138
|
-
|
|
139
|
-
shape = parameters.get("shape", "no_solder_ball")
|
|
140
|
-
diameter = parameters.get("diameter", "0.4mm")
|
|
141
|
-
mid_diameter = parameters.get("mid_diameter", diameter)
|
|
142
|
-
placement = parameters.get("placement", "above_padstack")
|
|
143
|
-
material = parameters.get("material", None)
|
|
144
|
-
|
|
145
|
-
pdef_data.SetSolderBallShape(self._solder_shape_type[shape])
|
|
146
|
-
if not shape == "no_solder_ball":
|
|
147
|
-
pdef_data.SetSolderBallParameter(self.pedb.edb_value(diameter), self.pedb.edb_value(mid_diameter))
|
|
148
|
-
pdef_data.SetSolderBallPlacement(self._solder_placement[placement])
|
|
149
|
-
|
|
150
|
-
if material:
|
|
151
|
-
pdef_data.SetSolderBallMaterial(material)
|
|
152
|
-
self.pyedb_obj._padstack_def_data = pdef_data
|
|
153
|
-
|
|
154
|
-
def _get_solder_parameters_from_edb(self):
|
|
155
|
-
pdef_data = self.parent.pyedb_obj._padstack_def_data
|
|
156
|
-
shape = pdef_data.GetSolderBallShape()
|
|
157
|
-
_, diameter, mid_diameter = pdef_data.GetSolderBallParameterValue()
|
|
158
|
-
placement = pdef_data.GetSolderBallPlacement()
|
|
159
|
-
material = pdef_data.GetSolderBallMaterial()
|
|
160
|
-
|
|
161
|
-
parameters = {
|
|
162
|
-
"shape": [i for i, j in self._solder_shape_type.items() if j == shape][0],
|
|
163
|
-
"diameter": self.pedb.edb_value(diameter).ToString(),
|
|
164
|
-
"mid_diameter": self.pedb.edb_value(mid_diameter).ToString(),
|
|
165
|
-
"placement": [i for i, j in self._solder_placement.items() if j == placement][0],
|
|
166
|
-
"material": material,
|
|
167
|
-
}
|
|
168
|
-
return parameters
|
|
169
|
-
|
|
170
|
-
def _get_pad_parameters_from_edb(self):
|
|
171
|
-
"""Pad parameters.
|
|
172
|
-
|
|
173
|
-
Returns
|
|
174
|
-
-------
|
|
175
|
-
dict
|
|
176
|
-
params = {
|
|
177
|
-
'regular_pad': [
|
|
178
|
-
{'layer_name': '1_Top', 'shape': 'circle', 'offset_x': '0.1mm', 'offset_y': '0', 'rotation': '0',
|
|
179
|
-
'diameter': '0.5mm'}
|
|
180
|
-
],
|
|
181
|
-
'anti_pad': [
|
|
182
|
-
{'layer_name': '1_Top', 'shape': 'circle', 'offset_x': '0', 'offset_y': '0', 'rotation': '0',
|
|
183
|
-
'diameter': '1mm'}
|
|
184
|
-
],
|
|
185
|
-
'thermal_pad': [
|
|
186
|
-
{'layer_name': '1_Top', 'shape': 'round90', 'offset_x': '0', 'offset_y': '0', 'rotation': '0',
|
|
187
|
-
'inner': '1mm', 'channel_width': '0.2mm', 'isolation_gap': '0.3mm'},
|
|
188
|
-
],
|
|
189
|
-
'hole': [
|
|
190
|
-
{'layer_name': '1_Top', 'shape': 'circle', 'offset_x': '0', 'offset_y': '0', 'rotation': '0',
|
|
191
|
-
'diameter': '0.1499997mm'},
|
|
192
|
-
]
|
|
193
|
-
}
|
|
194
|
-
"""
|
|
195
|
-
pdef_data = self.pyedb_obj._padstack_def_data
|
|
196
|
-
pad_type_list = [
|
|
197
|
-
self.pedb._edb.Definition.PadType.RegularPad,
|
|
198
|
-
self.pedb._edb.Definition.PadType.AntiPad,
|
|
199
|
-
self.pedb._edb.Definition.PadType.ThermalPad,
|
|
200
|
-
# self._ppadstack._pedb._edb.Definition.PadType.Hole,
|
|
201
|
-
# This property doesn't appear in UI. It is unclear what it is used for.
|
|
202
|
-
# Suppressing this property for now.
|
|
203
|
-
]
|
|
204
|
-
data = {}
|
|
205
|
-
for pad_type in pad_type_list:
|
|
206
|
-
pad_type_name = pascal_to_snake(pad_type.ToString())
|
|
207
|
-
temp_list = []
|
|
208
|
-
for lyr_name in list(pdef_data.GetLayerNames()):
|
|
209
|
-
result = pdef_data.GetPadParametersValue(lyr_name, pad_type)
|
|
210
|
-
_, pad_shape, params, offset_x, offset_y, rotation = result
|
|
211
|
-
pad_shape = pascal_to_snake(pad_shape.ToString())
|
|
212
|
-
|
|
213
|
-
pad_params = {}
|
|
214
|
-
pad_params["layer_name"] = lyr_name
|
|
215
|
-
pad_params["shape"] = pad_shape
|
|
216
|
-
pad_params["offset_x"] = offset_x.ToString()
|
|
217
|
-
pad_params["offset_y"] = offset_y.ToString()
|
|
218
|
-
pad_params["rotation"] = rotation.ToString()
|
|
219
|
-
|
|
220
|
-
for idx, i in enumerate(self.PAD_SHAPE_PARAMETERS[pad_shape]):
|
|
221
|
-
pad_params[i] = params[idx].ToString()
|
|
222
|
-
temp_list.append(pad_params)
|
|
223
|
-
data[pad_type_name] = temp_list
|
|
224
|
-
return data
|
|
225
|
-
|
|
226
|
-
def _set_pad_parameters_to_edb(self, param):
|
|
227
|
-
pdef_data = self.pyedb_obj._padstack_def_data
|
|
228
|
-
|
|
229
|
-
pad_type_list = [
|
|
230
|
-
self.pedb._edb.Definition.PadType.RegularPad,
|
|
231
|
-
self.pedb._edb.Definition.PadType.AntiPad,
|
|
232
|
-
self.pedb._edb.Definition.PadType.ThermalPad,
|
|
233
|
-
self.pedb._edb.Definition.PadType.Hole,
|
|
234
|
-
]
|
|
235
|
-
for pad_type in pad_type_list:
|
|
236
|
-
pad_type_name = pascal_to_snake(pad_type.ToString())
|
|
237
|
-
rpp = param.get(pad_type_name, [])
|
|
238
|
-
for idx, layer_data in enumerate(rpp):
|
|
239
|
-
# Get geometry type from kwargs
|
|
240
|
-
p = layer_data.get("shape")
|
|
241
|
-
temp_param = []
|
|
242
|
-
|
|
243
|
-
# Handle Circle geometry type
|
|
244
|
-
if p == pascal_to_snake(self.pedb._edb.Definition.PadGeometryType.Circle.ToString()):
|
|
245
|
-
temp_param.append(layer_data["diameter"])
|
|
246
|
-
pad_shape = self.pedb._edb.Definition.PadGeometryType.Circle
|
|
247
|
-
|
|
248
|
-
# Handle Square geometry type
|
|
249
|
-
elif p == pascal_to_snake(self.pedb._edb.Definition.PadGeometryType.Square.ToString()):
|
|
250
|
-
temp_param.append(layer_data["size"])
|
|
251
|
-
pad_shape = self.pedb._edb.Definition.PadGeometryType.Square
|
|
252
|
-
|
|
253
|
-
elif p == pascal_to_snake(self.pedb._edb.Definition.PadGeometryType.Rectangle.ToString()):
|
|
254
|
-
temp_param.append(layer_data["x_size"])
|
|
255
|
-
temp_param.append(layer_data["y_size"])
|
|
256
|
-
pad_shape = self.pedb._edb.Definition.PadGeometryType.Rectangle
|
|
257
|
-
|
|
258
|
-
# Handle Oval geometry type
|
|
259
|
-
elif p == pascal_to_snake(self.pedb._edb.Definition.PadGeometryType.Oval.ToString()):
|
|
260
|
-
temp_param.append(layer_data["x_size"])
|
|
261
|
-
temp_param.append(layer_data["y_size"])
|
|
262
|
-
temp_param.append(layer_data["corner_radius"])
|
|
263
|
-
pad_shape = self.pedb._edb.Definition.PadGeometryType.Oval
|
|
264
|
-
|
|
265
|
-
# Handle Bullet geometry type
|
|
266
|
-
elif p == pascal_to_snake(self.pedb._edb.Definition.PadGeometryType.Bullet.ToString()):
|
|
267
|
-
temp_param.append(layer_data["x_size"])
|
|
268
|
-
temp_param.append(layer_data["y_size"])
|
|
269
|
-
temp_param.append(layer_data["corner_radius"])
|
|
270
|
-
pad_shape = self.pedb._edb.Definition.PadGeometryType.Bullet
|
|
271
|
-
|
|
272
|
-
# Handle Round45 geometry type
|
|
273
|
-
elif p == pascal_to_snake(self.pedb._edb.Definition.PadGeometryType.Round45.ToString()):
|
|
274
|
-
temp_param.append(layer_data["inner"])
|
|
275
|
-
temp_param.append(layer_data["channel_width"])
|
|
276
|
-
temp_param.append(layer_data["isolation_gap"])
|
|
277
|
-
pad_shape = self.pedb._edb.Definition.PadGeometryType.Round45
|
|
278
|
-
|
|
279
|
-
# Handle Round90 geometry type
|
|
280
|
-
elif p == pascal_to_snake(self.pedb._edb.Definition.PadGeometryType.Round90.ToString()):
|
|
281
|
-
temp_param.append(layer_data["inner"])
|
|
282
|
-
temp_param.append(layer_data["channel_width"])
|
|
283
|
-
temp_param.append(layer_data["isolation_gap"])
|
|
284
|
-
pad_shape = self.pedb._edb.Definition.PadGeometryType.Round90
|
|
285
|
-
elif p == pascal_to_snake(self.pedb._edb.Definition.PadGeometryType.NoGeometry.ToString()):
|
|
286
|
-
continue
|
|
287
|
-
|
|
288
|
-
# Set pad parameters for the current layer
|
|
289
|
-
pdef_data.SetPadParameters(
|
|
290
|
-
layer_data["layer_name"],
|
|
291
|
-
pad_type,
|
|
292
|
-
pad_shape,
|
|
293
|
-
convert_py_list_to_net_list([self.pedb.edb_value(i) for i in temp_param]),
|
|
294
|
-
self.pedb.edb_value(layer_data.get("offset_x", 0)),
|
|
295
|
-
self.pedb.edb_value(layer_data.get("offset_y", 0)),
|
|
296
|
-
self.pedb.edb_value(layer_data.get("rotation", 0)),
|
|
297
|
-
)
|
|
298
|
-
self.pyedb_obj._padstack_def_data = pdef_data
|
|
299
|
-
|
|
300
|
-
def _get_hole_parameters_from_edb(self):
|
|
301
|
-
pdef_data = self.pyedb_obj._padstack_def_data
|
|
302
|
-
_, hole_shape, params, offset_x, offset_y, rotation = pdef_data.GetHoleParametersValue()
|
|
303
|
-
hole_shape = pascal_to_snake(hole_shape.ToString())
|
|
304
|
-
|
|
305
|
-
hole_params = {}
|
|
306
|
-
hole_params["shape"] = hole_shape
|
|
307
|
-
for idx, i in enumerate(self.PAD_SHAPE_PARAMETERS[hole_shape]):
|
|
308
|
-
hole_params[i] = params[idx].ToString()
|
|
309
|
-
hole_params["offset_x"] = offset_x.ToString()
|
|
310
|
-
hole_params["offset_y"] = offset_y.ToString()
|
|
311
|
-
hole_params["rotation"] = rotation.ToString()
|
|
312
|
-
return hole_params
|
|
313
|
-
|
|
314
|
-
def _set_hole_parameters_to_edb(self, params):
|
|
315
|
-
original_params = self.parent.hole_parameters
|
|
316
|
-
pdef_data = self.pyedb_obj._padstack_def_data
|
|
317
|
-
|
|
318
|
-
temp_param = []
|
|
319
|
-
shape = params["shape"]
|
|
320
|
-
if shape == "no_geometry":
|
|
321
|
-
return # .net api doesn't tell how to set no_geometry shape.
|
|
322
|
-
for idx, i in enumerate(self.PAD_SHAPE_PARAMETERS[shape]):
|
|
323
|
-
temp_param.append(params[i])
|
|
324
|
-
pedb_shape = getattr(self.pedb._edb.Definition.PadGeometryType, snake_to_pascal(shape))
|
|
325
|
-
|
|
326
|
-
pdef_data.SetHoleParameters(
|
|
327
|
-
pedb_shape,
|
|
328
|
-
convert_py_list_to_net_list([self.pedb.edb_value(i) for i in temp_param]),
|
|
329
|
-
self.pedb.edb_value(params.get("offset_x", original_params.get("offset_x", 0))),
|
|
330
|
-
self.pedb.edb_value(params.get("offset_y", original_params.get("offset_y", 0))),
|
|
331
|
-
self.pedb.edb_value(params.get("rotation", original_params.get("rotation", 0))),
|
|
332
|
-
)
|
|
333
|
-
self.pyedb_obj._padstack_def_data = pdef_data
|
|
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()
|
|
334
599
|
|
|
335
600
|
class Grpc(Common):
|
|
336
601
|
def __init__(self, parent):
|
|
@@ -365,50 +630,139 @@ class CfgPadstackInstance(CfgBase):
|
|
|
365
630
|
def pyedb_obj(self):
|
|
366
631
|
return self.parent.pyedb_obj
|
|
367
632
|
|
|
633
|
+
class Grpc:
|
|
634
|
+
def __init__(self, parent):
|
|
635
|
+
self.parent = parent
|
|
636
|
+
self._pedb = parent._pedb
|
|
637
|
+
|
|
638
|
+
def set_parameters_to_edb(self):
|
|
639
|
+
from ansys.edb.core.utility.value import Value as GrpcValue
|
|
640
|
+
|
|
641
|
+
if self.parent.parent.name is not None:
|
|
642
|
+
self.parent.pyedb_obj.aedt_name = self.parent.parent.name
|
|
643
|
+
self.parent.pyedb_obj.is_pin = self.parent.parent.is_pin
|
|
644
|
+
if self.parent.parent.net_name is not None:
|
|
645
|
+
self.parent.pyedb_obj.net_name = self._pedb.nets.find_or_create_net(
|
|
646
|
+
self.parent.parent.net_name
|
|
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
|
+
)
|
|
735
|
+
|
|
736
|
+
def retrieve_parameters_from_edb(self):
|
|
737
|
+
self.parent.parent.name = self.parent.pyedb_obj.aedt_name
|
|
738
|
+
self.parent.parent.is_pin = self.parent.pyedb_obj.is_pin
|
|
739
|
+
self.parent.parent.definition = self.parent.pyedb_obj.padstack_definition
|
|
740
|
+
self.parent.parent.backdrill_parameters = self.parent.pyedb_obj.backdrill_parameters
|
|
741
|
+
_, position, rotation = self.parent.pyedb_obj._edb_object.GetPositionAndRotationValue()
|
|
742
|
+
self.parent.parent.position = [position.X.ToString(), position.Y.ToString()]
|
|
743
|
+
self.parent.parent.rotation = rotation.ToString()
|
|
744
|
+
self.parent.parent._id = self.parent.pyedb_obj.id
|
|
745
|
+
(
|
|
746
|
+
self.parent.hole_override_enabled,
|
|
747
|
+
hole_override_diameter,
|
|
748
|
+
) = self.parent.pyedb_obj._edb_object.GetHoleOverrideValue()
|
|
749
|
+
self.parent.parent.hole_override_diameter = hole_override_diameter.ToString()
|
|
750
|
+
self.parent.parent.solder_ball_layer = self.parent.pyedb_obj._edb_object.GetSolderBallLayer().GetName()
|
|
751
|
+
self.parent.parent.layer_range = [self.parent.pyedb_obj.start_layer, self.parent.pyedb_obj.stop_layer]
|
|
752
|
+
|
|
368
753
|
def __init__(self, parent):
|
|
369
754
|
self.parent = parent
|
|
370
|
-
self.
|
|
755
|
+
self._pedb = parent.pedb
|
|
756
|
+
if self._pedb.grpc:
|
|
757
|
+
self.api = self.Grpc(self)
|
|
758
|
+
else:
|
|
759
|
+
self.api = self.DotNet(self)
|
|
371
760
|
|
|
372
761
|
def set_parameters_to_edb(self):
|
|
373
|
-
|
|
374
|
-
self.pyedb_obj.aedt_name = self.parent.name
|
|
375
|
-
if self.parent.net_name is not None:
|
|
376
|
-
self.pyedb_obj.net_name = self.pedb.nets.find_or_create_net(self.parent.net_name).name
|
|
377
|
-
if self.parent.layer_range[0] is not None:
|
|
378
|
-
self.pyedb_obj.start_layer = self.parent.layer_range[0]
|
|
379
|
-
if self.parent.layer_range[1] is not None:
|
|
380
|
-
self.pyedb_obj.stop_layer = self.parent.layer_range[1]
|
|
381
|
-
if self.parent.backdrill_parameters:
|
|
382
|
-
self.pyedb_obj.backdrill_parameters = self.parent.backdrill_parameters
|
|
383
|
-
if self.parent.solder_ball_layer:
|
|
384
|
-
self.pyedb_obj._edb_object.SetSolderBallLayer(
|
|
385
|
-
self.pedb.stackup[self.parent.solder_ball_layer]._edb_object
|
|
386
|
-
)
|
|
387
|
-
|
|
388
|
-
hole_override_enabled, hole_override_diam = self.pyedb_obj._edb_object.GetHoleOverrideValue()
|
|
389
|
-
hole_override_enabled = (
|
|
390
|
-
self.parent.hole_override_enabled if self.parent.hole_override_enabled else hole_override_enabled
|
|
391
|
-
)
|
|
392
|
-
hole_override_diam = (
|
|
393
|
-
self.parent.hole_override_diameter if self.parent.hole_override_diameter else hole_override_diam
|
|
394
|
-
)
|
|
395
|
-
self.pyedb_obj._edb_object.SetHoleOverride(hole_override_enabled, self.pedb.edb_value(hole_override_diam))
|
|
762
|
+
self.api.set_parameters_to_edb()
|
|
396
763
|
|
|
397
764
|
def retrieve_parameters_from_edb(self):
|
|
398
|
-
self.
|
|
399
|
-
self.parent.definition = self.pyedb_obj.padstack_definition
|
|
400
|
-
self.parent.backdrill_parameters = self.pyedb_obj.backdrill_parameters
|
|
401
|
-
_, position, rotation = self.pyedb_obj._edb_object.GetPositionAndRotationValue()
|
|
402
|
-
self.parent.position = [position.X.ToString(), position.Y.ToString()]
|
|
403
|
-
self.parent.rotation = rotation.ToString()
|
|
404
|
-
self.parent._id = self.pyedb_obj.id
|
|
405
|
-
(
|
|
406
|
-
self.parent.hole_override_enabled,
|
|
407
|
-
hole_override_diameter,
|
|
408
|
-
) = self.pyedb_obj._edb_object.GetHoleOverrideValue()
|
|
409
|
-
self.parent.hole_override_diameter = hole_override_diameter.ToString()
|
|
410
|
-
self.parent.solder_ball_layer = self.pyedb_obj._edb_object.GetSolderBallLayer().GetName()
|
|
411
|
-
self.parent.layer_range = [self.pyedb_obj.start_layer, self.pyedb_obj.stop_layer]
|
|
765
|
+
self.api.retrieve_parameters_from_edb()
|
|
412
766
|
|
|
413
767
|
class Grpc(Common):
|
|
414
768
|
def __init__(self, parent):
|
|
@@ -421,12 +775,13 @@ class CfgPadstackInstance(CfgBase):
|
|
|
421
775
|
def __init__(self, pedb, pyedb_obj, **kwargs):
|
|
422
776
|
self.pedb = pedb
|
|
423
777
|
self.pyedb_obj = pyedb_obj
|
|
424
|
-
if
|
|
778
|
+
if self.pedb.grpc:
|
|
425
779
|
self.api = self.Grpc(self)
|
|
426
780
|
else:
|
|
427
781
|
self.api = self.DotNet(self)
|
|
428
782
|
|
|
429
783
|
self.name = kwargs.get("name", None)
|
|
784
|
+
self.is_pin = kwargs.get("is_pin", False)
|
|
430
785
|
self.net_name = kwargs.get("net_name", None)
|
|
431
786
|
self.layer_range = kwargs.get("layer_range", [None, None])
|
|
432
787
|
self.definition = kwargs.get("definition", None)
|