spice runs SPICE3 circuit netlists from R and hands the results back as tidy data. The engine is Dune, a circuit simulator written in Rust and derived from Berkeley SPICE3f5 (with BSIM3v3.3, .sp, .measure and several revised routines derived from ngspice-47), checked circuit by circuit against ngspice.
-
Every SPICE3f5 analysis: operating point, DC sweep, transient, AC, pole-zero, noise, distortion, transfer function and sensitivity, plus periodic steady state (
spice_pss()). - Every SPICE3f5 device, and BSIM3v3.
-
Long tibbles out (
spice_tidy()), ready for ‘ggplot2’, or one column per variable (spice_wide()); plots picked by short name ("tran","ac") and variables by node;autoplot()for a quick look. -
Sessions and sweeps: alter a part and rerun without rebuilding (
spice_session()), or sweep parameters across threads (spice_sweep()). -
Decks as chunks: a knitr engine runs
```{spice}chunks in R Markdown and Quarto. -
Circuits from figures:
spice_pic()extracts the netlist of a schematic drawn in the pic language. -
Rawfiles in SPICE3’s own format, to exchange with other simulators (
spice_read_raw(),spice_write_raw()).
Installation
spice is not on CRAN yet. Install the development version from GitHub; it compiles Rust code, so it needs cargo and rustc (>= 1.88), from https://rust-lang.org/tools/install/.
# install.packages("remotes")
remotes::install_github("milkway/dune", subdir = "r")A first circuit
library(spice)
deck <- "RLC low-pass
vin in 0 pulse(0 1 0 1u) ac 1
r1 in mid 50
l1 mid out 1m
c1 out 0 1u
.tran 2u 1m
.ac dec 50 100 100k
.end"
res <- spice_run(deck)
res |> spice_tidy("tran", "out") # long: one row per point
res |> spice_tidy("ac", "out") # complex plots carry mag, db, phase
res |> spice_wide("tran") # wide: one column per variablevignette("spice") walks through this deck end to end.
Faithful to SPICE, and better where it can be measured
Netlist syntax, device models and analyses are SPICE3f5’s. Where Dune departs from it by default, it is because the result is measurably closer to the converged answer at the same step: a transient integrates with TR-BDF2 instead of the trapezoidal rule, a switch flips at the instant its control crosses the threshold, a lossy line keeps the corners of the waves it carries. One option restores the SPICE3 behaviour of all of them:
vignette("defaults") shows the difference on a small circuit.
How it works
spice_run() hands the deck to the engine. It is parsed and built into a circuit, and every point of every analysis is a Newton-Raphson loop: linearize the devices, solve the linear system, test convergence at SPICE’s tolerances. The accepted points come back as the plots that spice_tidy() and spice_wide() turn into tibbles.
The same engine elsewhere
spice is one of several front ends to Dune; a deck gives the same numbers in all of them.
| package | install | |
|---|---|---|
| Python | spice3 |
pip install spice3 |
| JavaScript / WebAssembly | @strategicprojects/dune-sim |
npm install @strategicprojects/dune-sim |
| Rust |
dune-core, with dune-netlist, dune-raw and dune-pic
|
cargo add dune-core |
| Command line | dune |
brew install milkway/tap/dune |
The circuit gallery shows every circuit of the engine’s test corpus with its results, and rpic is the pic-language implementation behind spice_pic().
Credits
The engine is a derived work: it is translated from SPICE3f5 (© 1985–1991 The Regents of the University of California; Thomas L. Quarles and many others at UC Berkeley) and, for BSIM3v3.3, the .sp analysis, the operating-point fallback chain, .measure, the transient noise sources and the revisions of several device routines, from ngspice-47 (the ngspice team and contributors; BSIM3v3.3.0 by the UC Berkeley BSIM Research Group). The file inst/COPYRIGHTS of the package (NOTICE in the repository) lists the upstream files and reproduces their copyright and licence notices.
Dune is an independent project: it is not affiliated with, sponsored by or endorsed by the University of California, Berkeley, the UC Berkeley BSIM Research Group or the ngspice project. The names “SPICE”, “SPICE3” and “ngspice” are used only descriptively, to identify the programs whose netlist language and behaviour Dune implements.
Citing
Dune has a DOI: 10.5281/zenodo.24052213. citation("spice") gives the entry for the package.