pyedb 0.27.0__py3-none-any.whl → 0.29.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.
Files changed (34) hide show
  1. pyedb/__init__.py +1 -1
  2. pyedb/configuration/cfg_boundaries.py +44 -74
  3. pyedb/configuration/cfg_common.py +1 -1
  4. pyedb/configuration/cfg_components.py +31 -105
  5. pyedb/configuration/cfg_data.py +4 -9
  6. pyedb/configuration/cfg_operations.py +19 -13
  7. pyedb/configuration/cfg_padstacks.py +66 -89
  8. pyedb/configuration/cfg_pin_groups.py +7 -8
  9. pyedb/configuration/cfg_ports_sources.py +4 -2
  10. pyedb/configuration/cfg_s_parameter_models.py +85 -29
  11. pyedb/configuration/configuration.py +48 -13
  12. pyedb/dotnet/application/Variables.py +43 -41
  13. pyedb/dotnet/edb.py +12 -4
  14. pyedb/dotnet/edb_core/cell/hierarchy/component.py +199 -0
  15. pyedb/dotnet/edb_core/cell/layout.py +4 -1
  16. pyedb/dotnet/edb_core/cell/primitive/primitive.py +2 -0
  17. pyedb/dotnet/edb_core/cell/terminal/pingroup_terminal.py +3 -3
  18. pyedb/dotnet/edb_core/cell/terminal/terminal.py +4 -3
  19. pyedb/dotnet/edb_core/definition/component_def.py +17 -1
  20. pyedb/dotnet/edb_core/definition/component_model.py +0 -4
  21. pyedb/dotnet/edb_core/edb_data/hfss_extent_info.py +3 -3
  22. pyedb/dotnet/edb_core/edb_data/nets_data.py +10 -7
  23. pyedb/dotnet/edb_core/edb_data/padstacks_data.py +301 -45
  24. pyedb/dotnet/edb_core/edb_data/primitives_data.py +2 -2
  25. pyedb/dotnet/edb_core/general.py +11 -0
  26. pyedb/dotnet/edb_core/layout_validation.py +3 -3
  27. pyedb/dotnet/edb_core/modeler.py +5 -2
  28. pyedb/dotnet/edb_core/nets.py +162 -181
  29. pyedb/edb_logger.py +1 -1
  30. pyedb/siwave.py +33 -7
  31. {pyedb-0.27.0.dist-info → pyedb-0.29.0.dist-info}/METADATA +5 -5
  32. {pyedb-0.27.0.dist-info → pyedb-0.29.0.dist-info}/RECORD +34 -34
  33. {pyedb-0.27.0.dist-info → pyedb-0.29.0.dist-info}/LICENSE +0 -0
  34. {pyedb-0.27.0.dist-info → pyedb-0.29.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.27.0"
47
+ __version__ = "0.29.0"
48
48
  version = __version__
49
49
 
50
50
  #
@@ -20,97 +20,50 @@
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
23
+ from pyedb.configuration.cfg_common import CfgBase
24
24
 
25
25
 
26
- class CfgBoundaries:
27
- def __init__(self, pdata, boundaries_dict):
28
- self._pedb = pdata._pedb
29
- self._boundaries_dict = boundaries_dict
30
- self.open_region = self._boundaries_dict.get("open_region", None)
31
- self._map_open_region_type()
32
- self.pml_visible = self._boundaries_dict.get("pml_visible", None)
33
- self.pml_operation_frequency = self._boundaries_dict.get("pml_operation_frequency", None)
34
- self.pml_radiation_factor = self._boundaries_dict.get("pml_radiation_factor", None)
35
- self._map_dielectric_extend_type()
36
- self.dielectric_base_polygon = self._boundaries_dict.get("dielectric_base_polygon", None)
37
- self.horizontal_padding = self._boundaries_dict.get("horizontal_padding", None)
38
- self.honor_primitives_on_dielectric_layers = self._boundaries_dict.get(
39
- "honor_primitives_on_dielectric_layers", False
40
- )
41
- self._map_air_box_extend_type()
42
- self.air_box_base_polygon = self._boundaries_dict.get("air_box_base_polygon", None)
43
- self.air_box_truncate_model_ground_layers = self._boundaries_dict.get(
44
- "air_box_truncate_model_ground_layers", None
45
- )
46
- self.air_box_horizontal_padding = self._boundaries_dict.get("air_box_horizontal_padding", None)
47
- self.air_box_positive_vertical_padding = self._boundaries_dict.get("air_box_positive_vertical_padding", None)
48
- self.air_box_negative_vertical_padding = self._boundaries_dict.get("air_box_negative_vertical_padding", None)
49
-
50
- def _map_air_box_extend_type(self):
51
- air_box_type = self._boundaries_dict.get("air_box_extents_type", None)
52
- if air_box_type == "bounding_box":
53
- self.air_box_extents_type = self.ExtentType.BOUNDING_BOX
54
- elif air_box_type == "conformal":
55
- self.air_box_extents_type = self.ExtentType.CONFORMAL
56
- elif air_box_type == "convex_hull":
57
- self.air_box_extents_type = self.ExtentType.CONVEX_HULL
58
- elif air_box_type == "polygon":
59
- self.air_box_extents_type = self.ExtentType.POLYGON
60
- else:
61
- self.air_box_extents_type = self.ExtentType.BOUNDING_BOX
62
-
63
- def _map_open_region_type(self):
64
- open_region = self._boundaries_dict.get("open_region_type", None)
65
- if open_region == "radiation":
66
- self.open_region_type = self.OpenRegionType.RADIATION
67
- elif open_region == "pec":
68
- self.open_region_type = self.OpenRegionType.PEC
69
- else:
70
- self.open_region_type = self.OpenRegionType.RADIATION
71
-
72
- def _map_dielectric_extend_type(self):
73
- extend_type = self._boundaries_dict.get("dielectric_extents_type", None)
74
- if extend_type == "bounding_box":
75
- self.dielectric_extents_type = self.ExtentType.BOUNDING_BOX
76
- elif extend_type == "conformal":
77
- self.dielectric_extents_type = self.ExtentType.CONFORMAL
78
- elif extend_type == "convex_hull":
79
- self.dielectric_extents_type = self.ExtentType.CONVEX_HULL
80
- elif extend_type == "polygon":
81
- self.dielectric_extents_type = self.ExtentType.POLYGON
82
- else:
83
- self.dielectric_extents_type = self.ExtentType.BOUNDING_BOX
84
-
85
- class OpenRegionType(Enum):
86
- RADIATION = 0
87
- PEC = 1
88
-
89
- class ExtentType(Enum):
90
- BOUNDING_BOX = 0
91
- CONFORMAL = 1
92
- CONVEX_HULL = 2
93
- POLYGON = 3
26
+ class CfgBoundaries(CfgBase):
27
+ def __init__(self, pedb, boundary_data):
28
+ self._pedb = pedb
29
+ self.open_region = boundary_data.get("open_region", None)
30
+ self.open_region_type = boundary_data.get("map_open_region_type", None)
31
+ self.pml_visible = boundary_data.get("pml_visible", None)
32
+ self.pml_operation_frequency = boundary_data.get("pml_operation_frequency", None)
33
+ self.pml_radiation_factor = boundary_data.get("pml_radiation_factor", None)
34
+ self.dielectric_extent_type = boundary_data.get("dielectric_extent_type", None)
35
+ # self.dielectric_base_polygon = self.**kwargs.get("dielectric_base_polygon", None)
36
+ self.horizontal_padding = boundary_data.get("horizontal_padding", None)
37
+ self.honor_primitives_on_dielectric_layers = boundary_data.get("honor_primitives_on_dielectric_layers", False)
38
+ self.air_box_extent_type = boundary_data.get("air_box_extent_type", None)
39
+ self.air_box_base_polygon = boundary_data.get("air_box_base_polygon", None)
40
+ self.air_box_truncate_model_ground_layers = boundary_data.get("air_box_truncate_model_ground_layers", None)
41
+ self.air_box_horizontal_padding = boundary_data.get("air_box_horizontal_padding", None)
42
+ self.air_box_positive_vertical_padding = boundary_data.get("air_box_positive_vertical_padding", None)
43
+ self.air_box_negative_vertical_padding = boundary_data.get("air_box_negative_vertical_padding", None)
94
44
 
95
45
  def apply(self):
96
46
  """Imports boundary information from JSON."""
97
47
  if self.open_region is not None:
98
48
  self._pedb.hfss.hfss_extent_info.use_open_region = self.open_region
99
- self._pedb.hfss.hfss_extent_info.open_region_type = self.open_region_type.name.lower()
49
+ if self.open_region_type:
50
+ self._pedb.hfss.hfss_extent_info.open_region_type = self.open_region_type.lower()
100
51
  if self.pml_visible is not None:
101
52
  self._pedb.hfss.hfss_extent_info.is_pml_visible = self.pml_visible
102
53
  if self.pml_operation_frequency:
103
54
  self._pedb.hfss.hfss_extent_info.operating_freq = self.pml_operation_frequency
104
55
  if self.pml_radiation_factor:
105
56
  self._pedb.hfss.hfss_extent_info.radiation_level = self.pml_radiation_factor
106
- self._pedb.hfss.hfss_extent_info.extent_type = self.dielectric_extents_type.name.lower()
107
- if self.dielectric_base_polygon:
108
- self._pedb.hfss.hfss_extent_info.dielectric_base_polygon = self.dielectric_base_polygon
57
+ if self.dielectric_extent_type:
58
+ self._pedb.hfss.hfss_extent_info.extent_type = self.dielectric_extent_type.lower()
59
+ # if self.dielectric_base_polygon:
60
+ # self._pedb.hfss.hfss_extent_info.dielectric_base_polygon = self.dielectric_base_polygon
109
61
  if self.horizontal_padding:
110
62
  self._pedb.hfss.hfss_extent_info.dielectric_extent_size = float(self.horizontal_padding)
111
63
  if self.honor_primitives_on_dielectric_layers is not None:
112
64
  self._pedb.hfss.hfss_extent_info.honor_user_dielectric = self.honor_primitives_on_dielectric_layers
113
- self._pedb.hfss.hfss_extent_info.extent_type = self.air_box_extents_type.name.lower()
65
+ if self.air_box_extent_type:
66
+ self._pedb.hfss.hfss_extent_info.extent_type = self.air_box_extent_type.lower()
114
67
  if self.air_box_truncate_model_ground_layers is not None:
115
68
  self._pedb.hfss.hfss_extent_info.truncate_air_box_at_ground = self.air_box_truncate_model_ground_layers
116
69
  if self.air_box_horizontal_padding:
@@ -123,3 +76,20 @@ class CfgBoundaries:
123
76
  self._pedb.hfss.hfss_extent_info.air_box_negative_vertical_extent = float(
124
77
  self.air_box_negative_vertical_padding
125
78
  )
79
+
80
+ def get_data_from_db(self):
81
+ self.open_region = self._pedb.hfss.hfss_extent_info.use_open_region
82
+ self.open_region_type = self._pedb.hfss.hfss_extent_info.open_region_type
83
+ self.pml_visible = self._pedb.hfss.hfss_extent_info.is_pml_visible
84
+ self.pml_operation_frequency = self._pedb.hfss.hfss_extent_info.operating_freq.tostring
85
+ self.pml_radiation_factor = self._pedb.hfss.hfss_extent_info.radiation_level.tostring
86
+ self.dielectric_extent_type = self._pedb.hfss.hfss_extent_info.extent_type
87
+ # self.dielectric_base_polygon = self._pedb.hfss.hfss_extent_info.dielectric_base_polygon
88
+ self.horizontal_padding = self._pedb.hfss.hfss_extent_info.dielectric_extent_size
89
+ self.honor_primitives_on_dielectric_layers = self._pedb.hfss.hfss_extent_info.honor_user_dielectric
90
+ self.air_box_extent_type = self._pedb.hfss.hfss_extent_info.extent_type
91
+ self.air_box_truncate_model_ground_layers = self._pedb.hfss.hfss_extent_info.truncate_air_box_at_ground
92
+ self.air_box_horizontal_padding = self._pedb.hfss.hfss_extent_info.air_box_horizontal_extent
93
+ self.air_box_positive_vertical_padding = self._pedb.hfss.hfss_extent_info.air_box_positive_vertical_extent
94
+ self.air_box_negative_vertical_padding = self._pedb.hfss.hfss_extent_info.air_box_negative_vertical_extent
95
+ return self.get_attributes()
@@ -30,7 +30,7 @@ class CfgBase:
30
30
  exclude = exclude if isinstance(exclude, list) else [exclude]
31
31
  attrs = {i: j for i, j in attrs.items() if i not in exclude}
32
32
  attrs = {i: j for i, j in attrs.items() if not i.startswith("_")}
33
- attrs = {i: j for i, j in attrs.items() if j is not None}
33
+ attrs = {i: j for i, j in attrs.items() if j not in [None, [], {}]}
34
34
  return attrs
35
35
 
36
36
  def set_attributes(self, pedb_object):
@@ -23,23 +23,6 @@
23
23
  from pyedb.configuration.cfg_common import CfgBase
24
24
 
25
25
 
26
- class CfgPortProperties(CfgBase):
27
- def __init__(self, **kwargs):
28
- self.reference_offset = kwargs.pop("reference_offset", 0)
29
- self.reference_size_auto = kwargs.pop("reference_size_auto", 0)
30
- self.reference_size_x = kwargs.pop("reference_size_x", 0)
31
- self.reference_size_y = kwargs.pop("reference_size_y", 0)
32
-
33
-
34
- class CfgSolderBallsProperties(CfgBase):
35
- def __init__(self, **kwargs):
36
- self.shape = kwargs.pop("shape", None)
37
- self.diameter = kwargs.pop("diameter", None)
38
- self.mid_diameter = kwargs.pop("mid_diameter", None)
39
- self.height = kwargs.pop("height", None)
40
- self.enabled = kwargs.pop("enabled", None)
41
-
42
-
43
26
  class CfgRlcModel(CfgBase):
44
27
  def __init__(self, **kwargs):
45
28
  self.resistance = kwargs.get("resistance", None)
@@ -51,45 +34,17 @@ class CfgRlcModel(CfgBase):
51
34
 
52
35
 
53
36
  class CfgComponent(CfgBase):
54
- protected_attributes = ["reference_designator", "definition", "location", "angle", "placement_layer"]
55
-
56
37
  def __init__(self, **kwargs):
57
38
  self.enabled = kwargs.get("enabled", None)
58
-
59
39
  self.reference_designator = kwargs.get("reference_designator", None)
60
40
  self.definition = kwargs.get("definition", None)
61
- self.type = kwargs.get("part_type", None)
62
- self.value = kwargs.get("value", None)
63
- self.port_properties = CfgPortProperties(**kwargs["port_properties"]) if "port_properties" in kwargs else None
64
- self.solder_ball_properties = (
65
- CfgSolderBallsProperties(**kwargs["solder_ball_properties"]) if "solder_ball_properties" in kwargs else None
66
- )
67
- rlc_models = kwargs.get("rlc_model", [])
68
-
69
- self.rlc_model = [CfgRlcModel(**rlc_m) for rlc_m in rlc_models]
70
-
71
- self.x_location, self.y_location = kwargs.get("location", [None, None])
72
- self.angle = kwargs.get("angle", None)
73
- self.placement_layer = kwargs.get("placement_layer", None)
74
-
75
- def export_properties(self):
76
- """Export component properties.
77
-
78
- Returns
79
- -------
80
- Dict
81
- """
82
- data_comp = {}
83
- data_comp["enabled"] = self.enabled
84
- data_comp["reference_designator"] = self.reference_designator
85
- data_comp["definition"] = self.definition
86
- data_comp["type"] = self.type
87
- data_comp["value"] = self.value
88
- data_comp["x_location"] = self.x_location
89
- data_comp["y_location"] = self.y_location
90
- # data_comp["angle"] = self.angle
91
- data_comp["placement_layer"] = self.placement_layer
92
- return data_comp
41
+ self.type = kwargs["part_type"].lower() if kwargs.get("part_type") else None
42
+ self.port_properties = kwargs.get("port_properties", {})
43
+ self.solder_ball_properties = kwargs.get("solder_ball_properties", {})
44
+ self.ic_die_properties = kwargs.get("ic_die_properties", {})
45
+ self.pin_pair_model = kwargs.get("pin_pair_model", None)
46
+ self.spice_model = kwargs.get("spice_model", None)
47
+ self.s_parameter_model = kwargs.get("s_parameter_model", None)
93
48
 
94
49
 
95
50
  class CfgComponents:
@@ -98,59 +53,25 @@ class CfgComponents:
98
53
  self.components = [CfgComponent(**comp) for comp in components_data]
99
54
 
100
55
  def apply(self):
101
- comps_in_db = self._pedb.components
56
+ comps_in_db = self._pedb.components.components
102
57
  for comp in self.components:
103
58
  c_db = comps_in_db[comp.reference_designator]
104
-
105
- for attr, value in comp.get_attributes().items(): # All component properties
106
- if attr == "solder_ball_properties":
107
- solder_ball_properties = value
108
- port_properties = comp.port_properties
109
- self._pedb.components.set_solder_ball(
110
- component=comp.reference_designator,
111
- sball_diam=solder_ball_properties.diameter,
112
- sball_mid_diam=solder_ball_properties.mid_diameter,
113
- sball_height=solder_ball_properties.height,
114
- shape=solder_ball_properties.shape,
115
- auto_reference_size=port_properties.reference_size_auto,
116
- reference_height=port_properties.reference_offset,
117
- reference_size_x=port_properties.reference_size_x,
118
- reference_size_y=port_properties.reference_size_y,
119
- )
120
- elif attr == "port_properties":
121
- pass
122
- elif attr == "rlc_model":
123
- rlc_models = value
124
- model_layout = c_db.model
125
- for pp in model_layout.pin_pairs:
126
- model_layout.delete_pin_pair_rlc(pp)
127
- for pp in rlc_models:
128
- pin_pair = self._pedb.edb_api.utility.PinPair(pp.p1, pp.p2)
129
- rlc = self._pedb.edb_api.utility.Rlc()
130
- rlc.IsParallel = False if pp.type else True
131
- if pp.resistance is not None:
132
- rlc.REnabled = True
133
- rlc.R = self._pedb.edb_value(pp.resistance)
134
- else:
135
- rlc.REnabled = False
136
- if pp.inductance is not None:
137
- rlc.LEnabled = True
138
- rlc.L = self._pedb.edb_value(pp.inductance)
139
- else:
140
- rlc.LEnabled = False
141
-
142
- if pp.capacitance is not None:
143
- rlc.CEnabled = True
144
- rlc.C = self._pedb.edb_value(pp.capacitance)
145
- else:
146
- rlc.CEnabled = False
147
- model_layout._set_pin_pair_rlc(pin_pair, rlc)
148
- comps_in_db.model = model_layout
149
- else:
150
- if attr in dir(c_db):
151
- setattr(c_db, attr, value)
152
- else:
153
- raise AttributeError(f"'{attr}' is not valid component attribute.")
59
+ if comp.definition:
60
+ c_db.definition = comp.definition
61
+ if comp.type:
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.set_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}
154
75
 
155
76
  def _load_data_from_db(self):
156
77
  self.components = []
@@ -160,10 +81,15 @@ class CfgComponents:
160
81
  enabled=comp.enabled,
161
82
  reference_designator=comp.name,
162
83
  part_type=comp.type,
163
- value=comp.value,
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"),
164
87
  definition=comp.component_def,
165
88
  location=comp.location,
166
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,
167
93
  )
168
94
  self.components.append(cfg_comp)
169
95
 
@@ -171,5 +97,5 @@ class CfgComponents:
171
97
  self._load_data_from_db()
172
98
  data = []
173
99
  for comp in self.components:
174
- data.append(comp.export_properties())
100
+ data.append(comp.get_attributes())
175
101
  return data
@@ -30,7 +30,7 @@ from pyedb.configuration.cfg_package_definition import CfgPackageDefinitions
30
30
  from pyedb.configuration.cfg_padstacks import CfgPadstacks
31
31
  from pyedb.configuration.cfg_pin_groups import CfgPinGroups
32
32
  from pyedb.configuration.cfg_ports_sources import CfgPorts, CfgSources
33
- from pyedb.configuration.cfg_s_parameter_models import CfgSParameterModel
33
+ from pyedb.configuration.cfg_s_parameter_models import CfgSParameters
34
34
  from pyedb.configuration.cfg_setup import CfgSetups
35
35
  from pyedb.configuration.cfg_spice_models import CfgSpiceModel
36
36
  from pyedb.configuration.cfg_stackup import CfgStackup
@@ -43,9 +43,7 @@ class CfgData(object):
43
43
  self._pedb = pedb
44
44
  self.general = CfgGeneral(self, kwargs.get("general", None))
45
45
 
46
- self.boundaries = {}
47
- if kwargs.get("boundaries", None):
48
- self.boundaries = CfgBoundaries(self, kwargs.get("boundaries", None))
46
+ self.boundaries = CfgBoundaries(self._pedb, kwargs.get("boundaries", {}))
49
47
 
50
48
  self.nets = CfgNets(
51
49
  self, kwargs.get("nets", {}).get("signal_nets", []), kwargs.get("nets", {}).get("power_ground_nets", [])
@@ -53,7 +51,7 @@ class CfgData(object):
53
51
 
54
52
  self.components = CfgComponents(self._pedb, components_data=kwargs.get("components", []))
55
53
 
56
- self.padstacks = CfgPadstacks(self, kwargs.get("padstacks", None))
54
+ self.padstacks = CfgPadstacks(self._pedb, kwargs.get("padstacks", None))
57
55
 
58
56
  self.pin_groups = CfgPinGroups(self._pedb, pingroup_data=kwargs.get("pin_groups", []))
59
57
 
@@ -65,10 +63,7 @@ class CfgData(object):
65
63
 
66
64
  self.stackup = CfgStackup(self._pedb, data=kwargs.get("stackup", {}))
67
65
 
68
- self.s_parameters = [
69
- CfgSParameterModel(self, self.general.s_parameter_library, sparam_model)
70
- for sparam_model in kwargs.get("s_parameters", [])
71
- ]
66
+ self.s_parameters = CfgSParameters(self._pedb, kwargs.get("s_parameters", []), self.general.s_parameter_library)
72
67
 
73
68
  self.spice_models = [
74
69
  CfgSpiceModel(self, self.general.spice_model_library, spice_model)
@@ -53,19 +53,21 @@ class CfgCutout(CfgBase):
53
53
 
54
54
  def get_data_from_db(self):
55
55
  if "pyedb_cutout" in self._pedb.stackup.all_layers:
56
- poly = self._pedb.layout.find_primitive(layer_name="pyedb_cutout")[0]
57
- self.custom_extent = poly.polygon_data.points
56
+ polygons = self._pedb.layout.find_primitive(layer_name="pyedb_cutout")
57
+ if polygons:
58
+ poly = polygons[0]
59
+ self.custom_extent = poly.polygon_data.points
58
60
 
59
- net_names = []
60
- for name, obj in self._pedb.nets.nets.items():
61
- if obj.primitives[0].layer.name == "pyedb_cutout":
62
- continue
63
- if len(obj.primitives) > 0:
64
- net_names.append(name)
61
+ net_names = []
62
+ for name, obj in self._pedb.nets.nets.items():
63
+ if obj.primitives[0].layer.name == "pyedb_cutout":
64
+ continue
65
+ if len(obj.primitives) > 0:
66
+ net_names.append(name)
65
67
 
66
- self.reference_list = []
67
- self.signal_list = net_names
68
- return self.export_properties()
68
+ self.reference_list = []
69
+ self.signal_list = net_names
70
+ return self.export_properties()
69
71
 
70
72
  def export_properties(self):
71
73
  return {
@@ -84,7 +86,7 @@ class CfgOperations(CfgBase):
84
86
  """Imports operation information from JSON."""
85
87
  if self.op_cutout:
86
88
  polygon_points = self._pedb.cutout(**self.op_cutout.get_attributes())
87
- if not "pyedb_cutout" in self._pedb.stackup.all_layers:
89
+ if "pyedb_cutout" not in self._pedb.stackup.all_layers:
88
90
  self._pedb.stackup.add_document_layer(name="pyedb_cutout")
89
91
  self._pedb.modeler.create_polygon(polygon_points, layer_name="pyedb_cutout", net_name="pyedb_cutout")
90
92
 
@@ -92,4 +94,8 @@ class CfgOperations(CfgBase):
92
94
 
93
95
  def get_data_from_db(self):
94
96
  self.op_cutout = CfgCutout(self._pedb)
95
- return {"cutout": self.op_cutout.get_data_from_db()}
97
+ data_from_db = self.op_cutout.get_data_from_db()
98
+ if data_from_db:
99
+ return {"cutout": data_from_db}
100
+ else:
101
+ return {}
@@ -20,110 +20,87 @@
20
20
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
21
  # SOFTWARE.
22
22
 
23
-
24
- from enum import Enum
23
+ from pyedb.configuration.cfg_common import CfgBase
25
24
 
26
25
 
27
26
  class CfgPadstacks:
28
27
  """Padstack data class."""
29
28
 
30
- def __init__(self, pdata, padstack_dict=None):
31
- self._pedb = pdata._pedb
29
+ def __init__(self, pedb, padstack_dict=None):
30
+ self._pedb = pedb
32
31
  self.definitions = []
33
32
  self.instances = []
34
- self._padstack_dict = padstack_dict
35
- if self._padstack_dict:
36
- if self._padstack_dict.get("definitions", ""):
37
- self._definitions_dict = self._padstack_dict.get("definitions", "")
38
- self.definitions = [Definition(pdata, definition) for definition in self._definitions_dict]
39
- if self._padstack_dict.get("instances", None):
40
- self._instances_dict = self._padstack_dict.get("instances", "")
41
- self.instances = [Instance(pdata, inst) for inst in self._instances_dict]
33
+ if padstack_dict:
34
+ for pdef in padstack_dict.get("definitions", []):
35
+ self.definitions.append(Definition(**pdef))
36
+ for inst in padstack_dict.get("instances", []):
37
+ self.instances.append(Instance(**inst))
42
38
 
43
39
  def apply(self):
44
40
  """Apply padstack definition and instances on layout."""
45
- for definition in self.definitions:
46
- definition.apply()
47
- for instance in self.instances:
48
- instance.apply()
41
+ if self.definitions:
42
+ padstack_defs_layout = self._pedb.padstacks.definitions
43
+ for pdef in self.definitions:
44
+ pdef_layout = padstack_defs_layout[pdef.name]
45
+ pdef_layout.set_properties(**pdef.get_attributes())
46
+ if self.instances:
47
+ instances_layout = self._pedb.padstacks.instances_by_name
48
+ for inst in self.instances:
49
+ inst_layout = instances_layout[inst.name]
50
+ if inst.definition:
51
+ # inst_layout.padstack_definition = inst.definition
52
+ # Not supported by EDB API
53
+ pass
54
+ if inst.backdrill_parameters:
55
+ inst_layout.backdrill_parameters = inst.backdrill_parameters
56
+
57
+ def get_data_from_db(self):
58
+ self.definitions = []
59
+ for pdef_name, pdef in self._pedb.padstacks.definitions.items():
60
+ self.definitions.append(
61
+ Definition(
62
+ name=pdef_name,
63
+ hole_plating_thickness=pdef.hole_plating_thickness,
64
+ hole_material=pdef.material,
65
+ hole_range=pdef.hole_range,
66
+ pad_parameters=pdef.pad_parameters,
67
+ hole_parameters=pdef.hole_parameters,
68
+ )
69
+ )
70
+ data = {}
71
+ definitions = []
72
+ for i in self.definitions:
73
+ definitions.append(i.get_attributes())
74
+ data["definitions"] = definitions
75
+
76
+ instances_layout = self._pedb.padstacks.instances_by_name
77
+ for name, obj in instances_layout.items():
78
+ self.instances.append(
79
+ Instance(name=name, definition=obj.padstack_definition, backdrill_parameters=obj.backdrill_parameters)
80
+ )
81
+ instances = []
82
+ for i in self.instances:
83
+ instances.append(i.get_attributes())
84
+ data["instances"] = instances
85
+ return data
49
86
 
50
87
 
51
- class Definition:
88
+ class Definition(CfgBase):
52
89
  """Padstack definition data class."""
53
90
 
54
- def __init__(self, pdata, definition_dict):
55
- self._pedb = pdata._pedb
56
- self._definition_dict = definition_dict
57
- self.name = self._definition_dict.get("name", None)
58
- self.hole_diameter = self._definition_dict.get("hole_diameter", None)
59
- self.hole_plating_thickness = self._definition_dict.get("hole_plating_thickness", None)
60
- self.hole_material = self._definition_dict.get("hole_material", None)
61
- self.hole_range = self._definition_dict.get("hole_range", None)
62
-
63
- def apply(self):
64
- """Apply padstack definition on layout."""
65
- padstack_defs = self._pedb.padstacks.definitions
66
- pdef = padstack_defs[self.name]
67
- if self.hole_diameter:
68
- pdef.hole_diameter = self.hole_diameter
69
- if self.hole_plating_thickness:
70
- pdef.hole_plating_thickness = self.hole_plating_thickness
71
- if self.hole_material:
72
- pdef.material = self.hole_material
73
- if self.hole_range:
74
- pdef.hole_range = self.hole_range
91
+ def __init__(self, **kwargs):
92
+ self.name = kwargs.get("name", None)
93
+ self.hole_plating_thickness = kwargs.get("hole_plating_thickness", None)
94
+ self.material = kwargs.get("hole_material", None)
95
+ self.hole_range = kwargs.get("hole_range", None)
96
+ self.pad_parameters = kwargs.get("pad_parameters", None)
97
+ self.hole_parameters = kwargs.get("hole_parameters", None)
75
98
 
76
99
 
77
- class Instance:
100
+ class Instance(CfgBase):
78
101
  """Instance data class."""
79
102
 
80
- def __init__(self, pdata, instances_dict):
81
- self._pedb = pdata._pedb
82
- self._instances_dict = instances_dict
83
- self.name = self._instances_dict.get("name", "")
84
- self.backdrill_top = None
85
- self.backdrill_bottom = None
86
- self._update_backdrill()
87
-
88
- def _update_backdrill(self):
89
- if "backdrill_top" in self._instances_dict:
90
- self.backdrill_top = self.BackDrill()
91
- self.backdrill_top.type = self.backdrill_top.BackDrillType.TOP
92
- backdrill_top_dict = self._instances_dict["backdrill_top"]
93
- self.backdrill_top.drill_to_layer = backdrill_top_dict.get("drill_to_layer", "")
94
- self.backdrill_top.drill_diameter = backdrill_top_dict.get("drill_diameter", "")
95
- self.backdrill_top.stub_length = backdrill_top_dict.get("stub_length", "")
96
- if "backdrill_bottom" in self._instances_dict:
97
- self.backdrill_bottom = self.BackDrill()
98
- backdrill_bottom_dict = self._instances_dict["backdrill_bottom"]
99
- self.backdrill_bottom.drill_to_layer = backdrill_bottom_dict.get("drill_to_layer", "")
100
- self.backdrill_bottom.drill_diameter = backdrill_bottom_dict.get("drill_diameter", "")
101
- self.backdrill_bottom.stub_length = backdrill_bottom_dict.get("stub_length", "")
102
-
103
- class BackDrill:
104
- """Backdrill data class."""
105
-
106
- def __init__(self):
107
- self.type = self.BackDrillType.BOTTOM
108
- self.drill_to_layer = ""
109
- self.drill_diameter = ""
110
- self.stub_length = ""
111
-
112
- class BackDrillType(Enum):
113
- TOP = 0
114
- BOTTOM = 1
115
-
116
- def apply(self):
117
- """Apply padstack instance on layout."""
118
- padstack_instances = self._pedb.padstacks.instances_by_name
119
- inst = padstack_instances[self.name]
120
- if self.backdrill_top:
121
- inst.set_backdrill_top(
122
- self.backdrill_top.drill_to_layer, self.backdrill_top.drill_diameter, self.backdrill_top.stub_length
123
- )
124
- if self.backdrill_bottom:
125
- inst.set_backdrill_bottom(
126
- self.backdrill_bottom.drill_to_layer,
127
- self.backdrill_bottom.drill_diameter,
128
- self.backdrill_bottom.stub_length,
129
- )
103
+ def __init__(self, **kwargs):
104
+ self.name = kwargs["name"]
105
+ self.definition = kwargs.get("definition", None)
106
+ self.backdrill_parameters = kwargs.get("backdrill_parameters", None)
@@ -36,12 +36,14 @@ class CfgPinGroups:
36
36
 
37
37
  def get_data_from_db(self):
38
38
  self.pin_groups = []
39
- for name, pg in self._pedb.siwave.pin_groups.items():
40
- pins = [p.aedt_name for p in pg.pins.values()]
39
+ layout_pin_groups = self._pedb.siwave.pin_groups
40
+ for pg_name, pg_obj in layout_pin_groups.items():
41
+ pins = list(pg_obj.pins.keys())
42
+ refdes = list(pg_obj.pins.values())[0].component.name
41
43
  cfg_pg = CfgPinGroup(
42
44
  self._pedb,
43
- name=name,
44
- reference_designator=None,
45
+ name=pg_name,
46
+ reference_designator=refdes,
45
47
  pins=pins,
46
48
  )
47
49
  self.pin_groups.append(cfg_pg)
@@ -65,10 +67,7 @@ class CfgPinGroup(CfgBase):
65
67
  def create(self):
66
68
  """Apply pin group on layout."""
67
69
  if self.pins:
68
- if self.reference_designator is None:
69
- self._pedb.modeler.create_pin_group(self.name, pins_by_aedt_name=self.pins)
70
- else:
71
- self._pedb.siwave.create_pin_group(self.reference_designator, list(self.pins), self.name)
70
+ self._pedb.siwave.create_pin_group(self.reference_designator, list(self.pins), self.name)
72
71
  elif self.net:
73
72
  if self.reference_designator in self._pedb.components.instances:
74
73
  comp = self._pedb.components.instances[self.reference_designator]