pyedb 0.35.0__py3-none-any.whl → 0.37.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 +37 -1
- pyedb/dotnet/edb.py +11 -4
- pyedb/dotnet/edb_core/cell/layout.py +22 -6
- pyedb/dotnet/edb_core/cell/primitive/primitive.py +64 -0
- pyedb/dotnet/edb_core/edb_data/control_file.py +60 -13
- pyedb/dotnet/edb_core/edb_data/nets_data.py +1 -1
- pyedb/dotnet/edb_core/edb_data/padstacks_data.py +70 -63
- pyedb/dotnet/edb_core/geometry/polygon_data.py +5 -0
- pyedb/dotnet/edb_core/modeler.py +1 -2
- pyedb/dotnet/edb_core/padstack.py +25 -6
- {pyedb-0.35.0.dist-info → pyedb-0.37.0.dist-info}/METADATA +1 -1
- {pyedb-0.35.0.dist-info → pyedb-0.37.0.dist-info}/RECORD +15 -15
- {pyedb-0.35.0.dist-info → pyedb-0.37.0.dist-info}/LICENSE +0 -0
- {pyedb-0.35.0.dist-info → pyedb-0.37.0.dist-info}/WHEEL +0 -0
pyedb/__init__.py
CHANGED
|
@@ -33,6 +33,9 @@ class CfgTerminalInfo(CfgBase):
|
|
|
33
33
|
self._pedb = pedb
|
|
34
34
|
self.type = list(kwargs.keys())[0]
|
|
35
35
|
self.value = kwargs[self.type]
|
|
36
|
+
self.contact_radius = kwargs.get("contact_radius", None)
|
|
37
|
+
self.num_of_contact = kwargs.get("num_of_contact", 1)
|
|
38
|
+
self.inline = kwargs.get("inline", False)
|
|
36
39
|
|
|
37
40
|
def export_properties(self):
|
|
38
41
|
return {self.type: self.value}
|
|
@@ -244,6 +247,7 @@ class CfgCircuitElement(CfgBase):
|
|
|
244
247
|
point = [self.positive_terminal_info.point_x, self.positive_terminal_info.point_y]
|
|
245
248
|
net_name = self.positive_terminal_info.net
|
|
246
249
|
pos_coor_terminal[self.name] = self._pedb.get_point_terminal(self.name, net_name, point, layer)
|
|
250
|
+
|
|
247
251
|
elif pos_type == "pin_group":
|
|
248
252
|
if self.distributed:
|
|
249
253
|
pins = self._get_pins(pos_type, pos_value)
|
|
@@ -276,7 +280,7 @@ class CfgCircuitElement(CfgBase):
|
|
|
276
280
|
|
|
277
281
|
if neg_type == "coordinates":
|
|
278
282
|
layer = self.negative_terminal_info.layer
|
|
279
|
-
point = [self.negative_terminal_info.point_x, self.
|
|
283
|
+
point = [self.negative_terminal_info.point_x, self.negative_terminal_info.point_y]
|
|
280
284
|
net_name = self.negative_terminal_info.net
|
|
281
285
|
self.neg_terminal = self._pedb.get_point_terminal(self.name + "_ref", net_name, point, layer)
|
|
282
286
|
elif neg_type == "nearest_pin":
|
|
@@ -378,6 +382,7 @@ class CfgSource(CfgCircuitElement):
|
|
|
378
382
|
super().__init__(pedb, **kwargs)
|
|
379
383
|
|
|
380
384
|
self.magnitude = kwargs.get("magnitude", 0.001)
|
|
385
|
+
self.equipotential = kwargs.get("equipotential", False)
|
|
381
386
|
|
|
382
387
|
def set_parameters_to_edb(self):
|
|
383
388
|
"""Create sources."""
|
|
@@ -397,6 +402,37 @@ class CfgSource(CfgCircuitElement):
|
|
|
397
402
|
elem.name = f"{self.name}_{elem.name}"
|
|
398
403
|
elem.magnitude = self.magnitude / self._elem_num
|
|
399
404
|
circuit_elements.append(elem)
|
|
405
|
+
for terminal in circuit_elements:
|
|
406
|
+
if self.equipotential:
|
|
407
|
+
terms = [terminal, terminal.ref_terminal] if terminal.ref_terminal else [terminal]
|
|
408
|
+
for t in terms:
|
|
409
|
+
if not t.is_reference_terminal:
|
|
410
|
+
radius = self.positive_terminal_info.contact_radius
|
|
411
|
+
num_of_contact = self.positive_terminal_info.num_of_contact
|
|
412
|
+
inline = self.positive_terminal_info.inline
|
|
413
|
+
else:
|
|
414
|
+
radius = self.negative_terminal_info.contact_radius
|
|
415
|
+
num_of_contact = self.negative_terminal_info.num_of_contact
|
|
416
|
+
inline = self.negative_terminal_info.inline
|
|
417
|
+
|
|
418
|
+
pads = []
|
|
419
|
+
if t.terminal_type == "PadstackInstanceTerminal":
|
|
420
|
+
pads.append(t.reference_object)
|
|
421
|
+
elif t.terminal_type == "PinGroupTerminal":
|
|
422
|
+
name = t._edb_object.GetPinGroup().GetName()
|
|
423
|
+
pg = self._pedb.siwave.pin_groups[name]
|
|
424
|
+
pads.extend([i for _, i in pg.pins.items()])
|
|
425
|
+
elif t.terminal_type == "PointTerminal" and radius:
|
|
426
|
+
temp = [i for i in self._pedb.layout.terminals if i.name == t.name][0]
|
|
427
|
+
if radius is not None:
|
|
428
|
+
prim = self._pedb.modeler.create_circle(
|
|
429
|
+
temp.layer.name, temp.location[0], temp.location[1], radius, temp.net_name
|
|
430
|
+
)
|
|
431
|
+
prim.dcir_equipotential_region = True
|
|
432
|
+
|
|
433
|
+
for i in pads:
|
|
434
|
+
i._set_equipotential(contact_radius=radius, inline=inline, num_of_contact=num_of_contact)
|
|
435
|
+
|
|
400
436
|
return circuit_elements
|
|
401
437
|
|
|
402
438
|
def export_properties(self):
|
pyedb/dotnet/edb.py
CHANGED
|
@@ -603,7 +603,7 @@ class Edb(Database):
|
|
|
603
603
|
def import_layout_pcb(
|
|
604
604
|
self,
|
|
605
605
|
input_file,
|
|
606
|
-
working_dir,
|
|
606
|
+
working_dir="",
|
|
607
607
|
anstranslator_full_path="",
|
|
608
608
|
use_ppe=False,
|
|
609
609
|
control_file=None,
|
|
@@ -616,7 +616,7 @@ class Edb(Database):
|
|
|
616
616
|
----------
|
|
617
617
|
input_file : str
|
|
618
618
|
Full path to the board file.
|
|
619
|
-
working_dir : str
|
|
619
|
+
working_dir : str, optional
|
|
620
620
|
Directory in which to create the ``aedb`` folder. The name given to the AEDB file
|
|
621
621
|
is the same as the name of the board file.
|
|
622
622
|
anstranslator_full_path : str, optional
|
|
@@ -1510,6 +1510,13 @@ class Edb(Database):
|
|
|
1510
1510
|
else:
|
|
1511
1511
|
return False
|
|
1512
1512
|
else:
|
|
1513
|
+
if anstranslator_full_path and os.path.exists(anstranslator_full_path):
|
|
1514
|
+
path = anstranslator_full_path
|
|
1515
|
+
else:
|
|
1516
|
+
path = os.path.join(self.base_path, "anstranslator")
|
|
1517
|
+
if is_windows:
|
|
1518
|
+
path += ".exe"
|
|
1519
|
+
|
|
1513
1520
|
temp_map_file = os.path.splitext(inputGDS)[0] + ".map"
|
|
1514
1521
|
temp_layermap_file = os.path.splitext(inputGDS)[0] + ".layermap"
|
|
1515
1522
|
|
|
@@ -1529,10 +1536,10 @@ class Edb(Database):
|
|
|
1529
1536
|
else:
|
|
1530
1537
|
self.logger.error("Unable to define control file.")
|
|
1531
1538
|
|
|
1532
|
-
command = [
|
|
1539
|
+
command = [path, inputGDS, f'-g="{map_file}"', f'-c="{control_file}"']
|
|
1533
1540
|
else:
|
|
1534
1541
|
command = [
|
|
1535
|
-
|
|
1542
|
+
path,
|
|
1536
1543
|
inputGDS,
|
|
1537
1544
|
f'-o="{control_file_temp}"' f'-t="{tech_file}"',
|
|
1538
1545
|
f'-g="{map_file}"',
|
|
@@ -220,7 +220,7 @@ class Layout(ObjBase):
|
|
|
220
220
|
-------
|
|
221
221
|
"""
|
|
222
222
|
|
|
223
|
-
return [EDBNetsData(net, self._pedb) for net in self._edb_object.Nets]
|
|
223
|
+
return [EDBNetsData(net, self._pedb) for net in self._edb_object.Nets if net]
|
|
224
224
|
|
|
225
225
|
@property
|
|
226
226
|
def primitives(self):
|
|
@@ -230,7 +230,7 @@ class Layout(ObjBase):
|
|
|
230
230
|
-------
|
|
231
231
|
list of :class:`dotnet.edb_core.dotnet.primitive.PrimitiveDotNet` cast objects.
|
|
232
232
|
"""
|
|
233
|
-
return [primitive_cast(self._pedb, p) for p in self._edb_object.Primitives]
|
|
233
|
+
return [primitive_cast(self._pedb, p) for p in self._edb_object.Primitives if p]
|
|
234
234
|
|
|
235
235
|
@property
|
|
236
236
|
def bondwires(self):
|
|
@@ -331,16 +331,32 @@ class Layout(ObjBase):
|
|
|
331
331
|
obj = self._pedb._edb.Cell.Hierarchy.Component.FindByName(self._edb_object, value)
|
|
332
332
|
return EDBComponent(self._pedb, obj) if obj is not None else None
|
|
333
333
|
|
|
334
|
-
def find_primitive(
|
|
334
|
+
def find_primitive(
|
|
335
|
+
self, layer_name: Union[str, list] = None, name: Union[str, list] = None, net_name: Union[str, list] = None
|
|
336
|
+
) -> list:
|
|
335
337
|
"""Find a primitive objects by layer name.
|
|
336
338
|
|
|
337
339
|
Parameters
|
|
338
340
|
----------
|
|
339
|
-
layer_name : str, list
|
|
341
|
+
layer_name : str, list, optional
|
|
340
342
|
Name of the layer.
|
|
343
|
+
name : str, list, optional
|
|
344
|
+
Name of the primitive
|
|
345
|
+
net_name : str, list, optional
|
|
346
|
+
Name of the primitive
|
|
341
347
|
Returns
|
|
342
348
|
-------
|
|
343
349
|
list
|
|
344
350
|
"""
|
|
345
|
-
|
|
346
|
-
|
|
351
|
+
if layer_name is not None:
|
|
352
|
+
layer_name = layer_name if isinstance(layer_name, list) else [layer_name]
|
|
353
|
+
if name is not None:
|
|
354
|
+
name = name if isinstance(name, list) else [name]
|
|
355
|
+
if net_name is not None:
|
|
356
|
+
net_name = net_name if isinstance(net_name, list) else [net_name]
|
|
357
|
+
|
|
358
|
+
prims = self.primitives
|
|
359
|
+
prims = [i for i in prims if i.aedt_name in name] if name is not None else prims
|
|
360
|
+
prims = [i for i in prims if i.layer_name in layer_name] if layer_name is not None else prims
|
|
361
|
+
prims = [i for i in prims if i.net_name in net_name] if net_name is not None else prims
|
|
362
|
+
return prims
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
20
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
21
|
# SOFTWARE.
|
|
22
|
+
import re
|
|
22
23
|
|
|
23
24
|
from pyedb.dotnet.edb_core.cell.connectable import Connectable
|
|
24
25
|
from pyedb.dotnet.edb_core.general import convert_py_list_to_net_list
|
|
@@ -787,3 +788,66 @@ class Primitive(Connectable):
|
|
|
787
788
|
self.polygon_data = polygon_data
|
|
788
789
|
return True
|
|
789
790
|
return False
|
|
791
|
+
|
|
792
|
+
@property
|
|
793
|
+
def _em_properties(self):
|
|
794
|
+
"""Get EM properties."""
|
|
795
|
+
default = (
|
|
796
|
+
r"$begin 'EM properties'\n"
|
|
797
|
+
r"\tType('Mesh')\n"
|
|
798
|
+
r"\tDataId='EM properties1'\n"
|
|
799
|
+
r"\t$begin 'Properties'\n"
|
|
800
|
+
r"\t\tGeneral=''\n"
|
|
801
|
+
r"\t\tModeled='true'\n"
|
|
802
|
+
r"\t\tUnion='true'\n"
|
|
803
|
+
r"\t\t'Use Precedence'='false'\n"
|
|
804
|
+
r"\t\t'Precedence Value'='1'\n"
|
|
805
|
+
r"\t\tPlanarEM=''\n"
|
|
806
|
+
r"\t\tRefined='true'\n"
|
|
807
|
+
r"\t\tRefineFactor='1'\n"
|
|
808
|
+
r"\t\tNoEdgeMesh='false'\n"
|
|
809
|
+
r"\t\tHFSS=''\n"
|
|
810
|
+
r"\t\t'Solve Inside'='false'\n"
|
|
811
|
+
r"\t\tSIwave=''\n"
|
|
812
|
+
r"\t\t'DCIR Equipotential Region'='false'\n"
|
|
813
|
+
r"\t$end 'Properties'\n"
|
|
814
|
+
r"$end 'EM properties'\n"
|
|
815
|
+
)
|
|
816
|
+
|
|
817
|
+
pid = self._pedb.edb_api.ProductId.Designer
|
|
818
|
+
_, p = self._edb_object.GetProductProperty(pid, 18, "")
|
|
819
|
+
if p:
|
|
820
|
+
return p
|
|
821
|
+
else:
|
|
822
|
+
return default
|
|
823
|
+
|
|
824
|
+
@_em_properties.setter
|
|
825
|
+
def _em_properties(self, em_prop):
|
|
826
|
+
"""Set EM properties"""
|
|
827
|
+
pid = self._pedb.edb_api.ProductId.Designer
|
|
828
|
+
self._edb_object.SetProductProperty(pid, 18, em_prop)
|
|
829
|
+
|
|
830
|
+
@property
|
|
831
|
+
def dcir_equipotential_region(self):
|
|
832
|
+
"""Check whether dcir equipotential region is enabled.
|
|
833
|
+
|
|
834
|
+
Returns
|
|
835
|
+
-------
|
|
836
|
+
bool
|
|
837
|
+
"""
|
|
838
|
+
pattern = r"'DCIR Equipotential Region'='([^']+)'"
|
|
839
|
+
em_pp = self._em_properties
|
|
840
|
+
result = re.search(pattern, em_pp).group(1)
|
|
841
|
+
if result == "true":
|
|
842
|
+
return True
|
|
843
|
+
else:
|
|
844
|
+
return False
|
|
845
|
+
|
|
846
|
+
@dcir_equipotential_region.setter
|
|
847
|
+
def dcir_equipotential_region(self, value):
|
|
848
|
+
"""Set dcir equipotential region."""
|
|
849
|
+
pp = r"'DCIR Equipotential Region'='true'" if value else r"'DCIR Equipotential Region'='false'"
|
|
850
|
+
em_pp = self._em_properties
|
|
851
|
+
pattern = r"'DCIR Equipotential Region'='([^']+)'"
|
|
852
|
+
new_em_pp = re.sub(pattern, pp, em_pp)
|
|
853
|
+
self._em_properties = new_em_pp
|
|
@@ -25,6 +25,7 @@ import os
|
|
|
25
25
|
import re
|
|
26
26
|
import subprocess
|
|
27
27
|
import sys
|
|
28
|
+
import xml
|
|
28
29
|
|
|
29
30
|
from pyedb.edb_logger import pyedb_logger
|
|
30
31
|
from pyedb.generic.general_methods import ET, env_path, env_value, is_linux
|
|
@@ -964,14 +965,14 @@ class ControlFileMeshOp:
|
|
|
964
965
|
class ControlFileSetup:
|
|
965
966
|
"""Setup Class."""
|
|
966
967
|
|
|
967
|
-
def __init__(self, name):
|
|
968
|
+
def __init__(self, name, adapt_freq="1GHz", maxdelta=0.02, maxpasses=10):
|
|
968
969
|
self.name = name
|
|
969
970
|
self.enabled = True
|
|
970
971
|
self.save_fields = False
|
|
971
972
|
self.save_rad_fields = False
|
|
972
|
-
self.frequency =
|
|
973
|
-
self.maxpasses =
|
|
974
|
-
self.max_delta =
|
|
973
|
+
self.frequency = adapt_freq
|
|
974
|
+
self.maxpasses = maxpasses
|
|
975
|
+
self.max_delta = maxdelta
|
|
975
976
|
self.union_polygons = True
|
|
976
977
|
self.small_voids_area = 0
|
|
977
978
|
self.mode_type = "IC"
|
|
@@ -1082,22 +1083,25 @@ class ControlFileSetups:
|
|
|
1082
1083
|
def __init__(self):
|
|
1083
1084
|
self.setups = []
|
|
1084
1085
|
|
|
1085
|
-
def add_setup(self, name,
|
|
1086
|
+
def add_setup(self, name, adapt_freq, maxdelta, maxpasses):
|
|
1086
1087
|
"""Add a new setup
|
|
1087
1088
|
|
|
1088
1089
|
Parameters
|
|
1089
1090
|
----------
|
|
1090
1091
|
name : str
|
|
1091
|
-
Setup
|
|
1092
|
-
|
|
1092
|
+
Setup Name.
|
|
1093
|
+
adapt_freq : str, optional
|
|
1093
1094
|
Setup Frequency.
|
|
1095
|
+
maxdelta : float, optional
|
|
1096
|
+
Maximum Delta.
|
|
1097
|
+
maxpasses : int, optional
|
|
1098
|
+
Maximum Number of Passes.
|
|
1094
1099
|
|
|
1095
1100
|
Returns
|
|
1096
1101
|
-------
|
|
1097
1102
|
:class:`pyedb.dotnet.edb_core.edb_data.control_file.ControlFileSetup`
|
|
1098
1103
|
"""
|
|
1099
|
-
setup = ControlFileSetup(name)
|
|
1100
|
-
setup.frequency = frequency
|
|
1104
|
+
setup = ControlFileSetup(name, adapt_freq, maxdelta, maxpasses)
|
|
1101
1105
|
self.setups.append(setup)
|
|
1102
1106
|
return setup
|
|
1103
1107
|
|
|
@@ -1112,17 +1116,17 @@ class ControlFile:
|
|
|
1112
1116
|
|
|
1113
1117
|
def __init__(self, xml_input=None, tecnhology=None, layer_map=None):
|
|
1114
1118
|
self.stackup = ControlFileStackup()
|
|
1119
|
+
self.boundaries = ControlFileBoundaries()
|
|
1120
|
+
self.setups = ControlFileSetups()
|
|
1115
1121
|
if xml_input:
|
|
1116
1122
|
self.parse_xml(xml_input)
|
|
1117
1123
|
if tecnhology:
|
|
1118
1124
|
self.parse_technology(tecnhology)
|
|
1119
1125
|
if layer_map:
|
|
1120
1126
|
self.parse_layer_map(layer_map)
|
|
1121
|
-
self.boundaries = ControlFileBoundaries()
|
|
1122
1127
|
self.remove_holes = False
|
|
1123
1128
|
self.remove_holes_area_minimum = 30
|
|
1124
1129
|
self.remove_holes_units = "um"
|
|
1125
|
-
self.setups = ControlFileSetups()
|
|
1126
1130
|
self.components = ControlFileComponents()
|
|
1127
1131
|
self.import_options = ControlFileImportOptions()
|
|
1128
1132
|
pass
|
|
@@ -1262,6 +1266,50 @@ class ControlFile:
|
|
|
1262
1266
|
via.remove_unconnected = (
|
|
1263
1267
|
True if i.attrib["RemoveUnconnected"] == "true" else False
|
|
1264
1268
|
)
|
|
1269
|
+
if el.tag == "Boundaries":
|
|
1270
|
+
for port_el in el:
|
|
1271
|
+
if port_el.tag == "CircuitPortPt":
|
|
1272
|
+
self.boundaries.add_port(
|
|
1273
|
+
name=port_el.attrib["Name"],
|
|
1274
|
+
x1=port_el.attrib["x1"],
|
|
1275
|
+
y1=port_el.attrib["y1"],
|
|
1276
|
+
layer1=port_el.attrib["Layer1"],
|
|
1277
|
+
x2=port_el.attrib["x2"],
|
|
1278
|
+
y2=port_el.attrib["y2"],
|
|
1279
|
+
layer2=port_el.attrib["Layer2"],
|
|
1280
|
+
z0=port_el.attrib["Z0"],
|
|
1281
|
+
)
|
|
1282
|
+
setups = root.find("SimulationSetups")
|
|
1283
|
+
if setups:
|
|
1284
|
+
hfsssetup = setups.find("HFSSSetup")
|
|
1285
|
+
if hfsssetup:
|
|
1286
|
+
if "Name" in hfsssetup.attrib:
|
|
1287
|
+
name = hfsssetup.attrib["Name"]
|
|
1288
|
+
hfsssimset = hfsssetup.find("HFSSSimulationSettings")
|
|
1289
|
+
if hfsssimset:
|
|
1290
|
+
hfssadaptset = hfsssimset.find("HFSSAdaptiveSettings")
|
|
1291
|
+
if hfssadaptset:
|
|
1292
|
+
adaptset = hfssadaptset.find("AdaptiveSettings")
|
|
1293
|
+
if adaptset:
|
|
1294
|
+
singlefreqdatalist = adaptset.find("SingleFrequencyDataList")
|
|
1295
|
+
if singlefreqdatalist:
|
|
1296
|
+
adaptfreqdata = singlefreqdatalist.find("AdaptiveFrequencyData")
|
|
1297
|
+
if adaptfreqdata:
|
|
1298
|
+
if isinstance(
|
|
1299
|
+
adaptfreqdata.find("AdaptiveFrequency"), xml.etree.ElementTree.Element
|
|
1300
|
+
):
|
|
1301
|
+
adapt_freq = adaptfreqdata.find("AdaptiveFrequency").text
|
|
1302
|
+
else:
|
|
1303
|
+
adapt_freq = "1GHz"
|
|
1304
|
+
if isinstance(adaptfreqdata.find("MaxDelta"), xml.etree.ElementTree.Element):
|
|
1305
|
+
maxdelta = adaptfreqdata.find("MaxDelta").text
|
|
1306
|
+
else:
|
|
1307
|
+
maxdelta = 0.02
|
|
1308
|
+
if isinstance(adaptfreqdata.find("MaxPasses"), xml.etree.ElementTree.Element):
|
|
1309
|
+
maxpasses = adaptfreqdata.find("MaxPasses").text
|
|
1310
|
+
else:
|
|
1311
|
+
maxpasses = 10
|
|
1312
|
+
self.setups.add_setup(name, adapt_freq, maxdelta, maxpasses)
|
|
1265
1313
|
return True
|
|
1266
1314
|
|
|
1267
1315
|
def write_xml(self, xml_output):
|
|
@@ -1278,8 +1326,7 @@ class ControlFile:
|
|
|
1278
1326
|
"""
|
|
1279
1327
|
control = ET.Element("{http://www.ansys.com/control}Control", attrib={"schemaVersion": "1.0"})
|
|
1280
1328
|
self.stackup._write_xml(control)
|
|
1281
|
-
|
|
1282
|
-
self.boundaries._write_xml(control)
|
|
1329
|
+
self.boundaries._write_xml(control)
|
|
1283
1330
|
if self.remove_holes:
|
|
1284
1331
|
hole = ET.SubElement(control, "RemoveHoles")
|
|
1285
1332
|
hole.set("HoleAreaMinimum", str(self.remove_holes_area_minimum))
|
|
@@ -59,7 +59,7 @@ class EDBNetsData(NetDotNet):
|
|
|
59
59
|
"""
|
|
60
60
|
from pyedb.dotnet.edb_core.cell.layout import primitive_cast
|
|
61
61
|
|
|
62
|
-
return [primitive_cast(self._app, i) for i in self.net_object.Primitives]
|
|
62
|
+
return [primitive_cast(self._app, i) for i in self.net_object.Primitives if i]
|
|
63
63
|
# return [self._app.layout.find_object_by_id(i.GetId()) for i in self.net_object.Primitives]
|
|
64
64
|
|
|
65
65
|
@property
|
|
@@ -22,9 +22,10 @@
|
|
|
22
22
|
|
|
23
23
|
from collections import OrderedDict
|
|
24
24
|
import math
|
|
25
|
-
import re
|
|
26
25
|
import warnings
|
|
27
26
|
|
|
27
|
+
import numpy as np
|
|
28
|
+
|
|
28
29
|
from pyedb.dotnet.clr_module import String
|
|
29
30
|
from pyedb.dotnet.edb_core.cell.primitive.primitive import Primitive
|
|
30
31
|
from pyedb.dotnet.edb_core.dotnet.database import PolygonDataDotNet
|
|
@@ -1248,68 +1249,77 @@ class EDBPadstackInstance(Primitive):
|
|
|
1248
1249
|
|
|
1249
1250
|
return self._pedb.create_port(terminal, ref_terminal, is_circuit_port)
|
|
1250
1251
|
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
default = (
|
|
1255
|
-
r"$begin 'EM properties'\n"
|
|
1256
|
-
r"\tType('Mesh')\n"
|
|
1257
|
-
r"\tDataId='EM properties1'\n"
|
|
1258
|
-
r"\t$begin 'Properties'\n"
|
|
1259
|
-
r"\t\tGeneral=''\n"
|
|
1260
|
-
r"\t\tModeled='true'\n"
|
|
1261
|
-
r"\t\tUnion='true'\n"
|
|
1262
|
-
r"\t\t'Use Precedence'='false'\n"
|
|
1263
|
-
r"\t\t'Precedence Value'='1'\n"
|
|
1264
|
-
r"\t\tPlanarEM=''\n"
|
|
1265
|
-
r"\t\tRefined='true'\n"
|
|
1266
|
-
r"\t\tRefineFactor='1'\n"
|
|
1267
|
-
r"\t\tNoEdgeMesh='false'\n"
|
|
1268
|
-
r"\t\tHFSS=''\n"
|
|
1269
|
-
r"\t\t'Solve Inside'='false'\n"
|
|
1270
|
-
r"\t\tSIwave=''\n"
|
|
1271
|
-
r"\t\t'DCIR Equipotential Region'='false'\n"
|
|
1272
|
-
r"\t$end 'Properties'\n"
|
|
1273
|
-
r"$end 'EM properties'\n"
|
|
1274
|
-
)
|
|
1275
|
-
|
|
1276
|
-
pid = self._pedb.edb_api.ProductId.Designer
|
|
1277
|
-
_, p = self._edb_padstackinstance.GetProductProperty(pid, 18, "")
|
|
1278
|
-
if p:
|
|
1279
|
-
return p
|
|
1280
|
-
else:
|
|
1281
|
-
return default
|
|
1252
|
+
def _set_equipotential(self, contact_radius=None, inline=False, num_of_contact=1):
|
|
1253
|
+
"""Workaround solution. Remove when EDBAPI bug is fixed for dcir_equipotential_region."""
|
|
1254
|
+
pad = self.definition.pad_by_layer[self.start_layer]
|
|
1282
1255
|
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
"""Set EM properties"""
|
|
1286
|
-
pid = self._pedb.edb_api.ProductId.Designer
|
|
1287
|
-
self._edb_padstackinstance.SetProductProperty(pid, 18, em_prop)
|
|
1256
|
+
pos_x, pos_y = self.position
|
|
1257
|
+
comp_rotation = self._pedb.edb_value(self.component.rotation).ToDouble() % 3.141592653589793
|
|
1288
1258
|
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1259
|
+
if contact_radius is not None:
|
|
1260
|
+
if num_of_contact == 1:
|
|
1261
|
+
prim = self._pedb.modeler.create_circle(pad.layer_name, pos_x, pos_y, contact_radius, self.net_name)
|
|
1262
|
+
prim.dcir_equipotential_region = True
|
|
1263
|
+
else:
|
|
1264
|
+
if pad.shape.lower() in ["rectangle", "oval"]:
|
|
1265
|
+
width, height = pad.parameters_values[0:2]
|
|
1266
|
+
radius = self._pedb.edb_value(contact_radius).ToDouble()
|
|
1267
|
+
else:
|
|
1268
|
+
return
|
|
1269
|
+
|
|
1270
|
+
if inline is False:
|
|
1271
|
+
x_offset = width / 2 - radius if comp_rotation == 0 else height / 2 - radius
|
|
1272
|
+
y_offset = height / 2 - radius if comp_rotation == 0 else width / 2 - radius
|
|
1273
|
+
positions = []
|
|
1274
|
+
for x, y in [[1, 1], [-1, 1], [1, -1], [-1, -1]]:
|
|
1275
|
+
positions.append([x_offset * x, y_offset * y])
|
|
1276
|
+
else:
|
|
1277
|
+
if width > height:
|
|
1278
|
+
offset = (width - radius * 2) / (num_of_contact - 1)
|
|
1279
|
+
else:
|
|
1280
|
+
offset = (height - radius * 2) / (num_of_contact - 1)
|
|
1281
|
+
|
|
1282
|
+
start_pos = (num_of_contact - 1) / 2
|
|
1283
|
+
offset = [offset * i for i in np.arange(start_pos * -1, start_pos + 1)]
|
|
1284
|
+
|
|
1285
|
+
if (width > height and comp_rotation == 0) or (width < height and comp_rotation != 0):
|
|
1286
|
+
positions = list(zip(offset, [0] * num_of_contact))
|
|
1287
|
+
else:
|
|
1288
|
+
positions = list(zip([0] * num_of_contact, offset))
|
|
1289
|
+
|
|
1290
|
+
for x, y in positions:
|
|
1291
|
+
prim = self._pedb.modeler.create_circle(pad.layer_name, pos_x + x, pos_y + y, radius, self.net_name)
|
|
1292
|
+
prim.dcir_equipotential_region = True
|
|
1293
|
+
return
|
|
1292
1294
|
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1295
|
+
elif pad.shape.lower() == "circle":
|
|
1296
|
+
ra = self._pedb.edb_value(pad.parameters_values[0] / 2)
|
|
1297
|
+
pos = self.position
|
|
1298
|
+
prim = self._pedb.modeler.create_circle(pad.layer_name, pos[0], pos[1], ra, self.net_name)
|
|
1299
|
+
elif pad.shape.lower() == "rectangle":
|
|
1300
|
+
width, height = pad.parameters_values
|
|
1301
|
+
prim = self._pedb.modeler.create_rectangle(
|
|
1302
|
+
pad.layer_name,
|
|
1303
|
+
self.net_name,
|
|
1304
|
+
width=width,
|
|
1305
|
+
height=height,
|
|
1306
|
+
representation_type="CenterWidthHeight",
|
|
1307
|
+
center_point=self.position,
|
|
1308
|
+
rotation=self.component.rotation,
|
|
1309
|
+
)
|
|
1310
|
+
elif pad.shape.lower() == "oval":
|
|
1311
|
+
width, height, _ = pad.parameters_values
|
|
1312
|
+
prim = self._pedb.modeler.create_circle(
|
|
1313
|
+
pad.layer_name, self.position[0], self.position[1], height / 2, self.net_name
|
|
1314
|
+
)
|
|
1315
|
+
elif pad.polygon_data:
|
|
1316
|
+
prim = self._pedb.modeler.create_polygon(
|
|
1317
|
+
pad.polygon_data._edb_object, self.start_layer, net_name=self.net_name
|
|
1318
|
+
)
|
|
1319
|
+
prim.move(self.position)
|
|
1302
1320
|
else:
|
|
1303
|
-
return
|
|
1304
|
-
|
|
1305
|
-
@dcir_equipotential_region.setter
|
|
1306
|
-
def dcir_equipotential_region(self, value):
|
|
1307
|
-
"""Set dcir equipotential region."""
|
|
1308
|
-
pp = r"'DCIR Equipotential Region'='true'" if value else r"'DCIR Equipotential Region'='false'"
|
|
1309
|
-
em_pp = self._em_properties
|
|
1310
|
-
pattern = r"'DCIR Equipotential Region'='([^']+)'"
|
|
1311
|
-
new_em_pp = re.sub(pattern, pp, em_pp)
|
|
1312
|
-
self._em_properties = new_em_pp
|
|
1321
|
+
return
|
|
1322
|
+
prim.dcir_equipotential_region = True
|
|
1313
1323
|
|
|
1314
1324
|
@property
|
|
1315
1325
|
def object_instance(self):
|
|
@@ -1577,7 +1587,6 @@ class EDBPadstackInstance(Primitive):
|
|
|
1577
1587
|
str
|
|
1578
1588
|
Name of the starting layer.
|
|
1579
1589
|
"""
|
|
1580
|
-
layer = self._pedb.edb_api.cell.layer("", self._pedb.edb_api.cell.layer_type.SignalLayer)
|
|
1581
1590
|
_, start_layer, stop_layer = self._edb_object.GetLayerRange()
|
|
1582
1591
|
|
|
1583
1592
|
if start_layer:
|
|
@@ -1599,7 +1608,6 @@ class EDBPadstackInstance(Primitive):
|
|
|
1599
1608
|
str
|
|
1600
1609
|
Name of the stopping layer.
|
|
1601
1610
|
"""
|
|
1602
|
-
layer = self._pedb.edb_api.cell.layer("", self._pedb.edb_api.cell.layer_type.SignalLayer)
|
|
1603
1611
|
_, start_layer, stop_layer = self._edb_padstackinstance.GetLayerRange()
|
|
1604
1612
|
|
|
1605
1613
|
if stop_layer:
|
|
@@ -1620,7 +1628,7 @@ class EDBPadstackInstance(Primitive):
|
|
|
1620
1628
|
layer_list = []
|
|
1621
1629
|
start_layer_name = start_layer.GetName()
|
|
1622
1630
|
stop_layer_name = stop_layer.GetName()
|
|
1623
|
-
for layer_name in list(self._pedb.stackup.
|
|
1631
|
+
for layer_name in list(self._pedb.stackup.signal_layers.keys()):
|
|
1624
1632
|
if started:
|
|
1625
1633
|
layer_list.append(layer_name)
|
|
1626
1634
|
if layer_name == stop_layer_name or layer_name == start_layer_name:
|
|
@@ -1705,7 +1713,6 @@ class EDBPadstackInstance(Primitive):
|
|
|
1705
1713
|
float
|
|
1706
1714
|
Rotatation value for the padstack instance.
|
|
1707
1715
|
"""
|
|
1708
|
-
point_data = self._pedb.edb_api.geometry.point_data(self._pedb.edb_value(0.0), self._pedb.edb_value(0.0))
|
|
1709
1716
|
out = self._edb_padstackinstance.GetPositionAndRotationValue()
|
|
1710
1717
|
|
|
1711
1718
|
if out[0]:
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
20
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
21
|
# SOFTWARE.
|
|
22
|
+
from typing import Union
|
|
22
23
|
|
|
23
24
|
from pyedb.dotnet.edb_core.general import convert_py_list_to_net_list
|
|
24
25
|
from pyedb.dotnet.edb_core.geometry.point_data import PointData
|
|
@@ -128,3 +129,7 @@ class PolygonData:
|
|
|
128
129
|
arcs = convert_py_list_to_net_list(arcs)
|
|
129
130
|
poly = self._edb_object.CreateFromArcs(arcs, flag)
|
|
130
131
|
return PolygonData(self._pedb, poly)
|
|
132
|
+
|
|
133
|
+
def point_in_polygon(self, x: Union[str, float], y: Union[str, float]) -> bool:
|
|
134
|
+
"""Determines whether a point is inside the polygon."""
|
|
135
|
+
return self._edb_object.PointInPolygon(self._pedb.point_data(x, y))
|
pyedb/dotnet/edb_core/modeler.py
CHANGED
|
@@ -661,8 +661,7 @@ class Modeler(object):
|
|
|
661
661
|
else:
|
|
662
662
|
polygonData = main_shape
|
|
663
663
|
if not polygonData or polygonData.IsNull():
|
|
664
|
-
|
|
665
|
-
return False
|
|
664
|
+
raise RuntimeError("Failed to create main shape polygon data")
|
|
666
665
|
for void in voids:
|
|
667
666
|
if isinstance(void, list):
|
|
668
667
|
void = self.Shape("polygon", points=void)
|
|
@@ -1636,14 +1636,12 @@ class EdbPadstacks(object):
|
|
|
1636
1636
|
merged_via_ids = []
|
|
1637
1637
|
if not contour_boxes:
|
|
1638
1638
|
raise Exception("No contour box provided, you need to pass a nested list as argument.")
|
|
1639
|
-
|
|
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
|
|
1639
|
+
|
|
1643
1640
|
instances_index = {}
|
|
1644
1641
|
for id, inst in self.instances.items():
|
|
1645
1642
|
instances_index[id] = inst.position
|
|
1646
1643
|
for contour_box in contour_boxes:
|
|
1644
|
+
all_instances = self.instances
|
|
1647
1645
|
instances = self.get_padstack_instances_id_intersecting_polygon(
|
|
1648
1646
|
points=contour_box, padstack_instances_index=instances_index
|
|
1649
1647
|
)
|
|
@@ -1651,7 +1649,28 @@ class EdbPadstacks(object):
|
|
|
1651
1649
|
raise Exception(f"No padstack instances found inside {contour_box}")
|
|
1652
1650
|
else:
|
|
1653
1651
|
if net_filter:
|
|
1654
|
-
instances = [id for id in instances if not self.instances[id].net_name in net_filter]
|
|
1652
|
+
# instances = [id for id in instances if not self.instances[id].net_name in net_filter]
|
|
1653
|
+
instances = [id for id in instances if all_instances[id].net_name not in net_filter]
|
|
1654
|
+
# filter instances by start and stop layer
|
|
1655
|
+
if start_layer:
|
|
1656
|
+
if start_layer not in self._pedb.stackup.layers.keys():
|
|
1657
|
+
raise Exception(f"{start_layer} not exist")
|
|
1658
|
+
else:
|
|
1659
|
+
instances = [id for id in instances if all_instances[id].start_layer == start_layer]
|
|
1660
|
+
if stop_layer:
|
|
1661
|
+
if stop_layer not in self._pedb.stackup.layers.keys():
|
|
1662
|
+
raise Exception(f"{stop_layer} not exist")
|
|
1663
|
+
else:
|
|
1664
|
+
instances = [id for id in instances if all_instances[id].stop_layer == stop_layer]
|
|
1665
|
+
if not instances:
|
|
1666
|
+
raise Exception(
|
|
1667
|
+
f"No padstack instances found inside {contour_box} between {start_layer} and {stop_layer}"
|
|
1668
|
+
)
|
|
1669
|
+
|
|
1670
|
+
if not start_layer:
|
|
1671
|
+
start_layer = list(self._pedb.stackup.layers.values())[0].name
|
|
1672
|
+
if not stop_layer:
|
|
1673
|
+
stop_layer = list(self._pedb.stackup.layers.values())[-1].name
|
|
1655
1674
|
|
|
1656
1675
|
net = self.instances[instances[0]].net_name
|
|
1657
1676
|
x_values = []
|
|
@@ -1692,7 +1711,7 @@ class EdbPadstacks(object):
|
|
|
1692
1711
|
merged_instance.stop_layer = stop_layer
|
|
1693
1712
|
|
|
1694
1713
|
merged_via_ids.append(merged_instance.id)
|
|
1695
|
-
[
|
|
1714
|
+
_ = [all_instances[id].delete() for id in instances]
|
|
1696
1715
|
return merged_via_ids
|
|
1697
1716
|
|
|
1698
1717
|
def merge_via_along_lines(
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
pyedb/__init__.py,sha256=
|
|
1
|
+
pyedb/__init__.py,sha256=bTsJ4CBHXe9DwW7gVeft0iIBTaHaGYTd7KW5dij8NdU,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
|
|
@@ -18,7 +18,7 @@ pyedb/configuration/cfg_operations.py,sha256=CFLBdM2kQBsW6f7W0NHWbV56RDMHSnaNQl3
|
|
|
18
18
|
pyedb/configuration/cfg_package_definition.py,sha256=f_RRT9R-3H5kHBlc4QSpjq9uQgYbaKQ78XXXrc_r3kg,5296
|
|
19
19
|
pyedb/configuration/cfg_padstacks.py,sha256=zZSEc92TwSqa7KSZBmDb4Sybm4ivM5lrvb8uMxFho8k,18292
|
|
20
20
|
pyedb/configuration/cfg_pin_groups.py,sha256=zNKfVP-fd1qUxS2wNb0ZTLGonkUnBmiXb4Rss1Rr7sE,3714
|
|
21
|
-
pyedb/configuration/cfg_ports_sources.py,sha256=
|
|
21
|
+
pyedb/configuration/cfg_ports_sources.py,sha256=1ngvubH02qQBHjkRI90BvpdRq4HMHRfbeFRKWEjEtAM,22988
|
|
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
|
|
@@ -26,7 +26,7 @@ pyedb/configuration/cfg_stackup.py,sha256=Ie2mdHfCgPn3F7BSdLlYZoZ3exhCDgPrhlYwxH
|
|
|
26
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=EDXhqDKk8uif6EVpZld3ggdmxs3uukgvpX-cjXAfAAk,186688
|
|
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
|
|
@@ -36,15 +36,15 @@ pyedb/dotnet/edb_core/hfss.py,sha256=oQFC6PwRbjAwfR60RoklwpZ_2sDI4OheNNdwaqY23ok
|
|
|
36
36
|
pyedb/dotnet/edb_core/layout_obj_instance.py,sha256=Pd8rfdO3b6HLFGwXBMw-tfE4LPIcW_9_X5KEdFaiito,1407
|
|
37
37
|
pyedb/dotnet/edb_core/layout_validation.py,sha256=S0IFx9t5toVpuTLTI2Cs9vvgR4BCebJLXnj0ydW2Op8,13597
|
|
38
38
|
pyedb/dotnet/edb_core/materials.py,sha256=s105DUTFkQoQRWgtRMp02DKcU2YcSrfLbJoi8hcTQII,42293
|
|
39
|
-
pyedb/dotnet/edb_core/modeler.py,sha256=
|
|
39
|
+
pyedb/dotnet/edb_core/modeler.py,sha256=XKlKzgTRtFll5ZZlhC4JEfKkO5AZvooAtgbV49VYbZc,55494
|
|
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=
|
|
42
|
+
pyedb/dotnet/edb_core/padstack.py,sha256=eUlIO6pBCfknjvToWWjdvxyz0zpFpyDdwFIMgyLVprk,73173
|
|
43
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
|
|
47
|
-
pyedb/dotnet/edb_core/cell/layout.py,sha256=
|
|
47
|
+
pyedb/dotnet/edb_core/cell/layout.py,sha256=zMTqjA_8I9vlJGNgZ6fgqmfs6B0krq2v1KlgXw1ZBJs,13172
|
|
48
48
|
pyedb/dotnet/edb_core/cell/layout_obj.py,sha256=S42rdiI6gVqO77DV3ikc4YxTNufTuqW_X1G-2zkWArA,2765
|
|
49
49
|
pyedb/dotnet/edb_core/cell/voltage_regulator.py,sha256=-uAzuyERV6ca0bFRzdH4SllcpGY2D9JEdpS7RYaQt6c,5387
|
|
50
50
|
pyedb/dotnet/edb_core/cell/hierarchy/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -58,7 +58,7 @@ pyedb/dotnet/edb_core/cell/hierarchy/spice_model.py,sha256=SGiUcan2l0n8DGk3GtwCs
|
|
|
58
58
|
pyedb/dotnet/edb_core/cell/primitive/__init__.py,sha256=8jByHkoaowAYQTCww-zRrTQmN061fLz_OHjTLSrzQQY,58
|
|
59
59
|
pyedb/dotnet/edb_core/cell/primitive/bondwire.py,sha256=fqIMdv0bNvk591DG6De5c--w9Rpkl5AOeo_qgzoPE6M,7322
|
|
60
60
|
pyedb/dotnet/edb_core/cell/primitive/path.py,sha256=XVN7dOVpccoBP28M8l5iMzK5QSQdHqpKqC4jK76UTis,12543
|
|
61
|
-
pyedb/dotnet/edb_core/cell/primitive/primitive.py,sha256=
|
|
61
|
+
pyedb/dotnet/edb_core/cell/primitive/primitive.py,sha256=nn2T3cG2r_qA4OEswTT-QLzS6HiYrkWh7YztGmZVZkE,28796
|
|
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
|
|
@@ -76,13 +76,13 @@ pyedb/dotnet/edb_core/dotnet/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NM
|
|
|
76
76
|
pyedb/dotnet/edb_core/dotnet/database.py,sha256=9mfEg451IX3Y8PKnyhbVPApqtgmB9R4VTeWyfux8Q0A,36691
|
|
77
77
|
pyedb/dotnet/edb_core/dotnet/primitive.py,sha256=2Mhh-pwnLzZUGLVRSCiBMtcxfvmrU40cASbpfXe1Ecs,49944
|
|
78
78
|
pyedb/dotnet/edb_core/edb_data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
79
|
-
pyedb/dotnet/edb_core/edb_data/control_file.py,sha256=
|
|
79
|
+
pyedb/dotnet/edb_core/edb_data/control_file.py,sha256=OhvB8bffgSeBYbpN_lqOsC_RvRYX77-yn-GbIyTRl0M,52550
|
|
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
83
|
pyedb/dotnet/edb_core/edb_data/layer_data.py,sha256=4Z_eaHSfGfwQBKETEmGSwMvwGzvirtwYw4G4TwonNiA,34314
|
|
84
|
-
pyedb/dotnet/edb_core/edb_data/nets_data.py,sha256=
|
|
85
|
-
pyedb/dotnet/edb_core/edb_data/padstacks_data.py,sha256=
|
|
84
|
+
pyedb/dotnet/edb_core/edb_data/nets_data.py,sha256=k15gL8A9yACRxw5UaMFZamijMLo19MR8YZbZb06tYMA,10142
|
|
85
|
+
pyedb/dotnet/edb_core/edb_data/padstacks_data.py,sha256=n9dsAcimNQdKpxFqfFB1-96KTGhZ6mz0vilAEHDKd4M,79557
|
|
86
86
|
pyedb/dotnet/edb_core/edb_data/ports.py,sha256=wr2RQi8VExuNIVmnp7c4VpTIhODgthmJmHr01zO4ueo,8873
|
|
87
87
|
pyedb/dotnet/edb_core/edb_data/primitives_data.py,sha256=kIXkd5SXeN881eJqdJ2KxEZebpimB4qFEed1g6w-Raw,16826
|
|
88
88
|
pyedb/dotnet/edb_core/edb_data/raptor_x_simulation_setup_data.py,sha256=P37-OIsc8TuTC_s3CXRmvZcJqxAftHA7SATfEyoAnMM,20953
|
|
@@ -92,7 +92,7 @@ pyedb/dotnet/edb_core/edb_data/utilities.py,sha256=3wZqOJ35eisOwOPKOs-bvJ8kmd62e
|
|
|
92
92
|
pyedb/dotnet/edb_core/edb_data/variables.py,sha256=LS1jZPOYgRvf4cyKf_x8hI9Brs-qbh4wrHu_QGLElrg,3501
|
|
93
93
|
pyedb/dotnet/edb_core/geometry/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
94
94
|
pyedb/dotnet/edb_core/geometry/point_data.py,sha256=hC9cRuSnX4cwg09Jr0ZK7ZTjFf_4NwXJMGbZ3s-ULpQ,1590
|
|
95
|
-
pyedb/dotnet/edb_core/geometry/polygon_data.py,sha256=
|
|
95
|
+
pyedb/dotnet/edb_core/geometry/polygon_data.py,sha256=qZ1dRQHMo2JNZaWiPkrqrE009YZU3IOCr8UGQ1MXot8,5272
|
|
96
96
|
pyedb/dotnet/edb_core/sim_setup_data/__init__.py,sha256=8jByHkoaowAYQTCww-zRrTQmN061fLz_OHjTLSrzQQY,58
|
|
97
97
|
pyedb/dotnet/edb_core/sim_setup_data/data/__init__.py,sha256=8jByHkoaowAYQTCww-zRrTQmN061fLz_OHjTLSrzQQY,58
|
|
98
98
|
pyedb/dotnet/edb_core/sim_setup_data/data/adaptive_frequency_data.py,sha256=tlHI7PUUoseNnJAtihpjb1PwXYNr-4ztAAnunlLLWVQ,2463
|
|
@@ -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.37.0.dist-info/LICENSE,sha256=qQWivZ12ETN5l3QxvTARY-QI5eoRRlyHdwLlAj0Bg5I,1089
|
|
192
|
+
pyedb-0.37.0.dist-info/WHEEL,sha256=CpUCUxeHQbRN5UGRQHYRJorO5Af-Qy_fHMctcQ8DSGI,82
|
|
193
|
+
pyedb-0.37.0.dist-info/METADATA,sha256=IwWf3GCdS37oFKRCZh99M_me8qd3vx0-QbUAvNpXME8,8513
|
|
194
|
+
pyedb-0.37.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|