pyedb 0.55.0__py3-none-any.whl → 0.57.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of pyedb might be problematic. Click here for more details.
- pyedb/__init__.py +1 -1
- pyedb/configuration/cfg_data.py +3 -0
- pyedb/configuration/cfg_operations.py +2 -2
- pyedb/configuration/cfg_ports_sources.py +1 -1
- pyedb/configuration/cfg_terminals.py +232 -0
- pyedb/configuration/configuration.py +146 -3
- pyedb/dotnet/clr_module.py +1 -2
- pyedb/dotnet/database/Variables.py +56 -41
- pyedb/dotnet/database/cell/layout.py +5 -1
- pyedb/dotnet/database/cell/primitive/primitive.py +2 -2
- pyedb/dotnet/database/cell/terminal/bundle_terminal.py +12 -0
- pyedb/dotnet/database/cell/terminal/pingroup_terminal.py +1 -1
- pyedb/dotnet/database/cell/terminal/terminal.py +38 -0
- pyedb/dotnet/database/components.py +55 -52
- pyedb/dotnet/database/dotnet/database.py +1 -0
- pyedb/dotnet/database/edb_data/control_file.py +6 -3
- pyedb/dotnet/database/edb_data/nets_data.py +3 -3
- pyedb/dotnet/database/edb_data/padstacks_data.py +5 -2
- pyedb/dotnet/database/edb_data/ports.py +0 -25
- pyedb/dotnet/database/edb_data/primitives_data.py +3 -3
- pyedb/dotnet/database/edb_data/raptor_x_simulation_setup_data.py +18 -19
- pyedb/dotnet/database/edb_data/simulation_configuration.py +3 -3
- pyedb/dotnet/database/hfss.py +9 -8
- pyedb/dotnet/database/layout_validation.py +6 -3
- pyedb/dotnet/database/materials.py +1 -3
- pyedb/dotnet/database/modeler.py +7 -3
- pyedb/dotnet/database/nets.py +27 -19
- pyedb/dotnet/database/padstack.py +91 -2
- pyedb/dotnet/database/sim_setup_data/io/siwave.py +1 -1
- pyedb/dotnet/database/siwave.py +4 -3
- pyedb/dotnet/database/stackup.py +50 -26
- pyedb/dotnet/database/utilities/heatsink.py +0 -1
- pyedb/dotnet/database/utilities/simulation_setup.py +7 -5
- pyedb/dotnet/database/utilities/siwave_cpa_simulation_setup.py +1 -0
- pyedb/dotnet/database/utilities/siwave_simulation_setup.py +5 -2
- pyedb/dotnet/edb.py +41 -36
- pyedb/exceptions.py +1 -2
- pyedb/extensions/create_cell_array.py +408 -0
- pyedb/generic/data_handlers.py +17 -28
- pyedb/generic/design_types.py +25 -38
- pyedb/generic/filesystem.py +9 -4
- pyedb/generic/general_methods.py +6 -7
- pyedb/generic/plot.py +2 -2
- pyedb/generic/settings.py +4 -0
- pyedb/grpc/database/_typing.py +0 -0
- pyedb/grpc/database/components.py +30 -11
- pyedb/grpc/database/control_file.py +14 -35
- pyedb/grpc/database/definition/materials.py +1 -1
- pyedb/grpc/database/definition/package_def.py +6 -3
- pyedb/grpc/database/definition/padstack_def.py +4 -7
- pyedb/grpc/database/hfss.py +1 -4
- pyedb/grpc/database/hierarchy/component.py +3 -4
- pyedb/grpc/database/hierarchy/pingroup.py +16 -3
- pyedb/grpc/database/layers/layer.py +1 -2
- pyedb/grpc/database/layers/stackup_layer.py +42 -19
- pyedb/grpc/database/layout/layout.py +117 -28
- pyedb/grpc/database/layout/voltage_regulator.py +6 -1
- pyedb/grpc/database/layout_validation.py +7 -4
- pyedb/grpc/database/modeler.py +241 -256
- pyedb/grpc/database/net/differential_pair.py +9 -2
- pyedb/grpc/database/net/extended_net.py +24 -9
- pyedb/grpc/database/net/net.py +14 -5
- pyedb/grpc/database/net/net_class.py +24 -7
- pyedb/grpc/database/nets.py +11 -43
- pyedb/grpc/database/padstacks.py +92 -16
- pyedb/grpc/database/primitive/bondwire.py +3 -67
- pyedb/grpc/database/primitive/circle.py +42 -3
- pyedb/grpc/database/primitive/padstack_instance.py +17 -19
- pyedb/grpc/database/primitive/path.py +154 -5
- pyedb/grpc/database/primitive/polygon.py +75 -9
- pyedb/grpc/database/primitive/primitive.py +2 -2
- pyedb/grpc/database/primitive/rectangle.py +105 -4
- pyedb/grpc/database/simulation_setup/hfss_general_settings.py +0 -2
- pyedb/grpc/database/simulation_setup/hfss_settings_options.py +0 -4
- pyedb/grpc/database/simulation_setup/siwave_cpa_simulation_setup.py +4 -2
- pyedb/grpc/database/simulation_setup/sweep_data.py +1 -3
- pyedb/grpc/database/siwave.py +6 -13
- pyedb/grpc/database/source_excitations.py +49 -57
- pyedb/grpc/database/stackup.py +50 -27
- pyedb/grpc/database/terminal/bundle_terminal.py +10 -3
- pyedb/grpc/database/terminal/pingroup_terminal.py +8 -1
- pyedb/grpc/database/terminal/terminal.py +19 -8
- pyedb/grpc/database/utility/heat_sink.py +0 -1
- pyedb/grpc/database/utility/hfss_extent_info.py +2 -2
- pyedb/grpc/database/utility/value.py +1 -0
- pyedb/grpc/database/utility/xml_control_file.py +6 -3
- pyedb/grpc/edb.py +33 -24
- pyedb/grpc/edb_init.py +1 -0
- pyedb/grpc/rpc_session.py +4 -3
- pyedb/ipc2581/ecad/cad_data/layer_feature.py +6 -2
- pyedb/ipc2581/ecad/cad_data/step.py +1 -1
- pyedb/ipc2581/ipc2581.py +8 -7
- pyedb/libraries/common.py +3 -4
- pyedb/libraries/rf_libraries/base_functions.py +7 -16
- pyedb/libraries/rf_libraries/planar_antennas.py +3 -21
- pyedb/misc/downloads.py +1 -0
- pyedb/misc/misc.py +5 -2
- pyedb/misc/siw_feature_config/emc_rule_checker_settings.py +1 -1
- pyedb/misc/utilities.py +0 -1
- pyedb/modeler/geometry_operators.py +9 -8
- pyedb/siwave.py +4 -6
- pyedb/siwave_core/__init__.py +0 -0
- pyedb/siwave_core/cpa/__init__.py +0 -0
- {pyedb-0.55.0.dist-info → pyedb-0.57.0.dist-info}/METADATA +3 -3
- {pyedb-0.55.0.dist-info → pyedb-0.57.0.dist-info}/RECORD +107 -102
- {pyedb-0.55.0.dist-info → pyedb-0.57.0.dist-info}/WHEEL +0 -0
- {pyedb-0.55.0.dist-info → pyedb-0.57.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -85,11 +85,13 @@ class RaptorXSimulationSetup(SimulationSetup):
|
|
|
85
85
|
Examples
|
|
86
86
|
--------
|
|
87
87
|
>>> setup1 = edbapp.create_hfss_setup("setup1")
|
|
88
|
-
>>> setup1.add_frequency_sweep(
|
|
89
|
-
...
|
|
90
|
-
...
|
|
91
|
-
...
|
|
92
|
-
...
|
|
88
|
+
>>> setup1.add_frequency_sweep(
|
|
89
|
+
... frequency_sweep=[
|
|
90
|
+
... ["linear count", "0", "1kHz", 1],
|
|
91
|
+
... ["log scale", "1kHz", "0.1GHz", 10],
|
|
92
|
+
... ["linear scale", "0.1GHz", "10GHz", "0.1GHz"],
|
|
93
|
+
... ]
|
|
94
|
+
... )
|
|
93
95
|
"""
|
|
94
96
|
if name in self.frequency_sweeps:
|
|
95
97
|
return False
|
|
@@ -234,9 +236,7 @@ class RaptorXSimulationAdvancedSettings(object):
|
|
|
234
236
|
if isinstance(value, list):
|
|
235
237
|
self._advanced_settings.NetSettingsOptions = convert_py_list_to_net_list(value)
|
|
236
238
|
else:
|
|
237
|
-
self.logger.error(
|
|
238
|
-
f"RaptorX setup net_settings_options input setter must be a list. " f"Provided value {value}"
|
|
239
|
-
)
|
|
239
|
+
self.logger.error(f"RaptorX setup net_settings_options input setter must be a list. Provided value {value}")
|
|
240
240
|
|
|
241
241
|
@property
|
|
242
242
|
def override_shrink_fac(self):
|
|
@@ -276,7 +276,7 @@ class RaptorXSimulationAdvancedSettings(object):
|
|
|
276
276
|
self._advanced_settings.UseAccelerateViaExtraction = value
|
|
277
277
|
else:
|
|
278
278
|
self.logger.error(
|
|
279
|
-
"RaptorX setup use_accelerate_via_extraction setter input must be boolean.
|
|
279
|
+
f"RaptorX setup use_accelerate_via_extraction setter input must be boolean. Provided value {value}"
|
|
280
280
|
)
|
|
281
281
|
|
|
282
282
|
@property
|
|
@@ -290,7 +290,7 @@ class RaptorXSimulationAdvancedSettings(object):
|
|
|
290
290
|
self._advanced_settings.UseAutoRemovalSliverPoly = value
|
|
291
291
|
else:
|
|
292
292
|
self.logger.error(
|
|
293
|
-
f"RaptorX setup use_auto_removal_sliver_poly setter must be a boolean.
|
|
293
|
+
f"RaptorX setup use_auto_removal_sliver_poly setter must be a boolean. Provided value {value}"
|
|
294
294
|
)
|
|
295
295
|
|
|
296
296
|
@property
|
|
@@ -334,7 +334,7 @@ class RaptorXSimulationAdvancedSettings(object):
|
|
|
334
334
|
self._advanced_settings.UseEliminateSlitPerHoles = value
|
|
335
335
|
else:
|
|
336
336
|
self.logger.error(
|
|
337
|
-
f"RaptorX setup use_eliminate_slit_per_holes setter must be a boolean.
|
|
337
|
+
f"RaptorX setup use_eliminate_slit_per_holes setter must be a boolean. Provided value {value}"
|
|
338
338
|
)
|
|
339
339
|
|
|
340
340
|
@property
|
|
@@ -350,7 +350,7 @@ class RaptorXSimulationAdvancedSettings(object):
|
|
|
350
350
|
self._advanced_settings.UseEnableAdvancedCapEffects = value
|
|
351
351
|
else:
|
|
352
352
|
self.logger.error(
|
|
353
|
-
f"RaptorX setup use_enable_advanced_cap_effects setter must be a boolean.
|
|
353
|
+
f"RaptorX setup use_enable_advanced_cap_effects setter must be a boolean. Provided value {value}"
|
|
354
354
|
)
|
|
355
355
|
|
|
356
356
|
@property
|
|
@@ -366,7 +366,7 @@ class RaptorXSimulationAdvancedSettings(object):
|
|
|
366
366
|
self._advanced_settings.UseEnableEtchTransform = value
|
|
367
367
|
else:
|
|
368
368
|
self.logger.error(
|
|
369
|
-
f"RaptorX setup use_enable_etch_transform setter must be a boolean.
|
|
369
|
+
f"RaptorX setup use_enable_etch_transform setter must be a boolean. Provided value {value}"
|
|
370
370
|
)
|
|
371
371
|
|
|
372
372
|
@property
|
|
@@ -382,7 +382,7 @@ class RaptorXSimulationAdvancedSettings(object):
|
|
|
382
382
|
self._advanced_settings.UseEnableHybridExtraction = value
|
|
383
383
|
else:
|
|
384
384
|
self.logger.error(
|
|
385
|
-
f"RaptorX setup use_enable_hybrid_extraction setter must be a boolean.
|
|
385
|
+
f"RaptorX setup use_enable_hybrid_extraction setter must be a boolean. Provided value {value}"
|
|
386
386
|
)
|
|
387
387
|
|
|
388
388
|
@property
|
|
@@ -414,7 +414,7 @@ class RaptorXSimulationAdvancedSettings(object):
|
|
|
414
414
|
self._advanced_settings.UseExtractFloatingMetalsDummy = value
|
|
415
415
|
else:
|
|
416
416
|
self.logger.error(
|
|
417
|
-
f"RaptorX setup use_extract_floating_metals_dummy setter must be a boolean.
|
|
417
|
+
f"RaptorX setup use_extract_floating_metals_dummy setter must be a boolean. Provided value {value}"
|
|
418
418
|
)
|
|
419
419
|
|
|
420
420
|
@property
|
|
@@ -430,8 +430,7 @@ class RaptorXSimulationAdvancedSettings(object):
|
|
|
430
430
|
self._advanced_settings.UseExtractFloatingMetalsFloating = value
|
|
431
431
|
else:
|
|
432
432
|
self.logger.error(
|
|
433
|
-
f"RaptorX setup use_extract_floating_metals_floating setter must be a boolean. "
|
|
434
|
-
f"Provided value {value}"
|
|
433
|
+
f"RaptorX setup use_extract_floating_metals_floating setter must be a boolean. Provided value {value}"
|
|
435
434
|
)
|
|
436
435
|
|
|
437
436
|
@property
|
|
@@ -493,7 +492,7 @@ class RaptorXSimulationAdvancedSettings(object):
|
|
|
493
492
|
self._advanced_settings.UsePlaneProjectionFactor = value
|
|
494
493
|
else:
|
|
495
494
|
self.logger.error(
|
|
496
|
-
f"RaptorX setup use_plane_projection_factor setter must be a boolean.
|
|
495
|
+
f"RaptorX setup use_plane_projection_factor setter must be a boolean. Provided value {value}"
|
|
497
496
|
)
|
|
498
497
|
|
|
499
498
|
@property
|
|
@@ -506,4 +505,4 @@ class RaptorXSimulationAdvancedSettings(object):
|
|
|
506
505
|
if isinstance(value, bool):
|
|
507
506
|
self._advanced_settings.UseRelaxedZAxis = value
|
|
508
507
|
else:
|
|
509
|
-
self.logger.error(f"RaptorX setup use_relaxed_z_axis setter must be a boolean.
|
|
508
|
+
self.logger.error(f"RaptorX setup use_relaxed_z_axis setter must be a boolean. Provided value {value}")
|
|
@@ -2132,7 +2132,7 @@ class SimulationConfiguration(object):
|
|
|
2132
2132
|
|
|
2133
2133
|
Defined the radiation box type, Conformal, Bounding box and ConvexHull are supported (HFSS only).
|
|
2134
2134
|
|
|
2135
|
-
>>> sim_setup.max_num_passes= 30
|
|
2135
|
+
>>> sim_setup.max_num_passes = 30
|
|
2136
2136
|
|
|
2137
2137
|
Default value is 30, specify the maximum number of adaptive passes (only HFSS). Reasonable high value is recommended
|
|
2138
2138
|
to force the solver reaching the convergence criteria.
|
|
@@ -2147,7 +2147,7 @@ class SimulationConfiguration(object):
|
|
|
2147
2147
|
local minima.
|
|
2148
2148
|
|
|
2149
2149
|
>>> from dotnet.generic.constants import BasisOrder
|
|
2150
|
-
>>> sim_setup.basis_order =
|
|
2150
|
+
>>> sim_setup.basis_order = BasisOrder.Single
|
|
2151
2151
|
|
|
2152
2152
|
Select the order basis (HFSS only), Zero, Single, Double and Mixed are supported. For Signal integrity Single or
|
|
2153
2153
|
Mixed should be used.
|
|
@@ -2229,7 +2229,7 @@ class SimulationConfiguration(object):
|
|
|
2229
2229
|
|
|
2230
2230
|
Activate the loop resistance usage per pin when ``True``
|
|
2231
2231
|
|
|
2232
|
-
>>> sim_setup.dc_via_report_path =
|
|
2232
|
+
>>> sim_setup.dc_via_report_path = "C:\\temp\\via_report_file"
|
|
2233
2233
|
|
|
2234
2234
|
Define the via report path file.
|
|
2235
2235
|
|
pyedb/dotnet/database/hfss.py
CHANGED
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
"""
|
|
24
24
|
This module contains the ``EdbHfss`` class.
|
|
25
25
|
"""
|
|
26
|
+
|
|
26
27
|
import math
|
|
27
28
|
|
|
28
29
|
from pyedb.dotnet.database.edb_data.hfss_extent_info import HfssExtentInfo
|
|
@@ -174,8 +175,8 @@ class EdbHfss(object):
|
|
|
174
175
|
|
|
175
176
|
>>> from pyedb import Edb
|
|
176
177
|
>>> edbapp = Edb("myaedbfolder", "project name", "release version")
|
|
177
|
-
>>> pins =edbapp.components.get_pin_from_component("U2A5")
|
|
178
|
-
>>> edbapp.hfss.create_circuit_port_on_pin(pins[0], pins[1],50,"port_name")
|
|
178
|
+
>>> pins = edbapp.components.get_pin_from_component("U2A5")
|
|
179
|
+
>>> edbapp.hfss.create_circuit_port_on_pin(pins[0], pins[1], 50, "port_name")
|
|
179
180
|
|
|
180
181
|
Returns
|
|
181
182
|
-------
|
|
@@ -211,8 +212,8 @@ class EdbHfss(object):
|
|
|
211
212
|
|
|
212
213
|
>>> from pyedb import Edb
|
|
213
214
|
>>> edbapp = Edb("myaedbfolder", "project name", "release version")
|
|
214
|
-
>>> pins =edbapp.components.get_pin_from_component("U2A5")
|
|
215
|
-
>>> edbapp.hfss.create_voltage_source_on_pin(pins[0], pins[1],50,"source_name")
|
|
215
|
+
>>> pins = edbapp.components.get_pin_from_component("U2A5")
|
|
216
|
+
>>> edbapp.hfss.create_voltage_source_on_pin(pins[0], pins[1], 50, "source_name")
|
|
216
217
|
"""
|
|
217
218
|
return self._pedb.siwave.create_voltage_source_on_pin(pos_pin, neg_pin, voltage_value, phase_value, source_name)
|
|
218
219
|
|
|
@@ -242,8 +243,8 @@ class EdbHfss(object):
|
|
|
242
243
|
|
|
243
244
|
>>> from pyedb import Edb
|
|
244
245
|
>>> edbapp = Edb("myaedbfolder", "project name", "release version")
|
|
245
|
-
>>> pins =edbapp.components.get_pin_from_component("U2A5")
|
|
246
|
-
>>> edbapp.hfss.create_current_source_on_pin(pins[0], pins[1],50,"source_name")
|
|
246
|
+
>>> pins = edbapp.components.get_pin_from_component("U2A5")
|
|
247
|
+
>>> edbapp.hfss.create_current_source_on_pin(pins[0], pins[1], 50, "source_name")
|
|
247
248
|
"""
|
|
248
249
|
|
|
249
250
|
return self._pedb.siwave.create_current_source_on_pin(pos_pin, neg_pin, current_value, phase_value, source_name)
|
|
@@ -272,8 +273,8 @@ class EdbHfss(object):
|
|
|
272
273
|
|
|
273
274
|
>>> from pyedb import Edb
|
|
274
275
|
>>> edbapp = Edb("myaedbfolder", "project name", "release version")
|
|
275
|
-
>>> pins =edbapp.components.get_pin_from_component("U2A5")
|
|
276
|
-
>>> edbapp.hfss.create_resistor_on_pin(pins[0], pins[1],50,"res_name")
|
|
276
|
+
>>> pins = edbapp.components.get_pin_from_component("U2A5")
|
|
277
|
+
>>> edbapp.hfss.create_resistor_on_pin(pins[0], pins[1], 50, "res_name")
|
|
277
278
|
"""
|
|
278
279
|
return self._pedb.siwave.create_resistor_on_pin(pos_pin, neg_pin, rvalue, resistor_name)
|
|
279
280
|
|
|
@@ -155,7 +155,7 @@ class LayoutValidation:
|
|
|
155
155
|
Examples
|
|
156
156
|
--------
|
|
157
157
|
|
|
158
|
-
>>> renamed_nets = edb.layout_validation.disjoint_nets(["GND","Net2"])
|
|
158
|
+
>>> renamed_nets = edb.layout_validation.disjoint_nets(["GND", "Net2"])
|
|
159
159
|
"""
|
|
160
160
|
|
|
161
161
|
if not net_list:
|
|
@@ -208,8 +208,11 @@ class LayoutValidation:
|
|
|
208
208
|
if isinstance(obj_dict[el], Primitive):
|
|
209
209
|
if not obj_dict[el].is_void:
|
|
210
210
|
sum += obj_dict[el].area()
|
|
211
|
-
except:
|
|
212
|
-
|
|
211
|
+
except Exception as e:
|
|
212
|
+
self._pedb.logger.warning(
|
|
213
|
+
f"A(n) {type(e).__name__} error occurred while calculating area "
|
|
214
|
+
f"for element {elem} - Default value of 0 is used: {str(e)}"
|
|
215
|
+
)
|
|
213
216
|
return sum
|
|
214
217
|
|
|
215
218
|
if order_by_area:
|
|
@@ -243,9 +243,7 @@ class Material(object):
|
|
|
243
243
|
if self.__dc_model and value:
|
|
244
244
|
self.__dc_model.SetDCRelativePermitivity(value)
|
|
245
245
|
else:
|
|
246
|
-
self.__edb.logger.error(
|
|
247
|
-
f"DC permittivity cannot be updated in material without DC model or value {value}." f""
|
|
248
|
-
)
|
|
246
|
+
self.__edb.logger.error(f"DC permittivity cannot be updated in material without DC model or value {value}.")
|
|
249
247
|
|
|
250
248
|
@property
|
|
251
249
|
def dielectric_model_frequency(self):
|
pyedb/dotnet/database/modeler.py
CHANGED
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
"""
|
|
24
24
|
This module contains these classes: `EdbLayout` and `Shape`.
|
|
25
25
|
"""
|
|
26
|
+
|
|
26
27
|
import math
|
|
27
28
|
import warnings
|
|
28
29
|
|
|
@@ -355,8 +356,11 @@ class Modeler(object):
|
|
|
355
356
|
bounding_box.Item2.X.ToDouble(),
|
|
356
357
|
bounding_box.Item2.Y.ToDouble(),
|
|
357
358
|
]
|
|
358
|
-
except:
|
|
359
|
-
|
|
359
|
+
except Exception as e:
|
|
360
|
+
self._logger.warning(
|
|
361
|
+
f"A(n) {type(e).__name__} error occurred while retrieving bounding box for polygon {polygon} - "
|
|
362
|
+
f"Empty list is returned: {str(e)}"
|
|
363
|
+
)
|
|
360
364
|
return bounding
|
|
361
365
|
|
|
362
366
|
def get_polygon_points(self, polygon):
|
|
@@ -383,7 +387,7 @@ class Modeler(object):
|
|
|
383
387
|
--------
|
|
384
388
|
|
|
385
389
|
>>> poly = database.modeler.get_polygons_by_layer("GND")
|
|
386
|
-
>>> points
|
|
390
|
+
>>> points = database.modeler.get_polygon_points(poly[0])
|
|
387
391
|
|
|
388
392
|
"""
|
|
389
393
|
points = []
|
pyedb/dotnet/database/nets.py
CHANGED
|
@@ -308,22 +308,30 @@ class EdbNets(CommonNets):
|
|
|
308
308
|
val_value = cmp.rlc_values
|
|
309
309
|
if refdes in exception_list:
|
|
310
310
|
pass
|
|
311
|
-
elif
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
311
|
+
elif val_type == "Inductor":
|
|
312
|
+
if val_value[1] is None:
|
|
313
|
+
continue
|
|
314
|
+
elif (
|
|
315
|
+
not self._pedb.edb_value(val_value[1]).ToDouble()
|
|
316
|
+
<= self._pedb.edb_value(inductor_below).ToDouble()
|
|
317
|
+
):
|
|
318
|
+
continue
|
|
319
|
+
elif val_type == "Resistor":
|
|
320
|
+
if val_value[0] is None:
|
|
321
|
+
continue
|
|
322
|
+
elif (
|
|
323
|
+
not self._pedb.edb_value(val_value[0]).ToDouble()
|
|
324
|
+
<= self._pedb.edb_value(resistor_below).ToDouble()
|
|
325
|
+
):
|
|
326
|
+
continue
|
|
327
|
+
elif val_type == "Capacitor":
|
|
328
|
+
if val_value[2] is None:
|
|
329
|
+
continue
|
|
330
|
+
elif (
|
|
331
|
+
not self._pedb.edb_value(val_value[2]).ToDouble()
|
|
332
|
+
>= self._pedb.edb_value(capacitor_above).ToDouble()
|
|
333
|
+
):
|
|
334
|
+
continue
|
|
327
335
|
else:
|
|
328
336
|
continue
|
|
329
337
|
|
|
@@ -575,7 +583,7 @@ class EdbNets(CommonNets):
|
|
|
575
583
|
Examples
|
|
576
584
|
--------
|
|
577
585
|
|
|
578
|
-
>>> deleted_nets = database.nets.delete(["Net1","Net2"])
|
|
586
|
+
>>> deleted_nets = database.nets.delete(["Net1", "Net2"])
|
|
579
587
|
"""
|
|
580
588
|
warnings.warn("Use :func:`delete` method instead.", DeprecationWarning)
|
|
581
589
|
return self.delete(netlist=netlist)
|
|
@@ -596,7 +604,7 @@ class EdbNets(CommonNets):
|
|
|
596
604
|
Examples
|
|
597
605
|
--------
|
|
598
606
|
|
|
599
|
-
>>> deleted_nets = database.nets.delete(["Net1","Net2"])
|
|
607
|
+
>>> deleted_nets = database.nets.delete(["Net1", "Net2"])
|
|
600
608
|
"""
|
|
601
609
|
if isinstance(netlist, str):
|
|
602
610
|
netlist = [netlist]
|
|
@@ -733,7 +741,7 @@ class EdbNets(CommonNets):
|
|
|
733
741
|
Examples
|
|
734
742
|
--------
|
|
735
743
|
|
|
736
|
-
>>> renamed_nets = database.nets.find_and_fix_disjoint_nets(["GND","Net2"])
|
|
744
|
+
>>> renamed_nets = database.nets.find_and_fix_disjoint_nets(["GND", "Net2"])
|
|
737
745
|
"""
|
|
738
746
|
warnings.warn("Use new function :func:`edb.layout_validation.disjoint_nets` instead.", DeprecationWarning)
|
|
739
747
|
return self._pedb.layout_validation.disjoint_nets(
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
"""
|
|
24
24
|
This module contains the `EdbPadstacks` class.
|
|
25
25
|
"""
|
|
26
|
+
|
|
26
27
|
from collections import defaultdict
|
|
27
28
|
import math
|
|
28
29
|
from typing import Dict, List
|
|
@@ -708,8 +709,9 @@ class EdbPadstacks(object):
|
|
|
708
709
|
)
|
|
709
710
|
else: # pragma no cover
|
|
710
711
|
self._logger.error(
|
|
711
|
-
"Failed to reassign anti-pad value {} on Pads-stack definition {},"
|
|
712
|
-
|
|
712
|
+
"Failed to reassign anti-pad value {} on Pads-stack definition {}, layer{}".format(
|
|
713
|
+
str(value), padstack.edb_padstack.GetName(), layer
|
|
714
|
+
)
|
|
713
715
|
)
|
|
714
716
|
all_succeed = False
|
|
715
717
|
padstack.edb_padstack.SetData(cloned_padstack_data)
|
|
@@ -1943,3 +1945,90 @@ class EdbPadstacks(object):
|
|
|
1943
1945
|
clusters[int(label)].append(padstack_ids[i])
|
|
1944
1946
|
|
|
1945
1947
|
return dict(clusters)
|
|
1948
|
+
|
|
1949
|
+
def reduce_via_by_density(
|
|
1950
|
+
self, padstacks: List[int], cell_size_x: float = 1e-3, cell_size_y: float = 1e-3, delete: bool = False
|
|
1951
|
+
) -> tuple[List[int], List[List[List[float]]]]:
|
|
1952
|
+
"""
|
|
1953
|
+
Reduce the number of vias by density. Keep only one via which is closest to the center of the cell. The cells
|
|
1954
|
+
are automatically populated based on the input vias.
|
|
1955
|
+
|
|
1956
|
+
Parameters
|
|
1957
|
+
----------
|
|
1958
|
+
padstacks: List[int]
|
|
1959
|
+
List of padstack ids to be reduced.
|
|
1960
|
+
|
|
1961
|
+
cell_size_x : float
|
|
1962
|
+
Width of each grid cell (default is 1e-3).
|
|
1963
|
+
|
|
1964
|
+
cell_size_y : float
|
|
1965
|
+
Height of each grid cell (default is 1e-3).
|
|
1966
|
+
|
|
1967
|
+
delete: bool
|
|
1968
|
+
If True, delete vias that are not kept (default is False).
|
|
1969
|
+
|
|
1970
|
+
Returns
|
|
1971
|
+
-------
|
|
1972
|
+
List[int]
|
|
1973
|
+
IDs of vias kept after reduction.
|
|
1974
|
+
|
|
1975
|
+
List[List[float]]
|
|
1976
|
+
coordinates for grid lines (for plotting).
|
|
1977
|
+
|
|
1978
|
+
"""
|
|
1979
|
+
to_keep = set()
|
|
1980
|
+
|
|
1981
|
+
all_instances = self.instances
|
|
1982
|
+
positions = np.array([all_instances[_id].position for _id in padstacks])
|
|
1983
|
+
|
|
1984
|
+
x_coords, y_coords = positions[:, 0], positions[:, 1]
|
|
1985
|
+
x_min, x_max = np.min(x_coords), np.max(x_coords)
|
|
1986
|
+
y_min, y_max = np.min(y_coords), np.max(y_coords)
|
|
1987
|
+
|
|
1988
|
+
padstacks_array = np.array(padstacks)
|
|
1989
|
+
cell_map = {} # {(cell_x, cell_y): [(id1, [x1, y1]), (id2, [x2, y2), ...]}
|
|
1990
|
+
grid = []
|
|
1991
|
+
|
|
1992
|
+
for idx, pos in enumerate(positions):
|
|
1993
|
+
i = int((pos[0] - x_min) // cell_size_x)
|
|
1994
|
+
j = int((pos[1] - y_min) // cell_size_y)
|
|
1995
|
+
cell_key = (i, j)
|
|
1996
|
+
cell_map.setdefault(cell_key, []).append((padstacks_array[idx], pos))
|
|
1997
|
+
|
|
1998
|
+
for (i, j), items in cell_map.items():
|
|
1999
|
+
# cell center
|
|
2000
|
+
cell_x_min = x_min + i * cell_size_x
|
|
2001
|
+
cell_y_min = y_min + j * cell_size_y
|
|
2002
|
+
cell_x_mid = cell_x_min + 0.5 * cell_size_x
|
|
2003
|
+
cell_y_mid = cell_y_min + 0.5 * cell_size_y
|
|
2004
|
+
|
|
2005
|
+
grid.append(
|
|
2006
|
+
[
|
|
2007
|
+
[
|
|
2008
|
+
cell_x_min,
|
|
2009
|
+
cell_x_min + cell_size_x,
|
|
2010
|
+
cell_x_min + cell_size_x,
|
|
2011
|
+
cell_x_min,
|
|
2012
|
+
cell_x_min,
|
|
2013
|
+
],
|
|
2014
|
+
[
|
|
2015
|
+
cell_y_min,
|
|
2016
|
+
cell_y_min,
|
|
2017
|
+
cell_y_min + cell_size_y,
|
|
2018
|
+
cell_y_min + cell_size_y,
|
|
2019
|
+
cell_y_min,
|
|
2020
|
+
],
|
|
2021
|
+
]
|
|
2022
|
+
)
|
|
2023
|
+
|
|
2024
|
+
# Find closest via to cell center
|
|
2025
|
+
distances = [np.linalg.norm(pos - [cell_x_mid, cell_y_mid]) for _, pos in items]
|
|
2026
|
+
closest_idx = np.argmin(distances)
|
|
2027
|
+
to_keep.add(items[closest_idx][0])
|
|
2028
|
+
|
|
2029
|
+
if delete:
|
|
2030
|
+
to_delete = set(padstacks) - to_keep
|
|
2031
|
+
for _id in to_delete:
|
|
2032
|
+
all_instances[_id].delete()
|
|
2033
|
+
|
|
2034
|
+
return list(to_keep), grid
|
|
@@ -349,7 +349,7 @@ class AdvancedSettings(SettingsBase):
|
|
|
349
349
|
``True`` if automatic mesh is used, ``False`` otherwise.
|
|
350
350
|
"""
|
|
351
351
|
warnings.warn(
|
|
352
|
-
"`automatic_mesh` is deprecated.
|
|
352
|
+
"`automatic_mesh` is deprecated. Use `mesh_automatic` instead.",
|
|
353
353
|
DeprecationWarning,
|
|
354
354
|
)
|
|
355
355
|
return self.sim_setup_info.simulation_settings.AdvancedSettings.MeshAutoMatic
|
pyedb/dotnet/database/siwave.py
CHANGED
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
This module contains these classes: ``CircuitPort``, ``CurrentSource``, ``EdbSiwave``,
|
|
25
25
|
``PinGroup``, ``ResistorSource``, ``Source``, ``SourceType``, and ``VoltageSource``.
|
|
26
26
|
"""
|
|
27
|
+
|
|
27
28
|
import os
|
|
28
29
|
import time
|
|
29
30
|
|
|
@@ -483,8 +484,8 @@ class EdbSiwave(object):
|
|
|
483
484
|
|
|
484
485
|
>>> from pyedb import Edb
|
|
485
486
|
>>> edbapp = Edb("myaedbfolder", "project name", "release version")
|
|
486
|
-
>>> pins =edbapp.components.get_pin_from_component("U2A5")
|
|
487
|
-
>>> edbapp.siwave.create_resistor_on_pin(pins[0], pins[1],50,"res_name")
|
|
487
|
+
>>> pins = edbapp.components.get_pin_from_component("U2A5")
|
|
488
|
+
>>> edbapp.siwave.create_resistor_on_pin(pins[0], pins[1], 50, "res_name")
|
|
488
489
|
"""
|
|
489
490
|
resistor = ResistorSource()
|
|
490
491
|
resistor.positive_node.net = pos_pin.net_name
|
|
@@ -625,7 +626,7 @@ class EdbSiwave(object):
|
|
|
625
626
|
|
|
626
627
|
>>> from pyedb import Edb
|
|
627
628
|
>>> edbapp = Edb("myaedbfolder", "project name", "release version")
|
|
628
|
-
>>> edb.siwave.create_voltage_source_on_net("U2A5","V1P5_S3","U2A5","GND",3.3,0,"source_name")
|
|
629
|
+
>>> edb.siwave.create_voltage_source_on_net("U2A5", "V1P5_S3", "U2A5", "GND", 3.3, 0, "source_name")
|
|
629
630
|
"""
|
|
630
631
|
if not negative_component_name:
|
|
631
632
|
negative_component_name = positive_component_name
|
pyedb/dotnet/database/stackup.py
CHANGED
|
@@ -1137,7 +1137,7 @@ class Stackup(LayerCollection):
|
|
|
1137
1137
|
|
|
1138
1138
|
Examples
|
|
1139
1139
|
--------
|
|
1140
|
-
>>> edb = Edb(edbpath=targetfile,
|
|
1140
|
+
>>> edb = Edb(edbpath=targetfile, edbversion="2021.2")
|
|
1141
1141
|
>>> edb.stackup.flip_design()
|
|
1142
1142
|
>>> edb.save()
|
|
1143
1143
|
>>> edb.close_edb()
|
|
@@ -1227,8 +1227,11 @@ class Stackup(LayerCollection):
|
|
|
1227
1227
|
sball_prop = cmp_prop.GetSolderBallProperty().Clone()
|
|
1228
1228
|
sball_prop.SetPlacement(self._pedb.definition.SolderballPlacement.AbovePadstack)
|
|
1229
1229
|
cmp_prop.SetSolderBallProperty(sball_prop)
|
|
1230
|
-
except:
|
|
1231
|
-
|
|
1230
|
+
except Exception as e:
|
|
1231
|
+
self._logger.warning(
|
|
1232
|
+
f"A(n) {type(e).__name__} error occurred while attempting to update "
|
|
1233
|
+
f"SolderBallProperty for component {cmp}: {str(e)}"
|
|
1234
|
+
)
|
|
1232
1235
|
if cmp_type == self._pedb.definition.ComponentType.IC:
|
|
1233
1236
|
die_prop = cmp_prop.GetDieProperty().Clone()
|
|
1234
1237
|
chip_orientation = die_prop.GetOrientation()
|
|
@@ -1356,22 +1359,28 @@ class Stackup(LayerCollection):
|
|
|
1356
1359
|
|
|
1357
1360
|
Examples
|
|
1358
1361
|
--------
|
|
1359
|
-
>>> edb1 = Edb(edbpath=targetfile1,
|
|
1362
|
+
>>> edb1 = Edb(edbpath=targetfile1, edbversion="2021.2")
|
|
1360
1363
|
>>> edb2 = Edb(edbpath=targetfile2, edbversion="2021.2")
|
|
1361
1364
|
|
|
1362
1365
|
>>> hosting_cmp = edb1.components.get_component_by_name("U100")
|
|
1363
1366
|
>>> mounted_cmp = edb2.components.get_component_by_name("BGA")
|
|
1364
1367
|
|
|
1365
1368
|
>>> vector, rotation, solder_ball_height = edb1.components.get_component_placement_vector(
|
|
1366
|
-
...
|
|
1367
|
-
...
|
|
1368
|
-
...
|
|
1369
|
-
...
|
|
1370
|
-
...
|
|
1371
|
-
...
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
...
|
|
1369
|
+
... mounted_component=mounted_cmp,
|
|
1370
|
+
... hosting_component=hosting_cmp,
|
|
1371
|
+
... mounted_component_pin1="A12",
|
|
1372
|
+
... mounted_component_pin2="A14",
|
|
1373
|
+
... hosting_component_pin1="A12",
|
|
1374
|
+
... hosting_component_pin2="A14",
|
|
1375
|
+
... )
|
|
1376
|
+
>>> edb2.stackup.place_in_layout(
|
|
1377
|
+
... edb1.active_cell,
|
|
1378
|
+
... angle=0.0,
|
|
1379
|
+
... offset_x=vector[0],
|
|
1380
|
+
... offset_y=vector[1],
|
|
1381
|
+
... flipped_stackup=False,
|
|
1382
|
+
... place_on_top=True,
|
|
1383
|
+
... )
|
|
1375
1384
|
"""
|
|
1376
1385
|
# if flipped_stackup and place_on_top or (not flipped_stackup and not place_on_top):
|
|
1377
1386
|
self.adjust_solder_dielectrics()
|
|
@@ -1453,13 +1462,18 @@ class Stackup(LayerCollection):
|
|
|
1453
1462
|
|
|
1454
1463
|
Examples
|
|
1455
1464
|
--------
|
|
1456
|
-
>>> edb1 = Edb(edbpath=targetfile1,
|
|
1465
|
+
>>> edb1 = Edb(edbpath=targetfile1, edbversion="2021.2")
|
|
1457
1466
|
>>> edb2 = Edb(edbpath=targetfile2, edbversion="2021.2")
|
|
1458
1467
|
>>> hosting_cmp = edb1.components.get_component_by_name("U100")
|
|
1459
1468
|
>>> mounted_cmp = edb2.components.get_component_by_name("BGA")
|
|
1460
|
-
>>> edb2.stackup.place_in_layout(
|
|
1461
|
-
...
|
|
1462
|
-
...
|
|
1469
|
+
>>> edb2.stackup.place_in_layout(
|
|
1470
|
+
... edb1.active_cell,
|
|
1471
|
+
... angle=0.0,
|
|
1472
|
+
... offset_x="1mm",
|
|
1473
|
+
... offset_y="2mm",
|
|
1474
|
+
... flipped_stackup=False,
|
|
1475
|
+
... place_on_top=True,
|
|
1476
|
+
... )
|
|
1463
1477
|
"""
|
|
1464
1478
|
_angle = angle * math.pi / 180.0
|
|
1465
1479
|
|
|
@@ -1592,13 +1606,18 @@ class Stackup(LayerCollection):
|
|
|
1592
1606
|
|
|
1593
1607
|
Examples
|
|
1594
1608
|
--------
|
|
1595
|
-
>>> edb1 = Edb(edbpath=targetfile1,
|
|
1609
|
+
>>> edb1 = Edb(edbpath=targetfile1, edbversion="2021.2")
|
|
1596
1610
|
>>> edb2 = Edb(edbpath=targetfile2, edbversion="2021.2")
|
|
1597
1611
|
>>> hosting_cmp = edb1.components.get_component_by_name("U100")
|
|
1598
1612
|
>>> mounted_cmp = edb2.components.get_component_by_name("BGA")
|
|
1599
|
-
>>> edb1.stackup.place_instance(
|
|
1600
|
-
...
|
|
1601
|
-
...
|
|
1613
|
+
>>> edb1.stackup.place_instance(
|
|
1614
|
+
... edb2,
|
|
1615
|
+
... angle=0.0,
|
|
1616
|
+
... offset_x="1mm",
|
|
1617
|
+
... offset_y="2mm",
|
|
1618
|
+
... flipped_stackup=False,
|
|
1619
|
+
... place_on_top=True,
|
|
1620
|
+
... )
|
|
1602
1621
|
"""
|
|
1603
1622
|
_angle = angle * math.pi / 180.0
|
|
1604
1623
|
|
|
@@ -1736,11 +1755,16 @@ class Stackup(LayerCollection):
|
|
|
1736
1755
|
|
|
1737
1756
|
Examples
|
|
1738
1757
|
--------
|
|
1739
|
-
>>> edb1 = Edb(edbpath=targetfile1,
|
|
1758
|
+
>>> edb1 = Edb(edbpath=targetfile1, edbversion="2021.2")
|
|
1740
1759
|
>>> a3dcomp_path = "connector.a3dcomp"
|
|
1741
|
-
>>> edb1.stackup.place_a3dcomp_3d_placement(
|
|
1742
|
-
...
|
|
1743
|
-
...
|
|
1760
|
+
>>> edb1.stackup.place_a3dcomp_3d_placement(
|
|
1761
|
+
... a3dcomp_path,
|
|
1762
|
+
... angle=0.0,
|
|
1763
|
+
... offset_x="1mm",
|
|
1764
|
+
... offset_y="2mm",
|
|
1765
|
+
... flipped_stackup=False,
|
|
1766
|
+
... place_on_top=True,
|
|
1767
|
+
... )
|
|
1744
1768
|
"""
|
|
1745
1769
|
zero_data = self._edb_value(0.0)
|
|
1746
1770
|
one_data = self._edb_value(1.0)
|
|
@@ -1795,7 +1819,7 @@ class Stackup(LayerCollection):
|
|
|
1795
1819
|
|
|
1796
1820
|
Examples
|
|
1797
1821
|
--------
|
|
1798
|
-
>>> edb = Edb(edbpath=targetfile1,
|
|
1822
|
+
>>> edb = Edb(edbpath=targetfile1, edbversion="2021.2")
|
|
1799
1823
|
>>> edb.stackup.residual_copper_area_per_layer()
|
|
1800
1824
|
"""
|
|
1801
1825
|
temp_data = {name: 0 for name, _ in self.signal_layers.items()}
|
|
@@ -371,11 +371,13 @@ class SimulationSetup(object):
|
|
|
371
371
|
Examples
|
|
372
372
|
--------
|
|
373
373
|
>>> setup1 = edbapp.create_siwave_syz_setup("setup1")
|
|
374
|
-
>>> setup1.add_frequency_sweep(
|
|
375
|
-
... [
|
|
376
|
-
...
|
|
377
|
-
...
|
|
378
|
-
...
|
|
374
|
+
>>> setup1.add_frequency_sweep(
|
|
375
|
+
... frequency_sweep=[
|
|
376
|
+
... ["linear count", "0", "1kHz", 1],
|
|
377
|
+
... ["log scale", "1kHz", "0.1GHz", 10],
|
|
378
|
+
... ["linear scale", "0.1GHz", "10GHz", "0.1GHz"],
|
|
379
|
+
... ]
|
|
380
|
+
... )
|
|
379
381
|
"""
|
|
380
382
|
warnings.warn("`add_frequency_sweep` is deprecated. Use `add_sweep` method instead.", DeprecationWarning)
|
|
381
383
|
return self.add_sweep(name, frequency_sweep)
|
|
@@ -691,6 +691,7 @@ class SIWaveCPASimulationSetup:
|
|
|
691
691
|
self._pedb = pedb
|
|
692
692
|
self._channel_setup = ChannelSetup(pedb)
|
|
693
693
|
self._solver_options = SolverOptions(pedb)
|
|
694
|
+
self.type = "cpa"
|
|
694
695
|
if isinstance(siwave_cpa_setup_class, SIwaveCpaSetup):
|
|
695
696
|
self._apply_cfg_object(siwave_cpa_setup_class)
|
|
696
697
|
else:
|