pyedb 0.17.0__py3-none-any.whl → 0.19.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_data.py +8 -11
- pyedb/configuration/cfg_nets.py +14 -0
- pyedb/configuration/cfg_pin_groups.py +57 -20
- pyedb/configuration/cfg_ports_sources.py +248 -60
- pyedb/configuration/configuration.py +51 -17
- pyedb/dotnet/edb.py +92 -28
- pyedb/dotnet/edb_core/cell/layout.py +48 -1
- pyedb/dotnet/edb_core/cell/terminal/padstack_instance_terminal.py +10 -0
- pyedb/dotnet/edb_core/cell/terminal/pingroup_terminal.py +5 -0
- pyedb/dotnet/edb_core/cell/terminal/point_terminal.py +0 -11
- pyedb/dotnet/edb_core/cell/terminal/terminal.py +35 -1
- pyedb/dotnet/edb_core/components.py +74 -18
- pyedb/dotnet/edb_core/dotnet/primitive.py +9 -6
- pyedb/dotnet/edb_core/edb_data/padstacks_data.py +8 -4
- pyedb/dotnet/edb_core/edb_data/ports.py +0 -18
- pyedb/dotnet/edb_core/edb_data/primitives_data.py +1 -1
- pyedb/dotnet/edb_core/padstack.py +10 -1
- pyedb/dotnet/edb_core/sim_setup_data/data/sim_setup_info.py +42 -3
- pyedb/dotnet/edb_core/sim_setup_data/data/simulation_settings.py +92 -158
- pyedb/dotnet/edb_core/sim_setup_data/data/siw_dc_ir_settings.py +22 -22
- pyedb/dotnet/edb_core/sim_setup_data/io/siwave.py +76 -76
- pyedb/dotnet/edb_core/utilities/hfss_simulation_setup.py +23 -94
- pyedb/dotnet/edb_core/utilities/simulation_setup.py +40 -38
- pyedb/dotnet/edb_core/utilities/siwave_simulation_setup.py +26 -17
- {pyedb-0.17.0.dist-info → pyedb-0.19.0.dist-info}/METADATA +8 -8
- {pyedb-0.17.0.dist-info → pyedb-0.19.0.dist-info}/RECORD +29 -29
- {pyedb-0.17.0.dist-info → pyedb-0.19.0.dist-info}/LICENSE +0 -0
- {pyedb-0.17.0.dist-info → pyedb-0.19.0.dist-info}/WHEEL +0 -0
|
@@ -65,14 +65,16 @@ class Configuration:
|
|
|
65
65
|
"""
|
|
66
66
|
if isinstance(config_file, dict):
|
|
67
67
|
data = config_file
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
68
|
+
else:
|
|
69
|
+
config_file = str(config_file)
|
|
70
|
+
if os.path.isfile(config_file):
|
|
71
|
+
with open(config_file, "r") as f:
|
|
72
|
+
if config_file.endswith(".json"):
|
|
73
|
+
data = json.load(f)
|
|
74
|
+
elif config_file.endswith(".toml"):
|
|
75
|
+
data = toml.load(f)
|
|
76
|
+
else: # pragma: no cover
|
|
77
|
+
return False
|
|
76
78
|
|
|
77
79
|
if not append: # pragma: no cover
|
|
78
80
|
self.data = {}
|
|
@@ -120,16 +122,13 @@ class Configuration:
|
|
|
120
122
|
self.cfg_data.padstacks.apply()
|
|
121
123
|
|
|
122
124
|
# Configure pin groups
|
|
123
|
-
|
|
124
|
-
pin_group.apply()
|
|
125
|
+
self.cfg_data.pin_groups.apply()
|
|
125
126
|
|
|
126
127
|
# Configure ports
|
|
127
|
-
|
|
128
|
-
port.create()
|
|
128
|
+
self.cfg_data.ports.apply()
|
|
129
129
|
|
|
130
130
|
# Configure sources
|
|
131
|
-
|
|
132
|
-
source.create()
|
|
131
|
+
self.cfg_data.sources.apply()
|
|
133
132
|
|
|
134
133
|
# Configure setup
|
|
135
134
|
self.cfg_data.setups.apply()
|
|
@@ -271,12 +270,30 @@ class Configuration:
|
|
|
271
270
|
data["package_definitions"] = self.cfg_data.package_definitions.get_data_from_db()
|
|
272
271
|
if kwargs.get("setups", False):
|
|
273
272
|
data["setups"] = self.cfg_data.setups.get_data_from_db()
|
|
273
|
+
if kwargs.get("sources", False):
|
|
274
|
+
data["sources"] = self.cfg_data.sources.get_data_from_db()
|
|
275
|
+
if kwargs.get("ports", False):
|
|
276
|
+
data["ports"] = self.cfg_data.ports.get_data_from_db()
|
|
274
277
|
if kwargs.get("components", False):
|
|
275
278
|
data["components"] = self.cfg_data.components.get_data_from_db()
|
|
279
|
+
if kwargs.get("nets", False):
|
|
280
|
+
data["nets"] = self.cfg_data.nets.get_data_from_db()
|
|
281
|
+
if kwargs.get("pin_groups", False):
|
|
282
|
+
data["pin_groups"] = self.cfg_data.pin_groups.get_data_from_db()
|
|
276
283
|
|
|
277
284
|
return data
|
|
278
285
|
|
|
279
|
-
def export(
|
|
286
|
+
def export(
|
|
287
|
+
self,
|
|
288
|
+
file_path,
|
|
289
|
+
stackup=True,
|
|
290
|
+
package_definitions=True,
|
|
291
|
+
setups=True,
|
|
292
|
+
sources=True,
|
|
293
|
+
ports=True,
|
|
294
|
+
nets=True,
|
|
295
|
+
pin_groups=True,
|
|
296
|
+
):
|
|
280
297
|
"""Export the configuration data from layout to a file.
|
|
281
298
|
|
|
282
299
|
Parameters
|
|
@@ -285,14 +302,31 @@ class Configuration:
|
|
|
285
302
|
File path to export the configuration data.
|
|
286
303
|
stackup : bool
|
|
287
304
|
Whether to export stackup or not.
|
|
288
|
-
|
|
305
|
+
package_definitions : bool
|
|
306
|
+
Whether to export package definitions or not.
|
|
307
|
+
setups : bool
|
|
308
|
+
Whether to export setups or not.
|
|
309
|
+
sources : bool
|
|
310
|
+
Whether to export sources or not.
|
|
311
|
+
ports : bool
|
|
312
|
+
Whether to export ports or not.
|
|
313
|
+
nets : bool
|
|
314
|
+
Whether to export nets.
|
|
289
315
|
Returns
|
|
290
316
|
-------
|
|
291
317
|
bool
|
|
292
318
|
"""
|
|
293
319
|
file_path = file_path if isinstance(file_path, Path) else Path(file_path)
|
|
294
320
|
file_path = file_path if file_path.suffix == ".json" else file_path.with_suffix(".json")
|
|
295
|
-
data = self.get_data_from_db(
|
|
321
|
+
data = self.get_data_from_db(
|
|
322
|
+
stackup=stackup,
|
|
323
|
+
package_definitions=package_definitions,
|
|
324
|
+
setups=setups,
|
|
325
|
+
sources=sources,
|
|
326
|
+
ports=ports,
|
|
327
|
+
nets=nets,
|
|
328
|
+
pin_groups=pin_groups,
|
|
329
|
+
)
|
|
296
330
|
with open(file_path, "w") as f:
|
|
297
331
|
json.dump(data, f, ensure_ascii=False, indent=4)
|
|
298
332
|
return True if os.path.isfile(file_path) else False
|
pyedb/dotnet/edb.py
CHANGED
|
@@ -510,6 +510,7 @@ class Edb(Database):
|
|
|
510
510
|
def sources(self):
|
|
511
511
|
"""Get all layout sources."""
|
|
512
512
|
terms = [term for term in self.layout.terminals if int(term.GetBoundaryType()) in [3, 4, 7]]
|
|
513
|
+
terms = [term for term in terms if not term.IsReferenceTerminal()]
|
|
513
514
|
return {ter.GetName(): ExcitationSources(self, ter) for ter in terms}
|
|
514
515
|
|
|
515
516
|
@property
|
|
@@ -1558,6 +1559,7 @@ class Edb(Database):
|
|
|
1558
1559
|
reference_list=[],
|
|
1559
1560
|
include_pingroups=True,
|
|
1560
1561
|
pins_to_preserve=None,
|
|
1562
|
+
inlcude_voids_in_extents=False,
|
|
1561
1563
|
):
|
|
1562
1564
|
if extent_type in [
|
|
1563
1565
|
"Conforming",
|
|
@@ -1574,6 +1576,7 @@ class Edb(Database):
|
|
|
1574
1576
|
smart_cut,
|
|
1575
1577
|
reference_list,
|
|
1576
1578
|
pins_to_preserve,
|
|
1579
|
+
inlcude_voids_in_extents=inlcude_voids_in_extents,
|
|
1577
1580
|
)
|
|
1578
1581
|
else:
|
|
1579
1582
|
_poly = self.layout.expanded_extent(
|
|
@@ -1632,6 +1635,7 @@ class Edb(Database):
|
|
|
1632
1635
|
smart_cutout=False,
|
|
1633
1636
|
reference_list=[],
|
|
1634
1637
|
pins_to_preserve=None,
|
|
1638
|
+
inlcude_voids_in_extents=False,
|
|
1635
1639
|
):
|
|
1636
1640
|
names = []
|
|
1637
1641
|
_polys = []
|
|
@@ -1649,7 +1653,7 @@ class Edb(Database):
|
|
|
1649
1653
|
|
|
1650
1654
|
for prim in self.modeler.primitives:
|
|
1651
1655
|
if prim is not None and prim.net_name in names:
|
|
1652
|
-
_polys.append(prim
|
|
1656
|
+
_polys.append(prim)
|
|
1653
1657
|
if smart_cutout:
|
|
1654
1658
|
objs_data = self._smart_cut(reference_list, expansion_size)
|
|
1655
1659
|
_polys.extend(objs_data)
|
|
@@ -1658,9 +1662,33 @@ class Edb(Database):
|
|
|
1658
1662
|
while k < 10:
|
|
1659
1663
|
unite_polys = []
|
|
1660
1664
|
for i in _polys:
|
|
1661
|
-
|
|
1665
|
+
if "PolygonData" not in str(i):
|
|
1666
|
+
obj_data = i.primitive_object.GetPolygonData().Expand(
|
|
1667
|
+
expansion_size, tolerance, round_corner, round_extension
|
|
1668
|
+
)
|
|
1669
|
+
else:
|
|
1670
|
+
obj_data = i.Expand(expansion_size, tolerance, round_corner, round_extension)
|
|
1662
1671
|
if obj_data:
|
|
1663
|
-
|
|
1672
|
+
if not inlcude_voids_in_extents:
|
|
1673
|
+
unite_polys.extend(list(obj_data))
|
|
1674
|
+
else:
|
|
1675
|
+
voids_poly = []
|
|
1676
|
+
try:
|
|
1677
|
+
if i.HasVoids():
|
|
1678
|
+
area = i.area()
|
|
1679
|
+
for void in i.Voids:
|
|
1680
|
+
void_polydata = void.GetPolygonData()
|
|
1681
|
+
if void_polydata.Area() >= 0.05 * area:
|
|
1682
|
+
voids_poly.append(void_polydata)
|
|
1683
|
+
if voids_poly:
|
|
1684
|
+
obj_data = obj_data[0].Subtract(
|
|
1685
|
+
convert_py_list_to_net_list(list(obj_data)),
|
|
1686
|
+
convert_py_list_to_net_list(voids_poly),
|
|
1687
|
+
)
|
|
1688
|
+
except:
|
|
1689
|
+
pass
|
|
1690
|
+
finally:
|
|
1691
|
+
unite_polys.extend(list(obj_data))
|
|
1664
1692
|
_poly_unite = self.edb_api.geometry.polygon_data.unite(unite_polys)
|
|
1665
1693
|
if len(_poly_unite) == 1:
|
|
1666
1694
|
self.logger.info("Correctly computed Extension at first iteration.")
|
|
@@ -1761,6 +1789,7 @@ class Edb(Database):
|
|
|
1761
1789
|
preserve_components_with_model=False,
|
|
1762
1790
|
simple_pad_check=True,
|
|
1763
1791
|
keep_lines_as_path=False,
|
|
1792
|
+
include_voids_in_extents=False,
|
|
1764
1793
|
):
|
|
1765
1794
|
"""Create a cutout using an approach entirely based on PyAEDT.
|
|
1766
1795
|
This method replaces all legacy cutout methods in PyAEDT.
|
|
@@ -1837,6 +1866,11 @@ class Edb(Database):
|
|
|
1837
1866
|
This feature works only in Electronics Desktop (3D Layout).
|
|
1838
1867
|
If the flag is set to ``True`` it can cause issues in SiWave once the Edb is imported.
|
|
1839
1868
|
Default is ``False`` to generate PolygonData of cut lines.
|
|
1869
|
+
include_voids_in_extents : bool, optional
|
|
1870
|
+
Whether to compute and include voids in pyaedt extent before the cutout. Cutout time can be affected.
|
|
1871
|
+
It works only with Conforming cutout.
|
|
1872
|
+
Default is ``False`` to generate extent without voids.
|
|
1873
|
+
|
|
1840
1874
|
|
|
1841
1875
|
Returns
|
|
1842
1876
|
-------
|
|
@@ -1896,6 +1930,7 @@ class Edb(Database):
|
|
|
1896
1930
|
use_pyaedt_extent_computing=use_pyaedt_extent_computing,
|
|
1897
1931
|
check_terminals=check_terminals,
|
|
1898
1932
|
include_pingroups=include_pingroups,
|
|
1933
|
+
inlcude_voids_in_extents=include_voids_in_extents,
|
|
1899
1934
|
)
|
|
1900
1935
|
else:
|
|
1901
1936
|
legacy_path = self.edbpath
|
|
@@ -1929,6 +1964,7 @@ class Edb(Database):
|
|
|
1929
1964
|
include_partial=include_partial_instances,
|
|
1930
1965
|
simple_pad_check=simple_pad_check,
|
|
1931
1966
|
keep_lines_as_path=keep_lines_as_path,
|
|
1967
|
+
inlcude_voids_in_extents=include_voids_in_extents,
|
|
1932
1968
|
)
|
|
1933
1969
|
if self.are_port_reference_terminals_connected():
|
|
1934
1970
|
if output_aedb_path:
|
|
@@ -1969,6 +2005,7 @@ class Edb(Database):
|
|
|
1969
2005
|
include_partial=include_partial_instances,
|
|
1970
2006
|
simple_pad_check=simple_pad_check,
|
|
1971
2007
|
keep_lines_as_path=keep_lines_as_path,
|
|
2008
|
+
inlcude_voids_in_extents=include_voids_in_extents,
|
|
1972
2009
|
)
|
|
1973
2010
|
if result and not open_cutout_at_end and self.edbpath != legacy_path:
|
|
1974
2011
|
self.save_edb()
|
|
@@ -1990,6 +2027,7 @@ class Edb(Database):
|
|
|
1990
2027
|
remove_single_pin_components=False,
|
|
1991
2028
|
check_terminals=False,
|
|
1992
2029
|
include_pingroups=True,
|
|
2030
|
+
inlcude_voids_in_extents=False,
|
|
1993
2031
|
):
|
|
1994
2032
|
expansion_size = self.edb_value(expansion_size).ToDouble()
|
|
1995
2033
|
|
|
@@ -2010,8 +2048,14 @@ class Edb(Database):
|
|
|
2010
2048
|
smart_cut=check_terminals,
|
|
2011
2049
|
reference_list=reference_list,
|
|
2012
2050
|
include_pingroups=include_pingroups,
|
|
2051
|
+
inlcude_voids_in_extents=inlcude_voids_in_extents,
|
|
2013
2052
|
)
|
|
2014
|
-
|
|
2053
|
+
_poly1 = _poly.CreateFromArcs(_poly.GetArcData(), True)
|
|
2054
|
+
if inlcude_voids_in_extents:
|
|
2055
|
+
for hole in list(_poly.Holes):
|
|
2056
|
+
if hole.Area() >= 0.05 * _poly1.Area():
|
|
2057
|
+
_poly1.AddHole(hole)
|
|
2058
|
+
_poly = _poly1
|
|
2015
2059
|
# Create new cutout cell/design
|
|
2016
2060
|
included_nets_list = signal_list + reference_list
|
|
2017
2061
|
included_nets = convert_py_list_to_net_list(
|
|
@@ -2172,6 +2216,7 @@ class Edb(Database):
|
|
|
2172
2216
|
include_partial=False,
|
|
2173
2217
|
simple_pad_check=True,
|
|
2174
2218
|
keep_lines_as_path=False,
|
|
2219
|
+
inlcude_voids_in_extents=False,
|
|
2175
2220
|
):
|
|
2176
2221
|
if is_ironpython: # pragma: no cover
|
|
2177
2222
|
self.logger.error("Method working only in Cpython")
|
|
@@ -2269,11 +2314,18 @@ class Edb(Database):
|
|
|
2269
2314
|
reference_list=reference_list,
|
|
2270
2315
|
include_pingroups=include_pingroups,
|
|
2271
2316
|
pins_to_preserve=pins_to_preserve,
|
|
2317
|
+
inlcude_voids_in_extents=inlcude_voids_in_extents,
|
|
2272
2318
|
)
|
|
2273
2319
|
if extent_type in ["Conforming", self.edb_api.geometry.extent_type.Conforming, 1]:
|
|
2274
2320
|
if extent_defeature > 0:
|
|
2275
2321
|
_poly = _poly.Defeature(extent_defeature)
|
|
2276
|
-
|
|
2322
|
+
|
|
2323
|
+
_poly1 = _poly.CreateFromArcs(_poly.GetArcData(), True)
|
|
2324
|
+
if inlcude_voids_in_extents:
|
|
2325
|
+
for hole in list(_poly.Holes):
|
|
2326
|
+
if hole.Area() >= 0.05 * _poly1.Area():
|
|
2327
|
+
_poly1.AddHole(hole)
|
|
2328
|
+
_poly = _poly1
|
|
2277
2329
|
if not _poly or _poly.IsNull():
|
|
2278
2330
|
self._logger.error("Failed to create Extent.")
|
|
2279
2331
|
return []
|
|
@@ -2312,29 +2364,39 @@ class Edb(Database):
|
|
|
2312
2364
|
pdata = prim_1.polygon_data.edb_api
|
|
2313
2365
|
int_data = _poly.GetIntersectionType(pdata)
|
|
2314
2366
|
if int_data == 2:
|
|
2315
|
-
|
|
2367
|
+
if not inlcude_voids_in_extents:
|
|
2368
|
+
return
|
|
2369
|
+
skip = False
|
|
2370
|
+
for hole in list(_poly.Holes):
|
|
2371
|
+
if hole.GetIntersectionType(pdata) == 0:
|
|
2372
|
+
prims_to_delete.append(prim_1)
|
|
2373
|
+
return
|
|
2374
|
+
elif hole.GetIntersectionType(pdata) == 1:
|
|
2375
|
+
skip = True
|
|
2376
|
+
if skip:
|
|
2377
|
+
return
|
|
2316
2378
|
elif int_data == 0:
|
|
2317
2379
|
prims_to_delete.append(prim_1)
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2380
|
+
return
|
|
2381
|
+
list_poly = intersect(_poly, pdata)
|
|
2382
|
+
if list_poly:
|
|
2383
|
+
net = prim_1.net_name
|
|
2384
|
+
voids = prim_1.voids
|
|
2385
|
+
for p in list_poly:
|
|
2386
|
+
if p.IsNull():
|
|
2387
|
+
continue
|
|
2388
|
+
# points = list(p.Points)
|
|
2389
|
+
list_void = []
|
|
2390
|
+
if voids:
|
|
2391
|
+
voids_data = [void.polygon_data.edb_api for void in voids]
|
|
2392
|
+
list_prims = subtract(p, voids_data)
|
|
2393
|
+
for prim in list_prims:
|
|
2394
|
+
if not prim.IsNull():
|
|
2395
|
+
poly_to_create.append([prim, prim_1.layer.name, net, list_void])
|
|
2396
|
+
else:
|
|
2397
|
+
poly_to_create.append([p, prim_1.layer.name, net, list_void])
|
|
2336
2398
|
|
|
2337
|
-
|
|
2399
|
+
prims_to_delete.append(prim_1)
|
|
2338
2400
|
|
|
2339
2401
|
def pins_clean(pinst):
|
|
2340
2402
|
if not pinst.in_polygon(_poly, include_partial=include_partial, simple_check=simple_pad_check):
|
|
@@ -2350,7 +2412,9 @@ class Edb(Database):
|
|
|
2350
2412
|
for pin in pins_to_delete:
|
|
2351
2413
|
pin.delete()
|
|
2352
2414
|
|
|
2353
|
-
self.logger.info_timer(
|
|
2415
|
+
self.logger.info_timer(
|
|
2416
|
+
"Padstack Instances removal completed. {} instances removed.".format(len(pins_to_delete))
|
|
2417
|
+
)
|
|
2354
2418
|
self.logger.reset_timer()
|
|
2355
2419
|
|
|
2356
2420
|
# with ThreadPoolExecutor(number_of_threads) as pool:
|
|
@@ -2369,7 +2433,7 @@ class Edb(Database):
|
|
|
2369
2433
|
for prim in prims_to_delete:
|
|
2370
2434
|
prim.delete()
|
|
2371
2435
|
|
|
2372
|
-
self.logger.info_timer("Primitives cleanup completed")
|
|
2436
|
+
self.logger.info_timer("Primitives cleanup completed. {} primitives deleted.".format(len(prims_to_delete)))
|
|
2373
2437
|
self.logger.reset_timer()
|
|
2374
2438
|
|
|
2375
2439
|
i = 0
|
|
@@ -3680,7 +3744,7 @@ class Edb(Database):
|
|
|
3680
3744
|
if float(self.edbversion) < 2024.2:
|
|
3681
3745
|
self.logger.error("HFSSPI simulation only supported with Ansys release 2024R2 and higher")
|
|
3682
3746
|
return False
|
|
3683
|
-
return HFSSPISimulationSetup(self
|
|
3747
|
+
return HFSSPISimulationSetup(self, name=name)
|
|
3684
3748
|
|
|
3685
3749
|
def create_siwave_syz_setup(self, name=None, **kwargs):
|
|
3686
3750
|
"""Create a setup from a template.
|
|
@@ -23,9 +23,11 @@
|
|
|
23
23
|
"""
|
|
24
24
|
This module contains these classes: `EdbLayout` and `Shape`.
|
|
25
25
|
"""
|
|
26
|
-
|
|
27
26
|
from pyedb.dotnet.edb_core.cell.primitive import Bondwire
|
|
28
27
|
from pyedb.dotnet.edb_core.edb_data.nets_data import EDBNetsData
|
|
28
|
+
from pyedb.dotnet.edb_core.edb_data.padstacks_data import EDBPadstackInstance
|
|
29
|
+
from pyedb.dotnet.edb_core.edb_data.sources import PinGroup
|
|
30
|
+
from pyedb.dotnet.edb_core.general import convert_py_list_to_net_list
|
|
29
31
|
from pyedb.dotnet.edb_core.layout import EdbLayout
|
|
30
32
|
|
|
31
33
|
|
|
@@ -65,6 +67,11 @@ class Layout(EdbLayout):
|
|
|
65
67
|
if i.GetPrimitiveType().ToString() == "Bondwire"
|
|
66
68
|
]
|
|
67
69
|
|
|
70
|
+
@property
|
|
71
|
+
def padstack_instances(self):
|
|
72
|
+
"""Get all padstack instances in a list."""
|
|
73
|
+
return [EDBPadstackInstance(i, self._pedb) for i in self._edb_object.PadstackInstances]
|
|
74
|
+
|
|
68
75
|
def create_bondwire(
|
|
69
76
|
self,
|
|
70
77
|
definition_name,
|
|
@@ -129,3 +136,43 @@ class Layout(EdbLayout):
|
|
|
129
136
|
end_y=self._pedb.edb_value(end_y),
|
|
130
137
|
net=self.nets[net]._edb_object,
|
|
131
138
|
)
|
|
139
|
+
|
|
140
|
+
def find_object_by_id(self, value: int):
|
|
141
|
+
"""Find a Connectable object by Database ID.
|
|
142
|
+
|
|
143
|
+
Parameters
|
|
144
|
+
----------
|
|
145
|
+
value : int
|
|
146
|
+
"""
|
|
147
|
+
obj = self._pedb._edb.Cell.Connectable.FindById(self._edb_object, value)
|
|
148
|
+
if obj.GetObjType().ToString() == "PadstackInstance":
|
|
149
|
+
return EDBPadstackInstance(obj, self._pedb)
|
|
150
|
+
|
|
151
|
+
def create_pin_group(self, name: str, pins_by_id: list[int] = None, pins_by_aedt_name: list[str] = None):
|
|
152
|
+
"""Create a PinGroup.
|
|
153
|
+
|
|
154
|
+
Parameters
|
|
155
|
+
name : str,
|
|
156
|
+
Name of the PinGroup.
|
|
157
|
+
pins_by_id : list[int] or None
|
|
158
|
+
List of pins by ID.
|
|
159
|
+
pins_by_aedt_name : list[str] or None
|
|
160
|
+
List of pins by AEDT name.
|
|
161
|
+
"""
|
|
162
|
+
pins = []
|
|
163
|
+
|
|
164
|
+
if pins_by_id is not None:
|
|
165
|
+
for p in pins_by_id:
|
|
166
|
+
pins.append(self.find_object_by_id(p._edb_object))
|
|
167
|
+
else:
|
|
168
|
+
p_inst = self.padstack_instances
|
|
169
|
+
while True:
|
|
170
|
+
p = p_inst.pop(0)
|
|
171
|
+
if p.aedt_name in pins_by_aedt_name:
|
|
172
|
+
pins.append(p._edb_object)
|
|
173
|
+
pins_by_aedt_name.remove(p.aedt_name)
|
|
174
|
+
if len(pins_by_aedt_name) == 0:
|
|
175
|
+
break
|
|
176
|
+
|
|
177
|
+
obj = self._edb.cell.hierarchy.pin_group.Create(self._edb_object, name, convert_py_list_to_net_list(pins))
|
|
178
|
+
return PinGroup(name, obj, self._pedb)
|
|
@@ -86,3 +86,13 @@ class PadstackInstanceTerminal(Terminal):
|
|
|
86
86
|
terminal = PadstackInstanceTerminal(self._pedb, terminal)
|
|
87
87
|
|
|
88
88
|
return terminal if not terminal.is_null else False
|
|
89
|
+
|
|
90
|
+
def _get_parameters(self):
|
|
91
|
+
"""Gets the parameters of the padstack instance terminal."""
|
|
92
|
+
_, padstack_inst, layer_obj = self._edb_object.GetParameters()
|
|
93
|
+
return padstack_inst, layer_obj
|
|
94
|
+
|
|
95
|
+
@property
|
|
96
|
+
def padstack_instance(self):
|
|
97
|
+
p_inst, _ = self._get_parameters()
|
|
98
|
+
return self._pedb.modeler.find_object_by_id(p_inst.GetId())
|
|
@@ -57,3 +57,8 @@ class PinGroupTerminal(Terminal):
|
|
|
57
57
|
)
|
|
58
58
|
term = PinGroupTerminal(self._pedb, term)
|
|
59
59
|
return term if not term.is_null else False
|
|
60
|
+
|
|
61
|
+
def pin_group(self):
|
|
62
|
+
"""Gets the pin group the terminal refers to."""
|
|
63
|
+
name = self._edb_object.GetPinGroup().GetName()
|
|
64
|
+
return self._pedb.siwave.pin_groups[name]
|
|
@@ -60,14 +60,3 @@ class PointTerminal(Terminal):
|
|
|
60
60
|
)
|
|
61
61
|
terminal = PointTerminal(self._pedb, terminal)
|
|
62
62
|
return terminal if not terminal.is_null else False
|
|
63
|
-
|
|
64
|
-
@property
|
|
65
|
-
def ref_terminal(self):
|
|
66
|
-
"""Get reference terminal."""
|
|
67
|
-
|
|
68
|
-
terminal = Terminal(self._pedb, self._edb_object.GetReferenceTerminal())
|
|
69
|
-
return terminal if not terminal.is_null else False
|
|
70
|
-
|
|
71
|
-
@ref_terminal.setter
|
|
72
|
-
def ref_terminal(self, value):
|
|
73
|
-
self._edb_object.SetReferenceTerminal(value._edb_object)
|
|
@@ -217,6 +217,21 @@ class Terminal(Connectable):
|
|
|
217
217
|
def boundary_type(self, value):
|
|
218
218
|
self._edb_object.SetBoundaryType(self._boundary_type_mapping[value])
|
|
219
219
|
|
|
220
|
+
@property
|
|
221
|
+
def is_port(self):
|
|
222
|
+
"""Whether it is a port."""
|
|
223
|
+
return True if self.boundary_type == "PortBoundary" else False
|
|
224
|
+
|
|
225
|
+
@property
|
|
226
|
+
def is_current_source(self):
|
|
227
|
+
"""Whether it is a current source."""
|
|
228
|
+
return True if self.boundary_type == "kCurrentSource" else False
|
|
229
|
+
|
|
230
|
+
@property
|
|
231
|
+
def is_voltage_source(self):
|
|
232
|
+
"""Whether it is a voltage source."""
|
|
233
|
+
return True if self.boundary_type == "kVoltageSource" else False
|
|
234
|
+
|
|
220
235
|
@property
|
|
221
236
|
def impedance(self):
|
|
222
237
|
"""Impedance of the port."""
|
|
@@ -235,7 +250,8 @@ class Terminal(Connectable):
|
|
|
235
250
|
def ref_terminal(self):
|
|
236
251
|
"""Get reference terminal."""
|
|
237
252
|
|
|
238
|
-
|
|
253
|
+
edb_terminal = self._edb_object.GetReferenceTerminal()
|
|
254
|
+
terminal = self._pedb.terminals[edb_terminal.GetName()]
|
|
239
255
|
if not terminal.is_null:
|
|
240
256
|
return terminal
|
|
241
257
|
|
|
@@ -444,3 +460,21 @@ class Terminal(Connectable):
|
|
|
444
460
|
pin_obj = pin
|
|
445
461
|
if pin_obj:
|
|
446
462
|
return EDBPadstackInstance(pin_obj, self._pedb)
|
|
463
|
+
|
|
464
|
+
@property
|
|
465
|
+
def magnitude(self):
|
|
466
|
+
"""Get the magnitude of the source."""
|
|
467
|
+
return self._edb_object.GetSourceAmplitude().ToDouble()
|
|
468
|
+
|
|
469
|
+
@magnitude.setter
|
|
470
|
+
def magnitude(self, value):
|
|
471
|
+
self._edb_object.SetSourceAmplitude(self._edb.utility.value(value))
|
|
472
|
+
|
|
473
|
+
@property
|
|
474
|
+
def phase(self):
|
|
475
|
+
"""Get the phase of the source."""
|
|
476
|
+
return self._edb_object.GetSourcePhase().ToDouble()
|
|
477
|
+
|
|
478
|
+
@phase.setter
|
|
479
|
+
def phase(self, value):
|
|
480
|
+
self._edb_object.SetSourcePhase(self._edb.utility.value(value))
|