pyedb 0.49.0__py3-none-any.whl → 0.50.1__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_modeler.py +42 -11
- pyedb/configuration/cfg_ports_sources.py +9 -1
- pyedb/dotnet/database/cell/hierarchy/component.py +6 -6
- pyedb/dotnet/database/components.py +3 -3
- pyedb/dotnet/database/edb_data/padstacks_data.py +13 -0
- pyedb/dotnet/database/edb_data/primitives_data.py +3 -3
- pyedb/dotnet/database/edb_data/variables.py +3 -3
- pyedb/dotnet/database/materials.py +16 -16
- pyedb/dotnet/database/modeler.py +38 -4
- pyedb/dotnet/database/sim_setup_data/data/settings.py +28 -0
- pyedb/dotnet/database/stackup.py +1 -0
- pyedb/dotnet/database/utilities/hfss_simulation_setup.py +5 -6
- pyedb/dotnet/edb.py +22 -20
- pyedb/extensions/__init__.py +0 -0
- pyedb/extensions/via_design_backend.py +681 -0
- pyedb/grpc/database/components.py +537 -686
- pyedb/grpc/database/control_file.py +458 -149
- pyedb/grpc/database/definition/component_def.py +17 -14
- pyedb/grpc/database/definition/materials.py +60 -60
- pyedb/grpc/database/definition/package_def.py +8 -8
- pyedb/grpc/database/definition/padstack_def.py +31 -33
- pyedb/grpc/database/definitions.py +6 -4
- 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 +399 -397
- pyedb/grpc/database/hierarchy/component.py +60 -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 +144 -44
- pyedb/grpc/database/layout/layout.py +12 -12
- pyedb/grpc/database/layout/voltage_regulator.py +8 -8
- pyedb/grpc/database/layout_validation.py +5 -5
- 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 +139 -122
- pyedb/grpc/database/padstacks.py +174 -190
- pyedb/grpc/database/ports/ports.py +23 -17
- pyedb/grpc/database/primitive/padstack_instance.py +45 -30
- pyedb/grpc/database/primitive/path.py +7 -7
- 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 +166 -214
- pyedb/grpc/database/source_excitations.py +156 -0
- pyedb/grpc/database/stackup.py +415 -316
- 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 +524 -764
- {pyedb-0.49.0.dist-info → pyedb-0.50.1.dist-info}/METADATA +1 -1
- {pyedb-0.49.0.dist-info → pyedb-0.50.1.dist-info}/RECORD +77 -77
- pyedb/extensions/pre_layout_design_toolkit/via_design.py +0 -1151
- pyedb/grpc/database/utility/simulation_configuration.py +0 -3305
- {pyedb-0.49.0.dist-info → pyedb-0.50.1.dist-info}/LICENSE +0 -0
- {pyedb-0.49.0.dist-info → pyedb-0.50.1.dist-info}/WHEEL +0 -0
pyedb/grpc/database/stackup.py
CHANGED
|
@@ -49,7 +49,6 @@ from ansys.edb.core.layer.layer_collection import LayerCollection as GrpcLayerCo
|
|
|
49
49
|
from ansys.edb.core.layer.layer_collection import LayerTypeSet as GrpcLayerTypeSet
|
|
50
50
|
from ansys.edb.core.layer.stackup_layer import StackupLayer as GrpcStackupLayer
|
|
51
51
|
from ansys.edb.core.layout.mcad_model import McadModel as GrpcMcadModel
|
|
52
|
-
from ansys.edb.core.utility.transform3d import Transform3D as GrpcTransform3D
|
|
53
52
|
from ansys.edb.core.utility.value import Value as GrpcValue
|
|
54
53
|
|
|
55
54
|
from pyedb.generic.general_methods import ET, generate_unique_name
|
|
@@ -79,7 +78,15 @@ logger = logging.getLogger(__name__)
|
|
|
79
78
|
|
|
80
79
|
|
|
81
80
|
class LayerCollection(GrpcLayerCollection):
|
|
82
|
-
"""
|
|
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
|
+
"""
|
|
83
90
|
|
|
84
91
|
def __init__(self, pedb, edb_object):
|
|
85
92
|
super().__init__(edb_object.msg)
|
|
@@ -87,12 +94,7 @@ class LayerCollection(GrpcLayerCollection):
|
|
|
87
94
|
self._pedb = pedb
|
|
88
95
|
|
|
89
96
|
def update_layout(self):
|
|
90
|
-
"""
|
|
91
|
-
|
|
92
|
-
Parameters
|
|
93
|
-
----------
|
|
94
|
-
stackup
|
|
95
|
-
"""
|
|
97
|
+
"""Update the layout with the current layer collection."""
|
|
96
98
|
self._pedb.layout.layer_collection = self
|
|
97
99
|
|
|
98
100
|
def add_layer_top(self, name, layer_type="signal", **kwargs):
|
|
@@ -102,13 +104,17 @@ class LayerCollection(GrpcLayerCollection):
|
|
|
102
104
|
----------
|
|
103
105
|
name : str
|
|
104
106
|
Name of the layer.
|
|
105
|
-
layer_type: str, optional
|
|
106
|
-
Type of the layer. The default
|
|
107
|
-
kwargs
|
|
107
|
+
layer_type : str, optional
|
|
108
|
+
Type of the layer. The default is ``"signal"``. Options are ``"signal"`` and ``"dielectric"``.
|
|
109
|
+
**kwargs : dict, optional
|
|
110
|
+
Additional keyword arguments. Possible keys are:
|
|
111
|
+
- ``thickness`` : float, layer thickness.
|
|
112
|
+
- ``material`` : str, layer material.
|
|
108
113
|
|
|
109
114
|
Returns
|
|
110
115
|
-------
|
|
111
|
-
|
|
116
|
+
:class:`pyedb.grpc.database.layers.stackup_layer.StackupLayer`
|
|
117
|
+
Layer object created.
|
|
112
118
|
"""
|
|
113
119
|
thickness = GrpcValue(0.0)
|
|
114
120
|
if "thickness" in kwargs:
|
|
@@ -123,19 +129,24 @@ class LayerCollection(GrpcLayerCollection):
|
|
|
123
129
|
return self._layer_collection.add_layer_top(layer)
|
|
124
130
|
|
|
125
131
|
def add_layer_bottom(self, name, layer_type="signal", **kwargs):
|
|
126
|
-
"""Add a layer
|
|
132
|
+
"""Add a layer at the bottom of the stackup.
|
|
127
133
|
|
|
128
134
|
Parameters
|
|
129
135
|
----------
|
|
130
136
|
name : str
|
|
131
137
|
Name of the layer.
|
|
132
|
-
layer_type: str, optional
|
|
133
|
-
Type of the layer. The default
|
|
134
|
-
kwargs
|
|
138
|
+
layer_type : str, optional
|
|
139
|
+
Type of the layer. The default is ``"signal"``. Options are ``"signal"`` and ``"dielectric"``.
|
|
140
|
+
**kwargs : dict, optional
|
|
141
|
+
Additional keyword arguments. Possible keys are:
|
|
142
|
+
- ``thickness`` : float, layer thickness.
|
|
143
|
+
- ``material`` : str, layer material.
|
|
144
|
+
- ``fill_material`` : str, fill material.
|
|
135
145
|
|
|
136
146
|
Returns
|
|
137
147
|
-------
|
|
138
|
-
|
|
148
|
+
:class:`pyedb.grpc.database.layers.stackup_layer.StackupLayer`
|
|
149
|
+
Layer object created.
|
|
139
150
|
"""
|
|
140
151
|
thickness = GrpcValue(0.0)
|
|
141
152
|
layer_type_map = {"dielectric": GrpcLayerType.DIELECTRIC_LAYER, "signal": GrpcLayerType.SIGNAL_LAYER}
|
|
@@ -158,21 +169,25 @@ class LayerCollection(GrpcLayerCollection):
|
|
|
158
169
|
return self._layer_collection.add_layer_bottom(layer)
|
|
159
170
|
|
|
160
171
|
def add_layer_below(self, name, base_layer_name, layer_type="signal", **kwargs):
|
|
161
|
-
"""Add a layer below a layer.
|
|
172
|
+
"""Add a layer below a specified layer.
|
|
162
173
|
|
|
163
174
|
Parameters
|
|
164
175
|
----------
|
|
165
176
|
name : str
|
|
166
177
|
Name of the layer.
|
|
167
|
-
base_layer_name: str
|
|
178
|
+
base_layer_name : str
|
|
168
179
|
Name of the base layer.
|
|
169
|
-
layer_type: str, optional
|
|
170
|
-
Type of the layer. The default
|
|
171
|
-
kwargs
|
|
180
|
+
layer_type : str, optional
|
|
181
|
+
Type of the layer. The default is ``"signal"``. Options are ``"signal"`` and ``"dielectric"``.
|
|
182
|
+
**kwargs : dict, optional
|
|
183
|
+
Additional keyword arguments. Possible keys are:
|
|
184
|
+
- ``thickness`` : float, layer thickness.
|
|
185
|
+
- ``material`` : str, layer material.
|
|
172
186
|
|
|
173
187
|
Returns
|
|
174
188
|
-------
|
|
175
|
-
|
|
189
|
+
:class:`pyedb.grpc.database.layers.stackup_layer.StackupLayer`
|
|
190
|
+
Layer object created.
|
|
176
191
|
"""
|
|
177
192
|
thickness = GrpcValue(0.0)
|
|
178
193
|
if "thickness" in kwargs:
|
|
@@ -195,21 +210,25 @@ class LayerCollection(GrpcLayerCollection):
|
|
|
195
210
|
return self._layer_collection.add_layer_below(layer, base_layer_name)
|
|
196
211
|
|
|
197
212
|
def add_layer_above(self, name, base_layer_name, layer_type="signal", **kwargs):
|
|
198
|
-
"""Add a layer above a layer.
|
|
213
|
+
"""Add a layer above a specified layer.
|
|
199
214
|
|
|
200
215
|
Parameters
|
|
201
216
|
----------
|
|
202
217
|
name : str
|
|
203
218
|
Name of the layer.
|
|
204
|
-
base_layer_name: str
|
|
219
|
+
base_layer_name : str
|
|
205
220
|
Name of the base layer.
|
|
206
|
-
layer_type: str, optional
|
|
207
|
-
Type of the layer. The default
|
|
208
|
-
kwargs
|
|
221
|
+
layer_type : str, optional
|
|
222
|
+
Type of the layer. The default is ``"signal"``. Options are ``"signal"`` and ``"dielectric"``.
|
|
223
|
+
**kwargs : dict, optional
|
|
224
|
+
Additional keyword arguments. Possible keys are:
|
|
225
|
+
- ``thickness`` : float, layer thickness.
|
|
226
|
+
- ``material`` : str, layer material.
|
|
209
227
|
|
|
210
228
|
Returns
|
|
211
229
|
-------
|
|
212
|
-
|
|
230
|
+
:class:`pyedb.grpc.database.layers.stackup_layer.StackupLayer`
|
|
231
|
+
Layer object created.
|
|
213
232
|
"""
|
|
214
233
|
thickness = GrpcValue(0.0)
|
|
215
234
|
if "thickness" in kwargs:
|
|
@@ -230,13 +249,15 @@ class LayerCollection(GrpcLayerCollection):
|
|
|
230
249
|
----------
|
|
231
250
|
name : str
|
|
232
251
|
Name of the layer.
|
|
233
|
-
layer_type: str, optional
|
|
234
|
-
Type of the layer. The default is ``"user"``. Options are ``"user"
|
|
235
|
-
kwargs
|
|
252
|
+
layer_type : str, optional
|
|
253
|
+
Type of the layer. The default is ``"user"``. Options are ``"user"`` and ``"outline"``.
|
|
254
|
+
**kwargs : dict, optional
|
|
255
|
+
Additional keyword arguments.
|
|
236
256
|
|
|
237
257
|
Returns
|
|
238
258
|
-------
|
|
239
|
-
|
|
259
|
+
:class:`pyedb.grpc.database.layers.layer.Layer`
|
|
260
|
+
Layer object created.
|
|
240
261
|
"""
|
|
241
262
|
added_layer = self.add_layer_top(name)
|
|
242
263
|
added_layer.type = GrpcLayerType.USER_LAYER
|
|
@@ -244,29 +265,65 @@ class LayerCollection(GrpcLayerCollection):
|
|
|
244
265
|
|
|
245
266
|
@property
|
|
246
267
|
def stackup_layers(self):
|
|
247
|
-
"""Retrieve the dictionary of signal and dielectric layers.
|
|
268
|
+
"""Retrieve the dictionary of signal and dielectric layers.
|
|
269
|
+
|
|
270
|
+
.. deprecated:: 0.6.61
|
|
271
|
+
Use :func:`layers` instead.
|
|
272
|
+
|
|
273
|
+
Returns
|
|
274
|
+
-------
|
|
275
|
+
dict[str, :class:`pyedb.grpc.database.layers.stackup_layer.StackupLayer`]
|
|
276
|
+
Dictionary of stackup layers.
|
|
277
|
+
"""
|
|
248
278
|
warnings.warn("Use new property :func:`layers` instead.", DeprecationWarning)
|
|
249
279
|
return self.layers
|
|
250
280
|
|
|
251
281
|
@property
|
|
252
282
|
def non_stackup_layers(self):
|
|
253
|
-
"""Retrieve the dictionary of
|
|
283
|
+
"""Retrieve the dictionary of non-stackup layers.
|
|
284
|
+
|
|
285
|
+
Returns
|
|
286
|
+
-------
|
|
287
|
+
dict[str, :class:`pyedb.grpc.database.layers.layer.Layer`]
|
|
288
|
+
Dictionary of non-stackup layers.
|
|
289
|
+
"""
|
|
254
290
|
return {
|
|
255
291
|
layer.name: Layer(self._pedb, layer) for layer in self.get_layers(GrpcLayerTypeSet.NON_STACKUP_LAYER_SET)
|
|
256
292
|
}
|
|
257
293
|
|
|
258
294
|
@property
|
|
259
295
|
def all_layers(self):
|
|
296
|
+
"""Retrieve all layers.
|
|
297
|
+
|
|
298
|
+
Returns
|
|
299
|
+
-------
|
|
300
|
+
dict[str, :class:`pyedb.grpc.database.layers.layer.Layer`]
|
|
301
|
+
Dictionary of all layers.
|
|
302
|
+
"""
|
|
260
303
|
return {layer.name: Layer(self._pedb, layer) for layer in self.get_layers(GrpcLayerTypeSet.ALL_LAYER_SET)}
|
|
261
304
|
|
|
262
305
|
@property
|
|
263
306
|
def signal_layers(self):
|
|
307
|
+
"""Retrieve the dictionary of signal layers.
|
|
308
|
+
|
|
309
|
+
Returns
|
|
310
|
+
-------
|
|
311
|
+
dict[str, :class:`pyedb.grpc.database.layers.stackup_layer.StackupLayer`]
|
|
312
|
+
Dictionary of signal layers.
|
|
313
|
+
"""
|
|
264
314
|
return {
|
|
265
315
|
layer.name: StackupLayer(self._pedb, layer) for layer in self.get_layers(GrpcLayerTypeSet.SIGNAL_LAYER_SET)
|
|
266
316
|
}
|
|
267
317
|
|
|
268
318
|
@property
|
|
269
319
|
def dielectric_layers(self):
|
|
320
|
+
"""Retrieve the dictionary of dielectric layers.
|
|
321
|
+
|
|
322
|
+
Returns
|
|
323
|
+
-------
|
|
324
|
+
dict[str, :class:`pyedb.grpc.database.layers.stackup_layer.StackupLayer`]
|
|
325
|
+
Dictionary of dielectric layers.
|
|
326
|
+
"""
|
|
270
327
|
return {
|
|
271
328
|
layer.name: StackupLayer(self._pedb, layer)
|
|
272
329
|
for layer in self.get_layers(GrpcLayerTypeSet.DIELECTRIC_LAYER_SET)
|
|
@@ -274,25 +331,46 @@ class LayerCollection(GrpcLayerCollection):
|
|
|
274
331
|
|
|
275
332
|
@property
|
|
276
333
|
def layers_by_id(self):
|
|
277
|
-
"""Retrieve the list of layers with their
|
|
334
|
+
"""Retrieve the list of layers with their IDs.
|
|
335
|
+
|
|
336
|
+
Returns
|
|
337
|
+
-------
|
|
338
|
+
list[list[int, str]]
|
|
339
|
+
List of layers with their IDs and names.
|
|
340
|
+
"""
|
|
278
341
|
return [[obj.id, name] for name, obj in self.all_layers.items()]
|
|
279
342
|
|
|
280
343
|
@property
|
|
281
344
|
def layers(self):
|
|
282
|
-
"""Retrieve the dictionary of layers.
|
|
345
|
+
"""Retrieve the dictionary of stackup layers (signal and dielectric).
|
|
283
346
|
|
|
284
347
|
Returns
|
|
285
348
|
-------
|
|
286
|
-
|
|
349
|
+
dict[str, :class:`pyedb.grpc.database.layers.stackup_layer.StackupLayer`]
|
|
350
|
+
Dictionary of stackup layers.
|
|
287
351
|
"""
|
|
288
352
|
return {obj.name: StackupLayer(self._pedb, obj) for obj in self.get_layers(GrpcLayerTypeSet.STACKUP_LAYER_SET)}
|
|
289
353
|
|
|
290
354
|
def find_layer_by_name(self, name: str):
|
|
291
|
-
"""
|
|
355
|
+
"""Find a layer by its name.
|
|
356
|
+
|
|
357
|
+
.. deprecated:: 0.29.0
|
|
358
|
+
Use :func:`find_by_name` instead.
|
|
359
|
+
|
|
360
|
+
Parameters
|
|
361
|
+
----------
|
|
362
|
+
name : str
|
|
363
|
+
Name of the layer.
|
|
292
364
|
|
|
293
|
-
|
|
294
|
-
|
|
365
|
+
Returns
|
|
366
|
+
-------
|
|
367
|
+
:class:`ansys.edb.core.layer.Layer`
|
|
368
|
+
Layer object found.
|
|
295
369
|
|
|
370
|
+
Raises
|
|
371
|
+
------
|
|
372
|
+
ValueError
|
|
373
|
+
If no layer with the given name is found.
|
|
296
374
|
"""
|
|
297
375
|
warnings.warn(
|
|
298
376
|
"`find_layer_by_name` is deprecated and is now located here "
|
|
@@ -306,37 +384,51 @@ class LayerCollection(GrpcLayerCollection):
|
|
|
306
384
|
|
|
307
385
|
|
|
308
386
|
class Stackup(LayerCollection):
|
|
309
|
-
"""Manages EDB methods for stackup.
|
|
387
|
+
"""Manages EDB methods for stackup operations.
|
|
388
|
+
|
|
389
|
+
Parameters
|
|
390
|
+
----------
|
|
391
|
+
pedb : :class:`pyedb.Edb`
|
|
392
|
+
EDB object.
|
|
393
|
+
edb_object : :class:`ansys.edb.core.layer.LayerCollection`, optional
|
|
394
|
+
EDB layer collection object. The default is ``None``.
|
|
395
|
+
"""
|
|
310
396
|
|
|
311
397
|
def __init__(self, pedb, edb_object=None):
|
|
312
398
|
super().__init__(pedb, edb_object)
|
|
313
399
|
self._pedb = pedb
|
|
314
400
|
|
|
401
|
+
def __getitem__(self, item):
|
|
402
|
+
if item in self.non_stackup_layers:
|
|
403
|
+
return Layer(self._pedb, self.find_by_name(item))
|
|
404
|
+
elif item in self.layers:
|
|
405
|
+
return StackupLayer(self._pedb, self.find_by_name(item))
|
|
406
|
+
else:
|
|
407
|
+
return None
|
|
408
|
+
|
|
315
409
|
@property
|
|
316
410
|
def _logger(self):
|
|
317
411
|
return self._pedb.logger
|
|
318
412
|
|
|
319
413
|
@property
|
|
320
414
|
def thickness(self):
|
|
321
|
-
"""Retrieve
|
|
415
|
+
"""Retrieve the stackup thickness.
|
|
322
416
|
|
|
323
417
|
Returns
|
|
324
418
|
-------
|
|
325
419
|
float
|
|
326
|
-
|
|
327
|
-
|
|
420
|
+
Stackup thickness.
|
|
328
421
|
"""
|
|
329
422
|
return self.get_layout_thickness()
|
|
330
423
|
|
|
331
424
|
@property
|
|
332
425
|
def num_layers(self):
|
|
333
|
-
"""Retrieve the
|
|
426
|
+
"""Retrieve the number of layers in the stackup.
|
|
334
427
|
|
|
335
428
|
Returns
|
|
336
429
|
-------
|
|
337
430
|
int
|
|
338
|
-
|
|
339
|
-
|
|
431
|
+
Number of layers.
|
|
340
432
|
"""
|
|
341
433
|
return len(list(self.layers.keys()))
|
|
342
434
|
|
|
@@ -355,7 +447,7 @@ class Stackup(LayerCollection):
|
|
|
355
447
|
Parameters
|
|
356
448
|
----------
|
|
357
449
|
layer_count : int
|
|
358
|
-
Number of
|
|
450
|
+
Number of layers. Must be even.
|
|
359
451
|
inner_layer_thickness : str, float, optional
|
|
360
452
|
Thickness of inner conductor layer.
|
|
361
453
|
outer_layer_thickness : str, float, optional
|
|
@@ -365,13 +457,14 @@ class Stackup(LayerCollection):
|
|
|
365
457
|
dielectric_material : str, optional
|
|
366
458
|
Material of dielectric layer.
|
|
367
459
|
soldermask : bool, optional
|
|
368
|
-
Whether to create soldermask layers. The default is``True``.
|
|
460
|
+
Whether to create soldermask layers. The default is ``True``.
|
|
369
461
|
soldermask_thickness : str, optional
|
|
370
462
|
Thickness of soldermask layer.
|
|
371
463
|
|
|
372
464
|
Returns
|
|
373
465
|
-------
|
|
374
466
|
bool
|
|
467
|
+
``True`` when successful, ``False`` when failed.
|
|
375
468
|
"""
|
|
376
469
|
if not np:
|
|
377
470
|
self._pedb.logger.error("Numpy is needed. Please, install it first.")
|
|
@@ -468,22 +561,26 @@ class Stackup(LayerCollection):
|
|
|
468
561
|
|
|
469
562
|
Returns
|
|
470
563
|
-------
|
|
471
|
-
|
|
472
|
-
Type of the stackup mode
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
* 2 - MultiZone
|
|
564
|
+
str
|
|
565
|
+
Type of the stackup mode. Options are:
|
|
566
|
+
- ``"laminate"``
|
|
567
|
+
- ``"overlapping"``
|
|
568
|
+
- ``"multizone"``
|
|
477
569
|
"""
|
|
478
570
|
return super().mode.name.lower()
|
|
479
571
|
|
|
480
572
|
@mode.setter
|
|
481
573
|
def mode(self, value):
|
|
482
|
-
if value == 0 or value == GrpcLayerCollectionMode.LAMINATE or value == "laminate":
|
|
574
|
+
if value == 0 or value == GrpcLayerCollectionMode.LAMINATE or value == "laminate" or value == "Laminate":
|
|
483
575
|
super(LayerCollection, self.__class__).mode.__set__(self, GrpcLayerCollectionMode.LAMINATE)
|
|
484
|
-
elif
|
|
576
|
+
elif (
|
|
577
|
+
value == 1
|
|
578
|
+
or value == GrpcLayerCollectionMode.OVERLAPPING
|
|
579
|
+
or value == "overlapping"
|
|
580
|
+
or value == "Overlapping"
|
|
581
|
+
):
|
|
485
582
|
super(LayerCollection, self.__class__).mode.__set__(self, GrpcLayerCollectionMode.OVERLAPPING)
|
|
486
|
-
elif value == 2 or value == GrpcLayerCollectionMode.MULTIZONE or value == "multizone":
|
|
583
|
+
elif value == 2 or value == GrpcLayerCollectionMode.MULTIZONE or value == "multizone" or value == "MultiZone":
|
|
487
584
|
super(LayerCollection, self.__class__).mode.__set__(self, GrpcLayerCollectionMode.MULTIZONE)
|
|
488
585
|
self.update_layout()
|
|
489
586
|
|
|
@@ -492,16 +589,19 @@ class Stackup(LayerCollection):
|
|
|
492
589
|
|
|
493
590
|
Parameters
|
|
494
591
|
----------
|
|
495
|
-
layer_clone : :class:`
|
|
592
|
+
layer_clone : :class:`ansys.edb.core.layer.StackupLayer`
|
|
593
|
+
Layer object to apply.
|
|
496
594
|
operation : str
|
|
497
|
-
Options are ``"change_attribute"``, ``"change_name"
|
|
498
|
-
|
|
595
|
+
Operation to perform. Options are ``"change_attribute"``, ``"change_name"``, ``"change_position"``,
|
|
596
|
+
``"insert_below"``, ``"insert_above"``, ``"add_on_top"``, ``"add_on_bottom"``, ``"non_stackup"``,
|
|
597
|
+
and ``"add_at_elevation"``.
|
|
499
598
|
base_layer : str, optional
|
|
500
599
|
Name of the base layer. The default value is ``None``.
|
|
501
600
|
|
|
502
601
|
Returns
|
|
503
602
|
-------
|
|
504
|
-
|
|
603
|
+
bool
|
|
604
|
+
``True`` when successful.
|
|
505
605
|
"""
|
|
506
606
|
lc = self._pedb.layout.layer_collection
|
|
507
607
|
if operation in ["change_position", "change_attribute", "change_name"]:
|
|
@@ -593,17 +693,15 @@ class Stackup(LayerCollection):
|
|
|
593
693
|
return result
|
|
594
694
|
|
|
595
695
|
def add_outline_layer(self, outline_name="Outline"):
|
|
596
|
-
"""Add an outline layer named
|
|
696
|
+
"""Add an outline layer named "Outline" if it is not present.
|
|
597
697
|
|
|
598
698
|
Returns
|
|
599
699
|
-------
|
|
600
700
|
bool
|
|
601
|
-
|
|
701
|
+
``True`` when successful.
|
|
602
702
|
"""
|
|
603
703
|
return self.add_document_layer(name="Outline", layer_type="outline")
|
|
604
704
|
|
|
605
|
-
# TODO: Update optional argument material into material_name and fillMaterial into fill_material_name
|
|
606
|
-
|
|
607
705
|
def add_layer(
|
|
608
706
|
self,
|
|
609
707
|
layer_name,
|
|
@@ -627,12 +725,29 @@ class Stackup(LayerCollection):
|
|
|
627
725
|
base_layer : str, optional
|
|
628
726
|
Name of the base layer.
|
|
629
727
|
method : str, optional
|
|
630
|
-
Where to insert the new layer. The default is ``"add_on_top"``. Options are
|
|
631
|
-
|
|
728
|
+
Where to insert the new layer. The default is ``"add_on_top"``. Options are:
|
|
729
|
+
- ``"add_on_top"``
|
|
730
|
+
- ``"add_on_bottom"``
|
|
731
|
+
- ``"insert_above"``
|
|
732
|
+
- ``"insert_below"``
|
|
733
|
+
- ``"add_at_elevation"``
|
|
632
734
|
layer_type : str, optional
|
|
633
|
-
Type of layer. The default is ``"signal"``. Options are
|
|
634
|
-
|
|
635
|
-
|
|
735
|
+
Type of layer. The default is ``"signal"``. Options are:
|
|
736
|
+
- ``"signal"``
|
|
737
|
+
- ``"dielectric"``
|
|
738
|
+
- ``"conducting"``
|
|
739
|
+
- ``"air_lines"``
|
|
740
|
+
- ``"error"``
|
|
741
|
+
- ``"symbol"``
|
|
742
|
+
- ``"measure"``
|
|
743
|
+
- ``"assembly"``
|
|
744
|
+
- ``"silkscreen"``
|
|
745
|
+
- ``"solder_mask"``
|
|
746
|
+
- ``"solder_paste"``
|
|
747
|
+
- ``"glue"``
|
|
748
|
+
- ``"wirebond"``
|
|
749
|
+
- ``"hfss_region"``
|
|
750
|
+
- ``"user"``
|
|
636
751
|
material : str, optional
|
|
637
752
|
Material of the layer.
|
|
638
753
|
fillMaterial : str, optional
|
|
@@ -650,7 +765,8 @@ class Stackup(LayerCollection):
|
|
|
650
765
|
|
|
651
766
|
Returns
|
|
652
767
|
-------
|
|
653
|
-
:class:`pyedb.
|
|
768
|
+
:class:`pyedb.grpc.database.layers.stackup_layer.StackupLayer`
|
|
769
|
+
Layer object created.
|
|
654
770
|
"""
|
|
655
771
|
if layer_name in self.layers:
|
|
656
772
|
logger.error("layer {} exists.".format(layer_name))
|
|
@@ -696,6 +812,7 @@ class Stackup(LayerCollection):
|
|
|
696
812
|
else:
|
|
697
813
|
new_layer = self._create_nonstackup_layer(layer_name, layer_type)
|
|
698
814
|
self._set_layout_stackup(new_layer, "non_stackup")
|
|
815
|
+
return self.non_stackup_layers[layer_name]
|
|
699
816
|
return self.layers[layer_name]
|
|
700
817
|
|
|
701
818
|
def remove_layer(self, name):
|
|
@@ -708,7 +825,8 @@ class Stackup(LayerCollection):
|
|
|
708
825
|
|
|
709
826
|
Returns
|
|
710
827
|
-------
|
|
711
|
-
|
|
828
|
+
bool
|
|
829
|
+
``True`` when successful.
|
|
712
830
|
"""
|
|
713
831
|
new_layer_collection = LayerCollection.create()
|
|
714
832
|
for layer_name, lyr in self.layers.items():
|
|
@@ -719,19 +837,26 @@ class Stackup(LayerCollection):
|
|
|
719
837
|
return True
|
|
720
838
|
|
|
721
839
|
def export(self, fpath, file_format="xml", include_material_with_layer=False):
|
|
722
|
-
"""Export stackup definition to a
|
|
840
|
+
"""Export stackup definition to a file.
|
|
723
841
|
|
|
724
842
|
Parameters
|
|
725
843
|
----------
|
|
726
844
|
fpath : str
|
|
727
|
-
File path to
|
|
845
|
+
File path to export to.
|
|
728
846
|
file_format : str, optional
|
|
729
|
-
Format of the file to export. The default is ``"
|
|
730
|
-
``"
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
847
|
+
Format of the file to export. The default is ``"xml"``. Options are:
|
|
848
|
+
- ``"csv"``
|
|
849
|
+
- ``"xlsx"``
|
|
850
|
+
- ``"json"``
|
|
851
|
+
- ``"xml"``
|
|
852
|
+
include_material_with_layer : bool, optional
|
|
853
|
+
Whether to include the material definition inside layer objects. This parameter is only used
|
|
854
|
+
when a JSON file is exported. The default is ``False``.
|
|
855
|
+
|
|
856
|
+
Returns
|
|
857
|
+
-------
|
|
858
|
+
bool
|
|
859
|
+
``True`` when successful.
|
|
735
860
|
|
|
736
861
|
Examples
|
|
737
862
|
--------
|
|
@@ -755,7 +880,7 @@ class Stackup(LayerCollection):
|
|
|
755
880
|
return False
|
|
756
881
|
|
|
757
882
|
def export_stackup(self, fpath, file_format="xml", include_material_with_layer=False):
|
|
758
|
-
"""Export stackup definition to a
|
|
883
|
+
"""Export stackup definition to a file.
|
|
759
884
|
|
|
760
885
|
.. deprecated:: 0.6.61
|
|
761
886
|
Use :func:`export` instead.
|
|
@@ -763,14 +888,15 @@ class Stackup(LayerCollection):
|
|
|
763
888
|
Parameters
|
|
764
889
|
----------
|
|
765
890
|
fpath : str
|
|
766
|
-
File path to
|
|
891
|
+
File path to export to.
|
|
767
892
|
file_format : str, optional
|
|
768
|
-
Format of the file to export. The default is ``"
|
|
769
|
-
|
|
770
|
-
|
|
893
|
+
Format of the file to export. The default is ``"xml"``. Options are:
|
|
894
|
+
- ``"csv"``
|
|
895
|
+
- ``"xlsx"``
|
|
896
|
+
- ``"json"``
|
|
897
|
+
include_material_with_layer : bool, optional
|
|
771
898
|
Whether to include the material definition inside layer objects. This parameter is only used
|
|
772
|
-
when a JSON file is exported. The default is ``False
|
|
773
|
-
section in the JSON file. If ``True``, the material definition is included inside the layer ones.
|
|
899
|
+
when a JSON file is exported. The default is ``False``.
|
|
774
900
|
|
|
775
901
|
Examples
|
|
776
902
|
--------
|
|
@@ -819,9 +945,6 @@ class Stackup(LayerCollection):
|
|
|
819
945
|
layers_out = {}
|
|
820
946
|
for k, v in self.layers.items():
|
|
821
947
|
data = v._json_format()
|
|
822
|
-
# FIXME: Update the API to avoid providing following information to our users
|
|
823
|
-
del data["pedb"]
|
|
824
|
-
del data["edb_object"]
|
|
825
948
|
layers_out[k] = data
|
|
826
949
|
if v.material in self._pedb.materials.materials:
|
|
827
950
|
layer_material = self._pedb.materials.materials[v.material]
|
|
@@ -845,57 +968,6 @@ class Stackup(LayerCollection):
|
|
|
845
968
|
else:
|
|
846
969
|
return False
|
|
847
970
|
|
|
848
|
-
# TODO: This method might need some refactoring
|
|
849
|
-
|
|
850
|
-
def _import_layer_stackup(self, input_file=None):
|
|
851
|
-
if input_file:
|
|
852
|
-
f = open(input_file)
|
|
853
|
-
json_dict = json.load(f) # pragma: no cover
|
|
854
|
-
for k, v in json_dict.items():
|
|
855
|
-
if k == "materials":
|
|
856
|
-
for material in v.values():
|
|
857
|
-
material_name = material["name"]
|
|
858
|
-
del material["name"]
|
|
859
|
-
if material_name not in self._pedb.materials:
|
|
860
|
-
self._pedb.materials.add_material(material_name, **material)
|
|
861
|
-
else:
|
|
862
|
-
self._pedb.materials.update_material(material_name, material)
|
|
863
|
-
if k == "layers":
|
|
864
|
-
if len(list(v.values())) == len(list(self.layers.values())):
|
|
865
|
-
imported_layers_list = [l_dict["name"] for l_dict in list(v.values())]
|
|
866
|
-
layout_layer_list = list(self.layers.keys())
|
|
867
|
-
for layer_name in imported_layers_list:
|
|
868
|
-
layer_index = imported_layers_list.index(layer_name)
|
|
869
|
-
if layout_layer_list[layer_index] != layer_name:
|
|
870
|
-
self.layers[layout_layer_list[layer_index]].name = layer_name
|
|
871
|
-
prev_layer = None
|
|
872
|
-
for layer_name, layer in v.items():
|
|
873
|
-
if layer["name"] not in self.layers:
|
|
874
|
-
if not prev_layer:
|
|
875
|
-
self.add_layer(
|
|
876
|
-
layer_name,
|
|
877
|
-
method="add_on_top",
|
|
878
|
-
layer_type=layer["type"],
|
|
879
|
-
material=layer["material"],
|
|
880
|
-
fillMaterial=layer["dielectric_fill"],
|
|
881
|
-
thickness=layer["thickness"],
|
|
882
|
-
)
|
|
883
|
-
prev_layer = layer_name
|
|
884
|
-
else:
|
|
885
|
-
self.add_layer(
|
|
886
|
-
layer_name,
|
|
887
|
-
base_layer=layer_name,
|
|
888
|
-
method="insert_below",
|
|
889
|
-
layer_type=layer["type"],
|
|
890
|
-
material=layer["material"],
|
|
891
|
-
fillMaterial=layer["dielectric_fill"],
|
|
892
|
-
thickness=layer["thickness"],
|
|
893
|
-
)
|
|
894
|
-
prev_layer = layer_name
|
|
895
|
-
if layer_name in self.layers:
|
|
896
|
-
self.layers[layer["name"]]._load_layer(layer)
|
|
897
|
-
return True
|
|
898
|
-
|
|
899
971
|
def limits(self, only_metals=False):
|
|
900
972
|
"""Retrieve stackup limits.
|
|
901
973
|
|
|
@@ -906,8 +978,12 @@ class Stackup(LayerCollection):
|
|
|
906
978
|
|
|
907
979
|
Returns
|
|
908
980
|
-------
|
|
909
|
-
|
|
910
|
-
|
|
981
|
+
tuple
|
|
982
|
+
Tuple containing:
|
|
983
|
+
- Upper layer name
|
|
984
|
+
- Upper layer top elevation
|
|
985
|
+
- Lower layer name
|
|
986
|
+
- Lower layer bottom elevation
|
|
911
987
|
"""
|
|
912
988
|
if only_metals:
|
|
913
989
|
input_layers = GrpcLayerTypeSet.SIGNAL_LAYER_SET
|
|
@@ -927,11 +1003,11 @@ class Stackup(LayerCollection):
|
|
|
927
1003
|
Returns
|
|
928
1004
|
-------
|
|
929
1005
|
bool
|
|
930
|
-
``True`` when
|
|
1006
|
+
``True`` when successful.
|
|
931
1007
|
|
|
932
1008
|
Examples
|
|
933
1009
|
--------
|
|
934
|
-
>>> edb = Edb(edbpath=targetfile,
|
|
1010
|
+
>>> edb = Edb(edbpath=targetfile, edbversion="2021.2")
|
|
935
1011
|
>>> edb.stackup.flip_design()
|
|
936
1012
|
>>> edb.save()
|
|
937
1013
|
>>> edb.close_edb()
|
|
@@ -1027,7 +1103,7 @@ class Stackup(LayerCollection):
|
|
|
1027
1103
|
Returns
|
|
1028
1104
|
-------
|
|
1029
1105
|
float
|
|
1030
|
-
|
|
1106
|
+
Thickness value.
|
|
1031
1107
|
"""
|
|
1032
1108
|
layers = list(self.layers.values())
|
|
1033
1109
|
layers.sort(key=lambda lay: lay.lower_elevation)
|
|
@@ -1039,10 +1115,14 @@ class Stackup(LayerCollection):
|
|
|
1039
1115
|
return round(thickness, 7)
|
|
1040
1116
|
|
|
1041
1117
|
def _get_solder_height(self, layer_name):
|
|
1118
|
+
height = 0.0
|
|
1042
1119
|
for _, val in self._pedb.components.instances.items():
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1120
|
+
try:
|
|
1121
|
+
if val.solder_ball_height and val.placement_layer == layer_name:
|
|
1122
|
+
height = val.solder_ball_height
|
|
1123
|
+
except:
|
|
1124
|
+
pass
|
|
1125
|
+
return height
|
|
1046
1126
|
|
|
1047
1127
|
def _remove_solder_pec(self, layer_name):
|
|
1048
1128
|
for _, val in self._pedb.components.instances.items():
|
|
@@ -1052,16 +1132,18 @@ class Stackup(LayerCollection):
|
|
|
1052
1132
|
port_property.reference_size_auto = False
|
|
1053
1133
|
port_property.reference_size = (GrpcValue(0.0), GrpcValue(0.0))
|
|
1054
1134
|
comp_prop.port_property = port_property
|
|
1055
|
-
val.
|
|
1135
|
+
val.component_property = comp_prop
|
|
1056
1136
|
|
|
1057
1137
|
def adjust_solder_dielectrics(self):
|
|
1058
|
-
"""Adjust the stack-up by adding or modifying dielectric layers that
|
|
1059
|
-
|
|
1060
|
-
the
|
|
1138
|
+
"""Adjust the stack-up by adding or modifying dielectric layers that contain solder balls.
|
|
1139
|
+
|
|
1140
|
+
This method identifies the solder-ball height and adjusts the dielectric thickness on top (or bottom)
|
|
1141
|
+
to fit the thickness in order to merge another layout.
|
|
1061
1142
|
|
|
1062
1143
|
Returns
|
|
1063
1144
|
-------
|
|
1064
1145
|
bool
|
|
1146
|
+
``True`` when successful.
|
|
1065
1147
|
"""
|
|
1066
1148
|
for el, val in self._pedb.components.instances.items():
|
|
1067
1149
|
if val.solder_ball_height:
|
|
@@ -1099,33 +1181,33 @@ class Stackup(LayerCollection):
|
|
|
1099
1181
|
flipped_stackup=True,
|
|
1100
1182
|
place_on_top=True,
|
|
1101
1183
|
):
|
|
1102
|
-
"""Place current
|
|
1103
|
-
|
|
1184
|
+
"""Place current cell into another cell using layer placement method.
|
|
1185
|
+
|
|
1186
|
+
Flip the current layer stackup of a layout if requested.
|
|
1104
1187
|
|
|
1105
1188
|
Parameters
|
|
1106
1189
|
----------
|
|
1107
|
-
edb : Edb
|
|
1108
|
-
|
|
1109
|
-
angle :
|
|
1110
|
-
|
|
1111
|
-
offset_x :
|
|
1112
|
-
|
|
1113
|
-
offset_y :
|
|
1114
|
-
|
|
1190
|
+
edb : :class:`pyedb.Edb`
|
|
1191
|
+
Target Edb object.
|
|
1192
|
+
angle : float, optional
|
|
1193
|
+
Rotation angle in degrees. The default is ``0.0``.
|
|
1194
|
+
offset_x : float, optional
|
|
1195
|
+
X offset value. The default is ``0.0``.
|
|
1196
|
+
offset_y : float, optional
|
|
1197
|
+
Y offset value. The default is ``0.0``.
|
|
1115
1198
|
flipped_stackup : bool, optional
|
|
1116
|
-
|
|
1117
|
-
If `True` and place_on_top is `True` the stackup will be flipped before the merge.
|
|
1199
|
+
Whether to flip the current layout. The default is ``True``.
|
|
1118
1200
|
place_on_top : bool, optional
|
|
1119
|
-
|
|
1201
|
+
Whether to place the current layout on top of the destination layout. The default is ``True``.
|
|
1120
1202
|
|
|
1121
1203
|
Returns
|
|
1122
1204
|
-------
|
|
1123
1205
|
bool
|
|
1124
|
-
``True`` when
|
|
1206
|
+
``True`` when successful.
|
|
1125
1207
|
|
|
1126
1208
|
Examples
|
|
1127
1209
|
--------
|
|
1128
|
-
>>> edb1 = Edb(edbpath=targetfile1,
|
|
1210
|
+
>>> edb1 = Edb(edbpath=targetfile1, edbversion="2021.2")
|
|
1129
1211
|
>>> edb2 = Edb(edbpath=targetfile2, edbversion="2021.2")
|
|
1130
1212
|
|
|
1131
1213
|
>>> hosting_cmp = edb1.components.get_component_by_name("U100")
|
|
@@ -1188,36 +1270,35 @@ class Stackup(LayerCollection):
|
|
|
1188
1270
|
place_on_top=True,
|
|
1189
1271
|
solder_height=0,
|
|
1190
1272
|
):
|
|
1191
|
-
"""Place current
|
|
1192
|
-
|
|
1273
|
+
"""Place current cell into another cell using 3D placement method.
|
|
1274
|
+
|
|
1275
|
+
Flip the current layer stackup of a layout if requested.
|
|
1193
1276
|
|
|
1194
1277
|
Parameters
|
|
1195
1278
|
----------
|
|
1196
|
-
edb : Edb
|
|
1197
|
-
|
|
1198
|
-
angle :
|
|
1199
|
-
|
|
1200
|
-
offset_x :
|
|
1201
|
-
|
|
1202
|
-
offset_y :
|
|
1203
|
-
|
|
1279
|
+
edb : :class:`pyedb.Edb`
|
|
1280
|
+
Target Edb object.
|
|
1281
|
+
angle : float, optional
|
|
1282
|
+
Rotation angle in degrees. The default is ``0.0``.
|
|
1283
|
+
offset_x : float, optional
|
|
1284
|
+
X offset value. The default is ``0.0``.
|
|
1285
|
+
offset_y : float, optional
|
|
1286
|
+
Y offset value. The default is ``0.0``.
|
|
1204
1287
|
flipped_stackup : bool, optional
|
|
1205
|
-
|
|
1206
|
-
If `True` and place_on_top is `True` the stackup will be flipped before the merge.
|
|
1288
|
+
Whether to flip the current layout. The default is ``True``.
|
|
1207
1289
|
place_on_top : bool, optional
|
|
1208
|
-
|
|
1290
|
+
Whether to place the current layout on top of the destination layout. The default is ``True``.
|
|
1209
1291
|
solder_height : float, optional
|
|
1210
|
-
Solder
|
|
1211
|
-
This value will be added to the elevation to align the two layouts.
|
|
1292
|
+
Solder ball or bumps height. This value will be added to the elevation to align the two layouts.
|
|
1212
1293
|
|
|
1213
1294
|
Returns
|
|
1214
1295
|
-------
|
|
1215
1296
|
bool
|
|
1216
|
-
``True`` when
|
|
1297
|
+
``True`` when successful.
|
|
1217
1298
|
|
|
1218
1299
|
Examples
|
|
1219
1300
|
--------
|
|
1220
|
-
>>> edb1 = Edb(edbpath=targetfile1,
|
|
1301
|
+
>>> edb1 = Edb(edbpath=targetfile1, edbversion="2021.2")
|
|
1221
1302
|
>>> edb2 = Edb(edbpath=targetfile2, edbversion="2021.2")
|
|
1222
1303
|
>>> hosting_cmp = edb1.components.get_component_by_name("U100")
|
|
1223
1304
|
>>> mounted_cmp = edb2.components.get_component_by_name("BGA")
|
|
@@ -1260,7 +1341,7 @@ class Stackup(LayerCollection):
|
|
|
1260
1341
|
_offset_y = GrpcValue(offset_y)
|
|
1261
1342
|
|
|
1262
1343
|
if edb_cell.name not in self._pedb.cell_names:
|
|
1263
|
-
list_cells = self._pedb.copy_cells(edb_cell
|
|
1344
|
+
list_cells = self._pedb.copy_cells(edb_cell)
|
|
1264
1345
|
edb_cell = list_cells[0]
|
|
1265
1346
|
self._pedb.layout.cell.is_blackbox = True
|
|
1266
1347
|
cell_inst2 = GrpcCellInstance.create(
|
|
@@ -1271,9 +1352,9 @@ class Stackup(LayerCollection):
|
|
|
1271
1352
|
stackup_source = self._pedb.layout.layer_collection
|
|
1272
1353
|
|
|
1273
1354
|
if place_on_top:
|
|
1274
|
-
cell_inst2.placement_layer = stackup_target.
|
|
1355
|
+
cell_inst2.placement_layer = list(LayerCollection(self._pedb, stackup_target).layers.values())[0]
|
|
1275
1356
|
else:
|
|
1276
|
-
cell_inst2.placement_layer = stackup_target.
|
|
1357
|
+
cell_inst2.placement_layer = list(LayerCollection(self._pedb, stackup_target).layers.values())[-1]
|
|
1277
1358
|
cell_inst2.placement_3d = True
|
|
1278
1359
|
res = stackup_target.get_top_bottom_stackup_layers(GrpcLayerTypeSet.SIGNAL_LAYER_SET)
|
|
1279
1360
|
target_top_elevation = res[1]
|
|
@@ -1301,7 +1382,13 @@ class Stackup(LayerCollection):
|
|
|
1301
1382
|
point_loc = GrpcPoint3DData(zero_data, zero_data, zero_data)
|
|
1302
1383
|
point_from = GrpcPoint3DData(one_data, zero_data, zero_data)
|
|
1303
1384
|
point_to = GrpcPoint3DData(math.cos(_angle), -1 * math.sin(_angle), zero_data)
|
|
1304
|
-
cell_inst2.transform3d
|
|
1385
|
+
transform = cell_inst2.transform3d.create_from_one_axis_to_another(from_axis=point_from, to_axis=point_to)
|
|
1386
|
+
cell_inst2.transform3d = transform
|
|
1387
|
+
transform = cell_inst2.transform3d.create_from_axis_and_angle(axis=point_loc, angle=angle)
|
|
1388
|
+
cell_inst2.transform3d = transform
|
|
1389
|
+
transform = cell_inst2.transform3d.create_from_offset(offset=point3d_t)
|
|
1390
|
+
cell_inst2.transform3d = transform
|
|
1391
|
+
# TODO check if component is properly placed.
|
|
1305
1392
|
return True
|
|
1306
1393
|
|
|
1307
1394
|
def place_instance(
|
|
@@ -1315,48 +1402,31 @@ class Stackup(LayerCollection):
|
|
|
1315
1402
|
place_on_top=True,
|
|
1316
1403
|
solder_height=0,
|
|
1317
1404
|
):
|
|
1318
|
-
"""Place
|
|
1319
|
-
Flip the current layer stackup of a layout if requested. Transform parameters currently not supported.
|
|
1405
|
+
"""Place a component instance in the layout using 3D placement.
|
|
1320
1406
|
|
|
1321
1407
|
Parameters
|
|
1322
1408
|
----------
|
|
1323
|
-
component_edb : Edb
|
|
1324
|
-
|
|
1325
|
-
angle :
|
|
1326
|
-
|
|
1327
|
-
offset_x :
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
The default
|
|
1333
|
-
offset_z : double, optional
|
|
1334
|
-
The z offset value. (i.e. elevation offset for placement relative to the top layer conductor).
|
|
1335
|
-
The default value is ``0.0``, which places the cell layout on top of the top conductor
|
|
1336
|
-
layer of the target EDB.
|
|
1409
|
+
component_edb : :class:`pyedb.Edb`
|
|
1410
|
+
Component Edb object to place.
|
|
1411
|
+
angle : float, optional
|
|
1412
|
+
Rotation angle in degrees. The default is ``0.0``.
|
|
1413
|
+
offset_x : float, optional
|
|
1414
|
+
X offset value. The default is ``0.0``.
|
|
1415
|
+
offset_y : float, optional
|
|
1416
|
+
Y offset value. The default is ``0.0``.
|
|
1417
|
+
offset_z : float, optional
|
|
1418
|
+
Z offset value (elevation offset). The default is ``0.0``.
|
|
1337
1419
|
flipped_stackup : bool, optional
|
|
1338
|
-
|
|
1339
|
-
If `True` and place_on_top is `True` the stackup will be flipped before the merge.
|
|
1420
|
+
Whether to flip the component stackup. The default is ``True``.
|
|
1340
1421
|
place_on_top : bool, optional
|
|
1341
|
-
|
|
1422
|
+
Whether to place the component on top of the target layout. The default is ``True``.
|
|
1342
1423
|
solder_height : float, optional
|
|
1343
|
-
Solder
|
|
1344
|
-
This value will be added to the elevation to align the two layouts.
|
|
1424
|
+
Solder ball or bumps height. The default is ``0``.
|
|
1345
1425
|
|
|
1346
1426
|
Returns
|
|
1347
1427
|
-------
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
Examples
|
|
1352
|
-
--------
|
|
1353
|
-
>>> edb1 = Edb(edbpath=targetfile1, edbversion="2021.2")
|
|
1354
|
-
>>> edb2 = Edb(edbpath=targetfile2, edbversion="2021.2")
|
|
1355
|
-
>>> hosting_cmp = edb1.components.get_component_by_name("U100")
|
|
1356
|
-
>>> mounted_cmp = edb2.components.get_component_by_name("BGA")
|
|
1357
|
-
>>> edb1.stackup.place_instance(edb2, angle=0.0, offset_x="1mm",
|
|
1358
|
-
... offset_y="2mm", flipped_stackup=False, place_on_top=True,
|
|
1359
|
-
... )
|
|
1428
|
+
:class:`ansys.edb.core.hierarchy.CellInstance`
|
|
1429
|
+
Cell instance created.
|
|
1360
1430
|
"""
|
|
1361
1431
|
_angle = angle * math.pi / 180.0
|
|
1362
1432
|
|
|
@@ -1392,7 +1462,7 @@ class Stackup(LayerCollection):
|
|
|
1392
1462
|
_offset_y = GrpcValue(offset_y)
|
|
1393
1463
|
|
|
1394
1464
|
if edb_cell.name not in self._pedb.cell_names:
|
|
1395
|
-
list_cells = self._pedb.copy_cells(edb_cell
|
|
1465
|
+
list_cells = self._pedb.copy_cells(edb_cell)
|
|
1396
1466
|
edb_cell = list_cells[0]
|
|
1397
1467
|
for cell in self._pedb.active_db.top_circuit_cells:
|
|
1398
1468
|
if cell.name == edb_cell.name:
|
|
@@ -1444,7 +1514,13 @@ class Stackup(LayerCollection):
|
|
|
1444
1514
|
point_loc = GrpcPoint3DData(zero_data, zero_data, zero_data)
|
|
1445
1515
|
point_from = GrpcPoint3DData(one_data, zero_data, zero_data)
|
|
1446
1516
|
point_to = GrpcPoint3DData(math.cos(_angle), -1 * math.sin(_angle), zero_data)
|
|
1447
|
-
cell_inst2.transform3d
|
|
1517
|
+
transform = cell_inst2.transform3d.create_from_axis_and_angle(axis=point_loc, angle=angle)
|
|
1518
|
+
cell_inst2.transform3d = transform
|
|
1519
|
+
transform = cell_inst2.transform3d.create_from_one_axis_to_another(point_from, point_to)
|
|
1520
|
+
cell_inst2.transform3d = transform
|
|
1521
|
+
transform = cell_inst2.transform3d.create_from_offset(point3d_t)
|
|
1522
|
+
cell_inst2.transform3d = transform
|
|
1523
|
+
# TODO check is position is correct.
|
|
1448
1524
|
return cell_inst2
|
|
1449
1525
|
|
|
1450
1526
|
def place_a3dcomp_3d_placement(
|
|
@@ -1455,51 +1531,46 @@ class Stackup(LayerCollection):
|
|
|
1455
1531
|
offset_y=0.0,
|
|
1456
1532
|
offset_z=0.0,
|
|
1457
1533
|
place_on_top=True,
|
|
1458
|
-
):
|
|
1459
|
-
"""Place a 3D
|
|
1460
|
-
|
|
1461
|
-
|
|
1534
|
+
) -> bool:
|
|
1535
|
+
"""Place a 3D component into the current layout.
|
|
1536
|
+
|
|
1537
|
+
3D Component ports are not visible via EDB. They will be visible after the EDB has been opened in Ansys
|
|
1538
|
+
Electronics Desktop as a project.
|
|
1462
1539
|
|
|
1463
1540
|
Parameters
|
|
1464
1541
|
----------
|
|
1465
1542
|
a3dcomp_path : str
|
|
1466
|
-
Path to the 3D Component file (
|
|
1467
|
-
angle :
|
|
1543
|
+
Path to the 3D Component file (``*.a3dcomp``) to place.
|
|
1544
|
+
angle : float, optional
|
|
1468
1545
|
Clockwise rotation angle applied to the a3dcomp.
|
|
1469
|
-
offset_x :
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
The default
|
|
1475
|
-
offset_z : double, optional
|
|
1476
|
-
The z offset value. (i.e. elevation)
|
|
1477
|
-
The default value is ``0.0``.
|
|
1546
|
+
offset_x : float, optional
|
|
1547
|
+
X offset value. The default is ``0.0``.
|
|
1548
|
+
offset_y : float, optional
|
|
1549
|
+
Y offset value. The default is ``0.0``.
|
|
1550
|
+
offset_z : float, optional
|
|
1551
|
+
Z offset value (elevation). The default is ``0.0``.
|
|
1478
1552
|
place_on_top : bool, optional
|
|
1479
|
-
Whether to place the 3D
|
|
1480
|
-
|
|
1553
|
+
Whether to place the 3D component on the top or the bottom of this layout. If ``False``, the 3D component
|
|
1554
|
+
will be flipped over around its X axis.
|
|
1481
1555
|
|
|
1482
1556
|
Returns
|
|
1483
1557
|
-------
|
|
1484
1558
|
bool
|
|
1485
|
-
``True`` if successful
|
|
1559
|
+
``True`` if successful, ``False`` if not.
|
|
1486
1560
|
|
|
1487
1561
|
Examples
|
|
1488
1562
|
--------
|
|
1489
|
-
>>> edb1 = Edb(edbpath=targetfile1,
|
|
1563
|
+
>>> edb1 = Edb(edbpath=targetfile1, edbversion="2021.2")
|
|
1490
1564
|
>>> a3dcomp_path = "connector.a3dcomp"
|
|
1491
1565
|
>>> edb1.stackup.place_a3dcomp_3d_placement(a3dcomp_path, angle=0.0, offset_x="1mm",
|
|
1492
1566
|
... offset_y="2mm", flipped_stackup=False, place_on_top=True,
|
|
1493
1567
|
... )
|
|
1494
1568
|
"""
|
|
1495
|
-
zero_data = GrpcValue(0.0)
|
|
1496
|
-
one_data = GrpcValue(1.0)
|
|
1497
|
-
local_origin = GrpcPoint3DData(0.0, 0.0, 0.0)
|
|
1498
1569
|
rotation_axis_from = GrpcPoint3DData(1.0, 0.0, 0.0)
|
|
1499
1570
|
_angle = angle * math.pi / 180.0
|
|
1500
1571
|
rotation_axis_to = GrpcPoint3DData(math.cos(_angle), -1 * math.sin(_angle), 0.0)
|
|
1501
1572
|
|
|
1502
|
-
stackup_target =
|
|
1573
|
+
stackup_target = LayerCollection(self._pedb, self._pedb.layout.layer_collection)
|
|
1503
1574
|
res = stackup_target.get_top_bottom_stackup_layers(GrpcLayerTypeSet.SIGNAL_LAYER_SET)
|
|
1504
1575
|
target_top_elevation = res[1]
|
|
1505
1576
|
target_bottom_elevation = res[3]
|
|
@@ -1521,9 +1592,12 @@ class Stackup(LayerCollection):
|
|
|
1521
1592
|
return False
|
|
1522
1593
|
|
|
1523
1594
|
mcad_model.cell_instance.placement_3d = True
|
|
1524
|
-
mcad_model.cell_instance.transform3d
|
|
1525
|
-
|
|
1595
|
+
transform_rotation = mcad_model.cell_instance.transform3d.create_from_axis_and_angle(
|
|
1596
|
+
axis=rotation_axis_from, angle=flip_angle.value
|
|
1526
1597
|
)
|
|
1598
|
+
mcad_model.cell_instance.transform3d = transform_rotation
|
|
1599
|
+
transform_translation = mcad_model.cell_instance.transform3d.create_from_offset(offset=location)
|
|
1600
|
+
mcad_model.cell_instance.transform3d = transform_translation
|
|
1527
1601
|
return True
|
|
1528
1602
|
|
|
1529
1603
|
def residual_copper_area_per_layer(self):
|
|
@@ -1532,11 +1606,11 @@ class Stackup(LayerCollection):
|
|
|
1532
1606
|
Returns
|
|
1533
1607
|
-------
|
|
1534
1608
|
dict
|
|
1535
|
-
|
|
1609
|
+
Dictionary of copper area per layer.
|
|
1536
1610
|
|
|
1537
1611
|
Examples
|
|
1538
1612
|
--------
|
|
1539
|
-
>>> edb = Edb(edbpath=targetfile1,
|
|
1613
|
+
>>> edb = Edb(edbpath=targetfile1, edbversion="2021.2")
|
|
1540
1614
|
>>> edb.stackup.residual_copper_area_per_layer()
|
|
1541
1615
|
"""
|
|
1542
1616
|
temp_data = {name: 0 for name, _ in self.signal_layers.items()}
|
|
@@ -1555,10 +1629,21 @@ class Stackup(LayerCollection):
|
|
|
1555
1629
|
temp_data = {name: area / outline_area * 100 for name, area in temp_data.items()}
|
|
1556
1630
|
return temp_data
|
|
1557
1631
|
|
|
1558
|
-
# TODO: This method might need some refactoring
|
|
1559
|
-
|
|
1560
1632
|
def _import_dict(self, json_dict, rename=False):
|
|
1561
|
-
"""Import stackup from a dictionary.
|
|
1633
|
+
"""Import stackup from a dictionary.
|
|
1634
|
+
|
|
1635
|
+
Parameters
|
|
1636
|
+
----------
|
|
1637
|
+
json_dict : dict
|
|
1638
|
+
Dictionary containing stackup information.
|
|
1639
|
+
rename : bool, optional
|
|
1640
|
+
Whether to rename layers. The default is ``False``.
|
|
1641
|
+
|
|
1642
|
+
Returns
|
|
1643
|
+
-------
|
|
1644
|
+
bool
|
|
1645
|
+
``True`` when successful.
|
|
1646
|
+
"""
|
|
1562
1647
|
if not "materials" in json_dict:
|
|
1563
1648
|
self._logger.info("Configuration file does not have material definition. Using aedb and syslib materials.")
|
|
1564
1649
|
else:
|
|
@@ -1699,7 +1784,20 @@ class Stackup(LayerCollection):
|
|
|
1699
1784
|
return True
|
|
1700
1785
|
|
|
1701
1786
|
def _import_json(self, file_path, rename=False):
|
|
1702
|
-
"""Import stackup from a
|
|
1787
|
+
"""Import stackup from a JSON file.
|
|
1788
|
+
|
|
1789
|
+
Parameters
|
|
1790
|
+
----------
|
|
1791
|
+
file_path : str
|
|
1792
|
+
Path to the JSON file.
|
|
1793
|
+
rename : bool, optional
|
|
1794
|
+
Whether to rename layers. The default is ``False``.
|
|
1795
|
+
|
|
1796
|
+
Returns
|
|
1797
|
+
-------
|
|
1798
|
+
bool
|
|
1799
|
+
``True`` when successful.
|
|
1800
|
+
"""
|
|
1703
1801
|
if file_path:
|
|
1704
1802
|
f = open(file_path)
|
|
1705
1803
|
json_dict = json.load(f) # pragma: no cover
|
|
@@ -1712,6 +1810,11 @@ class Stackup(LayerCollection):
|
|
|
1712
1810
|
----------
|
|
1713
1811
|
file_path : str
|
|
1714
1812
|
File path to the CSV file.
|
|
1813
|
+
|
|
1814
|
+
Returns
|
|
1815
|
+
-------
|
|
1816
|
+
bool
|
|
1817
|
+
``True`` when successful.
|
|
1715
1818
|
"""
|
|
1716
1819
|
if not pd:
|
|
1717
1820
|
self._pedb.logger.error("Pandas is needed. You must install it first.")
|
|
@@ -1753,16 +1856,19 @@ class Stackup(LayerCollection):
|
|
|
1753
1856
|
|
|
1754
1857
|
Parameters
|
|
1755
1858
|
----------
|
|
1756
|
-
layers: dict
|
|
1859
|
+
layers : dict, optional
|
|
1757
1860
|
Dictionary containing layer information.
|
|
1758
|
-
materials: dict
|
|
1861
|
+
materials : dict, optional
|
|
1759
1862
|
Dictionary containing material information.
|
|
1760
|
-
roughness: dict
|
|
1863
|
+
roughness : dict, optional
|
|
1761
1864
|
Dictionary containing roughness information.
|
|
1865
|
+
non_stackup_layers : dict, optional
|
|
1866
|
+
Dictionary containing non-stackup layer information.
|
|
1762
1867
|
|
|
1763
1868
|
Returns
|
|
1764
1869
|
-------
|
|
1765
|
-
|
|
1870
|
+
bool
|
|
1871
|
+
``True`` when successful.
|
|
1766
1872
|
"""
|
|
1767
1873
|
if materials:
|
|
1768
1874
|
self._add_materials_from_dictionary(materials)
|
|
@@ -1879,9 +1985,14 @@ class Stackup(LayerCollection):
|
|
|
1879
1985
|
def _get(self):
|
|
1880
1986
|
"""Get stackup information from layout.
|
|
1881
1987
|
|
|
1882
|
-
Returns
|
|
1883
|
-
|
|
1884
|
-
|
|
1988
|
+
Returns
|
|
1989
|
+
-------
|
|
1990
|
+
tuple
|
|
1991
|
+
Tuple containing:
|
|
1992
|
+
- layers (dict)
|
|
1993
|
+
- materials (dict)
|
|
1994
|
+
- roughness_models (dict)
|
|
1995
|
+
- non_stackup_layers (dict)
|
|
1885
1996
|
"""
|
|
1886
1997
|
layers = OrderedDict()
|
|
1887
1998
|
roughness_models = OrderedDict()
|
|
@@ -1946,39 +2057,30 @@ class Stackup(LayerCollection):
|
|
|
1946
2057
|
def _add_materials_from_dictionary(self, material_dict):
|
|
1947
2058
|
materials = self.self._pedb.materials.materials
|
|
1948
2059
|
for name, material_properties in material_dict.items():
|
|
1949
|
-
if
|
|
1950
|
-
|
|
1951
|
-
materials.add_conductor_material(name, material_properties["Conductivity"])
|
|
1952
|
-
else:
|
|
1953
|
-
materials.add_dielectric_material(
|
|
1954
|
-
name,
|
|
1955
|
-
material_properties["Permittivity"],
|
|
1956
|
-
material_properties["DielectricLossTangent"],
|
|
1957
|
-
)
|
|
2060
|
+
if "Conductivity" in material_properties:
|
|
2061
|
+
materials.add_conductor_material(name, material_properties["Conductivity"])
|
|
1958
2062
|
else:
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
material.loss_tanget = material_properties["DielectricLossTangent"]
|
|
2063
|
+
materials.add_dielectric_material(
|
|
2064
|
+
name,
|
|
2065
|
+
material_properties["Permittivity"],
|
|
2066
|
+
material_properties["DielectricLossTangent"],
|
|
2067
|
+
)
|
|
1965
2068
|
return True
|
|
1966
2069
|
|
|
1967
2070
|
def _import_xml(self, file_path, rename=False):
|
|
1968
|
-
"""Read external
|
|
1969
|
-
You can use xml file to import layer stackup but using json file is recommended.
|
|
1970
|
-
see :class:`pyedb.dotnet.database.edb_data.simulation_configuration.SimulationConfiguration´ class to
|
|
1971
|
-
generate files`.
|
|
2071
|
+
"""Read external XML file and convert into JSON format.
|
|
1972
2072
|
|
|
1973
2073
|
Parameters
|
|
1974
2074
|
----------
|
|
1975
|
-
file_path: str
|
|
2075
|
+
file_path : str
|
|
1976
2076
|
Path to external XML file.
|
|
2077
|
+
rename : bool, optional
|
|
2078
|
+
Whether to rename layers. The default is ``False``.
|
|
1977
2079
|
|
|
1978
2080
|
Returns
|
|
1979
2081
|
-------
|
|
1980
2082
|
bool
|
|
1981
|
-
``True`` when successful
|
|
2083
|
+
``True`` when successful.
|
|
1982
2084
|
"""
|
|
1983
2085
|
if not colors:
|
|
1984
2086
|
self._pedb.logger.error("Matplotlib is needed. Please, install it first.")
|
|
@@ -2037,17 +2139,17 @@ class Stackup(LayerCollection):
|
|
|
2037
2139
|
return self._pedb.configuration.load(cfg, apply_file=True)
|
|
2038
2140
|
|
|
2039
2141
|
def _export_xml(self, file_path):
|
|
2040
|
-
"""Export stackup information to an external
|
|
2142
|
+
"""Export stackup information to an external XML file.
|
|
2041
2143
|
|
|
2042
2144
|
Parameters
|
|
2043
2145
|
----------
|
|
2044
|
-
file_path: str
|
|
2146
|
+
file_path : str
|
|
2045
2147
|
Path to external XML file.
|
|
2046
2148
|
|
|
2047
2149
|
Returns
|
|
2048
2150
|
-------
|
|
2049
2151
|
bool
|
|
2050
|
-
``True`` when successful
|
|
2152
|
+
``True`` when successful.
|
|
2051
2153
|
"""
|
|
2052
2154
|
layers, materials, roughness, non_stackup_layers = self._get()
|
|
2053
2155
|
|
|
@@ -2087,25 +2189,23 @@ class Stackup(LayerCollection):
|
|
|
2087
2189
|
return True
|
|
2088
2190
|
|
|
2089
2191
|
def load(self, file_path, rename=False):
|
|
2090
|
-
"""Import stackup from a file.
|
|
2091
|
-
have the same number of signal layers. Signals layers can be renamed. Dielectric layers can be
|
|
2092
|
-
added and deleted.
|
|
2192
|
+
"""Import stackup from a file.
|
|
2093
2193
|
|
|
2194
|
+
Supported formats: XML, CSV, JSON.
|
|
2094
2195
|
|
|
2095
2196
|
Parameters
|
|
2096
2197
|
----------
|
|
2097
|
-
file_path : str
|
|
2098
|
-
Path to stackup file or
|
|
2099
|
-
rename : bool
|
|
2100
|
-
If
|
|
2101
|
-
|
|
2102
|
-
in the layout, layers are renamed according the file.
|
|
2103
|
-
Note that layer order matters, and has to be writtent from top to bottom layer in the file.
|
|
2198
|
+
file_path : str or dict
|
|
2199
|
+
Path to stackup file or dictionary with stackup details.
|
|
2200
|
+
rename : bool, optional
|
|
2201
|
+
If ``False``, layers in layout not found in the stackup file are deleted.
|
|
2202
|
+
If ``True`` and the number of layers in the stackup file equals the number of stackup layers
|
|
2203
|
+
in the layout, layers are renamed according to the file.
|
|
2104
2204
|
|
|
2105
2205
|
Returns
|
|
2106
2206
|
-------
|
|
2107
2207
|
bool
|
|
2108
|
-
``True`` when successful
|
|
2208
|
+
``True`` when successful.
|
|
2109
2209
|
|
|
2110
2210
|
Examples
|
|
2111
2211
|
--------
|
|
@@ -2135,32 +2235,31 @@ class Stackup(LayerCollection):
|
|
|
2135
2235
|
scale_elevation=True,
|
|
2136
2236
|
show=True,
|
|
2137
2237
|
):
|
|
2138
|
-
"""Plot current stackup and
|
|
2139
|
-
|
|
2238
|
+
"""Plot the current stackup and optionally overlap padstack definitions.
|
|
2239
|
+
|
|
2240
|
+
Only supports 'Laminate' and 'Overlapping' stackup types.
|
|
2140
2241
|
|
|
2141
2242
|
Parameters
|
|
2142
2243
|
----------
|
|
2143
2244
|
save_plot : str, optional
|
|
2144
|
-
|
|
2145
|
-
If ``save_plot`` is provided, the ``show`` parameter is ignored.
|
|
2245
|
+
Path to save the plot image. If provided, ``show`` is ignored.
|
|
2146
2246
|
size : tuple, optional
|
|
2147
|
-
Image size in
|
|
2148
|
-
plot_definitions : str
|
|
2149
|
-
List of padstack definitions to plot on the stackup.
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
Last layer to plot from the bottom. Default is `None` to plot up to top layer.
|
|
2247
|
+
Image size in pixels (width, height). Default is ``(2000, 1500)``.
|
|
2248
|
+
plot_definitions : str or list, optional
|
|
2249
|
+
List of padstack definitions to plot on the stackup. Only supported for Laminate mode.
|
|
2250
|
+
first_layer : str or :class:`pyedb.grpc.database.layers.layer.Layer`, optional
|
|
2251
|
+
First layer to plot from the bottom. Default is ``None`` (start from bottom).
|
|
2252
|
+
last_layer : str or :class:`pyedb.grpc.database.layers.layer.Layer`, optional
|
|
2253
|
+
Last layer to plot from the bottom. Default is ``None`` (plot up to top layer).
|
|
2155
2254
|
scale_elevation : bool, optional
|
|
2156
|
-
|
|
2157
|
-
Default is `True`.
|
|
2255
|
+
Scale real layer thickness so that max_thickness = 3 * min_thickness. Default is ``True``.
|
|
2158
2256
|
show : bool, optional
|
|
2159
|
-
Whether to show the plot
|
|
2257
|
+
Whether to show the plot. Default is ``True``.
|
|
2160
2258
|
|
|
2161
2259
|
Returns
|
|
2162
2260
|
-------
|
|
2163
|
-
:class:`matplotlib.
|
|
2261
|
+
:class:`matplotlib.pyplot`
|
|
2262
|
+
Matplotlib plot object.
|
|
2164
2263
|
"""
|
|
2165
2264
|
|
|
2166
2265
|
from pyedb.generic.constants import CSS4_COLORS
|
|
@@ -2363,7 +2462,7 @@ class Stackup(LayerCollection):
|
|
|
2363
2462
|
width = len(columns) + 1
|
|
2364
2463
|
for i, c in enumerate(columns[:-1]):
|
|
2365
2464
|
for j, r in enumerate(c):
|
|
2366
|
-
if r != 0: # and dname == r[0].name
|
|
2465
|
+
if r != 0: # and dname == r[0].name
|
|
2367
2466
|
if columns[i + 1][j] == 0:
|
|
2368
2467
|
# nothing on the right, so expand the fill
|
|
2369
2468
|
x = r[1]
|