pyedb 0.31.0__py3-none-any.whl → 0.34.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 -27
- pyedb/common/__init__.py +0 -0
- pyedb/common/nets.py +488 -0
- pyedb/configuration/cfg_common.py +20 -0
- pyedb/configuration/cfg_components.py +218 -57
- pyedb/configuration/cfg_data.py +6 -0
- pyedb/configuration/cfg_modeler.py +139 -0
- pyedb/configuration/cfg_operations.py +5 -4
- pyedb/configuration/cfg_padstacks.py +319 -55
- pyedb/configuration/cfg_ports_sources.py +99 -7
- pyedb/configuration/cfg_s_parameter_models.py +6 -6
- pyedb/configuration/configuration.py +31 -9
- pyedb/dotnet/clr_module.py +92 -32
- pyedb/dotnet/edb.py +54 -5
- pyedb/dotnet/edb_core/cell/hierarchy/component.py +0 -202
- pyedb/dotnet/edb_core/cell/layout.py +1 -1
- pyedb/dotnet/edb_core/cell/primitive/primitive.py +5 -27
- pyedb/dotnet/edb_core/edb_data/control_file.py +21 -0
- pyedb/dotnet/edb_core/edb_data/nets_data.py +6 -1
- pyedb/dotnet/edb_core/edb_data/padstacks_data.py +16 -222
- pyedb/dotnet/edb_core/edb_data/primitives_data.py +31 -0
- pyedb/dotnet/edb_core/hfss.py +2 -2
- pyedb/dotnet/edb_core/layout_validation.py +1 -3
- pyedb/dotnet/edb_core/materials.py +38 -38
- pyedb/dotnet/edb_core/modeler.py +4 -1
- pyedb/dotnet/edb_core/nets.py +2 -373
- pyedb/generic/filesystem.py +2 -5
- {pyedb-0.31.0.dist-info → pyedb-0.34.0.dist-info}/METADATA +12 -9
- {pyedb-0.31.0.dist-info → pyedb-0.34.0.dist-info}/RECORD +31 -28
- {pyedb-0.31.0.dist-info → pyedb-0.34.0.dist-info}/WHEEL +1 -1
- {pyedb-0.31.0.dist-info → pyedb-0.34.0.dist-info}/LICENSE +0 -0
|
@@ -21,81 +21,242 @@
|
|
|
21
21
|
# SOFTWARE.
|
|
22
22
|
|
|
23
23
|
from pyedb.configuration.cfg_common import CfgBase
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
class CfgRlcModel(CfgBase):
|
|
27
|
-
def __init__(self, **kwargs):
|
|
28
|
-
self.resistance = kwargs.get("resistance", None)
|
|
29
|
-
self.inductance = kwargs.get("inductance", None)
|
|
30
|
-
self.capacitance = kwargs.get("capacitance", None)
|
|
31
|
-
self.type = kwargs.get("type", None)
|
|
32
|
-
self.p1 = kwargs.get("p1", None)
|
|
33
|
-
self.p2 = kwargs.get("p2", None)
|
|
24
|
+
from pyedb.dotnet.edb_core.general import pascal_to_snake, snake_to_pascal
|
|
34
25
|
|
|
35
26
|
|
|
36
27
|
class CfgComponent(CfgBase):
|
|
37
|
-
def __init__(self, **kwargs):
|
|
28
|
+
def __init__(self, pedb, pedb_object, **kwargs):
|
|
29
|
+
self._pedb = pedb
|
|
30
|
+
self._pyedb_obj = pedb_object
|
|
31
|
+
|
|
38
32
|
self.enabled = kwargs.get("enabled", None)
|
|
39
33
|
self.reference_designator = kwargs.get("reference_designator", None)
|
|
40
34
|
self.definition = kwargs.get("definition", None)
|
|
41
35
|
self.type = kwargs["part_type"].lower() if kwargs.get("part_type") else None
|
|
36
|
+
self.placement_layer = kwargs.get("placement_layer", None)
|
|
37
|
+
self.pins = kwargs.get("pins", [])
|
|
38
|
+
|
|
42
39
|
self.port_properties = kwargs.get("port_properties", {})
|
|
43
40
|
self.solder_ball_properties = kwargs.get("solder_ball_properties", {})
|
|
44
41
|
self.ic_die_properties = kwargs.get("ic_die_properties", {})
|
|
45
|
-
self.pin_pair_model = kwargs.get("pin_pair_model",
|
|
46
|
-
self.spice_model = kwargs.get("spice_model",
|
|
47
|
-
self.s_parameter_model = kwargs.get("s_parameter_model",
|
|
42
|
+
self.pin_pair_model = kwargs.get("pin_pair_model", [])
|
|
43
|
+
self.spice_model = kwargs.get("spice_model", {})
|
|
44
|
+
self.s_parameter_model = kwargs.get("s_parameter_model", {})
|
|
45
|
+
self.netlist_model = kwargs.get("netlist_model", {})
|
|
46
|
+
|
|
47
|
+
def retrieve_model_properties_from_edb(self):
|
|
48
|
+
c_p = self._pyedb_obj.component_property
|
|
49
|
+
model = c_p.GetModel().Clone()
|
|
50
|
+
|
|
51
|
+
if model.GetModelType().ToString() == "NetlistModel":
|
|
52
|
+
self.netlist_model["netlist"] = model.GetNetlist()
|
|
53
|
+
elif model.GetModelType().ToString() == "PinPairModel":
|
|
54
|
+
temp = {}
|
|
55
|
+
for i in model.PinPairs:
|
|
56
|
+
temp["first_pin"] = i.FirstPin
|
|
57
|
+
temp["second_pin"] = i.SecondPin
|
|
58
|
+
rlc = model.GetPinPairRlc(i)
|
|
59
|
+
temp["is_parallel"] = rlc.IsParallel
|
|
60
|
+
temp["resistance"] = rlc.R.ToString()
|
|
61
|
+
temp["resistance_enabled"] = rlc.REnabled
|
|
62
|
+
temp["inductance"] = rlc.L.ToString()
|
|
63
|
+
temp["inductance_enabled"] = rlc.LEnabled
|
|
64
|
+
temp["capacitance"] = rlc.C.ToString()
|
|
65
|
+
temp["capacitance_enabled"] = rlc.CEnabled
|
|
66
|
+
self.pin_pair_model.append(temp)
|
|
67
|
+
elif model.GetModelType().ToString() == "SParameterModel":
|
|
68
|
+
self.s_parameter_model["reference_net"] = model.GetReferenceNet()
|
|
69
|
+
self.s_parameter_model["model_name"] = model.GetComponentModelName()
|
|
70
|
+
elif model.GetModelType().ToString() == "SPICEModel":
|
|
71
|
+
self.spice_model["model_name"] = model.GetModelName()
|
|
72
|
+
self.spice_model["model_path"] = model.GetModelPath()
|
|
73
|
+
self.spice_model["sub_circuit"] = model.GetSubCkt()
|
|
74
|
+
self.spice_model["terminal_pairs"] = [[i, j] for i, j in dict(model.GetTerminalPinPairs()).items()]
|
|
75
|
+
|
|
76
|
+
def _set_model_properties_to_edb(self):
|
|
77
|
+
c_p = self._pyedb_obj.component_property
|
|
78
|
+
if self.netlist_model:
|
|
79
|
+
m = self._pedb._edb.Cell.Hierarchy.SParameterModel()
|
|
80
|
+
m.SetNetlist(self.netlist_model["netlist"])
|
|
81
|
+
c_p.SetModel(m)
|
|
82
|
+
self.component_property = c_p
|
|
83
|
+
elif self.pin_pair_model:
|
|
84
|
+
m = self._pedb._edb.Cell.Hierarchy.PinPairModel()
|
|
85
|
+
for i in self.pin_pair_model:
|
|
86
|
+
p = self._pedb._edb.Utility.PinPair(str(i["first_pin"]), str(i["second_pin"]))
|
|
87
|
+
rlc = self._pedb._edb.Utility.Rlc(
|
|
88
|
+
self._pedb.edb_value(i["resistance"]),
|
|
89
|
+
i["resistance_enabled"],
|
|
90
|
+
self._pedb.edb_value(i["inductance"]),
|
|
91
|
+
i["inductance_enabled"],
|
|
92
|
+
self._pedb.edb_value(i["capacitance"]),
|
|
93
|
+
i["capacitance_enabled"],
|
|
94
|
+
i["is_parallel"],
|
|
95
|
+
)
|
|
96
|
+
m.SetPinPairRlc(p, rlc)
|
|
97
|
+
c_p.SetModel(m)
|
|
98
|
+
self._pyedb_obj.component_property = c_p
|
|
99
|
+
elif self.s_parameter_model:
|
|
100
|
+
m = self._pedb._edb.Cell.Hierarchy.SParameterModel()
|
|
101
|
+
m.SetComponentModelName(self.s_parameter_model["model_name"])
|
|
102
|
+
m.SetReferenceNet(self.s_parameter_model["reference_net"])
|
|
103
|
+
c_p.SetModel(m)
|
|
104
|
+
self.component_property = c_p
|
|
105
|
+
elif self.spice_model:
|
|
106
|
+
self._pyedb_obj.assign_spice_model(
|
|
107
|
+
self.spice_model["model_path"],
|
|
108
|
+
self.spice_model["model_name"],
|
|
109
|
+
self.spice_model["sub_circuit"],
|
|
110
|
+
self.spice_model["terminal_pairs"],
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
def _retrieve_ic_die_properties_from_edb(self):
|
|
114
|
+
temp = dict()
|
|
115
|
+
cp = self._pyedb_obj.component_property
|
|
116
|
+
ic_die_prop = cp.GetDieProperty().Clone()
|
|
117
|
+
die_type = pascal_to_snake(ic_die_prop.GetType().ToString())
|
|
118
|
+
temp["type"] = die_type
|
|
119
|
+
if not die_type == "no_die":
|
|
120
|
+
temp["orientation"] = pascal_to_snake(ic_die_prop.GetOrientation().ToString())
|
|
121
|
+
if die_type == "wire_bond":
|
|
122
|
+
temp["height"] = ic_die_prop.GetHeightValue().ToString()
|
|
123
|
+
self.ic_die_properties = temp
|
|
124
|
+
|
|
125
|
+
def _set_ic_die_properties_to_edb(self):
|
|
126
|
+
cp = self._pyedb_obj.component_property
|
|
127
|
+
ic_die_prop = cp.GetDieProperty().Clone()
|
|
128
|
+
die_type = self.ic_die_properties.get("type")
|
|
129
|
+
ic_die_prop.SetType(getattr(self._pedb._edb.Definition.DieType, snake_to_pascal(die_type)))
|
|
130
|
+
if not die_type == "no_die":
|
|
131
|
+
orientation = self.ic_die_properties.get("orientation")
|
|
132
|
+
if orientation:
|
|
133
|
+
ic_die_prop.SetOrientation(
|
|
134
|
+
getattr(self._pedb._edb.Definition.DieOrientation, snake_to_pascal(orientation))
|
|
135
|
+
)
|
|
136
|
+
if die_type == "wire_bond":
|
|
137
|
+
height = self.ic_die_properties.get("height")
|
|
138
|
+
if height:
|
|
139
|
+
ic_die_prop.SetHeight(self._pedb.edb_value(height))
|
|
140
|
+
cp.SetDieProperty(ic_die_prop)
|
|
141
|
+
self._pyedb_obj.component_property = cp
|
|
142
|
+
|
|
143
|
+
def _retrieve_solder_ball_properties_from_edb(self):
|
|
144
|
+
temp = dict()
|
|
145
|
+
cp = self._pyedb_obj.component_property
|
|
146
|
+
solder_ball_prop = cp.GetSolderBallProperty().Clone()
|
|
147
|
+
_, diam, mid_diam = solder_ball_prop.GetDiameterValue()
|
|
148
|
+
height = solder_ball_prop.GetHeightValue().ToString()
|
|
149
|
+
shape = solder_ball_prop.GetShape().ToString()
|
|
150
|
+
uses_solder_ball = solder_ball_prop.UsesSolderball()
|
|
151
|
+
temp["uses_solder_ball"] = uses_solder_ball
|
|
152
|
+
temp["shape"] = pascal_to_snake(shape)
|
|
153
|
+
temp["diameter"] = diam.ToString()
|
|
154
|
+
temp["mid_diameter"] = mid_diam.ToString()
|
|
155
|
+
temp["height"] = height
|
|
156
|
+
self.solder_ball_properties = temp
|
|
157
|
+
|
|
158
|
+
def _set_solder_ball_properties_to_edb(self):
|
|
159
|
+
cp = self._pyedb_obj.component_property
|
|
160
|
+
solder_ball_prop = cp.GetSolderBallProperty().Clone()
|
|
161
|
+
shape = self.solder_ball_properties.get("shape")
|
|
162
|
+
if shape:
|
|
163
|
+
solder_ball_prop.SetShape(getattr(self._pedb._edb.Definition.SolderballShape, snake_to_pascal(shape)))
|
|
164
|
+
else:
|
|
165
|
+
return
|
|
166
|
+
|
|
167
|
+
if shape == "cylinder":
|
|
168
|
+
diameter = self.solder_ball_properties["diameter"]
|
|
169
|
+
solder_ball_prop.SetDiameter(self._pedb.edb_value(diameter), self._pedb.edb_value(diameter))
|
|
170
|
+
elif shape == "spheroid":
|
|
171
|
+
diameter = self.solder_ball_properties["diameter"]
|
|
172
|
+
mid_diameter = self.solder_ball_properties["mid_diameter"]
|
|
173
|
+
solder_ball_prop.SetDiameter(self._pedb.edb_value(diameter), self._pedb.edb_value(mid_diameter))
|
|
174
|
+
else:
|
|
175
|
+
raise ValueError("Solderball shape must be either cylinder or spheroid")
|
|
176
|
+
solder_ball_prop.SetHeight(self._pedb.edb_value(self.solder_ball_properties["height"]))
|
|
177
|
+
cp.SetSolderBallProperty(solder_ball_prop)
|
|
178
|
+
self._pyedb_obj.component_property = cp
|
|
179
|
+
|
|
180
|
+
def _retrieve_port_properties_from_edb(self):
|
|
181
|
+
temp = dict()
|
|
182
|
+
cp = self._pyedb_obj.component_property
|
|
183
|
+
c_type = self.type.lower()
|
|
184
|
+
if c_type not in ["ic", "io", "other"]:
|
|
185
|
+
return
|
|
186
|
+
else:
|
|
187
|
+
port_prop = cp.GetPortProperty().Clone()
|
|
188
|
+
reference_height = port_prop.GetReferenceHeightValue().ToString()
|
|
189
|
+
reference_size_auto = port_prop.GetReferenceSizeAuto()
|
|
190
|
+
_, reference_size_x, reference_size_y = port_prop.GetReferenceSize()
|
|
191
|
+
temp["reference_height"] = reference_height
|
|
192
|
+
temp["reference_size_auto"] = reference_size_auto
|
|
193
|
+
temp["reference_size_x"] = str(reference_size_x)
|
|
194
|
+
temp["reference_size_y"] = str(reference_size_y)
|
|
195
|
+
self.port_properties = temp
|
|
196
|
+
|
|
197
|
+
def _set_port_properties_to_edb(self):
|
|
198
|
+
cp = self._pyedb_obj.component_property
|
|
199
|
+
port_prop = cp.GetPortProperty().Clone()
|
|
200
|
+
height = self.port_properties.get("reference_height")
|
|
201
|
+
if height:
|
|
202
|
+
port_prop.SetReferenceHeight(self._pedb.edb_value(height))
|
|
203
|
+
reference_size_auto = self.port_properties.get("reference_size_auto")
|
|
204
|
+
if reference_size_auto:
|
|
205
|
+
port_prop.SetReferenceSizeAuto(reference_size_auto)
|
|
206
|
+
reference_size_x = self.port_properties.get("reference_size_x", 0)
|
|
207
|
+
reference_size_y = self.port_properties.get("reference_size_y", 0)
|
|
208
|
+
port_prop.SetReferenceSize(self._pedb.edb_value(reference_size_x), self._pedb.edb_value(reference_size_y))
|
|
209
|
+
cp.SetPortProperty(port_prop)
|
|
210
|
+
self._pyedb_obj.component_property = cp
|
|
211
|
+
|
|
212
|
+
def set_parameters_to_edb(self):
|
|
213
|
+
if self.enabled:
|
|
214
|
+
self._pyedb_obj.enabled = self.enabled
|
|
215
|
+
if self.type:
|
|
216
|
+
self._pyedb_obj.type = self.type
|
|
217
|
+
|
|
218
|
+
self._set_model_properties_to_edb()
|
|
219
|
+
if self._pyedb_obj.type.lower() == "ic":
|
|
220
|
+
self._set_ic_die_properties_to_edb()
|
|
221
|
+
self._set_port_properties_to_edb()
|
|
222
|
+
elif self._pyedb_obj.type.lower() in ["io", "other"]:
|
|
223
|
+
self._set_solder_ball_properties_to_edb()
|
|
224
|
+
self._set_port_properties_to_edb()
|
|
225
|
+
|
|
226
|
+
def retrieve_parameters_from_edb(self):
|
|
227
|
+
self.type = self._pyedb_obj.type
|
|
228
|
+
self.definition = self._pyedb_obj.part_name
|
|
229
|
+
self.reference_designator = self._pyedb_obj.name
|
|
230
|
+
self.retrieve_model_properties_from_edb()
|
|
231
|
+
if self._pyedb_obj.type.lower() == "ic":
|
|
232
|
+
self._retrieve_ic_die_properties_from_edb()
|
|
233
|
+
self._retrieve_port_properties_from_edb()
|
|
234
|
+
elif self._pyedb_obj.type.lower() in ["io", "other"]:
|
|
235
|
+
self._retrieve_solder_ball_properties_from_edb()
|
|
236
|
+
self._retrieve_port_properties_from_edb()
|
|
48
237
|
|
|
49
238
|
|
|
50
239
|
class CfgComponents:
|
|
51
240
|
def __init__(self, pedb, components_data):
|
|
52
241
|
self._pedb = pedb
|
|
53
|
-
self.components = [
|
|
242
|
+
self.components = []
|
|
243
|
+
|
|
244
|
+
if components_data:
|
|
245
|
+
for comp in components_data:
|
|
246
|
+
obj = self._pedb.layout.find_component_by_name(comp["reference_designator"])
|
|
247
|
+
self.components.append(CfgComponent(self._pedb, obj, **comp))
|
|
248
|
+
|
|
249
|
+
def clean(self):
|
|
250
|
+
self.components = []
|
|
54
251
|
|
|
55
252
|
def apply(self):
|
|
56
|
-
comps_in_db = self._pedb.components
|
|
57
253
|
for comp in self.components:
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
c_db.type = comp.type
|
|
63
|
-
if comp.solder_ball_properties:
|
|
64
|
-
c_db.solder_ball_properties = comp.solder_ball_properties
|
|
65
|
-
if comp.port_properties:
|
|
66
|
-
c_db.port_properties = comp.port_properties
|
|
67
|
-
if comp.ic_die_properties:
|
|
68
|
-
c_db.ic_die_properties = comp.ic_die_properties
|
|
69
|
-
if comp.pin_pair_model:
|
|
70
|
-
c_db.model_properties = {"pin_pair_model": comp.pin_pair_model}
|
|
71
|
-
if comp.spice_model:
|
|
72
|
-
c_db.model_properties = {"spice_model": comp.spice_model}
|
|
73
|
-
if comp.s_parameter_model:
|
|
74
|
-
c_db.model_properties = {"s_parameter_model": comp.s_parameter_model}
|
|
75
|
-
|
|
76
|
-
def _load_data_from_db(self):
|
|
77
|
-
self.components = []
|
|
254
|
+
comp.set_parameters_to_edb()
|
|
255
|
+
|
|
256
|
+
def retrieve_parameters_from_edb(self):
|
|
257
|
+
self.clean()
|
|
78
258
|
comps_in_db = self._pedb.components
|
|
79
259
|
for _, comp in comps_in_db.instances.items():
|
|
80
|
-
cfg_comp = CfgComponent(
|
|
81
|
-
|
|
82
|
-
reference_designator=comp.name,
|
|
83
|
-
part_type=comp.type,
|
|
84
|
-
pin_pair_model=comp.model_properties.get("pin_pair_model"),
|
|
85
|
-
spice_model=comp.model_properties.get("spice_model"),
|
|
86
|
-
s_parameter_model=comp.model_properties.get("s_parameter_model"),
|
|
87
|
-
definition=comp.component_def,
|
|
88
|
-
location=comp.location,
|
|
89
|
-
placement_layer=comp.placement_layer,
|
|
90
|
-
solder_ball_properties=comp.solder_ball_properties,
|
|
91
|
-
ic_die_properties=comp.ic_die_properties,
|
|
92
|
-
port_properties=comp.port_properties,
|
|
93
|
-
)
|
|
260
|
+
cfg_comp = CfgComponent(self._pedb, comp)
|
|
261
|
+
cfg_comp.retrieve_parameters_from_edb()
|
|
94
262
|
self.components.append(cfg_comp)
|
|
95
|
-
|
|
96
|
-
def get_data_from_db(self):
|
|
97
|
-
self._load_data_from_db()
|
|
98
|
-
data = []
|
|
99
|
-
for comp in self.components:
|
|
100
|
-
data.append(comp.get_attributes())
|
|
101
|
-
return data
|
pyedb/configuration/cfg_data.py
CHANGED
|
@@ -22,8 +22,10 @@
|
|
|
22
22
|
|
|
23
23
|
|
|
24
24
|
from pyedb.configuration.cfg_boundaries import CfgBoundaries
|
|
25
|
+
from pyedb.configuration.cfg_common import CfgVariables
|
|
25
26
|
from pyedb.configuration.cfg_components import CfgComponents
|
|
26
27
|
from pyedb.configuration.cfg_general import CfgGeneral
|
|
28
|
+
from pyedb.configuration.cfg_modeler import CfgModeler
|
|
27
29
|
from pyedb.configuration.cfg_nets import CfgNets
|
|
28
30
|
from pyedb.configuration.cfg_operations import CfgOperations
|
|
29
31
|
from pyedb.configuration.cfg_package_definition import CfgPackageDefinitions
|
|
@@ -72,3 +74,7 @@ class CfgData(object):
|
|
|
72
74
|
|
|
73
75
|
self.package_definitions = CfgPackageDefinitions(self._pedb, data=kwargs.get("package_definitions", []))
|
|
74
76
|
self.operations = CfgOperations(self._pedb, data=kwargs.get("operations", []))
|
|
77
|
+
|
|
78
|
+
self.modeler = CfgModeler(self._pedb, data=kwargs.get("modeler", {}))
|
|
79
|
+
|
|
80
|
+
self.variables = CfgVariables(self._pedb, data=kwargs.get("variables", []))
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# Copyright (C) 2023 - 2024 ANSYS, Inc. and/or its affiliates.
|
|
2
|
+
# SPDX-License-Identifier: MIT
|
|
3
|
+
#
|
|
4
|
+
#
|
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
# furnished to do so, subject to the following conditions:
|
|
11
|
+
#
|
|
12
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
# copies or substantial portions of the Software.
|
|
14
|
+
#
|
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
# SOFTWARE.
|
|
22
|
+
|
|
23
|
+
from pyedb.configuration.cfg_components import CfgComponent
|
|
24
|
+
from pyedb.configuration.cfg_padstacks import CfgPadstackDefinition, CfgPadstackInstance
|
|
25
|
+
from pyedb.dotnet.edb_core.edb_data.padstacks_data import EDBPadstack
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class CfgTrace:
|
|
29
|
+
def __init__(self, **kwargs):
|
|
30
|
+
self.name = kwargs.get("name", "")
|
|
31
|
+
self.layer = kwargs["layer"]
|
|
32
|
+
self.path = kwargs["path"]
|
|
33
|
+
self.width = kwargs["width"]
|
|
34
|
+
self.net_name = kwargs.get("net_name", "")
|
|
35
|
+
self.start_cap_style = kwargs.get("start_cap_style", "round")
|
|
36
|
+
self.end_cap_style = kwargs.get("end_cap_style", "round")
|
|
37
|
+
self.corner_style = kwargs.get("corner_style", "sharp")
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class CfgPlane:
|
|
41
|
+
def __init__(self, **kwargs):
|
|
42
|
+
self.name = kwargs.get("name", "")
|
|
43
|
+
self.layer = kwargs["layer"]
|
|
44
|
+
self.net_name = kwargs.get("net_name", "")
|
|
45
|
+
self.type = kwargs.get("type", "rectangle")
|
|
46
|
+
|
|
47
|
+
# rectangle
|
|
48
|
+
self.lower_left_point = kwargs.get("lower_left_point", [])
|
|
49
|
+
self.upper_right_point = kwargs.get("upper_right_point", [])
|
|
50
|
+
self.corner_radius = kwargs.get("corner_radius", 0)
|
|
51
|
+
self.rotation = kwargs.get("rotation", 0)
|
|
52
|
+
self.voids = kwargs.get("voids", [])
|
|
53
|
+
|
|
54
|
+
# polygon
|
|
55
|
+
self.points = kwargs.get("points", [])
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
class CfgModeler:
|
|
59
|
+
"""Manage configuration general settings."""
|
|
60
|
+
|
|
61
|
+
def __init__(self, pedb, data):
|
|
62
|
+
self._pedb = pedb
|
|
63
|
+
self.traces = [CfgTrace(**i) for i in data.get("traces", [])]
|
|
64
|
+
self.padstack_defs = [
|
|
65
|
+
CfgPadstackDefinition(self._pedb, None, **i) for i in data.get("padstack_definitions", [])
|
|
66
|
+
]
|
|
67
|
+
self.padstack_instances = [
|
|
68
|
+
CfgPadstackInstance(self._pedb, None, **i) for i in data.get("padstack_instances", [])
|
|
69
|
+
]
|
|
70
|
+
self.planes = [CfgPlane(**i) for i in data.get("planes", [])]
|
|
71
|
+
self.components = [CfgComponent(self._pedb, None, **i) for i in data.get("components", [])]
|
|
72
|
+
|
|
73
|
+
def apply(self):
|
|
74
|
+
if self.traces:
|
|
75
|
+
for t in self.traces:
|
|
76
|
+
obj = self._pedb.modeler.create_trace(
|
|
77
|
+
path_list=t.path,
|
|
78
|
+
layer_name=t.layer,
|
|
79
|
+
net_name=t.net_name,
|
|
80
|
+
width=t.width,
|
|
81
|
+
start_cap_style=t.start_cap_style,
|
|
82
|
+
end_cap_style=t.end_cap_style,
|
|
83
|
+
corner_style=t.corner_style,
|
|
84
|
+
)
|
|
85
|
+
obj.aedt_name = t.name
|
|
86
|
+
|
|
87
|
+
if self.padstack_defs:
|
|
88
|
+
for p in self.padstack_defs:
|
|
89
|
+
pdata = self._pedb._edb.Definition.PadstackDefData.Create()
|
|
90
|
+
pdef = self._pedb._edb.Definition.PadstackDef.Create(self._pedb.active_db, p.name)
|
|
91
|
+
pdef.SetData(pdata)
|
|
92
|
+
pdef = EDBPadstack(pdef, self._pedb.padstacks)
|
|
93
|
+
p._pyedb_obj = pdef
|
|
94
|
+
p.set_parameters_to_edb()
|
|
95
|
+
|
|
96
|
+
if self.padstack_instances:
|
|
97
|
+
for p in self.padstack_instances:
|
|
98
|
+
p_inst = self._pedb.padstacks.place(
|
|
99
|
+
via_name=p.name,
|
|
100
|
+
position=p.position,
|
|
101
|
+
definition_name=p.definition,
|
|
102
|
+
)
|
|
103
|
+
p._pyedb_obj = p_inst
|
|
104
|
+
p.set_parameters_to_edb()
|
|
105
|
+
|
|
106
|
+
if self.planes:
|
|
107
|
+
for p in self.planes:
|
|
108
|
+
if p.type == "rectangle":
|
|
109
|
+
obj = self._pedb.modeler.create_rectangle(
|
|
110
|
+
layer_name=p.layer,
|
|
111
|
+
net_name=p.net_name,
|
|
112
|
+
lower_left_point=p.lower_left_point,
|
|
113
|
+
upper_right_point=p.upper_right_point,
|
|
114
|
+
corner_radius=p.corner_radius,
|
|
115
|
+
rotation=p.rotation,
|
|
116
|
+
)
|
|
117
|
+
obj.aedt_name = p.name
|
|
118
|
+
elif p.type == "polygon":
|
|
119
|
+
obj = self._pedb.modeler.create_polygon(
|
|
120
|
+
main_shape=p.points, layer_name=p.layer, net_name=p.net_name
|
|
121
|
+
)
|
|
122
|
+
obj.aedt_name = p.name
|
|
123
|
+
|
|
124
|
+
for v in p.voids:
|
|
125
|
+
for i in self._pedb.layout.primitives:
|
|
126
|
+
if i.aedt_name == v:
|
|
127
|
+
self._pedb.modeler.add_void(obj, i)
|
|
128
|
+
|
|
129
|
+
if self.components:
|
|
130
|
+
pedb_p_inst = self._pedb.padstacks.instances_by_name
|
|
131
|
+
for c in self.components:
|
|
132
|
+
obj = self._pedb.components.create(
|
|
133
|
+
[pedb_p_inst[i] for i in c.pins],
|
|
134
|
+
component_name=c.reference_designator,
|
|
135
|
+
placement_layer=c.placement_layer,
|
|
136
|
+
component_part_name=c.definition,
|
|
137
|
+
)
|
|
138
|
+
c._pyedb_obj = obj
|
|
139
|
+
c.set_parameters_to_edb()
|
|
@@ -60,10 +60,11 @@ class CfgCutout(CfgBase):
|
|
|
60
60
|
|
|
61
61
|
net_names = []
|
|
62
62
|
for name, obj in self._pedb.nets.nets.items():
|
|
63
|
-
if obj.primitives
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
63
|
+
if obj.primitives:
|
|
64
|
+
if obj.primitives[0].layer.name == "pyedb_cutout":
|
|
65
|
+
continue
|
|
66
|
+
else:
|
|
67
|
+
net_names.append(name)
|
|
67
68
|
|
|
68
69
|
self.reference_list = []
|
|
69
70
|
self.signal_list = net_names
|