ngspice – Interactive Mode!
September 30, 2010 22 Comments
Welcome back for the 5th tutorial on SPICE in Fedora Electronic Lab. This time we’ll look at ngspice’s interactive mode. We’ll see what this means in some time. Before that, make sure that you have gone through the previous tutorials. These are all filed under the SPICE category (point your mouse to Tutorials, then click SPICE). We will reuse the example circuits we created in the previous tutorials for this one. I hope you’ve gone through those first. We’ll begin with two circuits to show how some simple analysis can be done just like in batch mode. Finally we’ll end with an example which shows a great aspect of the interactive simulations – tweaking circuits automatically.
Before we begin any circuit, delete the SPICE include symbol from the schematic and get the netlist again. We do not need the cmd files now. Alternatively you could just open the netlist and delete the .INCLUDE line. We will be looking at the Bridge Rectifier, the BJT Amplifier and the op-amp non-inverting amplifier. Now lets begin
Example – 1 The Bridge Rectifier
Remember the bridge rectifier we made before? It had a tiny problem. We couldn’t plot the input voltage because the input was the voltage difference between two nodes. Start by opening the terminal and going to the directory where the netlist for the rectifier is present. Now type
Where bfwr.net is the name of the netlist. You should now see the ngspice prompt. Before we look at the simulation, let me introduce you to two basic commands you may need often. These are listing and display. The first, listing, displays the netlist on to the console (just like list in BASIC). The command display lists the details of the vectors that currently exist in the session you are running. A vector is an array of numbers (a 1-D matrix). You can create your own vectors but in most cases you use vectors that are created as a result of simulation. Now to simulate the circuit, we can use the same line as the cmd file with a small change. Remove the period symbol from the start of the line. Since we want a transient analysis we’ll type,
tran 100u 100m
Note that we have used lower case. TRAN will not work. From the command it is clear that we are running a transient analysis from 0 to 100 milliseconds in steps of 100 microseconds. Once the simulation is over, you will see the list of nodes where voltages were calculated. You will also see something like v2#branch showing that we have current calculated through the source V2 (remember that in SPICE, current can only be calculate through a voltage source). Now enter the listing command to display the netlist. Here is the output I got with the listing command :
* gnetlist -g spice-sdb -o bfwr.net bfwr.sch 2 : .global gnd 10 : .model 1n4007 d(is=76.9p rs=42.0m bv=1.00k ibv=5.00u cjo=26.5p m=0.333 n=1.45 tt=4.32u) 15 : v2 2 1 sin(0 5 60) 16 : r2 0 3 10k 17 : d8 1 3 1n4007 18 : d6 2 3 1n4007 19 : d4 0 2 1n4007 20 : d2 0 1 1n4007 14 : .options temp=25 22 : .end
What’s important is to see what we want to plot. The input is across source V2 so looking at the netlist we can see that we need the difference between the voltages at nodes 2 and 1. The output is from node 3 (Resistor R2). Again, just to make sure these are available to us (not necessary since all node voltages are created) run the display command. This is what you should see:
V(1) : voltage, real, 379 long V(2) : voltage, real, 379 long V(3) : voltage, real, 379 long time : time, real, 379 long [default scale] v2#branch : current, real, 379 long
As you can see, we not only get the vector names but also their type. As we discussed earlier, we need to plot the input by using the difference between voltages at nodes 2 and 1 and then the voltage at node 3. So this is what we do:
plot v(2,1) v(3)
You should now get a window with the waveforms we need:
I’m pretty sure you still prefer gwave since this plot doesn’t let you zoom in and reading out values isn’t as simple as gwave. So what we do is save these to a raw file. All you need to do it:
write bfwr.raw v(2,1) v(3)
I’m sure this command is quite straight forward - bfwr.raw is the output raw file and the remaining two arguments are the signals we want to save. Open another terminal and go to the bridge rectifier’s directory. You should see the raw file there. Open it in gwave and plot the signals:
And we’re back to good ol gwave . However, for the remaining two examples, we will stick to ngspice’s plots.
Example – 2 The BJT Amplifier
I hope you didn’t go ahead and type exit or quit in a hurry because we can load the next circuit from ngspice itself. Just type cd followed by the path of the directory where the netlist is located. In my case I had to type the following:
And in case you forgot to create the netlist or delete the .INCLUDE line, don’t despair, we can do both right here in ngspice using the shell command . The shell command lets you call any unix command. So to create the netlist we run:
shell gnetlist -g spice-sdb -o bjt-amp.net bjt-amp.sch
and you should see the netlist file created. You would’ve also noticed that we just ran the ls command from unix . Hope you realized that we could’ve run gwave the same way . At this point my terminal windows is filled with text. So I ran
Alright back to work. Now ngspice still has the bridge rectifier so we need to load this new circuit. For this run the following command:
And your circuit is loaded. Next we need to remove the INCLUDE line. ngspice has an edit command to help you edit the netlist. Note that for this, you need to familiar with the vi editor. Now run:
You should see the netlist. Scroll to the end and delete the include line. Save the file and exit the editor. You should be back to the ngspice prompt. Lets run a few analyses. Before that run the listing command to find out which nodes you want to plot. Lets first run an AC analysis
ac dec 10 1 1Meg
This is the same as the .AC command we came across earlier. Now we need to plot the output. In my case the ouput was at node 6 so this is what I had to run:
plot v(6) xlog
Note the xlog option. This uses a log scale for the x-axis. Here is the output:
We can also save this to another vector as:
let ac_out = v(6)
If you run display you can see ac_out displayed. Finally lets run a transient analysis,
tran 1u 9.5m 9m plot v(6) plot v(5)
The first was an input plot and the second the output. I kept these separate because the amplification is too high to see the input plot with the output. Here are the plots (Input on the left):
Example – 3 Inverting Op-Amp Amplifier
Like before, first load the netlist (create it using gnetlist if the netlist isn’t there):
cd ../op-amp-inv-amp source op-amp-inv-amp.net
And delete the .INCLUDE line. Before moving ahead, lets have another look at the schematic:
The resistance R4 is one of the factors deciding the amplification. For now, lets reduce it to 10k. Don’t open the schematic or run the edit command for this. There is a simpler way. Just run:
alter r4 10k
and the resistance value will change to 10k Ohms. This will not show when you run the listing command however. Anyways, the reason I’ve asked you to change is simple, I mentioned in the beginning of the tutorial that we can tweak circuits. We’re about to do just that . Lets tweak the circuit so that we get an output of 50mV. Enter these commands one by one. Just note that V(3) is my output node. So make changes to the lines if needed. I’ll explain them later.
let rval = 10k while true tran 100u 100m let vmax = vecmax(v(3)) print vmax if vmax gt 5e-2 echo **********Run Complete********** plot v(3) print vmax rval break end rval = rval + 5k alter r4 rval end
If you’ve done everything right you should see the simulation run again and again till finally the plot window pops up. Before we see the output, lets look at what the above commands do. The let command (we used this in the previous example) allows you to create a new vector or modify an existing vector’s value. The vector rval will be used to update the resistor’s value. The next is a while loop. The structure for such a loop in ngspice is:
while <condition> <statements> end
Here the condition is true (not a very good idea unless you’re sure the loop will terminate) so we basically have an infinite loop. Next line is familiar. We run a transient analysis. After this, we create a new vector, vmax and use the the vecmax function to get the maximum value of the output (which is stored in the vector V(3)). Next we have an if block. The structure of a basic if block is as follows:
if <condition> <statements> end
In this case, the condition checks whether vmax is greater than 5e-2 V. gt is the greater than operator When this condition is true, we would like to stop the loop as we are happy with the output. We would also like to plot the results and print the values of maximum output voltage and the resistance we altered. Hence you see a print and plot statement. The echo command just prints the line following it. The break command ends the while loop. After the if block we update the value of the resistance by first increasing rval and then altering resistance R4 with rval and thats the end of the loop. So the loop will basically perform a transient analysis, check the output, modify the resistance we specified if needed and stop when we have the circuit we want. Cool isn’t it? . Now we are done so here is the output:
And thats ngspice in interactive mode!
Well I believe we have covered quite a bit to be able to simulate almost any circuit out there. So now I will be moving on to Verilog and VHDL tools. I will however revisit SPICE. There is still digital and mixed mode simulation in ngspice that’s remaining, XCircuit, Qucs, tclspice and gnucap (hope I haven’t missed out anything) left for circuit simulation. I still have to learn these and will post tutorials as soon as I do. Till then go over the ngspice manual and gEDA documentation yourself and do try these tools too. . I have uploaded the schematics and cmds for these tutorials on Box.net. Check the right sidebar for gEDA-examples-1.0.zip.
So see you next time for verilog! Thanks for reading!