HFSS automatic configuration#

Purpose#

The HFSSAutoConfiguration class (and its factory function create_hfss_auto_configuration) is a production-ready, declarative helper that turns a full-board EDB into analysis-ready HFSS cut-out projects without manual intervention.

Typical use-cases#

  • Post-layout signal-integrity sign-off for high-speed digital interfaces (PCIe, DDR, USB, Ethernet, etc.)

  • Automated impedance, insertion-loss and return-loss validation for every active net in the design

  • Regression testing across design spins—every net is simulated with identical boundary conditions, mesh settings, and port types

  • Design-of-experiments (DoE) where the same schematic is re-simulated with different stack-ups, materials, or solder-ball geometries

What the helper does#

  1. Opens the source EDB (board layout)

  2. Identifies signal and power/ground nets automatically

  3. Picks the best reference net (GND, VSS, AGND …) using a curated regex table

  4. Optionally groups nets into batches (differential pairs are never split)

  5. Creates a cut-out for every batch (bounding box or convex-hull)

  6. Places coaxial or circuit ports on every component that touches the signal nets

  7. Applies solder-ball geometry when supplied (cylinder, sphere, spheroid)

  8. Writes a ready-to-solve HFSS setup (adaptive mesh, broadband sweep, auto-seeding)

  9. Saves an independent EDB project per batch so that simulations can be distributed on a compute farm

The user only supplies:

  • path to the source EDB

  • (optionally) a list of nets or prefix patterns—everything else is auto-discovered

Design philosophy#

  • No manual GUI work—100 % script driven

  • Repeatable—identical settings for every net, every run

  • Scalable—cut-outs + batching keep problem size small enough for overnight turnaround on a 32-core box

  • Extensible—every numeric setting, port type or mesh strategy is exposed as a dataclass field

Minimal quick-start#

from pyedb import Edb
from pyedb.workflows.sipi.hfss_auto_configuration import create_hfss_auto_configuration

cfg = create_hfss_auto_configuration(
    source_edb_path=r"../release/board.aedb",
    target_edb_path=r"../hfss/serdes.aedb",
    batch_size=50,  # max 50 nets per cut-out
    port_type="coaxial",
)
cfg.auto_populate_batch_groups()  # discover nets and group them
cfg.create_projects()  # write one EDB + HFSS setup per batch

The snippet above produces a folder ../hfss/serdes.aedb that contains:

  • a cut-out with ≤ 50 nets

  • coaxial ports on every component pin

  • adaptive mesh 10 GHz–40 GHz sweep

  • ready to be solved

Class and data model#

HFSSAutoConfiguration#

class pyedb.workflows.sipi.hfss_auto_configuration.HFSSAutoConfiguration(edb=None)#

Automatic HFSS simulation configuration from EDB designs.

This class automates the process of configuring HFSS simulations including net grouping, cutout creation, port generation, and simulation setup.

Parameters:
edbEdb or None, optional

Existing EDB object instance. If None, a new instance will be created from the source path. The default is None.

Attributes:
ansys_versionstr

ANSYS Electronics Desktop version to use. The default is "2025.2".

grpcbool

Whether to use gRPC API mode. The default is True.

source_edb_pathstr

Path to the source EDB file.

target_edb_pathstr

Path where the configured EDB will be saved.

batch_group_folderstr

Folder path for storing batch group projects.

signal_netslist

List of signal net names to include in the simulation.

power_netslist

List of power net names.

reference_netstr

Name of the reference (ground) net.

batch_sizeint

Maximum number of nets per batch group. The default is 100.

batch_groupslist of BatchGroup

Configured batch groups for simulation.

componentslist of str

Component reference designators to include.

solder_ballslist of SolderBallsInfo

Solder ball configurations for components.

simulation_setupSimulationSetup

Global simulation settings.

extent_typestr

Cutout extent algorithm: "bounding_box", "convex_hull", or "conformal". The default is "bounding_box".

cutout_expansionstr or float

Cutout expansion margin. The default is "2mm".

auto_mesh_seedingbool

Enable automatic mesh seeding. The default is True.

port_typestr

Port type to create: "coaxial" or "circuit_port". The default is "coaxial".

create_pin_groupbool

Whether to create pin groups for circuit ports. The default is False.

Examples

Basic configuration:

>>> from pyedb import Edb
>>> config = HFSSAutoConfiguration()
>>> config.source_edb_path = "design.aedb"
>>> config.target_edb_path = "design_hfss.aedb"
>>> config.auto_populate_batch_groups()
>>> config.create_projects()

Configure with existing EDB:

>>> edb = Edb("design.aedb")
>>> config = HFSSAutoConfiguration(edb)
>>> config.signal_nets = ["DDR4_DQ0", "DDR4_CLK"]
>>> config.reference_net = "GND"
>>> config.add_solder_ball("U1", diameter="0.3mm", height="0.2mm")
add_batch_group(name: str, nets: list[str] | None = None, *, simulation_setup: SimulationSetup | None = None) BatchGroup#

Append a new BatchGroup to the configuration.

Parameters:
namestr

Descriptive name for the group. Will also become the regex pattern when the group is built automatically.

netslist of str or None, optional

List of net names that belong to this batch. If None, an empty list is assumed and can be filled later. The default is None.

simulation_setupSimulationSetup or None, optional

Per-batch simulation settings. When None, the global self.simulation_setup is used. The default is None.

Returns:
BatchGroup

The freshly created instance (already appended to batch_groups) for further manipulation if desired.

Examples

>>> config = HFSSAutoConfiguration()
>>> group = config.add_batch_group("DDR4", nets=["DDR4_DQ0", "DDR4_CLK"])
>>> group.name
'DDR4'
>>> len(group.nets)
2

Add group with custom setup:

>>> setup = SimulationSetup(stop_frequency="30GHz")
>>> group = config.add_batch_group("PCIe", simulation_setup=setup)
>>> group.simulation_setup.stop_frequency
'30GHz'
add_simulation_setup(meshing_frequency: str | float | None = '10GHz', maximum_pass_number: int = 15, start_frequency: str | float | None = 0, stop_frequency: str | float | None = '40GHz', frequency_step: str | float | None = '0.05GHz', replace: bool = True) SimulationSetup#

Create a SimulationSetup instance and attach it to the configuration.

Parameters:
meshing_frequencystr or float or None, optional

Driven frequency used during mesh generation. The default is "10GHz".

maximum_pass_numberint, optional

Maximum number of adaptive passes. The default is 15.

start_frequencystr or float or None, optional

Lower bound of the sweep window. The default is 0.

stop_frequencystr or float or None, optional

Upper bound of the sweep window. The default is "40GHz".

frequency_stepstr or float or None, optional

Linear step size for the frequency sweep. The default is "0.05GHz".

replacebool, optional

Placement strategy for the new setup:

  • False - Append a per-batch setup by creating an auxiliary BatchGroup (name="extra_setup") whose simulation_setup points to the new object.

  • True - Overwrite the global simulation_setup attribute of the current instance. The default is True.

Returns:
SimulationSetup

The newly created instance (already stored inside the configuration).

Examples

Create global setup:

>>> config = HFSSAutoConfiguration()
>>> config.add_simulation_setup(stop_frequency="60GHz", replace=True)
>>> config.simulation_setup.stop_frequency
'60GHz'

Create per-batch setup:

>>> config.add_simulation_setup(frequency_step="0.1GHz", replace=False)
>>> config.batch_groups[-1].name
'extra_setup'
add_solder_ball(ref_des: str, shape: str = 'cylinder', diameter: str | float | None = None, mid_diameter: str | float | None = None, height: str | float | None = None) SolderBallsInfo#

Append a new solder ball definition to the configuration.

Parameters:
ref_desstr

Reference designator of the component to which the solder ball definition applies (e.g., "U1").

shapestr, optional

Geometric model used for the solder ball. Supported values are "cylinder", "sphere", "spheroid". The default is "cylinder".

diameterstr or float or None, optional

Nominal diameter. When None, HFSS auto-evaluates the value from the footprint. The default is None.

mid_diameterstr or float or None, optional

Middle diameter required only for spheroid shapes. Ignored for all other geometries. The default is None.

heightstr or float or None, optional

Ball height. When None, HFSS computes an appropriate value automatically. The default is None.

Returns:
SolderBallsInfo

The newly created instance (already appended to solder_balls). The object can be further edited in-place if desired.

Examples

Add cylinder solder balls:

>>> config = HFSSAutoConfiguration()
>>> config.add_solder_ball("U1", diameter="0.3mm", height="0.2mm")
>>> config.solder_balls[0].ref_des
'U1'

Add spheroid solder balls:

>>> config.add_solder_ball("U2", shape="spheroid", diameter="0.25mm", mid_diameter="0.35mm", height="0.18mm")
>>> config.solder_balls[1].shape
'spheroid'
auto_populate_batch_groups(pattern: str | list[str] | None = None) None#

Automatically create and populate batch groups from signal nets.

This method discovers signal nets, identifies reference nets, and groups nets by prefix patterns. It is a convenience wrapper around group_nets_by_prefix().

Parameters:
patternstr or list of str or None, optional

POSIX ERE prefix pattern(s) controlling which nets are grouped:

  • None (default) - Auto-discovery mode: nets are clustered heuristically and split into chunks of size batch_size.

  • str - Single string prefix pattern (automatically anchored: pattern + ".*").

  • list of str - Each element becomes its own prefix pattern; one BatchGroup created per list entry, regardless of batch_size.

Notes

  • Clears and repopulates batch_groups in-place

  • Automatically identifies reference nets (typically GND variants)

  • Opens and closes the EDB internally

Examples

Auto-discovery with automatic grouping:

>>> config = HFSSAutoConfiguration()
>>> config.source_edb_path = "design.aedb"
>>> config.auto_populate_batch_groups()
>>> len(config.batch_groups)
5

Group by specific prefixes:

>>> config = HFSSAutoConfiguration()
>>> config.source_edb_path = "design.aedb"
>>> config.auto_populate_batch_groups(["DDR4", "PCIe", "USB"])
>>> [g.name for g in config.batch_groups]
['DDR4', 'PCIe', 'USB']
create_projects()#

Generate HFSS projects from configured batch groups.

This method executes the complete workflow for each batch group including:

  1. Copying source EDB to target location

  2. Creating cutout with specified nets

  3. Creating ports on components

  4. Setting up simulation parameters

  5. Saving configured project

When multiple batch groups exist, each group is processed into a separate project file stored in the batch_group_folder directory.

Notes

  • For multiple batch groups, projects are saved in batch_group_folder

  • Each batch can have custom simulation settings

  • Automatically handles EDB session management

Examples

Create single project:

>>> config = HFSSAutoConfiguration()
>>> config.source_edb_path = "design.aedb"
>>> config.target_edb_path = "design_hfss.aedb"
>>> config.signal_nets = ["DDR4_DQ0", "DDR4_CLK"]
>>> config.reference_net = "GND"
>>> config.components = ["U1"]
>>> config.create_projects()

Create multiple batch projects:

>>> config = HFSSAutoConfiguration()
>>> config.source_edb_path = "design.aedb"
>>> config.auto_populate_batch_groups(["DDR4", "PCIe"])
>>> config.create_projects()
>>> # Creates projects in batch_groups/DDR4.aedb and batch_groups/PCIe.aedb
group_nets_by_prefix(prefix_patterns: list[str] | None = None) dict[str, list[list[str]]]#

Group signal nets into disjoint batches while preserving differential pairs.

This method organizes signal nets into batches based on prefix patterns, ensuring differential pairs (e.g., _P/_N, _M/_L) stay together.

Parameters:
prefix_patternslist of str or None, optional

POSIX ERE patterns that define the prefixes to be grouped. Example: ["PCIe", "USB"] → interpreted as ["PCIe.*", "USB.*"]. If None, patterns are derived heuristically from the data set.

Returns:
dict[str, list[list[str]]]

Keys are the original or generated pattern strings. Values are lists of batches; each batch is an alphabetically sorted list of net names. When prefix_patterns was supplied, the list contains exactly one element (the complete group); in auto-discovery mode, the list may contain multiple slices sized according to batch_size.

Notes

  • Differential recognition strips the suffixes _[PN], _[ML], _[+-] (case-insensitive).

  • The function updates the instance attribute batch_groups in place.

  • Every net is assigned to exactly one batch.

  • No batch contains only a single net; orphans are merged into the largest compatible group.

Examples

Explicit grouping:

>>> config = HFSSAutoConfiguration()
>>> config.signal_nets = ["PCIe_RX0_P", "PCIe_RX0_N", "USB3_DP", "DDR4_A0"]
>>> config.group_nets_by_prefix(["PCIe", "USB"])
{'PCIe': [['PCIe_RX0_N', 'PCIe_RX0_P']], 'USB': [['USB3_DP']]}

Auto-discovery with batching:

>>> config.batch_size = 2
>>> config.group_nets_by_prefix()
{'PCIe': [['PCIe_RX0_N', 'PCIe_RX0_P']], 'USB': [['USB3_DP']], 'DDR4': [['DDR4_A0']]}

Simulation setup#

class pyedb.workflows.sipi.hfss_auto_configuration.SimulationSetup(meshing_frequency: str | float = '10GHz', maximum_pass_number: int = 15, start_frequency: str | float = 0, stop_frequency: str | float = '40GHz', frequency_step: str | float = '0.05GHz')#

HFSS simulation setup parameters.

This dataclass defines the simulation configuration including meshing frequency, convergence criteria, and frequency sweep settings.

Attributes:
meshing_frequencystr or float

Driven frequency used during mesh generation. The default is "10GHz".

maximum_pass_numberint

Maximum number of adaptive passes. The default is 15.

start_frequencystr or float

Lower bound of the frequency sweep. The default is 0.

stop_frequencystr or float

Upper bound of the frequency sweep. The default is "40GHz".

frequency_stepstr or float

Linear step size for the frequency sweep. The default is "0.05GHz".

Examples

>>> setup = SimulationSetup(meshing_frequency="5GHz", maximum_pass_number=20, stop_frequency="60GHz")
>>> setup.maximum_pass_number
20
>>> setup.stop_frequency
'60GHz'
frequency_step: str | float = '0.05GHz'#
maximum_pass_number: int = 15#
meshing_frequency: str | float = '10GHz'#
start_frequency: str | float = 0#
stop_frequency: str | float = '40GHz'#

BatchGroup#

class pyedb.workflows.sipi.hfss_auto_configuration.BatchGroup(name: str = '', nets: list[str] = <factory>, simulation_setup: ~pyedb.workflows.sipi.hfss_auto_configuration.SimulationSetup | None = None)#

Group of nets to be processed together in a batch simulation.

This dataclass represents a collection of signal nets that will be simulated together with optional custom simulation settings.

Attributes:
namestr

Descriptive name for the batch group. The default is "".

netslist of str

List of net names to include in this batch. The default is an empty list.

simulation_setupSimulationSetup or None

Custom simulation settings for this batch. If None, the global configuration settings are used. The default is None.

Examples

>>> group = BatchGroup(
...     name="DDR4_Signals",
...     nets=["DDR4_DQ0", "DDR4_DQ1", "DDR4_CLK"],
...     simulation_setup=SimulationSetup(stop_frequency="20GHz"),
... )
>>> group.name
'DDR4_Signals'
>>> len(group.nets)
3
name: str = ''#
nets: list[str]#
simulation_setup: SimulationSetup | None = None#

SolderBallsInfo#

class pyedb.workflows.sipi.hfss_auto_configuration.SolderBallsInfo(ref_des: str = '', shape: str = 'cylinder', diameter: str | float | None = None, mid_diameter: str | float | None = None, height: str | float | None = None)#

Solder ball configuration for component modeling.

This dataclass stores geometric parameters for solder ball definitions used in HFSS port creation and component modeling.

Attributes:
ref_desstr

Reference designator of the component. The default is "".

shapestr

Geometric shape of the solder ball: "cylinder", "sphere", or "spheroid". The default is "cylinder".

diameterstr or float or None

Nominal diameter of the solder ball. The default is None.

mid_diameterstr or float or None

Middle diameter for spheroid shapes only. The default is None.

heightstr or float or None

Height of the solder ball. The default is None.

Examples

>>> ball = SolderBallsInfo(ref_des="U1", shape="cylinder", diameter="0.3mm", height="0.2mm")
>>> ball.ref_des
'U1'
>>> ball.diameter
'0.3mm'
diameter: str | float | None = None#
height: str | float | None = None#
mid_diameter: str | float | None = None#
ref_des: str = ''#
shape: str = 'cylinder'#

Factory function#

Net grouping logic#

Differential-pair preservation#

The helper recognises the suffixes _P/_N, _M/_P, _+/- (case-insensitive) and keeps those nets in the same batch regardless of the requested batch_size.

Prefix patterns#

  • Auto-discovery mode (pattern=None) Nets are clustered by longest common prefix; each cluster is then split into chunks of size batch_size.

  • Explicit mode (pattern=["PCIe", "USB"]) One batch group per pattern is created; batch_size is ignored. Patterns are automatically treated as POSIX ERE anchored at the start: PCIe.*, USB.*.

Reference-net selection#

The first net that matches any of the following regexes (case-insensitive) is used as reference:

^GND\d*$          ^VSS\w*          ^DGND$          ^AGND$
^PGND$            ^EGND$           ^SGND$          ^REF$
^VREF[A-Z0-9]*    ^VR[A-Z0-9]*     ^VTT$           ^0V$
^GND_plane$       ^GROUND$         ^SENSE\d*$      ^KSENSE\w*
… (≈ 30 patterns in total)

If multiple candidates exist, the one whose name contains the string “GND” is preferred; the rest become power nets.

Port creation details#

Coaxial ports#

A coaxial cylinder is constructed normal to the component pin. The outer radius is derived from the pad-stack anti-pad; the inner radius from the finished hole size. When solder_balls are supplied the 3-D model is extended by the ball height and diameter.

Circuit ports#

A two-pin circuit port is placed between the signal pin and the nearest reference (ground) pin on the same component. If create_pin_group=True all pins of the same net are shorted into a single pin-group before the port is attached.

Mesh and sweep defaults#

All values can be overridden globally (simulation_setup) or per batch (BatchGroup.simulation_setup).

File and folder layout#

After create_projects() finishes you obtain:

<target_edb_parent>/
└── batch_groups/
    ├── PCIe_RX0.aedb/          # cut-out, 43 nets
    ├── PCIe_TX0.aedb/          # cut-out, 37 nets
    ├── USB3.aedb/              # cut-out,  8 nets
    └── DDR4_A0_A07.aedb/       # cut-out, 50 nets

Each *.aedb folder is an independent HFSS project that can be opened, solved and post-processed separately.

Logging and error handling#

  • Every operation is logged through the native EDB logger (INFO level)

  • Missing components, duplicate net names or impossible cut-outs raise before any file is written

  • If a batch group ends up with only one net, it is automatically merged into the largest compatible group to avoid degenerate simulations

Performance notes#

  • Typical cut-out + port creation time: 2–5 s per batch (201 GB DDR4 board, 3000 nets, 32 cores)

  • Memory footprint: < 2 GB per batch because only the clipped geometry is kept in memory

  • Scales linearly with number of batches—jobs can be dispatched to an HPC cluster independently

API reference index#

Examples#

Complete PCIe Gen-4 sign-off#

cfg = create_hfss_auto_configuration(
    source_edb_path=r"../../design/PCIE_gen4.aedb",
    batch_group_folder=r"../../hfss_gen4",
    batch_size=30,
    port_type="coaxial",
    solder_balls=[
        {
            "ref_des": "U1",
            "shape": "spheroid",
            "diameter": "0.35mm",
            "mid_diameter": "0.45mm",
            "height": "0.25mm",
        },
    ],
)
cfg.auto_populate_batch_groups(pattern=["PCIe"])  # only PCIe nets
cfg.create_projects()

Troubleshooting#

“No reference net found” → Add your ground name to ref_patterns or set reference_net manually.

“Empty batch group” → Check that signal_nets is non-empty and that the supplied prefix patterns actually match net names in the design.

“Project fails to solve” → Inspect the cut-out in AEDT: look for overlapping ports or missing reference pins; reduce batch_size to isolate the problematic net.

License#

MIT License, see file header for full text.