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\tmpuyg9pt2r.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.30.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 2sec
PyAEDT INFO: Extent Creation Elapsed time: 0m 0sec
PyAEDT INFO: 1907 Padstack Instances deleted. Elapsed time: 0m 1sec
PyAEDT INFO: 438 Primitives deleted. Elapsed time: 0m 2sec
PyAEDT INFO: 968 components deleted
PyAEDT INFO: Cutout completed. Elapsed time: 0m 5sec
[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 0x12bad39b520>

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.12.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_db4341ff-8477-4b2b-8089-b50f26b9bd3b.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 62590
PyAEDT INFO: AEDT installation Path C:\Program Files\AnsysEM\v242\Win64
PyAEDT INFO: Ansoft.ElectronicsDesktop.2024.2 version started with process ID 4928.
PyAEDT INFO: EDB folder C:\Users\ansys\AppData\Local\Temp\tmpuyg9pt2r.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/tmpuyg9pt2r.ansys/edb/ANSYS-HSD_V1.aedt.
PyAEDT INFO: File C:/Users/ansys/AppData/Local/Temp/tmpuyg9pt2r.ansys/edb/ANSYS-HSD_V1.aedt correctly loaded. Elapsed time: 0m 0sec
PyAEDT INFO: aedt file load time 0.03129005432128906
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 0x12ba0b4cd60>

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/tmpuyg9pt2r.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()