Browse Source

Initial revision

pre-master-46
pnenzi 26 years ago
commit
978f1c32a2
  1. 1
      ANALYSES
  2. 39
      AUTHORS
  3. 31
      COPYING
  4. 107
      ChangeLog
  5. 167
      DEVICES
  6. 299
      FAQ
  7. 153
      INSTALL
  8. 15
      Makefile.am
  9. 108
      NEWS
  10. 162
      README
  11. 24
      acconfig.h
  12. 73
      autogen.sh
  13. 245
      configure.in
  14. 11
      contrib/ChangeLog
  15. 5
      contrib/mslib/COPYING
  16. 87
      contrib/mslib/datadef.h
  17. 93
      contrib/mslib/inc_LSD.c
  18. 199
      contrib/mslib/inc_inp.c
  19. 208
      contrib/mslib/inc_main.c
  20. 12
      contrib/mslib/makefile
  21. 35
      contrib/mslib/mslib_readme
  22. 5
      contrib/scripts/COPYING
  23. 77
      contrib/scripts/liblook
  24. 9
      contrib/scripts/liblook_readme
  25. 58
      contrib/scripts/libprm
  26. 14
      contrib/scripts/libprm_readme
  27. 18
      contrib/spiceprm/CHANGES
  28. 339
      contrib/spiceprm/COPYING
  29. 176
      contrib/spiceprm/EXAMPLES
  30. 216
      contrib/spiceprm/README
  31. 304
      contrib/spiceprm/spiceprm
  32. 19
      contrib/spiceprm/spiceprm-0.11.lsm
  33. 11
      doc/ChangeLog
  34. 11
      doc/Makefile.am
  35. 8496
      doc/ngspice.texi
  36. 5951
      doc/texinfo.tex
  37. 5
      man/Makefile.am
  38. 8
      man/man1/Makefile.am
  39. 1051
      man/man1/nutmeg.1
  40. 127
      man/man1/sconvert.1
  41. 325
      man/man1/spice.1
  42. 164
      notes/Linux.changes
  43. 7
      notes/dbx
  44. 98
      notes/internal
  45. 207
      notes/mac_port
  46. 237
      notes/porting
  47. 15
      notes/spice2
  48. 97
      src/ChangeLog
  49. 162
      src/Makefile.am
  50. 60
      src/analysis/ChangeLog
  51. 106
      src/analysis/Makefile.am
  52. 277
      src/analysis/acan.c
  53. 63
      src/analysis/acaskq.c
  54. 105
      src/analysis/acsetp.c
  55. 130
      src/analysis/ckt.h
  56. 47
      src/analysis/cktaccpt.c
  57. 142
      src/analysis/cktacct.c
  58. 43
      src/analysis/cktacdum.c
  59. 45
      src/analysis/cktask.c
  60. 25
      src/analysis/cktaskaq.c
  61. 43
      src/analysis/cktasknq.c
  62. 54
      src/analysis/cktbindn.c
  63. 25
      src/analysis/cktbkdum.c
  64. 39
      src/analysis/cktclrbk.c
  65. 47
      src/analysis/cktcrte.c
  66. 27
      src/analysis/cktdelt.c
  67. 61
      src/analysis/cktdest.c
  68. 177
      src/analysis/cktdisto.c
  69. 25
      src/analysis/cktdlti.c
  70. 45
      src/analysis/cktdltm.c
  71. 59
      src/analysis/cktdltn.c
  72. 146
      src/analysis/cktdojob.c
  73. 29
      src/analysis/cktdump.c
  74. 36
      src/analysis/cktfbran.c
  75. 86
      src/analysis/cktfdev.c
  76. 36
      src/analysis/cktfnda.c
  77. 53
      src/analysis/cktfndm.c
  78. 33
      src/analysis/cktfnode.c
  79. 25
      src/analysis/cktftask.c
  80. 46
      src/analysis/cktgrnd.c
  81. 66
      src/analysis/ckti2nod.c
  82. 57
      src/analysis/cktic.c
  83. 66
      src/analysis/cktinit.c
  84. 36
      src/analysis/cktlnkeq.c
  85. 166
      src/analysis/cktload.c
  86. 51
      src/analysis/cktmapn.c
  87. 30
      src/analysis/cktmask.c
  88. 45
      src/analysis/cktmcrt.c
  89. 45
      src/analysis/cktmkcur.c
  90. 32
      src/analysis/cktmknod.c
  91. 43
      src/analysis/cktmkvol.c
  92. 32
      src/analysis/cktmpar.c
  93. 45
      src/analysis/cktnames.c
  94. 34
      src/analysis/cktnewan.c
  95. 38
      src/analysis/cktneweq.c
  96. 45
      src/analysis/cktnewn.c
  97. 33
      src/analysis/cktnodn.c
  98. 140
      src/analysis/cktnoise.c
  99. 56
      src/analysis/cktntask.c
  100. 32
      src/analysis/cktnum2n.c

1
ANALYSES

@ -0,0 +1 @@
This file will contain a list of implemented analyses.

39
AUTHORS

@ -0,0 +1,39 @@
SPICE was originally written at The University of Berkeley (USA).
Contributors:
-------------
Giles C. Billingsley
Mansun Chan
Wayne A. Christopher
Noah Friedman <friedman@prep.ai.mit.edu>
David A. Gates
JianHui Huang
Jeffrey M. Hsu
S. Hwang
Gordon M. Jacobs
Min-Chie Jeng
Kenneth H. Keller
Mathew Lew
Weidong Liu
Gary W. Ng
Hong June Park
Thomas L. Quarles
Jaijeet S. Roychowdhury
Takayasu Sakurai
Kanwar Jit Singh
Andrew Tuckey <Tuckey@ieee.org>
NGSPICE is now actively hacked by:
* Glao S. Dezai <dezai@hotbot.com>
* Daniele Foci <d.foci@ieee.ing.uniroma1.it>
* Chris Inbody <cinbody@cowtown.net>
* Paolo Nenzi <pnenzi@ieee.ing.uniroma1.it>
* Arno Peters <A.W.Peters@ieee.org>
* Serban-Mihai Popescu <serbanp@ix.netcom.com>
* Emmanuel Rouat <emmanuel.rouat@wanadoo.fr>
* Michael Widlok <widlok@uci.agh.edu.pl>
(and many others...)

31
COPYING

@ -0,0 +1,31 @@
(The original copyright for Spice3f5.)
Copyright (C) 1996 The Regents of the University of California.
All Rights Reserved.
Permission to use, copy, modify, and distribute this software and its
documentation for educational, research and non-profit purposes,
without fee, and without a written agreement is hereby granted,
provided that the above copyright notice, this paragraph and the
following three paragraphs appear in all copies.
This software program and documentation are copyrighted by The Regents
of the University of California. The software program and
documentation are supplied "as is", without any accompanying services
from The Regents. The Regents does not warrant that the operation of
the program will be uninterrupted or error-free. The end-user
understands that the program was developed for research purposes and
is advised not to rely exclusively on the program for any reason.
IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES,
INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND
ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THE UNIVERSITY OF
CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS"
BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE
MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

107
ChangeLog

@ -0,0 +1,107 @@
1999-12-07 Arno Peters <A.W.Peters@ieee.org>
* source tree: Added MAINTAINERCLEANFILES to Makefile.am to
eliminate automatically generated cruft from patches. To create a
minimal patch between two trees, just do `make maintainer-clean'
on both trees and run `diff -ruN tree1 tree2'.
1999-10-15 Emmanuel Rouat <emmanuel.rouat@wanadoo.fr>
* source tree: entirely modified by Arno Peters (after discussion
on the mailing list)
1999-09-06 Emmanuel Rouat <emmanuel.rouat@wanadoo.fr>
* AUTHORS: added list provided by Arno Peters
* Applied patch supplied by Arno
1999-09-01 Emmanuel Rouat <emmanuel.rouat@wanadoo.fr>
* AUTHORS: some additions
* FAQ: a few minor corrections
1999-08-31 Emmanuel Rouat <emmanuel.rouat@wanadoo.fr>
* configure.in: config.h now in top directory
* All Makefile.am's: removed useless 'DEFS' line
1999-08-30 Emmanuel Rouat <emmanuel.rouat@wanadoo.fr>
* FAQ: added the FAQ to the distribution
1999-08-28 Emmanuel Rouat <emmanuel.rouat@wanadoo.fr>
* Removed mfb from build - nutmeg doesn't use it on Unix.
1999-08-23 Emmanuel Rouat <emmanuel.rouat@wanadoo.fr>
* configure.in: added tests ('make check')
* ng-spice.patch: added cleanup patch by Arno Peters
1999-08-08 Emmanuel Rouat <emmanuel.rouat@wanadoo.fr>
* configure.in: added some features
1999-08-03 Emmanuel Rouat <emmanuel.rouat@wanadoo.fr>
* configure.in: added a whole bunch of tests!
1999-08-02 Emmanuel Rouat <emmanuel.rouat@wanadoo.fr>
* configure.in: added --with-checkergcc option (experimental!)
added some maths checks
1999-07-31 Emmanuel Rouat <emmanuel.rouat@wanadoo.fr>
* configure.in: made X11 tests more efficient
ng-spice-0.0:
-------------
* changed HAX_X11 define to XMISSING_DISPLAY supplied in config.h
* added 'Changelog' files in all subdirectories
* added '--enable-ansi' option to configure
* put src/lib/dev/devsup.c into src/lib/dev/devsup/
* added header files into Makefile.am's
Chianti:
--------
(27/07/99)
* added some tests to configure.in (ncurses/termcap, xaw....)
* cleaned up some directories (examples, patches..)
* removed all .orig files
Pizza:
------
(25/07/99)
* added installation of man pages
* emptied 'COPYING' file until we know what to put in it
* fixed missing install of help and init files (created tune.c.in
to support this)
* added missing -DWANT_X11 and -DWANT_MFB in several compiles
(fixed some headers in: src/lib/fte/x11.c
src/lib/fte/x11disp.c )
Spaghetti:
----------
(25/07/99)
- first attempt at autoconf/automake support
- based on spice3f5-chili, hardly anything touched on it.

167
DEVICES

@ -0,0 +1,167 @@
DEVICES
-------------------------------------------------------------------------------
This file contains the status of devices available in ng-spice. This file will
be updated every time the device cospecific code is altered/changed.
**************************************
********** Linear devices **********
**************************************
CAP - Capacitor
Initial Release
IND - Inductor
Initial Release
RES - Resistor
This is a modified version of the spice3 resistance model. This model
supports different ac and dc values (ac=...). This changes are
introduced by Serban Popescu. This device needs more testing.
TO BE TESTED AND IMPROVED.
**************************************
******** Distributed elements ********
**************************************
TRA - Transmission line
Initial release
LTRA - Lossy Transmission line
Initial release
URC - Uniform distributed RC line
Initial release
**************************************
********** V/I Sources **********
**************************************
ASRC - Arbitrary Source
Initial Release
CCCS - Current Controlled Current Source
Initial Release
CCVS - Current Controlled Voltage Source
Initial Release
ISRC - Independent Current Source
Initial Release
VCCS - Voltage Controlled Current Source
Initial Release
VCVS - Voltage Controlled Voltage Source
Initial Release
VSRC - Indipendent Voltage Source
Initial Release
**************************************
********* Switches **********
**************************************
CSW - Current controlled switch
Initial release
SW - Voltage controlled switch
Initial release
**************************************
********** Diodes **********
**************************************
DIO - Junction Diode
Initial Release
**************************************
*********** Bipolar Devices **********
**************************************
BJT - Bipolar Junction Transistor
Initial Relelase
**************************************
********** FET Devices **********
**************************************
JFET - Junction Field Effect transistor
Initial Release
JFET2 - Jfet PS model
Initial release. TO BE TESTED
**************************************
********* MES devices *********
**************************************
MES - MESfet model
Initial release
**************************************
********* MOS devices *********
**************************************
MOS1 - Level 1 MOS model
Initial Release
MOS2 - Level 2 MOS model
Initial Release
MOS3 - Level 3 MOS model
Initial Release
MOS6 - Level 6 MOS model
Initial Release
BSIM1 - BSIM model level 1
Initial Release
BSIM2 - BSIM model level 2
Initial Release
BSIM3 - BSIM model level 3
This is the BSIM3v3.2.2 model from Berkeley device group.
You can find some test netlists with results for this model
at http://www-device.eecs.berkeley.edu/~bsim3.
BSIM3v1 - BSIM model level 3
This is the BSIM3v3.1 model modified by Serban Popescu. This
is level 49 model. It is an implementation that supports
HDIF and M parameters. Test netlists are available at the URL
above.
TO BE TESTED AND IMPROVED.
BSIM3v2 - BSIM model level 3
This is the BSIM3v3.2 model. It is proved only for compatibility
with existing netlists and parameters files. As always, tests are
availabe on the Berkeley's device group site (at the above URL).
BSIM4 - BSIM model level 4 (0.18 um)
Initial Release. TO BE TESTED.
**************************************
********** SOI Devices *********
**************************************
BSIM3SOI_DD - SOI model (dynamic depletion)
NOT YET IMPLEMENTED.
BSIM3SOI_FD - SOI model (fully depleted devices)
NOT YET IMPLEMENTED.
BSIM3SOI_PD - SOI model (partially depleted devices)
NOT YET IMPLEMENTED.

299
FAQ

@ -0,0 +1,299 @@
NG-Spice F.A.Q.
Frequently Asked Questions
(and Answers)
Maintened by Daniele Foci <d.foci@ieee.ing.uniroma1.it>
Last update: 29/08/1999
CONTENTS
1. INTRODUCTION AND GENERAL INFORMATION
1.1 What is NG-Spice?
1.2 Why resurrecting Berkeley's Spice?
1.3 What is the project's goal?
1.4 What you are going to do ?
1.5 Legal issues
1.6 What mailing lists exist for NG-Spice?
1.7 Are the mailing lists archived anywhere?
1.8 What newsgroups exist for NG-Spice?
1.9 Where can I get a copy of NG-Spice?
1.10 Where should I look on the World Wide Web for NG-Spice stuff?
2. DEVELOPMENT
2.1 What is the current version?
2.2 What are the latest features in the current release?
2.3 What does it look like ?
2.4 Who are the authors of ng-spice ?
2.5 How can I report a bug/request for a feature?
2.6 How can I join the development?
3. SOLUTIONS TO COMMON MISCELLANEOUS PROBLEMS
3.1 What systems are supported?
3.2 I get errors when I try to compile the source code, why?
3.3 This document didn't answer my question. Where else can I look for
an answer?
4. ADMINISTRATIVE INFORMATION AND ACKNOWLEDGEMENTS
4.1 Feedback
4.2 Formats in which this FAQ is available
4.3 Authorship and acknowledgements
4.4 Disclaimer and Copyright
-------------------------------------------------------------------------------
1. INTRODUCTION AND GENERAL INFORMATION
1.1 What is NG-Spice?
NG-spice is the name of a project and of a program in the project. Spice is
the famous circuit simulator developed by the CAD Group of the University
of California at Berkeley (UCB). The NG prefix has a lot of meanings: Next
Generation, New Good, etc. Choose or invent the one you prefer. The NG-spice
project aims to improve the capabilities of the Spice3 circuit simulator.
The heart of the project is the ng-spice program, a circuit simulator
derived from spice3f5.
1.2 Why resurrecting Berkeley's Spice?
Berkeley's Spice can be considered the father of most circuit simulators
available today. It is an old but still good piece of software, it may not
be the fastest or the most reliable but it's free, it's available in
source code and most of the electrical simulators inherited it's syntax.
On the more technical side, spice3 uses good numerical algorithms
( most commercial implementations have only strengthened them), implements
most of the models for MOSFET submicron designs and has a powerful set of
analyses. On the more "social" side, spice3 it's well introduced in the
academic environment.
1.3 What is the project's goal?
The final goal of NG-spice project is to develop a reliable, fast and
friendly circuit simulator for mixed signal/mixed level simulation.
Easy isn't it ;-).
1.4 What you are going to do?
The NG-spice project is divided in two main overlapping phases. The first
phase is strictly pertinent to the spice3f5 code: during this phase the
original spice3f5 code will be "cleaned" and corrected and small improvements
made to it. In phase one the Autoconf interface will replace the Berkeley's
one and this will lead to a different structure of the sources.
The second phase is the development of improvements in the ngspice code
(the old spice3f5 code cleaned and corrected) and of some programs that will
interface with it, like a schematic editor and a waveform viewer. A list of
proposed improvements follows:
1) The framework (or Graphic User Interface):
Spice is (and should continue to be) a command line or a text tool, but
this makes very difficult to design large circuits. To overcome this
difficulty, a schematic entry tool and a waveform viewer tools are needed.
Nevertheless, there are other tools that can be useful: a parts database,
an editor which higlights the syntax, a symbol editor, etc.
Most of these program already exists in the open source world, so they
need only to be integrated in a common EDA environment.
2) Documentation:
Commercial simulators have very good manuals with tutorials, models
equations explained, example of use, suggestions, etc. This line of
development has the task of providing the final spice user with an ordered
and comprehensive set of information on the program and its features.
The documentation should be useful for the student as well as for the
circuit professional.
3) Improvements to the Spice code:
This is the hard part. The target of this direction is to make ngspice a
commercial grade simulator. This means improving it's speed, its
numerical strenght, include the latest models available and some other
important features:
* Numerical Algorithms:
- More stable algorithms for integration (as Runge-Kutta Methods).
- Better convergence in Operating Point Calculation replacing the
Newton-Raphson algorithm, a modified version of Fixed-Point
Homotopy.
* Devices:
- Behavioral device: enhance the B device of spice3 to accepts IF THEN
ELSE conditions, and digital keywords like DELAY,
HIGHV, LOWV, etc. to simulate simple digital
device.
- Dynamically Loadable Devices: reduce the memory occupied by the
simulator by using shared object code
for devices. Each device is a .so
library that is inserted only if the
circuit contains an element modeled by
the device. If we are simulating CMOS,
we do not need BJT or SOI (in most of
the situations).
- Code Level Modeling: let users write their devices in C and use
them in the simulator.
- Improving device: include additional parameters to some devices as
HDIF, LDIF, etc.
* New types of analysis, oriented to circuits syntesis and optimization:
- Network analysis: given four nodes, extract z,y,s and the other
double bipole paramters.
- Monte Carlo analysis: statistical simulation based on device
tolerances.
- Worst Case analysis: find the worst case of operation of a given
circuit based on device tolerances.
- Parametric analysis: repeat an analysis when one or more parameters
assumes different values.
* Faster handling of sparse matrices.
* Possibility to mesure circuit pameters, like the delay between two
nodes, etc.
* ... whatever else can be judged useful.
1.5 Legal issues
[not written yet: GPL vs. Berkeley]
1.6 What mailing lists exist for NG-Spice?
Only one. Send an empty message to <ng-spice-help@ieee.ing.uniroma1.it> to
have information on subscription.
1.7 Is the mailing lists archived anywhere?
Yes, the list is archived. Send an empty message to
<ng-spice-help@ieee.ing.uniroma1.it> to have information on how to retrieve
old messages.
1.8 What newsgroups exist for NG-Spice?
None. Sorry.
1.9 Where can I get a copy of NG-Spice?
You can download NG-Spice from:
ftp://ieee.ing.uniroma1.it/pub/ng-spice/distribution/
1.10 Where should I look on the World Wide Web for NG-Spice stuff?
There is a WWW page for NG-Spice. The URL is:
http://geda.seul.org under the tools section.
2. DEVELOPMENT
2.1 What is the current version?
0.3 (released on 30/08/1999)
2.2 What are the latest features in the current release?
* New features:
- Autoconf interface.
- BSIM 3.2.2 Model.
- PS jfet Model (jfet level 2).
- Temperature and resistance sweeps.
- "spec" command for spectrum analysis.
* Bug fixes:
- Altermod command connected to the parser.
- Some memory leaks closed.
- Spice3f5 fixes available on the net.
2.3 What does it look like ?
This is a command line utility, no screenshots!
2.4 Who are the authors of ng-spice ?
The development is open to anyone who wish to contribute.
People who contributed are:
* Daniele Foci <d.foci@ieee.ing.uniroma1.it>
* Paolo Nenzi <pnenzi@ieee.ing.uniroma1.it>
* Arno Peters <A.W.Peters@ieee.org>
* Serban-Mihai Popescu <serbanp@ix.netcom.com>
* Emmanuel Rouat <emmanuel.rouat@wanadoo.fr>
* Michael Widlok <widlok@uci.agh.edu.pl>
This list is surely incomplete (due to open development group), there are
many people who contributed with improvements, pieces of code, bux fixes,
etc. If you have contributed and do not appear, write to:
ng-spice@ieee.ing.uniroma1.it
and ask to be included.
2.5 How can I report a bug/request for a feature?
Write in the mailing list.
2.6 How can I join the development?
To join the development just code the feature you want to add and send your
patch in the mailing list. Before you start coding check the latest
development release of NG-Spice from our CVS. It might be that your feature
has already been implemented.
To access the anonymous CVS do the following:
1) Install cvs on your machine (version 1.9.x - 1.10.x are just fine).
2) Set one of the following environment variables:
For bash:
export CVSROOT=:pserver:anonymous@ieee.ing.uniroma1.it:/var/services/cvsroot
For csh/tcsh:
setenv CVSROOT :pserver:anonymous@ieee.ing.uniroma1.it:/var/services/cvsroot
3) Login to the cvs server by running:
$> cvs login
The password is 'guest' (without the quotes of course). You will only
have to do this once.
4) Checkout the appropriate files executing the following commands:
$> mkdir somedirectory
$> cd somedirectory
$> cvs co ng-spice
5) Wait for the cvs logout.
3. SOLUTIONS TO COMMON MISCELLANEOUS PROBLEMS
3.1 What systems are supported?
This is the updated list:
Hardware O.S. Compiler Functional?
---------------- ------------------ -------------- -----------
i386 Linux (RedHat) gcc yes
i386 Linux (Debian) gcc yes
i386 Linux (SuSE) gcc yes
IBM Risc 6000 AiX lcc no
SUN Solaris 7 gcc yes
SUN Solaris 7 SUN Workshop ?
3.2 I get errors when I try to compile the source code, why?
[not written yet]
3.3 This document didn't answer my question. Where else can I look for
an answer?
Read old messages from the mailing list archive, search the web site or read
the docs. Upgrade to the latest version of NG-Spice, many problems are fixed
in the new versions. If you still can't find an answer, post your question
to the mailing list.
4. ADMINISTRATIVE INFORMATION AND ACKNOWLEDGEMENTS
4.1 Feedback
Send your comments about this F.A.Q. to <d.foci@ieee.ing.uniroma1.it>.
Send your comments about NG-Spice to <ng-spice@ieee.ing.uniroma1.it>.
4.2 Formats in which this FAQ is available
This document is available only in ASCII format in the NG-Spice source
package.
4.3 Authorship and acknowledgements
Parts of the questions and answers are originate from Paolo Nenzi.
4.4 Disclaimer and Copyright
This document is provided as is. The information in it is not warranted to
be correct: you use it at your own risk.

153
INSTALL

@ -0,0 +1,153 @@
Basic Installation
==================
The autoconf support is still very crude and needs work, but basically
you should be able to do:
./configure
make
make install
(default install dir is /usr/local/bin)
You can use some extra options to 'configure'
--disable-debug : this option will remove the '-g' option passed to the
compiler (speeds up compilation a *lot*)
--enable-ansi : configure will try to find an option for your compiler so
that it expects ansi-C
Do a './configure --help' to get all available options.
Compilers and Options
=====================
Some systems require unusual options for compilation or linking that
the `configure' script does not know about. You can give `configure'
initial values for variables by setting them in the environment. Using
a Bourne-compatible shell, you can do that on the command line like
this:
CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
Or on systems that have the `env' program, you can do it like this:
env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
Compiling For Multiple Architectures
====================================
You can compile the package for more than one kind of computer at the
same time, by placing the object files for each architecture in their
own directory. To do this, you must use a version of `make' that
supports the `VPATH' variable, such as GNU `make'. `cd' to the
directory where you want the object files and executables to go and run
the `configure' script. `configure' automatically checks for the
source code in the directory that `configure' is in and in `..'.
If you have to use a `make' that does not supports the `VPATH'
variable, you have to compile the package for one architecture at a time
in the source code directory. After you have installed the package for
one architecture, use `make distclean' before reconfiguring for another
architecture.
Installation Names
==================
By default, `make install' will install the package's files in
`/usr/local/bin', `/usr/local/man', etc. You can specify an
installation prefix other than `/usr/local' by giving `configure' the
option `--prefix=PATH'.
You can specify separate installation prefixes for
architecture-specific files and architecture-independent files. If you
give `configure' the option `--exec-prefix=PATH', the package will use
PATH as the prefix for installing programs and libraries.
Documentation and other data files will still use the regular prefix.
In addition, if you use an unusual directory layout you can give
options like `--bindir=PATH' to specify different values for particular
kinds of files. Run `configure --help' for a list of the directories
you can set and what kinds of files go in them.
If the package supports it, you can cause programs to be installed
with an extra prefix or suffix on their names by giving `configure' the
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
Optional Features
=================
Some packages pay attention to `--enable-FEATURE' options to
`configure', where FEATURE indicates an optional part of the package.
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
is something like `gnu-as' or `x' (for the X Window System). The
`README' should mention any `--enable-' and `--with-' options that the
package recognizes.
For packages that use the X Window System, `configure' can usually
find the X include and library files automatically, but if it doesn't,
you can use the `configure' options `--x-includes=DIR' and
`--x-libraries=DIR' to specify their locations.
Specifying the System Type
==========================
There may be some features `configure' can not figure out
automatically, but needs to determine by the type of host the package
will run on. Usually `configure' can figure that out, but if it prints
a message saying it can not guess the host type, give it the
`--host=TYPE' option. TYPE can either be a short name for the system
type, such as `sun4', or a canonical name with three fields:
CPU-COMPANY-SYSTEM
See the file `config.sub' for the possible values of each field. If
`config.sub' isn't included in this package, then this package doesn't
need to know the host type.
If you are building compiler tools for cross-compiling, you can also
use the `--target=TYPE' option to select the type of system they will
produce code for and the `--build=TYPE' option to select the type of
system on which you are compiling the package.
Sharing Defaults
================
If you want to set default values for `configure' scripts to share,
you can create a site shell script called `config.site' that gives
default values for variables like `CC', `cache_file', and `prefix'.
`configure' looks for `PREFIX/share/config.site' if it exists, then
`PREFIX/etc/config.site' if it exists. Or, you can set the
`CONFIG_SITE' environment variable to the location of the site script.
A warning: not all `configure' scripts look for a site script.
Operation Controls
==================
`configure' recognizes the following options to control how it
operates.
`--cache-file=FILE'
Use and save the results of the tests in FILE instead of
`./config.cache'. Set FILE to `/dev/null' to disable caching, for
debugging `configure'.
`--help'
Print a summary of the options to `configure', and exit.
`--quiet'
`--silent'
`-q'
Do not print messages saying which checks are being made. To
suppress all normal output, redirect it to `/dev/null' (any error
messages will still be shown).
`--srcdir=DIR'
Look for the package's source code in directory DIR. Usually
`configure' can determine that directory automatically.
`--version'
Print the version of Autoconf used to generate the `configure'
script, and exit.
`configure' also accepts some other, not widely useful, options.

15
Makefile.am

@ -0,0 +1,15 @@
## Process this file with automake to produce Makefile.in
SUBDIRS = doc src man tests
EXTRA_DIST = FAQ acconfig.h autogen.sh notes contrib
MAINTAINERCLEANFILES = Makefile.in aclocal.m4 config.guess \
config.h.in config.sub configure install-sh \
missing mkinstalldirs stamp-h.in ltconfig \
ltmain.sh
mrproper: maintainer-clean
rm -f `find . -type f -name "*~" -print`
rm -f `find . -type f -name "*.orig" -print`
rm -f `find . -type f -name "*.rej" -print`

108
NEWS

@ -0,0 +1,108 @@
Ng-spice-rework-10
============
Added BSIM4 model and closed a couple of serious bugs. Added DEVICES file
to distribution. This file contains the status of device models in this
simulator. Read it, this file can save you a lot of time.
Ng-spice-rework-9
============
Thanks to Arno Peters now all device models are dynamically loaed on demand.
Thay are linked as shared libraries. The next step is the dlopen() one which
will make possible to link devices without any recompilation.
Ng-spice-rework-8
============
Applied Arno's patch.
From his mail message:
Hi Paolo,
I have prepared a source cleaning patch.
Features:
+ patches don't get polluted with differences between automatically
generated Makefile.am files. Usually these make up the biggest part
of the patches. This allows me to read the patch on the mailing
list instead of sifting through 90% redundant and irrelevant changes.
+ the shell script autogen.sh automatically regenerates the required
files if the user has automake, autoconf and libtool installed.
+ this feature is only valuable to developers, not to end users.
Usage of this patch, once incorporated:
# create a working tree to work from
cp -a ng-spice-rework-x ng-spice
[ Changes made to ng-spice ]
# clean up all the automatically generated files
cd ng-spice; make maintainer-clean
# extract the differences
diff -ruN ng-spice-rework-x ng-spice > my.patch
[ Patch sent to ng-spice mailing list or you ]
# incorporate changes into the tree
cd ng-spice-rework-x; patch -p1 < my.patch
# update the automatically generated files
cd ng-spice-rework-x; sh autogen.sh
Ng-spice-rework-7 (22 Mar 2000)
============
Bug fix release
Ng-spice-rework-6 (29 Jan 2000)
============
This porting includes:
1) BSIM3V3.1 model as level 49. This is the version modified by Serban Popescu
which understands the M parameter and implements HDIF.
2) BSIM3V3.2 model al Level 50. This is the standard Berkeley version.
3) Now the resistor model can accepts two differents values for DC and AC
resistance.
Ng-spice-rework-5 and 5_2 (Jan 2000)
============
Internal development release, buggy and not working.
Ng-spice-rework-4 (22/12/99)
============
This porting includes a new feature:
1) dynamically loading of some device code as an experimental feature for
the future GPL simulator. Thanks to Arno Peters and Manu Rouat.
2) Patched the following bug (thanks to Andrew Tuckey for having supplied the
patch).
* Wsw (current controlled switch) in subckt, parsing bug.
* scale factor in arbitrary source.
* bug in noise analisys.
* save segmentation faults.

162
README

@ -0,0 +1,162 @@
README for NGSPICE
------------------
This long message describes what NG-SPICE may become in the (near ?)
future. I used a question mark because, as you will read, most of the
features of ng-spice are found on Hi-quality commercial products and
(which is the true reason) I have no idea on how can be implemented.
** Why resurrecting Berkeley's Spice ?
Berkeley's spice can be considered the father of most circuit simulator
available today. It is an old but still good piece of software. It may not
be the fastest or the most reliable, but it's free, it is available in
source code, and most of the electrical simulators inherited it's syntax.
On the more technical side, spice3f4(5) uses good numerical algorithms
(commercial implementations have only strengthened them), implements most
of the models for MOSFET submicron designs and has a powerful set of
analyses. On the more "social" side: it's weel introduced in the
academic environment.
** What does NG-SPICE mean ?
It stands for Next Generation Spice but that's not the official name of
the projest. This projects still lacks a name. NG-SPICE is a temporary
name.
** What will NG-SPICE be ?
Berkeley's Spice lacks in three directions:
a) Graphical user interface (I prefer to say "the framework").
b) Documentation.
c) Features in the code.
* The framework:
Spice is (and should continue to be) acommand line or a text tool, but
this makes very difficult to design large circuits. To overcome this
difficulty, a schematic entry tool and a waveform viewer tool are
needed. Nevertheless, there are other tools that can be useful:
a parts database, an editor which higlights the syntax, a symbol
editor, etc. Most of these program already exists in the open source
world, so they need ony to be integrated in a common EDA environment.
This is the first direction of development.
* Documentation: Commercial simulators (hi-end) have very good manuals
with tutorials, models equation explained, example of use, suggestions,
etc. This line of development has the task of provinding the final
spice user with an orderd and comprehensive set of information on the
program and it's features. The documentation should be useful for the
student as well as for the circuit professional.
* Improvements to the spice code: This is the hard part. Th target of
this direction is to make ng-spice a commercial grade simulator. This
means improving it's speed, it's numerical robustness, include the
latest models available and some other important features. I will
describe some of them briefly:
- Analyses -
Network analisys: given four nodes, extract z,y,s and the other
double bipole paramters.
Monte Carlo analisys: statistical simulation based on device
tolerances.
Worst Case analisys: find the worst case of operation of a given
circuit based on device tolerances.
Parametric analisys: repeat an analysis when one or more parameters
assumes different values.
- Devices -
Behavioral device: enhance the B device of spice3 to accepts IF THEN
ELSE conditions, and digital keywords like DELAY, HIGHV. LOWV, etc to
simulate simple digital device.
Dynamically loading of device: reduce the memory occupied by the
simulator by using shared object code for devices. Each device
is a .so library that is inserted only if the circuit contains
an element modeled by the device. If we are simulating CMOS,
we do not need BJT or SOI (in most of the situations).
Code Level Modeling: Let users write their devices in C and use
them in the simulator. I have discovered a couple of standars
for doing this at the Sematech ftp site.
Improving device: Include additional parameters to some devices:
HDIF, LDIF, etc. (Serban, can you explain better).
- Numerical Algs -
Integration: include (if necessary) more stable algorithms for
integration. Runge-Kutta Methods ?
Linearization:
Are there better algorithms for nonlinear equations the the Newton
raphson ?
- Sparse Matrix -
Faster handling of sparse matrices.
- Options -
Possibility to mesure circuit pameters, like the delay between two
nodes, etc.
... and others that will emerge during the project.
Paolo Nenzi (pnenzi@ieee.ing.uniroma.it)
NOTES:
------
This version builds correctly on redhat linux 6.0, and most probably
on any glibc2-based linux distribution. The executables have hardly been
tested, all I know is that they build. The main goal of this release is
to get autoconf to work.
The goal is to put all possible configurations flags into the autoconf support.
It should build on most other unices (especially POSIX ones), please report to me
if it does, or if you know how to fix it if it doesn't.
As the -Wall flag is turned on during compilation, you will notice a HUGE
amount of warnings - our first job should be to work on those to 'sanitize'
the existing code.
MAILING LISTS:
-------------
There are three mailing lists dedicated to the development of ngspice.
ng-spice@ieee.ing.uniroma1.it: This list is the list for the users of the
ng-spice simulator.
ng-spice-devel@ieee.ing.uniroma1.it: ng-spice development issues.
ng-spice-frontends@ieee.ing.uniroma1.it: issues related to development of
frontends for ng-spice.
To subscribe the list(s), send a message to:
<ng-spice-subscribe@ieee.ing.uniroma1.it>
<ng-spice-devel-subscribe@ieee.ing.uniroma1.it>
<ng-spice-frontends-subscribe@ieee.ing.uniroma1.it>
WEB SITE:
--------
This project is hosted on the IEEE Central & South Italy Section Server.
The home page is http://ieee.ing.uniroma1.it/ngspice
Manu (emmanuel.rouat@wanadoo.fr)
Paolo (p.nenzi@ieee.org)

24
acconfig.h

@ -0,0 +1,24 @@
/* Define the location of NGSPICEDATADIR */
#define NGSPICEDATADIR none
/* Define the location of NGSPICEBINDIR */
#define NGSPICEBINDIR none
/* Define the build date */
#define NGSPICEBUILDDATE none
/* Define if we have termcap */
#undef HAVE_TERMCAP
/* Define if we want NOBYPASS */
#undef NOBYPASS
/* Define if we want predictor algorithm */
#undef PREDICTOR
/* Define if we want spice2 sensitivity analysis */
#undef WANT_SENSE2
/* Define if we want some experimental code */
#undef EXPERIMENTAL_CODE

73
autogen.sh

@ -0,0 +1,73 @@
#!/bin/sh
# Run this to generate all the initial makefiles, etc.
PROJECT=ng-spice
TEST_TYPE=-d
FILE=src/circuit
DIE=0
(autoconf --version) < /dev/null > /dev/null 2>&1 || {
echo
echo "You must have autoconf installed to compile $PROJECT."
echo "Download the appropriate package for your distribution,"
echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/"
DIE=1
}
(libtool --version) < /dev/null > /dev/null 2>&1 || {
echo
echo "You must have libtool installed to compile $PROJECT."
echo "Get ftp://alpha.gnu.org/gnu/libtool-1.0h.tar.gz"
echo "(or a newer version if it is available)"
DIE=1
}
(automake --version) < /dev/null > /dev/null 2>&1 || {
echo
echo "You must have automake installed to compile $PROJECT."
echo "Get ftp://ftp.cygnus.com/pub/home/tromey/automake-1.2d.tar.gz"
echo "(or a newer version if it is available)"
DIE=1
}
if test "$DIE" -eq 1; then
exit 1
fi
test $TEST_TYPE $FILE || {
echo "You must run this script in the top-level $PROJECT directory"
exit 1
}
if test -z "$*"; then
echo "I am going to run ./configure with no arguments - if you wish "
echo "to pass any to it, please specify them on the $0 command line."
fi
case $CC in
*lcc | *lcc\ *) am_opt=--include-deps;;
esac
#echo "Running gettextize... Ignore non-fatal messages."
# Hmm, we specify --force here, since otherwise things don't
# get added reliably, but we don't want to overwrite intl
# while making dist.
#echo "no" | gettextize --copy --force
echo "Running libtoolize"
libtoolize --copy --force
aclocal $ACLOCAL_FLAGS
# optionally feature autoheader
(autoheader --version) < /dev/null > /dev/null 2>&1 && autoheader
automake -c -a $am_opt
autoconf
./configure "$@"
echo
echo "Now type 'make' to compile $PROJECT."

245
configure.in

@ -0,0 +1,245 @@
dnl Process this file with autoconf to produce a configure script.
AC_INIT(src/main.c)
dnl Create a configuration header
AM_CONFIG_HEADER(config.h)
dnl --enable-ansi : try to force --ansi option to the compiler
AC_ARG_ENABLE(ansi,
[ --enable-ansi Force --ansi option for compilation])
dnl --disable-debug : remove -g and -Wall option to the compiler
AC_ARG_ENABLE(debug,
[ --enable-debug Add -g option for compilation (default)])
dnl --enable-checker : add --with-checker-debug option to the compiler
AC_ARG_ENABLE(checker,
[ --enable-checkergcc Option for compilation with checkergcc])
dnl --enable-bypass : define BYPASS for the code
AC_ARG_ENABLE(nobypass,
[ --enable-nobypass Don't bypass recalculations of slowly changing variables])
dnl --enable-predictor : define PREDICTOR for the code
AC_ARG_ENABLE(predictor,
[ --enable-predictor Enables a predictor method for convergence])
dnl --enable-sense2 : define HAVE_SENSE2 for the code
AC_ARG_ENABLE(sense2,
[ --enable-sense2 Use spice2 sensitivity analysis])
dnl --enable-experimental : define EXPERIMENTAL_CODE for the code
AC_ARG_ENABLE(experimental,
[ --enable-experimental Enables some experimental code])
dnl Initialize automake stuff
AM_INIT_AUTOMAKE(ng-spice-rework,10)
dnl Enable maintainer commands only if requested
AM_MAINTAINER_MODE
dnl Work on compiler options according to system:
dnl Set default CFLAG - only use -Wall if we have gcc
AC_PROG_CC
if test "x$GCC" = "xyes"; then
CFLAGS="$CFLAGS -Wall "
fi
if test "$enable_debug" = "no"; then
AC_MSG_WARN(Removing debugging option!)
CFLAGS=" "
fi
dnl Not sure that this will work....
if test "$with_checkergcc" = "yes"; then
CC="checkergcc"
fi
dnl Checks for ANSI-C header files.
AC_HEADER_STDC
if test "$enable_ansi" = "yes"; then
AM_PROG_CC_STDC
if test ! "$am_cv_prog_cc_stdc"="yes"; then
AC_MSG_WARN(Failed to find Ansi flag!)
fi
fi
dnl Chech system we're on , and tune accordingly
AC_CANONICAL_HOST
case "$host" in
*bsd* ) CFLAGS="$CFLAGS";;
*linux*) CFLAGS="$CFLAGS";;
*rs6000* ) CFLAGS="$CFLAGS";;
*sgi* ) CFLAGS="$CFLAGS";;
*sun* ) CFLAGS="$CFLAGS";;
*ultrix* ) CFLAGS="$CFLAGS";;
esac
dnl Checks for programs
AC_LIBTOOL_DLOPEN
AM_PROG_LIBTOOL
dnl Checks for X11 header files and libraries - X11 support can be disabled
dnl by passing the '--without-x' option to configure:
AC_PATH_X
AC_PATH_XTRA
dnl Checks for X libraries - if X11 wasn't found then don't make following
dnl tests and compile without X11 support - otherwise, check if the following
dnl libraries are present (error if they are not)
if test ! "$no_x" = "yes" ; then
X_LIBS="$X_LIBS -lX11 -lXt"
AC_CHECK_LIB(Xext, XShmAttach,X_LIBS="$X_LIBS -lXext",AC_MSG_ERROR(Couldn't find Xext librairies), $X_LIBS $X_EXTRA_LIBS)
AC_CHECK_LIB(Xaw,main,X_LIBS="$X_LIBS -lXaw",AC_MSG_ERROR(Couldn't find Xaw librairies),$X_LIBS $X_EXTRA_LIBS)
AC_CHECK_LIB(Xmu,main,X_LIBS="$X_LIBS -lXmu",AC_MSG_ERROR(Couldn't find Xmu librairies), $X_LIBS $X_EXTRA_LIBS)
fi
dnl Check for a few typdefs:
AC_TYPE_PID_T
AC_TYPE_SIGNAL
dnl Check for a few libraries and headers:
dnl Look for ncurses first, then termcap
AC_SEARCH_LIBS(tputs,ncurses termcap,AC_DEFINE(HAVE_TERMCAP),
AC_MSG_ERROR(Found neither ncurses or termcap))
AC_HEADER_DIRENT
AC_CHECK_HEADERS(ctype.h unistd.h pwd.h fcntl.h)
AC_HEADER_SYS_WAIT
AC_HEADER_STAT
dnl Check time and ressources headers and functions:
AC_HEADER_TIME
AC_STRUCT_TM
AC_STRUCT_TIMEZONE
AC_CHECK_FUNCS(localtime)
AC_CHECK_FUNCS(gettimeofday time ftime , break)
AC_CHECK_FUNCS(getrusage utimes, break)
AC_CHECK_FUNCS(getrlimit ulimit, break)
dnl Look for termios first (posix)
AC_CHECK_HEADERS(termios.h termio.h sgtty.h , break)
AC_CHECK_FUNCS(isatty)
dnl Check for a few functions:
AC_FUNC_VFORK
AC_CHECK_FUNCS(access bcopy qsort dup2 popen)
AC_CHECK_FUNCS(strchr index , break)
AC_CHECK_FUNCS(getcwd getwd , break)
AC_MSG_RESULT(Checking mathematical features of the system:)
dnl Look for math library:
AC_CHECK_LIB(m,sqrt)
AC_CHECK_HEADERS(float.h limits.h values.h)
dnl Check for a few mathematical functions:
AC_CHECK_FUNCS(erfc logb scalb scalbn asinh acosh atanh)
# Expand the prefix variable (this is really annoying!)
if eval "test x$prefix = xNONE"; then
dprefix=$ac_default_prefix
else
dprefix=$prefix
fi
AC_DEFINE_UNQUOTED(NGSPICEBINDIR, "`echo $dprefix/bin`" )
AC_DEFINE_UNQUOTED(NGSPICEDATADIR, "`echo $dprefix/share/ng-spice`" )
AC_DEFINE_UNQUOTED(NGSPICEBUILDDATE, "`date`" )
# Recapitulate settings:
AC_MSG_RESULT(Settings which were chosen:)
if test "$enable_sense2" = "yes"; then
AC_DEFINE(WANT_SENSE2)
AC_MSG_RESULT(Spice2 sensitivity analysis enabled)
fi
if test "$enable_nobypass" = "yes"; then
AC_DEFINE(NOBYPASS)
AC_MSG_RESULT(NOBYPASS option enabled)
fi
if test "$enable_predictor" = "yes"; then
AC_DEFINE(PREDICTOR)
AC_MSG_RESULT(PREDICTOR algorithm enabled)
fi
if test "$enable_experimental" = "yes"; then
AC_DEFINE(EXPERIMENTAL_CODE)
AC_MSG_RESULT(EXPERIMENTAL_CODE enabled)
fi
AC_OUTPUT( \
Makefile \
doc/Makefile \
man/Makefile \
man/man1/Makefile \
src/Makefile \
src/analysis/Makefile \
src/circuit/Makefile \
src/devices/Makefile \
src/devices/asrc/Makefile \
src/devices/bjt/Makefile \
src/devices/bsim1/Makefile \
src/devices/bsim2/Makefile \
src/devices/bsim3v1/Makefile \
src/devices/bsim3/Makefile \
src/devices/bsim4/Makefile \
src/devices/bsim3v2/Makefile \
src/devices/cap/Makefile \
src/devices/cccs/Makefile \
src/devices/ccvs/Makefile \
src/devices/csw/Makefile \
src/devices/devsup/Makefile \
src/devices/dio/Makefile \
src/devices/disto/Makefile \
src/devices/ind/Makefile \
src/devices/isrc/Makefile \
src/devices/jfet/Makefile \
src/devices/jfet2/Makefile \
src/devices/ltra/Makefile \
src/devices/mes/Makefile \
src/devices/mos1/Makefile \
src/devices/mos2/Makefile \
src/devices/mos3/Makefile \
src/devices/mos6/Makefile \
src/devices/res/Makefile \
src/devices/sw/Makefile \
src/devices/tra/Makefile \
src/devices/urc/Makefile \
src/devices/vccs/Makefile \
src/devices/vcvs/Makefile \
src/devices/vsrc/Makefile \
src/frontend/Makefile \
src/hlp/Makefile \
src/include/Makefile \
src/maths/Makefile \
src/maths/cmaths/Makefile \
src/maths/ni/Makefile \
src/maths/sparse/Makefile \
src/misc/Makefile \
src/parser/Makefile \
tests/Makefile \
)

11
contrib/ChangeLog

@ -0,0 +1,11 @@
2000-03-22 Paolo Nenzi <p.nenzi@ieee.org>
* mslib: Major update. M. Widlok sent the new version of it's programs.
* spiceprm: Major update. See above line.
1999-09-14 Arno <A.W.Peters@ieee.org>
* mslib: Added.
* spiceprm: Added.

5
contrib/mslib/COPYING

@ -0,0 +1,5 @@
Mslib is free for everyone who think that it might by useful for
him. If someone makes it better please e-mail me.
Michael Widlok
widlok@uci.agh.edu.pl

87
contrib/mslib/datadef.h

@ -0,0 +1,87 @@
/*
* MW. Include for spice
*/
#ifndef DATADEF_INC
#define DATADEF_INC
/*
* Program defaults
*
* *Directory for input file and input libraries
*/
#define DECKPATH "./"
#define LIBPATH "/usr/local/lib/"
/*
* Name for output library file
*/
#define TMPLIBNAME ".lib" /*
* * * * actual name is "deck.TMPLIBNAME"
*/
/*
* Command for libraries, subckts and models declaration
*/
#define LIBINVL "*LIB"
#define SUBINVL "*SUB"
#define MODINVL "*MOD"
/*
* Keywords for subckt start, end and model
*/
#define SUBLINE ".SUBCKT"
#define SUBEND ".ENDS"
#define MODLINE ".MODEL"
#define MODEND
#define LIBMESSAGE "* MW Library include for Spice"
#define BSIZE 255
#define MODDLINE 1
#define SUBDLINE 4
#define LIBDLINE 8
#define SUBLLINE 16
#define MODLLINE 32
#define ENDSLLINE 64
#define CONTLLINE 128
#define NORMLINE 0
#define WRITESUB 0xffff
#define WRITEMOD 0x1111
#define NOWRITE 0x0
#define FAILED 0xffffff
#define SUCCESS 0
#define IS_LIB 0x1
#define LIB_OPEN 0x2
#define IS_MOD 0x10
#define IS_SUB 0x100
#define FINDED 0x400
#define DUPLICATE 0x800
#define DECK_OPEN 0x20000
#define TLIB_OPEN 0x100000
#define NAMEVALID 0xfff
#define NAMENOTV 0x0
struct LSData
{
char name[BSIZE];
FILE *filedes;
int flag;
struct LSData *prevLS;
struct LSData *nextLS;
};
struct LSData *LSinsert(struct LSData *LS, struct LSData *where);
struct LSData *LSclear(struct LSData *LS);
struct LSData *Backfree(struct LSData *LS);
int readdeck(FILE * tdeck, struct LSData *lib, \
struct LSData *sub, struct LSData *mod);
int readlib(struct LSData *lib, FILE * tlib, \
struct LSData *firstSUB, struct LSData *firstMOD);
int checkname(struct LSData *smp, char *name);
#endif

93
contrib/mslib/inc_LSD.c

@ -0,0 +1,93 @@
/*
* MW. Include for spice - LSData functions
*/
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <string.h>
#include "datadef.h"
char *Message = "Michael Widlok, all rights reserved \n"
"mslib - MW include for Spice models/subckts\n";
/*
* Add or cretate new LS structure just after where pointer
*/
struct LSData *
LSinsert(struct LSData *LS, struct LSData *where)
{
if (!(LS))
{
LS = (struct LSData *) malloc(sizeof(struct LSData));
if (!(LS))
{
fprintf(stderr, "LSinsert: Can't allocate LSData srtucture.\n");
exit(FAILED);
}
LS->filedes = NULL;
}
/*
* If where is given we must set nextLS and prevLS correctly
*/
if (where)
{
LS->prevLS = where;
if (LS->nextLS = where->nextLS)
where->nextLS->prevLS = LS;
where->nextLS = LS;
} else
LS->nextLS = LS->prevLS = NULL;
return LS;
}
/*
* Clear all LS list from end. This also closes opened files
*/
struct LSData *
LSclear(struct LSData *LS)
{
while (LS->nextLS)
LS = LS->nextLS;
return Backfree(LS);
}
/*
* Used by LSclear
*/
struct LSData *
Backfree(struct LSData *LS)
{
if (LS->filedes)
fclose(LS->filedes);
return (LS->prevLS) ? Backfree(LS->prevLS) : free(LS), LS;
}
/*
* Check if sub/mod name should by included
*/
int
checkname(struct LSData *smp, char *name)
{
do
{
if (!(strcmp(smp->name, name)))
{
if (smp->flag != FINDED)
{
smp->flag = FINDED;
return NAMEVALID;
} else
{
smp->flag = DUPLICATE;
return NAMEVALID;
}
}
smp = smp->nextLS;
}
while (smp);
return NAMENOTV;
}

199
contrib/mslib/inc_inp.c

@ -0,0 +1,199 @@
/*
* MW. Include for spice
*/
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <string.h>
#include "datadef.h"
static int whatdline(char *tbuf, char *firstname);
static int whatlline(char *tbuf, char *name);
extern int bsizer;
extern char buf[BSIZE];
/*
* Read deck and search for *MOD, *LIB, *SUB commands
*/
int
readdeck(FILE * tdeck, struct LSData *lib, \
struct LSData *sub, struct LSData *mod)
{
char firstname[BSIZE];
char *names, *smlp;
struct LSData *which;
while (fgets(buf, bsizer, tdeck))
{
smlp = buf;
/*
* Ignore control chars at the end of line
*/
do
{
smlp++;
}
while ((!(iscntrl(*smlp))) && (*smlp != '\0'));
*smlp = '\0';
switch (whatdline(buf, firstname))
{
case LIBDLINE:
lib->flag = IS_LIB;
which = lib;
break;
case SUBDLINE:
sub->flag = IS_SUB;
which = sub;
break;
case MODDLINE:
mod->flag = IS_MOD;
which = mod;
break;
default:
which = NULL;
}
/*
* If we finded something
*/
if (which)
{
names = buf;
strsep(&names, " ");
while (smlp = strsep(&names, " "))
{
if (*smlp)
{
which = LSinsert(NULL, which);
strcpy(which->name, smlp);
}
}
}
}
return ((lib->flag != IS_LIB) && (mod->flag != IS_MOD) \
&&(sub->flag != IS_SUB)) ? FAILED : SUCCESS;
}
/*
* Read library and write specififed models/subckts to tmplib
*/
int
readlib(struct LSData *lib, FILE * tlib, \
struct LSData *sub, struct LSData *mod)
{
char name[BSIZE];
int numi, wflag;
numi = 0;
wflag = NOWRITE;
while (fgets(buf, bsizer, lib->filedes))
{
/*
* Now we must check what line is it and if it should be written to tmplib
*/
switch (whatlline(buf, name))
{
case (MODLLINE):
if (wflag == WRITESUB)
fputs(buf, tlib);
else
{
if (mod)
{
if (checkname(mod, name))
{
wflag = WRITEMOD;
numi++;
fprintf(tlib, "* Model: %s, from: %s.\n", \
name, lib->name);
fputs(buf, tlib);
}
}
}
break;
case (SUBLLINE):
if (sub)
{
if (checkname(sub, name))
{
wflag = WRITESUB;
numi++;
fprintf(tlib, "* Subckt: %s, from: %s.\n", \
name, lib->name);
fputs(buf, tlib);
}
}
break;
case (NORMLINE):
if (wflag == WRITEMOD)
{
wflag = NOWRITE;
fputs("\n* End Model.\n\n", tlib);
}
if (wflag == WRITESUB)
fputs(buf, tlib);
break;
case (ENDSLLINE):
if (wflag == WRITESUB)
{
fprintf(tlib, "%s\n* End Subckt\n\n", buf);
}
wflag = NOWRITE;
break;
case (CONTLLINE):
if (wflag != NOWRITE)
fputs(buf, tlib);
}
}
return numi;
}
/*
* Check what line in deck it is
*/
int
whatdline(char *tbuf, char *firstname)
{
if (sscanf(tbuf, "*LIB %s", firstname) == 1)
return LIBDLINE;
if (sscanf(tbuf, "*SUB %s", firstname) == 1)
return SUBDLINE;
if (sscanf(tbuf, "*MOD %s", firstname) == 1)
return MODDLINE;
return NORMLINE;
}
/*
* Check what line it is. If we have model or subckt line we also read its name
*/
int
whatlline(char *tbuf, char *name)
{
if (sscanf(tbuf, ".SUBCKT %s %*s", name) == 1)
return SUBLLINE;
if (sscanf(tbuf, ".MODEL %s %*s", name) == 1)
return MODLLINE;
if (sscanf(tbuf, ".ENDS%c", name) == 1)
return ENDSLLINE;
if (sscanf(tbuf, "+%s", name) == 1)
return CONTLLINE;
return NORMLINE;
}

208
contrib/mslib/inc_main.c

@ -0,0 +1,208 @@
/*
* MW. Include - main functions
*/
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include "datadef.h"
struct LSData *firstLIB;
struct LSData *firstSUB;
struct LSData *firstMOD;
struct LSData *deck;
struct LSData *tmplib;
int bsize, bsizer;
char buf[BSIZE];
int
main(int argc, char *argv[])
{
/*
* Initialize everything
*/
struct LSData *subp, *libp, *modp;
char tch[BSIZE];
int mswritten;
tmplib = LSinsert(NULL, NULL);
deck = LSinsert(NULL, NULL);
*tch = '\0';
mswritten = 0;
switch (argc)
{
case 3:
strcpy(tmplib->name, argv[--argc]);
strcpy(tch, tmplib->name);
case 2:
strcpy(deck->name, argv[--argc]);
if (!(*tch))
{
sprintf(tmplib->name, "%s%s", deck->name, TMPLIBNAME);
strcpy(tch, tmplib->name);
}
break;
case 1:
fprintf(stdout, "Usage: mslib deck [tmplib]\n");
return FAILED;
default:
fprintf(stderr, "mslib: Incorrect parameters count.\n");
return FAILED;
}
/*
* Open deck
*/
if (!(deck->filedes = fopen(deck->name, "r")))
{
sprintf(deck->name, "%s%s", DECKPATH, argv[1]);
sprintf(tmplib->name, "%s%s", DECKPATH, tch);
if (!(deck->filedes = fopen(deck->name, "r")))
{
fprintf(stderr, "mslib: Can't open deck %s.\n", deck->name);
LSclear(deck);
LSclear(tmplib);
return FAILED;
}
}
bsizer = BSIZE;
bsize = bsizer--;
deck->flag = DECK_OPEN;
/*
* Create tmplib and write first line to it
*/
if (!(tmplib->filedes = fopen(tmplib->name, "w")))
{
fprintf(stderr, "mslib: Can't creat tmplib %s.\n", tmplib->name);
LSclear(tmplib);
LSclear(deck);
return FAILED;
}
tmplib->flag = TLIB_OPEN;
fprintf(tmplib->filedes, "%s\n* Tmp library: %s,\n* For deck: %s.\n\n", \
LIBMESSAGE, tmplib->name, deck->name);
firstLIB = LSinsert(NULL, NULL);
firstSUB = LSinsert(NULL, NULL);
firstMOD = LSinsert(NULL, NULL);
/*
* Find commands in deck
*/
readdeck(deck->filedes, firstLIB, firstSUB, firstMOD);
if (firstLIB->flag = IS_LIB)
{
libp = firstLIB->nextLS;
do
{
if (!(libp->filedes = fopen(libp->name, "r")))
{
strcpy(tch, libp->name);
sprintf(libp->name, "%s%s", LIBPATH, tch);
if (!(libp->filedes = fopen(libp->name, "r")))
{
libp->flag = FAILED;
}
}
/*
* Read libraries if everything is OK
*/
if (libp->flag != FAILED)
{
libp->flag = LIB_OPEN;
modp = (firstMOD->flag == IS_MOD) ? firstMOD->nextLS : NULL;
subp = (firstSUB->flag == IS_SUB) ? firstSUB->nextLS : NULL;
mswritten += readlib(libp, tmplib->filedes, subp, modp);
}
libp = libp->nextLS;
}
while (libp);
}
fprintf(stdout, "mslib: Written %d items to tmplib %s.\n", \
mswritten, tmplib->name);
if (libp = firstLIB->nextLS)
{
do
{
if (libp->flag != LIB_OPEN)
fprintf(stderr, " Can't open lib %s.\n", libp->name);
libp = libp->nextLS;
}
while (libp);
}
/*
* Check is models or subckts were find and
* * are not duplicated
*/
if (modp = firstMOD->nextLS)
{
do
{
switch (modp->flag)
{
case DUPLICATE:
fprintf(stderr, " Model duplicated %s.\n", \
modp->name);
break;
default:
fprintf(stderr, " Can't find model %s.\n", \
modp->name);
break;
case FINDED:
}
modp = modp->nextLS;
}
while (modp);
}
if (subp = firstSUB->nextLS)
{
do
{
switch (subp->flag)
{
case DUPLICATE:
fprintf(stderr, " Subckt duplicated %s.\n", \
subp->name);
break;
default:
fprintf(stderr, " Can't find subckt %s.\n", \
subp->name);
break;
case FINDED:
}
subp = subp->nextLS;
}
while (subp);
}
/*
* Clear all data and close files
*/
LSclear(tmplib);
LSclear(deck);
LSclear(firstLIB);
LSclear(firstSUB);
return SUCCESS;
}

12
contrib/mslib/makefile

@ -0,0 +1,12 @@
# MW. Include libs for Spice
CFLAGS= -O2 -s
LDFLAGS= -s
OBJS= inc_main.o inc_inp.o inc_LSD.o
HDRS= datadef.h
SRCC= inc_main.c inc_inp.c inc_LSD.c
mslib: $(OBJS)
$(CC) $(LDFLAGS) -o $@ $(OBJS)
$(OBJS): $(HDRS)

35
contrib/mslib/mslib_readme

@ -0,0 +1,35 @@
Mslib can create a small tmp library which can be .include to spice deck or
used as tmp file with libprm.
You invoke it like this: mslib deck_name [tmp_lib_name]. If second argument
is not given mslib uses deck_name.lib. Mslib then reads deck and looks for
special commands in it. This commands are:
*SUB name1 name2 ... - what subckts are used
*MOD name1 name2 ... - what models are used
*LIB name1 name2 ... - what libraries should be searched
You can give full path for libraries or just the name. Mslib tries to
find them in current directory and then in directory specified in datadef.h
file. There are also some other default options defined there. Check them
After all a tmp. library for the deck is created. It consist only the models
and subckts that were specified in *MOD and *SUB commands.
This is all.
Mslib is _NOT_ a good program. It should automatically recognize what models
or subckts were used and it should be written with flex or bison. Now it
just indicates what is my level of programming in C.
There are some options that You can set for mslib in datadef.h. I tried to
document all of them there, so when want to know more look to the sources.
And one more thing. There is a perl program "spiceprm" that lets You use
parameters in subckts. Many Intusoft's libraries use this feature. To use
parameters I have written a small shell script "libprm". This program
automatic runs spiceprm and mslib on Your's deck to give a working spice
input file. To see how this all works please read "libprm_readme" and
spiceprm readme.

5
contrib/scripts/COPYING

@ -0,0 +1,5 @@
These scripts are free for everyone who think that they might by useful for
him. If someone makes them better please e-mail me.
Michael Widlok
widlok@uci.agh.edu.pl

77
contrib/scripts/liblook

@ -0,0 +1,77 @@
#!/bin/sh
#set -x -v
# MW. Lib search / show program
# usage liblook libname [text_to_find] [l_before] [l_after]
LIBPATH=/usr/local/lib
function trapper()
{
echo User break!
echo Exiting . . .
unset LIBPATH
exit 1
}
trap trapper SIGINT SIGQUIT
function operror()
{
echo Incorrect parameters: $*, $#
echo Usage: liblook libname [text_to_find] [l_before] [l_after]
unset LIBPATH
exit 2
}
function showlib()
{
if test -f $LIBPATH/$1; then
less $LIBPATH/$1; exit 0; fi
if test -f [C./$1; then
less ./$1; exit 0; fi
echo Searching $1 in ~/ . . .
less $(find ~/ -name $1)
}
function searchlib()
{
if test -f $LIBPATH/$1; then
echo File: $LIBNMAE; echo;
grep -B"$3" -A"$4" --ignore-case -e "$2" $LIBPATH/$LIBNAME1;
echo; exit 0; fi
if test -f ./$1; then
echo File: $1; echo;
grep -B"$3" -A"$4" --ignore-case -e "$2" ./$1;
echo; exit 0; fi
#if *.lib or sth like this
echo Searching $1 in ~/ . . .;echo;
if (grep -B"$3" -A"$4" --ignore-case -e "$2" $(find ~/ -name $1)); then
echo; exit 0; fi
echo Searching $1 in $LIBPATH;echo;
if (grep -B"$3" -A"$4" --ignore-case -e "$2" $(find $LIBPATH -name $1)); then
echo; exit 0; fi
}
# Main body
if test $# -lt 1 -o $# -gt 4; then operror $*; fi
case $# in
1) showlib $*;;
2) searchlib $1 $2 2 2;;
3) searchlib $1 $2 $3 2;;
4) searchlib $1 $2 $3 $4;;
esac
unset LIBPATH
exit 0

9
contrib/scripts/liblook_readme

@ -0,0 +1,9 @@
Liblook is a script that can show specified model or sub-circuit entry in
spice library. Common use look like this:
liblook lib_name [text_to_find] [lines_before] [lines_after]
lines_before and lines_after are used when you want to specify how many lines
you want to see before or after given text. Look to he source for more
details.

58
contrib/scripts/libprm

@ -0,0 +1,58 @@
#!/bin/sh
#set -x -v
# MW. Lip / Param parsing program for spice
# -n normal, -f full (keep everything), -r replace original file
export TMPLP=/tmp/LibPrm.$$-
function trapper()
{
echo User break!
echo Exiting . . .
rm -f -v ${TMPLP}*
unset TMPLP
exit 1
}
trap trapper SIGINT SIGQUIT
function operror()
{
echo Incorrect parameters: $*, $#
unset TMPLP
exit 2
}
function repnormpl()
{
mslib $1 ${TMPLP}1
sed -n -e 'p' -e "1r ${TMPLP}1" $1 >${TMPLP}2
spiceprm ${TMPLP}2 $2
}
function keepall()
{
mslib $1
sed -n -e 'p' -e "1r $1.lib" $1 >${TMPLP}2
spiceprm ${TMPLP}2 $2
}
# Main body
if test $# -lt 2 -o $# -gt 3; then operror $*; fi
case $1$# in
-r3) operror $*;;
-n2) repnormpl $2 ${2%.cir}.ckt;;
-n3) repnormpl $2 $3;;
-r2) repnormpl $2 $2;;
-f2) keepall $2 ${2%.cir}.ckt;;
-f3) keepall $2 $3;;
esac
rm -f ${TMPLP}*
unset TMPLP
exit 0

14
contrib/scripts/libprm_readme

@ -0,0 +1,14 @@
So, this is my idea of using parametrized subckts with spice.
First I create an input file like foo.cir and I include commands for
mslib (*MOD, *SUB, *LIB) in it. Then I run "libprm -n foo.cir". Libprm then
runs mslib first to get all models and subckts form given libraries and then
runs spiceprm to evaluate all used parameters.
This works quite right for me, and I hope that You will find my idea
useful. Spiceprm is not my program (I get it from Internet), but I think
that it will better to enclose all used programs in this packet. Spiceprm
has it's own directory with very good readme and examples. If You want to
find out more about libprm or mslib look for the source code. These are rather
short and easy programs - they are all that I could write in quite short
time.

18
contrib/spiceprm/CHANGES

@ -0,0 +1,18 @@
----------------------------------------------------------------------
Version 0.11 January 2, 1996
----------------------------------------------------------------------
No new features.
Bug Fixes -
-----------
1. Duplicate name clash problem with parameterized subckt calls from
within a .subckt....ends block.
2. Writing continuation lines to the output file occaisionally choked.
----------------------------------------------------------------------
Version 0.10 October 10, 1996
----------------------------------------------------------------------
Original release.

339
contrib/spiceprm/COPYING

@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
675 Mass Ave, Cambridge, MA 02139, USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) 19yy <name of author>
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.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) 19yy name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

176
contrib/spiceprm/EXAMPLES

@ -0,0 +1,176 @@
****************************************************************
* Pi attenuator pad.
* Parameters: R0 = impedance
* DB = attenuation in dB (positive)
.SUBCKT PIPAD 1 2 { R0 DB }
R1 1 0 {R0*(1+2/(10**(DB/20)-1))}
R2 1 2 {(R0/2)*(10**(DB/20)-10**(DB/-20))}
R3 2 0 {R0*(1+2/(10**(DB/20)-1))}
.ENDS
****************************************************************
* PCB Via inductance + extra L.
* H = substrate height in inches
* D = via diameter in inches
* L = extra inductance in henries.
.SUBCKT VIA 1 2 { H D L }
LV 1 2 {L+
+ 5.08E-9*H*(log((2+sqrt(4+D*D/(H*H)))*H/D)+
+ .75*(D/H-sqrt(4+D*D/(H*H))))}
.ENDS
****************************************************************
* Voltage-controlled oscillator.
* Parameters: F = frequency @ Vc = 0 in Hz
* KV = tuning sensitivity in Hz/volt
* A = peak output amplitude
* RO = output port resistance
* Connections: Vc Out
.SUBCKT VCO 20 2 { F KV A RO }
RIN1 20 0 1E12
VSW 30 0 DC 0 PULSE 0 1
RSW 30 0 1E12
BIN 3 0 V=(V(20)+{F/KV})*V(30)
R3 3 0 1E6
GSIN 2 0 22 0 {1/RO}
RSIN 2 0 {RO}
B1 1 0 I=-(V(22)*V(3))
B2 22 0 I=V(1)*V(3)
R2 1 0 1E9
I1 0 1 PULSE {1E-9*A} 0
C2 1 0 {.159154943/KV}
C1 22 0 {.159154943/KV}
R1 22 0 1E9
.ENDS
****************************************************************
* Ideal Frequency converter.
* Parameters: F = Oscillator frequency
* RI = input port resistance
* RO = output port resistance
* Connections: In Out
.SUBCKT FCNVT 1 2 { F RI RO }
RIN 1 0 {RI}
VLO 3 0 DC 0 SIN 0 1 {F}
RLO 3 0 1E12
BMIX 0 2 I=(V(1)*V(3))/{RO}
RO 2 0 {RO}
.ENDS
****************************************************************
* 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
****************************************************************
* Sine wave 2-tone RF power source.
* Parameters: F1 = 1st tone frequency
* F2 = 2nd tone frequency
* R = output resistance
* P = power per tone in dBm
* V = DC (EMF)
.SUBCKT 2TGEN 1 2 { F1 F2 R P V }
* + -
I1 2 1 DC {V/R} SIN {V/R} {sqrt((10**(P/10))/(125*R))} {F1}
I2 2 1 DC 0 SIN 0 {sqrt((10**(P/10))/(125*R))} {F2}
Ro 1 2 {R}
.ENDS
****************************************************************
* Transmission lines
* All ports must have external connections.
* Parameters: Z0 = impedance
* L = length in inches
* VP = velocity-of-propagation rel. to air
* Connections: 1+ 1- 2+ 2-
.SUBCKT TXL 1 2 3 4 { Z0 L VP }
T1 1 2 3 4 Z0={Z0} TD={L/(1.180315E10*VP)}
.ENDS
****************************************************************
* Lossy transmission line.
* All ports must have external connections.
* Parameters: Z0 = impedance
* L = length in inches
* VP = velocity-of-propagation rel. to air
* A = loss in dB/inch
* Connections: 1+ 1- 2+ 2-
.SUBCKT LTXL 1 2 3 4 { Z0 L VP A }
O1 1 2 3 4 LOSSY
.MODEL LOSSY LTRA LEN={L}
+ R={5.848492e-3*A*Z0}
+ L={Z0/(1.180315E10*VP)}
+ C={1/(1.180315E10*VP*Z0)}
.ENDS
****************************************************************
* 2 coupled transmission lines
* All ports must have external connections.
* Parameters: Z0E = even-mode impedance
* Z0O = odd-mode impedance
* L = length in inches
* VP = velocity-of-propagation rel. to air
* Connections: 1+ 1- 2+ 2- { Z0E Z0O L VP }
.SUBCKT CPL2 1 2 3 4
T1 1 0 3 0 Z0={Z0E} TD={L/(1.180315E10*VP)}
T2 1 2 3 4 Z0={2*Z0E*Z0O/(Z0E-Z0O)} TD={L/(1.180315E10*VP)}
T3 2 0 4 0 Z0={Z0E} TD={L/(1.180315E10*VP)}
.ENDS
****************************************************************
* Generic Bipolar OpAmp - linear model
* Parameters: G = open-loop gain in dB
* FT = unity gain frequency in Hz
* IOS = input offset current in amps
* VOS = input offset voltage
* IB = input bias current in amps
.SUBCKT BIPOPA 2 3 6 7 4 { G FT IOS VOS IB }
* - In + Out Vcc Vee
RP 4 7 10K
RXX 4 0 10MEG
IBP 3 0 {IB-IOS}
RIP 3 0 10MEG
CIP 3 0 1.4PF
IBN 2 0 {IB}
RIN 2 0 10MEG
CIN 2 0 1.4PF
VOFST 2 10 {VOS}
RID 10 3 200K
EA 11 0 10 3 1
R1 11 12 5K
R2 12 13 50K
C1 12 0 {13E-6/FT}
GA 0 14 0 13 {0.0135*(10**(G/20))}
C2 13 14 {2.7E-6/FT}
RO 14 0 75
L 14 6 {30/FT}
RL 14 6 1000
CL 6 0 3PF
.ENDS
****************************************************************
* Generic FET OpAmp - linear model
* Parameters: G = open-loop gain in dB
* FT = unity gain frequency in Hz
* VOS = input offset voltage
.SUBCKT FETOPA 2 3 6 7 4 { G FT VOS }
* - In + Out Vcc Vee
RP 4 7 6K
RXX 4 0 10MEG
IBP 3 0 33E-12
RIP 3 0 1E12
CIP 3 0 3PF
IBN 2 0 30E-12
RIN 2 0 1E12
CIN 2 0 3PF
VOFST 2 10 {VOS}
RID 10 3 1E12
EA 11 0 10 3 1
R1 11 12 5K
R2 12 13 50K
C1 12 0 {24E-6/FT}
GA 0 14 0 13 {0.0135*(10**(G/20))}
C2 13 14 {2.33E-6/FT}
RO 14 0 75
L 14 6 {4E-6/FT}
RL 14 6 100
CL 6 0 3PF
.ENDS
****************************************************************

216
contrib/spiceprm/README

@ -0,0 +1,216 @@
------------------------------------------------------------------------
SPICEPRM - A Spice preprocessor for parameterized subcircuits (v 0.11)
Copyright (C) 1996 Andrew J. Borsa <andy@moose.mv.com>
------------------------------------------------------------------------
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.

304
contrib/spiceprm/spiceprm

@ -0,0 +1,304 @@
#! /usr/bin/perl
# spiceprm
# Pass parameters to spice subcircuits.
# Usage: spiceprm infile [outfile]
# infile and outfile must be different.
# Output written to STDOUT if outfile not given.
$BANNER = "Spiceprm version 0.11, Copyright (C) 1996 Andrew J. Borsa";
# NOTES:
# 1. Units not recognized inside .subckt {} expressions.
# 2. Perl exponent operator: "**", Spice exp op: "^".
# 3. "-" as part of subckt name doesn't work but "_" does.
# Netlist convention
# Xname n1 n2 n3 ... ni subname {p1 = val1 ... pj = valj}
# p1 thru pj are the parameters to be passed to the subcircuit.
# val is any valid spice value.
#
# .subckt name n1 n2 ... ni {p1 p2 ... pj}
# parameter expressions must be enclosed in {}.
# After substitution -
# Xname n1 n2 n3 ... ni subname#k
# *{p1 = val1 ... pj = valj}
# .subckt subname#k n1 n2 n3 ... ni
# ... listing with parameters substituted
# .ends
# %subckt: key = subname
# value = startline, endline, listing(.subckt ... .ends)
# Only for .subckts with parameters.
# %subprm: key = subname
# value = parameter name list
# %subcall: key = Xname[#subname0#subname1...]
# value = subname#k
# NOTE: IF Xname is called from within a .subckt, it will have calling
# .subckt names appended, delimited by #'s.
# %sub: key = subname#k
# value = p1 val1 ... pj valj, where val is a pure
# numeric with no units.
$MAXLEN = 70; # Max output file line length.
$DMAXLEN = 10; # Amount to increment if necessary.
$linenum = 0;
%units = ('f','1e-15','p','1e-12','n','1e-9','u','1e-6','mil','25.4e-6',
'm','1e-3','k','1e3','meg','1e6','g','1e9','t','1e12');
$* = 1; # Pattern match with multi-line strings.
($infile, $outfile) = @ARGV;
print "\n$BANNER\ninfile: $infile\noutfile: $outfile\n\n";
$#ARGV && ($infile eq $outfile)
&& die "Input and Output filenames must be different\n";
open(INFILE, $infile) || die "Can't open source file: $infile\n";
$hasprm = $depth = 0;
&prm_scan;
close(INFILE);
open(INFILE, $infile) || die "Can't open source file: $infile\n";
unlink $outfile if $#ARGV;
open(OUTFILE, $#ARGV ? ">$outfile" : ">-")
|| die "Can't open output file: $outfile\n";
$depth = 0;
&prm_wr;
close(INFILE);
close(OUTFILE);
# Get a line from the input file, combining any continuation lines into
# one long line. Skip comment and blank lines.
sub prm_getline {
local($line);
chop($line = defined($nxtline) ? $nxtline : <INFILE>);
$linenum = $.;
while ($nxtline = <INFILE>) {
if ($line =~ /^\*|^\s/) { $line = ''; }
if ($line eq '' || $nxtline =~ s/^(\+)/ /) {
chop($nxtline);
$line .= $nxtline;
}
else { last; }
}
$line;
}
# Scan the input file looking for subcircuit calls with parameter list and
# any subcircuits with defined parameters.
sub prm_scan {
local(@w, @tmp, @list);
local($xnm, $subnm, $i, $max, $m, $s, $n, $tmp, $start);
local($sublist) = '';
PRM_SCAN: while ($_ = &prm_getline) {
# skip .control - .endc blocks
if (/^\.control/i) {
while ($_ = &prm_getline) { next PRM_SCAN if (/^\.endc/i); }
}
tr/A-Z/a-z/;
PRM_TST: {
if (/^x/ && s/(\{([^\}]+)\})//) {
@w = split(' ');
@tmp = @w[0 .. $#w-1];
$xnm = $w[0] . $sublist; $subnm = $w[$#w];
$_ = $2; $i = 0;
while (/(\w+)\s*\=\s*([+-]?\d*(\.\d*)?([Ee][+-]?\d+)?)([a-z]\w*)?/) {
# 1 2 3 4 5
$prmval{$1} = $2*($5 ? &unit2mult($5) : 1);
$_ = $';
$i += 2;
}
$max = -1; $m = '';
CHKDUP: foreach $s (keys %sub) {
$s =~ /(\w+)\#(\d+)/;
if ($subnm eq $1) {
if ($max < $2) { $max = $2; }
$n = (@w = split(' ', $sub{$s}));
if ($n == $i) {
for ($i = 0; $i < $n; $i += 2) {
last if $w[$i+1] ne $prmval{$w[$i]};
}
if ($i >= $n) {
$m = 1;
$subcall{$xnm} = $s;
last CHKDUP;
}
}
}
}
if ($m eq '') {
foreach $n (keys %prmval) {
$m = join(' ', $m, $n, $prmval{$n});
}
$sub{($s = join('', $subnm, '#', $max+1))} = $m;
$subcall{$xnm} = $s;
}
push(@list, join(' ', @tmp, $subcall{$xnm})) if $depth;
undef %prmval;
last PRM_TST;
}
if (/^\.subckt\s+(\w+)/) {
$depth++; $tmp = $1;
$sublist .= '#' . $1;
if (s/(\{([^\}]+)\})//) {
if ($hasprm) {
print "Line $linenum: ",
"Nested parameterized subckt definitions not permitted\n\n";
}
else {
$hasprm = 1; $start = $.;
$subprm{$psubnm = $tmp} = $2;
}
}
push(@list, $_); # With {} parameter defs removed.
last PRM_TST;
}
if (/^\.ends/) {
$sublist =~ s/(\#\w+)$//;
if (--$depth == 0) {
if ($hasprm) {
$subckt{$psubnm} = join("\n",join(' ',$start,$.),@list,$_);
}
$hasprm = 0;
undef @list; $sublist = '';
}
last PRM_TST;
}
if ($depth) {
push(@list, $_);
last PRM_TST;
}
}
}
}
# Write the output file.
sub prm_wr {
local(@w, @pnms, @list, @line);
local($xnm, $subnm, $n, $m, $i, $s);
local($sublist) = '';
PRMWR_SCAN: while ($_ = &prm_getline) {
# write .control - .endc blocks
if (/^\.control/i) {
print OUTFILE "$_\n";
while ($_ = &prm_getline) {
prm_wrline($_);
next PRMWR_SCAN if (/^\.endc/i);
}
}
tr/A-Z/a-z/;
if (/^x/ && s/(\{([^\}]+)\})//) {
@w = split(' '); $subnm = pop(@w);
$xnm = $w[0] . $sublist;
prm_wrline(join(' ', @w, $subcall{$xnm}));
print OUTFILE "* $1\n";
if (!defined($subprm{$subnm})) {
print "Line $linenum: Subckt \"$subnm\" has no defined parameters\n\n";
next PRMWR_SCAN;
}
$n = @pnms = sort(split(' ', $subprm{$subnm}));
$m = (@w = split(' ', $sub{$subcall{$xnm}}));
if ($n == $m/2) {
for ($i = 0, undef(@list); $i < $m; $i += 2) {
push(@list, $w[$i]);
}
for ($i = 0, @w = sort(@list); $i < $n; ++$i) {
if ($pnms[$i] ne $w[$i]) {
print "Line $linenum: ",
"Undefined parameter \"$w[$i]\"",
"in subckt \"$subnm\" call\n\n";
next PRMWR_SCAN;
}
}
}
else {
print "Line $linenum: ",
"Incorrect number of parameters in subckt \"$subnm\" call\n\n";
}
next PRMWR_SCAN;
}
if (/^\.subckt\s+(\w+)/) {
if ($s = $subckt{$1}) {
$s =~ /\d+\s+(\d+)/;
$n = $1;
&prm_getline until $. == $n;
}
else {
$depth++; $sublist .= '#' . $1;
prm_wrline($_);
}
next PRMWR_SCAN;
}
if (/^\.end\b/) {
foreach $s (keys %sub) {
($subnm = $s) =~ s/\#\d+//;
@line = split(/\n/, $subckt{$subnm});
shift(@line);
$line[0] =~ s/$subnm/$s/;
%prmval = split(' ', $sub{$s});
foreach (@line) {
s/\{([^\}]+)\}/&prm_eval($1, %prmval)/eg;
prm_wrline($_);
}
}
print OUTFILE ".end\n";
last PRMWR_SCAN;
}
if (/^\.ends/) {
if (--$depth == 0) { $sublist = ''; }
else { $sublist =~ s/(\#\w+)$//; }
}
prm_wrline($_);
}
}
# Translate a possible unit into a multiplier factor.
# Parameter is the unit letter string assumed lower case.
sub unit2mult {
local($u) = shift;
$u = ($u =~ /^(mil|meg)/ ? $1 : substr($u, 0, 1));
$u = defined($units{$u}) ? $units{$u} : 1;
}
# Evaluate a parameter expression.
# Arguments: expression, parameter & value assoc. array.
sub prm_eval {
local($x,%prm) = @_;
foreach $key (keys %prm) {
$x =~ s/\b$key\b/$prm{$key}/eg;
}
eval($x . ';');
}
# Write an output file line with a max length. The line is split on
# whitespace or '=' at a point less than or equal to the max length
# and output as a spice continuation line.
# If a splitting delimiter is not found within $MAXLEN, then allowable
# length is increased, potentially up to the actual line length.
# NOTE: outputs '\n'.
# $MAXLEN sets the max value, $DMAXLEN the increment.
# File handle = OUTFILE.
sub prm_wrline {
local($line) = shift;
local($max, $s, $m);
$max = $MAXLEN;
until ($line eq '') {
if (length($line) > $max) {
$m = substr($line, 0, $max);
if ($m =~ /((\s|\=)[^(\s|\=)]*)$/) {
$s = $` . $2;
$line = '+' . substr($line, length($s));
}
else { $max += $DMAXLEN; next; }
}
else { $s = $line; $line = ''; }
print OUTFILE "$s\n";
$max = $MAXLEN;
}
}

19
contrib/spiceprm/spiceprm-0.11.lsm

@ -0,0 +1,19 @@
Begin3
Title: spiceprm-0.11.tar.gz
Version: 0.11
Entered-date: 02JAN97
Description: A Perl script preprocessor adding parameterized
subcircuit capability to the Berkeley Spice circuit
simulator. Should also work with any spice lacking
this feature.
Keywords: spice cad simulation preprocessor perl script
Author: andy@moose.mv.com (Andy Borsa)
Maintained-by:
Primary-site: sunsite.unc.edu /pub/Linux/apps/circuits
15.6kB spiceprm-0.11.tar.gz
Alternate-site:
Original-site:
Platforms: Linux or most any unix, Perl 4 or greater.
Tested with Linux and Perl 5.
Copying-policy: GNU General Public License. See file COPYING.
End

11
doc/ChangeLog

@ -0,0 +1,11 @@
1999-09-06 Arno Peters <A.W.Peters@ieee.org>
* ngspice.texi: Added TeX equivalents for some formula.
First tables converted to texinfo format.
1999-08-31 Emmanuel Rouat <emmanuel.rouat@wanadoo.fr>
* Makefile.am: added .texi file by Arno Peters - a distribution will now
include a postscript doc.
updated 'clean' rules

11
doc/Makefile.am

@ -0,0 +1,11 @@
## Process this file with automake to produce Makefile.in
EXTRA_DIST = ngspice.ps
info_TEXINFOS = ngspice.texi
CLEANFILES = *.fns *.pg *.tp *.aux *.cp *.ky *.vr *.fn *.log *.toc *.vrs
DISTCLEANFILES = $CLEANFILES *.ps *.dvi *.info*
MAINTAINERCLEANFILES = $DISTCLEANFILES Makefile.in

8496
doc/ngspice.texi
File diff suppressed because it is too large
View File

5951
doc/texinfo.tex
File diff suppressed because it is too large
View File

5
man/Makefile.am

@ -0,0 +1,5 @@
## Process this file with automake to produce Makefile.in
SUBDIRS = man1
MAINTAINERCLEANFILES = Makefile.in

8
man/man1/Makefile.am

@ -0,0 +1,8 @@
## Process this file with automake to produce Makefile.in
man_MANS = spice.1 nutmeg.1 sconvert.1
EXTRA_DIST = $(man_MANS)
MAINTAINERCLEANFILES = Makefile.in

1051
man/man1/nutmeg.1
File diff suppressed because it is too large
View File

127
man/man1/sconvert.1

@ -0,0 +1,127 @@
.\" RCS Info: $Revision$ on $Date$
.\" $Source$
.\" Copyright (c) 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
.TH SCONVERT 1 "20 March 1986"
.UC 4
.SH NAME
sconvert \- convert spice formats
.SH SYNOPSIS
.B sconvert fromtype fromfile totype tofile
.br
.B sconvert fromtype totype
.br
.B sconvert
.br
.SH DESCRIPTION
.B Sconvert
translates spice output files among three formats: the old
binary format, a new binary format, and a new ascii format.
The formats are specified by the
.B fromtype
and
.B totype
arguments: `o' for the old format, `b' for the new binary format,
and `a' for the new ascii format.
.B Fromtype
specifies the format to be read, and
.B totype
specifies the format to be written.
If
.B fromfile
and
.B tofile
are given, then they are used as the input and output, otherwise
standard input and output are used. (Note that this second option is
only available on \s-2UNIX\s+2 systems \- on VMS and other systems you must
supply the filenames.)
If no arguments are given, the parameters are prompted for.
.PP
Binary format is the preferred format for general use, as it is
the most economical in terms of space and speed of access, and ascii is
provided to make it easy to modify data files and transfer them
between machines with different floating-point formats.
The old format is provided only
for backward compatibility. The three formats are as follows:
.br
.nf
.B Old:
What Size in Bytes
title 80
date 8
time 8
numoutputs 2
the integer 4 2
variable names --
char[numoutputs][8] numoutputs * 8
types of output numoutputs * 2
node index numoutputs * 2
plot title numoutputs * 24
the actual data numpoints * numoutputs * 8
.B Ascii:
Title: \fITitle Card String\fR
Date: \fIDate\fR
[ Plotname: \fIPlot Name\fR
Flags: \fIcomplex\fR or \fIreal\fR
No. Variables: \fInumoutputs\fR
No. Points: \fInumpoints\fR
Command: \fInutmeg command\fR
Variables: 0 \fIvarname1\fR \fItypename1\fR
1 \fIvarname2\fR \fItypename2\fR
etc...
Values:
0 n n n n ...
1 n n n n ...
And so forth...
] repeated one or more times
.PP
If one of the flags is \fIcomplex\fR, the points look like r,i where r and i
are floating point (in %e format). Otherwise they are in %e format.
Only one of \fIreal\fR and \fIcomplex\fR should appear.
.PP
The lines are guaranteed to be less than 80 columns wide (unless the
plot title or variable names are very long), so this format is safe
to mail between systems like CMS.
.PP
Any number of \fBCommand:\fR lines may appear between the \fBNo. Points:\fR
and the \fBVariables:\fR lines, and whenever the plot is loaded into
\fBnutmeg\fR they will be executed.
.nf
.B Binary:
\fITitle Card\fR (a NULL terminated string)
\fIDate, Time\fR (a NULL terminated string)
[
\fIPlot title\fR (a NULL terminated string)
\fINumber of variables\fR (an int)
\fINumber of data points\fR (an int)
\fIflags\fR (a short)
\fIvariable header struct\fR (repeated numoutputs times)
\fIvariable name\fR (a NULL terminated string)
\fIvariable type\fR (an int)
\fIset of outputs\fR (repeated numpoints times)
] repeated one or more times.
.PP
A set of outputs is a vector of doubles of length numoutputs, or
a vector of real-imaginary pairs of doubles if the data is complex.
.SH "SEE ALSO"
nutmeg(1), spice(1), writedata(3)
.SH AUTHOR
Wayne Christopher (faustus@cad.berkeley.edu)
.SH BUGS
If variable names and the title
and plotname strings have trailing
blanks in them they will be stripped off when the file is read, if
it is in ascii format.
.PP
If a plot title begins with "Title:" \fBnutmeg\fR will be fooled into thinking
that this is an ascii format file. \fBSconvert\fR always requires the
type to be specified, however.

325
man/man1/spice.1

@ -0,0 +1,325 @@
.\" RCS Info: $Revision$ on $Date$
.\" $Source$
.\" Copyright (c) 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
.TH SPICE 1 "20 March 1986"
.ds S \s-2SPICE\s+2\&3
.UC 4
.SH NAME
spice \- circuit simulator
.SH SYNOPSIS
\fBspice [ -n ] [ -t term ] [ -r rawfile] [ -b ]
[ -i ] [ input file ... ]\fR
.SH DESCRIPTION
This manual page describes the commands available for interactive
use of \*S. For details of circuit descriptions and the
process of simulating a circuit, see the \*S User's Manual.
The commands available are a superset of those available for
\fBnutmeg\fR \- only the additional commands available in \*S
are described here. You should be familiar with the manual page for
\fBnutmeg(1)\fR before reading this manual page.
.PP
Arguments are:
.TP
\fB-n\fR (or \fB-N\fR)
Don't try to source the file ".spiceinit" upon startup. Normally \*S
tries to find the file in the current directory, and if it is not found then
in the user's home directory.
.TP
\fB-t term\fR (or \fB-T term\fR)
The program is being run on a terminal with \fImfb\fR name \fBterm\fR.
.TP
\fB-b\fR (or \fB-B\fR)
Run in batch mode. \*S will read the standard input or the specified
input file and do the simulation. Note that if the standard input
is not a terminal, \*S will default to batch mode, unless the
-i flag is given.
.TP
\fB-s\fR (or \fB-S\fR)
Run in server mode. This is like batch mode, except that a temporary
rawfile is used and then written to the standard output, preceded by
a line with a single "@", after the simulation is done. This mode
is used by the spice daemon.
.TP
\fB-i\fR (or \fB-I\fR)
Run in interactive mode. This is useful if the standard input is
not a terminal but interactive mode is desired. Command completion is
not available unless the standard input is a terminal, however.
.TP
\fB-r rawfile\fR (or \fB-R rawfile\fR)
Use \fBrawfile\fR as the default file into which the results of
the simulation are saved.
.PP
Further arguments are taken to be \*S input decks, which are read
and saved. (If batch mode is requested then they are run immediately.)
.PP
\*S will accept any \s-2SPICE\s+2\&2 input decks, and output
ascii plots, fourier analyses, and node printouts as specified
in .plot, .four, and .print cards. If a \fBout\fR parameter
is given on a .width card, the effect is the same as \fBset width = ...\fR.
Since \*S ascii plots do not use multiple ranges, however, if vectors
together on a .plot card have different ranges they will not provide
as much information as they would in \s-2SPICE\s+2\&2. The output
of \*S is also much less verbose than \s-2SPICE\s+2\&2, in that the only
data printed is that requested by the above cards.
.PP
Vector names are the same as in \fBnutmeg\fR, with this addition:
a name such as \fB@name[param]\fR, where \fBname\fR is either
the name of a device instance or model, denotes the value of the
\fBparam\fR parameter of the device or model. See the \*S User's
Manual for details of what parameters are available. The value is a
vector of length 1. This function is also available with the
\fBshow\fR command, and is available with variables for convenience for
command scripts.
.PP
\*S
commands are as follows (these are only those commands not also
available in \fBnutmeg\fR \- consult the \fBnutmeg\fR manual page for
more commands):
.TP
\fBsetcirc [circuit name]\fR
Change the current circuit. The current circuit is the one that is
used for the simulation commands below. When a circuit is loaded
with the \fIsource\fR command (see below) it becomes the
current circuit.
.TP
\fBop [.op card args]\fR
Do an operating point analysis.
.TP
\fBtran [.tran card args]\fR
Do a transient analysis.
.TP
\fBac [.ac card args]\fR
Do an ac analysis.
.TP
\fBdc [.dc card args]\fR
Do a dc transfer curve analysis.
.TP
\fBlisting [logical] [physical] [deck] [expand]\fR
Print a listing of the current circuit. If the \fBlogical\fR argument
is given, the listing is with all continuation lines collapsed
into one line, and if the \fBphysical\fR
argument is given the lines are printed out as they were found in
the file. The default is \fBlogical\fR. A \fBdeck\fR listing is just like
the \fBphysical\fR listing, except without the line numbers it recreates
the input file verbatim (except that it does not preserve case).
If the word \fBexpand\fR is present, the circuit will be printed with all
subcircuits expanded.
.TP
\fBedit [file]\fR
Print the current \*S deck into a file, call up the editor on that file
and allow the user to modify it, and then read it back in, replacing
the origonal deck. If a \fBfilename\fR is given, then edit that file
and load it, making the circuit the current one.
.TP
\fBresume\fR
Resume a simulation after a stop.
.TP
\fBshow \fR
Show a device parameter.
.TP
\fBalter \fR
Alter a device parameter.
.TP
\fBstate\fR
Print the state of the circuit. (This command is largely unimplemented.)
.TP
\fBsave [all] [output ...]\fR or \fB.save [all] [output ...]\fR
Save a set of outputs, discarding the rest. If a node has been mentioned
in a \fBsave\fR command, it will appear in the working plot after
a run has completed, or in the rawfile if spice is run in batch
mode. If a node is traced or plotted (see below) it will
also be saved. For backward compatibility, if there are \fBno\fR save
commands given, all outputs are saved.
.TP
\fBstop [ after n] [ when something cond something ] ... \fR
Set a breakpoint. The argument \fBafter n\fR means stop after \fBn\fR
iteration number \fBn\fR, and the argument
\fBwhen something cond something\fR means
stop when the first \fBsomething\fR is in the given relation with
the second \fBsomething\fR, the possible relations being
\fBeq\fR or = (equal to),
\fBne\fR or <> (not equal to),
\fBgt\fR or > (greater than),
\fBlt\fR or < (less than),
\fBge\fR or >= (greater than or equal to), and
\fBle\fR or <= (less than or equal to).
IO redirection is disabled for the \fBstop\fR command, since the relational
operations conflict with it (it doesn't produce any output anyway).
The \fBsomething\fR\&s above may be node names in
the running circuit, or real values.
If more than one condition is given, e.g.
\fBstop after 4 when v(1) > 4 when v(2) < 2\fR, the conjunction of
the conditions is implied.
.TP
\fBtrace [ node ...]\fR
Trace nodes. Every iteration the value of the node is printed to the
standard output.
.TP
\fBiplot [ node ...]\fR
Incrementally plot the values of the nodes while \*S runs.
.TP
\fBstep [number]\fR
Iterate \fBnumber\fR times, or once, and then stop.
.TP
\fBstatus\fR
Display all of the traces and breakpoints currently in effect.
.TP
\fBdelete [debug number ...]\fR
Delete the specified breakpoints and traces. The \fBdebug numbers\fR
are those shown by the \fBstatus\fR command. (Unless you do
\fBstatus > file\fR, in which case the debug numbers aren't printed.)
.TP
\fBreset\fR
Throw out any intermediate data in the circuit (e.g, after a breakpoint
or after one or more analyses have been done already), and re-parse
the deck. The circuit can then be re-run. (\fBNote\fR: this command
used to be \fBend\fR in \s-2SPICE\s+2 3a5 and earlier versions -- \fBend\fR
is now used for control structures.) The \fBrun\fR command will take
care of this automatically, so this command should not be necessary...
.TP
\fBrun [rawfile]\fR
Run the simulation as specified in the input file. If there were any
of the control cards .ac, .op, .tran, or .dc, they are executed. The output
is put in \fBrawfile\fR if it was given, in addition to being available
interactively.
.TP
\fBsource file\fR
Read the \*S input file \fBfile\fR. \fBNutmeg\fR and \*S commands may be
included in the file, and must be enclosed between the lines
\fI.control\fR and \fI.endc\fR. These commands
are executed immediately after the circuit is loaded, so a control line
of \fIac ...\fR will work the same as the corresponding \fI.ac\fR card.
The first line in any input file is considered a title
line and not parsed but kept as the name of the circuit. The
exception to this rule is the file \fI.spiceinit\fR.
Thus, a \*S command script must begin with a blank line and then with
a \fI.control\fR line.
Also, any line beginning with the characters *# is considered a control
line. This makes it possible to imbed commands in \*S input files
that will be ignored by earlier versions of \s-2SPICE\s+2.
\fINote:\fR in spice3a7 and before, the \fI.control\fR and \fI.endc\fR
lines were not needed, and any line beginning with the name of a front-end
command would be executed.
.TP
\fBlinearize vec ...\fR
Create a new plot with all of the vectors in the current plot, or
only those mentioned if arguments are given. The new vectors
will be interpolated onto a linear time scale, which is determined
by the values of \fBtstep, tstart,\fR and \fBtstop\fR in the
currently active transient analysis. The currently loaded deck
must include a transient analysis (a \fBtran\fR command may be run
interactively before the last \fBreset\fR, alternately), and the
current plot must be from this transient analysis. This command
is needed because \s-2SPICE\s+2\&3 doesn't output the results
from a transient analysis in the same manner that \s-2SPICE\s+2\&2 did.
.PP
There are several \fBset\fR variables that \*S uses but \fBnutmeg\fR
does not. They are:
.IP "" 16
\fBeditor\fR
.br
The editor to use for the \fBedit\fR command.
.IP
\fBmodelcard\fR
.br
The name of the model card (normally \fB.model\fR).
.IP
\fBnoaskquit\fR
.br
Do not check to make sure that there are no circuits suspended and
no plots unsaved. Normally \*S will warn the user when he tries to
quit if this is the case.
.IP
\fBnobjthack\fR
.br
Assume that BJT's have 4 nodes.
.IP
\fBnoparse\fR
.br
Don't attempt to parse decks when they are read in (useful for
debugging). Of course, they
cannot be run if they are not parsed.
.IP
\fBnosubckt\fR
.br
Don't expand subcircuits.
.IP
\fBrenumber\fR
.br
Renumber input lines when a deck has \fB.include\fR's.
.IP
\fBsubend\fR
.br
The card to end subcircuits (normally \fB.ends\fR).
.IP
\fBsubinvoke\fR
.br
The prefix to invoke subcircuits (normally \fBx\fR).
.IP
\fBsubstart\fR
.br
The card to begin subcircuits (normally \fB.subckt\fR).
.PP
There are a number of \fBrusage\fR parameters available, in addition
to the ones available in \fBnutmeg\fR:
.IP "" 16
.PP
If there are subcircuits in the input file, \*S expands instances of them.
A subcircuit is delimited by the cards
.B .subckt
and
.B .ends,
or whatever the value of the variables
.B substart
and
.B subend
is, respectively. An instance of a subcircuit is created by specifying
a device with type 'x' \- the device line is written
.IP
\fBxname node1 node2 ... subcktname\fR
.LP
where the nodes are the node names that replace the formal parameters
on the \fB.subckt\fR line. All nodes that are not formal parameters
are prepended with the name given to the instance and a ':', as are
the names of the devices in the subcircuit. If there are several nested
subcircuits, node and device names look like \fBsubckt1:subckt2:...:name\fR.
If the variable \fBsubinvoke\fR is set, then it is used as the prefix
that specifies instances of subcircuits, instead of 'x'.
.SH "VMS NOTES"
The standard suffix for rawspice files in VMS is ".raw".
.PP
You may have to redefine the value EDITOR if you wish to use the \fBedit\fR
command, since the default for VMS is "vi".
.SH "SEE ALSO"
nutmeg(1), sconvert(1), spice(1), mfb(3), writedata(3)
\*S User's Guide
.SH AUTHORS
\*S: Tom Quarles (quarles@cad.berkeley.edu)
.br
\fBnutmeg\fR / User interface: Wayne Christopher (faustus@cad.berkeley.edu)
.SH BUGS
.PP
\*S will recognise all the notations used in \s-2SPICE\s+2\&2 \fB.plot\fR
cards, and will translate \fBvp(1)\fR into \fBph(v(1))\fR, and so
forth. However, if there are spaces in these names it won't work. Hence
\fBv(1, 2)\fR and \fB(-.5, .5)\fR aren't recognised.
.PP
BJT's can have either 3 or 4 nodes, which makes it difficult for the subcircuit
expansion routines to decide what to rename. If the fourth parameter has
been declared as a model name, then it is assumed that there are 3 nodes,
otherwise it is considered a node. To disable this kludge, you can set
the variable "nobjthack", which will force BJT's to have 4 nodes (for the
purposes of subcircuit expansion, at least).
.PP
The \fB@name[param]\fR notation might not work with \fBtrace, iplot,\fR etc.
yet.
.PP
The first line of a command file (except for the \fI.spiceinit\fR file)
should be a comment. Otherwise \s-2SPICE\s+2 may create an empty circuit
structure.
.SH CAVEATS
.PP
\*S files specified on the command line are read in before the\fB .spiceinit\fR
file is read. Thus if you define aliases there that you call in a
\*S source file mentioned on the command line, they won't be recognised.

164
notes/Linux.changes

@ -0,0 +1,164 @@
So, this is third version of Spice3f5 for RedHat Linux 2.6. I took re-ported
version of spice3f5 and made changes to fix some bugs. If someone want to help,
please send me "newer" versions wtih more bugs fixed.
I hope that those who wnat to have good spice under Linux (no more Win95)
will find this port useful and maybe help each other to improve it.
There was a lot of bugs in previus versions, generally in command parsiong routines.
I copy all original files to *.orig and marked all my changes with /* MW. ... */
I changed cp/bquote.c and cp/var2.c to handle some special situations
and commands like $foo, `foo`. Also problems with 'gets()' (in sconvert and
inp.c) function are fixed. I chnaget it to fgets(buf, BSIZE_SP, stdin) for
safe use.
Globing ('[]{}?*') didn't work at all. Now it is removed (form cp/glob.c).
We don't need this features in spice.
Initial command parsing (cp_lexer() from cp/lexical.c) strip all commas from
strings. This was in conflict with aritchetic expressions.
com_let() in fte/postcoms.c caused core dump in some situations - fixed.
Editor problems. Com_edit() in fte/inp.c failed occasionally, when it
tryies to fclose() fp second time. Now inp_spsource() always closes fp, and
other calling functions do not. It seems to work right now.
vec_get() (fte/vectors.c) has some problems with devices parameters and
memory leaks. I hope that my changes fixed it at all.
I have to add INPinsertNofree() in inp/inpsymt.c. This is special case for
routines from fte/spiceif.c and fte/outitf.c - It does not do free() for
any pointers that it gets. This may cause small memory leaks, but I don't
know how to make it better.
com_alter_common() (fte/device.c) caused segmentation faults ocassionally,
due to double free the same pointers. It works right now.
cp_lexer() corretly gets ^V, ^D, and ESC. I have to #include ioctl.h file in
cp/lexical.c and cp/complete.c
There were problem with com_iplot() if it was called when X11 does not run.
I have to add additonal check to gr_pmsg() (from fte/graph.c) and now it
works fine.
Trace failed to display comlex data due to segmentation fault. Someone wants
to plot realdata even if given vector was complex. I changed gr_iplot()
(in fte/graf.c) and now it is fine.
There are some changes in os_linux.h and os_unix.h, but they are not mandatory,
I think. Also I have to add PI, and some other const. declarations in spice.h
They were needed somewhere. (why someone didn't used M_PI and so on instead ?)
In file fte/x11.c, was a prloblem with background color for plot windows. I
changed init_colors() and now we can use color0 variable.
Spice3f5 has a few memory leaks. I suppose that some vectors and maybe other
things are simple 'lost' somewhere. If you (just like me) trying to make this
program better, take care about this also.
Generally I didn't do much with graphisc interface, because it seems to work
quite good. Only problem is core dump, when cliking mouse on help screen.
Manuals are sometimes in error. Vector creation by [ el. el. ...] is not
supported I think. For indexing we must use [low , hi]. For setting 'list'
variables - ( el. el. ... ). Indexing also doesn't work with let xx[...] = yy.
Someone should change these f... manuals.
And now for those who think about makeing this program better. There is a big
problem with memory, when you run a few simulations. Destroy commad does not
free much memory, and after some time you can see that spice uses 3MB, when
you just clean all vectros. Also I don't know how to unload a circuit -
spice hold all sourced files in the "deck" list and there is no way to free
it from command line (or maybe I didn't find any).
Unfortunatelly I am sure that these are not all off the problems
with this program, but now I can use it quite effectively. If anyone will
know anything about bugs-free, good, commannd driven simulator for Linux
__PLEASE__ let me know.
For easer use I made special debug file (conf/debug). I used it for makeing
"debug" version of spice with efence library and -g option. Executable files
from this are located in spice3f5/objdbg/bin, when you do 'util/build linux debug'.
I am an electronic designer, so I really need a good working simulator...
Original readme file is given below.
Michael Widlok (widlok@uci.agh.edu.pl)
Uniersity of Mining and Metallurgy
Krakow, Poland.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This is my (re-)port of Spice3f4 to Linux version 2 (I am not the same
person who ported it before). It also wraps in the latest official
pre-3f5 patches from Berkeley I could find (found in
sp3f4.patch.tar.Z). Support for the MFB interface using the Linux
termcap library and some various Linux features have been ported.
This was not done for the hell of it, but it seemed that something
broke due to some Linux/system/library changes, so I decided to try
porting it from scratch. In fact, if you don't have any problems with
the previous port, your probably fine then. However, if you do have
problems (e.g. exiting Spice leaves you in uppercase mode), or want
MFB for some reason, then try this. It seems to work here.
Basically, I started out with sp3f4.kit.tar.Z. Then, I applied the
most recent patches contained in sp3f4.patch.tar.Z and wrote new Linux
build files: "linux" and "os_linux.h" (some minor mods to the source
were also necessary, protected with linux conditionals).
Since the previous spice3f4.tar.gz port file was generally available,
there was no point in duplicating source, so I just diffed from the
spice3f4.tar.gz tree to freshly ported tree and edited or removed a
few of the diffs. A few of the changes made in spice3f4.tar.gz have
been reverted to the distribution defaults, but one notable change is
that performing the install step will install the necessary files into
/usr/local/spice. You'll need to add /usr/local/spice/bin to your
shell path. See the file conf/linux to change the installation
location (this location gets hard-coded in the spice binaries).
This is a patched file of the original readme.Linux from
spice3f4.tar.gz, and the previous contents by Jeff@EE.Ryerson.Ca is
given below. Just follow the below instructions, so you should be
able to safely do:
./util/build linux
./util/build linux install
You should then find the spice binaries and library files
in e.g. /usr/local/spice. Example files and the man pages
are not installed, so you might want to copy them by hand.
Andrew Veliath (veliaa@rpi.edu)
January 25, 1997
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This is my port of Spice3f4 to Linux. It required a few more changes
than the porting document indicated would be necessary, mostly to do
with supported/unsupported functions in Linux libc & libm.
I've tried to make these changes in as as portable a way as possible,
so it should build cleanly on other Unicies, however I've removed the
MS-DOS support so the tarred and gziped source fits on one disk.
To build spice3, first have a look in the file readme, but you should
be able to just do...
./util/build linux
./util/build install linux
Note that there is a modifyer "gcc" you can try if you have trouble, but
it claims to work around some obscure bug in gcc that I'm positive got
fixed eons ago. To use it anyway, do ./util/build linux gcc.
I found this source through archie, (look for spice3f3.tar.Z, and then
patched it to 3f4 with patches from ic.berkeley.edu), I assume that the
ftp site I got it from has read thier license from Berkeley, which if
it's the same as the 3e2 license states that the holder can distribute
copies free of charge provided it does not fall into hands unfriendly
to the U.S. So... I guess if that's you, please destroy all copies of this
you might have!
Jeff@EE.Ryerson.Ca

7
notes/dbx

@ -0,0 +1,7 @@
A note when using dbx (under unix-type operating systems) to debug spice3:
To avoid a segmentation fault in the initial run, use the following command
in dbx:
setenv SPICE_NO_DATASEG_CHECK "1"
Or, the comparable command in your shell before running dbx. This
disable accurate tracking of how much memory is used.

98
notes/internal

@ -0,0 +1,98 @@
Internal Changes from 3e2
The device structure has changed: The state counter in all device
structures has been moved to correspond to GENstates in the
GENinstance structure.
Also, a new per-device-type function has been added: XXXunsetup,
which deallocates nodes and other resources created in the
XXXsetup function. ("XXX" is the device abbreviation.)
Internal Changes from 3d2
FILE NAMES:
Of the changes to spice3 between 3d2 and 3e1, the
the most obvious is the new filenames. All filesnames
have been converted to lowercase and are at most eight
characters plus an optional dot and three character extension.
This change was made to accomodate MS-DOS and other operating
systems which limit the maximum file name length.
ORGANIZATION
The top level directory contains the installation "readme" file
and a "makedefs" files used by the "build" command.
"src/" contains all of the C source code. This used to be named
"spice3" or "spice3d2" in previous releases.
"src/lib" is the library or "toolkit" portion of Spice3. Within
it are the following subdirectories:
ckt/ All of the analysis code.
ni/ Numerical algorithms (used by ckt routines).
sparse/ Sparse matrix package (used by ckt and ni).
misc/ Miscellaneous utility and portability routines.
dev/ All of the device specific code, with a subdir for
each device implementation.
inp/ Input parsing; could be much smaller.
fte/ The front end. Really bad.
cp/ More front end -- "C shell".
hlp/ The windowed help system.
mfb/ Terminal independant graphics package.
mfbpc/ MFB interface for the IBM PC.
"src/bin" contains the source for all executable programs (the
location for "main( )"). "main.c" is used by spice, nutmeg,
bspice, and cspice (the latter two for MS-DOS). The function
of "main.c" is altered by defining the pre-processor symbols
SIMULATOR (for either spice, bspice, or cspice), BATCH for
bspice, and BATCH and SPICE2 for cspice (no special defines
give nutmeg). Each variant of the simulator uses "conf.c" (or
"bconf.c" or "cconf.c", or "nconf.c" for nutmeg), which is
automatically generated from "config.c". "config.c" is a
template used to select devices and analyses. "tune.c"
("tunepc.c") contains the compiled in pathnames.
"examples/" contains several spice input files.
"lib/" contains standard data files for spice, such as the help
files and MFB capability files.
"man/" contains UNIX style manual pages (ala "man(1)").
"util/" contains utility scripts, such as "build" for running the
recursive "make" and "delall.bat" for deleting the distribution on
MS-DOS systems.
All "Makefile"s have been replaced with "makedefs" (and optionally
"depend" and "makeops"). "makedefs" is combined with other
make definition files with the "build" script.
SOURCE LEVEL CHANGES
(Added features are listed in the "README" file).
DEVICES: The interface to devices has, once again, changed.
The change is small from 3d2. Table size values in the device
information struction are now pointers to integers containing
the table sizes. Per-analyses functions have been surrounded
with "#ifdef AN_xx"/"#else"/"#endif" lines. Note that the
"itf.h" files are stored only in the "include/" subdirectory.
Adding devices to the master list is done in the file
"src/bin/config.c", instead of "FTE/SPIinit.c".
SPARSE MATRIX PACKAGE: the sparse matrix package in Spice3e1
and later is a more efficient implementation than in earlier releases.
The interface is the same.

207
notes/mac_port

@ -0,0 +1,207 @@
Compiling spice with Think C on a Macintosh.
A 68020 (Mac II) with co-processor is required.
The src directory from the spice distribution should be moved into
the C folder.
**** recompile think c libraries ****
Both the ANSI and unix libraries must be recompiled with the
following additional compiler settings:
Generate 68020 instructions
Generate 68881 instructions
4-bytes ints
Native floating-point format
The "console.c" file must be edited and should be removed from
the ANSI project. I actually recompiled copies of the ANSI and
unix libraries that I called ANSI.68881 and unix.68881.
Copy the "console.c" source (a THINK C file) to a suitable
location so that it can be included in the spice project. (See
the next section for details of how "consol.c" must be modified.)
**** creating the project ****
Create a new project and set the Options as follows:
Laguage Settings
Turn on the following options
Define #__STDC__
Recognize trigraphs
enums are always ints
Check pointer types
Language Extension
THINK C
Compiler Settings
Turn on the following options
Generate 68020 instructions
Generate 68881 instructions
4-bytes ints
Native floating-point format
Code Optimization
Turn on all options
Prefix
make sure there is no prefix (remove
default #include <macheaders>)
Note: The Language setting 'Strict Prototype Enforcement' must be
turned off.
Set the project type to application with at least 1024k partition
and turn on the 'Far DATA' option.
*** Adding the code to the project ***
Start Adding the code to the project. The code must be divided
into segments that are less that 32K each when compiled. The
following division has been used:
Segment 1: the ANSI.68881 and unix.68881 libraries.
Segment 2: all *.c files in /src/sparse
Segment 3: all *.c files in /src/lib/ni
Segment 4: all *.c files in /src/lib/misc
Segment 5: files /src/lib/inp/inp2dot.c
and /src/lib/inp/inptree.c
Segment 6: all other *.c files in /src/inp
Segment 7: all *.c files in /src/lib/hlp
Segment 8: all *.c files in /src/lib/cp
except /src/lib/cp/input.c
Segment 9: file /src/lib/ckt/dloadfns.c
Segment 10: files /src/lib/ckt/cktpzstr.c,
/src/lib/ckt/cktsens.c, /src/lib/ckt/dctran.c,
and /src/lib/ckt/distoan.c
Segment 11: all other *.c files in /src/lib/ckt
Segment 12: cmath*.c files in /src/lib/fte
Segment 13: files agraf.c, clip.c, display.c, graf.c,
graphdb.c, plot5.c, plotcurv.c and
postsc.c in /src/lib/fte
Segment 14: files evaluate.c, parse.c, postcoms.c,
and subckt.c in /src/lib/fte
Segment 15: files breakp.c, device.c, doplot.c,
grid.c and shyu.c in /src/lib/fte
Segment 16: files dotcards.c, inp.c, outif.c, rawfile.c,
spiceif.c and vectors.c in /src/lib/fte
Segment 17: all other *.c files in /src/lib/fte
except nutmegif.c
Segment 18: all *.c files in /src/lib/fte/vsrc
and /src/lib/fte/isrc
Segment 19: all *.c files in /src/lib/fte/jfet
Segment 20: all *.c files in /src/lib/fte/vccs,
/src/lib/fte/vcvs, /src/lib/fte/cccs,
and /src/lib/fte/ccvs
Segment 21: all *.c files in /src/lib/fte/asrc
and /src/lib/fte/urc
Segment 22: all *.c files in /src/lib/fte/cap,
/src/lib/fte/ind, and /src/lib/fte/res
Segment 23: all *.c files in /src/lib/fte/csw,
/src/lib/fte/sw, and /src/lib/fte/tra
Segment 24: all *.c files in /src/lib/fte/mos6
Segment 25: all *.c files in /src/lib/fte/mes
Segment 26: all *.c files in /src/lib/fte/ltra
Segment 27: file mos3load.c in /src/lib/fte/mos3
Segment 28: files mos3dist.c, mos3dset.c,
and mos3sld.c in /src/lib/fte/mos3
Segment 29: remaining *.c files in /src/lib/fte/mos3
Segment 30: all *.c files in /src/lib/fte/dio
Segment 31: file mos1load.c in /src/lib/fte/mos1
Segment 32: files mos1dist.c, mos1dset.c,
and mos1sld.c in /src/lib/fte/mos1
Segment 33: remaining *.c files in /src/lib/fte/mos1
Segment 34: file bjtload.c in /src/lib/fte/bjt
Segment 35: files bjtdisto.c, bjtdset.c,
and bjtsload.c in /src/lib/fte/bjt
Segment 36: remaining *.c files in /src/lib/fte/bjt
Segment 37: file mos2load.c in /src/lib/fte/mos2
Segment 38: file mos2dset.c in /src/lib/fte/mos2
Segment 39: files mos2dist.c, and mos2sld.c
in /src/lib/fte/mos2
Segment 40: remaining *.c files in /src/lib/fte/mos2
Segment 41: files b1dset.c, and b1ld.c in /src/lib/fte/bsim1
Segment 42: files b1disto.c, and b1eval.c in /src/lib/fte/bsim1
Segment 43: remaining *.c files in /src/lib/fte/bsim1
Segment 44: files b2eval.c, and b2ld.c in /src/lib/fte/bsim2
Segment 45: remaining *.c files in /src/lib/fte/bsim2
Segment 46: all *.c files in /src/lib/dev/disto,
and devsup.c in /src/lib/dev
Segment 47 all *.c files in /src/lib/mac,
and file /src/bin/main.c
Note that the following files are not included:
/src/lib/cp/input.c
/src/lib/fte/nutmegif.c
Add "console.c" (the copy made as described above) and make the
following alterations to it:
1. The lines:
static char console_environment, noPrint, interrupted;
static short console_refnum;
static MenuHandle appleMenu;
static WindowPeek theConsole;
must be changed to make console_environment and
appleMenu external:
extern char console_environment, noPrint, interrupted;
static char noPrint, interrupted;
static short console_refnum;
extern MenuHandle appleMenu;
static WindowPeek theConsole;
2. Alter the function ProcessEvent() to add a default switch
case. The altered section appears following a doEvent label as
(note: this code fragment has 4-space tabs and long lines
broken to fit an 80-column page; these changes do not affect
the code):
doEvent:
if (event.what == mouseDown) {
switch (FindWindow(event.where, &wp)) {
case inMenuBar:
InitCursor();
choice = MenuSelect(event.where);
goto doMenu;
case inSysWindow:
SystemClick(&event, wp);
break;
default: /* For spice to pass mouse
events to graphs */
if ((WindowPtr) wp != FrontWindow()) {
SelectWindow(wp);
in.cnt = 0;
} /* in.cnt=0 forces console to
return to application */
}
}
Compilation takes about 3 to 4 hours on a 25MHz mac. Set the cache
to at least 256k to eliminate a lot of disk access.
**** makeindx ****
Create a project with the same option settings decribed above.
Add src/bin/makeidx.c, ANSI.68881 and an unmodified version of
"console.c".
Build the makeindex application.
Move the application into lib/helpdir directory of the the spice
distribution. Run it and add the names of the files to be indexed
(nutmeg.txt spice.txt) to the command line and hit return.
**** proc2mod ****
Create a project with the same option settings decribed above.
Add src/bin/proc2mod.c, src/lib/misc/alloc.c, src/lib/misc/string.c
src/lib/inp/inpcfix.c, src/lib/inp/inpeval.c,
src/lib/inp/inpgtok.c, ANSI.68881 and an unmodified
version of console.c.
Build the proc2mod application.

237
notes/porting

@ -0,0 +1,237 @@
(ER - 7/08/99)
These are a few notes on the autoconf porting that is being done.
Autoconf automaticcaly provides #defines (in config.h) that describe
the system that ng-spice is being compiled on. Thus, all the os_xxx.h
files should no longer be necessary.
Here is a (as complete as possible) list of new #defines and their
corresponding #defines in the old build system:
#define HAS_VAX_FPERRORS - unused (should remove the code)
#define MAXPOSINT 4294967295 - don't know about that one
#define MAX_EXP_ARG 87.0 - same
---------- Operating System (os_xxx.h) parameters:
----- Enabling flags
#define AVAIL_MFB -DWANT_MFB passed to cpp
#define AVAIL_X11 X_DISPLAY_MISSING (reversed)
----- String or character constants
#define DIR_CWD "." now in spice.h
#define DIR_PATHSEP "/" now in spice;h
#define DIR_TERM '/' now in spice.h
On Unix, I don't think that there are other possibilities.
We should get rid of those.
----- sprintf( ) format strings
#define TEMPFORMAT "/tmp/%s%d" /* sprintf format for creating temp files */
#define SYSTEM_MAIL "mail -s \"%s (%s) Bug Report\" %s" /* mail command */
#define SYSTEM_PLOT5LPR "lpr -P%s -g %s" /* For printing Unix plot(5) files */
#define SYSTEM_PSLPR "lpr -P%s %s" /* For printing postscript files */
Same for these I guess...
----- System capabilities
#define HAS_ACCESS HAVE_ACCES
#define HAS_ASCII not handled yet
#define HAS_ATRIGH HAVE_ATANH HAVE_ACOSH HAVE_ASINH
#define HAS_BCOPY HAVE_BCOPY
#define HAS_BSDDIRS HAVE_DIR_H
#define HAS_BSDRANDOM unused
#define HAS_BSDRLIMIT HAVE_GETRLIMIT
#define HAS_BSDRUSAGE HAVE_GETRUSAGE
#define HAS_BSDSOCKETS unused
#define HAS_BSDTIME HAVE_GETTIMEOFDAY
#define HAS_BSDTTY HAVE_SGTTY_H
#define HAS_CHDIR removed
#define HAS_CLEARERR removed
#define HAS_CTYPE HAVE_CTYPE_H
#define HAS_DOSDIRS dos only - should remove code
#define HAS_DUP2 HAVE_DUP2
#define HAS_ENVIRON removed
#define HAS_EXIT1 vms only - should remove the code
#define HAS_FCNTL HAVE_FCNTL_H
#define HAS_FTIME HAVE_FTIME
#define HAS_GETCWD HAVE_GETCWD
#define HAS_GETPID removed
#define HAS_GETPW HAVE_PWD_H
#define HAS_GETWD HAVE_GETWD
#define HAS_INDEX HAVE_INDEX
#define HAS_NO_IEEE_LOGB HAVE_LOGB HAVE_SCALB HAVE_SCALBN
#define HAS_NO_IEEE_LOGB_DECL removed
#define HAS_ISATTY HAVE_ISATTY
#define HAS_LONGJUMP removed
#define HAS_MINDATA dos only? - should remove code if so
#define HAS_NOINLINE dos only? - should remove code if so
#define HAS_NOVM dos only? - should remove code if so
#define HAS_NO_ATRIGH_DECL removed
#define HAS_PCTERM dos only - should remove code
#define HAS_POPEN HAVE_POPEN
#define HAS_QSORT HAVE_QSORT
#define HAS_SHORTMACRO dos only - should remove code
#define HAS_STAT STAT_MACROS_BROKEN (reversed)
#define HAS_STDLIB STDC_HEADERS
#define HAS_STRCHR HAVE_STRCHR
#define HAS_STRINGS STDC_HEADERS (reversed) not sure about that one!
#define HAS_SYSTEM removed
#define HAS_SYSVDIRS HAVE_DIRENT_H
#define HAS_SYSVRLIMIT HAVE_ULIMIT
#define HAS_SYSVRUSAGE HAVE_UTIME
#define HAS_SYSVTIME HAVE_TIME
#define HAS_SYSVTTY HAVE_TERMIO_H
#define HAS_TERMCAP HAVE_TERMCAP
#define HAS_TERMREAD don't know what to do with this one
#define HAS_UNIX_SIGS removed
#define HAS_UNLINK removed
#define HAS_VFORK HAVE_VFORK_H
#define HAS_VMSHACK vms only - should remove the code
#define HAS_VPERROR removed
#define HAS_WAIT HAVE_WAIT
plus a few others:
#define HAS_MEMAVL dos only - should remove code
#define HAS_FLAT_INCLUDES macos only - should remove code
#define HAS_BATCHSIM dos only - should remove code
----------------------------------------------------------------------------
PORTING SPICE3e1
Porting Spice3 to a new operating system usually consists of listing
the capabilities of that operating system in a new '.h' file and
including this '.h' file in the standard portability sequence. This
also needs to be done separately for the numerical capabilities of the
system hardware (this consist of only two parameters at present).
For each operating system there is a file in the "include/" directory
named "os_xxx.h", where xxx identifies the given operating system (ex.
"os_bsd.h", "os_aix.h"). These files are selectively #include-d by
"include/port.h". For a new operating system, you should add the
appropriate "#include" line to "include/port.h". Be sure to guard
the new "#include" line with "#ifdef/#endif", as is done with the other
operating system capability files. The same may also need to be done
for your hardware (for the file "hw_xxx.h"), though there is typically
very little difference in hardware.
Note that operating system which are a derivative of another supported
system can '#include' the "os_xxx.h" file from the other system. For
example, "os_aix.h" includes "os_sysv.h", which in turn includes
"os_unix.h".
The entries that can go into a "os_xxx.h" file are described below;
most are simple flags (e.g. HAS_xxxx). To turn on a flag, insert the
"#define" line for that flag; to turn off the flag, simply leave the
"#define" line out. Other entries are strings, others single-quoted
characters or numbers. Be sure to use the same type as the example
values shown.
There are always exceptions to the rule. Some incompatibilities
have not yet been dealt with cleanly; review the other "os_xxx.h"
files, the file "capabil.h", and the file "suffix.h" to understand
how some problems have been handled (note especially the lines like
"#define index strchr"). After trying to compile, you may yet find
non-portable code that is not guarded by one of the following
options. You are encouraged to alter the source code (".c" or ".h"
files) in the style of the current portability scheme.
Note: to enable X11 or MFB, the flag AVAIL_X11 or AVAIL_MFB,
respectively, must be included in the "os_xxx.h" file; this _was_ to
simplify the problems of forgetting to re-edit the "config.h" file,
but this is no longer necessary.
---------- Machine architecture numerics (hw_xxx.h) parameters:
(In the future this will be more complete and will be used for
tuning the accuracy or performance of the numerical algorithms)
#define HAS_VAX_FPERRORS /* Only for Vax */
#define MAXPOSINT 4294967295 /* == 2^32 - 1, maximum positive integer */
#define MAX_EXP_ARG 87.0 /* Approximate largest arg to exp() */
---------- Operating System (os_xxx.h) parameters:
----- Enabling flags
#define AVAIL_MFB /* If the MFB package can work on this system */
#define AVAIL_X11 /* If the X11 Window System can work */
----- String or character constants
#define DIR_CWD "." /* Current working directory */
#define DIR_PATHSEP "/" /* subdirectory separator */
#define DIR_TERM '/' /* Subdirectory component terminator */
----- sprintf( ) format strings
#define TEMPFORMAT "/tmp/%s%d" /* sprintf format for creating temp files */
#define SYSTEM_MAIL "mail -s \"%s (%s) Bug Report\" %s" /* mail command */
#define SYSTEM_PLOT5LPR "lpr -P%s -g %s" /* For printing Unix plot(5) files */
#define SYSTEM_PSLPR "lpr -P%s %s" /* For printing postscript files */
----- System capabilities
#define HAS_ACCESS /* access( ) */
#define HAS_ASCII /* eighth bit of a character is not used */
#define HAS_ATRIGH /* acosh( ), asinh( ), atanh( ) */
#define HAS_BCOPY /* bcopy( ), bzero( ) */
#define HAS_BSDDIRS /* <sys/dir.h> */
#define HAS_BSDRANDOM /* srandom( ) and random( ) */
#define HAS_BSDRLIMIT /* getrlimit( ) returns proc limits */
#define HAS_BSDRUSAGE /* getrusage( ) returns cpu usage */
#define HAS_BSDSOCKETS /* <net/inet.h>, socket( ), etc. */
#define HAS_BSDTIME /* gettimeofday( ) return time */
#define HAS_BSDTTY /* <sgtty.h> */
#define HAS_CHDIR /* for tree filesystems, chdir( ) */
#define HAS_CLEARERR /* clearerr( ), should be in stdio */
#define HAS_CTYPE /* <ctype.h>, iswhite( ), etc. */
#define HAS_DOSDIRS /* Emulate opendir, etc. */
#define HAS_DUP2 /* dup2(a, b) for shifting file descrs. */
#define HAS_ENVIRON /* getenv( ) */
#define HAS_EXIT1 /* If exit status of 1 is normal for procs */
#define HAS_FCNTL /* acosh( ), asinh( ), atanh( ) */
#define HAS_FTIME /* ftime( ), <times.h> */
#define HAS_GETCWD /* getcwd(buf, size) */
#define HAS_GETPID /* getpid( ) to identify processes */
#define HAS_GETPW /* getpwuid( ), etc. */
#define HAS_GETWD /* getwd(buf) */
#define HAS_INDEX /* index( ) instead of strchr( ) */
#define HAS_NO_IEEE_LOGB /* no logb( ) and scalb( ) functions */
#define HAS_NO_IEEE_LOGB_DECL /* logb( ) and scalb( ) not in math.h */
#define HAS_ISATTY /* isatty( ) */
#define HAS_LONGJUMP /* setjmp( ), longjmp( ) */
#define HAS_MINDATA /* Machine has limited data area */
#define HAS_NOINLINE /* Machine has limited data area */
#define HAS_NOVM /* Machine has limited data area */
#define HAS_NO_ATRIGH_DECL /* if asinh( ) is not in math.h */
#define HAS_PCTERM /* For MS-DOS, use PC graphics for MFB */
#define HAS_POPEN /* popen( ), pipe through shell command */
#define HAS_QSORT /* qsort( ) exists */
#define HAS_SHORTMACRO /* If the compiler can't handle long macros */
#define HAS_STAT /* stat( ) returns info on files */
#define HAS_STDLIB /* #include <stdlib.h> for libc defs */
#define HAS_STRCHR /* strchr( ) instead of index( ) */
#define HAS_STRINGS /* #include <strings.h> (else <string.h>) */
#define HAS_SYSTEM /* system( ), execute system command */
#define HAS_SYSVDIRS /* <dirent.h> */
#define HAS_SYSVRLIMIT /* ulimit( ) reports on proc size limit */
#define HAS_SYSVRUSAGE /* utimes( ) reports on cpu usage */
#define HAS_SYSVTIME /* time( ) returns seconds from 1970 */
#define HAS_SYSVTTY /* <termio.h> */
#define HAS_TERMCAP /* tgetxxx( ) */
#define HAS_TERMREAD /* Has "read" syscall from terminals */
#define HAS_UNIX_SIGS /* signal( ), kill( ) */
#define HAS_UNLINK /* unlink( ), for removing files */
#define HAS_VFORK /* BSD-ism, should not be necessary */
#define HAS_VMSHACK /* Stand on your head for VMS */
#define HAS_VPERROR /* perror( ) defined by standard '.h's */
#define HAS_WAIT /* wait( ) wait for processes */

15
notes/spice2

@ -0,0 +1,15 @@
Incompatibilities between spice3 and spice2
The output format of spice3 is slightly different for .print and .plot lines.
Most notably, different traces on plots are not scaled independently. This
is most noticeable on phase/magnitude plots from an AC analysis (also,
phase is displayed in radians). Finally, frequency for ".PRINT AC" lines
is displayed as a complex quantity with an all-zero imaginary component.
For input, "POLY( )" sources are not supported (the non-linear dependent
source provides a more general replacement). Also, the ".ALTER" line
is not supported. The Spice3 parser may be slightly different
on subtle points of reading input (lines need not start at column 1
for instance).

97
src/ChangeLog

@ -0,0 +1,97 @@
2000-04-04 Paolo Nenzi <p.nenzi@ieee.org>
* ngspice.c: Added support for BSIM4.
* Makefile.am: Added support for bsim4 shared library.
2000-01-14 Paolo Nenzi <p.nenzi@ieee.org>
* conf.c: inserted definitions for bsim3v2 and bsim3v1 devices.
It is necessary to include old models for commercially available
components libraries.
1999-12-01 Emmanuel Rouat <emmanuel.rouat@wanadoo.fr>
* source code: created new directory 'frontend' mainly filled with
files from 'fte' - remaing files go into maths/cmaths (complex maths
routines)
1999-11-30 Emmanuel Rouat <emmanuel.rouat@wanadoo.fr>
* tune.c: removed
* conf.c/nconf.c : simplified
1999-09-07 Arno <A.W.Peters@ieee.org>
* conf.c: removed unused variables `devs' and `ans'
* help.c: return value from main() changed to int
1999-09-04 Emmanuel Rouat <emmanuel.rouat@wanadoo.fr>
* main.c: removed #include patchlec.h and suffix.h (and related code)
* Makefile.am: updated to reflect filename changes in fte/
1999-08-31 Emmanuel Rouat <emmanuel.rouat@wanadoo.fr>
* help.c: renamed helpfile 'ngspice'
* main.c: renamed helpfile 'ngspice'
1999-08-28 Emmanuel Rouat <emmanuel.rouat@wanadoo.fr>
* Removed all #includes of misc.h and util.h (now in spice.h)
1999-08-24 Paolo Nenzi <pnenzi@ieee.ing.uniroma1.it>
* conf.c: linked the jfet2 model to the devices table.
1999-08-08 Emmanuel Rouat <emmanuel.rouat@wanadoo.fr>
* makeidx.c: removed HAS_MAC_ARCARGV related code
* main.c: removed all code related to dos and macos features
1999-08-06 Emmanuel Rouat <emmanuel.rouat@wanadoo.fr>
* proc2mod.c: removed test on HAS_VPERROR (always true on Unix)
* main.c (main): changed HAS_ISATTY in HAVE_ISATTY
(main): removed test on HAS_LONGJUMP (always have it)
(main): removed test on HAS_UNIX_SIGS (always true on Unix)
(main): removed test on HAS_UNLINK (always true on Unix)
1999-08-05 Emmanuel Rouat <emmanuel.rouat@wanadoo.fr>
* main.c: changed HAS_GETPW in HAVE_PWD_H
(main): removed test on HAS_GETPID
1999-08-02 Emmanuel Rouat <emmanuel.rouat@wanadoo.fr>
* Makefile.am (LIBS): removed '-lm' since it is handled by autoconf
1999-08-01 Emmanuel Rouat <emmanuel.rouat@wanadoo.fr>
* conf.c: changed SIMinfo entry to 'ngspice'
* Makefile.am: changed binary name to ngspice
1999-07-31 Emmanuel Rouat <emmanuel.rouat@wanadoo.fr>
* Makefile.am: added @X_CFLAGS@ to INCLUDES list
1999-07-30 Emmanuel Rouat <emmanuel.rouat@wanadoo.fr>
* Makefile.am : fixed breaking of 'make distcheck'
29-07-1999 emmanuel.rouat@wanadoo.fr (Manu Rouat)
* tune.c: includes <config.h> which defines SPICEBINDIR etc
28-07-1999 emmanuel.rouat@wanadoo.fr (Manu Rouat)
* help.c: Changed HAS_X11 define to X_DISPLAY_MISSING (supplied by
autoconf in config.h)
* removed HAS_X11 in defs flag in Makefile.am

162
src/Makefile.am

@ -0,0 +1,162 @@
## Process this file with automake to produce Makefile.in
SUBDIRS = analysis circuit devices frontend hlp maths misc parser include
bin_PROGRAMS = ngspice nutmeg help sconvert proc2mod multidec makeidx
EXTRA_DIST = ngspice.txt ngspice.idx
helpdatadir = $(pkgdatadir)/helpdir
helpdata_DATA = ngspice.idx ngspice.txt
DYNAMIC_DEVICELIBS = \
devices/asrc/libasrc.la \
devices/bjt/libbjt.la \
devices/bsim1/libbsim1.la \
devices/bsim2/libbsim2.la \
devices/bsim3/libbsim3.la \
devices/bsim4/libbsim4.la \
devices/bsim3v1/libbsim3v1.la \
devices/bsim3v2/libbsim3v2.la \
devices/cap/libcap.la \
devices/cccs/libcccs.la \
devices/ccvs/libccvs.la \
devices/csw/libcsw.la \
devices/devsup/libdevsup.la \
devices/dio/libdio.la \
devices/disto/libdisto.la \
devices/ind/libind.la \
devices/isrc/libisrc.la \
devices/jfet/libjfet.la \
devices/jfet2/libjfet2.la \
devices/ltra/libltra.la \
devices/cccs/libcccs.la \
devices/ccvs/libccvs.la \
devices/csw/libcsw.la \
devices/devsup/libdevsup.la \
devices/dio/libdio.la \
devices/disto/libdisto.la \
devices/ind/libind.la \
devices/isrc/libisrc.la \
devices/jfet/libjfet.la \
devices/jfet2/libjfet2.la \
devices/ltra/libltra.la \
devices/mes/libmes.la \
devices/mos1/libmos1.la \
devices/mos2/libmos2.la \
devices/mos3/libmos3.la \
devices/mos6/libmos6.la \
devices/res/libres.la \
devices/sw/libsw.la \
devices/tra/libtra.la \
devices/urc/liburc.la \
devices/vccs/libvccs.la \
devices/vcvs/libvcvs.la \
devices/vsrc/libvsrc.la
## Build ngspice first:
ngspice_SOURCES = \
conf.c \
conf.h \
ngspice.c
ngspice_LDADD = \
spice.o \
frontend/libfte.a \
$(DYNAMIC_DEVICELIBS) \
analysis/libckt.a \
parser/libparser.a \
hlp/libhlp.a \
circuit/libinp.a \
maths/cmaths/libcmaths.a \
maths/ni/libni.a \
maths/sparse/libsparse.a \
misc/libmisc.a
spice.o: main.c
$(COMPILE) -DSIMULATOR -o spice.o -c $(srcdir)/main.c
## nutmeg:
nutmeg_SOURCES = \
main.c \
conf.c \
conf.h \
nutmeg.c
nutmeg_LDADD = \
frontend/libfte.a \
parser/libparser.a \
hlp/libhlp.a \
maths/cmaths/libcmaths.a \
misc/libmisc.a
## help:
help_SOURCES = help.c
help_LDADD = \
hlp/libhlp.a \
parser/libparser.a \
misc/libmisc.a
## sconvert:
sconvert_SOURCES = sconvert.c
sconvert_LDADD = \
frontend/libfte.a \
parser/libparser.a \
misc/libmisc.a
## proc2mod:
proc2mod_SOURCES = proc2mod.c
proc2mod_LDADD = \
parser/libparser.a \
circuit/libinp.a \
misc/libmisc.a
## multidec:
multidec_SOURCES = multidec.c
multidec_LDADD = \
maths/sparse/libsparse.a \
misc/libmisc.a
## makeidx:
makeidx_SOURCES = makeidx.c
makeidx_LDADD = \
misc/libmisc.a
## create index for online help:
all:
./makeidx $(srcdir)/ngspice.txt
## General Includes and libraries:
INCLUDES = -I$(top_srcdir)/src/include -I$(top_srcdir)/src/devices @X_CFLAGS@
LIBS = @LIBS@ @X_LIBS@ @X_PRE_LIBS@ @X_EXTRA_LIBS@
MAINTAINERCLEANFILES = Makefile.in

60
src/analysis/ChangeLog

@ -0,0 +1,60 @@
2000-04-04 Paolo Nenzi <p.nenzi@ieee.or
* noisean.c: Merged the previous code with the new one included in
bsim4 distribution. This code originated from Weidong Lu
(bsim group).
1999-12-20 Paolo Nenzi <p.nenzi@ieee.org>
* noisean.c:
Bug: he ac noise analysis in Spice3f4 has a serious bug. In interactive mode,
it fails to reproduce frequency dependence known to exist. In batch (Spice2)
mode, it works only if a corresponding ac analysis has been run first.
Fix: This bug is fixed by providing a call to CKTload() in noisean.c as shown
by the source code patch which is attached below.
1999-09-08 Emmanuel Rouat <emmanuel.rouat@wanadoo.fr>
* ckt.h: created (and included in Makefile.am)
1999-09-07 Arno <A.W.Peters@ieee.org>
* cktpzstr.c: reformatted and corrected(?) complex if condition.
1999-08-28 Emmanuel Rouat <emmanuel.rouat@wanadoo.fr>
* Removed all #includes of misc.h and util.h (now in spice.h)
1999-08-27 Paolo Nenzi <pnenzi@ieee.ing.uniroma1.it>
* Removed GENERIC and #include "suffix.h" from all the files.
GENERIC has been replaced by void. ANSIfied all functions with
protoize.
1999-08-26 Paolo Nenzi <pnenzi@ieee.ing.uniroma1.it>
* cktacct.c: added #include "spmatrix.h" to avoid implicit declaration
warning at compile time.
* dctran.c: ansified and substituted void with void.
* tranasq.c: same as before.
* traninit.c: same as before.
* transetp.c: same as before.
1999-08-08 Emmanuel Rouat <emmanuel.rouat@wanadoo.fr>
* Removed all HAS_SHORTMACRO and HAS_FLATINCLUDES code in directory
* cktdest.c (and other files): changed HAS_SENSE2 in WANT_SENSE2
1999-08-04 Paolo Nenzi <pnenzi@ieee.ing.uniroma1.it>
* changed dctrcurv.c: added code for temperature sweeps and
resistance sweeps. Now you can execute .dc temp <start> <stop>
<increment> to do a temp sweep, temp is the keyword for temp
sweeps (The code comes from a patch supplied by Serban-Mihai
Popescu <serbanp@ix.netcom.com>. To do a resitance sweep just
insert resistor name to the .cd line:.dc vin -5 5 1 rin 100 1000 10.
Resistance and temperature sweeps can be nested.

106
src/analysis/Makefile.am

@ -0,0 +1,106 @@
## Process this file with automake to produce Makefile.in
noinst_LIBRARIES = libckt.a
libckt_a_SOURCES = \
acan.c \
acaskq.c \
acsetp.c \
cktaccpt.c \
cktacct.c \
cktacdum.c \
cktask.c \
cktaskaq.c \
cktasknq.c \
cktbindn.c \
cktbkdum.c \
cktclrbk.c \
cktcrte.c \
cktdelt.c \
cktdest.c \
cktdisto.c \
cktdlti.c \
cktdltm.c \
cktdltn.c \
cktdojob.c \
cktdump.c \
cktfbran.c \
cktfdev.c \
cktfnda.c \
cktfndm.c \
cktfnode.c \
cktftask.c \
cktgrnd.c \
ckti2nod.c \
cktic.c \
cktinit.c \
cktlnkeq.c \
cktload.c \
cktmapn.c \
cktmask.c \
cktmcrt.c \
cktmkcur.c \
cktmknod.c \
cktmkvol.c \
cktmpar.c \
cktnames.c \
cktnewan.c \
cktneweq.c \
cktnewn.c \
cktnodn.c \
cktnoise.c \
cktntask.c \
cktnum2n.c \
cktop.c \
cktparam.c \
cktpartn.c \
cktpmnam.c \
cktpname.c \
cktpzld.c \
cktpzset.c \
cktpzstr.c \
cktsens.c \
cktsetap.c \
cktsetbk.c \
cktsetnp.c \
cktsetup.c \
cktsgen.c \
cktsopt.c \
ckttemp.c \
cktterr.c \
ckttroub.c \
ckttrunc.c \
ckttyplk.c \
daskq.c \
dcoaskq.c \
dcop.c \
dcosetp.c \
dctaskq.c \
dctran.c \
dctrcurv.c \
dctsetp.c \
distoan.c \
dkerproc.c \
dloadfns.c \
dsetparm.c \
naskq.c \
nevalsrc.c \
ninteg.c \
noisean.c \
nsetparm.c \
pzan.c \
pzaskq.c \
pzsetp.c \
sensaskq.c \
senssetp.c \
tfanal.c \
tfaskq.c \
tfsetp.c \
tranaskq.c \
traninit.c \
transetp.c \
ckt.h
INCLUDES = -I$(top_srcdir)/src/include -I$(top_srcdir)/src/devices
MAINTAINERCLEANFILES = Makefile.in

277
src/analysis/acan.c

@ -0,0 +1,277 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
#include "ngspice.h"
#include <stdio.h>
#include "cktdefs.h"
#include "acdefs.h"
#include "devdefs.h"
#include "sperror.h"
int
ACan(CKTcircuit *ckt, int restart)
{
double freq;
double freqTol; /* tolerence parameter for finding final frequency */
double startdTime;
double startsTime;
double startlTime;
double startcTime;
double startkTime;
double startTime;
int error;
int numNames;
IFuid *nameList;
IFuid freqUid;
static void *acPlot;
void *plot;
if(((ACAN*)ckt->CKTcurJob)->ACsaveFreq == 0 || restart) {
/* start at beginning */
if (((ACAN*)ckt->CKTcurJob)->ACnumberSteps < 1)
((ACAN*)ckt->CKTcurJob)->ACnumberSteps = 1;
switch(((ACAN*)ckt->CKTcurJob)->ACstepType) {
case DECADE:
((ACAN*)ckt->CKTcurJob)->ACfreqDelta =
exp(log(10.0)/((ACAN*)ckt->CKTcurJob)->ACnumberSteps);
break;
case OCTAVE:
((ACAN*)ckt->CKTcurJob)->ACfreqDelta =
exp(log(2.0)/((ACAN*)ckt->CKTcurJob)->ACnumberSteps);
break;
case LINEAR:
if (((ACAN*)ckt->CKTcurJob)->ACnumberSteps-1 > 1)
((ACAN*)ckt->CKTcurJob)->ACfreqDelta =
(((ACAN*)ckt->CKTcurJob)->ACstopFreq -
((ACAN*)ckt->CKTcurJob)->ACstartFreq)/
(((ACAN*)ckt->CKTcurJob)->ACnumberSteps-1);
else
((ACAN*)ckt->CKTcurJob)->ACfreqDelta = HUGE;
break;
default:
return(E_BADPARM);
}
error = CKTop(ckt,
(ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITJCT,
(ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITFLOAT,
ckt->CKTdcMaxIter);
if(error) return(error);
ckt->CKTmode = (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITSMSIG;
error = CKTload(ckt);
if(error) return(error);
error = CKTnames(ckt,&numNames,&nameList);
if(error) return(error);
if (ckt->CKTkeepOpInfo) {
/* Dump operating point. */
error = (*(SPfrontEnd->OUTpBeginPlot))((void *)ckt,
(void*)ckt->CKTcurJob, "AC Operating Point",
(IFuid)NULL,IF_REAL,numNames,nameList, IF_REAL,&plot);
if(error) return(error);
CKTdump(ckt,(double)0,plot);
(*(SPfrontEnd->OUTendPlot))(plot);
}
(*(SPfrontEnd->IFnewUid))((void *)ckt,&freqUid,(IFuid)NULL,
"frequency", UID_OTHER,(void **)NULL);
error = (*(SPfrontEnd->OUTpBeginPlot))((void *)ckt,
(void*)ckt->CKTcurJob,
ckt->CKTcurJob->JOBname,freqUid,IF_REAL,numNames,nameList,
IF_COMPLEX,&acPlot);
if(error) return(error);
if (((ACAN*)ckt->CKTcurJob)->ACstepType != LINEAR) {
(*(SPfrontEnd->OUTattributes))((void *)acPlot,NULL,
OUT_SCALE_LOG, NULL);
}
freq = ((ACAN*)ckt->CKTcurJob)->ACstartFreq;
} else { /* continue previous analysis */
freq = ((ACAN*)ckt->CKTcurJob)->ACsaveFreq;
((ACAN*)ckt->CKTcurJob)->ACsaveFreq = 0; /* clear the 'old' frequency */
}
switch(((ACAN*)ckt->CKTcurJob)->ACstepType) {
case DECADE:
case OCTAVE:
freqTol = ((ACAN*)ckt->CKTcurJob)->ACfreqDelta *
((ACAN*)ckt->CKTcurJob)->ACstopFreq * ckt->CKTreltol;
break;
case LINEAR:
freqTol = ((ACAN*)ckt->CKTcurJob)->ACfreqDelta * ckt->CKTreltol;
break;
default:
return(E_BADPARM);
}
startTime = SPfrontEnd->IFseconds();
startdTime = ckt->CKTstat->STATdecompTime;
startsTime = ckt->CKTstat->STATsolveTime;
startlTime = ckt->CKTstat->STATloadTime;
startcTime = ckt->CKTstat->STATcombineTime;
startkTime = ckt->CKTstat->STATsyncTime;
while(freq <= ((ACAN*)ckt->CKTcurJob)->ACstopFreq+freqTol) {
if( (*(SPfrontEnd->IFpauseTest))() ) {
/* user asked us to pause via an interrupt */
((ACAN*)ckt->CKTcurJob)->ACsaveFreq = freq;
return(E_PAUSE);
}
ckt->CKTomega = 2.0 * M_PI *freq;
ckt->CKTmode = (ckt->CKTmode&MODEUIC) | MODEAC;
error = NIacIter(ckt);
if (error) {
ckt->CKTcurrentAnalysis = DOING_AC;
ckt->CKTstat->STATacTime += SPfrontEnd->IFseconds() - startTime;
ckt->CKTstat->STATacDecompTime += ckt->CKTstat->STATdecompTime -
startdTime;
ckt->CKTstat->STATacSolveTime += ckt->CKTstat->STATsolveTime -
startsTime;
ckt->CKTstat->STATacLoadTime += ckt->CKTstat->STATloadTime -
startlTime;
ckt->CKTstat->STATacCombTime += ckt->CKTstat->STATcombineTime -
startcTime;
ckt->CKTstat->STATacSyncTime += ckt->CKTstat->STATsyncTime -
startkTime;
return(error);
}
#ifdef WANT_SENSE2
if(ckt->CKTsenInfo && (ckt->CKTsenInfo->SENmode&ACSEN) ){
save = ckt->CKTmode;
ckt->CKTmode=(ckt->CKTmode&MODEUIC)|MODEDCOP|MODEINITSMSIG;
save1 = ckt->CKTsenInfo->SENmode;
ckt->CKTsenInfo->SENmode = ACSEN;
if(freq == ((ACAN*)ckt->CKTcurJob)->ACstartFreq){
ckt->CKTsenInfo->SENacpertflag = 1;
}
else{
ckt->CKTsenInfo->SENacpertflag = 0;
}
if(error = CKTsenAC(ckt)) return (error);
ckt->CKTmode = save;
ckt->CKTsenInfo->SENmode = save1;
}
#endif
error = CKTacDump(ckt,freq,acPlot);
if (error) {
ckt->CKTcurrentAnalysis = DOING_AC;
ckt->CKTstat->STATacTime += SPfrontEnd->IFseconds() - startTime;
ckt->CKTstat->STATacDecompTime += ckt->CKTstat->STATdecompTime -
startdTime;
ckt->CKTstat->STATacSolveTime += ckt->CKTstat->STATsolveTime -
startsTime;
ckt->CKTstat->STATacLoadTime += ckt->CKTstat->STATloadTime -
startlTime;
ckt->CKTstat->STATacCombTime += ckt->CKTstat->STATcombineTime -
startcTime;
ckt->CKTstat->STATacSyncTime += ckt->CKTstat->STATsyncTime -
startkTime;
return(error);
}
/* increment frequency */
switch(((ACAN*)ckt->CKTcurJob)->ACstepType) {
case DECADE:
case OCTAVE:
freq *= ((ACAN*)ckt->CKTcurJob)->ACfreqDelta;
if(((ACAN*)ckt->CKTcurJob)->ACfreqDelta==1) goto endsweep;
break;
case LINEAR:
freq += ((ACAN*)ckt->CKTcurJob)->ACfreqDelta;
if(((ACAN*)ckt->CKTcurJob)->ACfreqDelta==0) goto endsweep;
break;
default:
return(E_INTERN);
}
}
endsweep:
(*(SPfrontEnd->OUTendPlot))(acPlot);
ckt->CKTcurrentAnalysis = 0;
ckt->CKTstat->STATacTime += SPfrontEnd->IFseconds() - startTime;
ckt->CKTstat->STATacDecompTime += ckt->CKTstat->STATdecompTime -
startdTime;
ckt->CKTstat->STATacSolveTime += ckt->CKTstat->STATsolveTime -
startsTime;
ckt->CKTstat->STATacLoadTime += ckt->CKTstat->STATloadTime -
startlTime;
ckt->CKTstat->STATacCombTime += ckt->CKTstat->STATcombineTime -
startcTime;
ckt->CKTstat->STATacSyncTime += ckt->CKTstat->STATsyncTime -
startkTime;
return(0);
}
/* CKTacLoad(ckt)
* this is a driver program to iterate through all the various
* ac load functions provided for the circuit elements in the
* given circuit
*/
int
CKTacLoad(register CKTcircuit *ckt)
{
extern SPICEdev *DEVices[];
register int i;
register int size;
int error;
#ifdef PARALLEL_ARCH
long type = MT_ACLOAD, length = 1;
#endif /* PARALLEL_ARCH */
double startTime;
startTime = SPfrontEnd->IFseconds();
size = SMPmatSize(ckt->CKTmatrix);
for (i=0;i<=size;i++) {
*(ckt->CKTrhs+i)=0;
*(ckt->CKTirhs+i)=0;
}
SMPcClear(ckt->CKTmatrix);
for (i=0;i<DEVmaxnum;i++) {
if ( ((*DEVices[i]).DEVacLoad != NULL) && (ckt->CKThead[i] != NULL) ){
error = (*((*DEVices[i]).DEVacLoad))(ckt->CKThead[i],ckt);
#ifdef PARALLEL_ARCH
if (error) goto combine;
#else
if(error) return(error);
#endif /* PARALLEL_ARCH */
}
}
#ifdef PARALLEL_ARCH
combine:
ckt->CKTstat->STATloadTime += SPfrontEnd->IFseconds() - startTime;
startTime = SPfrontEnd->IFseconds();
/* See if any of the DEVload functions bailed. If not, proceed. */
IGOP_( &type, &error, &length, "max" );
ckt->CKTstat->STATsyncTime += SPfrontEnd->IFseconds() - startTime;
if (error == OK) {
startTime = SPfrontEnd->IFseconds();
SMPcCombine( ckt->CKTmatrix, ckt->CKTrhs, ckt->CKTrhsSpare,
ckt->CKTirhs, ckt->CKTirhsSpare );
ckt->CKTstat->STATcombineTime += SPfrontEnd->IFseconds() - startTime;
return(OK);
} else {
return(error);
}
#else
ckt->CKTstat->STATloadTime += SPfrontEnd->IFseconds() - startTime;
return(OK);
#endif /* PARALLEL_ARCH */
}

63
src/analysis/acaskq.c

@ -0,0 +1,63 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/*
*/
#include "ngspice.h"
#include <stdio.h>
#include "ifsim.h"
#include "iferrmsg.h"
#include "acdefs.h"
#include "cktdefs.h"
/* ARGSUSED */
int
ACaskQuest(CKTcircuit *ckt, void *anal, int which, IFvalue *value)
{
switch(which) {
case AC_START:
value->rValue = ((ACAN*)anal)->ACstartFreq;
break;
case AC_STOP:
value->rValue = ((ACAN*)anal)->ACstopFreq ;
break;
case AC_STEPS:
value->iValue = ((ACAN*)anal)->ACnumberSteps;
break;
case AC_DEC:
if(((ACAN*)anal)->ACstepType == DECADE) {
value->iValue=1;
} else {
value->iValue=0;
}
break;
case AC_OCT:
if(((ACAN*)anal)->ACstepType == OCTAVE) {
value->iValue=1;
} else {
value->iValue=0;
}
break;
case AC_LIN:
if(((ACAN*)anal)->ACstepType == LINEAR) {
value->iValue=1;
} else {
value->iValue=0;
}
break;
default:
return(E_BADPARM);
}
return(OK);
}

105
src/analysis/acsetp.c

@ -0,0 +1,105 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
#include "ngspice.h"
#include <stdio.h>
#include "ifsim.h"
#include "iferrmsg.h"
#include "acdefs.h"
#include "cktdefs.h"
/* ARGSUSED */
int
ACsetParm(CKTcircuit *ckt, void *anal, int which, IFvalue *value)
{
switch(which) {
case AC_START:
if (value->rValue <= 0.0) {
errMsg = copy("Frequency of 0 is invalid");
((ACAN*)anal)->ACstartFreq = 1.0;
return(E_PARMVAL);
}
((ACAN*)anal)->ACstartFreq = value->rValue;
break;
case AC_STOP:
if (value->rValue <= 0.0) {
errMsg = copy("Frequency of 0 is invalid");
((ACAN*)anal)->ACstartFreq = 1.0;
return(E_PARMVAL);
}
((ACAN*)anal)->ACstopFreq = value->rValue;
break;
case AC_STEPS:
((ACAN*)anal)->ACnumberSteps = value->iValue;
break;
case AC_DEC:
if(value->iValue) {
((ACAN*)anal)->ACstepType = DECADE;
} else {
if( ((ACAN*)anal)->ACstepType == DECADE) {
((ACAN*)anal)->ACstepType = 0;
}
}
break;
case AC_OCT:
if(value->iValue) {
((ACAN*)anal)->ACstepType = OCTAVE;
} else {
if( ((ACAN*)anal)->ACstepType == OCTAVE) {
((ACAN*)anal)->ACstepType = 0;
}
}
break;
case AC_LIN:
if(value->iValue) {
((ACAN*)anal)->ACstepType = LINEAR;
} else {
if( ((ACAN*)anal)->ACstepType == LINEAR) {
((ACAN*)anal)->ACstepType = 0;
}
}
break;
default:
return(E_BADPARM);
}
return(OK);
}
static IFparm ACparms[] = {
{ "start", AC_START, IF_SET|IF_ASK|IF_REAL, "starting frequency" },
{ "stop", AC_STOP, IF_SET|IF_ASK|IF_REAL, "ending frequency" },
{ "numsteps", AC_STEPS,IF_SET|IF_ASK|IF_INTEGER, "number of frequencies"},
{ "dec", AC_DEC, IF_SET|IF_FLAG, "step by decades" },
{ "oct", AC_OCT, IF_SET|IF_FLAG, "step by octaves" },
{ "lin", AC_LIN, IF_SET|IF_FLAG, "step linearly" }
};
SPICEanalysis ACinfo = {
{
"AC",
"A.C. Small signal analysis",
sizeof(ACparms)/sizeof(IFparm),
ACparms
},
sizeof(ACAN),
FREQUENCYDOMAIN,
1,
ACsetParm,
ACaskQuest,
NULL,
ACan
};

130
src/analysis/ckt.h

@ -0,0 +1,130 @@
/*
* Copyright (c) 1985 Thomas L. Quarles
* Modified 1999 Paolo Nenzi - Removed non STDC definitions
* Kept only prototypes (structs defined in struct.h) ER
*/
#ifndef CKT_H_INCLUDED
#define CKT_H_INCLUDED
/* function prototypes */
int ACan( CKTcircuit *, int );
int ACaskQuest( CKTcircuit *, void *, int , IFvalue *);
int ACsetParm( CKTcircuit *, void *, int , IFvalue *);
int CKTacDump( CKTcircuit *, double , void *);
int CKTacLoad( CKTcircuit *);
int CKTaccept( CKTcircuit *);
int CKTacct( CKTcircuit *, void *, int , IFvalue *);
int CKTask( void *, void *, int , IFvalue *, IFvalue *);
int CKTaskAnalQ( void *, void *, int , IFvalue *, IFvalue *);
int CKTaskNodQst( void *, void *, int , IFvalue *, IFvalue *);
int CKTbindNode( void *, void *, int , void *);
void CKTbreakDump( CKTcircuit *);
int CKTclrBreak( CKTcircuit *);
int CKTconvTest( CKTcircuit *);
int CKTcrtElt( void *, void *, void **, IFuid );
int CKTdelTask( void *, void *);
int CKTdestroy( void *);
int CKTdltAnal( void *, void *, void *);
int CKTdltInst( void *, void *);
int CKTdltMod( void *, void *);
int CKTdltNod( void *, void *);
int CKTdoJob( void *, int , void *);
void CKTdump( CKTcircuit *, double, void *);
int CKTfndAnal( void *, int *, void **, IFuid , void *, IFuid );
int CKTfndBranch( CKTcircuit *, IFuid);
int CKTfndDev( void *, int *, void **, IFuid , void *, IFuid );
int CKTfndMod( void *, int *, void **, IFuid );
int CKTfndNode( void *, void **, IFuid );
int CKTfndTask( void *, void **, IFuid );
int CKTground( void *, void **, IFuid );
int CKTic( CKTcircuit *);
int CKTinit( void **);
int CKTinst2Node( void *, void *, int , void **, IFuid *);
int CKTlinkEq(CKTcircuit*,CKTnode*);
int CKTload( CKTcircuit *);
int CKTmapNode( void *, void **, IFuid );
int CKTmkCur( CKTcircuit *, CKTnode **, IFuid , char *);
int CKTmkNode(CKTcircuit*,CKTnode**);
int CKTmkVolt( CKTcircuit *, CKTnode **, IFuid , char *);
int CKTmodAsk( void *, void *, int , IFvalue *, IFvalue *);
int CKTmodCrt( void *, int , void **, IFuid );
int CKTmodParam( void *, void *, int , IFvalue *, IFvalue *);
int CKTnames(CKTcircuit *, int *, IFuid **);
int CKTnewAnal( void *, int , IFuid , void **, void *);
int CKTnewEq( void *, void **, IFuid );
int CKTnewNode( void *, void **, IFuid );
int CKTnewTask( void *, void **, IFuid );
IFuid CKTnodName( CKTcircuit *, int );
void CKTnodOut( CKTcircuit *);
CKTnode * CKTnum2nod( CKTcircuit *, int );
int CKTop(CKTcircuit *, long, long, int );
int CKTpModName( char *, IFvalue *, CKTcircuit *, int , IFuid , GENmodel **);
int CKTpName( char *, IFvalue *, CKTcircuit *, int , char *, GENinstance **);
int CKTparam( void *, void *, int , IFvalue *, IFvalue *);
int CKTpzFindZeros( CKTcircuit *, PZtrial **, int * );
int CKTpzLoad( CKTcircuit *, SPcomplex * );
int CKTpzSetup( CKTcircuit *, int);
int CKTsenAC( CKTcircuit *);
int CKTsenComp( CKTcircuit *);
int CKTsenDCtran( CKTcircuit *);
int CKTsenLoad( CKTcircuit *);
void CKTsenPrint( CKTcircuit *);
int CKTsenSetup( CKTcircuit *);
int CKTsenUpdate( CKTcircuit *);
int CKTsetAnalPm( void *, void *, int , IFvalue *, IFvalue *);
int CKTsetBreak( CKTcircuit *, double );
int CKTsetNodPm( void *, void *, int , IFvalue *, IFvalue *);
int CKTsetOpt( void *, void *, int , IFvalue *);
int CKTsetup( CKTcircuit *);
int CKTunsetup(CKTcircuit *ckt);
int CKTtemp( CKTcircuit *);
char *CKTtrouble(void *, char *);
void CKTterr( int , CKTcircuit *, double *);
int CKTtrunc( CKTcircuit *, double *);
int CKTtypelook( char *);
int DCOaskQuest( CKTcircuit *, void *, int , IFvalue *);
int DCOsetParm( CKTcircuit *, void *, int , IFvalue *);
int DCTaskQuest( CKTcircuit *, void *, int , IFvalue *);
int DCTsetParm( CKTcircuit *, void *, int , IFvalue *);
int DCop( CKTcircuit *);
int DCtrCurv( CKTcircuit *, int );
int DCtran( CKTcircuit *, int );
int DISTOan(CKTcircuit *, int);
int NOISEan(CKTcircuit *, int);
int PZan( CKTcircuit *, int );
int PZinit( CKTcircuit * );
int PZpost( CKTcircuit * );
int PZaskQuest( CKTcircuit *, void *, int , IFvalue *);
int PZsetParm( CKTcircuit *, void *, int , IFvalue *);
int SENaskQuest( CKTcircuit *, void *, int , IFvalue *);
void SENdestroy( SENstruct *);
int SENsetParm( CKTcircuit *, void *, int , IFvalue *);
int SENstartup( CKTcircuit *);
int SPIinit( IFfrontEnd *, IFsimulator **);
char * SPerror( int );
int TFanal( CKTcircuit *, int );
int TFaskQuest( CKTcircuit *, void *, int , IFvalue *);
int TFsetParm( CKTcircuit *, void *, int , IFvalue *);
int TRANaskQuest( CKTcircuit *, void *, int , IFvalue *);
int TRANsetParm( CKTcircuit *, void *, int , IFvalue *);
int TRANinit(CKTcircuit *, JOB *);
int NIacIter( CKTcircuit * );
int NIcomCof( CKTcircuit * );
int NIconvTest(CKTcircuit * );
void NIdestroy(CKTcircuit * );
int NIinit( CKTcircuit * );
int NIintegrate( CKTcircuit *, double *, double *, double , int );
int NIiter( CKTcircuit * , int );
int NIpzMuller(PZtrial **, PZtrial *);
int NIpzComplex(PZtrial **, PZtrial *);
int NIpzSym(PZtrial **, PZtrial *);
int NIpzSym2(PZtrial **, PZtrial *);
int NIreinit( CKTcircuit *);
int NIsenReinit( CKTcircuit *);
IFfrontEnd *SPfrontEnd;
#endif /*CKT*/

47
src/analysis/cktaccpt.c

@ -0,0 +1,47 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/* CKTaccept(ckt)
* this is a driver program to iterate through all the various
* accept functions provided for the circuit elements in the
* given circuit
*/
#include "ngspice.h"
#include <stdio.h>
#include "smpdefs.h"
#include "cktdefs.h"
#include "devdefs.h"
#include "sperror.h"
int
CKTaccept(register CKTcircuit *ckt)
{
extern SPICEdev *DEVices[];
register int i;
int error;
for (i=0;i<DEVmaxnum;i++) {
if ( ((*DEVices[i]).DEVaccept != NULL) && (ckt->CKThead[i] != NULL) ){
error = (*((*DEVices[i]).DEVaccept))(ckt,ckt->CKThead[i]);
if(error) return(error);
}
}
#ifdef PREDICTOR
/* now, move the sols vectors around */
temp = ckt->CKTsols[7];
for ( i=7;i>0;i--) {
ckt->CKTsols[i] = ckt->CKTsols[i-1];
}
ckt->CKTsols[0]=temp;
size = SMPmatSize(ckt->CKTmatrix);
for(i=0;i<=size;i++) {
ckt->CKTsols[0][i]=ckt->CKTrhs[i];
}
#endif /* PREDICTOR */
return(OK);
}

142
src/analysis/cktacct.c

@ -0,0 +1,142 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/*
*/
/*
* CKTacct
* get the specified accounting item into 'value' in the
* given circuit 'ckt'.
*/
#include "ngspice.h"
#include "const.h"
#include "optdefs.h"
#include "ifsim.h"
#include <stdio.h>
#include "cktdefs.h"
#include "spmatrix.h"
/* ARGSUSED */
int
CKTacct(CKTcircuit *ckt, void *anal, int which, IFvalue *val)
{
switch(which) {
case OPT_EQNS:
val->iValue = ckt->CKTmaxEqNum;
break;
case OPT_ORIGNZ:
if ( ckt->CKTmatrix != NULL ) {
val->iValue = spOriginalCount((char *)ckt->CKTmatrix);
} else {
val->iValue = 0;
}
break;
case OPT_FILLNZ:
if ( ckt->CKTmatrix != NULL ) {
val->iValue = spFillinCount((char *)ckt->CKTmatrix);
} else {
val->iValue = 0;
}
break;
case OPT_TOTALNZ:
if ( ckt->CKTmatrix != NULL ) {
val->iValue = spElementCount((char *)ckt->CKTmatrix);
} else {
val->iValue = 0;
}
break;
case OPT_ITERS:
val->iValue = ckt->CKTstat->STATnumIter;
break;
case OPT_TRANIT:
val->iValue = ckt->CKTstat->STATtranIter;
break;
case OPT_TRANCURITER:
val->iValue = ckt->CKTstat->STATnumIter - ckt->CKTstat->STAToldIter;
break;
case OPT_TRANPTS:
val->iValue = ckt->CKTstat->STATtimePts;
break;
case OPT_TRANACCPT:
val->iValue = ckt->CKTstat->STATaccepted;
break;
case OPT_TRANRJCT:
val->iValue = ckt->CKTstat->STATrejected;
break;
case OPT_TOTANALTIME:
val->rValue = ckt->CKTstat->STATtotAnalTime;
break;
case OPT_TRANTIME:
val->rValue = ckt->CKTstat->STATtranTime;
break;
case OPT_ACTIME:
val->rValue = ckt->CKTstat->STATacTime;
break;
case OPT_LOADTIME:
val->rValue = ckt->CKTstat->STATloadTime;
break;
case OPT_SYNCTIME:
val->rValue = ckt->CKTstat->STATsyncTime;
break;
case OPT_COMBTIME:
val->rValue = ckt->CKTstat->STATcombineTime;
break;
case OPT_REORDTIME:
val->rValue = ckt->CKTstat->STATreorderTime;
break;
case OPT_DECOMP:
val->rValue = ckt->CKTstat->STATdecompTime;
break;
case OPT_SOLVE:
val->rValue = ckt->CKTstat->STATsolveTime;
break;
case OPT_TRANLOAD:
val->rValue = ckt->CKTstat->STATtranLoadTime;
break;
case OPT_TRANSYNC:
val->rValue = ckt->CKTstat->STATtranSyncTime;
break;
case OPT_TRANCOMB:
val->rValue = ckt->CKTstat->STATtranCombTime;
break;
case OPT_TRANDECOMP:
val->rValue = ckt->CKTstat->STATtranDecompTime;
break;
case OPT_TRANSOLVE:
val->rValue = ckt->CKTstat->STATtranSolveTime;
break;
case OPT_TRANTRUNC:
val->rValue = ckt->CKTstat->STATtranTruncTime;
break;
case OPT_ACLOAD:
val->rValue = ckt->CKTstat->STATacLoadTime;
break;
case OPT_ACSYNC:
val->rValue = ckt->CKTstat->STATacSyncTime;
break;
case OPT_ACCOMB:
val->rValue = ckt->CKTstat->STATacCombTime;
break;
case OPT_ACDECOMP:
val->rValue = ckt->CKTstat->STATacDecompTime;
break;
case OPT_ACSOLVE:
val->rValue = ckt->CKTstat->STATacSolveTime;
break;
case OPT_TEMP:
val->rValue = ckt->CKTtemp - CONSTCtoK;
break;
case OPT_TNOM:
val->rValue = ckt->CKTnomTemp - CONSTCtoK;
break;
default:
return(-1);
}
return(0);
}

43
src/analysis/cktacdum.c

@ -0,0 +1,43 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/* CKTacDump(ckt,freq,file)
* this is a simple program to dump the complex rhs vector
* into the rawfile.
*/
#include "ngspice.h"
#include <stdio.h>
#include "smpdefs.h"
#include "cktdefs.h"
#include "iferrmsg.h"
#include "ifsim.h"
int
CKTacDump(register CKTcircuit *ckt, double freq, void *plot)
{
register double *rhsold;
register double *irhsold;
register int i;
register IFcomplex *data;
IFvalue freqData;
IFvalue valueData;
rhsold = ckt->CKTrhsOld;
irhsold = ckt->CKTirhsOld;
freqData.rValue = freq;
valueData.v.numValue = ckt->CKTmaxEqNum-1;
data = (IFcomplex *) MALLOC((ckt->CKTmaxEqNum-1)*sizeof(IFcomplex));
valueData.v.vec.cVec = data;
for (i=0;i<ckt->CKTmaxEqNum-1;i++) {
data[i].real = rhsold[i+1];
data[i].imag = irhsold[i+1];
}
(*(SPfrontEnd->OUTpData))(plot,&freqData,&valueData);
FREE(data);
return(OK);
}

45
src/analysis/cktask.c

@ -0,0 +1,45 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/* CKTask
* Ask questions about a specified device.
*/
#include "ngspice.h"
#include <stdio.h>
#include "cktdefs.h"
#include "ifsim.h"
#include "devdefs.h"
#include "sperror.h"
extern SPICEdev *DEVices[];
int
CKTask(void *ckt, void *fast, int which, IFvalue *value, IFvalue *selector)
{
register int type = ((GENinstance *)fast)->GENmodPtr->GENmodType;
int error;
#ifdef PARALLEL_ARCH
long msgtype, length;
long from = ((GENinstance *)fast)->GENowner;
#endif /* PARALLEL_ARCH */
if((*DEVices[type]).DEVask) {
error = DEVices[type]->DEVask((CKTcircuit *)ckt,
(GENinstance *)fast,which,value,selector);
} else {
error = E_BADPARM;
}
#ifdef PARALLEL_ARCH
msgtype = MT_ASK;
length = sizeof(IFvalue);
BRDCST_(&msgtype, (char *)value, &length, &from);
msgtype++;
length = sizeof(int);
BRDCST_(&msgtype, (char *)&error, &length, &from);
#endif /* PARALLEL_ARCH */
return(error);
}

25
src/analysis/cktaskaq.c

@ -0,0 +1,25 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
#include "ngspice.h"
#include <stdio.h>
#include "tskdefs.h"
#include "jobdefs.h"
#include "cktdefs.h"
#include "ifsim.h"
#include "iferrmsg.h"
extern SPICEanalysis *analInfo[];
/* ARGSUSED */
int
CKTaskAnalQ(void *ckt, void *analPtr, int parm, IFvalue *value, IFvalue *selector)
{
register int type = ((JOB *)analPtr)->JOBtype;
if((analInfo[type]->askQuest) == NULL) return(E_BADPARM);
return( (*(analInfo[type]->askQuest))((CKTcircuit*)ckt,analPtr,parm,value));
}

43
src/analysis/cktasknq.c

@ -0,0 +1,43 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/*
*CKTaskNodQst
*
* ask about a parameter on a node.
*/
#include "ngspice.h"
#include <stdio.h>
#include "ifsim.h"
#include "iferrmsg.h"
#include "cktdefs.h"
/* ARGSUSED */
int
CKTaskNodQst(void *ckt, void *node, int parm, IFvalue *value, IFvalue *selector)
{
if(!node) return(E_BADPARM);
switch(parm) {
case PARM_NS:
value->rValue = ((CKTnode *)node)->nodeset;
break;
case PARM_IC:
value->rValue = ((CKTnode *)node)->ic;
break;
case PARM_NODETYPE:
value->iValue = ((CKTnode *)node)->type;
break;
default:
return(E_BADPARM);
}
return(OK);
}

54
src/analysis/cktbindn.c

@ -0,0 +1,54 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/* CKTbindNode
* bind a node of the specified device of the given type to its place
* in the specified circuit.
*/
#include "ngspice.h"
#include <stdio.h>
#include "ifsim.h"
#include "smpdefs.h"
#include "cktdefs.h"
#include "devdefs.h"
#include "sperror.h"
extern SPICEdev *DEVices[];
/*ARGSUSED*/
int
CKTbindNode(void *ckt, void *fast, int term, void *node)
{
int mappednode;
register int type = ((GENinstance *)fast)->GENmodPtr->GENmodType;
mappednode = ((CKTnode *)node)->number;
if(*((*DEVices[type]).DEVpublic.terms) >= term && term >0 ) {
switch(term) {
default: return(E_NOTERM);
case 1:
((GENinstance *)fast)->GENnode1 = mappednode;
break;
case 2:
((GENinstance *)fast)->GENnode2 = mappednode;
break;
case 3:
((GENinstance *)fast)->GENnode3 = mappednode;
break;
case 4:
((GENinstance *)fast)->GENnode4 = mappednode;
break;
case 5:
((GENinstance *)fast)->GENnode5 = mappednode;
break;
}
return(OK);
} else {
return(E_NOTERM);
}
}

25
src/analysis/cktbkdum.c

@ -0,0 +1,25 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/*
*/
/* CKTbreakDump(ckt) - dump the breakpoint table associated with
* the given circuit
*/
#include "ngspice.h"
#include <stdio.h>
#include "cktdefs.h"
void
CKTbreakDump(CKTcircuit *ckt)
{
register int i;
for(i=0;i<ckt->CKTbreakSize;i++) {
(void)printf("breakpoint table entry %d is %g\n",i,*(ckt->CKTbreaks+i));
}
}

39
src/analysis/cktclrbk.c

@ -0,0 +1,39 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/*
*/
/* CKTclrBreak(ckt)
* delete the first time from the breakpoint table for the given circuit
*/
#include "ngspice.h"
#include <stdio.h>
#include "cktdefs.h"
#include "sperror.h"
int
CKTclrBreak(register CKTcircuit *ckt)
{
double *tmp;
register int j;
if(ckt->CKTbreakSize >2) {
tmp = (double *)MALLOC((ckt->CKTbreakSize-1)*sizeof(double));
if(tmp == (double *)NULL) return(E_NOMEM);
for(j=1;j<ckt->CKTbreakSize;j++) {
*(tmp+j-1) = *(ckt->CKTbreaks+j);
}
FREE(ckt->CKTbreaks);
ckt->CKTbreakSize--;
ckt->CKTbreaks=tmp;
} else {
*(ckt->CKTbreaks)= *(ckt->CKTbreaks+1);
*(ckt->CKTbreaks+1) = ckt->CKTfinalTime;
}
return(OK);
}

47
src/analysis/cktcrte.c

@ -0,0 +1,47 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/*
*/
/* CKTcrtElement(ckt,type,inModPtr,inInstPtr,name,subname)
* Create a device of the specified type, with the given name, using
* the specified model in the named circuit.
*/
#include "ngspice.h"
#include <stdio.h>
#include "ifsim.h"
#include "cktdefs.h"
#include "devdefs.h"
#include "sperror.h"
/*ARGSUSED*/
int
CKTcrtElt(void *ckt, void *inModPtr, void **inInstPtr, IFuid name)
{
GENinstance *instPtr = NULL;
GENmodel *modPtr=(GENmodel*)inModPtr;
extern SPICEdev *DEVices[];
int error;
int type;
if((GENmodel *)modPtr==(GENmodel*)NULL) return(E_NOMOD);
type = ((GENmodel*)modPtr)->GENmodType;
error =CKTfndDev(ckt,&type,(void**)&instPtr,name,inModPtr,(char *)NULL );
if (error== OK) {
if(inInstPtr) *inInstPtr=(void *)instPtr;
return(E_EXISTS);
} else if (error != E_NODEV) return(error);
instPtr = (GENinstance *)MALLOC(*DEVices[type]->DEVinstSize);
if(instPtr == (GENinstance *)NULL) return(E_NOMEM);
instPtr->GENname = name;
instPtr->GENmodPtr = modPtr;
instPtr->GENnextInstance = modPtr->GENinstances;
modPtr->GENinstances = instPtr;
if(inInstPtr != NULL) *inInstPtr = (void *)instPtr;
return(OK);
}

27
src/analysis/cktdelt.c

@ -0,0 +1,27 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
#include "ngspice.h"
#include <stdio.h>
#include "tskdefs.h"
#include "jobdefs.h"
#include "ifsim.h"
#include "iferrmsg.h"
/* ARGSUSED */
int
CKTdelTask(void *ckt, void *task)
{
JOB *job;
JOB *old=NULL;
for(job = ((TSKtask*)task)->jobs; job; job=job->JOBnextJob){
if(old) FREE(old);
old=job;
}
if(old)FREE(old);
FREE(task);
return(OK);
}

61
src/analysis/cktdest.c

@ -0,0 +1,61 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/*
*/
/* CKTdestroy(ckt)
* this is a driver program to iterate through all the various
* destroy functions provided for the circuit elements in the
* given circuit
*/
#include "ngspice.h"
#include <stdio.h>
#include "cktdefs.h"
#include "devdefs.h"
#include "ifsim.h"
#include "sperror.h"
extern SPICEdev *DEVices[];
int
CKTdestroy(void *inCkt)
{
register CKTcircuit *ckt = (CKTcircuit *)inCkt;
register int i;
register CKTnode *node;
register CKTnode *nnode;
#ifdef WANT_SENSE2
if(ckt->CKTsenInfo){
if(ckt->CKTrhsOp) FREE(ckt->CKTrhsOp);
if(ckt->CKTsenRhs) FREE(ckt->CKTsenRhs);
if(ckt->CKTseniRhs) FREE(ckt->CKTseniRhs);
SENdestroy(ckt->CKTsenInfo);
}
#endif
for (i=0;i<DEVmaxnum;i++) {
if ( ((*DEVices[i]).DEVdestroy != NULL) && (ckt->CKThead[i] != NULL) ){
(*((*DEVices[i]).DEVdestroy))(&(ckt->CKThead[i]));
}
}
for(i=0;i<=ckt->CKTmaxOrder+1;i++){
FREE(ckt->CKTstates[i]);
}
if(ckt->CKTmatrix) SMPdestroy(ckt->CKTmatrix);
if(ckt->CKTbreaks) FREE(ckt->CKTbreaks);
for(node = ckt->CKTnodes; node; ) {
nnode = node->next;
FREE(node);
node = nnode;
}
ckt->CKTnodes = (CKTnode *)NULL;
ckt->CKTlastNode = (CKTnode *)NULL;
FREE(ckt);
return(OK);
}

177
src/analysis/cktdisto.c

@ -0,0 +1,177 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1988 Jaijeet S Roychowdhury
**********/
/*
* CKTdisto (ckt, mode)
*/
#include "ngspice.h"
#include "cktdefs.h"
#include "devdefs.h"
#include "vsrc/vsrcdefs.h"
#include "isrc/isrcdefs.h"
#include "fteconst.h"
#include "iferrmsg.h"
#include "distodef.h"
#include "sperror.h"
#include <stdio.h>
int
CKTdisto (register CKTcircuit *ckt, int mode)
{
extern SPICEdev *DEVices[];
register DISTOAN* cv = (DISTOAN*) (ckt->CKTcurJob);
register int i;
int error=0;
int size;
switch(mode) {
case D_SETUP:
for (i=0;i<DEVmaxnum;i++) {
if ( ((*DEVices[i]).DEVdisto != NULL) && (ckt->CKThead[i] != NULL) ){
error = (*((*DEVices[i]).DEVdisto))(mode,ckt->CKThead[i],ckt);
if(error) return(error);
}
}
break;
case D_TWOF1:
case D_THRF1:
case D_F1PF2:
case D_F1MF2:
case D_2F1MF2:
size = SMPmatSize(ckt->CKTmatrix);
for (i=1; i<=size; i++)
{
ckt->CKTrhs[i] = 0.0;
ckt->CKTirhs[i] = 0.0;
}
for (i=0;i<DEVmaxnum;i++) {
if ( ((*DEVices[i]).DEVdisto != NULL) && (ckt->CKThead[i] != NULL) ){
error = (*((*DEVices[i]).DEVdisto))(mode,ckt->CKThead[i],ckt);
if(error) return(error);
}
}
break;
case D_RHSF1:
cv->Df2given = 0; /* will change if any F2 source is found */
case D_RHSF2:
{
int vcode;
int icode;
double mag=0.0;
double phase=0.0;
int size;
size = SMPmatSize(ckt->CKTmatrix);
for (i=0;i<=size;i++) {
*(ckt->CKTrhs+i)=0;
*(ckt->CKTirhs+i)=0;
}
vcode = CKTtypelook("Vsource");
icode = CKTtypelook("Isource");
if(vcode >= 0) {
/* voltage sources are in this version, so use them */
register VSRCinstance *here;
register VSRCmodel *model;
for(model = (VSRCmodel *)ckt->CKThead[vcode];model != NULL;
model=model->VSRCnextModel){
for(here=model->VSRCinstances;here!=NULL;
here=here->VSRCnextInstance) {
/* check if the source has a distortion input*/
if (here->VSRCdGiven) {
if (here->VSRCdF2given) cv->Df2given = 1;
if ((here->VSRCdF1given) && (mode == D_RHSF1)) {
mag = here->VSRCdF1mag;
phase = here->VSRCdF1phase;
}
else if ((here->VSRCdF2given) && (mode == D_RHSF2)) {
mag = here->VSRCdF2mag;
phase = here->VSRCdF2phase;
}
if (((here->VSRCdF1given) && (mode == D_RHSF1)) ||
((here->VSRCdF2given) && (mode == D_RHSF2))) {
*(ckt->CKTrhs + here->VSRCbranch) = 0.5*mag* cos(M_PI*phase/180.0);
*(ckt->CKTirhs + here->VSRCbranch) = 0.5*mag*sin(M_PI*phase/180.0);
}
}
}
}
}
if(icode >= 0 ) {
/* current sources are in this version, so use them */
register ISRCinstance *here;
register ISRCmodel *model;
for(model= (ISRCmodel *)ckt->CKThead[icode];model != NULL;
model=model->ISRCnextModel){
for(here=model->ISRCinstances;here!=NULL;
here=here->ISRCnextInstance) {
/* check if the source has a distortion input*/
if (here->ISRCdGiven) {
if (here->ISRCdF2given) cv->Df2given = 1;
if ((here->ISRCdF1given) && (mode == D_RHSF1)) {
mag = here->ISRCdF1mag;
phase = here->ISRCdF1phase;
}
else if ((here->ISRCdF2given) && (mode == D_RHSF2)) {
mag = here->ISRCdF2mag;
phase = here->ISRCdF2phase;
}
if (((here->ISRCdF1given) && (mode == D_RHSF1)) ||
((here->ISRCdF2given) && (mode == D_RHSF2))) {
*(ckt->CKTrhs + here->ISRCposNode) = - 0.5 * mag
* cos(M_PI*phase/180.0);
*(ckt->CKTrhs + here->ISRCnegNode) = 0.5 * mag * cos(
M_PI*phase/180.0);
*(ckt->CKTirhs + here->ISRCposNode) = - 0.5 * mag * sin(
M_PI*phase/180.0);
*(ckt->CKTirhs + here->ISRCnegNode) = 0.5 * mag * sin(
M_PI*phase/180.0);
}
}
}
}
}
}
error = 0;
break;
default:
error = E_BADPARM;
break;
}
return(error);
}

25
src/analysis/cktdlti.c

@ -0,0 +1,25 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/*
*/
/* CKTdltInst
* delete the specified instance - not yet supported in spice
*/
#include "ngspice.h"
#include <stdio.h>
#include "cktdefs.h"
#include "ifsim.h"
#include "sperror.h"
/* ARGSUSED */
int
CKTdltInst(void *ckt, void *instance)
{
return(E_UNSUPP);
}

45
src/analysis/cktdltm.c

@ -0,0 +1,45 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/* CKTdltMod
* delete the specified model - not yet supported in spice
*/
#include "ngspice.h"
#include <stdio.h>
#include "cktdefs.h"
#include "ifsim.h"
#include "sperror.h"
/* ARGSUSED */
int
CKTdltMod(void *cktp, void *modPtr)
{
CKTcircuit *ckt = (CKTcircuit *) cktp;
GENmodel *m = (GENmodel *) modPtr, *mod, **prevp;
GENinstance *h, *next_i;
int error;
prevp = &ckt->CKThead[m->GENmodType];
for (mod = *prevp; m && mod != m; mod = mod->GENnextModel)
prevp = &mod->GENnextModel;
if (!mod)
return OK;
*prevp = m->GENnextModel;
for (h = m->GENinstances; h; h = next_i) {
next_i = h->GENnextInstance;
error = (*(SPfrontEnd->IFdelUid))((void *)ckt,h->GENname,
UID_INSTANCE);
tfree(h);
}
error = (*(SPfrontEnd->IFdelUid))((void *)ckt,m->GENmodName, UID_MODEL);
tfree(m);
return(OK);
}

59
src/analysis/cktdltn.c

@ -0,0 +1,59 @@
/**********
Copyright 1992 Regents of the University of California. All rights reserved.
**********/
/* CKTdltNod
*/
#include "ngspice.h"
#include <stdio.h>
#include "cktdefs.h"
#include "ifsim.h"
#include "sperror.h"
int CKTdltNNum(void *cktp, int num);
/* ARGSUSED */
int
CKTdltNod(void *ckt, void *node)
{
return CKTdltNNum(ckt, ((CKTnode *) node)->number);
}
int
CKTdltNNum(void *cktp, int num)
{
CKTcircuit *ckt = (CKTcircuit *) cktp;
CKTnode *n, *prev, *node, *sprev;
int error;
prev = NULL;
node = NULL;
sprev = NULL;
for (n = ckt->CKTnodes; n; n = n->next) {
if (n->number == num) {
node = n;
sprev = prev;
}
prev = n;
}
if (!node)
return OK;
ckt->CKTmaxEqNum -= 1;
if (!sprev) {
ckt->CKTnodes = node->next;
} else {
sprev->next = node->next;
}
if (node == ckt->CKTlastNode)
ckt->CKTlastNode = sprev;
error = (*(SPfrontEnd->IFdelUid))((void *)ckt,node->name, UID_SIGNAL);
tfree(node);
return error;
}

146
src/analysis/cktdojob.c

@ -0,0 +1,146 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
#include "ngspice.h"
#include "cktdefs.h"
#include <stdio.h>
#include "sperror.h"
#include "trandefs.h"
extern SPICEanalysis *analInfo[];
extern int ANALmaxnum;
int
CKTdoJob(void *inCkt, int reset, void *inTask)
{
CKTcircuit *ckt = (CKTcircuit *)inCkt;
TSKtask *task = (TSKtask *)inTask;
JOB *job;
double startTime;
int error, i, error2;
#ifdef WANT_SENSE2
int senflag;
static int sens_num = -1;
/* Sensitivity is special */
if (sens_num < 0) {
for (i = 0; i < ANALmaxnum; i++)
if (!strcmp("SENS2", analInfo[i]->public.name))
break;
sens_num = i;
}
#endif
startTime = (*(SPfrontEnd->IFseconds))( );
ckt->CKTtemp = task->TSKtemp;
ckt->CKTnomTemp = task->TSKnomTemp;
ckt->CKTmaxOrder = task->TSKmaxOrder;
ckt->CKTintegrateMethod = task->TSKintegrateMethod;
ckt->CKTbypass = task->TSKbypass;
ckt->CKTdcMaxIter = task->TSKdcMaxIter;
ckt->CKTdcTrcvMaxIter = task->TSKdcTrcvMaxIter;
ckt->CKTtranMaxIter = task->TSKtranMaxIter;
ckt->CKTnumSrcSteps = task->TSKnumSrcSteps;
ckt->CKTnumGminSteps = task->TSKnumGminSteps;
ckt->CKTminBreak = task->TSKminBreak;
ckt->CKTabstol = task->TSKabstol;
ckt->CKTpivotAbsTol = task->TSKpivotAbsTol;
ckt->CKTpivotRelTol = task->TSKpivotRelTol;
ckt->CKTreltol = task->TSKreltol;
ckt->CKTchgtol = task->TSKchgtol;
ckt->CKTvoltTol = task->TSKvoltTol;
ckt->CKTgmin = task->TSKgmin;
ckt->CKTdelmin = task->TSKdelmin;
ckt->CKTtrtol = task->TSKtrtol;
ckt->CKTdefaultMosL = task->TSKdefaultMosL;
ckt->CKTdefaultMosW = task->TSKdefaultMosW;
ckt->CKTdefaultMosAD = task->TSKdefaultMosAD;
ckt->CKTdefaultMosAS = task->TSKdefaultMosAS;
ckt->CKTfixLimit = task->TSKfixLimit;
ckt->CKTnoOpIter = task->TSKnoOpIter;
ckt->CKTtryToCompact = task->TSKtryToCompact;
ckt->CKTbadMos3 = task->TSKbadMos3;
ckt->CKTkeepOpInfo = task->TSKkeepOpInfo;
ckt->CKTtroubleNode = 0;
ckt->CKTtroubleElt = NULL;
#ifdef NEWTRUNC
ckt->CKTlteReltol = task->TSKlteReltol;
ckt->CKTlteAbstol = task->TSKlteAbstol;
#endif /* NEWTRUNC */
error = 0;
if (reset) {
ckt->CKTdelta = 0.0;
ckt->CKTtime = 0.0;
ckt->CKTcurrentAnalysis = 0;
#ifdef WANT_SENSE2
senflag = 0;
if (sens_num < ANALmaxnum)
for (job = task->jobs; !error && job; job = job->JOBnextJob) {
if (job->JOBtype == sens_num) {
senflag = 1;
ckt->CKTcurJob = job;
ckt->CKTsenInfo = (SENstruct *) job;
error = (*(analInfo[sens_num]->an_func))(ckt, reset);
}
}
if (ckt->CKTsenInfo && (!senflag || error))
FREE(ckt->CKTsenInfo);
#endif
/* normal reset */
if (!error)
error = CKTunsetup(ckt);
if (!error)
error = CKTsetup(ckt);
if (!error)
error = CKTtemp(ckt);
if (error)
return error;
}
error2 = OK;
/* Analysis order is important */
for (i = 0; i < ANALmaxnum; i++) {
#ifdef WANT_SENSE2
if (i == sens_num)
continue;
#endif
for (job = task->jobs; job; job = job->JOBnextJob) {
if (job->JOBtype == i) {
ckt->CKTcurJob=job;
error = OK;
if (analInfo[i]->an_init)
error = (*(analInfo[i]->an_init))(ckt, job);
if (!error && analInfo[i]->do_ic)
error = CKTic(ckt);
if (!error)
error = (*(analInfo[i]->an_func))(ckt, reset);
if (error)
error2 = error;
}
}
}
ckt->CKTstat->STATtotAnalTime += (*(SPfrontEnd->IFseconds))( ) - startTime;
#ifdef WANT_SENSE2
if (ckt->CKTsenInfo)
SENdestroy(ckt->CKTsenInfo);
#endif
return(error2);
}

29
src/analysis/cktdump.c

@ -0,0 +1,29 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/*
*/
/* CKTdump(ckt)
* this is a simple program to dump the rhs vector to stdout
*/
#include "ngspice.h"
#include <stdio.h>
#include "smpdefs.h"
#include "cktdefs.h"
void
CKTdump(register CKTcircuit *ckt, double ref, void *plot)
{
IFvalue refData;
IFvalue valData;
refData.rValue = ref;
valData.v.numValue = ckt->CKTmaxEqNum-1;
valData.v.vec.rVec = ckt->CKTrhsOld+1;
(*(SPfrontEnd->OUTpData))(plot,&refData,&valData);
}

36
src/analysis/cktfbran.c

@ -0,0 +1,36 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/*
*/
/* CKTfndBranch(ckt,name)
* this is a driver program to iterate through all the various
* findBranch functions provided for the circuit elements in the
* given circuit
*/
#include "ngspice.h"
#include <stdio.h>
#include "cktdefs.h"
#include "devdefs.h"
int
CKTfndBranch(register CKTcircuit *ckt, IFuid name)
{
extern SPICEdev *DEVices[];
register int i;
int j;
for (i=0;i<DEVmaxnum;i++) {
if ((*DEVices[i]).DEVfindBranch != NULL && ckt->CKThead[i] != NULL) {
j = (*((*DEVices[i]).DEVfindBranch))(ckt,ckt->CKThead[i],name);
if(j != 0) return(j);
}
}
return(0);
}

86
src/analysis/cktfdev.c

@ -0,0 +1,86 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
#include "ngspice.h"
#include <stdio.h>
#include "ifsim.h"
#include "cktdefs.h"
#include "sperror.h"
int
CKTfndDev(void *Ckt, int *type, void **fast, IFuid name, void *modfast, IFuid modname)
{
register CKTcircuit *ckt=(CKTcircuit *)Ckt;
register GENinstance *here;
register GENmodel *mods;
if((GENinstance **)fast != (GENinstance **)NULL &&
*(GENinstance **)fast != (GENinstance *)NULL) {
/* already have fast, so nothing much to do */
/* just get & set type */
if(type) *type = (*((GENinstance**)fast))->GENmodPtr->GENmodType;
return(OK);
}
if(modfast) {
/* have model, just need device */
mods = (GENmodel*)modfast;
for(here = mods->GENinstances ; here != NULL;
here = here->GENnextInstance) {
if (here->GENname == name) {
if(fast != NULL) *(GENinstance **)fast = here;
if(type) *type = mods->GENmodType;
return(OK);
}
}
return(E_NODEV);
}
if(*type >=0 && *type < DEVmaxnum) {
/* have device type, need to find model & device */
/* look through all models */
for(mods=(GENmodel *)ckt->CKThead[*type]; mods != NULL ;
mods = mods->GENnextModel) {
/* and all instances */
if(modname == (char *)NULL || mods->GENmodName == modname) {
for(here = mods->GENinstances ; here != NULL;
here = here->GENnextInstance) {
if (here->GENname == name) {
if(fast != 0) *(GENinstance **)fast = here;
return(OK);
}
}
if(mods->GENmodName == modname) {
return(E_NODEV);
}
}
}
return(E_NOMOD);
} else if(*type == -1) {
/* look through all types (UGH - worst case - take forever) */
for(*type = 0;*type <DEVmaxnum;(*type)++) {
/* need to find model & device */
/* look through all models */
for(mods=(GENmodel *)ckt->CKThead[*type];mods!=NULL;
mods = mods->GENnextModel) {
/* and all instances */
if(modname == (char *)NULL || mods->GENmodName == modname) {
for(here = mods->GENinstances ; here != NULL;
here = here->GENnextInstance) {
if (here->GENname == name) {
if(fast != 0) *(GENinstance **)fast = here;
return(OK);
}
}
if(mods->GENmodName == modname) {
return(E_NODEV);
}
}
}
}
*type = -1;
return(E_NODEV);
} else return(E_BADPARM);
}

36
src/analysis/cktfnda.c

@ -0,0 +1,36 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/*
*/
/* CKTfndAnal
* find the given Analysis given its name and return the Analysis pointer
*/
#include "ngspice.h"
#include <stdio.h>
#include "ifsim.h"
#include "jobdefs.h"
#include "tskdefs.h"
#include "sperror.h"
#include "cktdefs.h"
/* ARGSUSED */
int
CKTfndAnal(void *ckt, int *analIndex, void **anal, IFuid name, void *inTask, IFuid taskName)
{
TSKtask *task = (TSKtask *)inTask;
register JOB *here;
for (here = ((TSKtask *)task)->jobs;here;here = here->JOBnextJob) {
if(strcmp(here->JOBname,name)==0) {
if(anal) *anal = (void *)here;
return(OK);
}
}
return(E_NOTFOUND);
}

53
src/analysis/cktfndm.c

@ -0,0 +1,53 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/*
*/
#include "ngspice.h"
#include <stdio.h>
#include "cktdefs.h"
#include "ifsim.h"
#include "sperror.h"
int
CKTfndMod(void *ckt, int *type, void **modfast, IFuid modname)
{
register GENmodel *mods;
if(modfast != NULL && *(GENmodel **)modfast != NULL) {
/* already have modfast, so nothing to do */
if(type) *type = (*(GENmodel **)modfast)->GENmodType;
return(OK);
}
if(*type >=0 && *type < DEVmaxnum) {
/* have device type, need to find model */
/* look through all models */
for(mods=((CKTcircuit *)ckt)->CKThead[*type]; mods != NULL ;
mods = mods->GENnextModel) {
if(mods->GENmodName == modname) {
*modfast = (char *)mods;
return(OK);
}
}
return(E_NOMOD);
} else if(*type == -1) {
/* look through all types (UGH - worst case - take forever) */
for(*type = 0;*type <DEVmaxnum;(*type)++) {
/* need to find model & device */
/* look through all models */
for(mods=((CKTcircuit *)ckt)->CKThead[*type];mods!=NULL;
mods = mods->GENnextModel) {
if(mods->GENmodName == modname) {
*modfast = (char *)mods;
return(OK);
}
}
}
*type = -1;
return(E_NOMOD);
} else return(E_BADPARM);
}

33
src/analysis/cktfnode.c

@ -0,0 +1,33 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/*
*/
/* CKTfndNode
* find the given node given its name and return the node pointer
*/
#include "ngspice.h"
#include <stdio.h>
#include "ifsim.h"
#include "sperror.h"
#include "cktdefs.h"
/* ARGSUSED */
int
CKTfndNode(void *ckt, void **node, IFuid name)
{
register CKTnode *here;
for (here = ((CKTcircuit *)ckt)->CKTnodes; here; here = here->next) {
if(here->name == name) {
if(node) *node = (char *)here;
return(OK);
}
}
return(E_NOTFOUND);
}

25
src/analysis/cktftask.c

@ -0,0 +1,25 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/*
*/
/* CKTfndTask
* find the specified task - not yet supported in spice
*/
#include "ngspice.h"
#include <stdio.h>
#include "cktdefs.h"
#include "ifsim.h"
#include "sperror.h"
/* ARGSUSED */
int
CKTfndTask(void *ckt, void **taskPtr, IFuid taskName)
{
return(E_UNSUPP);
}

46
src/analysis/cktgrnd.c

@ -0,0 +1,46 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/*
*/
/* CKTground(ckt,node)
* specify the node to be the ground node of the given circuit
*/
#include "ngspice.h"
#include <stdio.h>
#include "cktdefs.h"
#include "ifsim.h"
#include "sperror.h"
int
CKTground(void *inCkt, void **node, IFuid name)
{
register CKTcircuit *ckt = (CKTcircuit *)inCkt;
if(ckt->CKTnodes) {
if(ckt->CKTnodes->name) {
/*already exists - keep old name, but return it */
if(node)*node = (char *)ckt->CKTnodes;
return(E_EXISTS);
}
ckt->CKTnodes->name = name;
ckt->CKTnodes->type = SP_VOLTAGE;
ckt->CKTnodes->number = 0;
} else {
ckt->CKTnodes = (CKTnode *)MALLOC(sizeof(CKTnode));
if(ckt->CKTnodes == NULL) return(E_NOMEM);
ckt->CKTnodes->name = name;
ckt->CKTnodes->type = SP_VOLTAGE;
ckt->CKTnodes->number = 0;
ckt->CKTnodes->next = (CKTnode *)NULL;
ckt->CKTlastNode = ckt->CKTnodes;
}
if(node)*node = (char *)ckt->CKTnodes;
return(OK);
}

66
src/analysis/ckti2nod.c

@ -0,0 +1,66 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/*
*/
/* CKTinst2Node
* get the name and node pointer for a node given a device it is
* bound to and the terminal of the device.
*/
#include "ngspice.h"
#include <stdio.h>
#include "ifsim.h"
#include "sperror.h"
#include "cktdefs.h"
#include "gendefs.h"
#include "devdefs.h"
extern SPICEdev *DEVices[];
int
CKTinst2Node(void *ckt, void *instPtr, int terminal, void **node, IFuid *nodeName)
{
int nodenum;
register int type;
CKTnode *here;
type = ((GENinstance *)instPtr)->GENmodPtr->GENmodType;
if(*((*DEVices[type]).DEVpublic.terms) >= terminal && terminal >0 ) {
switch(terminal) {
default: return(E_NOTERM);
case 1:
nodenum = ((GENinstance *)instPtr)->GENnode1;
break;
case 2:
nodenum = ((GENinstance *)instPtr)->GENnode2;
break;
case 3:
nodenum = ((GENinstance *)instPtr)->GENnode3;
break;
case 4:
nodenum = ((GENinstance *)instPtr)->GENnode4;
break;
case 5:
nodenum = ((GENinstance *)instPtr)->GENnode5;
break;
}
/* ok, now we know its number, so we just have to find it.*/
for(here = ((CKTcircuit*)ckt)->CKTnodes;here;here = here->next) {
if(here->number == nodenum) {
/* found it */
*node = (void*) here;
*nodeName = here->name;
return(OK);
}
}
return(E_NOTFOUND);
} else {
return(E_NOTERM);
}
}

57
src/analysis/cktic.c

@ -0,0 +1,57 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
#include "ngspice.h"
#include <stdio.h>
#include "cktdefs.h"
#include "smpdefs.h"
#include "sperror.h"
#include "devdefs.h"
extern SPICEdev *DEVices[];
int
CKTic(CKTcircuit *ckt)
{
int error;
int size;
int i;
CKTnode *node;
size = SMPmatSize(ckt->CKTmatrix);
for (i=0;i<=size;i++) {
*(ckt->CKTrhs+i)=0;
}
for(node = ckt->CKTnodes;node != NULL; node = node->next) {
if(node->nsGiven) {
node->ptr = SMPmakeElt(ckt->CKTmatrix,node->number,node->number);
if(node->ptr == (double *)NULL) return(E_NOMEM);
ckt->CKThadNodeset = 1;
*(ckt->CKTrhs+node->number) = node->nodeset;
}
if(node->icGiven) {
if(! ( node->ptr)) {
node->ptr = SMPmakeElt(ckt->CKTmatrix,node->number,
node->number);
if(node->ptr == (double *)NULL) return(E_NOMEM);
}
*(ckt->CKTrhs+node->number) = node->ic;
}
}
if(ckt->CKTmode & MODEUIC) {
for (i=0;i<DEVmaxnum;i++) {
if( ((*DEVices[i]).DEVsetic != NULL) && (ckt->CKThead[i] != NULL) ){
error = (*((*DEVices[i]).DEVsetic))(ckt->CKThead[i],ckt);
if(error) return(error);
}
}
}
return(OK);
}

66
src/analysis/cktinit.c

@ -0,0 +1,66 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
#include "ngspice.h"
#include <stdio.h>
#include "ifsim.h"
#include "cktdefs.h"
#include "const.h"
#include "sperror.h"
int
CKTinit(void **ckt)
/* new circuit to create */
{
register int i;
register CKTcircuit *sckt;
sckt = (CKTcircuit *)( *ckt = (char *)MALLOC(sizeof(CKTcircuit)) );
if(sckt == NULL) return(E_NOMEM);
for (i=0;i<DEVmaxnum;i++) {
(sckt)->CKThead[i] = (GENmodel *) NULL;
}
(sckt)->CKTmaxEqNum = 1;
(sckt)->CKTnodes = (CKTnode *)NULL;
(sckt)->CKTlastNode = (CKTnode *)NULL;
sckt->CKTmatrix = NULL;
#ifdef notdef
error = NIinit(sckt);
if(error) return(error);
#endif
(sckt)->CKTgmin = 1e-12;
(sckt)->CKTabstol = 1e-12;
(sckt)->CKTreltol = 1e-3;
(sckt)->CKTchgtol = 1e-14;
(sckt)->CKTvoltTol = 1e-6;
(sckt)->CKTtrtol = 7;
(sckt)->CKTbypass = 1;
(sckt)->CKTisSetup = 0;
(sckt)->CKTtranMaxIter = 10;
(sckt)->CKTdcMaxIter = 100;
(sckt)->CKTdcTrcvMaxIter = 50;
(sckt)->CKTintegrateMethod = TRAPEZOIDAL;
(sckt)->CKTorder = 1;
(sckt)->CKTmaxOrder = 2;
(sckt)->CKTpivotAbsTol = 1e-13;
(sckt)->CKTpivotRelTol = 1e-3;
(sckt)->CKTtemp = 300.15;
(sckt)->CKTnomTemp = 300.15;
(sckt)->CKTdefaultMosL = 1e-4;
(sckt)->CKTdefaultMosW = 1e-4;
(sckt)->CKTdefaultMosAD = 0;
(sckt)->CKTdefaultMosAS = 0;
(sckt)->CKTsrcFact=1;
(sckt)->CKTdiagGmin=0;
(sckt)->CKTstat = (STATistics *)MALLOC(sizeof(STATistics));
(sckt)->CKTtroubleNode = 0;
(sckt)->CKTtroubleElt = NULL;
(sckt)->CKTtimePoints = NULL;
if( (sckt)->CKTstat == (STATistics *)NULL) return(E_NOMEM);
return(OK);
}

36
src/analysis/cktlnkeq.c

@ -0,0 +1,36 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/*
*CKTlinkEq
* Link an already allocated node into the necessary structure
*/
#include "ngspice.h"
#include <stdio.h>
#include "ifsim.h"
#include "iferrmsg.h"
#include "smpdefs.h"
#include "cktdefs.h"
int
CKTlinkEq(CKTcircuit *ckt, CKTnode *node)
{
if(!(ckt->CKTnodes)) { /* starting the list - allocate both ground and 1 */
ckt->CKTnodes = (CKTnode *) MALLOC(sizeof(CKTnode));
if(ckt->CKTnodes == (CKTnode *)NULL) return(E_NOMEM);
ckt->CKTnodes->name = (char *)NULL;
ckt->CKTnodes->type = SP_VOLTAGE;
ckt->CKTnodes->number = 0;
ckt->CKTlastNode = ckt->CKTnodes;
}
if(node == (CKTnode *)NULL) return(E_BADPARM);
ckt->CKTlastNode->next = node;
ckt->CKTlastNode = ckt->CKTlastNode->next;
ckt->CKTlastNode->number = ckt->CKTmaxEqNum++;
ckt->CKTlastNode->next = (CKTnode *)NULL;
return(OK);
}

166
src/analysis/cktload.c

@ -0,0 +1,166 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/*
*/
/* CKTload(ckt)
* this is a driver program to iterate through all the various
* load functions provided for the circuit elements in the
* given circuit
*/
#include "ngspice.h"
#include <stdio.h>
#include "smpdefs.h"
#include "cktdefs.h"
#include "devdefs.h"
#include "sperror.h"
static int ZeroNoncurRow(SMPmatrix *matrix, CKTnode *nodes, int rownum);
int
CKTload(register CKTcircuit *ckt)
{
extern SPICEdev *DEVices[];
register int i;
register int size;
double startTime;
CKTnode *node;
int error;
#ifdef PARALLEL_ARCH
int ibuf[2];
long type = MT_LOAD, length = 2;
#endif /* PARALLEL_ARCH */
#ifdef STEPDEBUG
int noncon;
#endif /* STEPDEBUG */
startTime = (*(SPfrontEnd->IFseconds))();
size = SMPmatSize(ckt->CKTmatrix);
for (i=0;i<=size;i++) {
*(ckt->CKTrhs+i)=0;
}
SMPclear(ckt->CKTmatrix);
#ifdef STEPDEBUG
noncon = ckt->CKTnoncon;
#endif /* STEPDEBUG */
for (i=0;i<DEVmaxnum;i++) {
if ( ((*DEVices[i]).DEVload != NULL) && (ckt->CKThead[i] != NULL) ){
error = (*((*DEVices[i]).DEVload))(ckt->CKThead[i],ckt);
if (ckt->CKTnoncon)
ckt->CKTtroubleNode = 0;
#ifdef STEPDEBUG
if(noncon != ckt->CKTnoncon) {
printf("device type %s nonconvergence\n",
(*DEVices[i]).DEVpublic.name);
noncon = ckt->CKTnoncon;
}
#endif /* STEPDEBUG */
#ifdef PARALLEL_ARCH
if (error) goto combine;
#else
if(error) return(error);
#endif /* PARALLEL_ARCH */
}
}
if(ckt->CKTmode & MODEDC) {
/* consider doing nodeset & ic assignments */
if(ckt->CKTmode & (MODEINITJCT | MODEINITFIX)) {
/* do nodesets */
for(node=ckt->CKTnodes;node;node=node->next) {
if(node->nsGiven) {
if (ZeroNoncurRow(ckt->CKTmatrix, ckt->CKTnodes,
node->number))
{
*(ckt->CKTrhs+node->number) = 1.0e10 * node->nodeset;
*(node->ptr) = 1e10;
} else {
*(ckt->CKTrhs+node->number) = node->nodeset;
*(node->ptr) = 1;
}
/* DAG: Original CIDER fix. If above fix doesn't work,
* revert to this.
*/
/*
*(ckt->CKTrhs+node->number) += 1.0e10 * node->nodeset;
*(node->ptr) += 1.0e10;
*/
}
}
}
if( (ckt->CKTmode & MODETRANOP) && (!(ckt->CKTmode & MODEUIC))) {
for(node=ckt->CKTnodes;node;node=node->next) {
if(node->icGiven) {
if (ZeroNoncurRow(ckt->CKTmatrix, ckt->CKTnodes,
node->number))
{
*(ckt->CKTrhs+node->number) += 1.0e10 * node->ic;
*(node->ptr) += 1.0e10;
} else {
*(ckt->CKTrhs+node->number) = node->ic;
*(node->ptr) = 1;
}
/* DAG: Original CIDER fix. If above fix doesn't work,
* revert to this.
*/
/*
*(ckt->CKTrhs+node->number) += 1.0e10 * node->ic;
*(node->ptr) += 1.0e10;
*/
}
}
}
}
/* SMPprint(ckt->CKTmatrix, stdout); if you want to debug, this is a
good place to start ... */
#ifdef PARALLEL_ARCH
combine:
ckt->CKTstat->STATloadTime += SPfrontEnd->IFseconds() - startTime;
startTime = SPfrontEnd->IFseconds();
/* See if any of the DEVload functions bailed. If not, proceed. */
ibuf[0] = error;
ibuf[1] = ckt->CKTnoncon;
IGOP_( &type, ibuf, &length, "+" );
ckt->CKTnoncon = ibuf[1];
ckt->CKTstat->STATsyncTime += SPfrontEnd->IFseconds() - startTime;
if (ibuf[0] == OK) {
startTime = SPfrontEnd->IFseconds();
SMPcombine( ckt->CKTmatrix, ckt->CKTrhs, ckt->CKTrhsSpare );
ckt->CKTstat->STATcombineTime += SPfrontEnd->IFseconds() - startTime;
return(OK);
} else {
if ( ibuf[0] != error ) {
error = E_MULTIERR;
}
return(error);
}
#else
ckt->CKTstat->STATloadTime += SPfrontEnd->IFseconds()-startTime;
return(OK);
#endif /* PARALLEL_ARCH */
}
static int
ZeroNoncurRow(SMPmatrix *matrix, CKTnode *nodes, int rownum)
{
CKTnode *n;
double *x;
int currents;
currents = 0;
for (n = nodes; n; n = n->next) {
x = (double *) SMPfindElt(matrix, rownum, n->number, 0);
if (x) {
if (n->type == SP_CURRENT)
currents = 1;
else
*x = 0.0;
}
}
return currents;
}

51
src/analysis/cktmapn.c

@ -0,0 +1,51 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/*
*/
/* CKTmapNode(ckt,node)
* map the given node to the compact node numbering set of the
* specified circuit
*/
#include "ngspice.h"
#include <stdio.h>
#include "ifsim.h"
#include "sperror.h"
#include "cktdefs.h"
/* ARGSUSED */
int
CKTmapNode(void *ckt, void **node, IFuid name)
{
register CKTnode *here;
int error;
IFuid uid;
CKTnode *mynode;
for (here = ((CKTcircuit *)ckt)->CKTnodes; here; here = here->next) {
if(here->name == name) {
if(node) *node = (char *)here;
return(E_EXISTS);
}
}
/* not found, so must be a new one */
error = CKTmkNode((CKTcircuit*)ckt,&mynode); /*allocate the node*/
if(error) return(error);
error = (*(SPfrontEnd->IFnewUid))((void *)ckt,
&uid,
(IFuid) NULL,
name,
UID_SIGNAL,
(void**)mynode); /* get a uid for it */
if(error) return(error);
mynode->name = uid; /* set the info we have */
mynode->type = SP_VOLTAGE;
error = CKTlinkEq((CKTcircuit*)ckt,mynode); /* and link it in */
if(node) *node = (void *)mynode; /* and finally, return it */
return(OK);
}

30
src/analysis/cktmask.c

@ -0,0 +1,30 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/* CKTmodAsk
* Ask questions about a specified device.
*/
#include "ngspice.h"
#include <stdio.h>
#include "cktdefs.h"
#include "ifsim.h"
#include "devdefs.h"
#include "sperror.h"
extern SPICEdev *DEVices[];
/* ARGSUSED */
int
CKTmodAsk(void *ckt, void *modfast, int which, IFvalue *value, IFvalue *selector)
{
int type = ((GENmodel *)modfast)->GENmodType;
if((*DEVices[type]).DEVmodAsk) {
return( (*((*DEVices[type]).DEVmodAsk)) ((CKTcircuit *)ckt,
(GENmodel *)modfast,which,value) );
}
return(E_BADPARM);
}

45
src/analysis/cktmcrt.c

@ -0,0 +1,45 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/*
*/
/* CKTmodCrt(type,name,ckt,fast)
* Create a device model of the specified type, with the given name
* in the named circuit.
*/
#include "ngspice.h"
#include <stdio.h>
#include "devdefs.h"
#include "cktdefs.h"
#include "sperror.h"
int
CKTmodCrt(void *ckt, int type, void **modfast, IFuid name)
{
extern SPICEdev *DEVices[];
GENmodel *mymodfast = NULL;
int error;
error = CKTfndMod(ckt,&type,(void**)&mymodfast,name);
if(error == E_NOMOD) {
mymodfast = (GENmodel *)MALLOC(*DEVices[type]->DEVmodSize);
if(mymodfast == (GENmodel *)NULL) return(E_NOMEM);
mymodfast->GENmodType = type;
mymodfast->GENmodName = name;
mymodfast->GENnextModel =(GENmodel *)((CKTcircuit *)ckt)->CKThead[type];
((CKTcircuit *)ckt)->CKThead[type]=(GENmodel *)mymodfast;
if(modfast) *modfast=(void *)mymodfast;
return(OK);
} else if (error==0) {
if(modfast) *modfast=(void *)mymodfast;
return(E_EXISTS);
} else {
return(error);
}
/*NOTREACHED*/
}

45
src/analysis/cktmkcur.c

@ -0,0 +1,45 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/*
*/
/* CKTmkCur
* make the given name a 'node' of type current in the
* specified circuit
*/
#include "ngspice.h"
#include <stdio.h>
#include "ifsim.h"
#include "sperror.h"
#include "cktdefs.h"
/* ARGSUSED */
int
CKTmkCur(CKTcircuit *ckt, CKTnode **node, IFuid basename, char *suffix)
{
IFuid uid;
int error;
CKTnode *mynode;
CKTnode *checknode;
error = CKTmkNode(ckt,&mynode);
if(error) return(error);
checknode = mynode;
error = (*(SPfrontEnd->IFnewUid))((void *)ckt,&uid,basename,
suffix,UID_SIGNAL,(void**)&checknode);
if(error) {
FREE(mynode);
if(node) *node = checknode;
return(error);
}
mynode->name = uid;
mynode->type = SP_CURRENT;
if(node) *node = mynode;
error = CKTlinkEq(ckt,mynode);
return(error);
}

32
src/analysis/cktmknod.c

@ -0,0 +1,32 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/*
*CKTmkNode(ckt,node)
* Tentatively allocate a new circuit equation structure
*/
#include "ngspice.h"
#include <stdio.h>
#include "ifsim.h"
#include "iferrmsg.h"
#include "smpdefs.h"
#include "cktdefs.h"
/* ARGSUSED */
int
CKTmkNode(CKTcircuit *ckt, CKTnode **node)
{
CKTnode *mynode;
mynode = (CKTnode *)MALLOC(sizeof(CKTnode));
if(mynode == (CKTnode *)NULL) return(E_NOMEM);
mynode->next = (CKTnode *)NULL;
mynode->name = (IFuid) 0;
if(node) *node = mynode;
return(OK);
}

43
src/analysis/cktmkvol.c

@ -0,0 +1,43 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/* CKTmkVolt
* make the given name a 'node' of type current in the
* specified circuit
*/
#include "ngspice.h"
#include <stdio.h>
#include "ifsim.h"
#include "sperror.h"
#include "cktdefs.h"
/* ARGSUSED */
int
CKTmkVolt(CKTcircuit *ckt, CKTnode **node, IFuid basename, char *suffix)
{
IFuid uid;
int error;
CKTnode *mynode;
CKTnode *checknode;
error = CKTmkNode(ckt,&mynode);
if(error) return(error);
checknode = mynode;
error = (*(SPfrontEnd->IFnewUid))((void *)ckt,&uid,basename,
suffix,UID_SIGNAL,(void**)&checknode);
if(error) {
FREE(mynode);
if(node) *node = checknode;
return(error);
}
mynode->name = uid;
mynode->type = SP_VOLTAGE;
if(node) *node = mynode;
error = CKTlinkEq(ckt,mynode);
return(error);
}

32
src/analysis/cktmpar.c

@ -0,0 +1,32 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/* CKTmodParam
* attach the given parameter to the specified model in the given circuit
*/
#include "ngspice.h"
#include <stdio.h>
#include "cktdefs.h"
#include "ifsim.h"
#include "devdefs.h"
#include "sperror.h"
extern SPICEdev *DEVices[];
/* ARGSUSED */
int
CKTmodParam(void *ckt, void *modfast, int param, IFvalue *val, IFvalue *selector)
{
register int type = ((GENmodel *)modfast)->GENmodType;
if (((*DEVices[type]).DEVmodParam)) {
return(((*((*DEVices[type]).DEVmodParam)) (param,val,
(GENmodel *)modfast)));
} else {
return(E_BADPARM);
}
}

45
src/analysis/cktnames.c

@ -0,0 +1,45 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1988 Thomas L. Quarles
**********/
/*
* CKTnames(ckt)
* output information on all circuit nodes/equations
*
*/
#include "ngspice.h"
#include <stdio.h>
#include "cktdefs.h"
#include "ifsim.h"
#include "iferrmsg.h"
int
CKTnames(register CKTcircuit *ckt, int *numNames, register IFuid **nameList)
{
register CKTnode *here;
register int i;
*numNames = ckt->CKTmaxEqNum-1;
*nameList = (IFuid *)MALLOC(*numNames * sizeof(IFuid ));
if ((*nameList) == (IFuid *)NULL) return(E_NOMEM);
i=0;
for (here = ckt->CKTnodes->next; here; here = here->next) {
*((*nameList)+i++) = here->name;
}
return(OK);
}
int
CKTdnames(CKTcircuit *ckt)
{
CKTnode *here;
register int i;
i=0;
for (here = ckt->CKTnodes->next; here; here = here->next) {
printf("%03d: %s\n", here->number, (char *)here->name);
}
return(OK);
}

34
src/analysis/cktnewan.c

@ -0,0 +1,34 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
#include "ngspice.h"
#include <stdio.h>
#include "tskdefs.h"
#include "jobdefs.h"
#include "ifsim.h"
#include "iferrmsg.h"
extern SPICEanalysis *analInfo[];
/* ARGSUSED */
int
CKTnewAnal(void *ckt, int type, IFuid name, void **analPtr, void *taskPtr)
{
if(type==0) {
/* special case for analysis type 0 == option card */
*analPtr=taskPtr; /* pointer to the task itself */
(*(JOB **)analPtr)->JOBname = name;
(*(JOB **)analPtr)->JOBtype = type;
return(OK); /* doesn't need to be created */
}
*analPtr = (void *)MALLOC(analInfo[type]->size);
if(*analPtr==NULL) return(E_NOMEM);
(*(JOB **)analPtr)->JOBname = name;
(*(JOB **)analPtr)->JOBtype = type;
(*(JOB **)analPtr)->JOBnextJob = ((TSKtask *)taskPtr)->jobs;
((TSKtask *)taskPtr)->jobs = (JOB *)*analPtr;
return(OK);
}

38
src/analysis/cktneweq.c

@ -0,0 +1,38 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/*
*CKTnewEq(ckt,node,name)
* Allocate a new circuit equation number (returned) in the specified
* circuit to contain a new equation or node
* returns -1 for failure to allocate a node number
*
*/
#include "ngspice.h"
#include <stdio.h>
#include "ifsim.h"
#include "iferrmsg.h"
#include "smpdefs.h"
#include "cktdefs.h"
int
CKTnewEq(void *inCkt, void **node, IFuid name)
{
CKTnode *mynode;
register CKTcircuit *ckt = (CKTcircuit *)inCkt;
int error;
error = CKTmkNode(ckt,&mynode);
if(error) return(error);
if(node) *node = (void *)mynode;
mynode->name = name;
error = CKTlinkEq(ckt,mynode);
return(error);
}

45
src/analysis/cktnewn.c

@ -0,0 +1,45 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/*
*CKTnewNode(ckt,node,name)
* Allocate a new circuit equation number (returned) in the specified
* circuit to contain a new equation or node
* returns -1 for failure to allocate a node number
*
*/
#include "ngspice.h"
#include <stdio.h>
#include "ifsim.h"
#include "iferrmsg.h"
#include "smpdefs.h"
#include "cktdefs.h"
/* should just call CKTnewEQ and set node type afterwards */
int
CKTnewNode(void *inCkt, void **node, IFuid name)
{
register CKTcircuit *ckt = (CKTcircuit *)inCkt;
if(!(ckt->CKTnodes)) { /* starting the list - allocate both ground and 1 */
ckt->CKTnodes = (CKTnode *) MALLOC(sizeof(CKTnode));
if(ckt->CKTnodes == (CKTnode *)NULL) return(E_NOMEM);
ckt->CKTnodes->name = (char *)NULL;
ckt->CKTnodes->type = SP_VOLTAGE;
ckt->CKTnodes->number = 0;
ckt->CKTlastNode = ckt->CKTnodes;
}
ckt->CKTlastNode->next = (CKTnode *)MALLOC(sizeof(CKTnode));
if(ckt->CKTlastNode->next == (CKTnode *)NULL) return(E_NOMEM);
ckt->CKTlastNode = ckt->CKTlastNode->next;
ckt->CKTlastNode->name = name;
ckt->CKTlastNode->number = ckt->CKTmaxEqNum++;
ckt->CKTlastNode->type = SP_VOLTAGE;
ckt->CKTlastNode->next = (CKTnode *)NULL;
if(node) *node = (void *)ckt->CKTlastNode;
return(OK);
}

33
src/analysis/cktnodn.c

@ -0,0 +1,33 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/*
*/
/*
*CKTnodName(ckt)
* output information on all circuit nodes/equations
*
*/
#include "ngspice.h"
#include <stdio.h>
#include "cktdefs.h"
IFuid
CKTnodName(CKTcircuit *ckt, register int nodenum)
{
register CKTnode *here;
for(here = ckt->CKTnodes;here; here = here->next) {
if(here->number == nodenum) {
/* found it */
return(here->name);
}
}
/* doesn't exist - do something */
return("UNKNOWN NODE");
}

140
src/analysis/cktnoise.c

@ -0,0 +1,140 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1987 Gary W. Ng
**********/
/*
* CKTnoise (ckt, mode, operation, data)
*
* This routine is responsible for naming and evaluating all of the
* noise sources in the circuit. It uses a series of subroutines to
* name and evaluate the sources associated with each model, and then
* it evaluates the noise for the entire circuit.
*/
#include "ngspice.h"
#include <stdio.h>
#include "cktdefs.h"
#include "devdefs.h"
#include "fteconst.h"
#include "iferrmsg.h"
#include "noisedef.h"
#include "sperror.h"
int
CKTnoise (CKTcircuit *ckt, int mode, int operation, Ndata *data)
{
double outNdens;
int i;
extern SPICEdev *DEVices[];
IFvalue outData; /* output variable (points to list of outputs)*/
IFvalue refVal; /* reference variable (always 0)*/
int error;
outNdens = 0.0;
/* let each device decide how many and what type of noise sources it has */
for (i=0; i < DEVmaxnum; i++) {
if ( ((*DEVices[i]).DEVnoise != NULL) && (ckt->CKThead[i] != NULL) ) {
error = (*((*DEVices[i]).DEVnoise))(mode,operation,ckt->CKThead[i],
ckt,data, &outNdens);
if (error) return (error);
}
}
switch (operation) {
case N_OPEN:
/* take care of the noise for the circuit as a whole */
switch (mode) {
case N_DENS:
data->namelist = (IFuid *)trealloc((char *)data->namelist,
(data->numPlots + 1)*sizeof(IFuid));
(*(SPfrontEnd->IFnewUid))(ckt, &(data->namelist[data->numPlots++]),
(IFuid)NULL,"onoise_spectrum",UID_OTHER,(void **)NULL);
data->namelist = (IFuid *)trealloc((char *)data->namelist,
(data->numPlots + 1)*sizeof(IFuid));
(*(SPfrontEnd->IFnewUid))(ckt, &(data->namelist[data->numPlots++]),
(IFuid)NULL,"inoise_spectrum",UID_OTHER,(void **)NULL);
/* we've added two more plots */
data->outpVector =
(double *)MALLOC(data->numPlots * sizeof(double));
break;
case INT_NOIZ:
data->namelist = (IFuid *)trealloc((char *)data->namelist,
(data->numPlots + 1)*sizeof(IFuid));
(*(SPfrontEnd->IFnewUid))(ckt, &(data->namelist[data->numPlots++]),
(IFuid)NULL,"onoise_total",UID_OTHER,(void **)NULL);
data->namelist = (IFuid *)trealloc((char *)data->namelist,
(data->numPlots + 1)*sizeof(IFuid));
(*(SPfrontEnd->IFnewUid))(ckt, &(data->namelist[data->numPlots++]),
(IFuid)NULL,"inoise_total",UID_OTHER,(void **)NULL);
/* we've added two more plots */
data->outpVector =
(double *) MALLOC(data->numPlots * sizeof(double));
break;
default:
return (E_INTERN);
}
break;
case N_CALC:
switch (mode) {
case N_DENS:
if ((((NOISEAN*)ckt->CKTcurJob)->NStpsSm == 0)
|| data->prtSummary)
{
data->outpVector[data->outNumber++] = outNdens;
data->outpVector[data->outNumber++] =
(outNdens * data->GainSqInv);
refVal.rValue = data->freq; /* the reference is the freq */
outData.v.numValue = data->outNumber; /* vector number */
outData.v.vec.rVec = data->outpVector; /* vector of outputs */
(*(SPfrontEnd->OUTpData))(data->NplotPtr,&refVal,&outData);
}
break;
case INT_NOIZ:
data->outpVector[data->outNumber++] = data->outNoiz;
data->outpVector[data->outNumber++] = data->inNoise;
outData.v.vec.rVec = data->outpVector; /* vector of outputs */
outData.v.numValue = data->outNumber; /* vector number */
(*(SPfrontEnd->OUTpData))(data->NplotPtr,&refVal,&outData);
break;
default:
return (E_INTERN);
}
break;
case N_CLOSE:
(*(SPfrontEnd->OUTendPlot))(data->NplotPtr);
FREE(data->namelist);
FREE(data->outpVector);
break;
default:
return (E_INTERN);
}
return (OK);
}

56
src/analysis/cktntask.c

@ -0,0 +1,56 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/*
*/
#include "ngspice.h"
#include <stdio.h>
#include "tskdefs.h"
#include "ifsim.h"
#include "cktdefs.h"
#include "iferrmsg.h"
/* ARGSUSED */
int
CKTnewTask(void *ckt, void **taskPtr, IFuid taskName)
{
register TSKtask *tsk;
*taskPtr = (void *)MALLOC(sizeof(TSKtask));
if(*taskPtr==NULL) return(E_NOMEM);
tsk = *(TSKtask **)taskPtr;
tsk->TSKname = taskName;
tsk->TSKgmin = 1e-12;
tsk->TSKabstol = 1e-12;
tsk->TSKreltol = 1e-3;
tsk->TSKchgtol = 1e-14;
tsk->TSKvoltTol = 1e-6;
#ifdef NEWTRUNC
tsk->TSKlteReltol = 1e-3;
tsk->TSKlteAbstol = 1e-6;
#endif /* NEWTRUNC */
tsk->TSKtrtol = 7;
tsk->TSKbypass = 1;
tsk->TSKtranMaxIter = 10;
tsk->TSKdcMaxIter = 100;
tsk->TSKdcTrcvMaxIter = 50;
tsk->TSKintegrateMethod = TRAPEZOIDAL;
tsk->TSKmaxOrder = 2;
tsk->TSKnumSrcSteps = 10;
tsk->TSKnumGminSteps = 10;
tsk->TSKpivotAbsTol = 1e-13;
tsk->TSKpivotRelTol = 1e-3;
tsk->TSKtemp = 300.15;
tsk->TSKnomTemp = 300.15;
tsk->TSKdefaultMosL = 1e-4;
tsk->TSKdefaultMosW = 1e-4;
tsk->TSKdefaultMosAD = 0;
tsk->TSKdefaultMosAS = 0;
tsk->TSKnoOpIter=0;
tsk->TSKtryToCompact=0;
tsk->TSKbadMos3=0;
tsk->TSKkeepOpInfo=0;
return(OK);
}

32
src/analysis/cktnum2n.c

@ -0,0 +1,32 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/*
*/
/* CKTnum2nod
* find the given node given its name and return the node pointer
*/
#include "ngspice.h"
#include <stdio.h>
#include "ifsim.h"
#include "sperror.h"
#include "cktdefs.h"
/* ARGSUSED */
CKTnode *
CKTnum2nod(CKTcircuit *ckt, int node)
{
register CKTnode *here;
for (here = ((CKTcircuit *)ckt)->CKTnodes; here; here = here->next) {
if(here->number == node) {
return(here);
}
}
return((CKTnode *)NULL);
}

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save