pyedb 0.39.1__py3-none-any.whl → 0.40.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/common/nets.py +11 -2
- pyedb/configuration/cfg_components.py +2 -0
- pyedb/configuration/cfg_padstacks.py +1 -1
- pyedb/configuration/cfg_ports_sources.py +63 -11
- pyedb/configuration/cfg_stackup.py +22 -1
- pyedb/dotnet/database/cell/terminal/edge_terminal.py +55 -0
- pyedb/dotnet/database/components.py +14 -12
- pyedb/dotnet/database/edb_data/ports.py +0 -55
- pyedb/dotnet/database/materials.py +40 -11
- pyedb/dotnet/database/modeler.py +11 -4
- pyedb/grpc/database/components.py +24 -72
- pyedb/grpc/database/definition/materials.py +16 -1
- pyedb/grpc/database/layout/layout.py +43 -4
- pyedb/grpc/database/layout_validation.py +164 -143
- pyedb/grpc/database/net/net.py +5 -8
- pyedb/grpc/database/padstacks.py +184 -31
- pyedb/grpc/database/primitive/padstack_instance.py +1 -1
- pyedb/grpc/database/source_excitations.py +83 -105
- pyedb/grpc/edb.py +41 -198
- {pyedb-0.39.1.dist-info → pyedb-0.40.0.dist-info}/METADATA +2 -1
- {pyedb-0.39.1.dist-info → pyedb-0.40.0.dist-info}/RECORD +24 -24
- {pyedb-0.39.1.dist-info → pyedb-0.40.0.dist-info}/LICENSE +0 -0
- {pyedb-0.39.1.dist-info → pyedb-0.40.0.dist-info}/WHEEL +0 -0
pyedb/__init__.py
CHANGED
pyedb/common/nets.py
CHANGED
|
@@ -22,6 +22,7 @@ class CommonNets:
|
|
|
22
22
|
show=True,
|
|
23
23
|
annotate_component_names=True,
|
|
24
24
|
plot_vias=False,
|
|
25
|
+
title=None,
|
|
25
26
|
**kwargs,
|
|
26
27
|
):
|
|
27
28
|
"""Plot a Net to Matplotlib 2D Chart.
|
|
@@ -57,6 +58,9 @@ class CommonNets:
|
|
|
57
58
|
plot_vias : bool, optional
|
|
58
59
|
Whether to plot vias (circular and rectangular) or not. This may impact in the plot computation time.
|
|
59
60
|
Default is ``False``.
|
|
61
|
+
title : str, optional
|
|
62
|
+
Specify the default plot title. Is value is ``None`` the project name is assigned by default. Default value
|
|
63
|
+
is ``None``.
|
|
60
64
|
show : bool, optional
|
|
61
65
|
Whether to show the plot or not. Default is `True`.
|
|
62
66
|
|
|
@@ -95,7 +99,7 @@ class CommonNets:
|
|
|
95
99
|
|
|
96
100
|
start_time = time.time()
|
|
97
101
|
if not nets:
|
|
98
|
-
nets = list(self.nets.keys())
|
|
102
|
+
nets = list(self._pedb.nets.nets.keys())
|
|
99
103
|
if isinstance(nets, str):
|
|
100
104
|
nets = [nets]
|
|
101
105
|
if not layers:
|
|
@@ -395,7 +399,12 @@ class CommonNets:
|
|
|
395
399
|
# Hide axes ticks
|
|
396
400
|
ax.set_xticks([])
|
|
397
401
|
ax.set_yticks([])
|
|
398
|
-
|
|
402
|
+
if not title:
|
|
403
|
+
if not self._pedb.grpc:
|
|
404
|
+
title = self._pedb.active_cell.GetName()
|
|
405
|
+
else:
|
|
406
|
+
title = self._pedb.active_cell.name
|
|
407
|
+
message = f"Edb Top View {title}" if top_view else f"Edb Bottom View {title}"
|
|
399
408
|
plt.title(message, size=20)
|
|
400
409
|
if show_legend:
|
|
401
410
|
plt.legend(loc="upper left", fontsize="x-large")
|
|
@@ -216,6 +216,7 @@ class CfgComponent(CfgBase):
|
|
|
216
216
|
if self.pyedb_obj.type.lower() == "ic":
|
|
217
217
|
self._set_ic_die_properties_to_edb()
|
|
218
218
|
self._set_port_properties_to_edb()
|
|
219
|
+
self._set_solder_ball_properties_to_edb()
|
|
219
220
|
elif self.pyedb_obj.type.lower() in ["io", "other"]:
|
|
220
221
|
self._set_solder_ball_properties_to_edb()
|
|
221
222
|
self._set_port_properties_to_edb()
|
|
@@ -228,6 +229,7 @@ class CfgComponent(CfgBase):
|
|
|
228
229
|
if self.pyedb_obj.type.lower() == "ic":
|
|
229
230
|
self._retrieve_ic_die_properties_from_edb()
|
|
230
231
|
self._retrieve_port_properties_from_edb()
|
|
232
|
+
self._retrieve_solder_ball_properties_from_edb()
|
|
231
233
|
elif self.pyedb_obj.type.lower() in ["io", "other"]:
|
|
232
234
|
self._retrieve_solder_ball_properties_from_edb()
|
|
233
235
|
self._retrieve_port_properties_from_edb()
|
|
@@ -427,7 +427,7 @@ class CfgPadstackInstance(CfgBase):
|
|
|
427
427
|
self.api = self.DotNet(self)
|
|
428
428
|
|
|
429
429
|
self.name = kwargs.get("name", None)
|
|
430
|
-
self.net_name = kwargs.get("net_name",
|
|
430
|
+
self.net_name = kwargs.get("net_name", None)
|
|
431
431
|
self.layer_range = kwargs.get("layer_range", [None, None])
|
|
432
432
|
self.definition = kwargs.get("definition", None)
|
|
433
433
|
self.backdrill_parameters = kwargs.get("backdrill_parameters", None)
|
|
@@ -24,6 +24,7 @@ import os
|
|
|
24
24
|
import numpy as np
|
|
25
25
|
|
|
26
26
|
from pyedb.configuration.cfg_common import CfgBase
|
|
27
|
+
from pyedb.dotnet.database.cell.primitive.primitive import Primitive
|
|
27
28
|
from pyedb.dotnet.database.edb_data.ports import WavePort
|
|
28
29
|
from pyedb.dotnet.database.general import convert_py_list_to_net_list
|
|
29
30
|
from pyedb.dotnet.database.geometry.point_data import PointData
|
|
@@ -53,6 +54,7 @@ class CfgTerminalInfo(CfgBase):
|
|
|
53
54
|
contact_radius = "0.1mm" if kwargs.get("contact_radius") is None else kwargs.get("contact_radius")
|
|
54
55
|
self.contact_radius = self._pedb.edb_value(contact_radius).ToDouble()
|
|
55
56
|
self.num_of_contact = kwargs.get("num_of_contact", 4)
|
|
57
|
+
self.contact_expansion = kwargs.get("contact_expansion", 1)
|
|
56
58
|
|
|
57
59
|
def export_properties(self):
|
|
58
60
|
return {self.type: self.value}
|
|
@@ -141,7 +143,7 @@ class CfgPorts:
|
|
|
141
143
|
self.ports = []
|
|
142
144
|
for p in ports_data:
|
|
143
145
|
if p["type"] == "wave_port":
|
|
144
|
-
self.ports.append(
|
|
146
|
+
self.ports.append(CfgEdgePort(self._pedb, **p))
|
|
145
147
|
elif p["type"] == "diff_wave_port":
|
|
146
148
|
self.ports.append(CfgDiffWavePort(self._pedb, **p))
|
|
147
149
|
elif p["type"] in ["coax", "circuit"]:
|
|
@@ -167,7 +169,12 @@ class CfgPorts:
|
|
|
167
169
|
|
|
168
170
|
for _, p in ports.items():
|
|
169
171
|
if not p.ref_terminal:
|
|
170
|
-
|
|
172
|
+
if p.terminal_type == "PadstackInstanceTerminal":
|
|
173
|
+
port_type = "coax"
|
|
174
|
+
elif p.hfss_type == "Wave":
|
|
175
|
+
port_type = "wave_port"
|
|
176
|
+
else:
|
|
177
|
+
port_type = "gap_port"
|
|
171
178
|
else:
|
|
172
179
|
port_type = "circuit"
|
|
173
180
|
|
|
@@ -206,7 +213,7 @@ class CfgPorts:
|
|
|
206
213
|
positive_terminal=pos_term_info,
|
|
207
214
|
negative_terminal=neg_term_info,
|
|
208
215
|
)
|
|
209
|
-
|
|
216
|
+
elif port_type == "coax":
|
|
210
217
|
cfg_port = CfgPort(
|
|
211
218
|
self._pedb,
|
|
212
219
|
name=p.name,
|
|
@@ -214,6 +221,22 @@ class CfgPorts:
|
|
|
214
221
|
reference_designator=refdes,
|
|
215
222
|
positive_terminal=pos_term_info,
|
|
216
223
|
)
|
|
224
|
+
else:
|
|
225
|
+
_, primitive, point = p._edb_object.GetEdges()[0].GetParameters()
|
|
226
|
+
|
|
227
|
+
primitive = Primitive(self._pedb, primitive)
|
|
228
|
+
point = PointData(self._pedb, point)
|
|
229
|
+
|
|
230
|
+
cfg_port = CfgEdgePort(
|
|
231
|
+
self._pedb,
|
|
232
|
+
name=p.name,
|
|
233
|
+
type=port_type,
|
|
234
|
+
primitive_name=primitive.aedt_name,
|
|
235
|
+
point_on_edge=[point._edb_object.X.ToString(), point._edb_object.Y.ToString()],
|
|
236
|
+
horizontal_extent_factor=p.horizontal_extent_factor,
|
|
237
|
+
vertical_extent_factor=p.vertical_extent_factor,
|
|
238
|
+
pec_launch_width=p.pec_launch_width,
|
|
239
|
+
)
|
|
217
240
|
|
|
218
241
|
self.ports.append(cfg_port)
|
|
219
242
|
return self.export_properties()
|
|
@@ -294,7 +317,11 @@ class CfgCircuitElement(CfgBase):
|
|
|
294
317
|
contact_type = self.positive_terminal_info.contact_type
|
|
295
318
|
radius = self.positive_terminal_info.contact_radius
|
|
296
319
|
num_of_contact = self.positive_terminal_info.num_of_contact
|
|
297
|
-
|
|
320
|
+
contact_expansion = self.positive_terminal_info.contact_expansion
|
|
321
|
+
|
|
322
|
+
virtual_pins = self._create_virtual_pins_on_pin(
|
|
323
|
+
pin, contact_type, radius, num_of_contact, contact_expansion
|
|
324
|
+
)
|
|
298
325
|
pos_objs.update(virtual_pins)
|
|
299
326
|
self._elem_num = len(pos_objs)
|
|
300
327
|
else:
|
|
@@ -309,7 +336,11 @@ class CfgCircuitElement(CfgBase):
|
|
|
309
336
|
contact_type = self.positive_terminal_info.contact_type
|
|
310
337
|
radius = self.positive_terminal_info.contact_radius
|
|
311
338
|
num_of_contact = self.positive_terminal_info.num_of_contact
|
|
312
|
-
|
|
339
|
+
contact_expansion = self.positive_terminal_info.contact_expansion
|
|
340
|
+
|
|
341
|
+
virtual_pins = self._create_virtual_pins_on_pin(
|
|
342
|
+
pin, contact_type, radius, num_of_contact, contact_expansion
|
|
343
|
+
)
|
|
313
344
|
pos_objs.update(virtual_pins)
|
|
314
345
|
self._elem_num = len(pos_objs)
|
|
315
346
|
else:
|
|
@@ -324,7 +355,11 @@ class CfgCircuitElement(CfgBase):
|
|
|
324
355
|
contact_type = self.positive_terminal_info.contact_type
|
|
325
356
|
radius = self.positive_terminal_info.contact_radius
|
|
326
357
|
num_of_contact = self.positive_terminal_info.num_of_contact
|
|
327
|
-
|
|
358
|
+
contact_expansion = self.positive_terminal_info.contact_expansion
|
|
359
|
+
|
|
360
|
+
virtual_pins = self._create_virtual_pins_on_pin(
|
|
361
|
+
pin, contact_type, radius, num_of_contact, contact_expansion
|
|
362
|
+
)
|
|
328
363
|
pos_objs.update(virtual_pins)
|
|
329
364
|
self._elem_num = len(pos_objs)
|
|
330
365
|
else:
|
|
@@ -400,7 +435,7 @@ class CfgCircuitElement(CfgBase):
|
|
|
400
435
|
pins.update({f"{reference_designator}_{terminal_value[0]}_{i}": j for i, j in temp.items()})
|
|
401
436
|
return pins
|
|
402
437
|
|
|
403
|
-
def _create_virtual_pins_on_pin(self, pin, contact_type, radius, num_of_contact=4):
|
|
438
|
+
def _create_virtual_pins_on_pin(self, pin, contact_type, radius, num_of_contact=4, expansion=1):
|
|
404
439
|
component = pin.component
|
|
405
440
|
placement_layer = component.placement_layer
|
|
406
441
|
pos_x, pos_y = pin.position
|
|
@@ -420,6 +455,9 @@ class CfgCircuitElement(CfgBase):
|
|
|
420
455
|
else: # pragma no cover
|
|
421
456
|
raise AttributeError(f"Unsupported pad shape {pad.shape.lower()}")
|
|
422
457
|
|
|
458
|
+
width = width * expansion
|
|
459
|
+
height = height * expansion
|
|
460
|
+
|
|
423
461
|
positions = []
|
|
424
462
|
if contact_type.lower() == "inline":
|
|
425
463
|
if width > height:
|
|
@@ -624,7 +662,7 @@ class CfgProbe(CfgCircuitElement):
|
|
|
624
662
|
self.api = self.DotNet(self)
|
|
625
663
|
|
|
626
664
|
|
|
627
|
-
class
|
|
665
|
+
class CfgEdgePort:
|
|
628
666
|
def __init__(self, pedb, **kwargs):
|
|
629
667
|
self._pedb = pedb
|
|
630
668
|
self.name = kwargs["name"]
|
|
@@ -650,10 +688,24 @@ class CfgWavePort:
|
|
|
650
688
|
wave_port.horizontal_extent_factor = self.horizontal_extent_factor
|
|
651
689
|
wave_port.vertical_extent_factor = self.vertical_extent_factor
|
|
652
690
|
wave_port.pec_launch_width = self.pec_launch_width
|
|
653
|
-
|
|
691
|
+
if self.type == "wave_port":
|
|
692
|
+
wave_port.hfss_type = "Wave"
|
|
693
|
+
else:
|
|
694
|
+
wave_port.hfss_type = "Gap"
|
|
654
695
|
wave_port.do_renormalize = True
|
|
655
696
|
return wave_port
|
|
656
697
|
|
|
698
|
+
def export_properties(self):
|
|
699
|
+
return {
|
|
700
|
+
"name": self.name,
|
|
701
|
+
"type": self.type,
|
|
702
|
+
"primitive_name": self.primitive_name,
|
|
703
|
+
"point_on_edge": self.point_on_edge,
|
|
704
|
+
"horizontal_extent_factor": self.horizontal_extent_factor,
|
|
705
|
+
"vertical_extent_factor": self.vertical_extent_factor,
|
|
706
|
+
"pec_launch_width": self.pec_launch_width,
|
|
707
|
+
}
|
|
708
|
+
|
|
657
709
|
|
|
658
710
|
class CfgDiffWavePort:
|
|
659
711
|
def __init__(self, pedb, **kwargs):
|
|
@@ -666,7 +718,7 @@ class CfgDiffWavePort:
|
|
|
666
718
|
|
|
667
719
|
kwargs["positive_terminal"]["type"] = "wave_port"
|
|
668
720
|
kwargs["positive_terminal"]["name"] = self.name + ":T1"
|
|
669
|
-
self.positive_port =
|
|
721
|
+
self.positive_port = CfgEdgePort(
|
|
670
722
|
self._pedb,
|
|
671
723
|
horizontal_extent_factor=self.horizontal_extent_factor,
|
|
672
724
|
vertical_extent_factor=self.vertical_extent_factor,
|
|
@@ -675,7 +727,7 @@ class CfgDiffWavePort:
|
|
|
675
727
|
)
|
|
676
728
|
kwargs["negative_terminal"]["type"] = "wave_port"
|
|
677
729
|
kwargs["negative_terminal"]["name"] = self.name + ":T2"
|
|
678
|
-
self.negative_port =
|
|
730
|
+
self.negative_port = CfgEdgePort(
|
|
679
731
|
self._pedb,
|
|
680
732
|
horizontal_extent_factor=self.horizontal_extent_factor,
|
|
681
733
|
vertical_extent_factor=self.vertical_extent_factor,
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
21
|
# SOFTWARE.
|
|
22
22
|
|
|
23
|
+
from pyedb import Edb
|
|
23
24
|
from pyedb.configuration.cfg_common import CfgBase
|
|
24
25
|
|
|
25
26
|
|
|
@@ -49,12 +50,32 @@ class CfgLayer(CfgBase):
|
|
|
49
50
|
|
|
50
51
|
|
|
51
52
|
class CfgStackup:
|
|
52
|
-
def __init__(self, pedb, data):
|
|
53
|
+
def __init__(self, pedb: Edb, data):
|
|
53
54
|
self._pedb = pedb
|
|
54
55
|
|
|
55
56
|
self.materials = [CfgMaterial(**mat) for mat in data.get("materials", [])]
|
|
56
57
|
self.layers = [CfgLayer(**lay) for lay in data.get("layers", [])]
|
|
57
58
|
|
|
59
|
+
materials = [m.name for m in self.materials]
|
|
60
|
+
for i in self.layers:
|
|
61
|
+
if i.type == "signal":
|
|
62
|
+
if i.material not in materials:
|
|
63
|
+
self.materials.append(
|
|
64
|
+
CfgMaterial(name=i.material, **self._pedb.materials.default_conductor_property_values)
|
|
65
|
+
)
|
|
66
|
+
materials.append(i.material)
|
|
67
|
+
if i.fill_material not in materials:
|
|
68
|
+
self.materials.append(
|
|
69
|
+
CfgMaterial(name=i.fill_material, **self._pedb.materials.default_dielectric_property_values)
|
|
70
|
+
)
|
|
71
|
+
materials.append(i.fill_material)
|
|
72
|
+
elif i.type == "dielectric":
|
|
73
|
+
if i.material not in materials:
|
|
74
|
+
self.materials.append(
|
|
75
|
+
CfgMaterial(name=i.material, **self._pedb.materials.default_dielectric_property_values)
|
|
76
|
+
)
|
|
77
|
+
materials.append(i.material)
|
|
78
|
+
|
|
58
79
|
def apply(self):
|
|
59
80
|
"""Apply configuration settings to the current design"""
|
|
60
81
|
if len(self.materials):
|
|
@@ -48,3 +48,58 @@ class EdgeTerminal(Terminal):
|
|
|
48
48
|
edb_list = convert_py_list_to_net_list(temp, self._edb.cell.terminal.Terminal)
|
|
49
49
|
_edb_bundle_terminal = self._edb.cell.terminal.BundleTerminal.Create(edb_list)
|
|
50
50
|
return self._pedb.ports[_edb_bundle_terminal.GetName()]
|
|
51
|
+
|
|
52
|
+
@property
|
|
53
|
+
def horizontal_extent_factor(self):
|
|
54
|
+
"""Horizontal extent factor."""
|
|
55
|
+
return self._hfss_port_property["Horizontal Extent Factor"]
|
|
56
|
+
|
|
57
|
+
@horizontal_extent_factor.setter
|
|
58
|
+
def horizontal_extent_factor(self, value):
|
|
59
|
+
p = self._hfss_port_property
|
|
60
|
+
p["Horizontal Extent Factor"] = value
|
|
61
|
+
self._hfss_port_property = p
|
|
62
|
+
|
|
63
|
+
@property
|
|
64
|
+
def vertical_extent_factor(self):
|
|
65
|
+
"""Vertical extent factor."""
|
|
66
|
+
return self._hfss_port_property["Vertical Extent Factor"]
|
|
67
|
+
|
|
68
|
+
@vertical_extent_factor.setter
|
|
69
|
+
def vertical_extent_factor(self, value):
|
|
70
|
+
p = self._hfss_port_property
|
|
71
|
+
p["Vertical Extent Factor"] = value
|
|
72
|
+
self._hfss_port_property = p
|
|
73
|
+
|
|
74
|
+
@property
|
|
75
|
+
def pec_launch_width(self):
|
|
76
|
+
"""Launch width for the printed electronic component (PEC)."""
|
|
77
|
+
return self._hfss_port_property["PEC Launch Width"]
|
|
78
|
+
|
|
79
|
+
@pec_launch_width.setter
|
|
80
|
+
def pec_launch_width(self, value):
|
|
81
|
+
p = self._hfss_port_property
|
|
82
|
+
p["PEC Launch Width"] = value
|
|
83
|
+
self._hfss_port_property = p
|
|
84
|
+
|
|
85
|
+
@property
|
|
86
|
+
def deembed(self):
|
|
87
|
+
"""Whether deembed is active."""
|
|
88
|
+
return self._edb_object.GetPortPostProcessingProp().DoDeembed
|
|
89
|
+
|
|
90
|
+
@deembed.setter
|
|
91
|
+
def deembed(self, value):
|
|
92
|
+
p = self._edb_object.GetPortPostProcessingProp()
|
|
93
|
+
p.DoDeembed = value
|
|
94
|
+
self._edb_object.SetPortPostProcessingProp(p)
|
|
95
|
+
|
|
96
|
+
@property
|
|
97
|
+
def deembed_length(self):
|
|
98
|
+
"""Deembed Length."""
|
|
99
|
+
return self._edb_object.GetPortPostProcessingProp().DeembedLength.ToDouble()
|
|
100
|
+
|
|
101
|
+
@deembed_length.setter
|
|
102
|
+
def deembed_length(self, value):
|
|
103
|
+
p = self._edb_object.GetPortPostProcessingProp()
|
|
104
|
+
p.DeembedLength = self._pedb.edb_value(value)
|
|
105
|
+
self._edb_object.SetPortPostProcessingProp(p)
|
|
@@ -820,12 +820,13 @@ class Components(object):
|
|
|
820
820
|
if not port_name:
|
|
821
821
|
port_name = "Port_{}_{}".format(pins[0].net_name, pins[0].name)
|
|
822
822
|
|
|
823
|
-
if len(pins) > 1
|
|
824
|
-
pec_boundary
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
823
|
+
if len(pins) > 1 or pingroup_on_single_pin:
|
|
824
|
+
if pec_boundary:
|
|
825
|
+
pec_boundary = False
|
|
826
|
+
self._logger.info(
|
|
827
|
+
"Disabling PEC boundary creation, this feature is supported on single pin "
|
|
828
|
+
f"ports only, {len(pins)} pins found (pingroup_on_single_pin: {pingroup_on_single_pin})."
|
|
829
|
+
)
|
|
829
830
|
group_name = "group_{}".format(port_name)
|
|
830
831
|
pin_group = self.create_pingroup_from_pins(pins, group_name)
|
|
831
832
|
term = self._create_pin_group_terminal(pingroup=pin_group, term_name=port_name)
|
|
@@ -834,12 +835,13 @@ class Components(object):
|
|
|
834
835
|
term.SetIsCircuitPort(True)
|
|
835
836
|
|
|
836
837
|
if len(reference_pins) > 1 or pingroup_on_single_pin:
|
|
837
|
-
pec_boundary
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
838
|
+
if pec_boundary:
|
|
839
|
+
pec_boundary = False
|
|
840
|
+
self._logger.info(
|
|
841
|
+
"Disabling PEC boundary creation. This feature is supported on single pin "
|
|
842
|
+
f"ports only, {len(reference_pins)} reference pins found "
|
|
843
|
+
f"(pingroup_on_single_pin: {pingroup_on_single_pin})."
|
|
844
|
+
)
|
|
843
845
|
ref_group_name = "group_{}_ref".format(port_name)
|
|
844
846
|
ref_pin_group = self.create_pingroup_from_pins(reference_pins, ref_group_name)
|
|
845
847
|
ref_term = self._create_pin_group_terminal(pingroup=ref_pin_group, term_name=port_name + "_ref")
|
|
@@ -117,61 +117,6 @@ class WavePort(EdgeTerminal):
|
|
|
117
117
|
def __init__(self, pedb, edb_terminal):
|
|
118
118
|
super().__init__(pedb, edb_terminal)
|
|
119
119
|
|
|
120
|
-
@property
|
|
121
|
-
def horizontal_extent_factor(self):
|
|
122
|
-
"""Horizontal extent factor."""
|
|
123
|
-
return self._hfss_port_property["Horizontal Extent Factor"]
|
|
124
|
-
|
|
125
|
-
@horizontal_extent_factor.setter
|
|
126
|
-
def horizontal_extent_factor(self, value):
|
|
127
|
-
p = self._hfss_port_property
|
|
128
|
-
p["Horizontal Extent Factor"] = value
|
|
129
|
-
self._hfss_port_property = p
|
|
130
|
-
|
|
131
|
-
@property
|
|
132
|
-
def vertical_extent_factor(self):
|
|
133
|
-
"""Vertical extent factor."""
|
|
134
|
-
return self._hfss_port_property["Vertical Extent Factor"]
|
|
135
|
-
|
|
136
|
-
@vertical_extent_factor.setter
|
|
137
|
-
def vertical_extent_factor(self, value):
|
|
138
|
-
p = self._hfss_port_property
|
|
139
|
-
p["Vertical Extent Factor"] = value
|
|
140
|
-
self._hfss_port_property = p
|
|
141
|
-
|
|
142
|
-
@property
|
|
143
|
-
def pec_launch_width(self):
|
|
144
|
-
"""Launch width for the printed electronic component (PEC)."""
|
|
145
|
-
return self._hfss_port_property["PEC Launch Width"]
|
|
146
|
-
|
|
147
|
-
@pec_launch_width.setter
|
|
148
|
-
def pec_launch_width(self, value):
|
|
149
|
-
p = self._hfss_port_property
|
|
150
|
-
p["PEC Launch Width"] = value
|
|
151
|
-
self._hfss_port_property = p
|
|
152
|
-
|
|
153
|
-
@property
|
|
154
|
-
def deembed(self):
|
|
155
|
-
"""Whether deembed is active."""
|
|
156
|
-
return self._edb_object.GetPortPostProcessingProp().DoDeembed
|
|
157
|
-
|
|
158
|
-
@deembed.setter
|
|
159
|
-
def deembed(self, value):
|
|
160
|
-
p = self._edb_object.GetPortPostProcessingProp()
|
|
161
|
-
p.DoDeembed = value
|
|
162
|
-
self._edb_object.SetPortPostProcessingProp(p)
|
|
163
|
-
|
|
164
|
-
@property
|
|
165
|
-
def deembed_length(self):
|
|
166
|
-
"""Deembed Length."""
|
|
167
|
-
return self._edb_object.GetPortPostProcessingProp().DeembedLength.ToDouble()
|
|
168
|
-
|
|
169
|
-
@deembed_length.setter
|
|
170
|
-
def deembed_length(self, value):
|
|
171
|
-
p = self._edb_object.GetPortPostProcessingProp()
|
|
172
|
-
p.DeembedLength = self._pedb.edb_value(value)
|
|
173
|
-
self._edb_object.SetPortPostProcessingProp(p)
|
|
174
|
-
|
|
175
120
|
|
|
176
121
|
class ExcitationSources(Terminal):
|
|
177
122
|
"""Manage sources properties.
|
|
@@ -446,6 +446,33 @@ class Material(object):
|
|
|
446
446
|
class Materials(object):
|
|
447
447
|
"""Manages EDB methods for material management accessible from `Edb.materials` property."""
|
|
448
448
|
|
|
449
|
+
default_conductor_property_values = {
|
|
450
|
+
"conductivity": 58000000,
|
|
451
|
+
"dielectric_loss_tangent": 0,
|
|
452
|
+
"magnetic_loss_tangent": 0,
|
|
453
|
+
"mass_density": 8933,
|
|
454
|
+
"permittivity": 1,
|
|
455
|
+
"permeability": 0.999991,
|
|
456
|
+
"poisson_ratio": 0.38,
|
|
457
|
+
"specific_heat": 385,
|
|
458
|
+
"thermal_conductivity": 400,
|
|
459
|
+
"youngs_modulus": 120000000000,
|
|
460
|
+
"thermal_expansion_coefficient": 1.77e-05,
|
|
461
|
+
}
|
|
462
|
+
default_dielectric_property_values = {
|
|
463
|
+
"conductivity": 0,
|
|
464
|
+
"dielectric_loss_tangent": 0.02,
|
|
465
|
+
"magnetic_loss_tangent": 0,
|
|
466
|
+
"mass_density": 1900,
|
|
467
|
+
"permittivity": 4.4,
|
|
468
|
+
"permeability": 1,
|
|
469
|
+
"poisson_ratio": 0.28,
|
|
470
|
+
"specific_heat": 1150,
|
|
471
|
+
"thermal_conductivity": 0.294,
|
|
472
|
+
"youngs_modulus": 11000000000,
|
|
473
|
+
"thermal_expansion_coefficient": 1.5e-05,
|
|
474
|
+
}
|
|
475
|
+
|
|
449
476
|
def __init__(self, edb: Edb):
|
|
450
477
|
self.__edb = edb
|
|
451
478
|
self.__edb_definition = edb.edb_api.definition
|
|
@@ -520,14 +547,14 @@ class Materials(object):
|
|
|
520
547
|
|
|
521
548
|
return material
|
|
522
549
|
|
|
523
|
-
def add_conductor_material(self, name, conductivity, **kwargs):
|
|
550
|
+
def add_conductor_material(self, name, conductivity=58000000, **kwargs):
|
|
524
551
|
"""Add a new conductor material.
|
|
525
552
|
|
|
526
553
|
Parameters
|
|
527
554
|
----------
|
|
528
555
|
name : str
|
|
529
556
|
Name of the new material.
|
|
530
|
-
conductivity : str, float, int
|
|
557
|
+
conductivity : str, float, int, optional
|
|
531
558
|
Conductivity of the new material.
|
|
532
559
|
|
|
533
560
|
Returns
|
|
@@ -535,10 +562,11 @@ class Materials(object):
|
|
|
535
562
|
:class:`pyedb.dotnet.database.materials.Material`
|
|
536
563
|
|
|
537
564
|
"""
|
|
565
|
+
props = self.default_conductor_property_values.copy()
|
|
566
|
+
props["conductivity"] = conductivity
|
|
538
567
|
extended_kwargs = {key: value for (key, value) in kwargs.items()}
|
|
539
|
-
extended_kwargs
|
|
540
|
-
material = self.add_material(name, **
|
|
541
|
-
|
|
568
|
+
props.update(extended_kwargs)
|
|
569
|
+
material = self.add_material(name, **props)
|
|
542
570
|
return material
|
|
543
571
|
|
|
544
572
|
def add_dielectric_material(self, name, permittivity, dielectric_loss_tangent, **kwargs):
|
|
@@ -548,20 +576,21 @@ class Materials(object):
|
|
|
548
576
|
----------
|
|
549
577
|
name : str
|
|
550
578
|
Name of the new material.
|
|
551
|
-
permittivity : str, float, int
|
|
579
|
+
permittivity : str, float, int, optional
|
|
552
580
|
Permittivity of the new material.
|
|
553
|
-
dielectric_loss_tangent : str, float, int
|
|
581
|
+
dielectric_loss_tangent : str, float, int, optional
|
|
554
582
|
Dielectric loss tangent of the new material.
|
|
555
583
|
|
|
556
584
|
Returns
|
|
557
585
|
-------
|
|
558
586
|
:class:`pyedb.dotnet.database.materials.Material`
|
|
559
587
|
"""
|
|
588
|
+
props = self.default_dielectric_property_values.copy()
|
|
589
|
+
props["permittivity"] = permittivity
|
|
590
|
+
props["dielectric_loss_tangent"] = dielectric_loss_tangent
|
|
560
591
|
extended_kwargs = {key: value for (key, value) in kwargs.items()}
|
|
561
|
-
extended_kwargs
|
|
562
|
-
|
|
563
|
-
material = self.add_material(name, **extended_kwargs)
|
|
564
|
-
|
|
592
|
+
props.update(extended_kwargs)
|
|
593
|
+
material = self.add_material(name, **props)
|
|
565
594
|
return material
|
|
566
595
|
|
|
567
596
|
def add_djordjevicsarkar_dielectric(
|
pyedb/dotnet/database/modeler.py
CHANGED
|
@@ -307,9 +307,13 @@ class Modeler(object):
|
|
|
307
307
|
_obj_instances = list(self._pedb.layout_instance.FindLayoutObjInstance(pt, None, nets).Items)
|
|
308
308
|
returned_obj = []
|
|
309
309
|
if layer:
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
310
|
+
selected_prim = [
|
|
311
|
+
obj.GetLayoutObj()
|
|
312
|
+
for obj in _obj_instances
|
|
313
|
+
if layer in [lay.GetName() for lay in list(obj.GetLayers())]
|
|
314
|
+
and "Terminal" not in str(obj.GetLayoutObj())
|
|
315
|
+
]
|
|
316
|
+
for prim in selected_prim:
|
|
313
317
|
obj_id = prim.GetId()
|
|
314
318
|
prim_type = str(prim.GetPrimitiveType())
|
|
315
319
|
if prim_type == "Polygon":
|
|
@@ -321,7 +325,10 @@ class Modeler(object):
|
|
|
321
325
|
else:
|
|
322
326
|
for obj in _obj_instances:
|
|
323
327
|
obj_id = obj.GetLayoutObj().GetId()
|
|
324
|
-
[
|
|
328
|
+
[
|
|
329
|
+
returned_obj.append(Primitive(p, self._pedb))
|
|
330
|
+
for p in [obj for obj in self.primitives if obj.id == obj_id]
|
|
331
|
+
]
|
|
325
332
|
return returned_obj
|
|
326
333
|
|
|
327
334
|
def get_polygon_bounding_box(self, polygon):
|