pyedb 0.44.0__py3-none-any.whl → 0.45.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_boundaries.py +1 -1
- pyedb/configuration/cfg_components.py +7 -7
- pyedb/configuration/cfg_general.py +8 -2
- pyedb/configuration/cfg_modeler.py +7 -0
- pyedb/configuration/cfg_operations.py +40 -1
- pyedb/configuration/cfg_pin_groups.py +1 -1
- pyedb/configuration/cfg_ports_sources.py +159 -51
- pyedb/configuration/cfg_s_parameter_models.py +51 -1
- pyedb/configuration/cfg_setup.py +77 -16
- pyedb/configuration/configuration.py +13 -3
- pyedb/dotnet/database/cell/primitive/path.py +12 -0
- pyedb/dotnet/database/geometry/point_data.py +26 -0
- pyedb/dotnet/database/geometry/polygon_data.py +9 -0
- pyedb/dotnet/database/nets.py +13 -3
- pyedb/dotnet/edb.py +41 -18
- pyedb/grpc/database/components.py +1 -2
- pyedb/grpc/database/definition/component_def.py +1 -1
- pyedb/grpc/database/hfss.py +10 -1
- pyedb/grpc/database/layout_validation.py +2 -2
- pyedb/grpc/database/padstacks.py +15 -9
- pyedb/grpc/database/ports/ports.py +3 -3
- pyedb/grpc/database/simulation_setup/hfss_simulation_setup.py +18 -13
- pyedb/grpc/database/simulation_setup/siwave_simulation_setup.py +73 -30
- pyedb/grpc/database/simulation_setup/sweep_data.py +12 -1
- pyedb/grpc/database/siwave.py +10 -1
- pyedb/grpc/database/source_excitations.py +12 -2
- pyedb/grpc/database/stackup.py +12 -4
- pyedb/grpc/database/terminal/edge_terminal.py +93 -0
- pyedb/grpc/database/terminal/pingroup_terminal.py +14 -1
- pyedb/grpc/edb.py +13 -9
- pyedb/grpc/edb_init.py +19 -15
- pyedb/grpc/rpc_session.py +11 -8
- {pyedb-0.44.0.dist-info → pyedb-0.45.0.dist-info}/METADATA +6 -6
- {pyedb-0.44.0.dist-info → pyedb-0.45.0.dist-info}/RECORD +37 -37
- {pyedb-0.44.0.dist-info → pyedb-0.45.0.dist-info}/LICENSE +0 -0
- {pyedb-0.44.0.dist-info → pyedb-0.45.0.dist-info}/WHEEL +0 -0
pyedb/__init__.py
CHANGED
|
@@ -79,7 +79,7 @@ class CfgBoundaries(CfgBase):
|
|
|
79
79
|
if self.air_box_horizontal_padding:
|
|
80
80
|
self._pedb.hfss.hfss_extent_info.air_box_horizontal_extent = float(self.air_box_horizontal_padding)
|
|
81
81
|
if self.air_box_positive_vertical_padding:
|
|
82
|
-
self._pedb.hfss.hfss_extent_info.
|
|
82
|
+
self._pedb.hfss.hfss_extent_info.air_box_positive_vertical_extent = float(
|
|
83
83
|
self.air_box_positive_vertical_padding
|
|
84
84
|
)
|
|
85
85
|
if self.air_box_negative_vertical_padding:
|
|
@@ -136,9 +136,9 @@ class CfgComponent(CfgBase):
|
|
|
136
136
|
die_type = pascal_to_snake(ic_die_prop.die_type.name)
|
|
137
137
|
temp["type"] = die_type
|
|
138
138
|
if not die_type == "no_die":
|
|
139
|
-
temp["orientation"] =
|
|
139
|
+
temp["orientation"] = ic_die_prop.die_orientation.name.lower()
|
|
140
140
|
if die_type == "wire_bond":
|
|
141
|
-
temp["height"] = ic_die_prop.height.value
|
|
141
|
+
temp["height"] = str(ic_die_prop.height.value)
|
|
142
142
|
|
|
143
143
|
self.parent.ic_die_properties = temp
|
|
144
144
|
|
|
@@ -183,10 +183,10 @@ class CfgComponent(CfgBase):
|
|
|
183
183
|
uses_solder_ball = solder_ball_prop.uses_solderball
|
|
184
184
|
|
|
185
185
|
temp["uses_solder_ball"] = uses_solder_ball
|
|
186
|
-
temp["shape"] =
|
|
187
|
-
temp["diameter"] = diam
|
|
188
|
-
temp["mid_diameter"] = mid_diam
|
|
189
|
-
temp["height"] = height
|
|
186
|
+
temp["shape"] = shape.lower()
|
|
187
|
+
temp["diameter"] = str(diam)
|
|
188
|
+
temp["mid_diameter"] = str(mid_diam)
|
|
189
|
+
temp["height"] = str(height)
|
|
190
190
|
temp["material"] = material
|
|
191
191
|
|
|
192
192
|
self.parent.solder_ball_properties = temp
|
|
@@ -495,7 +495,7 @@ class CfgComponent(CfgBase):
|
|
|
495
495
|
|
|
496
496
|
self.port_properties = kwargs.get("port_properties", {})
|
|
497
497
|
self.solder_ball_properties = kwargs.get("solder_ball_properties", {})
|
|
498
|
-
self.ic_die_properties = kwargs.get("ic_die_properties", {})
|
|
498
|
+
self.ic_die_properties = kwargs.get("ic_die_properties", {"type": "no_die"})
|
|
499
499
|
self.pin_pair_model = kwargs.get("pin_pair_model", [])
|
|
500
500
|
self.spice_model = kwargs.get("spice_model", {})
|
|
501
501
|
self.s_parameter_model = kwargs.get("s_parameter_model", {})
|
|
@@ -34,8 +34,8 @@ class CfgGeneral:
|
|
|
34
34
|
self.pedb.active_cell.suppress_pads = self.parent.suppress_pads
|
|
35
35
|
|
|
36
36
|
def get_parameters_from_edb(self):
|
|
37
|
-
anti_pads_always_on = self.pedb.
|
|
38
|
-
suppress_pads = self.pedb.
|
|
37
|
+
anti_pads_always_on = self.pedb.active_cell.anti_pads_always_on
|
|
38
|
+
suppress_pads = self.pedb.active_cell.suppress_pads
|
|
39
39
|
data = {"anti_pads_always_on": anti_pads_always_on, "suppress_pads": suppress_pads}
|
|
40
40
|
return data
|
|
41
41
|
|
|
@@ -49,6 +49,12 @@ class CfgGeneral:
|
|
|
49
49
|
if self.parent.suppress_pads is not None:
|
|
50
50
|
self.pedb.design_options.suppress_pads = self.parent.suppress_pads
|
|
51
51
|
|
|
52
|
+
def get_parameters_from_edb(self):
|
|
53
|
+
anti_pads_always_on = self.pedb.design_options.antipads_always_on
|
|
54
|
+
suppress_pads = self.pedb.design_options.suppress_pads
|
|
55
|
+
data = {"anti_pads_always_on": anti_pads_always_on, "suppress_pads": suppress_pads}
|
|
56
|
+
return data
|
|
57
|
+
|
|
52
58
|
def __init__(self, pedb, data):
|
|
53
59
|
self.pedb = pedb
|
|
54
60
|
if self.pedb.grpc:
|
|
@@ -141,6 +141,11 @@ class CfgModeler:
|
|
|
141
141
|
c.pyedb_obj = obj
|
|
142
142
|
c.api.set_parameters_to_edb()
|
|
143
143
|
|
|
144
|
+
def delete_primitives(self):
|
|
145
|
+
primitives = self._pedb.layout.find_primitive(**self.parent.primitives_to_delete)
|
|
146
|
+
for i in primitives:
|
|
147
|
+
i.delete()
|
|
148
|
+
|
|
144
149
|
class DotNet(Grpc):
|
|
145
150
|
def __init__(self, parent):
|
|
146
151
|
super().__init__(parent)
|
|
@@ -230,6 +235,8 @@ class CfgModeler:
|
|
|
230
235
|
]
|
|
231
236
|
self.planes = [CfgPlane(**i) for i in data.get("planes", [])]
|
|
232
237
|
self.components = [CfgComponent(self._pedb, None, **i) for i in data.get("components", [])]
|
|
238
|
+
self.primitives_to_delete = data.get("primitives_to_delete", {"layer_name": [], "name": [], "net_name": []})
|
|
233
239
|
|
|
234
240
|
def apply(self):
|
|
235
241
|
self.api.set_parameter_to_edb()
|
|
242
|
+
self.api.delete_primitives()
|
|
@@ -56,6 +56,9 @@ class CfgCutout(CfgBase):
|
|
|
56
56
|
self.api = self.Grpc(self)
|
|
57
57
|
else:
|
|
58
58
|
self.api = self.DotNet(self)
|
|
59
|
+
self.auto_identify_nets = kwargs.get(
|
|
60
|
+
"auto_identify_nets", {"enabled": False, "resistor_below": 100, "inductor_below": 1, "capacitor_above": 1}
|
|
61
|
+
)
|
|
59
62
|
self.signal_list = kwargs.get("signal_list")
|
|
60
63
|
self.reference_list = kwargs.get("reference_list")
|
|
61
64
|
self.extent_type = kwargs.get("extent_type")
|
|
@@ -99,7 +102,43 @@ class CfgOperations(CfgBase):
|
|
|
99
102
|
|
|
100
103
|
def apply_on_edb(self):
|
|
101
104
|
if self.parent.op_cutout:
|
|
102
|
-
|
|
105
|
+
cutout_params = self.parent.op_cutout.get_attributes()
|
|
106
|
+
auto_identify_nets = cutout_params.pop("auto_identify_nets")
|
|
107
|
+
if auto_identify_nets["enabled"]:
|
|
108
|
+
reference_list = cutout_params.get("reference_list", [])
|
|
109
|
+
if auto_identify_nets:
|
|
110
|
+
self._pedb.nets.generate_extended_nets(
|
|
111
|
+
auto_identify_nets["resistor_below"],
|
|
112
|
+
auto_identify_nets["inductor_below"],
|
|
113
|
+
auto_identify_nets["capacitor_above"],
|
|
114
|
+
auto_identify_nets.get("exception_list", []),
|
|
115
|
+
)
|
|
116
|
+
signal_nets = []
|
|
117
|
+
for i in self._pedb.ports.values():
|
|
118
|
+
# Positive terminal
|
|
119
|
+
extended_net = i.net.extended_net
|
|
120
|
+
if extended_net:
|
|
121
|
+
temp = [i2 for i2 in extended_net.nets.keys() if i2 not in reference_list]
|
|
122
|
+
temp = [i2 for i2 in temp if i2 not in signal_nets]
|
|
123
|
+
signal_nets.extend(temp)
|
|
124
|
+
else:
|
|
125
|
+
signal_nets.append(i.net.name)
|
|
126
|
+
|
|
127
|
+
# Negative terminal
|
|
128
|
+
ref_net = i.ref_terminal.net if i.ref_terminal else None
|
|
129
|
+
if ref_net is None:
|
|
130
|
+
continue
|
|
131
|
+
elif ref_net.name not in reference_list:
|
|
132
|
+
extended_net = ref_net.extended_net
|
|
133
|
+
if extended_net:
|
|
134
|
+
temp = [i2 for i2 in extended_net.nets.keys() if i2 not in reference_list]
|
|
135
|
+
temp = [i2 for i2 in temp if i2 not in signal_nets]
|
|
136
|
+
signal_nets.extend(temp)
|
|
137
|
+
else:
|
|
138
|
+
signal_nets.append(ref_net.name)
|
|
139
|
+
|
|
140
|
+
cutout_params["signal_list"] = signal_nets
|
|
141
|
+
polygon_points = self._pedb.cutout(**cutout_params)
|
|
103
142
|
if "pyedb_cutout" not in self._pedb.stackup.all_layers:
|
|
104
143
|
self._pedb.stackup.add_document_layer(name="pyedb_cutout")
|
|
105
144
|
self._pedb.modeler.create_polygon(
|
|
@@ -40,7 +40,7 @@ class CfgPinGroups:
|
|
|
40
40
|
layout_pin_groups = self._pedb.siwave.pin_groups
|
|
41
41
|
for pg_name, pg_obj in layout_pin_groups.items():
|
|
42
42
|
if self._pedb.grpc:
|
|
43
|
-
pins = pg_obj.pins
|
|
43
|
+
pins = list(pg_obj.pins.values())
|
|
44
44
|
refdes = pins[0].component.name
|
|
45
45
|
cfg_pg = CfgPinGroup(
|
|
46
46
|
self._pedb,
|
|
@@ -108,8 +108,27 @@ class CfgNearestPinTerminalInfo(CfgTerminalInfo):
|
|
|
108
108
|
|
|
109
109
|
|
|
110
110
|
class CfgSources:
|
|
111
|
+
class Grpc:
|
|
112
|
+
def __init__(self, parent):
|
|
113
|
+
self.parent = parent
|
|
114
|
+
self._pedb = parent._pedb
|
|
115
|
+
|
|
116
|
+
def get_pin_group_name(self, src):
|
|
117
|
+
return src.pin_group.name
|
|
118
|
+
|
|
119
|
+
class DotNet(Grpc):
|
|
120
|
+
def __init__(self, parent):
|
|
121
|
+
super().__init__(parent)
|
|
122
|
+
|
|
123
|
+
def get_pin_group_name(self, src):
|
|
124
|
+
return src._edb_object.GetPinGroup().GetName()
|
|
125
|
+
|
|
111
126
|
def __init__(self, pedb, sources_data):
|
|
112
127
|
self._pedb = pedb
|
|
128
|
+
if self._pedb.grpc:
|
|
129
|
+
self.api = self.Grpc(self)
|
|
130
|
+
else:
|
|
131
|
+
self.api = self.DotNet(self)
|
|
113
132
|
self.sources = [CfgSource(self._pedb, **src) for src in sources_data]
|
|
114
133
|
|
|
115
134
|
def apply(self):
|
|
@@ -128,7 +147,7 @@ class CfgSources:
|
|
|
128
147
|
|
|
129
148
|
if src.terminal_type == "PinGroupTerminal":
|
|
130
149
|
refdes = ""
|
|
131
|
-
pg = self._pedb.siwave.pin_groups[
|
|
150
|
+
pg = self._pedb.siwave.pin_groups[self.api.get_pin_group_name(src)]
|
|
132
151
|
pos_term_info = {"pin_group": pg.name}
|
|
133
152
|
elif src.terminal_type == "PadstackInstanceTerminal":
|
|
134
153
|
refdes = src.component.refdes if src.component else ""
|
|
@@ -136,7 +155,7 @@ class CfgSources:
|
|
|
136
155
|
|
|
137
156
|
neg_term = self._pedb.terminals[src.ref_terminal.name]
|
|
138
157
|
if neg_term.terminal_type == "PinGroupTerminal":
|
|
139
|
-
pg = self._pedb.siwave.pin_groups[
|
|
158
|
+
pg = self._pedb.siwave.pin_groups[self.api.get_pin_group_name(neg_term)]
|
|
140
159
|
neg_term_info = {"pin_group": pg.name}
|
|
141
160
|
elif neg_term.terminal_type == "PadstackInstanceTerminal":
|
|
142
161
|
neg_term_info = {"padstack": neg_term.padstack_instance.aedt_name}
|
|
@@ -172,6 +191,26 @@ class CfgPorts:
|
|
|
172
191
|
def get_edge_info(self, port):
|
|
173
192
|
return port._edb_object.GetEdges()[0].GetParameters()
|
|
174
193
|
|
|
194
|
+
def _get_edge_port_from_edb(self, p, port_type):
|
|
195
|
+
# primitive, point = p._edb_object.GetEdges()[0].GetParameters()
|
|
196
|
+
edges = p.edges
|
|
197
|
+
primitive = None
|
|
198
|
+
point = None
|
|
199
|
+
primitive = Primitive(self._pedb, primitive)
|
|
200
|
+
point = PointData(self._pedb, point)
|
|
201
|
+
|
|
202
|
+
cfg_port = CfgEdgePort(
|
|
203
|
+
self._pedb,
|
|
204
|
+
name=p.name,
|
|
205
|
+
type=port_type,
|
|
206
|
+
primitive_name=primitive.aedt_name,
|
|
207
|
+
point_on_edge=[point._edb_object.X.ToString(), point._edb_object.Y.ToString()],
|
|
208
|
+
horizontal_extent_factor=p.horizontal_extent_factor,
|
|
209
|
+
vertical_extent_factor=p.vertical_extent_factor,
|
|
210
|
+
pec_launch_width=p.pec_launch_width,
|
|
211
|
+
)
|
|
212
|
+
return cfg_port
|
|
213
|
+
|
|
175
214
|
class DotNet(Grpc):
|
|
176
215
|
def __init__(self, parent):
|
|
177
216
|
super().__init__(parent)
|
|
@@ -179,6 +218,24 @@ class CfgPorts:
|
|
|
179
218
|
def get_pin_group(self, port):
|
|
180
219
|
return self._pedb.siwave.pin_groups[port._edb_object.GetPinGroup().GetName()]
|
|
181
220
|
|
|
221
|
+
def _get_edge_port_from_edb(self, p, port_type):
|
|
222
|
+
_, primitive, point = p._edb_object.GetEdges()[0].GetParameters()
|
|
223
|
+
|
|
224
|
+
primitive = Primitive(self._pedb, primitive)
|
|
225
|
+
point = PointData(self._pedb, point)
|
|
226
|
+
|
|
227
|
+
cfg_port = CfgEdgePort(
|
|
228
|
+
self._pedb,
|
|
229
|
+
name=p.name,
|
|
230
|
+
type=port_type,
|
|
231
|
+
primitive_name=primitive.aedt_name,
|
|
232
|
+
point_on_edge=[point._edb_object.X.ToString(), point._edb_object.Y.ToString()],
|
|
233
|
+
horizontal_extent_factor=p.horizontal_extent_factor,
|
|
234
|
+
vertical_extent_factor=p.vertical_extent_factor,
|
|
235
|
+
pec_launch_width=p.pec_launch_width,
|
|
236
|
+
)
|
|
237
|
+
return cfg_port
|
|
238
|
+
|
|
182
239
|
def __init__(self, pedb, ports_data):
|
|
183
240
|
self._pedb = pedb
|
|
184
241
|
if self._pedb.grpc:
|
|
@@ -189,6 +246,8 @@ class CfgPorts:
|
|
|
189
246
|
for p in ports_data:
|
|
190
247
|
if p["type"] == "wave_port":
|
|
191
248
|
self.ports.append(CfgEdgePort(self._pedb, **p))
|
|
249
|
+
elif p["type"] == "gap_port":
|
|
250
|
+
self.ports.append(CfgEdgePort(self._pedb, **p))
|
|
192
251
|
elif p["type"] == "diff_wave_port":
|
|
193
252
|
self.ports.append(CfgDiffWavePort(self._pedb, **p))
|
|
194
253
|
elif p["type"] in ["coax", "circuit"]:
|
|
@@ -205,7 +264,7 @@ class CfgPorts:
|
|
|
205
264
|
if i.aedt_name:
|
|
206
265
|
edb_primitives[i.aedt_name] = i
|
|
207
266
|
for p in self.ports:
|
|
208
|
-
if p.type in ["wave_port", "diff_wave_port"]:
|
|
267
|
+
if p.type in ["wave_port", "diff_wave_port", "gap_port"]:
|
|
209
268
|
p.set_parameters_to_edb(edb_primitives)
|
|
210
269
|
else:
|
|
211
270
|
p.set_parameters_to_edb()
|
|
@@ -221,10 +280,10 @@ class CfgPorts:
|
|
|
221
280
|
port_type = "coax"
|
|
222
281
|
elif p.terminal_type == "PinGroupTerminal":
|
|
223
282
|
port_type = "circuit"
|
|
224
|
-
elif p.
|
|
225
|
-
port_type = "wave_port"
|
|
283
|
+
elif p.terminal_type == "EdgeTerminal":
|
|
284
|
+
port_type = "wave_port" if p.hfss_type == "Wave" else "gap_port"
|
|
226
285
|
else:
|
|
227
|
-
|
|
286
|
+
raise ValueError("Unknown terminal type")
|
|
228
287
|
else:
|
|
229
288
|
port_type = "circuit"
|
|
230
289
|
|
|
@@ -273,22 +332,7 @@ class CfgPorts:
|
|
|
273
332
|
positive_terminal=pos_term_info,
|
|
274
333
|
)
|
|
275
334
|
else:
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
primitive = Primitive(self._pedb, primitive)
|
|
279
|
-
point = PointData(self._pedb, point)
|
|
280
|
-
|
|
281
|
-
cfg_port = CfgEdgePort(
|
|
282
|
-
self._pedb,
|
|
283
|
-
name=p.name,
|
|
284
|
-
type=port_type,
|
|
285
|
-
primitive_name=primitive.aedt_name,
|
|
286
|
-
point_on_edge=[point._edb_object.X.ToString(), point._edb_object.Y.ToString()],
|
|
287
|
-
horizontal_extent_factor=p.horizontal_extent_factor,
|
|
288
|
-
vertical_extent_factor=p.vertical_extent_factor,
|
|
289
|
-
pec_launch_width=p.pec_launch_width,
|
|
290
|
-
)
|
|
291
|
-
|
|
335
|
+
cfg_port = self.api._get_edge_port_from_edb(p, port_type)
|
|
292
336
|
self.ports.append(cfg_port)
|
|
293
337
|
return self.export_properties()
|
|
294
338
|
|
|
@@ -723,8 +767,99 @@ class CfgProbe(CfgCircuitElement):
|
|
|
723
767
|
|
|
724
768
|
|
|
725
769
|
class CfgEdgePort:
|
|
770
|
+
class Grpc:
|
|
771
|
+
def __init__(self, parent):
|
|
772
|
+
self.parent = parent
|
|
773
|
+
self._pedb = parent._pedb
|
|
774
|
+
|
|
775
|
+
def set_parameters_to_edb(self, edb_primitives):
|
|
776
|
+
from ansys.edb.core.geometry.point_data import PointData as GrpcPointData
|
|
777
|
+
from ansys.edb.core.terminal.edge_terminal import (
|
|
778
|
+
EdgeTerminal as GrpcEdgeTerminal,
|
|
779
|
+
)
|
|
780
|
+
from ansys.edb.core.terminal.edge_terminal import (
|
|
781
|
+
PrimitiveEdge as GrpcPrimitiveEdge,
|
|
782
|
+
)
|
|
783
|
+
from ansys.edb.core.utility.value import Value as GrpcValue
|
|
784
|
+
|
|
785
|
+
from pyedb.grpc.database.ports.ports import WavePort
|
|
786
|
+
|
|
787
|
+
point_on_edge = GrpcPointData(self.parent.point_on_edge)
|
|
788
|
+
primitive = edb_primitives[self.parent.primitive_name]
|
|
789
|
+
pos_edge = GrpcPrimitiveEdge.create(primitive, point_on_edge)
|
|
790
|
+
edge_term = GrpcEdgeTerminal.create(
|
|
791
|
+
layout=primitive.layout, name=self.parent.name, net=primitive.net, edges=[pos_edge], is_ref=False
|
|
792
|
+
)
|
|
793
|
+
edge_term.impedance = GrpcValue(50)
|
|
794
|
+
wave_port = WavePort(self._pedb, edge_term)
|
|
795
|
+
wave_port.horizontal_extent_factor = self.parent.horizontal_extent_factor
|
|
796
|
+
wave_port.vertical_extent_factor = self.parent.vertical_extent_factor
|
|
797
|
+
wave_port.pec_launch_width = self.parent.pec_launch_width
|
|
798
|
+
if self.parent.type == "wave_port":
|
|
799
|
+
wave_port.hfss_type = "Wave"
|
|
800
|
+
else:
|
|
801
|
+
wave_port.hfss_type = "Gap"
|
|
802
|
+
wave_port.do_renormalize = True
|
|
803
|
+
return wave_port
|
|
804
|
+
|
|
805
|
+
def export_properties(self):
|
|
806
|
+
return {
|
|
807
|
+
"name": self.name,
|
|
808
|
+
"type": self.type,
|
|
809
|
+
"primitive_name": self.primitive_name,
|
|
810
|
+
"point_on_edge": self.point_on_edge,
|
|
811
|
+
"horizontal_extent_factor": self.horizontal_extent_factor,
|
|
812
|
+
"vertical_extent_factor": self.vertical_extent_factor,
|
|
813
|
+
"pec_launch_width": self.pec_launch_width,
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
class DotNet(Grpc):
|
|
817
|
+
def __init__(self, parent):
|
|
818
|
+
super().__init__(parent)
|
|
819
|
+
|
|
820
|
+
def set_parameters_to_edb(self, edb_primitives):
|
|
821
|
+
point_on_edge = PointData(self._pedb, x=self.parent.point_on_edge[0], y=self.parent.point_on_edge[1])
|
|
822
|
+
primitive = edb_primitives[self.parent.primitive_name]
|
|
823
|
+
pos_edge = self._pedb.edb_api.cell.terminal.PrimitiveEdge.Create(
|
|
824
|
+
primitive._edb_object, point_on_edge._edb_object
|
|
825
|
+
)
|
|
826
|
+
pos_edge = convert_py_list_to_net_list(pos_edge, self._pedb.edb_api.cell.terminal.Edge)
|
|
827
|
+
edge_term = self._pedb.edb_api.cell.terminal.EdgeTerminal.Create(
|
|
828
|
+
primitive._edb_object.GetLayout(),
|
|
829
|
+
primitive._edb_object.GetNet(),
|
|
830
|
+
self.parent.name,
|
|
831
|
+
pos_edge,
|
|
832
|
+
isRef=False,
|
|
833
|
+
)
|
|
834
|
+
edge_term.SetImpedance(self._pedb.edb_value(50))
|
|
835
|
+
wave_port = WavePort(self._pedb, edge_term)
|
|
836
|
+
wave_port.horizontal_extent_factor = self.parent.horizontal_extent_factor
|
|
837
|
+
wave_port.vertical_extent_factor = self.parent.vertical_extent_factor
|
|
838
|
+
wave_port.pec_launch_width = self.parent.pec_launch_width
|
|
839
|
+
if self.parent.type == "wave_port":
|
|
840
|
+
wave_port.hfss_type = "Wave"
|
|
841
|
+
else:
|
|
842
|
+
wave_port.hfss_type = "Gap"
|
|
843
|
+
wave_port.do_renormalize = True
|
|
844
|
+
return wave_port
|
|
845
|
+
|
|
846
|
+
def export_properties(self):
|
|
847
|
+
return {
|
|
848
|
+
"name": self.parent.name,
|
|
849
|
+
"type": self.parent.type,
|
|
850
|
+
"primitive_name": self.parent.primitive_name,
|
|
851
|
+
"point_on_edge": self.parent.point_on_edge,
|
|
852
|
+
"horizontal_extent_factor": self.parent.horizontal_extent_factor,
|
|
853
|
+
"vertical_extent_factor": self.parent.vertical_extent_factor,
|
|
854
|
+
"pec_launch_width": self.parent.pec_launch_width,
|
|
855
|
+
}
|
|
856
|
+
|
|
726
857
|
def __init__(self, pedb, **kwargs):
|
|
727
858
|
self._pedb = pedb
|
|
859
|
+
if self._pedb.grpc:
|
|
860
|
+
self.api = self.Grpc(self)
|
|
861
|
+
else:
|
|
862
|
+
self.api = self.DotNet(self)
|
|
728
863
|
self.name = kwargs["name"]
|
|
729
864
|
self.type = kwargs["type"]
|
|
730
865
|
self.primitive_name = kwargs["primitive_name"]
|
|
@@ -734,37 +869,10 @@ class CfgEdgePort:
|
|
|
734
869
|
self.pec_launch_width = kwargs.get("pec_launch_width", "0.01mm")
|
|
735
870
|
|
|
736
871
|
def set_parameters_to_edb(self, edb_primitives):
|
|
737
|
-
|
|
738
|
-
primitive = edb_primitives[self.primitive_name]
|
|
739
|
-
pos_edge = self._pedb.edb_api.cell.terminal.PrimitiveEdge.Create(
|
|
740
|
-
primitive._edb_object, point_on_edge._edb_object
|
|
741
|
-
)
|
|
742
|
-
pos_edge = convert_py_list_to_net_list(pos_edge, self._pedb.edb_api.cell.terminal.Edge)
|
|
743
|
-
edge_term = self._pedb.edb_api.cell.terminal.EdgeTerminal.Create(
|
|
744
|
-
primitive._edb_object.GetLayout(), primitive._edb_object.GetNet(), self.name, pos_edge, isRef=False
|
|
745
|
-
)
|
|
746
|
-
edge_term.SetImpedance(self._pedb.edb_value(50))
|
|
747
|
-
wave_port = WavePort(self._pedb, edge_term)
|
|
748
|
-
wave_port.horizontal_extent_factor = self.horizontal_extent_factor
|
|
749
|
-
wave_port.vertical_extent_factor = self.vertical_extent_factor
|
|
750
|
-
wave_port.pec_launch_width = self.pec_launch_width
|
|
751
|
-
if self.type == "wave_port":
|
|
752
|
-
wave_port.hfss_type = "Wave"
|
|
753
|
-
else:
|
|
754
|
-
wave_port.hfss_type = "Gap"
|
|
755
|
-
wave_port.do_renormalize = True
|
|
756
|
-
return wave_port
|
|
872
|
+
return self.api.set_parameters_to_edb(edb_primitives)
|
|
757
873
|
|
|
758
874
|
def export_properties(self):
|
|
759
|
-
return
|
|
760
|
-
"name": self.name,
|
|
761
|
-
"type": self.type,
|
|
762
|
-
"primitive_name": self.primitive_name,
|
|
763
|
-
"point_on_edge": self.point_on_edge,
|
|
764
|
-
"horizontal_extent_factor": self.horizontal_extent_factor,
|
|
765
|
-
"vertical_extent_factor": self.vertical_extent_factor,
|
|
766
|
-
"pec_launch_width": self.pec_launch_width,
|
|
767
|
-
}
|
|
875
|
+
return self.api.export_properties()
|
|
768
876
|
|
|
769
877
|
|
|
770
878
|
class CfgDiffWavePort:
|
|
@@ -80,7 +80,7 @@ class CfgSParameters:
|
|
|
80
80
|
else:
|
|
81
81
|
pin_order = compdef_obj.get_properties()["pin_order"]
|
|
82
82
|
temp_comps = [i for i in cfg_components if i["definition"] == name]
|
|
83
|
-
for
|
|
83
|
+
for model_obj in nport_models:
|
|
84
84
|
temp_comp_list = []
|
|
85
85
|
reference_net_per_component = {}
|
|
86
86
|
for i in temp_comps:
|
|
@@ -155,6 +155,56 @@ class CfgSParameters:
|
|
|
155
155
|
ref_net = s_param.reference_net
|
|
156
156
|
comp.use_s_parameter_model(s_param.name, reference_net=ref_net)
|
|
157
157
|
|
|
158
|
+
def get_data_from_db(self, cfg_components):
|
|
159
|
+
db_comp_def = self._pedb.definitions.component
|
|
160
|
+
for name, compdef_obj in db_comp_def.items():
|
|
161
|
+
nport_models = compdef_obj.component_models
|
|
162
|
+
if not nport_models:
|
|
163
|
+
continue
|
|
164
|
+
else:
|
|
165
|
+
pin_order = compdef_obj.get_properties()["pin_order"]
|
|
166
|
+
temp_comps = [i for i in cfg_components if i["definition"] == name]
|
|
167
|
+
for model_name, model_obj in nport_models.items():
|
|
168
|
+
temp_comp_list = []
|
|
169
|
+
reference_net_per_component = {}
|
|
170
|
+
for i in temp_comps:
|
|
171
|
+
s_param_model = i.get("s_parameter_model")
|
|
172
|
+
if s_param_model:
|
|
173
|
+
if s_param_model["model_name"] == model_name:
|
|
174
|
+
temp_comp_list.append(i["reference_designator"])
|
|
175
|
+
reference_net_per_component[i["reference_designator"]] = s_param_model[
|
|
176
|
+
"reference_net"
|
|
177
|
+
]
|
|
178
|
+
else:
|
|
179
|
+
continue
|
|
180
|
+
|
|
181
|
+
self.parent.s_parameters_models.append(
|
|
182
|
+
CfgSParameterModel(
|
|
183
|
+
name=model_name,
|
|
184
|
+
component_definition=name,
|
|
185
|
+
file_path=model_obj.reference_file,
|
|
186
|
+
apply_to_all=False,
|
|
187
|
+
components=temp_comp_list,
|
|
188
|
+
reference_net_per_component=reference_net_per_component,
|
|
189
|
+
pin_order=pin_order,
|
|
190
|
+
)
|
|
191
|
+
)
|
|
192
|
+
|
|
193
|
+
data = []
|
|
194
|
+
for i in self.parent.s_parameters_models:
|
|
195
|
+
data.append(
|
|
196
|
+
{
|
|
197
|
+
"name": i.name,
|
|
198
|
+
"component_definition": i.component_definition,
|
|
199
|
+
"file_path": i.file_path,
|
|
200
|
+
"apply_to_all": i.apply_to_all,
|
|
201
|
+
"components": i.components,
|
|
202
|
+
"reference_net_per_component": i.reference_net_per_component,
|
|
203
|
+
"pin_order": i.pin_order,
|
|
204
|
+
}
|
|
205
|
+
)
|
|
206
|
+
return data
|
|
207
|
+
|
|
158
208
|
def __init__(self, pedb, data, path_lib=None):
|
|
159
209
|
self._pedb = pedb
|
|
160
210
|
if self._pedb.grpc:
|
pyedb/configuration/cfg_setup.py
CHANGED
|
@@ -32,6 +32,59 @@ class CfgSetup:
|
|
|
32
32
|
"""
|
|
33
33
|
|
|
34
34
|
class Common:
|
|
35
|
+
class Grpc:
|
|
36
|
+
def __init__(self, parent):
|
|
37
|
+
self.parent = parent
|
|
38
|
+
|
|
39
|
+
def apply_freq_sweep(self, edb_setup):
|
|
40
|
+
for i in self.parent.parent.freq_sweep:
|
|
41
|
+
f_set = []
|
|
42
|
+
freq_string = []
|
|
43
|
+
for f in i.get("frequencies", []):
|
|
44
|
+
if isinstance(f, dict):
|
|
45
|
+
increment = f.get("increment", f.get("points", f.get("samples", f.get("step"))))
|
|
46
|
+
f_set.append([f["distribution"], f["start"], f["stop"], increment])
|
|
47
|
+
else:
|
|
48
|
+
freq_string.append(f)
|
|
49
|
+
discrete_sweep = True
|
|
50
|
+
if i["type"] == "interpolation":
|
|
51
|
+
discrete_sweep = False
|
|
52
|
+
if freq_string:
|
|
53
|
+
for _sweep in freq_string:
|
|
54
|
+
_sw = _sweep.split(" ")
|
|
55
|
+
edb_setup.add_sweep(
|
|
56
|
+
name=i["name"],
|
|
57
|
+
distribution=_sw[0],
|
|
58
|
+
start_freq=_sw[1],
|
|
59
|
+
stop_freq=_sw[2],
|
|
60
|
+
step=_sw[3],
|
|
61
|
+
discrete=discrete_sweep,
|
|
62
|
+
)
|
|
63
|
+
else:
|
|
64
|
+
edb_setup.add_sweep(i["name"], frequency_set=f_set, discrete=discrete_sweep)
|
|
65
|
+
|
|
66
|
+
class DotNet(Grpc):
|
|
67
|
+
def __init__(self, parent):
|
|
68
|
+
super().__init__(parent)
|
|
69
|
+
|
|
70
|
+
@staticmethod
|
|
71
|
+
def set_frequency_string(sweep, freq_string):
|
|
72
|
+
sweep.frequency_string = freq_string
|
|
73
|
+
|
|
74
|
+
def apply_freq_sweep(self, edb_setup):
|
|
75
|
+
for i in self.parent.parent.freq_sweep:
|
|
76
|
+
f_set = []
|
|
77
|
+
freq_string = []
|
|
78
|
+
for f in i.get("frequencies", []):
|
|
79
|
+
if isinstance(f, dict):
|
|
80
|
+
increment = f.get("increment", f.get("points", f.get("samples", f.get("step"))))
|
|
81
|
+
f_set.append([f["distribution"], f["start"], f["stop"], increment])
|
|
82
|
+
else:
|
|
83
|
+
freq_string.append(f)
|
|
84
|
+
sweep = edb_setup.add_sweep(i["name"], frequency_set=f_set, sweep_type=i["type"])
|
|
85
|
+
if len(freq_string) > 0:
|
|
86
|
+
self.parent.api.set_frequency_string(sweep, freq_string)
|
|
87
|
+
|
|
35
88
|
@property
|
|
36
89
|
def pyedb_obj(self):
|
|
37
90
|
return self.parent.pyedb_obj
|
|
@@ -39,24 +92,17 @@ class CfgSetup:
|
|
|
39
92
|
def __init__(self, parent):
|
|
40
93
|
self.parent = parent
|
|
41
94
|
self.pedb = parent.pedb
|
|
95
|
+
if self.pedb.grpc:
|
|
96
|
+
self.api = self.Grpc(self)
|
|
97
|
+
else:
|
|
98
|
+
self.api = self.DotNet(self)
|
|
42
99
|
|
|
43
100
|
def _retrieve_parameters_from_edb_common(self):
|
|
44
101
|
self.parent.name = self.pyedb_obj.name
|
|
45
102
|
self.parent.type = self.pyedb_obj.type
|
|
46
103
|
|
|
47
104
|
def _apply_freq_sweep(self, edb_setup):
|
|
48
|
-
|
|
49
|
-
f_set = []
|
|
50
|
-
freq_string = []
|
|
51
|
-
for f in i.get("frequencies", []):
|
|
52
|
-
if isinstance(f, dict):
|
|
53
|
-
increment = f.get("increment", f.get("points", f.get("samples", f.get("step"))))
|
|
54
|
-
f_set.append([f["distribution"], f["start"], f["stop"], increment])
|
|
55
|
-
else:
|
|
56
|
-
freq_string.append(f)
|
|
57
|
-
sweep = edb_setup.add_sweep(i["name"], frequency_set=f_set, sweep_type=i["type"])
|
|
58
|
-
if len(freq_string) > 0:
|
|
59
|
-
sweep.frequency_string = freq_string
|
|
105
|
+
self.api.apply_freq_sweep(edb_setup)
|
|
60
106
|
|
|
61
107
|
class Grpc(Common):
|
|
62
108
|
def __init__(self, parent):
|
|
@@ -149,7 +195,7 @@ class CfgSIwaveDCSetup(CfgSetup):
|
|
|
149
195
|
name=self.parent.name, dc_slider_position=self.parent.dc_slider_position
|
|
150
196
|
)
|
|
151
197
|
edb_setup.settings.dc.dc_slider_pos = self.parent.dc_slider_position
|
|
152
|
-
edb_setup.settings.export_dc_thermal_data = self.parent.dc_ir_settings
|
|
198
|
+
edb_setup.settings.export_dc_thermal_data = self.parent.dc_ir_settings.get("export_dc_thermal_data", False)
|
|
153
199
|
|
|
154
200
|
def retrieve_parameters_from_edb(self):
|
|
155
201
|
self._retrieve_parameters_from_edb_common()
|
|
@@ -168,7 +214,7 @@ class CfgSIwaveDCSetup(CfgSetup):
|
|
|
168
214
|
)
|
|
169
215
|
edb_setup.dc_settings.dc_slider_position = self.parent.dc_slider_position
|
|
170
216
|
dc_ir_settings = self.parent.dc_ir_settings
|
|
171
|
-
edb_setup.dc_ir_settings.export_dc_thermal_data = dc_ir_settings
|
|
217
|
+
edb_setup.dc_ir_settings.export_dc_thermal_data = dc_ir_settings.get("export_dc_thermal_data", False)
|
|
172
218
|
|
|
173
219
|
def __init__(self, pedb, pyedb_obj, **kwargs):
|
|
174
220
|
super().__init__(pedb, pyedb_obj, **kwargs)
|
|
@@ -216,8 +262,12 @@ class CfgHFSSSetup(CfgSetup):
|
|
|
216
262
|
self.parent.max_num_passes = single_frequency_adaptive_solution.max_passes
|
|
217
263
|
self.parent.max_mag_delta_s = float(single_frequency_adaptive_solution.max_delta)
|
|
218
264
|
self.parent.freq_sweep = []
|
|
219
|
-
|
|
220
|
-
|
|
265
|
+
setup_sweeps = self.sort_sweep_data(self.pyedb_obj.sweep_data)
|
|
266
|
+
for setup_name, sweeps in setup_sweeps.items():
|
|
267
|
+
sw_name = sweeps[0].name
|
|
268
|
+
sw_type = sweeps[0].type.name.lower().split("_")[0]
|
|
269
|
+
freq_strings = [f.frequency_string for f in sweeps]
|
|
270
|
+
self.parent.freq_sweep.append({"name": sw_name, "type": sw_type, "frequencies": freq_strings})
|
|
221
271
|
|
|
222
272
|
self.parent.mesh_operations = []
|
|
223
273
|
from ansys.edb.core.simulation_setup.mesh_operation import (
|
|
@@ -241,6 +291,17 @@ class CfgHFSSSetup(CfgSetup):
|
|
|
241
291
|
}
|
|
242
292
|
)
|
|
243
293
|
|
|
294
|
+
@staticmethod
|
|
295
|
+
def sort_sweep_data(sweep_data):
|
|
296
|
+
"""grpc sweep data contains all sweeps for each setup, we need to sort thwm by setup"""
|
|
297
|
+
setups = {}
|
|
298
|
+
for sweep in sweep_data:
|
|
299
|
+
if sweep.name not in setups:
|
|
300
|
+
setups[sweep.name] = [sweep]
|
|
301
|
+
else:
|
|
302
|
+
setups[sweep.name].append(sweep)
|
|
303
|
+
return setups
|
|
304
|
+
|
|
244
305
|
class DotNet(Grpc):
|
|
245
306
|
def __init__(self, parent):
|
|
246
307
|
super().__init__(parent)
|