Skip to content

Commit

Permalink
layer stackup
Browse files Browse the repository at this point in the history
  • Loading branch information
svandenb-dev committed May 29, 2024
1 parent 3631e20 commit 9eeb874
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 129 deletions.
3 changes: 2 additions & 1 deletion src/pyedb/configuration/cfg_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
from pyedb.configuration.cfg_s_parameter_models import CfgSParameterModel
from pyedb.configuration.cfg_setup import CfgSetup
from pyedb.configuration.cfg_spice_models import CfgSpiceModel
from pyedb.configuration.cfg_stackup import CfgLayerStackup


class CfgData(object):
Expand All @@ -55,7 +56,7 @@ def __init__(self, pedb, **kwargs):
self.setups = [CfgSetup(self)]
if kwargs.get("setups", None):
self.setups = [CfgSetup(self, setup) for setup in kwargs.get("setups", [])]
self.stackup = None
self.stackup = CfgLayerStackup(self, kwargs.get("materials", {}), kwargs.get("layers", {}))
self.s_parameters = [
CfgSParameterModel(self, self.general.s_parameter_library, sparam_model)
for sparam_model in kwargs.get("s_parameters", [])
Expand Down
188 changes: 130 additions & 58 deletions src/pyedb/configuration/cfg_stackup.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
from enum import Enum
import random

from pyedb.dotnet.edb_core.stackup import LayerCollection


class LayerType(Enum):
SIGNAL = 0
Expand All @@ -32,13 +34,77 @@ class LayerType(Enum):
class CfgLayerStackup:
def __init__(self, pdata, materials=None, layers=None):
self._pedb = pdata.pedb
self._materials_dict = materials
self._layers_dict = layers
self.materials = []
self.layers = []
if self._materials_dict:
self.materials = [Material(self._pedb, material_dict) for material_dict in self._materials_dict.items()]
if self._layers_dict:
self.layers = [Layer(self._pedb, layer_dict) for layer_dict in self._layers_dict.items()]

def apply(self):
for material in self.materials:
material.apply()
self.__apply_layers()

def __apply_layers(self):
lc = self._pedb.stackup
input_signal_layers = [layer for layer in self.layers if layer.type == LayerType.SIGNAL]
if not len(input_signal_layers) == len(lc.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
for layer in self.layers:
if layer.type == LayerType.SIGNAL:
clone = layer_clones.pop(0)
clone.update(layer.__dict__())
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 layer in doc_layer_clones:
doc_layer = lc_new.add_document_layer(name=layer.name, layer_clone=layer)
first_doc_layer_name = doc_layer.name

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

lc._edb_object = lc_new._edb_object
lc_new.auto_refresh = True
lc.update_layout()


class Material:
def __init__(self, pedb):
def __init__(self, pedb, material_dict=None):
self._pedb = pedb
self._material_dict = material_dict
self.name = ""
self.conductivity = 0.0
self.loss_tangent = 0.0
Expand All @@ -56,18 +122,41 @@ def __init__(self, pedb):
self.dielectric_model_frequency = None
self.loss_tangent_at_frequency = None
self.permittivity_at_frequency = None
self.__update()

def __update(self):
if self._material_dict:
self.name = self._material_dict.get("name", "")
self.conductivity = self._material_dict.get("conductivity", 0.0)
self.loss_tangent = self._material_dict.get("loss_tangent", 0.0)
self.magnetic_loss_tangent = self._material_dict.get("magnetic_loss_tangent", 0.0)
self.mass_density = self._material_dict.get("mass_density", 0.0)
self.permittivity = self._material_dict.get("permittivity", 1.0)
self.permeability = self._material_dict.get("permeability", 1.0)
self.poisson_ratio = self._material_dict.get("poisson_ratio", 0.0)
self.specific_heat = self._material_dict.get("specific_heat", 0.0)
self.thermal_conductivity = self._material_dict.get("thermal_conductivity", 0.0)
self.youngs_modulus = self._material_dict.get("youngs_modulus", 0.0)
self.thermal_expansion_coefficient = self._material_dict.get("thermal_expansion_coefficient", 0.0)
self.dc_conductivity = self._material_dict.get("dc_conductivity", None)
self.dc_permittivity = self._material_dict.get("dc_permittivity", None)
self.dielectric_model_frequency = self._material_dict.get("dc_permittivity", None)
self.loss_tangent_at_frequency = self._material_dict.get("loss_tangent_at_frequency", None)
self.permittivity_at_frequency = self._material_dict.get("permittivity_at_frequency", None)

def apply(self):
edb_materials = {i.lower(): i for i, _ in self._pedb.materials.materials.items()}
if self.name.lower() in edb_materials:
self._pedb.materials.delete_material(edb_materials[self.name])
self._pedb.materials.add_material(**mat)
self._pedb.materials.add_material(self.__dict__)


class Layer:
def __init__(self):
def __init__(self, pedb, layer_dict=None):
self._pedb = pedb
self._layer_dict = layer_dict
self.name = ""
self.color = [random.randint(1, 255), random.randint(1, 255), random.randint(1, 255)]
self.color = [random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)]
self.type = LayerType.SIGNAL
self.material = "copper"
self.dielectric_fill = "fr4"
Expand All @@ -82,58 +171,41 @@ def __init__(self):
self.side_hallhuray_surface_ratio = 0.0
self.upper_elevation = 0.0
self.lower_elevation = 0.0
self.__update()

def __update(self):
if self._layer_dict:
self.name = self._layer_dict.get("name", self.name)
self.color = self._layer_dict.get("color", self.color)
self.__map_layer_type()
self.material = self._layer_dict.get("material", self.material)
self.dielectric_fill = self._layer_dict.get("dielectric_fill", self.dielectric_fill)
self.thickness = self._layer_dict.get("thickness", self.thickness)
self.etch_factor = self._layer_dict.get("etch_factor", self.etch_factor)
self.roughness_enabled = self._layer_dict.get("roughness_enabled", self.roughness_enabled)
self.top_hallhuray_nodule_radius = self._layer_dict.get(
"top_hallhuray_nodule_radius", self.top_hallhuray_nodule_radius
)
self.top_hallhuray_surface_ratio = self._layer_dict.get(
"top_hallhuray_surface_ratio", self.top_hallhuray_surface_ratio
)
self.bottom_hallhuray_nodule_radius = self._layer_dict.get(
"bottom_hallhuray_nodule_radius", self.bottom_hallhuray_nodule_radius
)
self.bottom_hallhuray_surface_ratio = self._layer_dict.get(
"bottom_hallhuray_surface_ratio", self.bottom_hallhuray_surface_ratio
)
self.side_hallhuray_nodule_radius = self._layer_dict.get(
"side_hallhuray_nodule_radius", self.side_hallhuray_nodule_radius
)
self.side_hallhuray_surface_ratio = self._layer_dict.get(
"side_hallhuray_surface_ratio", self.side_hallhuray_surface_ratio
)
self.upper_elevation = self._layer_dict.get("upper_elevation", self.upper_elevation)
self.lower_elevation = self._layer_dict.get("lower_elevation", self.lower_elevation)

# data = self.data["stackup"]
# materials = data.get("materials")
#
# 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):
# 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
# 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
#
# # 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"]]
# else:
# prev_layer_clone = lc_new.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()
def __map_layer_type(self):
if self._layer_dict.get("type") == "signal":
self.type = LayerType.SIGNAL
elif self._layer_dict.get("type") == "dielectric":
self.type = LayerType.DIELECTRIC
70 changes: 0 additions & 70 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 @@ -164,75 +163,6 @@ def run(self):

return True

@pyedb_function_handler
def _load_stackup(self):
"""Imports stackup information from json."""
data = self.data["stackup"]
materials = data.get("materials")

if materials:
edb_materials = {i.lower(): i for i, _ in self._pedb.materials.materials.items()}
for mat in materials:
name = mat["name"].lower()
if name in edb_materials:
self._pedb.materials.delete_material(edb_materials[name])
for mat in materials:
self._pedb.materials.add_material(**mat)

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):
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
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

# 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"]]
else:
prev_layer_clone = lc_new.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()

@pyedb_function_handler
def _load_operations(self):
"""Imports operation information from JSON."""
Expand Down

0 comments on commit 9eeb874

Please sign in to comment.