pyedb 0.39.1__py3-none-any.whl → 0.41.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/common/nets.py +11 -2
- pyedb/configuration/cfg_components.py +2 -0
- pyedb/configuration/cfg_padstacks.py +1 -1
- pyedb/configuration/cfg_ports_sources.py +63 -11
- pyedb/configuration/cfg_stackup.py +22 -1
- pyedb/dotnet/database/cell/terminal/edge_terminal.py +55 -0
- pyedb/dotnet/database/components.py +14 -12
- pyedb/dotnet/database/edb_data/padstacks_data.py +80 -3
- pyedb/dotnet/database/edb_data/ports.py +0 -55
- pyedb/dotnet/database/materials.py +40 -11
- pyedb/dotnet/database/modeler.py +11 -4
- pyedb/dotnet/edb.py +18 -0
- pyedb/grpc/database/components.py +24 -72
- pyedb/grpc/database/definition/materials.py +16 -1
- pyedb/grpc/database/layout/layout.py +43 -4
- pyedb/grpc/database/layout_validation.py +164 -143
- pyedb/grpc/database/net/net.py +5 -8
- pyedb/grpc/database/padstacks.py +184 -31
- pyedb/grpc/database/primitive/padstack_instance.py +1 -1
- pyedb/grpc/database/source_excitations.py +83 -105
- pyedb/grpc/edb.py +59 -198
- {pyedb-0.39.1.dist-info → pyedb-0.41.0.dist-info}/METADATA +2 -1
- {pyedb-0.39.1.dist-info → pyedb-0.41.0.dist-info}/RECORD +26 -26
- {pyedb-0.39.1.dist-info → pyedb-0.41.0.dist-info}/LICENSE +0 -0
- {pyedb-0.39.1.dist-info → pyedb-0.41.0.dist-info}/WHEEL +0 -0
|
@@ -22,8 +22,11 @@
|
|
|
22
22
|
|
|
23
23
|
import re
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
from ansys.edb.core.database import ProductIdType as GrpcProductIdType
|
|
26
|
+
|
|
27
|
+
from pyedb.generic.general_methods import generate_unique_name
|
|
28
|
+
from pyedb.grpc.database.primitive.padstack_instance import PadstackInstance
|
|
29
|
+
|
|
27
30
|
# from pyedb.grpc.database.primitive.primitive import Primitive
|
|
28
31
|
|
|
29
32
|
|
|
@@ -120,146 +123,145 @@ class LayoutValidation:
|
|
|
120
123
|
i.net = self._pedb.nets.nets[temp_name]
|
|
121
124
|
return dc_shorts
|
|
122
125
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
# return new_nets
|
|
126
|
+
def disjoint_nets(
|
|
127
|
+
self,
|
|
128
|
+
net_list=None,
|
|
129
|
+
keep_only_main_net=False,
|
|
130
|
+
clean_disjoints_less_than=0.0,
|
|
131
|
+
order_by_area=False,
|
|
132
|
+
keep_disjoint_pins=False,
|
|
133
|
+
):
|
|
134
|
+
"""Find and fix disjoint nets from a given netlist.
|
|
135
|
+
|
|
136
|
+
Parameters
|
|
137
|
+
----------
|
|
138
|
+
net_list : str, list, optional
|
|
139
|
+
List of nets on which check disjoints. If `None` is provided then the algorithm will loop on all nets.
|
|
140
|
+
keep_only_main_net : bool, optional
|
|
141
|
+
Remove all secondary nets other than principal one (the one with more objects in it). Default is `False`.
|
|
142
|
+
clean_disjoints_less_than : bool, optional
|
|
143
|
+
Clean all disjoint nets with area less than specified area in square meters. Default is `0.0` to disable it.
|
|
144
|
+
order_by_area : bool, optional
|
|
145
|
+
Whether if the naming order has to be by number of objects (fastest) or area (slowest but more accurate).
|
|
146
|
+
Default is ``False``.
|
|
147
|
+
keep_disjoint_pins : bool, optional
|
|
148
|
+
Whether if delete disjoints pins not connected to any other primitive or not. Default is ``False``.
|
|
149
|
+
|
|
150
|
+
Returns
|
|
151
|
+
-------
|
|
152
|
+
List
|
|
153
|
+
New nets created.
|
|
154
|
+
|
|
155
|
+
Examples
|
|
156
|
+
--------
|
|
157
|
+
|
|
158
|
+
>>> renamed_nets = edb.layout_validation.disjoint_nets(["GND","Net2"])
|
|
159
|
+
"""
|
|
160
|
+
timer_start = self._pedb.logger.reset_timer()
|
|
161
|
+
|
|
162
|
+
if not net_list:
|
|
163
|
+
net_list = list(self._pedb.nets.keys())
|
|
164
|
+
elif isinstance(net_list, str):
|
|
165
|
+
net_list = [net_list]
|
|
166
|
+
_objects_list = {}
|
|
167
|
+
_padstacks_list = {}
|
|
168
|
+
for prim in self._pedb.modeler.primitives:
|
|
169
|
+
if not prim.net.is_null:
|
|
170
|
+
n_name = prim.net.name
|
|
171
|
+
if n_name in _objects_list:
|
|
172
|
+
_objects_list[n_name].append(prim)
|
|
173
|
+
else:
|
|
174
|
+
_objects_list[n_name] = [prim]
|
|
175
|
+
for pad in list(self._pedb.padstacks.instances.values()):
|
|
176
|
+
if not pad.net.is_null:
|
|
177
|
+
n_name = pad.net_name
|
|
178
|
+
if n_name in _padstacks_list:
|
|
179
|
+
_padstacks_list[n_name].append(pad)
|
|
180
|
+
else:
|
|
181
|
+
_padstacks_list[n_name] = [pad]
|
|
182
|
+
new_nets = []
|
|
183
|
+
disjoints_objects = []
|
|
184
|
+
self._pedb.logger.reset_timer()
|
|
185
|
+
for net in net_list:
|
|
186
|
+
net_groups = []
|
|
187
|
+
obj_dict = {}
|
|
188
|
+
for i in _objects_list.get(net, []):
|
|
189
|
+
obj_dict[i.id] = i
|
|
190
|
+
for i in _padstacks_list.get(net, []):
|
|
191
|
+
obj_dict[i.id] = i
|
|
192
|
+
objs = list(obj_dict.values())
|
|
193
|
+
l = len(objs)
|
|
194
|
+
while l > 0:
|
|
195
|
+
l1 = self._layout_instance.get_connected_objects(objs[0].layout_object_instance, False)
|
|
196
|
+
l1.append(objs[0].id)
|
|
197
|
+
repetition = False
|
|
198
|
+
for net_list in net_groups:
|
|
199
|
+
if set(l1).intersection(net_list):
|
|
200
|
+
net_groups.append([i for i in l1 if i not in net_list])
|
|
201
|
+
repetition = True
|
|
202
|
+
if not repetition:
|
|
203
|
+
net_groups.append(l1)
|
|
204
|
+
objs = [i for i in objs if i.id not in l1]
|
|
205
|
+
l = len(objs)
|
|
206
|
+
if len(net_groups) > 1:
|
|
207
|
+
|
|
208
|
+
def area_calc(elem):
|
|
209
|
+
sum = 0
|
|
210
|
+
for el in elem:
|
|
211
|
+
try:
|
|
212
|
+
if el.layout_obj.obj_type.value == 0:
|
|
213
|
+
if not el.is_void:
|
|
214
|
+
sum += el.area()
|
|
215
|
+
except:
|
|
216
|
+
pass
|
|
217
|
+
return sum
|
|
218
|
+
|
|
219
|
+
if order_by_area:
|
|
220
|
+
areas = [area_calc(i) for i in net_groups]
|
|
221
|
+
sorted_list = [x for _, x in sorted(zip(areas, net_groups), reverse=True)]
|
|
222
|
+
else:
|
|
223
|
+
sorted_list = sorted(net_groups, key=len, reverse=True)
|
|
224
|
+
for disjoints in sorted_list[1:]:
|
|
225
|
+
if keep_only_main_net:
|
|
226
|
+
for geo in disjoints:
|
|
227
|
+
try:
|
|
228
|
+
obj_dict[geo].delete()
|
|
229
|
+
except KeyError:
|
|
230
|
+
pass
|
|
231
|
+
elif len(disjoints) == 1 and (
|
|
232
|
+
clean_disjoints_less_than
|
|
233
|
+
and "area" in dir(obj_dict[disjoints[0]])
|
|
234
|
+
and obj_dict[disjoints[0]].area() < clean_disjoints_less_than
|
|
235
|
+
):
|
|
236
|
+
try:
|
|
237
|
+
obj_dict[disjoints[0]].delete()
|
|
238
|
+
except KeyError:
|
|
239
|
+
pass
|
|
240
|
+
elif (
|
|
241
|
+
len(disjoints) == 1
|
|
242
|
+
and not keep_disjoint_pins
|
|
243
|
+
and isinstance(obj_dict[disjoints[0]], PadstackInstance)
|
|
244
|
+
):
|
|
245
|
+
try:
|
|
246
|
+
obj_dict[disjoints[0]].delete()
|
|
247
|
+
except KeyError:
|
|
248
|
+
pass
|
|
249
|
+
|
|
250
|
+
else:
|
|
251
|
+
new_net_name = generate_unique_name(net, n=6)
|
|
252
|
+
net_obj = self._pedb.nets.find_or_create_net(new_net_name)
|
|
253
|
+
if net_obj:
|
|
254
|
+
new_nets.append(net_obj.name)
|
|
255
|
+
for geo in disjoints:
|
|
256
|
+
try:
|
|
257
|
+
obj_dict[geo].net_name = net_obj.name
|
|
258
|
+
except KeyError:
|
|
259
|
+
pass
|
|
260
|
+
disjoints_objects.extend(disjoints)
|
|
261
|
+
self._pedb._logger.info("Found {} objects in {} new nets.".format(len(disjoints_objects), len(new_nets)))
|
|
262
|
+
self._pedb._logger.info_timer("Disjoint Cleanup Completed.", timer_start)
|
|
263
|
+
|
|
264
|
+
return new_nets
|
|
263
265
|
|
|
264
266
|
def fix_self_intersections(self, net_list=None):
|
|
265
267
|
"""Find and fix self intersections from a given netlist.
|
|
@@ -274,7 +276,7 @@ class LayoutValidation:
|
|
|
274
276
|
bool
|
|
275
277
|
"""
|
|
276
278
|
if not net_list:
|
|
277
|
-
net_list = list(self._pedb.nets.keys())
|
|
279
|
+
net_list = list(self._pedb.nets.nets.keys())
|
|
278
280
|
elif isinstance(net_list, str):
|
|
279
281
|
net_list = [net_list]
|
|
280
282
|
new_prims = []
|
|
@@ -317,3 +319,22 @@ class LayoutValidation:
|
|
|
317
319
|
v.rlc_values = [0, 1, 0]
|
|
318
320
|
self._pedb._logger.info(f"Found {len(temp)} inductors have no value.")
|
|
319
321
|
return
|
|
322
|
+
|
|
323
|
+
def padstacks_no_name(self, fix=False):
|
|
324
|
+
pds = self._pedb.layout.padstack_instances
|
|
325
|
+
counts = 0
|
|
326
|
+
via_count = 1
|
|
327
|
+
for obj in pds:
|
|
328
|
+
name = obj.get_product_property(GrpcProductIdType.DESIGNER, 11)
|
|
329
|
+
name = str(name).strip("'")
|
|
330
|
+
if name == "":
|
|
331
|
+
counts += 1
|
|
332
|
+
if fix:
|
|
333
|
+
if not obj.component:
|
|
334
|
+
obj.set_product_property(GrpcProductIdType.DESIGNER, 11, f"Via{via_count}")
|
|
335
|
+
via_count = via_count + 1
|
|
336
|
+
else:
|
|
337
|
+
obj.set_product_property(
|
|
338
|
+
GrpcProductIdType.DESIGNER, 11, f"{obj.component.name}-{obj.component_pin}"
|
|
339
|
+
)
|
|
340
|
+
self._pedb._logger.info(f"Found {counts}/{len(pds)} padstacks have no name.")
|
pyedb/grpc/database/net/net.py
CHANGED
|
@@ -122,13 +122,7 @@ class Net(GrpcNet):
|
|
|
122
122
|
return self._pedb.layout_validation.dc_shorts(self.name, fix)
|
|
123
123
|
|
|
124
124
|
def plot(
|
|
125
|
-
self,
|
|
126
|
-
layers=None,
|
|
127
|
-
show_legend=True,
|
|
128
|
-
save_plot=None,
|
|
129
|
-
outline=None,
|
|
130
|
-
size=(2000, 1000),
|
|
131
|
-
show=True,
|
|
125
|
+
self, layers=None, show_legend=True, save_plot=None, outline=None, size=(2000, 1000), show=True, title=None
|
|
132
126
|
):
|
|
133
127
|
"""Plot a net to Matplotlib 2D chart.
|
|
134
128
|
|
|
@@ -147,7 +141,9 @@ class Net(GrpcNet):
|
|
|
147
141
|
size : tuple, optional
|
|
148
142
|
Image size in pixel (width, height).
|
|
149
143
|
show : bool, optional
|
|
150
|
-
Whether to show the plot or not. Default is
|
|
144
|
+
Whether to show the plot or not. Default is ``True``.
|
|
145
|
+
title : str, optional
|
|
146
|
+
Plot title. If value is ``None`` the project name is assigned by default. Default value is ``None``.
|
|
151
147
|
"""
|
|
152
148
|
|
|
153
149
|
self._pedb.nets.plot(
|
|
@@ -160,6 +156,7 @@ class Net(GrpcNet):
|
|
|
160
156
|
show=show,
|
|
161
157
|
plot_components=True,
|
|
162
158
|
plot_vias=True,
|
|
159
|
+
title=None,
|
|
163
160
|
)
|
|
164
161
|
|
|
165
162
|
def get_smallest_trace_width(self):
|