README-0.120100644000175000017500000000213707254354401011334 0ustar billybillyThis is a script that will link together a few tools in linux to do circuit simulation. The tools are GNU Octave, and the spice-2g6 circuit simulator. Octave is freely available and easy to find. Spice was distributed with RedHat-5.2. You can get spice from RedHat or any mirror site that has old distributions. If you have problems getting spice to install, try rpm --nodeps spicexxx.rpm this worked for me on a debian box and spice is running fine. You will also need to install the Term::ReadKey and Term::ANSIColor modules from CPAN. Other than these you "should" have no problems. The install script will just copy bbsim.pl to /usr/bin and copy the man page to /usr/share/man/man1. The spice manual that is included is from Spice 2g6, I did some editing to it so that it is a little more readable. I have also included a couple of example decks to run. These are very simple decks. This script is in its infancy so there is bound to be a few bugs. I have used it for the purposes that I will be using it for and it is working well. I hope it works well for you. Let me know. enjoy, billy bbryant@cubsmvp.com amp20100644000175000017500000000340107253470426010660 0ustar billybilly*First amp design that worked a little * BJT Model for q2n5088 npn's * Collector * | Base * | | Emitter * | | | .SUBCKT Q2N5088 3 2 1 Q1 3 2 1 M195 .MODEL M195 NPN BF=445,IS=2.14E-14,RB=1.46,RC=37.5,RE=.18, +VA=44,IK=.113,C2=2.38,NE=1.387,TF=2.28E-9,CJE=4.9P,PE=.82,ME=.3, +CJC=4.5P,PC=.78,MC=.3,EG=1.11 CJC0 2 3 .18E-12 CJE0 2 1 .1E-12 .ENDS Q2N5088 * BJT model for pnp's * Collector * | Base * | | Emitter * | | | .SUBCKT Q2N3906 3 2 1 Q1 3 2 1 M188 .MODEL M188 PNP BF=135, BR=4.55,IS=4.47E-15,RB=5.8,RC=25,RE=.8, +VA=25,VB=10.8,IK=61.7M,C2=4.25,NE=1.394,IKR=.03,C4=100,NC=1.325,TF=.282N, +CJE=5.67P,PE=.83,ME=.4,CJC=2.21P,PC=.43,MC=.5,EG=1.11 CJC0 2 3 1.4E-12 CJE0 2 1 .4E-12 .ENDS Q2N3906 * Diode Model for the shack's cheapies. * .MODEL D1N914 D( IS=2.90E-09 RS=2.000 N=1.8000 TT=4.68E-07 + CJO=2.53E-11 VJ=0.90000 M=0.50000 ) Vcc 1 0 9v vin 2 0 sin(0 .3 1k 0 0) *vin 2 0 AC 1 * Rc1 and Rc2 are the bias resistors for the * base of the driver stage. r1 1 4 7.8k r2 4 0 1.2k * re1 sets the ac gain. * re2 is the bypassed emitter resistor * r5 is the bootstrap resistor. Rin =~ 1MEG rc 1 6 4.7k re1 5 7 600 re2 5 0 600 r5 3 4 4.7k * ren and rep are the thermal stability * resistors for the push pull stage. ren 13 14 1 rep 14 15 1 * rp1 and rp2 are the bias resistors * for the push pull stage. rp1 1 8 15k rp2 11 0 15k rout 17 0 30 c1 2 3 1.5u c2 4 5 80u c3 7 0 133u co 14 17 1m d1 8 9 D1N914 d2 9 6 D1N914 d3 6 10 D1N914 d4 10 11 D1N914 xbjt1 6 3 5 Q2N5088 xbjt2 1 8 12 Q2N5088 xbjt3 1 12 13 Q2N5088 xbjt4 0 16 15 Q2N3906 xbjt5 0 11 16 Q2N3906 *Analysis requests .TRAN 25u 5m 0 25u *output requests .PRINT TRAN V(2) V(17) *.PRINT AC Vdb(2) Vdb(17) .end bbsim.10100644000175000017500000002254007254407311011253 0ustar billybilly.\" Some nice comment .TH bbsim 1 "15 March 2001" "" "bbsim simulator" .SH NAME .I "bbsim.pl" -Circuit simulation script. .SH SYNOPSIS .B bbsim [-i] .SH DESCRIPTION .P bbsim is a perl script which links together freely available tools in the Linux operating system. The main purpose of this script is to generate graphic output of circuit simulations using the spice 2g6 circuit simulation program. Spice was distributed with RedHat version 5.2 and is freely available. ftp://linux-rep.fnal.gov/pub/mirrors/old-releases/redhat-5.2/i386/RedHat/RPMS is one such source. bbsim uses GNU Octave to generate graphical output for the user. GNU Octave is an excellent program available from many mirror sites. Note that throughout this document the terms deck, netlist and circuit are used interchangeably. I assume that there is at least some familiarity with at least one flavor of spice. If not, then it is advisable that you read the documentation that comes with spice 2g6. I also assume that there is some familiarity with gnuplot or GNU Octave. If not you should probably get familiar with those programs also. .P The typical order of operations for this script would be to load a netlist either on the command line with the .I "-i" at startup or through the .B "load" command. Then using the .B "setup" command, setup the type of analysis that you would like to perform. If you have setup the analysis requests on your own in the netlist then it is of course not necessary to do this. Once the circuit is set up to be simulated use the .B "simulate" command to run spice on the circuit. If there are any errors from the spice output these will be printed out in red to the screen. Once the simulation has been successfully run, you can view the output by typing the appropriate command for the type of analysis performed. For example, if you did a transient analysis you would use the .B 'tran' command to see the output. .P To get graphical output, use the plot command followed by the type of analysis that was performed. For example, for the same transient analysis as above you would type .B 'plot tran' This will start up Octave and display a graph of the output. At this point you can use the cursors by typing the command .B 'cursors' The numeric keypad keys control the movement of the cursors. There are several options available at this point. See the commands section below for the full listing. Enjoy... .SH OPTIONS .I "\-i netlist/deck" The script will load the netlist specified after .I "\-i" The script operates in one of three modes. The first mode is when the script is initially started. This is the simulation/setup mode. There are several commands available in this mode: .SH COMMANDS .B load .I "'input deck'" This command will first verify that the specified deck does exist and then will open it up and read the contents into memory. .B activate .I "'deck'" This command will set the specified deck active, which means that if you use the simulate command, then that is the deck which will be simulated. The currently active deck will be the one that is displayed on the command prompt. Using .B activate without any arguments will list the currently loaded decks that could be activated. .B edit This will start up an editor session with the currently active deck. By default this will be the vi editor because it has the highest probability of being on every machine. You can change this by changing the EDITOR environment variable at the top of the script. .B deck This command will display the contents of the currently active deck. .B decks This will display the currently loaded decks. .B help .I "''" Without any arguments this will give a list of the commands. If an argument is given then it will print out a brief info message about the command. .B quit|exit exit the script. .B setup This command will guide the user through an interactive setup of the analysis requests to be passed on to spice. Currently AC, Transient and Fourier analysis are implemented. .B simulate This causes the currently active deck to be simulated by spice. The output from the analysis requests that were set up will be parsed out of the spice output. This data will then be stored. .B ac This command will print out the results of an AC analysis that was performed on the currently active circuit. If no AC analysis has been performed, an error will be printed to notfy the user. .B tran This command will print out the results of a transient analysis that was performed on the currently active circuit. If no transient has been performed, the user will be notified with an error message. .B four This command will print out the results of a fourier analysis that has been performed on the currently active circuit. The fourier output from spice is in the form of a voltage component. This value is parsed out of the file and changed into decibels RMS. Future versions of this script will probably contain some flexibility in this output. Note that if you would like db peak, you should add 3db to these values. If no four analysis has been performed the user will be notified with an error message. .B node .I [1 2 3...] If called without any arguments this command will display all of the DC Bias voltages from the spice output. If called with node numbers of the form 1 2 3.... then only those values will be displayed. Note that if you do a transient analysis DC bias is not calculated by spice by default. You have to include a .OP statement for this to happen with transient analysis. Keep this in mind if you set up the netlist on your own. If you go through the interactive setup of this script, this is included by the script. .B cd .I "'dir'" change directory. .B ls list the contents of the directory. .B pwd Print working directory. .B plot .I This will plot the results of an ac, transient or fourier simulation. This works by starting up an interactive session with GNU Octave and reading the output values that were stored during the simulation into the octave program through a pipe. Once the plot is up, the user will be in the plot mode of the script in which there are a few unique commands which will be described below. Plot mode will be obvious by the presence of the plot and the command prompt will display plot in it. .SS PLOT COMMANDS These are the available commands once the script is in plot mode. .B cursors This command will turn on the cursors for tracing of the output data. The cursors movement can be controlled by the '8', '6', '2', '4' keys. The '5' key will place the cursors in the middle of the data. Use the 'q' key to exit the cursors. There are several keypress operations available inside of the cursors function. .I 'm' while the cursors are active, pressing the m key will mark the current location of the cursors with an arrow and a label. The following keys effect the arrow and label .I 'r' This will cause the arrow and label to be rotated around to adjust the placement. .I 'l' This will cause the length of the arrow to be increased. .I 's' This will cause the length of the arrow to be decreased. .I 'i' This will cause the spacing between the label and the end of the arrow to be increased. .I 'd' If used while in the marking mode this will cause the spacing between the label and the end of the arrow to be decreased. If used while the cursors are active, this will delete arrows from the last to the first marked. .I 'q' This will exit the mark mode and return the user to the cursors where they were left off. .B save This will save the graph to the current directory. The default format will be png. Future versions of this script will probably have some more flexibility with this. .B gset .I [arg1, arg2 ...] This passes the argument to octave. Octave has many gset functions most of which are documented. For the entire gset listing see the help pages for gnuplot. .B replot This will replot the plot. This is to be used with the gset command function. Changes will not visible until a replot has been done. .B deck As above this will print out the text of the currently active netlist. .B node As above this will show the dc values of the nodes in the circuit. Again, if you are doing a transient analysis you must put a .OP in the netlist to get the bias values. If you use the setup utility in this script it will be done for you. .B help .I [command] If called without any arguments this will print out a list of the commands available in the plot mode. If an argument is specified a brief description of the command will be printed. .B exit|quit This will exit the plot mode of the simulator. You will be placed back into the starting mode and the plot will be killed. .SH CONDITIONS As always, there are no waranties with this free software. The only conditions for the use of this script are that if you make modifications please let me know so that I can add them if they are advantageous. Please make an effort to read the code and understand what is going on. if you don't know perl and are using Linux, you should probably learn it. .SH BUGS At this stage probably several. I have exercised the script for my purposes and it seems to be working well but there are a few problem areas. If you do an AC DEC plot and use use the labels the spacing and length controls will not work totally correct. I am working on it. The log x axis makes this challenging. .SH "SEE ALSO" .BR spice, .BR octave, .BR gnuplot, .BR perl .SH AUTHOR .I "Billy W. Bryant Jr." .I "bbryant@cubsmvp.com" bbsim.pl-0.120100755000175000017500000013545407254407662012131 0ustar billybilly#!/usr/bin/perl #################################################################### # bbsim.pl -i # This is a perl script that links together several tools that are # available under the linux operating system to do circuit analysis # and simulation. The tools are the Perl programming language, # Berkeley Spice Version 2g6, and GNU Octave. # This script will either accept a complete spice deck as input # or will guide the user through an interactive setup for analyss # of a circuit. The available analysis types so far are transient, # ac, fourier, and operating point. # The basic instructions are to start the script. Then the user would # load an input deck using the load command. If the analysis # parameters are not setup, then they could be set up using the # setup command. THe user would then simulate the deck with the sim # command. After simulation the user can view the output of the analysis # by typing the appropriate type. For example, if a transient analysis # were done, the user would type tran to see the output, for ac,the user # would type ac, node will give all of the node voltages. # Graphical representation of the output can be done by using the plot # command. For example, after doing a transient analysis the user # plot the output by doing 'plot tran'. At this point this will work # for transient, ac, and fourier. When the plot comes up, the user # can trace through the plot by using the cursors. Start the cursors # by typing cursors. The numeric keys '8', '4', '2' and '6' control # the movement of the cursors. Any points can be labeled by pressing # 'm' once the cursors are on. The label can be moved around by # pressing the 'r' key. 'l' and 's' lengthen and shorten the arrow # length. To exit the mark, or cursors, press 'q'. The plot can be # saved by typing 'save'. # This is of course free software with no waranty or promises. You # are welcome and encouraged to make modifications as long as you # redistribute free of charge. Please send me a copy of any # modifications you make. # #################################################################### use Getopt::Std; use FileHandle; use Term::ANSIColor qw(:constants); use Term::ReadLine; use Term::ReadKey; use IPC::Open2; use Cwd; getopts ("i:", \%args); # This is the basic layout of the circuit object. %circuit = ( name => "", deck => "", dcnode => [], num_nodes => "", AC => { parameters => [], }, TRAN => { parameters => [], }, FOUR => { parameters => [], }, ); # Clear the hash where the circuits will be stored. %circuits = {}; # If you don't like editing with vi, change it here. $EDITOR = "vi"; if ($args{i}) {load($args{i});} # Make a term object. $term = new Term::ReadLine 'bbsim.pl simulator'; $OUT = $term->OUT || STDOUT; my ($command, $deck, @time, $time, @args); do { # Sit here until quit or exit. @time = split ' ', scalar localtime; $time = @time[3]; if($circuit->{name}) {$deck = $circuit->{name};} else {$deck = "NAD";} $prompt = "$time $deck--> "; $command = $term->readline($prompt); $term->addhistory($command) if /\S/; @args = split ' ', $command; $command = shift @args; if ($command =~ /^load/i) {load(@args);} elsif ($command =~ /^edit/i) {edit();} elsif ($command =~ /setup/i) {setup();} elsif ($command =~ /decks/i) {show_decks();} elsif ($command =~ /deck/i) {show_deck();} elsif ($command =~ /activate/i) {activate(@args);} elsif ($command =~ /^sim/i) {simulate();} elsif ($command =~ /^node/i) {show_node(@args);} elsif ($command =~ /^ac/i) {show_ac(@args);} elsif ($command =~ /^tran/i) {show_tran(@args);} elsif ($command =~ /^four/i) {show_four(@args);} elsif ($command =~ /^plot/i) {plot(@args);} elsif ($command =~ /^help/i) {help(@args);} elsif ($command =~ /quit|exit/i) {exit(0);} elsif ($command =~ /cd/) {chdir $args[0];} elsif ($command =~ /ls/) {system "ls --color";} elsif ($command =~ /pwd/) {printf"%s\n", cwd();} } while (1); ############################### End of main routine. ######################################################## # help # This sub-routine will print a brief help message and # return. If the user just types help, it will display # all of the possible commands. If the user types help # with one of the commands as an argument, a brief # message will be displayed describing the use of the # command. ######################################################## sub help { my $arg = shift @_; my %help => { load => "", edit => "", setup => "", decks => "", deck => "", activate => "", simulate => "", node => "", ac => "", tran => "", four => "", plot => "", cd => "", ls => "", pwd => "", }; $help{load} = "load file1 file2 ...\nUse this to load the deck that you would like to simulate.\n"; $help{edit} = "edit: \nEdit the deck currently loaded.\n"; $help{setup} = "Setup the circuit for analysis. Follow the prompts.\n"; $help{decks} = "This will print out the decks that are currently loaded into memory.\n"; $help{deck} = "This will display the currently active deck.\n"; $help{activate} = "activate :\nThis will set the entered deck active.\n"; $help{simulate} = "This will attempt to simulate the currently active deck.\n"; $help{node} = "After a simulation has been done, this will show the DC node values.\n"; $help{ac} = "After a simulation has been done, this will show the ac values.\n"; $help{tran} = "After a simulation has been done, this will show the transient values.\n"; $help{four} = "After a simulation has been done, this will show the Fourier values.\n"; $help{plot} = "plot \nuse this after simulation to plot the output.\nOnce inside the\ plot mode, type help for command list.\n"; $help{cd} = "Change Directory.\n"; $help{ls} = "list contents of current directory.\n"; $help{pwd} = "Print working directory.\n"; if ($arg) {print "$help{$arg}\n";} else { foreach $command (keys %help) { print "$command\n"; } } return(1); } ######################################################## # edit # To edit the current deck using the editor defined # by the variable EDITOR. If you don't like default # editor which is 'vi', then change the variable # EDITOR at the beginning of the script. # This will start an editor session with the currently # active deck. ######################################################## sub edit { if(! $circuit->{name}) {print "You must load a deck first.\n";} else { system("$EDITOR $circuit->{name}"); undef $/; open DECK, "< $circuit->{name}" || die "Unable to reload $circuit->{name}: $!"; $circuit->{deck} = ; $/ = "\n"; } return(1); } ###################################################### # setup # Interactively setup the analysis requests. # This will guide you through the setup process for # the spice deck you are working on. Don't want to say # too much here because this is going to change. ###################################################### sub setup { my ($type, $choice, $fstart, $fstop, $limpts, $points); my ($string, $node, $nodes, $deck, $uic); if(! $circuit->{name}) {print "No active deck.\n"; return(1);} print "Analysis type (l for list): "; chomp($type = <>); if ($type =~ /l/i) { print "AC, TRAN, TRAN UIC, FOUR\n"; print "Analysis type: "; chomp($type = <>); unless ($type =~ /ac|tran/i) {return(1);} } if ($type =~ /ac/i) { $type = ".AC"; print "DEC, LIN, OCT: "; chomp($choice = <>); if ($choice =~ /dec/i) { $type .= " DEC"; print "Points per Decade: "; chomp($points = <>); translate(\$points); unless ($points > 0) {return(1);} print "Starting Frequency: "; chomp($fstart = <>); translate(\$fstart); if ($fstart == 0) {$fstart = 1;} if ($fstart <= 0) { print "Starting frequency must be greater than 0.\n"; return(1); } print "Stop Frequency: "; chomp($fstop = <>); translate(\$fstop); unless ($fstop > $fstart) { print "Stop Freq must be larger than start freq.\n"; return(1); } $limpts = (cheap_log10($fstop) - cheap_log10($fstart)) * $points; $limpts += 50; # Give a little extra. } elsif ($choice =~ /oct/i) { $type .= " OCT"; print "Points per Octave: "; chomp($points = <>); translate(\$points); unless ($points > 0) {return(1);} print "Starting Frequency: "; chomp($fstart = <>); translate(\$fstart); if ($fstart == 0) {$fstart = 1;} if ($fstart <= 0) { print "Starting frequency must be greater than 0.\n"; return(1); } print "Stop Frequency: "; chomp($fstop = <>); translate(\$fstop); unless ($fstop > $fstart) { print "Stop Freq must be larger than start freq.\n"; return(1); } $limpts = (cheap_log2($fstop) - cheap_log2($fstart)) * $points; $limpts += 50; # Give a little extra. } elsif ($choice =~ /lin/i) { $type .= " LIN"; print "Number of points: "; chomp($points = <>); translate(\$points); unless ($points > 0) {return(1);} print "Starting Frequency: "; chomp($fstart = <>); translate(\$fstart); if ($fstart == 0) {$fstart = 1;} if ($fstart <= 0) { print "Starting frequency must be greater than 0.\n"; return(1); } print "Stop Frequency: "; chomp($fstop = <>); translate(\$fstop); unless ($fstop > $fstart) { print "Stop Freq must be larger than start freq.\n"; return(1); } $limpts = $points + 5; } else { # Didn't enter anything valid. print "You must enter DEC, LIN, or OCT for AC analysis.\n"; return(1); } $nodes = ".PRINT AC"; $string = "$type $points $fstart $fstop"; } elsif (($type =~ /^tran$/i) || ($type =~ /(^tran uic$)/i)) { if ($1) {$uic = 1;} # Just checking to see if uic was set. $type = ".TRAN"; print "Start time: "; chomp($tstart = <>); translate(\$tstart); if (! $tstart) {$tstart = 0;} print "Stop time: "; chomp($tstop = <>); translate(\$tstop); unless ($tstop > $tstart) { print "Stop time must be greater than start time.\n"; return(1); } print "Number of points: "; chomp($points = <>); translate(\$points); unless ($points > 1) {return(1);} my $step_size = ($tstop - $tstart) / $points; $limpts = ($tstop / $step_size) + 100; # Here just want to have a way for the user to specify to use # initial conditions. if ($uic) {$string = "$type $step_size $tstop $tstart $step_size UIC";} else {$string = "$type $step_size $tstop $tstart $step_size";} $nodes = ".PRINT TRAN"; } elsif ($type =~ /four.*/i) { if (!($circuit->{deck} =~ /\n\.tran.+/i)) { print "You must set up a transient first.\n"; return(1); } $type = ".FOUR"; print "Enter the Fundamental Frequency: "; chomp($fund_freq = <>); if ($fund_freq <= 0) {print "error\n"; return(1);} $type .= " $fund_freq "; do { # Get the nodes from the user. print "Enter node: "; chomp($node = <>); if($node =~ /^\d/) { # Voltage by default. $node = "v($node)"; print "$node added\n"; $nodes .= " $node"; } elsif($node =~ /^([a-z]{1,3}\(.+\)$)/i) { print "$node added\n"; $nodes .= " $node"; } elsif($node =~ /^([a-z]{1,3}\d)/i) { $node =~ s/^([a-z]{1,3})(\d+,?\d*)/$1\($2\)/i; print "$node added\n"; $nodes .= " $node"; } } while ($node); $type .= "$nodes"; if (!($circuit->{deck} =~ s/(\.FOUR .*)/$type/mgi)) { $circuit->{deck} =~ s/(^\.end$)//mgi; $circuit->{deck} =~ s/(^\n)//mgi; $circuit->{deck} .= "\n$type\n"; $circuit->{deck} .= ".END"; } return(1); } do { # Get the nodes from the user. print "Enter node: "; chomp($node = <>); if($node =~ /^\d/) { # Voltage by default. $node = "v($node)"; print "$node added\n"; $nodes .= " $node"; } elsif($node =~ /^([a-z]{1,3}\(.+\)$)/i) { print "$node added\n"; $nodes .= " $node"; } elsif($node =~ /^([a-z]{1,3}\d)/i) { $node =~ s/^([a-z]{1,3})(\d+,?\d*)/$1\($2\)/i; print "$node added\n"; $nodes .= " $node"; } } while ($node); # At this point then the type of analysis is set up # and we can change the deck around. if (!($circuit->{deck} =~ s/limpts\s*=\s*\d*/limpts=$limpts/mgi)) { $circuit->{deck} .= ".OPTIONS limpts=$limpts\n"; } $circuit->{deck} =~ s/(^\.ac.*)//mgi; $circuit->{deck} =~ s/(^\.op$)/.OP/mgi; $circuit->{deck} =~ s/(^\.tran.*)//mgi; $circuit->{deck} =~ s/(^\.print.*)//mgi; $circuit->{deck} =~ s/(^\.plot.*)//mgi; $circuit->{deck} =~ s/(^\.end$)//mgi; $circuit->{deck} =~ s/(^\n)//mgi; $circuit->{deck} .= "$string\n$nodes\n.END\n"; return(1); } ####################################################### # translate # # This is a sub that will take a number in the form # of 4u or 4m and put the proper multiplier on it for # us engineering types. # ####################################################### sub translate { $num = shift @_; if (!($$num =~ /\d+[f|p|n|u|m|k|g|t]$/i)) {return(1);} @num = split '', $$num; $multiplier = pop @num; if ($multiplier =~ /f/i) {$multiplier = 1e-15;} elsif ($multiplier =~ /p/i) {$multiplier = 1e-12;} elsif ($multiplier =~ /n/i) {$multiplier = 1e-9;} elsif ($multiplier =~ /u/i) {$multiplier = 1e-6;} elsif ($multiplier =~ /m/) {$multiplier = 1e-3;} elsif ($multiplier =~ /k/i) {$multiplier = 1e+3;} elsif ($multiplier =~ /M/) {$multiplier = 1e+6;} elsif ($multiplier =~ /g/i) {$multiplier = 1e+9;} elsif ($multiplier =~ /t/i) {$multiplier = 1e+12;} $$num = join '', @num; $$num = $$num * $multiplier; } ###################################################### # load # This will check to make sure that the netlist is # for real. If it is then the deck will be loaded into # a variable called deck in the $circuit structure. ###################################################### sub load { my @args = @_; my $deck = @_[0]; if(!$args[0]) {print "Load what??\n"; return(1);} undef $/; if ($circuits->{$deck}) { print "$deck is already loaded, use activate.\n"; return(1); } if (-r $deck) { undef $circuit; $circuit->{name} = $deck; open deck, "< $deck" || die "Could not open $deck: $!\n"; $circuit->{deck} = ; if (defined $circuit->{deck}) {print "$circuit->{name} loaded.\n";} } else { print "$deck does not exist or is not readable.\n"; } # Now store the circuit in the hash. $circuits->{$circuit->{name}} = $circuit; $/ = "\n"; } ##################################################### # cheap_log10 # Perl does not have a base10 log function by # default so have to use this method. Any base log # can be found by using ln(arg)/ln(desired base). # These two log functions are used to calculate the # number of points needed for the limpts parameter in # the spice deck. # ##################################################### sub cheap_log10 { my $val = shift @_; $val = (log($val)/log(10)); use integer; return($val); } ##################################################### # cheap_log2 # This is the same as above. ##################################################### sub cheap_log2 { my $val = shift @_; $val = (log($val)/log(2)); use integer; return($val); } ##################################################### # Show Decks # As the name implies, this will show the decks # that the user has currently loaded into memory. ##################################################### sub show_decks { print "Currently loaded decks:\n"; foreach $deck (keys %{$circuits}) { print "$deck "; } print "\n"; return(1); } ###################################################### # Show deck # This sub will show the current active deck. If it # is larger than one screen the output will be piped # through the more command. ##################################################### sub show_deck { $MORE = new FileHandle; $MORE->autoflush(); open $MORE, "| more" || die "Could not pipe to more: $!\n"; print $MORE "$circuit->{deck}"; close($MORE); return(1); } ###################################################### # Activate # This command will set the given argument as the # currently active deck. ###################################################### sub activate { my @decks = keys %{$circuits}; if (! defined @_[0]) { # Nothing passed in. print "Currently loaded decks:\n@decks\n"; } elsif($circuits->{@_[0]}) { # Argument passed. $circuits->{$circuit->{name}} = $circuit; undef $circuit; $circuit = $circuits->{@_[0]}; return(1); } else { # Argument was not a loaded deck. print "@_[0] is not loaded.\n"; print "Currently loaded decks:\n@decks\n"; } } ####################################################### # simulate # This will simulate the netlist. # This works by opening up a pipe to the spice program. # Once the pipe is opened, the currently active deck is # read into the write end of the pipe. The write end # is then closed to let spice know that nothing else # be coming through the pipe. At this point spice will # start up and send its output to the read end of the # pipe. This is labeled with the FileHandle INPUT. # As the spice output is being read there are multiple # regular expression searchel going on for the different # types of output. When it is found, it is placed in # the $circuit structure for storage. # ####################################################### sub simulate { open2(*INPUT, *WRITER, "spice"); print WRITER "$circuit->{deck}"; close(WRITER); my $i = 0; my $j = 0; my @values = []; my $fields = 0; my $nodes = 0; my $ac = 0; my $tran = 0; undef $four; while () { # Looking for errors or warnings # If there are any, they will be printed out # for the user to see. if (/^0warning:/ .. /^\n/) { print RED $_, RESET; } if (/^0\*error\*:/ .. /^\n/) { print RED $_, RESET unless ($_ =~ /\.end/); } # Looking for .AC, always begins with freq. # $ac var just keeps tran values out of AC. if (/^\s+freq/) { $circuit->{AC} = (); $ac = 1; @fields = split ' ', $_; foreach (@fields) {tr/\(\)//d;} $fields = scalar(@fields) - 1; # How many? @{ $circuit->{AC}->{$parameters} } = @fields; } # Getting the AC values if ((/^x{1}\n/ && $ac) ... /^y{1}\n/) { if (/(\s\D?\d\W\d{3}\D{2}\d\d\s{1,}){2,}/) { @values = split ' ', $_; for($ac = 0; $ac <= $fields; $ac++) { push (@{$circuit->{AC}->{$fields[$ac]}}, $values[$ac]); } } } # Looking for Transient values here. # $tran var keeps ac out of tran. if (/^\s+time/) { $circuit->{TRAN} = (); $tran = 1; @fields = split ' ', $_; foreach (@fields) {tr/\(\)//d;} $fields = scalar(@fields) - 1; # How many? @{ $circuit->{TRAN}->{$parameters} } = @fields; } # Getting the TRAN values if ((/^x{1}\n/ && $tran) ... (/^y{1}\n/)) { if (/(\s\D?\d\W\d{3}\D{2}\d\d\s{1,}){2,}/) { @values = split ' ', $_; for($tran = 0; $tran <= $fields; $tran++) { push (@{$circuit->{TRAN}->{$fields[$tran]}}, $values[$tran]); } } } # Looking for Fourier output here. # The fourier output will be converted into # rms db. This way it will match a reading # off of an oscilloscope. If voltage is desired # make changes here. if (/^\s{1}fourier components of transient response/ ... /^\s+total harmonic distortion/) { if (! defined $four) {$circuit->{FOUR} = ();} if (/^\s{1}fourier components of transient response/) { $four = 0; @tmp = split ' ',$_; ($parameter = pop @tmp) =~ tr/\(\)//d; $parameter =~ s/v(\d+)/vdb$1/i; # Going to be in db's. push(@{$circuit->{FOUR}->{$parameters}}, $parameter); } if (/^\s+\d+/) { @tmp = split ' ', $_; if (scalar(@{ $circuit->{FOUR}->{$parameters} }) < 2) { push(@{ $circuit->{FOUR}->{freq} }, $tmp[1]); } push(@{ $circuit->{FOUR}->{$parameter} }, sprintf("%6.3f",20 * log($tmp[2])/log(10) - 3)); } $four++; } # Looking for Bias (Node) Voltages. if(/(\s+\(\s+\d+\)\s+\d\.\d+){1,}/) { $i = 0; chop (@node = grep /\d\)/, split ' ', $_); @voltage = grep /\d\.\d+/, split ' ', $_; while(@node[$i]) { $circuit->{$dcnode}[$i+$nodes] = $voltage[$i]; $i++; } $nodes = scalar(@{$circuit->{$dcnode}}); } } $circuit->{num_nodes} = $nodes; $circuits->{$circuit->{name}} = $circuit; # In these next three loops, the max and min points # are found and stored. THis is used by the cursors to # set the ends. This is necessary because octave does # not have any means of giving the plot boundaries back # to the script, which would be ideal. if ($ac) { foreach $parameter (@{$circuit->{AC}->{$parameters}}) { $circuit->{AC}->{$parameter.max} = get_max(@{$circuit->{AC}->{$parameter}}); $circuit->{AC}->{$parameter.min} = get_min(@{$circuit->{AC}->{$parameter}}); } } if ($tran) { foreach $parameter (@{$circuit->{TRAN}->{$parameters}}) { $circuit->{TRAN}->{$parameter.max} = get_max(@{$circuit->{TRAN}->{$parameter}}); $circuit->{TRAN}->{$parameter.min} = get_min(@{$circuit->{TRAN}->{$parameter}}); } } if ($four) { unshift @{ $circuit->{FOUR}->{$parameters} }, "freq"; foreach $parameter (@{$circuit->{FOUR}->{$parameters}}) { $circuit->{FOUR}->{$parameter.max} = get_max(@{$circuit->{FOUR}->{$parameter}}); $circuit->{FOUR}->{$parameter.min} = get_min(@{$circuit->{FOUR}->{$parameter}}); } } close(INPUT); return(1); } ####################################################### # get_max # This takes an array and gives back the maximum # element. ####################################################### sub get_max { my @tmp = @_; my $i = 0; my $max = $tmp[0]; for($i = 1; $i < scalar(@tmp); $i++) { if($tmp[$i] > $max) {$max = $tmp[$i];} } return($max); } ##################################################### # get_min # This takes an array and gives back the minimum # element. ##################################################### sub get_min { my @tmp = @_; my $i = 0; my $min = $tmp[0]; for($i = 1; $i < scalar(@tmp); $i++) { if($tmp[$i] < $min) {$min = $tmp[$i];} } return($min); } ###################################################### # show_ac # This sub will print out the AC values for the user # to see. ###################################################### sub show_ac { my $fields = scalar($circuit->{AC}->{$parameters}) - 1; my $key = $circuit->{AC}->{$parameters}[0]; my $i = 0; # First make sure that AC was done. if(! defined @{$circuit->{AC}->{$parameters}}) { print "AC analysis has not been performed.\n"; return(1); } my $OUT = new FileHandle; $OUT->autoflush(); open $OUT, "| more" || die "Can't pipe to more: $!\n"; foreach $array (@{ $circuit->{AC}->{$parameters} }) { printf $OUT "%10s", $array; } print $OUT "\n"; while($circuit->{AC}->{$key}[$i]) { foreach $array (@{ $circuit->{AC}->{$parameters} }) { printf $OUT "%10.3f", $circuit->{AC}->{$array}[$i]; } printf $OUT "\n"; $i++; } close($OUT); return(1); } ###################################################### # show_tran # THis sub will print out the transient values for # the user to see. ###################################################### sub show_tran { my $fields = scalar($circuit->{TRAN}->{$parameters}) - 1; my $key = $circuit->{TRAN}->{$parameters}[0]; my $i = 0; # First make sure that Transient was done. if(! defined @{$circuit->{TRAN}->{$parameters}}) { print "Transient analysis has not been performed.\n"; return(1); } my $OUT = new FileHandle; $OUT->autoflush(); open $OUT, "| more" || die "Can't pipe to less: $!\n"; foreach $array (@{ $circuit->{TRAN}->{$parameters} }) { printf $OUT "%10s", $array; } print $OUT "\n"; while($circuit->{TRAN}->{$key}[$i]) { foreach $array (@{ $circuit->{TRAN}->{$parameters} }) { printf $OUT "%10.3f", $circuit->{TRAN}->{$array}[$i]; } printf $OUT "\n"; $i++; } close(OUT); return(1); } ###################################################### # show_four # This sub will print out the fourier values for the # user to see. ###################################################### sub show_four { my $fields = scalar($circuit->{FOUR}->{$parameters}) - 1; my $key = $circuit->{FOUR}->{$parameters}[0]; my $i = 0; # First make sure that Transient was done. if(! defined @{$circuit->{FOUR}->{$parameters}}) { print "Transient analysis has not been performed.\n"; return(1); } my $OUT = new FileHandle; $OUT->autoflush(); open $OUT, "| more" || die "Can't pipe to less: $!\n"; foreach $array (@{ $circuit->{FOUR}->{$parameters} }) { printf $OUT "%10s", $array; } print $OUT "\n"; while($circuit->{FOUR}->{$key}[$i]) { foreach $array (@{ $circuit->{FOUR}->{$parameters} }) { printf $OUT "%10.3f", $circuit->{FOUR}->{$array}[$i]; } printf $OUT "\n"; $i++; } close(OUT); return(1); } ######################################################## # show_node # This sub will print out the node voltages for the # user to see. The user can also specify a particular # node if they desire. ######################################################### sub show_node { my @args = @_; my $i = 0; my $nodes = $circuit->{num_nodes}; if(! defined $circuit->{$dcnode}) { print "DC .OP not performed for $circuit->{name}.\n"; return(1); } if (scalar(@args)) { if ($args[0] < 1 || $args[0] > $nodes) { print "Invalid Node Number.\n"; print "There are $nodes nodes in this circuit.\n"; return(1); } foreach (@args) { print "Node($_) = $circuit->{$dcnode}[$_-1] Volts\n"; } } else { for ($i = 1; $i <= $nodes; $i++) { print "Node($i) = $circuit->{$dcnode}[$i-1] Volts\n"; } } } ######################################################### # plot # This subroutine will start up an interactive session # with the octave program. The user must specify ac, tran # or four for the plot type. The user may specify # particular nodes to plot if there are many that were # analyzed. If none are specified, then all nodes are # plotted. # # # ######################################################### sub plot { my($type, @fields) = @_; my @tmp; my $pid = 0; my $i = 0; my ($prompt, $time, @time, @args); $arrow = 3; # This is here for a reason. It needs to be global # and be defined up here so that the user can # go back and forth between plot, and cursors # and not get their marks nuked. if ($type !~ /[ac|tran|four]/i) { print "Must specify AC, Tran or Four.\n"; return(1); } $type = uc $type; #AC, TRAN and FOUR are all cap's. if (! scalar(@{$circuit->{$type}->{$parameters}})) { print "$type analysis has not been performed for $circuit->{name}.\n"; return(1); } # Now want to check that if specific nodes were specified that # the simulation was done for them. If they weren't then the # sub will return and let the user know. if (scalar(@fields)) { OUTER: foreach $request (@fields) { if ($request =~ /time|freq/i) {next OUTER;} foreach $parameter (@{$circuit->{$type}->{$parameters}}) { if($request =~ $parameter) { push(@tmp,$request); next OUTER; } } if ($tmp[-1] !~ $request) { print "$request is not a valid parameter.\n"; } } if(! scalar(@tmp)) { print "No valid requests found for $type plot.\n"; return(1); } $fields[0] = $circuit->{$type}->{$parameters}[0]; # Time or Freq. push(@fields,@tmp); } else { # There was nothing specified for parameters So we will plot all. @fields = @{$circuit->{$type}->{$parameters}}; } # So if we are here, then there is data to plot. # We will be plotting the parameters contained in # the array @fields. $OCTAVE = new FileHandle; $OCTAVE->autoflush(); # Want to use the FileHandle module here for the # autoflush method. This ensures that octave will # get the commands that it should get immediately. # Any output other than errors from octave will be redirected # to the /dev/null file. $pid = open $OCTAVE, "| octave -q --interactive > /dev/null" || die "Could not open: $!\n"; # Need to read the data to octave. # If the user did difference nodes such as # v(3,2), then need to trick octave. if ($#fields > 1) {print $OCTAVE "hold on;\n";} # freq, time or whatever is always going to be the first element # of the fields array so read it in here. for ($i = 0; $i < scalar(@{$circuit->{$type}->{$fields[0]}}); $i++) { print $OCTAVE "$fields[0]($i+1)=$circuit->{$type}->{$fields[0]}[$i];\n"; } # What the *!?ck is going on here? # If the user wants to see the output from # the difference between 2 nodes this is entered into spice # as v(2,1) for example. Perl wants to treat that as a function # called v(), to get around this we take the parentheses out # and just call the node v3,2. This is not a problem. # The problem comes when we want to read the value of the # output of this node to Octave. Octave will not accept # a variable of the form v3,2 therefore we have to # massage it a little. Above this the value of the first # element of te fields array is read into octave. This first # value will always be either freq, time, or maybe some DC # value later on, it will always be the idnependent variable. # I set it up this way. Therefore it is safe to do this. # Then when we get to here we want to read the rest of the # outputs into octave and plot them. So we look for nodes # of the type v3,2 if we find one then we change it # to be of the form v_3_2, octave has no trouble with # this. If the node is of the form vdb3,2 then we make it # vdb_3_2. If the node is a normal one, then we just send it # over to octave. foreach $parameter (@fields) { if ($parameter =~ /(v|i)([a-z]){0,2}(\d+),(\d+)/i) { for ($i = 0; $i < scalar(@{$circuit->{$type}->{$fields[0]}}); $i++) { print $OCTAVE "$1$2_$3_$4($i+1)=$circuit->{$type}->{$parameter}[$i];\n"; } print $OCTAVE "plot ($fields[0],$1$2_$3_$4);\n"; } elsif ($parameter !~ $fields[0]) { for ($i = 0; $i < scalar(@{$circuit->{$type}->{$fields[0]}}); $i++) { print $OCTAVE "$parameter($i+1)=$circuit->{$type}->{$parameter}[$i];\n"; } print $OCTAVE "plot ($fields[0], $parameter);\n"; } } # Get some units. Leaving the units, and labels global so # that they can be easily used elswhere. if ($type =~ /AC|FOUR/i) {$x_label = "Frequency(Hz)"; $x_units = "Hz";} elsif ($type =~ /TRAN/i) {$x_label = "Time(sec)"; $x_units = "S";} $y_label = $fields[1]; for ($i = 2; $i <= $#fields; $i++) {$y_label .= ", $fields[$i]";} # Set log x for Decade plots. if (grep(/\.AC DEC/, $circuit->{deck})) { print $OCTAVE "gset logscale x;\n"; $logscale = 1; } print $OCTAVE "gset title \'$type Response\';\n"; print $OCTAVE "gset xlabel \"$x_label\";\n"; print $OCTAVE "gset ylabel \"$y_label\";\n"; print $OCTAVE "gset nokey;\n"; print $OCTAVE "replot;\n"; do { # Sit here until the user exits. @time = split ' ', scalar localtime; $time = @time[3]; $prompt = "$time plot $type--> "; $command = $term->readline($prompt); $term->addhistory($command) if /\S/; @args = split ' ', $command; $command = shift @args; if ($command =~ /^gset/i) {print $OCTAVE "gset @args\n";} elsif ($command =~ /replot/i) {print $OCTAVE "replot\n";} elsif ($command =~ /deck/i) {show_deck();} elsif ($command =~ /^node/i) {show_node(@args);} elsif ($command =~ /cursors/i) {cursors($type, @fields);} elsif ($command =~ /save/i) {save_plot();} elsif ($command =~ /help/i) {plot_help(@args);} } while($command !~ /quit|exit/); kill 9, $pid; close($OCTAVE); } ######################################################## # Cursors # This is by far the hairiest part of this script. # This will be the first part re-written in future # versions so I don't want to say too much about this # now. ######################################################## sub cursors { my ($type, @fields) = @_; my $key = 0; my $i = 0; my $x = 0; my $y = 0; my $toggle = 1; my ($max_x, $min_x, $max_y, $min_y); my $max_i = scalar(@{$circuit->{$type}->{$fields[0]}}) - 1; $max_x = $circuit->{$type}->{$fields[0].max}; $min_x = $circuit->{$type}->{$fields[0].min}; $max_y = $circuit->{$type}->{$fields[1].max}; $min_y = $circuit->{$type}->{$fields[1].min}; if ($fields[$toggle] =~ /^[v|i]\d+/i) {$y_units = "V";} elsif ($fields[$toggle] =~ /^[v|i]p\d+/i) {$y_units = "deg";} elsif ($fields[$toggle] =~ /^[v|i]db\d+/i) {$y_units = "db";} ReadMode 'raw'; $x = $circuit->{$type}->{$fields[0]}[$i]; $y = $circuit->{$type}->{$fields[$toggle]}[$i]; print $OCTAVE "gset arrow 1 from $x,$min_y to $x,$max_y nohead;\n"; print $OCTAVE "gset arrow 2 from $min_x,$y to $max_x,$y nohead;\n"; print $OCTAVE "gset title \'($x$x_units,$y$y_units)\';\n"; print $OCTAVE "replot;\n"; do { $key = ReadKey(0); if (($key =~ '8') || ($key =~ '6')) { $i+=1; if ($i > $max_i) {$i = 0;} $x = $circuit->{$type}->{$fields[0]}[$i]; $y = $circuit->{$type}->{$fields[$toggle]}[$i]; print $OCTAVE "gset noarrow 1;\n"; print $OCTAVE "gset noarrow 2;\n"; print $OCTAVE "gset arrow 1 from $x,$min_y to $x,$max_y nohead;\n"; print $OCTAVE "gset arrow 2 from $min_x,$y to $max_x,$y nohead;\n"; print $OCTAVE "gset title \'($x$x_units,$y$y_units)\';\n"; print $OCTAVE "replot;\n"; } elsif (($key =~ '2') || ($key =~ '4')) { $i-=1; if ($i < 0) {$i = $max_i;} $x = $circuit->{$type}->{$fields[0]}[$i]; $y = $circuit->{$type}->{$fields[$toggle]}[$i]; print $OCTAVE "gset noarrow 1;\n"; print $OCTAVE "gset noarrow 2;\n"; print $OCTAVE "gset arrow 1 from $x,$min_y to $x,$max_y nohead;\n"; print $OCTAVE "gset arrow 2 from $min_x,$y to $max_x,$y nohead;\n"; print $OCTAVE "gset title \'($x$x_units,$y$y_units)\';\n"; print $OCTAVE "replot;\n"; } elsif ($key =~ 'n') { $toggle++; if ($toggle > $#fields) {$toggle = 1;} if ($fields[$toggle] =~ /^[v|i]\d+/i) {$y_units = "V";} elsif ($fields[$toggle] =~ /^[v|i]p\d+/i) {$y_units = "deg";} elsif ($fields[$toggle] =~ /^[v|i]db\d+/i) {$y_units = "db";} $max_y = $circuit->{$type}->{$fields[$toggle].max}; $min_y = $circuit->{$type}->{$fields[$toggle].min}; $y = $circuit->{$type}->{$fields[$toggle]}[$i]; print $OCTAVE "gset noarrow 1;\n"; print $OCTAVE "gset noarrow 2;\n"; print $OCTAVE "gset arrow 1 from $x,$min_y to $x,$max_y nohead;\n"; print $OCTAVE "gset arrow 2 from $min_x,$y to $max_x,$y nohead;\n"; print $OCTAVE "gset title \'($x$x_units,$y$y_units)\';\n"; print $OCTAVE "replot;\n"; } elsif ($key =~ '5') { use integer; $i = $max_i/2; $x = $circuit->{$type}->{$fields[0]}[$i]; $y = $circuit->{$type}->{$fields[$toggle]}[$i]; print $OCTAVE "gset noarrow 1;\n"; print $OCTAVE "gset noarrow 2;\n"; print $OCTAVE "gset arrow 1 from $x,$min_y to $x,$max_y nohead;\n"; print $OCTAVE "gset arrow 2 from $min_x,$y to $max_x,$y nohead;\n"; print $OCTAVE "gset title \'($x$x_units,$y$y_units)\';\n"; print $OCTAVE "replot;\n"; } elsif ($key =~ 'm') { # Label some points. my $key = 0; # Need to use this here. my $from_x = 0; my $from_y = 0; my $label_x = 0; my $label_y = 0; my $i = 0; my $angle = 0; my @angle = qw(0 .393 .785 1.18 1.57 1.96 2.36 2.75 3.14 3.54 3.93 4.32 4.71 5.1 5.5 5.89); my $multiplier = .1; # This is the scaling multiplier for # the arrow length. my ($x_arrow_length, $y_arrow_length); # Need to find out the plot boundaries to calculate # appropriate default arrow lengths. if ($#fields > 1) { for($i = 1; $i <= $#fields; $i++) { if ($max_y < $circuit->{$type}->{$fields[$i].max}) { $max_y = $circuit->{$type}->{$fields[$i].max}; } if ($min_y > $circuit->{$type}->{$fields[$i].min}) { $min_y = $circuit->{$type}->{$fields[$i].min}; } } $i = 0; } if ($logscale) { $x_arrow_length = 10**((log($x)/log(10)) + .5); } else { $x_arrow_length = $multiplier * ($max_x - $min_x); } $y_arrow_length = $multiplier * ($max_y - $min_y); # $from_x and $from_y are used for the point that # the arrow comes from. $from_x = $x + $x_arrow_length * cos($angle[$angle]); $from_y = $y + $y_arrow_length * sin($angle[$angle]); # $x_label_space and $y_label_space are calculated # here off of the plot boundaries. 1% is an acceptable # value for this spacing. Note that these are only # calculated once. Initialy tried to calculate these # using the arrow length, but since it changes, the space # was changing correspndingly and this was no good. $x_label_space = ($max_x - $min_x) * .01; $y_label_space = ($max_y - $min_y) * .025; if ($logscale) {$label_x = $from_x;} else {$label_x = $from_x + $x_label_space;} $label_y = $from_y; print $OCTAVE "gset noarrow 1;\n"; print $OCTAVE "gset noarrow 2;\n"; print $OCTAVE "gset arrow $arrow from $from_x,$from_y to $x,$y;\n"; print $OCTAVE "gset label $arrow \'($x$x_units, $y$y_units)\' at $label_x,$label_y l;\n"; print $OCTAVE "replot;\n"; do { $key = ReadKey(0); if ($key =~ 'r') { # Want to rotate the arrow. $angle++; if ($angle > $#angle) {$angle = 0;} if (($logscale) && (($angle > 4) && ($angle < 12))) { $x_arrow_length = 10**((log($x)/log(10))-.2); $from_x = $x + $x_arrow_length * cos($angle[$angle]); } else { $from_x = $x + $x_arrow_length * cos($angle[$angle]); } $from_y = $y + $y_arrow_length * sin($angle[$angle]); print $OCTAVE "gset noarrow $arrow;\n"; print $OCTAVE "gset nolabel $arrow;\n"; print $OCTAVE "gset arrow $arrow from $from_x,$from_y to $x,$y;\n"; ## This block is just to get the label in the right place. if ((($angle >= 0) && ($angle <= 3)) || (($angle >= 13) && ($angle <= 15))) { if ($logscale) {$label_x = $from_x;} else{$label_x = $x_label_space + $from_x;} $label_y = $from_y; print $OCTAVE "gset label $arrow \'($x$x_units, $y$y_units)\' at $label_x,$label_y l;\n"; } elsif (($angle > 4) && ($angle < 12)) { if($logscale) {$label_x = $from_x;} else{$label_x = $from_x - $x_label_space;} $label_y = $from_y; print $OCTAVE "gset label $arrow \'($x$x_units, $y$y_units)\' at $label_x,$label_y r;\n"; } elsif($angle == 4) { $label_x = $from_x; $label_y = $from_y + $y_label_space; print $OCTAVE "gset label $arrow \'($x$x_units, $y$y_units)\' at $label_x,$label_y c;\n"; } elsif($angle == 12) { $label_x = $from_x; $label_y = $from_y - $y_label_space; print $OCTAVE "gset label $arrow \'($x$x_units, $y$y_units)\' at $label_x, $label_y c;\n"; } # End of label computation block. Repeated in each below. } elsif ($key =~ 'l') { # Want to lengthen the arrow. $x_arrow_length = $x_arrow_length * 1.1; $y_arrow_length = $y_arrow_length * 1.1; $from_x = $x + $x_arrow_length * cos($angle[$angle]); $from_y = $y + $y_arrow_length * sin($angle[$angle]); print $OCTAVE "gset noarrow $arrow;\n"; print $OCTAVE "gset nolabel $arrow;\n"; print $OCTAVE "gset arrow $arrow from $from_x,$from_y to $x,$y;\n"; if ((($angle >= 0) && ($angle <= 3)) || (($angle >= 13) && ($angle <= 15))) { if ($logscale) {$label_x = $from_x;} else{$label_x = $x_label_space + $from_x;} $label_y = $from_y; print $OCTAVE "gset label $arrow \'($x$x_units, $y$y_units)\' at $label_x,$label_y l;\n"; } elsif (($angle > 4) && ($angle < 12)) { if($logscale) {$label_x = $from_x;} else{$label_x = $from_x - $x_label_space;} $label_y = $from_y; print $OCTAVE "gset label $arrow \'($x$x_units, $y$y_units)\' at $label_x,$label_y r;\n"; } elsif($angle == 4) { $label_x = $from_x; $label_y = $from_y + $y_label_space; print $OCTAVE "gset label $arrow \'($x$x_units, $y$y_units)\' at $label_x,$label_y c;\n"; } elsif($angle == 12) { $label_x = $from_x; $label_y = $from_y - $y_label_space; print $OCTAVE "gset label $arrow \'($x$x_units, $y$y_units)\' at $label_x, $label_y c;\n"; } } elsif ($key =~ 's') { # Want to shorten the arrow. $x_arrow_length = $x_arrow_length * .95; $y_arrow_length = $y_arrow_length * .95; $from_x = $x + $x_arrow_length * cos($angle[$angle]); $from_y = $y + $y_arrow_length * sin($angle[$angle]); print $OCTAVE "gset noarrow $arrow;\n"; print $OCTAVE "gset nolabel $arrow;\n"; print $OCTAVE "gset arrow $arrow from $from_x,$from_y to $x,$y;\n"; if ((($angle >= 0) && ($angle <= 3)) || (($angle >= 13) && ($angle <= 15))) { if ($logscale) {$label_x = $from_x;} else{$label_x = $x_label_space + $from_x;} $label_y = $from_y; print $OCTAVE "gset label $arrow \'($x$x_units, $y$y_units)\' at $label_x,$label_y l;\n"; } elsif (($angle > 4) && ($angle < 12)) { if($logscale) {$label_x = $from_x;} else{$label_x = $from_x - $x_label_space;} $label_y = $from_y; print $OCTAVE "gset label $arrow \'($x$x_units, $y$y_units)\' at $label_x,$label_y r;\n"; } elsif($angle == 4) { $label_x = $from_x; $label_y = $from_y + $y_label_space; print $OCTAVE "gset label $arrow \'($x$x_units, $y$y_units)\' at $label_x,$label_y c;\n"; } elsif($angle == 12) { $label_x = $from_x; $label_y = $from_y - $y_label_space; print $OCTAVE "gset label $arrow \'($x$x_units, $y$y_units)\' at $label_x, $label_y c;\n"; } } elsif ($key =~ 'i') { # Increase the label spacing $x_label_space *= 1.05; $y_label_space *= 1.05; print $OCTAVE "gset noarrow $arrow;\n"; print $OCTAVE "gset nolabel $arrow;\n"; print $OCTAVE "gset arrow $arrow from $from_x,$from_y to $x,$y;\n"; if ((($angle >= 0) && ($angle <= 3)) || (($angle >= 13) && ($angle <= 15))) { if ($logscale) {$label_x = $from_x;} else{$label_x = $x_label_space + $from_x;} $label_y = $from_y; print $OCTAVE "gset label $arrow \'($x$x_units, $y$y_units)\' at $label_x,$label_y l;\n"; } elsif (($angle > 4) && ($angle < 12)) { if($logscale) {$label_x = $from_x;} else{$label_x = $from_x - $x_label_space;} $label_y = $from_y; print $OCTAVE "gset label $arrow \'($x$x_units, $y$y_units)\' at $label_x,$label_y r;\n"; } elsif($angle == 4) { $label_x = $from_x; $label_y = $from_y + $y_label_space; print $OCTAVE "gset label $arrow \'($x$x_units, $y$y_units)\' at $label_x,$label_y c;\n"; } elsif($angle == 12) { $label_x = $from_x; $label_y = $from_y - $y_label_space; print $OCTAVE "gset label $arrow \'($x$x_units, $y$y_units)\' at $label_x, $label_y c;\n"; } } elsif ($key =~ 'd') { # Decrease the label spacing $x_label_space *= .95; $y_label_space *= .95; print $OCTAVE "gset noarrow $arrow;\n"; print $OCTAVE "gset nolabel $arrow;\n"; print $OCTAVE "gset arrow $arrow from $from_x,$from_y to $x,$y;\n"; if ((($angle >= 0) && ($angle <= 3)) || (($angle >= 13) && ($angle <= 15))) { if ($logscale) {$label_x = $from_x;} else{$label_x = $x_label_space + $from_x;} $label_y = $from_y; print $OCTAVE "gset label $arrow \'($x$x_units, $y$y_units)\' at $label_x,$label_y l;\n"; } elsif (($angle > 4) && ($angle < 12)) { if($logscale) {$label_x = $from_x;} else{$label_x = $from_x - $x_label_space;} $label_y = $from_y; print $OCTAVE "gset label $arrow \'($x$x_units, $y$y_units)\' at $label_x,$label_y r;\n"; } elsif($angle == 4) { $label_x = $from_x; $label_y = $from_y + $y_label_space; print $OCTAVE "gset label $arrow \'($x$x_units, $y$y_units)\' at $label_x,$label_y c;\n"; } elsif($angle == 12) { $label_x = $from_x; $label_y = $from_y - $y_label_space; print $OCTAVE "gset label $arrow \'($x$x_units, $y$y_units)\' at $label_x, $label_y c;\n"; } } print $OCTAVE "replot;\n"; } while ($key !~ 'q'); print $OCTAVE "gset arrow 1 from $x,$min_y to $x,$max_y nohead;\n"; print $OCTAVE "gset arrow 2 from $min_x,$y to $max_x,$y nohead;\n"; print $OCTAVE "replot;\n"; $arrow++; } ## This is the end of $key = `m` elsif (($key =~ 'd') && ($arrow > 3)) { # Want to delete arrows. $arrow--; print $OCTAVE "gset noarrow $arrow;\n"; print $OCTAVE "gset nolabel $arrow;\n"; print $OCTAVE "replot;\n"; } } while ($key !~ /q/); ReadMode 'restore'; # Put things back into plot mode. print $OCTAVE "gset title \'$type Response\';\n"; print $OCTAVE "gset noarrow 1;\n"; print $OCTAVE "gset noarrow 2;\n"; print $OCTAVE "replot;\n"; return(1); } ############################################## # save_plot # This will save the plot to a file. ############################################## sub save_plot { my $plot; print "Save as: "; chomp($plot = <>); print $OCTAVE "gset terminal png;\n"; print $OCTAVE "gset output \'$plot.png\';\n"; print $OCTAVE "gset size 1,.7;\n"; print $OCTAVE "replot;\n"; print $OCTAVE "gset output;\n"; print $OCTAVE "gset terminal x11;\n"; print $OCTAVE "gset size 1,1;\n"; } ################################################### # plot_help # Prints out some very basic help for the plot # mode of the script. #################################################### sub plot_help { my $arg = shift @_; my %help => { gset => "", cursors => "", replot => "", save => "", }; $help{gset} = "gset , see octave help.\n"; $help{cursors} ="activate cursors, use 4,8,6,2 to move, m = mark, l = lengthen, s = shorten, r = rotate, q = exit.\n"; $help{replot} = "replot the plot after changes.\n"; $help{save} = "save the plot to file.\n"; if ($arg) { print "$help{$arg}\n"; } else { foreach $command (keys %help) { print "$command\n"; } } return(1); } install0100755000175000017500000000024707254410667011501 0ustar billybilly#!/bin/sh # # This will copy the script and man page to # the following locations. Thats it. # # cp ./bbsim.pl-0.12 /usr/bin/bbsim mv ./bbsim.1 /usr/share/man/man1 lab2.deck0100644000175000017500000000120107254103246011534 0ustar billybilly*Input deck for lab2 .SUBCKT Q2N5088 3 2 1 Q1 3 2 1 M195 .MODEL M195 NPN BF=445,IS=2.14E-14,RB=1.46,RC=37.5,RE=.18, +VA=44,IK=.113,C2=2.38,NE=1.387,TF=2.28E-9,CJE=4.9P,PE=.82,ME=.3, +CJC=4.5P,PC=.78,MC=.3,EG=1.11 CJC0 2 3 .18E-12 CJE0 2 1 .1E-12 .ENDS Q2N5088 Vs 1 0 12 *Vin 2 0 AC Vin 2 0 pulse(0 1 0 1n 1n 25u 50u) cin 2 3 5.3n x1 6 3 4 Q2N5088 rb1 1 3 19.7k rb2 3 0 4.3k l1 1 8 93.5u rc 8 6 6.23 cc 1 6 27.1n re1 4 5 87 re2 5 0 220 ce 5 0 80n cout 6 7 1.6n rl 7 0 10k .OPTIONS limpts=50000 itl5=50000 *.AC LIN 200 50k 150k .TRAN 1.25u 550u 300u 1.25u UIC .FOUR 20k V(2) V(7) .OP *.PRINT AC Vdb(7) Vp(7) .PRINT TRAN V(7) V(2) .end lowpass0100644000175000017500000000023307254354330011505 0ustar billybilly*Lowpass filter *circuit description** R1 1 2 1.6k R2 2 0 160k C1 2 0 1uF IC=0 V1 1 0 AC 1v *Analysis requests .AC OCT 10 10 1000 .PRINT AC Vdb(2) .END spice_manual0100644000175000017500000024102607254353341012465 0ustar billybillySPICE Version 2G User's Guide (10 Aug 1981) A.Vladimirescu, Kaihe Zhang, A.R.Newton, D.O.Pederson, A.Sangiovanni-Vincentelli Department of Electrical Engineering and Computer Sciences University of California Berkeley, Ca., 94720 Acknowledgement: Dr. Richard Dowell and Dr. Sally Liu have con- tributed to develop the present SPICE version. SPICE was origi- nally developed by Dr. Lawrence Nagel and has been modified extensively by Dr. Ellis Cohen. SPICE is a general-purpose circuit simulation program for nonlinear dc, nonlinear transient, and linear ac analyses. Cir- cuits may contain resistors, capacitors, inductors, mutual induc- tors, independent voltage and current sources, four types of dependent sources, transmission lines, and the four most common semiconductor devices: diodes, BJT's, JFET's, and MOSFET's. SPICE has built-in models for the semiconductor devices, and the user need specify only the pertinent model parameter values. The model for the BJT is based on the integral charge model of Gummel and Poon; however, if the Gummel- Poon parameters are not specified, the model reduces to the simpler Ebers-Moll model. In either case, charge storage effects, ohmic resistances, and a current-dependent output conductance may be included. The diode model can be used for either junction diodes or Schottky barrier diodes. The JFET model is based on the FET model of Shichman and Hodges. Three MOSFET models are implemented; MOS1 is described by a square-law I-V characteristic MOS2 is an analytical model while MOS3 is a semi-empirical model. Both MOS2 and MOS3 include second-order effects such as channel length modulation, subthres- hold conduction, scattering limited velocity saturation, small- size effects and charge-controlled capacitances. 1. TYPES OF ANALYSIS 1.1. DC Analysis The dc analysis portion of SPICE determines the dc operating point of the circuit with inductors shorted and capacitors opened. A dc analysis is automatically performed prior to a transient analysis to determine the transient initial conditions, and prior to an ac small-signal analysis to determine the linear- ized, small-signal models for nonlinear devices. If requested, the dc small-signal value of a transfer function (ratio of output variable to input source), input resistance, and output resis- tance will also be computed as a part of the dc solution. The dc analysis can also be used to generate dc transfer curves: a specified independent voltage or current source is stepped over a user-specified range and the dc output variables are stored for each sequential source value. If requested, SPICE also will determine the dc small-signal sensitivities of specified output variables with respect to circuit parameters. The dc analysis options are specified on the .DC, .TF, .OP, and .SENS control cards. If one desires to see the small-signal models for nonlinear devices in conjunction with a transient analysis operating point, then the .OP card must be provided. The dc bias conditions will be identical for each case, but the more comprehensive operating point information is not available to be printed when transient initial conditions are computed. 1.2. AC Small-Signal Analysis The ac small-signal portion of SPICE computes the ac output variables as a function of frequency. The program first computes the dc operating point of the circuit and determines linearized, small-signal models for all of the nonlinear devices in the cir- cuit. The resultant linear circuit is then analyzed over a user-specified range of frequencies. The desired output of an ac small- signal analysis is usually a transfer function (voltage gain, transimpedance, etc). If the circuit has only one ac input, it is convenient to set that input to unity and zero phase, so that output variables have the same value as the transfer function of the output variable with respect to the input. The generation of white noise by resistors and semiconductor devices can also be simulated with the ac small-signal portion of SPICE. Equivalent noise source values are determined automati- cally from the small-signal operating point of the circuit, and the contribution of each noise source is added at a given summing point. The total output noise level and the equivalent input noise level are determined at each frequency point. The output and input noise levels are normalized with respect to the square root of the noise bandwidth and have the units Volts/rt Hz or Amps/rt Hz. The output noise and equivalent input noise can be printed or plotted in the same fashion as other output variables. No additional input data are necessary for this analysis. Flicker noise sources can be simulated in the noise analysis by including values for the parameters KF and AF on the appropri- ate device model cards. The distortion characteristics of a circuit in the small- signal mode can be simulated as a part of the ac small-signal analysis. The analysis is performed assuming that one or two signal frequencies are imposed at the input. The frequency range and the noise and distortion analysis parameters are specified on the .AC, .NOISE, and .DISTO control lines. 1.3. Transient Analysis The transient analysis portion of SPICE computes the tran- sient output variables as a function of time over a user- specified time interval. The initial conditions are automati- cally determined by a dc analysis. All sources which are not time dependent (for example, power supplies) are set to their dc value. For large-signal sinusoidal simulations, a Fourier analysis of the output waveform can be specified to obtain the frequency domain Fourier coefficients. The transient time inter- val and the Fourier analysis options are specified on the .TRAN and .FOURIER control lines. 1.4. Analysis at Different Temperatures All input data for SPICE is assumed to have been measured at 27 deg C (300 deg K). The simulation also assumes a nominal tem- perature of 27 deg C. The circuit can be simulated at other tem- peratures by using a .TEMP control line. Temperature appears explicitly in the exponential terms of the BJT and diode model equations. In addition, saturation currents have a built-in temperature dependence. The temperature dependence of the saturation current in the BJT models is deter- mined by: IS(T1) = IS(T0)*((T1/T0)**XTI)*exp(q*EG*(T1-T0)/(k*T1*T0)) where k is Boltzmann's constant, q is the electronic charge, EG is the energy gap which is a model parameter, and XTI is the saturation current temperature exponent (also a model parameter, and usually equal to 3). The temperature dependence of forward and reverse beta is according to the formula: beta(T1)=beta(T0)*(T1/T0)**XTB where T1 and T0 are in degrees Kelvin, and XTB is a user-supplied model parameter. Temperature effects on beta are carried out by appropriate adjustment to the values of BF, ISE, BR, and ISC. Temperature dependence of the saturation current in the junction diode model is determined by: IS(T1) = IS(T0)*((T1/T0)**(XTI/N))*exp(q*EG*(T1-T0)/(k*N*T1*T0)) where N is the emission coefficient, which is a model parameter, and the other symbols have the same meaning as above. Note that for Schottky barrier diodes, the value of the saturation current temperature exponent, XTI, is usually 2. Temperature appears explicitly in the value of junction potential, PHI, for all the device models. The temperature dependence is determined by: PHI(TEMP) = k*TEMP/q*log(Na*Nd/Ni(TEMP)**2) where k is Boltzmann's constant, q is the electronic charge, Na is the acceptor impurity density, Nd is the donor impurity den- sity, Ni is the intrinsic concentration, and EG is the energy gap. Temperature appears explicitly in the value of surface mobility, UO, for the MOSFET model. The temperature dependence is determined by: UO(TEMP) = UO(TNOM)/(TEMP/TNOM)**(1.5) The effects of temperature on resistors is modeled by the for- mula: value(TEMP) = value(TNOM)*(1+TC1*(TEMP-TNOM)+TC2*(TEMP-TNOM)**2)) where TEMP is the circuit temperature, TNOM is the nominal tem- perature, and TC1 and TC2 are the first- and second-order tem- perature coefficients. 2. CONVERGENCE Both dc and transient solutions are obtained by an iterative process which is terminated when both of the following conditions hold: 1) The nonlinear branch currents converge to within a tolerance of 0.1 percent or 1 picoamp (1.0E-12 Amp), whichever is larger. 2) The node voltages converge to within a tolerance of 0.1 per- cent or 1 microvolt (1.0E-6 Volt), whichever is larger. Although the algorithm used in SPICE has been found to be very reliable, in some cases it will fail to converge to a solu- tion. When this failure occurs, the program will print the node voltages at the last iteration and terminate the job. In such cases, the node voltages that are printed are not necessarily correct or even close to the correct solution. Failure to converge in the dc analysis is usually due to an error in specifying circuit connections, element values, or model parameter values. Regenerative switching circuits or circuits with positive feedback probably will not converge in the dc analysis unless the OFF option is used for some of the devices in the feedback path, or the .NODESET card is used to force the cir- cuit to converge to the desired state. 3. INPUT FORMAT The input format for SPICE is of the free format type. Fields on a card are separated by one or more blanks, a comma, an equal (=) sign, or a left or right parenthesis; extra spaces are ignored. A card may be continued by entering a + (plus) in column 1 of the following card; SPICE continues reading begin- ning with column 2. A name field must begin with a letter (A through Z) and can- not contain any delimiters. Only the first eight characters of the name are used. A number field may be an integer field (12, -44), a floating point field (3.14159), either an integer or floating point number followed by an integer exponent (1E-14, 2.65E3), or either an integer or a floating point number followed by one of the follow- ing scale factors: T=1E12 G=1E9 MEG=1E6 K=1E3 MIL=25.4E-6 M=1E-3 U=1E-6 N=1E-9 P=1E-12 F=1E-15 Letters immediately following a number that are not scale factors are ignored, and letters immediately following a scale factor are ignored. Hence, 10, 10V, 10VOLTS, and 10HZ all represent the same number, and M, MA, MSEC, and MMHOS all represent the same scale factor. Note that 1000, 1000.0, 1000HZ, 1E3, 1.0E3, 1KHZ, and 1K all represent the same number. 4. CIRCUIT DESCRIPTION The circuit to be analyzed is described to SPICE by a set of element cards, which define the circuit topology and element values, and a set of control cards, which define the model param- eters and the run controls. The first card in the input deck must be a title card, and the last card must be a .END card. The order of the remaining cards is arbitrary (except, of course, that continuation cards must immediately follow the card being continued). Each element in the circuit is specified by an element card that contains the element name, the circuit nodes to which the element is connected, and the values of the parameters that determine the electrical characteristics of the element. The first letter of the element name specifies the element type. The format for the SPICE element types is given in what follows. The strings XXXXXXX, YYYYYYY, and ZZZZZZZ denote arbitrary alphanumeric strings. For example, a resistor name must begin with the letter R and can contain from one to eight characters. Hence, R, R1, RSE, ROUT, and R3AC2ZY are valid resistor names. Data fields that are enclosed in lt and gt signs '< >' are optional. All indicated punctuation (parentheses, equal signs, etc.) are required. With respect to branch voltages and currents, SPICE uniformly uses the associated reference conven- tion (current flows in the direction of voltage drop). Nodes must be nonnegative integers but need not be numbered sequentially. The datum (ground) node must be numbered zero. The circuit cannot contain a loop of voltage sources and/or inductors and cannot contain a cutset of current sources and/or capacitors. Each node in the circuit must have a dc path to ground. Every node must have at least two connections except for transmission line nodes (to permit unterminated transmission lines) and MOSFET substrate nodes (which have two internal con- nections anyway). 5. TITLE CARD, COMMENT CARDS AND .END CARD 5.1. Title Card Examples: POWER AMPLIFIER CIRCUIT TEST OF CAM CELL This card must be the first card in the input deck. Its contents are printed verbatim as the heading for each section of output. 5.2. .END Card Examples: .END This card must always be the last card in the input deck. Note that the period is an integral part of the name. 5.3. Comment Card General Form: * Examples: * RF=1K GAIN SHOULD BE 100 * MAY THE FORCE BE WITH MY CIRCUIT The asterisk in the first column indicates that this card is a comment card. Comment cards may be placed anywhere in the cir- cuit description. 6. ELEMENT CARDS 6.1. Resistors General form: RXXXXXXX N1 N2 VALUE > Examples: R1 1 2 100 RC1 12 17 1K TC=0.001,0.015 N1 and N2 are the two element nodes. VALUE is the resis- tance (in ohms) and may be positive or negative but not zero. TC1 and TC2 are the (optional) temperature coefficients; if not specified, zero is assumed for both. The value of the resistor as a function of temperature is given by: value(TEMP) = value(TNOM)*(1+TC1*(TEMP-TNOM)+TC2*(TEMP-TNOM)**2)) 6.2. Capacitors and Inductors General form: CXXXXXXX N+ N- VALUE LYYYYYYY N+ N- VALUE Examples: CBYP 13 0 1UF COSC 17 23 10U IC=3V LLINK 42 69 1UH LSHUNT 23 51 10U IC=15.7MA N+ and N- are the positive and negative element nodes, respectively. VALUE is the capacitance in Farads or the induc- tance in Henries. For the capacitor, the (optional) initial condition is the initial (time-zero) value of capacitor voltage (in Volts). For the inductor, the (optional) initial condition is the initial (time-zero) value of inductor current (in Amps) that flows from N+, through the inductor, to N-. Note that the initial condi- tions (if any) apply 'only' if the UIC option is specified on the .TRAN card. Nonlinear capacitors and inductors can be described. General form : CXXXXXXX N+ N- POLY C0 C1 C2 ... LYYYYYYY N+ N- POLY L0 L1 L2 ... C0 C1 C2 ...(and L0 L1 L2 ...) are the coefficients of a polynomial describing the element value. The capacitance is expressed as a function of the voltage across the element while the inductance is a function of the current through the inductor. The value is computed as value=C0+C1*V+C2*V**2+... value=L0+L1*I+L2*I**2+... where V is the voltage across the capacitor and I the current flowing in the inductor. 6.3. Coupled (Mutual) Inductors General form: KXXXXXXX LYYYYYYY LZZZZZZZ VALUE Examples: K43 LAA LBB 0.999 KXFRMR L1 L2 0.87 LYYYYYYY and LZZZZZZZ are the names of the two coupled inductors, and VALUE is the coefficient of coupling, K, which must be greater than 0 and less than or equal to 1. Using the 'dot' convention, place a 'dot' on the first node of each induc- tor. 6.4. Transmission Lines (Lossless) General form: TXXXXXXX N1 N2 N3 N4 Z0=VALUE > + Examples: T1 1 0 2 0 Z0=50 TD=10NS N1 and N2 are the nodes at port 1; N3 and N4 are the nodes at port 2. Z0 is the characteristic impedance. The length of the line may be expressed in either of two forms. The transmis- sion delay, TD, may be specified directly (as TD=10ns, for exam- ple). Alternatively, a frequency F may be given, together with NL, the normalized electrical length of the transmission line with respect to the wavelength in the line at the frequency F. If a frequency is specified but NL is omitted, 0.25 is assumed (that is, the frequency is assumed to be the quarter-wave fre- quency). Note that although both forms for expressing the line length are indicated as optional, one of the two must be speci- fied. Note that this element models only one propagating mode. If all four nodes are distinct in the actual circuit, then two modes may be excited. To simulate such a situation, two transmission- line elements are required. (see the example in Appendix A for further clarification.) The (optional) initial condition specification consists of the voltage and current at each of the transmission line ports. Note that the initial conditions (if any) apply 'only' if the UIC option is specified on the .TRAN card. One should be aware that SPICE will use a transient time- step which does not exceed 1/2 the minimum transmission line delay. Therefore very short transmission lines (compared with the analysis time frame) will cause long run times. 6.5. Linear Dependent Sources SPICE allows circuits to contain linear dependent sources characterized by any of the four equations i=g*v v=e*v i=f*i v=h*i where g, e, f, and h are constants representing transconductance, voltage gain, current gain, and transresistance, respectively. Note: a more complete description of dependent sources as imple- mented in SPICE is given in Appendix B. 6.6. Linear Voltage-Controlled Current Sources General form: GXXXXXXX N+ N- NC+ NC- VALUE Examples: G1 2 0 5 0 0.1MMHO N+ and N- are the positive and negative nodes, respectively. Current flow is from the positive node, through the source, to the negative node. NC+ and NC- are the positive and negative controlling nodes, respectively. VALUE is the transconductance (in mhos). 6.7. Linear Voltage-Controlled Voltage Sources General form: EXXXXXXX N+ N- NC+ NC- VALUE Examples: E1 2 3 14 1 2.0 N+ is the positive node, and N- is the negative node. NC+ and NC- are the positive and negative controlling nodes, respec- tively. VALUE is the voltage gain. 6.8. Linear Current-Controlled Current Sources General form: FXXXXXXX N+ N- VNAM VALUE Examples: F1 13 5 VSENS 5 N+ and N- are the positive and negative nodes, respectively. Current flow is from the positive node, through the source, to the negative node. VNAM is the name of a voltage source through which the controlling current flows. The direction of positive controlling current flow is from the positive node, through the source, to the negative node of VNAM. VALUE is the current gain. 6.9. Linear Current-Controlled Voltage Sources General form: HXXXXXXX N+ N- VNAM VALUE Examples: HX 5 17 VZ 0.5K N+ and N- are the positive and negative nodes, respectively. VNAM is the name of a voltage source through which the control- ling current flows. The direction of positive controlling current flow is from the positive node, through the source, to the negative node of VNAM. VALUE is the transresistance (in ohms). 6.10. Independent Sources General form: VXXXXXXX N+ N- < DC/TRAN VALUE> >> IYYYYYYY N+ N- < DC/TRAN VALUE> >> Examples: VCC 10 0 DC 6 VIN 13 2 0.001 AC 1 SIN(0 1 1MEG) ISRC 23 21 AC 0.333 45.0 SFFM(0 1 10K 5 1K) VMEAS 12 9 N+ and N- are the positive and negative nodes, respectively. Note that voltage sources need not be grounded. Positive current is assumed to flow from the positive node, through the source, to the negative node. A current source of positive value, will force current to flow out of the N+ node, through the source, and into the N- node. Voltage sources, in addition to being used for circuit excitation, are the 'ammeters' for SPICE, that is, zero valued voltage sources may be inserted into the circuit for the purpose of measuring current. They will, of course, have no effect on circuit operation since they represent short-circuits. DC/TRAN is the dc and transient analysis value of the source. If the source value is zero both for dc and transient analyses, this value may be omitted. If the source value is time-invariant (e.g., a power supply), then the value may option- ally be preceded by the letters DC. ACMAG is the ac magnitude and ACPHASE is the ac phase. The source is set to this value in the ac analysis. If ACMAG is omitted following the keyword AC, a value of unity is assumed. If ACPHASE is omitted, a value of zero is assumed. If the source is not an ac small-signal input, the keyword AC and the ac values are omitted. Any independent source can be assigned a time-dependent value for transient analysis. If a source is assigned a time- dependent value, the time-zero value is used for dc analysis. There are five independent source functions: pulse, exponential, sinusoidal, piece-wise linear, and single-frequency FM. If parameters other than source values are omitted or set to zero, the default values shown will be assumed. (TSTEP is the printing increment and TSTOP is the final time (see the .TRAN card for explanation)). 1. Pulse PULSE(V1 V2 TD TR TF PW PER) Examples: VIN 3 0 PULSE(-1 1 2NS 2NS 2NS 50NS 100NS) parameters default values units V1 (initial value) Volts or Amps V2 (pulsed value) Volts or Amps TD (delay time) 0.0 seconds TR (rise time) TSTEP seconds TF (fall time) TSTEP seconds PW (pulse width) TSTOP seconds PER(period) TSTOP seconds A single pulse so specified is described by the following table: time value 0 V1 TD V1 TD+TR V2 TD+TR+PW V2 TD+TR+PW+TF V1 TSTOP V1 Intermediate points are determined by linear interpolation. 2. Sinusoidal SIN(VO VA FREQ TD THETA) Examples: VIN 3 0 SIN(0 1 100MEG 1NS 1E10) parameters default value units VO (offset) Volts or Amps VA (amplitude) Volts or Amps FREQ (frequency) 1/TSTOP Hz TD (delay) 0.0 seconds THETA (damping factor) 0.0 1/seconds The shape of the waveform is described by the following table: time value 0 to TD VO TD to TSTOP VO + VA*exp(-(time-TD)*THETA)*sine(twopi*FREQ*(time+TD)) 3. Exponential EXP(V1 V2 TD1 TAU1 TD2 TAU2) Examples: VIN 3 0 EXP(-4 -1 2NS 30NS 60NS 40NS) parameters default values units V1 (initial value) Volts or Amps V2 (pulsed value) Volts or Amps TD1 (rise delay time) 0.0 seconds TAU1 (rise time constant) TSTEP seconds TD2 (fall delay time) TD1+TSTEP seconds TAU2 (fall time constant) TSTEP seconds The shape of the waveform is described by the following table: time value 0 to TD1 V1 TD1 to TD2 V1+(V2-V1)*(1-exp(-(time-TD1)/TAU1)) TD2 to TSTOP V1+(V2-V1)*(1-exp(-(time-TD1)/TAU1)) +(V1-V2)*(1-exp(-(time-TD2)/TAU2)) 4. Piece-Wise Linear PWL(T1 V1 ) Examples: VCLOCK 7 5 PWL(0 -7 10NS -7 11NS -3 17NS -3 18NS -7 50NS -7) Parameters and default values Each pair of values (Ti, Vi) specifies that the value of the source is Vi (in Volts or Amps) at time=Ti. The value of the source at intermediate values of time is determined by using linear interpolation on the input values. 5. Single-Frequency FM SFFM(VO VA FC MDI FS) Examples: V1 12 0 SFFM(0 1M 20K 5 1K) parameters default values units VO (offset) Volts or Amps VA (amplitude) Volts or Amps FC (carrier frequency) 1/TSTOP Hz MDI (modulation index) FS (signal frequency) 1/TSTOP Hz The shape of the waveform is described by the following equation: value = VO + VA*sine((twopi*FC*time) + MDI*sine(twopi*FS*time)) 7. SEMICONDUCTOR DEVICES The elements that have been described to this point typi- cally require only a few parameter values to specify completely the electrical characteristics of the element. However, the models for the four semiconductor devices that are included in the SPICE program require many parameter values. Moreover, many devices in a circuit often are defined by the same set of device model parameters. For these reasons, a set of device model parameters is defined on a separate .MODEL card and assigned a unique model name. The device element cards in SPICE then refer- ence the model name. This scheme alleviates the need to specify all of the model parameters on each device element card. Each device element card contains the device name, the nodes to which the device is connected, and the device model name. In addition, other optional parameters may be specified for each device: geometric factors and an initial condition. The area factor used on the diode, BJT and JFET device card determines the number of equivalent parallel devices of a speci- fied model. The affected parameters are marked with an asterisk under the heading 'area' in the model descriptions below. Several geometric factors associated with the channel and the drain and source diffusions can be specified on the MOSFET device card. Two different forms of initial conditions may be specified for devices. The first form is included to improve the dc con- vergence for circuits that contain more than one stable state. If a device is specified OFF, the dc operating point is deter- mined with the terminal voltages for that device set to zero. After convergence is obtained, the program continues to iterate to obtain the exact value for the terminal voltages. If a cir- cuit has more than one dc stable state, the OFF option can be used to force the solution to correspond to a desired state. If a device is specified OFF when in reality the device is conduct- ing, the program will still obtain the correct solution (assuming the solutions converge) but more iterations will be required since the program must independently converge to two separate solutions. The .NODESET card serves a similar purpose as the OFF option. The .NODESET option is easier to apply and is the pre- ferred means to aid convergence. The second form of initial conditions are specified for use with the transient analysis. These are true 'initial conditions' as opposed to the convergence aids above. See the description of the .IC card and the .TRAN card for a detailed explanation of initial conditions. 7.1. Junction Diodes General form: DXXXXXXX N+ N- MNAME Examples: DBRIDGE 2 10 DIODE1 DCLMP 3 7 DMOD 3.0 IC=0.2 N+ and N- are the positive and negative nodes, respectively. MNAME is the model name, AREA is the area factor, and off indi- cates an (optional) starting condition on the device for dc analysis. If the area factor is omitted, a value of 1.0 is assumed. The (optional) initial condition specification using IC=VD is intended for use with the UIC option on the .TRAN card, when a transient analysis is desired starting from other than the quiescent operating point. 7.2. Bipolar Junction Transistors (BJT's) General form: QXXXXXXX NC NB NE MNAME Examples: Q23 10 24 13 QMOD IC=0.6,5.0 Q50A 11 26 4 20 MOD1 NC, NB, and NE are the collector, base, and emitter nodes, respectively. NS is the (optional) substrate node. If unspeci- fied, ground is used. MNAME is the model name, AREA is the area factor, and OFF indicates an (optional) initial condition on the device for the dc analysis. If the area factor is omitted, a value of 1.0 is assumed. The (optional) initial condition specification using IC=VBE,VCE is intended for use with the UIC option on the .TRAN card, when a transient analysis is desired starting from other than the quiescent operating point. See the .IC card description for a better way to set transient initial conditions. 7.3. Junction Field-Effect Transistors (JFET's) General form: JXXXXXXX ND NG NS MNAME Examples: J1 7 2 3 JM1 OFF ND, NG, and NS are the drain, gate, and source nodes, respectively. MNAME is the model name, AREA is the area factor, and OFF indicates an (optional) initial condition on the device for dc analysis. If the area factor is omitted, a value of 1.0 is assumed. The (optional) initial condition specification, using IC=VDS,VGS is intended for use with the UIC option on the .TRAN card, when a transient analysis is desired starting from other than the quiescent operating point (see the .IC card for a better way to set initial conditions). 7.4. MOSFET's General form: MXXXXXXX ND NG NS NB MNAME + Examples: M1 24 2 0 20 TYPE1 M31 2 17 6 10 MODM L=5U W=2U M31 2 16 6 10 MODM 5U 2U M1 2 9 3 0 MOD1 L=10U W=5U AD=100P AS=100P PD=40U PS=40U M1 2 9 3 0 MOD1 10U 5U 2P 2P ND, NG, NS, and NB are the drain, gate, source, and bulk (sub- strate) nodes, respectively. MNAME is the model name. L and W are the channel length and width, in meters. AD and AS are the areas of the drain and source diffusions, in sq-meters. Note that the suffix U specifies microns (1E-6 m) and P sq-microns (1E-12 sq-m). If any of L, W, AD, or AS are not specified, default values are used. The user may specify the values to be used for these default parameters on the .OPTIONS card. The use of defaults simplifies input deck preparation, as well as the editing required if device geometries are to be changed. PD and PS are the perimeters of the drain and source junctions, in meters. NRD and NRS designate the equivalent number of squares of the drain and source diffusions; these values multiply the sheet resistance RSH specified on the .MODEL card for an accurate representation of the parasitic series drain and source resis- tance of each transistor. PD and PS default to 0.0 while NRD and NRS to 1.0. OFF indicates an (optional) initial condition on the device for dc analysis. The (optional) initial condition specif- ication using IC=VDS,VGS,VBS is intended for use with the UIC option on the .TRAN card, when a transient analysis is desired starting from other than the quiescent operating point. See the .IC card for a better and more convenient way to specify tran- sient initial conditions. 7.5. .MODEL Card General form: .MODEL MNAME TYPE(PNAME1=PVAL1 PNAME2=PVAL2 ... ) Examples: .MODEL MOD1 NPN BF=50 IS=1E-13 VBF=50 The .MODEL card specifies a set of model parameters that will be used by one or more devices. MNAME is the model name, and type is one of the following seven types: NPN NPN BJT model PNP PNP BJT model D diode model NJF N-channel JFET model PJF P-channel JFET model NMOS N-channel MOSFET model PMOS P-channel MOSFET model Parameter values are defined by appending the parameter name, as given below for each model type, followed by an equal sign and the parameter value. Model parameters that are not given a value are assigned the default values given below for each model type. 7.6. Diode Model The dc characteristics of the diode are determined by the parameters IS and N. An ohmic resistance, RS, is included. Charge storage effects are modeled by a transit time, TT, and a nonlinear depletion layer capacitance which is determined by the parameters CJO, VJ, and M. The temperature dependence of the saturation current is defined by the parameters EG, the energy and XTI, the saturation current temperature exponent. Reverse breakdown is modeled by an exponential increase in the reverse diode current and is determined by the parameters BV and IBV (both of which are positive numbers). name parameter units default example area 1 IS saturation current A 1.0E-14 1.0E-14 * 2 RS ohmic resistance Ohm 0 10 * 3 N emission coefficient - 1 1.0 4 TT transit-time sec 0 0.1Ns 5 CJO zero-bias junction capacitance F 0 2PF * 6 VJ junction potential V 1 0.6 7 M grading coefficient - 0.5 0.5 8 EG activation energy eV 1.11 1.11 Si 0.69 Sbd 0.67 Ge 9 XTI saturation-current temp. exp - 3.0 3.0 jn 2.0 Sbd 10 KF flicker noise coefficient - 0 11 AF flicker noise exponent - 1 12 FC coefficient for forward-bias - 0.5 depletion capacitance formula 13 BV reverse breakdown voltage V infinite 40.0 14 IBV current at breakdown voltage A 1.0E-3 7.7. BJT Models (both NPN and PNP) The bipolar junction transistor model in SPICE is an adapta- tion of the integral charge control model of Gummel and Poon. This modified Gummel-Poon model extends the original model to include several effects at high bias levels. The model will automatically simplify to the simpler Ebers-Moll model when cer- tain parameters are not specified. The parameter names used in the modified Gummel-Poon model have been chosen to be more easily understood by the program user, and to reflect better both physi- cal and circuit design thinking. The dc model is defined by the parameters IS, BF, NF, ISE, IKF, and NE which determine the forward current gain characteris- tics, IS, BR, NR, ISC, IKR, and NC which determine the reverse current gain characteristics, and VAF and VAR which determine the output conductance for forward and reverse regions. Three ohmic resistances RB, RC, and RE are included, where RB can be high current dependent. Base charge storage is modeled by forward and reverse transit times, TF and TR, the forward transit time TF being bias dependent if desired, and nonlinear depletion layer capacitances which are determined by CJE, VJE, and MJE for the B-E junction , CJC, VJC, and MJC for the B-C junction and CJS, VJS, and MJS for the C-S (Collector-Substrate) junction. The temperature dependence of the saturation current, IS, is deter- mined by the energy-gap, EG, and the saturation current tempera- ture exponent, XTI. Additionally base current temperature depen- dence is modeled by the beta temperature exponent XTB in the new model. The BJT parameters used in the modified Gummel-Poon model are listed below. The parameter names used in earlier versions of SPICE2 are still accepted. Modified Gummel-Poon BJT Parameters. name parameter units default example area 1 IS transport saturation current A 1.0E-16 1.0E-15 * 2 BF ideal maximum forward beta - 100 100 3 NF forward current emission coefficient - 1.0 1 4 VAF forward Early voltage V infinite 200 5 IKF corner for forward beta high current roll-off A infinite 0.01 * 6 ISE B-E leakage saturation current A 0 1.0E-13 * 7 NE B-E leakage emission coefficient - 1.5 2 8 BR ideal maximum reverse beta - 1 0.1 9 NR reverse current emission coefficient - 1 1 10 VAR reverse Early voltage V infinite 200 11 IKR corner for reverse beta high current roll-off A infinite 0.01 * 12 ISC B-C leakage saturation current A 0 1.0E-13 * 13 NC B-C leakage emission coefficient - 2 1.5 14 RB zero bias base resistance Ohms 0 100 * 15 IRB current where base resistance falls halfway to its min value A infinite 0.1 * 16 RBM minimum base resistance at high currents Ohms RB 10 * 17 RE emitter resistance Ohms 0 1 * 18 RC collector resistance Ohms 0 10 * 19 CJE B-E zero-bias depletion capacitance F 0 2PF * 20 VJE B-E built-in potential V 0.75 0.6 21 MJE B-E junction exponential factor - 0.33 0.33 22 TF ideal forward transit time sec 0 0.1Ns 23 XTF coefficient for bias dependence of TF - 0 24 VTF voltage describing VBC dependence of TF V infinite 25 ITF high-current parameter for effect on TF A 0 * 26 PTF excess phase at freq=1.0/(TF*2PI) Hz deg 0 27 CJC B-C zero-bias depletion capacitance F 0 2PF * 28 VJC B-C built-in potential V 0.75 0.5 29 MJC B-C junction exponential factor - 0.33 0.5 30 XCJC fraction of B-C depletion capacitance - 1 connected to internal base node 31 TR ideal reverse transit time sec 0 10Ns 32 CJS zero-bias collector-substrate capacitance F 0 2PF * 33 VJS substrate junction built-in potential V 0.75 34 MJS substrate junction exponential factor - 0 0.5 35 XTB forward and reverse beta temperature exponent - 0 36 EG energy gap for temperature effect on IS eV 1.11 37 XTI temperature exponent for effect on IS - 3 38 KF flicker-noise coefficient - 0 39 AF flicker-noise exponent - 1 40 FC coefficient for forward-bias depletion capacitance formula - 0.5 7.8. JFET Models (both N and P Channel) The JFET model is derived from the FET model of Shichman and Hodges. The dc characteristics are defined by the parameters VTO and BETA, which determine the variation of drain current with gate voltage, LAMBDA, which determines the output conductance, and IS, the saturation current of the two gate junctions. Two ohmic resistances, RD and RS, are included. Charge storage is modeled by nonlinear depletion layer capacitances for both gate junctions which vary as the -1/2 power of junction voltage and are defined by the parameters CGS, CGD, and PB. name parameter units default example area 1 VTO threshold voltage V -2.0 -2.0 2 BETA transconductance parameter A/V**2 1.0E-4 1.0E-3 * 3 LAMBDA channel length modulation parameter 1/V 0 1.0E-4 4 RD drain ohmic resistance Ohm 0 100 * 5 RS source ohmic resistance Ohm 0 100 * 6 CGS zero-bias G-S junction capacitance F 0 5PF * 7 CGD zero-bias G-D junction capacitance F 0 1PF * 8 PB gate junction potential V 1 0.6 9 IS gate junction saturation current A 1.0E-14 1.0E-14 * 10 KF flicker noise coefficient - 0 11 AF flicker noise exponent - 1 12 FC coefficient for forward-bias - 0.5 depletion capacitance formula 7.9. MOSFET Models (both N and P channel) SPICE provides three MOSFET device models which differ in the formulation of the I-V characteristic. The variable LEVEL specifies the model to be used: LEVEL=1 -> Shichman-Hodges LEVEL=2 -> MOS2 (as described in [1]) LEVEL=3 -> MOS3, a semi-empirical model(see [1]) The dc characteristics of the MOSFET are defined by the device parameters VTO, KP, LAMBDA, PHI and GAMMA. These parameters are computed by SPICE if process parameters (NSUB, TOX, ...) are given, but user-specified values always override. VTO is posi- tive (negative) for enhancement mode and negative (positive) for depletion mode N-channel (P-channel) devices. Charge storage is modeled by three constant capacitors, CGSO, CGDO, and CGBO which represent overlap capacitances, by the nonlinear thin-oxide capa- citance which is distributed among the gate, source, drain, and bulk regions, and by the nonlinear depletion-layer capacitances for both substrate junctions divided into bottom and periphery, which vary as the MJ and MJSW power of junction voltage respec- tively, and are determined by the parameters CBD, CBS, CJ, CJSW, MJ, MJSW and PB. There are two built-in models of the charge storage effects associated with the thin-oxide. The default is the piecewise linear voltage-dependent capacitance model proposed by Meyer. The second choice is the charge-controlled capacitance model of Ward and Dutton [1]. The XQC model parameter acts as a flag and a coefficient at the same time. As the former it causes the program to use Meyer's model whenever larger than 0.5 or not specified, and the charge-controlled model when between 0 and 0.5. In the latter case its value defines the share of the chan- nel charge associated with the drain terminal in the saturation region. The thin-oxide charge storage effects are treated slightly different for the LEVEL=1 model. These voltage- dependent capacitances are included only if TOX is specified in the input description and they are represented using Meyer's for- mulation. There is some overlap among the parameters describing the junctions, e.g. the reverse current can be input either as IS (in A) or as JS (in A/m**2). Whereas the first is an absolute value the second is multiplied by AD and AS to give the reverse current of the drain and source junctions respectively. This methodology has been chosen since there is no sense in relating always junc- tion characteristics with AD and AS entered on the device card; the areas can be defaulted. The same idea applies also to the zero-bias junction capacitances CBD and CBS (in F) on one hand, and CJ (in F/m**2) on the other. The parasitic drain and source series resistance can be expressed as either RD and RS (in ohms) or RSH (in ohms/sq.), the latter being multiplied by the number of squares NRD and NRS input on the device card. name parameter units default example 1 LEVEL model index - 1 2 VTO zero-bias threshold voltage V 0.0 1.0 3 KP transconductance parameter A/V**2 2.0E-5 3.1E-5 4 GAMMA bulk threshold parameter V**0.5 0.0 0.37 5 PHI surface potential V 0.6 0.65 6 LAMBDA channel-length modulation (MOS1 and MOS2 only) 1/V 0.0 0.02 7 RD drain ohmic resistance Ohm 0.0 1.0 8 RS source ohmic resistance Ohm 0.0 1.0 9 CBD zero-bias B-D junction capacitance F 0.0 20FF 10 CBS zero-bias B-S junction capacitance F 0.0 20FF 11 IS bulk junction saturation current A 1.0E-14 1.0E-15 12 PB bulk junction potential V 0.8 0.87 13 CGSO gate-source overlap capacitance per meter channel width F/m 0.0 4.0E-11 14 CGDO gate-drain overlap capacitance per meter channel width F/m 0.0 4.0E-11 15 CGBO gate-bulk overlap capacitance per meter channel length F/m 0.0 2.0E-10 16 RSH drain and source diffusion sheet resisitance Ohm/sq. 0.0 10.0 17 CJ zero-bias bulk junction bottom cap. per sq-meter of junction area F/m**2 0.0 2.0E-4 18 MJ bulk junction bottom grading coef. - 0.5 0.5 19 CJSW zero-bias bulk junction sidewall cap. per meter of junction perimeter F/m 0.0 1.0E-9 20 MJSW bulk junction sidewall grading coef. - 0.33 21 JS bulk junction saturation current per sq-meter of junction area A/m**2 1.0E-8 22 TOX oxide thickness meter 1.0E-7 1.0E-7 23 NSUB substrate doping 1/cm**3 0.0 4.0E15 24 NSS surface state density 1/cm**2 0.0 1.0E10 25 NFS fast surface state density 1/cm**2 0.0 1.0E10 26 TPG type of gate material: - 1.0 +1 opp. to substrate -1 same as substrate 0 Al gate 27 XJ metallurgical junction depth meter 0.0 1U 28 LD lateral diffusion meter 0.0 0.8U 29 UO surface mobility cm**2/V-s 600 700 30 UCRIT critical field for mobility degradation (MOS2 only) V/cm 1.0E4 1.0E4 31 UEXP critical field exponent in mobility degradation (MOS2 only) - 0.0 0.1 32 UTRA transverse field coef (mobility) (deleted for MOS2) - 0.0 0.3 33 VMAX maximum drift velocity of carriers m/s 0.0 5.0E4 34 NEFF total channel charge (fixed and mobile) coefficient (MOS2 only) - 1.0 5.0 35 XQC thin-oxide capacitance model flag and coefficient of channel charge share attributed to drain (0-0.5) - 1.0 0.4 36 KF flicker noise coefficient - 0.0 1.0E-26 37 AF flicker noise exponent - 1.0 1.2 38 FC coefficient for forward-bias depletion capacitance formula - 0.5 39 DELTA width effect on threshold voltage (MOS2 and MOS3) - 0.0 1.0 40 THETA mobility modulation (MOS3 only) 1/V 0.0 0.1 41 ETA static feedback (MOS3 only) - 0.0 1.0 42 KAPPA saturation field factor (MOS3 only) - 0.2 0.5 8. SUBCIRCUITS A subcircuit that consists of SPICE elements can be defined and referenced in a fashion similar to device models. The sub- circuit is defined in the input deck by a grouping of element cards; the program then automatically inserts the group of ele- ments wherever the subcircuit is referenced. There is no limit on the size or complexity of subcircuits, and subcircuits may contain other subcircuits. An example of subcircuit usage is given in Appendix A. 8.1. .SUBCKT Card General form: .SUBCKT subnam N1 Examples: .SUBCKT OPAMP 1 2 3 4 A circuit definition is begun with a .SUBCKT card. SUBNAM is the subcircuit name, and N1, N2, ... are the external nodes, which cannot be zero. The group of element cards which immedi- ately follow the .SUBCKT card define the subcircuit. The last card in a subcircuit definition is the .ENDS card (see below). Control cards may not appear within a subcircuit definition; however, subcircuit definitions may contain anything else, including other subcircuit definitions, device models, and sub- circuit calls (see below). Note that any device models or sub- circuit definitions included as part of a subcircuit definition are strictly local (i.e., such models and definitions are not known outside the subcircuit definition). Also, any element nodes not included on the .SUBCKT card are strictly local, with the exception of 0 (ground) which is always global. 8.2. .ENDS Card General form: .ENDS Examples: .ENDS OPAMP This card must be the last one for any subcircuit defini- tion. The subcircuit name, if included, indicates which subcir- cuit definition is being terminated; if omitted, all subcircuits being defined are terminated. The name is needed only when nested subcircuit definitions are being made. 8.3. Subcircuit Calls General form: XYYYYYYY N1 SUBNAM Examples: X1 2 4 17 3 1 MULTI Subcircuits are used in SPICE by specifying pseudo-elements beginning with the letter X, followed by the circuit nodes to be used in expanding the subcircuit. 9. CONTROL CARDS 9.1. .TEMP Card General form: .TEMP T1 > Examples: .TEMP -55.0 25.0 125.0 This card specifies the temperatures at which the circuit is to be simulated. T1, T2, ... Are the different temperatures, in degrees C. Temperatures less than -223.0 deg C are ignored. Model data are specified at TNOM degrees (see the .OPTIONS card for TNOM); if the .TEMP card is omitted, the simulation will also be performed at a temperature equal to TNOM. 9.2. .WIDTH Card General form: .WIDTH IN=COLNUM OUT=COLNUM Examples: .WIDTH IN=72 OUT=133 COLNUM is the last column read from each line of input; the setting takes effect with the next line read. The default value for COLNUM is 80. The out parameter specifies the output print width. Permissible values for the output print width are 80 and 133. 9.3. .OPTIONS Card General form: .OPTIONS OPT1 OPT2 ... (or OPT=OPTVAL ...) Examples: .OPTIONS ACCT LIST NODE This card allows the user to reset program control and user options for specific simulation purposes. Any combination of the following options may be included, in any order. 'x' (below) represents some positive number. option effect ACCT causes accounting and run time statistics to be printed LIST causes the summary listing of the input data to be printed NOMOD suppresses the printout of the model parameters. NOPAGE suppresses page ejects NODE causes the printing of the node table. OPTS causes the option values to be printed. GMIN=x resets the value of GMIN, the minimum conductance allowed by the program. The default value is 1.0E-12. RELTOL=x resets the relative error tolerance of the program. The default value is 0.001 (0.1 percent). ABSTOL=x resets the absolute current error tolerance of the program. The default value is 1 picoamp. VNTOL=x resets the absolute voltage error tolerance of the program. The default value is 1 microvolt. TRTOL=x resets the transient error tolerance. The default value is 7.0. This parameter is an estimate of the factor by which SPICE overestimates the actual truncation error. CHGTOL=x resets the charge tolerance of the program. The default value is 1.0E-14. PIVTOL=x resets the absolute minimum value for a matrix entry to be accepted as a pivot. The default value is 1.0E-13. PIVREL=x resets the relative ratio between the largest column entry and an acceptable pivot value. The default value is 1.0E-3. In the numerical pivoting algorithm the allowed minimum pivot value is determined by EPSREL=AMAX1(PIVREL*MAXVAL,PIVTOL) where MAXVAL is the maximum element in the column where a pivot is sought (partial pivoting). NUMDGT=x resets the number of significant digits printed for output variable values. X must satisfy the relation 0 < x < 8. The default value is 4. Note: this option is independent of the error tolerance used by SPICE (i.e., if the values of options RELTOL, ABSTOL, etc., are not changed then one may be printing numerical 'noise' for NUMDGT > 4. TNOM=x resets the nominal temperature. The default value is 27 deg C (300 deg K). ITL1=x resets the dc iteration limit. The default is 100. ITL2=x resets the dc transfer curve iteration limit. The default is 50. ITL3=x resets the lower transient analysis iteration limit. the default value is 4. ITL4=x resets the transient analysis timepoint iteration limit. the default is 10. ITL5=x resets the transient analysis total iteration limit. the default is 5000. Set ITL5=0 to omit this test. ITL6=x resets the dc iteration limit at each step of the source stepping method. The default is 0 which means not to use this method. CPTIME=x the maximum cpu-time in seconds allowed for this job. LIMTIM=x resets the amount of cpu time reserved by SPICE for generating plots should a cpu time-limit cause job termination. The default value is 2 (seconds). LIMPTS=x resets the total number of points that can be printed or plotted in a dc, ac, or transient analysis. The default value is 201. LVLCOD=x if x is 2 (two), then machine code for the matrix solution will be generated. Otherwise, no machine code is generated. The default value is 2. Applies only to CDC computers. LVLTIM=x if x is 1 (one), the iteration timestep control is used. if x is 2 (two), the truncation-error timestep is used. The default value is 2. If method=Gear and MAXORD>2 then LVLTIM is set to 2 by SPICE. METHOD=name sets the numerical integration method used by SPICE. Possible names are Gear or trapezoidal. The default is trapezoidal. MAXORD=x sets the maximum order for the integration method if Gear's variable-order method is used. X must be between 2 and 6. The default value is 2. DEFL=x resets the value for MOS channel length; the default is 100.0 micrometer. DEFW=x resets the value for MOS channel width; the default is 100.0 micrometer. DEFAD=x resets the value for MOS drain diffusion area; the default is 0.0. DEFAS=x resets the value for MOS source diffusion area; the default is 0.0. 9.4. .OP Card General form: .OP The inclusion of this card in an input deck will force SPICE to determine the dc operating point of the circuit with inductors shorted and capacitors opened. Note: a dc analysis is automati- cally performed prior to a transient analysis to determine the transient initial conditions, and prior to an ac small-signal analysis to determine the linearized, small-signal models for nonlinear devices. SPICE performs a dc operating point analysis if no other analyses are requested. 9.5. .DC Card General form: .DC SRCNAM VSTART VSTOP VINCR [SRC2 START2 STOP2 INCR2] Examples: .DC VIN 0.25 5.0 0.25 .DC VDS 0 10 .5 VGS 0 5 1 .DC VCE 0 10 .25 IB 0 10U 1U This card defines the dc transfer curve source and sweep limits. SRCNAM is the name of an independent voltage or current source. VSTART, VSTOP, and VINCR are the starting, final, and incrementing values respectively. The first example will cause the value of the voltage source VIN to be swept from 0.25 Volts to 5.0 Volts in increments of 0.25 Volts. A second source (SRC2) may optionally be specified with associated sweep parameters. In this case, the first source will be swept over its range for each value of the second source. This option can be useful for obtaining semiconductor device output characteristics. See the second example data deck in that section of the guide. 9.6. .NODESET Card General form: .NODESET V(NODNUM)=VAL V(NODNUM)=VAL ... Examples: .NODESET V(12)=4.5 V(4)=2.23 This card helps the program find the dc or initial transient solution by making a preliminary pass with the specified nodes held to the given voltages. The restriction is then released and the iteration continues to the true solution. The .NODESET card may be necessary for convergence on bistable or astable circuits. In general, this card should not be necessary. 9.7. .IC Card General form: .IC V(NODNUM)=VAL V(NODNUM)=VAL ... Examples: .IC V(11)=5 V(4)=-5 V(2)=2.2 This card is for setting transient initial conditions. It has two different interpretations, depending on whether the UIC parameter is specified on the .TRAN card. Also, one should not confuse this card with the .NODESET card. The .NODESET card is only to help dc convergence, and does not affect final bias solu- tion (except for multi-stable circuits). The two interpretations of this card are as follows: 1. When the UIC parameter is specified on the .TRAN card, then the node voltages specified on the .IC card are used to compute the capacitor, diode, BJT, JFET, and MOSFET initial conditions. This is equivalent to specifying the IC=... parameter on each device card, but is much more convenient. The IC=... parameter can still be specified and will take precedence over the .IC values. Since no dc bias (initial transient) solution is com- puted before the transient analysis, one should take care to specify all dc source voltages on the .IC card if they are to be used to compute device initial conditions. 2. When the UIC parameter is not specified on the .TRAN card, the dc bias (initial transient) solution will be computed before the transient analysis. In this case, the node voltages speci- fied on the .IC card will be forced to the desired initial values during the bias solution. During transient analysis, the con- straint on these node voltages is removed. 9.8. .TF Card General form: .TF OUTVAR INSRC Examples: .TF V(5,3) VIN .TF I(VLOAD) VIN This card defines the small-signal output and input for the dc small- signal analysis. OUTVAR is the small-signal output variable and INSRC is the small-signal input source. If this card is included, SPICE will compute the dc small-signal value of the transfer function (output/input), input resistance, and out- put resistance. For the first example, SPICE would compute the ratio of V(5,3) to VIN, the small-signal input resistance at VIN, and the small-signal output resistance measured across nodes 5 and 3. 9.9. .SENS Card General form: .SENS OV1 Examples: .SENS V(9) V(4,3) V(17) I(VCC) If a .SENS card is included in the input deck, SPICE will determine the dc small-signal sensitivities of each specified output variable with respect to every circuit parameter. Note: for large circuits, large amounts of output can be generated. 9.10. .AC Card General form: .AC DEC ND FSTART FSTOP .AC OCT NO FSTART FSTOP .AC LIN NP FSTART FSTOP Examples: .AC DEC 10 1 10K .AC DEC 10 1K 100MEG .AC LIN 100 1 100HZ DEC stands for decade variation, and ND is the number of points per decade. OCT stands for octave variation, and NO is the number of points per octave. LIN stands for linear varia- tion, and NP is the number of points. FSTART is the starting frequency, and FSTOP is the final frequency. If this card is included in the deck, SPICE will perform an ac analysis of the circuit over the specified frequency range. Note that in order for this analysis to be meaningful, at least one independent source must have been specified with an ac value. 9.11. .DISTO Card General form: .DISTO RLOAD >>> Examples: .DISTO RL 2 0.95 1.0E-3 0.75 This card controls whether SPICE will compute the distortion characteristic of the circuit in a small-signal mode as a part of the ac small-signal sinusoidal steady-state analysis. The analysis is performed assuming that one or two signal frequencies are imposed at the input; let the two frequencies be f1 (the nominal analysis frequency) and f2 (=SKW2*f1). The program then computes the following distortion measures: HD2 - the magnitude of the frequency component 2*f1 assuming that f2 is not present. HD3 - the magnitude of the frequency component 3*f1 assuming that f2 is not present. SIM2 - the magnitude of the frequency component f1 + f2. DIM2 - the magnitude of the frequency component f1 - f2. DIM3 - the magnitude of the frequency component 2*f1 - f2. RLOAD is the name of the output load resistor into which all distortion power products are to be computed. INTER is the interval at which the summary printout of the contributions of all nonlinear devices to the total distortion is to be printed. If omitted or set to zero, no summary printout will be made. REFPWR is the reference power level used in computing the distor- tion products; if omitted, a value of 1 mW (that is, dbm) is used. SKW2 is the ratio of f2 to f1. If omitted, a value of 0.9 is used (i.e., f2 = 0.9*f1). SPW2 is the amplitude of f2. If omitted, a value of 1.0 is assumed. The distortion measures HD2, HD3, SIM2, DIM2, and DIM3 may also be be printed and/or plotted (see the description of the .PRINT and .PLOT cards). 9.12. .NOISE Card General form: .NOISE OUTV INSRC NUMS Examples: .NOISE V(5) VIN 10 This card controls the noise analysis of the circuit. The noise analysis is performed in conjunction with the ac analysis (see .AC card). OUTV is an output voltage which defines the sum- ming point. INSRC is the name of the independent voltage or current source which is the noise input reference. NUMS is the summary interval. SPICE will compute the equivalent output noise at the specified output as well as the equivalent input noise at the specified input. In addition, the contributions of every noise generator in the circuit will be printed at every NUMS fre- quency points (the summary interval). If NUMS is zero, no sum- mary printout will be made. The output noise and the equivalent input noise may also be printed and/or plotted (see the description of the .PRINT and .PLOT cards). 9.13. .TRAN Card General form: .TRAN TSTEP TSTOP > Examples: .TRAN 1NS 100NS .TRAN 1NS 1000NS 500NS .TRAN 10NS 1US UIC TSTEP is the printing or plotting increment for line-printer output. For use with the post-processor, TSTEP is the suggested computing increment. TSTOP is the final time, and TSTART is the initial time. If TSTART is omitted, it is assumed to be zero. The transient analysis always begins at time zero. In the inter- val , the circuit is analyzed (to reach a steady state), but no outputs are stored. In the interval , the circuit is analyzed and outputs are stored. TMAX is the maximum stepsize that SPICE will use (for default, the pro- gram chooses either TSTEP or (TSTOP-TSTART)/50.0, whichever is smaller. TMAX is useful when one wishes to guarantee a computing interval which is smaller than the printer increment, TSTEP. UIC (use initial conditions) is an optional keyword which indicates that the user does not want SPICE to solve for the quiescent operating point before beginning the transient analysis. If this keyword is specified, SPICE uses the values specified using IC=... on the various elements as the initial transient condition and proceeds with the analysis. If the .IC card has been specified, then the node voltages on the .IC card are used to compute the intitial conditions for the devices. Look at the description on the .IC card for its interpretation when UIC is not specified. 9.14. .FOUR Card General form: .FOUR FREQ OV1 Examples: .FOUR 100K V(5) This card controls whether SPICE performs a Fourier analysis as a part of the transient analysis. FREQ is the fundamental frequency, and OV1, ..., are the output variables for which the analysis is desired. The Fourier analysis is performed over the interval , where TSTOP is the final time specified for the transient analysis, and period is one period of the fundamental frequency. The dc component and the first nine components are determined. For maximum accuracy, TMAX (see the .TRAN card) should be set to period/100.0 (or less for very high-Q circuits). 9.15. .PRINT Cards General form: .PRINT PRTYPE OV1 Examples: .PRINT TRAN V(4) I(VIN) .PRINT AC VM(4,2) VR(7) VP(8,3) .PRINT DC V(2) I(VSRC) V(23,17) .PRINT NOISE INOISE .PRINT DISTO HD3 SIM2(DB) This card defines the contents of a tabular listing of one to eight output variables. PRTYPE is the type of the analysis (DC, AC, TRAN, NOISE, or DISTO) for which the specified outputs are desired. The form for voltage or current output variables is as follows: V(N1<,N2>) specifies the voltage difference between nodes N1 and N2. If N2 (and the preceding comma) is omitted, ground (0) is assumed. For the ac analysis, five additional outputs can be accessed by replacing the letter V by: VR - real part VI - imaginary part VM - magnitude VP - phase VDB - 20*log10(magnitude) I(VXXXXXXX) specifies the current flowing in the independent vol- tage source named VXXXXXXX. Positive current flows from the positive node, through the source, to the negative node. For the ac analysis, the corresponding replacements for the letter I may be made in the same way as described for voltage outputs. Output variables for the noise and distortion analyses have a different general form from that of the other analyses, i.e. OV<(X)> where OV is any of ONOISE (output noise), INOISE (equivalent input noise), D2, HD3, SIM2, DIM2, or DIM3 (see description of distortion analysis), and X may be any of: R - real part I - imaginary part M - magnitude (default if nothing specified) P - phase DB - 20*log10(magnitude) thus, SIM2 (or SIM2(M)) describes the magnitude of the SIM2 dis- tortion measure, while HD2(R) describes the real part of the HD2 distortion measure. There is no limit on the number of .PRINT cards for each type of analysis. 9.16. .PLOT Cards General form: .PLOT PLTYPE OV1 <(PLO1,PHI1)> ... OV8> Examples: .PLOT DC V(4) V(5) V(1) .PLOT TRAN V(17,5) (2,5) I(VIN) V(17) (1,9) .PLOT AC VM(5) VM(31,24) VDB(5) VP(5) .PLOT DISTO HD2 HD3(R) SIM2 .PLOT TRAN V(5,3) V(4) (0,5) V(7) (0,10) This card defines the contents of one plot of from one to eight output variables. PLTYPE is the type of analysis (DC, AC, TRAN, NOISE, or DISTO) for which the specified outputs are desired. The syntax for the OVI is identical to that for the .PRINT card, described above. The optional plot limits (PLO,PHI) may be specified after any of the output variables. All output variables to the left of a pair of plot limits (PLO,PHI) will be plotted using the same lower and upper plot bounds. If plot limits are not specified, SPICE will automatically determine the minimum and maximum values of all output variables being plotted and scale the plot to fit. More than one scale will be used if the output variable values warrant (i.e., mixing output variables with values which are orders-of-magnitude different still gives readable plots). The overlap of two or more traces on any plot is indicated by the letter X. When more than one output variable appears on the same plot, the first variable specified will be printed as well as plotted. If a printout of all variables is desired, then a companion .PRINT card should be included. There is no limit on the number of .PLOT cards specified for each type of analysis. 10. APPENDIX A: EXAMPLE DATA DECKS 10.1. Circuit 1 The following deck determines the dc operating point and small-signal transfer function of a simple differential pair. In addition, the ac small-signal response is computed over the fre- quency range 1Hz to 100MEGHz. SIMPLE DIFFERENTIAL PAIR VCC 7 0 12 VEE 8 0 -12 VIN 1 0 AC 1 RS1 1 2 1K RS2 6 0 1K Q1 3 2 4 MOD1 Q2 5 6 4 MOD1 RC1 7 3 10K RC2 7 5 10K RE 4 8 10K .MODEL MOD1 NPN BF=50 VAF=50 IS=1.E-12 RB=100 CJC=.5PF TF=.6NS .TF V(5) VIN .AC DEC 10 1 100MEG .PLOT AC VM(5) VP(5) .PRINT AC VM(5) VP(5) .END 10.2. Circuit 2 The following deck computes the output characteristics of a MOS- FET device over the range 0-10V for VDS and 0-5V for VGS. MOS OUTPUT CHARACTERISTICS .OPTIONS NODE NOPAGE VDS 3 0 VGS 2 0 M1 1 2 0 0 MOD1 L=4U W=6U AD=10P AS=10P .MODEL MOD1 NMOS VTO=-2 NSUB=1.0E15 UO=550 * VIDS MEASURES ID, WE COULD HAVE USED VDS, BUT ID WOULD BE NEGATIVE VIDS 3 1 .DC VDS 0 10 .5 VGS 0 5 1 .PRINT DC I(VIDS) V(2) .PLOT DC I(VIDS) .END 10.3. Circuit 3 The following deck determines the dc transfer curve and the transient pulse response of a simple RTL inverter. The input is a pulse from 0 to 5 Volts with delay, rise, and fall times of 2ns and a pulse width of 30ns. The transient interval is 0 to 100ns, with printing to be done every nanosecond. SIMPLE RTL INVERTER VCC 4 0 5 VIN 1 0 PULSE 0 5 2NS 2NS 2NS 30NS RB 1 2 10K Q1 3 2 0 Q1 RC 3 4 1K .PLOT DC V(3) .PLOT TRAN V(3) (0,5) .PRINT TRAN V(3) .MODEL Q1 NPN BF 20 RB 100 TF .1NS CJC 2PF .DC VIN 0 5 0.1 .TRAN 1NS 100NS .END 10.4. Circuit 4 The following deck simulates a four-bit binary adder, using several subcircuits to describe various pieces of the overall circuit. ADDER - 4 BIT ALL-NAND-GATE BINARY ADDER *** SUBCIRCUIT DEFINITIONS .SUBCKT NAND 1 2 3 4 * NODES: INPUT(2), OUTPUT, VCC Q1 9 5 1 QMOD D1CLAMP 0 1 DMOD Q2 9 5 2 QMOD D2CLAMP 0 2 DMOD RB 4 5 4K R1 4 6 1.6K Q3 6 9 8 QMOD R2 8 0 1K RC 4 7 130 Q4 7 6 10 QMOD DVBEDROP 10 3 DMOD Q5 3 8 0 QMOD .ENDS NAND .SUBCKT ONEBIT 1 2 3 4 5 6 * NODES: INPUT(2), CARRY-IN, OUTPUT, CARRY-OUT, VCC X1 1 2 7 6 NAND X2 1 7 8 6 NAND X3 2 7 9 6 NAND X4 8 9 10 6 NAND X5 3 10 11 6 NAND X6 3 11 12 6 NAND X7 10 11 13 6 NAND X8 12 13 4 6 NAND X9 11 7 5 6 NAND .ENDS ONEBIT .SUBCKT TWOBIT 1 2 3 4 5 6 7 8 9 * NODES: INPUT - BIT0(2) / BIT1(2), OUTPUT - BIT0 / BIT1, * CARRY-IN, CARRY-OUT, VCC X1 1 2 7 5 10 9 ONEBIT X2 3 4 10 6 8 9 ONEBIT .ENDS TWOBIT .SUBCKT FOURBIT 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 * NODES: INPUT - BIT0(2) / BIT1(2) / BIT2(2) / BIT3(2), * OUTPUT - BIT0 / BIT1 / BIT2 / BIT3, CARRY-IN, CARRY-OUT, VCC X1 1 2 3 4 9 10 13 16 15 TWOBIT X2 5 6 7 8 11 12 16 14 15 TWOBIT .ENDS FOURBIT *** DEFINE NOMINAL CIRCUIT .MODEL DMOD D .MODEL QMOD NPN(BF=75 RB=100 CJE=1PF CJC=3PF) VCC 99 0 DC 5V VIN1A 1 0 PULSE(0 3 0 10NS 10NS 10NS 50NS) VIN1B 2 0 PULSE(0 3 0 10NS 10NS 20NS 100NS) VIN2A 3 0 PULSE(0 3 0 10NS 10NS 40NS 200NS) VIN2B 4 0 PULSE(0 3 0 10NS 10NS 80NS 400NS) VIN3A 5 0 PULSE(0 3 0 10NS 10NS 160NS 800NS) VIN3B 6 0 PULSE(0 3 0 10NS 10NS 320NS 1600NS) VIN4A 7 0 PULSE(0 3 0 10NS 10NS 640NS 3200NS) VIN4B 8 0 PULSE(0 3 0 10NS 10NS 1280NS 6400NS) X1 1 2 3 4 5 6 7 8 9 10 11 12 0 13 99 FOURBIT RBIT0 9 0 1K RBIT1 10 0 1K RBIT2 11 0 1K RBIT3 12 0 1K RCOUT 13 0 1K .PLOT TRAN V(1) V(2) V(3) V(4) V(5) V(6) V(7) V(8) .PLOT TRAN V(9) V(10) V(11) V(12) V(13) .PRINT TRAN V(1) V(2) V(3) V(4) V(5) V(6) V(7) V(8) .PRINT TRAN V(9) V(10) V(11) V(12) V(13) .TRAN 1NS 6400NS .OPTIONS ACCT LIST NODE LIMPTS=6401 .END 10.5. Circuit 5 The following deck simulates a transmission-line inverter. Two transmission-line elements are required since two propagation modes are excited. In the case of a coaxial line, the first line (T1) models the inner conductor with respect to the shield, and the second line (T2) models the shield with respect to the out- side world. TRANSMISSION-LINE INVERTER V1 1 0 PULSE(0 1 0 0.1N) R1 1 2 50 X1 2 0 0 4 TLINE R2 4 0 50 .SUBCKT TLINE 1 2 3 4 T1 1 2 3 4 Z0=50 TD=1.5NS T2 2 0 4 0 Z0=100 TD=1NS .ENDS TLINE .TRAN 0.1NS 20NS .PLOT TRAN V(2) V(4) .END 11. APPENDIX B: NONLINEAR DEPENDENT SOURCES SPICE allows circuits to contain dependent sources charac- terized by any of the four equations i=f(v) v=f(v) i=f(i) v=f(i) where the functions must be polynomials, and the arguments may be multidimensional. The polynomial functions are specified by a set of coefficients p0, p1, ..., pn. Both the number of dimen- sions and the number of coefficients are arbitrary. The meaning of the coefficients depends upon the dimension of the polynomial, as shown in the following examples: Suppose that the function is one-dimensional (that is, a function of one argument). Then the function value fv is deter- mined by the following expression in fa (the function argument): fv = p0 + (p1*fa) + (p2*fa**2) + (p3*fa**3) + (p4*fa**4) + (p5*fa**5) + ... Suppose now that the function is two-dimensional, with argu- ments fa and fb. Then the function value fv is determined by the following expression: fv = p0 + (p1*fa) + (p2*fb) + (p3*fa**2) + (p4*fa*fb) + (p5*fb**2) + (p6*fa**3) + (p7*fa**2*fb) + (p8*fa*fb**2) + (p9*fb**3) + ... Consider now the case of a three-dimensional polynomial function with arguments fa, fb, and fc. Then the function value fv is determined by the following expression: fv = p0 + (p1*fa) + (p2*fb) + (p3*fc) + (p4*fa**2) + (p5*fa*fb) + (p6*fa*fc) + (p7*fb**2) + (p8*fb*fc) + (p9*fc**2) + (p10*fa**3) + (p11*fa**2*fb) + (p12*fa**2*fc) + (p13*fa*fb**2) + (p14*fa*fb*fc) + (p15*fa*fc**2) + (p16*fb**3) + (p17*fb**2*fc) + (p18*fb*fc**2) + (p19*fc**3) + (p20*fa**4) + ... Note: if the polynomial is one-dimensional and exactly one coefficient is specified, then SPICE assumes it to be p1 (and p0 = 0.0), in order to facilitate the input of linear controlled sources. For all four of the dependent sources described below, the initial condition parameter is described as optional. If not specified, SPICE assumes 0 the initial condition for dependent sources is an initial 'guess' for the value of the controlling variable. The program uses this initial condition to obtain the dc operating point of the circuit. After convergence has been obtained, the program continues iterating to obtain the exact value for the controlling variable. Hence, to reduce the compu- tational effort for the dc operating point (or if the polynomial specifies a strong nonlinearity), a value fairly close to the actual controlling variable should be specified for the initial condition. 11.1. Voltage-Controlled Current Sources General form: GXXXXXXX N+ N- NC1+ NC1- ... P0 Examples: G1 1 0 5 3 0 0.1M GR 17 3 17 3 0 1M 1.5M IC=2V GMLT 23 17 POLY(2) 3 5 1 2 0 1M 17M 3.5U IC=2.5, 1.3 N+ and N- are the positive and negative nodes, respectively. Current flow is from the positive node, through the source, to the negative node. POLY(ND) only has to be specified if the source is multi-dimensional (one-dimensional is the default). If specified, ND is the number of dimensions, which must be posi- tive. NC1+, NC1-, ... Are the positive and negative controlling nodes, respectively. One pair of nodes must be specified for each dimension. P0, P1, P2, ..., Pn are the polynomial coefficients. The (optional) initial condition is the initial guess at the value(s) of the controlling voltage(s). If not specified, 0.0 is assumed. The polynomial specifies the source current as a function of the controlling voltage(s). The second example above describes a current source with value I = 1E-3*V(17,3) + 1.5E-3*V(17,3)**2 note that since the source nodes are the same as the controlling nodes, this source actually models a nonlinear resistor. 11.2. Voltage-Controlled Voltage Sources General form: EXXXXXXX N+ N- NC1+ NC1- ... P0 Examples: E1 3 4 21 17 10.5 2.1 1.75 EX 17 0 POLY(3) 13 0 15 0 17 0 0 1 1 1 IC=1.5,2.0,17.35 N+ and N- are the positive and negative nodes, respectively. POLY(ND) only has to be specified if the source is multi- dimensional (one-dimensional is the default). If specified, ND is the number of dimensions, which must be positive. NC1+, NC1-, ... are the positive and negative controlling nodes, respec- tively. One pair of nodes must be specified for each dimension. P0, P1, P2, ..., Pn are the polynomial coefficients. The (optional) initial condition is the initial guess at the value(s) of the controlling voltage(s). If not specified, 0.0 is assumed. The polynomial specifies the source voltage as a function of the controlling voltage(s). The second example above describes a voltage source with value V = V(13,0) + V(15,0) + V(17,0) (in other words, an ideal voltage summer). 11.3. Current-Controlled Current Sources General form: FXXXXXXX N+ N- VN1 P0 Examples: F1 12 10 VCC 1MA 1.3M FXFER 13 20 VSENS 0 1 N+ and N- are the positive and negative nodes, respectively. Current flow is from the positive node, through the source, to the negative node. POLY(ND) only has to be specified if the source is multi-dimensional (one-dimensional is the default). If specified, ND is the number of dimensions, which must be posi- tive. VN1, VN2, ... are the names of voltage sources through which the controlling current flows; one name must be specified for each dimension. The direction of positive controlling current flow is from the positive node, through the source, to the negative node of each voltage source. P0, P1, P2, ..., Pn are the polynomial coefficients. The (optional) initial condi- tion is the initial guess at the value(s) of the controlling current(s) (in Amps). If not specified, 0.0 is assumed. The polynomial specifies the source current as a function of the con- trolling current(s). The first example above describes a current source with value I = 1E-3 + 1.3E-3*I(VCC) 11.4. Current-Controlled Voltage Sources General form: HXXXXXXX N+ N- VN1 P0 Examples: HXY 13 20 POLY(2) VIN1 VIN2 0 0 0 0 1 IC=0.5 1.3 HR 4 17 VX 0 0 1 N+ and N- are the positive and negative nodes, respectively. POLY(ND) only has to be specified if the source is multi- dimensional (one-dimensional is the default). If specified, ND is the number of dimensions, which must be positive. VN1, VN2, ... are the names of voltage sources through which the control- ling current flows; one name must be specified for each dimen- sion. The direction of positive controlling current flow is from the positive node, through the source, to the negative node of each voltage source. P0, P1, P2, ..., Pn are the polynomial coefficients. The (optional) initial condition is the initial guess at the value(s) of the controlling current(s) (in Amps). If not specified, 0.0 is assumed. The polynomial specifies the source voltage as a function of the controlling current(s). The first example above describes a voltage source with value V = I(VIN1)*I(VIN2) 12. APPENDIX D: ALTER STATEMENT AND THE SOURCE-STEPPING METHOD The ALTER statement allows SPICE to run with altered circuit parameters. General form: .ALTER ELEMENT CARDS (DEVICE CARDS, MODEL CARDS) .ALTER (or .END CARD) Examples: R1 1 0 5K VCC 3 0 10 M1 3 2 0 MOD1 L=5U W=2U .MODEL MOD1 NMOS(VTO=1.0 KP=2.0E-5 PHI=0.6 NSUB=2.0E15 TOX=0.1U) .ALTER R1 1 0 3.5K VCC 3 0 12 M1 3 2 0 MOD1 L=10U W=2U .MODEL MOD1 NMOS(VTO=1.2 KP=2.0E-5 PHI=0.6 NSUB=5.0E15 TOX=1.5U) .ALTER M1 3 2 0 MOD1 L=10U W=4U .END This card introduces the element(s), device(s) and model(s) whose parameters are changed during the execution of the input deck. The analyses specified in the deck will start over again with the changed parameters. The .ALTER card with the cards defining the new parameters should be placed just before the .END card. The syntax for the element (device, model) cards is ident- ical to that of the cards with the original parameters. There is no limit on the number of .ALTER cards and the cir- cuit will be re-analyzed as many times as the number of .ALTER cards. Subsequent ALTER operations employ parameters of the pre- vious change. No topological change of the circuit is allowed. The source-stepping method can enhance DC convergence. But it is slower than direct use of the Newton-Raphson method. Therefore it is best used as an alternative to achieve conver- gence of DC operating point when the circuit fails to converge by using the Newton-Raphson method. The source-stepping method is used by SPICE when the variable ITL6 in the .OPTIONS card is set to the iteration limit at each step of the source(s). For example, .OPTIONS ITL6=30 will cause SPICE to use source-stepping method with iteration limit 30 at each step. By default, ITL6 is 0 which means to use the Newton-Raphson method directly.