Skip to content

Commit

Permalink
FIX: stackup load (#527)
Browse files Browse the repository at this point in the history
* FIX: stackup load

* MISC: Auto fixes from pre-commit.com hooks

For more information, see https://pre-commit.ci

* FIX: stackup load

* FIX: stackup load

* FIX: stackup load

* MISC: Auto fixes from pre-commit.com hooks

For more information, see https://pre-commit.ci

---------

Co-authored-by: ring630 <@gmail.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
  • Loading branch information
hui-zhou-a and pre-commit-ci[bot] authored May 31, 2024
1 parent e35734d commit 70ad2bf
Show file tree
Hide file tree
Showing 7 changed files with 149 additions and 107 deletions.
16 changes: 14 additions & 2 deletions src/pyedb/configuration/cfg_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,30 +39,42 @@ def __init__(self, pedb, **kwargs):
self.pedb = pedb
self.edb_comps = self.pedb.components.components
self.general = CfgGeneral(self, kwargs.get("general", None))

self.boundaries = {}
if kwargs.get("boundaries", None):
self.boundaries = CfgBoundaries(self, kwargs.get("boundaries", None))
self.nets = CfgNets(self)

self.nets = None
if kwargs.get("nets"):
self.nets = CfgNets(
self, kwargs.get("nets", {}).get("signal_nets", []), kwargs.get("nets", {}).get("power_ground_nets", [])
)

self.components = [CfgComponent(self, **component) for component in kwargs.get("components", [])]

self.padstacks = CfgPadstacks(self, kwargs.get("padstacks", None))

self.pin_groups = [CfgPinGroup(self, pin_group) for pin_group in kwargs.get("pin_groups", [])]

self.ports = [CfgPort(self, **port) for port in kwargs.get("ports", [])]

self.sources = [CfgSources(self, **source) for source in kwargs.get("sources", [])]
self.setups = [CfgSetup(self)]

self.setups = []
if kwargs.get("setups", None):
self.setups = [CfgSetup(self, setup) for setup in kwargs.get("setups", [])]

self.stackup = None

self.s_parameters = [
CfgSParameterModel(self, self.general.s_parameter_library, sparam_model)
for sparam_model in kwargs.get("s_parameters", [])
]

self.spice_models = [
CfgSpiceModel(self, self.general.spice_model_library, spice_model)
for spice_model in kwargs.get("spice_models", [])
]

self.package_definition = None
self.operations = None
59 changes: 23 additions & 36 deletions src/pyedb/configuration/configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@

from pyedb.configuration.cfg_data import CfgData
from pyedb.dotnet.edb_core.definition.package_def import PackageDef
from pyedb.dotnet.edb_core.stackup import LayerCollection
from pyedb.generic.general_methods import pyedb_function_handler


Expand Down Expand Up @@ -182,56 +181,44 @@ def _load_stackup(self):
layers = data.get("layers")

if layers:
lc = self._pedb.stackup
input_signal_layers = [i for i in layers if i["type"].lower() == "signal"]
if not len(input_signal_layers) == len(lc.signal_layers):
if not len(input_signal_layers) == len(self._pedb.stackup.signal_layers):
self._pedb.logger.error("Input signal layer count do not match.")
return False

layer_clones = []
doc_layer_clones = []
for name, obj in lc.layers.items():
if obj.is_stackup_layer:
if obj.type == "signal": # keep signal layers
layer_clones.append(obj)
else:
doc_layer_clones.append(obj)

lc_new = LayerCollection(self._pedb)
lc_new.auto_refresh = False
signal_layer_ids = {}
top_layer_clone = None

# add all signal layers
removal_list = []
lc_signal_layers = []
for name, obj in self._pedb.stackup.all_layers.items():
if obj.type == "dielectric":
removal_list.append(name)
elif obj.type == "signal":
lc_signal_layers.append(obj.id)
for l in removal_list:
self._pedb.stackup.remove_layer(l)

# update all signal layers
id_name = {i[0]: i[1] for i in self._pedb.stackup.layers_by_id}
signal_idx = 0
for l in layers:
if l["type"] == "signal":
clone = layer_clones.pop(0)
clone.update(**l)
lc_new.add_layer_bottom(name=clone.name, layer_clone=clone)
signal_layer_ids[clone.name] = clone.id

# add all document layers at bottom
for l in doc_layer_clones:
doc_layer = lc_new.add_document_layer(name=l.name, layer_clone=l)
first_doc_layer_name = doc_layer.name
layer_id = lc_signal_layers[signal_idx]
layer_name = id_name[layer_id]
self._pedb.stackup.layers[layer_name].update(**l)
signal_idx = signal_idx + 1

# add all dielectric layers. Dielectric layers must be added last. Otherwise,
# dielectric layer will occupy signal and document layer id.
prev_layer_clone = None
l = layers.pop(0)
if l["type"] == "signal":
prev_layer_clone = lc_new.layers[l["name"]]
prev_layer_clone = self._pedb.stackup.layers[l["name"]]
else:
prev_layer_clone = lc_new.add_layer_top(**l)
prev_layer_clone = self._pedb.stackup.add_layer_top(**l)
for idx, l in enumerate(layers):
if l["type"] == "dielectric":
prev_layer_clone = lc_new.add_layer_below(base_layer_name=prev_layer_clone.name, **l)
else:
prev_layer_clone = lc_new.layers[l["name"]]

lc._edb_object = lc_new._edb_object
lc_new.auto_refresh = True
lc.update_layout()
prev_layer_clone = self._pedb.stackup.add_layer_below(base_layer_name=prev_layer_clone.name, **l)
elif l["type"] == "signal":
prev_layer_clone = self._pedb.stackup.layers[l["name"]]

@pyedb_function_handler
def _load_operations(self):
Expand Down
4 changes: 1 addition & 3 deletions src/pyedb/dotnet/edb.py
Original file line number Diff line number Diff line change
Expand Up @@ -846,9 +846,7 @@ def stackup(self):
>>> edbapp.stackup.layers["TOP"].thickness == 4e-05
>>> edbapp.stackup.add_layer("Diel", "GND", layer_type="dielectric", thickness="0.1mm", material="FR4_epoxy")
"""
if not self._stackup2 and self.active_db:
self._stackup2 = Stackup(self, self.layout.layer_collection)
return self._stackup2
return Stackup(self, self.layout.layer_collection)

@property
def materials(self):
Expand Down
4 changes: 2 additions & 2 deletions src/pyedb/dotnet/edb_core/edb_data/layer_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -257,8 +257,8 @@ def __init__(self, pedb, edb_object=None, name="", layer_type="signal", **kwargs
self._lower_elevation = 0.0

def _create(self, layer_type):
layer_type = self._layer_name_mapping[layer_type]
layer_type = self._layer_type_mapping[layer_type]
layer_type_edb_name = self._layer_name_mapping[layer_type]
layer_type = self._layer_type_mapping[layer_type_edb_name]
self._edb_object = self._pedb.edb_api.cell._cell.StackupLayer(
self._name,
layer_type,
Expand Down
101 changes: 40 additions & 61 deletions src/pyedb/dotnet/edb_core/stackup.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,6 @@


class LayerCollection(object):
auto_refresh = True

def __init__(self, pedb, edb_object=None):
self._pedb = pedb

Expand All @@ -91,17 +89,21 @@ def __init__(self, pedb, edb_object=None):
"multizone": self._pedb.edb_api.cell._cell.LayerCollectionMode.MultiZone,
}

def update_layout(self, stackup=None):
def update_layout(self):
"""Set layer collection into edb.
Parameters
----------
stackup
"""
if stackup:
self._edb_object = stackup._edb_object
self._pedb.layout.layer_collection = self._edb_object

@pyedb_function_handler()
def refresh_layer_collection(self):
"""Refresh layer collection from Edb. This method is run on demand after all edit operations on stackup."""
self._edb_object = self._pedb.edb_api.cell._cell.LayerCollection(self._pedb.layout.layer_collection)
self._lc = self._edb_object

@pyedb_function_handler
def _add_layer(self, add_method, base_layer_name="", **kwargs):
"""Add a layer to edb.
Expand All @@ -115,7 +117,13 @@ def _add_layer(self, add_method, base_layer_name="", **kwargs):
if layer_clone:
obj = layer_clone
else:
obj = StackupLayerEdbClass(self._pedb, edb_object=None, **kwargs)
layer_type = kwargs.get("layer_type", None)
if not layer_type:
layer_type = kwargs["type"]
if layer_type in ["signal", "dielectric"]:
obj = StackupLayerEdbClass(self._pedb, edb_object=None, **kwargs)
else:
obj = LayerEdbClass(self._pedb, edb_object=None, **kwargs)
method_top_bottom = None
method_above_below = None
if add_method == "add_layer_top":
Expand All @@ -134,8 +142,7 @@ def _add_layer(self, add_method, base_layer_name="", **kwargs):
obj = obj if method_top_bottom(obj._edb_object) else False
elif method_above_below:
obj = obj if method_above_below(obj._edb_object, base_layer_name) else False
if self.auto_refresh:
self.update_layout()
self.update_layout()
return obj

@pyedb_function_handler
Expand Down Expand Up @@ -268,8 +275,7 @@ def set_layer_clone(self, layer_clone):
lc.AddLayerBottom(i._edb_object)

self._edb_object = lc
if self.auto_refresh:
self.update_layout()
self.update_layout()

if not obj:
logger.info("Layer clone was not found in stackup or non stackup layers.")
Expand All @@ -278,33 +284,32 @@ def set_layer_clone(self, layer_clone):
@property
def stackup_layers(self):
"""Retrieve the dictionary of signal and dielectric layers."""
temp = list(self._edb_object.Layers((self._pedb.edb_api.cell.layer_type_set.StackupLayerSet)))
layers = OrderedDict()
for i in temp:
name = i.GetName()
layers[name] = StackupLayerEdbClass(self._pedb, i.Clone(), name=name)
return layers
warnings.warn("Use new property :func:`layers` instead.", DeprecationWarning)
return self.layers

@property
def non_stackup_layers(self):
"""Retrieve the dictionary of signal layers."""
temp = list(self._edb_object.Layers(self._layer_type_set_mapping["non_stackup_layer_set"]))
layers = OrderedDict()
for i in temp:
name = i.GetName()
layers[name] = LayerEdbClass(self._pedb, i, name=name)
return layers
return {name: obj for name, obj in self.all_layers.items() if not obj.is_stackup_layer}

@property
def layers_by_id(self):
"""Retrieve the list of layers with their ids."""
layer_list = list(self._layer_collection.Layers(self._pedb.edb_api.cell.layer_type_set.AllLayerSet))
temp = []
def all_layers(self):
self.refresh_layer_collection()
layer_list = list(self._edb_object.Layers(self._pedb.edb_api.cell.layer_type_set.AllLayerSet))
temp = dict()
for i in layer_list:
obj = StackupLayerEdbClass(self._pedb, i.Clone(), name=i.GetName)
temp.append([obj.id, obj.name])
if i.IsStackupLayer():
obj = StackupLayerEdbClass(self._pedb, i.Clone(), name=i.GetName())
else:
obj = LayerEdbClass(self._pedb, i.Clone(), name=i.GetName())
temp[obj.name] = obj
return temp

@property
def layers_by_id(self):
"""Retrieve the list of layers with their ids."""
return [[obj.id, name] for name, obj in self.all_layers.items()]

@property
def layers(self):
"""Retrieve the dictionary of layers.
Expand All @@ -313,22 +318,14 @@ def layers(self):
-------
Dict[str, :class:`pyedb.dotnet.edb_core.edb_data.layer_data.LayerEdbClass`]
"""
_lays = OrderedDict()
layer_list = list(self._edb_object.Layers(self._pedb.edb_api.cell.layer_type_set.AllLayerSet))
for l in layer_list:
name = l.GetName()
if not l.IsStackupLayer():
_lays[name] = LayerEdbClass(self._pedb, l, name=name)
else:
_lays[name] = StackupLayerEdbClass(self._pedb, l, name=name)
return _lays
return {name: obj for name, obj in self.all_layers.items() if obj.is_stackup_layer}


class Stackup(LayerCollection):
"""Manages EDB methods for stackup accessible from `Edb.stackup` property."""

def __getitem__(self, item):
return self.layers[item]
return self.all_layers[item]

def __init__(self, pedb, edb_object=None):
super().__init__(pedb, edb_object)
Expand Down Expand Up @@ -576,12 +573,6 @@ def create_symmetric_stackup(
)
return True

@pyedb_function_handler()
def refresh_layer_collection(self):
"""Refresh layer collection from Edb. This method is run on demand after all edit operations on stackup."""
self._lc = self._pedb.edb_api.cell._cell.LayerCollection(self._pedb.layout.layer_collection)
self._edb_object = self._lc

@property
def _layer_collection(self):
"""Copy of EDB layer collection.
Expand All @@ -591,8 +582,7 @@ def _layer_collection(self):
:class:`Ansys.Ansoft.Edb.Cell.LayerCollection`
Collection of layers.
"""
if not self._lc:
self.refresh_layer_collection()
self.refresh_layer_collection()
return self._lc

@property
Expand Down Expand Up @@ -620,7 +610,7 @@ def mode(self, value):
self._layer_collection.SetMode(mode.Overlapping)
elif value == 2 or value == mode.MultiZone or value == "MultiZone":
self._layer_collection.SetMode(mode.MultiZone)
self._pedb.layout.layer_collection = self._layer_collection
self.update_layout()

@property
def stackup_mode(self):
Expand Down Expand Up @@ -744,9 +734,8 @@ def _set_layout_stackup(self, layer_clone, operation, base_layer=None, method=1)
_lc.AddStackupLayerAtElevation(layer_clone)
elif operation == "non_stackup":
_lc.AddLayerBottom(layer_clone)
if self.auto_refresh:
self._pedb.layout.layer_collection = _lc
self.refresh_layer_collection()
self._pedb.layout.layer_collection = _lc
self.refresh_layer_collection()
return True

@pyedb_function_handler()
Expand Down Expand Up @@ -814,17 +803,7 @@ def add_outline_layer(self, outline_name="Outline"):
bool
"True" if successful, ``False`` if failed.
"""
outlineLayer = self._pedb.edb_api.cell.layer.FindByName(self._pedb.layout.layer_collection, outline_name)
if outlineLayer.IsNull():
return self.add_layer(
outline_name,
layer_type="outline",
material="",
fillMaterial="",
thickness="",
)
else:
return False
return self.add_document_layer(name="Outline", layer_type="outline")

# TODO: Update optional argument material into material_name and fillMaterial into fill_material_name
@pyedb_function_handler()
Expand Down
Loading

0 comments on commit 70ad2bf

Please sign in to comment.