pyedb 0.56.0__py3-none-any.whl → 0.57.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 +3 -0
- pyedb/configuration/cfg_terminals.py +232 -0
- pyedb/configuration/configuration.py +146 -3
- pyedb/dotnet/clr_module.py +1 -2
- pyedb/dotnet/database/Variables.py +30 -22
- pyedb/dotnet/database/cell/layout.py +5 -1
- pyedb/dotnet/database/cell/primitive/primitive.py +2 -2
- pyedb/dotnet/database/cell/terminal/bundle_terminal.py +12 -0
- pyedb/dotnet/database/cell/terminal/pingroup_terminal.py +1 -1
- pyedb/dotnet/database/cell/terminal/terminal.py +38 -0
- pyedb/dotnet/database/components.py +14 -16
- pyedb/dotnet/database/dotnet/database.py +1 -0
- pyedb/dotnet/database/edb_data/control_file.py +6 -3
- pyedb/dotnet/database/edb_data/nets_data.py +3 -3
- pyedb/dotnet/database/edb_data/padstacks_data.py +5 -2
- pyedb/dotnet/database/edb_data/ports.py +0 -25
- pyedb/dotnet/database/edb_data/primitives_data.py +3 -3
- pyedb/dotnet/database/edb_data/raptor_x_simulation_setup_data.py +18 -19
- pyedb/dotnet/database/edb_data/simulation_configuration.py +3 -3
- pyedb/dotnet/database/hfss.py +9 -8
- pyedb/dotnet/database/layout_validation.py +6 -3
- pyedb/dotnet/database/materials.py +1 -3
- pyedb/dotnet/database/modeler.py +7 -3
- pyedb/dotnet/database/nets.py +27 -19
- pyedb/dotnet/database/padstack.py +4 -2
- pyedb/dotnet/database/sim_setup_data/io/siwave.py +1 -1
- pyedb/dotnet/database/siwave.py +4 -3
- pyedb/dotnet/database/stackup.py +50 -26
- pyedb/dotnet/database/utilities/heatsink.py +0 -1
- pyedb/dotnet/database/utilities/simulation_setup.py +7 -5
- pyedb/dotnet/database/utilities/siwave_cpa_simulation_setup.py +1 -0
- pyedb/dotnet/database/utilities/siwave_simulation_setup.py +5 -2
- pyedb/dotnet/edb.py +39 -34
- pyedb/exceptions.py +1 -2
- pyedb/extensions/create_cell_array.py +19 -5
- pyedb/generic/data_handlers.py +13 -23
- pyedb/generic/design_types.py +9 -35
- pyedb/generic/filesystem.py +4 -2
- pyedb/generic/general_methods.py +4 -5
- pyedb/generic/plot.py +2 -2
- pyedb/grpc/database/_typing.py +0 -0
- pyedb/grpc/database/components.py +7 -8
- pyedb/grpc/database/control_file.py +14 -35
- pyedb/grpc/database/definition/materials.py +1 -1
- pyedb/grpc/database/definition/package_def.py +6 -3
- pyedb/grpc/database/definition/padstack_def.py +4 -7
- pyedb/grpc/database/hfss.py +1 -4
- pyedb/grpc/database/hierarchy/component.py +3 -4
- pyedb/grpc/database/hierarchy/pingroup.py +16 -3
- pyedb/grpc/database/layers/layer.py +1 -2
- pyedb/grpc/database/layers/stackup_layer.py +42 -19
- pyedb/grpc/database/layout/layout.py +43 -27
- pyedb/grpc/database/layout/voltage_regulator.py +6 -1
- pyedb/grpc/database/layout_validation.py +5 -2
- pyedb/grpc/database/modeler.py +226 -244
- pyedb/grpc/database/net/differential_pair.py +9 -2
- pyedb/grpc/database/net/extended_net.py +24 -9
- pyedb/grpc/database/net/net.py +14 -5
- pyedb/grpc/database/net/net_class.py +24 -7
- pyedb/grpc/database/nets.py +11 -43
- pyedb/grpc/database/padstacks.py +5 -16
- pyedb/grpc/database/primitive/bondwire.py +3 -67
- pyedb/grpc/database/primitive/circle.py +42 -3
- pyedb/grpc/database/primitive/padstack_instance.py +17 -19
- pyedb/grpc/database/primitive/path.py +154 -5
- pyedb/grpc/database/primitive/polygon.py +73 -7
- pyedb/grpc/database/primitive/primitive.py +2 -2
- pyedb/grpc/database/primitive/rectangle.py +105 -4
- pyedb/grpc/database/simulation_setup/hfss_general_settings.py +0 -2
- pyedb/grpc/database/simulation_setup/hfss_settings_options.py +0 -4
- pyedb/grpc/database/simulation_setup/siwave_cpa_simulation_setup.py +1 -0
- pyedb/grpc/database/simulation_setup/sweep_data.py +1 -3
- pyedb/grpc/database/siwave.py +6 -13
- pyedb/grpc/database/source_excitations.py +39 -56
- pyedb/grpc/database/stackup.py +50 -27
- pyedb/grpc/database/terminal/bundle_terminal.py +10 -3
- pyedb/grpc/database/terminal/pingroup_terminal.py +8 -1
- pyedb/grpc/database/terminal/terminal.py +19 -8
- pyedb/grpc/database/utility/heat_sink.py +0 -1
- pyedb/grpc/database/utility/hfss_extent_info.py +2 -2
- pyedb/grpc/database/utility/xml_control_file.py +6 -3
- pyedb/grpc/edb.py +24 -19
- pyedb/grpc/edb_init.py +1 -0
- pyedb/ipc2581/ecad/cad_data/layer_feature.py +6 -2
- pyedb/ipc2581/ecad/cad_data/step.py +1 -1
- pyedb/ipc2581/ipc2581.py +8 -7
- pyedb/libraries/common.py +3 -4
- pyedb/libraries/rf_libraries/base_functions.py +7 -16
- pyedb/libraries/rf_libraries/planar_antennas.py +3 -21
- pyedb/misc/downloads.py +1 -0
- pyedb/misc/misc.py +5 -2
- pyedb/misc/siw_feature_config/emc_rule_checker_settings.py +1 -1
- pyedb/misc/utilities.py +0 -1
- pyedb/modeler/geometry_operators.py +3 -2
- {pyedb-0.56.0.dist-info → pyedb-0.57.0.dist-info}/METADATA +3 -3
- {pyedb-0.56.0.dist-info → pyedb-0.57.0.dist-info}/RECORD +99 -97
- {pyedb-0.56.0.dist-info → pyedb-0.57.0.dist-info}/WHEEL +0 -0
- {pyedb-0.56.0.dist-info → pyedb-0.57.0.dist-info}/licenses/LICENSE +0 -0
pyedb/__init__.py
CHANGED
pyedb/configuration/cfg_data.py
CHANGED
|
@@ -36,6 +36,7 @@ from pyedb.configuration.cfg_s_parameter_models import CfgSParameters
|
|
|
36
36
|
from pyedb.configuration.cfg_setup import CfgSetups
|
|
37
37
|
from pyedb.configuration.cfg_spice_models import CfgSpiceModel
|
|
38
38
|
from pyedb.configuration.cfg_stackup import CfgStackup
|
|
39
|
+
from pyedb.configuration.cfg_terminals import CfgTerminals
|
|
39
40
|
|
|
40
41
|
|
|
41
42
|
class CfgData(object):
|
|
@@ -59,6 +60,8 @@ class CfgData(object):
|
|
|
59
60
|
|
|
60
61
|
self.pin_groups = CfgPinGroups(self._pedb, pingroup_data=kwargs.get("pin_groups", []))
|
|
61
62
|
|
|
63
|
+
self.terminals = CfgTerminals.create(terminals=kwargs.get("terminals", []))
|
|
64
|
+
|
|
62
65
|
self.ports = CfgPorts(self._pedb, ports_data=kwargs.get("ports", []))
|
|
63
66
|
|
|
64
67
|
self.sources = CfgSources(self._pedb, sources_data=kwargs.get("sources", []))
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
from typing import List, Literal, Optional, Union
|
|
2
|
+
|
|
3
|
+
from pydantic import BaseModel
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class CfgBase(BaseModel):
|
|
7
|
+
model_config = {
|
|
8
|
+
"populate_by_name": True,
|
|
9
|
+
"extra": "forbid",
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class CfgTerminal(CfgBase):
|
|
14
|
+
name: str
|
|
15
|
+
impedance: Union[float, int, str]
|
|
16
|
+
is_circuit_port: bool
|
|
17
|
+
reference_terminal: Optional[str] = None
|
|
18
|
+
amplitude: Optional[Union[float, int, str]] = 1
|
|
19
|
+
phase: Optional[Union[float, int, str]] = 0
|
|
20
|
+
terminal_to_ground: Optional[Literal["kNoGround", "kNegative", "kPositive"]] = "kNoGround"
|
|
21
|
+
boundary_type: Literal[
|
|
22
|
+
"PortBoundary",
|
|
23
|
+
"PecBoundary",
|
|
24
|
+
"RlcBoundary",
|
|
25
|
+
"kCurrentSource",
|
|
26
|
+
"kVoltageSource",
|
|
27
|
+
"kNexximGround",
|
|
28
|
+
"kNexximPort",
|
|
29
|
+
"kDcTerminal",
|
|
30
|
+
"kVoltageProbe",
|
|
31
|
+
"InvalidBoundary",
|
|
32
|
+
]
|
|
33
|
+
hfss_type: Literal["Wave", "Gap", None]
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class CfgPadstackInstanceTerminal(CfgTerminal):
|
|
37
|
+
terminal_type: str = "padstack_instance"
|
|
38
|
+
padstack_instance: str
|
|
39
|
+
padstack_instance_id: Optional[int] = None
|
|
40
|
+
layer: Optional[Union[str, None]] = None
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class CfgPinGroupTerminal(CfgTerminal):
|
|
44
|
+
terminal_type: str = "pin_group"
|
|
45
|
+
is_circuit_port: bool = True
|
|
46
|
+
pin_group: str
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class CfgPointTerminal(CfgTerminal):
|
|
50
|
+
terminal_type: str = "point"
|
|
51
|
+
x: Union[float, int, str]
|
|
52
|
+
y: Union[float, int, str]
|
|
53
|
+
layer: str
|
|
54
|
+
net: str
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
class CfgEdgeTerminal(CfgTerminal):
|
|
58
|
+
terminal_type: str = "edge"
|
|
59
|
+
name: str
|
|
60
|
+
primitive: str
|
|
61
|
+
point_on_edge_x: Union[float, int, str]
|
|
62
|
+
point_on_edge_y: Union[float, int, str]
|
|
63
|
+
horizontal_extent_factor: Union[int, str]
|
|
64
|
+
vertical_extent_factor: Union[int, str]
|
|
65
|
+
pec_launch_width: Union[int, str]
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
class CfgBundleTerminal(CfgBase):
|
|
69
|
+
terminal_type: str = "bundle"
|
|
70
|
+
terminals: List[str]
|
|
71
|
+
name: str
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
class CfgTerminals(CfgBase):
|
|
75
|
+
terminals: List[
|
|
76
|
+
Union[
|
|
77
|
+
CfgPadstackInstanceTerminal, CfgPinGroupTerminal, CfgPointTerminal, CfgEdgeTerminal, CfgBundleTerminal, dict
|
|
78
|
+
]
|
|
79
|
+
]
|
|
80
|
+
|
|
81
|
+
@classmethod
|
|
82
|
+
def create(cls, terminals: List[dict]):
|
|
83
|
+
manager = cls(terminals=[])
|
|
84
|
+
for i in terminals:
|
|
85
|
+
terminal_type = i.pop("terminal_type")
|
|
86
|
+
if terminal_type == "padstack_instance":
|
|
87
|
+
manager.add_padstack_instance_terminal(**i)
|
|
88
|
+
elif terminal_type == "pin_group":
|
|
89
|
+
manager.add_pin_group_terminal(**i)
|
|
90
|
+
elif terminal_type == "point":
|
|
91
|
+
manager.add_point_terminal(**i)
|
|
92
|
+
elif terminal_type == "edge":
|
|
93
|
+
manager.add_edge_terminal(**i)
|
|
94
|
+
elif terminal_type == "bundle":
|
|
95
|
+
manager.add_bundle_terminal(**i)
|
|
96
|
+
else: # pragma: no cover
|
|
97
|
+
raise ValueError(f"Unknown terminal type: {terminal_type}")
|
|
98
|
+
return manager
|
|
99
|
+
|
|
100
|
+
def add_padstack_instance_terminal(
|
|
101
|
+
self,
|
|
102
|
+
padstack_instance,
|
|
103
|
+
name,
|
|
104
|
+
impedance,
|
|
105
|
+
is_circuit_port,
|
|
106
|
+
boundary_type,
|
|
107
|
+
hfss_type,
|
|
108
|
+
reference_terminal=None,
|
|
109
|
+
amplitude=1,
|
|
110
|
+
phase=0,
|
|
111
|
+
terminal_to_ground="kNoGround",
|
|
112
|
+
padstack_instance_id=None,
|
|
113
|
+
layer=None,
|
|
114
|
+
):
|
|
115
|
+
terminal = CfgPadstackInstanceTerminal(
|
|
116
|
+
padstack_instance=padstack_instance,
|
|
117
|
+
name=name,
|
|
118
|
+
impedance=impedance,
|
|
119
|
+
is_circuit_port=is_circuit_port,
|
|
120
|
+
boundary_type=boundary_type,
|
|
121
|
+
reference_terminal=reference_terminal,
|
|
122
|
+
amplitude=amplitude,
|
|
123
|
+
phase=phase,
|
|
124
|
+
terminal_to_ground=terminal_to_ground,
|
|
125
|
+
layer=layer,
|
|
126
|
+
hfss_type=hfss_type,
|
|
127
|
+
padstack_instance_id=padstack_instance_id,
|
|
128
|
+
)
|
|
129
|
+
self.terminals.append(terminal)
|
|
130
|
+
|
|
131
|
+
def add_pin_group_terminal(
|
|
132
|
+
self,
|
|
133
|
+
pin_group,
|
|
134
|
+
name,
|
|
135
|
+
impedance,
|
|
136
|
+
boundary_type,
|
|
137
|
+
reference_terminal=None,
|
|
138
|
+
amplitude=1,
|
|
139
|
+
phase=0,
|
|
140
|
+
terminal_to_ground="kNoGround",
|
|
141
|
+
):
|
|
142
|
+
terminal = CfgPinGroupTerminal(
|
|
143
|
+
pin_group=pin_group,
|
|
144
|
+
name=name,
|
|
145
|
+
impedance=impedance,
|
|
146
|
+
is_circuit_port=True,
|
|
147
|
+
boundary_type=boundary_type,
|
|
148
|
+
reference_terminal=reference_terminal,
|
|
149
|
+
amplitude=amplitude,
|
|
150
|
+
phase=phase,
|
|
151
|
+
terminal_to_ground=terminal_to_ground,
|
|
152
|
+
hfss_type=None,
|
|
153
|
+
)
|
|
154
|
+
self.terminals.append(terminal)
|
|
155
|
+
|
|
156
|
+
def add_point_terminal(
|
|
157
|
+
self,
|
|
158
|
+
x,
|
|
159
|
+
y,
|
|
160
|
+
layer,
|
|
161
|
+
name,
|
|
162
|
+
impedance,
|
|
163
|
+
boundary_type,
|
|
164
|
+
net,
|
|
165
|
+
reference_terminal=None,
|
|
166
|
+
amplitude=1,
|
|
167
|
+
phase=0,
|
|
168
|
+
terminal_to_ground="kNoGround",
|
|
169
|
+
):
|
|
170
|
+
terminal = CfgPointTerminal(
|
|
171
|
+
x=x,
|
|
172
|
+
y=y,
|
|
173
|
+
layer=layer,
|
|
174
|
+
name=name,
|
|
175
|
+
impedance=impedance,
|
|
176
|
+
is_circuit_port=True,
|
|
177
|
+
boundary_type=boundary_type,
|
|
178
|
+
reference_terminal=reference_terminal,
|
|
179
|
+
amplitude=amplitude,
|
|
180
|
+
phase=phase,
|
|
181
|
+
net=net,
|
|
182
|
+
terminal_to_ground=terminal_to_ground,
|
|
183
|
+
hfss_type=None,
|
|
184
|
+
)
|
|
185
|
+
self.terminals.append(terminal)
|
|
186
|
+
|
|
187
|
+
def add_edge_terminal(
|
|
188
|
+
self,
|
|
189
|
+
name,
|
|
190
|
+
impedance,
|
|
191
|
+
is_circuit_port,
|
|
192
|
+
boundary_type,
|
|
193
|
+
primitive,
|
|
194
|
+
point_on_edge_x,
|
|
195
|
+
point_on_edge_y,
|
|
196
|
+
horizontal_extent_factor=6,
|
|
197
|
+
vertical_extent_factor=8,
|
|
198
|
+
pec_launch_width="0.02mm",
|
|
199
|
+
reference_terminal=None,
|
|
200
|
+
amplitude=1,
|
|
201
|
+
phase=0,
|
|
202
|
+
terminal_to_ground="kNoGround",
|
|
203
|
+
):
|
|
204
|
+
terminal = CfgEdgeTerminal(
|
|
205
|
+
name=name,
|
|
206
|
+
impedance=impedance,
|
|
207
|
+
is_circuit_port=is_circuit_port,
|
|
208
|
+
boundary_type=boundary_type,
|
|
209
|
+
reference_terminal=reference_terminal,
|
|
210
|
+
amplitude=amplitude,
|
|
211
|
+
phase=phase,
|
|
212
|
+
terminal_to_ground=terminal_to_ground,
|
|
213
|
+
primitive=primitive,
|
|
214
|
+
point_on_edge_x=point_on_edge_x,
|
|
215
|
+
point_on_edge_y=point_on_edge_y,
|
|
216
|
+
horizontal_extent_factor=horizontal_extent_factor,
|
|
217
|
+
vertical_extent_factor=vertical_extent_factor,
|
|
218
|
+
pec_launch_width=pec_launch_width,
|
|
219
|
+
hfss_type="Wave",
|
|
220
|
+
)
|
|
221
|
+
self.terminals.append(terminal)
|
|
222
|
+
|
|
223
|
+
def add_bundle_terminal(
|
|
224
|
+
self,
|
|
225
|
+
terminals,
|
|
226
|
+
name,
|
|
227
|
+
):
|
|
228
|
+
terminal = CfgBundleTerminal(
|
|
229
|
+
terminals=terminals,
|
|
230
|
+
name=name,
|
|
231
|
+
)
|
|
232
|
+
self.terminals.append(terminal)
|
|
@@ -29,6 +29,8 @@ import toml
|
|
|
29
29
|
|
|
30
30
|
from pyedb import Edb
|
|
31
31
|
from pyedb.configuration.cfg_data import CfgData
|
|
32
|
+
from pyedb.dotnet.database.general import convert_py_list_to_net_list
|
|
33
|
+
from pyedb.misc.decorators import execution_timer
|
|
32
34
|
|
|
33
35
|
|
|
34
36
|
class Configuration:
|
|
@@ -146,8 +148,9 @@ class Configuration:
|
|
|
146
148
|
self.__apply_with_logging("Applying package definitions", self.cfg_data.package_definitions.apply)
|
|
147
149
|
self.__apply_with_logging("Applying modeler", self.apply_modeler)
|
|
148
150
|
self.__apply_with_logging("Placing ports", self.cfg_data.ports.apply)
|
|
151
|
+
self.apply_terminals()
|
|
149
152
|
self.__apply_with_logging("Placing probes", self.cfg_data.probes.apply)
|
|
150
|
-
self.
|
|
153
|
+
self.apply_operations()
|
|
151
154
|
|
|
152
155
|
return True
|
|
153
156
|
|
|
@@ -433,6 +436,9 @@ class Configuration:
|
|
|
433
436
|
setups = self.cfg_data.setups
|
|
434
437
|
setups.retrieve_parameters_from_edb()
|
|
435
438
|
data["setups"] = setups.to_dict()
|
|
439
|
+
if kwargs.get("terminals", False):
|
|
440
|
+
self.get_terminals()
|
|
441
|
+
data.update(self.cfg_data.terminals.model_dump(exclude_none=True))
|
|
436
442
|
if kwargs.get("sources", False):
|
|
437
443
|
data["sources"] = self.cfg_data.sources.get_data_from_db()
|
|
438
444
|
if kwargs.get("ports", False):
|
|
@@ -472,6 +478,7 @@ class Configuration:
|
|
|
472
478
|
|
|
473
479
|
return data
|
|
474
480
|
|
|
481
|
+
@execution_timer("Applying operations")
|
|
475
482
|
def apply_operations(self):
|
|
476
483
|
"""Apply operations to the current design."""
|
|
477
484
|
op_cutout = self.cfg_data.operations.cutout
|
|
@@ -530,6 +537,138 @@ class Configuration:
|
|
|
530
537
|
signal_list=signal_list,
|
|
531
538
|
)
|
|
532
539
|
|
|
540
|
+
@execution_timer("Placing terminals")
|
|
541
|
+
def apply_terminals(self):
|
|
542
|
+
terminals_dict = {}
|
|
543
|
+
bungle_terminals = []
|
|
544
|
+
edge_terminals = {}
|
|
545
|
+
for cfg_terminal in self.cfg_data.terminals.terminals:
|
|
546
|
+
if cfg_terminal.terminal_type == "padstack_instance":
|
|
547
|
+
if cfg_terminal.padstack_instance_id:
|
|
548
|
+
pds = self._pedb.layout.find_padstack_instances(
|
|
549
|
+
instance_id=cfg_terminal.padstack_instance_id,
|
|
550
|
+
aedt_name=None,
|
|
551
|
+
component_name=None,
|
|
552
|
+
component_pin_name=None,
|
|
553
|
+
)[0]
|
|
554
|
+
else:
|
|
555
|
+
pds = self._pedb.layout.find_padstack_instances(
|
|
556
|
+
instance_id=None,
|
|
557
|
+
aedt_name=cfg_terminal.padstack_instance,
|
|
558
|
+
component_name=None,
|
|
559
|
+
component_pin_name=None,
|
|
560
|
+
)[0]
|
|
561
|
+
terminal = pds.create_terminal(name=cfg_terminal.name)
|
|
562
|
+
|
|
563
|
+
elif cfg_terminal.terminal_type == "pin_group":
|
|
564
|
+
pg = self._pedb.siwave.pin_groups[cfg_terminal.pin_group]
|
|
565
|
+
terminal = pg.create_terminal(name=cfg_terminal.name)
|
|
566
|
+
elif cfg_terminal.terminal_type == "point":
|
|
567
|
+
terminal = self._pedb.get_point_terminal(
|
|
568
|
+
cfg_terminal.name, cfg_terminal.net, [cfg_terminal.x, cfg_terminal.y], cfg_terminal.layer
|
|
569
|
+
)
|
|
570
|
+
elif cfg_terminal.terminal_type == "edge":
|
|
571
|
+
pt = self._pedb.pedb_class.database.geometry.point_data.PointData.create_from_xy(
|
|
572
|
+
self._pedb, x=cfg_terminal.point_on_edge_x, y=cfg_terminal.point_on_edge_y
|
|
573
|
+
)
|
|
574
|
+
primitive = self._pedb.layout.primitives_by_aedt_name[cfg_terminal.primitive]
|
|
575
|
+
edge = self._pedb.core.Cell.Terminal.PrimitiveEdge.Create(primitive._edb_object, pt._edb_object)
|
|
576
|
+
edge = convert_py_list_to_net_list(edge, self._pedb.core.Cell.Terminal.Edge)
|
|
577
|
+
_terminal = self._pedb.core.Cell.Terminal.EdgeTerminal.Create(
|
|
578
|
+
primitive._edb_object.GetLayout(),
|
|
579
|
+
primitive._edb_object.GetNet(),
|
|
580
|
+
cfg_terminal.name,
|
|
581
|
+
edge,
|
|
582
|
+
isRef=False,
|
|
583
|
+
)
|
|
584
|
+
terminal = self._pedb.pedb_class.database.cell.terminal.edge_terminal.EdgeTerminal(
|
|
585
|
+
self._pedb, _terminal
|
|
586
|
+
)
|
|
587
|
+
terminal.horizontal_extent_factor = terminal.horizontal_extent_factor
|
|
588
|
+
terminal.vertical_extent_factor = terminal.vertical_extent_factor
|
|
589
|
+
terminal.pec_launch_width = terminal.pec_launch_width
|
|
590
|
+
terminal.do_renormalize = True
|
|
591
|
+
edge_terminals[cfg_terminal.name] = terminal
|
|
592
|
+
elif cfg_terminal.terminal_type == "bundle":
|
|
593
|
+
bungle_terminals.append(cfg_terminal)
|
|
594
|
+
continue
|
|
595
|
+
else:
|
|
596
|
+
self._pedb.logger.warning(f"Terminal type {cfg_terminal.terminal_type} not supported.")
|
|
597
|
+
continue
|
|
598
|
+
|
|
599
|
+
terminal.impedance = cfg_terminal.impedance
|
|
600
|
+
terminal.is_circuit_port = cfg_terminal.is_circuit_port
|
|
601
|
+
terminal.boundary_type = cfg_terminal.boundary_type
|
|
602
|
+
terminal.source_amplitude = cfg_terminal.amplitude
|
|
603
|
+
terminal.source_phase = cfg_terminal.phase
|
|
604
|
+
terminal.terminal_to_ground = cfg_terminal.terminal_to_ground
|
|
605
|
+
|
|
606
|
+
terminals_dict[cfg_terminal.name] = cfg_terminal, terminal
|
|
607
|
+
|
|
608
|
+
for _, obj in terminals_dict.items():
|
|
609
|
+
cfg, obj = obj
|
|
610
|
+
if cfg.reference_terminal:
|
|
611
|
+
obj.reference_terminal = terminals_dict[cfg.reference_terminal][1]
|
|
612
|
+
|
|
613
|
+
for i in bungle_terminals:
|
|
614
|
+
boundle_terminal = self._pedb.pedb_class.database.cell.terminal.bundle_terminal.BundleTerminal.create(
|
|
615
|
+
self._pedb, i.name, i.terminals
|
|
616
|
+
)
|
|
617
|
+
bundle_term = boundle_terminal.terminals
|
|
618
|
+
bundle_term[0].name = i.name + ":T1"
|
|
619
|
+
bundle_term[1].mame = i.name + ":T2"
|
|
620
|
+
|
|
621
|
+
@execution_timer("Retrieving terminal information")
|
|
622
|
+
def get_terminals(self):
|
|
623
|
+
manager = self.cfg_data.terminals
|
|
624
|
+
manager.terminals = []
|
|
625
|
+
for i in self._pedb.terminals.values():
|
|
626
|
+
if i.terminal_type == "PadstackInstanceTerminal":
|
|
627
|
+
manager.add_padstack_instance_terminal(
|
|
628
|
+
padstack_instance=i.padstack_instance.aedt_name,
|
|
629
|
+
padstack_instance_id=i.padstack_instance.id,
|
|
630
|
+
name=i.name,
|
|
631
|
+
impedance=i.impedance,
|
|
632
|
+
is_circuit_port=i.is_circuit_port,
|
|
633
|
+
boundary_type=i.boundary_type,
|
|
634
|
+
amplitude=i.source_amplitude,
|
|
635
|
+
phase=i.source_phase,
|
|
636
|
+
terminal_to_ground=i.terminal_to_ground,
|
|
637
|
+
reference_terminal=i.reference_terminal.name if i.reference_terminal else None,
|
|
638
|
+
hfss_type=i.hfss_type if i.hfss_type else "Wave",
|
|
639
|
+
)
|
|
640
|
+
elif i.terminal_type == "PinGroupTerminal":
|
|
641
|
+
manager.add_pin_group_terminal(
|
|
642
|
+
pin_group=i.pin_group().name,
|
|
643
|
+
name=i.name,
|
|
644
|
+
impedance=i.impedance,
|
|
645
|
+
boundary_type=i.boundary_type,
|
|
646
|
+
reference_terminal=i.reference_terminal.name if i.reference_terminal else None,
|
|
647
|
+
amplitude=i.source_amplitude,
|
|
648
|
+
phase=i.source_phase,
|
|
649
|
+
terminal_to_ground=i.terminal_to_ground,
|
|
650
|
+
)
|
|
651
|
+
elif i.terminal_type == "PointTerminal":
|
|
652
|
+
manager.add_point_terminal(
|
|
653
|
+
x=i.location[0],
|
|
654
|
+
y=i.location[1],
|
|
655
|
+
layer=i.layer.name,
|
|
656
|
+
name=i.name,
|
|
657
|
+
impedance=i.impedance,
|
|
658
|
+
boundary_type=i.boundary_type,
|
|
659
|
+
reference_terminal=i.reference_terminal.name if i.reference_terminal else None,
|
|
660
|
+
amplitude=i.source_amplitude,
|
|
661
|
+
phase=i.source_phase,
|
|
662
|
+
terminal_to_ground=i.terminal_to_ground,
|
|
663
|
+
net=i.net_name,
|
|
664
|
+
)
|
|
665
|
+
elif i.terminal_type == "EdgeTerminal":
|
|
666
|
+
pass
|
|
667
|
+
elif i.terminal_type == "BundleTerminal":
|
|
668
|
+
pass
|
|
669
|
+
else: # pragma: no cover
|
|
670
|
+
raise RuntimeError(f"Terminal type {i.terminal_type} not supported.")
|
|
671
|
+
|
|
533
672
|
def export(
|
|
534
673
|
self,
|
|
535
674
|
file_path,
|
|
@@ -547,6 +686,7 @@ class Configuration:
|
|
|
547
686
|
padstacks=True,
|
|
548
687
|
general=True,
|
|
549
688
|
variables=True,
|
|
689
|
+
terminals=False,
|
|
550
690
|
):
|
|
551
691
|
"""Export the configuration data from layout to a file.
|
|
552
692
|
|
|
@@ -561,9 +701,9 @@ class Configuration:
|
|
|
561
701
|
setups : bool
|
|
562
702
|
Whether to export setups or not.
|
|
563
703
|
sources : bool
|
|
564
|
-
Whether to export sources or not.
|
|
704
|
+
Whether to export sources or not. Alternative to terminals.
|
|
565
705
|
ports : bool
|
|
566
|
-
Whether to export ports or not.
|
|
706
|
+
Whether to export ports or not. Alternative to terminals.
|
|
567
707
|
nets : bool
|
|
568
708
|
Whether to export nets.
|
|
569
709
|
pin_groups : bool
|
|
@@ -582,6 +722,8 @@ class Configuration:
|
|
|
582
722
|
Whether to export general information.
|
|
583
723
|
variables : bool
|
|
584
724
|
Whether to export variable.
|
|
725
|
+
terminals : bool
|
|
726
|
+
Whether to export terminals. Alternative to ports and sources.
|
|
585
727
|
Returns
|
|
586
728
|
-------
|
|
587
729
|
bool
|
|
@@ -601,6 +743,7 @@ class Configuration:
|
|
|
601
743
|
padstacks=padstacks,
|
|
602
744
|
general=general,
|
|
603
745
|
variables=variables,
|
|
746
|
+
terminals=terminals,
|
|
604
747
|
)
|
|
605
748
|
|
|
606
749
|
file_path = file_path if isinstance(file_path, Path) else Path(file_path)
|
pyedb/dotnet/clr_module.py
CHANGED
|
@@ -51,8 +51,7 @@ if is_linux: # pragma: no cover
|
|
|
51
51
|
# TODO: Fall backing to dotnetcore2 should be removed in a near future.
|
|
52
52
|
except Exception:
|
|
53
53
|
warnings.warn(
|
|
54
|
-
"Unable to set .NET root and locate the runtime configuration file. "
|
|
55
|
-
"Falling back to using dotnetcore2."
|
|
54
|
+
"Unable to set .NET root and locate the runtime configuration file. Falling back to using dotnetcore2."
|
|
56
55
|
)
|
|
57
56
|
warnings.warn(LINUX_WARNING)
|
|
58
57
|
|
|
@@ -35,9 +35,12 @@ Examples
|
|
|
35
35
|
|
|
36
36
|
"""
|
|
37
37
|
|
|
38
|
-
from __future__ import
|
|
39
|
-
|
|
38
|
+
from __future__ import (
|
|
39
|
+
absolute_import, # noreorder
|
|
40
|
+
division,
|
|
41
|
+
)
|
|
40
42
|
|
|
43
|
+
import ast
|
|
41
44
|
import os
|
|
42
45
|
import re
|
|
43
46
|
import types
|
|
@@ -493,13 +496,13 @@ class VariableManager(object):
|
|
|
493
496
|
--------
|
|
494
497
|
>>> hfss = Hfss()
|
|
495
498
|
>>> print(hfss.variable_manager.decompose("5mm"))
|
|
496
|
-
>>> (5.0,
|
|
499
|
+
>>> (5.0, "mm")
|
|
497
500
|
>>> hfss["v1"] = "3N"
|
|
498
501
|
>>> print(hfss.variable_manager.decompose("v1"))
|
|
499
|
-
>>> (3.0,
|
|
502
|
+
>>> (3.0, "N")
|
|
500
503
|
>>> hfss["v2"] = "2*v1"
|
|
501
504
|
>>> print(hfss.variable_manager.decompose("v2"))
|
|
502
|
-
>>> (6.0,
|
|
505
|
+
>>> (6.0, "N")
|
|
503
506
|
"""
|
|
504
507
|
if variable_value in self.independent_variable_names:
|
|
505
508
|
val, unit = decompose_variable_value(self[variable_value].expression)
|
|
@@ -1009,8 +1012,13 @@ class VariableManager(object):
|
|
|
1009
1012
|
creating the property if it does not already exist. Also make
|
|
1010
1013
|
it read-only and hidden and add a description.
|
|
1011
1014
|
|
|
1012
|
-
>>> aedtapp.variable_manager.set_variable(
|
|
1013
|
-
...
|
|
1015
|
+
>>> aedtapp.variable_manager.set_variable(
|
|
1016
|
+
... variable_name="p2",
|
|
1017
|
+
... expression="10mm",
|
|
1018
|
+
... readonly=True,
|
|
1019
|
+
... hidden=True,
|
|
1020
|
+
... description="This is the description of this variable.",
|
|
1021
|
+
... )
|
|
1014
1022
|
|
|
1015
1023
|
Set the value of the project variable ``$p1`` to ``"30mm"``,
|
|
1016
1024
|
creating the variable if it does not exist.
|
|
@@ -1073,8 +1081,8 @@ class VariableManager(object):
|
|
|
1073
1081
|
desktop_object.Undo()
|
|
1074
1082
|
self._logger.clear_messages()
|
|
1075
1083
|
return
|
|
1076
|
-
except:
|
|
1077
|
-
|
|
1084
|
+
except Exception:
|
|
1085
|
+
self._logger.debug(f"Something went wrong when deleting '{variable_name}'.")
|
|
1078
1086
|
else:
|
|
1079
1087
|
raise Exception("Unhandled input type to the design property or project variable.") # pragma: no cover
|
|
1080
1088
|
|
|
@@ -1204,8 +1212,8 @@ class VariableManager(object):
|
|
|
1204
1212
|
]
|
|
1205
1213
|
)
|
|
1206
1214
|
return True
|
|
1207
|
-
except:
|
|
1208
|
-
|
|
1215
|
+
except Exception:
|
|
1216
|
+
self._logger.debug("Failed to change desktop object property.")
|
|
1209
1217
|
return False
|
|
1210
1218
|
|
|
1211
1219
|
def delete_variable(self, var_name): # pragma: no cover
|
|
@@ -1244,8 +1252,8 @@ class VariableManager(object):
|
|
|
1244
1252
|
],
|
|
1245
1253
|
]
|
|
1246
1254
|
)
|
|
1247
|
-
except: # pragma: no cover
|
|
1248
|
-
|
|
1255
|
+
except Exception: # pragma: no cover
|
|
1256
|
+
self._logger.debug("Failed to change desktop object property.")
|
|
1249
1257
|
else:
|
|
1250
1258
|
self._cleanup_variables()
|
|
1251
1259
|
return True
|
|
@@ -1411,8 +1419,8 @@ class Variable(object):
|
|
|
1411
1419
|
if result:
|
|
1412
1420
|
break
|
|
1413
1421
|
i += 1
|
|
1414
|
-
except:
|
|
1415
|
-
|
|
1422
|
+
except Exception:
|
|
1423
|
+
self._app.logger.debug(f"Failed to set property '{prop}' value.")
|
|
1416
1424
|
|
|
1417
1425
|
def _get_prop_val(self, prop): # pragma: no cover
|
|
1418
1426
|
if self._app.design_type == "Maxwell Circuit":
|
|
@@ -1432,8 +1440,8 @@ class Variable(object):
|
|
|
1432
1440
|
else:
|
|
1433
1441
|
name = "LocalVariables"
|
|
1434
1442
|
return self._app.get_oo_object(self._aedt_obj, "{}/{}".format(name, self._variable_name)).GetPropValue(prop)
|
|
1435
|
-
except:
|
|
1436
|
-
|
|
1443
|
+
except Exception:
|
|
1444
|
+
self._app.logger.debug(f"Failed to get property '{prop}' value.")
|
|
1437
1445
|
|
|
1438
1446
|
@property
|
|
1439
1447
|
def name(self): # pragma: no cover
|
|
@@ -1642,7 +1650,7 @@ class Variable(object):
|
|
|
1642
1650
|
def numeric_value(self): # pragma: no cover
|
|
1643
1651
|
"""Numeric part of the expression as a float value."""
|
|
1644
1652
|
if is_array(self._value):
|
|
1645
|
-
return list(
|
|
1653
|
+
return list(ast.literal_eval(self._value))
|
|
1646
1654
|
try:
|
|
1647
1655
|
var_obj = self._aedt_obj.GetChildObject("Variables").GetChildObject(self._variable_name)
|
|
1648
1656
|
val, _ = decompose_variable_value(var_obj.GetPropEvaluatedValue("EvaluatedValue"))
|
|
@@ -1708,7 +1716,7 @@ class Variable(object):
|
|
|
1708
1716
|
>>> hfss = Hfss()
|
|
1709
1717
|
>>> hfss["v1"] = "3N"
|
|
1710
1718
|
>>> print(hfss.variable_manager["v1"].decompose("v1"))
|
|
1711
|
-
>>> (3.0,
|
|
1719
|
+
>>> (3.0, "N")
|
|
1712
1720
|
|
|
1713
1721
|
"""
|
|
1714
1722
|
return decompose_variable_value(self.evaluated_value)
|
|
@@ -1760,9 +1768,9 @@ class Variable(object):
|
|
|
1760
1768
|
>>> from pyedb.dotnet.database.Variables import Variable
|
|
1761
1769
|
|
|
1762
1770
|
>>> v = Variable("10W")
|
|
1763
|
-
>>> assert v.format("f") ==
|
|
1764
|
-
>>> assert v.format("06.2f") ==
|
|
1765
|
-
>>> assert v.format("6.2f") ==
|
|
1771
|
+
>>> assert v.format("f") == "10.000000W"
|
|
1772
|
+
>>> assert v.format("06.2f") == "010.00W"
|
|
1773
|
+
>>> assert v.format("6.2f") == " 10.00W"
|
|
1766
1774
|
|
|
1767
1775
|
"""
|
|
1768
1776
|
return ("{0:" + format + "}{1}").format(self.numeric_value, self._units)
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
"""
|
|
24
24
|
This module contains these classes: `EdbLayout` and `Shape`.
|
|
25
25
|
"""
|
|
26
|
+
|
|
26
27
|
from typing import List, Union
|
|
27
28
|
|
|
28
29
|
from pyedb.dotnet.database.cell.hierarchy.component import EDBComponent
|
|
@@ -55,6 +56,8 @@ from pyedb.dotnet.database.utilities.obj_base import ObjBase
|
|
|
55
56
|
|
|
56
57
|
|
|
57
58
|
def primitive_cast(pedb, edb_object):
|
|
59
|
+
if not hasattr(edb_object, "GetPrimitiveType"):
|
|
60
|
+
return
|
|
58
61
|
if edb_object.GetPrimitiveType().ToString() == "Rectangle":
|
|
59
62
|
return EdbRectangle(edb_object, pedb)
|
|
60
63
|
elif edb_object.GetPrimitiveType().ToString() == "Circle":
|
|
@@ -234,7 +237,7 @@ class Layout(ObjBase):
|
|
|
234
237
|
primitives = list(self._edb_object.Primitives)
|
|
235
238
|
if len(primitives) != len(self._primitives):
|
|
236
239
|
self._primitives = [primitive_cast(self._pedb, p) for p in primitives]
|
|
237
|
-
return self._primitives
|
|
240
|
+
return [p for p in self._primitives if p is not None] # non stackup primitives are None
|
|
238
241
|
|
|
239
242
|
@property
|
|
240
243
|
def primitives_by_aedt_name(self) -> dict:
|
|
@@ -406,6 +409,7 @@ class Layout(ObjBase):
|
|
|
406
409
|
"""
|
|
407
410
|
candidates = self.padstack_instances
|
|
408
411
|
if instance_id is not None:
|
|
412
|
+
instance_id = int(instance_id)
|
|
409
413
|
value = instance_id if isinstance(instance_id, list) else [instance_id]
|
|
410
414
|
candidates = [i for i in candidates if i.id in value]
|
|
411
415
|
|
|
@@ -39,8 +39,8 @@ class Primitive(Connectable):
|
|
|
39
39
|
>>> from pyedb import Edb
|
|
40
40
|
>>> edb = Edb(myedb, edbversion="2021.2")
|
|
41
41
|
>>> edb_prim = edb.modeler.primitives[0]
|
|
42
|
-
>>> edb_prim.is_void
|
|
43
|
-
>>> edb_prim.IsVoid()
|
|
42
|
+
>>> edb_prim.is_void # Class Property
|
|
43
|
+
>>> edb_prim.IsVoid() # EDB Object Property
|
|
44
44
|
"""
|
|
45
45
|
|
|
46
46
|
def __init__(self, pedb, edb_object):
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
|
|
23
23
|
from pyedb.dotnet.database.cell.terminal.edge_terminal import EdgeTerminal
|
|
24
24
|
from pyedb.dotnet.database.cell.terminal.terminal import Terminal
|
|
25
|
+
from pyedb.dotnet.database.general import convert_py_list_to_net_list
|
|
25
26
|
|
|
26
27
|
|
|
27
28
|
class BundleTerminal(Terminal):
|
|
@@ -46,3 +47,14 @@ class BundleTerminal(Terminal):
|
|
|
46
47
|
def decouple(self):
|
|
47
48
|
"""Ungroup a bundle of terminals."""
|
|
48
49
|
return self._edb_object.Ungroup()
|
|
50
|
+
|
|
51
|
+
@classmethod
|
|
52
|
+
def create(cls, pedb, name, terminals):
|
|
53
|
+
terminal_list = [pedb.terminals[i]._edb_object for i in terminals]
|
|
54
|
+
edb_list = convert_py_list_to_net_list(terminal_list, pedb._edb.Cell.Terminal.Terminal)
|
|
55
|
+
_edb_boundle_terminal = pedb._edb.Cell.Terminal.BundleTerminal.Create(edb_list)
|
|
56
|
+
_edb_boundle_terminal.SetName(name)
|
|
57
|
+
pos, neg = list(_edb_boundle_terminal.GetTerminals())
|
|
58
|
+
pos.SetName(name + ":T1")
|
|
59
|
+
neg.SetName(name + ":T2")
|
|
60
|
+
return pedb.terminals[name]
|