pyedb 0.34.3__py3-none-any.whl → 0.35.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_components.py +2 -2
- pyedb/configuration/cfg_modeler.py +1 -0
- pyedb/configuration/cfg_padstacks.py +9 -9
- pyedb/configuration/cfg_pin_groups.py +7 -8
- pyedb/configuration/cfg_ports_sources.py +6 -3
- pyedb/configuration/cfg_stackup.py +1 -0
- pyedb/configuration/configuration.py +9 -5
- pyedb/dotnet/edb.py +1 -0
- pyedb/dotnet/edb_core/cell/hierarchy/pin_pair_model.py +3 -3
- pyedb/dotnet/edb_core/cell/terminal/padstack_instance_terminal.py +12 -0
- pyedb/dotnet/edb_core/cell/terminal/point_terminal.py +12 -0
- pyedb/dotnet/edb_core/cell/terminal/terminal.py +6 -15
- pyedb/dotnet/edb_core/components.py +21 -45
- pyedb/dotnet/edb_core/edb_data/layer_data.py +22 -2
- pyedb/dotnet/edb_core/padstack.py +198 -10
- pyedb/dotnet/edb_core/siwave.py +1 -2
- pyedb/generic/process.py +10 -10
- {pyedb-0.34.3.dist-info → pyedb-0.35.0.dist-info}/METADATA +6 -6
- {pyedb-0.34.3.dist-info → pyedb-0.35.0.dist-info}/RECORD +22 -22
- {pyedb-0.34.3.dist-info → pyedb-0.35.0.dist-info}/LICENSE +0 -0
- {pyedb-0.34.3.dist-info → pyedb-0.35.0.dist-info}/WHEEL +0 -0
pyedb/__init__.py
CHANGED
|
@@ -210,10 +210,10 @@ class CfgComponent(CfgBase):
|
|
|
210
210
|
self._pyedb_obj.component_property = cp
|
|
211
211
|
|
|
212
212
|
def set_parameters_to_edb(self):
|
|
213
|
-
if self.enabled:
|
|
214
|
-
self._pyedb_obj.enabled = self.enabled
|
|
215
213
|
if self.type:
|
|
216
214
|
self._pyedb_obj.type = self.type
|
|
215
|
+
if self.enabled:
|
|
216
|
+
self._pyedb_obj.enabled = self.enabled
|
|
217
217
|
|
|
218
218
|
self._set_model_properties_to_edb()
|
|
219
219
|
if self._pyedb_obj.type.lower() == "ic":
|
|
@@ -124,6 +124,15 @@ class CfgPadstackDefinition(CfgBase):
|
|
|
124
124
|
if self.solder_ball_parameters:
|
|
125
125
|
self._set_solder_parameters_to_edb(self.solder_ball_parameters)
|
|
126
126
|
|
|
127
|
+
def retrieve_parameters_from_edb(self):
|
|
128
|
+
self.name = self._pyedb_obj.name
|
|
129
|
+
self.hole_plating_thickness = self._pyedb_obj.hole_plating_thickness
|
|
130
|
+
self.material = self._pyedb_obj.material
|
|
131
|
+
self.hole_range = self._pyedb_obj.hole_range
|
|
132
|
+
self.pad_parameters = self._get_pad_parameters_from_edb()
|
|
133
|
+
self.hole_parameters = self._get_hole_parameters_from_edb()
|
|
134
|
+
self.solder_ball_parameters = self._get_solder_parameters_from_edb()
|
|
135
|
+
|
|
127
136
|
def _set_solder_parameters_to_edb(self, parameters):
|
|
128
137
|
pdef_data = self._pyedb_obj._padstack_def_data
|
|
129
138
|
|
|
@@ -158,15 +167,6 @@ class CfgPadstackDefinition(CfgBase):
|
|
|
158
167
|
}
|
|
159
168
|
return parameters
|
|
160
169
|
|
|
161
|
-
def retrieve_parameters_from_edb(self):
|
|
162
|
-
self.name = self._pyedb_obj.name
|
|
163
|
-
self.hole_plating_thickness = self._pyedb_obj.hole_plating_thickness
|
|
164
|
-
self.material = self._pyedb_obj.material
|
|
165
|
-
self.hole_range = self._pyedb_obj.hole_range
|
|
166
|
-
self.pad_parameters = self._get_pad_parameters_from_edb()
|
|
167
|
-
self.hole_parameters = self._get_hole_parameters_from_edb()
|
|
168
|
-
self.solder_ball_parameters = self._get_solder_parameters_from_edb()
|
|
169
|
-
|
|
170
170
|
def _get_pad_parameters_from_edb(self):
|
|
171
171
|
"""Pad parameters.
|
|
172
172
|
|
|
@@ -67,17 +67,16 @@ class CfgPinGroup(CfgBase):
|
|
|
67
67
|
def create(self):
|
|
68
68
|
"""Apply pin group on layout."""
|
|
69
69
|
if self.pins:
|
|
70
|
-
self.
|
|
70
|
+
pins = self.pins if isinstance(self.pins, list) else [self.pins]
|
|
71
|
+
self._pedb.siwave.create_pin_group(self.reference_designator, pins, self.name)
|
|
71
72
|
elif self.net:
|
|
72
|
-
if self.
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
raise f"Component not found for creating pin group {self.name}."
|
|
76
|
-
pins = [p for p, obj in comp.pins.items() if obj.net_name in self.net]
|
|
73
|
+
nets = self.net if isinstance(self.net, list) else [self.net]
|
|
74
|
+
comp = self._pedb.components.instances[self.reference_designator]
|
|
75
|
+
pins = [p for p, obj in comp.pins.items() if obj.net_name in nets]
|
|
77
76
|
if not self._pedb.siwave.create_pin_group(self.reference_designator, pins, self.name):
|
|
78
|
-
|
|
77
|
+
raise RuntimeError(f"Failed to create pin group {self.name}")
|
|
79
78
|
else:
|
|
80
|
-
|
|
79
|
+
raise RuntimeError(f"No net and pins defined for defining pin group {self.name}")
|
|
81
80
|
|
|
82
81
|
def export_properties(self):
|
|
83
82
|
if self.pins:
|
|
@@ -265,7 +265,7 @@ class CfgCircuitElement(CfgBase):
|
|
|
265
265
|
pins = {pos_value: self._pedb.components.instances[self.reference_designator].pins[pos_value]}
|
|
266
266
|
pos_objs.update(pins)
|
|
267
267
|
else:
|
|
268
|
-
raise f"Wrong positive terminal type {pos_type}"
|
|
268
|
+
raise Exception(f"Wrong positive terminal type {pos_type}.")
|
|
269
269
|
|
|
270
270
|
self.pos_terminals = {i: j.create_terminal(i) for i, j in pos_objs.items()}
|
|
271
271
|
self.pos_terminals.update(pos_coor_terminal)
|
|
@@ -297,9 +297,12 @@ class CfgCircuitElement(CfgBase):
|
|
|
297
297
|
# create pin group
|
|
298
298
|
neg_obj = self._create_pin_group(pins, True)
|
|
299
299
|
elif neg_type == "pin":
|
|
300
|
-
|
|
300
|
+
terminal_name = f"{self.reference_designator}_{neg_value}"
|
|
301
|
+
neg_obj = {
|
|
302
|
+
terminal_name: self._pedb.components.instances[self.reference_designator].pins[neg_value]
|
|
303
|
+
}
|
|
301
304
|
else:
|
|
302
|
-
raise f"Wrong negative terminal type {neg_type}"
|
|
305
|
+
raise Exception(f"Wrong negative terminal type {neg_type}.")
|
|
303
306
|
self.neg_terminal = [
|
|
304
307
|
j.create_terminal(i) if not j.terminal else j.terminal for i, j in neg_obj.items()
|
|
305
308
|
][0]
|
|
@@ -134,13 +134,17 @@ class Configuration:
|
|
|
134
134
|
|
|
135
135
|
# Configure stackup
|
|
136
136
|
if kwargs.get("fix_padstack_def"):
|
|
137
|
+
from pyedb.configuration.cfg_padstacks import CfgPadstackDefinition
|
|
138
|
+
|
|
137
139
|
pedb_defs = self._pedb.padstacks.definitions
|
|
138
|
-
temp =
|
|
139
|
-
for
|
|
140
|
-
|
|
140
|
+
temp = []
|
|
141
|
+
for _, pdef in pedb_defs.items():
|
|
142
|
+
cfg_def = CfgPadstackDefinition(self._pedb, pdef)
|
|
143
|
+
cfg_def.retrieve_parameters_from_edb()
|
|
144
|
+
temp.append(cfg_def)
|
|
141
145
|
self.cfg_data.stackup.apply()
|
|
142
|
-
for
|
|
143
|
-
|
|
146
|
+
for cfg_pdef in temp:
|
|
147
|
+
cfg_pdef.set_parameters_to_edb()
|
|
144
148
|
else:
|
|
145
149
|
self.cfg_data.stackup.apply()
|
|
146
150
|
|
pyedb/dotnet/edb.py
CHANGED
|
@@ -4564,6 +4564,7 @@ class Edb(Database):
|
|
|
4564
4564
|
port_poly = cloned_edb.modeler.create_polygon(
|
|
4565
4565
|
main_shape=void_info[0].polygon_data._edb_object, layer_name="ref", net_name="GND"
|
|
4566
4566
|
)
|
|
4567
|
+
port_poly.scale(1.1)
|
|
4567
4568
|
pec_poly = cloned_edb.modeler.create_polygon(
|
|
4568
4569
|
main_shape=port_poly.polygon_data._edb_object, layer_name="port_pec", net_name="GND"
|
|
4569
4570
|
)
|
|
@@ -66,7 +66,7 @@ class PinPair(object): # pragma: no cover
|
|
|
66
66
|
@resistance.setter
|
|
67
67
|
def resistance(self, value):
|
|
68
68
|
self._pin_pair_rlc.R = value
|
|
69
|
-
self._set_comp_prop(
|
|
69
|
+
self._set_comp_prop() # pragma: no cover
|
|
70
70
|
|
|
71
71
|
@property
|
|
72
72
|
def inductance(self):
|
|
@@ -75,7 +75,7 @@ class PinPair(object): # pragma: no cover
|
|
|
75
75
|
@inductance.setter
|
|
76
76
|
def inductance(self, value):
|
|
77
77
|
self._pin_pair_rlc.L = value
|
|
78
|
-
self._set_comp_prop(
|
|
78
|
+
self._set_comp_prop() # pragma: no cover
|
|
79
79
|
|
|
80
80
|
@property
|
|
81
81
|
def capacitance(self):
|
|
@@ -84,7 +84,7 @@ class PinPair(object): # pragma: no cover
|
|
|
84
84
|
@capacitance.setter
|
|
85
85
|
def capacitance(self, value):
|
|
86
86
|
self._pin_pair_rlc.C = value
|
|
87
|
-
self._set_comp_prop(
|
|
87
|
+
self._set_comp_prop() # pragma: no cover
|
|
88
88
|
|
|
89
89
|
@property
|
|
90
90
|
def rlc_values(self): # pragma: no cover
|
|
@@ -101,3 +101,15 @@ class PadstackInstanceTerminal(Terminal):
|
|
|
101
101
|
def padstack_instance(self):
|
|
102
102
|
p_inst, _ = self._get_parameters()
|
|
103
103
|
return self._pedb.layout.find_object_by_id(p_inst.GetId())
|
|
104
|
+
|
|
105
|
+
@property
|
|
106
|
+
def layer(self):
|
|
107
|
+
"""Get layer of the terminal."""
|
|
108
|
+
_, _, layer = self._edb_object.GetParameters()
|
|
109
|
+
return self._pedb.stackup.all_layers[layer.GetName()]
|
|
110
|
+
|
|
111
|
+
@layer.setter
|
|
112
|
+
def layer(self, value):
|
|
113
|
+
layer = self._pedb.stackup.layers[value]._edb_layer
|
|
114
|
+
point_data = self._pedb.point_data(*self.location)
|
|
115
|
+
self._edb_object.SetParameters(point_data, layer)
|
|
@@ -66,3 +66,15 @@ class PointTerminal(Terminal):
|
|
|
66
66
|
raise Exception(msg)
|
|
67
67
|
else:
|
|
68
68
|
return terminal
|
|
69
|
+
|
|
70
|
+
@property
|
|
71
|
+
def layer(self):
|
|
72
|
+
"""Get layer of the terminal."""
|
|
73
|
+
_, _, layer = self._edb_object.GetParameters()
|
|
74
|
+
return self._pedb.stackup.all_layers[layer.GetName()]
|
|
75
|
+
|
|
76
|
+
@layer.setter
|
|
77
|
+
def layer(self, value):
|
|
78
|
+
layer = self._pedb.stackup.layers[value]._edb_layer
|
|
79
|
+
point_data = self._pedb.point_data(*self.location)
|
|
80
|
+
self._edb_object.SetParameters(point_data, layer)
|
|
@@ -105,25 +105,16 @@ class Terminal(Connectable):
|
|
|
105
105
|
@property
|
|
106
106
|
def layer(self):
|
|
107
107
|
"""Get layer of the terminal."""
|
|
108
|
-
|
|
109
|
-
layer = list(self._pedb.stackup.layers.values())[0]._edb_layer
|
|
110
|
-
if self._edb_object.GetParameters(point_data, layer):
|
|
111
|
-
return self._pedb.stackup.all_layers[layer.GetName()]
|
|
112
|
-
else:
|
|
113
|
-
self._pedb.logger.warning(f"No pad parameters found for terminal {self.name}")
|
|
114
|
-
|
|
115
|
-
@layer.setter
|
|
116
|
-
def layer(self, value):
|
|
117
|
-
layer = self._pedb.stackup.layers[value]._edb_layer
|
|
118
|
-
point_data = self._pedb.point_data(*self.location)
|
|
119
|
-
self._edb_object.SetParameters(point_data, layer)
|
|
108
|
+
return self._pedb.logger.error("Cannot determine terminal layer")
|
|
120
109
|
|
|
121
110
|
@property
|
|
122
111
|
def location(self):
|
|
123
112
|
"""Location of the terminal."""
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
113
|
+
try:
|
|
114
|
+
_, point_data, _ = self._edb_object.GetParameters()
|
|
115
|
+
return [point_data.X.ToDouble(), point_data.Y.ToDouble()]
|
|
116
|
+
except:
|
|
117
|
+
self._pedb.logger.error("Cannot determine terminal location")
|
|
127
118
|
|
|
128
119
|
@location.setter
|
|
129
120
|
def location(self, value):
|
|
@@ -111,16 +111,9 @@ class Components(object):
|
|
|
111
111
|
|
|
112
112
|
def __init__(self, p_edb):
|
|
113
113
|
self._pedb = p_edb
|
|
114
|
-
self.
|
|
115
|
-
self._res = {}
|
|
116
|
-
self._cap = {}
|
|
117
|
-
self._ind = {}
|
|
118
|
-
self._ios = {}
|
|
119
|
-
self._ics = {}
|
|
120
|
-
self._others = {}
|
|
114
|
+
self.refresh_components()
|
|
121
115
|
self._pins = {}
|
|
122
116
|
self._comps_by_part = {}
|
|
123
|
-
self._init_parts()
|
|
124
117
|
self._padstack = EdbPadstacks(self._pedb)
|
|
125
118
|
|
|
126
119
|
@property
|
|
@@ -132,16 +125,6 @@ class Components(object):
|
|
|
132
125
|
def _edb(self):
|
|
133
126
|
return self._pedb.edb_api
|
|
134
127
|
|
|
135
|
-
def _init_parts(self):
|
|
136
|
-
a = self.instances
|
|
137
|
-
a = self.resistors
|
|
138
|
-
a = self.ICs
|
|
139
|
-
a = self.Others
|
|
140
|
-
a = self.inductors
|
|
141
|
-
a = self.IOs
|
|
142
|
-
a = self.components_by_partname
|
|
143
|
-
return True
|
|
144
|
-
|
|
145
128
|
def _get_edb_value(self, value):
|
|
146
129
|
return self._pedb.edb_value(value)
|
|
147
130
|
|
|
@@ -205,8 +188,6 @@ class Components(object):
|
|
|
205
188
|
>>> edbapp.components.instances
|
|
206
189
|
|
|
207
190
|
"""
|
|
208
|
-
if not self._cmp:
|
|
209
|
-
self.refresh_components()
|
|
210
191
|
return self._cmp
|
|
211
192
|
|
|
212
193
|
@property
|
|
@@ -310,10 +291,29 @@ class Components(object):
|
|
|
310
291
|
|
|
311
292
|
def refresh_components(self):
|
|
312
293
|
"""Refresh the component dictionary."""
|
|
313
|
-
# self._logger.info("Refreshing the Components dictionary.")
|
|
314
294
|
self._cmp = {}
|
|
295
|
+
self._res = {}
|
|
296
|
+
self._ind = {}
|
|
297
|
+
self._cap = {}
|
|
298
|
+
self._ics = {}
|
|
299
|
+
self._ios = {}
|
|
300
|
+
self._others = {}
|
|
315
301
|
for i in self._pedb.layout.groups:
|
|
316
302
|
self._cmp[i.name] = i
|
|
303
|
+
if i.type == "Resistor":
|
|
304
|
+
self._res[i.name] = i
|
|
305
|
+
elif i.type == "Capacitor":
|
|
306
|
+
self._cap[i.name] = i
|
|
307
|
+
elif i.type == "Inductor":
|
|
308
|
+
self._ind[i.name] = i
|
|
309
|
+
elif i.type == "IC":
|
|
310
|
+
self._ics[i.name] = i
|
|
311
|
+
elif i.type == "IO":
|
|
312
|
+
self._ios[i.name] = i
|
|
313
|
+
elif i.type == "Other":
|
|
314
|
+
self._others[i.name] = i
|
|
315
|
+
else:
|
|
316
|
+
self._logger.warning(f"Unknown component type {i.name} found while refreshing components, will ignore")
|
|
317
317
|
return True
|
|
318
318
|
|
|
319
319
|
@property
|
|
@@ -332,10 +332,6 @@ class Components(object):
|
|
|
332
332
|
>>> edbapp = Edb("myaedbfolder")
|
|
333
333
|
>>> edbapp.components.resistors
|
|
334
334
|
"""
|
|
335
|
-
self._res = {}
|
|
336
|
-
for el, val in self.instances.items():
|
|
337
|
-
if val.type == "Resistor":
|
|
338
|
-
self._res[el] = val
|
|
339
335
|
return self._res
|
|
340
336
|
|
|
341
337
|
@property
|
|
@@ -354,10 +350,6 @@ class Components(object):
|
|
|
354
350
|
>>> edbapp = Edb("myaedbfolder")
|
|
355
351
|
>>> edbapp.components.capacitors
|
|
356
352
|
"""
|
|
357
|
-
self._cap = {}
|
|
358
|
-
for el, val in self.instances.items():
|
|
359
|
-
if val.type == "Capacitor":
|
|
360
|
-
self._cap[el] = val
|
|
361
353
|
return self._cap
|
|
362
354
|
|
|
363
355
|
@property
|
|
@@ -377,10 +369,6 @@ class Components(object):
|
|
|
377
369
|
>>> edbapp.components.inductors
|
|
378
370
|
|
|
379
371
|
"""
|
|
380
|
-
self._ind = {}
|
|
381
|
-
for el, val in self.instances.items():
|
|
382
|
-
if val.type == "Inductor":
|
|
383
|
-
self._ind[el] = val
|
|
384
372
|
return self._ind
|
|
385
373
|
|
|
386
374
|
@property
|
|
@@ -400,10 +388,6 @@ class Components(object):
|
|
|
400
388
|
>>> edbapp.components.ICs
|
|
401
389
|
|
|
402
390
|
"""
|
|
403
|
-
self._ics = {}
|
|
404
|
-
for el, val in self.instances.items():
|
|
405
|
-
if val.type == "IC":
|
|
406
|
-
self._ics[el] = val
|
|
407
391
|
return self._ics
|
|
408
392
|
|
|
409
393
|
@property
|
|
@@ -423,10 +407,6 @@ class Components(object):
|
|
|
423
407
|
>>> edbapp.components.IOs
|
|
424
408
|
|
|
425
409
|
"""
|
|
426
|
-
self._ios = {}
|
|
427
|
-
for el, val in self.instances.items():
|
|
428
|
-
if val.type == "IO":
|
|
429
|
-
self._ios[el] = val
|
|
430
410
|
return self._ios
|
|
431
411
|
|
|
432
412
|
@property
|
|
@@ -446,10 +426,6 @@ class Components(object):
|
|
|
446
426
|
>>> edbapp.components.others
|
|
447
427
|
|
|
448
428
|
"""
|
|
449
|
-
self._others = {}
|
|
450
|
-
for el, val in self.instances.items():
|
|
451
|
-
if val.type == "Other":
|
|
452
|
-
self._others[el] = val
|
|
453
429
|
return self._others
|
|
454
430
|
|
|
455
431
|
@property
|
|
@@ -60,6 +60,8 @@ class LayerEdbClass(object):
|
|
|
60
60
|
self.__setattr__(k, v)
|
|
61
61
|
elif k == "roughness":
|
|
62
62
|
self.properties = {"roughness": v}
|
|
63
|
+
elif k == "etching":
|
|
64
|
+
self.properties = {"etching": v}
|
|
63
65
|
else:
|
|
64
66
|
self._pedb.logger.error(f"{k} is not a valid layer attribute")
|
|
65
67
|
|
|
@@ -792,6 +794,15 @@ class StackupLayerEdbClass(LayerEdbClass):
|
|
|
792
794
|
data["thickness"] = self._edb_object.GetThicknessValue().ToString()
|
|
793
795
|
data["color"] = self.color
|
|
794
796
|
|
|
797
|
+
data["etching"] = {
|
|
798
|
+
"factor": self._edb_layer.GetEtchFactor().ToString(),
|
|
799
|
+
"enabled": self._edb_layer.IsEtchFactorEnabled(),
|
|
800
|
+
}
|
|
801
|
+
if self._pedb.edbversion >= "2024.2":
|
|
802
|
+
etch_power_ground_nets = int(self._edb_layer.GetEtchNetClass())
|
|
803
|
+
etch_power_ground_nets = False if etch_power_ground_nets else True
|
|
804
|
+
data["etching"]["etch_power_ground_nets"] = etch_power_ground_nets
|
|
805
|
+
|
|
795
806
|
roughness = {}
|
|
796
807
|
for region in ["top", "bottom", "side"]:
|
|
797
808
|
temp = {}
|
|
@@ -851,5 +862,14 @@ class StackupLayerEdbClass(LayerEdbClass):
|
|
|
851
862
|
getattr(self._pedb._edb.Cell.RoughnessModel.Region, region.capitalize()), r_model
|
|
852
863
|
)
|
|
853
864
|
self._pedb.stackup._set_layout_stackup(layer_clone, "change_attribute")
|
|
854
|
-
|
|
855
|
-
|
|
865
|
+
etching = params.get("etching")
|
|
866
|
+
if etching:
|
|
867
|
+
layer_clone = self._edb_layer
|
|
868
|
+
layer_clone.SetEtchFactorEnabled(etching["enabled"])
|
|
869
|
+
layer_clone.SetEtchFactor(self._pedb.stackup._edb_value(float(etching["factor"])))
|
|
870
|
+
if self._pedb.edbversion >= "2024.2":
|
|
871
|
+
if etching["etch_power_ground_nets"]:
|
|
872
|
+
layer_clone.SetEtchNetClass(self._pedb._edb.Cell.EtchNetClass.NoEtchPowerGroundNets)
|
|
873
|
+
else:
|
|
874
|
+
layer_clone.SetEtchNetClass(self._pedb._edb.Cell.EtchNetClass.EtchAllNets)
|
|
875
|
+
self._pedb.stackup._set_layout_stackup(layer_clone, "change_attribute")
|
|
@@ -26,7 +26,9 @@ This module contains the `EdbPadstacks` class.
|
|
|
26
26
|
import math
|
|
27
27
|
import warnings
|
|
28
28
|
|
|
29
|
+
import numpy as np
|
|
29
30
|
import rtree
|
|
31
|
+
from scipy.spatial import ConvexHull
|
|
30
32
|
|
|
31
33
|
from pyedb.dotnet.clr_module import Array
|
|
32
34
|
from pyedb.dotnet.edb_core.edb_data.padstacks_data import (
|
|
@@ -1553,7 +1555,7 @@ class EdbPadstacks(object):
|
|
|
1553
1555
|
padstack_instances_index.insert(inst.id, inst.position)
|
|
1554
1556
|
return padstack_instances_index
|
|
1555
1557
|
|
|
1556
|
-
def
|
|
1558
|
+
def get_padstack_instances_id_intersecting_polygon(self, points, nets=None, padstack_instances_index=None):
|
|
1557
1559
|
"""Returns the list of padstack instances ID intersecting a given bounding box and nets.
|
|
1558
1560
|
|
|
1559
1561
|
Parameters
|
|
@@ -1563,6 +1565,38 @@ class EdbPadstacks(object):
|
|
|
1563
1565
|
nets : str or list, optional
|
|
1564
1566
|
net name of list of nets name applying filtering on padstack instances selection. If ``None`` is provided
|
|
1565
1567
|
all instances are included in the index. Default value is ``None``.
|
|
1568
|
+
padstack_instances_index : optional, Rtree object.
|
|
1569
|
+
Can be provided optionally to prevent computing padstack instances Rtree index again.
|
|
1570
|
+
|
|
1571
|
+
Returns
|
|
1572
|
+
-------
|
|
1573
|
+
List of padstack instances ID intersecting the bounding box.
|
|
1574
|
+
"""
|
|
1575
|
+
if not points:
|
|
1576
|
+
raise Exception("No points defining polygon was provided")
|
|
1577
|
+
if not padstack_instances_index:
|
|
1578
|
+
padstack_instances_index = {}
|
|
1579
|
+
for inst in self.instances:
|
|
1580
|
+
padstack_instances_index[inst.id] = inst.position
|
|
1581
|
+
_x = [pt[0] for pt in points]
|
|
1582
|
+
_y = [pt[1] for pt in points]
|
|
1583
|
+
points = [_x, _y]
|
|
1584
|
+
return [
|
|
1585
|
+
ind for ind, pt in padstack_instances_index.items() if GeometryOperators.is_point_in_polygon(pt, points)
|
|
1586
|
+
]
|
|
1587
|
+
|
|
1588
|
+
def get_padstack_instances_intersecting_bounding_box(self, bounding_box, nets=None, padstack_instances_index=None):
|
|
1589
|
+
"""Returns the list of padstack instances ID intersecting a given bounding box and nets.
|
|
1590
|
+
|
|
1591
|
+
Parameters
|
|
1592
|
+
----------
|
|
1593
|
+
bounding_box : tuple or list.
|
|
1594
|
+
bounding box, [x1, y1, x2, y2]
|
|
1595
|
+
nets : str or list, optional
|
|
1596
|
+
net name of list of nets name applying filtering on padstack instances selection. If ``None`` is provided
|
|
1597
|
+
all instances are included in the index. Default value is ``None``.
|
|
1598
|
+
padstack_instances_index : optional, Rtree object.
|
|
1599
|
+
Can be provided optionally to prevent computing padstack instances Rtree index again.
|
|
1566
1600
|
|
|
1567
1601
|
Returns
|
|
1568
1602
|
-------
|
|
@@ -1570,15 +1604,104 @@ class EdbPadstacks(object):
|
|
|
1570
1604
|
"""
|
|
1571
1605
|
if not bounding_box:
|
|
1572
1606
|
raise Exception("No bounding box was provided")
|
|
1573
|
-
|
|
1607
|
+
if not padstack_instances_index:
|
|
1608
|
+
index = self.get_padstack_instances_rtree_index(nets=nets)
|
|
1609
|
+
else:
|
|
1610
|
+
index = padstack_instances_index
|
|
1574
1611
|
if not len(bounding_box) == 4:
|
|
1575
1612
|
raise Exception("The bounding box length must be equal to 4")
|
|
1576
1613
|
if isinstance(bounding_box, list):
|
|
1577
1614
|
bounding_box = tuple(bounding_box)
|
|
1578
1615
|
return list(index.intersection(bounding_box))
|
|
1579
1616
|
|
|
1617
|
+
def merge_via(self, contour_boxes, net_filter=None, start_layer=None, stop_layer=None):
|
|
1618
|
+
"""Evaluate padstack instances included on the provided point list and replace all by single instance.
|
|
1619
|
+
|
|
1620
|
+
Parameters
|
|
1621
|
+
----------
|
|
1622
|
+
contour_boxes : List[List[List[float, float]]]
|
|
1623
|
+
Nested list of polygon with points [x,y].
|
|
1624
|
+
net_filter : optional
|
|
1625
|
+
List[str: net_name] apply a net filter, nets included in the filter are excluded from the via merge.
|
|
1626
|
+
start_layer : optional, str
|
|
1627
|
+
Padstack instance start layer, if `None` the top layer is selected.
|
|
1628
|
+
stop_layer : optional, str
|
|
1629
|
+
Padstack instance stop layer, if `None` the bottom layer is selected.
|
|
1630
|
+
|
|
1631
|
+
Return
|
|
1632
|
+
------
|
|
1633
|
+
List[str], list of created padstack instances ID.
|
|
1634
|
+
|
|
1635
|
+
"""
|
|
1636
|
+
merged_via_ids = []
|
|
1637
|
+
if not contour_boxes:
|
|
1638
|
+
raise Exception("No contour box provided, you need to pass a nested list as argument.")
|
|
1639
|
+
if not start_layer:
|
|
1640
|
+
start_layer = list(self._pedb.stackup.layers.values())[0].name
|
|
1641
|
+
if not stop_layer:
|
|
1642
|
+
stop_layer = list(self._pedb.stackup.layers.values())[-1].name
|
|
1643
|
+
instances_index = {}
|
|
1644
|
+
for id, inst in self.instances.items():
|
|
1645
|
+
instances_index[id] = inst.position
|
|
1646
|
+
for contour_box in contour_boxes:
|
|
1647
|
+
instances = self.get_padstack_instances_id_intersecting_polygon(
|
|
1648
|
+
points=contour_box, padstack_instances_index=instances_index
|
|
1649
|
+
)
|
|
1650
|
+
if not instances:
|
|
1651
|
+
raise Exception(f"No padstack instances found inside {contour_box}")
|
|
1652
|
+
else:
|
|
1653
|
+
if net_filter:
|
|
1654
|
+
instances = [id for id in instances if not self.instances[id].net_name in net_filter]
|
|
1655
|
+
|
|
1656
|
+
net = self.instances[instances[0]].net_name
|
|
1657
|
+
x_values = []
|
|
1658
|
+
y_values = []
|
|
1659
|
+
for inst in instances:
|
|
1660
|
+
pos = instances_index[inst]
|
|
1661
|
+
x_values.append(pos[0])
|
|
1662
|
+
y_values.append(pos[1])
|
|
1663
|
+
x_values = list(set(x_values))
|
|
1664
|
+
y_values = list(set(y_values))
|
|
1665
|
+
if len(x_values) == 1 or len(y_values) == 1:
|
|
1666
|
+
create_instances = self.merge_via_along_lines(
|
|
1667
|
+
net_name=net, padstack_instances_id=instances, minimum_via_number=2
|
|
1668
|
+
)
|
|
1669
|
+
merged_via_ids.extend(create_instances)
|
|
1670
|
+
else:
|
|
1671
|
+
instances_pts = np.array([instances_index[id] for id in instances])
|
|
1672
|
+
convex_hull_contour = ConvexHull(instances_pts)
|
|
1673
|
+
contour_points = list(instances_pts[convex_hull_contour.vertices])
|
|
1674
|
+
layer = list(self._pedb.stackup.layers.values())[0].name
|
|
1675
|
+
polygon = self._pedb.modeler.create_polygon(main_shape=contour_points, layer_name=layer)
|
|
1676
|
+
polygon_data = polygon.polygon_data
|
|
1677
|
+
polygon.delete()
|
|
1678
|
+
new_padstack_def = generate_unique_name(self.instances[instances[0]].definition.name)
|
|
1679
|
+
if not self.create(
|
|
1680
|
+
padstackname=new_padstack_def,
|
|
1681
|
+
pad_shape="Polygon",
|
|
1682
|
+
antipad_shape="Polygon",
|
|
1683
|
+
pad_polygon=polygon_data,
|
|
1684
|
+
antipad_polygon=polygon_data,
|
|
1685
|
+
polygon_hole=polygon_data,
|
|
1686
|
+
start_layer=start_layer,
|
|
1687
|
+
stop_layer=stop_layer,
|
|
1688
|
+
):
|
|
1689
|
+
raise Exception(f"Failed to create padstack definition {new_padstack_def}")
|
|
1690
|
+
merged_instance = self.place(position=[0, 0], definition_name=new_padstack_def, net_name=net)
|
|
1691
|
+
merged_instance.start_layer = start_layer
|
|
1692
|
+
merged_instance.stop_layer = stop_layer
|
|
1693
|
+
|
|
1694
|
+
merged_via_ids.append(merged_instance.id)
|
|
1695
|
+
[self.instances[id].delete() for id in instances]
|
|
1696
|
+
return merged_via_ids
|
|
1697
|
+
|
|
1580
1698
|
def merge_via_along_lines(
|
|
1581
|
-
self,
|
|
1699
|
+
self,
|
|
1700
|
+
net_name="GND",
|
|
1701
|
+
distance_threshold=5e-3,
|
|
1702
|
+
minimum_via_number=6,
|
|
1703
|
+
selected_angles=None,
|
|
1704
|
+
padstack_instances_id=None,
|
|
1582
1705
|
):
|
|
1583
1706
|
"""Replace padstack instances along lines into a single polygon.
|
|
1584
1707
|
|
|
@@ -1602,11 +1725,15 @@ class EdbPadstacks(object):
|
|
|
1602
1725
|
Specify angle in degrees to detected, for instance [0, 180] is only detecting horizontal and vertical lines.
|
|
1603
1726
|
Other values can be assigned like 45 degrees. When `None` is provided all lines are detected. Default value
|
|
1604
1727
|
is `None`.
|
|
1728
|
+
padstack_instances_id : List[int]
|
|
1729
|
+
List of padstack instances ID's to include. If `None`, the algorithm will scan all padstack instances belonging
|
|
1730
|
+
to the specified net. Default value is `None`.
|
|
1731
|
+
|
|
1605
1732
|
|
|
1606
1733
|
Returns
|
|
1607
1734
|
-------
|
|
1608
1735
|
bool
|
|
1609
|
-
|
|
1736
|
+
List[int], list of created padstack instances id.
|
|
1610
1737
|
|
|
1611
1738
|
"""
|
|
1612
1739
|
_def = list(
|
|
@@ -1615,12 +1742,16 @@ class EdbPadstacks(object):
|
|
|
1615
1742
|
if not _def:
|
|
1616
1743
|
self._logger.error(f"No padstack definition found for net {net_name}")
|
|
1617
1744
|
return False
|
|
1745
|
+
instances_created = []
|
|
1618
1746
|
_instances_to_delete = []
|
|
1619
1747
|
padstack_instances = []
|
|
1620
|
-
|
|
1621
|
-
padstack_instances.
|
|
1622
|
-
|
|
1623
|
-
|
|
1748
|
+
if padstack_instances_id:
|
|
1749
|
+
padstack_instances = [[self.instances[id] for id in padstack_instances_id]]
|
|
1750
|
+
else:
|
|
1751
|
+
for pdstk_def in _def:
|
|
1752
|
+
padstack_instances.append(
|
|
1753
|
+
[inst for inst in self.definitions[pdstk_def].instances if inst.net_name == net_name]
|
|
1754
|
+
)
|
|
1624
1755
|
for pdstk_series in padstack_instances:
|
|
1625
1756
|
instances_location = [inst.position for inst in pdstk_series]
|
|
1626
1757
|
lines, line_indexes = GeometryOperators.find_points_along_lines(
|
|
@@ -1652,8 +1783,65 @@ class EdbPadstacks(object):
|
|
|
1652
1783
|
polygon_hole=polygon_data,
|
|
1653
1784
|
):
|
|
1654
1785
|
self._logger.error(f"Failed to create padstack definition {new_padstack_def}")
|
|
1655
|
-
|
|
1786
|
+
new_instance = self.place(position=[0, 0], definition_name=new_padstack_def, net_name=net_name)
|
|
1787
|
+
if not new_instance:
|
|
1656
1788
|
self._logger.error(f"Failed to place padstack instance {new_padstack_def}")
|
|
1789
|
+
else:
|
|
1790
|
+
instances_created.append(new_instance.id)
|
|
1657
1791
|
for inst in _instances_to_delete:
|
|
1658
1792
|
inst.delete()
|
|
1659
|
-
return
|
|
1793
|
+
return instances_created
|
|
1794
|
+
|
|
1795
|
+
def reduce_via_in_bounding_box(self, bounding_box, x_samples, y_samples, nets=None):
|
|
1796
|
+
"""
|
|
1797
|
+
reduce the number of vias intersecting bounding box and nets by x and y samples.
|
|
1798
|
+
|
|
1799
|
+
Parameters
|
|
1800
|
+
----------
|
|
1801
|
+
bounding_box : tuple or list.
|
|
1802
|
+
bounding box, [x1, y1, x2, y2]
|
|
1803
|
+
x_samples : int
|
|
1804
|
+
y_samples : int
|
|
1805
|
+
nets : str or list, optional
|
|
1806
|
+
net name of list of nets name applying filtering on padstack instances selection. If ``None`` is provided
|
|
1807
|
+
all instances are included in the index. Default value is ``None``.
|
|
1808
|
+
|
|
1809
|
+
Returns
|
|
1810
|
+
-------
|
|
1811
|
+
bool
|
|
1812
|
+
``True`` when succeeded ``False`` when failed. <
|
|
1813
|
+
"""
|
|
1814
|
+
|
|
1815
|
+
padstacks_inbox = self.get_padstack_instances_intersecting_bounding_box(bounding_box, nets)
|
|
1816
|
+
if not padstacks_inbox:
|
|
1817
|
+
self._logger.info("no padstack in bounding box")
|
|
1818
|
+
return False
|
|
1819
|
+
else:
|
|
1820
|
+
if len(padstacks_inbox) <= (x_samples * y_samples):
|
|
1821
|
+
self._logger.info(f"more samples {x_samples * y_samples} than existing {len(padstacks_inbox)}")
|
|
1822
|
+
return False
|
|
1823
|
+
else:
|
|
1824
|
+
# extract ids and positions
|
|
1825
|
+
vias = {item: self.instances[item].position for item in padstacks_inbox}
|
|
1826
|
+
ids, positions = zip(*vias.items())
|
|
1827
|
+
pt_x, pt_y = zip(*positions)
|
|
1828
|
+
|
|
1829
|
+
# meshgrid
|
|
1830
|
+
_x_min, _x_max = min(pt_x), max(pt_x)
|
|
1831
|
+
_y_min, _y_max = min(pt_y), max(pt_y)
|
|
1832
|
+
|
|
1833
|
+
x_grid, y_grid = np.meshgrid(
|
|
1834
|
+
np.linspace(_x_min, _x_max, x_samples), np.linspace(_y_min, _y_max, y_samples)
|
|
1835
|
+
)
|
|
1836
|
+
|
|
1837
|
+
# mapping to meshgrid
|
|
1838
|
+
to_keep = {
|
|
1839
|
+
ids[np.argmin(np.square(_x - pt_x) + np.square(_y - pt_y))]
|
|
1840
|
+
for _x, _y in zip(x_grid.ravel(), y_grid.ravel())
|
|
1841
|
+
}
|
|
1842
|
+
|
|
1843
|
+
for item in padstacks_inbox:
|
|
1844
|
+
if item not in to_keep:
|
|
1845
|
+
self.instances[item].delete()
|
|
1846
|
+
|
|
1847
|
+
return True
|
pyedb/dotnet/edb_core/siwave.py
CHANGED
|
@@ -1242,8 +1242,7 @@ class EdbSiwave(object):
|
|
|
1242
1242
|
)
|
|
1243
1243
|
|
|
1244
1244
|
if edb_pingroup.IsNull(): # pragma: no cover
|
|
1245
|
-
|
|
1246
|
-
return False
|
|
1245
|
+
raise RuntimeError(f"Failed to create pin group {group_name}.")
|
|
1247
1246
|
else:
|
|
1248
1247
|
names = [i for i in pins if i.GetNet().GetName()]
|
|
1249
1248
|
edb_pingroup.SetNet(names[0].GetNet())
|
pyedb/generic/process.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import os.path
|
|
2
2
|
import subprocess
|
|
3
3
|
|
|
4
|
-
from pyedb.generic.general_methods import env_path, is_linux
|
|
4
|
+
from pyedb.generic.general_methods import env_path, is_linux, is_windows
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
class SiwaveSolve(object):
|
|
@@ -144,19 +144,19 @@ class SiwaveSolve(object):
|
|
|
144
144
|
f.write("oDoc.ScrExport3DModel('{}', q3d_filename)\n".format(format_3d))
|
|
145
145
|
f.write("oDoc.ScrCloseProject()\n")
|
|
146
146
|
f.write("oApp.Quit()\n")
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
_exe = '"' + os.path.join(self.installer_path, "siwave.exe") + '"'
|
|
147
|
+
_exe = os.path.join(self.installer_path, "siwave")
|
|
148
|
+
if is_windows:
|
|
149
|
+
_exe += ".exe"
|
|
151
150
|
command = [_exe]
|
|
152
151
|
if hidden:
|
|
153
152
|
command.append("-embedding")
|
|
154
|
-
command
|
|
155
|
-
command.append(scriptname)
|
|
153
|
+
command += ["-RunScriptAndExit", scriptname]
|
|
156
154
|
print(command)
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
155
|
+
try:
|
|
156
|
+
result = subprocess.run(command, check=True, capture_output=True)
|
|
157
|
+
print(result.stdout.decode())
|
|
158
|
+
except subprocess.CalledProcessError as e:
|
|
159
|
+
print(f"Error occurred: {e.stderr.decode()}")
|
|
160
160
|
return os.path.join(output_folder, aedt_file_name)
|
|
161
161
|
|
|
162
162
|
def export_dc_report(
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: pyedb
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.35.0
|
|
4
4
|
Summary: Higher-Level Pythonic Ansys Electronics Data Base
|
|
5
5
|
Author-email: "ANSYS, Inc." <pyansys.core@ansys.com>
|
|
6
6
|
Maintainer-email: PyEDB developers <simon.vandenbrouck@ansys.com>
|
|
@@ -21,13 +21,13 @@ Requires-Dist: ansys-pythonnet >= 3.1.0rc4
|
|
|
21
21
|
Requires-Dist: dotnetcore2 ==3.1.23;platform_system=='Linux'
|
|
22
22
|
Requires-Dist: numpy>=1.20.0,<3
|
|
23
23
|
Requires-Dist: pandas>=1.1.0,<2.3
|
|
24
|
-
Requires-Dist: pydantic>=2.6.4,<2.
|
|
24
|
+
Requires-Dist: pydantic>=2.6.4,<2.11
|
|
25
25
|
Requires-Dist: Rtree >= 1.2.0
|
|
26
26
|
Requires-Dist: toml == 0.10.2
|
|
27
27
|
Requires-Dist: scikit-rf
|
|
28
28
|
Requires-Dist: ansys-sphinx-theme>=0.10.0,<1.1 ; extra == "doc"
|
|
29
29
|
Requires-Dist: imageio>=2.30.0,<2.37 ; extra == "doc"
|
|
30
|
-
Requires-Dist: ipython>=8.13.0,<8.
|
|
30
|
+
Requires-Dist: ipython>=8.13.0,<8.32 ; extra == "doc"
|
|
31
31
|
Requires-Dist: jupyterlab>=4.0.0,<4.4 ; extra == "doc"
|
|
32
32
|
Requires-Dist: jupytext>=1.16.0,<1.17 ; extra == "doc"
|
|
33
33
|
Requires-Dist: matplotlib>=3.5.0,<3.10 ; extra == "doc"
|
|
@@ -76,7 +76,7 @@ Provides-Extra: tests
|
|
|
76
76
|
|
|
77
77
|
## What is PyEDB?
|
|
78
78
|
|
|
79
|
-
PyEDB is Python client library for processing complex and large layout designs in the
|
|
79
|
+
PyEDB is a Python client library for processing complex and large layout designs in the
|
|
80
80
|
Ansys Electronics Database (EDB) format, which stores information describing designs for
|
|
81
81
|
[Ansys Electronics Desktop](https://www.ansys.com/products/electronics) (AEDT).
|
|
82
82
|
|
|
@@ -102,7 +102,7 @@ HFSS 3D Layout, Icepak, Maxwell, Q3D, and SIwave.
|
|
|
102
102
|
|
|
103
103
|
EDB provides a proprietary database file format (AEDB) for efficient and fast layout design
|
|
104
104
|
handling and processing for building ready-to-solve projects. EDB addresses signal integrity
|
|
105
|
-
(SI), power integrity (PI-DC), and electro-thermal
|
|
105
|
+
(SI), power integrity (PI-DC), and electro-thermal workflows. You can import an AEDB file
|
|
106
106
|
into AEDT to modify the layout, assign materials, and define ports, simulations, and constraints.
|
|
107
107
|
You can then launch any of the Ansys electromagnetic simulators.
|
|
108
108
|
|
|
@@ -112,7 +112,7 @@ memory, it provides the fastest and most efficient way to handle a large and com
|
|
|
112
112
|
|
|
113
113
|
You can also parse an AEDB file from a command line in batch in an Ansys electromagnetic simulator
|
|
114
114
|
like HFSS or SIwave. Thus, you can deploy completely non-graphical flows, from layout
|
|
115
|
-
translation through
|
|
115
|
+
translation through simulation results.
|
|
116
116
|
|
|
117
117
|
Additionally, you can use PyAEDT to import an AEDB file into AEDT to view a project,
|
|
118
118
|
combine 3D designs, or perform simulation postprocessing. EDB also supports 3D component models.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
pyedb/__init__.py,sha256=
|
|
1
|
+
pyedb/__init__.py,sha256=QJGYOhTvr2BmugtK2s-wdaTRzp_3L2rc1RWwDKYu0yU,1525
|
|
2
2
|
pyedb/edb_logger.py,sha256=7KXPvAMCKzlzJ5zioiNO5A3zkqbpCHhWHB4aXKfgu5Y,14959
|
|
3
3
|
pyedb/exceptions.py,sha256=n94xluzUks6BA24vd_L6HkrvoP_H_l6__hQmqzdCyPo,111
|
|
4
4
|
pyedb/siwave.py,sha256=Mgg5ZGzOUOtNdlePHcnrgN3rletQ7jrqRi3WfxF58uU,17727
|
|
@@ -9,28 +9,28 @@ pyedb/component_libraries/ansys_components.py,sha256=O3ypt832IHY9zG2AD_yrRrbH2KH
|
|
|
9
9
|
pyedb/configuration/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10
10
|
pyedb/configuration/cfg_boundaries.py,sha256=5_v6HD0VgkFCJHgx5zTIn_nxPv3KpcCuGz9P4Kk4ywM,6246
|
|
11
11
|
pyedb/configuration/cfg_common.py,sha256=feXGIBSlTPAewSsmu0m1SgyfF9DuK4C7SNP_RNQGD2A,2549
|
|
12
|
-
pyedb/configuration/cfg_components.py,sha256=
|
|
12
|
+
pyedb/configuration/cfg_components.py,sha256=E-gPe2XYry5C3kjjjqOzRfAG2UsBJfwbApNSgW_pIJs,12400
|
|
13
13
|
pyedb/configuration/cfg_data.py,sha256=qCCR-Oo5_le61qWWmjrK4gIt_HH9jVqu4K0GbekAJkU,3773
|
|
14
14
|
pyedb/configuration/cfg_general.py,sha256=DJAKTW8Sqojfqzc3jO3MU1-J8MrmVi37jUIkTD_Tw6o,2068
|
|
15
|
-
pyedb/configuration/cfg_modeler.py,sha256=
|
|
15
|
+
pyedb/configuration/cfg_modeler.py,sha256=gXjc_thxa_sFiZ-b1zJCS8f6piCoM0d8In6MD26ZFZo,5930
|
|
16
16
|
pyedb/configuration/cfg_nets.py,sha256=18NezeNh0ZOwk2ehz3zWJF_xYR7IYCqGlpDfDt7Ilho,2349
|
|
17
17
|
pyedb/configuration/cfg_operations.py,sha256=CFLBdM2kQBsW6f7W0NHWbV56RDMHSnaNQl3BmqDWQWo,4707
|
|
18
18
|
pyedb/configuration/cfg_package_definition.py,sha256=f_RRT9R-3H5kHBlc4QSpjq9uQgYbaKQ78XXXrc_r3kg,5296
|
|
19
|
-
pyedb/configuration/cfg_padstacks.py,sha256=
|
|
20
|
-
pyedb/configuration/cfg_pin_groups.py,sha256=
|
|
21
|
-
pyedb/configuration/cfg_ports_sources.py,sha256=
|
|
19
|
+
pyedb/configuration/cfg_padstacks.py,sha256=zZSEc92TwSqa7KSZBmDb4Sybm4ivM5lrvb8uMxFho8k,18292
|
|
20
|
+
pyedb/configuration/cfg_pin_groups.py,sha256=zNKfVP-fd1qUxS2wNb0ZTLGonkUnBmiXb4Rss1Rr7sE,3714
|
|
21
|
+
pyedb/configuration/cfg_ports_sources.py,sha256=p6pauq8r14N4whuzxirSkKTS2lu4ViRMxB0KbIcBj5c,20944
|
|
22
22
|
pyedb/configuration/cfg_s_parameter_models.py,sha256=DgBprcEYR2r_3BY4f_CuwuhJw_QFEag3xaAlLTRfMuE,5356
|
|
23
23
|
pyedb/configuration/cfg_setup.py,sha256=QGKQHAEeo196TYtKMvIMb2-p8KC4U8fmHx0yn0SpgMo,10351
|
|
24
24
|
pyedb/configuration/cfg_spice_models.py,sha256=Q_5j2-V6cepSFcnijot8iypTqzanLp7HOz-agmnwKns,2570
|
|
25
|
-
pyedb/configuration/cfg_stackup.py,sha256=
|
|
26
|
-
pyedb/configuration/configuration.py,sha256=
|
|
25
|
+
pyedb/configuration/cfg_stackup.py,sha256=Ie2mdHfCgPn3F7BSdLlYZoZ3exhCDgPrhlYwxHZ6ABU,6484
|
|
26
|
+
pyedb/configuration/configuration.py,sha256=kQvUa9pkrdIw5gZE6RlaVdQOiioH0T0JkqUzb8fvdnU,15635
|
|
27
27
|
pyedb/dotnet/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
28
28
|
pyedb/dotnet/clr_module.py,sha256=EabqZgZgBZOhJD9_V8Ll8sEKgBFj9xe9zARNYIvYM_s,5304
|
|
29
|
-
pyedb/dotnet/edb.py,sha256=
|
|
29
|
+
pyedb/dotnet/edb.py,sha256=vl2Jbwq55eI3vdSq9Je-iklZBhnb7ccKC806s67kSrE,186428
|
|
30
30
|
pyedb/dotnet/application/Variables.py,sha256=awNhyiLASBYrNjWIyW8IJowgqt7FfFPKF9UElRWyjZg,77750
|
|
31
31
|
pyedb/dotnet/application/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
32
32
|
pyedb/dotnet/edb_core/__init__.py,sha256=nIRLJ8VZLcMAp12zmGsnZ5x2BEEl7q_Kj_KAOXxVjpQ,52
|
|
33
|
-
pyedb/dotnet/edb_core/components.py,sha256=
|
|
33
|
+
pyedb/dotnet/edb_core/components.py,sha256=qfMw7vRtw5n1KhYKrUIvZaoyJwV_yNyJBX6aYz_M6og,110487
|
|
34
34
|
pyedb/dotnet/edb_core/general.py,sha256=k2Bcr5VV-QUzEZlYorqYCX1ZchHBH7WqUvc8maMxId0,4716
|
|
35
35
|
pyedb/dotnet/edb_core/hfss.py,sha256=oQFC6PwRbjAwfR60RoklwpZ_2sDI4OheNNdwaqY23ok,68671
|
|
36
36
|
pyedb/dotnet/edb_core/layout_obj_instance.py,sha256=Pd8rfdO3b6HLFGwXBMw-tfE4LPIcW_9_X5KEdFaiito,1407
|
|
@@ -39,8 +39,8 @@ pyedb/dotnet/edb_core/materials.py,sha256=s105DUTFkQoQRWgtRMp02DKcU2YcSrfLbJoi8h
|
|
|
39
39
|
pyedb/dotnet/edb_core/modeler.py,sha256=rVJ-eh3eKOnCHENaBLZ8D7duH7tUtUqZJNLKGLFsZ_M,55519
|
|
40
40
|
pyedb/dotnet/edb_core/net_class.py,sha256=4U6Cc1Gn7ZJ_ub9uKmtrsoz5wD1XS42afci3Y3ewRp0,11354
|
|
41
41
|
pyedb/dotnet/edb_core/nets.py,sha256=Wc84urZG6nM3fZYqMj2HzM6CgNz_B4s4O3WmMGr-5H0,25199
|
|
42
|
-
pyedb/dotnet/edb_core/padstack.py,sha256=
|
|
43
|
-
pyedb/dotnet/edb_core/siwave.py,sha256=
|
|
42
|
+
pyedb/dotnet/edb_core/padstack.py,sha256=Qp5nSQNo1Ze0u8GUE3FjtbSYD73uQcNJhEOoUAHXLBo,72102
|
|
43
|
+
pyedb/dotnet/edb_core/siwave.py,sha256=QF4JyVNWoDeNQRRBBExlCxxVUt1-5DpKIlpuYkXd4k0,64286
|
|
44
44
|
pyedb/dotnet/edb_core/stackup.py,sha256=b56leXg7X7dEVPP2DUD9n8LZIakWcjIsjiqqkIWsyZU,120035
|
|
45
45
|
pyedb/dotnet/edb_core/cell/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
46
46
|
pyedb/dotnet/edb_core/cell/connectable.py,sha256=gc5jhWx4DX718T7koL6oZZzfS4EdQNTiFX76ZJ2c83E,2864
|
|
@@ -52,7 +52,7 @@ pyedb/dotnet/edb_core/cell/hierarchy/component.py,sha256=Iri2YVNntt02ojqtBAg-Nos
|
|
|
52
52
|
pyedb/dotnet/edb_core/cell/hierarchy/hierarchy_obj.py,sha256=OUNK6INKlbJkCbzy6jKZzrQs7fvCR1qiTjt7te0S7nQ,2160
|
|
53
53
|
pyedb/dotnet/edb_core/cell/hierarchy/model.py,sha256=LwXE4VUfptG5rJ9gmAmye0hECBv7bUGtby1ZzNFkeT0,3198
|
|
54
54
|
pyedb/dotnet/edb_core/cell/hierarchy/netlist_model.py,sha256=fF6tY-6s-lW9EuvJ5sw3RlIkjuoSjeZbrNk5wG-_hzM,1356
|
|
55
|
-
pyedb/dotnet/edb_core/cell/hierarchy/pin_pair_model.py,sha256=
|
|
55
|
+
pyedb/dotnet/edb_core/cell/hierarchy/pin_pair_model.py,sha256=nq_22nNC2EWo9rirAztOE2mysfP6uV9cdMnamy6zTu4,3792
|
|
56
56
|
pyedb/dotnet/edb_core/cell/hierarchy/s_parameter_model.py,sha256=o7Omw4R9uQGCBDj4dIU-R73Uf6v3p_zKLMAzJlaH9VA,1456
|
|
57
57
|
pyedb/dotnet/edb_core/cell/hierarchy/spice_model.py,sha256=SGiUcan2l0n8DGk3GtwCskkqZ3rdVHMSS_fGlAfwJSk,1443
|
|
58
58
|
pyedb/dotnet/edb_core/cell/primitive/__init__.py,sha256=8jByHkoaowAYQTCww-zRrTQmN061fLz_OHjTLSrzQQY,58
|
|
@@ -62,10 +62,10 @@ pyedb/dotnet/edb_core/cell/primitive/primitive.py,sha256=wZcHylKr_OVnXzVfNtce_Wu
|
|
|
62
62
|
pyedb/dotnet/edb_core/cell/terminal/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
63
63
|
pyedb/dotnet/edb_core/cell/terminal/bundle_terminal.py,sha256=qM0wEXkZ-DpoJ6vlVa560Ce8IgOdp4vyIJPedvoa3O0,1977
|
|
64
64
|
pyedb/dotnet/edb_core/cell/terminal/edge_terminal.py,sha256=lafPRrvsDPYKcysvrkO-5tEZXF3h4IcTXdeJgTjleuI,2158
|
|
65
|
-
pyedb/dotnet/edb_core/cell/terminal/padstack_instance_terminal.py,sha256=
|
|
65
|
+
pyedb/dotnet/edb_core/cell/terminal/padstack_instance_terminal.py,sha256=ViG6tYI7_WNW67Coi36XHSV6bEGCm35AHkRSAtbQvn0,4417
|
|
66
66
|
pyedb/dotnet/edb_core/cell/terminal/pingroup_terminal.py,sha256=Xupr55vseJsAR6y62Ekv1Kie_ILc6RVNzT3Sgxdi7X4,2753
|
|
67
|
-
pyedb/dotnet/edb_core/cell/terminal/point_terminal.py,sha256=
|
|
68
|
-
pyedb/dotnet/edb_core/cell/terminal/terminal.py,sha256=
|
|
67
|
+
pyedb/dotnet/edb_core/cell/terminal/point_terminal.py,sha256=zrGG4fxjuEqKaSLZz5w1uV0f-aigUJmN166p2j67RPI,3015
|
|
68
|
+
pyedb/dotnet/edb_core/cell/terminal/terminal.py,sha256=jQ1Zl7c7p6sQquNeRgtGg2L1flNCNPzJ9r2iuAX-bmY,18671
|
|
69
69
|
pyedb/dotnet/edb_core/definition/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
70
70
|
pyedb/dotnet/edb_core/definition/component_def.py,sha256=iXrGs1CpFHoLZ4cJZ7hebf592Hq5mG9Kp4Ip1TfuMjo,7404
|
|
71
71
|
pyedb/dotnet/edb_core/definition/component_model.py,sha256=HZzS3YX9hZBq5vv5Q9fS9MAN8S7Bxc3M6xcOETKvfT0,1838
|
|
@@ -80,7 +80,7 @@ pyedb/dotnet/edb_core/edb_data/control_file.py,sha256=qIXBJG0V_dvpvSqIycQcNOb8Ur
|
|
|
80
80
|
pyedb/dotnet/edb_core/edb_data/design_options.py,sha256=RO9ip-T5Bfxpsl97_QEk0qDZsza3tLzIX2t25XLutys,2057
|
|
81
81
|
pyedb/dotnet/edb_core/edb_data/edbvalue.py,sha256=Vj_11HXsQUNavizKp5FicORm6cjhXRh9uvxhv_D_RJc,1977
|
|
82
82
|
pyedb/dotnet/edb_core/edb_data/hfss_extent_info.py,sha256=wIKH4it1uYkEae4OimS3YE6QoSf8rAAIhxdTwtR9cqU,13040
|
|
83
|
-
pyedb/dotnet/edb_core/edb_data/layer_data.py,sha256=
|
|
83
|
+
pyedb/dotnet/edb_core/edb_data/layer_data.py,sha256=4Z_eaHSfGfwQBKETEmGSwMvwGzvirtwYw4G4TwonNiA,34314
|
|
84
84
|
pyedb/dotnet/edb_core/edb_data/nets_data.py,sha256=fXJ1U18ZLm9xI7MJD3UcTsI8XNZSq5kf20KF2IMib4o,10137
|
|
85
85
|
pyedb/dotnet/edb_core/edb_data/padstacks_data.py,sha256=1j_GG552iwvzvx6TKI3Yx6C3RXOWiSNehdlbD8AuzaI,78474
|
|
86
86
|
pyedb/dotnet/edb_core/edb_data/ports.py,sha256=wr2RQi8VExuNIVmnp7c4VpTIhODgthmJmHr01zO4ueo,8873
|
|
@@ -117,7 +117,7 @@ pyedb/generic/design_types.py,sha256=qHyIaz-Vd3ra4CP9xER76-nGRonYmSAiI3Dr8YPUeH8
|
|
|
117
117
|
pyedb/generic/filesystem.py,sha256=EqsLGwdhCgY3asomjoWZBBYWQiGhVOBlSzQlM6FCZhw,3674
|
|
118
118
|
pyedb/generic/general_methods.py,sha256=HfDQEiQkNng4apFUbStsEfvKDbPkZ0Oz9Wjlqqz5LSI,42798
|
|
119
119
|
pyedb/generic/plot.py,sha256=0x2-v_xNSoy07rILKGQStQMTUIYrvJEvFO1n9KuSfAc,4717
|
|
120
|
-
pyedb/generic/process.py,sha256=
|
|
120
|
+
pyedb/generic/process.py,sha256=i0poMbEnFFAsnNOPWN-myMnUaG7hMClKi9kGPMFyvCM,11148
|
|
121
121
|
pyedb/generic/settings.py,sha256=QTX5OVZ8sVPIy_QaSxRODUWvoXkYkVpzh3l6pQPseKQ,9220
|
|
122
122
|
pyedb/ipc2581/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
123
123
|
pyedb/ipc2581/history_record.py,sha256=s1GjcIgnZHlNCBOeEERBDX7xDuqhXmh2Ctt3ccFDWso,2739
|
|
@@ -188,7 +188,7 @@ pyedb/misc/siw_feature_config/xtalk_scan/scan_config.py,sha256=YmYI6WTQulL5Uf8Wx
|
|
|
188
188
|
pyedb/misc/siw_feature_config/xtalk_scan/td_xtalk_config.py,sha256=KHa-UqcXuabiVfT2CV-UvWl5Q2qGYHF2Ye9azcAlnXc,3966
|
|
189
189
|
pyedb/modeler/geometry_operators.py,sha256=g_Sy7a6R23sP6RtboJn1rl8uTuo8oeLmMF21rNkzwjk,74198
|
|
190
190
|
pyedb/siwave_core/icepak.py,sha256=WnZ-t8mik7LDY06V8hZFV-TxRZJQWK7bu_8Ichx-oBs,5206
|
|
191
|
-
pyedb-0.
|
|
192
|
-
pyedb-0.
|
|
193
|
-
pyedb-0.
|
|
194
|
-
pyedb-0.
|
|
191
|
+
pyedb-0.35.0.dist-info/LICENSE,sha256=qQWivZ12ETN5l3QxvTARY-QI5eoRRlyHdwLlAj0Bg5I,1089
|
|
192
|
+
pyedb-0.35.0.dist-info/WHEEL,sha256=CpUCUxeHQbRN5UGRQHYRJorO5Af-Qy_fHMctcQ8DSGI,82
|
|
193
|
+
pyedb-0.35.0.dist-info/METADATA,sha256=FuDrrBF8NzY_z8cYDUfz0hI2iVKmUn2AwxXR4NBbdRQ,8513
|
|
194
|
+
pyedb-0.35.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|