EDB: Network Analysis in SIwave#

This example shows how to use PyAEDT to set up SYZ analysis on a serdes channel. The signal input is applied differetially. The positive net is “PCIe_Gen4_TX3_CAP_P”. The negative net is “PCIe_Gen4_TX3_CAP_N”. In this example, ports are placed on the driver and receiver components.

Perform required imports#

Perform required imports, which includes importing a section.

[1]:
import tempfile
import time
[2]:
import ansys.aedt.core
[3]:
import pyedb
from pyedb.misc.downloads import download_file

Download file#

Download the AEDB file and copy it in the temporary folder.

[4]:
temp_dir = tempfile.TemporaryDirectory(suffix=".ansys")
edb_full_path = download_file("edb/ANSYS-HSD_V1.aedb", destination=temp_dir.name)
time.sleep(5)

print(edb_full_path)
C:\Users\ansys\AppData\Local\Temp\tmp3mh0aoig.ansys\edb/ANSYS-HSD_V1.aedb

Configure EDB#

Create an instance of the pyedb.Edb class.

[5]:
# Select EDB version (change it manually if needed, e.g. "2024.2")
edb_version = "2024.2"
print(f"EDB version: {edb_version}")

edbapp = pyedb.Edb(edbpath=edb_full_path, edbversion=edb_version)
EDB version: 2024.2
PyAEDT INFO: Logger is initialized in EDB.
PyAEDT INFO: legacy v0.29.0
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: Database ANSYS-HSD_V1.aedb Opened in 2024.2
PyAEDT INFO: Cell main Opened
PyAEDT INFO: Builder was initialized.
PyAEDT INFO: EDB initialized.

Generate extended nets#

An extended net consists of two nets that are connected through a passive component such as a resistor or capacitor.

[6]:
all_nets = edbapp.extended_nets.auto_identify_signal(resistor_below=10, inductor_below=1, capacitor_above=1e-9)

Review the properties of extended nets.

[7]:
diff_p = edbapp.nets["PCIe_Gen4_TX3_CAP_P"]
diff_n = edbapp.nets["PCIe_Gen4_TX3_CAP_N"]

nets_p = list(diff_p.extended_net.nets.keys())
nets_n = list(diff_n.extended_net.nets.keys())

comp_p = list(diff_p.extended_net.components.keys())
comp_n = list(diff_n.extended_net.components.keys())

rlc_p = list(diff_p.extended_net.rlc.keys())
rlc_n = list(diff_n.extended_net.rlc.keys())

print(comp_p, rlc_p, comp_n, rlc_n, sep="\n")
['U1', 'C379', 'X1']
['C379']
['U1', 'C380', 'X1']
['C380']

Prepare input data for port creation.

[8]:
ports = []
for net_name, net_obj in diff_p.extended_net.nets.items():
    for comp_name, comp_obj in net_obj.components.items():
        if comp_obj.type not in ["Resistor", "Capacitor", "Inductor"]:
            ports.append(
                {
                    "port_name": "{}_{}".format(comp_name, net_name),
                    "comp_name": comp_name,
                    "net_name": net_name,
                }
            )

for net_name, net_obj in diff_n.extended_net.nets.items():
    for comp_name, comp_obj in net_obj.components.items():
        if comp_obj.type not in ["Resistor", "Capacitor", "Inductor"]:
            ports.append(
                {
                    "port_name": "{}_{}".format(comp_name, net_name),
                    "comp_name": comp_name,
                    "net_name": net_name,
                }
            )

print(*ports, sep="\n")
{'port_name': 'U1_PCIe_Gen4_TX3_CAP_P', 'comp_name': 'U1', 'net_name': 'PCIe_Gen4_TX3_CAP_P'}
{'port_name': 'X1_PCIe_Gen4_TX3_P', 'comp_name': 'X1', 'net_name': 'PCIe_Gen4_TX3_P'}
{'port_name': 'U1_PCIe_Gen4_TX3_CAP_N', 'comp_name': 'U1', 'net_name': 'PCIe_Gen4_TX3_CAP_N'}
{'port_name': 'X1_PCIe_Gen4_TX3_N', 'comp_name': 'X1', 'net_name': 'PCIe_Gen4_TX3_N'}

Create ports#

Solder balls are generated automatically. The default port type is coax port.

[9]:
for d in ports:
    port_name = d["port_name"]
    comp_name = d["comp_name"]
    net_name = d["net_name"]
    edbapp.components.create_port_on_component(component=comp_name, net_list=net_name, port_name=port_name)

Cutout#

Retain only relevant parts of the layout.

[10]:
nets = []
nets.extend(nets_p)
nets.extend(nets_n)
edbapp.cutout(signal_list=nets, reference_list=["GND"], extent_type="Bounding")
PyAEDT INFO: Cutout Multithread started.
PyAEDT INFO: Net clean up Elapsed time: 0m 4sec
PyAEDT INFO: Expanded Net Polygon Creation Elapsed time: 0m 0sec
PyAEDT INFO: Padstack Instances removal completed. 1907 instances removed. Elapsed time: 0m 1sec
PyAEDT INFO: Primitives cleanup completed. 438 primitives deleted. Elapsed time: 0m 4sec
PyAEDT INFO: Deleted 968 additional components
PyAEDT INFO: Cutout completed. Elapsed time: 0m 10sec
[10]:
[[0.016139999279999998, 0.05419999847],
 [0.016139999279999998, 0.03255000329],
 [0.06875000112, 0.03255000329],
 [0.06875000112, 0.05419999847]]

Set up the model for network analysis in SIwave.

[11]:
setup = edbapp.create_siwave_syz_setup("setup1")
setup.add_frequency_sweep(
    frequency_sweep=[
        ["linear count", "0", "1kHz", 1],
        ["log scale", "1kHz", "0.1GHz", 10],
        ["linear scale", "0.1GHz", "10GHz", "0.1GHz"],
    ]
)
[11]:
<pyedb.dotnet.edb_core.sim_setup_data.data.sweep_data.SweepData at 0x27b6d7f2880>

Save and close the EDB.

[12]:
edbapp.save()
edbapp.close_edb()
PyAEDT INFO: EDB file release time: 0.00ms
[12]:
True

Launch Hfss3dLayout#

The HFSS 3D Layout user interface in AEDT is used to import the EDB and run the analysis. AEDT 3D Layout can be used to view the model if it is launched in graphical mode.

[13]:
h3d = ansys.aedt.core.Hfss3dLayout(
    edb_full_path,
    specified_version="2024.2",
    non_graphical=False,  # Set to true for non-graphical mode.
    new_desktop_session=True,
)
PyAEDT WARNING: Argument `specified_version` is deprecated for method `__init__`; use `version` instead.
PyAEDT WARNING: Argument `new_desktop_session` is deprecated for method `__init__`; use `new_desktop` instead.
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.11.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_41010cf1-dadc-4afb-b78a-f5e2b9456e5d.log is enabled.
PyAEDT INFO: Log on AEDT is enabled.
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 50542
PyAEDT INFO: AEDT installation Path C:\Program Files\AnsysEM\v242\Win64
PyAEDT INFO: Ansoft.ElectronicsDesktop.2024.2 version started with process ID 7796.
PyAEDT INFO: EDB folder C:\Users\ansys\AppData\Local\Temp\tmp3mh0aoig.ansys\edb/ANSYS-HSD_V1.aedb has been imported to project ANSYS-HSD_V1
PyAEDT INFO: Active Design set to 0;main
PyAEDT INFO: Aedt Objects correctly read

Define the differential pair.

[14]:
h3d.set_differential_pair(
    positive_terminal="U1_PCIe_Gen4_TX3_CAP_P",
    negative_terminal="U1_PCIe_Gen4_TX3_CAP_N",
    diff_name="PAIR_U1",
)
h3d.set_differential_pair(
    positive_terminal="X1_PCIe_Gen4_TX3_P",
    negative_terminal="X1_PCIe_Gen4_TX3_N",
    diff_name="PAIR_X1",
)
PyAEDT WARNING: Argument `positive_terminal` is deprecated for method `set_differential_pair`; use `assignment` instead.
PyAEDT WARNING: Argument `negative_terminal` is deprecated for method `set_differential_pair`; use `reference` instead.
PyAEDT WARNING: Argument `diff_name` is deprecated for method `set_differential_pair`; use `differential_mode` instead.
PyAEDT WARNING: Argument `positive_terminal` is deprecated for method `set_differential_pair`; use `assignment` instead.
PyAEDT WARNING: Argument `negative_terminal` is deprecated for method `set_differential_pair`; use `reference` instead.
PyAEDT WARNING: Argument `diff_name` is deprecated for method `set_differential_pair`; use `differential_mode` instead.
[14]:
True

Solve and plot the results.

[15]:
h3d.analyze(num_cores=4)
PyAEDT WARNING: Argument `num_cores` is deprecated for method `analyze`; use `cores` instead.
PyAEDT INFO: Key Desktop/ActiveDSOConfigurations/HFSS 3D Layout Design correctly changed.
PyAEDT INFO: Solving all design setups.
PyAEDT INFO: Key Desktop/ActiveDSOConfigurations/HFSS 3D Layout Design correctly changed.
PyAEDT INFO: Design setup None solved correctly in 0.0h 0.0m 27.0s
[15]:
True

Visualze the results.

[16]:
h3d.post.create_report("dB(S(PAIR_U1,PAIR_U1))", context="Differential Pairs")
PyAEDT INFO: Parsing C:/Users/ansys/AppData/Local/Temp/tmp3mh0aoig.ansys/edb/ANSYS-HSD_V1.aedt.
PyAEDT INFO: File C:/Users/ansys/AppData/Local/Temp/tmp3mh0aoig.ansys/edb/ANSYS-HSD_V1.aedt correctly loaded. Elapsed time: 0m 0sec
PyAEDT INFO: aedt file load time 0.0625002384185791
PyAEDT INFO: Loading Modeler.
PyAEDT INFO: Modeler loaded.
PyAEDT INFO: EDB loaded.
PyAEDT INFO: Layers loaded.
PyAEDT INFO: Primitives loaded.
PyAEDT INFO: Modeler class has been initialized! Elapsed time: 0m 0sec
PyAEDT INFO: PostProcessor class has been initialized! Elapsed time: 0m 0sec
PyAEDT INFO: Post class has been initialized! Elapsed time: 0m 0sec
[16]:
<ansys.aedt.core.visualization.report.standard.Standard at 0x23ab1548370>

Close AEDT.

[17]:
h3d.save_project()
print("Project is saved to {}".format(h3d.project_path))
h3d.release_desktop(True, True)
PyAEDT INFO: Project ANSYS-HSD_V1 Saved correctly
Project is saved to C:/Users/ansys/AppData/Local/Temp/tmp3mh0aoig.ansys/edb/
PyAEDT INFO: Desktop has been released and closed.
[17]:
True

The following cell cleans up the temporary directory and removes all project data.

[18]:
temp_dir.cleanup()