pyedb 0.38.0__py3-none-any.whl → 0.39.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/common/nets.py +53 -139
- pyedb/configuration/cfg_components.py +1 -1
- pyedb/configuration/cfg_general.py +4 -2
- pyedb/configuration/cfg_modeler.py +1 -1
- pyedb/configuration/cfg_package_definition.py +1 -1
- pyedb/configuration/cfg_padstacks.py +1 -1
- pyedb/configuration/cfg_ports_sources.py +56 -23
- pyedb/configuration/configuration.py +18 -1
- pyedb/dotnet/{application → database}/Variables.py +21 -21
- pyedb/dotnet/{edb_core → database}/cell/connectable.py +5 -5
- pyedb/dotnet/{edb_core → database}/cell/hierarchy/component.py +11 -11
- pyedb/dotnet/{edb_core → database}/cell/hierarchy/hierarchy_obj.py +1 -1
- pyedb/dotnet/{edb_core → database}/cell/hierarchy/model.py +1 -1
- pyedb/dotnet/{edb_core → database}/cell/layout.py +17 -17
- pyedb/dotnet/{edb_core → database}/cell/layout_obj.py +3 -3
- pyedb/dotnet/{edb_core → database}/cell/primitive/bondwire.py +1 -1
- pyedb/dotnet/{edb_core → database}/cell/primitive/path.py +4 -4
- pyedb/dotnet/{edb_core → database}/cell/primitive/primitive.py +14 -14
- pyedb/dotnet/{edb_core → database}/cell/terminal/bundle_terminal.py +2 -2
- pyedb/dotnet/{edb_core → database}/cell/terminal/edge_terminal.py +4 -4
- pyedb/dotnet/{edb_core → database}/cell/terminal/padstack_instance_terminal.py +2 -2
- pyedb/dotnet/{edb_core → database}/cell/terminal/pingroup_terminal.py +2 -2
- pyedb/dotnet/{edb_core → database}/cell/terminal/point_terminal.py +2 -2
- pyedb/dotnet/{edb_core → database}/cell/terminal/terminal.py +11 -11
- pyedb/dotnet/{edb_core → database}/cell/voltage_regulator.py +2 -2
- pyedb/dotnet/{edb_core → database}/components.py +101 -124
- pyedb/dotnet/{edb_core → database}/definition/component_def.py +5 -5
- pyedb/dotnet/{edb_core → database}/definition/component_model.py +1 -1
- pyedb/dotnet/{edb_core → database}/definition/definition_obj.py +1 -1
- pyedb/dotnet/{edb_core → database}/definition/definitions.py +2 -2
- pyedb/dotnet/{edb_core → database}/definition/package_def.py +4 -4
- pyedb/dotnet/{edb_core → database}/dotnet/database.py +8 -8
- pyedb/dotnet/{edb_core → database}/dotnet/primitive.py +9 -9
- pyedb/dotnet/{edb_core → database}/edb_data/control_file.py +12 -12
- pyedb/dotnet/{edb_core → database}/edb_data/hfss_extent_info.py +7 -7
- pyedb/dotnet/{edb_core → database}/edb_data/nets_data.py +10 -13
- pyedb/dotnet/{edb_core → database}/edb_data/padstacks_data.py +16 -16
- pyedb/dotnet/{edb_core → database}/edb_data/ports.py +4 -4
- pyedb/dotnet/{edb_core → database}/edb_data/primitives_data.py +5 -5
- pyedb/dotnet/{edb_core → database}/edb_data/raptor_x_simulation_setup_data.py +4 -4
- pyedb/dotnet/{edb_core → database}/edb_data/simulation_configuration.py +10 -10
- pyedb/dotnet/{edb_core → database}/edb_data/sources.py +4 -4
- pyedb/dotnet/{edb_core → database}/edb_data/variables.py +1 -1
- pyedb/dotnet/{edb_core → database}/geometry/polygon_data.py +4 -4
- pyedb/dotnet/{edb_core → database}/hfss.py +8 -8
- pyedb/dotnet/{edb_core → database}/layout_obj_instance.py +1 -1
- pyedb/dotnet/{edb_core → database}/layout_validation.py +2 -2
- pyedb/dotnet/{edb_core → database}/materials.py +23 -8
- pyedb/dotnet/{edb_core → database}/modeler.py +27 -27
- pyedb/dotnet/{edb_core → database}/net_class.py +8 -8
- pyedb/dotnet/{edb_core → database}/nets.py +12 -12
- pyedb/dotnet/{edb_core → database}/padstack.py +15 -15
- pyedb/dotnet/{edb_core → database}/sim_setup_data/data/mesh_operation.py +1 -1
- pyedb/dotnet/{edb_core → database}/sim_setup_data/data/settings.py +3 -3
- pyedb/dotnet/{edb_core → database}/sim_setup_data/data/sim_setup_info.py +2 -2
- pyedb/dotnet/{edb_core → database}/sim_setup_data/data/simulation_settings.py +1 -1
- pyedb/dotnet/{edb_core → database}/sim_setup_data/data/siw_dc_ir_settings.py +1 -1
- pyedb/dotnet/{edb_core → database}/sim_setup_data/data/sweep_data.py +1 -1
- pyedb/dotnet/{edb_core → database}/siwave.py +10 -10
- pyedb/dotnet/{edb_core → database}/stackup.py +12 -12
- pyedb/dotnet/{edb_core → database}/utilities/hfss_simulation_setup.py +15 -15
- pyedb/dotnet/{edb_core → database}/utilities/obj_base.py +1 -1
- pyedb/dotnet/{edb_core → database}/utilities/simulation_setup.py +3 -3
- pyedb/dotnet/{edb_core → database}/utilities/siwave_simulation_setup.py +6 -6
- pyedb/dotnet/edb.py +117 -112
- pyedb/generic/design_types.py +26 -19
- pyedb/generic/general_methods.py +1 -1
- pyedb/generic/plot.py +0 -2
- pyedb/grpc/database/__init__.py +1 -0
- pyedb/grpc/database/components.py +2354 -0
- pyedb/grpc/database/control_file.py +1277 -0
- pyedb/grpc/database/definition/component_def.py +218 -0
- pyedb/grpc/database/definition/component_model.py +39 -0
- pyedb/grpc/database/definition/component_pin.py +32 -0
- pyedb/grpc/database/definition/materials.py +1207 -0
- pyedb/grpc/database/definition/n_port_component_model.py +34 -0
- pyedb/grpc/database/definition/package_def.py +227 -0
- pyedb/grpc/database/definition/padstack_def.py +842 -0
- pyedb/grpc/database/definitions.py +70 -0
- pyedb/grpc/database/general.py +43 -0
- pyedb/grpc/database/geometry/__init__.py +0 -0
- pyedb/grpc/database/geometry/arc_data.py +93 -0
- pyedb/grpc/database/geometry/point_3d_data.py +79 -0
- pyedb/grpc/database/geometry/point_data.py +30 -0
- pyedb/grpc/database/geometry/polygon_data.py +133 -0
- pyedb/grpc/database/hfss.py +1279 -0
- pyedb/grpc/database/hierarchy/__init__.py +0 -0
- pyedb/grpc/database/hierarchy/component.py +1301 -0
- pyedb/grpc/database/hierarchy/model.py +31 -0
- pyedb/grpc/database/hierarchy/netlist_model.py +30 -0
- pyedb/grpc/database/hierarchy/pin_pair_model.py +128 -0
- pyedb/grpc/database/hierarchy/pingroup.py +245 -0
- pyedb/grpc/database/hierarchy/s_parameter_model.py +33 -0
- pyedb/grpc/database/hierarchy/spice_model.py +48 -0
- pyedb/grpc/database/layers/__init__.py +0 -0
- pyedb/grpc/database/layers/layer.py +57 -0
- pyedb/grpc/database/layers/stackup_layer.py +410 -0
- pyedb/grpc/database/layout/__init__.py +0 -0
- pyedb/grpc/database/layout/cell.py +30 -0
- pyedb/grpc/database/layout/layout.py +196 -0
- pyedb/grpc/database/layout/voltage_regulator.py +149 -0
- pyedb/grpc/database/layout_validation.py +319 -0
- pyedb/grpc/database/modeler.py +1468 -0
- pyedb/grpc/database/net/__init__.py +0 -0
- pyedb/grpc/database/net/differential_pair.py +138 -0
- pyedb/grpc/database/net/extended_net.py +340 -0
- pyedb/grpc/database/net/net.py +198 -0
- pyedb/grpc/database/net/net_class.py +93 -0
- pyedb/grpc/database/nets.py +633 -0
- pyedb/grpc/database/padstacks.py +1500 -0
- pyedb/grpc/database/ports/__init__.py +0 -0
- pyedb/grpc/database/ports/ports.py +396 -0
- pyedb/grpc/database/primitive/__init__.py +3 -0
- pyedb/grpc/database/primitive/bondwire.py +181 -0
- pyedb/grpc/database/primitive/circle.py +75 -0
- pyedb/grpc/database/primitive/padstack_instance.py +1116 -0
- pyedb/grpc/database/primitive/path.py +346 -0
- pyedb/grpc/database/primitive/polygon.py +276 -0
- pyedb/grpc/database/primitive/primitive.py +739 -0
- pyedb/grpc/database/primitive/rectangle.py +146 -0
- pyedb/grpc/database/simulation_setup/__init__.py +0 -0
- pyedb/grpc/database/simulation_setup/adaptive_frequency.py +33 -0
- pyedb/grpc/database/simulation_setup/hfss_advanced_meshing_settings.py +32 -0
- pyedb/grpc/database/simulation_setup/hfss_advanced_settings.py +59 -0
- pyedb/grpc/database/simulation_setup/hfss_dcr_settings.py +35 -0
- pyedb/grpc/database/simulation_setup/hfss_general_settings.py +61 -0
- pyedb/grpc/database/simulation_setup/hfss_settings_options.py +78 -0
- pyedb/grpc/database/simulation_setup/hfss_simulation_settings.py +118 -0
- pyedb/grpc/database/simulation_setup/hfss_simulation_setup.py +355 -0
- pyedb/grpc/database/simulation_setup/hfss_solver_settings.py +34 -0
- pyedb/grpc/database/simulation_setup/mesh_operation.py +34 -0
- pyedb/grpc/database/simulation_setup/raptor_x_advanced_settings.py +34 -0
- pyedb/grpc/database/simulation_setup/raptor_x_general_settings.py +33 -0
- pyedb/grpc/database/simulation_setup/raptor_x_simulation_settings.py +64 -0
- pyedb/grpc/database/simulation_setup/raptor_x_simulation_setup.py +125 -0
- pyedb/grpc/database/simulation_setup/siwave_dcir_simulation_setup.py +34 -0
- pyedb/grpc/database/simulation_setup/siwave_simulation_setup.py +119 -0
- pyedb/grpc/database/simulation_setup/sweep_data.py +32 -0
- pyedb/grpc/database/siwave.py +1023 -0
- pyedb/grpc/database/source_excitations.py +2572 -0
- pyedb/grpc/database/stackup.py +2574 -0
- pyedb/grpc/database/terminal/__init__.py +0 -0
- pyedb/grpc/database/terminal/bundle_terminal.py +218 -0
- pyedb/grpc/database/terminal/edge_terminal.py +51 -0
- pyedb/grpc/database/terminal/padstack_instance_terminal.py +171 -0
- pyedb/grpc/database/terminal/pingroup_terminal.py +162 -0
- pyedb/grpc/database/terminal/point_terminal.py +99 -0
- pyedb/grpc/database/terminal/terminal.py +470 -0
- pyedb/grpc/database/utility/__init__.py +3 -0
- pyedb/grpc/database/utility/constants.py +25 -0
- pyedb/grpc/database/utility/heat_sink.py +124 -0
- pyedb/grpc/database/utility/hfss_extent_info.py +448 -0
- pyedb/grpc/database/utility/layout_statistics.py +277 -0
- pyedb/grpc/database/utility/rlc.py +80 -0
- pyedb/grpc/database/utility/simulation_configuration.py +3305 -0
- pyedb/grpc/database/utility/sources.py +388 -0
- pyedb/grpc/database/utility/sweep_data_distribution.py +83 -0
- pyedb/grpc/database/utility/xml_control_file.py +1277 -0
- pyedb/grpc/edb.py +4152 -0
- pyedb/grpc/edb_init.py +481 -0
- pyedb/grpc/rpc_session.py +177 -0
- pyedb/ipc2581/ecad/cad_data/assembly_drawing.py +3 -2
- pyedb/ipc2581/ecad/cad_data/feature.py +4 -3
- pyedb/ipc2581/ecad/cad_data/layer_feature.py +32 -20
- pyedb/ipc2581/ecad/cad_data/outline.py +3 -2
- pyedb/ipc2581/ecad/cad_data/package.py +4 -3
- pyedb/ipc2581/ecad/cad_data/path.py +82 -31
- pyedb/ipc2581/ecad/cad_data/polygon.py +122 -60
- pyedb/ipc2581/ecad/cad_data/profile.py +13 -12
- pyedb/ipc2581/ecad/cad_data/step.py +53 -21
- pyedb/ipc2581/ipc2581.py +47 -49
- pyedb/modeler/geometry_operators.py +1 -1
- {pyedb-0.38.0.dist-info → pyedb-0.39.1.dist-info}/METADATA +5 -2
- pyedb-0.39.1.dist-info/RECORD +288 -0
- pyedb-0.38.0.dist-info/RECORD +0 -195
- /pyedb/dotnet/{edb_core → database}/__init__.py +0 -0
- /pyedb/dotnet/{application → database/cell}/__init__.py +0 -0
- /pyedb/dotnet/{edb_core/cell → database/cell/hierarchy}/__init__.py +0 -0
- /pyedb/dotnet/{edb_core → database}/cell/hierarchy/netlist_model.py +0 -0
- /pyedb/dotnet/{edb_core → database}/cell/hierarchy/pin_pair_model.py +0 -0
- /pyedb/dotnet/{edb_core → database}/cell/hierarchy/s_parameter_model.py +0 -0
- /pyedb/dotnet/{edb_core → database}/cell/hierarchy/spice_model.py +0 -0
- /pyedb/dotnet/{edb_core → database}/cell/primitive/__init__.py +0 -0
- /pyedb/dotnet/{edb_core/cell/hierarchy → database/cell/terminal}/__init__.py +0 -0
- /pyedb/dotnet/{edb_core/cell/terminal → database/definition}/__init__.py +0 -0
- /pyedb/dotnet/{edb_core/definition → database/dotnet}/__init__.py +0 -0
- /pyedb/dotnet/{edb_core/dotnet → database/edb_data}/__init__.py +0 -0
- /pyedb/dotnet/{edb_core → database}/edb_data/design_options.py +0 -0
- /pyedb/dotnet/{edb_core → database}/edb_data/edbvalue.py +0 -0
- /pyedb/dotnet/{edb_core → database}/edb_data/layer_data.py +0 -0
- /pyedb/dotnet/{edb_core → database}/edb_data/utilities.py +0 -0
- /pyedb/dotnet/{edb_core → database}/general.py +0 -0
- /pyedb/dotnet/{edb_core/edb_data → database/geometry}/__init__.py +0 -0
- /pyedb/dotnet/{edb_core → database}/geometry/point_data.py +0 -0
- /pyedb/dotnet/{edb_core → database}/sim_setup_data/__init__.py +0 -0
- /pyedb/dotnet/{edb_core → database}/sim_setup_data/data/__init__.py +0 -0
- /pyedb/dotnet/{edb_core → database}/sim_setup_data/data/adaptive_frequency_data.py +0 -0
- /pyedb/dotnet/{edb_core/geometry → database/sim_setup_data/io}/__init__.py +0 -0
- /pyedb/dotnet/{edb_core → database}/sim_setup_data/io/siwave.py +0 -0
- /pyedb/dotnet/{edb_core → database}/utilities/__init__.py +0 -0
- /pyedb/dotnet/{edb_core → database}/utilities/heatsink.py +0 -0
- /pyedb/{dotnet/edb_core/sim_setup_data/io → grpc/database/definition}/__init__.py +0 -0
- {pyedb-0.38.0.dist-info → pyedb-0.39.1.dist-info}/LICENSE +0 -0
- {pyedb-0.38.0.dist-info → pyedb-0.39.1.dist-info}/WHEEL +0 -0
|
@@ -0,0 +1,633 @@
|
|
|
1
|
+
# Copyright (C) 2023 - 2024 ANSYS, Inc. and/or its affiliates.
|
|
2
|
+
# SPDX-License-Identifier: MIT
|
|
3
|
+
#
|
|
4
|
+
#
|
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
# furnished to do so, subject to the following conditions:
|
|
11
|
+
#
|
|
12
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
# copies or substantial portions of the Software.
|
|
14
|
+
#
|
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
# SOFTWARE.
|
|
22
|
+
|
|
23
|
+
from __future__ import absolute_import # noreorder
|
|
24
|
+
|
|
25
|
+
import warnings
|
|
26
|
+
|
|
27
|
+
from pyedb.common.nets import CommonNets
|
|
28
|
+
from pyedb.generic.general_methods import generate_unique_name
|
|
29
|
+
from pyedb.grpc.database.net.net import Net
|
|
30
|
+
from pyedb.grpc.database.primitive.bondwire import Bondwire
|
|
31
|
+
from pyedb.grpc.database.primitive.path import Path
|
|
32
|
+
from pyedb.grpc.database.primitive.polygon import Polygon
|
|
33
|
+
from pyedb.misc.utilities import compute_arc_points
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class Nets(CommonNets):
|
|
37
|
+
"""Manages EDB methods for nets management accessible from `Edb.nets` property.
|
|
38
|
+
|
|
39
|
+
Examples
|
|
40
|
+
--------
|
|
41
|
+
>>> from pyedb import Edb
|
|
42
|
+
>>> edbapp = Edb("myaedbfolder", edbversion="2021.2")
|
|
43
|
+
>>> edb_nets = edbapp.nets
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
def __getitem__(self, name):
|
|
47
|
+
"""Get nets from the Edb project.
|
|
48
|
+
|
|
49
|
+
Parameters
|
|
50
|
+
----------
|
|
51
|
+
name : str, int
|
|
52
|
+
|
|
53
|
+
Returns
|
|
54
|
+
-------
|
|
55
|
+
:class:` .:class:`pyedb.grpc.database.nets_data.EDBNets`
|
|
56
|
+
|
|
57
|
+
"""
|
|
58
|
+
return Net(self._pedb, Net.find_by_name(self._active_layout, name))
|
|
59
|
+
|
|
60
|
+
def __contains__(self, name):
|
|
61
|
+
"""Determine if a net is named ``name`` or not.
|
|
62
|
+
|
|
63
|
+
Parameters
|
|
64
|
+
----------
|
|
65
|
+
name : str
|
|
66
|
+
|
|
67
|
+
Returns
|
|
68
|
+
-------
|
|
69
|
+
bool
|
|
70
|
+
``True`` when one of the net is named ``name``, ``False`` otherwise.
|
|
71
|
+
|
|
72
|
+
"""
|
|
73
|
+
return name in self.nets
|
|
74
|
+
|
|
75
|
+
def __init__(self, p_edb):
|
|
76
|
+
CommonNets.__init__(self, p_edb)
|
|
77
|
+
self._nets_by_comp_dict = {}
|
|
78
|
+
self._comps_by_nets_dict = {}
|
|
79
|
+
|
|
80
|
+
@property
|
|
81
|
+
def _edb(self):
|
|
82
|
+
""" """
|
|
83
|
+
return self._pedb
|
|
84
|
+
|
|
85
|
+
@property
|
|
86
|
+
def _active_layout(self):
|
|
87
|
+
""" """
|
|
88
|
+
return self._pedb.active_layout
|
|
89
|
+
|
|
90
|
+
@property
|
|
91
|
+
def _layout(self):
|
|
92
|
+
""" """
|
|
93
|
+
return self._pedb.layout
|
|
94
|
+
|
|
95
|
+
@property
|
|
96
|
+
def _cell(self):
|
|
97
|
+
""" """
|
|
98
|
+
return self._pedb.cell
|
|
99
|
+
|
|
100
|
+
@property
|
|
101
|
+
def db(self):
|
|
102
|
+
"""Db object."""
|
|
103
|
+
return self._pedb.active_db
|
|
104
|
+
|
|
105
|
+
@property
|
|
106
|
+
def _logger(self):
|
|
107
|
+
"""Edb logger."""
|
|
108
|
+
return self._pedb.logger
|
|
109
|
+
|
|
110
|
+
@property
|
|
111
|
+
def nets(self):
|
|
112
|
+
"""Nets.
|
|
113
|
+
|
|
114
|
+
Returns
|
|
115
|
+
-------
|
|
116
|
+
dict[str, :class:`pyedb.dotnet.database.edb_data.nets_data.EDBNetsData`]
|
|
117
|
+
Dictionary of nets.
|
|
118
|
+
"""
|
|
119
|
+
return {i.name: i for i in self._pedb.layout.nets}
|
|
120
|
+
|
|
121
|
+
@property
|
|
122
|
+
def netlist(self):
|
|
123
|
+
"""Return the cell netlist.
|
|
124
|
+
|
|
125
|
+
Returns
|
|
126
|
+
-------
|
|
127
|
+
list
|
|
128
|
+
Net names.
|
|
129
|
+
"""
|
|
130
|
+
return list(self.nets.keys())
|
|
131
|
+
|
|
132
|
+
@property
|
|
133
|
+
def signal(self):
|
|
134
|
+
"""Signal nets.
|
|
135
|
+
|
|
136
|
+
Returns
|
|
137
|
+
-------
|
|
138
|
+
dict[str, :class:`pyedb.dotnet.database.edb_data.EDBNetsData`]
|
|
139
|
+
Dictionary of signal nets.
|
|
140
|
+
"""
|
|
141
|
+
nets = {}
|
|
142
|
+
for net, value in self.nets.items():
|
|
143
|
+
if not value.is_power_ground:
|
|
144
|
+
nets[net] = value
|
|
145
|
+
return nets
|
|
146
|
+
|
|
147
|
+
@property
|
|
148
|
+
def power(self):
|
|
149
|
+
"""Power nets.
|
|
150
|
+
|
|
151
|
+
Returns
|
|
152
|
+
-------
|
|
153
|
+
dict[str, :class:`pyedb.dotnet.database.edb_data.EDBNetsData`]
|
|
154
|
+
Dictionary of power nets.
|
|
155
|
+
"""
|
|
156
|
+
nets = {}
|
|
157
|
+
for net, value in self.nets.items():
|
|
158
|
+
if value.is_power_ground:
|
|
159
|
+
nets[net] = value
|
|
160
|
+
return nets
|
|
161
|
+
|
|
162
|
+
def eligible_power_nets(self, threshold=0.3):
|
|
163
|
+
"""Return a list of nets calculated by area to be eligible for PWR/Ground net classification.
|
|
164
|
+
It uses the same algorithm implemented in SIwave.
|
|
165
|
+
|
|
166
|
+
Parameters
|
|
167
|
+
----------
|
|
168
|
+
threshold : float, optional
|
|
169
|
+
Area ratio used by the ``get_power_ground_nets`` method.
|
|
170
|
+
|
|
171
|
+
Returns
|
|
172
|
+
-------
|
|
173
|
+
list of :class:`pyedb.dotnet.database.edb_data.EDBNetsData`
|
|
174
|
+
"""
|
|
175
|
+
pwr_gnd_nets = []
|
|
176
|
+
for net in self._layout.nets[:]:
|
|
177
|
+
total_plane_area = 0.0
|
|
178
|
+
total_trace_area = 0.0
|
|
179
|
+
for primitive in net.primitives:
|
|
180
|
+
primitive = primitive
|
|
181
|
+
if isinstance(primitive, Bondwire):
|
|
182
|
+
continue
|
|
183
|
+
if isinstance(primitive, Path) or isinstance(primitive, Polygon):
|
|
184
|
+
total_plane_area += primitive.polygon_data.area()
|
|
185
|
+
if total_plane_area == 0.0:
|
|
186
|
+
continue
|
|
187
|
+
if total_trace_area == 0.0:
|
|
188
|
+
pwr_gnd_nets.append(Net(self._pedb, net))
|
|
189
|
+
continue
|
|
190
|
+
if total_plane_area > 0.0 and total_trace_area > 0.0:
|
|
191
|
+
if total_plane_area / (total_plane_area + total_trace_area) > threshold:
|
|
192
|
+
pwr_gnd_nets.append(Net(self._pedb, net))
|
|
193
|
+
return pwr_gnd_nets
|
|
194
|
+
|
|
195
|
+
@property
|
|
196
|
+
def nets_by_components(self):
|
|
197
|
+
# type: () -> dict
|
|
198
|
+
"""Get all nets for each component instance."""
|
|
199
|
+
for comp, i in self._pedb.components.instances.items():
|
|
200
|
+
self._nets_by_comp_dict[comp] = i.nets
|
|
201
|
+
return self._nets_by_comp_dict
|
|
202
|
+
|
|
203
|
+
@property
|
|
204
|
+
def components_by_nets(self):
|
|
205
|
+
# type: () -> dict
|
|
206
|
+
"""Get all component instances grouped by nets."""
|
|
207
|
+
for comp, i in self._pedb.components.instances.items():
|
|
208
|
+
for n in i.nets:
|
|
209
|
+
if n in self._comps_by_nets_dict:
|
|
210
|
+
self._comps_by_nets_dict[n].append(comp)
|
|
211
|
+
else:
|
|
212
|
+
self._comps_by_nets_dict[n] = [comp]
|
|
213
|
+
return self._comps_by_nets_dict
|
|
214
|
+
|
|
215
|
+
def generate_extended_nets(
|
|
216
|
+
self,
|
|
217
|
+
resistor_below=10,
|
|
218
|
+
inductor_below=1,
|
|
219
|
+
capacitor_above=1,
|
|
220
|
+
exception_list=None,
|
|
221
|
+
include_signal=True,
|
|
222
|
+
include_power=True,
|
|
223
|
+
):
|
|
224
|
+
# type: (int | float, int | float, int |float, list, bool, bool) -> list
|
|
225
|
+
"""Get extended net and associated components.
|
|
226
|
+
|
|
227
|
+
. deprecated:: pyedb 0.30.0
|
|
228
|
+
Use :func:`pyedb.grpc.extended_nets.generate_extended_nets` instead.
|
|
229
|
+
|
|
230
|
+
Parameters
|
|
231
|
+
----------
|
|
232
|
+
resistor_below : int, float, optional
|
|
233
|
+
Threshold of resistor value. Search extended net across resistors which has value lower than the threshold.
|
|
234
|
+
inductor_below : int, float, optional
|
|
235
|
+
Threshold of inductor value. Search extended net across inductances which has value lower than the
|
|
236
|
+
threshold.
|
|
237
|
+
capacitor_above : int, float, optional
|
|
238
|
+
Threshold of capacitor value. Search extended net across capacitors which has value higher than the
|
|
239
|
+
threshold.
|
|
240
|
+
exception_list : list, optional
|
|
241
|
+
List of components to bypass when performing threshold checks. Components
|
|
242
|
+
in the list are considered as serial components. The default is ``None``.
|
|
243
|
+
include_signal : str, optional
|
|
244
|
+
Whether to generate extended signal nets. The default is ``True``.
|
|
245
|
+
include_power : str, optional
|
|
246
|
+
Whether to generate extended power nets. The default is ``True``.
|
|
247
|
+
|
|
248
|
+
Returns
|
|
249
|
+
-------
|
|
250
|
+
list
|
|
251
|
+
List of all extended nets.
|
|
252
|
+
|
|
253
|
+
Examples
|
|
254
|
+
--------
|
|
255
|
+
>>> from pyedb import Edb
|
|
256
|
+
>>> app = Edb()
|
|
257
|
+
>>> app.nets.get_extended_nets()
|
|
258
|
+
"""
|
|
259
|
+
warnings.warn("Use new method :func:`edb.extended_nets.generate_extended_nets` instead.", DeprecationWarning)
|
|
260
|
+
self._pedb.extended_nets.generate_extended_nets(
|
|
261
|
+
resistor_below, inductor_below, capacitor_above, exception_list, include_signal, include_power
|
|
262
|
+
)
|
|
263
|
+
|
|
264
|
+
@staticmethod
|
|
265
|
+
def _get_points_for_plot(self, my_net_points):
|
|
266
|
+
"""
|
|
267
|
+
Get the points to be plotted.
|
|
268
|
+
"""
|
|
269
|
+
# fmt: off
|
|
270
|
+
x = []
|
|
271
|
+
y = []
|
|
272
|
+
for i, point in enumerate(my_net_points):
|
|
273
|
+
if not point.is_arc:
|
|
274
|
+
x.append(point.x.value)
|
|
275
|
+
y.append(point.y.value)
|
|
276
|
+
else:
|
|
277
|
+
arc_h = point.arc_height.value
|
|
278
|
+
p1 = [my_net_points[i - 1].x.value, my_net_points[i - 1].y.value]
|
|
279
|
+
if i + 1 < len(my_net_points):
|
|
280
|
+
p2 = [my_net_points[i + 1].X.ToDouble(), my_net_points[i + 1].Y.ToDouble()]
|
|
281
|
+
else:
|
|
282
|
+
p2 = [my_net_points[0].X.ToDouble(), my_net_points[0].Y.ToDouble()]
|
|
283
|
+
x_arc, y_arc = compute_arc_points(p1, p2, arc_h)
|
|
284
|
+
x.extend(x_arc)
|
|
285
|
+
y.extend(y_arc)
|
|
286
|
+
# i += 1
|
|
287
|
+
# fmt: on
|
|
288
|
+
return x, y
|
|
289
|
+
|
|
290
|
+
def classify_nets(self, power_nets=None, signal_nets=None):
|
|
291
|
+
"""Reassign power/ground or signal nets based on list of nets.
|
|
292
|
+
|
|
293
|
+
Parameters
|
|
294
|
+
----------
|
|
295
|
+
power_nets : str, list, optional
|
|
296
|
+
List of power nets to assign. Default is `None`.
|
|
297
|
+
signal_nets : str, list, optional
|
|
298
|
+
List of signal nets to assign. Default is `None`.
|
|
299
|
+
|
|
300
|
+
Returns
|
|
301
|
+
-------
|
|
302
|
+
bool
|
|
303
|
+
``True`` when successful, ``False`` when failed.
|
|
304
|
+
"""
|
|
305
|
+
if isinstance(power_nets, str):
|
|
306
|
+
power_nets = []
|
|
307
|
+
elif not power_nets:
|
|
308
|
+
power_nets = []
|
|
309
|
+
if isinstance(signal_nets, str):
|
|
310
|
+
signal_nets = []
|
|
311
|
+
elif not signal_nets:
|
|
312
|
+
signal_nets = []
|
|
313
|
+
for net in power_nets:
|
|
314
|
+
if net in self.nets:
|
|
315
|
+
self.nets[net].is_power_ground = True
|
|
316
|
+
for net in signal_nets:
|
|
317
|
+
if net in self.nets:
|
|
318
|
+
self.nets[net].is_power_ground = False
|
|
319
|
+
return True
|
|
320
|
+
|
|
321
|
+
def is_power_gound_net(self, netname_list):
|
|
322
|
+
"""Determine if one of the nets in a list is power or ground.
|
|
323
|
+
|
|
324
|
+
Parameters
|
|
325
|
+
----------
|
|
326
|
+
netname_list : list
|
|
327
|
+
List of net names.
|
|
328
|
+
|
|
329
|
+
Returns
|
|
330
|
+
-------
|
|
331
|
+
bool
|
|
332
|
+
``True`` when one of the net names is ``"power"`` or ``"ground"``, ``False`` otherwise.
|
|
333
|
+
"""
|
|
334
|
+
if isinstance(netname_list, str):
|
|
335
|
+
netname_list = [netname_list]
|
|
336
|
+
power_nets_names = list(self.power.keys())
|
|
337
|
+
for netname in netname_list:
|
|
338
|
+
if netname in power_nets_names:
|
|
339
|
+
return True
|
|
340
|
+
return False
|
|
341
|
+
|
|
342
|
+
def get_dcconnected_net_list(self, ground_nets=["GND"], res_value=0.001):
|
|
343
|
+
"""Get the nets connected to the direct current through inductors.
|
|
344
|
+
|
|
345
|
+
.. note::
|
|
346
|
+
Only inductors are considered.
|
|
347
|
+
|
|
348
|
+
Parameters
|
|
349
|
+
----------
|
|
350
|
+
ground_nets : list, optional
|
|
351
|
+
List of ground nets. The default is ``["GND"]``.
|
|
352
|
+
|
|
353
|
+
Returns
|
|
354
|
+
-------
|
|
355
|
+
list
|
|
356
|
+
List of nets connected to DC through inductors.
|
|
357
|
+
"""
|
|
358
|
+
temp_list = []
|
|
359
|
+
for _, comp_obj in self._pedb.components.inductors.items():
|
|
360
|
+
numpins = comp_obj.numpins
|
|
361
|
+
|
|
362
|
+
if numpins == 2:
|
|
363
|
+
nets = comp_obj.nets
|
|
364
|
+
if not set(nets).intersection(set(ground_nets)):
|
|
365
|
+
temp_list.append(set(nets))
|
|
366
|
+
else:
|
|
367
|
+
pass
|
|
368
|
+
for _, comp_obj in self._pedb.components.resistors.items():
|
|
369
|
+
numpins = comp_obj.numpins
|
|
370
|
+
|
|
371
|
+
if numpins == 2 and comp_obj.res_value <= res_value:
|
|
372
|
+
nets = comp_obj.nets
|
|
373
|
+
if not set(nets).intersection(set(ground_nets)):
|
|
374
|
+
temp_list.append(set(nets))
|
|
375
|
+
else:
|
|
376
|
+
pass
|
|
377
|
+
dcconnected_net_list = []
|
|
378
|
+
|
|
379
|
+
while not not temp_list:
|
|
380
|
+
s = temp_list.pop(0)
|
|
381
|
+
interseciton_flag = False
|
|
382
|
+
for i in temp_list:
|
|
383
|
+
if not not s.intersection(i):
|
|
384
|
+
i.update(s)
|
|
385
|
+
interseciton_flag = True
|
|
386
|
+
|
|
387
|
+
if not interseciton_flag:
|
|
388
|
+
dcconnected_net_list.append(s)
|
|
389
|
+
|
|
390
|
+
return dcconnected_net_list
|
|
391
|
+
|
|
392
|
+
def get_powertree(self, power_net_name, ground_nets):
|
|
393
|
+
"""Retrieve the power tree.
|
|
394
|
+
|
|
395
|
+
Parameters
|
|
396
|
+
----------
|
|
397
|
+
power_net_name : str
|
|
398
|
+
Name of the power net.
|
|
399
|
+
ground_nets :
|
|
400
|
+
|
|
401
|
+
|
|
402
|
+
Returns
|
|
403
|
+
-------
|
|
404
|
+
|
|
405
|
+
"""
|
|
406
|
+
flag_in_ng = False
|
|
407
|
+
net_group = []
|
|
408
|
+
for ng in self.get_dcconnected_net_list(ground_nets):
|
|
409
|
+
if power_net_name in ng:
|
|
410
|
+
flag_in_ng = True
|
|
411
|
+
net_group.extend(ng)
|
|
412
|
+
break
|
|
413
|
+
|
|
414
|
+
if not flag_in_ng:
|
|
415
|
+
net_group.append(power_net_name)
|
|
416
|
+
|
|
417
|
+
component_list = []
|
|
418
|
+
rats = self._pedb.components.get_rats()
|
|
419
|
+
for net in net_group:
|
|
420
|
+
for el in rats:
|
|
421
|
+
if net in el["net_name"]:
|
|
422
|
+
i = 0
|
|
423
|
+
for n in el["net_name"]:
|
|
424
|
+
if n == net:
|
|
425
|
+
df = [el["refdes"][i], el["pin_name"][i], net]
|
|
426
|
+
component_list.append(df)
|
|
427
|
+
i += 1
|
|
428
|
+
|
|
429
|
+
component_type = []
|
|
430
|
+
for el in component_list:
|
|
431
|
+
refdes = el[0]
|
|
432
|
+
comp_type = self._pedb.components._cmp[refdes].type
|
|
433
|
+
component_type.append(comp_type)
|
|
434
|
+
el.append(comp_type)
|
|
435
|
+
|
|
436
|
+
comp_partname = self._pedb.components._cmp[refdes].partname
|
|
437
|
+
el.append(comp_partname)
|
|
438
|
+
pins = self._pedb.components.get_pin_from_component(component=refdes, net_name=el[2])
|
|
439
|
+
el.append("-".join([i.name for i in pins]))
|
|
440
|
+
|
|
441
|
+
component_list_columns = [
|
|
442
|
+
"refdes",
|
|
443
|
+
"pin_name",
|
|
444
|
+
"net_name",
|
|
445
|
+
"component_type",
|
|
446
|
+
"component_partname",
|
|
447
|
+
"pin_list",
|
|
448
|
+
]
|
|
449
|
+
return component_list, component_list_columns, net_group
|
|
450
|
+
|
|
451
|
+
def get_net_by_name(self, net_name):
|
|
452
|
+
"""Find a net by name."""
|
|
453
|
+
edb_net = Net.find_by_name(self._active_layout, net_name)
|
|
454
|
+
if edb_net is not None:
|
|
455
|
+
return edb_net
|
|
456
|
+
|
|
457
|
+
def delete(self, netlist):
|
|
458
|
+
"""Delete one or more nets from EDB.
|
|
459
|
+
|
|
460
|
+
Parameters
|
|
461
|
+
----------
|
|
462
|
+
netlist : str or list
|
|
463
|
+
One or more nets to delete.
|
|
464
|
+
|
|
465
|
+
Returns
|
|
466
|
+
-------
|
|
467
|
+
list
|
|
468
|
+
List of nets that were deleted.
|
|
469
|
+
|
|
470
|
+
Examples
|
|
471
|
+
--------
|
|
472
|
+
|
|
473
|
+
>>> deleted_nets = database.nets.delete(["Net1","Net2"])
|
|
474
|
+
"""
|
|
475
|
+
if isinstance(netlist, str):
|
|
476
|
+
netlist = [netlist]
|
|
477
|
+
|
|
478
|
+
self._pedb.modeler.delete_primitives(netlist)
|
|
479
|
+
self._pedb.padstacks.delete_padstack_instances(netlist)
|
|
480
|
+
|
|
481
|
+
nets_deleted = []
|
|
482
|
+
|
|
483
|
+
for i in self._pedb.nets.nets.values():
|
|
484
|
+
if i.name in netlist:
|
|
485
|
+
i.delete()
|
|
486
|
+
nets_deleted.append(i.name)
|
|
487
|
+
return nets_deleted
|
|
488
|
+
|
|
489
|
+
def find_or_create_net(self, net_name="", start_with="", contain="", end_with=""):
|
|
490
|
+
"""Find or create the net with the given name in the layout.
|
|
491
|
+
|
|
492
|
+
Parameters
|
|
493
|
+
----------
|
|
494
|
+
net_name : str, optional
|
|
495
|
+
Name of the net to find or create. The default is ``""``.
|
|
496
|
+
|
|
497
|
+
start_with : str, optional
|
|
498
|
+
All net name starting with the string. Not case-sensitive.
|
|
499
|
+
|
|
500
|
+
contain : str, optional
|
|
501
|
+
All net name containing the string. Not case-sensitive.
|
|
502
|
+
|
|
503
|
+
end_with : str, optional
|
|
504
|
+
All net name ending with the string. Not case-sensitive.
|
|
505
|
+
|
|
506
|
+
Returns
|
|
507
|
+
-------
|
|
508
|
+
object
|
|
509
|
+
Net Object.
|
|
510
|
+
"""
|
|
511
|
+
if not net_name and not start_with and not contain and not end_with:
|
|
512
|
+
net_name = generate_unique_name("NET_")
|
|
513
|
+
net = Net.create(self._active_layout, net_name)
|
|
514
|
+
return net
|
|
515
|
+
else:
|
|
516
|
+
if not start_with and not contain and not end_with:
|
|
517
|
+
net = Net.find_by_name(self._active_layout, net_name)
|
|
518
|
+
if net.is_null:
|
|
519
|
+
net = Net.create(self._active_layout, net_name)
|
|
520
|
+
return net
|
|
521
|
+
elif start_with:
|
|
522
|
+
nets_found = [self.nets[net] for net in list(self.nets.keys()) if net.lower().startswith(start_with)]
|
|
523
|
+
return nets_found
|
|
524
|
+
elif start_with and end_with:
|
|
525
|
+
nets_found = [
|
|
526
|
+
self.nets[net]
|
|
527
|
+
for net in list(self.nets.keys())
|
|
528
|
+
if net.lower().startswith(start_with) and net.lower().endswith(end_with)
|
|
529
|
+
]
|
|
530
|
+
return nets_found
|
|
531
|
+
elif start_with and contain and end_with:
|
|
532
|
+
nets_found = [
|
|
533
|
+
self.nets[net].net_object
|
|
534
|
+
for net in list(self.nets.keys())
|
|
535
|
+
if net.lower().startswith(start_with) and net.lower().endswith(end_with) and contain in net.lower()
|
|
536
|
+
]
|
|
537
|
+
return nets_found
|
|
538
|
+
elif start_with and contain:
|
|
539
|
+
nets_found = [
|
|
540
|
+
self.nets[net]
|
|
541
|
+
for net in list(self.nets.keys())
|
|
542
|
+
if net.lower().startswith(start_with) and contain in net.lower()
|
|
543
|
+
]
|
|
544
|
+
return nets_found
|
|
545
|
+
elif contain and end_with:
|
|
546
|
+
nets_found = [
|
|
547
|
+
self.nets[net]
|
|
548
|
+
for net in list(self.nets.keys())
|
|
549
|
+
if net.lower().endswith(end_with) and contain in net.lower()
|
|
550
|
+
]
|
|
551
|
+
return nets_found
|
|
552
|
+
elif end_with and not start_with and not contain:
|
|
553
|
+
nets_found = [self.nets[net] for net in list(self.nets.keys()) if net.lower().endswith(end_with)]
|
|
554
|
+
return nets_found
|
|
555
|
+
elif contain and not start_with and not end_with:
|
|
556
|
+
nets_found = [self.nets[net] for net in list(self.nets.keys()) if contain in net.lower()]
|
|
557
|
+
return nets_found
|
|
558
|
+
|
|
559
|
+
def is_net_in_component(self, component_name, net_name):
|
|
560
|
+
"""Check if a net belongs to a component.
|
|
561
|
+
|
|
562
|
+
Parameters
|
|
563
|
+
----------
|
|
564
|
+
component_name : str
|
|
565
|
+
Name of the component.
|
|
566
|
+
net_name : str
|
|
567
|
+
Name of the net.
|
|
568
|
+
|
|
569
|
+
Returns
|
|
570
|
+
-------
|
|
571
|
+
bool
|
|
572
|
+
``True`` if the net is found in component pins.
|
|
573
|
+
|
|
574
|
+
"""
|
|
575
|
+
if component_name not in self._pedb.components.instances:
|
|
576
|
+
return False
|
|
577
|
+
for net in self._pedb.components.instances[component_name].nets:
|
|
578
|
+
if net_name == net:
|
|
579
|
+
return True
|
|
580
|
+
return False
|
|
581
|
+
|
|
582
|
+
def find_and_fix_disjoint_nets(
|
|
583
|
+
self, net_list=None, keep_only_main_net=False, clean_disjoints_less_than=0.0, order_by_area=False
|
|
584
|
+
):
|
|
585
|
+
"""Find and fix disjoint nets from a given netlist.
|
|
586
|
+
|
|
587
|
+
.. deprecated::
|
|
588
|
+
Use new property :func:`edb.layout_validation.disjoint_nets` instead.
|
|
589
|
+
|
|
590
|
+
Parameters
|
|
591
|
+
----------
|
|
592
|
+
net_list : str, list, optional
|
|
593
|
+
List of nets on which check disjoints. If `None` is provided then the algorithm will loop on all nets.
|
|
594
|
+
keep_only_main_net : bool, optional
|
|
595
|
+
Remove all secondary nets other than principal one (the one with more objects in it). Default is `False`.
|
|
596
|
+
clean_disjoints_less_than : bool, optional
|
|
597
|
+
Clean all disjoint nets with area less than specified area in square meters. Default is `0.0` to disable it.
|
|
598
|
+
order_by_area : bool, optional
|
|
599
|
+
Whether if the naming order has to be by number of objects (fastest) or area (slowest but more accurate).
|
|
600
|
+
Default is ``False``.
|
|
601
|
+
|
|
602
|
+
Returns
|
|
603
|
+
-------
|
|
604
|
+
List
|
|
605
|
+
New nets created.
|
|
606
|
+
|
|
607
|
+
Examples
|
|
608
|
+
--------
|
|
609
|
+
|
|
610
|
+
>>> renamed_nets = database.nets.find_and_fix_disjoint_nets(["GND","Net2"])
|
|
611
|
+
"""
|
|
612
|
+
warnings.warn("Use new function :func:`edb.layout_validation.disjoint_nets` instead.", DeprecationWarning)
|
|
613
|
+
return self._pedb.layout_validation.disjoint_nets(
|
|
614
|
+
net_list, keep_only_main_net, clean_disjoints_less_than, order_by_area
|
|
615
|
+
)
|
|
616
|
+
|
|
617
|
+
def merge_nets_polygons(self, net_names_list):
|
|
618
|
+
"""Convert paths from net into polygons, evaluate all connected polygons and perform the merge.
|
|
619
|
+
|
|
620
|
+
Parameters
|
|
621
|
+
----------
|
|
622
|
+
net_names_list : str or list[str]
|
|
623
|
+
Net name of list of net name.
|
|
624
|
+
|
|
625
|
+
Returns
|
|
626
|
+
-------
|
|
627
|
+
bool
|
|
628
|
+
``True`` when successful, ``False`` when failed.
|
|
629
|
+
|
|
630
|
+
"""
|
|
631
|
+
if isinstance(net_names_list, str):
|
|
632
|
+
net_names_list = [net_names_list]
|
|
633
|
+
return self._pedb.modeler.unite_polygons_on_layer(net_names_list=net_names_list)
|