pyedb 0.38.0__py3-none-any.whl → 0.39.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.

Files changed (205) hide show
  1. pyedb/__init__.py +1 -1
  2. pyedb/common/nets.py +53 -139
  3. pyedb/configuration/cfg_components.py +1 -1
  4. pyedb/configuration/cfg_general.py +4 -2
  5. pyedb/configuration/cfg_modeler.py +1 -1
  6. pyedb/configuration/cfg_package_definition.py +1 -1
  7. pyedb/configuration/cfg_padstacks.py +1 -1
  8. pyedb/configuration/cfg_ports_sources.py +56 -23
  9. pyedb/configuration/configuration.py +18 -1
  10. pyedb/dotnet/{application → database}/Variables.py +21 -21
  11. pyedb/dotnet/{edb_core → database}/cell/connectable.py +5 -5
  12. pyedb/dotnet/{edb_core → database}/cell/hierarchy/component.py +11 -11
  13. pyedb/dotnet/{edb_core → database}/cell/hierarchy/hierarchy_obj.py +1 -1
  14. pyedb/dotnet/{edb_core → database}/cell/hierarchy/model.py +1 -1
  15. pyedb/dotnet/{edb_core → database}/cell/layout.py +17 -17
  16. pyedb/dotnet/{edb_core → database}/cell/layout_obj.py +3 -3
  17. pyedb/dotnet/{edb_core → database}/cell/primitive/bondwire.py +1 -1
  18. pyedb/dotnet/{edb_core → database}/cell/primitive/path.py +4 -4
  19. pyedb/dotnet/{edb_core → database}/cell/primitive/primitive.py +14 -14
  20. pyedb/dotnet/{edb_core → database}/cell/terminal/bundle_terminal.py +2 -2
  21. pyedb/dotnet/{edb_core → database}/cell/terminal/edge_terminal.py +4 -4
  22. pyedb/dotnet/{edb_core → database}/cell/terminal/padstack_instance_terminal.py +2 -2
  23. pyedb/dotnet/{edb_core → database}/cell/terminal/pingroup_terminal.py +2 -2
  24. pyedb/dotnet/{edb_core → database}/cell/terminal/point_terminal.py +2 -2
  25. pyedb/dotnet/{edb_core → database}/cell/terminal/terminal.py +11 -11
  26. pyedb/dotnet/{edb_core → database}/cell/voltage_regulator.py +2 -2
  27. pyedb/dotnet/{edb_core → database}/components.py +101 -124
  28. pyedb/dotnet/{edb_core → database}/definition/component_def.py +5 -5
  29. pyedb/dotnet/{edb_core → database}/definition/component_model.py +1 -1
  30. pyedb/dotnet/{edb_core → database}/definition/definition_obj.py +1 -1
  31. pyedb/dotnet/{edb_core → database}/definition/definitions.py +2 -2
  32. pyedb/dotnet/{edb_core → database}/definition/package_def.py +4 -4
  33. pyedb/dotnet/{edb_core → database}/dotnet/database.py +8 -8
  34. pyedb/dotnet/{edb_core → database}/dotnet/primitive.py +9 -9
  35. pyedb/dotnet/{edb_core → database}/edb_data/control_file.py +12 -12
  36. pyedb/dotnet/{edb_core → database}/edb_data/hfss_extent_info.py +7 -7
  37. pyedb/dotnet/{edb_core → database}/edb_data/nets_data.py +10 -13
  38. pyedb/dotnet/{edb_core → database}/edb_data/padstacks_data.py +16 -16
  39. pyedb/dotnet/{edb_core → database}/edb_data/ports.py +4 -4
  40. pyedb/dotnet/{edb_core → database}/edb_data/primitives_data.py +5 -5
  41. pyedb/dotnet/{edb_core → database}/edb_data/raptor_x_simulation_setup_data.py +4 -4
  42. pyedb/dotnet/{edb_core → database}/edb_data/simulation_configuration.py +10 -10
  43. pyedb/dotnet/{edb_core → database}/edb_data/sources.py +4 -4
  44. pyedb/dotnet/{edb_core → database}/edb_data/variables.py +1 -1
  45. pyedb/dotnet/{edb_core → database}/geometry/polygon_data.py +4 -4
  46. pyedb/dotnet/{edb_core → database}/hfss.py +8 -8
  47. pyedb/dotnet/{edb_core → database}/layout_obj_instance.py +1 -1
  48. pyedb/dotnet/{edb_core → database}/layout_validation.py +2 -2
  49. pyedb/dotnet/{edb_core → database}/materials.py +23 -8
  50. pyedb/dotnet/{edb_core → database}/modeler.py +27 -27
  51. pyedb/dotnet/{edb_core → database}/net_class.py +8 -8
  52. pyedb/dotnet/{edb_core → database}/nets.py +12 -12
  53. pyedb/dotnet/{edb_core → database}/padstack.py +15 -15
  54. pyedb/dotnet/{edb_core → database}/sim_setup_data/data/mesh_operation.py +1 -1
  55. pyedb/dotnet/{edb_core → database}/sim_setup_data/data/settings.py +3 -3
  56. pyedb/dotnet/{edb_core → database}/sim_setup_data/data/sim_setup_info.py +2 -2
  57. pyedb/dotnet/{edb_core → database}/sim_setup_data/data/simulation_settings.py +1 -1
  58. pyedb/dotnet/{edb_core → database}/sim_setup_data/data/siw_dc_ir_settings.py +1 -1
  59. pyedb/dotnet/{edb_core → database}/sim_setup_data/data/sweep_data.py +1 -1
  60. pyedb/dotnet/{edb_core → database}/siwave.py +10 -10
  61. pyedb/dotnet/{edb_core → database}/stackup.py +12 -12
  62. pyedb/dotnet/{edb_core → database}/utilities/hfss_simulation_setup.py +15 -15
  63. pyedb/dotnet/{edb_core → database}/utilities/obj_base.py +1 -1
  64. pyedb/dotnet/{edb_core → database}/utilities/simulation_setup.py +3 -3
  65. pyedb/dotnet/{edb_core → database}/utilities/siwave_simulation_setup.py +6 -6
  66. pyedb/dotnet/edb.py +117 -112
  67. pyedb/generic/design_types.py +26 -19
  68. pyedb/generic/general_methods.py +1 -1
  69. pyedb/generic/plot.py +0 -2
  70. pyedb/grpc/database/__init__.py +1 -0
  71. pyedb/grpc/database/components.py +2354 -0
  72. pyedb/grpc/database/control_file.py +1277 -0
  73. pyedb/grpc/database/definition/component_def.py +218 -0
  74. pyedb/grpc/database/definition/component_model.py +39 -0
  75. pyedb/grpc/database/definition/component_pin.py +32 -0
  76. pyedb/grpc/database/definition/materials.py +1207 -0
  77. pyedb/grpc/database/definition/n_port_component_model.py +34 -0
  78. pyedb/grpc/database/definition/package_def.py +227 -0
  79. pyedb/grpc/database/definition/padstack_def.py +842 -0
  80. pyedb/grpc/database/definitions.py +70 -0
  81. pyedb/grpc/database/general.py +43 -0
  82. pyedb/grpc/database/geometry/__init__.py +0 -0
  83. pyedb/grpc/database/geometry/arc_data.py +93 -0
  84. pyedb/grpc/database/geometry/point_3d_data.py +79 -0
  85. pyedb/grpc/database/geometry/point_data.py +30 -0
  86. pyedb/grpc/database/geometry/polygon_data.py +133 -0
  87. pyedb/grpc/database/hfss.py +1279 -0
  88. pyedb/grpc/database/hierarchy/__init__.py +0 -0
  89. pyedb/grpc/database/hierarchy/component.py +1301 -0
  90. pyedb/grpc/database/hierarchy/model.py +31 -0
  91. pyedb/grpc/database/hierarchy/netlist_model.py +30 -0
  92. pyedb/grpc/database/hierarchy/pin_pair_model.py +128 -0
  93. pyedb/grpc/database/hierarchy/pingroup.py +245 -0
  94. pyedb/grpc/database/hierarchy/s_parameter_model.py +33 -0
  95. pyedb/grpc/database/hierarchy/spice_model.py +48 -0
  96. pyedb/grpc/database/layers/__init__.py +0 -0
  97. pyedb/grpc/database/layers/layer.py +57 -0
  98. pyedb/grpc/database/layers/stackup_layer.py +410 -0
  99. pyedb/grpc/database/layout/__init__.py +0 -0
  100. pyedb/grpc/database/layout/cell.py +30 -0
  101. pyedb/grpc/database/layout/layout.py +196 -0
  102. pyedb/grpc/database/layout/voltage_regulator.py +149 -0
  103. pyedb/grpc/database/layout_validation.py +319 -0
  104. pyedb/grpc/database/modeler.py +1468 -0
  105. pyedb/grpc/database/net/__init__.py +0 -0
  106. pyedb/grpc/database/net/differential_pair.py +138 -0
  107. pyedb/grpc/database/net/extended_net.py +340 -0
  108. pyedb/grpc/database/net/net.py +198 -0
  109. pyedb/grpc/database/net/net_class.py +93 -0
  110. pyedb/grpc/database/nets.py +633 -0
  111. pyedb/grpc/database/padstacks.py +1500 -0
  112. pyedb/grpc/database/ports/__init__.py +0 -0
  113. pyedb/grpc/database/ports/ports.py +396 -0
  114. pyedb/grpc/database/primitive/__init__.py +3 -0
  115. pyedb/grpc/database/primitive/bondwire.py +181 -0
  116. pyedb/grpc/database/primitive/circle.py +75 -0
  117. pyedb/grpc/database/primitive/padstack_instance.py +1116 -0
  118. pyedb/grpc/database/primitive/path.py +346 -0
  119. pyedb/grpc/database/primitive/polygon.py +276 -0
  120. pyedb/grpc/database/primitive/primitive.py +739 -0
  121. pyedb/grpc/database/primitive/rectangle.py +146 -0
  122. pyedb/grpc/database/simulation_setup/__init__.py +0 -0
  123. pyedb/grpc/database/simulation_setup/adaptive_frequency.py +33 -0
  124. pyedb/grpc/database/simulation_setup/hfss_advanced_meshing_settings.py +32 -0
  125. pyedb/grpc/database/simulation_setup/hfss_advanced_settings.py +59 -0
  126. pyedb/grpc/database/simulation_setup/hfss_dcr_settings.py +35 -0
  127. pyedb/grpc/database/simulation_setup/hfss_general_settings.py +61 -0
  128. pyedb/grpc/database/simulation_setup/hfss_settings_options.py +78 -0
  129. pyedb/grpc/database/simulation_setup/hfss_simulation_settings.py +118 -0
  130. pyedb/grpc/database/simulation_setup/hfss_simulation_setup.py +355 -0
  131. pyedb/grpc/database/simulation_setup/hfss_solver_settings.py +34 -0
  132. pyedb/grpc/database/simulation_setup/mesh_operation.py +34 -0
  133. pyedb/grpc/database/simulation_setup/raptor_x_advanced_settings.py +34 -0
  134. pyedb/grpc/database/simulation_setup/raptor_x_general_settings.py +33 -0
  135. pyedb/grpc/database/simulation_setup/raptor_x_simulation_settings.py +64 -0
  136. pyedb/grpc/database/simulation_setup/raptor_x_simulation_setup.py +125 -0
  137. pyedb/grpc/database/simulation_setup/siwave_dcir_simulation_setup.py +34 -0
  138. pyedb/grpc/database/simulation_setup/siwave_simulation_setup.py +119 -0
  139. pyedb/grpc/database/simulation_setup/sweep_data.py +32 -0
  140. pyedb/grpc/database/siwave.py +1023 -0
  141. pyedb/grpc/database/source_excitations.py +2572 -0
  142. pyedb/grpc/database/stackup.py +2574 -0
  143. pyedb/grpc/database/terminal/__init__.py +0 -0
  144. pyedb/grpc/database/terminal/bundle_terminal.py +218 -0
  145. pyedb/grpc/database/terminal/edge_terminal.py +51 -0
  146. pyedb/grpc/database/terminal/padstack_instance_terminal.py +171 -0
  147. pyedb/grpc/database/terminal/pingroup_terminal.py +162 -0
  148. pyedb/grpc/database/terminal/point_terminal.py +99 -0
  149. pyedb/grpc/database/terminal/terminal.py +470 -0
  150. pyedb/grpc/database/utility/__init__.py +3 -0
  151. pyedb/grpc/database/utility/constants.py +25 -0
  152. pyedb/grpc/database/utility/heat_sink.py +124 -0
  153. pyedb/grpc/database/utility/hfss_extent_info.py +448 -0
  154. pyedb/grpc/database/utility/layout_statistics.py +277 -0
  155. pyedb/grpc/database/utility/rlc.py +80 -0
  156. pyedb/grpc/database/utility/simulation_configuration.py +3305 -0
  157. pyedb/grpc/database/utility/sources.py +388 -0
  158. pyedb/grpc/database/utility/sweep_data_distribution.py +83 -0
  159. pyedb/grpc/database/utility/xml_control_file.py +1277 -0
  160. pyedb/grpc/edb.py +4151 -0
  161. pyedb/grpc/edb_init.py +481 -0
  162. pyedb/grpc/rpc_session.py +177 -0
  163. pyedb/ipc2581/ecad/cad_data/assembly_drawing.py +3 -2
  164. pyedb/ipc2581/ecad/cad_data/feature.py +4 -3
  165. pyedb/ipc2581/ecad/cad_data/layer_feature.py +32 -20
  166. pyedb/ipc2581/ecad/cad_data/outline.py +3 -2
  167. pyedb/ipc2581/ecad/cad_data/package.py +4 -3
  168. pyedb/ipc2581/ecad/cad_data/path.py +82 -31
  169. pyedb/ipc2581/ecad/cad_data/polygon.py +122 -60
  170. pyedb/ipc2581/ecad/cad_data/profile.py +13 -12
  171. pyedb/ipc2581/ecad/cad_data/step.py +53 -21
  172. pyedb/ipc2581/ipc2581.py +47 -49
  173. pyedb/modeler/geometry_operators.py +1 -1
  174. {pyedb-0.38.0.dist-info → pyedb-0.39.0.dist-info}/METADATA +5 -2
  175. pyedb-0.39.0.dist-info/RECORD +288 -0
  176. pyedb-0.38.0.dist-info/RECORD +0 -195
  177. /pyedb/dotnet/{edb_core → database}/__init__.py +0 -0
  178. /pyedb/dotnet/{application → database/cell}/__init__.py +0 -0
  179. /pyedb/dotnet/{edb_core/cell → database/cell/hierarchy}/__init__.py +0 -0
  180. /pyedb/dotnet/{edb_core → database}/cell/hierarchy/netlist_model.py +0 -0
  181. /pyedb/dotnet/{edb_core → database}/cell/hierarchy/pin_pair_model.py +0 -0
  182. /pyedb/dotnet/{edb_core → database}/cell/hierarchy/s_parameter_model.py +0 -0
  183. /pyedb/dotnet/{edb_core → database}/cell/hierarchy/spice_model.py +0 -0
  184. /pyedb/dotnet/{edb_core → database}/cell/primitive/__init__.py +0 -0
  185. /pyedb/dotnet/{edb_core/cell/hierarchy → database/cell/terminal}/__init__.py +0 -0
  186. /pyedb/dotnet/{edb_core/cell/terminal → database/definition}/__init__.py +0 -0
  187. /pyedb/dotnet/{edb_core/definition → database/dotnet}/__init__.py +0 -0
  188. /pyedb/dotnet/{edb_core/dotnet → database/edb_data}/__init__.py +0 -0
  189. /pyedb/dotnet/{edb_core → database}/edb_data/design_options.py +0 -0
  190. /pyedb/dotnet/{edb_core → database}/edb_data/edbvalue.py +0 -0
  191. /pyedb/dotnet/{edb_core → database}/edb_data/layer_data.py +0 -0
  192. /pyedb/dotnet/{edb_core → database}/edb_data/utilities.py +0 -0
  193. /pyedb/dotnet/{edb_core → database}/general.py +0 -0
  194. /pyedb/dotnet/{edb_core/edb_data → database/geometry}/__init__.py +0 -0
  195. /pyedb/dotnet/{edb_core → database}/geometry/point_data.py +0 -0
  196. /pyedb/dotnet/{edb_core → database}/sim_setup_data/__init__.py +0 -0
  197. /pyedb/dotnet/{edb_core → database}/sim_setup_data/data/__init__.py +0 -0
  198. /pyedb/dotnet/{edb_core → database}/sim_setup_data/data/adaptive_frequency_data.py +0 -0
  199. /pyedb/dotnet/{edb_core/geometry → database/sim_setup_data/io}/__init__.py +0 -0
  200. /pyedb/dotnet/{edb_core → database}/sim_setup_data/io/siwave.py +0 -0
  201. /pyedb/dotnet/{edb_core → database}/utilities/__init__.py +0 -0
  202. /pyedb/dotnet/{edb_core → database}/utilities/heatsink.py +0 -0
  203. /pyedb/{dotnet/edb_core/sim_setup_data/io → grpc/database/definition}/__init__.py +0 -0
  204. {pyedb-0.38.0.dist-info → pyedb-0.39.0.dist-info}/LICENSE +0 -0
  205. {pyedb-0.38.0.dist-info → pyedb-0.39.0.dist-info}/WHEEL +0 -0
@@ -0,0 +1,149 @@
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 ansys.edb.core.layout.voltage_regulator import (
24
+ VoltageRegulator as GrpcVoltageRegulator,
25
+ )
26
+ from ansys.edb.core.utility.value import Value as GrpcValue
27
+
28
+ from pyedb.dotnet.database.edb_data.padstacks_data import EDBPadstackInstance
29
+
30
+
31
+ class VoltageRegulator(GrpcVoltageRegulator):
32
+ """Class managing voltage regulator."""
33
+
34
+ def __init__(self, pedb, edb_object):
35
+ super().__init__(edb_object)
36
+ self._pedb = pedb
37
+
38
+ @property
39
+ def component(self):
40
+ """Voltage regulator component
41
+
42
+ Returns
43
+ -------
44
+ :class:`Component <pyedb.grpc.database.hierarchy.component.Component>`
45
+ Component.
46
+ """
47
+ if not self.component.is_null:
48
+ ref_des = self.component.name
49
+ if not ref_des:
50
+ return False
51
+ return self._pedb.components.instances[ref_des]
52
+ return False
53
+
54
+ @component.setter
55
+ def component(self, value):
56
+ if not isinstance(value, str):
57
+ self._pedb.logger.error("refdes name must be provided to set vrm component")
58
+ return
59
+ if value not in self._pedb.components.instances:
60
+ self._pedb.logger.error(f"component {value} not found in layout")
61
+ return
62
+ self.group = self._pedb.components.instances[value]
63
+
64
+ @property
65
+ def load_regulator_current(self):
66
+ """Load regulator current value
67
+
68
+ Returns
69
+ -------
70
+ float
71
+ Current value.
72
+ """
73
+ return self.load_regulator_current.value
74
+
75
+ @load_regulator_current.setter
76
+ def load_regulator_current(self, value):
77
+ self.load_regulation_percent = GrpcValue(value)
78
+
79
+ @property
80
+ def load_regulation_percent(self):
81
+ """Retrieve load regulation percent value.
82
+
83
+ Returns
84
+ -------
85
+ float
86
+ Percent value.
87
+ """
88
+ return self.load_regulation_percent.value
89
+
90
+ @load_regulation_percent.setter
91
+ def load_regulation_percent(self, value):
92
+ self.load_regulation_percent = GrpcValue(value)
93
+
94
+ @property
95
+ def negative_remote_sense_pin(self):
96
+ """Retrieve negative remote sense pin.
97
+
98
+ Returns
99
+ -------
100
+ :class:`PadstackInstance pyedb.grpc.database.primitive.padstack_instance.PadstackInstance`
101
+ PadstackInstance.
102
+ """
103
+ return self._pedb.padstacks.instances[self.negative_remote_sense_pin.id]
104
+
105
+ @negative_remote_sense_pin.setter
106
+ def negative_remote_sense_pin(self, value):
107
+ if isinstance(value, int):
108
+ if value in self._pedb.padsatcks.instances:
109
+ self.neg_remote_sense_pin = self._pedb.padsatcks.instances[value]
110
+ elif isinstance(value, EDBPadstackInstance):
111
+ self.neg_remote_sense_pin = value
112
+
113
+ @property
114
+ def positive_remote_sense_pin(self):
115
+ """Retrieve positive remote sense pin.
116
+
117
+ Returns
118
+ -------
119
+ :class:`PadstackInstance pyedb.grpc.database.primitive.padstack_instance.PadstackInstance`
120
+ PadstackInstance.
121
+ """
122
+ return self._pedb.padstacks.instances[self.pos_remote_sense_pin.id]
123
+
124
+ @positive_remote_sense_pin.setter
125
+ def positive_remote_sense_pin(self, value):
126
+ if isinstance(value, int):
127
+ if value in self._pedb.padsatcks.instances:
128
+ self.positive_remote_sense_pin = self._pedb.padsatcks.instances[value]
129
+ if not self.component:
130
+ self.component = self._pedb.padsatcks.instances[value].component.name
131
+ elif isinstance(value, EDBPadstackInstance):
132
+ self.positive_remote_sense_pin = value
133
+ if not self.component:
134
+ self.component = value.component.name
135
+
136
+ @property
137
+ def voltage(self):
138
+ """Retrieve voltage value.
139
+
140
+ Returns
141
+ -------
142
+ float
143
+ Voltage value.
144
+ """
145
+ return self.voltage.value
146
+
147
+ @voltage.setter
148
+ def voltage(self, value):
149
+ self.voltage = GrpcValue(value)
@@ -0,0 +1,319 @@
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
+ import re
24
+
25
+ # from pyedb.generic.general_methods import generate_unique_name
26
+ # from pyedb.grpc.database.primitive.padstack_instances import PadstackInstance
27
+ # from pyedb.grpc.database.primitive.primitive import Primitive
28
+
29
+
30
+ class LayoutValidation:
31
+ """Manages all layout validation capabilities"""
32
+
33
+ def __init__(self, pedb):
34
+ self._pedb = pedb
35
+ self._layout_instance = self._pedb.layout_instance
36
+
37
+ def dc_shorts(self, net_list=None, fix=False):
38
+ """Find DC shorts on layout.
39
+
40
+ Parameters
41
+ ----------
42
+ net_list : str or list[str], optional
43
+ List of nets.
44
+ fix : bool, optional
45
+ If `True`, rename all the nets. (default)
46
+ If `False`, only report dc shorts.
47
+
48
+ Returns
49
+ -------
50
+ List[List[str, str]]
51
+ [[net name, net name]].
52
+
53
+ Examples
54
+ --------
55
+
56
+ >>> edb = Edb("edb_file")
57
+ >>> dc_shorts = edb.layout_validation.dc_shorts()
58
+
59
+ """
60
+ if not net_list:
61
+ net_list = list(self._pedb.nets.nets.keys())
62
+ elif isinstance(net_list, str):
63
+ net_list = [net_list]
64
+ _objects_list = {}
65
+ _padstacks_list = {}
66
+ for prim in self._pedb.modeler.primitives:
67
+ n_name = prim.net_name
68
+ if n_name in _objects_list:
69
+ _objects_list[n_name].append(prim)
70
+ else:
71
+ _objects_list[n_name] = [prim]
72
+ for pad in list(self._pedb.padstacks.instances.values()):
73
+ n_name = pad.net_name
74
+ if n_name in _padstacks_list:
75
+ _padstacks_list[n_name].append(pad)
76
+ else:
77
+ _padstacks_list[n_name] = [pad]
78
+ dc_shorts = []
79
+ all_shorted_nets = []
80
+ for net in net_list:
81
+ if net in all_shorted_nets:
82
+ continue
83
+ objs = []
84
+ for i in _objects_list.get(net, []):
85
+ objs.append(i)
86
+ for i in _padstacks_list.get(net, []):
87
+ objs.append(i)
88
+ if not len(objs):
89
+ self._pedb.nets[net].delete()
90
+ continue
91
+
92
+ connected_objs = objs[0].get_connected_objects()
93
+ connected_objs.append(objs[0])
94
+ net_dc_shorts = [obj for obj in connected_objs]
95
+ all_shorted_nets.append(net)
96
+ if net_dc_shorts:
97
+ dc_nets = list(set([obj.net.name for obj in net_dc_shorts]))
98
+ dc_nets = [i for i in dc_nets if i != net]
99
+ for dc in dc_nets:
100
+ if dc:
101
+ dc_shorts.append([net, dc])
102
+ all_shorted_nets.append(dc)
103
+ if fix:
104
+ temp = []
105
+ for i in net_dc_shorts:
106
+ temp.append(i.net.name)
107
+ temp_key = set(temp)
108
+ temp_count = {temp.count(i): i for i in temp_key}
109
+ temp_count = dict(sorted(temp_count.items()))
110
+ while True:
111
+ temp_name = list(temp_count.values()).pop()
112
+ if not temp_name.lower().startswith("unnamed"):
113
+ break
114
+ elif temp_name.lower():
115
+ break
116
+ elif len(temp) == 0:
117
+ break
118
+ rename_shorts = [i for i in net_dc_shorts if i.net.name != temp_name]
119
+ for i in rename_shorts:
120
+ i.net = self._pedb.nets.nets[temp_name]
121
+ return dc_shorts
122
+
123
+ # def disjoint_nets(
124
+ # self,
125
+ # net_list=None,
126
+ # keep_only_main_net=False,
127
+ # clean_disjoints_less_than=0.0,
128
+ # order_by_area=False,
129
+ # keep_disjoint_pins=False,
130
+ # ):
131
+ # """Find and fix disjoint nets from a given netlist.
132
+ #
133
+ # Parameters
134
+ # ----------
135
+ # net_list : str, list, optional
136
+ # List of nets on which check disjoints. If `None` is provided then the algorithm will loop on all nets.
137
+ # keep_only_main_net : bool, optional
138
+ # Remove all secondary nets other than principal one (the one with more objects in it). Default is `False`.
139
+ # clean_disjoints_less_than : bool, optional
140
+ # Clean all disjoint nets with area less than specified area in square meters. Default is `0.0` to disable it.
141
+ # order_by_area : bool, optional
142
+ # Whether if the naming order has to be by number of objects (fastest) or area (slowest but more accurate).
143
+ # Default is ``False``.
144
+ # keep_disjoint_pins : bool, optional
145
+ # Whether if delete disjoints pins not connected to any other primitive or not. Default is ``False``.
146
+ #
147
+ # Returns
148
+ # -------
149
+ # List
150
+ # New nets created.
151
+ #
152
+ # Examples
153
+ # --------
154
+ #
155
+ # >>> renamed_nets = edb.layout_validation.disjoint_nets(["GND","Net2"])
156
+ # """
157
+ # from ansys.edb.core.geometry.point_data import PointData as GrpcPointData
158
+ # timer_start = self._pedb.logger.reset_timer()
159
+ #
160
+ # if not net_list:
161
+ # net_list = list(self._pedb.nets.keys())
162
+ # elif isinstance(net_list, str):
163
+ # net_list = [net_list]
164
+ # _objects_list = {}
165
+ # _padstacks_list = {}
166
+ # for prim in self._pedb.modeler.primitives:
167
+ # if not prim.net.is_null:
168
+ # n_name = prim.net.name
169
+ # if n_name in _objects_list:
170
+ # _objects_list[n_name].append(prim)
171
+ # else:
172
+ # _objects_list[n_name] = [prim]
173
+ # for pad in list(self._pedb.padstacks.instances.values()):
174
+ # if not pad.net.is_null:
175
+ # n_name = pad.net_name
176
+ # if n_name in _padstacks_list:
177
+ # _padstacks_list[n_name].append(pad)
178
+ # else:
179
+ # _padstacks_list[n_name] = [pad]
180
+ # new_nets = []
181
+ # disjoints_objects = []
182
+ # self._pedb.logger.reset_timer()
183
+ # for net in net_list:
184
+ # net_groups = []
185
+ # obj_dict = {}
186
+ # for i in _objects_list.get(net, []):
187
+ # obj_dict[i.id] = i
188
+ # for i in _padstacks_list.get(net, []):
189
+ # obj_dict[i.id] = i
190
+ # objs = list(obj_dict.values())
191
+ # l = len(objs)
192
+ # while l > 0:
193
+ # l1 = self._layout_instance.get_connected_objects(objs[0].layout_object_instance, False)
194
+ # l1.append(objs[0].id)
195
+ # repetition = False
196
+ # for net_list in net_groups:
197
+ # if set(l1).intersection(net_list):
198
+ # net_groups.append([i for i in l1 if i not in net_list])
199
+ # repetition = True
200
+ # if not repetition:
201
+ # net_groups.append(l1)
202
+ # objs = [i for i in objs if i.id not in l1]
203
+ # l = len(objs)
204
+ # if len(net_groups) > 1:
205
+ #
206
+ # def area_calc(elem):
207
+ # sum = 0
208
+ # for el in elem:
209
+ # try:
210
+ # if el.layout_obj.obj_type.value == 0:
211
+ # if not el.is_void:
212
+ # sum += el.area()
213
+ # except:
214
+ # pass
215
+ # return sum
216
+ #
217
+ # if order_by_area:
218
+ # areas = [area_calc(i) for i in net_groups]
219
+ # sorted_list = [x for _, x in sorted(zip(areas, net_groups), reverse=True)]
220
+ # else:
221
+ # sorted_list = sorted(net_groups, key=len, reverse=True)
222
+ # for disjoints in sorted_list[1:]:
223
+ # if keep_only_main_net:
224
+ # for geo in disjoints:
225
+ # try:
226
+ # obj_dict[geo].delete()
227
+ # except KeyError:
228
+ # pass
229
+ # elif len(disjoints) == 1 and (
230
+ # clean_disjoints_less_than
231
+ # and "area" in dir(obj_dict[disjoints[0]])
232
+ # and obj_dict[disjoints[0]].area() < clean_disjoints_less_than
233
+ # ):
234
+ # try:
235
+ # obj_dict[disjoints[0]].delete()
236
+ # except KeyError:
237
+ # pass
238
+ # elif (
239
+ # len(disjoints) == 1
240
+ # and not keep_disjoint_pins
241
+ # and isinstance(obj_dict[disjoints[0]], PadstackInstance)
242
+ # ):
243
+ # try:
244
+ # obj_dict[disjoints[0]].delete()
245
+ # except KeyError:
246
+ # pass
247
+ #
248
+ # else:
249
+ # new_net_name = generate_unique_name(net, n=6)
250
+ # net_obj = self._pedb.nets.find_or_create_net(new_net_name)
251
+ # if net_obj:
252
+ # new_nets.append(net_obj.name)
253
+ # for geo in disjoints:
254
+ # try:
255
+ # obj_dict[geo].net_name = net_obj.name
256
+ # except KeyError:
257
+ # pass
258
+ # disjoints_objects.extend(disjoints)
259
+ # self._pedb._logger.info("Found {} objects in {} new nets.".format(len(disjoints_objects), len(new_nets)))
260
+ # self._pedb._logger.info_timer("Disjoint Cleanup Completed.", timer_start)
261
+ #
262
+ # return new_nets
263
+
264
+ def fix_self_intersections(self, net_list=None):
265
+ """Find and fix self intersections from a given netlist.
266
+
267
+ Parameters
268
+ ----------
269
+ net_list : str, list, optional
270
+ List of nets on which check disjoints. If `None` is provided then the algorithm will loop on all nets.
271
+
272
+ Returns
273
+ -------
274
+ bool
275
+ """
276
+ if not net_list:
277
+ net_list = list(self._pedb.nets.keys())
278
+ elif isinstance(net_list, str):
279
+ net_list = [net_list]
280
+ new_prims = []
281
+ for prim in self._pedb.modeler.polygons:
282
+ if prim.net_name in net_list:
283
+ new_prims.extend(prim.fix_self_intersections())
284
+ if new_prims:
285
+ self._pedb._logger.info("Self-intersections detected and removed.")
286
+ else:
287
+ self._pedb._logger.info("Self-intersection not found.")
288
+ return True
289
+
290
+ def illegal_net_names(self, fix=False):
291
+ """Find and fix illegal net names."""
292
+ pattern = r"[\(\)\\\/:;*?<>\'\"|`~$]"
293
+
294
+ nets = self._pedb.nets.nets
295
+
296
+ renamed_nets = []
297
+ for net, val in nets.items():
298
+ if re.findall(pattern, net):
299
+ renamed_nets.append(net)
300
+ if fix:
301
+ new_name = re.sub(pattern, "_", net)
302
+ val.name = new_name
303
+
304
+ self._pedb._logger.info("Found {} illegal net names.".format(len(renamed_nets)))
305
+ return
306
+
307
+ def illegal_rlc_values(self, fix=False):
308
+ """Find and fix RLC illegal values."""
309
+ inductors = self._pedb.components.inductors
310
+
311
+ temp = []
312
+ for k, v in inductors.items():
313
+ model = v.component_property.model
314
+ if not len(model.pin_pairs): # pragma: no cover
315
+ temp.append(k)
316
+ if fix:
317
+ v.rlc_values = [0, 1, 0]
318
+ self._pedb._logger.info(f"Found {len(temp)} inductors have no value.")
319
+ return