pyedb 0.42.0__py3-none-any.whl → 0.43.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.

@@ -33,8 +33,331 @@ from pyedb.dotnet.database.definition.package_def import PackageDef
33
33
  class Configuration:
34
34
  """Enables export and import of a JSON configuration file that can be applied to a new or existing design."""
35
35
 
36
+ class Grpc:
37
+ def __init__(self, parent):
38
+ self.parent = parent
39
+ self._pedb = parent._pedb
40
+
41
+ def configuration_stackup(self, kwargs):
42
+ if kwargs.get("fix_padstack_def"):
43
+ from pyedb.configuration.cfg_padstacks import CfgPadstackDefinition
44
+
45
+ pedb_defs = self._pedb.padstacks.definitions
46
+ temp = []
47
+ for _, pdef in pedb_defs.items():
48
+ cfg_def = CfgPadstackDefinition(self._pedb, pdef)
49
+ cfg_def.api.retrieve_parameters_from_edb()
50
+ temp.append(cfg_def)
51
+ self.parent.cfg_data.stackup.apply()
52
+ for cfg_pdef in temp:
53
+ cfg_pdef.api.set_parameters_to_edb()
54
+ else:
55
+ temp_pdef_data = {}
56
+ from ansys.edb.core.definition.padstack_def_data import (
57
+ PadType as GrpcPadType,
58
+ )
59
+
60
+ for pdef_name, pdef in self._pedb.padstacks.definitions.items():
61
+ for layer in pdef.data.layer_names:
62
+ result = pdef.data.get_pad_parameters(layer, GrpcPadType.REGULAR_PAD)
63
+ if len(result) == 4:
64
+ # polygon based
65
+ temp_pdef_data[pdef_name] = pdef.data
66
+ break
67
+ self.parent.cfg_data.stackup.apply()
68
+ for pdef_name, pdef_data in temp_pdef_data.items():
69
+ pdef = self._pedb.padstacks.definitions[pdef_name]
70
+ pdef._padstack_def_data = pdef_data
71
+
72
+ def _load_stackup(self):
73
+ """Imports stackup information from json."""
74
+ data = self.data["stackup"]
75
+ materials = data.get("materials")
76
+
77
+ if materials:
78
+ edb_materials = {i.lower(): i for i, _ in self._pedb.materials.materials.items()}
79
+ for mat in materials:
80
+ name = mat["name"].lower()
81
+ if name in edb_materials:
82
+ self._pedb.materials.delete_material(edb_materials[name])
83
+ for mat in materials:
84
+ self._pedb.materials.add_material(**mat)
85
+
86
+ layers = data.get("layers")
87
+
88
+ if layers:
89
+ input_signal_layers = [i for i in layers if i["type"].lower() == "signal"]
90
+ if not len(input_signal_layers) == len(self._pedb.stackup.signal_layers):
91
+ self._pedb.logger.error("Input signal layer count do not match.")
92
+ return False
93
+
94
+ removal_list = []
95
+ lc_signal_layers = []
96
+ for name, obj in self._pedb.stackup.all_layers.items():
97
+ if obj.type == "dielectric":
98
+ removal_list.append(name)
99
+ elif obj.type == "signal":
100
+ lc_signal_layers.append(obj.id)
101
+ for l in removal_list:
102
+ self._pedb.stackup.remove_layer(l)
103
+
104
+ # update all signal layers
105
+ id_name = {i[0]: i[1] for i in self._pedb.stackup.layers_by_id}
106
+ signal_idx = 0
107
+ for l in layers:
108
+ if l["type"] == "signal":
109
+ layer_id = lc_signal_layers[signal_idx]
110
+ layer_name = id_name[layer_id]
111
+ self._pedb.stackup.layers[layer_name].update(**l)
112
+ signal_idx = signal_idx + 1
113
+
114
+ # add all dielectric layers. Dielectric layers must be added last. Otherwise,
115
+ # dielectric layer will occupy signal and document layer id.
116
+ prev_layer_clone = None
117
+ l = layers.pop(0)
118
+ if l["type"] == "signal":
119
+ prev_layer_clone = self._pedb.stackup.layers[l["name"]]
120
+ else:
121
+ prev_layer_clone = self._pedb.stackup.add_layer_top(**l)
122
+ for idx, l in enumerate(layers):
123
+ if l["type"] == "dielectric":
124
+ prev_layer_clone = self._pedb.stackup.add_layer_below(
125
+ base_layer_name=prev_layer_clone.name, **l
126
+ )
127
+ elif l["type"] == "signal":
128
+ prev_layer_clone = self._pedb.stackup.layers[l["name"]]
129
+
130
+ def _load_package_def(self):
131
+ """Imports package definition information from JSON."""
132
+ comps = self._pedb.components.instances
133
+ for pkgd in self.parent.data["package_definitions"]:
134
+ name = pkgd["name"]
135
+ if name in self._pedb.definitions.package:
136
+ self._pedb.definitions.package[name].delete()
137
+ extent_bounding_box = pkgd.get("extent_bounding_box", None)
138
+ if extent_bounding_box:
139
+ package_def = PackageDef(self._pedb, name=name, extent_bounding_box=extent_bounding_box)
140
+ else:
141
+ package_def = PackageDef(self._pedb, name=name, component_part_name=pkgd["component_definition"])
142
+ package_def.maximum_power = pkgd["maximum_power"]
143
+ package_def.therm_cond = pkgd["therm_cond"]
144
+ package_def.theta_jb = pkgd["theta_jb"]
145
+ package_def.theta_jc = pkgd["theta_jc"]
146
+ package_def.height = pkgd["height"]
147
+
148
+ heatsink = pkgd.get("heatsink", None)
149
+ if heatsink:
150
+ package_def.set_heatsink(
151
+ heatsink["fin_base_height"],
152
+ heatsink["fin_height"],
153
+ heatsink["fin_orientation"],
154
+ heatsink["fin_spacing"],
155
+ heatsink["fin_thickness"],
156
+ )
157
+
158
+ comp_def_name = pkgd["component_definition"]
159
+ comp_def = self._pedb.definitions.component[comp_def_name]
160
+
161
+ comp_list = dict()
162
+ if pkgd["apply_to_all"]:
163
+ comp_list.update(
164
+ {
165
+ refdes: comp
166
+ for refdes, comp in comp_def.components.items()
167
+ if refdes not in pkgd["components"]
168
+ }
169
+ )
170
+ else:
171
+ comp_list.update(
172
+ {refdes: comp for refdes, comp in comp_def.components.items() if refdes in pkgd["components"]}
173
+ )
174
+ for _, i in comp_list.items():
175
+ i.package_def = name
176
+
177
+ def get_data_from_db(self, **kwargs):
178
+ """Get configuration data from layout.
179
+
180
+ Parameters
181
+ ----------
182
+ stackup
183
+
184
+ Returns
185
+ -------
186
+
187
+ """
188
+ self._pedb.logger.info("Getting data from layout database.")
189
+ data = {}
190
+ if kwargs.get("general", False):
191
+ data["general"] = self.parent.cfg_data.general.get_data_from_db()
192
+ if kwargs.get("stackup", False):
193
+ data["stackup"] = self.parent.cfg_data.stackup.get_data_from_db()
194
+ if kwargs.get("package_definitions", False):
195
+ data["package_definitions"] = self.parent.cfg_data.package_definitions.get_data_from_db()
196
+ if kwargs.get("setups", False):
197
+ setups = self.parent.cfg_data.setups
198
+ setups.retrieve_parameters_from_edb()
199
+ data["setups"] = setups.to_dict()
200
+ if kwargs.get("sources", False):
201
+ data["sources"] = self.parent.cfg_data.sources.get_data_from_db()
202
+ if kwargs.get("ports", False):
203
+ data["ports"] = self.parent.cfg_data.ports.get_data_from_db()
204
+ if kwargs.get("components", False) or kwargs.get("s_parameters", False):
205
+ self.parent.cfg_data.components.retrieve_parameters_from_edb()
206
+ components = []
207
+ for i in self.parent.cfg_data.components.components:
208
+ components.append(i.get_attributes())
209
+
210
+ if kwargs.get("components", False):
211
+ data["components"] = components
212
+ elif kwargs.get("s_parameters", False):
213
+ data["s_parameters"] = self.parent.cfg_data.s_parameters.get_data_from_db(components)
214
+ if kwargs.get("nets", False):
215
+ data["nets"] = self.parent.cfg_data.nets.get_data_from_db()
216
+ if kwargs.get("pin_groups", False):
217
+ data["pin_groups"] = self.parent.cfg_data.pin_groups.get_data_from_db()
218
+ if kwargs.get("operations", False):
219
+ data["operations"] = self.parent.cfg_data.operations.get_data_from_db()
220
+ if kwargs.get("padstacks", False):
221
+ self.parent.cfg_data.padstacks.retrieve_parameters_from_edb()
222
+ definitions = []
223
+ for i in self.parent.cfg_data.padstacks.definitions:
224
+ definitions.append(i.get_attributes())
225
+ instances = []
226
+ for i in self.parent.cfg_data.padstacks.instances:
227
+ instances.append(i.get_attributes())
228
+ data["padstacks"] = dict()
229
+ data["padstacks"]["definitions"] = definitions
230
+ data["padstacks"]["instances"] = instances
231
+
232
+ if kwargs.get("boundaries", False):
233
+ data["boundaries"] = self.parent.cfg_data.boundaries.get_data_from_db()
234
+
235
+ return data
236
+
237
+ def export(
238
+ self,
239
+ file_path,
240
+ stackup=True,
241
+ package_definitions=False,
242
+ setups=True,
243
+ sources=True,
244
+ ports=True,
245
+ nets=True,
246
+ pin_groups=True,
247
+ operations=True,
248
+ components=True,
249
+ boundaries=True,
250
+ s_parameters=True,
251
+ padstacks=True,
252
+ general=True,
253
+ ):
254
+ """Export the configuration data from layout to a file.
255
+
256
+ Parameters
257
+ ----------
258
+ file_path : str, Path
259
+ File path to export the configuration data.
260
+ stackup : bool
261
+ Whether to export stackup or not.
262
+ package_definitions : bool
263
+ Whether to export package definitions or not.
264
+ setups : bool
265
+ Whether to export setups or not.
266
+ sources : bool
267
+ Whether to export sources or not.
268
+ ports : bool
269
+ Whether to export ports or not.
270
+ nets : bool
271
+ Whether to export nets.
272
+ pin_groups : bool
273
+ Whether to export pin groups.
274
+ operations : bool
275
+ Whether to export operations.
276
+ components : bool
277
+ Whether to export component.
278
+ boundaries : bool
279
+ Whether to export boundaries.
280
+ s_parameters : bool
281
+ Whether to export s_parameters.
282
+ padstacks : bool
283
+ Whether to export padstacks.
284
+ general : bool
285
+ Whether to export general information.
286
+ Returns
287
+ -------
288
+ bool
289
+ """
290
+ data = self.get_data_from_db(
291
+ stackup=stackup,
292
+ package_definitions=package_definitions,
293
+ setups=setups,
294
+ sources=sources,
295
+ ports=ports,
296
+ nets=nets,
297
+ pin_groups=pin_groups,
298
+ operations=operations,
299
+ components=components,
300
+ boundaries=boundaries,
301
+ s_parameters=s_parameters,
302
+ padstacks=padstacks,
303
+ general=general,
304
+ )
305
+
306
+ file_path = file_path if isinstance(file_path, Path) else Path(file_path)
307
+ file_path = file_path.with_suffix(".json") if file_path.suffix == "" else file_path
308
+
309
+ with open(file_path, "w") as f:
310
+ if file_path.suffix == ".json":
311
+ json.dump(data, f, ensure_ascii=False, indent=4)
312
+ else:
313
+ toml.dump(data, f)
314
+ return True if os.path.isfile(file_path) else False
315
+
316
+ class DotNet(Grpc):
317
+ def __init__(self, parent):
318
+ super().__init__(parent)
319
+
320
+ def configuration_stackup(self, kwargs):
321
+ if kwargs.get("fix_padstack_def"):
322
+ from pyedb.configuration.cfg_padstacks import CfgPadstackDefinition
323
+
324
+ pedb_defs = self._pedb.padstacks.definitions
325
+ temp = []
326
+ for _, pdef in pedb_defs.items():
327
+ cfg_def = CfgPadstackDefinition(self._pedb, pdef)
328
+ cfg_def.api.retrieve_parameters_from_edb()
329
+ temp.append(cfg_def)
330
+ self.parent.cfg_data.stackup.apply()
331
+ for cfg_pdef in temp:
332
+ cfg_pdef.api.set_parameters_to_edb()
333
+ else:
334
+ temp_pdef_data = {}
335
+ for pdef_name, pdef in self._pedb.padstacks.definitions.items():
336
+ pdef_data = pdef._padstack_def_data
337
+ for lyr_name in list(pdef_data.GetLayerNames()):
338
+ result = pdef_data.GetPadParametersValue(
339
+ lyr_name, self._pedb._edb.Definition.PadType.RegularPad
340
+ )
341
+ flag, pad_shape, params, offset_x, offset_y, rotation = result
342
+ if flag is False:
343
+ result = pdef_data.GetPolygonalPadParameters(
344
+ lyr_name, self._pedb._edb.Definition.PadType.RegularPad
345
+ )
346
+ flag, polygon_data, offset_x, offset_y, rotation = result
347
+ if flag:
348
+ temp_pdef_data[pdef_name] = pdef_data
349
+ break
350
+ self.parent.cfg_data.stackup.apply()
351
+ for pdef_name, pdef_data in temp_pdef_data.items():
352
+ pdef = self._pedb.padstacks.definitions[pdef_name]
353
+ pdef._padstack_def_data = pdef_data
354
+
36
355
  def __init__(self, pedb):
37
356
  self._pedb = pedb
357
+ if self._pedb.grpc:
358
+ self.api = self.Grpc(self)
359
+ else:
360
+ self.api = self.DotNet(self)
38
361
  self._components = self._pedb.components.instances
39
362
  self.data = {}
40
363
  self._s_parameter_library = ""
@@ -133,52 +456,7 @@ class Configuration:
133
456
  self.cfg_data.setups.apply()
134
457
 
135
458
  # Configure stackup
136
- if kwargs.get("fix_padstack_def"):
137
- from pyedb.configuration.cfg_padstacks import CfgPadstackDefinition
138
-
139
- pedb_defs = self._pedb.padstacks.definitions
140
- temp = []
141
- for _, pdef in pedb_defs.items():
142
- cfg_def = CfgPadstackDefinition(self._pedb, pdef)
143
- cfg_def.api.retrieve_parameters_from_edb()
144
- temp.append(cfg_def)
145
- self.cfg_data.stackup.apply()
146
- for cfg_pdef in temp:
147
- cfg_pdef.api.set_parameters_to_edb()
148
- else:
149
- temp_pdef_data = {}
150
- if self._pedb.grpc:
151
- from ansys.edb.core.definition.padstack_def_data import (
152
- PadType as GrpcPadType,
153
- )
154
-
155
- for pdef_name, pdef in self._pedb.padstacks.definitions.items():
156
- for layer in pdef.data.layer_names:
157
- result = pdef.data.get_pad_parameters(layer, GrpcPadType.REGULAR_PAD)
158
- if len(result) == 4:
159
- # polygon based
160
- temp_pdef_data[pdef_name] = pdef.data
161
- break
162
- else:
163
- for pdef_name, pdef in self._pedb.padstacks.definitions.items():
164
- pdef_data = pdef._padstack_def_data
165
- for lyr_name in list(pdef_data.GetLayerNames()):
166
- result = pdef_data.GetPadParametersValue(
167
- lyr_name, self._pedb._edb.Definition.PadType.RegularPad
168
- )
169
- flag, pad_shape, params, offset_x, offset_y, rotation = result
170
- if flag is False:
171
- result = pdef_data.GetPolygonalPadParameters(
172
- lyr_name, self._pedb._edb.Definition.PadType.RegularPad
173
- )
174
- flag, polygon_data, offset_x, offset_y, rotation = result
175
- if flag:
176
- temp_pdef_data[pdef_name] = pdef_data
177
- break
178
- self.cfg_data.stackup.apply()
179
- for pdef_name, pdef_data in temp_pdef_data.items():
180
- pdef = self._pedb.padstacks.definitions[pdef_name]
181
- pdef._padstack_def_data = pdef_data
459
+ self.api.configuration_stackup(kwargs)
182
460
 
183
461
  # Configure padstacks
184
462
  if self.cfg_data.padstacks:
@@ -210,102 +488,11 @@ class Configuration:
210
488
 
211
489
  def _load_stackup(self):
212
490
  """Imports stackup information from json."""
213
- data = self.data["stackup"]
214
- materials = data.get("materials")
215
-
216
- if materials:
217
- edb_materials = {i.lower(): i for i, _ in self._pedb.materials.materials.items()}
218
- for mat in materials:
219
- name = mat["name"].lower()
220
- if name in edb_materials:
221
- self._pedb.materials.delete_material(edb_materials[name])
222
- for mat in materials:
223
- self._pedb.materials.add_material(**mat)
224
-
225
- layers = data.get("layers")
226
-
227
- if layers:
228
- input_signal_layers = [i for i in layers if i["type"].lower() == "signal"]
229
- if not len(input_signal_layers) == len(self._pedb.stackup.signal_layers):
230
- self._pedb.logger.error("Input signal layer count do not match.")
231
- return False
232
-
233
- removal_list = []
234
- lc_signal_layers = []
235
- for name, obj in self._pedb.stackup.all_layers.items():
236
- if obj.type == "dielectric":
237
- removal_list.append(name)
238
- elif obj.type == "signal":
239
- lc_signal_layers.append(obj.id)
240
- for l in removal_list:
241
- self._pedb.stackup.remove_layer(l)
242
-
243
- # update all signal layers
244
- id_name = {i[0]: i[1] for i in self._pedb.stackup.layers_by_id}
245
- signal_idx = 0
246
- for l in layers:
247
- if l["type"] == "signal":
248
- layer_id = lc_signal_layers[signal_idx]
249
- layer_name = id_name[layer_id]
250
- self._pedb.stackup.layers[layer_name].update(**l)
251
- signal_idx = signal_idx + 1
252
-
253
- # add all dielectric layers. Dielectric layers must be added last. Otherwise,
254
- # dielectric layer will occupy signal and document layer id.
255
- prev_layer_clone = None
256
- l = layers.pop(0)
257
- if l["type"] == "signal":
258
- prev_layer_clone = self._pedb.stackup.layers[l["name"]]
259
- else:
260
- prev_layer_clone = self._pedb.stackup.add_layer_top(**l)
261
- for idx, l in enumerate(layers):
262
- if l["type"] == "dielectric":
263
- prev_layer_clone = self._pedb.stackup.add_layer_below(base_layer_name=prev_layer_clone.name, **l)
264
- elif l["type"] == "signal":
265
- prev_layer_clone = self._pedb.stackup.layers[l["name"]]
491
+ self.api._load_stackup()
266
492
 
267
493
  def _load_package_def(self):
268
494
  """Imports package definition information from JSON."""
269
- comps = self._pedb.components.instances
270
- for pkgd in self.data["package_definitions"]:
271
- name = pkgd["name"]
272
- if name in self._pedb.definitions.package:
273
- self._pedb.definitions.package[name].delete()
274
- extent_bounding_box = pkgd.get("extent_bounding_box", None)
275
- if extent_bounding_box:
276
- package_def = PackageDef(self._pedb, name=name, extent_bounding_box=extent_bounding_box)
277
- else:
278
- package_def = PackageDef(self._pedb, name=name, component_part_name=pkgd["component_definition"])
279
- package_def.maximum_power = pkgd["maximum_power"]
280
- package_def.therm_cond = pkgd["therm_cond"]
281
- package_def.theta_jb = pkgd["theta_jb"]
282
- package_def.theta_jc = pkgd["theta_jc"]
283
- package_def.height = pkgd["height"]
284
-
285
- heatsink = pkgd.get("heatsink", None)
286
- if heatsink:
287
- package_def.set_heatsink(
288
- heatsink["fin_base_height"],
289
- heatsink["fin_height"],
290
- heatsink["fin_orientation"],
291
- heatsink["fin_spacing"],
292
- heatsink["fin_thickness"],
293
- )
294
-
295
- comp_def_name = pkgd["component_definition"]
296
- comp_def = self._pedb.definitions.component[comp_def_name]
297
-
298
- comp_list = dict()
299
- if pkgd["apply_to_all"]:
300
- comp_list.update(
301
- {refdes: comp for refdes, comp in comp_def.components.items() if refdes not in pkgd["components"]}
302
- )
303
- else:
304
- comp_list.update(
305
- {refdes: comp for refdes, comp in comp_def.components.items() if refdes in pkgd["components"]}
306
- )
307
- for _, i in comp_list.items():
308
- i.package_def = name
495
+ self.api._load_package_def()
309
496
 
310
497
  def get_data_from_db(self, **kwargs):
311
498
  """Get configuration data from layout.
@@ -318,52 +505,7 @@ class Configuration:
318
505
  -------
319
506
 
320
507
  """
321
- self._pedb.logger.info("Getting data from layout database.")
322
- data = {}
323
- if kwargs.get("general", False):
324
- data["general"] = self.cfg_data.general.get_data_from_db()
325
- if kwargs.get("stackup", False):
326
- data["stackup"] = self.cfg_data.stackup.get_data_from_db()
327
- if kwargs.get("package_definitions", False):
328
- data["package_definitions"] = self.cfg_data.package_definitions.get_data_from_db()
329
- if kwargs.get("setups", False):
330
- data["setups"] = self.cfg_data.setups.get_data_from_db()
331
- if kwargs.get("sources", False):
332
- data["sources"] = self.cfg_data.sources.get_data_from_db()
333
- if kwargs.get("ports", False):
334
- data["ports"] = self.cfg_data.ports.get_data_from_db()
335
- if kwargs.get("components", False) or kwargs.get("s_parameters", False):
336
- self.cfg_data.components.retrieve_parameters_from_edb()
337
- components = []
338
- for i in self.cfg_data.components.components:
339
- components.append(i.get_attributes())
340
-
341
- if kwargs.get("components", False):
342
- data["components"] = components
343
- elif kwargs.get("s_parameters", False):
344
- data["s_parameters"] = self.cfg_data.s_parameters.get_data_from_db(components)
345
- if kwargs.get("nets", False):
346
- data["nets"] = self.cfg_data.nets.get_data_from_db()
347
- if kwargs.get("pin_groups", False):
348
- data["pin_groups"] = self.cfg_data.pin_groups.get_data_from_db()
349
- if kwargs.get("operations", False):
350
- data["operations"] = self.cfg_data.operations.get_data_from_db()
351
- if kwargs.get("padstacks", False):
352
- self.cfg_data.padstacks.retrieve_parameters_from_edb()
353
- definitions = []
354
- for i in self.cfg_data.padstacks.definitions:
355
- definitions.append(i.get_attributes())
356
- instances = []
357
- for i in self.cfg_data.padstacks.instances:
358
- instances.append(i.get_attributes())
359
- data["padstacks"] = dict()
360
- data["padstacks"]["definitions"] = definitions
361
- data["padstacks"]["instances"] = instances
362
-
363
- if kwargs.get("boundaries", False):
364
- data["boundaries"] = self.cfg_data.boundaries.get_data_from_db()
365
-
366
- return data
508
+ return self.api.get_data_from_db(**kwargs)
367
509
 
368
510
  def export(
369
511
  self,
@@ -418,28 +560,19 @@ class Configuration:
418
560
  -------
419
561
  bool
420
562
  """
421
- data = self.get_data_from_db(
422
- stackup=stackup,
423
- package_definitions=package_definitions,
424
- setups=setups,
425
- sources=sources,
426
- ports=ports,
427
- nets=nets,
428
- pin_groups=pin_groups,
429
- operations=operations,
430
- components=components,
431
- boundaries=boundaries,
432
- s_parameters=s_parameters,
433
- padstacks=padstacks,
434
- general=general,
563
+ return self.api.export(
564
+ file_path,
565
+ stackup=True,
566
+ package_definitions=False,
567
+ setups=True,
568
+ sources=True,
569
+ ports=True,
570
+ nets=True,
571
+ pin_groups=True,
572
+ operations=True,
573
+ components=True,
574
+ boundaries=True,
575
+ s_parameters=True,
576
+ padstacks=True,
577
+ general=True,
435
578
  )
436
-
437
- file_path = file_path if isinstance(file_path, Path) else Path(file_path)
438
- file_path = file_path.with_suffix(".json") if file_path.suffix == "" else file_path
439
-
440
- with open(file_path, "w") as f:
441
- if file_path.suffix == ".json":
442
- json.dump(data, f, ensure_ascii=False, indent=4)
443
- else:
444
- toml.dump(data, f)
445
- return True if os.path.isfile(file_path) else False
@@ -2142,7 +2142,7 @@ class EDBPadstackInstance(Primitive):
2142
2142
  component_only=component_only,
2143
2143
  )
2144
2144
 
2145
- def split(self):
2145
+ def split(self) -> list:
2146
2146
  """Split padstack instance into multiple instances. The new instances only connect adjacent layers."""
2147
2147
  pdef_name = self.padstack_definition
2148
2148
  position = self.position
@@ -2151,11 +2151,16 @@ class EDBPadstackInstance(Primitive):
2151
2151
  stackup_layer_range = list(self._pedb.stackup.signal_layers.keys())
2152
2152
  start_idx = stackup_layer_range.index(self.start_layer)
2153
2153
  stop_idx = stackup_layer_range.index(self.stop_layer)
2154
+ temp = []
2154
2155
  for idx, (l1, l2) in enumerate(
2155
2156
  list(zip(stackup_layer_range[start_idx:stop_idx], stackup_layer_range[start_idx + 1 : stop_idx + 1]))
2156
2157
  ):
2157
- self._pedb.padstacks.place(position, pdef_name, net_name, f"{name}_{idx}", fromlayer=l1, tolayer=l2)
2158
+ pd_inst = self._pedb.padstacks.place(
2159
+ position, pdef_name, net_name, f"{name}_{idx}", fromlayer=l1, tolayer=l2
2160
+ )
2161
+ temp.append(pd_inst)
2158
2162
  self.delete()
2163
+ return temp
2159
2164
 
2160
2165
  def convert_hole_to_conical_shape(self, angle=75):
2161
2166
  """Convert actual padstack instance to microvias 3D Objects with a given aspect ratio.