SPICE on gEDA HOWTO -- simulation
There are several options for doing SPICE simulations under Linux; I will highlight two:
LTSpice was written by Mike Englehardt at Linear Technologies, and was originally given away by LinearTech as a design aid for engineers wishing to simulate the performance of LinearTech's switch mode power supply controllers. The package incorporates a schematic capture front end, fast and powerful SPICE engine, and the capability for plotting the results of many different types of SPICE analysis. Personally, I think the schematic capture front-end is hard to use and clunky; gschem knocks its socks off for ease of use and features. However, the SPICE engine and analysis stuff in LTSpice is simply great.
LTSpice was originally developed to run under Windows, but Mike has tweaked it so that it runs fairly well on Linux under wine. (Only the help menu system is broken -- the rest of the package runs well.) Another good feature of LTSpice is that it is well supported -- Mike reads the newsgroup sci.electronics.cad regularly and is generally happy to help people who experience problems with it. Therefore, despite its Windoze heritage, I recommend LTSpice as a powerful, professional-quality simulation and analysis back end for gEDA.
LTSpice can read a file holding a gEDA SPICE netlist. I have had success doing LTSpice sumulations in the following way:
Ngspice was started at the University of Rome by Paolo Nenzi as an attempt to create a GPL'ed version of the standard Berkeley SPICE version 3 by re-writing the entire SPICE package. Plans were also laid to create better, more robust computational algorithms for the simulation engine. More information is available at the ngspice website: http://ngspice.sourceforge.net/. Unfortunately, development on ngspice seems to have ceased at the end of 2001. Moreover, my initial experiences with ngspice were not good -- it crashed and burned when run on many of my netlists, and it couldn't deal with SPICE 2's POLY construct in dependent sources. Dependent sources with PLOY attributes are common in vendor models, so this represents a real deficiency.
Fortunately, some friendly people at MultiGig Ltd. (www.multigig.com) were busy developing a branch of ngspice which they called "tclspice". The purpose of tclspice is to enable SPICE commands to be embedded into TCL scripts, thereby enabling automated circuit optimization. The project homepage is at: http://tclspice.sourceforge.net/. Since the tclspice branch of the code was alive, I decided to work on it, instead of the seemingly dead main ngspice branch. During spring 2003, I fixed tclspice in three useful (IMNSHO) ways:
To install ngspice and tclspice, do the following:
Running ngspice is very simple. Just issue the command "ngspice filename.net" at the unix command prompt, and ngspice will load the SPICE netlist called "filename.net" into its workspace, and leave you at an ngspice command prompt. You can run the simulator by saying "run". Your results will be stored in SPICE vectors for later printing or plotting. The command set available to you is documented at http://newton.ex.ac.uk/teaching/CDHW/Electronics2/userguide/sec5.html#5 .
To make use of the SPICE2 POLY codemodel, you need to load it into ngspice before you load your netlist. (If you load it after loading your netlist, POLYs in your netlist are not translated, and therefore won't be simulated correctly.) To load the codemodel, just say "codemodel /usr/local/src/tclspice-0.2.12/src/xspice/icm/spice2poly.cm" at the ngspice prompt. Note that you must provide the absolute path to the location of the codemodel; ngspice isn't smart enough to look for it in any default locations. (Also note that you should specify the location where spice2poly.cm lives on your machine; the path above is for mine.)
A better way to read in the spice2poly codemodel is to include it in the ngspice initialization file, "spinit". The initialization file lives in the directory /usr/local/geda/share/ng-spice-rework/scripts (or where ever you placed your geda installation). Other ngspice customizations may also be placed into the spinit file.
The tclspice package is a superset of ngspice. Not only does the package include the ngspice interactive environment; tclspice also provides a facility which exports the ngspice command set as TCL commands for inclusion into a TCL script. This is a very powerful tool: With tclspice you can write a TCL script which runs a loop, tweaks component values, runs an analysis, and then evaluates the circuit performance with the tweaked components before looping again. Obviously, this ability can be used to perform automated, multi-dimensional circuit optimization.
To use tclspice, you just need to say "package require spice" at the beginning of your TCL program. Thereafter, to invoke a SPICE command, you just call it in the spice namesapce. For example, the following TCL program will read in a SPICE netlist, command a transient analysis, run the simulation, and then plot the voltage observed over time on net Vout:
#! tclshNote that since tclspice doesn't read the ngspice initialization file "spinit", you will need to put any initialization commands directly into the TCL program. For example, in the above example we read the spice2poly codemodel directly into the workspace. Many other commands are also available; the entire tclspice commandset is documented at: http://tclspice.sourceforge.net/docs/tclspice_com.html
package require spice
spice::codemodel /usr/local/src/tclspice-0.2.12/src/xspice/icm/spice2poly.cm
spice::source netlistname.cir
spice::tran 0.1ns 40ns
spice::run
spice::plot Vout
puts "All done now!"
A major problem with tclspice (which was inherited from ngspice) is that it leaks memory. Therefore, the time over which you may run a simulation is limited. This means that if you want to do an optimization by looping through a circuit many, many times, you may run out of memory before your program has completed its optimization. This is a known issue with tclspice, and efforts are underway to plug the leaks.
Meanwhile, there are some workarounds which can be used on moderate-sized designs to facilitate long optimization runs. One method I have employed is to have the optimizer write its current state into a file after every circuit analysis, and read its starting state from the same file. The optimizer also stores the current list of best components in another file, and reads this file at the start of every run. Then, I have a TCL program called TaskMgr.tcl which runs in a loop; at each iteration of the loop it forks a child process to run the optimizer. Meanwhile, the parent process waits for 5 minutes (a heuristically determined time), and then issues a "KILL" signal to the child before looping and starting the optimizer again. This way, the optimizer never runs long enough to consume all the memory in my machine. The TaskMgr.tcl program is shown here:
#! tclshNote that TaskMgr.tcl needs the TclX package you already installed to run tclspice. Also, you may want to change the wait time to a different value depending upon the memory and speed of your machine. Finally, the parent has to wait on $PID because that causes the child process's corpse to be taken off the Linux kernal's task list when it dies. Otherwise, you will end up with a lot of zombie processes lurking around your machine as the optimizer runs -- a long optimization could turn your system into "the night of the living dead"!
package require Tclx
while {1} {}
- set PID [fork]
if {$PID} {
} else {
- # Parent
after 300000
puts "About to kill child PID = $PID . . . ."
kill $PID
wait $PID
}
- # Child
source Optimize.tcl
# If we ever get through this, we can print out the following:
error "We are done now!!!!!!"
This method of waiting a specific amout of time for the child process is preferable if a single analysis run takes a relativly short time compared to the time required to eat all memory in the machine. If the analysis time is comparable to the time taken to eat all memory in the machine, a better approach is to have the parent keep track of the analysis state, kick off a single analysis run, and then have the run terminate after every iteration. Whether this is preferable depends upon the size and complexity of your design; you may want to experiment with your analysis to see just how long it takes and how much memory it consumes. I have found that a design comprised of six op amps (with corresponding vendor models) and 50 or so passives will run in under 10 seconds on a PIII 333MHz with 128MB RAM. Therefore, your design must be very big before a single analysis will eat a significant amount of RAM.
Back to the table of contents.Please send comments or questions about this HOWTO to Stuart Brorson at sdb@cloud9.net.