pyedb 0.2.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of pyedb might be problematic. Click here for more details.

Files changed (128) hide show
  1. pyedb/__init__.py +17 -0
  2. pyedb/dotnet/__init__.py +0 -0
  3. pyedb/dotnet/application/Variables.py +2261 -0
  4. pyedb/dotnet/application/__init__.py +0 -0
  5. pyedb/dotnet/clr_module.py +103 -0
  6. pyedb/dotnet/edb.py +4237 -0
  7. pyedb/dotnet/edb_core/__init__.py +1 -0
  8. pyedb/dotnet/edb_core/cell/__init__.py +0 -0
  9. pyedb/dotnet/edb_core/cell/hierarchy/__init__.py +0 -0
  10. pyedb/dotnet/edb_core/cell/hierarchy/model.py +66 -0
  11. pyedb/dotnet/edb_core/components.py +2669 -0
  12. pyedb/dotnet/edb_core/configuration.py +423 -0
  13. pyedb/dotnet/edb_core/definition/__init__.py +0 -0
  14. pyedb/dotnet/edb_core/definition/component_def.py +166 -0
  15. pyedb/dotnet/edb_core/definition/component_model.py +30 -0
  16. pyedb/dotnet/edb_core/definition/definition_obj.py +18 -0
  17. pyedb/dotnet/edb_core/definition/definitions.py +12 -0
  18. pyedb/dotnet/edb_core/dotnet/__init__.py +0 -0
  19. pyedb/dotnet/edb_core/dotnet/database.py +1218 -0
  20. pyedb/dotnet/edb_core/dotnet/layout.py +238 -0
  21. pyedb/dotnet/edb_core/dotnet/primitive.py +1517 -0
  22. pyedb/dotnet/edb_core/edb_data/__init__.py +0 -0
  23. pyedb/dotnet/edb_core/edb_data/components_data.py +938 -0
  24. pyedb/dotnet/edb_core/edb_data/connectable.py +113 -0
  25. pyedb/dotnet/edb_core/edb_data/control_file.py +1268 -0
  26. pyedb/dotnet/edb_core/edb_data/design_options.py +35 -0
  27. pyedb/dotnet/edb_core/edb_data/edbvalue.py +45 -0
  28. pyedb/dotnet/edb_core/edb_data/hfss_extent_info.py +330 -0
  29. pyedb/dotnet/edb_core/edb_data/hfss_simulation_setup_data.py +1607 -0
  30. pyedb/dotnet/edb_core/edb_data/layer_data.py +576 -0
  31. pyedb/dotnet/edb_core/edb_data/nets_data.py +281 -0
  32. pyedb/dotnet/edb_core/edb_data/obj_base.py +19 -0
  33. pyedb/dotnet/edb_core/edb_data/padstacks_data.py +2080 -0
  34. pyedb/dotnet/edb_core/edb_data/ports.py +287 -0
  35. pyedb/dotnet/edb_core/edb_data/primitives_data.py +1397 -0
  36. pyedb/dotnet/edb_core/edb_data/simulation_configuration.py +2914 -0
  37. pyedb/dotnet/edb_core/edb_data/simulation_setup.py +716 -0
  38. pyedb/dotnet/edb_core/edb_data/siwave_simulation_setup_data.py +1205 -0
  39. pyedb/dotnet/edb_core/edb_data/sources.py +514 -0
  40. pyedb/dotnet/edb_core/edb_data/terminals.py +632 -0
  41. pyedb/dotnet/edb_core/edb_data/utilities.py +148 -0
  42. pyedb/dotnet/edb_core/edb_data/variables.py +91 -0
  43. pyedb/dotnet/edb_core/general.py +181 -0
  44. pyedb/dotnet/edb_core/hfss.py +1646 -0
  45. pyedb/dotnet/edb_core/layout.py +1244 -0
  46. pyedb/dotnet/edb_core/layout_validation.py +272 -0
  47. pyedb/dotnet/edb_core/materials.py +939 -0
  48. pyedb/dotnet/edb_core/net_class.py +335 -0
  49. pyedb/dotnet/edb_core/nets.py +1215 -0
  50. pyedb/dotnet/edb_core/padstack.py +1389 -0
  51. pyedb/dotnet/edb_core/siwave.py +1427 -0
  52. pyedb/dotnet/edb_core/stackup.py +2703 -0
  53. pyedb/edb_logger.py +396 -0
  54. pyedb/generic/__init__.py +0 -0
  55. pyedb/generic/constants.py +1063 -0
  56. pyedb/generic/data_handlers.py +320 -0
  57. pyedb/generic/design_types.py +104 -0
  58. pyedb/generic/filesystem.py +150 -0
  59. pyedb/generic/general_methods.py +1535 -0
  60. pyedb/generic/plot.py +1840 -0
  61. pyedb/generic/process.py +285 -0
  62. pyedb/generic/settings.py +224 -0
  63. pyedb/ipc2581/__init__.py +0 -0
  64. pyedb/ipc2581/bom/__init__.py +0 -0
  65. pyedb/ipc2581/bom/bom.py +21 -0
  66. pyedb/ipc2581/bom/bom_item.py +32 -0
  67. pyedb/ipc2581/bom/characteristics.py +37 -0
  68. pyedb/ipc2581/bom/refdes.py +16 -0
  69. pyedb/ipc2581/content/__init__.py +0 -0
  70. pyedb/ipc2581/content/color.py +38 -0
  71. pyedb/ipc2581/content/content.py +55 -0
  72. pyedb/ipc2581/content/dictionary_color.py +29 -0
  73. pyedb/ipc2581/content/dictionary_fill.py +28 -0
  74. pyedb/ipc2581/content/dictionary_line.py +30 -0
  75. pyedb/ipc2581/content/entry_color.py +13 -0
  76. pyedb/ipc2581/content/entry_line.py +14 -0
  77. pyedb/ipc2581/content/fill.py +15 -0
  78. pyedb/ipc2581/content/layer_ref.py +10 -0
  79. pyedb/ipc2581/content/standard_geometries_dictionary.py +72 -0
  80. pyedb/ipc2581/ecad/__init__.py +0 -0
  81. pyedb/ipc2581/ecad/cad_data/__init__.py +0 -0
  82. pyedb/ipc2581/ecad/cad_data/assembly_drawing.py +26 -0
  83. pyedb/ipc2581/ecad/cad_data/cad_data.py +37 -0
  84. pyedb/ipc2581/ecad/cad_data/component.py +41 -0
  85. pyedb/ipc2581/ecad/cad_data/drill.py +30 -0
  86. pyedb/ipc2581/ecad/cad_data/feature.py +54 -0
  87. pyedb/ipc2581/ecad/cad_data/layer.py +41 -0
  88. pyedb/ipc2581/ecad/cad_data/layer_feature.py +151 -0
  89. pyedb/ipc2581/ecad/cad_data/logical_net.py +32 -0
  90. pyedb/ipc2581/ecad/cad_data/outline.py +25 -0
  91. pyedb/ipc2581/ecad/cad_data/package.py +104 -0
  92. pyedb/ipc2581/ecad/cad_data/padstack_def.py +38 -0
  93. pyedb/ipc2581/ecad/cad_data/padstack_hole_def.py +24 -0
  94. pyedb/ipc2581/ecad/cad_data/padstack_instance.py +62 -0
  95. pyedb/ipc2581/ecad/cad_data/padstack_pad_def.py +26 -0
  96. pyedb/ipc2581/ecad/cad_data/path.py +89 -0
  97. pyedb/ipc2581/ecad/cad_data/phy_net.py +80 -0
  98. pyedb/ipc2581/ecad/cad_data/pin.py +31 -0
  99. pyedb/ipc2581/ecad/cad_data/polygon.py +169 -0
  100. pyedb/ipc2581/ecad/cad_data/profile.py +40 -0
  101. pyedb/ipc2581/ecad/cad_data/stackup.py +31 -0
  102. pyedb/ipc2581/ecad/cad_data/stackup_group.py +42 -0
  103. pyedb/ipc2581/ecad/cad_data/stackup_layer.py +21 -0
  104. pyedb/ipc2581/ecad/cad_data/step.py +275 -0
  105. pyedb/ipc2581/ecad/cad_header.py +33 -0
  106. pyedb/ipc2581/ecad/ecad.py +19 -0
  107. pyedb/ipc2581/ecad/spec.py +46 -0
  108. pyedb/ipc2581/history_record.py +37 -0
  109. pyedb/ipc2581/ipc2581.py +387 -0
  110. pyedb/ipc2581/logistic_header.py +25 -0
  111. pyedb/misc/__init__.py +0 -0
  112. pyedb/misc/aedtlib_personalib_install.py +14 -0
  113. pyedb/misc/downloads.py +322 -0
  114. pyedb/misc/misc.py +67 -0
  115. pyedb/misc/pyedb.runtimeconfig.json +13 -0
  116. pyedb/misc/siw_feature_config/__init__.py +0 -0
  117. pyedb/misc/siw_feature_config/emc/__init__.py +0 -0
  118. pyedb/misc/siw_feature_config/emc/component_tags.py +46 -0
  119. pyedb/misc/siw_feature_config/emc/net_tags.py +37 -0
  120. pyedb/misc/siw_feature_config/emc/tag_library.py +62 -0
  121. pyedb/misc/siw_feature_config/emc/xml_generic.py +78 -0
  122. pyedb/misc/siw_feature_config/emc_rule_checker_settings.py +179 -0
  123. pyedb/misc/utilities.py +27 -0
  124. pyedb/modeler/geometry_operators.py +2082 -0
  125. pyedb-0.2.0.dist-info/LICENSE +21 -0
  126. pyedb-0.2.0.dist-info/METADATA +208 -0
  127. pyedb-0.2.0.dist-info/RECORD +128 -0
  128. pyedb-0.2.0.dist-info/WHEEL +4 -0
@@ -0,0 +1,938 @@
1
+ import logging
2
+ import re
3
+ import warnings
4
+
5
+ from pyedb.dotnet.edb_core.cell.hierarchy.model import PinPairModel
6
+ from pyedb.dotnet.edb_core.edb_data.padstacks_data import EDBPadstackInstance
7
+ from pyedb.generic.general_methods import is_ironpython
8
+
9
+ if not is_ironpython:
10
+ try:
11
+ import numpy as np
12
+ except ImportError:
13
+ warnings.warn(
14
+ "The NumPy module is required to run some functionalities of EDB.\n"
15
+ "Install with \n\npip install numpy\n\nRequires CPython."
16
+ )
17
+ from pyedb.generic.general_methods import (
18
+ get_filename_without_extension,
19
+ pyedb_function_handler,
20
+ )
21
+
22
+
23
+ class EDBComponent(object):
24
+ """Manages EDB functionalities for components.
25
+
26
+ Parameters
27
+ ----------
28
+ parent : :class:`pyedb.dotnet.edb_core.components.Components`
29
+ Inherited AEDT object.
30
+ component : object
31
+ Edb Component Object
32
+
33
+ """
34
+
35
+ class _PinPair(object): # pragma: no cover
36
+ def __init__(self, pcomp, edb_comp, edb_comp_prop, edb_model, edb_pin_pair):
37
+ self._pedb_comp = pcomp
38
+ self._edb_comp = edb_comp
39
+ self._edb_comp_prop = edb_comp_prop
40
+ self._edb_model = edb_model
41
+ self._edb_pin_pair = edb_pin_pair
42
+
43
+ def _edb_value(self, value):
44
+ return self._pedb_comp._get_edb_value(value) # pragma: no cover
45
+
46
+ @property
47
+ def is_parallel(self):
48
+ return self._pin_pair_rlc.IsParallel # pragma: no cover
49
+
50
+ @is_parallel.setter
51
+ def is_parallel(self, value):
52
+ rlc = self._pin_pair_rlc
53
+ rlc.IsParallel = value
54
+ self._set_comp_prop() # pragma: no cover
55
+
56
+ @property
57
+ def _pin_pair_rlc(self):
58
+ return self._edb_model.GetPinPairRlc(self._edb_pin_pair)
59
+
60
+ @property
61
+ def rlc_enable(self):
62
+ rlc = self._pin_pair_rlc
63
+ return [rlc.REnabled, rlc.LEnabled, rlc.CEnabled]
64
+
65
+ @rlc_enable.setter
66
+ def rlc_enable(self, value):
67
+ rlc = self._pin_pair_rlc
68
+ rlc.REnabled = value[0]
69
+ rlc.LEnabled = value[1]
70
+ rlc.CEnabled = value[2]
71
+ self._set_comp_prop() # pragma: no cover
72
+
73
+ @property
74
+ def resistance(self):
75
+ return self._pin_pair_rlc.R.ToDouble() # pragma: no cover
76
+
77
+ @resistance.setter
78
+ def resistance(self, value):
79
+ self._pin_pair_rlc.R = value
80
+ self._set_comp_prop(self._pin_pair_rlc) # pragma: no cover
81
+
82
+ @property
83
+ def inductance(self):
84
+ return self._pin_pair_rlc.L.ToDouble() # pragma: no cover
85
+
86
+ @inductance.setter
87
+ def inductance(self, value):
88
+ self._pin_pair_rlc.L = value
89
+ self._set_comp_prop(self._pin_pair_rlc) # pragma: no cover
90
+
91
+ @property
92
+ def capacitance(self):
93
+ return self._pin_pair_rlc.C.ToDouble() # pragma: no cover
94
+
95
+ @capacitance.setter
96
+ def capacitance(self, value):
97
+ self._pin_pair_rlc.C = value
98
+ self._set_comp_prop(self._pin_pair_rlc) # pragma: no cover
99
+
100
+ @property
101
+ def rlc_values(self): # pragma: no cover
102
+ rlc = self._pin_pair_rlc
103
+ return [rlc.R.ToDouble(), rlc.L.ToDouble(), rlc.C.ToDouble()]
104
+
105
+ @rlc_values.setter
106
+ def rlc_values(self, values): # pragma: no cover
107
+ rlc = self._pin_pair_rlc
108
+ rlc.R = self._edb_value(values[0])
109
+ rlc.L = self._edb_value(values[1])
110
+ rlc.C = self._edb_value(values[2])
111
+ self._set_comp_prop() # pragma: no cover
112
+
113
+ def _set_comp_prop(self): # pragma: no cover
114
+ self._edb_model.SetPinPairRlc(self._edb_pin_pair, self._pin_pair_rlc)
115
+ self._edb_comp_prop.SetModel(self._edb_model)
116
+ self._edb_comp.SetComponentProperty(self._edb_comp_prop)
117
+
118
+ class _SpiceModel(object): # pragma: no cover
119
+ def __init__(self, edb_model):
120
+ self._edb_model = edb_model
121
+
122
+ @property
123
+ def file_path(self):
124
+ return self._edb_model.GetSPICEFilePath()
125
+
126
+ @property
127
+ def name(self):
128
+ return self._edb_model.GetSPICEName()
129
+
130
+ class _SparamModel(object): # pragma: no cover
131
+ def __init__(self, edb_model):
132
+ self._edb_model = edb_model
133
+
134
+ @property
135
+ def name(self):
136
+ return self._edb_model.GetComponentModelName()
137
+
138
+ @property
139
+ def reference_net(self):
140
+ return self._edb_model.GetReferenceNet()
141
+
142
+ class _NetlistModel(object): # pragma: no cover
143
+ def __init__(self, edb_model):
144
+ self._edb_model = edb_model
145
+
146
+ @property
147
+ def netlist(self):
148
+ return self._edb_model.GetNetlist()
149
+
150
+ def __init__(self, pedb, cmp):
151
+ self._pedb = pedb
152
+ self.edbcomponent = cmp
153
+ self._layout_instance = None
154
+ self._comp_instance = None
155
+
156
+ @property
157
+ def layout_instance(self):
158
+ """EDB layout instance object."""
159
+ return self._pedb.layout_instance
160
+
161
+ @property
162
+ def component_instance(self):
163
+ """Edb component instance."""
164
+ if self._comp_instance is None:
165
+ self._comp_instance = self.layout_instance.GetLayoutObjInstance(self.edbcomponent, None)
166
+ return self._comp_instance
167
+
168
+ @property
169
+ def _active_layout(self): # pragma: no cover
170
+ return self._pedb.active_layout
171
+
172
+ @property
173
+ def component_property(self):
174
+ """``ComponentProperty`` object."""
175
+ return self.edbcomponent.GetComponentProperty().Clone()
176
+
177
+ @property
178
+ def _edb_model(self): # pragma: no cover
179
+ return self.component_property.GetModel().Clone()
180
+
181
+ @property # pragma: no cover
182
+ def _pin_pairs(self):
183
+ edb_comp_prop = self.component_property
184
+ edb_model = self._edb_model
185
+ return [
186
+ self._PinPair(self, self.edbcomponent, edb_comp_prop, edb_model, pin_pair)
187
+ for pin_pair in list(edb_model.PinPairs)
188
+ ]
189
+
190
+ @property
191
+ def model(self):
192
+ """Component model."""
193
+ edb_object = self.component_property.GetModel().Clone()
194
+ model_type = edb_object.ToString().split(".")[-1]
195
+ if model_type == "PinPairModel":
196
+ return PinPairModel(self._pedb, edb_object)
197
+
198
+ @model.setter
199
+ def model(self, value):
200
+ if not isinstance(value, PinPairModel):
201
+ self._pedb.logger.error("Invalid input. Set model failed.")
202
+
203
+ comp_prop = self.component_property
204
+ comp_prop.SetModel(value._edb_object)
205
+ self.edbcomponent.SetComponentProperty(comp_prop)
206
+
207
+ @property
208
+ def is_enabled(self):
209
+ """Get or Set the component to active mode.
210
+
211
+ Returns
212
+ -------
213
+ bool
214
+ ``True`` if component is active, ``False`` if is disabled..
215
+ """
216
+ return self.component_property.IsEnabled()
217
+
218
+ @is_enabled.setter
219
+ def is_enabled(self, value):
220
+ cmp_prop = self.component_property.Clone()
221
+ cmp_prop.SetEnabled(value)
222
+ self.edbcomponent.SetComponentProperty(cmp_prop)
223
+
224
+ @property
225
+ def spice_model(self):
226
+ """Get assigned Spice model properties."""
227
+ if not self.model_type == "SPICEModel":
228
+ return None
229
+ else:
230
+ return self._SpiceModel(self._edb_model)
231
+
232
+ @property
233
+ def s_param_model(self):
234
+ """Get assigned S-parameter model properties."""
235
+ if not self.model_type == "SParameterModel":
236
+ return None
237
+ else:
238
+ return self._SparamModel(self._edb_model)
239
+
240
+ @property
241
+ def netlist_model(self):
242
+ """Get assigned netlist model properties."""
243
+ if not self.model_type == "NetlistModel":
244
+ return None
245
+ else:
246
+ return self._NetlistModel(self._edb_model)
247
+
248
+ @property
249
+ def solder_ball_height(self):
250
+ """Solder ball height if available."""
251
+ if "GetSolderBallProperty" in dir(self.component_property):
252
+ return self.component_property.GetSolderBallProperty().GetHeight()
253
+ return None
254
+
255
+ @property
256
+ def solder_ball_placement(self):
257
+ """Solder ball placement if available.."""
258
+ if "GetSolderBallProperty" in dir(self.component_property):
259
+ return int(self.component_property.GetSolderBallProperty().GetPlacement())
260
+ return 2
261
+
262
+ @property
263
+ def refdes(self):
264
+ """Reference Designator Name.
265
+
266
+ Returns
267
+ -------
268
+ str
269
+ Reference Designator Name.
270
+ """
271
+ return self.edbcomponent.GetName()
272
+
273
+ @refdes.setter
274
+ def refdes(self, name):
275
+ self.edbcomponent.SetName(name)
276
+
277
+ @property
278
+ def is_null(self):
279
+ """Flag indicating if the current object exists."""
280
+ return self.edbcomponent.IsNull()
281
+
282
+ @property
283
+ def is_enabled(self):
284
+ """Flag indicating if the current object is enabled.
285
+
286
+ Returns
287
+ -------
288
+ bool
289
+ ``True`` if current object is enabled, ``False`` otherwise.
290
+ """
291
+ if self.type in ["Resistor", "Capacitor", "Inductor"]:
292
+ return self.component_property.IsEnabled()
293
+ else: # pragma: no cover
294
+ return True
295
+
296
+ @is_enabled.setter
297
+ def is_enabled(self, enabled):
298
+ """Enables the current object."""
299
+ if self.type in ["Resistor", "Capacitor", "Inductor"]:
300
+ component_property = self.component_property
301
+ component_property.SetEnabled(enabled)
302
+ self.edbcomponent.SetComponentProperty(component_property)
303
+
304
+ @property
305
+ def model_type(self):
306
+ """Retrieve assigned model type."""
307
+ _model_type = self._edb_model.ToString().split(".")[-1]
308
+ if _model_type == "PinPairModel":
309
+ return "RLC"
310
+ else:
311
+ return _model_type
312
+
313
+ @property
314
+ def rlc_values(self):
315
+ """Get component rlc values."""
316
+ if not len(self._pin_pairs):
317
+ return [None, None, None]
318
+ pin_pair = self._pin_pairs[0]
319
+ return pin_pair.rlc_values
320
+
321
+ @rlc_values.setter
322
+ def rlc_values(self, value):
323
+ if isinstance(value, list): # pragma no cover
324
+ rlc_enabled = [True if i else False for i in value]
325
+ rlc_values = [self._get_edb_value(i) for i in value]
326
+ model = self._edb.cell.hierarchy._hierarchy.PinPairModel()
327
+ pin_names = list(self.pins.keys())
328
+ for idx, i in enumerate(np.arange(len(pin_names) // 2)):
329
+ pin_pair = self._edb.utility.utility.PinPair(pin_names[idx], pin_names[idx + 1])
330
+ rlc = self._edb.utility.utility.Rlc(
331
+ rlc_values[0], rlc_enabled[0], rlc_values[1], rlc_enabled[1], rlc_values[2], rlc_enabled[2], False
332
+ )
333
+ model.SetPinPairRlc(pin_pair, rlc)
334
+ self._set_model(model)
335
+
336
+ @property
337
+ def value(self):
338
+ """Retrieve discrete component value.
339
+
340
+ Returns
341
+ -------
342
+ str
343
+ Value. ``None`` if not an RLC Type.
344
+ """
345
+ if self.model_type == "RLC":
346
+ if not self._pin_pairs:
347
+ if self.type == "Inductor":
348
+ return 1e-9
349
+ elif self.type == "Resistor":
350
+ return 1e6
351
+ else:
352
+ return 1
353
+ else:
354
+ pin_pair = self._pin_pairs[0]
355
+ if len([i for i in pin_pair.rlc_enable if i]) == 1:
356
+ return [pin_pair.rlc_values[idx] for idx, val in enumerate(pin_pair.rlc_enable) if val][0]
357
+ else:
358
+ return pin_pair.rlc_values
359
+ elif self.model_type == "SPICEModel":
360
+ return self.spice_model.file_path
361
+ elif self.model_type == "SParameterModel":
362
+ return self.s_param_model.name
363
+ else:
364
+ return self.netlist_model.netlist
365
+
366
+ @value.setter
367
+ def value(self, value):
368
+ rlc_enabled = [True if i == self.type else False for i in ["Resistor", "Inductor", "Capacitor"]]
369
+ rlc_values = [value if i == self.type else 0 for i in ["Resistor", "Inductor", "Capacitor"]]
370
+ rlc_values = [self._get_edb_value(i) for i in rlc_values]
371
+
372
+ model = self._edb.cell.hierarchy._hierarchy.PinPairModel()
373
+ pin_names = list(self.pins.keys())
374
+ for idx, i in enumerate(np.arange(len(pin_names) // 2)):
375
+ pin_pair = self._edb.utility.utility.PinPair(pin_names[idx], pin_names[idx + 1])
376
+ rlc = self._edb.utility.utility.Rlc(
377
+ rlc_values[0], rlc_enabled[0], rlc_values[1], rlc_enabled[1], rlc_values[2], rlc_enabled[2], False
378
+ )
379
+ model.SetPinPairRlc(pin_pair, rlc)
380
+ self._set_model(model)
381
+
382
+ @property
383
+ def res_value(self):
384
+ """Resistance value.
385
+
386
+ Returns
387
+ -------
388
+ str
389
+ Resistance value or ``None`` if not an RLC type.
390
+ """
391
+ cmp_type = int(self.edbcomponent.GetComponentType())
392
+ if 0 < cmp_type < 4:
393
+ componentProperty = self.edbcomponent.GetComponentProperty()
394
+ model = componentProperty.GetModel().Clone()
395
+ pinpairs = model.PinPairs
396
+ if not list(pinpairs):
397
+ return "0"
398
+ for pinpair in pinpairs:
399
+ pair = model.GetPinPairRlc(pinpair)
400
+ return pair.R.ToString()
401
+ return None
402
+
403
+ @res_value.setter
404
+ def res_value(self, value): # pragma no cover
405
+ if value:
406
+ if self.rlc_values == [None, None, None]:
407
+ self.rlc_values = [value, 0, 0]
408
+ else:
409
+ self.rlc_values = [value, self.rlc_values[1], self.rlc_values[2]]
410
+
411
+ @property
412
+ def cap_value(self):
413
+ """Capacitance Value.
414
+
415
+ Returns
416
+ -------
417
+ str
418
+ Capacitance Value. ``None`` if not an RLC Type.
419
+ """
420
+ cmp_type = int(self.edbcomponent.GetComponentType())
421
+ if 0 < cmp_type < 4:
422
+ componentProperty = self.edbcomponent.GetComponentProperty()
423
+ model = componentProperty.GetModel().Clone()
424
+ pinpairs = model.PinPairs
425
+ if not list(pinpairs):
426
+ return "0"
427
+ for pinpair in pinpairs:
428
+ pair = model.GetPinPairRlc(pinpair)
429
+ return pair.C.ToString()
430
+ return None
431
+
432
+ @cap_value.setter
433
+ def cap_value(self, value): # pragma no cover
434
+ if value:
435
+ if self.rlc_values == [None, None, None]:
436
+ self.rlc_values = [0, 0, value]
437
+ else:
438
+ self.rlc_values = [self.rlc_values[1], self.rlc_values[2], value]
439
+
440
+ @property
441
+ def ind_value(self):
442
+ """Inductance Value.
443
+
444
+ Returns
445
+ -------
446
+ str
447
+ Inductance Value. ``None`` if not an RLC Type.
448
+ """
449
+ cmp_type = int(self.edbcomponent.GetComponentType())
450
+ if 0 < cmp_type < 4:
451
+ componentProperty = self.edbcomponent.GetComponentProperty()
452
+ model = componentProperty.GetModel().Clone()
453
+ pinpairs = model.PinPairs
454
+ if not list(pinpairs):
455
+ return "0"
456
+ for pinpair in pinpairs:
457
+ pair = model.GetPinPairRlc(pinpair)
458
+ return pair.L.ToString()
459
+ return None
460
+
461
+ @ind_value.setter
462
+ def ind_value(self, value): # pragma no cover
463
+ if value:
464
+ if self.rlc_values == [None, None, None]:
465
+ self.rlc_values = [0, value, 0]
466
+ else:
467
+ self.rlc_values = [self.rlc_values[1], value, self.rlc_values[2]]
468
+
469
+ @property
470
+ def is_parallel_rlc(self):
471
+ """Define if model is Parallel or Series.
472
+
473
+ Returns
474
+ -------
475
+ bool
476
+ ``True`` if it is a parallel rlc model. ``False`` for series RLC. ``None`` if not an RLC Type.
477
+ """
478
+ cmp_type = int(self.edbcomponent.GetComponentType())
479
+ if 0 < cmp_type < 4:
480
+ model = self.component_property.GetModel().Clone()
481
+ pinpairs = model.PinPairs
482
+ for pinpair in pinpairs:
483
+ pair = model.GetPinPairRlc(pinpair)
484
+ return pair.IsParallel
485
+ return None
486
+
487
+ @is_parallel_rlc.setter
488
+ def is_parallel_rlc(self, value): # pragma no cover
489
+ if not len(self._pin_pairs):
490
+ logging.warning(self.refdes, " has no pin pair.")
491
+ else:
492
+ if isinstance(value, bool):
493
+ componentProperty = self.edbcomponent.GetComponentProperty()
494
+ model = componentProperty.GetModel().Clone()
495
+ pinpairs = model.PinPairs
496
+ if not list(pinpairs):
497
+ return "0"
498
+ for pin_pair in pinpairs:
499
+ pin_pair_rlc = model.GetPinPairRlc(pin_pair)
500
+ pin_pair_rlc.IsParallel = value
501
+ pin_pair_model = self._edb_model
502
+ pin_pair_model.SetPinPairRlc(pin_pair, pin_pair_rlc)
503
+ comp_prop = self.component_property
504
+ comp_prop.SetModel(pin_pair_model)
505
+ self.edbcomponent.SetComponentProperty(comp_prop)
506
+
507
+ @property
508
+ def center(self):
509
+ """Compute the component center.
510
+
511
+ Returns
512
+ -------
513
+ list
514
+ """
515
+ center = self.component_instance.GetCenter()
516
+ return [center.X.ToDouble(), center.Y.ToDouble()]
517
+
518
+ @property
519
+ def bounding_box(self):
520
+ """Component's bounding box.
521
+
522
+ Returns
523
+ -------
524
+ List[float]
525
+ List of coordinates for the component's bounding box, with the list of
526
+ coordinates in this order: [X lower left corner, Y lower left corner,
527
+ X upper right corner, Y upper right corner].
528
+ """
529
+ bbox = self.component_instance.GetBBox()
530
+ pt1 = bbox.Item1
531
+ pt2 = bbox.Item2
532
+ return [pt1.X.ToDouble(), pt1.Y.ToDouble(), pt2.X.ToDouble(), pt2.Y.ToDouble()]
533
+
534
+ @property
535
+ def rotation(self):
536
+ """Compute the component rotation in radian.
537
+
538
+ Returns
539
+ -------
540
+ float
541
+ """
542
+ return self.edbcomponent.GetTransform().Rotation.ToDouble()
543
+
544
+ @property
545
+ def pinlist(self):
546
+ """Pins of the component.
547
+
548
+ Returns
549
+ -------
550
+ list
551
+ List of Pins of Component.
552
+ """
553
+ pins = [
554
+ p
555
+ for p in self.edbcomponent.LayoutObjs
556
+ if p.GetObjType() == self._edb.cell.layout_object_type.PadstackInstance
557
+ and p.IsLayoutPin()
558
+ and p.GetComponent().GetName() == self.refdes
559
+ ]
560
+ return pins
561
+
562
+ @property
563
+ def nets(self):
564
+ """Nets of Component.
565
+
566
+ Returns
567
+ -------
568
+ list
569
+ List of Nets of Component.
570
+ """
571
+ netlist = []
572
+ for pin in self.pinlist:
573
+ netlist.append(pin.GetNet().GetName())
574
+ return list(set(netlist))
575
+
576
+ @property
577
+ def pins(self):
578
+ """EDBPadstackInstance of Component.
579
+
580
+ Returns
581
+ -------
582
+ dic[str, :class:`dotnet.edb_core.edb_data.definitions.EDBPadstackInstance`]
583
+ Dictionary of EDBPadstackInstance Components.
584
+ """
585
+ pins = {}
586
+ for el in self.pinlist:
587
+ pins[el.GetName()] = EDBPadstackInstance(el, self._pedb)
588
+ return pins
589
+
590
+ @property
591
+ def type(self):
592
+ """Component type.
593
+
594
+ Returns
595
+ -------
596
+ str
597
+ Component type.
598
+ """
599
+ cmp_type = int(self.edbcomponent.GetComponentType())
600
+ if cmp_type == 1:
601
+ return "Resistor"
602
+ elif cmp_type == 2:
603
+ return "Inductor"
604
+ elif cmp_type == 3:
605
+ return "Capacitor"
606
+ elif cmp_type == 4:
607
+ return "IC"
608
+ elif cmp_type == 5:
609
+ return "IO"
610
+ elif cmp_type == 0:
611
+ return "Other"
612
+
613
+ @type.setter
614
+ def type(self, new_type):
615
+ """Set component type
616
+
617
+ Parameters
618
+ ----------
619
+ new_type : str
620
+ Type of the component. Options are ``"Resistor"``, ``"Inductor"``, ``"Capacitor"``,
621
+ ``"IC"``, ``"IO"`` and ``"Other"``.
622
+ """
623
+ if new_type == "Resistor":
624
+ type_id = self._pedb.definition.ComponentType.Resistor
625
+ elif new_type == "Inductor":
626
+ type_id = self._pedb.definition.ComponentType.Inductor
627
+ elif new_type == "Capacitor":
628
+ type_id = self._pedb.definition.ComponentType.Capacitor
629
+ elif new_type == "IC":
630
+ type_id = self._pedb.definition.ComponentType.IC
631
+ elif new_type == "IO":
632
+ type_id = self._pedb.definition.ComponentType.IO
633
+ elif new_type == "Other":
634
+ type_id = self._pedb.definition.ComponentType.Other
635
+ else:
636
+ return
637
+ self.edbcomponent.SetComponentType(type_id)
638
+
639
+ @property
640
+ def numpins(self):
641
+ """Number of Pins of Component.
642
+
643
+ Returns
644
+ -------
645
+ int
646
+ Number of Pins of Component.
647
+ """
648
+ return self.edbcomponent.GetNumberOfPins()
649
+
650
+ @property
651
+ def partname(self): # pragma: no cover
652
+ """Component part name.
653
+
654
+ Returns
655
+ -------
656
+ str
657
+ Component Part Name.
658
+ """
659
+ return self.part_name
660
+
661
+ @partname.setter
662
+ def partname(self, name): # pragma: no cover
663
+ """Set component part name."""
664
+ self.part_name = name
665
+
666
+ @property
667
+ def part_name(self):
668
+ """Component part name.
669
+
670
+ Returns
671
+ -------
672
+ str
673
+ Component part name.
674
+ """
675
+ return self.edbcomponent.GetComponentDef().GetName()
676
+
677
+ @part_name.setter
678
+ def part_name(self, name): # pragma: no cover
679
+ """Set component part name."""
680
+ self.edbcomponent.GetComponentDef().SetName(name)
681
+
682
+ @property
683
+ def _edb(self):
684
+ return self._pedb.edb_api
685
+
686
+ @property
687
+ def placement_layer(self):
688
+ """Placement layer.
689
+
690
+ Returns
691
+ -------
692
+ str
693
+ Name of the placement layer.
694
+ """
695
+ return self.edbcomponent.GetPlacementLayer().Clone().GetName()
696
+
697
+ @property
698
+ def is_top_mounted(self):
699
+ """Check if a component is mounted on top or bottom of the layout.
700
+ Returns
701
+ -------
702
+ bool
703
+ ``True`` component is mounted on top, ``False`` on down.
704
+ """
705
+ signal_layers = [lay.name for lay in list(self._pedb.stackup.signal_layers.values())]
706
+ if self.placement_layer in signal_layers[: int(len(signal_layers) / 2)]:
707
+ return True
708
+ return False
709
+
710
+ @property
711
+ def lower_elevation(self):
712
+ """Lower elevation of the placement layer.
713
+
714
+ Returns
715
+ -------
716
+ float
717
+ Lower elevation of the placement layer.
718
+ """
719
+ return self.edbcomponent.GetPlacementLayer().Clone().GetLowerElevation()
720
+
721
+ @property
722
+ def upper_elevation(self):
723
+ """Upper elevation of the placement layer.
724
+
725
+ Returns
726
+ -------
727
+ float
728
+ Upper elevation of the placement layer.
729
+
730
+ """
731
+ return self.edbcomponent.GetPlacementLayer().Clone().GetUpperElevation()
732
+
733
+ @property
734
+ def top_bottom_association(self):
735
+ """Top/bottom association of the placement layer.
736
+
737
+ Returns
738
+ -------
739
+ int
740
+ Top/bottom association of the placement layer, where:
741
+
742
+ * 0 - Top associated
743
+ * 1 - No association
744
+ * 2 - Bottom associated
745
+ * 4 - Number of top/bottom associations.
746
+ * -1 - Undefined
747
+ """
748
+ return int(self.edbcomponent.GetPlacementLayer().GetTopBottomAssociation())
749
+
750
+ @pyedb_function_handler()
751
+ def _get_edb_value(self, value):
752
+ return self._pedb.edb_value(value)
753
+
754
+ @pyedb_function_handler()
755
+ def _set_model(self, model): # pragma: no cover
756
+ comp_prop = self.component_property
757
+ comp_prop.SetModel(model)
758
+ if not self.edbcomponent.SetComponentProperty(comp_prop):
759
+ logging.error("Fail to assign model on {}.".format(self.refdes))
760
+ return False
761
+ return True
762
+
763
+ @pyedb_function_handler()
764
+ def assign_spice_model(self, file_path, name=None):
765
+ """Assign Spice model to this component.
766
+
767
+ Parameters
768
+ ----------
769
+ file_path : str
770
+ File path of the Spice model.
771
+ name : str, optional
772
+ Name of the Spice model.
773
+
774
+ Returns
775
+ -------
776
+
777
+ """
778
+ if not name:
779
+ name = get_filename_without_extension(file_path)
780
+
781
+ with open(file_path, "r") as f:
782
+ for line in f:
783
+ if "subckt" in line.lower():
784
+ pinNames = [i.strip() for i in re.split(" |\t", line) if i]
785
+ pinNames.remove(pinNames[0])
786
+ pinNames.remove(pinNames[0])
787
+ break
788
+ if len(pinNames) == self.numpins:
789
+ model = self._edb.cell.hierarchy._hierarchy.SPICEModel()
790
+ model.SetModelPath(file_path)
791
+ model.SetModelName(name)
792
+ terminal = 1
793
+ for pn in pinNames:
794
+ model.AddTerminalPinPair(pn, str(terminal))
795
+ terminal += 1
796
+ else: # pragma: no cover
797
+ logging.error("Wrong number of Pins")
798
+ return False
799
+ return self._set_model(model)
800
+
801
+ @pyedb_function_handler()
802
+ def assign_s_param_model(self, file_path, name=None, reference_net=None):
803
+ """Assign S-parameter to this component.
804
+
805
+ Parameters
806
+ ----------
807
+ file_path : str
808
+ File path of the S-parameter model.
809
+ name : str, optional
810
+ Name of the S-parameter model.
811
+
812
+ Returns
813
+ -------
814
+
815
+ """
816
+ if not name:
817
+ name = get_filename_without_extension(file_path)
818
+
819
+ edbComponentDef = self.edbcomponent.GetComponentDef()
820
+ nPortModel = self._edb.definition.NPortComponentModel.FindByName(edbComponentDef, name)
821
+ if nPortModel.IsNull():
822
+ nPortModel = self._edb.definition.NPortComponentModel.Create(name)
823
+ nPortModel.SetReferenceFile(file_path)
824
+ edbComponentDef.AddComponentModel(nPortModel)
825
+
826
+ model = self._edb.cell.hierarchy._hierarchy.SParameterModel()
827
+ model.SetComponentModelName(name)
828
+ if reference_net:
829
+ model.SetReferenceNet(reference_net)
830
+ return self._set_model(model)
831
+
832
+ @pyedb_function_handler()
833
+ def use_s_parameter_model(self, name, reference_net=None):
834
+ """Use S-parameter model on the component.
835
+
836
+ Parameters
837
+ ----------
838
+ name: str
839
+ Name of the S-parameter model.
840
+ reference_net: str, optional
841
+ Reference net of the model.
842
+
843
+ Returns
844
+ -------
845
+ bool
846
+ ``True`` when successful, ``False`` when failed.
847
+
848
+ Examples
849
+ --------
850
+ >>> edbapp = Edb()
851
+ >>>comp_def = edbapp.definitions.components["CAPC3216X180X55ML20T25"]
852
+ >>>comp_def.add_n_port_model("c:GRM32_DC0V_25degC_series.s2p", "GRM32_DC0V_25degC_series")
853
+ >>>edbapp.components["C200"].use_s_parameter_model("GRM32_DC0V_25degC_series")
854
+ """
855
+ model = self._edb.cell.hierarchy._hierarchy.SParameterModel()
856
+ model.SetComponentModelName(name)
857
+ if reference_net:
858
+ model.SetReferenceNet(reference_net)
859
+ return self._set_model(model)
860
+
861
+
862
+ @pyedb_function_handler()
863
+ def assign_rlc_model(self, res=None, ind=None, cap=None, is_parallel=False):
864
+ """Assign RLC to this component.
865
+
866
+ Parameters
867
+ ----------
868
+ res : int, float
869
+ Resistance. Default is ``None``.
870
+ ind : int, float
871
+ Inductance. Default is ``None``.
872
+ cap : int, float
873
+ Capacitance. Default is ``None``.
874
+ is_parallel : bool, optional
875
+ Whether it is a parallel or series RLC component. The default is ``False``.
876
+ """
877
+ if res is None and ind is None and cap is None:
878
+ self._pedb.logger.error("At least one value has to be provided.")
879
+ return False
880
+ r_enabled = True if res else False
881
+ l_enabled = True if ind else False
882
+ c_enabled = True if cap else False
883
+ res = 0 if res is None else res
884
+ ind = 0 if ind is None else ind
885
+ cap = 0 if cap is None else cap
886
+ res, ind, cap = self._get_edb_value(res), self._get_edb_value(ind), self._get_edb_value(cap)
887
+ model = self._edb.cell.hierarchy._hierarchy.PinPairModel()
888
+
889
+ pin_names = list(self.pins.keys())
890
+ for idx, i in enumerate(np.arange(len(pin_names) // 2)):
891
+ pin_pair = self._edb.utility.utility.PinPair(pin_names[idx], pin_names[idx + 1])
892
+
893
+ rlc = self._edb.utility.utility.Rlc(res, r_enabled, ind, l_enabled, cap, c_enabled, is_parallel)
894
+ model.SetPinPairRlc(pin_pair, rlc)
895
+ return self._set_model(model)
896
+
897
+ @pyedb_function_handler()
898
+ def create_clearance_on_component(self, extra_soldermask_clearance=1e-4):
899
+ """Create a Clearance on Soldermask layer by drawing a rectangle.
900
+
901
+ Parameters
902
+ ----------
903
+ extra_soldermask_clearance : float, optional
904
+ Extra Soldermask value in meter to be applied on component bounding box.
905
+
906
+ Returns
907
+ -------
908
+ bool
909
+ """
910
+ bounding_box = self.bounding_box
911
+ opening = [bounding_box[0] - extra_soldermask_clearance]
912
+ opening.append(bounding_box[1] - extra_soldermask_clearance)
913
+ opening.append(bounding_box[2] + extra_soldermask_clearance)
914
+ opening.append(bounding_box[3] + extra_soldermask_clearance)
915
+
916
+ comp_layer = self.placement_layer
917
+ layer_names = list(self._pedb.stackup.stackup_layers.keys())
918
+ layer_index = layer_names.index(comp_layer)
919
+ if comp_layer in [layer_names[0] + layer_names[-1]]:
920
+ return False
921
+ elif layer_index < len(layer_names) / 2:
922
+ soldermask_layer = layer_names[layer_index - 1]
923
+ else:
924
+ soldermask_layer = layer_names[layer_index + 1]
925
+
926
+ if not self._pedb.modeler.get_primitives(layer_name=soldermask_layer):
927
+ all_nets = list(self._pedb.nets.nets.values())
928
+ poly = self._pedb._create_conformal(all_nets, 0, 1e-12, False, 0)
929
+ self._pedb.modeler.create_polygon(poly, soldermask_layer, [], "")
930
+
931
+ void = self._pedb.modeler.create_rectangle(
932
+ soldermask_layer,
933
+ "{}_opening".format(self.refdes),
934
+ lower_left_point=opening[:2],
935
+ upper_right_point=opening[2:],
936
+ )
937
+ void.is_negative = True
938
+ return True