kicad_skills

Analog simulation (ngspice)

One of the kicad_skills usage guides for the eda CLI — all six. Plain Markdown: read it directly, or hand it to whatever assistant you use.

ngspice runs inside the container (see the eda-environment guide), the same engine KiCad’s built-in simulator uses, so results agree with what the user sees in Eeschema.

Workflow

# 1. write the deck (plain SPICE, any editor/tool)
# 2. cheap syntax check before burning a run
./bin/eda.sh sim lint sim/rc.cir
# 3. run it: writes raw + CSV + measurements + PNG plots
./bin/eda.sh sim run sim/rc.cir -o sim/out

sim run returns JSON: ok, errors (parsed from the ngspice log), and one entry per analysis with csv, plot (PNG) and measurements. Read the PNG with the Read tool when the shape of the response matters — the numbers alone hide ringing, clipping and convergence artefacts.

Deck conventions that avoid the usual failures

* first line is ALWAYS the title - it is discarded
V1 in 0 DC 0 AC 1 SIN(0 1 1k)      * AC 1 = 1 V stimulus for .ac
R1 in out 1k
C1 out 0 159.155n
.ac dec 200 10 100k                * decade sweep, 200 points/decade
.tran 10u 5m
.end

What is measured automatically

Analysis Measurements returned
.ac max gain (dB) and its frequency, gain/phase at both ends, -3 dB corner(s), bandwidth, unity gain frequency, phase margin
.tran min/max/peak-to-peak/mean/RMS/final, plus either step metrics (10-90 % rise time, overshoot %, 2 % settling time) or periodic metrics (amplitude, estimated frequency) depending on the waveform
.dc min/max, endpoints, maximum slope (small-signal gain), monotonicity
.op every node voltage and branch current

THD needs the fundamental, so it is a separate call:

./bin/eda.sh sim measure sim/out/work/sim.raw --thd "v(out)" --fundamental 1000 --skip 1m

Will it still work with real parts? (tolerance analysis)

A nominal simulation is the one circuit you will never build. Vary the parts inside their tolerance and look at the spread of the number you actually care about:

./bin/eda.sh sim montecarlo sim/rc.cir -o sim/mc \
    --vary R1=1% --vary C1=10% \
    --metric ac.v(out).f_minus_3db_hz \
    --trials 200

Returns statistics (mean, stdev, min/max, p05/median/p95, spread_pct), nominal_metric for reference, a histogram.png and trials.csv. The metric is a path into the usual measurements: <analysis>.<signal>.<key> — e.g. ac.v(out).gain_db_max, tran.v(out).overshoot_pct, or op.v(out).

Which part is responsible

The same run also answers “so which component do I need to buy tighter?”. sensitivity ranks every varied part, with sensitivity.png as the picture:

{"explained_pct": 99.7,
 "parameters": [{"parameter": "C1", "contribution_pct": 99.3, "elasticity": -0.99},
                {"parameter": "R1", "contribution_pct":  0.7, "elasticity": -0.96}]}

It costs no extra simulation — it is the trials you already ran, read column-wise. It needs at least three trials and more trials than varied parts.

Judge the result against the requirement, not against the nominal: “fc = 1000 Hz nominal, 5th–95th percentile 968–1035 Hz with 1 % parts, spec is ±5 % → passes with margin”.

Does it survive the temperature range?

./bin/eda.sh sim temperature sim/bias.cir -o sim/temp \
    --temperatures -40 0 25 85 125 --metric op.v(out)

Runs the deck at each temperature (.temp) and reports the metric per point plus drift_per_celsius. Only models with temperature coefficients will move — ideal R and C do not, so a flat result means the models are ideal, not that the circuit is stable.

Simulating a KiCad schematic

./bin/eda.sh sim netlist hardware/amp.kicad_sch -o sim/amp.cir   # kicad-cli export
./bin/eda.sh sim run sim/amp.cir -o sim/out

The export only produces a usable deck when the symbols carry Spice model fields (Spice_Primitive, Spice_Model, .model/.subckt includes). For a plain schematic it is usually faster and more honest to hand-write a deck for the sub-circuit under investigation and say so in the report.

Interpreting the result honestly