pyedb 0.2.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 +17 -0
- pyedb/dotnet/__init__.py +0 -0
- pyedb/dotnet/application/Variables.py +2261 -0
- pyedb/dotnet/application/__init__.py +0 -0
- pyedb/dotnet/clr_module.py +103 -0
- pyedb/dotnet/edb.py +4237 -0
- pyedb/dotnet/edb_core/__init__.py +1 -0
- pyedb/dotnet/edb_core/cell/__init__.py +0 -0
- pyedb/dotnet/edb_core/cell/hierarchy/__init__.py +0 -0
- pyedb/dotnet/edb_core/cell/hierarchy/model.py +66 -0
- pyedb/dotnet/edb_core/components.py +2669 -0
- pyedb/dotnet/edb_core/configuration.py +423 -0
- pyedb/dotnet/edb_core/definition/__init__.py +0 -0
- pyedb/dotnet/edb_core/definition/component_def.py +166 -0
- pyedb/dotnet/edb_core/definition/component_model.py +30 -0
- pyedb/dotnet/edb_core/definition/definition_obj.py +18 -0
- pyedb/dotnet/edb_core/definition/definitions.py +12 -0
- pyedb/dotnet/edb_core/dotnet/__init__.py +0 -0
- pyedb/dotnet/edb_core/dotnet/database.py +1218 -0
- pyedb/dotnet/edb_core/dotnet/layout.py +238 -0
- pyedb/dotnet/edb_core/dotnet/primitive.py +1517 -0
- pyedb/dotnet/edb_core/edb_data/__init__.py +0 -0
- pyedb/dotnet/edb_core/edb_data/components_data.py +938 -0
- pyedb/dotnet/edb_core/edb_data/connectable.py +113 -0
- pyedb/dotnet/edb_core/edb_data/control_file.py +1268 -0
- pyedb/dotnet/edb_core/edb_data/design_options.py +35 -0
- pyedb/dotnet/edb_core/edb_data/edbvalue.py +45 -0
- pyedb/dotnet/edb_core/edb_data/hfss_extent_info.py +330 -0
- pyedb/dotnet/edb_core/edb_data/hfss_simulation_setup_data.py +1607 -0
- pyedb/dotnet/edb_core/edb_data/layer_data.py +576 -0
- pyedb/dotnet/edb_core/edb_data/nets_data.py +281 -0
- pyedb/dotnet/edb_core/edb_data/obj_base.py +19 -0
- pyedb/dotnet/edb_core/edb_data/padstacks_data.py +2080 -0
- pyedb/dotnet/edb_core/edb_data/ports.py +287 -0
- pyedb/dotnet/edb_core/edb_data/primitives_data.py +1397 -0
- pyedb/dotnet/edb_core/edb_data/simulation_configuration.py +2914 -0
- pyedb/dotnet/edb_core/edb_data/simulation_setup.py +716 -0
- pyedb/dotnet/edb_core/edb_data/siwave_simulation_setup_data.py +1205 -0
- pyedb/dotnet/edb_core/edb_data/sources.py +514 -0
- pyedb/dotnet/edb_core/edb_data/terminals.py +632 -0
- pyedb/dotnet/edb_core/edb_data/utilities.py +148 -0
- pyedb/dotnet/edb_core/edb_data/variables.py +91 -0
- pyedb/dotnet/edb_core/general.py +181 -0
- pyedb/dotnet/edb_core/hfss.py +1646 -0
- pyedb/dotnet/edb_core/layout.py +1244 -0
- pyedb/dotnet/edb_core/layout_validation.py +272 -0
- pyedb/dotnet/edb_core/materials.py +939 -0
- pyedb/dotnet/edb_core/net_class.py +335 -0
- pyedb/dotnet/edb_core/nets.py +1215 -0
- pyedb/dotnet/edb_core/padstack.py +1389 -0
- pyedb/dotnet/edb_core/siwave.py +1427 -0
- pyedb/dotnet/edb_core/stackup.py +2703 -0
- pyedb/edb_logger.py +396 -0
- pyedb/generic/__init__.py +0 -0
- pyedb/generic/constants.py +1063 -0
- pyedb/generic/data_handlers.py +320 -0
- pyedb/generic/design_types.py +104 -0
- pyedb/generic/filesystem.py +150 -0
- pyedb/generic/general_methods.py +1535 -0
- pyedb/generic/plot.py +1840 -0
- pyedb/generic/process.py +285 -0
- pyedb/generic/settings.py +224 -0
- pyedb/ipc2581/__init__.py +0 -0
- pyedb/ipc2581/bom/__init__.py +0 -0
- pyedb/ipc2581/bom/bom.py +21 -0
- pyedb/ipc2581/bom/bom_item.py +32 -0
- pyedb/ipc2581/bom/characteristics.py +37 -0
- pyedb/ipc2581/bom/refdes.py +16 -0
- pyedb/ipc2581/content/__init__.py +0 -0
- pyedb/ipc2581/content/color.py +38 -0
- pyedb/ipc2581/content/content.py +55 -0
- pyedb/ipc2581/content/dictionary_color.py +29 -0
- pyedb/ipc2581/content/dictionary_fill.py +28 -0
- pyedb/ipc2581/content/dictionary_line.py +30 -0
- pyedb/ipc2581/content/entry_color.py +13 -0
- pyedb/ipc2581/content/entry_line.py +14 -0
- pyedb/ipc2581/content/fill.py +15 -0
- pyedb/ipc2581/content/layer_ref.py +10 -0
- pyedb/ipc2581/content/standard_geometries_dictionary.py +72 -0
- pyedb/ipc2581/ecad/__init__.py +0 -0
- pyedb/ipc2581/ecad/cad_data/__init__.py +0 -0
- pyedb/ipc2581/ecad/cad_data/assembly_drawing.py +26 -0
- pyedb/ipc2581/ecad/cad_data/cad_data.py +37 -0
- pyedb/ipc2581/ecad/cad_data/component.py +41 -0
- pyedb/ipc2581/ecad/cad_data/drill.py +30 -0
- pyedb/ipc2581/ecad/cad_data/feature.py +54 -0
- pyedb/ipc2581/ecad/cad_data/layer.py +41 -0
- pyedb/ipc2581/ecad/cad_data/layer_feature.py +151 -0
- pyedb/ipc2581/ecad/cad_data/logical_net.py +32 -0
- pyedb/ipc2581/ecad/cad_data/outline.py +25 -0
- pyedb/ipc2581/ecad/cad_data/package.py +104 -0
- pyedb/ipc2581/ecad/cad_data/padstack_def.py +38 -0
- pyedb/ipc2581/ecad/cad_data/padstack_hole_def.py +24 -0
- pyedb/ipc2581/ecad/cad_data/padstack_instance.py +62 -0
- pyedb/ipc2581/ecad/cad_data/padstack_pad_def.py +26 -0
- pyedb/ipc2581/ecad/cad_data/path.py +89 -0
- pyedb/ipc2581/ecad/cad_data/phy_net.py +80 -0
- pyedb/ipc2581/ecad/cad_data/pin.py +31 -0
- pyedb/ipc2581/ecad/cad_data/polygon.py +169 -0
- pyedb/ipc2581/ecad/cad_data/profile.py +40 -0
- pyedb/ipc2581/ecad/cad_data/stackup.py +31 -0
- pyedb/ipc2581/ecad/cad_data/stackup_group.py +42 -0
- pyedb/ipc2581/ecad/cad_data/stackup_layer.py +21 -0
- pyedb/ipc2581/ecad/cad_data/step.py +275 -0
- pyedb/ipc2581/ecad/cad_header.py +33 -0
- pyedb/ipc2581/ecad/ecad.py +19 -0
- pyedb/ipc2581/ecad/spec.py +46 -0
- pyedb/ipc2581/history_record.py +37 -0
- pyedb/ipc2581/ipc2581.py +387 -0
- pyedb/ipc2581/logistic_header.py +25 -0
- pyedb/misc/__init__.py +0 -0
- pyedb/misc/aedtlib_personalib_install.py +14 -0
- pyedb/misc/downloads.py +322 -0
- pyedb/misc/misc.py +67 -0
- pyedb/misc/pyedb.runtimeconfig.json +13 -0
- pyedb/misc/siw_feature_config/__init__.py +0 -0
- pyedb/misc/siw_feature_config/emc/__init__.py +0 -0
- pyedb/misc/siw_feature_config/emc/component_tags.py +46 -0
- pyedb/misc/siw_feature_config/emc/net_tags.py +37 -0
- pyedb/misc/siw_feature_config/emc/tag_library.py +62 -0
- pyedb/misc/siw_feature_config/emc/xml_generic.py +78 -0
- pyedb/misc/siw_feature_config/emc_rule_checker_settings.py +179 -0
- pyedb/misc/utilities.py +27 -0
- pyedb/modeler/geometry_operators.py +2082 -0
- pyedb-0.2.0.dist-info/LICENSE +21 -0
- pyedb-0.2.0.dist-info/METADATA +208 -0
- pyedb-0.2.0.dist-info/RECORD +128 -0
- pyedb-0.2.0.dist-info/WHEEL +4 -0
|
@@ -0,0 +1,1205 @@
|
|
|
1
|
+
import warnings
|
|
2
|
+
|
|
3
|
+
from pyedb.dotnet.edb_core.edb_data.simulation_setup import BaseSimulationSetup
|
|
4
|
+
from pyedb.dotnet.edb_core.general import (
|
|
5
|
+
convert_netdict_to_pydict,
|
|
6
|
+
convert_pydict_to_netdict,
|
|
7
|
+
)
|
|
8
|
+
from pyedb.generic.general_methods import is_linux, pyedb_function_handler
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def _parse_value(v):
|
|
12
|
+
"""Parse value in C sharp format."""
|
|
13
|
+
# duck typing parse of the value 'v'
|
|
14
|
+
if v is None or v == "":
|
|
15
|
+
pv = v
|
|
16
|
+
elif v == "true":
|
|
17
|
+
pv = True
|
|
18
|
+
elif v == "false":
|
|
19
|
+
pv = False
|
|
20
|
+
else:
|
|
21
|
+
try:
|
|
22
|
+
pv = int(v)
|
|
23
|
+
except ValueError:
|
|
24
|
+
try:
|
|
25
|
+
pv = float(v)
|
|
26
|
+
except ValueError:
|
|
27
|
+
if isinstance(v, str) and v[0] == v[-1] == "'":
|
|
28
|
+
pv = v[1:-1]
|
|
29
|
+
else:
|
|
30
|
+
pv = v
|
|
31
|
+
return pv
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class SettingsBase(object):
|
|
35
|
+
"""Provide base settings."""
|
|
36
|
+
|
|
37
|
+
def __init__(self, parent):
|
|
38
|
+
self._parent = parent
|
|
39
|
+
|
|
40
|
+
@property
|
|
41
|
+
def sim_setup_info(self):
|
|
42
|
+
"""EDB internal simulation setup object."""
|
|
43
|
+
return self._parent.get_sim_setup_info
|
|
44
|
+
|
|
45
|
+
@pyedb_function_handler
|
|
46
|
+
def get_configurations(self):
|
|
47
|
+
"""Get all attributes.
|
|
48
|
+
|
|
49
|
+
Returns
|
|
50
|
+
-------
|
|
51
|
+
dict
|
|
52
|
+
"""
|
|
53
|
+
temp = {}
|
|
54
|
+
attrs_list = [i for i in dir(self) if not i.startswith("_")]
|
|
55
|
+
attrs_list = [
|
|
56
|
+
i
|
|
57
|
+
for i in attrs_list
|
|
58
|
+
if i
|
|
59
|
+
not in [
|
|
60
|
+
"get_configurations",
|
|
61
|
+
"sim_setup_info",
|
|
62
|
+
"defaults",
|
|
63
|
+
"si_defaults",
|
|
64
|
+
"pi_defaults",
|
|
65
|
+
"set_dc_slider",
|
|
66
|
+
"set_si_slider",
|
|
67
|
+
"set_pi_slider",
|
|
68
|
+
]
|
|
69
|
+
]
|
|
70
|
+
for i in attrs_list:
|
|
71
|
+
temp[i] = self.__getattribute__(i)
|
|
72
|
+
return temp
|
|
73
|
+
|
|
74
|
+
@pyedb_function_handler
|
|
75
|
+
def restore_default(self):
|
|
76
|
+
for k, val in self.defaults.items():
|
|
77
|
+
self.__setattr__(k, val)
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
class AdvancedSettings(SettingsBase):
|
|
81
|
+
def __init__(self, parent):
|
|
82
|
+
super().__init__(parent)
|
|
83
|
+
self.defaults = {
|
|
84
|
+
"automatic_mesh": True,
|
|
85
|
+
"ignore_non_functional_pads": True,
|
|
86
|
+
"include_coplane_coupling": True,
|
|
87
|
+
"include_fringe_coupling": True,
|
|
88
|
+
"include_infinite_ground": False,
|
|
89
|
+
"include_inter_plane_coupling": False,
|
|
90
|
+
"include_split_plane_coupling": True,
|
|
91
|
+
"include_trace_coupling": True,
|
|
92
|
+
"include_vi_sources": False,
|
|
93
|
+
"infinite_ground_location": "0",
|
|
94
|
+
"max_coupled_lines": 12,
|
|
95
|
+
"mesh_frequency": "4GHz",
|
|
96
|
+
"min_pad_area_to_mesh": "28mm2",
|
|
97
|
+
"min_plane_area_to_mesh": "5e-5mm2",
|
|
98
|
+
"min_void_area": "2mm2",
|
|
99
|
+
"perform_erc": False,
|
|
100
|
+
"return_current_distribution": False,
|
|
101
|
+
"snap_length_threshold": "2.5um",
|
|
102
|
+
"xtalk_threshold": "-34",
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
self.si_defaults = {
|
|
106
|
+
"include_coplane_coupling": [False, True, True],
|
|
107
|
+
"include_fringe_coupling": [False, True, True],
|
|
108
|
+
"include_inter_plane_coupling": [False, False, False],
|
|
109
|
+
"include_split_plane_coupling": [False, True, True],
|
|
110
|
+
"max_coupled_lines": [12, 12, 40],
|
|
111
|
+
"return_current_distribution": [False, False, True],
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
self.pi_defaults = {
|
|
115
|
+
"include_coplane_coupling": [False, False, True],
|
|
116
|
+
"include_fringe_coupling": [False, True, True],
|
|
117
|
+
"include_split_plane_coupling": [False, False, True],
|
|
118
|
+
"include_trace_coupling": [False, False, True],
|
|
119
|
+
"max_coupled_lines": [12, 12, 40],
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
@pyedb_function_handler
|
|
123
|
+
def set_si_slider(self, value):
|
|
124
|
+
for k, val in self.si_defaults.items():
|
|
125
|
+
self.__setattr__(k, val[value])
|
|
126
|
+
|
|
127
|
+
@pyedb_function_handler
|
|
128
|
+
def set_pi_slider(self, value):
|
|
129
|
+
for k, val in self.pi_defaults.items():
|
|
130
|
+
self.__setattr__(k, val[value])
|
|
131
|
+
|
|
132
|
+
@property
|
|
133
|
+
def include_inter_plane_coupling(self):
|
|
134
|
+
"""Whether to turn on InterPlane Coupling.
|
|
135
|
+
The setter will also enable custom settings.
|
|
136
|
+
|
|
137
|
+
Returns
|
|
138
|
+
-------
|
|
139
|
+
bool
|
|
140
|
+
``True`` if interplane coupling is used, ``False`` otherwise.
|
|
141
|
+
"""
|
|
142
|
+
return self.sim_setup_info.SimulationSettings.AdvancedSettings.IncludeInterPlaneCoupling
|
|
143
|
+
|
|
144
|
+
@property
|
|
145
|
+
def xtalk_threshold(self):
|
|
146
|
+
"""XTalk threshold.
|
|
147
|
+
The setter enables custom settings.
|
|
148
|
+
|
|
149
|
+
Returns
|
|
150
|
+
-------
|
|
151
|
+
str
|
|
152
|
+
"""
|
|
153
|
+
return self.sim_setup_info.SimulationSettings.AdvancedSettings.XtalkThreshold
|
|
154
|
+
|
|
155
|
+
@property
|
|
156
|
+
def min_void_area(self):
|
|
157
|
+
"""Minimum void area to include.
|
|
158
|
+
|
|
159
|
+
Returns
|
|
160
|
+
-------
|
|
161
|
+
bool
|
|
162
|
+
"""
|
|
163
|
+
return self.sim_setup_info.SimulationSettings.AdvancedSettings.MinVoidArea
|
|
164
|
+
|
|
165
|
+
@property
|
|
166
|
+
def min_pad_area_to_mesh(self):
|
|
167
|
+
"""Minimum void pad area to mesh to include.
|
|
168
|
+
|
|
169
|
+
Returns
|
|
170
|
+
-------
|
|
171
|
+
bool
|
|
172
|
+
"""
|
|
173
|
+
return self.sim_setup_info.SimulationSettings.AdvancedSettings.MinPadAreaToMesh
|
|
174
|
+
|
|
175
|
+
@property
|
|
176
|
+
def min_plane_area_to_mesh(self):
|
|
177
|
+
"""Minimum plane area to mesh to include.
|
|
178
|
+
|
|
179
|
+
Returns
|
|
180
|
+
-------
|
|
181
|
+
bool
|
|
182
|
+
"""
|
|
183
|
+
return self.sim_setup_info.SimulationSettings.AdvancedSettings.MinPlaneAreaToMesh
|
|
184
|
+
|
|
185
|
+
@property
|
|
186
|
+
def snap_length_threshold(self):
|
|
187
|
+
"""Snapping length threshold.
|
|
188
|
+
|
|
189
|
+
Returns
|
|
190
|
+
-------
|
|
191
|
+
str
|
|
192
|
+
"""
|
|
193
|
+
return self.sim_setup_info.SimulationSettings.AdvancedSettings.SnapLengthThreshold
|
|
194
|
+
|
|
195
|
+
@property
|
|
196
|
+
def return_current_distribution(self):
|
|
197
|
+
"""Whether to enable the return current distribution.
|
|
198
|
+
This option is used to accurately model the change of the characteristic impedance
|
|
199
|
+
of transmission lines caused by a discontinuous ground plane. Instead of injecting
|
|
200
|
+
the return current of a trace into a single point on the ground plane,
|
|
201
|
+
the return current for a high impedance trace is spread out.
|
|
202
|
+
The trace return current is not distributed when all traces attached to a node
|
|
203
|
+
have a characteristic impedance less than 75 ohms or if the difference between
|
|
204
|
+
two connected traces is less than 25 ohms.
|
|
205
|
+
|
|
206
|
+
Returns
|
|
207
|
+
-------
|
|
208
|
+
bool
|
|
209
|
+
``True`` if return current distribution is used, ``False`` otherwise.
|
|
210
|
+
"""
|
|
211
|
+
return self.sim_setup_info.SimulationSettings.AdvancedSettings.ReturnCurrentDistribution
|
|
212
|
+
|
|
213
|
+
@property
|
|
214
|
+
def ignore_non_functional_pads(self):
|
|
215
|
+
"""Exclude non-functional pads.
|
|
216
|
+
|
|
217
|
+
Returns
|
|
218
|
+
-------
|
|
219
|
+
bool
|
|
220
|
+
`True`` if functional pads have to be ignored, ``False`` otherwise.
|
|
221
|
+
"""
|
|
222
|
+
return self.sim_setup_info.SimulationSettings.AdvancedSettings.IgnoreNonFunctionalPads
|
|
223
|
+
|
|
224
|
+
@property
|
|
225
|
+
def include_coplane_coupling(self):
|
|
226
|
+
"""Whether to enable coupling between traces and adjacent plane edges.
|
|
227
|
+
This option provides a model for crosstalk between signal lines and planes.
|
|
228
|
+
Plane edges couple to traces when they are parallel.
|
|
229
|
+
Traces and coplanar edges that are oblique to each other do not overlap
|
|
230
|
+
and cannot be considered for coupling.
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
Returns
|
|
234
|
+
-------
|
|
235
|
+
bool
|
|
236
|
+
``True`` if coplane coupling is used, ``False`` otherwise.
|
|
237
|
+
"""
|
|
238
|
+
return self.sim_setup_info.SimulationSettings.AdvancedSettings.IncludeCoPlaneCoupling
|
|
239
|
+
|
|
240
|
+
@property
|
|
241
|
+
def include_fringe_coupling(self):
|
|
242
|
+
"""Whether to include the effect of fringe field coupling between stacked cavities.
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
Returns
|
|
246
|
+
-------
|
|
247
|
+
bool
|
|
248
|
+
``True`` if fringe coupling is used, ``False`` otherwise.
|
|
249
|
+
"""
|
|
250
|
+
return self.sim_setup_info.SimulationSettings.AdvancedSettings.IncludeFringeCoupling
|
|
251
|
+
|
|
252
|
+
@property
|
|
253
|
+
def include_split_plane_coupling(self):
|
|
254
|
+
"""Whether to account for coupling between adjacent parallel plane edges.
|
|
255
|
+
Primarily, two different cases are being considered:
|
|
256
|
+
- Plane edges that form a split.
|
|
257
|
+
- Plane edges that form a narrow trace-like plane.
|
|
258
|
+
The former leads to crosstalk between adjacent planes for which
|
|
259
|
+
a specific coupling model is applied. For the latter, fringing effects
|
|
260
|
+
are considered to model accurately the propagation characteristics
|
|
261
|
+
of trace-like cavities. Further, the coupling between narrow planes is
|
|
262
|
+
also modeled by enabling this feature.
|
|
263
|
+
|
|
264
|
+
Returns
|
|
265
|
+
-------
|
|
266
|
+
bool
|
|
267
|
+
``True`` if split plane coupling is used, ``False`` otherwise.
|
|
268
|
+
"""
|
|
269
|
+
return self.sim_setup_info.SimulationSettings.AdvancedSettings.IncludeSplitPlaneCoupling
|
|
270
|
+
|
|
271
|
+
@property
|
|
272
|
+
def include_infinite_ground(self):
|
|
273
|
+
"""Whether to Include a ground plane to serve as a voltage reference for traces and planes
|
|
274
|
+
if they are not defined in the layout.
|
|
275
|
+
|
|
276
|
+
Returns
|
|
277
|
+
-------
|
|
278
|
+
bool
|
|
279
|
+
``True`` if infinite ground is used, ``False`` otherwise.
|
|
280
|
+
"""
|
|
281
|
+
return self.sim_setup_info.SimulationSettings.AdvancedSettings.IncludeInfGnd
|
|
282
|
+
|
|
283
|
+
@property
|
|
284
|
+
def include_trace_coupling(self):
|
|
285
|
+
"""Whether to model coupling between adjacent traces.
|
|
286
|
+
Coupling is considered for parallel and almost parallel trace segments.
|
|
287
|
+
|
|
288
|
+
Returns
|
|
289
|
+
-------
|
|
290
|
+
bool
|
|
291
|
+
``True`` if trace coupling is used, ``False`` otherwise.
|
|
292
|
+
"""
|
|
293
|
+
return self.sim_setup_info.SimulationSettings.AdvancedSettings.IncludeTraceCoupling
|
|
294
|
+
|
|
295
|
+
@property
|
|
296
|
+
def include_vi_sources(self):
|
|
297
|
+
"""Whether to include the effect of parasitic elements from voltage and
|
|
298
|
+
current sources.
|
|
299
|
+
|
|
300
|
+
Returns
|
|
301
|
+
-------
|
|
302
|
+
bool
|
|
303
|
+
``True`` if vi sources is used, ``False`` otherwise.
|
|
304
|
+
"""
|
|
305
|
+
return self.sim_setup_info.SimulationSettings.AdvancedSettings.IncludeVISources
|
|
306
|
+
|
|
307
|
+
@property
|
|
308
|
+
def infinite_ground_location(self):
|
|
309
|
+
"""Elevation of the infinite unconnected ground plane placed under the design.
|
|
310
|
+
|
|
311
|
+
Returns
|
|
312
|
+
-------
|
|
313
|
+
str
|
|
314
|
+
"""
|
|
315
|
+
return self.sim_setup_info.SimulationSettings.AdvancedSettings.InfGndLocation
|
|
316
|
+
|
|
317
|
+
@property
|
|
318
|
+
def max_coupled_lines(self):
|
|
319
|
+
"""Maximum number of coupled lines to build the new coupled transmission line model.
|
|
320
|
+
|
|
321
|
+
Returns
|
|
322
|
+
-------
|
|
323
|
+
int
|
|
324
|
+
"""
|
|
325
|
+
return self.sim_setup_info.SimulationSettings.AdvancedSettings.MaxCoupledLines
|
|
326
|
+
|
|
327
|
+
@property
|
|
328
|
+
def automatic_mesh(self):
|
|
329
|
+
"""Whether to automatically pick a suitable mesh refinement frequency,
|
|
330
|
+
depending on drawing size, number of modes, and/or maximum sweep
|
|
331
|
+
frequency.
|
|
332
|
+
|
|
333
|
+
Returns
|
|
334
|
+
-------
|
|
335
|
+
bool
|
|
336
|
+
``True`` if automatic mesh is used, ``False`` otherwise.
|
|
337
|
+
"""
|
|
338
|
+
return self.sim_setup_info.SimulationSettings.AdvancedSettings.MeshAutoMatic
|
|
339
|
+
|
|
340
|
+
@property
|
|
341
|
+
def perform_erc(self):
|
|
342
|
+
"""Whether to perform an electrical rule check while generating the solver input.
|
|
343
|
+
In some designs, the same net may be divided into multiple nets with separate names.
|
|
344
|
+
These nets are connected at a "star" point. To simulate these nets, the error checking
|
|
345
|
+
for DC shorts must be turned off. All overlapping nets are then internally united
|
|
346
|
+
during simulation.
|
|
347
|
+
|
|
348
|
+
Returns
|
|
349
|
+
-------
|
|
350
|
+
bool
|
|
351
|
+
``True`` if perform erc is used, ``False`` otherwise.
|
|
352
|
+
"""
|
|
353
|
+
return self.sim_setup_info.SimulationSettings.AdvancedSettings.PerformERC
|
|
354
|
+
|
|
355
|
+
@property
|
|
356
|
+
def mesh_frequency(self):
|
|
357
|
+
"""Mesh size based on the effective wavelength at the specified frequency.
|
|
358
|
+
|
|
359
|
+
Returns
|
|
360
|
+
-------
|
|
361
|
+
str
|
|
362
|
+
"""
|
|
363
|
+
return self.sim_setup_info.SimulationSettings.AdvancedSettings.MeshFrequency
|
|
364
|
+
|
|
365
|
+
@include_inter_plane_coupling.setter
|
|
366
|
+
def include_inter_plane_coupling(self, value):
|
|
367
|
+
edb_setup_info = self.sim_setup_info
|
|
368
|
+
edb_setup_info.SimulationSettings.AdvancedSettings.IncludeInterPlaneCoupling = value
|
|
369
|
+
self._parent._edb_object = self._parent._set_edb_setup_info(edb_setup_info)
|
|
370
|
+
self._parent._update_setup()
|
|
371
|
+
|
|
372
|
+
@xtalk_threshold.setter
|
|
373
|
+
def xtalk_threshold(self, value):
|
|
374
|
+
edb_setup_info = self.sim_setup_info
|
|
375
|
+
edb_setup_info.SimulationSettings.AdvancedSettings.XtalkThreshold = value
|
|
376
|
+
self._parent._edb_object = self._parent._set_edb_setup_info(edb_setup_info)
|
|
377
|
+
self._parent._update_setup()
|
|
378
|
+
|
|
379
|
+
@min_void_area.setter
|
|
380
|
+
def min_void_area(self, value):
|
|
381
|
+
edb_setup_info = self.sim_setup_info
|
|
382
|
+
edb_setup_info.SimulationSettings.AdvancedSettings.MinVoidArea = value
|
|
383
|
+
self._parent._edb_object = self._parent._set_edb_setup_info(edb_setup_info)
|
|
384
|
+
self._parent._update_setup()
|
|
385
|
+
|
|
386
|
+
@min_pad_area_to_mesh.setter
|
|
387
|
+
def min_pad_area_to_mesh(self, value):
|
|
388
|
+
edb_setup_info = self.sim_setup_info
|
|
389
|
+
edb_setup_info.SimulationSettings.AdvancedSettings.MinPadAreaToMesh = value
|
|
390
|
+
self._parent._edb_object = self._parent._set_edb_setup_info(edb_setup_info)
|
|
391
|
+
self._parent._update_setup()
|
|
392
|
+
|
|
393
|
+
@min_plane_area_to_mesh.setter
|
|
394
|
+
def min_plane_area_to_mesh(self, value):
|
|
395
|
+
edb_setup_info = self.sim_setup_info
|
|
396
|
+
edb_setup_info.SimulationSettings.AdvancedSettings.MinPlaneAreaToMesh = value
|
|
397
|
+
self._parent._edb_object = self._parent._set_edb_setup_info(edb_setup_info)
|
|
398
|
+
self._parent._update_setup()
|
|
399
|
+
|
|
400
|
+
@snap_length_threshold.setter
|
|
401
|
+
def snap_length_threshold(self, value):
|
|
402
|
+
edb_setup_info = self.sim_setup_info
|
|
403
|
+
edb_setup_info.SimulationSettings.AdvancedSettings.SnapLengthThreshold = value
|
|
404
|
+
self._parent._edb_object = self._parent._set_edb_setup_info(edb_setup_info)
|
|
405
|
+
self._parent._update_setup()
|
|
406
|
+
|
|
407
|
+
@return_current_distribution.setter
|
|
408
|
+
def return_current_distribution(self, value):
|
|
409
|
+
edb_setup_info = self.sim_setup_info
|
|
410
|
+
edb_setup_info.SimulationSettings.AdvancedSettings.ReturnCurrentDistribution = value
|
|
411
|
+
self._parent._edb_object = self._parent._set_edb_setup_info(edb_setup_info)
|
|
412
|
+
self._parent._update_setup()
|
|
413
|
+
|
|
414
|
+
@ignore_non_functional_pads.setter
|
|
415
|
+
def ignore_non_functional_pads(self, value):
|
|
416
|
+
edb_setup_info = self.sim_setup_info
|
|
417
|
+
edb_setup_info.SimulationSettings.AdvancedSettings.IgnoreNonFunctionalPads = value
|
|
418
|
+
self._parent._edb_object = self._parent._set_edb_setup_info(edb_setup_info)
|
|
419
|
+
self._parent._update_setup()
|
|
420
|
+
|
|
421
|
+
@include_coplane_coupling.setter
|
|
422
|
+
def include_coplane_coupling(self, value):
|
|
423
|
+
edb_setup_info = self.sim_setup_info
|
|
424
|
+
edb_setup_info.SimulationSettings.AdvancedSettings.IncludeCoPlaneCoupling = value
|
|
425
|
+
self._parent._edb_object = self._parent._set_edb_setup_info(edb_setup_info)
|
|
426
|
+
self._parent._update_setup()
|
|
427
|
+
|
|
428
|
+
@include_fringe_coupling.setter
|
|
429
|
+
def include_fringe_coupling(self, value):
|
|
430
|
+
edb_setup_info = self.sim_setup_info
|
|
431
|
+
|
|
432
|
+
edb_setup_info.SimulationSettings.AdvancedSettings.IncludeFringeCoupling = value
|
|
433
|
+
self._parent._edb_object = self._parent._set_edb_setup_info(edb_setup_info)
|
|
434
|
+
self._parent._update_setup()
|
|
435
|
+
|
|
436
|
+
@include_split_plane_coupling.setter
|
|
437
|
+
def include_split_plane_coupling(self, value):
|
|
438
|
+
edb_setup_info = self.sim_setup_info
|
|
439
|
+
|
|
440
|
+
edb_setup_info.SimulationSettings.AdvancedSettings.IncludeSplitPlaneCoupling = value
|
|
441
|
+
self._parent._edb_object = self._parent._set_edb_setup_info(edb_setup_info)
|
|
442
|
+
self._parent._update_setup()
|
|
443
|
+
|
|
444
|
+
@include_infinite_ground.setter
|
|
445
|
+
def include_infinite_ground(self, value):
|
|
446
|
+
edb_setup_info = self.sim_setup_info
|
|
447
|
+
|
|
448
|
+
edb_setup_info.SimulationSettings.AdvancedSettings.IncludeInfGnd = value
|
|
449
|
+
self._parent._edb_object = self._parent._set_edb_setup_info(edb_setup_info)
|
|
450
|
+
self._parent._update_setup()
|
|
451
|
+
|
|
452
|
+
@include_trace_coupling.setter
|
|
453
|
+
def include_trace_coupling(self, value):
|
|
454
|
+
edb_setup_info = self.sim_setup_info
|
|
455
|
+
|
|
456
|
+
edb_setup_info.SimulationSettings.AdvancedSettings.IncludeTraceCoupling = value
|
|
457
|
+
self._parent._edb_object = self._parent._set_edb_setup_info(edb_setup_info)
|
|
458
|
+
self._parent._update_setup()
|
|
459
|
+
|
|
460
|
+
@include_vi_sources.setter
|
|
461
|
+
def include_vi_sources(self, value):
|
|
462
|
+
edb_setup_info = self.sim_setup_info
|
|
463
|
+
|
|
464
|
+
edb_setup_info.SimulationSettings.AdvancedSettings.IncludeVISources = value
|
|
465
|
+
self._parent._edb_object = self._parent._set_edb_setup_info(edb_setup_info)
|
|
466
|
+
self._parent._update_setup()
|
|
467
|
+
|
|
468
|
+
@infinite_ground_location.setter
|
|
469
|
+
def infinite_ground_location(self, value):
|
|
470
|
+
edb_setup_info = self.sim_setup_info
|
|
471
|
+
|
|
472
|
+
edb_setup_info.SimulationSettings.AdvancedSettings.InfGndLocation = value
|
|
473
|
+
self._parent._edb_object = self._parent._set_edb_setup_info(edb_setup_info)
|
|
474
|
+
self._parent._update_setup()
|
|
475
|
+
|
|
476
|
+
@max_coupled_lines.setter
|
|
477
|
+
def max_coupled_lines(self, value):
|
|
478
|
+
edb_setup_info = self.sim_setup_info
|
|
479
|
+
|
|
480
|
+
edb_setup_info.SimulationSettings.AdvancedSettings.MaxCoupledLines = value
|
|
481
|
+
self._parent._edb_object = self._parent._set_edb_setup_info(edb_setup_info)
|
|
482
|
+
self._parent._update_setup()
|
|
483
|
+
|
|
484
|
+
@automatic_mesh.setter
|
|
485
|
+
def automatic_mesh(self, value):
|
|
486
|
+
edb_setup_info = self.sim_setup_info
|
|
487
|
+
|
|
488
|
+
edb_setup_info.SimulationSettings.AdvancedSettings.MeshAutoMatic = value
|
|
489
|
+
self._parent._edb_object = self._parent._set_edb_setup_info(edb_setup_info)
|
|
490
|
+
self._parent._update_setup()
|
|
491
|
+
|
|
492
|
+
@perform_erc.setter
|
|
493
|
+
def perform_erc(self, value):
|
|
494
|
+
edb_setup_info = self.sim_setup_info
|
|
495
|
+
edb_setup_info.SimulationSettings.AdvancedSettings.PerformERC = value
|
|
496
|
+
self._parent._edb_object = self._parent._set_edb_setup_info(edb_setup_info)
|
|
497
|
+
self._parent._update_setup()
|
|
498
|
+
|
|
499
|
+
@mesh_frequency.setter
|
|
500
|
+
def mesh_frequency(self, value):
|
|
501
|
+
edb_setup_info = self.sim_setup_info
|
|
502
|
+
|
|
503
|
+
edb_setup_info.SimulationSettings.AdvancedSettings.MeshFrequency = value
|
|
504
|
+
self._parent._edb_object = self._parent._set_edb_setup_info(edb_setup_info)
|
|
505
|
+
self._parent._update_setup()
|
|
506
|
+
|
|
507
|
+
|
|
508
|
+
class DCSettings(SettingsBase):
|
|
509
|
+
def __init__(self, parent):
|
|
510
|
+
super().__init__(parent)
|
|
511
|
+
self.defaults = {
|
|
512
|
+
"compute_inductance": False,
|
|
513
|
+
"contact_radius": "0.1mm",
|
|
514
|
+
"use_dc_custom_settings": False,
|
|
515
|
+
"plot_jv": True,
|
|
516
|
+
}
|
|
517
|
+
self.dc_defaults = {
|
|
518
|
+
"dc_slider_position": [0, 1, 2],
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
@property
|
|
522
|
+
def compute_inductance(self):
|
|
523
|
+
"""Whether to compute Inductance.
|
|
524
|
+
|
|
525
|
+
Returns
|
|
526
|
+
-------
|
|
527
|
+
bool
|
|
528
|
+
``True`` if inductances will be computed, ``False`` otherwise.
|
|
529
|
+
"""
|
|
530
|
+
|
|
531
|
+
return self.sim_setup_info.SimulationSettings.DCSettings.ComputeInductance
|
|
532
|
+
|
|
533
|
+
@compute_inductance.setter
|
|
534
|
+
def compute_inductance(self, value):
|
|
535
|
+
edb_setup_info = self.sim_setup_info
|
|
536
|
+
edb_setup_info.SimulationSettings.DCSettings.ComputeInductance = value
|
|
537
|
+
self._parent._edb_object = self._parent._set_edb_setup_info(edb_setup_info)
|
|
538
|
+
self._parent._update_setup()
|
|
539
|
+
|
|
540
|
+
@property
|
|
541
|
+
def contact_radius(self):
|
|
542
|
+
"""Circuit element contact radius.
|
|
543
|
+
|
|
544
|
+
Returns
|
|
545
|
+
-------
|
|
546
|
+
str
|
|
547
|
+
"""
|
|
548
|
+
return self.sim_setup_info.SimulationSettings.DCSettings.ContactRadius
|
|
549
|
+
|
|
550
|
+
@contact_radius.setter
|
|
551
|
+
def contact_radius(self, value):
|
|
552
|
+
edb_setup_info = self.sim_setup_info
|
|
553
|
+
edb_setup_info.SimulationSettings.DCSettings.ContactRadius = value
|
|
554
|
+
self._parent._edb_object = self._parent._set_edb_setup_info(edb_setup_info)
|
|
555
|
+
self._parent._update_setup()
|
|
556
|
+
|
|
557
|
+
@property
|
|
558
|
+
def dc_slider_position(self):
|
|
559
|
+
"""DC simulation accuracy level slider position. This property only change slider position.
|
|
560
|
+
Options:
|
|
561
|
+
0- ``optimal speed``
|
|
562
|
+
1- ``balanced``
|
|
563
|
+
2- ``optimal accuracy``.
|
|
564
|
+
"""
|
|
565
|
+
return self.sim_setup_info.SimulationSettings.DCSettings.DCSliderPos
|
|
566
|
+
|
|
567
|
+
@dc_slider_position.setter
|
|
568
|
+
def dc_slider_position(self, value):
|
|
569
|
+
edb_setup_info = self.sim_setup_info
|
|
570
|
+
edb_setup_info.SimulationSettings.DCSettings.DCSliderPos = value
|
|
571
|
+
self._parent._edb_object = self._parent._set_edb_setup_info(edb_setup_info)
|
|
572
|
+
self._parent._update_setup()
|
|
573
|
+
|
|
574
|
+
@property
|
|
575
|
+
def use_dc_custom_settings(self):
|
|
576
|
+
"""Whether to use DC custom settings.
|
|
577
|
+
This setting is automatically enabled by other properties when needed.
|
|
578
|
+
|
|
579
|
+
Returns
|
|
580
|
+
-------
|
|
581
|
+
bool
|
|
582
|
+
``True`` if custom dc settings are used, ``False`` otherwise.
|
|
583
|
+
"""
|
|
584
|
+
return self.sim_setup_info.SimulationSettings.DCSettings.UseDCCustomSettings
|
|
585
|
+
|
|
586
|
+
@use_dc_custom_settings.setter
|
|
587
|
+
def use_dc_custom_settings(self, value):
|
|
588
|
+
edb_setup_info = self.sim_setup_info
|
|
589
|
+
edb_setup_info.SimulationSettings.DCSettings.UseDCCustomSettings = value
|
|
590
|
+
self._parent._edb_object = self._parent._set_edb_setup_info(edb_setup_info)
|
|
591
|
+
self._parent._update_setup()
|
|
592
|
+
|
|
593
|
+
@property
|
|
594
|
+
def plot_jv(self):
|
|
595
|
+
"""Plot current and voltage distributions.
|
|
596
|
+
|
|
597
|
+
Returns
|
|
598
|
+
-------
|
|
599
|
+
bool
|
|
600
|
+
``True`` if plot JV is used, ``False`` otherwise.
|
|
601
|
+
"""
|
|
602
|
+
return self.sim_setup_info.SimulationSettings.DCSettings.PlotJV
|
|
603
|
+
|
|
604
|
+
@plot_jv.setter
|
|
605
|
+
def plot_jv(self, value):
|
|
606
|
+
edb_setup_info = self.sim_setup_info
|
|
607
|
+
edb_setup_info.SimulationSettings.DCSettings.PlotJV = value
|
|
608
|
+
self._parent._edb_object = self._parent._set_edb_setup_info(edb_setup_info)
|
|
609
|
+
self._parent._update_setup()
|
|
610
|
+
|
|
611
|
+
|
|
612
|
+
class DCAdvancedSettings(SettingsBase):
|
|
613
|
+
def __init__(self, parent):
|
|
614
|
+
super().__init__(parent)
|
|
615
|
+
self.defaults = {
|
|
616
|
+
"dc_min_void_area_to_mesh": "0.001mm2",
|
|
617
|
+
"max_init_mesh_edge_length": "5mm",
|
|
618
|
+
"dc_min_plane_area_to_mesh": "1.5mm2",
|
|
619
|
+
"num_bondwire_sides": 8,
|
|
620
|
+
"num_via_sides": 8,
|
|
621
|
+
"percent_local_refinement": 20.0,
|
|
622
|
+
}
|
|
623
|
+
self.dc_defaults = {
|
|
624
|
+
"energy_error": [2, 2, 1],
|
|
625
|
+
"max_num_pass": [5, 5, 10],
|
|
626
|
+
"mesh_bondwires": [False, True, True],
|
|
627
|
+
"mesh_vias": [False, True, True],
|
|
628
|
+
"min_num_pass": [1, 1, 3],
|
|
629
|
+
"perform_adaptive_refinement": [False, True, True],
|
|
630
|
+
"refine_bondwires": [False, False, True],
|
|
631
|
+
"refine_vias": [False, False, True],
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
@pyedb_function_handler
|
|
635
|
+
def set_dc_slider(self, value):
|
|
636
|
+
for k, val in self.dc_defaults.items():
|
|
637
|
+
self.__setattr__(k, val[value])
|
|
638
|
+
|
|
639
|
+
@property
|
|
640
|
+
def dc_min_void_area_to_mesh(self):
|
|
641
|
+
"""DC minimum area below which voids are ignored.
|
|
642
|
+
|
|
643
|
+
Returns
|
|
644
|
+
-------
|
|
645
|
+
float
|
|
646
|
+
"""
|
|
647
|
+
return self.sim_setup_info.SimulationSettings.DCAdvancedSettings.DcMinVoidAreaToMesh
|
|
648
|
+
|
|
649
|
+
@property
|
|
650
|
+
def dc_min_plane_area_to_mesh(self):
|
|
651
|
+
"""Minimum area below which geometry is ignored.
|
|
652
|
+
|
|
653
|
+
Returns
|
|
654
|
+
-------
|
|
655
|
+
float
|
|
656
|
+
"""
|
|
657
|
+
return self.sim_setup_info.SimulationSettings.DCAdvancedSettings.DcMinPlaneAreaToMesh
|
|
658
|
+
|
|
659
|
+
@property
|
|
660
|
+
def energy_error(self):
|
|
661
|
+
"""Energy error.
|
|
662
|
+
|
|
663
|
+
Returns
|
|
664
|
+
-------
|
|
665
|
+
float
|
|
666
|
+
"""
|
|
667
|
+
return self.sim_setup_info.SimulationSettings.DCAdvancedSettings.EnergyError
|
|
668
|
+
|
|
669
|
+
@property
|
|
670
|
+
def max_init_mesh_edge_length(self):
|
|
671
|
+
"""Initial mesh maximum edge length.
|
|
672
|
+
|
|
673
|
+
Returns
|
|
674
|
+
-------
|
|
675
|
+
float
|
|
676
|
+
"""
|
|
677
|
+
return self.sim_setup_info.SimulationSettings.DCAdvancedSettings.MaxInitMeshEdgeLength
|
|
678
|
+
|
|
679
|
+
@property
|
|
680
|
+
def max_num_pass(self):
|
|
681
|
+
"""Maximum number of passes.
|
|
682
|
+
|
|
683
|
+
Returns
|
|
684
|
+
-------
|
|
685
|
+
int
|
|
686
|
+
"""
|
|
687
|
+
return self.sim_setup_info.SimulationSettings.DCAdvancedSettings.MaxNumPasses
|
|
688
|
+
|
|
689
|
+
@property
|
|
690
|
+
def min_num_pass(self):
|
|
691
|
+
"""Minimum number of passes.
|
|
692
|
+
|
|
693
|
+
Returns
|
|
694
|
+
-------
|
|
695
|
+
int
|
|
696
|
+
"""
|
|
697
|
+
return self.sim_setup_info.SimulationSettings.DCAdvancedSettings.MinNumPasses
|
|
698
|
+
|
|
699
|
+
@property
|
|
700
|
+
def mesh_bondwires(self):
|
|
701
|
+
"""Mesh bondwires.
|
|
702
|
+
|
|
703
|
+
Returns
|
|
704
|
+
-------
|
|
705
|
+
bool
|
|
706
|
+
"""
|
|
707
|
+
return self.sim_setup_info.SimulationSettings.DCAdvancedSettings.MeshBws
|
|
708
|
+
|
|
709
|
+
@property
|
|
710
|
+
def mesh_vias(self):
|
|
711
|
+
"""Mesh vias.
|
|
712
|
+
|
|
713
|
+
Returns
|
|
714
|
+
-------
|
|
715
|
+
bool
|
|
716
|
+
"""
|
|
717
|
+
return self.sim_setup_info.SimulationSettings.DCAdvancedSettings.MeshVias
|
|
718
|
+
|
|
719
|
+
@property
|
|
720
|
+
def num_bondwire_sides(self):
|
|
721
|
+
"""Number of bondwire sides.
|
|
722
|
+
|
|
723
|
+
Returns
|
|
724
|
+
-------
|
|
725
|
+
int
|
|
726
|
+
"""
|
|
727
|
+
return self.sim_setup_info.SimulationSettings.DCAdvancedSettings.NumBwSides
|
|
728
|
+
|
|
729
|
+
@property
|
|
730
|
+
def num_via_sides(self):
|
|
731
|
+
"""Number of via sides.
|
|
732
|
+
|
|
733
|
+
Returns
|
|
734
|
+
-------
|
|
735
|
+
int
|
|
736
|
+
"""
|
|
737
|
+
return self.sim_setup_info.SimulationSettings.DCAdvancedSettings.NumViaSides
|
|
738
|
+
|
|
739
|
+
@property
|
|
740
|
+
def percent_local_refinement(self):
|
|
741
|
+
"""Percentage of local refinement.
|
|
742
|
+
|
|
743
|
+
Returns
|
|
744
|
+
-------
|
|
745
|
+
float
|
|
746
|
+
"""
|
|
747
|
+
return self.sim_setup_info.SimulationSettings.DCAdvancedSettings.PercentLocalRefinement
|
|
748
|
+
|
|
749
|
+
@property
|
|
750
|
+
def perform_adaptive_refinement(self):
|
|
751
|
+
"""Whether to perform adaptive mesh refinement.
|
|
752
|
+
|
|
753
|
+
Returns
|
|
754
|
+
-------
|
|
755
|
+
bool
|
|
756
|
+
``True`` if adaptive refinement is used, ``False`` otherwise.
|
|
757
|
+
"""
|
|
758
|
+
return self.sim_setup_info.SimulationSettings.DCAdvancedSettings.PerformAdaptiveRefinement
|
|
759
|
+
|
|
760
|
+
@property
|
|
761
|
+
def refine_bondwires(self):
|
|
762
|
+
"""Whether to refine mesh along bondwires.
|
|
763
|
+
|
|
764
|
+
Returns
|
|
765
|
+
-------
|
|
766
|
+
bool
|
|
767
|
+
``True`` if refine bondwires is used, ``False`` otherwise.
|
|
768
|
+
"""
|
|
769
|
+
return self.sim_setup_info.SimulationSettings.DCAdvancedSettings.RefineBws
|
|
770
|
+
|
|
771
|
+
@property
|
|
772
|
+
def refine_vias(self):
|
|
773
|
+
"""Whether to refine mesh along vias.
|
|
774
|
+
|
|
775
|
+
Returns
|
|
776
|
+
-------
|
|
777
|
+
bool
|
|
778
|
+
``True`` if via refinement is used, ``False`` otherwise.
|
|
779
|
+
|
|
780
|
+
"""
|
|
781
|
+
return self.sim_setup_info.SimulationSettings.DCAdvancedSettings.RefineVias
|
|
782
|
+
|
|
783
|
+
@dc_min_void_area_to_mesh.setter
|
|
784
|
+
def dc_min_void_area_to_mesh(self, value):
|
|
785
|
+
edb_setup_info = self.sim_setup_info
|
|
786
|
+
edb_setup_info.SimulationSettings.DCAdvancedSettings.DcMinVoidAreaToMesh = value
|
|
787
|
+
self._parent._edb_object = self._parent._set_edb_setup_info(edb_setup_info)
|
|
788
|
+
self._parent._update_setup()
|
|
789
|
+
|
|
790
|
+
@dc_min_plane_area_to_mesh.setter
|
|
791
|
+
def dc_min_plane_area_to_mesh(self, value):
|
|
792
|
+
edb_setup_info = self.sim_setup_info
|
|
793
|
+
edb_setup_info.SimulationSettings.DCAdvancedSettings.DcMinPlaneAreaToMesh = value
|
|
794
|
+
self._parent._edb_object = self._parent._set_edb_setup_info(edb_setup_info)
|
|
795
|
+
self._parent._update_setup()
|
|
796
|
+
|
|
797
|
+
@energy_error.setter
|
|
798
|
+
def energy_error(self, value):
|
|
799
|
+
edb_setup_info = self.sim_setup_info
|
|
800
|
+
|
|
801
|
+
edb_setup_info.SimulationSettings.DCAdvancedSettings.EnergyError = value
|
|
802
|
+
self._parent._edb_object = self._parent._set_edb_setup_info(edb_setup_info)
|
|
803
|
+
self._parent._update_setup()
|
|
804
|
+
|
|
805
|
+
@max_init_mesh_edge_length.setter
|
|
806
|
+
def max_init_mesh_edge_length(self, value):
|
|
807
|
+
edb_setup_info = self.sim_setup_info
|
|
808
|
+
|
|
809
|
+
edb_setup_info.SimulationSettings.DCAdvancedSettings.MaxInitMeshEdgeLength = value
|
|
810
|
+
self._parent._edb_object = self._parent._set_edb_setup_info(edb_setup_info)
|
|
811
|
+
self._parent._update_setup()
|
|
812
|
+
|
|
813
|
+
@max_num_pass.setter
|
|
814
|
+
def max_num_pass(self, value):
|
|
815
|
+
edb_setup_info = self.sim_setup_info
|
|
816
|
+
|
|
817
|
+
edb_setup_info.SimulationSettings.DCAdvancedSettings.MaxNumPasses = value
|
|
818
|
+
self._parent._edb_object = self._parent._set_edb_setup_info(edb_setup_info)
|
|
819
|
+
self._parent._update_setup()
|
|
820
|
+
|
|
821
|
+
@min_num_pass.setter
|
|
822
|
+
def min_num_pass(self, value):
|
|
823
|
+
edb_setup_info = self.sim_setup_info
|
|
824
|
+
|
|
825
|
+
edb_setup_info.SimulationSettings.DCAdvancedSettings.MinNumPasses = value
|
|
826
|
+
self._parent._edb_object = self._parent._set_edb_setup_info(edb_setup_info)
|
|
827
|
+
self._parent._update_setup()
|
|
828
|
+
|
|
829
|
+
@mesh_bondwires.setter
|
|
830
|
+
def mesh_bondwires(self, value):
|
|
831
|
+
edb_setup_info = self.sim_setup_info
|
|
832
|
+
|
|
833
|
+
edb_setup_info.SimulationSettings.DCAdvancedSettings.MeshBws = value
|
|
834
|
+
self._parent._edb_object = self._parent._set_edb_setup_info(edb_setup_info)
|
|
835
|
+
self._parent._update_setup()
|
|
836
|
+
|
|
837
|
+
@mesh_vias.setter
|
|
838
|
+
def mesh_vias(self, value):
|
|
839
|
+
edb_setup_info = self.sim_setup_info
|
|
840
|
+
edb_setup_info.SimulationSettings.DCAdvancedSettings.MeshVias = value
|
|
841
|
+
self._parent._edb_object = self._parent._set_edb_setup_info(edb_setup_info)
|
|
842
|
+
self._parent._update_setup()
|
|
843
|
+
|
|
844
|
+
@num_bondwire_sides.setter
|
|
845
|
+
def num_bondwire_sides(self, value):
|
|
846
|
+
edb_setup_info = self.sim_setup_info
|
|
847
|
+
edb_setup_info.SimulationSettings.DCAdvancedSettings.NumBwSides = value
|
|
848
|
+
self._parent._edb_object = self._parent._set_edb_setup_info(edb_setup_info)
|
|
849
|
+
self._parent._update_setup()
|
|
850
|
+
|
|
851
|
+
@num_via_sides.setter
|
|
852
|
+
def num_via_sides(self, value):
|
|
853
|
+
edb_setup_info = self.sim_setup_info
|
|
854
|
+
edb_setup_info.SimulationSettings.DCAdvancedSettings.NumViaSides = value
|
|
855
|
+
self._parent._edb_object = self._parent._set_edb_setup_info(edb_setup_info)
|
|
856
|
+
self._parent._update_setup()
|
|
857
|
+
|
|
858
|
+
@percent_local_refinement.setter
|
|
859
|
+
def percent_local_refinement(self, value):
|
|
860
|
+
edb_setup_info = self.sim_setup_info
|
|
861
|
+
|
|
862
|
+
edb_setup_info.SimulationSettings.DCAdvancedSettings.PercentLocalRefinement = value
|
|
863
|
+
self._parent._edb_object = self._parent._set_edb_setup_info(edb_setup_info)
|
|
864
|
+
self._parent._update_setup()
|
|
865
|
+
|
|
866
|
+
@perform_adaptive_refinement.setter
|
|
867
|
+
def perform_adaptive_refinement(self, value):
|
|
868
|
+
edb_setup_info = self.sim_setup_info
|
|
869
|
+
|
|
870
|
+
edb_setup_info.SimulationSettings.DCAdvancedSettings.PerformAdaptiveRefinement = value
|
|
871
|
+
self._parent._edb_object = self._parent._set_edb_setup_info(edb_setup_info)
|
|
872
|
+
self._parent._update_setup()
|
|
873
|
+
|
|
874
|
+
@refine_bondwires.setter
|
|
875
|
+
def refine_bondwires(self, value):
|
|
876
|
+
edb_setup_info = self.sim_setup_info
|
|
877
|
+
edb_setup_info.SimulationSettings.DCAdvancedSettings.RefineBws = value
|
|
878
|
+
self._parent._edb_object = self._parent._set_edb_setup_info(edb_setup_info)
|
|
879
|
+
self._parent._update_setup()
|
|
880
|
+
|
|
881
|
+
@refine_vias.setter
|
|
882
|
+
def refine_vias(self, value):
|
|
883
|
+
edb_setup_info = self.sim_setup_info
|
|
884
|
+
edb_setup_info.SimulationSettings.DCAdvancedSettings.RefineVias = value
|
|
885
|
+
self._parent._edb_object = self._parent._set_edb_setup_info(edb_setup_info)
|
|
886
|
+
self._parent._update_setup()
|
|
887
|
+
|
|
888
|
+
|
|
889
|
+
class SiwaveSYZSimulationSetup(BaseSimulationSetup):
|
|
890
|
+
"""Manages EDB methods for SIwave simulation setup.
|
|
891
|
+
|
|
892
|
+
Parameters
|
|
893
|
+
----------
|
|
894
|
+
pedb : :class:`pyedb.dotnet.edb.Edb`
|
|
895
|
+
Inherited AEDT object.
|
|
896
|
+
edb_setup : :class:`Ansys.Ansoft.Edb.Utility.SIWaveSimulationSetup`
|
|
897
|
+
Edb object.
|
|
898
|
+
"""
|
|
899
|
+
|
|
900
|
+
def __init__(self, pedb, edb_setup=None):
|
|
901
|
+
super().__init__(pedb, edb_setup)
|
|
902
|
+
self._edb = self._pedb
|
|
903
|
+
self._setup_type = "kSIwave"
|
|
904
|
+
self._sim_setup_info = None
|
|
905
|
+
|
|
906
|
+
@pyedb_function_handler()
|
|
907
|
+
def create(self, name=None):
|
|
908
|
+
"""Create a SIwave SYZ setup.
|
|
909
|
+
|
|
910
|
+
Returns
|
|
911
|
+
-------
|
|
912
|
+
:class:`SiwaveDCSimulationSetup`
|
|
913
|
+
"""
|
|
914
|
+
self._name = name
|
|
915
|
+
self._create(name)
|
|
916
|
+
self.si_slider_position = 1
|
|
917
|
+
|
|
918
|
+
return self
|
|
919
|
+
|
|
920
|
+
@pyedb_function_handler
|
|
921
|
+
def get_configurations(self):
|
|
922
|
+
"""Get SIwave SYZ simulation settings.
|
|
923
|
+
|
|
924
|
+
Returns
|
|
925
|
+
-------
|
|
926
|
+
dict
|
|
927
|
+
Dictionary of SIwave SYZ simulation settings.
|
|
928
|
+
"""
|
|
929
|
+
return {
|
|
930
|
+
"pi_slider_position": self.pi_slider_position,
|
|
931
|
+
"si_slider_position": self.si_slider_position,
|
|
932
|
+
"use_custom_settings": self.use_si_settings,
|
|
933
|
+
"use_si_settings": self.use_si_settings,
|
|
934
|
+
"advanced_settings": self.advanced_settings.get_configurations(),
|
|
935
|
+
}
|
|
936
|
+
|
|
937
|
+
@property
|
|
938
|
+
def advanced_settings(self):
|
|
939
|
+
"""SIwave advanced settings."""
|
|
940
|
+
return AdvancedSettings(self)
|
|
941
|
+
|
|
942
|
+
@property
|
|
943
|
+
def get_sim_setup_info(self):
|
|
944
|
+
"""Get simulation information from the setup."""
|
|
945
|
+
if self._sim_setup_info:
|
|
946
|
+
return self._sim_setup_info
|
|
947
|
+
|
|
948
|
+
edb_setup = self._edb_object
|
|
949
|
+
edb_sim_setup_info = self._pedb.simsetupdata.SimSetupInfo[self._setup_type_mapping[self._setup_type]]()
|
|
950
|
+
edb_sim_setup_info.Name = edb_setup.GetName()
|
|
951
|
+
|
|
952
|
+
string = edb_setup.ToString().replace("\t", "").split("\r\n")
|
|
953
|
+
|
|
954
|
+
if is_linux:
|
|
955
|
+
string = string[0].split("\n")
|
|
956
|
+
keys = [i.split("=")[0] for i in string if len(i.split("=")) == 2 and "SourceTermsToGround" not in i]
|
|
957
|
+
values = [i.split("=")[1] for i in string if len(i.split("=")) == 2 and "SourceTermsToGround" not in i]
|
|
958
|
+
for val in string:
|
|
959
|
+
if "SourceTermsToGround()" in val:
|
|
960
|
+
break
|
|
961
|
+
elif "SourceTermsToGround" in val:
|
|
962
|
+
sources = {}
|
|
963
|
+
val = val.replace("SourceTermsToGround(", "").replace(")", "").split(",")
|
|
964
|
+
for v in val:
|
|
965
|
+
source = v.split("=")
|
|
966
|
+
sources[source[0]] = source[1]
|
|
967
|
+
edb_sim_setup_info.SimulationSettings.DCIRSettings.SourceTermsToGround = convert_pydict_to_netdict(
|
|
968
|
+
sources
|
|
969
|
+
)
|
|
970
|
+
break
|
|
971
|
+
for k in keys:
|
|
972
|
+
value = _parse_value(values[keys.index(k)])
|
|
973
|
+
setter = None
|
|
974
|
+
if k in dir(edb_sim_setup_info.SimulationSettings):
|
|
975
|
+
setter = edb_sim_setup_info.SimulationSettings
|
|
976
|
+
elif k in dir(edb_sim_setup_info.SimulationSettings.AdvancedSettings):
|
|
977
|
+
setter = edb_sim_setup_info.SimulationSettings.AdvancedSettings
|
|
978
|
+
|
|
979
|
+
elif k in dir(edb_sim_setup_info.SimulationSettings.DCAdvancedSettings):
|
|
980
|
+
setter = edb_sim_setup_info.SimulationSettings.DCAdvancedSettings
|
|
981
|
+
elif "DCIRSettings" in dir(edb_sim_setup_info.SimulationSettings) and k in dir(
|
|
982
|
+
edb_sim_setup_info.SimulationSettings.DCIRSettings
|
|
983
|
+
):
|
|
984
|
+
setter = edb_sim_setup_info.SimulationSettings.DCIRSettings
|
|
985
|
+
elif k in dir(edb_sim_setup_info.SimulationSettings.DCSettings):
|
|
986
|
+
setter = edb_sim_setup_info.SimulationSettings.DCSettings
|
|
987
|
+
elif k in dir(edb_sim_setup_info.SimulationSettings.AdvancedSettings):
|
|
988
|
+
setter = edb_sim_setup_info.SimulationSettings.AdvancedSettings
|
|
989
|
+
if setter:
|
|
990
|
+
try:
|
|
991
|
+
setter.__setattr__(k, value)
|
|
992
|
+
except TypeError:
|
|
993
|
+
try:
|
|
994
|
+
setter.__setattr__(k, str(value))
|
|
995
|
+
except:
|
|
996
|
+
pass
|
|
997
|
+
|
|
998
|
+
return edb_sim_setup_info
|
|
999
|
+
|
|
1000
|
+
@pyedb_function_handler
|
|
1001
|
+
def set_pi_slider(self, value):
|
|
1002
|
+
"""Set SIwave PI simulation accuracy level.
|
|
1003
|
+
Options are:
|
|
1004
|
+
- ``0``: Optimal speed
|
|
1005
|
+
- ``1``: Balanced
|
|
1006
|
+
- ``2``: Optimal accuracy
|
|
1007
|
+
|
|
1008
|
+
.. deprecated:: 0.7.5
|
|
1009
|
+
Use :property:`pi_slider_position` property instead.
|
|
1010
|
+
|
|
1011
|
+
"""
|
|
1012
|
+
warnings.warn("`set_pi_slider` is deprecated. Use `pi_slider_position` property instead.", DeprecationWarning)
|
|
1013
|
+
self.pi_slider_position = value
|
|
1014
|
+
|
|
1015
|
+
@pyedb_function_handler
|
|
1016
|
+
def set_si_slider(self, value):
|
|
1017
|
+
"""Set SIwave SI simulation accuracy level.
|
|
1018
|
+
|
|
1019
|
+
Options are:
|
|
1020
|
+
- ``0``: Optimal speed;
|
|
1021
|
+
- ``1``: Balanced;
|
|
1022
|
+
- ``2``: Optimal accuracy```.
|
|
1023
|
+
"""
|
|
1024
|
+
self.use_si_settings = True
|
|
1025
|
+
self.use_custom_settings = False
|
|
1026
|
+
self.si_slider_position = value
|
|
1027
|
+
self.advanced_settings.set_si_slider(value)
|
|
1028
|
+
|
|
1029
|
+
@property
|
|
1030
|
+
def pi_slider_position(self):
|
|
1031
|
+
"""PI solider position. Values are from ``1`` to ``3``."""
|
|
1032
|
+
return self.get_sim_setup_info.SimulationSettings.PISliderPos
|
|
1033
|
+
|
|
1034
|
+
@pi_slider_position.setter
|
|
1035
|
+
def pi_slider_position(self, value):
|
|
1036
|
+
edb_setup_info = self.get_sim_setup_info
|
|
1037
|
+
edb_setup_info.SimulationSettings.PISliderPos = value
|
|
1038
|
+
self._edb_object = self._set_edb_setup_info(edb_setup_info)
|
|
1039
|
+
self._update_setup()
|
|
1040
|
+
|
|
1041
|
+
self.use_si_settings = False
|
|
1042
|
+
self.use_custom_settings = False
|
|
1043
|
+
self.advanced_settings.set_pi_slider(value)
|
|
1044
|
+
|
|
1045
|
+
@property
|
|
1046
|
+
def si_slider_position(self):
|
|
1047
|
+
"""SI slider position. Values are from ``1`` to ``3``."""
|
|
1048
|
+
return self.get_sim_setup_info.SimulationSettings.SISliderPos
|
|
1049
|
+
|
|
1050
|
+
@si_slider_position.setter
|
|
1051
|
+
def si_slider_position(self, value):
|
|
1052
|
+
edb_setup_info = self.get_sim_setup_info
|
|
1053
|
+
edb_setup_info.SimulationSettings.SISliderPos = value
|
|
1054
|
+
self._edb_object = self._set_edb_setup_info(edb_setup_info)
|
|
1055
|
+
self._update_setup()
|
|
1056
|
+
|
|
1057
|
+
self.use_si_settings = True
|
|
1058
|
+
self.use_custom_settings = False
|
|
1059
|
+
self.advanced_settings.set_si_slider(value)
|
|
1060
|
+
|
|
1061
|
+
@property
|
|
1062
|
+
def use_custom_settings(self):
|
|
1063
|
+
"""Custom settings to use.
|
|
1064
|
+
|
|
1065
|
+
Returns
|
|
1066
|
+
-------
|
|
1067
|
+
bool
|
|
1068
|
+
"""
|
|
1069
|
+
return self.get_sim_setup_info.SimulationSettings.UseCustomSettings
|
|
1070
|
+
|
|
1071
|
+
@use_custom_settings.setter
|
|
1072
|
+
def use_custom_settings(self, value):
|
|
1073
|
+
edb_setup_info = self.get_sim_setup_info
|
|
1074
|
+
edb_setup_info.SimulationSettings.UseCustomSettings = value
|
|
1075
|
+
self._edb_object = self._set_edb_setup_info(edb_setup_info)
|
|
1076
|
+
self._update_setup()
|
|
1077
|
+
|
|
1078
|
+
@property
|
|
1079
|
+
def use_si_settings(self):
|
|
1080
|
+
"""Whether to use SI Settings.
|
|
1081
|
+
|
|
1082
|
+
Returns
|
|
1083
|
+
-------
|
|
1084
|
+
bool
|
|
1085
|
+
"""
|
|
1086
|
+
return self.get_sim_setup_info.SimulationSettings.UseSISettings
|
|
1087
|
+
|
|
1088
|
+
@use_si_settings.setter
|
|
1089
|
+
def use_si_settings(self, value):
|
|
1090
|
+
edb_setup_info = self.get_sim_setup_info
|
|
1091
|
+
edb_setup_info.SimulationSettings.UseSISettings = value
|
|
1092
|
+
self._edb_object = self._set_edb_setup_info(edb_setup_info)
|
|
1093
|
+
self._update_setup()
|
|
1094
|
+
|
|
1095
|
+
|
|
1096
|
+
class SiwaveDCSimulationSetup(SiwaveSYZSimulationSetup):
|
|
1097
|
+
"""Manages EDB methods for SIwave DC simulation setup.
|
|
1098
|
+
|
|
1099
|
+
Parameters
|
|
1100
|
+
----------
|
|
1101
|
+
pedb : :class:`pyedb.dotnet.edb.Edb`
|
|
1102
|
+
Inherited AEDT object.
|
|
1103
|
+
edb_setup : Ansys.Ansoft.Edb.Utility.SIWDCIRSimulationSettings
|
|
1104
|
+
EDB object. The default is ``None``.
|
|
1105
|
+
"""
|
|
1106
|
+
|
|
1107
|
+
def __init__(self, pedb, edb_object=None):
|
|
1108
|
+
super().__init__(pedb, edb_object)
|
|
1109
|
+
self._setup_type = "kSIwaveDCIR"
|
|
1110
|
+
self._edb = pedb
|
|
1111
|
+
self._mesh_operations = {}
|
|
1112
|
+
|
|
1113
|
+
def create(self, name=None):
|
|
1114
|
+
"""Create a SIwave DCIR setup.
|
|
1115
|
+
|
|
1116
|
+
Returns
|
|
1117
|
+
-------
|
|
1118
|
+
:class:`SiwaveDCSimulationSetup`
|
|
1119
|
+
"""
|
|
1120
|
+
self._name = name
|
|
1121
|
+
self._create(name)
|
|
1122
|
+
self.set_dc_slider(1)
|
|
1123
|
+
return self
|
|
1124
|
+
|
|
1125
|
+
@pyedb_function_handler
|
|
1126
|
+
def get_configurations(self):
|
|
1127
|
+
"""Get SIwave DC simulation settings.
|
|
1128
|
+
|
|
1129
|
+
Returns
|
|
1130
|
+
-------
|
|
1131
|
+
dict
|
|
1132
|
+
Dictionary of SIwave DC simulation settings.
|
|
1133
|
+
"""
|
|
1134
|
+
return {
|
|
1135
|
+
"dc_settings": self.dc_settings.get_configurations(),
|
|
1136
|
+
"dc_advanced_settings": self.dc_advanced_settings.get_configurations(),
|
|
1137
|
+
}
|
|
1138
|
+
|
|
1139
|
+
@pyedb_function_handler
|
|
1140
|
+
def set_dc_slider(self, value):
|
|
1141
|
+
"""Set DC simulation accuracy level.
|
|
1142
|
+
|
|
1143
|
+
Options are:
|
|
1144
|
+
|
|
1145
|
+
- ``0``: Optimal speed
|
|
1146
|
+
- ``1``: Balanced
|
|
1147
|
+
- ``2``: Optimal accuracy
|
|
1148
|
+
"""
|
|
1149
|
+
self.use_custom_settings = False
|
|
1150
|
+
self.dc_settings.dc_slider_position = value
|
|
1151
|
+
self.dc_advanced_settings.set_dc_slider(value)
|
|
1152
|
+
|
|
1153
|
+
@property
|
|
1154
|
+
def dc_settings(self):
|
|
1155
|
+
"""SIwave DC setting."""
|
|
1156
|
+
return DCSettings(self)
|
|
1157
|
+
|
|
1158
|
+
@property
|
|
1159
|
+
def dc_advanced_settings(self):
|
|
1160
|
+
"""Siwave DC advanced settings.
|
|
1161
|
+
|
|
1162
|
+
Returns
|
|
1163
|
+
-------
|
|
1164
|
+
:class:`pyedb.dotnet.edb_core.edb_data.siwave_simulation_setup_data.SiwaveDCAdvancedSettings`
|
|
1165
|
+
"""
|
|
1166
|
+
return DCAdvancedSettings(self)
|
|
1167
|
+
|
|
1168
|
+
@property
|
|
1169
|
+
def source_terms_to_ground(self):
|
|
1170
|
+
"""Dictionary of grounded terminals.
|
|
1171
|
+
|
|
1172
|
+
Returns
|
|
1173
|
+
-------
|
|
1174
|
+
Dictionary
|
|
1175
|
+
{str, int}, keys is source name, value int 0 unspecified, 1 negative node, 2 positive one.
|
|
1176
|
+
|
|
1177
|
+
"""
|
|
1178
|
+
return convert_netdict_to_pydict(self.get_sim_setup_info.SimulationSettings.DCIRSettings.SourceTermsToGround)
|
|
1179
|
+
|
|
1180
|
+
@pyedb_function_handler()
|
|
1181
|
+
def add_source_terminal_to_ground(self, source_name, terminal=0):
|
|
1182
|
+
"""Add a source terminal to ground.
|
|
1183
|
+
|
|
1184
|
+
Parameters
|
|
1185
|
+
----------
|
|
1186
|
+
source_name : str,
|
|
1187
|
+
Source name.
|
|
1188
|
+
terminal : int, optional
|
|
1189
|
+
Terminal to assign. Options are:
|
|
1190
|
+
|
|
1191
|
+
- 0=Unspecified
|
|
1192
|
+
- 1=Negative node
|
|
1193
|
+
- 2=Positive none
|
|
1194
|
+
|
|
1195
|
+
Returns
|
|
1196
|
+
-------
|
|
1197
|
+
bool
|
|
1198
|
+
|
|
1199
|
+
"""
|
|
1200
|
+
terminals = self.source_terms_to_ground
|
|
1201
|
+
terminals[source_name] = terminal
|
|
1202
|
+
self.get_sim_setup_info.SimulationSettings.DCIRSettings.SourceTermsToGround = convert_pydict_to_netdict(
|
|
1203
|
+
terminals
|
|
1204
|
+
)
|
|
1205
|
+
return self._update_setup()
|