Download this example

Download this example as a Jupyter Notebook or as a Python script.


Set up EDB for Serdes channel S-parameter extraction#

Perform imports and define constants#

Perform required imports.

[1]:
import json
import os
import tempfile

from ansys.aedt.core import Hfss3dLayout
from ansys.aedt.core.examples.downloads import download_file
from pyedb import Edb

Define constants.

[2]:
AEDT_VERSION = "2025.2"
NG_MODE = False

Download the example PCB data.

[3]:
temp_folder = tempfile.TemporaryDirectory(suffix=".ansys")
file_edb = download_file(source="edb/ANSYS-HSD_V1.aedb", local_path=temp_folder.name)
download_file(source="touchstone", name="GRM32_DC0V_25degC_series.s2p", local_path=os.path.split(file_edb)[0])
[3]:
'C:\\Users\\ansys\\AppData\\Local\\Temp\\tmp1m5vjiea.ansys\\edb\\touchstone\\GRM32_DC0V_25degC_series.s2p'

Load example layout#

[4]:
edbapp = Edb(file_edb, edbversion=AEDT_VERSION)
C:\actions-runner\_work\pyaedt-examples\pyaedt-examples\.venv\lib\site-packages\pyedb\misc\decorators.py:33: UserWarning: Argument `edbversion` is deprecated for method `Edb`; use `version` instead.
  warnings.warn(
C:\actions-runner\_work\pyaedt-examples\pyaedt-examples\.venv\lib\site-packages\pyedb\generic\design_types.py:327: UserWarning: Your ANSYS AEDT version is eligible to gRPC version.You might consider switching to that version for better user experience.For more information please check this link: https://edb.docs.pyansys.com/version/dev/grpc_api/index.html
  warnings.warn(GRPC_GENERAL_WARNING, UserWarning)
PyEDB INFO: Star initializing Edb 04:02:18.551930
PyEDB INFO: Edb version 2025.2
PyEDB INFO: Logger is initialized. Log file is saved to C:\Users\ansys\AppData\Local\Temp\pyedb_ansys.log.
PyEDB INFO: legacy v0.56.0
PyEDB INFO: Python version 3.10.11 (tags/v3.10.11:7d4cc5a, Apr  5 2023, 00:38:17) [MSC v.1929 64 bit (AMD64)]
PyEDB INFO: Database ANSYS-HSD_V1.aedb Opened in 2025.2
PyEDB INFO: Cell main Opened
PyEDB INFO: Builder was initialized.
PyEDB INFO: open_edb completed in 7.4381 seconds.
PyEDB INFO: EDB initialization completed in 7.5015 seconds.

Create config file#

[5]:
cfg_general = {"anti_pads_always_on": True, "suppress_pads": True}

Define dielectric materials, stackup and surface roughness model.

[6]:
cfg_stackup = {
    "materials": [
        {"name": "copper", "permittivity": 1, "conductivity": 58000000.0},
        {"name": "megtron4", "permittivity": 3.77, "dielectric_loss_tangent": 0.005},
        {"name": "solder_resist", "permittivity": 3.0, "dielectric_loss_tangent": 0.035},
    ],
    "layers": [
        {
            "name": "Top",
            "type": "signal",
            "material": "copper",
            "fill_material": "solder_resist",
            "thickness": "0.035mm",
            "roughness": {
                "top": {"model": "huray", "nodule_radius": "0.5um", "surface_ratio": "5"},
                "bottom": {"model": "huray", "nodule_radius": "0.5um", "surface_ratio": "5"},
                "side": {"model": "huray", "nodule_radius": "0.5um", "surface_ratio": "5"},
                "enabled": True,
            },
        },
        {"name": "DE1", "type": "dielectric", "material": "megtron4", "fill_material": "", "thickness": "0.1mm"},
        {"name": "Inner1", "type": "signal", "material": "copper", "fill_material": "megtron4", "thickness": "0.017mm"},
        {"name": "DE2", "type": "dielectric", "material": "megtron4", "fill_material": "", "thickness": "0.088mm"},
        {"name": "Inner2", "type": "signal", "material": "copper", "fill_material": "megtron4", "thickness": "0.017mm"},
        {"name": "DE3", "type": "dielectric", "material": "megtron4", "fill_material": "", "thickness": "0.1mm"},
        {"name": "Inner3", "type": "signal", "material": "copper", "fill_material": "megtron4", "thickness": "0.017mm"},
        {"name": "Megtron4-1mm", "type": "dielectric", "material": "megtron4", "fill_material": "", "thickness": 0.001},
        {"name": "Inner4", "type": "signal", "material": "copper", "fill_material": "megtron4", "thickness": "0.017mm"},
        {"name": "DE5", "type": "dielectric", "material": "megtron4", "fill_material": "", "thickness": "0.1mm"},
        {"name": "Inner5", "type": "signal", "material": "copper", "fill_material": "megtron4", "thickness": "0.017mm"},
        {"name": "DE6", "type": "dielectric", "material": "megtron4", "fill_material": "", "thickness": "0.088mm"},
        {"name": "Inner6", "type": "signal", "material": "copper", "fill_material": "megtron4", "thickness": "0.017mm"},
        {"name": "DE7", "type": "dielectric", "material": "megtron4", "fill_material": "", "thickness": "0.1mm"},
        {
            "name": "Bottom",
            "type": "signal",
            "material": "copper",
            "fill_material": "solder_resist",
            "thickness": "0.035mm",
        },
    ],
}

Define Component with solderballs.

[7]:
cfg_components = [
    {
        "reference_designator": "U1",
        "part_type": "io",
        "solder_ball_properties": {"shape": "cylinder", "diameter": "300um", "height": "300um"},
        "port_properties": {
            "reference_offset": "0",
            "reference_size_auto": True,
            "reference_size_x": 0,
            "reference_size_y": 0,
        },
    }
]

Edit via padstack definition. Add backdrilling.

[8]:
cfg_padstacks = {
    "definitions": [
        {
            "name": "v40h15-2",
            "material": "copper",
            "hole_range": "upper_pad_to_lower_pad",
            "hole_parameters": {"shape": "circle", "diameter": "0.2mm"},
        },
        {
            "name": "v35h15-1",
            "material": "copper",
            "hole_range": "upper_pad_to_lower_pad",
            "hole_parameters": {"shape": "circle", "diameter": "0.25mm"},
        },
    ],
    "instances": [
        {
            "name": "Via313",
            "backdrill_parameters": {
                "from_bottom": {"drill_to_layer": "Inner3", "diameter": "1mm", "stub_length": "0.2mm"}
            },
        },
        {
            "name": "Via314",
            "backdrill_parameters": {
                "from_bottom": {"drill_to_layer": "Inner3", "diameter": "1mm", "stub_length": "0.2mm"}
            },
        },
    ],
}

Define ports.

[9]:
cfg_ports = [
    {
        "name": "port_1",
        "reference_designator": "U1",
        "type": "coax",
        "positive_terminal": {"net": "PCIe_Gen4_TX2_CAP_P"},
    },
    {
        "name": "port_2",
        "reference_designator": "U1",
        "type": "coax",
        "positive_terminal": {"net": "PCIe_Gen4_TX2_CAP_N"},
    },
    {
        "name": "port_3",
        "reference_designator": "X1",
        "type": "circuit",
        "positive_terminal": {"pin": "B8"},
        "negative_terminal": {"pin": "B7"},
    },
    {
        "name": "port_4",
        "reference_designator": "X1",
        "type": "circuit",
        "positive_terminal": {"pin": "B9"},
        "negative_terminal": {"pin": "B10"},
    },
]

Define S-parameter assignment

[10]:
cfg_s_parameters = [
    {
        "name": "cap_10nf",
        "file_path": "$PROJECTDIR\\touchstone\\GRM32_DC0V_25degC_series.s2p",
        "component_definition": "CAPC1005X55X25LL05T10",
        "components": ["C375", "C376"],
        "reference_net": "GND",
    }
]

Define SIwave setup.

[11]:
cfg_setups = [
    {
        "name": "siwave_setup",
        "type": "siwave_ac",
        "si_slider_position": 1,
        "freq_sweep": [
            {
                "name": "Sweep1",
                "type": "interpolation",
                "frequencies": [
                    {"distribution": "linear_scale", "start": "50MHz", "stop": "20GHz", "increment": "50MHz"}
                ],
            }
        ],
    }
]

Define cutout.

[12]:
cfg_operations = {
    "cutout": {
        "signal_list": ["PCIe_Gen4_TX2_CAP_P", "PCIe_Gen4_TX2_CAP_N", "PCIe_Gen4_TX2_P", "PCIe_Gen4_TX2_N"],
        "reference_list": ["GND"],
        "custom_extent": [
            [0.014, 0.055],
            [0.03674271504652968, 0.05493094625752912],
            [0.07, 0.039],
            [0.07, 0.034],
            [0.05609890516829415, 0.03395233061637539],
            [0.014, 0.044],
        ],
    }
}

Create final configuration.

[13]:
cfg = {
    "general": cfg_general,
    "stackup": cfg_stackup,
    "components": cfg_components,
    "padstacks": cfg_padstacks,
    "ports": cfg_ports,
    "s_parameters": cfg_s_parameters,
    "setups": cfg_setups,
    "operations": cfg_operations,
}

Create the config file.

[14]:
file_json = os.path.join(temp_folder.name, "edb_configuration.json")
with open(file_json, "w") as f:
    json.dump(cfg, f, indent=4, ensure_ascii=False)

Apply Config file#

Apply configuration to the example layout

[15]:
edbapp.configuration.load(config_file=file_json)
edbapp.configuration.run()
PyEDB INFO: Updating boundaries finished. Time lapse 0:00:00
PyEDB INFO: Updating nets finished. Time lapse 0:00:00
PyEDB INFO: Updating components finished. Time lapse 0:00:00.031590
PyEDB INFO: Creating pin groups finished. Time lapse 0:00:00
PyEDB INFO: Placing sources finished. Time lapse 0:00:00
PyEDB INFO: Creating setups finished. Time lapse 0:00:00.238935
PyEDB INFO: Applying materials finished. Time lapse 0:00:00.015844
PyEDB INFO: Updating stackup finished. Time lapse 0:00:08.800638
PyEDB INFO: Applying padstacks finished. Time lapse 0:00:00.016134
PyEDB INFO: Applying S-parameters finished. Time lapse 0:00:00
PyEDB INFO: Applying package definitions finished. Time lapse 0:00:00
PyEDB INFO: Applying modeler finished. Time lapse 0:00:00.461932
PyEDB INFO: Placing ports finished. Time lapse 0:00:00.333983
PyEDB INFO: Placing probes finished. Time lapse 0:00:00
PyEDB INFO: Cutout Multithread started.
PyEDB INFO: Net clean up Elapsed time: 0m 1sec
PyEDB INFO: Extent Creation Elapsed time: 0m 0sec
PyEDB INFO: 1949 Padstack Instances deleted. Elapsed time: 0m 1sec
PyEDB INFO: 443 Primitives deleted. Elapsed time: 0m 3sec
PyEDB INFO: 980 components deleted
PyEDB INFO: Cutout completed. Elapsed time: 0m 5sec
PyEDB INFO: Applying operations finished. Time lapse 0:00:04.870970
[15]:
True
[16]:
edbapp.nets.plot(nets=[])
../../../_images/examples_edb_use_configuration_serdes_32_0.png
PyEDB INFO: Plot Generation time 0.824
[16]:
(<Figure size 6000x3000 with 1 Axes>,
 <Axes: title={'center': 'Edb Top View main'}>)

Save and close EDB.

[17]:
edbapp.save()
edbapp.close()
PyEDB INFO: Save Edb file completed in 0.0479 seconds.
PyEDB INFO: Close Edb file completed in 0.0952 seconds.
[17]:
True

The configured EDB file is saved in a temp folder.

[18]:
print(temp_folder.name)
C:\Users\ansys\AppData\Local\Temp\tmp1m5vjiea.ansys

Load edb into HFSS 3D Layout.#

[19]:
h3d = Hfss3dLayout(edbapp.edbpath, version=AEDT_VERSION, non_graphical=NG_MODE, new_desktop=True)
PyAEDT INFO: Python version 3.10.11 (tags/v3.10.11:7d4cc5a, Apr  5 2023, 00:38:17) [MSC v.1929 64 bit (AMD64)].
PyAEDT INFO: PyAEDT version 0.20.dev0.
PyAEDT INFO: Initializing new Desktop session.
PyAEDT INFO: Log on console is enabled.
PyAEDT INFO: Log on file C:\Users\ansys\AppData\Local\Temp\pyaedt_ansys_0c1b34e8-f2fb-4f5a-bd37-75cd7ed623c4.log is enabled.
PyAEDT INFO: Log on AEDT is disabled.
PyAEDT INFO: Debug logger is disabled. PyAEDT methods will not be logged.
PyAEDT INFO: Launching PyAEDT with gRPC plugin.
PyAEDT INFO: New AEDT session is starting on gRPC port 57390.
PyAEDT INFO: Electronics Desktop started on gRPC port: 57390 after 11.477855920791626 seconds.
PyAEDT INFO: AEDT installation Path C:\Program Files\ANSYS Inc\v252\AnsysEM
PyAEDT INFO: Ansoft.ElectronicsDesktop.2025.2 version started with process ID 5956.
PyAEDT INFO: EDB folder C:\Users\ansys\AppData\Local\Temp\tmp1m5vjiea.ansys\edb\ANSYS-HSD_V1.aedb has been imported to project ANSYS-HSD_V1
PyAEDT INFO: Active Design set to 0;main
PyAEDT INFO: Active Design set to 0;main
PyAEDT INFO: Aedt Objects correctly read

Create differential pair definition.

[20]:
h3d.set_differential_pair(
    differential_mode="DIFF_BGA",
    assignment="port_1",
    reference="port_2",
)
[20]:
True
[21]:
h3d.set_differential_pair(
    differential_mode="DIFF_CONN",
    assignment="port_3",
    reference="port_4",
)
[21]:
True

Solve. Un-comment to analyze SIwave.

h3d.analyze(setup=”siwave_setup”)

Plot insertion loss.

solutions = h3d.post.get_solution_data(expressions=”mag(S(DIFF_CONN,DIFF_BGA))”, context=”Differential Pairs”) solutions.plot(formula=”db20”)

Shut Down Electronics Desktop

[22]:
h3d.close_desktop()
PyAEDT INFO: Desktop has been released and closed.
[22]:
True

All project files are saved in the folder temp_file.dir. If you’ve run this example as a Jupyter notebook you can retrieve those project files.


Download this example

Download this example as a Jupyter Notebook or as a Python script.