Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Regular integration of new pyaedt PRs related to EDB #92

Merged
merged 9 commits into from
Dec 22, 2023
Binary file added doc/source/_static/connector_example.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added doc/source/_static/parametrized_design.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
198 changes: 198 additions & 0 deletions examples/legacy/pyaedt_integration/13_edb_create_component.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
"""
EDB: geometry creation
----------------------
This example shows how to
1, Create a layout layer stackup.
2, Create Padstack definition.
3, Place padstack instances at given location.
4, Create primitives, polygon and trace.
5, Create component from pins.
6, Create HFSS simulation setup and excitation ports.
"""
######################################################################
#
# Final expected project
# ~~~~~~~~~~~~~~~~~~~~~~
#
# .. image:: ../../_static/connector_example.png
# :width: 600
# :alt: Connector from Vias.
######################################################################

######################################################################
# Create connector component from pad-stack
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Initialize an empty EDB layout object on version 2023 R2.
######################################################################

import os

from pyaedt import Hfss3dLayout

import pyedb
from pyedb.generic.general_methods import (
generate_unique_folder_name,
generate_unique_name,
)

aedb_path = os.path.join(generate_unique_folder_name(), generate_unique_name("component_example") + ".aedb")


edb = pyedb.Edb(edbpath=aedb_path, edbversion="2023.2")
print("EDB is located at {}".format(aedb_path))

######################
# Initialize variables
# ~~~~~~~~~~~~~~~~~~~~

layout_count = 12
diel_material_name = "FR4_epoxy"
diel_thickness = "0.15mm"
cond_thickness_outer = "0.05mm"
cond_thickness_inner = "0.017mm"
soldermask_thickness = "0.05mm"
trace_in_layer = "TOP"
trace_out_layer = "L10"
trace_width = "200um"
connector_size = 2e-3
conectors_position = [[0, 0], [10e-3, 0]]

################
# Create stackup
# ~~~~~~~~~~~~~~
edb.stackup.create_symmetric_stackup(
layer_count=layout_count,
inner_layer_thickness=cond_thickness_inner,
outer_layer_thickness=cond_thickness_outer,
soldermask_thickness=soldermask_thickness,
dielectric_thickness=diel_thickness,
dielectric_material=diel_material_name,
)

######################
# Create ground planes
# ~~~~~~~~~~~~~~~~~~~~
#

ground_layers = [
layer_name for layer_name in edb.stackup.signal_layers.keys() if layer_name not in [trace_in_layer, trace_out_layer]
]
plane_shape = edb.modeler.Shape("rectangle", pointA=["-3mm", "-3mm"], pointB=["13mm", "3mm"])
for i in ground_layers:
edb.modeler.create_polygon(plane_shape, i, net_name="VSS")

######################
# Add design variables
# ~~~~~~~~~~~~~~~~~~~~

edb.add_design_variable("$via_hole_size", "0.3mm")
edb.add_design_variable("$antipaddiam", "0.7mm")
edb.add_design_variable("$paddiam", "0.5mm")
edb.add_design_variable("trace_in_width", "0.2mm", is_parameter=True)
edb.add_design_variable("trace_out_width", "0.1mm", is_parameter=True)

############################
# Create padstack definition
# ~~~~~~~~~~~~~~~~~~~~~~~~~~

edb.padstacks.create_padstack(
padstackname="Via", holediam="$via_hole_size", antipaddiam="$antipaddiam", paddiam="$paddiam"
)

####################
# Create connector 1
# ~~~~~~~~~~~~~~~~~~

component1_pins = [
edb.padstacks.place_padstack(
conectors_position[0], "Via", net_name="VDD", fromlayer=trace_in_layer, tolayer=trace_out_layer
),
edb.padstacks.place_padstack(
[conectors_position[0][0] - connector_size / 2, conectors_position[0][1] - connector_size / 2],
"Via",
net_name="VSS",
),
edb.padstacks.place_padstack(
[conectors_position[0][0] + connector_size / 2, conectors_position[0][1] - connector_size / 2],
"Via",
net_name="VSS",
),
edb.padstacks.place_padstack(
[conectors_position[0][0] + connector_size / 2, conectors_position[0][1] + connector_size / 2],
"Via",
net_name="VSS",
),
edb.padstacks.place_padstack(
[conectors_position[0][0] - connector_size / 2, conectors_position[0][1] + connector_size / 2],
"Via",
net_name="VSS",
),
]

####################
# Create connector 2
# ~~~~~~~~~~~~~~~~~~

component2_pins = [
edb.padstacks.place_padstack(
conectors_position[-1], "Via", net_name="VDD", fromlayer=trace_in_layer, tolayer=trace_out_layer
),
edb.padstacks.place_padstack(
[conectors_position[1][0] - connector_size / 2, conectors_position[1][1] - connector_size / 2],
"Via",
net_name="VSS",
),
edb.padstacks.place_padstack(
[conectors_position[1][0] + connector_size / 2, conectors_position[1][1] - connector_size / 2],
"Via",
net_name="VSS",
),
edb.padstacks.place_padstack(
[conectors_position[1][0] + connector_size / 2, conectors_position[1][1] + connector_size / 2],
"Via",
net_name="VSS",
),
edb.padstacks.place_padstack(
[conectors_position[1][0] - connector_size / 2, conectors_position[1][1] + connector_size / 2],
"Via",
net_name="VSS",
),
]

####################
# Create layout pins
# ~~~~~~~~~~~~~~~~~~

for padstack_instance in list(edb.padstacks.instances.values()):
padstack_instance.is_pin = True

############################
# create component from pins
# ~~~~~~~~~~~~~~~~~~~~~~~~~~

edb.components.create(component1_pins, "connector_1")
edb.components.create(component2_pins, "connector_2")

################################################################################
# Creating ports and adding simulation setup using SimulationConfiguration class
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

sim_setup = edb.new_simulation_configuration()
sim_setup.solver_type = sim_setup.SOLVER_TYPE.Hfss3dLayout
sim_setup.batch_solve_settings.cutout_subdesign_expansion = 0.01
sim_setup.batch_solve_settings.do_cutout_subdesign = False
sim_setup.batch_solve_settings.signal_nets = ["VDD"]
sim_setup.batch_solve_settings.components = ["connector_1", "connector_2"]
sim_setup.batch_solve_settings.power_nets = ["VSS"]
sim_setup.ac_settings.start_freq = "0GHz"
sim_setup.ac_settings.stop_freq = "5GHz"
sim_setup.ac_settings.step_freq = "1GHz"
edb.build_simulation_project(sim_setup)

###########################
# Save EDB and open in AEDT
# ~~~~~~~~~~~~~~~~~~~~~~~~~
edb.save_edb()
edb.close_edb()
h3d = Hfss3dLayout(specified_version="2023.2", projectname=aedb_path, non_graphical=False)
h3d.release_desktop(False, False)
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
"""
EDB: parameterized design
------------------------
This example shows how to
1, Create an HFSS simulation project using SimulationConfiguration class.
2, Create automatically parametrized design.
"""
######################################################################
#
# Final expected project
# ~~~~~~~~~~~~~~~~~~~~~~
#
# .. image:: ../../_static/parametrized_design.png
# :width: 600
# :alt: Fully automated parametrization.
######################################################################

######################################################################
# Create HFSS simulatio project
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Load an existing EDB folder.
######################################################################

from pyaedt import Hfss3dLayout

import pyedb
from pyedb.generic.general_methods import generate_unique_folder_name
from pyedb.legacy.downloads import download_file

project_path = generate_unique_folder_name()
target_aedb = download_file("edb/ANSYS-HSD_V1.aedb", destination=project_path)
print("Project folder will be", target_aedb)

aedt_version = "2023.2"
edb = pyedb.Edb(edbpath=target_aedb, edbversion=aedt_version)
print("EDB is located at {}".format(target_aedb))

########################################################################
# Create SimulationConfiguration object and define simulation parameters
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

simulation_configuration = edb.new_simulation_configuration()
simulation_configuration.signal_nets = ["PCIe_Gen4_RX0_P", "PCIe_Gen4_RX0_N", "PCIe_Gen4_RX1_P", "PCIe_Gen4_RX1_N"]
simulation_configuration.power_nets = ["GND"]
simulation_configuration.components = ["X1", "U1"]
simulation_configuration.do_cutout_subdesign = True
simulation_configuration.start_freq = "OGHz"
simulation_configuration.stop_freq = "20GHz"
simulation_configuration.step_freq = "10MHz"

##########################
# Build simulation project
# ~~~~~~~~~~~~~~~~~~~~~~~~

edb.build_simulation_project(simulation_configuration)

#############################
# Generated design parameters
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~
#

edb.auto_parametrize_design(layers=True, materials=True, via_holes=True, pads=True, antipads=True, traces=True)
edb.save_edb()
edb.close_edb()

######################
# Open project in AEDT
# ~~~~~~~~~~~~~~~~~~~~

hfss = Hfss3dLayout(projectname=target_aedb, specified_version=aedt_version)
hfss.release_desktop(False, False)
5 changes: 3 additions & 2 deletions src/pyedb/ipc2581/bom/bom.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@


class Bom(object):
def __init__(self):
self.name = "bom"
def __init__(self, edb):
self._edb = edb
self.name = self._edb.cell_names[0]
self.revision = "1.0"
self.step_ref = "1.0"
self.bom_items = []
Expand Down
4 changes: 2 additions & 2 deletions src/pyedb/ipc2581/bom/bom_item.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ def write_xml(self, bom): # pragma no cover
bom_item.set("category", self.category)
bom_item.set("category", self.category)
for refdes in self.refdes_list:
refdes.write_xml(bom)
self.charactistics.write_xml(bom)
refdes.write_xml(bom_item)
self.charactistics.write_xml(bom_item)

def add_refdes(self, component_name=None, package_def=None, populate=True, placement_layer=""): # pragma no cover
refdes = RefDes()
Expand Down
8 changes: 4 additions & 4 deletions src/pyedb/ipc2581/ipc2581.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def __init__(self, pedb, units):
self.content = Content(self)
self.logistic_header = LogisticHeader()
self.history_record = HistoryRecord()
self.bom = Bom()
self.bom = Bom(pedb)
self.ecad = Ecad(self, pedb, units)
self.file_path = ""
self.design_name = ""
Expand Down Expand Up @@ -367,9 +367,9 @@ def write_xml(self):
ipc.set("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance")
ipc.set("xmlns:xsd", "http://www.w3.org/2001/XMLSchema")
self.content.write_wml(ipc)
# self.logistic_header.write_xml(ipc)
# self.history_record.write_xml(ipc)
# self.bom.write_xml(ipc)
self.logistic_header.write_xml(ipc)
self.history_record.write_xml(ipc)
self.bom.write_xml(ipc)
self.ecad.write_xml(ipc)
try:
ET.indent(ipc)
Expand Down
Loading
Loading