pyedb 0.12.1__py3-none-any.whl → 0.13.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 (40) hide show
  1. pyedb/__init__.py +1 -1
  2. pyedb/configuration/cfg_boundaries.py +1 -1
  3. pyedb/configuration/cfg_common.py +48 -0
  4. pyedb/configuration/cfg_components.py +94 -166
  5. pyedb/configuration/cfg_data.py +12 -7
  6. pyedb/configuration/cfg_general.py +1 -1
  7. pyedb/configuration/cfg_nets.py +1 -1
  8. pyedb/configuration/cfg_operations.py +63 -0
  9. pyedb/configuration/cfg_package_definition.py +128 -0
  10. pyedb/configuration/cfg_padstacks.py +3 -3
  11. pyedb/configuration/cfg_pin_groups.py +1 -1
  12. pyedb/configuration/cfg_ports_sources.py +4 -4
  13. pyedb/configuration/cfg_s_parameter_models.py +1 -1
  14. pyedb/configuration/cfg_setup.py +1 -1
  15. pyedb/configuration/cfg_spice_models.py +1 -1
  16. pyedb/configuration/cfg_stackup.py +169 -0
  17. pyedb/configuration/configuration.py +46 -19
  18. pyedb/dotnet/edb.py +167 -7
  19. pyedb/dotnet/edb_core/cell/hierarchy/model.py +1 -1
  20. pyedb/dotnet/edb_core/{edb_data/connectable.py → cell/layout_obj.py} +1 -1
  21. pyedb/dotnet/edb_core/cell/primitive.py +142 -0
  22. pyedb/dotnet/edb_core/components.py +1 -1
  23. pyedb/dotnet/edb_core/definition/component_def.py +1 -1
  24. pyedb/dotnet/edb_core/definition/component_model.py +1 -1
  25. pyedb/dotnet/edb_core/definition/definition_obj.py +1 -1
  26. pyedb/dotnet/edb_core/definition/package_def.py +2 -1
  27. pyedb/dotnet/edb_core/edb_data/components_data.py +19 -7
  28. pyedb/dotnet/edb_core/edb_data/padstacks_data.py +3 -3
  29. pyedb/dotnet/edb_core/edb_data/primitives_data.py +5 -126
  30. pyedb/dotnet/edb_core/edb_data/terminals.py +2 -2
  31. pyedb/dotnet/edb_core/geometry/polygon_data.py +1 -1
  32. pyedb/dotnet/edb_core/materials.py +2 -1
  33. pyedb/dotnet/edb_core/padstack.py +86 -27
  34. pyedb/generic/general_methods.py +33 -0
  35. pyedb/siwave.py +23 -2
  36. {pyedb-0.12.1.dist-info → pyedb-0.13.0.dist-info}/METADATA +2 -2
  37. {pyedb-0.12.1.dist-info → pyedb-0.13.0.dist-info}/RECORD +40 -35
  38. /pyedb/dotnet/edb_core/{obj_base.py → utilities/obj_base.py} +0 -0
  39. {pyedb-0.12.1.dist-info → pyedb-0.13.0.dist-info}/LICENSE +0 -0
  40. {pyedb-0.12.1.dist-info → pyedb-0.13.0.dist-info}/WHEEL +0 -0
pyedb/__init__.py CHANGED
@@ -44,7 +44,7 @@ deprecation_warning()
44
44
  #
45
45
 
46
46
  pyedb_path = os.path.dirname(__file__)
47
- __version__ = "0.12.1"
47
+ __version__ = "0.13.0"
48
48
  version = __version__
49
49
 
50
50
  #
@@ -25,7 +25,7 @@ from enum import Enum
25
25
 
26
26
  class CfgBoundaries:
27
27
  def __init__(self, pdata, boundaries_dict):
28
- self._pedb = pdata.pedb
28
+ self._pedb = pdata._pedb
29
29
  self._boundaries_dict = boundaries_dict
30
30
  self.open_region = self._boundaries_dict.get("open_region", None)
31
31
  self._map_open_region_type()
@@ -0,0 +1,48 @@
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
+
24
+ from pyedb.generic.general_methods import pyedb_function_handler
25
+
26
+
27
+ class CfgBase:
28
+ @property
29
+ def protected_attributes(self):
30
+ return []
31
+
32
+ @pyedb_function_handler
33
+ def get_attributes(self, exclude=None):
34
+ attrs = {i: j for i, j in self.__dict__.items() if i not in self.protected_attributes}
35
+ if exclude is not None:
36
+ exclude = exclude if isinstance(exclude, list) else [exclude]
37
+ attrs = {i: j for i, j in attrs.items() if i not in exclude}
38
+ attrs = {i: j for i, j in attrs.items() if not i.startswith("_")}
39
+ attrs = {i: j for i, j in attrs.items() if j is not None}
40
+ return attrs
41
+
42
+ @pyedb_function_handler
43
+ def set_attributes(self, pedb_object):
44
+ attrs = self.get_attributes()
45
+ for attr, value in attrs.items():
46
+ if attr not in dir(pedb_object):
47
+ raise AttributeError(f"Invalid attribute '{attr}' in '{pedb_object}'")
48
+ setattr(pedb_object, attr, value)
@@ -20,186 +20,114 @@
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 enum import Enum
24
-
25
-
26
- class CfgRlcModel:
27
- def __init__(self):
28
- self.resistance = 0.0
29
- self.inductance = 0.0
30
- self.capacitance = 0.0
31
- self.rlc_model_type = self.RlcModelType.SERIES
32
- self.enabled = False
33
- self.pin_pairs = []
34
-
35
- class RlcModelType(Enum):
36
- SERIES = 0
37
- PARALLEL = 1
38
-
39
-
40
- class CfgPortProperties:
41
- def __init__(self):
42
- self.ref_offset = 0.0
43
- self.ref_size_auto = True
44
- self.ref_size_x = 0.0
45
- self.ref_size_y = 0.0
46
-
47
-
48
- class CfgSolderBallsProperties:
49
- def __init__(self):
50
- self.shape = self.Shape.CYLINDER
51
- self.diameter = 0.0
52
- self.mid_diameter = 0.0
53
- self.height = 0.0
54
- self.enable = True
55
-
56
- class Shape(Enum):
57
- CYLINDER = 0
58
- SPHEROID = 1
59
-
60
-
61
- class CfgComponent:
62
- def __init__(self, pdata, **kwargs):
63
- self._pedb = pdata.pedb
64
- self._comp_dict = kwargs
65
- self.reference_designator = ""
66
- self.part_type = self.ComponentType.RESISTOR
67
- self.enabled = True
68
- self.rlc_model = CfgRlcModel()
69
- self.port_properties = CfgPortProperties()
70
- self.solder_balls = CfgSolderBallsProperties()
71
- self._update()
72
- self.layout_comp = None
73
-
74
- class ComponentType(Enum):
75
- RESISTOR = 0
76
- INDUCTOR = 1
77
- CAPACITOR = 2
78
- IO = 3
79
- IC = 4
80
- OTHER = 5
81
-
82
- def _update(self):
83
- self.reference_designator = self._comp_dict.get("reference_designator")
84
- self.enabled = self._comp_dict.get("enabled")
85
- part_type = self._comp_dict["part_type"].lower()
86
- if part_type == "resistor":
87
- self.part_type = self.part_type.RESISTOR
88
- elif part_type == "capacitor":
89
- self.part_type = self.part_type.CAPACITOR
90
- elif part_type == "inductor":
91
- self.part_type = self.part_type.INDUCTOR
92
- elif part_type == "io":
93
- self.part_type = self.part_type.IO
94
- elif part_type == "ic":
95
- self.part_type = self.part_type.IC
96
- else:
97
- self.part_type = self.part_type.OTHER
98
-
99
- if self.part_type.value in [0, 1, 2]:
100
- rlc_model = self._comp_dict["rlc_model"] if "rlc_model" in self._comp_dict else None
101
- if rlc_model:
102
- pin_pairs = rlc_model["pin_pairs"] if "pin_pairs" in rlc_model else None
103
- if pin_pairs:
104
- self.rlc_model.pin_pairs = []
105
- for pp in pin_pairs:
106
- if pp["type"] == "Parallel":
107
- self.rlc_model.rlc_model_type = self.rlc_model.rlc_model_type.PARALLEL
108
-
109
- self.rlc_model.pin_pairs.append([pp["p1"], pp["p2"]])
110
- self.rlc_model.resistance = pp["resistance"] if "resistance" in pp else None
111
- self.rlc_model.inductance = pp["inductance"] if "inductance" in pp else None
112
- self.rlc_model.capacitance = pp["capacitance"] if "capacitance" in pp else None
113
-
114
- port_properties = self._comp_dict["port_properties"] if "port_properties" in self._comp_dict else None
115
- if port_properties:
116
- self.port_properties.ref_offset = float(port_properties["reference_offset"])
117
- self.port_properties.ref_size_auto = bool(port_properties["reference_size_auto"])
118
- self.port_properties.ref_size_x = float(port_properties["reference_size_x"])
119
- self.port_properties.ref_size_y = float(port_properties["reference_size_y"])
120
-
121
- solder_ball_properties = (
122
- self._comp_dict["solder_ball_properties"] if "solder_ball_properties" in self._comp_dict else None
23
+ from pyedb.configuration.cfg_common import CfgBase
24
+ from pyedb.generic.general_methods import pyedb_function_handler
25
+
26
+
27
+ class CfgPortProperties(CfgBase):
28
+ def __init__(self, **kwargs):
29
+ self.reference_offset = kwargs.pop("reference_offset", 0)
30
+ self.reference_size_auto = kwargs.pop("reference_size_auto", 0)
31
+ self.reference_size_x = kwargs.pop("reference_size_x", 0)
32
+ self.reference_size_y = kwargs.pop("reference_size_y", 0)
33
+
34
+
35
+ class CfgSolderBallsProperties(CfgBase):
36
+ def __init__(self, **kwargs):
37
+ self.shape = kwargs.pop("shape", None)
38
+ self.diameter = kwargs.pop("diameter", None)
39
+ self.mid_diameter = kwargs.pop("mid_diameter", None)
40
+ self.height = kwargs.pop("height", None)
41
+ self.enabled = kwargs.pop("enabled", None)
42
+
43
+
44
+ class CfgRlcModel(CfgBase):
45
+ def __init__(self, **kwargs):
46
+ self.resistance = kwargs.get("resistance", None)
47
+ self.inductance = kwargs.get("inductance", None)
48
+ self.capacitance = kwargs.get("capacitance", None)
49
+ self.type = kwargs.get("type", None)
50
+ self.p1 = kwargs.get("p1", None)
51
+ self.p2 = kwargs.get("p2", None)
52
+
53
+
54
+ class CfgComponent(CfgBase):
55
+ def __init__(self, **kwargs):
56
+ self.enabled = kwargs.get("enabled", None)
57
+
58
+ self.reference_designator = kwargs.get("reference_designator", None)
59
+ self.type = kwargs.get("part_type", None)
60
+ self.value = kwargs.get("value", None)
61
+ self.port_properties = CfgPortProperties(**kwargs["port_properties"]) if "port_properties" in kwargs else None
62
+ self.solder_ball_properties = (
63
+ CfgSolderBallsProperties(**kwargs["solder_ball_properties"]) if "solder_ball_properties" in kwargs else None
123
64
  )
124
- if solder_ball_properties:
125
- if solder_ball_properties["shape"].lower() == "spheroid":
126
- self.solder_balls.shape = self.solder_balls.shape.SPHEROID
127
- self.solder_balls.diameter = solder_ball_properties["diameter"]
128
- self.solder_balls.mid_diameter = (
129
- float(solder_ball_properties["mid_diameter"])
130
- if "mid_diameter" in solder_ball_properties
131
- else self.solder_balls.diameter
132
- )
133
- self.solder_balls.height = solder_ball_properties["height"]
65
+ rlc_models = kwargs.get("rlc_model", [])
134
66
 
67
+ self.rlc_model = [CfgRlcModel(**rlc_m) for rlc_m in rlc_models]
68
+
69
+ @property
70
+ def protected_attributes(self):
71
+ return ["reference_designator"]
72
+
73
+
74
+ class CfgComponents:
75
+ def __init__(self, pedb, data):
76
+ self._pedb = pedb
77
+ self.components = [CfgComponent(**comp) for comp in data]
78
+
79
+ @pyedb_function_handler
135
80
  def apply(self):
136
- """Apply component on layout."""
137
- self.layout_comp = self._pedb.components[self.reference_designator]
138
- if self.layout_comp:
139
- self._apply_part_type()
140
- if self.part_type.name in ["CAPACITOR", "RESISTOR", "INDUCTOR"]:
141
- self._apply_rlc_model()
142
- else:
143
- self._apply_solder_balls()
144
-
145
- def _apply_part_type(self):
146
- if self.part_type.name == "CAPACITOR":
147
- self.layout_comp.type = "Capacitor"
148
- elif self.part_type.name == "RESISTOR":
149
- self.layout_comp.type = "Resistor"
150
- elif self.part_type.name == "INDUCTOR":
151
- self.layout_comp.type = "Inductor"
152
- elif self.part_type.name == "IC":
153
- self.layout_comp.type = "IC"
154
- elif self.part_type.name == "IO":
155
- self.layout_comp.type = "IO"
156
- elif self.part_type.name == "OTHER":
157
- self.layout_comp.type = "Other"
158
-
159
- def _apply_rlc_model(self):
160
- if self.part_type.value in [0, 1, 2]:
161
- self.layout_comp.is_enabled = self.enabled
162
- if self.rlc_model:
163
- model_layout = self.layout_comp.model
164
- if self.rlc_model.pin_pairs:
81
+ comps_in_db = self._pedb.components
82
+ for comp in self.components:
83
+ c_db = comps_in_db[comp.reference_designator]
84
+
85
+ for attr, value in comp.get_attributes().items(): # All component properties
86
+ if attr == "solder_ball_properties":
87
+ solder_ball_properties = value
88
+ port_properties = comp.port_properties
89
+ self._pedb.components.set_solder_ball(
90
+ component=comp.reference_designator,
91
+ sball_diam=solder_ball_properties.diameter,
92
+ sball_mid_diam=solder_ball_properties.mid_diameter,
93
+ sball_height=solder_ball_properties.height,
94
+ shape=solder_ball_properties.shape,
95
+ auto_reference_size=port_properties.reference_size_auto,
96
+ reference_height=port_properties.reference_offset,
97
+ reference_size_x=port_properties.reference_size_x,
98
+ reference_size_y=port_properties.reference_size_y,
99
+ )
100
+ elif attr == "port_properties":
101
+ pass
102
+ elif attr == "rlc_model":
103
+ rlc_models = value
104
+ model_layout = c_db.model
165
105
  for pp in model_layout.pin_pairs:
166
106
  model_layout.delete_pin_pair_rlc(pp)
167
- for pp in self.rlc_model.pin_pairs:
168
- pin_pair = self._pedb.edb_api.utility.PinPair(pp[0], pp[1])
107
+ for pp in rlc_models:
108
+ pin_pair = self._pedb.edb_api.utility.PinPair(pp.p1, pp.p2)
169
109
  rlc = self._pedb.edb_api.utility.Rlc()
170
- rlc.IsParallel = False if self.rlc_model.rlc_model_type.SERIES else True
171
- if not self.rlc_model.resistance is None:
110
+ rlc.IsParallel = False if pp.type else True
111
+ if pp.resistance is not None:
172
112
  rlc.REnabled = True
173
- rlc.R = self._pedb.edb_value(self.rlc_model.resistance)
113
+ rlc.R = self._pedb.edb_value(pp.resistance)
174
114
  else:
175
115
  rlc.REnabled = False
176
- if not self.rlc_model.inductance is None:
116
+ if pp.inductance is not None:
177
117
  rlc.LEnabled = True
178
- rlc.L = self._pedb.edb_value(self.rlc_model.inductance)
118
+ rlc.L = self._pedb.edb_value(pp.inductance)
179
119
  else:
180
120
  rlc.LEnabled = False
181
121
 
182
- if not self.rlc_model.capacitance is None:
122
+ if pp.capacitance is not None:
183
123
  rlc.CEnabled = True
184
- rlc.C = self._pedb.edb_value(self.rlc_model.capacitance)
124
+ rlc.C = self._pedb.edb_value(pp.capacitance)
185
125
  else:
186
126
  rlc.CEnabled = False
187
127
  model_layout._set_pin_pair_rlc(pin_pair, rlc)
188
- self.layout_comp.model = model_layout
189
-
190
- def _apply_solder_balls(self):
191
- if self.solder_balls.enable:
192
- shape = "Cylinder"
193
- if self.solder_balls.shape == self.solder_balls.shape.SPHEROID:
194
- shape = "Spheroid"
195
- self._pedb.components.set_solder_ball(
196
- component=self.reference_designator,
197
- sball_diam=self.solder_balls.diameter,
198
- sball_mid_diam=self.solder_balls.mid_diameter,
199
- sball_height=self.solder_balls.height,
200
- shape=shape,
201
- auto_reference_size=self.port_properties.ref_size_auto,
202
- reference_height=self.port_properties.ref_offset,
203
- reference_size_x=self.port_properties.ref_size_x,
204
- reference_size_y=self.port_properties.ref_size_y,
205
- )
128
+ comps_in_db.model = model_layout
129
+ else:
130
+ if attr in dir(c_db):
131
+ setattr(c_db, attr, value)
132
+ else:
133
+ raise AttributeError(f"'{attr}' is not valid component attribute.")
@@ -20,24 +20,28 @@
20
20
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
21
  # SOFTWARE.
22
22
 
23
+
23
24
  from pyedb.configuration.cfg_boundaries import CfgBoundaries
24
- from pyedb.configuration.cfg_components import CfgComponent
25
+ from pyedb.configuration.cfg_components import CfgComponents
25
26
  from pyedb.configuration.cfg_general import CfgGeneral
26
27
  from pyedb.configuration.cfg_nets import CfgNets
28
+ from pyedb.configuration.cfg_operations import CfgOperations
29
+ from pyedb.configuration.cfg_package_definition import CfgPackageDefinitions
27
30
  from pyedb.configuration.cfg_padstacks import CfgPadstacks
28
31
  from pyedb.configuration.cfg_pin_groups import CfgPinGroup
29
32
  from pyedb.configuration.cfg_ports_sources import CfgPort, CfgSources
30
33
  from pyedb.configuration.cfg_s_parameter_models import CfgSParameterModel
31
34
  from pyedb.configuration.cfg_setup import CfgSetup
32
35
  from pyedb.configuration.cfg_spice_models import CfgSpiceModel
36
+ from pyedb.configuration.cfg_stackup import CfgStackup
33
37
 
34
38
 
35
39
  class CfgData(object):
36
40
  """Manages configure data."""
37
41
 
38
42
  def __init__(self, pedb, **kwargs):
39
- self.pedb = pedb
40
- self.edb_comps = self.pedb.components.components
43
+ self._pedb = pedb
44
+ self.edb_comps = self._pedb.components.components
41
45
  self.general = CfgGeneral(self, kwargs.get("general", None))
42
46
 
43
47
  self.boundaries = {}
@@ -50,7 +54,8 @@ class CfgData(object):
50
54
  self, kwargs.get("nets", {}).get("signal_nets", []), kwargs.get("nets", {}).get("power_ground_nets", [])
51
55
  )
52
56
 
53
- self.components = [CfgComponent(self, **component) for component in kwargs.get("components", [])]
57
+ # self.components = [CfgComponent(self, **component) for component in kwargs.get("components", [])]
58
+ self.components = CfgComponents(self._pedb, data=kwargs.get("components", []))
54
59
 
55
60
  self.padstacks = CfgPadstacks(self, kwargs.get("padstacks", None))
56
61
 
@@ -64,7 +69,7 @@ class CfgData(object):
64
69
  if kwargs.get("setups", None):
65
70
  self.setups = [CfgSetup(self, setup) for setup in kwargs.get("setups", [])]
66
71
 
67
- self.stackup = None
72
+ self.stackup = CfgStackup(self._pedb, data=kwargs.get("stackup", {}))
68
73
 
69
74
  self.s_parameters = [
70
75
  CfgSParameterModel(self, self.general.s_parameter_library, sparam_model)
@@ -76,5 +81,5 @@ class CfgData(object):
76
81
  for spice_model in kwargs.get("spice_models", [])
77
82
  ]
78
83
 
79
- self.package_definition = None
80
- self.operations = None
84
+ self.package_definitions = CfgPackageDefinitions(self._pedb, data=kwargs.get("package_definitions", []))
85
+ self.operations = CfgOperations(self._pedb, data=kwargs.get("operations", []))
@@ -25,7 +25,7 @@ class CfgGeneral:
25
25
  """Manage configuration general settings."""
26
26
 
27
27
  def __init__(self, pdata, general_dict):
28
- self._pedb = pdata.pedb
28
+ self._pedb = pdata._pedb
29
29
  self.spice_model_library = ""
30
30
  self.s_parameter_library = ""
31
31
  if general_dict:
@@ -25,7 +25,7 @@ class CfgNets:
25
25
  """Manage configuration net class."""
26
26
 
27
27
  def __init__(self, pdata, signal_nets=None, power_nets=None):
28
- self._pedb = pdata.pedb
28
+ self._pedb = pdata._pedb
29
29
  self.signal_nets = []
30
30
  self.power_nets = []
31
31
  if signal_nets:
@@ -0,0 +1,63 @@
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_common import CfgBase
24
+ from pyedb.generic.general_methods import pyedb_function_handler
25
+
26
+
27
+ class CfgCutout(CfgBase):
28
+ def __init__(self, **kwargs):
29
+ self.signal_list = kwargs.get("signal_list")
30
+ self.reference_list = kwargs.get("reference_list")
31
+ self.extent_type = kwargs.get("extent_type")
32
+ self.expansion_size = kwargs.get("expansion_size")
33
+ self.use_round_corner = kwargs.get("use_round_corner")
34
+ self.output_aedb_path = kwargs.get("output_aedb_path")
35
+ self.open_cutout_at_end = kwargs.get("open_cutout_at_end")
36
+ self.use_pyaedt_cutout = kwargs.get("use_pyaedt_cutout")
37
+ self.number_of_threads = kwargs.get("number_of_threads")
38
+ self.use_pyaedt_extent_computing = kwargs.get("use_pyaedt_extent_computing")
39
+ self.extent_defeature = kwargs.get("extent_defeature")
40
+ self.remove_single_pin_components = kwargs.get("remove_single_pin_components")
41
+ self.custom_extent = kwargs.get("custom_extent")
42
+ self.custom_extent_units = kwargs.get("custom_extent_units")
43
+ self.include_partial_instances = kwargs.get("include_partial_instances")
44
+ self.keep_voids = kwargs.get("keep_voids")
45
+ self.check_terminals = kwargs.get("check_terminals")
46
+ self.include_pingroups = kwargs.get("include_pingroups")
47
+ self.expansion_factor = kwargs.get("expansion_factor")
48
+ self.maximum_iterations = kwargs.get("maximum_iterations")
49
+ self.preserve_components_with_model = kwargs.get("preserve_components_with_model")
50
+ self.simple_pad_check = kwargs.get("simple_pad_check")
51
+ self.keep_lines_as_path = kwargs.get("keep_lines_as_path")
52
+
53
+
54
+ class CfgOperations(CfgBase):
55
+ def __init__(self, pedb, data):
56
+ self._pedb = pedb
57
+ self.op_cutout = CfgCutout(**data["cutout"]) if "cutout" in data else None
58
+
59
+ @pyedb_function_handler
60
+ def apply(self):
61
+ """Imports operation information from JSON."""
62
+ if self.op_cutout:
63
+ self._pedb.cutout(**self.op_cutout.get_attributes())
@@ -0,0 +1,128 @@
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_common import CfgBase
24
+ from pyedb.dotnet.edb_core.definition.package_def import PackageDef
25
+ from pyedb.generic.general_methods import pyedb_function_handler
26
+
27
+
28
+ class CfgPackage(CfgBase):
29
+ """Configuration package class."""
30
+
31
+ def __init__(self, **kwargs):
32
+ self.name = kwargs.get("name", None)
33
+ self.component_definition = kwargs.get("component_definition", None)
34
+ self.maximum_power = kwargs.get("maximum_power", None)
35
+ self.therm_cond = kwargs.get("therm_cond", None)
36
+ self.theta_jb = kwargs.get("theta_jb", None)
37
+ self.theta_jc = kwargs.get("theta_jc", None)
38
+ self.height = kwargs.get("height", None)
39
+ self.apply_to_all = kwargs.get("apply_to_all", None)
40
+ self.components = kwargs.get("components", [])
41
+ self.extent_bounding_box = kwargs.get("extent_bounding_box", None)
42
+ self._heatsink = CfgHeatSink(**kwargs["heatsink"]) if "heatsink" in kwargs else None
43
+
44
+ @property
45
+ def heatsink(self):
46
+ return self._heatsink
47
+
48
+ @heatsink.setter
49
+ def heatsink(self, value):
50
+ self._heatsink = value
51
+
52
+ @property
53
+ def protected_attributes(self):
54
+ """Attributes cannot be set to package definition class or don't exist in package definition class."""
55
+ return ["apply_to_all", "components", "extent_bounding_box", "component_definition"]
56
+
57
+
58
+ class CfgHeatSink(CfgBase):
59
+ """Configuration heat sink class."""
60
+
61
+ def __init__(self, **kwargs):
62
+ self.fin_base_height = kwargs.get("fin_base_height", None)
63
+ self.fin_height = kwargs.get("fin_height", None)
64
+ self.fin_orientation = kwargs.get("fin_orientation", None)
65
+ self.fin_spacing = kwargs.get("fin_spacing", None)
66
+ self.fin_thickness = kwargs.get("fin_thickness", None)
67
+
68
+
69
+ class CfgPackageDefinitions:
70
+ def __init__(self, pedb, data):
71
+ self._pedb = pedb
72
+ self.packages = [CfgPackage(**package) for package in data]
73
+
74
+ def apply(self):
75
+ for pkg in self.packages:
76
+ comp_def_from_db = self._pedb.definitions.component[pkg.component_definition]
77
+ if pkg.name in self._pedb.definitions.package:
78
+ self._pedb.definitions.package[pkg.name].delete()
79
+
80
+ if pkg.extent_bounding_box:
81
+ package_def = PackageDef(self._pedb, name=pkg.name, extent_bounding_box=pkg.extent_bounding_box)
82
+ else:
83
+ package_def = PackageDef(self._pedb, name=pkg.name, component_part_name=pkg.component_definition)
84
+ pkg.set_attributes(package_def)
85
+
86
+ if pkg.heatsink:
87
+ attrs = pkg.heatsink.get_attributes()
88
+ for attr, value in attrs.items():
89
+ package_def.set_heatsink(**attrs)
90
+
91
+ comp_list = dict()
92
+ if pkg.apply_to_all:
93
+ comp_list.update(
94
+ {
95
+ refdes: comp
96
+ for refdes, comp in comp_def_from_db.components.items()
97
+ if refdes not in pkg.components
98
+ }
99
+ )
100
+ else:
101
+ comp_list.update(
102
+ {refdes: comp for refdes, comp in comp_def_from_db.components.items() if refdes in pkg.components}
103
+ )
104
+ for _, i in comp_list.items():
105
+ i.package_def = pkg.name
106
+
107
+ @pyedb_function_handler
108
+ def get_data_from_db(self):
109
+ package_definitions = []
110
+
111
+ for pkg_name, pkg_obj in self._pedb.definitions.package.items():
112
+ pkg = {}
113
+ pkg_attrs = [i for i in dir(pkg_obj) if not i.startswith("_")]
114
+ pkg_attrs = {i for i in pkg_attrs if i in CfgPackage().__dict__}
115
+ for pkg_attr_name in pkg_attrs:
116
+ pkg[pkg_attr_name] = getattr(pkg_obj, pkg_attr_name)
117
+
118
+ hs_obj = pkg_obj.heatsink
119
+ if hs_obj:
120
+ hs = {}
121
+ hs_attrs = [i for i in dir(hs_obj) if not i.startswith("_")]
122
+ hs_attrs = [i for i in hs_attrs if i in CfgHeatSink().__dict__]
123
+ for hs_attr_name in hs_attrs:
124
+ hs[hs_attr_name] = getattr(hs_obj, hs_attr_name)
125
+ pkg["heatsink"] = hs
126
+ package_definitions.append(pkg)
127
+
128
+ return package_definitions
@@ -28,7 +28,7 @@ class CfgPadstacks:
28
28
  """Padstack data class."""
29
29
 
30
30
  def __init__(self, pdata, padstack_dict=None):
31
- self._pedb = pdata.pedb
31
+ self._pedb = pdata._pedb
32
32
  self.definitions = []
33
33
  self.instances = []
34
34
  self._padstack_dict = padstack_dict
@@ -52,7 +52,7 @@ class Definition:
52
52
  """Padstack definition data class."""
53
53
 
54
54
  def __init__(self, pdata, definition_dict):
55
- self._pedb = pdata.pedb
55
+ self._pedb = pdata._pedb
56
56
  self._definition_dict = definition_dict
57
57
  self.name = self._definition_dict.get("name", None)
58
58
  self.hole_diameter = self._definition_dict.get("hole_diameter", None)
@@ -78,7 +78,7 @@ class Instance:
78
78
  """Instance data class."""
79
79
 
80
80
  def __init__(self, pdata, instances_dict):
81
- self._pedb = pdata.pedb
81
+ self._pedb = pdata._pedb
82
82
  self._instances_dict = instances_dict
83
83
  self.name = self._instances_dict.get("name", "")
84
84
  self.backdrill_top = None
@@ -25,7 +25,7 @@ class CfgPinGroup:
25
25
  """Manage configuration pin group class."""
26
26
 
27
27
  def __init__(self, pdata, pingroup_dict):
28
- self._pedb = pdata.pedb
28
+ self._pedb = pdata._pedb
29
29
  self._pingroup_dict = pingroup_dict
30
30
  self.name = self._pingroup_dict.get("name", "")
31
31
  self.reference_designator = self._pingroup_dict.get("reference_designator", "")