This is the second part of our series on SPICE simulation basics and its fundamentals. In the previous part, we covered what SPICE is, its role in electronics, some history, and its different versions, as well as an overview of SPICE structure and netlists. If you haven’t seen it yet, you can check it out through this link.
Easy Guide to SPICE Fundamentals and Circuit Simulation Basics | PART-1
In this part, we’ll pick up where we left off in Part 1. Previously, we created a netlist for a capacitor charging circuit using the .tran
command. Now, we’ll dive deeper into that command, covering how to use it effectively, how to save the netlist file, and how to load it in a SPICE simulator.
How to Create a SPICE Simulation Netlist File
This SPICE netlist from our previous post represents a capacitor charging circuit powered by a 5V DC source. To create a netlist file, you can use a simple text editor like Notepad and save it with a .cir
extension.
Capacitor Charging Circuit V1 1 0 DC 5 R1 1 2 1k C1 2 0 10u .end
For demonstration purposes, we’ll name this file cccnetlist.cir
, where ‘ccc’ stands for ‘capacitor charging circuit.’ This filename shortens ‘capacitor charging circuit netlist’ to cccnetlist
. Instead of .cir
, you could also use extensions like .sp
, .spi
, or .net
. All of these are valid for SPICE netlist files, and the simulator will accept any of them.
You may have noticed that I removed the transient analysis command from the netlist. Without the .tran
command, our netlist is complete, and SPICE won’t show any errors. However, the simulation won’t actually run because the .tran
command is what starts the simulation, enabling SPICE to perform a transient analysis.
This command is essential, and we’ll add it later after loading the netlist file. The reason for doing this relates to how a SPICE simulator operates, which we’ll discuss in the next section. For now, I’ve written the netlist in a text file and saved it as cccnetlist.cir
, as shown in the image below.
Choosing a Version for Running a SPICE Simulation
In our previous post, we discussed the original SPICE versions and some commercial variants. SPICE3 is the latest in the original line of SPICE simulators, written in C, while earlier versions like SPICE2 were written in Fortran. SPICE3 introduced several advancements, such as interactive simulation capabilities and improved convergence algorithms. Over time, SPICE3 has received numerous updates, with the final, stable revision being SPICE3F5. You can find more details about SPICE3 on the SPICE WEB PAGE.
The original SPICE3F5 version was designed for UNIX and MS-DOS systems, so it cannot be directly used on modern Windows operating systems. For Windows users, there are commercial SPICE versions available, but we’ll focus on Ngspice, a free and open-source alternative.
NGSPICE
Ngspice builds on SPICE3F5, incorporating additional features from Cider for enhanced device-level accuracy and Xspice for digital and mixed-signal simulation. While Ngspice doesn’t offer a schematic entry tool, it uses command-line or file-based inputs. It’s compatible with PSPICE or LTspice device models and netlists for discrete circuit simulations, and it can also read HSPICE device libraries from semiconductor foundry PDKs, making it suitable for integrated circuit simulation.
You can download from the NGSPICE Download Page.
After downloading, you’ll get a ZIP file; go ahead and extract it. Once extracted, navigate to the bin
folder by following this path: ngspice-43_64 -> Spice64 -> bin
.
In this folder, you’ll find two executable files for running Ngspice:
- ngspice_con.exe – This version is for command-line use and runs in the Windows console.
- ngspice.exe – This provides a simple GUI. While not fully featured, it lets you load netlist files and enter commands through a basic interface.
When you launch ngspice.exe
, you’ll see a window like this:
Place your netlist file in the Ngspice bin
folder, then open Ngspice again. In the command input bar, type the name of your netlist file—in this case, cccnetlist.cir
—and press Enter to run it.
NGSpice is now ready for simulation. The netlist has been loaded and is displayed below the command bar. You can also see that NGSpice shows some status information in the simulation output area.
First is our netlist file, which we have loaded into NGSpice. The second line is a note about compatibility mode, indicating that no compatibility mode is selected.
In Ngspice, compatibility mode is a feature that allows the software to emulate the behavior of other SPICE variants, such as HSPICE, KiCad, LTSPICE, EAGLE or PSPICE, to some extent. This mode adjusts how Ngspice interprets netlists and model files, making it easier to use netlists, device models, and parameter files originally created for different SPICE tools.
The variable ngbehavior
sets the compatibility mode. By default, no compatibility mode is selected. We will discuss later how to set other compatibility modes for different variants of SPICE simulation.
Transient Analysis
Now we need to use an analysis command according to the simulation we want. We type the .tran
command in the command input bar. The .tran
command generally has the following syntax:
.tran <Tstep> <Tstop> [Tstart] [Tmaxstep] [UIC]
Each parameter in the .tran
command serves a specific purpose. Tstep (Time Step) defines the basic simulation step size, determining the intervals at which SPICE calculates and logs values of voltages and currents in the circuit. It is typically set small enough to capture significant changes without causing unnecessary computation time; for example, a setting of 1ms in .tran 1ms 100ms
means SPICE will record values every millisecond.
Tstop (End Time) represents the total simulation time, or the duration over which SPICE will run the analysis, running from time 0 to Tstop; for instance, a Tstop of 100ms indicates the simulation will last for 100 milliseconds.
Tstart (Optional, Start Time) is an optional parameter that specifies a time after which data should be collected; while the simulation still begins at 0, SPICE only starts logging data after Tstart, which can be useful for skipping initial transients; for example, setting Tstart to 10ms means SPICE will only log data after the first 10 milliseconds.
Tmaxstep (Optional, Maximum Step Size) limits the largest time step SPICE can take during the simulation, ensuring finer resolution for specific parts of the circuit, such as fast-changing signals; for instance, setting Tmaxstep to 0.5ms prevents SPICE from using steps larger than 0.5 milliseconds, thereby providing more detailed output.
Finally, UIC (Optional, Use Initial Conditions) instructs SPICE to ignore the circuit’s default initial conditions and utilize user-specified initial conditions instead, which is useful for forcing certain starting voltages or currents in the simulation; for example, if you want a capacitor to start with an initial charge, using UIC allows you to specify that condition.
We will use the .tran
command with the following parameters: .tran 1ms 50ms UIC
. However, first, I want to demonstrate something, so I will use the .tran
command without the UIC option: .tran 1ms 50ms
.
It’s important to note that in Ngspice, all dot commands should be entered without the dot when using them in the command input bar. The dot is only necessary when the command is part of the direct netlist structure without any other controlling commands. After entering the command in the input command bar, hit Enter, and you will see the following results.
In the simulation output area, you can see the results. After our transient analysis command, it displays temperature values, indicating that the simulation is running at a default temperature of 27°C (room temperature). TEMP
is the actual simulation temperature, and TNOM
is the nominal temperature at which device parameters are defined.
In NGSpice, temperature is a property associated with the entire circuit rather than an analysis option. You can change these values in the circuit by using commands like .options temp=60
and .options tnom=40
.
Following this, you’ll see a line indicating that NGSpice uses SPARSE 1.3, an efficient linear solver, to handle the mathematical equations involved in the simulation. This solver is optimized to manage large, sparse matrices efficiently, which improves the simulation’s speed and accuracy.
The table under “Initial Transient Solution” shows the voltages at different nodes in the circuit at the initial simulation time. Node 1 and Node 2 both have a voltage of 5V. v1#branch = 0
simply means that initially, there is zero current through the voltage source v1
at the start of the simulation
Graph Based Simulation Result
Now, let’s look at the transient simulation results in a graph. To do this, we will use the .plot
command.
plot v(2)
The general format for this command is:
.plot [type] [function(s)]
- type: This tells Ngspice what kind of analysis you’re plotting. For example, use “tran” for transient analysis or “ac” for AC analysis. If you leave it out, Ngspice will plot from the most recent analysis.
- function(s): This includes the variables you want to plot, like voltages at specific points or currents through components.
We will plot the voltage across the capacitor at Node 2 and the current through the voltage source V1 (which is also the current charging the capacitor). First, we will see the charging voltage curve, and then we will see the charging current. Since we just performed a transient analysis, we don’t need to include the type option in our plot command.
That’s why our command looks like this: ➜ plot v(2)
. Once you press Enter, you will see the following graph.
In an RC charging circuit, the voltage across the capacitor as it charges over time can be described by the following equation:
τ=R×C
τ = 1000Ω × 10 × 10⁻⁶ F = 0.01s = 10ms
The capacitor charges up to about 63.2% of the source voltage after one time constant (10 ms), and progressively closer to the source voltage over multiple time constants. Here’s a breakdown of the voltage at different times:
At t = τ = 10 ms:
V(10 ms) = 5 × (1 − e⁻¹) ≈ 5 × 0.632 = 3.16 V
At t = 2τ = 20 ms:
V(20 ms) = 5 × (1 − e⁻²) ≈ 5 × 0.865 = 4.33 V
At t = 3τ = 30 ms:
V(30 ms) = 5 × (1 − e⁻³) ≈ 5 × 0.95 = 4.75 V
At t = 4τ = 40 ms:
V(40 ms) = 5 × (1 − e⁻⁴) ≈ 5 × 0.982 = 4.91 V
At t = 5τ = 50 ms:
V(50 ms) = 5 × (1 − e⁻⁵) ≈ 5 × 0.993 = 4.97 V
After about 5 time constants (50 ms), the capacitor will have charged to more than 99% of the source voltage, effectively reaching its steady-state voltage close to 5V. This gradual rise should be visible on a properly configured simulation, showing an exponential charging curve.
The plot shows a nearly instant jump to 5V across the capacitor, which is not typical for a real RC charging circuit. In an RC circuit, we expect a gradual rise in voltage across the capacitor as it charges over time, following an exponential curve. Shortly after, the voltage levels off around 5V, showing that the capacitor has nearly reached its maximum charge in the circuit.
Understanding the Default Behavior
In ngspice, when you run a transient (tran
) analysis, it typically starts by calculating a DC operating point. This DC operating point assumes that any capacitors connected to a DC source through a resistor have already reached their steady-state voltage.
In this case, ngspice determines that the capacitor should be fully charged to 5V, skipping the initial charging phase. As a result, the simulation begins with the capacitor already at 5V, showing a flat line in the plot instead of a charging curve.
Initial Conditions (UIC)
To observe the charging process from 0V, you need to force ngspice to skip the DC operating point calculation and use the initial condition. You can do this by adding the UIC
(Use Initial Conditions) option to the .tran
command:
Adding UIC
to the .tran
command instructs ngspice to skip the DC operating point and start the capacitor at 0V, enabling you to observe the full charging curve.
This represents the voltage across the capacitor, which gradually rises from 0V towards 5V, showing the charging curve. This is expected behavior in an RC charging circuit, as the capacitor slowly reaches the supply voltage according to the RC time constant.
Let’s see the charging current plot using the -i(v1)
command. This will plot the current through the voltage source V1, which, in this setup, is the same as the current flowing through the resistor R1 and into the capacitor. (The minus sign here indicates the direction of current flowing out of the positive terminal of V1.)
plot -i(V1)
in the command bar and hit Enter, and you will see the graph. The current I(t)
in an RC charging circuit decreases exponentially as the capacitor charges, following the equation:I(t) = Vsource / R
where:
- Vsource = 5 V,
- R = 1000 Ω,
- C = 10 μF.
So initially, the current will be:
I(0) = 5 / 1000 = 5 mA
Over time, as the capacitor charges, the current will decay exponentially toward zero. In the plot, you should see a high initial current of 5 mA that gradually decreases as the capacitor approaches full charge (steady state at 5V). The charging current should approach zero by the end of the simulation time (50 ms).
In this article, we got hands-on with SPICE simulation basics, focusing on transient analysis and learning how to use the plot command to view capacitor charging curves. Next time, we’ll explore more SPICE fundamentals to build on what we’ve learned.