SPICE (Simulation Program with Integrated Circuit Emphasis) is an analog electronic circuit simulator. SPICE can cover from the board-level circuit design to integrated circuits. It has originally developed at the Electronics Research Laboratory of the U.C. Berkeley in 1973. Since the update of Berkeley SPICE stopped at version 3f5 in 1993, many improved descendants came out from various vendors to the public.
There are many SPICE variations available HSPICE, PSPICE, NGSPICE, LTSPICE, SPICE OPUS, etc. BUT I chose NGSPICE basically it is free to the public, and it has good compatibly with KiCAD which is my main circuit design tool. HSPICE and PSPICE are the industrial majority, but it is a far too expensive for a hobbyist such as myself. LTSPICE is only for WINDOWS OS and I want to stick to Linux where I can go much more flexible in scripting and batch run.
How to run NGSPICE?
Basically, NGSPICE is a command line tool. So, everything is supposed to be done by typing commands and dealing with text files in the shell environment. There are some GUI integrations, as in KiCAD or Qucs-S. You will be temped to use GUI first because it looks easier at the beginning. But, you will be back to command-line mode in the end for the more flexibility and more options. Actually, the GUI is not really useful unless you understand how it works in command-line mode. Or, you will find the GUI tools are not so convenient compared to command-line mode. Most people do mixed way - Generate netlists using KiCAD or Qucs-S and include into input file to the simulation to run it in command-line. Therefore, learning NGSPICE the original way is inevitable.
Once you installed NGSPICE, Typing ngspice on the shell prompt will lead you to the interactive mode. Then, you can source the input file.
% > ngspice
*****************************************
some messages ...
*****************************************
ngspice 1 -> source input_file.cir
Once you've got into NGSPICE interactive mode, you can apply the various kinds of simulation requests and output requests. You can interactively test and get the result from the circuit described in the input file. But, my favourite way to run the simulation is to prepare the input_file with all the controls included and run the sim as below.
% > ngspice input_file.cir
This can run the sim all at once and either you can make it get interactive mode or you can run and exit to shell after the simulation. It is all depends on how to put controls in inpuit_file.cir. You can even run a batch simulation using the controls of NGSPICE or using the shell scripts.
Input File
An input file is an input to SPICE simulation. It contains circuit description - they call this SPICE netlist - and controls. The control block in the input file includes analysis requests, data output controls, and some flow controls.
The typical structure of an input file looks like this.
.title “Simulation Title”
* netlist
* subcircuits
* models
.control
* analysis requests and output controls
.endc
.END
SPICE input file is not case-sensitive. Uppercase or lowercase does not make any difference. It only helps readability. Any line that starts with an asterisk is a comment line. The first line has to be filled with a title or comment. An empty first line will cause an error and fail the simulation. NGSPICE supports HSPICE style, but putting all the control statements inside .control and .endc. give you more options and flexibility. You can have all the native NGSPICE features inside the control block. Finally, don't forget to put .end at the end of the simulation.
SPICE Netlist
A SPICE netlist is a circuit description in plain ASCII text. It just describes how the elements are connected to each other. It is like a text version of a circuit diagram. The format to describe an element connection is as below.
element_name <connected_nodes> <element_value or model_name> <optional_parameters>
The element name must start with a specific alphabet letter assigned to each types of electric elements. Here are some alphabet letters for the frequently used circuit elements.
First Letter | Element Type | Example |
R | Resistor | Rout out 0 1K |
L | Inductor | L12 vin node_1 12M |
C | Capacitor | C10 3 0 1u |
D | Diode | Dmod in GND 1N4001 Area=3.0 IC=0.2 |
Q | BJT | Q1 nC nB nE QMOD IC=0.5 |
M | MOSFET | M0 nD nG nS nb MOSN L=5u W=2u |
V | Independent Voltage Source | VCC PWR GND DC 15 VIN N1 N2 0.001 AC 1 SIN(0 1 1MEG) |
I | Independent Current Source | ISRC 23 21 AC 0.3333 |
E | VCVS (Voltage Controlled Voltage Source) | Evc0 n1 n2 ref+ ref- 2M |
F | CCCS (Current controlled Current Source) | FDRV n1 n2 VSEN 5 * vsen is a name of a voltage source |
G | VCCS (Voltage Controlled Current Source) | GOUT 2 0 in 0 2M |
H | CCVS (Current Controlled Voltage Source) | HX0 5 17 VZ 0 0.5K |
X | subcircuits | Xop in1 in2 out opamp_1 .subckt opamp_1 plus minus output |
Any kind of string - numbers or text - can be used for the nodes, but number 0 is reserved for common global ground. The voltage controlled dependent sources - VCVS, VCCS - will have reference nodes right after the list of the connected nodes, and the current controlled dependent source - CCVS, CCCS will have a name of independent voltage source where the reference current will be sensed. An independent voltage source is the only way to check the current through it in SPICE simulations. So, whenever, you need to check the current on the branch, you want to put a zero-value independent source on the branch.
Let's look at an example.

The following is the netlist of the circuit depicted in Fig 1
.global vcc
vcc vcc 0 dc 10
vin in 0 dc 1.7
rb in nb 100k
rc vcc out 5k
qa out nb 0 model_name
Everything obvious already. .global vcc means set vcc node global. This simply means vcc is common to everywhere, hence can be connected from everywhere. As depicted in Fig 1, the ground node is set to 0, which is the global node as well. The BJT element qa must use model name instead of element value. There are several ways to provide model to the active elements.
Applying models
You can use models that are provided by NGSPICE. These models are general and minimal models based on several different kinds of modelling method and application case. For the device-specific models, you'd better download them from the manufacture website. The models provided by the manufactures are much more specific and realistic in general. However, in case you want to model, for example, a transmission line to mimic a copper path on a PCB board, you can use NGSPICE default models with some good parameters to reach a reasonable realistic result.
.title The first simulation
*** first_sim.cir
*** Netlist starts here
.global vcc
vcc vcc 0 dc 10
vin in 0 dc 1.7
rb in nb 100k
rc vcc out 5k
qa out nb 0 QMOD
.model QMOD NPN level=1 BF=90
*** control starts here
.control
op
print v(out)
.endc
.end
In the list above, NGSPICE level 1 model is applied to the netlist of Fig 1 and some controls for the simulation are included. In the .model statement, QMOD is a model name. You can put any name you like, but this name must match with the one on the qa element line. NPN is the type of the BJT. BF=90 is the parameter that means Forward Beta parameter for the BJT.
In the control block, there is only one analysis request. The command op request the simulator to calculate quiescent operating points of the circuit. And, the print command prints out requested data. In the above example, it only prints out the voltage of the 'out' node. Create a file named "first_sim.cir" and run "ngspice first_sim.cir" then you will get into interactive mode with the simulation result right above the first prompt as below.
...
No. of Data Rows : 1
v(out) = 5.361446e+00
nqspice 1 -> _
Generating Signals
For the transient analysis, You need to generate signals, such as sine wave, square wave, pulse, etc. Most of SPICE provide signal generation command. You can simply put this command at the end of any independence source.

Let's attach a sine wave signal generator to the vin in the netlist of Fig 1.
.global vcc
vcc vcc 0 dc 10
vin in 0 dc 1.7 ac 1 SIN(1.7 1 10K 0 0)
rb in nb 100k
rc vcc out 5k
qa out nb 0 QMOD
.model QMOD NPN BF=90
On the vin independent voltage source line above, three different kinds of signal sources are added and these are independent of each other. dc 1.7V is for dc analysis and OP, and ac 1 is for ac analysis. In ac 1, 1 does not really mean 1V, rather 1 is more like a scale factor. SIN(1.7 1 10K 0 0) is added for the transient analysis. The added sine wave has 1.7V dc offset, 1V amplitude and 10KHz frequency. No delay, no decay, no phase shift applied.
Using subcircuits
A subcircuit is a block of netlist packed for the frequent usage in a circuit. Subcircuits are similar to functions in a programming language. It reduces time and labour by reducing repetitive tasks for the circuit designers. Also, it is another way to apply a model to electronic compounds such as circuit modules or integrated circuits. For example, for an opamp, you use a subcircuit instead of a model.
Let's try to make a subcircuit to the BJT in the Fig 1. They don't usually use subcircuits for a BJT, but I want to show that it is also possible.

Fig 3 shows a simple BJT small signal model and its SPICE subcircuit equivalent. The voltage source vsen is added to sense the reference current for CCCS Fce. And beta is the current gain of the BJT. The input file that uses this subcircuit looks like the following.
.title The subcircut example
* first_sim_w_subckt.cir
.global vcc
vcc vcc 0 dc 10
vin in 0 dc 1.7 ac 1 SIN(1.7 1 10K 0 0)
rb in nb 100k
rc vcc out 5k
xqa out nB 0 my_bjt beta=90 rpi=2.5K ro=150K
.subckt my_bjt C B E beta=100 rpi=3K ro=100K
rpi B nSen {rpi}
vsib nSen E 0
Fce C E vsib {beta}
ro C E {ro}
.ends
.control
ac dec 10 1 1e6
let vgain = v(out) / v(in)
meas ac voltage_gain find vgain at=1K
.endc
.end
In the above input file, the subcircuit definition begins with .subckt and my_bjt is a subcircuit name. C, B, E are the terminals of the subcircuit. And, there are some parameters after the list of terminals. The values inside { and } will substitute the parameters listed on .subckt statement. These values can be overwritten when the subcircuit is invoked in the netlist. The first letter of a subcircuit element name must be x, so xqa is used for the BJT subcircuit element name in the example above.
Save the input file into first_sim.w_subckt.cir and run ngspice first_sim.w_subckt.cir, then you will get
...
No. of Data Rows : 61
voltage_gain = -4.248623e+00
ngspice 1 ->
This matches the hand calculation result from below.
This subcircuit only works for ac analysis because the model in Fig 3 is a small-signal model. And, its frequency response is meaningless because it will be infinite.
Controls
You can put analysis requests and output controls in the control block. NGSPICE also provides language-like control statements such as while, dowhile, repeat, foreach, and more.
Analysis requests
To get meaningful results from the simulation, you must give instruction to the simulator about what to simulate or how to simulate. These instructions are called analysis requests. There are many types of request - DC, AC, Transient, Pole-Zero, Distortion, Noise, and more. Some basic and frequently used requests are listed in Table 2.Analysis Requests | Spice Context |
Operating Point Analysis | op |
DC Transfer Function | dc srcnam vstart vstop vincr [src2 start2 stop2 incr2] dc VIN 0.25 5.0 0.25 |
Small-Signal AC Analysis | ac ( dec | oct | lin ) np fstart fstop ac dec 10 1 10K |
Transient Analysis | tran Tstep Tstop [ Tstart [ Tmax ] ] [ UIC ] tran 1ns 1000ns 500ns tran 10ns 1us |
Output controls
There are control commands to control how to manipulate the simulation results. You can print, plot and save to a file for the further data manipulation or analysis. For the arguments of the output controls, v(n1<,n2>) specifies the voltage between n1 and n2. If n2 is not specified, then it regarded as the voltage between n1 and ground. I(vsens) specifies the current flowing in the independent voltage source named vsens. The current from the positive terminal to the negative terminal is regarded as positive. vm(node), vp(node) mean the voltage magnitude and phase, each. vdb(node) means voltage magnitude in decibel.
Control function | SPICE context |
print out the result in tabular form. | print prtype ov1 <ov2 ... ov8> print tran v(4) i(vin) |
plot the graphs. | plot expr1 [vs scale_expr1] [expr2 [vs scale_expr2]] [all] [allv] [alli] <other options> Plot v(o), I(vsens) |
gnuplot | gnuplot [file] [extrs] |
write | write [file] [exprs] |
Using models from the manufacture
Let's do a more realistic simulation with a model from a manufacture. Download 2N2222A NPN BJT spice model from here. This model is written in PSPICE parameter format. You need to set the compatibility to PSPICE to use this model. Create a file name ".spiceinit" at home directory of your account and add text as following.
set ngbehavior=ps
Then, change the name of the downloaded file, 2N2222A.LIB.TXT to 2N2222A.LIB. If you look into the file, you can see the .model line.
.MODEL Q2n2222a npn
...
Now, all you have to do is include the LIB into the input file and use the model name Q2n2222a on qa element line.
.title The first simulation
*** Netlist starts here
.global vcc
vcc vcc 0 dc 10
vin in 0 dc 1.7 ac 1 SIN(1.7 1 10K 0 0)
rb in nb 100k
rc vcc out 5k
qa out nb 0 Q2n2222a
.inc 2N2222A.LIB
*** control starts here
.control
...
.endc
.end
Flow control
ngspice provides language-like flow control. You can use while, dowhile, repeat, foreach, if-then clause. Even, you can use goto and label. continue and break statements are also provided. Let's add some flow control and analysis requests to the netlist with manufacture's BJT model to get some realistic results. The input file below is to running all 3 kinds of simulations at the same time, and repeat flow control is used for the DC sweep to get a curve trace for the BJT 2N222A..title The first simulation
*** Netlist starts here
.global vcc
vcc vcc 0 dc 10
vin in 0 dc 1.7 ac 1 SIN(1.7 1 10K 0 0)
rb in nb 100k
rc vcc out 5k
qa out nb 0 Q2n2222a
.inc 2N2222A.LIB
*** control starts here
.control
set xbrushwidth=3
let vinn = 0.7
repeat 5
alter vin $&vinn
dc vcc 0 20 10mv
let vinn = vinn + 0.1
end
plot (-dc1.I(vcc)) (-dc2.I(vcc)) (-dc3.I(vcc)) (-dc4.I(vcc)) (-dc5.I(vcc))
reset
tran 10n 500u
plot v(in) v(out)
reset
ac dec 10 1 1e6
set units=degrees
plot db(out)
plot ph(out)
.endc
.end
The input file above repeated 5 times of dc sweep, with the vin values increased by 0.1 for each run. You need to put negative sign to I(vcc) since the examining current on the collector to emitter branch is coming out of vcc source - current flow into the plus terminal of vcc source is positive. Once you run 5 dc analysis, you can retrieve the 5 different data groups dc1, dc2, … , dc5. You can run all different types of analysis at the same time by putting reset command at the end of each analysis.
The followings are the plots that will pop up after the simulations are done.




The default NGSPICE plots are quite basic and limited in usage. You can get better plot manipulation with GNUplot.
Using Gnuplot
GNUplot is a popular plot application. To use GNUplot, you can use the gnuplot command instead of the plot command. There is an additional argument that needs to be passed.
.control
…
reset
ac dec 10 1 1e6
set units=degrees
gnuplot ac_sim db(out) ph(out)
exit
.endc
With the NGSPICE basic plot, all the plots disappear once you exit the interactive mode. On the other hand, the GNUplot stays even if you exit the interactive mode. Now, you can put exit command to get out of the interactive mode after the simulation completed. Another good news is the fact that the gnuplot command above will save plot control file ac_sim.plt and data file ac_sim.dat each when it draws the plot so that you can modify the ac_sim.plt to make the plot nicer. By keeping these .plt and .data files you can redraw later anytime you want. Here is the list of ac_sim.plt file that modified for dual plot with some better labels. Fig 8 is the plot result of the modified ac_sim.plt
# ac_sim.plt
# generated when by gnuplot ac_sim db(out) ph(out)
# in the input file "first_sim.cir"
...(ommitted)
# This original plot is commented.
# plot 'ac_sim.data' using 1:2 with lines lw 3 title "db(out)",\
# 'ac_sim.data' using 3:4 with lines lw 3 title "ph(out)"
# modified for multi-plot
set multiplot
set size 1, 0.5
set origin 0, 0.5
set yrange [0:20]
set ylabel "gain, dB"
set title "The AC Analysis - gain"
plot 'ac_sim.data' using 1:2 with lines lw 3 lt rgb "blue" title "db(out)"
set origin 0, 0
set yrange [0:180]
set ylabel "phase, degree"
set title "The AC Analysis - phase"
plot 'ac_sim.data' using 3:4 with lines lw 3 lt rgb "red" title "ph(out)"
unset multiplot

Using Gtk Analog Wave viewer(gaw)
If you want something like AvanWaves that comes with hspice, you can try gaw - Awaves are much better but not a free tool. gaw lets you use the cursor line to check the value of every each point on the graph, and you can have as many as panels you want. To use gaw, you need to write the simulation data into a file.
.control
set xbrushwidth=3
let vinn = 0.7
repeat 5
alter vin $&vinn
dc vcc 0 20 10mv
let vinn = vinn + 0.1
end
write dc_sim.out (-dc1.I(vcc)) (-dc2.I(vcc)) (-dc3.I(vcc)) (-dc4.I(vcc)) (-dc5.I(vcc))
…
exit
.endc
Usage of the write command is similar to the gnuplot command. Once you run the simulation input file, the example above will save the simulation result into “ac_sim.out” file. Now you can open “ac_sim.out" file with gaw waveform viewer. Select the panel to draw on first, and then choose the signals to draw the graph.

You can use two cursors to get the differences as shown in Fig 9.
Conclusion
NGSPICE is as good as other spice simulators, or better in a way. NGSPICE is a handy tool for hobbyists who want to build a precision analog circuits such as amplifiers, RF frontend, and some sensor frontends. And, also, it is a reliable tool for one who aims to check the interface between analog front-end and the digital I/O's. The usage shown here is just a basic introduction. I hope this will be a little clue to the hobbyist who wants to get into the SPICE world. There are a lot more features to enjoy. Even in the analog only applications, switch models, transmission line models, Monte Carlo simulation, noise sources, Non-linear dependent sources, and more. NGSPICE also covers mixed-mode(analog-digital altogether simulation mode) applications. NGSPICE supports XSPICE mixed-mode and Behavioural Modelling, Verilog-A Compact Device Models, and Digital Device Models and Digital simulation, etc. Vast application area you can play with.
References
- Ngspice User's Manual (ngspice release version) - version 44plus. Holger Vogt, Giles Atkinson, Paolo Nenzi, December 29th, 2024
- NGSPICE home - tutorials, introductory videos, downloads, news, etc.
- gnuplot homepage - all the information and gnuplot download
- xschem-gaw github - gaw download and install