pyedb 0.28.0__py3-none-any.whl → 0.30.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 +29 -3
- pyedb/configuration/cfg_boundaries.py +44 -74
- pyedb/configuration/cfg_common.py +1 -1
- pyedb/configuration/cfg_components.py +31 -105
- pyedb/configuration/cfg_data.py +4 -9
- pyedb/configuration/cfg_general.py +19 -8
- pyedb/configuration/cfg_operations.py +14 -10
- pyedb/configuration/cfg_padstacks.py +41 -61
- pyedb/configuration/cfg_ports_sources.py +4 -2
- pyedb/configuration/cfg_s_parameter_models.py +85 -29
- pyedb/configuration/cfg_setup.py +5 -0
- pyedb/configuration/cfg_stackup.py +2 -6
- pyedb/configuration/configuration.py +42 -9
- pyedb/dotnet/edb.py +116 -57
- pyedb/dotnet/edb_core/cell/hierarchy/component.py +202 -0
- pyedb/dotnet/edb_core/cell/layout.py +2 -13
- pyedb/dotnet/edb_core/cell/primitive/primitive.py +10 -2
- pyedb/dotnet/edb_core/cell/terminal/terminal.py +4 -3
- pyedb/dotnet/edb_core/components.py +1 -2
- pyedb/dotnet/edb_core/definition/component_def.py +17 -1
- pyedb/dotnet/edb_core/definition/component_model.py +0 -4
- pyedb/dotnet/edb_core/edb_data/hfss_extent_info.py +3 -3
- pyedb/dotnet/edb_core/edb_data/layer_data.py +95 -1
- pyedb/dotnet/edb_core/edb_data/nets_data.py +10 -7
- pyedb/dotnet/edb_core/edb_data/padstacks_data.py +67 -5
- pyedb/dotnet/edb_core/layout_validation.py +27 -4
- pyedb/dotnet/edb_core/nets.py +162 -181
- pyedb/dotnet/edb_core/padstack.py +0 -1
- pyedb/siwave.py +5 -1
- {pyedb-0.28.0.dist-info → pyedb-0.30.0.dist-info}/METADATA +3 -3
- {pyedb-0.28.0.dist-info → pyedb-0.30.0.dist-info}/RECORD +33 -33
- {pyedb-0.28.0.dist-info → pyedb-0.30.0.dist-info}/LICENSE +0 -0
- {pyedb-0.28.0.dist-info → pyedb-0.30.0.dist-info}/WHEEL +0 -0
|
@@ -33,6 +33,7 @@ from pyedb.dotnet.edb_core.cell.hierarchy.s_parameter_model import SparamModel
|
|
|
33
33
|
from pyedb.dotnet.edb_core.cell.hierarchy.spice_model import SpiceModel
|
|
34
34
|
from pyedb.dotnet.edb_core.definition.package_def import PackageDef
|
|
35
35
|
from pyedb.dotnet.edb_core.edb_data.padstacks_data import EDBPadstackInstance
|
|
36
|
+
from pyedb.dotnet.edb_core.general import pascal_to_snake, snake_to_pascal
|
|
36
37
|
|
|
37
38
|
try:
|
|
38
39
|
import numpy as np
|
|
@@ -1008,3 +1009,204 @@ class EDBComponent(Group):
|
|
|
1008
1009
|
)
|
|
1009
1010
|
void.is_negative = True
|
|
1010
1011
|
return True
|
|
1012
|
+
|
|
1013
|
+
@property
|
|
1014
|
+
def model_properties(self):
|
|
1015
|
+
pp = {}
|
|
1016
|
+
c_p = self.component_property
|
|
1017
|
+
model = c_p.GetModel().Clone()
|
|
1018
|
+
netlist_model = {}
|
|
1019
|
+
pin_pair_model = []
|
|
1020
|
+
s_parameter_model = {}
|
|
1021
|
+
spice_model = {}
|
|
1022
|
+
if model.GetModelType().ToString() == "NetlistModel":
|
|
1023
|
+
netlist_model["netlist"] = model.GetNetlist()
|
|
1024
|
+
elif model.GetModelType().ToString() == "PinPairModel":
|
|
1025
|
+
temp = {}
|
|
1026
|
+
for i in model.PinPairs:
|
|
1027
|
+
temp["first_pin"] = i.FirstPin
|
|
1028
|
+
temp["second_pin"] = i.SecondPin
|
|
1029
|
+
rlc = model.GetPinPairRlc(i)
|
|
1030
|
+
temp["is_parallel"] = rlc.IsParallel
|
|
1031
|
+
temp["resistance"] = rlc.R.ToString()
|
|
1032
|
+
temp["resistance_enabled"] = rlc.REnabled
|
|
1033
|
+
temp["inductance"] = rlc.L.ToString()
|
|
1034
|
+
temp["inductance_enabled"] = rlc.LEnabled
|
|
1035
|
+
temp["capacitance"] = rlc.C.ToString()
|
|
1036
|
+
temp["capacitance_enabled"] = rlc.CEnabled
|
|
1037
|
+
pin_pair_model.append(temp)
|
|
1038
|
+
elif model.GetModelType().ToString() == "SParameterModel":
|
|
1039
|
+
s_parameter_model["reference_net"] = model.GetReferenceNet()
|
|
1040
|
+
s_parameter_model["model_name"] = model.GetComponentModelName()
|
|
1041
|
+
elif model.GetModelType().ToString() == "SPICEModel":
|
|
1042
|
+
spice_model["model_name"] = model.GetModelName()
|
|
1043
|
+
spice_model["model_path"] = model.GetModelPath()
|
|
1044
|
+
spice_model["sub_circuit"] = model.GetSubCkt()
|
|
1045
|
+
spice_model["terminal_pairs"] = [[i, j] for i, j in dict(model.GetTerminalPinPairs()).items()]
|
|
1046
|
+
|
|
1047
|
+
if netlist_model:
|
|
1048
|
+
pp["netlist_model"] = netlist_model
|
|
1049
|
+
if pin_pair_model:
|
|
1050
|
+
pp["pin_pair_model"] = pin_pair_model
|
|
1051
|
+
if s_parameter_model:
|
|
1052
|
+
pp["s_parameter_model"] = s_parameter_model
|
|
1053
|
+
if spice_model:
|
|
1054
|
+
pp["spice_model"] = spice_model
|
|
1055
|
+
return pp
|
|
1056
|
+
|
|
1057
|
+
@model_properties.setter
|
|
1058
|
+
def model_properties(self, kwargs):
|
|
1059
|
+
netlist_model = kwargs.get("netlist_model")
|
|
1060
|
+
pin_pair_model = kwargs.get("pin_pair_model")
|
|
1061
|
+
s_parameter_model = kwargs.get("s_parameter_model")
|
|
1062
|
+
spice_model = kwargs.get("spice_model")
|
|
1063
|
+
|
|
1064
|
+
c_p = self.component_property
|
|
1065
|
+
if netlist_model:
|
|
1066
|
+
m = self._pedb._edb.Cell.Hierarchy.SParameterModel()
|
|
1067
|
+
m.SetNetlist(netlist_model["netlist"])
|
|
1068
|
+
c_p.SetModel(m)
|
|
1069
|
+
self.component_property = c_p
|
|
1070
|
+
elif pin_pair_model:
|
|
1071
|
+
m = self._pedb._edb.Cell.Hierarchy.PinPairModel()
|
|
1072
|
+
for i in pin_pair_model:
|
|
1073
|
+
p = self._pedb._edb.Utility.PinPair(str(i["first_pin"]), str(i["second_pin"]))
|
|
1074
|
+
rlc = self._pedb._edb.Utility.Rlc(
|
|
1075
|
+
self._pedb.edb_value(i["resistance"]),
|
|
1076
|
+
i["resistance_enabled"],
|
|
1077
|
+
self._pedb.edb_value(i["inductance"]),
|
|
1078
|
+
i["inductance_enabled"],
|
|
1079
|
+
self._pedb.edb_value(i["capacitance"]),
|
|
1080
|
+
i["capacitance_enabled"],
|
|
1081
|
+
i["is_parallel"],
|
|
1082
|
+
)
|
|
1083
|
+
m.SetPinPairRlc(p, rlc)
|
|
1084
|
+
c_p.SetModel(m)
|
|
1085
|
+
self.component_property = c_p
|
|
1086
|
+
elif s_parameter_model:
|
|
1087
|
+
m = self._pedb._edb.Cell.Hierarchy.SParameterModel()
|
|
1088
|
+
m.SetComponentModelName(s_parameter_model["model_name"])
|
|
1089
|
+
m.SetReferenceNet(s_parameter_model["reference_net"])
|
|
1090
|
+
c_p.SetModel(m)
|
|
1091
|
+
self.component_property = c_p
|
|
1092
|
+
elif spice_model:
|
|
1093
|
+
self.assign_spice_model(
|
|
1094
|
+
spice_model["model_path"],
|
|
1095
|
+
spice_model["model_name"],
|
|
1096
|
+
spice_model["sub_circuit"],
|
|
1097
|
+
spice_model["terminal_pairs"],
|
|
1098
|
+
)
|
|
1099
|
+
|
|
1100
|
+
@property
|
|
1101
|
+
def ic_die_properties(self):
|
|
1102
|
+
temp = dict()
|
|
1103
|
+
cp = self.component_property
|
|
1104
|
+
c_type = self.type.lower()
|
|
1105
|
+
if not c_type == "ic":
|
|
1106
|
+
return temp
|
|
1107
|
+
else:
|
|
1108
|
+
ic_die_prop = cp.GetDieProperty().Clone()
|
|
1109
|
+
die_type = pascal_to_snake(ic_die_prop.GetType().ToString())
|
|
1110
|
+
temp["type"] = die_type
|
|
1111
|
+
if not die_type == "no_die":
|
|
1112
|
+
temp["orientation"] = pascal_to_snake(ic_die_prop.GetOrientation().ToString())
|
|
1113
|
+
if die_type == "wire_bond":
|
|
1114
|
+
temp["height"] = ic_die_prop.GetHeightValue().ToString()
|
|
1115
|
+
return temp
|
|
1116
|
+
|
|
1117
|
+
@ic_die_properties.setter
|
|
1118
|
+
def ic_die_properties(self, kwargs):
|
|
1119
|
+
cp = self.component_property
|
|
1120
|
+
c_type = self.type.lower()
|
|
1121
|
+
if not c_type == "ic":
|
|
1122
|
+
return
|
|
1123
|
+
else:
|
|
1124
|
+
ic_die_prop = cp.GetDieProperty().Clone()
|
|
1125
|
+
die_type = kwargs.get("type")
|
|
1126
|
+
ic_die_prop.SetType(getattr(self._edb.definition.DieType, snake_to_pascal(die_type)))
|
|
1127
|
+
if not die_type == "no_die":
|
|
1128
|
+
orientation = kwargs.get("orientation")
|
|
1129
|
+
if orientation:
|
|
1130
|
+
ic_die_prop.SetOrientation(
|
|
1131
|
+
getattr(self._edb.definition.DieOrientation, snake_to_pascal(orientation))
|
|
1132
|
+
)
|
|
1133
|
+
if die_type == "wire_bond":
|
|
1134
|
+
height = kwargs.get("height")
|
|
1135
|
+
if height:
|
|
1136
|
+
ic_die_prop.SetHeight(self._pedb.edb_value(height))
|
|
1137
|
+
cp.SetDieProperty(ic_die_prop)
|
|
1138
|
+
self.component_property = cp
|
|
1139
|
+
|
|
1140
|
+
@property
|
|
1141
|
+
def solder_ball_properties(self):
|
|
1142
|
+
temp = dict()
|
|
1143
|
+
cp = self.component_property
|
|
1144
|
+
c_type = self.type.lower()
|
|
1145
|
+
if c_type not in ["io", "other"]:
|
|
1146
|
+
return temp
|
|
1147
|
+
else:
|
|
1148
|
+
solder_ball_prop = cp.GetSolderBallProperty().Clone()
|
|
1149
|
+
_, diam, mid_diam = solder_ball_prop.GetDiameterValue()
|
|
1150
|
+
height = solder_ball_prop.GetHeightValue().ToString()
|
|
1151
|
+
shape = solder_ball_prop.GetShape().ToString()
|
|
1152
|
+
uses_solder_ball = solder_ball_prop.UsesSolderball()
|
|
1153
|
+
temp["uses_solder_ball"] = uses_solder_ball
|
|
1154
|
+
temp["shape"] = pascal_to_snake(shape)
|
|
1155
|
+
temp["diameter"] = diam.ToString()
|
|
1156
|
+
temp["mid_diameter"] = mid_diam.ToString()
|
|
1157
|
+
temp["height"] = height
|
|
1158
|
+
return temp
|
|
1159
|
+
|
|
1160
|
+
@solder_ball_properties.setter
|
|
1161
|
+
def solder_ball_properties(self, kwargs):
|
|
1162
|
+
cp = self.component_property
|
|
1163
|
+
solder_ball_prop = cp.GetSolderBallProperty().Clone()
|
|
1164
|
+
shape = kwargs.get("shape")
|
|
1165
|
+
if shape:
|
|
1166
|
+
solder_ball_prop.SetShape(getattr(self._edb.definition.SolderballShape, snake_to_pascal(shape)))
|
|
1167
|
+
if shape == "cylinder":
|
|
1168
|
+
diameter = kwargs["diameter"]
|
|
1169
|
+
solder_ball_prop.SetDiameter(self._pedb.edb_value(diameter), self._pedb.edb_value(diameter))
|
|
1170
|
+
elif shape == "spheroid":
|
|
1171
|
+
diameter = kwargs["diameter"]
|
|
1172
|
+
mid_diameter = kwargs["mid_diameter"]
|
|
1173
|
+
solder_ball_prop.SetDiameter(self._pedb.edb_value(diameter), self._pedb.edb_value(mid_diameter))
|
|
1174
|
+
else:
|
|
1175
|
+
return
|
|
1176
|
+
solder_ball_prop.SetHeight(self._get_edb_value(kwargs["height"]))
|
|
1177
|
+
cp.SetSolderBallProperty(solder_ball_prop)
|
|
1178
|
+
self.component_property = cp
|
|
1179
|
+
|
|
1180
|
+
@property
|
|
1181
|
+
def port_properties(self):
|
|
1182
|
+
temp = dict()
|
|
1183
|
+
cp = self.component_property
|
|
1184
|
+
c_type = self.type.lower()
|
|
1185
|
+
if c_type not in ["ic", "io", "other"]:
|
|
1186
|
+
return temp
|
|
1187
|
+
else:
|
|
1188
|
+
port_prop = cp.GetPortProperty().Clone()
|
|
1189
|
+
reference_height = port_prop.GetReferenceHeightValue().ToString()
|
|
1190
|
+
reference_size_auto = port_prop.GetReferenceSizeAuto()
|
|
1191
|
+
_, reference_size_x, reference_size_y = port_prop.GetReferenceSize()
|
|
1192
|
+
temp["reference_height"] = reference_height
|
|
1193
|
+
temp["reference_size_auto"] = reference_size_auto
|
|
1194
|
+
temp["reference_size_x"] = str(reference_size_x)
|
|
1195
|
+
temp["reference_size_y"] = str(reference_size_y)
|
|
1196
|
+
return temp
|
|
1197
|
+
|
|
1198
|
+
@port_properties.setter
|
|
1199
|
+
def port_properties(self, kwargs):
|
|
1200
|
+
cp = self.component_property
|
|
1201
|
+
port_prop = cp.GetPortProperty().Clone()
|
|
1202
|
+
height = kwargs.get("reference_height")
|
|
1203
|
+
if height:
|
|
1204
|
+
port_prop.SetReferenceHeight(self._pedb.edb_value(height))
|
|
1205
|
+
reference_size_auto = kwargs.get("reference_size_auto")
|
|
1206
|
+
if reference_size_auto:
|
|
1207
|
+
port_prop.SetReferenceSizeAuto(reference_size_auto)
|
|
1208
|
+
reference_size_x = kwargs.get("reference_size_x", 0)
|
|
1209
|
+
reference_size_y = kwargs.get("reference_size_y", 0)
|
|
1210
|
+
port_prop.SetReferenceSize(self._pedb.edb_value(reference_size_x), self._pedb.edb_value(reference_size_y))
|
|
1211
|
+
cp.SetPortProperty(port_prop)
|
|
1212
|
+
self.component_property = cp
|
|
@@ -230,11 +230,7 @@ class Layout(ObjBase):
|
|
|
230
230
|
-------
|
|
231
231
|
list of :class:`dotnet.edb_core.dotnet.primitive.PrimitiveDotNet` cast objects.
|
|
232
232
|
"""
|
|
233
|
-
|
|
234
|
-
for p in self._edb_object.Primitives:
|
|
235
|
-
obj = primitive_cast(self._pedb, p)
|
|
236
|
-
prims.append(obj)
|
|
237
|
-
return prims
|
|
233
|
+
return [primitive_cast(self._pedb, p) for p in self._edb_object.Primitives]
|
|
238
234
|
|
|
239
235
|
@property
|
|
240
236
|
def bondwires(self):
|
|
@@ -249,14 +245,7 @@ class Layout(ObjBase):
|
|
|
249
245
|
|
|
250
246
|
@property
|
|
251
247
|
def groups(self):
|
|
252
|
-
|
|
253
|
-
for i in list(self._edb_object.Groups):
|
|
254
|
-
group_type = i.ToString().split(".")[-1].lower()
|
|
255
|
-
if group_type == "component":
|
|
256
|
-
temp.append(EDBComponent(self._pedb, i))
|
|
257
|
-
else:
|
|
258
|
-
pass
|
|
259
|
-
return temp
|
|
248
|
+
return [EDBComponent(self._pedb, i) for i in self._edb_object.Groups if i.ToString().endswith(".Component")]
|
|
260
249
|
|
|
261
250
|
@property
|
|
262
251
|
def pin_groups(self):
|
|
@@ -43,8 +43,6 @@ class Primitive(Connectable):
|
|
|
43
43
|
def __init__(self, pedb, edb_object):
|
|
44
44
|
super().__init__(pedb, edb_object)
|
|
45
45
|
self._app = self._pedb
|
|
46
|
-
self._core_stackup = pedb.stackup
|
|
47
|
-
self._core_net = pedb.nets
|
|
48
46
|
self.primitive_object = self._edb_object
|
|
49
47
|
|
|
50
48
|
bondwire_type = self._pedb._edb.Cell.Primitive.BondwireType
|
|
@@ -62,6 +60,14 @@ class Primitive(Connectable):
|
|
|
62
60
|
"rectangle": bondwire_cross_section_type.BondwireRectangle,
|
|
63
61
|
}
|
|
64
62
|
|
|
63
|
+
@property
|
|
64
|
+
def _core_stackup(self):
|
|
65
|
+
return self._app.stackup
|
|
66
|
+
|
|
67
|
+
@property
|
|
68
|
+
def _core_net(self):
|
|
69
|
+
return self._app.nets
|
|
70
|
+
|
|
65
71
|
@property
|
|
66
72
|
def type(self):
|
|
67
73
|
"""Return the type of the primitive.
|
|
@@ -160,6 +166,8 @@ class Primitive(Connectable):
|
|
|
160
166
|
-------
|
|
161
167
|
float
|
|
162
168
|
"""
|
|
169
|
+
if "GetPolygonData" not in dir(self._edb_object):
|
|
170
|
+
return 0
|
|
163
171
|
area = self._edb_object.GetPolygonData().Area()
|
|
164
172
|
if include_voids:
|
|
165
173
|
for el in self._edb_object.Voids:
|
|
@@ -223,9 +223,10 @@ class Terminal(Connectable):
|
|
|
223
223
|
"""Get reference terminal."""
|
|
224
224
|
|
|
225
225
|
edb_terminal = self._edb_object.GetReferenceTerminal()
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
226
|
+
if not edb_terminal.IsNull():
|
|
227
|
+
return self._pedb.terminals[edb_terminal.GetName()]
|
|
228
|
+
else:
|
|
229
|
+
return None
|
|
229
230
|
|
|
230
231
|
@ref_terminal.setter
|
|
231
232
|
def ref_terminal(self, value):
|
|
@@ -313,8 +313,7 @@ class Components(object):
|
|
|
313
313
|
# self._logger.info("Refreshing the Components dictionary.")
|
|
314
314
|
self._cmp = {}
|
|
315
315
|
for i in self._pedb.layout.groups:
|
|
316
|
-
|
|
317
|
-
self._cmp[i.name] = i
|
|
316
|
+
self._cmp[i.name] = i
|
|
318
317
|
return True
|
|
319
318
|
|
|
320
319
|
@property
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
import os
|
|
24
24
|
|
|
25
25
|
from pyedb.dotnet.edb_core.definition.component_model import NPortComponentModel
|
|
26
|
+
from pyedb.dotnet.edb_core.general import convert_py_list_to_net_list
|
|
26
27
|
from pyedb.dotnet.edb_core.utilities.obj_base import ObjBase
|
|
27
28
|
|
|
28
29
|
|
|
@@ -171,7 +172,7 @@ class EDBComponentDef(ObjBase):
|
|
|
171
172
|
def component_models(self):
|
|
172
173
|
temp = {}
|
|
173
174
|
for i in list(self._edb_object.GetComponentModels()):
|
|
174
|
-
temp_type = i.ToString().split(".")[
|
|
175
|
+
temp_type = i.ToString().split(".")[-1]
|
|
175
176
|
if temp_type == "NPortComponentModel":
|
|
176
177
|
edb_object = NPortComponentModel(self._pedb, i)
|
|
177
178
|
temp[edb_object.name] = edb_object
|
|
@@ -197,3 +198,18 @@ class EDBComponentDef(ObjBase):
|
|
|
197
198
|
footprint_cell = self._pedb._active_cell.cell.Create(self._pedb.active_db, cell_type, name)
|
|
198
199
|
edb_object = self._pedb.edb_api.definition.ComponentDef.Create(self._pedb.active_db, name, footprint_cell)
|
|
199
200
|
return EDBComponentDef(self._pedb, edb_object)
|
|
201
|
+
|
|
202
|
+
def get_properties(self):
|
|
203
|
+
data = {}
|
|
204
|
+
temp = []
|
|
205
|
+
for i in list(self._edb_object.ComponentDefPins):
|
|
206
|
+
temp.append(i.GetName())
|
|
207
|
+
data["pin_order"] = temp
|
|
208
|
+
return data
|
|
209
|
+
|
|
210
|
+
def set_properties(self, **kwargs):
|
|
211
|
+
pin_order = kwargs.get("pin_order")
|
|
212
|
+
if pin_order:
|
|
213
|
+
old = {i.GetName(): i for i in list(self._edb_object.ComponentDefPins)}
|
|
214
|
+
temp = convert_py_list_to_net_list([old[str(i)] for i in pin_order])
|
|
215
|
+
self._edb_object.ReorderPins(temp)
|
|
@@ -30,10 +30,6 @@ class ComponentModel(ObjBase):
|
|
|
30
30
|
super().__init__(pedb, edb_object)
|
|
31
31
|
self._model_type_mapping = {"PinPairModel": self._pedb.edb_api.cell}
|
|
32
32
|
|
|
33
|
-
def name(self):
|
|
34
|
-
"""Name of the component model."""
|
|
35
|
-
return self._edb_object.GetName()
|
|
36
|
-
|
|
37
33
|
|
|
38
34
|
class NPortComponentModel(ComponentModel):
|
|
39
35
|
"""Class for n-port component models."""
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
|
|
23
23
|
from pyedb.dotnet.edb_core.edb_data.edbvalue import EdbValue
|
|
24
24
|
from pyedb.dotnet.edb_core.edb_data.primitives_data import cast
|
|
25
|
-
from pyedb.dotnet.edb_core.general import convert_pytuple_to_nettuple
|
|
25
|
+
from pyedb.dotnet.edb_core.general import convert_pytuple_to_nettuple, pascal_to_snake
|
|
26
26
|
|
|
27
27
|
|
|
28
28
|
class HfssExtentInfo:
|
|
@@ -192,7 +192,7 @@ class HfssExtentInfo:
|
|
|
192
192
|
@property
|
|
193
193
|
def dielectric_extent_type(self):
|
|
194
194
|
"""Dielectric extent type."""
|
|
195
|
-
return self._edb_hfss_extent_info.DielectricExtentType.ToString()
|
|
195
|
+
return pascal_to_snake(self._edb_hfss_extent_info.DielectricExtentType.ToString())
|
|
196
196
|
|
|
197
197
|
@dielectric_extent_type.setter
|
|
198
198
|
def dielectric_extent_type(self, value):
|
|
@@ -204,7 +204,7 @@ class HfssExtentInfo:
|
|
|
204
204
|
@property
|
|
205
205
|
def extent_type(self):
|
|
206
206
|
"""Extent type."""
|
|
207
|
-
return self._edb_hfss_extent_info.ExtentType.ToString()
|
|
207
|
+
return pascal_to_snake(self._edb_hfss_extent_info.ExtentType.ToString())
|
|
208
208
|
|
|
209
209
|
@extent_type.setter
|
|
210
210
|
def extent_type(self, value):
|
|
@@ -58,6 +58,8 @@ class LayerEdbClass(object):
|
|
|
58
58
|
for k, v in kwargs.items():
|
|
59
59
|
if k in dir(self):
|
|
60
60
|
self.__setattr__(k, v)
|
|
61
|
+
elif k == "roughness":
|
|
62
|
+
self.properties = {"roughness": v}
|
|
61
63
|
else:
|
|
62
64
|
self._pedb.logger.error(f"{k} is not a valid layer attribute")
|
|
63
65
|
|
|
@@ -178,7 +180,7 @@ class LayerEdbClass(object):
|
|
|
178
180
|
RGB.
|
|
179
181
|
"""
|
|
180
182
|
layer_color = self._edb_layer.GetColor()
|
|
181
|
-
return layer_color.Item1, layer_color.Item2, layer_color.Item3
|
|
183
|
+
return [layer_color.Item1, layer_color.Item2, layer_color.Item3]
|
|
182
184
|
|
|
183
185
|
@color.setter
|
|
184
186
|
def color(self, rgb):
|
|
@@ -238,6 +240,26 @@ class LayerEdbClass(object):
|
|
|
238
240
|
self._type = value
|
|
239
241
|
self._pedb.stackup._set_layout_stackup(layer_clone, "change_attribute")
|
|
240
242
|
|
|
243
|
+
@property
|
|
244
|
+
def properties(self):
|
|
245
|
+
data = {}
|
|
246
|
+
data["name"] = self.name
|
|
247
|
+
data["type"] = self.type
|
|
248
|
+
data["color"] = self.color
|
|
249
|
+
return data
|
|
250
|
+
|
|
251
|
+
@properties.setter
|
|
252
|
+
def properties(self, params):
|
|
253
|
+
name = params.get("name", "")
|
|
254
|
+
if name:
|
|
255
|
+
self.name = name
|
|
256
|
+
type = params.get("type", "")
|
|
257
|
+
if type:
|
|
258
|
+
self.type = type
|
|
259
|
+
color = params.get("color", "")
|
|
260
|
+
if color:
|
|
261
|
+
self.color = color
|
|
262
|
+
|
|
241
263
|
|
|
242
264
|
class StackupLayerEdbClass(LayerEdbClass):
|
|
243
265
|
def __init__(self, pedb, edb_object=None, name="", layer_type="signal", **kwargs):
|
|
@@ -705,3 +727,75 @@ class StackupLayerEdbClass(LayerEdbClass):
|
|
|
705
727
|
layer["side_hallhuray_surface_ratio"],
|
|
706
728
|
apply_on_surface="side",
|
|
707
729
|
)
|
|
730
|
+
|
|
731
|
+
@property
|
|
732
|
+
def properties(self):
|
|
733
|
+
data = {}
|
|
734
|
+
data["name"] = self.name
|
|
735
|
+
data["type"] = self.type
|
|
736
|
+
data["material"] = self.material
|
|
737
|
+
data["fill_material"] = self.fill_material
|
|
738
|
+
data["thickness"] = self._edb_object.GetThicknessValue().ToString()
|
|
739
|
+
data["color"] = self.color
|
|
740
|
+
|
|
741
|
+
roughness = {}
|
|
742
|
+
for region in ["top", "bottom", "side"]:
|
|
743
|
+
temp = {}
|
|
744
|
+
r_model = self._edb_object.GetRoughnessModel(
|
|
745
|
+
getattr(self._pedb._edb.Cell.RoughnessModel.Region, region.capitalize())
|
|
746
|
+
)
|
|
747
|
+
if r_model.ToString().split(".")[-1] == "HurrayRoughnessModel":
|
|
748
|
+
temp["model"] = "huray"
|
|
749
|
+
temp["nodule_radius"] = r_model.NoduleRadius.ToString()
|
|
750
|
+
temp["surface_ratio"] = r_model.SurfaceRatio.ToString()
|
|
751
|
+
else:
|
|
752
|
+
temp["model"] = "groisse"
|
|
753
|
+
temp["roughness"] = r_model.Roughness.ToString()
|
|
754
|
+
roughness[region] = temp
|
|
755
|
+
roughness["enabled"] = self._edb_object.IsRoughnessEnabled()
|
|
756
|
+
data["roughness"] = roughness
|
|
757
|
+
return data
|
|
758
|
+
|
|
759
|
+
@properties.setter
|
|
760
|
+
def properties(self, params):
|
|
761
|
+
name = params.get("name")
|
|
762
|
+
if name:
|
|
763
|
+
self.name = name
|
|
764
|
+
type = params.get("type")
|
|
765
|
+
if type:
|
|
766
|
+
self.type = type
|
|
767
|
+
material = params.get("material")
|
|
768
|
+
if material:
|
|
769
|
+
self.material = material
|
|
770
|
+
fill_material = params.get("fill_material")
|
|
771
|
+
if fill_material:
|
|
772
|
+
self.fill_material = fill_material
|
|
773
|
+
thickness = params.get("thickness")
|
|
774
|
+
if thickness:
|
|
775
|
+
self.thickness = self._pedb.edb_value(thickness)
|
|
776
|
+
color = params.get("color")
|
|
777
|
+
if color:
|
|
778
|
+
self.color = color
|
|
779
|
+
roughness = params.get("roughness")
|
|
780
|
+
if roughness:
|
|
781
|
+
layer_clone = self._edb_layer
|
|
782
|
+
layer_clone.SetRoughnessEnabled(roughness["enabled"])
|
|
783
|
+
for region in ["top", "bottom", "side"]:
|
|
784
|
+
r_data = roughness.get(region)
|
|
785
|
+
if r_data:
|
|
786
|
+
if r_data["model"] == "huray":
|
|
787
|
+
r_model = self._pedb._edb.Cell.HurrayRoughnessModel(
|
|
788
|
+
self._pedb.edb_value(r_data["nodule_radius"]), self._pedb.edb_value(r_data["surface_ratio"])
|
|
789
|
+
)
|
|
790
|
+
else:
|
|
791
|
+
r_model = self._pedb._edb.Cell.GroisseRoughnessModel(self._pedb.edb_value(r_data["roughness"]))
|
|
792
|
+
else:
|
|
793
|
+
r_model = self._pedb._edb.Cell.HurrayRoughnessModel(
|
|
794
|
+
self._pedb.edb_value("0"), self._pedb.edb_value("0")
|
|
795
|
+
)
|
|
796
|
+
layer_clone.SetRoughnessModel(
|
|
797
|
+
getattr(self._pedb._edb.Cell.RoughnessModel.Region, region.capitalize()), r_model
|
|
798
|
+
)
|
|
799
|
+
self._pedb.stackup._set_layout_stackup(layer_clone, "change_attribute")
|
|
800
|
+
|
|
801
|
+
layer_clone.SetRoughnessEnabled(True)
|
|
@@ -19,7 +19,6 @@
|
|
|
19
19
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
20
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
21
|
# SOFTWARE.
|
|
22
|
-
|
|
23
22
|
from pyedb.dotnet.edb_core.dotnet.database import (
|
|
24
23
|
DifferentialPairDotNet,
|
|
25
24
|
ExtendedNetDotNet,
|
|
@@ -58,7 +57,10 @@ class EDBNetsData(NetDotNet):
|
|
|
58
57
|
-------
|
|
59
58
|
list of :class:`pyedb.dotnet.edb_core.edb_data.primitives_data.EDBPrimitives`
|
|
60
59
|
"""
|
|
61
|
-
|
|
60
|
+
from pyedb.dotnet.edb_core.cell.layout import primitive_cast
|
|
61
|
+
|
|
62
|
+
return [primitive_cast(self._app, i) for i in self.net_object.Primitives]
|
|
63
|
+
# return [self._app.layout.find_object_by_id(i.GetId()) for i in self.net_object.Primitives]
|
|
62
64
|
|
|
63
65
|
@property
|
|
64
66
|
def padstack_instances(self):
|
|
@@ -67,10 +69,11 @@ class EDBNetsData(NetDotNet):
|
|
|
67
69
|
Returns
|
|
68
70
|
-------
|
|
69
71
|
list of :class:`pyedb.dotnet.edb_core.edb_data.padstacks_data.EDBPadstackInstance`"""
|
|
70
|
-
name = self.name
|
|
71
|
-
return [
|
|
72
|
-
|
|
73
|
-
]
|
|
72
|
+
# name = self.name
|
|
73
|
+
# return [
|
|
74
|
+
# EDBPadstackInstance(i, self._app) for i in self.net_object.PadstackInstances if i.GetNet().GetName() == name
|
|
75
|
+
# ]
|
|
76
|
+
return [EDBPadstackInstance(i, self._app) for i in self.net_object.PadstackInstances]
|
|
74
77
|
|
|
75
78
|
@property
|
|
76
79
|
def components(self):
|
|
@@ -133,7 +136,7 @@ class EDBNetsData(NetDotNet):
|
|
|
133
136
|
Whether to show the plot or not. Default is `True`.
|
|
134
137
|
"""
|
|
135
138
|
|
|
136
|
-
self._app.nets.plot(
|
|
139
|
+
return self._app.nets.plot(
|
|
137
140
|
self.name,
|
|
138
141
|
layers=layers,
|
|
139
142
|
show_legend=show_legend,
|
|
@@ -499,7 +499,8 @@ class EDBPadstack(object):
|
|
|
499
499
|
self._ppadstack._pedb._edb.Definition.PadType.RegularPad,
|
|
500
500
|
self._ppadstack._pedb._edb.Definition.PadType.AntiPad,
|
|
501
501
|
self._ppadstack._pedb._edb.Definition.PadType.ThermalPad,
|
|
502
|
-
self._ppadstack._pedb._edb.Definition.PadType.Hole,
|
|
502
|
+
# self._ppadstack._pedb._edb.Definition.PadType.Hole,
|
|
503
|
+
# This property doesn't appear in UI. It is unclear what it is used for. Suppressing this property for now.
|
|
503
504
|
]
|
|
504
505
|
data = {}
|
|
505
506
|
for pad_type in pad_type_list:
|
|
@@ -588,15 +589,14 @@ class EDBPadstack(object):
|
|
|
588
589
|
continue
|
|
589
590
|
|
|
590
591
|
# Set pad parameters for the current layer
|
|
591
|
-
default = original_params[pad_type_name]
|
|
592
592
|
pdef_data.SetPadParameters(
|
|
593
593
|
layer_data["layer_name"],
|
|
594
594
|
pad_type,
|
|
595
595
|
pad_shape,
|
|
596
596
|
convert_py_list_to_net_list([self._ppadstack._pedb.edb_value(i) for i in temp_param]),
|
|
597
|
-
self._ppadstack._pedb.edb_value(layer_data.get("offset_x",
|
|
598
|
-
self._ppadstack._pedb.edb_value(layer_data.get("offset_y",
|
|
599
|
-
self._ppadstack._pedb.edb_value(layer_data.get("rotation",
|
|
597
|
+
self._ppadstack._pedb.edb_value(layer_data.get("offset_x", 0)),
|
|
598
|
+
self._ppadstack._pedb.edb_value(layer_data.get("offset_y", 0)),
|
|
599
|
+
self._ppadstack._pedb.edb_value(layer_data.get("rotation", 0)),
|
|
600
600
|
)
|
|
601
601
|
self._padstack_def_data = pdef_data
|
|
602
602
|
|
|
@@ -1672,6 +1672,56 @@ class EDBPadstackInstance(Primitive):
|
|
|
1672
1672
|
else:
|
|
1673
1673
|
return
|
|
1674
1674
|
|
|
1675
|
+
@property
|
|
1676
|
+
def backdrill_parameters(self):
|
|
1677
|
+
data = {}
|
|
1678
|
+
flag, drill_to_layer, offset, diameter = self._edb_object.GetBackDrillParametersLayerValue(
|
|
1679
|
+
self._pedb.edb_api.cell.layer("", self._pedb.edb_api.cell.layer_type.SignalLayer),
|
|
1680
|
+
self._pedb.edb_value(0),
|
|
1681
|
+
self._pedb.edb_value(0.0),
|
|
1682
|
+
True,
|
|
1683
|
+
)
|
|
1684
|
+
if flag:
|
|
1685
|
+
if drill_to_layer.GetName():
|
|
1686
|
+
data["from_bottom"] = {
|
|
1687
|
+
"drill_to_layer": drill_to_layer.GetName(),
|
|
1688
|
+
"diameter": diameter.ToString(),
|
|
1689
|
+
"stub_length": offset.ToString(),
|
|
1690
|
+
}
|
|
1691
|
+
flag, drill_to_layer, offset, diameter = self._edb_object.GetBackDrillParametersLayerValue(
|
|
1692
|
+
self._pedb.edb_api.cell.layer("", self._pedb.edb_api.cell.layer_type.SignalLayer),
|
|
1693
|
+
self._pedb.edb_value(0),
|
|
1694
|
+
self._pedb.edb_value(0.0),
|
|
1695
|
+
False,
|
|
1696
|
+
)
|
|
1697
|
+
if flag:
|
|
1698
|
+
if drill_to_layer.GetName():
|
|
1699
|
+
data["from_top"] = {
|
|
1700
|
+
"drill_to_layer": drill_to_layer.GetName(),
|
|
1701
|
+
"diameter": diameter.ToString(),
|
|
1702
|
+
"stub_length": offset.ToString(),
|
|
1703
|
+
}
|
|
1704
|
+
return data
|
|
1705
|
+
|
|
1706
|
+
@backdrill_parameters.setter
|
|
1707
|
+
def backdrill_parameters(self, params):
|
|
1708
|
+
from_bottom = params.get("from_bottom")
|
|
1709
|
+
if from_bottom:
|
|
1710
|
+
self._edb_object.SetBackDrillParameters(
|
|
1711
|
+
self._pedb.stackup.layers[from_bottom.get("drill_to_layer")]._edb_object,
|
|
1712
|
+
self._pedb.edb_value(from_bottom.get("stub_length")),
|
|
1713
|
+
self._pedb.edb_value(from_bottom.get("diameter")),
|
|
1714
|
+
True,
|
|
1715
|
+
)
|
|
1716
|
+
from_top = params.get("from_top")
|
|
1717
|
+
if from_top:
|
|
1718
|
+
self._edb_object.SetBackDrillParameters(
|
|
1719
|
+
self._pedb.stackup.layers[from_top.get("drill_to_layer")]._edb_object,
|
|
1720
|
+
self._pedb.edb_value(from_top.get("stub_length")),
|
|
1721
|
+
self._pedb.edb_value(from_top.get("diameter")),
|
|
1722
|
+
False,
|
|
1723
|
+
)
|
|
1724
|
+
|
|
1675
1725
|
def set_backdrill_bottom(self, drill_depth, drill_diameter, offset=0.0):
|
|
1676
1726
|
"""Set backdrill from bottom.
|
|
1677
1727
|
|
|
@@ -2274,3 +2324,15 @@ class EDBPadstackInstance(Primitive):
|
|
|
2274
2324
|
max_limit=max_limit,
|
|
2275
2325
|
component_only=component_only,
|
|
2276
2326
|
)
|
|
2327
|
+
|
|
2328
|
+
@property
|
|
2329
|
+
def properties(self):
|
|
2330
|
+
data = {}
|
|
2331
|
+
data["name"] = self.aedt_name
|
|
2332
|
+
data["definition"] = self.padstack_definition
|
|
2333
|
+
data["backdrill_parameters"] = self.backdrill_parameters
|
|
2334
|
+
_, position, rotation = self._edb_object.GetPositionAndRotationValue()
|
|
2335
|
+
data["position"] = [position.X.ToString(), position.Y.ToString()]
|
|
2336
|
+
data["rotation"] = [rotation.ToString()]
|
|
2337
|
+
data["id"] = self.id
|
|
2338
|
+
return data
|