Skip to content

Device models testing against measurements - #1026

Open
atorkmabrains wants to merge 9 commits into
IHP-GmbH:devfrom
mabrains:device_models_testing
Open

atorkmabrains wants to merge 9 commits into
IHP-GmbH:devfrom
mabrains:device_models_testing

Conversation

@atorkmabrains

@atorkmabrains atorkmabrains commented Jun 30, 2026 •

Copy link
Copy Markdown
Contributor

This PR adds a framework that verifies the SG13G2 ngspice device models against IHP's measurements
(ihp-sg13g2/libs.doc/meas), in ihp-sg13g2/libs.tech/ngspice/testing/devices/, and a CI workflow that runs it.

What is tested

devices measurements what is judged
MOS LV / HV, nmos / pmos (PSP103 through OpenVAF / OSDI) DC transistor sweeps, junction diodes, C-V (junction, gate, oxide) every curve; the V_DS = 0 point of I_D / I_S is not judged (no channel current flows there, the meter reads its offset)
HBT npn13g2, npn13g2l, npn13g2v (VBIC) DC Gummel and output curves; S-parameters: C_jE, C_jC, f_T at 30 GHz as the MQA for SiGe HBTs asks (G. G. Fischer, IHP, 2025-12-16): its characteristics (fg_vcb0, fg_vce, fo_vb on I_C, spar_vb, spar_vc, spar_vcb025 / spar_vcb05), bias windows and structures (npn13g2_T03, npn13g2l_T01, npn13g2v_T01); the other 11 measured structures run on request
pnpMPA (Gummel-Poon) DC of 14 DUTs (forward / reverse Gummel and output), C-V every curve (not covered by the MQA)

How a curve is judged

  • A curve (one measured data block and quantity) passes when the measurement lies inside the band of the
    bcs / wcs corner simulations, widened by corner_tolerance_percent, for all but threshold_percent_oob of
    its points. The typical simulation is judged against the same band.
  • Exceptions (waivers/): a reviewed failing curve keeps the exit code at 0 only while the simulation
    reproduces its recorded failing points exactly (per toolchain fingerprint); every report still counts it as
    a failure. The current entries are recorded from the runs and pending review.

Layout

  • models_verifier/: MDM parsing, DC / S-parameter / C-V runners (ngspice), range checker, exception store and
    generator, reports (final_reports/: results_summary.csv, full_results.csv, new_failures.csv,
    stale_exceptions.csv, final_summary.md)
  • configs/: one YAML per device (and HBT test structure): measurement folder, corners, metrics, tolerances,
    MQA windows; netlist templates
  • waivers/: the committed exceptions
  • tools/: pinned toolchains (toolchain.lock, toolchain.py: ngspice 46 / 47, OpenVAF-Reloaded b4517ad /
    fdf2522), CI helpers, HBT de-embedding check
  • validation/plot_verification_results.py: measured-vs-simulated figures; workflow_notebooks/: notebooks
  • Makefile: make test-all (or test-mos, test-hbt, test-hbt-sparam, test-pnp, test-cv,
    test-<case>), make waive-<case>, make plot-<case>, make unit-tests, make check-deembedding,
    make eda-mos (MOS error report, not a gate)

CI (.github/workflows/device-testing.yml)

Thin: every step calls a make target or a script. Each pinned ngspice version and OpenVAF-Reloaded commit is
built once and cached; then one job per toolchain and make target, plus the unit tests and the de-embedding
check. A job fails on new failures, simulation errors, or exceptions whose curve is missing; its summary lists
the counts.

Run locally

cd ihp-sg13g2/libs.tech/ngspice/testing/devices
python3 tools/toolchain.py list
make test-all TOOLCHAIN=ng47-ovr-b4517ad

Details: README.md in that folder.

@KrzysztofHerman

Copy link
Copy Markdown
Contributor

HI @atorkmabrains, is there any passivity to simplify this PR. It has 53 commits and 901 files changed.

@atorkmabrains
atorkmabrains marked this pull request as draft July 22, 2026 17:38
@atorkmabrains

Copy link
Copy Markdown
Contributor Author

Hi @KrzysztofHerman

I'll simplify it.

@atorkmabrains
atorkmabrains force-pushed the device_models_testing branch from 1ea8d97 to fd1e6c0 Compare July 22, 2026 18:03
@atorkmabrains atorkmabrains changed the title Device models testing with EDA Device models testing against measurements Jul 22, 2026
@atorkmabrains

Copy link
Copy Markdown
Contributor Author

@KrzysztofHerman Simplified, but not ready for merge. Please wait.

@atorkmabrains
atorkmabrains marked this pull request as ready for review October 15, 2026 07:39
Model-vs-measurement verification for 8 devices (4 MOS, 3 HBT, pnpMPA):
MQA bias-window gating with fixed limits, waiver/baseline system,
MOS error EDA (clustering + rule-based labeling + reports), and HBT
S-parameter CjE/CjC/fT extraction and checks.

Signed-off-by: Amro Tork <amro_tork@mabrains.com>
Signed-off-by: Amro Tork <amro_tork@mabrains.com>
- Honour IC-CAP SYNC inputs: keep the swept master as the sweep variable,
  carry the slave relation into the netlist and reference the slave source
  to a VCVS copy of the master node. Constant-VCB Gummel sweeps (fg_vcb0,
  fg_vcb05, fg_vcbm05, ...) were simulated with the base grounded, VBE = 0.
- Run sweeps that cross 0 V as two segments from 0 V outward, and keep the
  points of a corner that aborts part-way instead of dropping the whole
  characteristic for every corner.
- Clip currents sign-preserving and score points where measurement and both
  corners sit at the noise floor as agreement. Negative currents (PMOS id,
  NMOS is, pnp ib/ic, HBT reverse ib) were collapsed onto the positive floor
  on both sides and passed vacuously.
- Correct the pnpMPA DUT area table to m^2; values were 1e6 times too large.
- Add design_param_overrides for the DC and S-parameter paths, make the
  template sweep branches case-insensitive, sort input_vars for a
  deterministic column order, add unit checks and a README section.

Signed-off-by: Amro Tork <amro_tork@mabrains.com>
The npn13g2l_T01 MDM headers carry REMARKS "Nx=5", while the MQA proposal
defines the default variant as le=2.5 um, Nx=4 and the model card limits
npn13G2l to Nx=1-4. Simulated with Nx=5, measured IC and CjE sit at 0.80
and 0.81 of the typical model, exactly the 4/5 expected from a mislabelled
emitter count; with Nx=4 they sit at 0.92 and 1.007.

Signed-off-by: Amro Tork <amro_tork@mabrains.com>
DC waivers for the 8 devices and S-parameter waivers for the 3 HBTs were
rebuilt from scratch with ngspice-47. The previous baseline encoded
simulations at the wrong bias (SYNC sweeps), vacuous passes of clipped
negative currents and the pnpMPA area error rather than model-versus-
measurement differences. All 15 suite steps exit 0 with the new files.

Signed-off-by: Amro Tork <amro_tork@mabrains.com>
- Makefile: plot-<device>, plot-hbt, plot-pnp, plot-mos and plot-all wrap
  validation/plot_verification_results.py; figures go to figures/<device>/
  (FIG_DIR=<dir> redirects), HBT S-parameter figures to figures/<device>_sparam/.
- validation/plot_verification_results.py: infer sweep_var, output_vars and
  block_id when a combined_results table lacks them, so the S-parameter tables
  (cje, cjc, ft versus bias) plot the same way as the DC characteristics.
- README: "Generating figures" section; .gitignore: figures/.

Signed-off-by: Amro Tork <amro_tork@mabrains.com>
Exceptions (schema 2): one entry per curve with, per toolchain, the number
of judged and failing points and a fingerprint of the failing points (bias,
simulated tt/ss/ff, 6 significant digits). A failure is waived only when it
is reproduced exactly; reports count waived curves as failures; exit 1 only
on new failures, simulation errors, or exceptions whose curve is missing
from the run. make waive-* records the failures of a finished run as
auto-waived, pending review; every current failure is recorded for the four
toolchains (bipolar devices per ngspice version).

Toolchains: toolchain.lock pins ngspice 46/47 and OpenVAF-Reloaded
b4517ad/fdf2522; tools/toolchain.py builds, registers and compiles PSP103;
make TOOLCHAIN=<id>; every run records toolchain.txt and checks that the
binaries belong to the ID.

Checks: every measured point is kept (the VG = 0 V point of every MOS Id-Vg
curve was dropped before); a point the simulation did not give fails its
curve; unreadable files, unmatched blocks and duplicate curve keys stop the
run. Split DC sweeps restart from a fresh circuit for the second segment.

New coverage: MOS junction diodes (diode template), pnpMPA with 14 DUTs,
11 more HBT test structures (configs/hbt/variants), extra HBT S-parameter
files (self de-embedding, declared copies, de-embedding check), MOS and
pnpMPA C-V tier (cv_runner).

Figures show the judged band and bias windows (shared plotter). Thin GitHub
Actions workflow: cached ngspice / OpenVAF / PSP103 builds, unit tests, one
job per make target and toolchain, job summary with counts, new failures
and the toolchain record.

Signed-off-by: Amro Tork <amro_tork@mabrains.com>
…dged

- MOS: valid_range on id / is leaves out the V_DS = 0 point of the output
  curves (no channel current flows there; the meter reads its offset).
- HBT: only the MQA ranges are judged (mqa_ranges_only, RangeChecker
  mqa_only); fT only on the MQA file, at 30 GHz; fo_vb on I_C only; only the
  MQA structures (npn13g2_T03, npn13g2l_T01, npn13g2v_T01) are part of
  test-all, waive-all and the CI, the other test structures stay runnable on
  request.
- Exceptions recorded again on the four toolchains; those of curves that are
  no longer checked are removed.
- Tests for the MQA windows, fT at 30 GHz and the HBT configs; README updates.

Signed-off-by: Amro Tork <amro_tork@mabrains.com>
spar_vcb10's IC-CAP S_deemb is a copy of spar_vcb05's. Neither file is judged
since fT is checked on the MQA file only, so the copy was no longer declared
and the de-embedding check stopped. Declared with sparam_copied_deemb.

Signed-off-by: Amro Tork <amro_tork@mabrains.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants