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,423 @@
|
|
|
1
|
+
import json
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
|
|
4
|
+
from pyedb.generic.general_methods import pyedb_function_handler
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def load_json(config_file):
|
|
8
|
+
if isinstance(config_file, (str, Path)):
|
|
9
|
+
with open(config_file, "r") as f:
|
|
10
|
+
return json.load(f)
|
|
11
|
+
elif isinstance(config_file, dict):
|
|
12
|
+
return config_file
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class Configuration:
|
|
16
|
+
"""Enables export and import of a JSON configuration file that can be applied to a new or existing design."""
|
|
17
|
+
|
|
18
|
+
def __init__(self, pedb):
|
|
19
|
+
self._pedb = pedb
|
|
20
|
+
self._components = self._pedb.components.components
|
|
21
|
+
self.data = {}
|
|
22
|
+
|
|
23
|
+
@pyedb_function_handler
|
|
24
|
+
def load(self, config_file, append=True, apply_file=False, output_file=None, open_at_the_end=True):
|
|
25
|
+
"""Import configuration settings from a JSON file.
|
|
26
|
+
|
|
27
|
+
Parameters
|
|
28
|
+
----------
|
|
29
|
+
config_file : str
|
|
30
|
+
Full path to json file.
|
|
31
|
+
append : bool, optional
|
|
32
|
+
Whether if the new file will append to existing properties or the properties will be cleared before import.
|
|
33
|
+
Default is ``True`` to keep stored properties
|
|
34
|
+
apply_file : bool, optional
|
|
35
|
+
Whether to apply the file after the load or not. Default is ``False``.
|
|
36
|
+
output_file : str, optional
|
|
37
|
+
Full path to the new aedb folder where the configured project will be saved.
|
|
38
|
+
open_at_the_end : bool, optional
|
|
39
|
+
Whether to keep the new generated file opened at the end. Default is ``True``.
|
|
40
|
+
|
|
41
|
+
Returns
|
|
42
|
+
-------
|
|
43
|
+
dict
|
|
44
|
+
Config dictionary.
|
|
45
|
+
"""
|
|
46
|
+
|
|
47
|
+
data = load_json(config_file)
|
|
48
|
+
if not append:
|
|
49
|
+
self.data = {}
|
|
50
|
+
for k, v in data.items():
|
|
51
|
+
self.data[k] = v
|
|
52
|
+
if apply_file:
|
|
53
|
+
original_file = self._pedb.edbpath
|
|
54
|
+
if output_file:
|
|
55
|
+
self._pedb.save_edb_as(output_file)
|
|
56
|
+
self.run()
|
|
57
|
+
if output_file and not open_at_the_end:
|
|
58
|
+
self._pedb.save_edb()
|
|
59
|
+
self._pedb.close_edb()
|
|
60
|
+
self._pedb.edbpath = original_file
|
|
61
|
+
self._pedb.open_edb()
|
|
62
|
+
return self.data
|
|
63
|
+
|
|
64
|
+
@pyedb_function_handler()
|
|
65
|
+
def run(self):
|
|
66
|
+
"""Apply configuration settings to the current design"""
|
|
67
|
+
|
|
68
|
+
# Configure components
|
|
69
|
+
if not self.data:
|
|
70
|
+
self._pedb.logger.error("No data loaded. Please load a configuration file.")
|
|
71
|
+
return False
|
|
72
|
+
|
|
73
|
+
if "components" in self.data:
|
|
74
|
+
self._load_components()
|
|
75
|
+
|
|
76
|
+
# Configure ports
|
|
77
|
+
if "ports" in self.data:
|
|
78
|
+
self._load_ports()
|
|
79
|
+
|
|
80
|
+
# Configure sources
|
|
81
|
+
if "sources" in self.data:
|
|
82
|
+
self._load_sources()
|
|
83
|
+
|
|
84
|
+
# Configure HFSS setup
|
|
85
|
+
if "setups" in self.data:
|
|
86
|
+
self._load_setups()
|
|
87
|
+
|
|
88
|
+
# Configure stackup
|
|
89
|
+
if "stackup" in self.data:
|
|
90
|
+
self._load_stackup()
|
|
91
|
+
|
|
92
|
+
# Configure S-parameter
|
|
93
|
+
if "s_parameters" in self.data:
|
|
94
|
+
self._load_s_parameter()
|
|
95
|
+
|
|
96
|
+
return True
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
@pyedb_function_handler
|
|
100
|
+
def _load_components(self):
|
|
101
|
+
"""Imports component information from json."""
|
|
102
|
+
|
|
103
|
+
for comp in self.data["components"] :
|
|
104
|
+
refdes = comp["reference_designator"]
|
|
105
|
+
part_type = comp["part_type"].lower()
|
|
106
|
+
if part_type == "resistor":
|
|
107
|
+
part_type = "Resistor"
|
|
108
|
+
elif part_type == "capacitor":
|
|
109
|
+
part_type = "Capacitor"
|
|
110
|
+
elif part_type == "inductor":
|
|
111
|
+
part_type = "Inductor"
|
|
112
|
+
elif part_type == "io":
|
|
113
|
+
part_type = "IO"
|
|
114
|
+
elif part_type == "ic":
|
|
115
|
+
part_type = "IC"
|
|
116
|
+
else:
|
|
117
|
+
part_type = "Other"
|
|
118
|
+
|
|
119
|
+
comp_layout = self._components[refdes]
|
|
120
|
+
comp_layout.type = part_type
|
|
121
|
+
|
|
122
|
+
if part_type in ["Resistor", "Capacitor", "Inductor"]:
|
|
123
|
+
comp_layout.is_enabled = comp["enabled"]
|
|
124
|
+
rlc_model = comp["rlc_model"] if "rlc_model" in comp else None
|
|
125
|
+
# n_port_model = comp["NPortModel"] if "NPortModel" in comp else None
|
|
126
|
+
# netlist_model = comp["NetlistModel"] if "NetlistModel" in comp else None
|
|
127
|
+
# spice_model = comp["SpiceModel"] if "SpiceModel" in comp else None
|
|
128
|
+
|
|
129
|
+
if rlc_model:
|
|
130
|
+
model_layout = comp_layout.model
|
|
131
|
+
|
|
132
|
+
pin_pairs = rlc_model["pin_pairs"] if "pin_pairs" in rlc_model else None
|
|
133
|
+
if pin_pairs:
|
|
134
|
+
for pp in model_layout.pin_pairs:
|
|
135
|
+
model_layout.delete_pin_pair_rlc(pp)
|
|
136
|
+
|
|
137
|
+
for pp in pin_pairs:
|
|
138
|
+
rlc_model_type = pp["type"]
|
|
139
|
+
p1 = pp["p1"]
|
|
140
|
+
p2 = pp["p2"]
|
|
141
|
+
|
|
142
|
+
r = pp["resistance"] if "resistance" in pp else None
|
|
143
|
+
l = pp["inductance"] if "inductance" in pp else None
|
|
144
|
+
c = pp["capacitance"] if "capacitance" in pp else None
|
|
145
|
+
|
|
146
|
+
pin_pair = self._pedb.edb_api.utility.PinPair(p1, p2)
|
|
147
|
+
rlc = self._pedb.edb_api.utility.Rlc()
|
|
148
|
+
|
|
149
|
+
rlc.IsParallel = False if rlc_model_type == "series" else True
|
|
150
|
+
if not r is None:
|
|
151
|
+
rlc.REnabled = True
|
|
152
|
+
rlc.R = self._pedb.edb_value(r)
|
|
153
|
+
else:
|
|
154
|
+
rlc.REnabled = False
|
|
155
|
+
|
|
156
|
+
if not l is None:
|
|
157
|
+
rlc.LEnabled = True
|
|
158
|
+
rlc.L = self._pedb.edb_value(l)
|
|
159
|
+
else:
|
|
160
|
+
rlc.LEnabled = False
|
|
161
|
+
|
|
162
|
+
if not c is None:
|
|
163
|
+
rlc.CEnabled = True
|
|
164
|
+
rlc.C = self._pedb.edb_value(c)
|
|
165
|
+
else:
|
|
166
|
+
rlc.CEnabled = False
|
|
167
|
+
|
|
168
|
+
model_layout._set_pin_pair_rlc(pin_pair, rlc)
|
|
169
|
+
comp_layout.model = model_layout
|
|
170
|
+
|
|
171
|
+
# Configure port properties
|
|
172
|
+
port_properties = comp["port_properties"] if "port_properties" in comp else None
|
|
173
|
+
if port_properties:
|
|
174
|
+
ref_offset = port_properties["reference_offset"]
|
|
175
|
+
ref_size_auto = port_properties["reference_size_auto"]
|
|
176
|
+
ref_size_x = port_properties["reference_size_x"]
|
|
177
|
+
ref_size_y = port_properties["reference_size_y"]
|
|
178
|
+
else:
|
|
179
|
+
ref_offset = 0
|
|
180
|
+
ref_size_auto = True
|
|
181
|
+
ref_size_x = 0
|
|
182
|
+
ref_size_y = 0
|
|
183
|
+
|
|
184
|
+
# Configure solder ball properties
|
|
185
|
+
solder_ball_properties = comp["solder_ball_properties"] if "solder_ball_properties" in comp else None
|
|
186
|
+
if solder_ball_properties:
|
|
187
|
+
shape = solder_ball_properties["shape"]
|
|
188
|
+
diameter = solder_ball_properties["diameter"]
|
|
189
|
+
mid_diameter = (
|
|
190
|
+
solder_ball_properties["mid_diameter"] if "mid_diameter" in solder_ball_properties else diameter
|
|
191
|
+
)
|
|
192
|
+
height = solder_ball_properties["height"]
|
|
193
|
+
|
|
194
|
+
self._pedb.components.set_solder_ball(
|
|
195
|
+
component=refdes,
|
|
196
|
+
sball_diam=diameter,
|
|
197
|
+
sball_mid_diam=mid_diameter,
|
|
198
|
+
sball_height=height,
|
|
199
|
+
shape=shape,
|
|
200
|
+
auto_reference_size=ref_size_auto,
|
|
201
|
+
reference_height=ref_offset,
|
|
202
|
+
reference_size_x=ref_size_x,
|
|
203
|
+
reference_size_y=ref_size_y,
|
|
204
|
+
)
|
|
205
|
+
|
|
206
|
+
@pyedb_function_handler
|
|
207
|
+
def _load_ports(self):
|
|
208
|
+
"""Imports port information from json."""
|
|
209
|
+
for port in self.data["ports"]:
|
|
210
|
+
port_type = port["type"]
|
|
211
|
+
refdes = port["reference_designator"]
|
|
212
|
+
comp_layout = self._components[refdes]
|
|
213
|
+
pos = port["from"]
|
|
214
|
+
if "pin" in pos:
|
|
215
|
+
pin_name = pos["pin"]
|
|
216
|
+
port_name = "{}_{}".format(refdes, pin_name)
|
|
217
|
+
pos_terminal = comp_layout.pins[pin_name].get_terminal(port_name, True)
|
|
218
|
+
else: # Net
|
|
219
|
+
net_name = pos["net"]
|
|
220
|
+
port_name = "{}_{}".format(refdes, net_name)
|
|
221
|
+
if port_type == "circuit":
|
|
222
|
+
pg_name = "pg_{}".format(port_name)
|
|
223
|
+
_, pg = self._pedb.siwave.create_pin_group_on_net(refdes, net_name, pg_name)
|
|
224
|
+
pos_terminal = pg.get_terminal(port_name, True)
|
|
225
|
+
else: # Coax port
|
|
226
|
+
for _, p in comp_layout.pins.items():
|
|
227
|
+
if p.net_name == net_name:
|
|
228
|
+
pos_terminal = p.get_terminal(port_name, True)
|
|
229
|
+
break
|
|
230
|
+
|
|
231
|
+
if port_type == "circuit":
|
|
232
|
+
neg = port["to"]
|
|
233
|
+
if "pin" in neg:
|
|
234
|
+
pin_name = neg["pin"]
|
|
235
|
+
port_name = "{}_{}_ref".format(refdes, pin_name)
|
|
236
|
+
neg_terminal = comp_layout.pins[pin_name].get_terminal(port_name, True)
|
|
237
|
+
else:
|
|
238
|
+
net_name = neg["net"]
|
|
239
|
+
port_name = "{}_{}_ref".format(refdes, net_name)
|
|
240
|
+
pg_name = "pg_{}".format(port_name)
|
|
241
|
+
if pg_name not in self._pedb.siwave.pin_groups:
|
|
242
|
+
_, pg = self._pedb.siwave.create_pin_group_on_net(refdes, net_name, pg_name)
|
|
243
|
+
else:
|
|
244
|
+
pg = self._pedb.siwave.pin_groups[pg_name]
|
|
245
|
+
neg_terminal = pg.get_terminal(port_name, True)
|
|
246
|
+
|
|
247
|
+
self._pedb.create_port(pos_terminal, neg_terminal, True)
|
|
248
|
+
else:
|
|
249
|
+
self._pedb.create_port(pos_terminal)
|
|
250
|
+
|
|
251
|
+
@pyedb_function_handler
|
|
252
|
+
def _load_sources(self):
|
|
253
|
+
"""Imports source information from json."""
|
|
254
|
+
|
|
255
|
+
for src in self.data["sources"]:
|
|
256
|
+
src_type = src["type"]
|
|
257
|
+
refdes = src["reference_designator"]
|
|
258
|
+
name = src["name"]
|
|
259
|
+
comp_layout = self._components[refdes]
|
|
260
|
+
|
|
261
|
+
pos = src["from"]
|
|
262
|
+
if "pin" in pos:
|
|
263
|
+
pin_name = pos["pin"]
|
|
264
|
+
src_name = name
|
|
265
|
+
pos_terminal = comp_layout.pins[pin_name].get_terminal(src_name, True)
|
|
266
|
+
elif "net" in pos: # Net
|
|
267
|
+
net_name = pos["net"]
|
|
268
|
+
src_name = "{}_{}".format(refdes, net_name)
|
|
269
|
+
pg_name = "pg_{}".format(src_name)
|
|
270
|
+
_, pg = self._pedb.siwave.create_pin_group_on_net(refdes, net_name, pg_name)
|
|
271
|
+
pos_terminal = pg.get_terminal(src_name, True)
|
|
272
|
+
|
|
273
|
+
neg = src["to"]
|
|
274
|
+
if "pin" in neg:
|
|
275
|
+
pin_name = neg["pin"]
|
|
276
|
+
src_name = name + "_ref"
|
|
277
|
+
neg_terminal = comp_layout.pins[pin_name].get_terminal(src_name, True)
|
|
278
|
+
elif "net" in neg:
|
|
279
|
+
net_name = neg["net"]
|
|
280
|
+
src_name = name + "_ref"
|
|
281
|
+
pg_name = "pg_{}".format(src_name)
|
|
282
|
+
if pg_name not in self._pedb.siwave.pin_groups:
|
|
283
|
+
_, pg = self._pedb.siwave.create_pin_group_on_net(refdes, net_name, pg_name)
|
|
284
|
+
else: # pragma no cover
|
|
285
|
+
pg = self._pedb.siwave.pin_groups[pg_name]
|
|
286
|
+
neg_terminal = pg.get_terminal(src_name, True)
|
|
287
|
+
|
|
288
|
+
if src_type == "voltage":
|
|
289
|
+
src_obj = self._pedb.create_voltage_source(pos_terminal, neg_terminal)
|
|
290
|
+
src_obj.magnitude = src["magnitude"]
|
|
291
|
+
elif src_type == "current":
|
|
292
|
+
src_obj = self._pedb.create_current_source(pos_terminal, neg_terminal)
|
|
293
|
+
src_obj.magnitude = src["magnitude"]
|
|
294
|
+
|
|
295
|
+
@pyedb_function_handler
|
|
296
|
+
def _load_setups(self):
|
|
297
|
+
"""Imports setup information from json."""
|
|
298
|
+
for setup in self.data["setups"]:
|
|
299
|
+
setup_type = setup["type"]
|
|
300
|
+
|
|
301
|
+
edb_setup = None
|
|
302
|
+
name = setup["name"]
|
|
303
|
+
|
|
304
|
+
if setup_type.lower() == "siwave_dc":
|
|
305
|
+
if name not in self._pedb.setups:
|
|
306
|
+
self._pedb.logger.info("Setup {} created.".format(name))
|
|
307
|
+
edb_setup = self._pedb.create_siwave_dc_setup(name)
|
|
308
|
+
else:
|
|
309
|
+
self._pedb.logger.warning("Setup {} already existing. Editing it.".format(name))
|
|
310
|
+
edb_setup = self._pedb.setups[name]
|
|
311
|
+
edb_setup.set_dc_slider(setup["dc_slider_position"])
|
|
312
|
+
else:
|
|
313
|
+
if setup_type.lower() == "hfss":
|
|
314
|
+
if name not in self._pedb.setups:
|
|
315
|
+
self._pedb.logger.info("Setup {} created.".format(name))
|
|
316
|
+
edb_setup = self._pedb.create_hfss_setup(name)
|
|
317
|
+
else:
|
|
318
|
+
self._pedb.logger.warning("Setup {} already existing. Editing it.".format(name))
|
|
319
|
+
edb_setup = self._pedb.setups[name]
|
|
320
|
+
edb_setup.set_solution_single_frequency(
|
|
321
|
+
setup["f_adapt"], max_num_passes=setup["max_num_passes"], max_delta_s=setup["max_mag_delta_s"]
|
|
322
|
+
)
|
|
323
|
+
elif setup_type.lower() == "siwave_syz":
|
|
324
|
+
name = setup["name"]
|
|
325
|
+
if name not in self._pedb.setups:
|
|
326
|
+
self._pedb.logger.info("Setup {} created.".format(name))
|
|
327
|
+
edb_setup = self._pedb.create_siwave_syz_setup(name)
|
|
328
|
+
else:
|
|
329
|
+
self._pedb.logger.warning("Setup {} already existing. Editing it.".format(name))
|
|
330
|
+
edb_setup = self._pedb.setups[name]
|
|
331
|
+
edb_setup.si_slider_position = setup["si_slider_position"]
|
|
332
|
+
|
|
333
|
+
if "freq_sweep" in setup:
|
|
334
|
+
for fsweep in setup["freq_sweep"]:
|
|
335
|
+
frequencies = fsweep["frequencies"]
|
|
336
|
+
freqs = []
|
|
337
|
+
|
|
338
|
+
for d in frequencies:
|
|
339
|
+
if d["distribution"] == "linear step":
|
|
340
|
+
freqs.append(
|
|
341
|
+
[
|
|
342
|
+
"linear scale",
|
|
343
|
+
self._pedb.edb_value(d["start"]).ToString(),
|
|
344
|
+
self._pedb.edb_value(d["stop"]).ToString(),
|
|
345
|
+
self._pedb.edb_value(d["step"]).ToString(),
|
|
346
|
+
]
|
|
347
|
+
)
|
|
348
|
+
elif d["distribution"] == "linear count":
|
|
349
|
+
freqs.append(
|
|
350
|
+
[
|
|
351
|
+
"linear count",
|
|
352
|
+
self._pedb.edb_value(d["start"]).ToString(),
|
|
353
|
+
self._pedb.edb_value(d["stop"]).ToString(),
|
|
354
|
+
int(d["points"]),
|
|
355
|
+
]
|
|
356
|
+
)
|
|
357
|
+
elif d["distribution"] == "log scale":
|
|
358
|
+
freqs.append(
|
|
359
|
+
[
|
|
360
|
+
"log scale",
|
|
361
|
+
self._pedb.edb_value(d["start"]).ToString(),
|
|
362
|
+
self._pedb.edb_value(d["stop"]).ToString(),
|
|
363
|
+
int(d["samples"]),
|
|
364
|
+
]
|
|
365
|
+
)
|
|
366
|
+
|
|
367
|
+
edb_setup.add_frequency_sweep(
|
|
368
|
+
fsweep["name"],
|
|
369
|
+
frequency_sweep=freqs,
|
|
370
|
+
)
|
|
371
|
+
|
|
372
|
+
@pyedb_function_handler
|
|
373
|
+
def _load_stackup(self):
|
|
374
|
+
"""Imports stackup information from json."""
|
|
375
|
+
data = self.data["stackup"]
|
|
376
|
+
materials = data["materials"] if "materials" in data else []
|
|
377
|
+
materials_reformatted = {}
|
|
378
|
+
for mat in materials:
|
|
379
|
+
new_mat = {}
|
|
380
|
+
new_mat["name"] = mat["name"]
|
|
381
|
+
if "conductivity" in mat:
|
|
382
|
+
new_mat["conductivity"] = mat["conductivity"]
|
|
383
|
+
if "permittivity" in mat:
|
|
384
|
+
new_mat["permittivity"] = mat["permittivity"]
|
|
385
|
+
if "dielectricLoss_tangent" in mat:
|
|
386
|
+
new_mat["loss_tangent"] = mat["dielectricLoss_tangent"]
|
|
387
|
+
|
|
388
|
+
materials_reformatted[mat["name"]] = new_mat
|
|
389
|
+
|
|
390
|
+
layers = data["layers"]
|
|
391
|
+
layers_reformatted = {}
|
|
392
|
+
|
|
393
|
+
for l in layers:
|
|
394
|
+
lyr = {
|
|
395
|
+
"name": l["name"],
|
|
396
|
+
"type": l["type"],
|
|
397
|
+
"material": l["material"],
|
|
398
|
+
"thickness": l["thickness"],
|
|
399
|
+
}
|
|
400
|
+
if "fill_material" in l:
|
|
401
|
+
lyr["dielectric_fill"] = l["fill_material"]
|
|
402
|
+
layers_reformatted[l["name"]] = lyr
|
|
403
|
+
stackup_reformated = {"layers": layers_reformatted, "materials": materials_reformatted}
|
|
404
|
+
self._pedb.stackup.load(stackup_reformated)
|
|
405
|
+
|
|
406
|
+
@pyedb_function_handler
|
|
407
|
+
def _load_s_parameter(self):
|
|
408
|
+
"""Imports s-parameter information from json."""
|
|
409
|
+
|
|
410
|
+
for sp in self.data["s_parameters"]:
|
|
411
|
+
fpath = sp["file_path"]
|
|
412
|
+
sp_name = sp["name"]
|
|
413
|
+
comp_def_name = sp["component_definition"]
|
|
414
|
+
comp_def = self._pedb.definitions.component[comp_def_name]
|
|
415
|
+
comp_def.add_n_port_model(fpath, sp_name)
|
|
416
|
+
if sp["apply_to_all"]:
|
|
417
|
+
for refdes, comp in comp_def.components.items():
|
|
418
|
+
if refdes not in sp["components"]:
|
|
419
|
+
comp.use_s_parameter_model(sp_name)
|
|
420
|
+
else:
|
|
421
|
+
for refdes, comp in comp_def.components.items():
|
|
422
|
+
if refdes in sp["components"]:
|
|
423
|
+
comp.use_s_parameter_model(sp_name)
|
|
File without changes
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
3
|
+
from pyedb.dotnet.edb_core.edb_data.obj_base import ObjBase
|
|
4
|
+
from pyedb.generic.general_methods import pyedb_function_handler
|
|
5
|
+
from pyedb.dotnet.edb_core.definition.component_model import (
|
|
6
|
+
NPortComponentModel
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class EDBComponentDef(ObjBase):
|
|
11
|
+
"""Manages EDB functionalities for component definitions.
|
|
12
|
+
|
|
13
|
+
Parameters
|
|
14
|
+
----------
|
|
15
|
+
parent : :class:`pyedb.dotnet.edb_core.components.Components`
|
|
16
|
+
Inherited AEDT object.
|
|
17
|
+
comp_def : object
|
|
18
|
+
Edb ComponentDef Object
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
def __init__(self, pedb, edb_object=None):
|
|
22
|
+
super().__init__(pedb, edb_object)
|
|
23
|
+
self._pedb = pedb
|
|
24
|
+
|
|
25
|
+
@property
|
|
26
|
+
def _comp_model(self):
|
|
27
|
+
return list(self._edb_object.GetComponentModels()) # pragma: no cover
|
|
28
|
+
|
|
29
|
+
@property
|
|
30
|
+
def part_name(self):
|
|
31
|
+
"""Retrieve component definition name."""
|
|
32
|
+
return self._edb_object.GetName()
|
|
33
|
+
|
|
34
|
+
@part_name.setter
|
|
35
|
+
def part_name(self, name):
|
|
36
|
+
self._edb_object.SetName(name)
|
|
37
|
+
|
|
38
|
+
@property
|
|
39
|
+
def type(self):
|
|
40
|
+
"""Retrieve the component definition type.
|
|
41
|
+
|
|
42
|
+
Returns
|
|
43
|
+
-------
|
|
44
|
+
str
|
|
45
|
+
"""
|
|
46
|
+
num = len(set(comp.type for refdes, comp in self.components.items()))
|
|
47
|
+
if num == 0: # pragma: no cover
|
|
48
|
+
return None
|
|
49
|
+
elif num == 1:
|
|
50
|
+
return list(self.components.values())[0].type
|
|
51
|
+
else:
|
|
52
|
+
return "mixed" # pragma: no cover
|
|
53
|
+
|
|
54
|
+
@type.setter
|
|
55
|
+
def type(self, value):
|
|
56
|
+
for comp in list(self.components.values()):
|
|
57
|
+
comp.type = value
|
|
58
|
+
|
|
59
|
+
@property
|
|
60
|
+
def components(self):
|
|
61
|
+
"""Get the list of components belonging to this component definition.
|
|
62
|
+
|
|
63
|
+
Returns
|
|
64
|
+
-------
|
|
65
|
+
dict of :class:`EDBComponent`
|
|
66
|
+
"""
|
|
67
|
+
from pyedb.dotnet.edb_core.edb_data.components_data import EDBComponent
|
|
68
|
+
comp_list = [
|
|
69
|
+
EDBComponent(self._pedb, l)
|
|
70
|
+
for l in self._pedb.edb_api.cell.hierarchy.component.FindByComponentDef(
|
|
71
|
+
self._pedb.active_layout, self.part_name
|
|
72
|
+
)
|
|
73
|
+
]
|
|
74
|
+
return {comp.refdes: comp for comp in comp_list}
|
|
75
|
+
|
|
76
|
+
@pyedb_function_handler()
|
|
77
|
+
def assign_rlc_model(self, res=None, ind=None, cap=None, is_parallel=False):
|
|
78
|
+
"""Assign RLC to all components under this part name.
|
|
79
|
+
|
|
80
|
+
Parameters
|
|
81
|
+
----------
|
|
82
|
+
res : int, float
|
|
83
|
+
Resistance. Default is ``None``.
|
|
84
|
+
ind : int, float
|
|
85
|
+
Inductance. Default is ``None``.
|
|
86
|
+
cap : int, float
|
|
87
|
+
Capacitance. Default is ``None``.
|
|
88
|
+
is_parallel : bool, optional
|
|
89
|
+
Whether it is parallel or series RLC component.
|
|
90
|
+
"""
|
|
91
|
+
for comp in list(self.components.values()):
|
|
92
|
+
res, ind, cap = res, ind, cap
|
|
93
|
+
comp.assign_rlc_model(res, ind, cap, is_parallel)
|
|
94
|
+
return True
|
|
95
|
+
|
|
96
|
+
@pyedb_function_handler()
|
|
97
|
+
def assign_s_param_model(self, file_path, model_name=None, reference_net=None):
|
|
98
|
+
"""Assign S-parameter to all components under this part name.
|
|
99
|
+
|
|
100
|
+
Parameters
|
|
101
|
+
----------
|
|
102
|
+
file_path : str
|
|
103
|
+
File path of the S-parameter model.
|
|
104
|
+
name : str, optional
|
|
105
|
+
Name of the S-parameter model.
|
|
106
|
+
|
|
107
|
+
Returns
|
|
108
|
+
-------
|
|
109
|
+
|
|
110
|
+
"""
|
|
111
|
+
for comp in list(self.components.values()):
|
|
112
|
+
comp.assign_s_param_model(file_path, model_name, reference_net)
|
|
113
|
+
return True
|
|
114
|
+
|
|
115
|
+
@pyedb_function_handler()
|
|
116
|
+
def assign_spice_model(self, file_path, model_name=None):
|
|
117
|
+
"""Assign Spice model to all components under this part name.
|
|
118
|
+
|
|
119
|
+
Parameters
|
|
120
|
+
----------
|
|
121
|
+
file_path : str
|
|
122
|
+
File path of the Spice model.
|
|
123
|
+
name : str, optional
|
|
124
|
+
Name of the Spice model.
|
|
125
|
+
|
|
126
|
+
Returns
|
|
127
|
+
-------
|
|
128
|
+
|
|
129
|
+
"""
|
|
130
|
+
for comp in list(self.components.values()):
|
|
131
|
+
comp.assign_spice_model(file_path, model_name)
|
|
132
|
+
return True
|
|
133
|
+
|
|
134
|
+
@property
|
|
135
|
+
def component_models(self):
|
|
136
|
+
temp = {}
|
|
137
|
+
for i in list(self._edb_object.GetComponentModels()):
|
|
138
|
+
temp_type = i.ToString().split(".")[0]
|
|
139
|
+
if temp_type == "NPortComponentModel":
|
|
140
|
+
edb_object = NPortComponentModel(self._pedb, i)
|
|
141
|
+
temp[edb_object.name] = edb_object
|
|
142
|
+
return temp
|
|
143
|
+
|
|
144
|
+
@pyedb_function_handler
|
|
145
|
+
def _add_component_model(self, value):
|
|
146
|
+
self._edb_object.AddComponentModel(value._edb_object)
|
|
147
|
+
|
|
148
|
+
@pyedb_function_handler
|
|
149
|
+
def add_n_port_model(self, fpath, name=None):
|
|
150
|
+
if not name:
|
|
151
|
+
name = os.path.splitext(os.path.basename(fpath)[0])
|
|
152
|
+
|
|
153
|
+
from pyedb.dotnet.edb_core.definition.component_model import NPortComponentModel
|
|
154
|
+
|
|
155
|
+
edb_object = self._pedb.definition.NPortComponentModel.Create(name)
|
|
156
|
+
n_port_comp_model = NPortComponentModel(self._pedb, edb_object)
|
|
157
|
+
n_port_comp_model.reference_file = fpath
|
|
158
|
+
|
|
159
|
+
self._add_component_model(n_port_comp_model)
|
|
160
|
+
|
|
161
|
+
@pyedb_function_handler
|
|
162
|
+
def create(self, name):
|
|
163
|
+
cell_type = self._pedb.edb_api.cell.CellType.FootprintCell
|
|
164
|
+
footprint_cell = self._pedb._active_cell.cell.Create(self._pedb.active_db, cell_type, name)
|
|
165
|
+
edb_object = self._pedb.edb_api.definition.ComponentDef.Create(self._pedb.active_db, name, footprint_cell)
|
|
166
|
+
return EDBComponentDef(self._pedb, edb_object)
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
from pyedb.dotnet.edb_core.edb_data.obj_base import ObjBase
|
|
2
|
+
from pyedb.generic.general_methods import pyedb_function_handler
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class ComponentModel(ObjBase):
|
|
6
|
+
"""Manages component model class."""
|
|
7
|
+
|
|
8
|
+
def __init__(self, pedb, edb_object):
|
|
9
|
+
super().__init__(pedb, edb_object)
|
|
10
|
+
self._model_type_mapping = {"PinPairModel": self._pedb.edb_api.cell}
|
|
11
|
+
|
|
12
|
+
@pyedb_function_handler()
|
|
13
|
+
def name(self):
|
|
14
|
+
"""Name of the component model."""
|
|
15
|
+
return self._edb_object.GetName()
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class NPortComponentModel(ComponentModel):
|
|
19
|
+
"""Class for n-port component models."""
|
|
20
|
+
|
|
21
|
+
def __init__(self, pedb, edb_object):
|
|
22
|
+
super().__init__(pedb, edb_object)
|
|
23
|
+
|
|
24
|
+
@property
|
|
25
|
+
def reference_file(self):
|
|
26
|
+
return self._edb_object.GetReferenceFile()
|
|
27
|
+
|
|
28
|
+
@reference_file.setter
|
|
29
|
+
def reference_file(self, value):
|
|
30
|
+
self._edb_object.SetReferenceFile(value)
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
from pyedb.dotnet.edb_core.edb_data.obj_base import ObjBase
|
|
2
|
+
from pyedb.generic.general_methods import pyedb_function_handler
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class DefinitionObj(ObjBase):
|
|
6
|
+
"""Base class for definition objects."""
|
|
7
|
+
|
|
8
|
+
def __init__(self, pedb, edb_object):
|
|
9
|
+
super().__init__(pedb, edb_object)
|
|
10
|
+
|
|
11
|
+
@property
|
|
12
|
+
def definition_obj_type(self):
|
|
13
|
+
return self._edb_object.GetDefinitionObjType()
|
|
14
|
+
|
|
15
|
+
@property
|
|
16
|
+
def name(self):
|
|
17
|
+
return self._edb_object.GetName()
|
|
18
|
+
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from pyedb.dotnet.edb_core.definition.component_def import EDBComponentDef
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class Definitions:
|
|
6
|
+
def __init__(self, pedb):
|
|
7
|
+
self._pedb = pedb
|
|
8
|
+
|
|
9
|
+
@property
|
|
10
|
+
def component(self):
|
|
11
|
+
"""Component definitions"""
|
|
12
|
+
return {l.GetName(): EDBComponentDef(self._pedb, l) for l in list(self._pedb.active_db.ComponentDefs)}
|
|
File without changes
|