pyedb 0.10.dev0__py3-none-any.whl → 0.11.2__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_boundaries.py +115 -0
- pyedb/configuration/cfg_components.py +205 -0
- pyedb/configuration/cfg_data.py +38 -15
- pyedb/configuration/cfg_general.py +34 -0
- pyedb/{dotnet/sim_setup_data/data/siw_dc_ir_settings.py → configuration/cfg_nets.py} +18 -21
- pyedb/configuration/cfg_padstacks.py +125 -0
- pyedb/configuration/cfg_pin_groups.py +58 -0
- pyedb/configuration/cfg_ports_sources.py +164 -0
- pyedb/configuration/cfg_s_parameter_models.py +60 -0
- pyedb/configuration/cfg_setup.py +201 -0
- pyedb/configuration/cfg_spice_models.py +49 -0
- pyedb/configuration/configuration.py +37 -532
- pyedb/dotnet/edb.py +37 -8
- pyedb/dotnet/edb_core/components.py +43 -0
- pyedb/dotnet/edb_core/edb_data/hfss_pi_simulation_setup_data.py +465 -0
- pyedb/dotnet/edb_core/edb_data/nets_data.py +6 -2
- pyedb/dotnet/edb_core/edb_data/padstacks_data.py +17 -1
- pyedb/dotnet/edb_core/edb_data/raptor_x_simulation_setup_data.py +0 -4
- pyedb/dotnet/edb_core/edb_data/siwave_simulation_setup_data.py +4 -2
- pyedb/dotnet/edb_core/edb_data/sources.py +21 -5
- pyedb/dotnet/edb_core/edb_data/terminals.py +2 -1
- pyedb/dotnet/edb_core/layout.py +13 -8
- pyedb/dotnet/edb_core/nets.py +7 -3
- pyedb/dotnet/edb_core/padstack.py +23 -3
- pyedb/dotnet/edb_core/sim_setup_data/__init__.py +3 -0
- pyedb/dotnet/edb_core/sim_setup_data/data/__init__.py +3 -0
- pyedb/dotnet/edb_core/sim_setup_data/data/siw_dc_ir_settings.py +235 -0
- pyedb/dotnet/edb_core/siwave.py +2 -1
- pyedb/dotnet/edb_core/stackup.py +45 -33
- pyedb/dotnet/edb_core/utilities/simulation_setup.py +21 -5
- pyedb/generic/plot.py +6 -5
- pyedb/siwave.py +32 -6
- pyedb/siwave_core/icepak.py +153 -0
- {pyedb-0.10.dev0.dist-info → pyedb-0.11.2.dist-info}/METADATA +6 -6
- {pyedb-0.10.dev0.dist-info → pyedb-0.11.2.dist-info}/RECORD +38 -25
- pyedb/configuration/cfg_ports.py +0 -149
- {pyedb-0.10.dev0.dist-info → pyedb-0.11.2.dist-info}/LICENSE +0 -0
- {pyedb-0.10.dev0.dist-info → pyedb-0.11.2.dist-info}/WHEEL +0 -0
pyedb/dotnet/edb.py
CHANGED
|
@@ -46,6 +46,9 @@ from pyedb.dotnet.edb_core.edb_data.control_file import (
|
|
|
46
46
|
)
|
|
47
47
|
from pyedb.dotnet.edb_core.edb_data.design_options import EdbDesignOptions
|
|
48
48
|
from pyedb.dotnet.edb_core.edb_data.edbvalue import EdbValue
|
|
49
|
+
from pyedb.dotnet.edb_core.edb_data.hfss_pi_simulation_setup_data import (
|
|
50
|
+
HFSSPISimulationSetup,
|
|
51
|
+
)
|
|
49
52
|
from pyedb.dotnet.edb_core.edb_data.hfss_simulation_setup_data import (
|
|
50
53
|
HfssSimulationSetup,
|
|
51
54
|
)
|
|
@@ -194,7 +197,6 @@ class Edb(Database):
|
|
|
194
197
|
self.standalone = True
|
|
195
198
|
self.oproject = oproject
|
|
196
199
|
self._main = sys.modules["__main__"]
|
|
197
|
-
self.edbversion = edbversion
|
|
198
200
|
self.isaedtowned = isaedtowned
|
|
199
201
|
self.isreadonly = isreadonly
|
|
200
202
|
self.cellname = cellname
|
|
@@ -1525,9 +1527,7 @@ class Edb(Database):
|
|
|
1525
1527
|
"""
|
|
1526
1528
|
if tech_file or map_file:
|
|
1527
1529
|
control_file_temp = os.path.join(tempfile.gettempdir(), os.path.split(inputGDS)[-1][:-3] + "xml")
|
|
1528
|
-
|
|
1529
|
-
control_file_temp
|
|
1530
|
-
)
|
|
1530
|
+
ControlFile(xml_input=control_file, tecnhology=tech_file, layer_map=map_file).write_xml(control_file_temp)
|
|
1531
1531
|
elif tech_file:
|
|
1532
1532
|
self.logger.error("Technology files are supported only in Linux. Use control file instead.")
|
|
1533
1533
|
return False
|
|
@@ -1536,7 +1536,7 @@ class Edb(Database):
|
|
|
1536
1536
|
working_dir=WorkDir,
|
|
1537
1537
|
anstranslator_full_path=anstranslator_full_path,
|
|
1538
1538
|
use_ppe=use_ppe,
|
|
1539
|
-
control_file=
|
|
1539
|
+
control_file=control_file_temp,
|
|
1540
1540
|
):
|
|
1541
1541
|
return True
|
|
1542
1542
|
else:
|
|
@@ -3597,6 +3597,8 @@ class Edb(Database):
|
|
|
3597
3597
|
setups[i.GetName()] = SiwaveDCSimulationSetup(self, i)
|
|
3598
3598
|
elif i.GetType() == self.edb_api.utility.utility.SimulationSetupType.kRaptorX:
|
|
3599
3599
|
setups[i.GetName()] = RaptorXSimulationSetup(self, i)
|
|
3600
|
+
elif i.GetType() == self.edb_api.utility.utility.SimulationSetupType.kHFSSPI:
|
|
3601
|
+
setups[i.GetName()] = HFSSPISimulationSetup(self, i)
|
|
3600
3602
|
return setups
|
|
3601
3603
|
|
|
3602
3604
|
@property
|
|
@@ -3682,6 +3684,31 @@ class Edb(Database):
|
|
|
3682
3684
|
self.logger.error("RaptorX simulation only supported with Ansys release 2024R2 and higher")
|
|
3683
3685
|
return False
|
|
3684
3686
|
|
|
3687
|
+
def create_hfsspi_setup(self, name=None):
|
|
3688
|
+
"""Create an HFSS PI simulation setup from a template.
|
|
3689
|
+
|
|
3690
|
+
Parameters
|
|
3691
|
+
----------
|
|
3692
|
+
name : str, optional
|
|
3693
|
+
Setup name.
|
|
3694
|
+
|
|
3695
|
+
Returns
|
|
3696
|
+
-------
|
|
3697
|
+
:class:`legacy.edb_core.edb_data.hfss_pi_simulation_setup_data.HFSSPISimulationSetup when succeeded, ``False``
|
|
3698
|
+
when failed.
|
|
3699
|
+
|
|
3700
|
+
"""
|
|
3701
|
+
if name in self.setups:
|
|
3702
|
+
self.logger.error("Setup name already used in the layout")
|
|
3703
|
+
return False
|
|
3704
|
+
version = self.edbversion.split(".")
|
|
3705
|
+
if int(version[0]) == 2024 and int(version[-1]) >= 2 or int(version[0]) > 2024:
|
|
3706
|
+
setup = HFSSPISimulationSetup(self).create(name)
|
|
3707
|
+
return setup
|
|
3708
|
+
else:
|
|
3709
|
+
self.logger.error("HFSSPI simulation only supported with Ansys release 2024R2 and higher")
|
|
3710
|
+
return False
|
|
3711
|
+
|
|
3685
3712
|
@pyedb_function_handler()
|
|
3686
3713
|
def create_siwave_syz_setup(self, name=None):
|
|
3687
3714
|
"""Create a setup from a template.
|
|
@@ -3959,7 +3986,7 @@ class Edb(Database):
|
|
|
3959
3986
|
return connected_ports_list
|
|
3960
3987
|
|
|
3961
3988
|
@pyedb_function_handler
|
|
3962
|
-
def create_port(self, terminal, ref_terminal=None, is_circuit_port=False):
|
|
3989
|
+
def create_port(self, terminal, ref_terminal=None, is_circuit_port=False, name=None):
|
|
3963
3990
|
"""Create a port.
|
|
3964
3991
|
|
|
3965
3992
|
Parameters
|
|
@@ -3977,7 +4004,8 @@ class Edb(Database):
|
|
|
3977
4004
|
Negative terminal of the port.
|
|
3978
4005
|
is_circuit_port : bool, optional
|
|
3979
4006
|
Whether it is a circuit port. The default is ``False``.
|
|
3980
|
-
|
|
4007
|
+
name: str, optional
|
|
4008
|
+
Name of the created port. The default is None, a random name is generated.
|
|
3981
4009
|
Returns
|
|
3982
4010
|
-------
|
|
3983
4011
|
list: [:class:`pyedb.dotnet.edb_core.edb_data.ports.GapPort`,
|
|
@@ -3990,7 +4018,8 @@ class Edb(Database):
|
|
|
3990
4018
|
if ref_terminal:
|
|
3991
4019
|
ref_terminal.boundary_type = "PortBoundary"
|
|
3992
4020
|
terminal.ref_terminal = ref_terminal
|
|
3993
|
-
|
|
4021
|
+
if name:
|
|
4022
|
+
terminal.name = name
|
|
3994
4023
|
return self.ports[terminal.name]
|
|
3995
4024
|
|
|
3996
4025
|
@pyedb_function_handler
|
|
@@ -785,6 +785,8 @@ class Components(object):
|
|
|
785
785
|
reference_pins = [reference_pins]
|
|
786
786
|
if isinstance(refdes, str) or isinstance(refdes, EDBComponent):
|
|
787
787
|
refdes = self.instances[refdes]
|
|
788
|
+
if any(refdes.rlc_values):
|
|
789
|
+
return self.deactivate_rlc_component(component=refdes, create_circuit_port=True)
|
|
788
790
|
if len([pin for pin in pins if isinstance(pin, str)]) == len(pins):
|
|
789
791
|
cmp_pins = []
|
|
790
792
|
for pin_name in pins:
|
|
@@ -2289,6 +2291,18 @@ class Components(object):
|
|
|
2289
2291
|
f.writelines([delimiter.join([refdes, part_name, comp_type, value + "\n"])])
|
|
2290
2292
|
return True
|
|
2291
2293
|
|
|
2294
|
+
@pyedb_function_handler
|
|
2295
|
+
def find_by_reference_designator(self, reference_designator):
|
|
2296
|
+
"""Find a component.
|
|
2297
|
+
|
|
2298
|
+
Parameters
|
|
2299
|
+
----------
|
|
2300
|
+
reference_designator : str
|
|
2301
|
+
Reference designator of the component.
|
|
2302
|
+
"""
|
|
2303
|
+
obj = self._pedb.edb_api.cell.hierarchy.component.FindByName(self._active_layout, reference_designator)
|
|
2304
|
+
return EDBComponent(self._pedb, obj)
|
|
2305
|
+
|
|
2292
2306
|
@pyedb_function_handler()
|
|
2293
2307
|
def get_pin_from_component(self, component, netName=None, pinName=None):
|
|
2294
2308
|
"""Retrieve the pins of a component.
|
|
@@ -2317,6 +2331,7 @@ class Components(object):
|
|
|
2317
2331
|
>>> edbapp.components.get_pin_from_component("R1", refdes)
|
|
2318
2332
|
|
|
2319
2333
|
"""
|
|
2334
|
+
warnings.warn("Use new property :func:`edb.padstacks.get_instances` instead.", DeprecationWarning)
|
|
2320
2335
|
if not isinstance(component, self._pedb.edb_api.cell.hierarchy.component):
|
|
2321
2336
|
component = self._pedb.edb_api.cell.hierarchy.component.FindByName(self._active_layout, component)
|
|
2322
2337
|
if netName:
|
|
@@ -2373,6 +2388,34 @@ class Components(object):
|
|
|
2373
2388
|
name = str(name).strip("'")
|
|
2374
2389
|
return name
|
|
2375
2390
|
|
|
2391
|
+
@pyedb_function_handler
|
|
2392
|
+
def get_pins(self, reference_designator, net_name=None, pin_name=None):
|
|
2393
|
+
"""Get component pins.
|
|
2394
|
+
|
|
2395
|
+
Parameters
|
|
2396
|
+
----------
|
|
2397
|
+
reference_designator : str
|
|
2398
|
+
Reference designator of the component.
|
|
2399
|
+
net_name : str, optional
|
|
2400
|
+
Name of the net.
|
|
2401
|
+
pin_name : str, optional
|
|
2402
|
+
Name of the pin.
|
|
2403
|
+
|
|
2404
|
+
Returns
|
|
2405
|
+
-------
|
|
2406
|
+
|
|
2407
|
+
"""
|
|
2408
|
+
comp = self.find_by_reference_designator(reference_designator)
|
|
2409
|
+
|
|
2410
|
+
pins = comp.pins
|
|
2411
|
+
if net_name:
|
|
2412
|
+
pins = {i: j for i, j in pins.items() if j.net_name == net_name}
|
|
2413
|
+
|
|
2414
|
+
if pin_name:
|
|
2415
|
+
pins = {i: j for i, j in pins.items() if i == pin_name}
|
|
2416
|
+
|
|
2417
|
+
return pins
|
|
2418
|
+
|
|
2376
2419
|
@pyedb_function_handler()
|
|
2377
2420
|
def get_pin_position(self, pin):
|
|
2378
2421
|
"""Retrieve the pin position in meters.
|
|
@@ -0,0 +1,465 @@
|
|
|
1
|
+
# Copyright (C) 2023 - 2024 ANSYS, Inc. and/or its affiliates.
|
|
2
|
+
# SPDX-License-Identifier: MIT
|
|
3
|
+
#
|
|
4
|
+
#
|
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
# furnished to do so, subject to the following conditions:
|
|
11
|
+
#
|
|
12
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
# copies or substantial portions of the Software.
|
|
14
|
+
#
|
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
# FITNE SS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
# SOFTWARE.
|
|
22
|
+
|
|
23
|
+
from pyedb.dotnet.edb_core.general import convert_py_list_to_net_list
|
|
24
|
+
from pyedb.dotnet.edb_core.utilities.simulation_setup import (
|
|
25
|
+
BaseSimulationSetup,
|
|
26
|
+
EdbFrequencySweep,
|
|
27
|
+
)
|
|
28
|
+
from pyedb.generic.data_handlers import pyedb_function_handler
|
|
29
|
+
from pyedb.generic.general_methods import generate_unique_name
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class HFSSPISimulationSetup(BaseSimulationSetup):
|
|
33
|
+
"""Manages EDB methods for HFSSPI simulation setup."""
|
|
34
|
+
|
|
35
|
+
def __init__(self, pedb, edb_object=None):
|
|
36
|
+
super().__init__(pedb, edb_object)
|
|
37
|
+
self._pedb = pedb
|
|
38
|
+
self._setup_type = "kHFSSPI"
|
|
39
|
+
self._edb_setup_info = None
|
|
40
|
+
self.logger = self._pedb.logger
|
|
41
|
+
|
|
42
|
+
@pyedb_function_handler
|
|
43
|
+
def create(self, name=None):
|
|
44
|
+
"""Create an HFSS setup."""
|
|
45
|
+
self._name = name
|
|
46
|
+
self._create(name)
|
|
47
|
+
return self
|
|
48
|
+
|
|
49
|
+
@property
|
|
50
|
+
def setup_type(self):
|
|
51
|
+
return self._setup_type
|
|
52
|
+
|
|
53
|
+
@property
|
|
54
|
+
def settings(self):
|
|
55
|
+
return HFSSPISimulationSettings(self._edb_setup_info, self._pedb)
|
|
56
|
+
|
|
57
|
+
@property
|
|
58
|
+
def enabled(self):
|
|
59
|
+
return self.settings.enabled
|
|
60
|
+
|
|
61
|
+
@enabled.setter
|
|
62
|
+
def enabled(self, value):
|
|
63
|
+
if isinstance(value, bool):
|
|
64
|
+
self.settings.enabled = value
|
|
65
|
+
else:
|
|
66
|
+
self.logger.error(f"Property enabled expects a boolean value while the provided value is {value}.")
|
|
67
|
+
|
|
68
|
+
@property
|
|
69
|
+
def position(self):
|
|
70
|
+
return self._edb_setup_info.Position
|
|
71
|
+
|
|
72
|
+
@position.setter
|
|
73
|
+
def position(self, value):
|
|
74
|
+
if isinstance(value, int):
|
|
75
|
+
self._edb_setup_info.Position = value
|
|
76
|
+
else:
|
|
77
|
+
self.logger.error(f"Property position expects an integer value while the provided value is {value}.")
|
|
78
|
+
|
|
79
|
+
@pyedb_function_handler()
|
|
80
|
+
def add_frequency_sweep(self, name=None, frequency_sweep=None):
|
|
81
|
+
"""Add frequency sweep.
|
|
82
|
+
|
|
83
|
+
Parameters
|
|
84
|
+
----------
|
|
85
|
+
name : str, optional
|
|
86
|
+
Name of the frequency sweep.
|
|
87
|
+
frequency_sweep : list, optional
|
|
88
|
+
List of frequency points.
|
|
89
|
+
|
|
90
|
+
Returns
|
|
91
|
+
-------
|
|
92
|
+
:class:`pyedb.dotnet.edb_core.edb_data.hfss_simulation_setup_data.EdbFrequencySweep`wheen succeeded, ``False``
|
|
93
|
+
when failed.
|
|
94
|
+
|
|
95
|
+
Examples
|
|
96
|
+
--------
|
|
97
|
+
>>> setup1 = edbapp.create_hfss_setup("setup1")
|
|
98
|
+
>>> setup1.add_frequency_sweep(frequency_sweep=[
|
|
99
|
+
... ["linear count", "0", "1kHz", 1],
|
|
100
|
+
... ["log scale", "1kHz", "0.1GHz", 10],
|
|
101
|
+
... ["linear scale", "0.1GHz", "10GHz", "0.1GHz"],
|
|
102
|
+
... ])
|
|
103
|
+
"""
|
|
104
|
+
if name in self.frequency_sweeps:
|
|
105
|
+
self.logger.error("Frequency sweep with same name already defined.")
|
|
106
|
+
return False
|
|
107
|
+
if not name:
|
|
108
|
+
name = generate_unique_name("sweep")
|
|
109
|
+
return EdbFrequencySweep(self, frequency_sweep, name)
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
class HFSSPISimulationSettings(object):
|
|
113
|
+
def __init__(self, edb_setup_info, pedb):
|
|
114
|
+
self._pedb = pedb
|
|
115
|
+
self.logger = self._pedb.logger
|
|
116
|
+
self._edb_setup_info = edb_setup_info
|
|
117
|
+
self._simulation_settings = edb_setup_info.SimulationSettings
|
|
118
|
+
|
|
119
|
+
@property
|
|
120
|
+
def auto_select_nets_for_simulation(self):
|
|
121
|
+
"""Auto select nets for simulation.
|
|
122
|
+
|
|
123
|
+
Returns
|
|
124
|
+
-------
|
|
125
|
+
bool
|
|
126
|
+
"""
|
|
127
|
+
return self._simulation_settings.AutoSelectNetsForSimulation
|
|
128
|
+
|
|
129
|
+
@auto_select_nets_for_simulation.setter
|
|
130
|
+
def auto_select_nets_for_simulation(self, value):
|
|
131
|
+
if isinstance(value, bool):
|
|
132
|
+
self._simulation_settings.AutoSelectNetsForSimulation = value
|
|
133
|
+
else:
|
|
134
|
+
self.logger.error(
|
|
135
|
+
"Property auto_select_nets_for_simulation expects a boolean "
|
|
136
|
+
f"value while the provided value is {value}."
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
@property
|
|
140
|
+
def enabled(self):
|
|
141
|
+
return self._simulation_settings.Enabled
|
|
142
|
+
|
|
143
|
+
@enabled.setter
|
|
144
|
+
def enabled(self, value):
|
|
145
|
+
if isinstance(value, bool):
|
|
146
|
+
self._simulation_settings.Enabled = value
|
|
147
|
+
else:
|
|
148
|
+
self.logger.error(f"Property enabled expects a boolean value while the provided value is {value}.")
|
|
149
|
+
|
|
150
|
+
@property
|
|
151
|
+
def ignore_dummy_nets_for_selected_nets(self):
|
|
152
|
+
"""Auto select Nets for simulation
|
|
153
|
+
|
|
154
|
+
Returns
|
|
155
|
+
-------
|
|
156
|
+
bool
|
|
157
|
+
"""
|
|
158
|
+
return self._simulation_settings.IgnoreDummyNetsForSelectedNets
|
|
159
|
+
|
|
160
|
+
@ignore_dummy_nets_for_selected_nets.setter
|
|
161
|
+
def ignore_dummy_nets_for_selected_nets(self, value):
|
|
162
|
+
if isinstance(value, bool):
|
|
163
|
+
self._simulation_settings.IgnoreDummyNetsForSelectedNets = value
|
|
164
|
+
else:
|
|
165
|
+
self.logger.error(
|
|
166
|
+
"Property ignore_dummy_nets_for_selected_nets expects a boolean "
|
|
167
|
+
f"value while the provided value is {value}."
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
@property
|
|
171
|
+
def ignore_small_holes(self):
|
|
172
|
+
"""Ignore small holes choice.
|
|
173
|
+
|
|
174
|
+
Returns
|
|
175
|
+
-------
|
|
176
|
+
bool
|
|
177
|
+
"""
|
|
178
|
+
return self._simulation_settings.IgnoreSmallHoles
|
|
179
|
+
|
|
180
|
+
@ignore_small_holes.setter
|
|
181
|
+
def ignore_small_holes(self, value):
|
|
182
|
+
if isinstance(value, bool):
|
|
183
|
+
self._simulation_settings.IgnoreSmallHoles = value
|
|
184
|
+
else:
|
|
185
|
+
self.logger.error(
|
|
186
|
+
f"Property ignore_small_holes expects a boolean value while the provided value is {value}."
|
|
187
|
+
)
|
|
188
|
+
|
|
189
|
+
@property
|
|
190
|
+
def ignore_small_holes_min_diameter(self):
|
|
191
|
+
"""Min diameter to ignore small holes.
|
|
192
|
+
|
|
193
|
+
Returns
|
|
194
|
+
-------
|
|
195
|
+
str
|
|
196
|
+
"""
|
|
197
|
+
return self._simulation_settings.IgnoreSmallHolesMinDiameter
|
|
198
|
+
|
|
199
|
+
@ignore_small_holes_min_diameter.setter
|
|
200
|
+
def ignore_small_holes_min_diameter(self, value):
|
|
201
|
+
self._simulation_settings.IgnoreSmallHolesMinDiameter = self._pedb.edb_value(value).ToString()
|
|
202
|
+
|
|
203
|
+
@property
|
|
204
|
+
def improved_loss_model(self):
|
|
205
|
+
"""Improved Loss Model on power ground nets option.
|
|
206
|
+
|
|
207
|
+
Returns
|
|
208
|
+
-------
|
|
209
|
+
str
|
|
210
|
+
``Level1``, ``Level2``, ``Level3``
|
|
211
|
+
"""
|
|
212
|
+
return self._simulation_settings.ImprovedLossModel
|
|
213
|
+
|
|
214
|
+
@improved_loss_model.setter
|
|
215
|
+
def improved_loss_model(self, value):
|
|
216
|
+
expected_values = ["Level1", "Level2", "Level3"]
|
|
217
|
+
if isinstance(value, str) and value in expected_values:
|
|
218
|
+
self._simulation_settings.ImprovedLossModel = value
|
|
219
|
+
else:
|
|
220
|
+
self.logger.error(
|
|
221
|
+
"Property improved_loss_model expects a string value among "
|
|
222
|
+
f"'Level1', 'Level2' or 'Level3' while the provided value is {value}."
|
|
223
|
+
)
|
|
224
|
+
|
|
225
|
+
@property
|
|
226
|
+
def include_enhanced_bond_wire_modeling(self):
|
|
227
|
+
"""Enhance Bond wire modeling.
|
|
228
|
+
|
|
229
|
+
Returns
|
|
230
|
+
-------
|
|
231
|
+
bool
|
|
232
|
+
"""
|
|
233
|
+
return self._simulation_settings.IncludeEnhancedBondWireModeling
|
|
234
|
+
|
|
235
|
+
@include_enhanced_bond_wire_modeling.setter
|
|
236
|
+
def include_enhanced_bond_wire_modeling(self, value):
|
|
237
|
+
if isinstance(value, bool):
|
|
238
|
+
self._simulation_settings.IncludeEnhancedBondWireModeling = value
|
|
239
|
+
else:
|
|
240
|
+
self.logger.error(
|
|
241
|
+
"Property include_enhanced_bond_wire_modeling expects a "
|
|
242
|
+
f"boolean value while the provided value is {value}."
|
|
243
|
+
)
|
|
244
|
+
|
|
245
|
+
@property
|
|
246
|
+
def include_nets(self):
|
|
247
|
+
"""Add Additional Nets for simulation.
|
|
248
|
+
|
|
249
|
+
Returns
|
|
250
|
+
-------
|
|
251
|
+
[str]
|
|
252
|
+
List of net name.
|
|
253
|
+
"""
|
|
254
|
+
return list(self._simulation_settings.IncludeNets)
|
|
255
|
+
|
|
256
|
+
@include_nets.setter
|
|
257
|
+
def include_nets(self, value):
|
|
258
|
+
if isinstance(value, str):
|
|
259
|
+
value = [value]
|
|
260
|
+
if isinstance(value, list):
|
|
261
|
+
self._simulation_settings.IncludeNets = convert_py_list_to_net_list(value)
|
|
262
|
+
else:
|
|
263
|
+
self.logger.error(
|
|
264
|
+
f"Property include_nets expects a string or list of string while the provided value is {value}."
|
|
265
|
+
)
|
|
266
|
+
|
|
267
|
+
@property
|
|
268
|
+
def min_plane_area_to_mesh(self):
|
|
269
|
+
"""The minimum area below which geometry is ignored.
|
|
270
|
+
|
|
271
|
+
Returns
|
|
272
|
+
-------
|
|
273
|
+
str
|
|
274
|
+
"""
|
|
275
|
+
return self._simulation_settings.MinPlaneAreaToMesh
|
|
276
|
+
|
|
277
|
+
@min_plane_area_to_mesh.setter
|
|
278
|
+
def min_plane_area_to_mesh(self, value):
|
|
279
|
+
self._simulation_settings.MinPlaneAreaToMesh = self._pedb.edb_value(value).ToString()
|
|
280
|
+
|
|
281
|
+
@property
|
|
282
|
+
def min_void_area_to_mesh(self):
|
|
283
|
+
"""The minimum area below which voids are ignored.
|
|
284
|
+
|
|
285
|
+
Returns
|
|
286
|
+
-------
|
|
287
|
+
str
|
|
288
|
+
"""
|
|
289
|
+
return self._simulation_settings.MinVoidAreaToMesh
|
|
290
|
+
|
|
291
|
+
@min_void_area_to_mesh.setter
|
|
292
|
+
def min_void_area_to_mesh(self, value):
|
|
293
|
+
self._simulation_settings.MinVoidAreaToMesh = self._pedb.edb_value(value).ToString()
|
|
294
|
+
|
|
295
|
+
@property
|
|
296
|
+
def model_type(self):
|
|
297
|
+
"""Model Type setting.
|
|
298
|
+
|
|
299
|
+
Returns
|
|
300
|
+
-------
|
|
301
|
+
int
|
|
302
|
+
Model type: ``0``=RDL, ``1``=Package, ``2``=PCB
|
|
303
|
+
"""
|
|
304
|
+
return self._simulation_settings.ModelType
|
|
305
|
+
|
|
306
|
+
@model_type.setter
|
|
307
|
+
def model_type(self, value):
|
|
308
|
+
if isinstance(value, int) and value in range(3):
|
|
309
|
+
self._simulation_settings.ModelType = value
|
|
310
|
+
else:
|
|
311
|
+
self.logger.error(
|
|
312
|
+
f"Property model_type expects an integer value among 0, 1 or 2 while the provided value is {value}."
|
|
313
|
+
)
|
|
314
|
+
|
|
315
|
+
@property
|
|
316
|
+
def perform_erc(self):
|
|
317
|
+
"""Perform ERC
|
|
318
|
+
|
|
319
|
+
Returns
|
|
320
|
+
-------
|
|
321
|
+
bool
|
|
322
|
+
"""
|
|
323
|
+
return self._simulation_settings.PerformERC
|
|
324
|
+
|
|
325
|
+
@perform_erc.setter
|
|
326
|
+
def perform_erc(self, value):
|
|
327
|
+
if isinstance(value, bool):
|
|
328
|
+
self._simulation_settings.PerformERC = value
|
|
329
|
+
else:
|
|
330
|
+
self.logger.error(f"Property perform_erc expects a boolean value while the provided value is {value}.")
|
|
331
|
+
|
|
332
|
+
@property
|
|
333
|
+
def pi_slider_pos(self):
|
|
334
|
+
"""The Simulation Preference Slider setting
|
|
335
|
+
|
|
336
|
+
Returns
|
|
337
|
+
-------
|
|
338
|
+
int
|
|
339
|
+
Model type: ``0``= balanced, ``1``=Accuracy.
|
|
340
|
+
"""
|
|
341
|
+
return self._simulation_settings.PISliderPos
|
|
342
|
+
|
|
343
|
+
@pi_slider_pos.setter
|
|
344
|
+
def pi_slider_pos(self, value):
|
|
345
|
+
if isinstance(value, int) and value in range(2):
|
|
346
|
+
self._simulation_settings.PISliderPos = value
|
|
347
|
+
else:
|
|
348
|
+
self.logger.error(
|
|
349
|
+
f"Property pi_slider_pos expects an integer value among 0 or 1 while the provided value is {value}."
|
|
350
|
+
)
|
|
351
|
+
|
|
352
|
+
@property
|
|
353
|
+
def rms_surface_roughness(self):
|
|
354
|
+
"""RMS Surface Roughness setting
|
|
355
|
+
|
|
356
|
+
Returns
|
|
357
|
+
-------
|
|
358
|
+
str
|
|
359
|
+
"""
|
|
360
|
+
return self._simulation_settings.RMSSurfaceRoughness
|
|
361
|
+
|
|
362
|
+
@rms_surface_roughness.setter
|
|
363
|
+
def rms_surface_roughness(self, value):
|
|
364
|
+
self._simulation_settings.RMSSurfaceRoughness = self._pedb.edb_value(value).ToString()
|
|
365
|
+
|
|
366
|
+
@property
|
|
367
|
+
def signal_nets_conductor_modeling(self):
|
|
368
|
+
"""Conductor Modeling
|
|
369
|
+
|
|
370
|
+
Returns
|
|
371
|
+
-------
|
|
372
|
+
str
|
|
373
|
+
Value: ``"MeshInside"`` or ``"ImpedanceBoundary"``.
|
|
374
|
+
"""
|
|
375
|
+
return self._simulation_settings.SignalNetsConductorModeling
|
|
376
|
+
|
|
377
|
+
@signal_nets_conductor_modeling.setter
|
|
378
|
+
def signal_nets_conductor_modeling(self, value):
|
|
379
|
+
expected_values = ["MeshInside", "ImpedanceBoundary"]
|
|
380
|
+
if isinstance(value, str) and value in expected_values:
|
|
381
|
+
self._simulation_settings.SignalNetsConductorModeling = value
|
|
382
|
+
else:
|
|
383
|
+
self.logger.error(
|
|
384
|
+
"Property signal_nets_conductor_modeling expects a string value among "
|
|
385
|
+
f"'MeshInside' or 'ImpedanceBoundary' while the provided value is {value}."
|
|
386
|
+
)
|
|
387
|
+
|
|
388
|
+
@property
|
|
389
|
+
def signal_nets_error_tolerance(self):
|
|
390
|
+
"""Error Tolerance
|
|
391
|
+
|
|
392
|
+
Returns
|
|
393
|
+
-------
|
|
394
|
+
str
|
|
395
|
+
Value between 0.02 and 1.
|
|
396
|
+
"""
|
|
397
|
+
return self._simulation_settings.SignalNetsErrorTolerance
|
|
398
|
+
|
|
399
|
+
@signal_nets_error_tolerance.setter
|
|
400
|
+
def signal_nets_error_tolerance(self, value):
|
|
401
|
+
self._simulation_settings.SignalNetsErrorTolerance = self._pedb.edb_value(value).ToString()
|
|
402
|
+
|
|
403
|
+
@property
|
|
404
|
+
def signal_nets_include_improved_dielectric_fill_refinement(self):
|
|
405
|
+
return self._simulation_settings.SignalNetsIncludeImprovedDielectricFillRefinement
|
|
406
|
+
|
|
407
|
+
@signal_nets_include_improved_dielectric_fill_refinement.setter
|
|
408
|
+
def signal_nets_include_improved_dielectric_fill_refinement(self, value):
|
|
409
|
+
if isinstance(value, bool):
|
|
410
|
+
self._simulation_settings.SignalNetsIncludeImprovedDielectricFillRefinement = value
|
|
411
|
+
else:
|
|
412
|
+
self.logger.error(
|
|
413
|
+
"Property signal_nets_include_improved_dielectric_fill_refinement "
|
|
414
|
+
f"expects a boolean value while the provided value is {value}."
|
|
415
|
+
)
|
|
416
|
+
|
|
417
|
+
@property
|
|
418
|
+
def signal_nets_include_improved_loss_handling(self):
|
|
419
|
+
"""Improved Dielectric Fill Refinement choice.
|
|
420
|
+
|
|
421
|
+
Returns
|
|
422
|
+
-------
|
|
423
|
+
bool
|
|
424
|
+
"""
|
|
425
|
+
return self._simulation_settings.SignalNetsIncludeImprovedLossHandling
|
|
426
|
+
|
|
427
|
+
@signal_nets_include_improved_loss_handling.setter
|
|
428
|
+
def signal_nets_include_improved_loss_handling(self, value):
|
|
429
|
+
if isinstance(value, bool):
|
|
430
|
+
self._simulation_settings.SignalNetsIncludeImprovedLossHandling = value
|
|
431
|
+
else:
|
|
432
|
+
self.logger.error(
|
|
433
|
+
"Property signal_nets_include_improved_loss_handling "
|
|
434
|
+
f"expects a boolean value while the provided value is {value}."
|
|
435
|
+
)
|
|
436
|
+
|
|
437
|
+
@property
|
|
438
|
+
def snap_length_threshold(self):
|
|
439
|
+
return self._simulation_settings.SnapLengthThreshold
|
|
440
|
+
|
|
441
|
+
@snap_length_threshold.setter
|
|
442
|
+
def snap_length_threshold(self, value):
|
|
443
|
+
self._simulation_settings.SnapLengthThreshold = self._pedb.edb_value(value).ToString()
|
|
444
|
+
|
|
445
|
+
@property
|
|
446
|
+
def surface_roughness_model(self):
|
|
447
|
+
"""Chosen Model setting
|
|
448
|
+
|
|
449
|
+
Returns
|
|
450
|
+
-------
|
|
451
|
+
str
|
|
452
|
+
Model allowed, ``"None"``, ``"Exponential"`` or ``"Hammerstad"``.
|
|
453
|
+
"""
|
|
454
|
+
return self._simulation_settings.SurfaceRoughnessModel
|
|
455
|
+
|
|
456
|
+
@surface_roughness_model.setter
|
|
457
|
+
def surface_roughness_model(self, value):
|
|
458
|
+
expected_values = ["None", "Exponential", "Hammerstad"]
|
|
459
|
+
if isinstance(value, str) and value in expected_values:
|
|
460
|
+
self._simulation_settings.SurfaceRoughnessModel = value
|
|
461
|
+
else:
|
|
462
|
+
self.logger.error(
|
|
463
|
+
"Property surface_roughness_model expects a string value among "
|
|
464
|
+
f"'None', 'Exponential' or 'Hammerstad' while the provided value is {value}."
|
|
465
|
+
)
|
|
@@ -123,6 +123,7 @@ class EDBNetsData(NetDotNet):
|
|
|
123
123
|
save_plot=None,
|
|
124
124
|
outline=None,
|
|
125
125
|
size=(2000, 1000),
|
|
126
|
+
show=True,
|
|
126
127
|
):
|
|
127
128
|
"""Plot a net to Matplotlib 2D chart.
|
|
128
129
|
|
|
@@ -134,12 +135,14 @@ class EDBNetsData(NetDotNet):
|
|
|
134
135
|
If `True` the legend is shown in the plot. (default)
|
|
135
136
|
If `False` the legend is not shown.
|
|
136
137
|
save_plot : str, optional
|
|
137
|
-
If
|
|
138
|
-
If
|
|
138
|
+
If a path is specified the plot will be saved in this location.
|
|
139
|
+
If ``save_plot`` is provided, the ``show`` parameter is ignored.
|
|
139
140
|
outline : list, optional
|
|
140
141
|
List of points of the outline to plot.
|
|
141
142
|
size : tuple, optional
|
|
142
143
|
Image size in pixel (width, height).
|
|
144
|
+
show : bool, optional
|
|
145
|
+
Whether to show the plot or not. Default is `True`.
|
|
143
146
|
"""
|
|
144
147
|
|
|
145
148
|
self._app.nets.plot(
|
|
@@ -149,6 +152,7 @@ class EDBNetsData(NetDotNet):
|
|
|
149
152
|
save_plot=save_plot,
|
|
150
153
|
outline=outline,
|
|
151
154
|
size=size,
|
|
155
|
+
show=show,
|
|
152
156
|
)
|
|
153
157
|
|
|
154
158
|
@pyedb_function_handler()
|