pyedb 0.50.0__py3-none-any.whl → 0.51.2__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_ports_sources.py +79 -239
- pyedb/configuration/configuration.py +27 -0
- pyedb/dotnet/clr_module.py +9 -3
- pyedb/dotnet/database/cell/hierarchy/component.py +3 -3
- pyedb/dotnet/database/cell/layout.py +10 -1
- pyedb/dotnet/database/dotnet/database.py +0 -2
- pyedb/dotnet/database/edb_data/padstacks_data.py +13 -0
- pyedb/dotnet/database/layout_validation.py +17 -13
- pyedb/dotnet/database/modeler.py +0 -1
- pyedb/dotnet/edb.py +7 -1
- pyedb/generic/design_types.py +183 -62
- pyedb/grpc/database/components.py +604 -652
- pyedb/grpc/database/control_file.py +597 -155
- pyedb/grpc/database/definition/component_def.py +17 -14
- pyedb/grpc/database/definition/materials.py +27 -27
- pyedb/grpc/database/definition/package_def.py +8 -8
- pyedb/grpc/database/definition/padstack_def.py +31 -33
- pyedb/grpc/database/definitions.py +36 -2
- pyedb/grpc/database/geometry/arc_data.py +5 -5
- pyedb/grpc/database/geometry/point_3d_data.py +3 -3
- pyedb/grpc/database/geometry/polygon_data.py +5 -5
- pyedb/grpc/database/hfss.py +412 -395
- pyedb/grpc/database/hierarchy/component.py +67 -58
- pyedb/grpc/database/hierarchy/pin_pair_model.py +6 -6
- pyedb/grpc/database/hierarchy/pingroup.py +13 -11
- pyedb/grpc/database/hierarchy/s_parameter_model.py +1 -1
- pyedb/grpc/database/hierarchy/spice_model.py +1 -1
- pyedb/grpc/database/layers/layer.py +2 -2
- pyedb/grpc/database/layers/stackup_layer.py +26 -23
- pyedb/grpc/database/layout/layout.py +12 -12
- pyedb/grpc/database/layout/voltage_regulator.py +8 -8
- pyedb/grpc/database/layout_validation.py +58 -7
- pyedb/grpc/database/modeler.py +248 -245
- pyedb/grpc/database/net/differential_pair.py +4 -4
- pyedb/grpc/database/net/extended_net.py +7 -8
- pyedb/grpc/database/net/net.py +57 -46
- pyedb/grpc/database/nets.py +362 -116
- pyedb/grpc/database/padstacks.py +259 -178
- pyedb/grpc/database/ports/ports.py +23 -17
- pyedb/grpc/database/primitive/padstack_instance.py +45 -30
- pyedb/grpc/database/primitive/path.py +6 -6
- pyedb/grpc/database/primitive/polygon.py +9 -9
- pyedb/grpc/database/primitive/primitive.py +21 -21
- pyedb/grpc/database/primitive/rectangle.py +1 -1
- pyedb/grpc/database/simulation_setup/hfss_advanced_settings.py +1 -1
- pyedb/grpc/database/simulation_setup/hfss_general_settings.py +1 -1
- pyedb/grpc/database/simulation_setup/hfss_settings_options.py +1 -1
- pyedb/grpc/database/simulation_setup/hfss_simulation_settings.py +6 -6
- pyedb/grpc/database/simulation_setup/hfss_simulation_setup.py +2 -2
- pyedb/grpc/database/simulation_setup/raptor_x_simulation_settings.py +2 -2
- pyedb/grpc/database/simulation_setup/raptor_x_simulation_setup.py +1 -1
- pyedb/grpc/database/simulation_setup/siwave_simulation_setup.py +3 -3
- pyedb/grpc/database/siwave.py +226 -214
- pyedb/grpc/database/source_excitations.py +307 -40
- pyedb/grpc/database/stackup.py +461 -283
- pyedb/grpc/database/terminal/bundle_terminal.py +12 -12
- pyedb/grpc/database/terminal/edge_terminal.py +6 -5
- pyedb/grpc/database/terminal/padstack_instance_terminal.py +13 -13
- pyedb/grpc/database/terminal/pingroup_terminal.py +12 -12
- pyedb/grpc/database/terminal/point_terminal.py +6 -6
- pyedb/grpc/database/terminal/terminal.py +26 -26
- pyedb/grpc/database/utility/heat_sink.py +5 -5
- pyedb/grpc/database/utility/hfss_extent_info.py +21 -21
- pyedb/grpc/database/utility/layout_statistics.py +13 -13
- pyedb/grpc/database/utility/rlc.py +3 -3
- pyedb/grpc/database/utility/sources.py +1 -1
- pyedb/grpc/database/utility/sweep_data_distribution.py +1 -1
- pyedb/grpc/edb.py +542 -739
- pyedb/grpc/edb_init.py +50 -3
- {pyedb-0.50.0.dist-info → pyedb-0.51.2.dist-info}/METADATA +1 -1
- {pyedb-0.50.0.dist-info → pyedb-0.51.2.dist-info}/RECORD +74 -75
- pyedb/grpc/database/utility/simulation_configuration.py +0 -3305
- {pyedb-0.50.0.dist-info → pyedb-0.51.2.dist-info}/LICENSE +0 -0
- {pyedb-0.50.0.dist-info → pyedb-0.51.2.dist-info}/WHEEL +0 -0
pyedb/grpc/database/stackup.py
CHANGED
|
@@ -78,7 +78,15 @@ logger = logging.getLogger(__name__)
|
|
|
78
78
|
|
|
79
79
|
|
|
80
80
|
class LayerCollection(GrpcLayerCollection):
|
|
81
|
-
"""
|
|
81
|
+
"""Manages layer collections in an EDB database.
|
|
82
|
+
|
|
83
|
+
Parameters
|
|
84
|
+
----------
|
|
85
|
+
pedb : :class:`pyedb.Edb`
|
|
86
|
+
EDB object.
|
|
87
|
+
edb_object : :class:`ansys.edb.core.layer.LayerCollection`
|
|
88
|
+
EDB layer collection object.
|
|
89
|
+
"""
|
|
82
90
|
|
|
83
91
|
def __init__(self, pedb, edb_object):
|
|
84
92
|
super().__init__(edb_object.msg)
|
|
@@ -86,11 +94,13 @@ class LayerCollection(GrpcLayerCollection):
|
|
|
86
94
|
self._pedb = pedb
|
|
87
95
|
|
|
88
96
|
def update_layout(self):
|
|
89
|
-
"""
|
|
97
|
+
"""Update the layout with the current layer collection.
|
|
90
98
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
99
|
+
Examples
|
|
100
|
+
--------
|
|
101
|
+
>>> from pyedb import Edb
|
|
102
|
+
>>> edb = Edb()
|
|
103
|
+
>>> edb.stackup.update_layout()
|
|
94
104
|
"""
|
|
95
105
|
self._pedb.layout.layer_collection = self
|
|
96
106
|
|
|
@@ -101,13 +111,24 @@ class LayerCollection(GrpcLayerCollection):
|
|
|
101
111
|
----------
|
|
102
112
|
name : str
|
|
103
113
|
Name of the layer.
|
|
104
|
-
layer_type: str, optional
|
|
105
|
-
Type of the layer. The default
|
|
106
|
-
kwargs
|
|
114
|
+
layer_type : str, optional
|
|
115
|
+
Type of the layer. The default is ``"signal"``. Options are ``"signal"`` and ``"dielectric"``.
|
|
116
|
+
**kwargs : dict, optional
|
|
117
|
+
Additional keyword arguments. Possible keys are:
|
|
118
|
+
- ``thickness`` : float, layer thickness.
|
|
119
|
+
- ``material`` : str, layer material.
|
|
107
120
|
|
|
108
121
|
Returns
|
|
109
122
|
-------
|
|
123
|
+
:class:`pyedb.grpc.database.layers.stackup_layer.StackupLayer`
|
|
124
|
+
Layer object created.
|
|
110
125
|
|
|
126
|
+
Examples
|
|
127
|
+
--------
|
|
128
|
+
>>> from pyedb import Edb
|
|
129
|
+
>>> edb = Edb()
|
|
130
|
+
>>> top_layer = edb.stackup.add_layer_top("NewTopLayer", layer_type="signal", thickness="0.1mm",
|
|
131
|
+
... material="copper")
|
|
111
132
|
"""
|
|
112
133
|
thickness = GrpcValue(0.0)
|
|
113
134
|
if "thickness" in kwargs:
|
|
@@ -122,19 +143,31 @@ class LayerCollection(GrpcLayerCollection):
|
|
|
122
143
|
return self._layer_collection.add_layer_top(layer)
|
|
123
144
|
|
|
124
145
|
def add_layer_bottom(self, name, layer_type="signal", **kwargs):
|
|
125
|
-
"""Add a layer
|
|
146
|
+
"""Add a layer at the bottom of the stackup.
|
|
126
147
|
|
|
127
148
|
Parameters
|
|
128
149
|
----------
|
|
129
150
|
name : str
|
|
130
151
|
Name of the layer.
|
|
131
|
-
layer_type: str, optional
|
|
132
|
-
Type of the layer. The default
|
|
133
|
-
kwargs
|
|
152
|
+
layer_type : str, optional
|
|
153
|
+
Type of the layer. The default is ``"signal"``. Options are ``"signal"`` and ``"dielectric"``.
|
|
154
|
+
**kwargs : dict, optional
|
|
155
|
+
Additional keyword arguments. Possible keys are:
|
|
156
|
+
- ``thickness`` : float, layer thickness.
|
|
157
|
+
- ``material`` : str, layer material.
|
|
158
|
+
- ``fill_material`` : str, fill material.
|
|
134
159
|
|
|
135
160
|
Returns
|
|
136
161
|
-------
|
|
162
|
+
:class:`pyedb.grpc.database.layers.stackup_layer.StackupLayer`
|
|
163
|
+
Layer object created.
|
|
137
164
|
|
|
165
|
+
Examples
|
|
166
|
+
--------
|
|
167
|
+
>>> from pyedb import Edb
|
|
168
|
+
>>> edb = Edb()
|
|
169
|
+
>>> bot_layer = edb.stackup.add_layer_bottom("NewBottomLayer", layer_type="signal", thickness="0.1mm",
|
|
170
|
+
... material="copper")
|
|
138
171
|
"""
|
|
139
172
|
thickness = GrpcValue(0.0)
|
|
140
173
|
layer_type_map = {"dielectric": GrpcLayerType.DIELECTRIC_LAYER, "signal": GrpcLayerType.SIGNAL_LAYER}
|
|
@@ -157,21 +190,31 @@ class LayerCollection(GrpcLayerCollection):
|
|
|
157
190
|
return self._layer_collection.add_layer_bottom(layer)
|
|
158
191
|
|
|
159
192
|
def add_layer_below(self, name, base_layer_name, layer_type="signal", **kwargs):
|
|
160
|
-
"""Add a layer below a layer.
|
|
193
|
+
"""Add a layer below a specified layer.
|
|
161
194
|
|
|
162
195
|
Parameters
|
|
163
196
|
----------
|
|
164
197
|
name : str
|
|
165
198
|
Name of the layer.
|
|
166
|
-
base_layer_name: str
|
|
199
|
+
base_layer_name : str
|
|
167
200
|
Name of the base layer.
|
|
168
|
-
layer_type: str, optional
|
|
169
|
-
Type of the layer. The default
|
|
170
|
-
kwargs
|
|
201
|
+
layer_type : str, optional
|
|
202
|
+
Type of the layer. The default is ``"signal"``. Options are ``"signal"`` and ``"dielectric"``.
|
|
203
|
+
**kwargs : dict, optional
|
|
204
|
+
Additional keyword arguments. Possible keys are:
|
|
205
|
+
- ``thickness`` : float, layer thickness.
|
|
206
|
+
- ``material`` : str, layer material.
|
|
171
207
|
|
|
172
208
|
Returns
|
|
173
209
|
-------
|
|
210
|
+
:class:`pyedb.grpc.database.layers.stackup_layer.StackupLayer`
|
|
211
|
+
Layer object created.
|
|
174
212
|
|
|
213
|
+
Examples
|
|
214
|
+
--------
|
|
215
|
+
>>> from pyedb import Edb
|
|
216
|
+
>>> edb = Edb()
|
|
217
|
+
>>> new_layer = edb.stackup.add_layer_below("NewLayer", "TopLayer", layer_type="dielectric", thickness="0.05mm")
|
|
175
218
|
"""
|
|
176
219
|
thickness = GrpcValue(0.0)
|
|
177
220
|
if "thickness" in kwargs:
|
|
@@ -194,21 +237,31 @@ class LayerCollection(GrpcLayerCollection):
|
|
|
194
237
|
return self._layer_collection.add_layer_below(layer, base_layer_name)
|
|
195
238
|
|
|
196
239
|
def add_layer_above(self, name, base_layer_name, layer_type="signal", **kwargs):
|
|
197
|
-
"""Add a layer above a layer.
|
|
240
|
+
"""Add a layer above a specified layer.
|
|
198
241
|
|
|
199
242
|
Parameters
|
|
200
243
|
----------
|
|
201
244
|
name : str
|
|
202
245
|
Name of the layer.
|
|
203
|
-
base_layer_name: str
|
|
246
|
+
base_layer_name : str
|
|
204
247
|
Name of the base layer.
|
|
205
|
-
layer_type: str, optional
|
|
206
|
-
Type of the layer. The default
|
|
207
|
-
kwargs
|
|
248
|
+
layer_type : str, optional
|
|
249
|
+
Type of the layer. The default is ``"signal"``. Options are ``"signal"`` and ``"dielectric"``.
|
|
250
|
+
**kwargs : dict, optional
|
|
251
|
+
Additional keyword arguments. Possible keys are:
|
|
252
|
+
- ``thickness`` : float, layer thickness.
|
|
253
|
+
- ``material`` : str, layer material.
|
|
208
254
|
|
|
209
255
|
Returns
|
|
210
256
|
-------
|
|
257
|
+
:class:`pyedb.grpc.database.layers.stackup_layer.StackupLayer`
|
|
258
|
+
Layer object created.
|
|
211
259
|
|
|
260
|
+
Examples
|
|
261
|
+
--------
|
|
262
|
+
>>> from pyedb import Edb
|
|
263
|
+
>>> edb = Edb()
|
|
264
|
+
>>> new_layer = edb.stackup.add_layer_above("NewLayer", "BottomLayer", layer_type="signal", thickness="0.05mm")
|
|
212
265
|
"""
|
|
213
266
|
thickness = GrpcValue(0.0)
|
|
214
267
|
if "thickness" in kwargs:
|
|
@@ -229,13 +282,21 @@ class LayerCollection(GrpcLayerCollection):
|
|
|
229
282
|
----------
|
|
230
283
|
name : str
|
|
231
284
|
Name of the layer.
|
|
232
|
-
layer_type: str, optional
|
|
233
|
-
Type of the layer. The default is ``"user"``. Options are ``"user"
|
|
234
|
-
kwargs
|
|
285
|
+
layer_type : str, optional
|
|
286
|
+
Type of the layer. The default is ``"user"``. Options are ``"user"`` and ``"outline"``.
|
|
287
|
+
**kwargs : dict, optional
|
|
288
|
+
Additional keyword arguments.
|
|
235
289
|
|
|
236
290
|
Returns
|
|
237
291
|
-------
|
|
292
|
+
:class:`pyedb.grpc.database.layers.layer.Layer`
|
|
293
|
+
Layer object created.
|
|
238
294
|
|
|
295
|
+
Examples
|
|
296
|
+
--------
|
|
297
|
+
>>> from pyedb import Edb
|
|
298
|
+
>>> edb = Edb()
|
|
299
|
+
>>> outline_layer = edb.stackup.add_document_layer("Outline", layer_type="outline")
|
|
239
300
|
"""
|
|
240
301
|
added_layer = self.add_layer_top(name)
|
|
241
302
|
added_layer.type = GrpcLayerType.USER_LAYER
|
|
@@ -243,29 +304,89 @@ class LayerCollection(GrpcLayerCollection):
|
|
|
243
304
|
|
|
244
305
|
@property
|
|
245
306
|
def stackup_layers(self):
|
|
246
|
-
"""Retrieve the dictionary of signal and dielectric layers.
|
|
307
|
+
"""Retrieve the dictionary of signal and dielectric layers.
|
|
308
|
+
|
|
309
|
+
.. deprecated:: 0.6.61
|
|
310
|
+
Use :func:`layers` instead.
|
|
311
|
+
|
|
312
|
+
Returns
|
|
313
|
+
-------
|
|
314
|
+
dict[str, :class:`pyedb.grpc.database.layers.stackup_layer.StackupLayer`]
|
|
315
|
+
Dictionary of stackup layers.
|
|
316
|
+
"""
|
|
247
317
|
warnings.warn("Use new property :func:`layers` instead.", DeprecationWarning)
|
|
248
318
|
return self.layers
|
|
249
319
|
|
|
250
320
|
@property
|
|
251
321
|
def non_stackup_layers(self):
|
|
252
|
-
"""Retrieve the dictionary of
|
|
322
|
+
"""Retrieve the dictionary of non-stackup layers.
|
|
323
|
+
|
|
324
|
+
Returns
|
|
325
|
+
-------
|
|
326
|
+
dict[str, :class:`pyedb.grpc.database.layers.layer.Layer`]
|
|
327
|
+
Dictionary of non-stackup layers.
|
|
328
|
+
|
|
329
|
+
Examples
|
|
330
|
+
--------
|
|
331
|
+
>>> from pyedb import Edb
|
|
332
|
+
>>> edb = Edb()
|
|
333
|
+
>>> non_stackup = edb.stackup.non_stackup_layers
|
|
334
|
+
"""
|
|
253
335
|
return {
|
|
254
336
|
layer.name: Layer(self._pedb, layer) for layer in self.get_layers(GrpcLayerTypeSet.NON_STACKUP_LAYER_SET)
|
|
255
337
|
}
|
|
256
338
|
|
|
257
339
|
@property
|
|
258
340
|
def all_layers(self):
|
|
341
|
+
"""Retrieve all layers.
|
|
342
|
+
|
|
343
|
+
Returns
|
|
344
|
+
-------
|
|
345
|
+
dict[str, :class:`pyedb.grpc.database.layers.layer.Layer`]
|
|
346
|
+
Dictionary of all layers.
|
|
347
|
+
|
|
348
|
+
Examples
|
|
349
|
+
--------
|
|
350
|
+
>>> from pyedb import Edb
|
|
351
|
+
>>> edb = Edb()
|
|
352
|
+
>>> all_layers = edb.stackup.all_layers
|
|
353
|
+
"""
|
|
259
354
|
return {layer.name: Layer(self._pedb, layer) for layer in self.get_layers(GrpcLayerTypeSet.ALL_LAYER_SET)}
|
|
260
355
|
|
|
261
356
|
@property
|
|
262
357
|
def signal_layers(self):
|
|
358
|
+
"""Retrieve the dictionary of signal layers.
|
|
359
|
+
|
|
360
|
+
Returns
|
|
361
|
+
-------
|
|
362
|
+
dict[str, :class:`pyedb.grpc.database.layers.stackup_layer.StackupLayer`]
|
|
363
|
+
Dictionary of signal layers.
|
|
364
|
+
|
|
365
|
+
Examples
|
|
366
|
+
--------
|
|
367
|
+
>>> from pyedb import Edb
|
|
368
|
+
>>> edb = Edb()
|
|
369
|
+
>>> signal_layers = edb.stackup.signal_layers
|
|
370
|
+
"""
|
|
263
371
|
return {
|
|
264
372
|
layer.name: StackupLayer(self._pedb, layer) for layer in self.get_layers(GrpcLayerTypeSet.SIGNAL_LAYER_SET)
|
|
265
373
|
}
|
|
266
374
|
|
|
267
375
|
@property
|
|
268
376
|
def dielectric_layers(self):
|
|
377
|
+
"""Retrieve the dictionary of dielectric layers.
|
|
378
|
+
|
|
379
|
+
Returns
|
|
380
|
+
-------
|
|
381
|
+
dict[str, :class:`pyedb.grpc.database.layers.stackup_layer.StackupLayer`]
|
|
382
|
+
Dictionary of dielectric layers.
|
|
383
|
+
|
|
384
|
+
Examples
|
|
385
|
+
--------
|
|
386
|
+
>>> from pyedb import Edb
|
|
387
|
+
>>> edb = Edb()
|
|
388
|
+
>>> dielectric_layers = edb.stackup.dielectric_layers
|
|
389
|
+
"""
|
|
269
390
|
return {
|
|
270
391
|
layer.name: StackupLayer(self._pedb, layer)
|
|
271
392
|
for layer in self.get_layers(GrpcLayerTypeSet.DIELECTRIC_LAYER_SET)
|
|
@@ -273,25 +394,58 @@ class LayerCollection(GrpcLayerCollection):
|
|
|
273
394
|
|
|
274
395
|
@property
|
|
275
396
|
def layers_by_id(self):
|
|
276
|
-
"""Retrieve the list of layers with their
|
|
397
|
+
"""Retrieve the list of layers with their IDs.
|
|
398
|
+
|
|
399
|
+
Returns
|
|
400
|
+
-------
|
|
401
|
+
list[list[int, str]]
|
|
402
|
+
List of layers with their IDs and names.
|
|
403
|
+
|
|
404
|
+
Examples
|
|
405
|
+
--------
|
|
406
|
+
>>> from pyedb import Edb
|
|
407
|
+
>>> edb = Edb()
|
|
408
|
+
>>> layers_by_id = edb.stackup.layers_by_id
|
|
409
|
+
"""
|
|
277
410
|
return [[obj.id, name] for name, obj in self.all_layers.items()]
|
|
278
411
|
|
|
279
412
|
@property
|
|
280
413
|
def layers(self):
|
|
281
|
-
"""Retrieve the dictionary of layers.
|
|
414
|
+
"""Retrieve the dictionary of stackup layers (signal and dielectric).
|
|
282
415
|
|
|
283
416
|
Returns
|
|
284
417
|
-------
|
|
285
|
-
|
|
418
|
+
dict[str, :class:`pyedb.grpc.database.layers.stackup_layer.StackupLayer`]
|
|
419
|
+
Dictionary of stackup layers.
|
|
420
|
+
|
|
421
|
+
Examples
|
|
422
|
+
--------
|
|
423
|
+
>>> from pyedb import Edb
|
|
424
|
+
>>> edb = Edb()
|
|
425
|
+
>>> layers = edb.stackup.layers
|
|
286
426
|
"""
|
|
287
427
|
return {obj.name: StackupLayer(self._pedb, obj) for obj in self.get_layers(GrpcLayerTypeSet.STACKUP_LAYER_SET)}
|
|
288
428
|
|
|
289
429
|
def find_layer_by_name(self, name: str):
|
|
290
|
-
"""
|
|
430
|
+
"""Find a layer by its name.
|
|
291
431
|
|
|
292
|
-
|
|
293
|
-
|
|
432
|
+
.. deprecated:: 0.29.0
|
|
433
|
+
Use :func:`find_by_name` instead.
|
|
294
434
|
|
|
435
|
+
Parameters
|
|
436
|
+
----------
|
|
437
|
+
name : str
|
|
438
|
+
Name of the layer.
|
|
439
|
+
|
|
440
|
+
Returns
|
|
441
|
+
-------
|
|
442
|
+
:class:`ansys.edb.core.layer.Layer`
|
|
443
|
+
Layer object found.
|
|
444
|
+
|
|
445
|
+
Raises
|
|
446
|
+
------
|
|
447
|
+
ValueError
|
|
448
|
+
If no layer with the given name is found.
|
|
295
449
|
"""
|
|
296
450
|
warnings.warn(
|
|
297
451
|
"`find_layer_by_name` is deprecated and is now located here "
|
|
@@ -305,7 +459,15 @@ class LayerCollection(GrpcLayerCollection):
|
|
|
305
459
|
|
|
306
460
|
|
|
307
461
|
class Stackup(LayerCollection):
|
|
308
|
-
"""Manages EDB methods for stackup.
|
|
462
|
+
"""Manages EDB methods for stackup operations.
|
|
463
|
+
|
|
464
|
+
Parameters
|
|
465
|
+
----------
|
|
466
|
+
pedb : :class:`pyedb.Edb`
|
|
467
|
+
EDB object.
|
|
468
|
+
edb_object : :class:`ansys.edb.core.layer.LayerCollection`, optional
|
|
469
|
+
EDB layer collection object. The default is ``None``.
|
|
470
|
+
"""
|
|
309
471
|
|
|
310
472
|
def __init__(self, pedb, edb_object=None):
|
|
311
473
|
super().__init__(pedb, edb_object)
|
|
@@ -325,25 +487,35 @@ class Stackup(LayerCollection):
|
|
|
325
487
|
|
|
326
488
|
@property
|
|
327
489
|
def thickness(self):
|
|
328
|
-
"""Retrieve
|
|
490
|
+
"""Retrieve the stackup thickness.
|
|
329
491
|
|
|
330
492
|
Returns
|
|
331
493
|
-------
|
|
332
494
|
float
|
|
333
|
-
|
|
495
|
+
Stackup thickness.
|
|
334
496
|
|
|
497
|
+
Examples
|
|
498
|
+
--------
|
|
499
|
+
>>> from pyedb import Edb
|
|
500
|
+
>>> edb = Edb()
|
|
501
|
+
>>> thickness = edb.stackup.thickness
|
|
335
502
|
"""
|
|
336
503
|
return self.get_layout_thickness()
|
|
337
504
|
|
|
338
505
|
@property
|
|
339
506
|
def num_layers(self):
|
|
340
|
-
"""Retrieve the
|
|
507
|
+
"""Retrieve the number of layers in the stackup.
|
|
341
508
|
|
|
342
509
|
Returns
|
|
343
510
|
-------
|
|
344
511
|
int
|
|
345
|
-
|
|
512
|
+
Number of layers.
|
|
346
513
|
|
|
514
|
+
Examples
|
|
515
|
+
--------
|
|
516
|
+
>>> from pyedb import Edb
|
|
517
|
+
>>> edb = Edb()
|
|
518
|
+
>>> num_layers = edb.stackup.num_layers
|
|
347
519
|
"""
|
|
348
520
|
return len(list(self.layers.keys()))
|
|
349
521
|
|
|
@@ -356,13 +528,13 @@ class Stackup(LayerCollection):
|
|
|
356
528
|
dielectric_material="FR4_epoxy",
|
|
357
529
|
soldermask=True,
|
|
358
530
|
soldermask_thickness="20um",
|
|
359
|
-
): # pragma: no cover
|
|
531
|
+
) -> bool: # pragma: no cover
|
|
360
532
|
"""Create a symmetric stackup.
|
|
361
533
|
|
|
362
534
|
Parameters
|
|
363
535
|
----------
|
|
364
536
|
layer_count : int
|
|
365
|
-
Number of
|
|
537
|
+
Number of layers. Must be even.
|
|
366
538
|
inner_layer_thickness : str, float, optional
|
|
367
539
|
Thickness of inner conductor layer.
|
|
368
540
|
outer_layer_thickness : str, float, optional
|
|
@@ -372,13 +544,20 @@ class Stackup(LayerCollection):
|
|
|
372
544
|
dielectric_material : str, optional
|
|
373
545
|
Material of dielectric layer.
|
|
374
546
|
soldermask : bool, optional
|
|
375
|
-
Whether to create soldermask layers. The default is``True``.
|
|
547
|
+
Whether to create soldermask layers. The default is ``True``.
|
|
376
548
|
soldermask_thickness : str, optional
|
|
377
549
|
Thickness of soldermask layer.
|
|
378
550
|
|
|
379
551
|
Returns
|
|
380
552
|
-------
|
|
381
553
|
bool
|
|
554
|
+
``True`` when successful, ``False`` when failed.
|
|
555
|
+
|
|
556
|
+
Examples
|
|
557
|
+
--------
|
|
558
|
+
>>> from pyedb import Edb
|
|
559
|
+
>>> edb = Edb()
|
|
560
|
+
>>> edb.stackup.create_symmetric_stackup(layer_count=4)
|
|
382
561
|
"""
|
|
383
562
|
if not np:
|
|
384
563
|
self._pedb.logger.error("Numpy is needed. Please, install it first.")
|
|
@@ -475,12 +654,17 @@ class Stackup(LayerCollection):
|
|
|
475
654
|
|
|
476
655
|
Returns
|
|
477
656
|
-------
|
|
478
|
-
|
|
479
|
-
Type of the stackup mode
|
|
657
|
+
str
|
|
658
|
+
Type of the stackup mode. Options are:
|
|
659
|
+
- ``"laminate"``
|
|
660
|
+
- ``"overlapping"``
|
|
661
|
+
- ``"multizone"``
|
|
480
662
|
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
663
|
+
Examples
|
|
664
|
+
--------
|
|
665
|
+
>>> from pyedb import Edb
|
|
666
|
+
>>> edb = Edb()
|
|
667
|
+
>>> mode = edb.stackup.mode
|
|
484
668
|
"""
|
|
485
669
|
return super().mode.name.lower()
|
|
486
670
|
|
|
@@ -504,16 +688,19 @@ class Stackup(LayerCollection):
|
|
|
504
688
|
|
|
505
689
|
Parameters
|
|
506
690
|
----------
|
|
507
|
-
layer_clone : :class:`
|
|
691
|
+
layer_clone : :class:`ansys.edb.core.layer.StackupLayer`
|
|
692
|
+
Layer object to apply.
|
|
508
693
|
operation : str
|
|
509
|
-
Options are ``"change_attribute"``, ``"change_name"
|
|
510
|
-
|
|
694
|
+
Operation to perform. Options are ``"change_attribute"``, ``"change_name"``, ``"change_position"``,
|
|
695
|
+
``"insert_below"``, ``"insert_above"``, ``"add_on_top"``, ``"add_on_bottom"``, ``"non_stackup"``,
|
|
696
|
+
and ``"add_at_elevation"``.
|
|
511
697
|
base_layer : str, optional
|
|
512
698
|
Name of the base layer. The default value is ``None``.
|
|
513
699
|
|
|
514
700
|
Returns
|
|
515
701
|
-------
|
|
516
|
-
|
|
702
|
+
bool
|
|
703
|
+
``True`` when successful.
|
|
517
704
|
"""
|
|
518
705
|
lc = self._pedb.layout.layer_collection
|
|
519
706
|
if operation in ["change_position", "change_attribute", "change_name"]:
|
|
@@ -605,17 +792,21 @@ class Stackup(LayerCollection):
|
|
|
605
792
|
return result
|
|
606
793
|
|
|
607
794
|
def add_outline_layer(self, outline_name="Outline"):
|
|
608
|
-
"""Add an outline layer named
|
|
795
|
+
"""Add an outline layer named "Outline" if it is not present.
|
|
609
796
|
|
|
610
797
|
Returns
|
|
611
798
|
-------
|
|
612
799
|
bool
|
|
613
|
-
|
|
800
|
+
``True`` when successful.
|
|
801
|
+
|
|
802
|
+
Examples
|
|
803
|
+
--------
|
|
804
|
+
>>> from pyedb import Edb
|
|
805
|
+
>>> edb = Edb()
|
|
806
|
+
>>> edb.stackup.add_outline_layer()
|
|
614
807
|
"""
|
|
615
808
|
return self.add_document_layer(name="Outline", layer_type="outline")
|
|
616
809
|
|
|
617
|
-
# TODO: Update optional argument material into material_name and fillMaterial into fill_material_name
|
|
618
|
-
|
|
619
810
|
def add_layer(
|
|
620
811
|
self,
|
|
621
812
|
layer_name,
|
|
@@ -639,12 +830,29 @@ class Stackup(LayerCollection):
|
|
|
639
830
|
base_layer : str, optional
|
|
640
831
|
Name of the base layer.
|
|
641
832
|
method : str, optional
|
|
642
|
-
Where to insert the new layer. The default is ``"add_on_top"``. Options are
|
|
643
|
-
|
|
833
|
+
Where to insert the new layer. The default is ``"add_on_top"``. Options are:
|
|
834
|
+
- ``"add_on_top"``
|
|
835
|
+
- ``"add_on_bottom"``
|
|
836
|
+
- ``"insert_above"``
|
|
837
|
+
- ``"insert_below"``
|
|
838
|
+
- ``"add_at_elevation"``
|
|
644
839
|
layer_type : str, optional
|
|
645
|
-
Type of layer. The default is ``"signal"``. Options are
|
|
646
|
-
|
|
647
|
-
|
|
840
|
+
Type of layer. The default is ``"signal"``. Options are:
|
|
841
|
+
- ``"signal"``
|
|
842
|
+
- ``"dielectric"``
|
|
843
|
+
- ``"conducting"``
|
|
844
|
+
- ``"air_lines"``
|
|
845
|
+
- ``"error"``
|
|
846
|
+
- ``"symbol"``
|
|
847
|
+
- ``"measure"``
|
|
848
|
+
- ``"assembly"``
|
|
849
|
+
- ``"silkscreen"``
|
|
850
|
+
- ``"solder_mask"``
|
|
851
|
+
- ``"solder_paste"``
|
|
852
|
+
- ``"glue"``
|
|
853
|
+
- ``"wirebond"``
|
|
854
|
+
- ``"hfss_region"``
|
|
855
|
+
- ``"user"``
|
|
648
856
|
material : str, optional
|
|
649
857
|
Material of the layer.
|
|
650
858
|
fillMaterial : str, optional
|
|
@@ -662,7 +870,8 @@ class Stackup(LayerCollection):
|
|
|
662
870
|
|
|
663
871
|
Returns
|
|
664
872
|
-------
|
|
665
|
-
:class:`pyedb.
|
|
873
|
+
:class:`pyedb.grpc.database.layers.stackup_layer.StackupLayer`
|
|
874
|
+
Layer object created.
|
|
666
875
|
"""
|
|
667
876
|
if layer_name in self.layers:
|
|
668
877
|
logger.error("layer {} exists.".format(layer_name))
|
|
@@ -721,7 +930,8 @@ class Stackup(LayerCollection):
|
|
|
721
930
|
|
|
722
931
|
Returns
|
|
723
932
|
-------
|
|
724
|
-
|
|
933
|
+
bool
|
|
934
|
+
``True`` when successful.
|
|
725
935
|
"""
|
|
726
936
|
new_layer_collection = LayerCollection.create()
|
|
727
937
|
for layer_name, lyr in self.layers.items():
|
|
@@ -732,19 +942,26 @@ class Stackup(LayerCollection):
|
|
|
732
942
|
return True
|
|
733
943
|
|
|
734
944
|
def export(self, fpath, file_format="xml", include_material_with_layer=False):
|
|
735
|
-
"""Export stackup definition to a
|
|
945
|
+
"""Export stackup definition to a file.
|
|
736
946
|
|
|
737
947
|
Parameters
|
|
738
948
|
----------
|
|
739
949
|
fpath : str
|
|
740
|
-
File path to
|
|
950
|
+
File path to export to.
|
|
741
951
|
file_format : str, optional
|
|
742
|
-
Format of the file to export. The default is ``"
|
|
743
|
-
``"
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
952
|
+
Format of the file to export. The default is ``"xml"``. Options are:
|
|
953
|
+
- ``"csv"``
|
|
954
|
+
- ``"xlsx"``
|
|
955
|
+
- ``"json"``
|
|
956
|
+
- ``"xml"``
|
|
957
|
+
include_material_with_layer : bool, optional
|
|
958
|
+
Whether to include the material definition inside layer objects. This parameter is only used
|
|
959
|
+
when a JSON file is exported. The default is ``False``.
|
|
960
|
+
|
|
961
|
+
Returns
|
|
962
|
+
-------
|
|
963
|
+
bool
|
|
964
|
+
``True`` when successful.
|
|
748
965
|
|
|
749
966
|
Examples
|
|
750
967
|
--------
|
|
@@ -768,7 +985,7 @@ class Stackup(LayerCollection):
|
|
|
768
985
|
return False
|
|
769
986
|
|
|
770
987
|
def export_stackup(self, fpath, file_format="xml", include_material_with_layer=False):
|
|
771
|
-
"""Export stackup definition to a
|
|
988
|
+
"""Export stackup definition to a file.
|
|
772
989
|
|
|
773
990
|
.. deprecated:: 0.6.61
|
|
774
991
|
Use :func:`export` instead.
|
|
@@ -776,14 +993,15 @@ class Stackup(LayerCollection):
|
|
|
776
993
|
Parameters
|
|
777
994
|
----------
|
|
778
995
|
fpath : str
|
|
779
|
-
File path to
|
|
996
|
+
File path to export to.
|
|
780
997
|
file_format : str, optional
|
|
781
|
-
Format of the file to export. The default is ``"
|
|
782
|
-
|
|
783
|
-
|
|
998
|
+
Format of the file to export. The default is ``"xml"``. Options are:
|
|
999
|
+
- ``"csv"``
|
|
1000
|
+
- ``"xlsx"``
|
|
1001
|
+
- ``"json"``
|
|
1002
|
+
include_material_with_layer : bool, optional
|
|
784
1003
|
Whether to include the material definition inside layer objects. This parameter is only used
|
|
785
|
-
when a JSON file is exported. The default is ``False
|
|
786
|
-
section in the JSON file. If ``True``, the material definition is included inside the layer ones.
|
|
1004
|
+
when a JSON file is exported. The default is ``False``.
|
|
787
1005
|
|
|
788
1006
|
Examples
|
|
789
1007
|
--------
|
|
@@ -855,57 +1073,6 @@ class Stackup(LayerCollection):
|
|
|
855
1073
|
else:
|
|
856
1074
|
return False
|
|
857
1075
|
|
|
858
|
-
# TODO: This method might need some refactoring
|
|
859
|
-
|
|
860
|
-
def _import_layer_stackup(self, input_file=None):
|
|
861
|
-
if input_file:
|
|
862
|
-
f = open(input_file)
|
|
863
|
-
json_dict = json.load(f) # pragma: no cover
|
|
864
|
-
for k, v in json_dict.items():
|
|
865
|
-
if k == "materials":
|
|
866
|
-
for material in v.values():
|
|
867
|
-
material_name = material["name"]
|
|
868
|
-
del material["name"]
|
|
869
|
-
if material_name not in self._pedb.materials:
|
|
870
|
-
self._pedb.materials.add_material(material_name, **material)
|
|
871
|
-
else:
|
|
872
|
-
self._pedb.materials.update_material(material_name, material)
|
|
873
|
-
if k == "layers":
|
|
874
|
-
if len(list(v.values())) == len(list(self.layers.values())):
|
|
875
|
-
imported_layers_list = [l_dict["name"] for l_dict in list(v.values())]
|
|
876
|
-
layout_layer_list = list(self.layers.keys())
|
|
877
|
-
for layer_name in imported_layers_list:
|
|
878
|
-
layer_index = imported_layers_list.index(layer_name)
|
|
879
|
-
if layout_layer_list[layer_index] != layer_name:
|
|
880
|
-
self.layers[layout_layer_list[layer_index]].name = layer_name
|
|
881
|
-
prev_layer = None
|
|
882
|
-
for layer_name, layer in v.items():
|
|
883
|
-
if layer["name"] not in self.layers:
|
|
884
|
-
if not prev_layer:
|
|
885
|
-
self.add_layer(
|
|
886
|
-
layer_name,
|
|
887
|
-
method="add_on_top",
|
|
888
|
-
layer_type=layer["type"],
|
|
889
|
-
material=layer["material"],
|
|
890
|
-
fillMaterial=layer["dielectric_fill"],
|
|
891
|
-
thickness=layer["thickness"],
|
|
892
|
-
)
|
|
893
|
-
prev_layer = layer_name
|
|
894
|
-
else:
|
|
895
|
-
self.add_layer(
|
|
896
|
-
layer_name,
|
|
897
|
-
base_layer=layer_name,
|
|
898
|
-
method="insert_below",
|
|
899
|
-
layer_type=layer["type"],
|
|
900
|
-
material=layer["material"],
|
|
901
|
-
fillMaterial=layer["dielectric_fill"],
|
|
902
|
-
thickness=layer["thickness"],
|
|
903
|
-
)
|
|
904
|
-
prev_layer = layer_name
|
|
905
|
-
if layer_name in self.layers:
|
|
906
|
-
self.layers[layer["name"]]._load_layer(layer)
|
|
907
|
-
return True
|
|
908
|
-
|
|
909
1076
|
def limits(self, only_metals=False):
|
|
910
1077
|
"""Retrieve stackup limits.
|
|
911
1078
|
|
|
@@ -916,8 +1083,12 @@ class Stackup(LayerCollection):
|
|
|
916
1083
|
|
|
917
1084
|
Returns
|
|
918
1085
|
-------
|
|
919
|
-
|
|
920
|
-
|
|
1086
|
+
tuple
|
|
1087
|
+
Tuple containing:
|
|
1088
|
+
- Upper layer name
|
|
1089
|
+
- Upper layer top elevation
|
|
1090
|
+
- Lower layer name
|
|
1091
|
+
- Lower layer bottom elevation
|
|
921
1092
|
"""
|
|
922
1093
|
if only_metals:
|
|
923
1094
|
input_layers = GrpcLayerTypeSet.SIGNAL_LAYER_SET
|
|
@@ -937,11 +1108,11 @@ class Stackup(LayerCollection):
|
|
|
937
1108
|
Returns
|
|
938
1109
|
-------
|
|
939
1110
|
bool
|
|
940
|
-
``True`` when
|
|
1111
|
+
``True`` when successful.
|
|
941
1112
|
|
|
942
1113
|
Examples
|
|
943
1114
|
--------
|
|
944
|
-
>>> edb = Edb(edbpath=targetfile,
|
|
1115
|
+
>>> edb = Edb(edbpath=targetfile, edbversion="2021.2")
|
|
945
1116
|
>>> edb.stackup.flip_design()
|
|
946
1117
|
>>> edb.save()
|
|
947
1118
|
>>> edb.close_edb()
|
|
@@ -1037,7 +1208,7 @@ class Stackup(LayerCollection):
|
|
|
1037
1208
|
Returns
|
|
1038
1209
|
-------
|
|
1039
1210
|
float
|
|
1040
|
-
|
|
1211
|
+
Thickness value.
|
|
1041
1212
|
"""
|
|
1042
1213
|
layers = list(self.layers.values())
|
|
1043
1214
|
layers.sort(key=lambda lay: lay.lower_elevation)
|
|
@@ -1069,13 +1240,15 @@ class Stackup(LayerCollection):
|
|
|
1069
1240
|
val.component_property = comp_prop
|
|
1070
1241
|
|
|
1071
1242
|
def adjust_solder_dielectrics(self):
|
|
1072
|
-
"""Adjust the stack-up by adding or modifying dielectric layers that
|
|
1073
|
-
|
|
1074
|
-
the
|
|
1243
|
+
"""Adjust the stack-up by adding or modifying dielectric layers that contain solder balls.
|
|
1244
|
+
|
|
1245
|
+
This method identifies the solder-ball height and adjusts the dielectric thickness on top (or bottom)
|
|
1246
|
+
to fit the thickness in order to merge another layout.
|
|
1075
1247
|
|
|
1076
1248
|
Returns
|
|
1077
1249
|
-------
|
|
1078
1250
|
bool
|
|
1251
|
+
``True`` when successful.
|
|
1079
1252
|
"""
|
|
1080
1253
|
for el, val in self._pedb.components.instances.items():
|
|
1081
1254
|
if val.solder_ball_height:
|
|
@@ -1113,33 +1286,33 @@ class Stackup(LayerCollection):
|
|
|
1113
1286
|
flipped_stackup=True,
|
|
1114
1287
|
place_on_top=True,
|
|
1115
1288
|
):
|
|
1116
|
-
"""Place current
|
|
1117
|
-
|
|
1289
|
+
"""Place current cell into another cell using layer placement method.
|
|
1290
|
+
|
|
1291
|
+
Flip the current layer stackup of a layout if requested.
|
|
1118
1292
|
|
|
1119
1293
|
Parameters
|
|
1120
1294
|
----------
|
|
1121
|
-
edb : Edb
|
|
1122
|
-
|
|
1123
|
-
angle :
|
|
1124
|
-
|
|
1125
|
-
offset_x :
|
|
1126
|
-
|
|
1127
|
-
offset_y :
|
|
1128
|
-
|
|
1295
|
+
edb : :class:`pyedb.Edb`
|
|
1296
|
+
Target Edb object.
|
|
1297
|
+
angle : float, optional
|
|
1298
|
+
Rotation angle in degrees. The default is ``0.0``.
|
|
1299
|
+
offset_x : float, optional
|
|
1300
|
+
X offset value. The default is ``0.0``.
|
|
1301
|
+
offset_y : float, optional
|
|
1302
|
+
Y offset value. The default is ``0.0``.
|
|
1129
1303
|
flipped_stackup : bool, optional
|
|
1130
|
-
|
|
1131
|
-
If `True` and place_on_top is `True` the stackup will be flipped before the merge.
|
|
1304
|
+
Whether to flip the current layout. The default is ``True``.
|
|
1132
1305
|
place_on_top : bool, optional
|
|
1133
|
-
|
|
1306
|
+
Whether to place the current layout on top of the destination layout. The default is ``True``.
|
|
1134
1307
|
|
|
1135
1308
|
Returns
|
|
1136
1309
|
-------
|
|
1137
1310
|
bool
|
|
1138
|
-
``True`` when
|
|
1311
|
+
``True`` when successful.
|
|
1139
1312
|
|
|
1140
1313
|
Examples
|
|
1141
1314
|
--------
|
|
1142
|
-
>>> edb1 = Edb(edbpath=targetfile1,
|
|
1315
|
+
>>> edb1 = Edb(edbpath=targetfile1, edbversion="2021.2")
|
|
1143
1316
|
>>> edb2 = Edb(edbpath=targetfile2, edbversion="2021.2")
|
|
1144
1317
|
|
|
1145
1318
|
>>> hosting_cmp = edb1.components.get_component_by_name("U100")
|
|
@@ -1202,36 +1375,35 @@ class Stackup(LayerCollection):
|
|
|
1202
1375
|
place_on_top=True,
|
|
1203
1376
|
solder_height=0,
|
|
1204
1377
|
):
|
|
1205
|
-
"""Place current
|
|
1206
|
-
|
|
1378
|
+
"""Place current cell into another cell using 3D placement method.
|
|
1379
|
+
|
|
1380
|
+
Flip the current layer stackup of a layout if requested.
|
|
1207
1381
|
|
|
1208
1382
|
Parameters
|
|
1209
1383
|
----------
|
|
1210
|
-
edb : Edb
|
|
1211
|
-
|
|
1212
|
-
angle :
|
|
1213
|
-
|
|
1214
|
-
offset_x :
|
|
1215
|
-
|
|
1216
|
-
offset_y :
|
|
1217
|
-
|
|
1384
|
+
edb : :class:`pyedb.Edb`
|
|
1385
|
+
Target Edb object.
|
|
1386
|
+
angle : float, optional
|
|
1387
|
+
Rotation angle in degrees. The default is ``0.0``.
|
|
1388
|
+
offset_x : float, optional
|
|
1389
|
+
X offset value. The default is ``0.0``.
|
|
1390
|
+
offset_y : float, optional
|
|
1391
|
+
Y offset value. The default is ``0.0``.
|
|
1218
1392
|
flipped_stackup : bool, optional
|
|
1219
|
-
|
|
1220
|
-
If `True` and place_on_top is `True` the stackup will be flipped before the merge.
|
|
1393
|
+
Whether to flip the current layout. The default is ``True``.
|
|
1221
1394
|
place_on_top : bool, optional
|
|
1222
|
-
|
|
1395
|
+
Whether to place the current layout on top of the destination layout. The default is ``True``.
|
|
1223
1396
|
solder_height : float, optional
|
|
1224
|
-
Solder
|
|
1225
|
-
This value will be added to the elevation to align the two layouts.
|
|
1397
|
+
Solder ball or bumps height. This value will be added to the elevation to align the two layouts.
|
|
1226
1398
|
|
|
1227
1399
|
Returns
|
|
1228
1400
|
-------
|
|
1229
1401
|
bool
|
|
1230
|
-
``True`` when
|
|
1402
|
+
``True`` when successful.
|
|
1231
1403
|
|
|
1232
1404
|
Examples
|
|
1233
1405
|
--------
|
|
1234
|
-
>>> edb1 = Edb(edbpath=targetfile1,
|
|
1406
|
+
>>> edb1 = Edb(edbpath=targetfile1, edbversion="2021.2")
|
|
1235
1407
|
>>> edb2 = Edb(edbpath=targetfile2, edbversion="2021.2")
|
|
1236
1408
|
>>> hosting_cmp = edb1.components.get_component_by_name("U100")
|
|
1237
1409
|
>>> mounted_cmp = edb2.components.get_component_by_name("BGA")
|
|
@@ -1335,48 +1507,31 @@ class Stackup(LayerCollection):
|
|
|
1335
1507
|
place_on_top=True,
|
|
1336
1508
|
solder_height=0,
|
|
1337
1509
|
):
|
|
1338
|
-
"""Place
|
|
1339
|
-
Flip the current layer stackup of a layout if requested. Transform parameters currently not supported.
|
|
1510
|
+
"""Place a component instance in the layout using 3D placement.
|
|
1340
1511
|
|
|
1341
1512
|
Parameters
|
|
1342
1513
|
----------
|
|
1343
|
-
component_edb : Edb
|
|
1344
|
-
|
|
1345
|
-
angle :
|
|
1346
|
-
|
|
1347
|
-
offset_x :
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
The default
|
|
1353
|
-
offset_z : double, optional
|
|
1354
|
-
The z offset value. (i.e. elevation offset for placement relative to the top layer conductor).
|
|
1355
|
-
The default value is ``0.0``, which places the cell layout on top of the top conductor
|
|
1356
|
-
layer of the target EDB.
|
|
1514
|
+
component_edb : :class:`pyedb.Edb`
|
|
1515
|
+
Component Edb object to place.
|
|
1516
|
+
angle : float, optional
|
|
1517
|
+
Rotation angle in degrees. The default is ``0.0``.
|
|
1518
|
+
offset_x : float, optional
|
|
1519
|
+
X offset value. The default is ``0.0``.
|
|
1520
|
+
offset_y : float, optional
|
|
1521
|
+
Y offset value. The default is ``0.0``.
|
|
1522
|
+
offset_z : float, optional
|
|
1523
|
+
Z offset value (elevation offset). The default is ``0.0``.
|
|
1357
1524
|
flipped_stackup : bool, optional
|
|
1358
|
-
|
|
1359
|
-
If `True` and place_on_top is `True` the stackup will be flipped before the merge.
|
|
1525
|
+
Whether to flip the component stackup. The default is ``True``.
|
|
1360
1526
|
place_on_top : bool, optional
|
|
1361
|
-
|
|
1527
|
+
Whether to place the component on top of the target layout. The default is ``True``.
|
|
1362
1528
|
solder_height : float, optional
|
|
1363
|
-
Solder
|
|
1364
|
-
This value will be added to the elevation to align the two layouts.
|
|
1529
|
+
Solder ball or bumps height. The default is ``0``.
|
|
1365
1530
|
|
|
1366
1531
|
Returns
|
|
1367
1532
|
-------
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
Examples
|
|
1372
|
-
--------
|
|
1373
|
-
>>> edb1 = Edb(edbpath=targetfile1, edbversion="2021.2")
|
|
1374
|
-
>>> edb2 = Edb(edbpath=targetfile2, edbversion="2021.2")
|
|
1375
|
-
>>> hosting_cmp = edb1.components.get_component_by_name("U100")
|
|
1376
|
-
>>> mounted_cmp = edb2.components.get_component_by_name("BGA")
|
|
1377
|
-
>>> edb1.stackup.place_instance(edb2, angle=0.0, offset_x="1mm",
|
|
1378
|
-
... offset_y="2mm", flipped_stackup=False, place_on_top=True,
|
|
1379
|
-
... )
|
|
1533
|
+
:class:`ansys.edb.core.hierarchy.CellInstance`
|
|
1534
|
+
Cell instance created.
|
|
1380
1535
|
"""
|
|
1381
1536
|
_angle = angle * math.pi / 180.0
|
|
1382
1537
|
|
|
@@ -1482,37 +1637,35 @@ class Stackup(LayerCollection):
|
|
|
1482
1637
|
offset_z=0.0,
|
|
1483
1638
|
place_on_top=True,
|
|
1484
1639
|
) -> bool:
|
|
1485
|
-
"""Place a 3D
|
|
1486
|
-
|
|
1487
|
-
|
|
1640
|
+
"""Place a 3D component into the current layout.
|
|
1641
|
+
|
|
1642
|
+
3D Component ports are not visible via EDB. They will be visible after the EDB has been opened in Ansys
|
|
1643
|
+
Electronics Desktop as a project.
|
|
1488
1644
|
|
|
1489
1645
|
Parameters
|
|
1490
1646
|
----------
|
|
1491
1647
|
a3dcomp_path : str
|
|
1492
|
-
Path to the 3D Component file (
|
|
1493
|
-
angle :
|
|
1648
|
+
Path to the 3D Component file (``*.a3dcomp``) to place.
|
|
1649
|
+
angle : float, optional
|
|
1494
1650
|
Clockwise rotation angle applied to the a3dcomp.
|
|
1495
|
-
offset_x :
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
The default
|
|
1501
|
-
offset_z : double, optional
|
|
1502
|
-
The z offset value. (i.e. elevation)
|
|
1503
|
-
The default value is ``0.0``.
|
|
1651
|
+
offset_x : float, optional
|
|
1652
|
+
X offset value. The default is ``0.0``.
|
|
1653
|
+
offset_y : float, optional
|
|
1654
|
+
Y offset value. The default is ``0.0``.
|
|
1655
|
+
offset_z : float, optional
|
|
1656
|
+
Z offset value (elevation). The default is ``0.0``.
|
|
1504
1657
|
place_on_top : bool, optional
|
|
1505
|
-
Whether to place the 3D
|
|
1506
|
-
|
|
1658
|
+
Whether to place the 3D component on the top or the bottom of this layout. If ``False``, the 3D component
|
|
1659
|
+
will be flipped over around its X axis.
|
|
1507
1660
|
|
|
1508
1661
|
Returns
|
|
1509
1662
|
-------
|
|
1510
1663
|
bool
|
|
1511
|
-
``True`` if successful
|
|
1664
|
+
``True`` if successful, ``False`` if not.
|
|
1512
1665
|
|
|
1513
1666
|
Examples
|
|
1514
1667
|
--------
|
|
1515
|
-
>>> edb1 = Edb(edbpath=targetfile1,
|
|
1668
|
+
>>> edb1 = Edb(edbpath=targetfile1, edbversion="2021.2")
|
|
1516
1669
|
>>> a3dcomp_path = "connector.a3dcomp"
|
|
1517
1670
|
>>> edb1.stackup.place_a3dcomp_3d_placement(a3dcomp_path, angle=0.0, offset_x="1mm",
|
|
1518
1671
|
... offset_y="2mm", flipped_stackup=False, place_on_top=True,
|
|
@@ -1558,11 +1711,11 @@ class Stackup(LayerCollection):
|
|
|
1558
1711
|
Returns
|
|
1559
1712
|
-------
|
|
1560
1713
|
dict
|
|
1561
|
-
|
|
1714
|
+
Dictionary of copper area per layer.
|
|
1562
1715
|
|
|
1563
1716
|
Examples
|
|
1564
1717
|
--------
|
|
1565
|
-
>>> edb = Edb(edbpath=targetfile1,
|
|
1718
|
+
>>> edb = Edb(edbpath=targetfile1, edbversion="2021.2")
|
|
1566
1719
|
>>> edb.stackup.residual_copper_area_per_layer()
|
|
1567
1720
|
"""
|
|
1568
1721
|
temp_data = {name: 0 for name, _ in self.signal_layers.items()}
|
|
@@ -1581,10 +1734,21 @@ class Stackup(LayerCollection):
|
|
|
1581
1734
|
temp_data = {name: area / outline_area * 100 for name, area in temp_data.items()}
|
|
1582
1735
|
return temp_data
|
|
1583
1736
|
|
|
1584
|
-
# TODO: This method might need some refactoring
|
|
1585
|
-
|
|
1586
1737
|
def _import_dict(self, json_dict, rename=False):
|
|
1587
|
-
"""Import stackup from a dictionary.
|
|
1738
|
+
"""Import stackup from a dictionary.
|
|
1739
|
+
|
|
1740
|
+
Parameters
|
|
1741
|
+
----------
|
|
1742
|
+
json_dict : dict
|
|
1743
|
+
Dictionary containing stackup information.
|
|
1744
|
+
rename : bool, optional
|
|
1745
|
+
Whether to rename layers. The default is ``False``.
|
|
1746
|
+
|
|
1747
|
+
Returns
|
|
1748
|
+
-------
|
|
1749
|
+
bool
|
|
1750
|
+
``True`` when successful.
|
|
1751
|
+
"""
|
|
1588
1752
|
if not "materials" in json_dict:
|
|
1589
1753
|
self._logger.info("Configuration file does not have material definition. Using aedb and syslib materials.")
|
|
1590
1754
|
else:
|
|
@@ -1725,7 +1889,20 @@ class Stackup(LayerCollection):
|
|
|
1725
1889
|
return True
|
|
1726
1890
|
|
|
1727
1891
|
def _import_json(self, file_path, rename=False):
|
|
1728
|
-
"""Import stackup from a
|
|
1892
|
+
"""Import stackup from a JSON file.
|
|
1893
|
+
|
|
1894
|
+
Parameters
|
|
1895
|
+
----------
|
|
1896
|
+
file_path : str
|
|
1897
|
+
Path to the JSON file.
|
|
1898
|
+
rename : bool, optional
|
|
1899
|
+
Whether to rename layers. The default is ``False``.
|
|
1900
|
+
|
|
1901
|
+
Returns
|
|
1902
|
+
-------
|
|
1903
|
+
bool
|
|
1904
|
+
``True`` when successful.
|
|
1905
|
+
"""
|
|
1729
1906
|
if file_path:
|
|
1730
1907
|
f = open(file_path)
|
|
1731
1908
|
json_dict = json.load(f) # pragma: no cover
|
|
@@ -1738,6 +1915,11 @@ class Stackup(LayerCollection):
|
|
|
1738
1915
|
----------
|
|
1739
1916
|
file_path : str
|
|
1740
1917
|
File path to the CSV file.
|
|
1918
|
+
|
|
1919
|
+
Returns
|
|
1920
|
+
-------
|
|
1921
|
+
bool
|
|
1922
|
+
``True`` when successful.
|
|
1741
1923
|
"""
|
|
1742
1924
|
if not pd:
|
|
1743
1925
|
self._pedb.logger.error("Pandas is needed. You must install it first.")
|
|
@@ -1779,16 +1961,19 @@ class Stackup(LayerCollection):
|
|
|
1779
1961
|
|
|
1780
1962
|
Parameters
|
|
1781
1963
|
----------
|
|
1782
|
-
layers: dict
|
|
1964
|
+
layers : dict, optional
|
|
1783
1965
|
Dictionary containing layer information.
|
|
1784
|
-
materials: dict
|
|
1966
|
+
materials : dict, optional
|
|
1785
1967
|
Dictionary containing material information.
|
|
1786
|
-
roughness: dict
|
|
1968
|
+
roughness : dict, optional
|
|
1787
1969
|
Dictionary containing roughness information.
|
|
1970
|
+
non_stackup_layers : dict, optional
|
|
1971
|
+
Dictionary containing non-stackup layer information.
|
|
1788
1972
|
|
|
1789
1973
|
Returns
|
|
1790
1974
|
-------
|
|
1791
|
-
|
|
1975
|
+
bool
|
|
1976
|
+
``True`` when successful.
|
|
1792
1977
|
"""
|
|
1793
1978
|
if materials:
|
|
1794
1979
|
self._add_materials_from_dictionary(materials)
|
|
@@ -1905,9 +2090,14 @@ class Stackup(LayerCollection):
|
|
|
1905
2090
|
def _get(self):
|
|
1906
2091
|
"""Get stackup information from layout.
|
|
1907
2092
|
|
|
1908
|
-
Returns
|
|
1909
|
-
|
|
1910
|
-
|
|
2093
|
+
Returns
|
|
2094
|
+
-------
|
|
2095
|
+
tuple
|
|
2096
|
+
Tuple containing:
|
|
2097
|
+
- layers (dict)
|
|
2098
|
+
- materials (dict)
|
|
2099
|
+
- roughness_models (dict)
|
|
2100
|
+
- non_stackup_layers (dict)
|
|
1911
2101
|
"""
|
|
1912
2102
|
layers = OrderedDict()
|
|
1913
2103
|
roughness_models = OrderedDict()
|
|
@@ -1972,39 +2162,30 @@ class Stackup(LayerCollection):
|
|
|
1972
2162
|
def _add_materials_from_dictionary(self, material_dict):
|
|
1973
2163
|
materials = self.self._pedb.materials.materials
|
|
1974
2164
|
for name, material_properties in material_dict.items():
|
|
1975
|
-
if
|
|
1976
|
-
|
|
1977
|
-
materials.add_conductor_material(name, material_properties["Conductivity"])
|
|
1978
|
-
else:
|
|
1979
|
-
materials.add_dielectric_material(
|
|
1980
|
-
name,
|
|
1981
|
-
material_properties["Permittivity"],
|
|
1982
|
-
material_properties["DielectricLossTangent"],
|
|
1983
|
-
)
|
|
2165
|
+
if "Conductivity" in material_properties:
|
|
2166
|
+
materials.add_conductor_material(name, material_properties["Conductivity"])
|
|
1984
2167
|
else:
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
material.loss_tanget = material_properties["DielectricLossTangent"]
|
|
2168
|
+
materials.add_dielectric_material(
|
|
2169
|
+
name,
|
|
2170
|
+
material_properties["Permittivity"],
|
|
2171
|
+
material_properties["DielectricLossTangent"],
|
|
2172
|
+
)
|
|
1991
2173
|
return True
|
|
1992
2174
|
|
|
1993
2175
|
def _import_xml(self, file_path, rename=False):
|
|
1994
|
-
"""Read external
|
|
1995
|
-
You can use xml file to import layer stackup but using json file is recommended.
|
|
1996
|
-
see :class:`pyedb.dotnet.database.edb_data.simulation_configuration.SimulationConfiguration´ class to
|
|
1997
|
-
generate files`.
|
|
2176
|
+
"""Read external XML file and convert into JSON format.
|
|
1998
2177
|
|
|
1999
2178
|
Parameters
|
|
2000
2179
|
----------
|
|
2001
|
-
file_path: str
|
|
2180
|
+
file_path : str
|
|
2002
2181
|
Path to external XML file.
|
|
2182
|
+
rename : bool, optional
|
|
2183
|
+
Whether to rename layers. The default is ``False``.
|
|
2003
2184
|
|
|
2004
2185
|
Returns
|
|
2005
2186
|
-------
|
|
2006
2187
|
bool
|
|
2007
|
-
``True`` when successful
|
|
2188
|
+
``True`` when successful.
|
|
2008
2189
|
"""
|
|
2009
2190
|
if not colors:
|
|
2010
2191
|
self._pedb.logger.error("Matplotlib is needed. Please, install it first.")
|
|
@@ -2063,17 +2244,17 @@ class Stackup(LayerCollection):
|
|
|
2063
2244
|
return self._pedb.configuration.load(cfg, apply_file=True)
|
|
2064
2245
|
|
|
2065
2246
|
def _export_xml(self, file_path):
|
|
2066
|
-
"""Export stackup information to an external
|
|
2247
|
+
"""Export stackup information to an external XML file.
|
|
2067
2248
|
|
|
2068
2249
|
Parameters
|
|
2069
2250
|
----------
|
|
2070
|
-
file_path: str
|
|
2251
|
+
file_path : str
|
|
2071
2252
|
Path to external XML file.
|
|
2072
2253
|
|
|
2073
2254
|
Returns
|
|
2074
2255
|
-------
|
|
2075
2256
|
bool
|
|
2076
|
-
``True`` when successful
|
|
2257
|
+
``True`` when successful.
|
|
2077
2258
|
"""
|
|
2078
2259
|
layers, materials, roughness, non_stackup_layers = self._get()
|
|
2079
2260
|
|
|
@@ -2113,25 +2294,23 @@ class Stackup(LayerCollection):
|
|
|
2113
2294
|
return True
|
|
2114
2295
|
|
|
2115
2296
|
def load(self, file_path, rename=False):
|
|
2116
|
-
"""Import stackup from a file.
|
|
2117
|
-
have the same number of signal layers. Signals layers can be renamed. Dielectric layers can be
|
|
2118
|
-
added and deleted.
|
|
2297
|
+
"""Import stackup from a file.
|
|
2119
2298
|
|
|
2299
|
+
Supported formats: XML, CSV, JSON.
|
|
2120
2300
|
|
|
2121
2301
|
Parameters
|
|
2122
2302
|
----------
|
|
2123
|
-
file_path : str
|
|
2124
|
-
Path to stackup file or
|
|
2125
|
-
rename : bool
|
|
2126
|
-
If
|
|
2127
|
-
|
|
2128
|
-
in the layout, layers are renamed according the file.
|
|
2129
|
-
Note that layer order matters, and has to be writtent from top to bottom layer in the file.
|
|
2303
|
+
file_path : str or dict
|
|
2304
|
+
Path to stackup file or dictionary with stackup details.
|
|
2305
|
+
rename : bool, optional
|
|
2306
|
+
If ``False``, layers in layout not found in the stackup file are deleted.
|
|
2307
|
+
If ``True`` and the number of layers in the stackup file equals the number of stackup layers
|
|
2308
|
+
in the layout, layers are renamed according to the file.
|
|
2130
2309
|
|
|
2131
2310
|
Returns
|
|
2132
2311
|
-------
|
|
2133
2312
|
bool
|
|
2134
|
-
``True`` when successful
|
|
2313
|
+
``True`` when successful.
|
|
2135
2314
|
|
|
2136
2315
|
Examples
|
|
2137
2316
|
--------
|
|
@@ -2161,32 +2340,31 @@ class Stackup(LayerCollection):
|
|
|
2161
2340
|
scale_elevation=True,
|
|
2162
2341
|
show=True,
|
|
2163
2342
|
):
|
|
2164
|
-
"""Plot current stackup and
|
|
2165
|
-
|
|
2343
|
+
"""Plot the current stackup and optionally overlap padstack definitions.
|
|
2344
|
+
|
|
2345
|
+
Only supports 'Laminate' and 'Overlapping' stackup types.
|
|
2166
2346
|
|
|
2167
2347
|
Parameters
|
|
2168
2348
|
----------
|
|
2169
2349
|
save_plot : str, optional
|
|
2170
|
-
|
|
2171
|
-
If ``save_plot`` is provided, the ``show`` parameter is ignored.
|
|
2350
|
+
Path to save the plot image. If provided, ``show`` is ignored.
|
|
2172
2351
|
size : tuple, optional
|
|
2173
|
-
Image size in
|
|
2174
|
-
plot_definitions : str
|
|
2175
|
-
List of padstack definitions to plot on the stackup.
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
Last layer to plot from the bottom. Default is `None` to plot up to top layer.
|
|
2352
|
+
Image size in pixels (width, height). Default is ``(2000, 1500)``.
|
|
2353
|
+
plot_definitions : str or list, optional
|
|
2354
|
+
List of padstack definitions to plot on the stackup. Only supported for Laminate mode.
|
|
2355
|
+
first_layer : str or :class:`pyedb.grpc.database.layers.layer.Layer`, optional
|
|
2356
|
+
First layer to plot from the bottom. Default is ``None`` (start from bottom).
|
|
2357
|
+
last_layer : str or :class:`pyedb.grpc.database.layers.layer.Layer`, optional
|
|
2358
|
+
Last layer to plot from the bottom. Default is ``None`` (plot up to top layer).
|
|
2181
2359
|
scale_elevation : bool, optional
|
|
2182
|
-
|
|
2183
|
-
Default is `True`.
|
|
2360
|
+
Scale real layer thickness so that max_thickness = 3 * min_thickness. Default is ``True``.
|
|
2184
2361
|
show : bool, optional
|
|
2185
|
-
Whether to show the plot
|
|
2362
|
+
Whether to show the plot. Default is ``True``.
|
|
2186
2363
|
|
|
2187
2364
|
Returns
|
|
2188
2365
|
-------
|
|
2189
|
-
:class:`matplotlib.
|
|
2366
|
+
:class:`matplotlib.pyplot`
|
|
2367
|
+
Matplotlib plot object.
|
|
2190
2368
|
"""
|
|
2191
2369
|
|
|
2192
2370
|
from pyedb.generic.constants import CSS4_COLORS
|
|
@@ -2389,7 +2567,7 @@ class Stackup(LayerCollection):
|
|
|
2389
2567
|
width = len(columns) + 1
|
|
2390
2568
|
for i, c in enumerate(columns[:-1]):
|
|
2391
2569
|
for j, r in enumerate(c):
|
|
2392
|
-
if r != 0: # and dname == r[0].name
|
|
2570
|
+
if r != 0: # and dname == r[0].name
|
|
2393
2571
|
if columns[i + 1][j] == 0:
|
|
2394
2572
|
# nothing on the right, so expand the fill
|
|
2395
2573
|
x = r[1]
|