SkillAgentSearch skills...

Gerber2ems

Python interface to OpenEMS, for PCB trace simulation. Accepts Gerber files as input. Features automatic grid generation and postprocessing.

Install / Use

/learn @antmicro/Gerber2ems
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

gerber2ems - openEMS simulation based on Gerber files

Copyright (c) 2023-2026 Antmicro

This project is a Python script that aims to streamline signal integrity simulations using open source tools. It takes PCB production files as input (Gerber, drill files, stackup information) and simulates trace SI performance using openEMS - a free and open source electromagnetic field solver that uses the FDTD method.

Installation

OpenEMS

Install the following packages (on Debian/Ubuntu):

sudo apt update
sudo apt install build-essential cmake git libhdf5-dev libvtk9-dev libboost-all-dev libcgal-dev libtinyxml-dev qtbase5-dev libvtk9-qt-dev cython3 pip

Clone the repository, compile and install openEMS:

It is recommended to use the a30587728affa4f8451e13819981899bd8ab6b64 commit, as this is the latest one tested with gerber2ems.

git clone https://github.com/thliebig/openEMS-Project.git
pushd ./openEMS-Project
git checkout a30587728affa4f8451e13819981899bd8ab6b64
git submodule update --init --recursive
./update_openEMS.sh ~/opt/openEMS --python
popd

Script installation

  1. Install the dependencies:
sudo apt install gerbv python3
  1. Clone and install gerber2ems
git clone https://github.com/antmicro/gerber2ems.git
pushd ./gerber2ems
source ~/opt/openEMS/venv/bin/activate
pip install .
ln -s ~/opt/openEMS/venv/bin/{gerber2ems,ems2paraview,ems2png} ~/.local/bin
popd

[!NOTE] I you want to use ems2paraview command run also sudo apt install paraview python3-paraview.

You can test gerber2ems with built-in examples. The examples are slices of our open hardware Signal Integrity Test Board, which were generated using the KiCad SI wrapper. Selected examples contain VNA measurements in dedicated vna.csv files, which allows us to compare openEMS simulation results with real life measurements.

cd ./gerber2ems/examples/stub_short
gerber2ems -a

Usage

For quick lookup, use gerber2ems --help.

To simulate a trace, follow these steps:

Results

The simulation output of the stub_short example is shown below. This software returns the following types of output:

S-parameter and impedance data

Impedance and S-parameter data gathered during the simulations, stored in CSV format with a header.

S-parameter chart

Plot of each S-parameter measured during each excitation.

Smith chart

Plot of parameter S-11 for each excitation.

Impedance chart

Plot of each excited port vs. frequency.

The stub_short example contains a vna.csv file, which can be used to verify simulation results.

How it works

Project preparation

Simulating an entire PCB is extremely resource-intensive, so it is important to separate a region of interest as small in size as possible - unneeded traces, pours etc., should be removed. If entire layers are redundant, you can remove them in later steps.

Ports of interest should be marked by a virtual component in positions files. Their designator should begin with "SP" and be followed by port number.

Origin point for drill files should be placed in bottom-left corner.

Every trace or pour that is somehow terminated in reality and will exist in the simulation should also be terminated using a simulation port or connected to ground.

For now, capacitors are not simulated and, for high frequency simulation, they can be aproximated by shorting them using a trace.

PCB input file preparation

This script requires multiple input files for geometry creation. They should all reside in the "fab" folder and are listed below:

  • Gerber files - each simulated copper layer should have a corresponding Gerber file named in the following format: "<optional-text>-<name-from-stackup-file>.gbr"

  • Stackup file - a file describing the PCB stackup, named "stackup.json". Example format:

    {
        "layers": [
            {
                "name": "F.Cu",
                "type": "copper",
                "color": null,
                "thickness": 0.035,
                "material": null,
                "epsilon": null,
                "lossTangent": null
            },
            {
                "name": "dielectric 1",
                "type": "core",
                "color": null,
                "thickness": 0.2,
                "material": "FR4",
                "epsilon": 4.5,
                "lossTangent": 0.02
            }
        ],
        "format_version": "1.0"
    }
    
  • Drill file - Drill file in excellon format with plated through-holes. Filename should end with "-PTH.drl"

  • Position file - File describing positions of ports.

    • Filename should end with "-pos.csv"

    • Coordinates should be given in relation to bottom left corner

    • The area of the port is calculated using the formulas in the table below, based on the Width and Length values from the simulation.json file:

      | Rotation [°] | X span | Y span | Wave travel direction | | ------------ | ------------------------------ | ------------------------------ | --------------------- | | 0 | (PosX-Width/2, PosX+Width/2) | (PosY, PosY+Length) | Along Y | | 90 | (PosX-Length, PosX) | (PosY-Width/2, PosY+Width/2) | Opposite to X | | 180 | (PosX-Width/2, PosX+Width/2) | (PosY-Length, PosY) | Opposite to Y | | 270 | (PosX, PosX+Length) | (PosY-Width/2, PosY+Width/2) | Along X |

    • Example file:

      # Ref     Val              Package                PosX       PosY       Rot  Side
      SP1       Simulation_Port  Simulation_Port      3.0000    11.7500  180.0000  top
      

Config preparation

The simulation.json file configures the entire simulation. You can find sample files in the example_gerbers folder. All dimensions in this file are specified in micrometers. This config file consists of three sections:

Miscellaneous

  • format_version - specifies the format of the config file When writing a new config, it should be the newest supported version (visible in the constants.py file)
  • frequency - start specifies the lowest frequency of interest and stop the highest (in Hz)
  • max_steps - max number of simulation steps after which the simulation will stop unconditionally
  • pixel_size - size of pixel in microns. Used during gerber conversion (default: 5) (due to a limitation of libcairo, this needs to be increased for larger boards, but try to keep as low as possible)
  • via/plating_thickness - via plating thickness (micrometers)
  • via/filling_epsilon - dielectric constant of the material the vias are filled in with If they are not filled in, it should be 1

Grid

  • inter_layers - number of grid lines in Z axis between neighboring PCB layers (default: 4)
  • optimal - basic mesh grid pitch (micrometers) (used for cells on metal edge) (default: 50) (Hint: Reduce for fine detailed designs)
  • diagonal - mesh grid pitch (micrometers) (used for regions with diagonal paths) (default: 50)
  • perpendicular - mesh grid pitch (micrometers) (used for regions with paths perpendicular to grid) (default: 200)
  • max - maximum mesh grid pitch (micrometers) (used outside of the board area) (default: 500)
  • cell_ratio/xy - optimal neighboring cell size ratio (X/Y axis) (default: 1.2)
  • cell_ratio/xy - optimal neighboring cell size ratio (Z axis) (default: 1.5)
  • margin/xy - margin size in X/Y axis (micrometers) (how far beyond pcb the grid spreads) (default: 1500)
  • margin/z - margin size in Z axis (micrometers) (default: 2000) (Hint: Increase for designs with wide features or ports or tall ports)
  • margin/from_trace - Limit simulation space based on nets-of-interest bounding box (default: True) (if False, board b-box is used).

Grid pitch options should follow optimal<=diagonal<=perpendicular<=max<=λmin/10

Ports

ports is a list of ports. Each port has the following parameters:

  • width - width of the port (micrometers)
  • length - length of the port (ports are currently composed of microstripline fragments whose length should be at least 8x mesh cell size) (micrometers)
  • impedance - terminating impedance of the port (impedance of driver or receiver) (Ohms)
  • layer - the number of the copper layer where the port is located (counting from the top)
  • plane - the number of the copper layer where the reference plane of the microstrip is located (counting from the top)
  • excite - whether the simulator should use this port as an input port (for multiple excited ports, they will be excited in separate simulations).

differential_pairs/traces

differential_pairs/traces are lists of simulated signals. Each signal can have following fields:

  • start_p, stop_p, start_n, stop_n - port numbers used for signal (differential_pair)
  • start, stop - port numbers used for signal (single
View on GitHub
GitHub Stars219
CategoryDevelopment
Updated1d ago
Forks29

Languages

Python

Security Score

100/100

Audited on Apr 4, 2026

No findings