------------------------------------------------------------------------ SPICEPRM - A Spice preprocessor for parameterized subcircuits (v 0.11) Copyright (C) 1996 Andrew J. Borsa ------------------------------------------------------------------------ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ------------------------------------------------------------------------ Spiceprm was written in the course of moving my engineering activities to the Linux operating system. My previous MSDOS spice package permitted passing parameters to subcircuits. The raw Berkely Spice doesn't. Anyone used to this feature knows the frustration of trying to use a simulator without it. This script is the result of my desperation. It translates a circuit file containing parameterized subcircuits with math expressions into another circuit file meeting raw spice requirements. You then run spice on the translated output file. This is an alpha version. It probably has some bugs I haven't caught. But I have used it in a work environment enough to feel comfortable about releasing it for comments and improvement suggestions. What's So Great About Subcircuits With Parameters? -------------------------------------------------- 1. You can generalize a model once and then use it without having to recalculate values of it's internal elements every time. 2. Many electronic devices can be modelled by using mathematical expressions. The independent variables can be passed to the model as parameters, evaluated in equations, and used to set the behavior of a particular model instance. 3. They save mucho time and minimize human calculation error. Installation ------------ 1. Copy the executable script to an accessible directory. I keep mine in $HOME/bin so it's on my path. 2. Modify the top line if necessary to reflect the path to your Perl interpreter. For ex., #! /usr/bin/perl may have to become #! /usr/local/bin/perl or wherever the perl binary is located. Usage ----- spiceprm infile [outfile] infile: Circuit file name containing parameterized subcircuits. outfile: Transformed file meeting raw spice netlist conventions. Optional. If not given, output is produced on standard output (stdout). My file name convention: infile = *.cir, outfile = *.ckt infile == outfile isn't permitted for a coupla good reasons, the best being you don't want to trash your original source. Now source outfile from spice. I always check the output from a new infile just to make sure. This version only checks for a few obvious errors, so scanning outfile for reasonable looking values and netlist correctness is wise. Note that comment and blank lines are discarded in outfile and alphabetic characters are transformed to lower case. Parameterized Subcircuit Netlist Convention ------------------------------------------- Calling a parameterized subcircuit works similarly to a normal spice call except for the addition of a {} delimited list of parameter value assignments - Xname n1 n2 n3 ... ni subname {p1 = val1 ... pj = valj} p1 thru pj are the parameter assignments to be passed to the subcircuit. val is any valid spice value. {} (braces) must enclose the parameter assignment sequence. After running the preprocessor on this file, each call in the netlist will be replaced by the following - Xname n1 n2 n3 ... ni subname#k *{p1 = val1 ... pj = valj} where k is a digit or digits representing a subcircuit with that specific set of parameter substitutions. k will be incremented for each unique set of parameters and matched by a new .subckt listing named subname#k as follows - .subckt subname#k n1 n2 n3 ... ni ... listing with parameters substituted and equations evaluated .ends Creating Parameterized Subcircuits ---------------------------------- Below is a simple example. See the EXAMPLES file for a number of illustrative and useful models for Spice3. This model creates an RF power source specified using the natural output power units of dBm (dB referenced to 1 milliwatt). Note that the model parameters must be declared on the ".subckt" definition line inside curly braces {}. **************************************************************** * Sine wave RF power source. * Parameters: F = Frequency * R = Output resistance * P = Power in dBm * V = DC (EMF) .SUBCKT RFGEN 1 2 {F R P V} * + - Is 2 1 DC {V/R} SIN {V/R} {sqrt((10**(P/10))/(125*R))} {F} Ro 1 2 {R} .ENDS **************************************************************** Note that independent current source Is has it's literal spice parameters replaced by equations that calculate the required values from the passed parameters. Each equation must be enclosed by {} to inform the preprocessor that a substitution and calculation must be performed for whatever appears between the braces. Equations may span multiple lines by using the spice line continuation symbol "+" as the first character of the following line. .MODEL statements inside subcircuits may also use passed parameters. In fact, anything between {} inside a subcircuit will be evaluated and replaced with a result. Be careful in situations like the following: Bx 3 0 v = {v(1)*sgn(v(2))*frick/frack} WRONG!!! The Spice3 nonlinear source element "B" also accepts equations describing it's output dependency on functions of circuit voltages and currents. If "frick" and "frack" are parameters, you must separate them from the element's equation as follows - Bx 3 0 v = v(1)*sgn(v(2))*{frick/frack} Just remember that preprocessor equations and spice functions must never meld. The parameter substitution first replaces all parameters between any {} with their numerical values and then uses Perl's eval() function to produce a final numerical value. Theoretically at least, you could execute a Perl program within those braces. I haven't explored this yet so feel free. Realize though, that whatever's inside the braces gets a ";" appended at the end to make a valid Perl statement from the usual equation. Also, Perl's block delimiters are braces, so extra one's could confuse the current parsing which is simply oriented to equations. Ah well. Known Bugs, Anomalies, and Perl Gotcha's ---------------------------------------- 1. Minimal error checking! Be forewarned! 2. Don't use ".ends subckt_name" with parameters. Use ".ends" only. The preprocessor modifies subckt_name to subckt_name#k. 3. Spice unit representations like "k", "meg", etc, are not recognized inside the {} equation sections of .subckt listings. They may, however, be used in the parameter assignment section of a .subckt call. 4. "-" as part of .subckt name doesn't work but "_" does. Stick to alphanumeric names with optional underscore characters. 5. Equations must use Perl math operators and functions. The following lists operator differences I'm aware of - Exponentiation - Perl : ** Spice3 : ^ Logical AND, OR - Perl : &&, || Spice3 : &, | Equality, Inequality - Perl : ==, != Spice3 : =, <> These operators are the same for Perl and Spice3 - + - * / % ! < > <= >= These operators are unique to Perl - & | ^ ~ : bitwise AND, OR, exclusive OR, complement Perl math functions - abs(EXPR) : absolute value of EXPR atan2(Y,X) : arctangent of Y/X in the range of -pi to +pi cos(EXPR) : cosine of EXPR in radians exp(EXPR) : e raised to EXPR int(EXPR) : integer portion of EXPR log(EXPR) : natural logarithm (base e) of EXPR rand[(EXPR)]: returns a random fractional number between 0 and the value of EXPR. If EXPR is omitted, returns a value between 0 and 1. sin(EXPR) : sine of EXPR in radians sqrt(EXPR) : square root of EXPR Finally, if you could make use of a language allowing you to do neat things like this with minimal pain, give Perl a try. It's naturally suited for text processing and transformation tasks like pre and post processors, along with any math manipulation required.