Skip to content

Repository files navigation

An Open-Source Analog Mixed-Signal Chip Design Template & Tutorial for the ihp-sg13g2 Open-PDK

License: Solderpad Hardware License v2.1 Quarto Publish Regression Tutorial DOI

(c) 2026 Simon Dorrer and Harald Pretl

Institute for Integrated Circuits and Quantum Computing, Johannes Kepler University (JKU), Linz, Austria

Important

This repository requires the IIC-OSIC-TOOLS container with tag 2026.06 or later.

Chip render of the ihp-sg13g2 analog-mixed signal template chip (1.6 mm x 1.6 mm)
Chip render of the ihp-sg13g2 analog-mixed signal template chip (1.6 mm x 1.6 mm).

Render of the TopMetal2 AMS Chip logo, generated with the tool ArtistIC
Render of the TopMetal2 AMS Chip logo, generated with the tool ArtistIC.

Overview

This Makefile-driven repository simulates, builds, and fully verifies (LVS, DRC, PEX) a complete analog mixed-signal chip for the ihp-sg13g2 130nm Open-PDK, including padframe generation and top-level assembly. It uses:

The repository is the starting point for your own custom silicon and provides a universal design flow solution: Just clone the repo, enter the IIC-OSIC-TOOLS container, and run make all to get a tapeout-ready analog-mixed signal chip. Focus on your design and do not care about the tools and the design flow!

Furthermore, it serves as a regression test for the above-mentioned open-source tools and their dependencies using the ihp-sg13g2 Open-PDK.

Tutorial

A step-by-step tutorial, including additional exercises, can be found here.

An overview of the open source IC design landscape is presented here.

Examples

Examples based on this template are:

  • TinyWhisper: An Open-Source Fully-Integrated Multi-Mode Short-Wave Transmitter for Amateur Radio Applications in 130-nm CMOS
  • SPARX: An Open-Source, Automated, Programmatically Generated, Frequency-Scalable Six-Port Receiver in 130-nm CMOS
  • wafer.space gf180mcuD MPW Multi-Project Chip

Chip Documentation

A designer-oriented description of this chip can be found in doc/:

  • doc/specifications.md: top-level specifications (technology, supplies, clock, macro inventory, functional behaviour).
  • doc/pinout.md: full 32-pad bondpad table per side, with the chip_top port and the role each pad carries inside chip_core.
  • doc/floorplan.md: die / core geometry, hard-macro placement coordinates, PDN strategy and the floorplan diagram.

Directory Structure

📁 ihp-sg13g2-ams-chip-template/
├─ 📁 doc/
│  ├─ 📁 ihp-sg13g2-Open-PDK/
│  ├─ 📁 ihp-structure-proposals/
│  ├─ 📁 klayout/
│  ├─ 📁 librelane/
│  ├─ 📁 sizing/
│  ├─ floorplan.md
│  ├─ pinout.md
│  └─ specifications.md
├─ 📁 flow/
│  ├─ 📁 artistic/
│  ├─ 📁 librelane/
│  │  ├─ chip_top.sdc
│  │  ├─ config.yaml
│  │  └─ pdn_cfg.tcl
│  └─ 📁 logo/
│     └─ chip_logo_mono.png
├─ 📁 ip/
│  ├─ 📁 sg13g2_io_custom/
│  ├─ 📁 sg13g2_ip__bondpad_70x70/
│  │  ├─ 📁 final/
│  │  ├─ 📁 script/
│  │  ├─ 📁 verification/
│  │  ├─ Makefile
│  │  └─ README.md
│  ├─ 📁 sg13g2_ip__jku/
│  │  ├─ 📁 final/
│  │  ├─ 📁 logo/
│  │  ├─ 📁 script/
│  │  ├─ 📁 verification/
│  │  ├─ Makefile
│  │  └─ README.md
│  └─ 📁 sg13g2_ip__jku_names/
│     ├─ 📁 final/
│     ├─ 📁 logo/
│     ├─ 📁 script/
│     ├─ 📁 verification/
│     ├─ Makefile
│     └─ README.md
├─ 📁 layout/
│  ├─ chip_top.gds.gz
│  └─ chip_top_logo_fill.gds.gz
├─ 📁 macros/
│  ├─ 📁 counter/
│  │  ├─ 📁 final/
│  │  ├─ 📁 flow/
│  │  ├─ 📁 fpga/
│  │  ├─ 📁 netlist/
│  │  ├─ 📁 render/
│  │  ├─ 📁 rtl/
│  │  ├─ 📁 schematic/
│  │  ├─ 📁 scripts/
│  │  ├─ 📁 testbenches/
│  │  ├─ 📁 verification/
│  │  ├─ Makefile
│  │  └─ README.md
│  └─ 📁 inverter/
│     ├─ 📁 final/
│     ├─ 📁 layout/
│     ├─ 📁 netlist/
│     ├─ 📁 render/
│     ├─ 📁 schematic/
│     ├─ 📁 scripts/
│     ├─ 📁 testbenches/
│     ├─ 📁 verification/
│     ├─ Makefile
│     └─ README.md
├─ 📁 netlist/
│  ├─ 📁 layout/
│  ├─ 📁 nl/
│  ├─ 📁 pex/
│  ├─ 📁 pnl/
│  └─ 📁 spice/
├─ 📁 release/
│  └─ 📁 v.1.0.0/
│     ├─ 📁 gds/
│     ├─ 📁 img/
│     ├─ 📁 netlist/
│     └─ README.md
├─ 📁 render/
│  ├─ 📁 blender/
│  └─ 📁 img/
├─ 📁 rtl/
│  ├─ chip_core.sv
│  └─ chip_top.sv
├─ 📁 schematic/
│  └─ 📁 xschem/
│     ├─ chip_top.sch
│     ├─ chip_top.sym
│     ├─ chip_top_pex.sym
│     └─ xschemrc
├─ 📁 scripts/
│  ├─ 📁 plot_simulations/
│  ├─ add_logo_fill.sh
│  ├─ add_rectangle.py
│  └─ lay2img.py
├─ 📁 testbenches/
│  ├─ 📁 cocotb/
│  │  ├─ chip_top_tb.gtkw
│  │  ├─ chip_top_tb.py
│  │  └─ chip_top_tb.surf.ron
│  └─ 📁 xschem/
│     ├─ chip_top_tb_tran.sch
│     └─ xschemrc
├─ 📁 tutorial/
│  ├─ 📁 fig/
│  ├─ _quarto.yml
│  ├─ index.qmd
│  ├─ Makefile
│  └─ requirements.txt
├─ 📁 verification/
│  ├─ 📁 drc/
│  ├─ 📁 lvs/
│  └─ 📁 reports/
│     ├─ antenna_summary.rpt
│     ├─ antenna_violations.rpt
│     ├─ hold_setup_timing.rpt
│     ├─ irdrop.rpt
│     ├─ lvs.netgen.rpt
│     ├─ manufacturability.rpt
│     ├─ stapostpnr_*.rpt
│     ├─ stat.rpt
│     ├─ yosys_post_dff.rpt
│     ├─ yosys_pre_techmap.rpt
│     └─ yosys_synth_check.rpt
├─ CITATION.cff
├─ LICENSE
├─ Makefile
├─ README.md
└─ ToDo.md

Show Available Targets

The default Make target is help, so running make prints usage and all available targets with short descriptions.

make
make help

Initialize Git Submodules

Initializes and updates the repository submodules (for example ArtistIC):

make init-submodules

Run this after cloning the repository, or whenever submodule pointers are updated.

Simulation

We use cocotb, a Python-based testbench environment, for the verification of the chip. The underlying simulator is Icarus Verilog.

The simulation targets accept an optional CELL variable (default: chip_top). The testbench is located in testbenches/cocotb/chip_top_tb.py. To run the RTL simulation, use:

make sim-rtl-cocotb

To run the gate-level (GL) simulation with cocotb, use:

make sim-gl-cocotb

To run the gate-level simulation with Xschem, use:

make sim-gl-xschem

Note

sim-gl-xschem is available and converges, but it may take a long time depending on the hardware used. It is therefore not included in sim-all and must be called manually.

To plot the Xschem simulation results using the Python script in scripts/plot_simulations/, use:

make sim-view-xschem
make sim-view-xschem CELL=chip_top

The target runs python3 scripts/plot_simulations/plot_<CELL>.py. CELL defaults to chip_top.

Note

sim-view-xschem is intentionally not called by sim-all. It opens the generated Python figures, which blocks the shell until the window is closed. It is designed for interactive use and must be called manually after the simulation has completed.

The cocotb simulations generate a waveform file under testbenches/cocotb/sim_build/chip_top.fst. You can view it with a waveform viewer such as GTKWave or Surfer. The waveform viewer can be changed with WAVEFORM_VIEWER=<gtkwave|surfer> (default: gtkwave).

make sim-view-cocotb                                          # view chip_top waveform with GTKWave (default)
make sim-view-cocotb WAVEFORM_VIEWER=surfer                   # use Surfer instead

Each cocotb simulation folder contains a pre-configured waveform layout file (<CELL>_tb.gtkw for GTKWave, <CELL>_tb.surf.ron for Surfer). The view target loads it automatically together with the current .fst, so signal formatting is preserved across runs.

To run all non-interactive simulation targets in sequence (RTL cocotb and GL cocotb), use:

make sim-all

Note

sim-view-cocotb is intentionally not called by sim-all. It opens a waveform viewer GUI (GTKWave or Surfer), which blocks the shell until the window is closed. It is designed for interactive use and must be called manually after the simulation has completed.

Note

sim-gl-xschem and sim-view-xschem are also not included in sim-all because sim-gl-xschem may take a long time depending on the hardware used. Run them manually with make sim-gl-xschem followed by make sim-view-xschem when needed.

LibreLane Flow

Run the LibreLane flow with:

make librelane

Additional targets are available for different DRC configurations:

  • make librelane-nodrc – run LibreLane without DRC checks
  • make librelane-magicdrc – run LibreLane with only Magic DRC checks
  • make librelane-klayoutdrc – run LibreLane with only KLayout DRC checks

These targets are also available for the digital macros. After the LibreLane flow completes successfully, the generated views are saved under flow/final/.

View the Design

After completion, you can view the design using the OpenROAD GUI:

make librelane-openroad

Or using KLayout:

make librelane-klayout

These commands are also available for the digital macros.

Copy Important Reports

To copy the Yosys synthesis checks, antenna-violation reports, post-PnR hold & setup timing summary, LVS report, and manufacturability report from the latest LibreLane run into verification/reports/, run:

make copy-reports

This only works if the latest run completed without errors. This command is also available for the digital macros.

Note

The Magic and KLayout DRC reports are temporarily not copied because IHP's metal1_pin_offgrid rule trips on the pad ring. Once it is fixed upstream the corresponding cp lines in Makefile :: copy-reports will be re-enabled.

Copy the Final GDS

To copy and compress the latest GDS from flow/final/gds/ into layout/, run:

make copy-gds

Copy the Final Netlist

To copy the latest SPICE, PnL, and NL netlists from flow/final/spice/ into netlist/spice/, from flow/final/pnl/ into netlist/pnl/, and from flow/final/nl/ into netlist/nl/, run:

make copy-netlist

This only works if the latest run completed without errors.

Copy the Final Render

To copy the latest LibreLane chip render from flow/final/render/ into render/img/, run:

make copy-render

This creates render/img/chip_top_librelane.png. This only works if the latest run completed without errors.

Render Top Layout

Renders the top-level GDS from layout/ and saves it in the render/img/ folder:

make render-gds

This only works if the latest run completed without errors. This command is also available for the digital macros.

Build Bondpad

To build the bondpad in the ip folder, run the following command:

make build-bondpad

Build Logos

To build the logos in the ip folder, run the following command:

make build-logos

Initialize a New Macro

To scaffold a new macro (directory tree, Makefile, README.md, sizing/plot script skeletons, CACE spec skeleton — or RTL stubs and LibreLane config for digital macros) from the templates in macros/_templates/, run:

make init-macro MACRO=<name> [TYPE=analog|digital]

TYPE defaults to analog. The wrapper cell producing the final GDS is <core>_top: for MACRO=rx_fe the cells are rx_fe/rx_fe_top; a name that already ends in _top (e.g. MACRO=vco_top) yields vco/vco_top. The script prints the next steps; once the macro has content to build, add it to the MACROS list in the top-level Makefile so build-macros includes it.

Build Macros

To build a specific macro, run make build-<macroname> (a generic pattern target that dispatches to the macro's in-tree make all). To build all currently enabled macros (the MACROS list in the Makefile), run:

make build-macros

Build Digital Macros

The following command builds the counter digital macro:

make build-counter

For each digital macro this dispatches to its in-tree make all, which lints, simulates, runs LibreLane, copies the reports, and renders the final GDS.

Tip

Each macro has its own Makefile and README.md with additional targets, such as linting, simulation, and verification. For example, to lint the counter or run its simulation, refer to macros/counter/README.md.

Build Analog Macros

Each analog macro has its own klayout-verify and magic-verify targets that run LVS, DRC, and PEX for the top-level cell.

To build the inverter macro:

make build-inverter

All analog macros are included in build-macros alongside the digital macros.

Build Top

To run LibreLane for the top-level chip and copy the resulting reports, GDS, netlist, and chip render back into the source tree, then add the logo + fill structures and render the final GDS, run:

make build-top

Internally this executes (in order): librelane-nodrccopy-reportscopy-gdscopy-netlistcopy-renderadd-logo-fillrender-gds.

Build All

To initialise submodules, build the bondpad, build the logos, build the macros, and run the full build-top flow, run:

make build-all

This is useful if you want to rebuild the chip from scratch. Clone the repository, enter the IIC-OSIC-TOOLS environment, and run make build-all.

Add Logo and Fill

To add the chip logo (PNG → GDS) and the fill structures on top of the LibreLane output (so the final GDS in layout/ includes the artwork), run:

make add-logo-fill

This calls scripts/add_logo_fill.sh and writes layout/chip_top_logo_fill.gds.gz. The step is also called from make build-top.

Note

In the future, it is planned to replace this script and Makefile target with a custom librelane step.

Export Schematic Netlist for LVS

Exports the schematic netlist for LVS from Xschem and places it in netlist/schematic/.

The EV_PRECISION parameter sets the number of significant digits used by Xschem's ev function when calculating device properties (default: 5). Increase this to avoid LVS mismatches caused by floating-point rounding differences between Xschem and KLayout (see xschem#465).

Currently, KLayout LVS extracts ntap and ptap devices, so the schematic netlist must include them as well. In contrast, Magic + Netgen LVS does not extract ntap and ptap. Therefore, the schematic uses lvs_ignore = short for these devices and conditional net labels (see xschem#474). To make this effective during schematic netlist export, set lvs_ignore 1 must be set in the magic-lvs-netlist target.

KLayout uses CDL netlists, while Magic uses SPICE netlists. Accordingly, klayout-lvs-netlist uses the Xschem commands set spiceprefix 1, set lvs_netlist 1, set top_is_subckt 1, and set lvs_ignore 0. In contrast, magic-lvs-netlist uses set spiceprefix 1, set lvs_netlist 0, set top_is_subckt 1, and set lvs_ignore 1.

To extract a CDL schematic netlist for KLayout LVS, use:

make klayout-lvs-netlist
make klayout-lvs-netlist CELL=chip_top
make klayout-lvs-netlist EV_PRECISION=5

To extract a SPICE schematic netlist for Magic + Netgen LVS, use:

make magic-lvs-netlist
make magic-lvs-netlist CELL=chip_top
make magic-lvs-netlist EV_PRECISION=5

Layout Versus Schematic (LVS)

Exports the schematic netlist from Xschem, then runs LVS. Compares the GDS layout in layout/ against the schematic netlist in netlist/schematic/. Reports are saved to verification/lvs/. The extracted layout netlist is moved to netlist/layout/.

KLayout LVS uses run_lvs.py from the IHP Open-PDK:

make klayout-lvs
make klayout-lvs CELL=chip_top

Magic + Netgen LVS uses sak-lvs.sh:

make magic-lvs
make magic-lvs CELL=chip_top

Design Rule Check (DRC)

Runs DRC on the GDS layout in layout/. Reports are saved to verification/drc/.

KLayout DRC (minimum) runs a pre-check KLayout DRC on the final top-level layout with logo and fill structures:

make klayout-drc-minimum

KLayout DRC (regular) runs a regular KLayout DRC on the final top-level layout with logo and fill structures:

make klayout-drc-regular

KLayout DRC uses run_drc.py from the IHP Open-PDK with relaxed rules (FEOL, density checks, and extra rules disabled):

make klayout-drc
make klayout-drc CELL=chip_top

Magic DRC uses sak-drc.sh:

make magic-drc
make magic-drc CELL=chip_top

Parasitic Extraction (PEX)

Runs parasitic extraction on the GDS layout in layout/. The extracted SPICE netlist is written to netlist/pex/.

The extracted SPICE filenames include the selected extraction mode:

  • klayout-pex writes netlist/pex/<CELL>_klayout_pex_<EXT_MODE>.spice
  • magic-pex writes netlist/pex/<CELL>_magic_pex_<EXT_MODE>.spice

The EXT_MODE parameter selects the extraction mode:

  • 1 = C-decoupled (default)
  • 2 = C-coupled
  • 3 = full-RC

Note

For klayout-pex, EXT_MODE=1 (C-decoupled) is not yet supported by kpex and automatically falls back to EXT_MODE=2 (CC) with a warning.

The .subckt name in the extracted SPICE file is automatically renamed from <CELL>_flat (kpex) or <CELL> (Magic) to <CELL>_pex.

If a matching Xschem symbol (schematic/<CELL>_pex.sym) exists, the .subckt pin order in the extracted SPICE file is automatically reordered to match the symbol's pin positions. This ensures the PEX netlist can be used directly with the corresponding Xschem symbol for simulation regardless of the selected EXT_MODE.

KLayout PEX uses kpex with the Magic extraction engine currently (2.5D engine is work in progress):

make klayout-pex
make klayout-pex CELL=chip_top
make klayout-pex CELL=chip_top EXT_MODE=3

Magic PEX uses sak-pex.sh:

make magic-pex
make magic-pex CELL=chip_top
make magic-pex CELL=chip_top EXT_MODE=3

Verify a Specific Cell

Runs LVS, DRC, and PEX for a specific cell (e.g. chip_top):

make klayout-verify CELL=chip_top
make magic-verify CELL=chip_top

Verify Top Cell

Runs LVS, DRC, and PEX for the top cell:

make klayout-verify
make magic-verify

Build and Verify All

Runs full simulation (sim-all), then build-all, followed by Magic DRC for both chip_top and chip_top_logo_fill:

make all

Release

Copies the final top-level GDS with logo and fill structures from layout/ to release/v.<VERSION>/gds/, copies the generated netlists into release/v.<VERSION>/netlist/, and copies the chip renders into release/v.<VERSION>/img/.

The following netlist folders are exported:

  • netlist/layout -> release/v.<VERSION>/netlist/layout
  • netlist/pnl -> release/v.<VERSION>/netlist/pnl
  • netlist/spice -> release/v.<VERSION>/netlist/spice

The following chip renders are exported:

  • render/img/chip_top_black.png -> release/v.<VERSION>/img/chip_top_black.png
  • render/img/chip_top_white.png -> release/v.<VERSION>/img/chip_top_white.png
  • render/img/chip_top_librelane.png -> release/v.<VERSION>/img/chip_top_librelane.png

Note

netlist/schematic and netlist/pex are currently not copied by the release target.

Run with default version (1.0.0):

make release

Run with a custom version:

make release VERSION=2.1.0

Regression

The regression target is the project's end-to-end smoke test for the IIC-OSIC-TOOLS environment. Its goal is to exercise every tool and flow in the template at least once with the shortest possible runtime. It is a tool/flow regression, not a design sign-off.

make regression

This target also runs automatically in continuous integration: the regression GitHub Actions workflow runs make regression inside the IIC-OSIC-TOOLS container nightly (and on manual dispatch), and its status is shown by the Regression badge at the top of this README. The scheduled run is gated so it only executes when there have been changes since the previous night.

To keep the runtime low while still covering the full toolchain, the regression makes the following trade-offs:

  • The counter macro is hardened with librelane-magicdrc (only Magic DRC enabled, the slower KLayout DRC is skipped). Netgen LVS still runs as part of the flow.
  • The chip top-level runs librelane-nodrc. All DRC checks are skipped to save runtime on the large top-level assembly. The macros and IP blocks are DRC-checked individually beforehand, so this only leaves the top-level routing/fill unchecked.
  • KLayout DRC (run_drc.py) is skipped inside the LibreLane runs, but is still exercised in the bondpad and logo IP builds, and in the inverter klayout-verify.
  • Only one logo (sg13g2_ip__jku) is regenerated. It is the only step that exercises the PNG to GDS flow. The second logo (sg13g2_ip__jku_names) uses an identical toolchain and reuses its committed views.
  • Exactly one CACE parameter set is run (the AC VDD sweep ac_params, no Monte-Carlo). Swap ac_params for ac_mc_params / ac_mm_params in the target to also exercise the Monte-Carlo flow.

The regression runs bottom-up: first the inverter and counter macros, then the top-level assembly (submodules, bondpad, logo) and finally the chip top-level LibreLane run that integrates the freshly built macros and IP. After the counter is hardened, copy-final copies its fresh flow/final/ views into macros/counter/final/, so that the gate-level simulation (sim-gl-cocotb) and the chip top-level integration use the freshly built outputs rather than the committed ones.

The following tools and flows are checked:

Tool / flow Where it is exercised
git submodules init-submodules
KLayout scripting (bondpad generator), KLayout DRC, Magic DRC build-bondpad
PNG to GDS logo generation, KLayout DRC, Magic DRC sg13g2_ip__jku all (single logo)
Xschem + ngspice (analog simulation) inverter sim-xschem (inverter_tb_dc_vout)
CACE (+ ngspice) inverter CACE, single parameter set (ac_params)
KLayout LVS (run_lvs.py) + KLayout DRC (run_drc.py) + KLayout PEX (kpex) inverter klayout-verify CELL=inverter_top
Magic extract + Netgen LVS + Magic DRC + Magic PEX (sak-pex.sh) inverter magic-verify CELL=inverter_top
Magic LEF export + LIB + Verilog stub + lay2img render inverter build-top
Verilator lint counter lint-verilog-all
Icarus Verilog (iverilog/vvp) counter sim-rtl-verilog
cocotb (RTL + gate-level) counter sim-rtl-cocotb, sim-gl-cocotb
yosys + nextpnr-ice40 + icepack (FPGA) counter build-fpga
LibreLane (OpenROAD / yosys / KLayout streamout / Netgen LVS) counter librelane-magicdrc, chip librelane-nodrc
Magic DRC (sign-off, run inside LibreLane) counter librelane-magicdrc
vlog2Verilog / vlog2Spice / spi2xspice counter generate-xspice
Xschem gate-level counter sim-gl-xschem

Cite This Work

@software{2026_ams_chip_template,
	author = {Dorrer, Simon and Pretl, Harald},
	month = apr,
    year = {2026},
	title = {{GitHub Repository of an Open-Source Analog-Mixed Signal Chip Design Template for the ihp-sg13g2 Open-PDK}},
	url = {https://github.com/iic-jku/ihp-sg13g2-ams-chip-template},
	doi = {10.5281/zenodo.20129233}
}

Acknowledgements

First, we would like to thank the open-source chip design community for its valuable input and constructive feedback. We especially thank

This project is funded by the JKU/SAL IWS Lab, a collaboration of Johannes Kepler University and Silicon Austria Labs.

Johannes Kepler University: Institute for Integrated Circuits and Quantum Computing Silicon Austria Labs

License

Licensed under the Solderpad Hardware License v2.1, see LICENSE.

About

An RF frontend IC for the LinHT project, used as an I and Q modulator/demodulator

Resources

Stars

10 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages