Steps to install IHP 130 nm + Qucs-S + Xyce + ngspice

These steps were verified on Lubuntu 24.04 on May 1, 2026

The stack consists of:

  • Qucs-S — schematic capture and simulation frontend

  • ngspice — SPICE simulator (easiest path, works out of the box with IHP PDK)

  • Xyce — Sandia’s SPICE-compatible simulator (requires plugin build for IHP PDK)

  • IHP Open PDK SG13G2 — 130nm SiGe BiCMOS process design kit

  • OpenVAF — Verilog-A compiler for ngspice OSDI plugins

  • ADMS — Verilog-A compiler for Xyce plugins


Part 1: System Dependencies

sudo apt update
sudo apt install -y build-essential cmake git curl libfftw3-dev libsuitesparse-dev libqt5core5a libqt5gui5 libqt5widgets5 libqt5svg5 flex bison adms python3 python3-pip gperf dos2unix qt6-base-dev qt6-tools-dev qt6-tools-dev-tools libglx-dev linguist-qt6 qt6-l10n-tools libqt6svg6-dev libgl1-mesa-dev gfortran

You can install the ngspice binaries via apt command, but you can also install ngspice from source. The former method is very straighforward, but the latter ensures you have the latest version.

Precompiled binaries

sudo apt-get install ngspice

Install from source

sudo apt update
sudo apt install autoconf automake libtool libxaw7-dev libreadline-dev bison libsndfile1-dev libsamplerate0-dev flex

git clone https://git.code.sf.net/p/ngspice/ngspice ngspice-ngspice
cd ngspice-ngspice
./autogen.sh
./configure --enable-osdi
make -j$(nproc)
sudo make install

Part 2: Install Qucs-S from source

Despite Qucs-S binaries are available, I recommend to install Qucs-S from source.

mkdir ~/git
cd ~/git

git clone https://github.com/ra3xdh/qucs_s.git
cd qucs_s
mkdir build && cd build

cmake ..

make -j$(nproc)
sudo make install

Part 3: Install IHP Open PDK

cd ~
mkdir -p ~/git && cd ~/git
git clone https://github.com/IHP-GmbH/IHP-Open-PDK.git

Set environment variables and add to ~/.bashrc for persistence:

echo 'export PDK_ROOT=$HOME/git/IHP-Open-PDK' >> ~/.bashrc
echo 'export PDK=ihp-sg13g2' >> ~/.bashrc
source ~/.bashrc

Part 4: Set up ngspice with IHP PDK

ngspice uses OpenVAF-compiled OSDI plugins for the PSP103 model.

Install OpenVAF

Download the latest OpenVAF binary from https://openvaf.semimod.de/download/

You can do it through the web browser or as indicated below:

cd ~/Downloads
wget https://openva.fra1.cdn.digitaloceanspaces.com/openvaf_23_5_0_linux_amd64.tar.gz
tar -xvzf openvaf_23_5_0_linux_amd64.tar.gz 
sudo cp openvaf /usr/local/bin/openvaf

Check that openvaf is available on the path

which openvaf
openvaf --version

Compile Verilog-A IHP devices and install them in Qucs-S

cd $PDK_ROOT/$PDK/libs.tech/qucs-s/
python3 install.py

Open Qucs-S, and go to (CTRL + ,) File->Application Settings->Locations.

At the bottom add “~/QucsWorkspace/user_lib” to the locations panel.

Notice that a sample IHP project is created at the QucsWorspace directory. You should be able to run the simulations with NGspice at this point.

Part 5: Set up Xyce with IHP PDK

Xyce requires Verilog-A models to be compiled into shared object plugins using ADMS. This is more involved than ngspice but gives access to Xyce-specific simulation features.

5.1 Clone Trilinos and Xyce

mkdir -p ~/git && cd ~/git

git clone https://github.com/trilinos/Trilinos.git
cd Trilinos && git checkout trilinos-release-14-4-0 && cd ..

git clone https://github.com/Xyce/Xyce.git

5.2 Build Trilinos with shared libs

cd ~/git/Trilinos
rm -rf build
mkdir build && cd build

cmake .. \
  -DCMAKE_BUILD_TYPE=Release \
  -DCMAKE_INSTALL_PREFIX=/usr/local \
  -DCMAKE_C_COMPILER=/usr/bin/gcc \
  -DCMAKE_CXX_COMPILER=/usr/bin/g++ \
  -DTrilinos_ENABLE_ALL_PACKAGES=OFF \
  -DTrilinos_ENABLE_ALL_OPTIONAL_PACKAGES=OFF \
  -DTrilinos_ENABLE_TESTS=OFF \
  -DTrilinos_ENABLE_EXAMPLES=OFF \
  -DTrilinos_ENABLE_Amesos=ON \
  -DTrilinos_ENABLE_Epetra=ON \
  -DTrilinos_ENABLE_EpetraExt=ON \
  -DEpetraExt_BUILD_BTF=ON \
  -DEpetraExt_BUILD_EXPERIMENTAL=ON \
  -DEpetraExt_BUILD_GRAPH_REORDERINGS=ON \
  -DTrilinos_ENABLE_Ifpack=ON \
  -DTrilinos_ENABLE_NOX=ON \
  -DTrilinos_ENABLE_Teuchos=ON \
  -DTrilinos_ENABLE_Sacado=ON \
  -DTrilinos_ENABLE_Triutils=ON \
  -DTrilinos_ENABLE_AztecOO=ON \
  -DTrilinos_ENABLE_Belos=ON \
  -DTrilinos_ENABLE_TrilinosCouplings=ON \
  -DTrilinos_ENABLE_CXX11=ON \
  -DTPL_ENABLE_MPI=OFF \
  -DTPL_ENABLE_AMD=ON \
  -DAMD_INCLUDE_DIRS='/usr/include/suitesparse' \
  -DBUILD_SHARED_LIBS=ON \
  -DTrilinos_ENABLE_COMPLEX=OFF \
  -DTrilinos_ENABLE_COMPLEX_DOUBLE=ON \
  -DTrilinos_ENABLE_DOUBLE=ON \
  -DTrilinos_ENABLE_EXPLICIT_INSTANTIATION=ON \
  -DTrilinos_ENABLE_Kokkos=ON \
  -DKokkos_ENABLE_SERIAL=ON

# Apply cstdint patch (required for GCC 13+)
grep -q "cstdint" \
  ~/git/Trilinos/packages/kokkos/core/src/impl/Kokkos_MemoryPool.cpp || \
  sed -i '/#include <sstream>/a #include <cstdint>' \
  ~/git/Trilinos/packages/kokkos/core/src/impl/Kokkos_MemoryPool.cpp

make -j$(nproc)
sudo make install

5.3 Build Xyce with plugin support

cd ~/git/Xyce
rm -rf build  # Always start with a clean build directory
mkdir build && cd build

cmake .. \
  -DCMAKE_BUILD_TYPE=Release \
  -DCMAKE_INSTALL_PREFIX=/usr/local \
  -DTrilinos_DIR=/usr/local/lib/cmake/Trilinos \
  -DBUILD_SHARED_LIBS=ON \
  -DXyce_PLUGIN_SUPPORT=ON

Then build and install:

make -j$(nproc)
sudo make install

5.5 Patch buildxyceplugin.sh for include path support

The script doesn’t pass -I to admsXml, causing include file failures. Patch it once after installation:

sudo cp /usr/local/bin/buildxyceplugin.sh /usr/local/bin/buildxyceplugin.sh.bak

sudo sed -i \
  's|admsXml -D__XYCE__ -x -e|admsXml -D__XYCE__ -x -I$(dirname $1) -e|' \
  /usr/local/bin/buildxyceplugin.sh

# Verify the patch
grep "admsXml" /usr/local/bin/buildxyceplugin.sh
# Should contain: admsXml -D__XYCE__ -x -I$(dirname $1) -e ...

5.6 Fix IHP PDK Verilog-A source issues

Two issues in the PDK sources must be fixed before building plugins.

Fix 1: Remove mosvar’s incompatible discipline.h

rm $PDK_ROOT/$PDK/libs.tech/verilog-a/mosvar/discipline.h

Fix 2: Create PSP103 wrapper to resolve dual module declaration

psp103.va contains two module declarations in an ifdef __XYCE__ block that ADMS cannot handle correctly, producing an empty module with no parameters. Create a wrapper that pre-defines __XYCE__:

cat > $PDK_ROOT/$PDK/libs.tech/verilog-a/psp103/psp103_xyce_wrapper.va << 'EOF'
`define __XYCE__
`include "psp103.va"
EOF

5.7 Build the PDK plugins

Each plugin must be built in a clean directory to avoid symbol conflicts.

PLUGINS_DIR=$PDK_ROOT/$PDK/libs.tech/xyce/plugins
FINAL_DIR=$PDK_ROOT/$PDK/libs.tech/xyce/plugins_final
mkdir -p $FINAL_DIR
mkdir -p $PLUGINS_DIR

# --- PSP103 (use wrapper, NOT psp103.va directly) ---
rm -rf $PLUGINS_DIR/*
cd $PDK_ROOT/$PDK/libs.tech/verilog-a/psp103
buildxyceplugin -o Xyce_Plugin_PSP103_VA  $(pwd)/psp103_xyce_wrapper.va $PLUGINS_DIR
cp $PLUGINS_DIR/libXyce_Plugin_PSP103_VA.so $FINAL_DIR/

# --- r3_cmc ---
rm -rf $PLUGINS_DIR/*
cd $PDK_ROOT/$PDK/libs.tech/verilog-a/r3_cmc
buildxyceplugin $(pwd)/r3_cmc.va $PLUGINS_DIR
cp $PLUGINS_DIR/libXyce_Plugin_r3_cmc.so $FINAL_DIR/

# --- mosvar ---
rm -rf $PLUGINS_DIR/*
cd $PDK_ROOT/$PDK/libs.tech/verilog-a/mosvar
buildxyceplugin $(pwd)/mosvar.va $PLUGINS_DIR
cp $PLUGINS_DIR/libXyce_Plugin_mosvar.so $FINAL_DIR/

# Collect all final plugins
rm -rf $PLUGINS_DIR/*
cp $FINAL_DIR/*.so $PLUGINS_DIR/

# Verify
ls $PLUGINS_DIR/*.so
# Expected:
#   libXyce_Plugin_PSP103_VA.so
#   libXyce_Plugin_r3_cmc.so
#   libXyce_Plugin_mosvar.so

5.8 Create Xyce-ihp wrapper script

Create a wrapper that automatically loads the IHP plugins:

sudo tee /usr/local/bin/Xyce-ihp > /dev/null << EOF
#!/bin/bash
PLUGINS_DIR=$HOME/git/IHP-Open-PDK/ihp-sg13g2/libs.tech/xyce/plugins
exec /usr/local/bin/Xyce \\
  -plugin "\$PLUGINS_DIR/libXyce_Plugin_PSP103_VA.so" \\
  "\$@"
EOF
sudo chmod +x /usr/local/bin/Xyce-ihp

5.9 Configure Qucs-S for Xyce

In Qucs-S go to Simulation->Simulator Settings and set the Xyce executable to:

/usr/local/bin/Xyce-ihp

Part 6: Netlist Guidelines

Always use absolute paths in .LIB

Relative paths work in ngspice but fail in Xyce. Use absolute paths always. Add this before $PDK_ROOT/$PDK/libs.tech/xyce/models/ the library in the spicecode block in Qucs-S.

Library and corner reference

Device

ngspice lib

Xyce lib

LV NMOS/PMOS

ngspice/models/cornerMOSlv.lib

xyce/models/cornerMOSlv.lib

HV NMOS/PMOS

ngspice/models/cornerMOShv.lib

xyce/models/cornerMOShv.lib

HBT

ngspice/models/cornerHBT.lib

xyce/models/cornerHBT.lib

Resistors

ngspice/models/cornerRES.lib

xyce/models/cornerRES.lib

Capacitors

ngspice/models/cornerCAP.lib

xyce/models/cornerCAP.lib