pyedb 0.50.1__py3-none-any.whl → 0.52.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_ports_sources.py +79 -239
- pyedb/configuration/configuration.py +213 -340
- pyedb/dotnet/clr_module.py +9 -3
- pyedb/dotnet/database/cell/layout.py +10 -1
- pyedb/dotnet/database/dotnet/database.py +0 -2
- pyedb/dotnet/database/edb_data/padstacks_data.py +8 -2
- pyedb/dotnet/database/layout_validation.py +20 -26
- pyedb/dotnet/database/modeler.py +0 -1
- pyedb/dotnet/database/stackup.py +4 -3
- pyedb/dotnet/edb.py +42 -2
- pyedb/generic/design_types.py +183 -62
- pyedb/grpc/database/__init__.py +0 -1
- pyedb/grpc/database/components.py +110 -0
- pyedb/grpc/database/control_file.py +150 -17
- pyedb/grpc/database/definition/materials.py +7 -7
- pyedb/grpc/database/definitions.py +36 -2
- pyedb/grpc/database/hfss.py +15 -0
- pyedb/grpc/database/hierarchy/component.py +10 -2
- pyedb/grpc/database/hierarchy/pin_pair_model.py +1 -1
- pyedb/grpc/database/layout_validation.py +58 -7
- pyedb/grpc/database/net/differential_pair.py +2 -1
- pyedb/grpc/database/nets.py +233 -4
- pyedb/grpc/database/padstacks.py +97 -0
- pyedb/grpc/database/primitive/padstack_instance.py +1 -1
- pyedb/grpc/database/primitive/polygon.py +1 -1
- pyedb/grpc/database/siwave.py +63 -3
- pyedb/grpc/database/source_excitations.py +317 -50
- pyedb/grpc/database/stackup.py +107 -2
- pyedb/grpc/database/terminal/point_terminal.py +2 -2
- pyedb/grpc/database/terminal/terminal.py +1 -1
- pyedb/grpc/edb.py +190 -224
- pyedb/grpc/edb_init.py +54 -5
- {pyedb-0.50.1.dist-info → pyedb-0.52.0.dist-info}/METADATA +4 -4
- {pyedb-0.50.1.dist-info → pyedb-0.52.0.dist-info}/RECORD +37 -37
- {pyedb-0.50.1.dist-info → pyedb-0.52.0.dist-info}/LICENSE +0 -0
- {pyedb-0.50.1.dist-info → pyedb-0.52.0.dist-info}/WHEEL +0 -0
|
@@ -35,23 +35,156 @@ from pyedb.misc.misc import list_installed_ansysem
|
|
|
35
35
|
def convert_technology_file(tech_file, edbversion=None, control_file=None):
|
|
36
36
|
"""Convert a technology file to EDB control file (XML).
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
38
|
+
Parameters
|
|
39
|
+
----------
|
|
40
|
+
tech_file : str
|
|
41
|
+
Full path to technology file.
|
|
42
|
+
edbversion : str, optional
|
|
43
|
+
EDB version to use. If ``None``, uses latest available version.
|
|
44
|
+
control_file : str, optional
|
|
45
|
+
Output control file path. If ``None``, uses same path and name as ``tech_file``.
|
|
46
|
+
|
|
47
|
+
Returns
|
|
48
|
+
-------
|
|
49
|
+
str or bool
|
|
50
|
+
Full path to created control file if successful, ``False`` otherwise.
|
|
51
|
+
|
|
52
|
+
Notes
|
|
53
|
+
-----
|
|
54
|
+
This function is only supported on Linux systems.
|
|
55
|
+
|
|
56
|
+
Example
|
|
57
|
+
-------
|
|
58
|
+
# Example 1: Converting a technology file to control file
|
|
59
|
+
>>> converted_file = convert_technology_file(
|
|
60
|
+
>>> tech_file="/path/to/tech.t",
|
|
61
|
+
>>> edbversion="2025.2",
|
|
62
|
+
>>> control_file="/path/to/output.xml"
|
|
63
|
+
>>> )
|
|
64
|
+
>>> if converted_file:
|
|
65
|
+
>>> print(f"Converted to: {converted_file}")
|
|
66
|
+
|
|
67
|
+
# Example 2: Creating a material
|
|
68
|
+
>>> from pyedb import ControlFileMaterial
|
|
69
|
+
>>> material = ControlFileMaterial(
|
|
70
|
+
>>> "Copper",
|
|
71
|
+
>>> {"Permittivity": 1.0, "Conductivity": 5.8e7}
|
|
72
|
+
>>> )
|
|
73
|
+
|
|
74
|
+
# Example 3: Creating a dielectric layer
|
|
75
|
+
>>> from pyedb import ControlFileDielectric
|
|
76
|
+
>>> dielectric = ControlFileDielectric(
|
|
77
|
+
>>> "Core",
|
|
78
|
+
>>> {"Thickness": "0.2mm", "Material": "FR4"}
|
|
79
|
+
>>> )
|
|
80
|
+
|
|
81
|
+
# Example 4: Creating a signal layer
|
|
82
|
+
>>> from pyedb import ControlFileLayer
|
|
83
|
+
>>> signal_layer = ControlFileLayer(
|
|
84
|
+
>>> "TopLayer",
|
|
85
|
+
>>> {"Type": "signal", "Material": "Copper", "Thickness": "0.035mm"}
|
|
86
|
+
>>> )
|
|
87
|
+
|
|
88
|
+
# Example 5: Creating a via layer
|
|
89
|
+
>>> from pyedb import ControlFileVia
|
|
90
|
+
>>> via_layer = ControlFileVia(
|
|
91
|
+
>>> "Via1",
|
|
92
|
+
>>> {"StartLayer": "TopLayer", "StopLayer": "BottomLayer"}
|
|
93
|
+
>>> )
|
|
94
|
+
>>> via_layer.create_via_group = True
|
|
95
|
+
>>> via_layer.tolerance = "0.1mm"
|
|
96
|
+
|
|
97
|
+
# Example 6: Managing stackup
|
|
98
|
+
>>> from pyedb import ControlFileStackup
|
|
99
|
+
>>> stackup = ControlFileStackup(units="mm")
|
|
100
|
+
>>> stackup.add_material("FR4", permittivity=4.4, dielectric_loss_tg=0.02)
|
|
101
|
+
>>> stackup.add_layer("L1", elevation=0, material="Copper", thickness=0.035)
|
|
102
|
+
>>> stackup.add_dielectric("Diel1", material="FR4", thickness=0.2)
|
|
103
|
+
>>> stackup.add_via("Via1", start_layer="L1", stop_layer="L2")
|
|
104
|
+
|
|
105
|
+
# Example 7: Configuring import options
|
|
106
|
+
>>> from pyedb import ControlFileImportOptions
|
|
107
|
+
>>> import_ops = ControlFileImportOptions()
|
|
108
|
+
>>> import_ops.auto_close = True
|
|
109
|
+
>>> import_ops.defeature_tolerance = 0.001
|
|
110
|
+
|
|
111
|
+
# Example 8: Setting up simulation extents
|
|
112
|
+
>>> from pyedb import ControlExtent
|
|
113
|
+
>>> extent = ControlExtent(
|
|
114
|
+
>>> type="Conforming",
|
|
115
|
+
>>> diel_hactor=0.3,
|
|
116
|
+
>>> airbox_hfactor=0.5
|
|
117
|
+
>>> )
|
|
118
|
+
|
|
119
|
+
# Example 9: Creating circuit ports
|
|
120
|
+
>>> from pyedb import ControlCircuitPt
|
|
121
|
+
>>> port = ControlCircuitPt("Port1", 0, 0, "TopLayer", 1, 0, "TopLayer", 50)
|
|
122
|
+
|
|
123
|
+
# Example 10: Managing components
|
|
124
|
+
>>> from pyedb import ControlFileComponent
|
|
125
|
+
>>> comp = ControlFileComponent()
|
|
126
|
+
>>> comp.refdes = "U1"
|
|
127
|
+
>>> comp.add_pin("Pin1", 0.5, 0.5, "TopLayer")
|
|
128
|
+
>>> comp.add_port("Port1", 50, "Pin1", refpin="GND")
|
|
129
|
+
|
|
130
|
+
# Example 11: Component management
|
|
131
|
+
>>> from pyedb import ControlFileComponents
|
|
132
|
+
>>> components = ControlFileComponents()
|
|
133
|
+
>>> ic = components.add_component("U1", "BGA", "IC", die_type="Flip chip")
|
|
134
|
+
>>> ic.add_pin("A1", 1.0, 1.0, "TopLayer")
|
|
135
|
+
|
|
136
|
+
# Example 12: Boundary setup
|
|
137
|
+
>>> from pyedb import ControlFileBoundaries
|
|
138
|
+
>>> boundaries = ControlFileBoundaries()
|
|
139
|
+
>>> boundaries.add_port("Port1", 0, 0, "L1", 1, 0, "L1", 50)
|
|
140
|
+
>>> boundaries.add_extent(diel_hactor=0.3)
|
|
141
|
+
|
|
142
|
+
# Example 13: Frequency sweep configuration
|
|
143
|
+
>>> from pyedb import ControlFileSweep
|
|
144
|
+
>>> sweep = ControlFileSweep(
|
|
145
|
+
>>> "Sweep1", "1GHz", "10GHz", "0.1GHz",
|
|
146
|
+
>>> "Interpolating", "LinearStep", True
|
|
147
|
+
>>> )
|
|
148
|
+
|
|
149
|
+
# Example 14: Mesh operation setup
|
|
150
|
+
>>> from pyedb import ControlFileMeshOp
|
|
151
|
+
>>> mesh_op = ControlFileMeshOp(
|
|
152
|
+
>>> "FineMesh", "Region1", "MeshOperationSkinDepth",
|
|
153
|
+
>>> {"Net1": "TopLayer"}
|
|
154
|
+
>>> )
|
|
155
|
+
>>> mesh_op.skin_depth = "1um"
|
|
156
|
+
|
|
157
|
+
# Example 15: Simulation setup configuration
|
|
158
|
+
>>> from pyedb import ControlFileSetup
|
|
159
|
+
>>> setup = ControlFileSetup("SimSetup1")
|
|
160
|
+
>>> setup.frequency = "5GHz"
|
|
161
|
+
>>> setup.add_sweep("Sweep1", "1GHz", "10GHz", "0.5GHz")
|
|
162
|
+
>>> setup.add_mesh_operation("Mesh1", "Chip", "MeshOperationLength", {"PWR": "Top"})
|
|
163
|
+
|
|
164
|
+
# Example 16: Setup management
|
|
165
|
+
>>> from pyedb import ControlFileSetups
|
|
166
|
+
>>> setups = ControlFileSetups()
|
|
167
|
+
>>> sim_setup = setups.add_setup("MySetup", "10GHz")
|
|
168
|
+
>>> sim_setup.add_sweep("Swp1", "1GHz", "20GHz", 100, step_type="LinearCount")
|
|
169
|
+
|
|
170
|
+
# Example 17: Main control file creation
|
|
171
|
+
>>> from pyedb import ControlFile
|
|
172
|
+
|
|
173
|
+
# Create from scratch
|
|
174
|
+
>>> ctrl = ControlFile()
|
|
175
|
+
>>> ctrl.stackup.add_material("Copper", conductivity=5.8e7)
|
|
176
|
+
>>> ctrl.stackup.add_layer("Signal", thickness=0.035, material="Copper")
|
|
177
|
+
>>> ctrl.boundaries.add_port("Input", 0, 0, "Signal", 1, 0, "Signal", 50)
|
|
178
|
+
>>> ctrl.write_xml("/path/to/control.xml")
|
|
179
|
+
|
|
180
|
+
# Parse existing file
|
|
181
|
+
>>> ctrl = ControlFile(xml_input="/path/to/existing.xml")
|
|
182
|
+
|
|
183
|
+
# Convert technology file
|
|
184
|
+
>>> ctrl = ControlFile(tecnhology="/path/to/tech.t")
|
|
185
|
+
|
|
186
|
+
# Apply layer mapping
|
|
187
|
+
>>> ctrl.parse_layer_map("/path/to/layer_map.txt")
|
|
55
188
|
"""
|
|
56
189
|
if is_linux: # pragma: no cover
|
|
57
190
|
if not edbversion:
|
|
@@ -228,14 +228,14 @@ class Material(GrpcMaterialDef):
|
|
|
228
228
|
|
|
229
229
|
"""
|
|
230
230
|
try:
|
|
231
|
-
return self.dielectric_material_model.
|
|
231
|
+
return self.dielectric_material_model.dc_relative_permittivity
|
|
232
232
|
except:
|
|
233
233
|
return None
|
|
234
234
|
|
|
235
235
|
@dc_permittivity.setter
|
|
236
236
|
def dc_permittivity(self, value):
|
|
237
237
|
if self.dielectric_material_model:
|
|
238
|
-
self.dielectric_material_model.
|
|
238
|
+
self.dielectric_material_model.dc_relative_permittivity = float(value)
|
|
239
239
|
|
|
240
240
|
@property
|
|
241
241
|
def loss_tangent_at_frequency(self) -> float:
|
|
@@ -289,14 +289,14 @@ class Material(GrpcMaterialDef):
|
|
|
289
289
|
|
|
290
290
|
"""
|
|
291
291
|
try:
|
|
292
|
-
return self.dielectric_material_model.
|
|
292
|
+
return self.dielectric_material_model.relative_permittivity_at_frequency
|
|
293
293
|
except:
|
|
294
294
|
return None
|
|
295
295
|
|
|
296
296
|
@permittivity_at_frequency.setter
|
|
297
297
|
def permittivity_at_frequency(self, value):
|
|
298
298
|
if self.dielectric_material_model:
|
|
299
|
-
self.dielectric_material_model.
|
|
299
|
+
self.dielectric_material_model.relative_permittivity_at_frequency = float(value)
|
|
300
300
|
|
|
301
301
|
@property
|
|
302
302
|
def permittivity(self) -> float:
|
|
@@ -771,14 +771,14 @@ class Materials(object):
|
|
|
771
771
|
raise ValueError(f"Material names are case-insensitive and {name.lower()} already exists.")
|
|
772
772
|
|
|
773
773
|
material_model = GrpcDjordjecvicSarkarModel.create()
|
|
774
|
-
material_model.
|
|
774
|
+
material_model.relative_permittivity_at_frequency = permittivity_at_frequency
|
|
775
775
|
material_model.loss_tangent_at_frequency = loss_tangent_at_frequency
|
|
776
776
|
material_model.frequency = dielectric_model_frequency
|
|
777
777
|
if dc_conductivity is not None:
|
|
778
778
|
material_model.dc_conductivity = dc_conductivity
|
|
779
779
|
material_model.use_dc_relative_conductivity = True
|
|
780
780
|
if dc_permittivity is not None:
|
|
781
|
-
material_model.
|
|
781
|
+
material_model.dc_relative_permittivity = dc_permittivity
|
|
782
782
|
try:
|
|
783
783
|
material = self.__add_dielectric_material_model(name, material_model)
|
|
784
784
|
for key, value in kwargs.items():
|
|
@@ -841,7 +841,7 @@ class Materials(object):
|
|
|
841
841
|
material_model = GrpcDebyeModel.create()
|
|
842
842
|
material_model.frequency_range = (lower_freqency, higher_frequency)
|
|
843
843
|
material_model.loss_tangent_at_high_low_frequency = (loss_tangent_low, loss_tangent_high)
|
|
844
|
-
material_model.
|
|
844
|
+
material_model.relative_permittivity_at_high_low_frequency = (permittivity_low, permittivity_high)
|
|
845
845
|
try:
|
|
846
846
|
material = self.__add_dielectric_material_model(name, material_model)
|
|
847
847
|
for key, value in kwargs.items():
|
|
@@ -34,12 +34,30 @@ class Definitions:
|
|
|
34
34
|
|
|
35
35
|
@property
|
|
36
36
|
def component(self) -> dict[str, ComponentDef]:
|
|
37
|
-
"""Component definitions
|
|
37
|
+
"""Component definitions
|
|
38
|
+
|
|
39
|
+
Examples
|
|
40
|
+
--------
|
|
41
|
+
>>> from pyedb import Edb
|
|
42
|
+
>>> edb = Edb()
|
|
43
|
+
>>> component_defs = edb.definitions.component
|
|
44
|
+
>>> for name, comp_def in component_defs.items():
|
|
45
|
+
... print(f"Component: {name}, Part: {comp_def.part}")
|
|
46
|
+
"""
|
|
38
47
|
return {l.name: ComponentDef(self._pedb, l) for l in self._pedb.active_db.component_defs}
|
|
39
48
|
|
|
40
49
|
@property
|
|
41
50
|
def package(self) -> dict[str, PackageDef]:
|
|
42
|
-
"""Package definitions.
|
|
51
|
+
"""Package definitions.
|
|
52
|
+
|
|
53
|
+
Examples
|
|
54
|
+
--------
|
|
55
|
+
>>> from pyedb import Edb
|
|
56
|
+
>>> edb = Edb()
|
|
57
|
+
>>> package_defs = edb.definitions.package
|
|
58
|
+
>>> for name, pkg_def in package_defs.items():
|
|
59
|
+
... print(f"Package: {name}, Boundary: {pkg_def.exterior_boundary}")
|
|
60
|
+
"""
|
|
43
61
|
return {l.name: PackageDef(self._pedb, l) for l in self._pedb.active_db.package_defs}
|
|
44
62
|
|
|
45
63
|
def add_package_def(self, name, component_part_name=None, boundary_points=None) -> Union[PackageDef, bool]:
|
|
@@ -57,6 +75,22 @@ class Definitions:
|
|
|
57
75
|
Returns
|
|
58
76
|
-------
|
|
59
77
|
PackageDef object.
|
|
78
|
+
|
|
79
|
+
Examples
|
|
80
|
+
--------
|
|
81
|
+
>>> from pyedb import Edb
|
|
82
|
+
>>> edb = Edb()
|
|
83
|
+
|
|
84
|
+
Example 1: Create package using component's bounding box
|
|
85
|
+
>>> comp_def = edb.definitions.add_package_def("QFP64", "QFP64_COMPONENT")
|
|
86
|
+
>>> if comp_def: # Check if created successfully
|
|
87
|
+
... print(f"Created package: {comp_def.name}")
|
|
88
|
+
|
|
89
|
+
Example 2: Create package with custom boundary
|
|
90
|
+
>>> boundary = [[0, 0], [10e-3, 0], [10e-3, 10e-3], [0, 10e-3]]
|
|
91
|
+
>>> custom_pkg = edb.definitions.add_package_def("CustomIC", boundary_points=boundary)
|
|
92
|
+
>>> if custom_pkg:
|
|
93
|
+
... print(f"Custom package boundary: {custom_pkg.exterior_boundary}")
|
|
60
94
|
"""
|
|
61
95
|
if not name in self.package:
|
|
62
96
|
package_def = PackageDef.create(self._pedb.active_db, name=name)
|
pyedb/grpc/database/hfss.py
CHANGED
|
@@ -200,6 +200,12 @@ class Hfss(object):
|
|
|
200
200
|
-------
|
|
201
201
|
dict
|
|
202
202
|
Dictionary mapping net names to smallest trace widths.
|
|
203
|
+
|
|
204
|
+
Examples
|
|
205
|
+
--------
|
|
206
|
+
>>> widths = edb.hfss.get_trace_width_for_traces_with_ports()
|
|
207
|
+
>>> for net_name, width in widths.items():
|
|
208
|
+
... print(f"Net '{net_name}': Smallest width = {width}")
|
|
203
209
|
"""
|
|
204
210
|
nets = {}
|
|
205
211
|
for net in self._pedb.excitations_nets:
|
|
@@ -925,6 +931,15 @@ class Hfss(object):
|
|
|
925
931
|
-------
|
|
926
932
|
list
|
|
927
933
|
[min_x, min_y, max_x, max_y] coordinates.
|
|
934
|
+
|
|
935
|
+
Examples
|
|
936
|
+
--------
|
|
937
|
+
>>> bbox = edb.hfss.get_layout_bounding_box()
|
|
938
|
+
>>> print(f"Layout Bounding Box: {bbox}")
|
|
939
|
+
>>>
|
|
940
|
+
>>> # With custom parameters
|
|
941
|
+
>>> custom_layout = edb.layouts["MyLayout"]
|
|
942
|
+
>>> bbox = edb.hfss.get_layout_bounding_box(custom_layout, 5)
|
|
928
943
|
"""
|
|
929
944
|
if not layout:
|
|
930
945
|
layout = self._active_layout
|
|
@@ -132,7 +132,7 @@ class Component(GrpcComponentGroup):
|
|
|
132
132
|
self.enabled = value
|
|
133
133
|
|
|
134
134
|
@property
|
|
135
|
-
def ic_die_properties(self) ->
|
|
135
|
+
def ic_die_properties(self) -> any:
|
|
136
136
|
"""IC Die property.
|
|
137
137
|
|
|
138
138
|
returns
|
|
@@ -877,12 +877,20 @@ class Component(GrpcComponentGroup):
|
|
|
877
877
|
def numpins(self) -> int:
|
|
878
878
|
"""Number of Pins of Component.
|
|
879
879
|
|
|
880
|
+
..deprecated:: 0.51.0
|
|
881
|
+
Use: func:`num_pins` instead.
|
|
880
882
|
Returns
|
|
881
883
|
-------
|
|
882
884
|
int
|
|
883
885
|
Component pins number.
|
|
884
886
|
"""
|
|
885
|
-
|
|
887
|
+
|
|
888
|
+
warnings.warn("Use num_pins instead.", DeprecationWarning)
|
|
889
|
+
try:
|
|
890
|
+
return self.num_pins
|
|
891
|
+
except Exception as e:
|
|
892
|
+
self._pedb.logger.error(f"{e}")
|
|
893
|
+
return 0
|
|
886
894
|
|
|
887
895
|
@property
|
|
888
896
|
def partname(self) -> str:
|
|
@@ -55,10 +55,12 @@ class LayoutValidation:
|
|
|
55
55
|
|
|
56
56
|
Examples
|
|
57
57
|
--------
|
|
58
|
-
|
|
59
58
|
>>> edb = Edb("edb_file")
|
|
60
|
-
>>>
|
|
61
|
-
|
|
59
|
+
>>> # Find shorts without fixing
|
|
60
|
+
>>> shorts = edb.layout_validation.dc_shorts()
|
|
61
|
+
>>>
|
|
62
|
+
>>> # Find and fix shorts on specific nets
|
|
63
|
+
>>> fixed_shorts = edb.layout_validation.dc_shorts(net_list=["GND", "VCC"], fix=True)
|
|
62
64
|
"""
|
|
63
65
|
if not net_list:
|
|
64
66
|
net_list = list(self._pedb.nets.nets.keys())
|
|
@@ -154,8 +156,17 @@ class LayoutValidation:
|
|
|
154
156
|
|
|
155
157
|
Examples
|
|
156
158
|
--------
|
|
157
|
-
|
|
158
|
-
>>>
|
|
159
|
+
>>> edb = Edb("edb_file")
|
|
160
|
+
>>> # Find disjoint nets on all nets
|
|
161
|
+
>>> new_nets = edb.layout_validation.disjoint_nets()
|
|
162
|
+
>>>
|
|
163
|
+
>>> # Clean disjoints on specific nets with advanced options
|
|
164
|
+
>>> cleaned = edb.layout_validation.disjoint_nets(
|
|
165
|
+
... net_list=["GND"],
|
|
166
|
+
... keep_only_main_net=True,
|
|
167
|
+
... clean_disjoints_less_than=1e-6,
|
|
168
|
+
... order_by_area=True
|
|
169
|
+
... ))
|
|
159
170
|
"""
|
|
160
171
|
timer_start = self._pedb.logger.reset_timer()
|
|
161
172
|
|
|
@@ -274,6 +285,15 @@ class LayoutValidation:
|
|
|
274
285
|
Returns
|
|
275
286
|
-------
|
|
276
287
|
bool
|
|
288
|
+
|
|
289
|
+
Examples
|
|
290
|
+
--------
|
|
291
|
+
>>> edb = Edb("edb_file")
|
|
292
|
+
>>> # Fix self-intersections on all nets
|
|
293
|
+
>>> edb.layout_validation.fix_self_intersections()
|
|
294
|
+
>>>
|
|
295
|
+
>>> # Fix self-intersections on specific nets
|
|
296
|
+
>>> edb.layout_validation.fix_self_intersections(net_list=["RF_line"])
|
|
277
297
|
"""
|
|
278
298
|
if not net_list:
|
|
279
299
|
net_list = list(self._pedb.nets.nets.keys())
|
|
@@ -290,7 +310,17 @@ class LayoutValidation:
|
|
|
290
310
|
return True
|
|
291
311
|
|
|
292
312
|
def illegal_net_names(self, fix=False):
|
|
293
|
-
"""Find and fix illegal net names.
|
|
313
|
+
"""Find and fix illegal net names.
|
|
314
|
+
|
|
315
|
+
Examples
|
|
316
|
+
--------
|
|
317
|
+
>>> edb = Edb("edb_file")
|
|
318
|
+
>>> # Identify illegal net names
|
|
319
|
+
>>> edb.layout_validation.illegal_net_names()
|
|
320
|
+
>>>
|
|
321
|
+
>>> # Find and automatically fix illegal names
|
|
322
|
+
>>> edb.layout_validation.illegal_net_names(fix=True)
|
|
323
|
+
"""
|
|
294
324
|
pattern = r"[\(\)\\\/:;*?<>\'\"|`~$]"
|
|
295
325
|
|
|
296
326
|
nets = self._pedb.nets.nets
|
|
@@ -307,7 +337,17 @@ class LayoutValidation:
|
|
|
307
337
|
return
|
|
308
338
|
|
|
309
339
|
def illegal_rlc_values(self, fix=False) -> list[str]:
|
|
310
|
-
"""Find and fix RLC illegal values.
|
|
340
|
+
"""Find and fix RLC illegal values.
|
|
341
|
+
|
|
342
|
+
Examples
|
|
343
|
+
--------
|
|
344
|
+
>>> edb = Edb("edb_file")
|
|
345
|
+
>>> # Identify components with illegal RLC values
|
|
346
|
+
>>> bad_components = edb.layout_validation.illegal_rlc_values()
|
|
347
|
+
>>>
|
|
348
|
+
>>> # Automatically fix invalid inductor values
|
|
349
|
+
>>> edb.layout_validation.illegal_rlc_values(fix=True)
|
|
350
|
+
"""
|
|
311
351
|
inductors = self._pedb.components.inductors
|
|
312
352
|
|
|
313
353
|
temp = []
|
|
@@ -321,6 +361,17 @@ class LayoutValidation:
|
|
|
321
361
|
return temp
|
|
322
362
|
|
|
323
363
|
def padstacks_no_name(self, fix=False):
|
|
364
|
+
"""Identify and fix padstacks without names.
|
|
365
|
+
|
|
366
|
+
Examples
|
|
367
|
+
--------
|
|
368
|
+
>>> edb = Edb("edb_file")
|
|
369
|
+
>>> # Report unnamed padstacks
|
|
370
|
+
>>> edb.layout_validation.padstacks_no_name()
|
|
371
|
+
>>>
|
|
372
|
+
>>> # Automatically assign names to unnamed padstacks
|
|
373
|
+
>>> edb.layout_validation.padstacks_no_name(fix=True)
|
|
374
|
+
"""
|
|
324
375
|
pds = self._pedb.layout.padstack_instances
|
|
325
376
|
counts = 0
|
|
326
377
|
via_count = 1
|
|
@@ -85,10 +85,11 @@ class DifferentialPairs:
|
|
|
85
85
|
-------
|
|
86
86
|
list
|
|
87
87
|
A list containing identified differential pair names.
|
|
88
|
+
|
|
88
89
|
Examples
|
|
89
90
|
--------
|
|
90
91
|
>>> from pyedb import Edb
|
|
91
|
-
>>> edbapp = Edb("myaedbfolder", edbversion="
|
|
92
|
+
>>> edbapp = Edb("myaedbfolder", edbversion="2025.2")
|
|
92
93
|
>>> edb_nets = edbapp.differential_pairs.auto_identify()
|
|
93
94
|
"""
|
|
94
95
|
nets = self._pedb.nets.nets
|