tclspice 0.2.7 import

This commit is contained in:
stefanjones 2002-11-26 10:11:50 +00:00
parent 2d7004cb81
commit d06b4a9f05
567 changed files with 17245 additions and 19095 deletions

75
AUTHORS
View File

@ -1,39 +1,40 @@
@c This file will be processed with texinfo.
SPICE was originally written at The University of Berkeley (USA).
Since then, there have been many people working on the software.
The following people have contributed in some way:
Giles C. Billingsley,
Mansun Chan,
Wayne A. Christopher,
Glao S. Dezai <dezai@@hotbot.com>,
Daniele Foci <d.foci@@ieee.ing.uniroma1.it>,
Noah Friedman <friedman@@prep.ai.mit.edu>,
David A. Gates,
Alan Gillespie <alan.gillespie@@analog.com>,
JianHui Huang,
Jeffrey M. Hsu,
S. Hwang,
Chris Inbody <cinbody@@cowtown.net>,
Gordon M. Jacobs,
Min-Chie Jeng,
Kenneth H. Keller,
Mathew Lew,
Weidong Liu,
Richard D. McRoberts,
Manfred Metzger <ManfredMetzger@@gmx.de>,
Paolo Nenzi <pnenzi@@ieee.ing.uniroma1.it>,
Gary W. Ng,
Hong June Park,
Arno Peters <A.W.Peters@@ieee.org>,
Serban-Mihai Popescu <serbanp@@ix.netcom.com>,
Thomas L. Quarles,
Emmanuel Rouat <emmanuel.rouat@@wanadoo.fr>,
Jaijeet S. Roychowdhury,
Takayasu Sakurai,
Kanwar Jit Singh,
Andrew Tuckey <Tuckey@@ieee.org>
Michael Widlok <widlok@@uci.agh.edu.pl>,
and many others...
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...)
If you feel you should be on this list, write to
<ngspice-user@lists.sourceforge.net>.

235
ChangeLog
View File

@ -1,3 +1,238 @@
2001-12-05 Emmanuel Rouat <emmanuel.rouat@wanadoo.fr>
* configure.in: removed (unnecessary) macros to handle GNU getopt
(I'm an idiot!)
2001-12-04 Emmanuel Rouat <emmanuel.rouat@wanadoo.fr>
* configure.in, main.c: Forgot a bit to handle GNU getopt correctly
2001-11-25 Emmanuel Rouat <emmanuel.rouat@wanadoo.fr>
* configure.in: New way (cleaner) to handle GNU getopt.
2001-01-21 Paolo Nenzi <p.nenzi@ieee.org>
* bsim3soi_dd/*: BSIM3SOI (DD) support added as level 11. Added tests in
tests directory (tests/bsim3soidd/*).
* ???: Integrated patch form Alan Gillespie <Alan.Gillespie@analog.com>
to revert the spice raw format to the spice3 original.
* configure.in: corrected a bug that broke the on line help system.
Help system now works again but its text is a little bit outdated.
* ???: all binaries now have ng prependend, so ngspice can be installed
with other spice flavours.
2000-10-18 Arno W. Peters <A.W.Peters@ieee.org>
* Makefile.am: Changes for notes dir -> NOTES file conversion.
* tests/Makefile.am: Make distcheck target work again.
2000-10-17 Arno W. Peters <A.W.Peters@ieee.org>
* TODO: Little updates.
2000-10-14 Arno W. Peters <A.W.Peters@ieee.org>
* acconfig.h, configure.in, src/frontend/inpcom.c,
src/include/complex.h src/include/macros.h, src/include/memory.h
src/include/ngspice.h, src/maths/cmaths/Makefile.am
src/maths/cmaths/cmath1.c, src/maths/cmaths/cmath2.c
src/maths/cmaths/cmath3.c, src/maths/cmaths/cmath4.c
src/maths/cmaths/test_cx_j.c, src/maths/cmaths/test_cx_mag.c
src/maths/cmaths/test_cx_ph.c, src/misc/alloc.c src/misc/alloc.h:
Added support for the Boehm-Weiser conservative garbage collector.
* NOTES, src/maths/cmaths/cmath.h: Added.
* notes/Linux.changes, notes/dbx, notes/internal, notes/mac_port
notes/porting, notes/spice2: Removed or incorporated into
NOTES.
* *: replaced malloc, realloc and free calls to use tmalloc,
trealloc and txfree.
2000-09-05 Arno W. Peters <A.W.Peters@ieee.org>
* ???: Paolo and I have integrated patches from Alan Gillespie
<Alan.Gillespie@analog.com>.
2000-07-28 Arno W. Peters <A.W.Peters@ieee.org>
* tests/polezero/*.out: Changed the content of these files because
the bug that caused the incorrect pole-zero results have been
traced to src/spicelib/analysis/cktpzstr.c.
2000-07-05 Arno W. Peters <A.W.Peters@ieee.org>
* src/devices/dev.c: Added first_device() and next_device() to
abstract manipulations to the devices list. Now change all the
code that uses direct access to these functions...
2000-07-03 Arno W. Peters <A.W.Peters@ieee.org>
* src/parser/alias.c, src/parser/alias.h: contain frontend alias
command. Moved them to src/frontend/com_alias.c and
src/frontend/com_alias.h. Updated Makefile.am's as appropreate.
* src/parser/front.c, src/parser/front.h, src/parser/history.c,
src/parser/history.h, src/parser/modify.c, src/parser/modify.h,
src/parser/variable.c, src/parser/variable.h: Empty files.
Removed.
* src/include/spconfig.h: Removed spCOMPLEX,
spSEPARATED_COMPLEX_VECTORS and spCOMPATIBILITY defines. This
made including this file from src/include/spmatrix.h unnecessary.
Moved this file to src/maths/sparse/spconfig.h.
* src/include/spmatrix.h: Removed include of
src/include/spconfig.h.
* src/maths/sparse/spalloc.c, src/maths/sparse/spbuild.c,
src/maths/sparse/spcombin.c, src/maths/sparse/spdefs.h,
src/maths/sparse/spfactor.c, src/maths/sparse/spoutput.c,
src/maths/sparse/spsmp.c, src/maths/sparse/spsolve.c,
src/maths/sparse/sputils.c: The other files affected by the
removal of spCOMPLEX, spSEPARATED_COMPLEX_VECTORS and
spCOMPATIBILITY defines. Also: assertions are enabled by
default.
* src/include/smpdefs.h, src/maths/sparse/spsmp.c: SMPmatrix is
now a typedef for void, instead of char. Updated all function
declarations to match this. Also added function prototypes not
previously mentioned in src/include/smpdefs.h.
* src/include/complex.h: Updates of cast from char * to void *
* src/analysis/cktsens.c: Matrixes cannot be created non-complex.
Also added a check to detect an error condition on delta_Y =
spCreate(...).
2000-06-27 Arno W. Peters <A.W.Peters@ieee.org>
* src/parser: Refactored commands from the frontend into the
frontend directory. Major changes to organization, but not to
functionality.
2000-06-19 Arno W. Peters <A.W.Peters@ieee.org>
* src/analysis/cktask.c: moved to src/devices.
* src/analysis/cktbindn.c: moved, renamed to
src/devices/cktbindnode.c.
* src/analysis/cktfdev.c: moved, renamed to
src/devices/cktfinddev.c.
2000-06-18 Arno W. Peters <A.W.Peters@ieee.org>
* AUTHORS, doc/ngspice.texi: Included an acknowledgements
section.
2000-06-16 Arno W. Peters <A.W.Peters@ieee.org>
* src/frontend/doplot.c: Refactored into the following files:
src/frontend/com_asciiplot.c src/frontend/com_asciiplot.h
src/frontend/com_hardcopy.c src/frontend/com_hardcopy.h
src/frontend/com_plot.c src/frontend/com_plot.h
src/frontend/com_xgraph.c src/frontend/com_xgraph.h
src/frontend/plotting/plotit.c src/frontend/plotting/plotit.h
* src/frontend/Makefile.am src/frontend/plotting/Makefile.am:
Updated to match the new files.
2000-06-15 Arno W. Peters <A.W.Peters@ieee.org>
* src/frontend/graphdb.c, src/frontend/graphdb.c,
src/frontend/Makefile.am, src/frontend/plotting/graphdb.c,
src/frontend/plotting/graphdb.c,
src/frontend/plotting/Makefile.am: Moved plotting specific files
into plotting directory.
2000-06-05 Arno W. Peters <A.W.Peters@ieee.org>
* tests/*: Added a little hierarchy to the tests. Removed
config.sh in favor of check.sh. This script does all checking.
Made names of the tests better reflect the circuit under test.
2000-06-03 Arno W. Peters <A.W.Peters@ieee.org>
* src/include/complex.h, src/include/macros.h,
src/include/memory.h, src/maths/sparse/spdefs.h: Moved definitions
of complex into complex.h. There are three different ways to
declare a complex number in Spice. We need further work to reduce
this to only one.
* src/maths/cmaths/Makefile.am, src/maths/cmaths/.cvsignore,
src/maths/cmaths/test_cx_ph.c: Added a new test and updated the
corresponding support files.
2000-06-02 Arno W. Peters <A.W.Peters@ieee.org>
* src/circuit/inp2dot.c: Refactoring introduced a bug in the line
parsing. Passing line as an extra parameter to the refactored
functions fixes the bug.
2000-05-30 Arno W. Peters <A.W.Peters@ieee.org>
* TODO: Updated.
* src/maths/cmaths/Makefile.am, src/maths/cmaths/test_cx_mag.c,
src/maths/cmaths/test_cx_j.c: Added first testcases for complex
math library.
2000-05-25 Arno W. Peters <A.W.Peters@ieee.org>
* src/circuit/inp2dot.c: First refactoring of INP2dot into smaller
functions. Still needs work.
* src/circuit/sperror.c: Reworked, now much simpler.
* src/include/inpdefs.h, src/include/sperror.h: Removed redundancy
in the definition of function prototypes.
2000-05-06 Arno W. Peters <A.W.Peters@ieee.org>
* src/include/fte*: Broken header files into smaller pieces. This
avoids long recompile times as less needs to be rebuilt on changes
to the header files. Adjusted all callers to use the new header
files. Left a warning message in the header file to indicate its
obsolence. You will see this message when compiling.
* src/frontend/*: Reorganized part of the frontend commands into
their own source file. Moved plotting parts into new plotting
directory.
* src/devices/*: Removed all RCS log and rcsid from the devices
source files. They only give extra clutter and all the
information you need is available through CVS.
2000-05-04 Arno W. Peters <A.W.Peters@ieee.org>
* src/maths/ni/nipzmeth.c: Corrected an overeager deletion.
2000-05-03 Arno W. Peters <A.W.Peters@ieee.org>
* source tree: removed most of `#ifdef notdef' and made converted
some function calls from K&R -> ANSI.
2000-05-01 Arno W. Peters <A.W.Peters@ieee.org>
* Added .cvsignore files to prevent CVS from marking generated
files as unknown.
* src/devices/Makefile.am, src/devices/dev.c, src/devices/dev.h,
src/Makefile.am, src/ngspice.c, src/main.c: Refactored devices
initialization code into the devices dir.
* tests/respart.cir, tests/respart.out, tests/respart.sh:
additional tests for resistor.
1999-12-07 Arno Peters <A.W.Peters@ieee.org>
* source tree: Added MAINTAINERCLEANFILES to Makefile.am to

167
DEVICES
View File

@ -1,167 +0,0 @@
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.

530
FAQ
View File

@ -1,299 +1,377 @@
Ngspice F.A.Q.Version 1.0
Maintened by Paolo Nenzi <p.nenzi@ieee.org>
Last update: 05/12/2001
This document contains the Frequently Asked Questions (and Answers)
for ngspice project.
______________________________________________________________________
Table of Contents
NG-Spice F.A.Q.
Frequently Asked Questions
(and Answers)
1. INTRODUCTION AND GENERAL INFORMATION
1.1 What is ngspice?
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 ngspice?
1.7 Are the mailing lists archived anywhere?
1.8 What newsgroups exist for ngspice?
1.9 Where can I get a copy of ngspice?
1.10 Where should I look on the World Wide Web for ngspice stuff?
1.11 Where should I look on the World Wide Web for Spice documentation?
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. 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.3 What does it look like?
2.4 Who are the authors of ngspice?
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. 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
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.
11.. IINNTTRROODDUUCCTTIIOONN AANNDD GGEENNEERRAALL IINNFFOORRMMAATTIIOONN
1.5 Legal issues
[not written yet: GPL vs. Berkeley]
11..11.. WWhhaatt iiss nnggssppiiccee??
1.6 What mailing lists exist for NG-Spice?
Ngspice 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 ngspice project aims to improve the capabilities
of the Spice3 circuit simulator. The heart of the project is the
ngspice program, a circuit simulator derived from spice3f5.
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?
11..22.. WWhhyy rreessuurrrreeccttiinngg BBeerrkkeelleeyy''ss SSppiiccee??
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.
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.8 What newsgroups exist for NG-Spice?
11..33.. WWhhaatt iiss tthhee pprroojjeecctt''ss ggooaall??
The final goal of ngspice project is to develop a reliable, fast and
friendly circuit simulator for mixed signal/mixed level simulation.
Easy isn't it? ;-).
11..44.. WWhhaatt yyoouu aarree ggooiinngg ttoo ddoo??
We are going to develop a circuit simulation program. The line of
development follows two parallel paths:
1. EEnnhhaanncceemmeennttss aanndd bbuugg--ffiixxiinngg ooff tthhee oorriiggiinnaall ssppiiccee33ff55 ccooddee..
2. DDeevveellppppmmeenntt ooff aa nneeww GGPPLL''eedd ssiimmuullaattoorr..
The first phat will lead to a better spice3f5 and nothing more than
this, while the second one will bring us a new simulator,
compatible with its father but more expandable and presumably
faster and numerically stronger.
There is another project in ngspice: the development of one or more
frontend to the new simulator. One of the key issues of our project is
to let users design the front end they want, using the widget set and
the language they prefer. For this reason ngspice differs a lot from
spice3f5: in ngspice there is a clear distinction between the front
end and the back end. In ngspice the front end takes care of the
interaction with the user. It is back-end's task to maintain the
object database, to exchange data with the simulator, etc.
There are various improvements we are planning, some follows:
1. TThhee ffrraammeewwoorrkk ((oorr GGrraapphhiicc UUsseerr IInntteerrffaaccee)):: 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. DDooccuummeennttaattiioonn:: 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. IImmpprroovveemmeennttss ttoo tthhee SSppiiccee ccooddee:: 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:
+o Numerical Algorithms:
+o More stable algorithms for integration (as Runge-Kutta
Methods (?) ).
+o Better convergence in Operating Point Calculation adding a
modified version of Fixed-Point Homotopy to the Newton-
Raphson algorithm,
+o Devices:
+o 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 macromodels.
+o 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).
+o Code Level Modeling: let users write their devices in C and
use them in the simulator.
+o Improving device: include additional parameters to some
devices as HDIF, LDIF, etc.
+o New types of analysis, oriented to circuits syntesis and
optimization:
+o Network analysis: given four nodes, extract z,y,s and the
other double bipole paramters.
+o Monte Carlo analysis: statistical simulation based on device
tolerances.
+o Worst Case analysis: find the worst case of operation of a
given circuit based on device parameters tolerances.
+o Parametric analysis: repeat an analysis when one or more
parameters assumes different values.
+o Faster handling of sparse matrices.
+o Possibility to mesure circuit pameters, like the delay between
two nodes, etc.
+o Whatever else can be judged useful.
11..55.. LLeeggaall iissssuueess
The improved spice3f5 will be relased under the original Berkeley's
lincese. The new simulator will be released as GPL. Make ngspice a GPL
program, allow us to link a lot of good code laying on the net and
obviously contribute to the GPL community.
11..66.. WWhhaatt mmaaiilliinngg lliissttss eexxiisstt ffoorr nnggssppiiccee??
There are three mailing lists dedicated to the ngspice project. Send
an empty message to the following addresses to get information on
subscription. <ngspice-users-help@lists.sourceforge.net>
<ngspice-devel-help@lists.sourceforge.net>
<ngspice-frontends-help@lists.sourceforge.net>
11..77.. AArree tthhee mmaaiilliinngg lliissttss aarrcchhiivveedd aannyywwhheerree??
Yes, the list are archived. Look at the project's web site to access
archives.
11..88.. WWhhaatt nneewwssggrroouuppss eexxiisstt ffoorr nnggssppiiccee??
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/
11..99.. WWhheerree ccaann II ggeett aa ccooppyy ooff nnggssppiiccee??
1.10 Where should I look on the World Wide Web for NG-Spice stuff?
You can download ngspice from:
There is a WWW page for NG-Spice. The URL is:
http://geda.seul.org under the tools section.
<http://sourceforge.net/projects/ngspice>
2. DEVELOPMENT
11..1100.. WWhheerree sshhoouulldd II llooookk oonn tthhee WWoorrlldd WWiiddee WWeebb ffoorr nnggssppiiccee ssttuuffff??
2.1 What is the current version?
Look at the official NG-Spice Web Page
<http://ngspice.sourceforge.net>
0.3 (released on 30/08/1999)
2.2 What are the latest features in the current release?
11..1111.. WWhheerree sshhoouulldd II llooookk oonn tthhee WWoorrlldd WWiiddee WWeebb ffoorr SSppiiccee ddooccuummeennttaa--
ttiioonn??
* New features:
- Autoconf interface.
- BSIM 3.2.2 Model.
- PS jfet Model (jfet level 2).
- Temperature and resistance sweeps.
- "spec" command for spectrum analysis.
50 Circuits analyzed with SPICE
<http://www.dacafe.com/DACafe/EDATools/EDAbooks/SpiceHandBook/01_TOC.html>
* Bug fixes:
- Altermod command connected to the parser.
- Some memory leaks closed.
- Spice3f5 fixes available on the net.
<http://www.dacafe.com/DACafe/EDATools/EDAbooks/SMPS/SMPS.htm>
2.3 What does it look like ?
22.. DDEEVVEELLOOPPMMEENNTT
22..11.. WWhhaatt iiss tthhee ccuurrrreenntt vveerrssiioonn??
rework-14 (released on 10/12/2001)
22..22.. WWhhaatt aarree tthhee llaatteesstt ffeeaattuurreess iinn tthhee ccuurrrreenntt rreelleeaassee??
New features:
+o New functions for vectors: vecmax (find max element in a vector),
vecmin (find minimum element in a vector), vecd (differentiate a
vector).
+o BSIM 4 and support EKV models.
Bug fixes:
+o Some memory leaks closed.
+o Error reporting more verbose
22..33.. WWhhaatt ddooeess iitt llooookk lliikkee??
This is a command line utility, no screenshots!
2.4 Who are the authors of ng-spice ?
22..44.. WWhhoo aarree tthhee aauutthhoorrss ooff nnggssppiiccee??
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
People who contributed are (in alphabetical order):
+o Daniele Foci <dfoci@ieee.ing.uniroma1.it>
+o Paolo Nenzi <pnenzi@ieee.ing.uniroma1.it>
+o Arno Peters <A.W.Peters@ieee.org>
+o Serban-Mihai Popescu <serbanp@ix.netcom.com>
+o Emmanuel Rouat <emmanuel.rouat@wanadoo.fr>
+o Michael Widlok <twidlok@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, bug
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.
22..55.. HHooww ccaann II rreeppoorrtt aa bbuugg//rreeqquueesstt ffoorr aa ffeeaattuurree??
2.6 How can I join the development?
Look at the projects summary page: ngspice summary page
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:
22..66.. HHooww ccaann II jjooiinn tthhee ddeevveellooppmmeenntt??
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.
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 ngspice from our CVS. It might be that
your feature has already been implemented.
3. SOLUTIONS TO COMMON MISCELLANEOUS PROBLEMS
33.. SSOOLLUUTTIIOONNSS TTOO CCOOMMMMOONN MMIISSCCEELLLLAANNEEOOUUSS PPRROOBBLLEEMMSS
3.1 What systems are supported?
33..11.. WWhhaatt ssyysstteemmss aarree ssuuppppoorrtteedd??
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 ?
Hardware O.S. Version Compiler Functional?
---------------- ----------------------- -------------- -----------
???? HP-UX 10.10 gcc 2.95.2 yes
IBM Risc 6000 ??? lcc no
i386 Debian GNU/Linux 2.1 gcc 2.7.2 yes
i386 Red Hat Linux 5.2 gcc 2.7.2 yes
i386 SuSE Linux 6.0 gcc 2.7.2 yes
i386 Linux (SuSE) gcc yes
UltraSPARC Solaris 7 gcc yes
UltraSPARC Solaris 7 SUN Workshop ?
3.2 I get errors when I try to compile the source code, why?
MS-Dos, VMS and MacOS are no longer supported.
33..22.. II ggeett eerrrroorrss wwhheenn II ttrryy ttoo ccoommppiillee tthhee ssoouurrccee ccooddee,, wwhhyy??
[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.
33..33.. TThhiiss ddooccuummeenntt ddiiddnn''tt aannsswweerr mmyy qquueessttiioonn.. WWhheerree eellssee ccaann II llooookk
ffoorr aann aannsswweerr??
Read old messages from the mailing list archive, search the web site
or read the docs. Upgrade to the latest version of ngspice, 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
44.. AADDMMIINNIISSTTRRAATTIIVVEE IINNFFOORRMMAATTIIOONN AANNDD AACCKKNNOOWWLLEEDDGGEEMMEENNTTSS
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>.
44..11.. FFeeeeddbbaacckk
4.2 Formats in which this FAQ is available
Send your comments about this F.A.Q. to:
This document is available only in ASCII format in the NG-Spice source
Paolo Nenzi <p.nenzi@ieee.org>.
Send your comments about ngspice to:
Paolo Nenzi <p.nenzi@ieee.org>.
44..22.. FFoorrmmaattss iinn wwhhiicchh tthhiiss FFAAQQ iiss aavvaaiillaabbllee
This document is available only in ASCII format in the ngspice source
package.
4.3 Authorship and acknowledgements
44..33.. AAuutthhoorrsshhiipp aanndd aacckknnoowwlleeddggeemmeennttss
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.
44..44.. DDiissccllaaiimmeerr aanndd CCooppyyrriigghhtt
This document is provided as is. The information in it is not
warranted to be correct: you use it at your own risk.

View File

@ -2,7 +2,7 @@
SUBDIRS = doc src man tests
EXTRA_DIST = FAQ acconfig.h autogen.sh notes contrib
EXTRA_DIST = FAQ acconfig.h autogen.sh NOTES contrib BUGS
MAINTAINERCLEANFILES = Makefile.in aclocal.m4 config.guess \
config.h.in config.sub configure install-sh \
@ -13,3 +13,8 @@ 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`
tcl:
cd src && $(MAKE) tcl
tcl_install:
cd src && $(MAKE) tcl_install

224
NEWS
View File

@ -1,16 +1,212 @@
Ng-spice-rework-14
============
This is a major release in terms of bug-fixes. Some enhancements
have been included: BSIM4 model and support for EKV model. The
source code for the latter must be obtained from EKV web site
(see DEVICE for more info). To enable EKV support you have
to obtain the code first and then use the configure switch
"--enable-ekv".
The spice code contains an option to debug frontend code, now
this is available in configure as "--enable-ftedebug".
Ng-spice-rework-13
============
This is a major release in terms of fixes and enhancements.
A garbage collector support has been added. If the configuration
script detects that you have installed GC (Bohem-Weiser conservative
garbage collector), it will use it. Some memory leaks have been
fixed too.
Enhancements to the code comes from Alan's contribute code, a
description of improvements follows (extracted form Alan's mail):
Output File Format Changes -
Rawfile format changed to PSPICE Probe format (Usable with
Demo version of Microsim's Probe).
(NOTE: Do not rely on this, we may revert to the old format
in the next release).
Text mode .OP results even though "rawfile" written.
Internal device nodes are not saved to "rawfile" (reduces
file size). Optionally, these internal nodes can be replaced
by device currents and saved.
DC Convergence Enhancements -
"Source-Stepping" algorithm modified with a "Dynamic" step size.
After each successful step, the node voltages are saved, the
source-factor is increased by the step-factor, and the step-factor
is increased (for the next step). If the step fails, i.e. the
circuit does not converge, the source-factor is set to the value
from the previous successful step, the previously stored node
voltages are restored, the step-factor is reduced, the source
factor is increased by this smaller step-factor, and convergance
is attempted again.
Same thing done for "Gmin-stepping" algorithm.
"Gshunt" option added. This sets the "diagGmin" variable used in
the gmin-stepping algorithm to a non-zero value for the final
solution. (Normally this is set to zero for the final solution).
This helps for circuits with floating nodes (and for some others
too).
The Gmin implementation across the substrate diodes of MOS1, MOS2,
MOS3, MOS6 and BSIM3 devices, and across BJT base-emitter and
base-collector diodes, was incorrect. Correcting this dramatically
improved DC convergance. (I think this also effects BSIM1 and 2
but I haven't fixed them yet !)
The gm, gmb and gds calculations in the MOS3 model were all wrong.
The device equations were fixed, leading to much improved
convergance.
The Vcrit value used for diode voltage limiting was calculated
without taking into account the device area (and in some cases
without using the temperature corrected saturation current).
This could cause floating point overflows, especially in device
models designed to be scaled by a small area, e.g. 2u by 2u diodes
(area=4e-12). This is now fixed for Diode, BJT, MOS1, MOS2, and
MOS3 models.
The diode voltage limiting was modified to add negative voltage
limiting. Negative diode voltages are now limited to 3*Vdp-10,
where Vdp is the voltage from the previous iteration. If Vdp is
positive, then the voltage is limited to -10V. This prevents some
more floating point overflows. (Actually, I'm still playing with
the best values for this).
The Spice3 "fix" for the MOS3 gds discontinuity between the
linear and saturated regions only works if the VMAX parameter
is non-zero. A "tweak" has been added for the VMAX=0 case.
Transient Convergance Enhancements -
Temperature correction of various diode capacitances was implemented
slightly incorrectly, leading to capacitance discontinuities in
simulations at temperatures other than nominal. This affected the
Diode and MOS3 models.
A mistake in the implementation of the MOS3 source-bulk capacitance
model resulted in a charge storage discontinuity. This has been fixed.
The level 2 MOSFET model seems to calculate Von and Vth values for
the threshold and subthreshold values respectively, but then uses
Vbin to calculate the Vdsat voltage used to find the drain current.
However, a jump statement uses Von to decide that the device is in
the "cutoff" region, which means that when this jump allows the
drain current to be calculated, Vdsat can already be well above
zero. This leads to a discontinuity of drain current with respect
to gate voltage. The code is now modified to use Vbin for the jump
decision. It looks like the code should actually use Vth as the
threshold voltage, but since PSPICE and HSPICE both follow the
original Berkeley code, this was left alone.
New Model Parameters -
A PSPICE/HSPICE-like "M" device parameter (i.e. M devices in
parallel) was added to the MOS1,2,3 and BSIM3 mosfet models.
Input Read-in and Checking -
Numbers beginning with a + sign got the input routine confused.
Fixed now.
Attempts to nodeset (or .IC) non-existant nodes are flagged with a
warning.
PWL statements on Voltage or Current sources are now checked for
"non-increasing" time-points at the start of the simulation.
Previously each time-point was checked as it was reached during
the simulation, which could be very annoying if you made a mistake
which caused the simulation to fail after hours of run-time.
A check which was performed at the end of each sub-circuit expansion
was moved to the top level. This check makes sure that all sub-circuits
have been defined, but in its original position, it meant that if a
sub-circuit included ANY .MODEL statements at all, then ALL the models
called in that sub-circuit must also be defined within that
sub-circuit. Now SPICE behaves as expected, i.e. a subcircuit may
define its own models, but may also use models defined at any level
above.
Miscellaneous Fixes/Enhancements -
MOS devices reported only half of the Meyer capacitances, and did not
include overlap capacitances, when reporting to the .OP printout, or
when storing device capacitances to the "rawfile".
The ideal switch devices had no time-step control to stop their
controlling voltages/currents overshooting the switching thresholds.
The time-step control has been modified to use the last two time
points to estimate if the next one will move the controlling
voltage/current past a switching threshold. If this looks likely,
then the time-step is reduced.
The "rawfile" writing routines have been modified to print the
"reference value" to the console during the simulation. This lets
the user see exactly how far and how fast the simulation is
proceeding.
.OP printout tidied up a lot to make the printout clearer.
Analysis order changed to fix a "feature" where, if you ask for
a .OP and a .TRAN in the same simulation, the node voltages
printed out correspond to the .OP, but the device data was from
the last timepoint of the .TRAN
Etc. -
There are other minor bug fixes, and changes to reduce compiler
warnings. There are probably some more significant fixes which
I've forgotten :-)
Ng-spice-rework-12
============
Arno did a great work this summer!
The pole-zero analysis has been corrected. The error was introduced
in an attempt to eliminate compiler warnings. The source has been
reworked and info file have been updated. As you may see, a new dir
called "spicelib" has been created, another step toward the separation
of the simulator from the frontend.
Ng-spice-rework-11
============
Resistor code (device) has been modified to conform to spice3 device
coding standard.
A new step function (U2) has been introduced.
Documentation updated.
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.
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.
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.
@ -74,13 +270,13 @@ 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.
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.
3) Now the resistor model can accepts two differents values for DC and
AC resistance.
@ -94,11 +290,11 @@ 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.
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).
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.

69
README
View File

@ -1,32 +1,32 @@
README for NGSPICE
------------------
This long message describes what NG-SPICE may become in the (near ?)
This long message describes what NGSPICE 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
features of ngspice 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
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 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
analyses. On the more "social" side: it's well introduced in the
academic environment.
** What does NG-SPICE mean ?
** What does NGSPICE 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
the projest. This projects still lacks a name. NGSPICE is a temporary
name.
** What will NG-SPICE be ?
** What will NGSPICE be ?
Berkeley's Spice lacks in three directions:
@ -51,53 +51,56 @@ Berkeley's Spice lacks in three directions:
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
* 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, 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.
Network analysis: given four nodes, extract z,y,s and the other
double bipole parameters.
Monte Carlo analisys: statistical simulation based on device
tolerances.
Monte Carlo analysis: statistical simulation based on device
parameters tolerances.
Worst Case analisys: find the worst case of operation of a given
circuit based on device tolerances.
Worst Case analysis: find the worst case of operation of a given
circuit based on device parameters tolerances.
Parametric analisys: repeat an analysis when one or more parameters
Parametric analysis: 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.
simulate simple digital circuits.
Dynamically loading of device: reduce the memory occupied by the
simulator by using shared object code for devices. Each device
simulator 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.
for doing this at the Sematech ftp site.
Improving device: Include additional parameters to some devices:
HDIF, LDIF, etc. (Serban, can you explain better).
HDIF, LDIF, etc.
- Numerical Algs -
Integration: include (if necessary) more stable algorithms for
integration. Runge-Kutta Methods ?
integration. What about Runge-Kutta Methods ?
How if we check LKC at every node as convergence test ?
Linearization:
Are there better algorithms for nonlinear equations the the Newton
raphson ?
- Sparse Matrix -
Faster handling of sparse matrices.
Faster handling of sparse matrices: new processors offers generous
caches and vectors operations.
- Options -
@ -136,25 +139,27 @@ 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.
ngspice-users@lists.sourceforge.net: This list is the list for the users of the
ngspice simulator.
ng-spice-devel@ieee.ing.uniroma1.it: ng-spice development issues.
ngspice-devel@lists.sourceforge.net: ngspice development issues. Developers and
"want to be" developers should
subscribe here.
ng-spice-frontends@ieee.ing.uniroma1.it: issues related to development of
frontends for ng-spice.
ngspice-frontend@list.sourceforge.net: issues related to development of
frontends for ngspice.
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>
<ngspice-users-subscribe@lists.sourceforge.net>
<ngspice-devel-subscribe@lists.sourceforge.net>
<ngspice-frontend-subscribe@lists.sourceforge.net>
WEB SITE:
--------
This project is hosted on the IEEE Central & South Italy Section Server.
The home page is http://ieee.ing.uniroma1.it/ngspice
This project is hosted on Sourceforge.
The home page is http://ngspice.sourceforge.net
Manu (emmanuel.rouat@wanadoo.fr)
Paolo (p.nenzi@ieee.org)

View File

@ -8,6 +8,9 @@
/* Define the build date */
#define NGSPICEBUILDDATE none
/* Define if we want garbage collection enabled */
#undef HAVE_LIBGC
/* Define if we have termcap */
#undef HAVE_TERMCAP
@ -22,3 +25,24 @@
/* Define if we want some experimental code */
#undef EXPERIMENTAL_CODE
/* Define if we want noise integration code */
#undef INT_NOISE
/* Undefine HAVE_EKV since it is not included in the standard distribution */
#undef HAVE_EKV
/* Define if we have GNU readline */
#undef HAVE_GNUREADLINE
/* We do not want spurios debug info into non-developer code */
#undef FTEDEBUG
/*The xspice enhancements*/
#undef XSPICE
/*Tcl Spice module*/
#undef TCL_MODULE
/* Spice cluster support */
#undef CLUSTER

View File

@ -2,8 +2,8 @@
# Run this to generate all the initial makefiles, etc.
PROJECT=ng-spice
TEST_TYPE=-d
FILE=src/circuit
TEST_TYPE=-f
FILE=DEVICES
DIE=0
@ -40,34 +40,10 @@ test $TEST_TYPE $FILE || {
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."

View File

@ -1,8 +1,16 @@
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 Initialize automake stuff
AM_INIT_AUTOMAKE(ng-spice-rework,14)
dnl --enable-ftedebug : enable frontend debug macros
AC_ARG_ENABLE(ftedebug,
[ --enable-ftedebug Enable ngspice frontend debug])
dnl --enable-ansi : try to force --ansi option to the compiler
AC_ARG_ENABLE(ansi,
[ --enable-ansi Force --ansi option for compilation])
@ -27,13 +35,33 @@ dnl --enable-sense2 : define HAVE_SENSE2 for the code
AC_ARG_ENABLE(sense2,
[ --enable-sense2 Use spice2 sensitivity analysis])
dnl --enable-intnoise : define INT_NOISE for the code
AC_ARG_ENABLE(intnoise,
[ --enable-intnoise Enables noise integration in noise analysis])
dnl --enable-smoketest : a smoketest
AC_ARG_ENABLE(smoketest,
[ --enable-smoketest Enables smoketest compile])
dnl --enable-experimental : define EXPERIMENTAL_CODE for the code
AC_ARG_ENABLE(experimental,
[ --enable-experimental Enables some experimental code])
dnl --enable-ekv: define HAVE_EKV in the code. This is for EKV model support
AC_ARG_ENABLE(ekv,
[ --enable-ekv Enables ekv model *not in standard distribution*])
dnl Initialize automake stuff
AM_INIT_AUTOMAKE(ng-spice-rework,10)
dnl --enable-xspice: define XSPICE in the code. This is for xspice support
AC_ARG_ENABLE(xspice,
[ --enable-xspice Enables XSpice enchancements, experimental *not in standard distribution*])
dnl --enable-tcl: define TCL_MODULE in the code. This is for tcl support
AC_ARG_ENABLE(tcl,
[ --enable-tcl Compiles the tcl module instead, experimental, see README in src/tcl/README])
dnl --enable-cluster: define CLUSTER in the code. This is for tcl support
AC_ARG_ENABLE(cluster,
[ --enable-cluster Enables cluster support, experimental *not in standard distribution*])
dnl Enable maintainer commands only if requested
AM_MAINTAINER_MODE
@ -52,6 +80,7 @@ if test "$enable_debug" = "no"; then
CFLAGS=" "
fi
dnl Not sure that this will work....
if test "$with_checkergcc" = "yes"; then
CC="checkergcc"
@ -68,24 +97,20 @@ if test "$enable_ansi" = "yes"; then
fi
fi
if test "$enable_smoketest" = "yes"; then
dnl CFLAGS="$CFLAGS -Werror"
CFLAGS="$CFLAGS -pedantic -W -Wmissing-prototypes"
CFLAGS="$CFLAGS -Wstrict-prototypes -Wtraditional"
CFLAGS="$CFLAGS -Wconversion -Wshadow -Wpointer-arith"
CFLAGS="$CFLAGS -Wcast-qual -Wcast-align -Wwrite-strings"
CFLAGS="$CFLAGS -Waggregate-return -fshort-enums -fno-common"
CFLAGS="$CFLAGS -Wnested-externs -Dinline= -g -O4"
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
@ -93,6 +118,99 @@ AC_LIBTOOL_DLOPEN
AM_PROG_LIBTOOL
dnl
dnl The tclSpice options
dnl
if test "$enable_tcl" = "yes"; then
AC_DEFINE(TCL_MODULE)
with_x=no
AC_MSG_CHECKING([for tclConfig.sh])
tcl_config_sh=""
if test "x$blt_with_tcl" != "x" ; then
for dir in \
$blt_with_tcl
do
if test -r "$dir/tclConfig.sh" ; then
tcl_config_sh="$dir/tclConfig.sh"
break
elif test -r "$dir/lib/tclConfig.sh" ; then
tcl_config_sh="$dir/lib/tclConfig.sh"
break
elif test -r "$dir/unix/tclConfig.sh" ; then
tcl_config_sh="$dir/unix/tclConfig.sh"
break
fi
done
else
for dir in \
$prefix \
$exec_prefix
do
if test -r "$dir/tclConfig.sh" ; then
tcl_config_sh="$dir/tclConfig.sh"
break
elif test -r "$dir/lib/tclConfig.sh" ; then
tcl_config_sh="$dir/lib/tclConfig.sh"
break
elif test -r "$dir/unix/tclConfig.sh" ; then
tcl_config_sh="$dir/unix/tclConfig.sh"
break
fi
done
if test "x$tcl_config_sh" = "x" ; then
for dir in \
`ls -dr /usr/local/tcl/tcl[[7-9]].[[0-9]]* 2>/dev/null` \
/usr/local/tcl \
/usr/local \
/usr
do
if test -r "$dir/tclConfig.sh" ; then
tcl_config_sh="$dir/tclConfig.sh"
break
elif test -r "$dir/lib/tclConfig.sh" ; then
tcl_config_sh="$dir/lib/tclConfig.sh"
break
fi
done
fi
fi
AC_MSG_RESULT([${tcl_config_sh}])
if test "x$tcl_config_sh" = "x" ; then
echo "can't find Tcl configuration script \"tclConfig.sh\""
exit 1
fi
. $tcl_config_sh
AC_MSG_CHECKING(for TCL module BLT)
rm -f conftest.tcl
cat > conftest.tcl << EOF
package require BLT;
exit;
EOF
if (wish conftest.tcl; exit) 2>/dev/null; then
AC_MSG_RESULT(Found)
else
AC_MSG_ERROR(Couldn't find BLT)
fi
rm -f conftest.tcl
else
TCL_PACKAGE_PATH=""
TCL_BUILD_LIB_SPEC=""
fi
AC_SUBST(TCL_PACKAGE_PATH)
AC_SUBST(TCL_BUILD_LIB_SPEC)
dnl Checks for X11 header files and libraries - X11 support can be disabled
dnl by passing the '--without-x' option to configure:
@ -109,8 +227,9 @@ 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)
AC_CHECK_LIB(Xaw,main,X_LIBS="$X_LIBS -lXaw",AC_MSG_ERROR(Couldn't find Xaw librairies),$X_LIBS $X_EXTRA_LIBS)
fi
@ -126,7 +245,7 @@ AC_SEARCH_LIBS(tputs,ncurses termcap,AC_DEFINE(HAVE_TERMCAP),
AC_HEADER_DIRENT
AC_CHECK_HEADERS(ctype.h unistd.h pwd.h fcntl.h)
AC_CHECK_HEADERS(ctype.h unistd.h pwd.h fcntl.h string.h)
AC_HEADER_SYS_WAIT
AC_HEADER_STAT
@ -158,6 +277,13 @@ 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)
AC_MSG_RESULT(Checking for the presence of the Garbage Collector:)
dnl Check for the garbage collector:
AC_CHECK_LIB(gc,GC_malloc,AC_DEFINE(HAVE_LIBGC) LIBS="$LIBS -lgc")
dnl Check for the asprintf function:
AC_CHECK_FUNCS(asprintf)
# Expand the prefix variable (this is really annoying!)
if eval "test x$prefix = xNONE"; then
@ -167,7 +293,7 @@ else
fi
AC_DEFINE_UNQUOTED(NGSPICEBINDIR, "`echo $dprefix/bin`" )
AC_DEFINE_UNQUOTED(NGSPICEDATADIR, "`echo $dprefix/share/ng-spice`" )
AC_DEFINE_UNQUOTED(NGSPICEDATADIR, "`echo $dprefix/share/ng-spice-rework`" )
AC_DEFINE_UNQUOTED(NGSPICEBUILDDATE, "`date`" )
@ -185,11 +311,75 @@ if test "$enable_predictor" = "yes"; then
AC_DEFINE(PREDICTOR)
AC_MSG_RESULT(PREDICTOR algorithm enabled)
fi
if test "$enable_intnoise" = "yes"; then
AC_DEFINE(INT_NOISE)
AC_MSG_RESULT(Noise integration enabled)
fi
if test "$enable_experimental" = "yes"; then
AC_DEFINE(EXPERIMENTAL_CODE)
AC_MSG_RESULT(EXPERIMENTAL_CODE enabled)
fi
if test "$enable_ftedebug" = "yes"; then
AC_DEFINE(FTEDEBUG)
AC_MSG_RESULT(WARNING: Frontend debug is enabled)
fi
if test "$enable_ekv" = "yes"; then
AC_MSG_RESULT(Model EKV included)
AC_DEFINE(HAVE_EKV)
EKVDIR="ekv"
EKVLIB="spicelib/devices/ekv/libekv.la"
else
EKVDIR=""
EKVLIB=""
fi
AC_SUBST(EKVDIR)
AC_SUBST(EKVLIB)
if test "$enable_xspice" = "yes"; then
AC_MSG_RESULT(X-Spice features included)
AC_DEFINE(XSPICE)
XSPICEDIR="xspice"
XSPICELIB1="$XSPICEDIR/xspice.o \
$XSPICEDIR/mif/libmifxsp.a \
$XSPICEDIR/cm/libcmxsp.a"
XSPICELIB2="$XSPICEDIR/evt/libevtxsp.a \
$XSPICEDIR/enh/libenhxsp.a \
$XSPICEDIR/ipc/libipcxsp.a \
$XSPICEDIR/idn/libidnxsp.a \
-ldl"
else
XSPCIEDIR=""
XSPICELIB1=""
XSPICELIB2=""
fi
AC_SUBST(XSPICEDIR)
AC_SUBST(XSPICELIB1)
AC_SUBST(XSPICELIB2)
dnl Printout Tcl option
if test "$enable_tcl" = "yes"; then
AC_MSG_RESULT(Tcl module being made, use "make tcl" and "make tcl_install", read README in src/tcl/README)
fi
dnl Cluster option
if test "$enable_cluster" = "yes"; then
AC_MSG_RESULT(Cluster version is being compiled)
AC_DEFINE(CLUSTER)
LIBS="$LIBS -lpthread"
fi
dnl --with-readline : the user wants to use readline library
AC_ARG_WITH(readline,
[ --with-readline Use the readline package: SEE README],
AC_MSG_RESULT(Checking for readline library:)
dnl Check for the readline library:
AC_CHECK_LIB(readline,readline, AC_DEFINE(HAVE_GNUREADLINE) LIBS="$LIBS -lreadline")
)
AC_OUTPUT( \
Makefile \
@ -197,49 +387,78 @@ 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/spicelib/Makefile \
src/spicelib/analysis/Makefile \
src/spicelib/devices/Makefile \
src/spicelib/devices/asrc/Makefile \
src/spicelib/devices/bjt/Makefile \
src/spicelib/devices/bjt2/Makefile \
src/spicelib/devices/bsim1/Makefile \
src/spicelib/devices/bsim2/Makefile \
src/spicelib/devices/bsim3v1/Makefile \
src/spicelib/devices/bsim3/Makefile \
src/spicelib/devices/bsim4/Makefile \
src/spicelib/devices/bsim3v2/Makefile \
src/spicelib/devices/bsim3soi_pd/Makefile \
src/spicelib/devices/bsim3soi_fd/Makefile \
src/spicelib/devices/bsim3soi_dd/Makefile \
src/spicelib/devices/cap/Makefile \
src/spicelib/devices/cccs/Makefile \
src/spicelib/devices/ccvs/Makefile \
src/spicelib/devices/csw/Makefile \
src/spicelib/devices/cpl/Makefile \
src/spicelib/devices/dio/Makefile \
src/spicelib/devices/ekv/Makefile \
src/spicelib/devices/ind/Makefile \
src/spicelib/devices/isrc/Makefile \
src/spicelib/devices/hfet1/Makefile \
src/spicelib/devices/hfet2/Makefile \
src/spicelib/devices/jfet/Makefile \
src/spicelib/devices/jfet2/Makefile \
src/spicelib/devices/ltra/Makefile \
src/spicelib/devices/mes/Makefile \
src/spicelib/devices/mesa/Makefile \
src/spicelib/devices/mos1/Makefile \
src/spicelib/devices/mos2/Makefile \
src/spicelib/devices/mos3/Makefile \
src/spicelib/devices/mos6/Makefile \
src/spicelib/devices/mos9/Makefile \
src/spicelib/devices/res/Makefile \
src/spicelib/devices/soi3/Makefile \
src/spicelib/devices/sw/Makefile \
src/spicelib/devices/tra/Makefile \
src/spicelib/devices/txl/Makefile \
src/spicelib/devices/urc/Makefile \
src/spicelib/devices/vccs/Makefile \
src/spicelib/devices/vcvs/Makefile \
src/spicelib/devices/vsrc/Makefile \
src/spicelib/parser/Makefile \
src/frontend/Makefile \
src/hlp/Makefile \
src/frontend/help/Makefile \
src/frontend/parser/Makefile \
src/frontend/plotting/Makefile \
src/include/Makefile \
src/maths/Makefile \
src/maths/cmaths/Makefile \
src/maths/ni/Makefile \
src/maths/deriv/Makefile \
src/maths/poly/Makefile \
src/maths/sparse/Makefile \
src/misc/Makefile \
src/parser/Makefile \
src/xspice/Makefile \
src/xspice/cm/Makefile \
src/xspice/mif/Makefile \
src/xspice/evt/Makefile \
src/xspice/enh/Makefile \
src/xspice/ipc/Makefile \
src/xspice/idn/Makefile \
tests/Makefile \
tests/filters/Makefile \
tests/polezero/Makefile \
tests/resistance/Makefile \
tests/bsim3soipd/Makefile \
tests/bsim3soifd/Makefile \
tests/bsim3soidd/Makefile \
tests/bsim4/Makefile \
tests/mesa/Makefile
)

View File

@ -1,10 +1,16 @@
2000-03-22 Paolo Nenzi <p.nenzi@ieee.org>
2000-10-10 Arno W. Peters <A.W.Peters@ieee.org>
* mslib, spiceprm: Michael Widlok released new version of his
programs.
2000-03-22 Paolo Nenzi <p.nenzi@ieee.org>
* mslib: Major update. M. Widlok sent the new version of it's programs.
* 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>
1999-09-14 Arno W. Peters <A.W.Peters@ieee.org>
* mslib: Added.

View File

@ -92,10 +92,11 @@ readlib(struct LSData *lib, FILE * tlib, \
{
char name[BSIZE];
int numi, wflag;
int numi, wflag, nextsub;
numi = 0;
wflag = NOWRITE;
nextsub = 0;
while (fgets(buf, bsizer, lib->filedes))
{
@ -128,7 +129,16 @@ readlib(struct LSData *lib, FILE * tlib, \
case (SUBLLINE):
if (sub)
{
if (checkname(sub, name))
if (wflag==WRITESUB)
{
/* subckt inside subckt
not so funny */
nextsub++;
fputs(buf, tlib);
break;
}
if (checkname(sub, name))
{
wflag = WRITESUB;
numi++;
@ -150,12 +160,20 @@ readlib(struct LSData *lib, FILE * tlib, \
break;
case (ENDSLLINE):
if (wflag == WRITESUB)
if (nextsub)
{
nextsub--;
fputs(buf, tlib);
break;
} else {
if (wflag == WRITESUB)
{
fprintf(tlib, "%s\n* End Subckt\n\n", buf);
}
wflag = NOWRITE;
break;
}
case (CONTLLINE):
if (wflag != NOWRITE)

View File

@ -7,6 +7,9 @@ HDRS= datadef.h
SRCC= inc_main.c inc_inp.c inc_LSD.c
mslib: $(OBJS)
$(CC) $(LDFLAGS) -o $@ $(OBJS)
$(CC) $(LDFLAGS) -o $@ $(OBJS)
$(OBJS): $(HDRS)
clean:
$(RM) $(OBJS) mslib
$(OBJS): $(HDRS)

View File

@ -1,3 +1,10 @@
-------------------------------
MW. 01-10-2000
Bugs Fixes -
-----------
.subckt inside another parametrized .subckt works right now.
----------------------------------------------------------------------
Version 0.11 January 2, 1996
----------------------------------------------------------------------

View File

@ -163,8 +163,9 @@ sub prm_scan {
}
$hasprm = 0;
undef @list; $sublist = '';
last PRM_TST;
}
last PRM_TST;
# MW. 'last PRM_TST' should be inside 'if' loop to allow nestle subckts.
}
if ($depth) {
push(@list, $_);
@ -248,7 +249,7 @@ sub prm_wr {
last PRMWR_SCAN;
}
if (/^\.ends/) {
if (--$depth == 0) { $sublist = ''; }
if (--$depth == 0) { $sublist = ''; }
else { $sublist =~ s/(\#\w+)$//; }
}
prm_wrline($_);

View File

@ -1,3 +1,15 @@
2001-12-05 Emmanuel Rouat <emmanuel.rouat@wanadoo.fr>
* ngspice.texi: changed (most) references of spice3 to ngspice.
2001-12-04 Emmanuel Rouat <emmanuel.rouat@wanadoo.fr>
* ngspice.texi: corrected a few bugs, and made some chapters readable.
2000-05-22 Paolo Nenzi <p.nenzi@ieee.org>
* ngspice.texi: Added text for u2 function and for resistance ac
paramter.
1999-09-06 Arno Peters <A.W.Peters@ieee.org>
* ngspice.texi: Added TeX equivalents for some formula.

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
## Process this file with automake to produce Makefile.in
man_MANS = spice.1 nutmeg.1 sconvert.1
man_MANS = ngspice.1 ngnutmeg.1 ngsconvert.1
EXTRA_DIST = $(man_MANS)

View File

@ -1,3 +1,82 @@
2001-12-04 Emmanuel Rouat <emmanuel.rouat@wanadoo.fr>
* maths/cmaths/Makefile.am (noinst_PROGRAMS): test programs
shouldnt get installed
2000-10-13 Arno W. Peters <A.W.Peters@ieee.org>
* ngspice.txt: changes SPICE: to NGSPICE: to restore help
functionality. Thanks go to Michael Widlok for the analysis.
2000-07-21 Arno W. Peters <A.W.Peters@ieee.org>
* src/analysis/*: Moved these files into src/devices/analysis.
The files in this directory implement the analysis and simulation
for electrical circuits.
This is the final step to separating the Spice sources into a
library part and a frontend part. Now, the devices subdirectory
has to be renamed to spicelib and the devices that are now
scattered in that directory should be moved into a new devices
directory.
* configure.in, src/Makefile.am, src/devices/Makefile.am: Files
affected by the move.
2000-07-20 Arno W. Peters <A.W.Peters@ieee.org>
* src/hlp/*: moved these files into src/frontend/help. The files
in this directory implement the help system for the frontend.
* configure.in, src/Makefile.am, src/frontend/Makefile.am: Files
affected by the move.
* src/circuit/*: moved these files into src/devices/parser. The
files in this directory take a model line from the input file and
add the corresponding element to the representation of
the circuit in memory.
* configure.in, src/Makefile.am, src/devices/Makefile.am: Files
affected by the move.
2000-07-18 Arno W. Peters <A.W.Peters@ieee.org>
* main.c: Added the call to the initialization function of the
devices.
2000-07-07 Arno W. Peters <A.W.Peters@ieee.org>
* parser/cshpar.c: Separated out com_chdir(), com_echo(),
com_rehash() and com_shell() and moved them into frontend
directory.
* frontend/com_chdir.c, frontend/com_echo.c, frontend/com_rehash.c,
frontend/com_shell.c: Their new homes.
* parser/quote.c, parser/quote.h: The quote/unquote functions are
used exclusively in the frontend, moved them there.
* frontend/quote.c, frontend/quote.h: Their new location.
* parser/input.c, parser/input.h: Input, output and error streams
handled in the frontend. Moved to the frontend directory.
* frontend/streams.c: Its new home.
* frontend/Makefile.am: Updates for new files.
* frontend/breakp2.c, frontend/newcoms.c, frontend/postcoms.c,
frontend/resource.c, frontend/terminal.h, frontend/variable.c,
frontend/variable.h, frontend/com_compose.c,
frontend/com_display.c, frontend/com_setscale.c,
frontend/com_strcmp.c: Include files update.
* parser/var2.c, parser/var2.h: Empty files, removed.
* parser/Makefile.am: Updates for removed files.
* parser/lexical.c: Small adjustments
2000-04-04 Paolo Nenzi <p.nenzi@ieee.org>
* ngspice.c: Added support for BSIM4.

View File

@ -1,61 +1,64 @@
## Process this file with automake to produce Makefile.in
SUBDIRS = analysis circuit devices frontend hlp maths misc parser include
SUBDIRS = misc maths frontend spicelib include @XSPICEDIR@
bin_PROGRAMS = ngspice nutmeg help sconvert proc2mod multidec makeidx
bin_PROGRAMS = ngspice ngnutmeg nghelp ngsconvert ngproc2mod ngmultidec makeidx
EXTRA_DIST = ngspice.txt ngspice.idx
EXTRA_DIST = ngspice.txt spinit setplot spectrum
helpdatadir = $(pkgdatadir)/helpdir
helpdata_DATA = ngspice.idx ngspice.txt
helpdata_DATA = ngspice.txt
initdatadir = $(pkgdatadir)/scripts
initdata_DATA = spinit setplot spectrum
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
spicelib/devices/asrc/libasrc.la \
spicelib/devices/bjt/libbjt.la \
## spicelib/devices/bjt2/libbjt2.la \
spicelib/devices/bsim1/libbsim1.la \
spicelib/devices/bsim2/libbsim2.la \
spicelib/devices/bsim3/libbsim3.la \
spicelib/devices/bsim3v1/libbsim3v1.la \
spicelib/devices/bsim3v2/libbsim3v2.la \
spicelib/devices/bsim4/libbsim4.la \
spicelib/devices/cap/libcap.la \
spicelib/devices/bsim3soi_pd/libbsim3soipd.la \
spicelib/devices/bsim3soi_fd/libbsim3soifd.la \
spicelib/devices/bsim3soi_dd/libbsim3soidd.la \
spicelib/devices/cccs/libcccs.la \
spicelib/devices/ccvs/libccvs.la \
spicelib/devices/ccvs/libccvs.la \
spicelib/devices/cpl/libcpl.la \
spicelib/devices/csw/libcsw.la \
spicelib/devices/dio/libdio.la \
@EKVLIB@ \
spicelib/devices/ind/libind.la \
spicelib/devices/isrc/libisrc.la \
spicelib/devices/hfet1/libhfet.la \
spicelib/devices/hfet2/libhfet2.la \
spicelib/devices/jfet/libjfet.la \
spicelib/devices/jfet2/libjfet2.la \
spicelib/devices/ltra/libltra.la \
spicelib/devices/mes/libmes.la \
spicelib/devices/mesa/libmesa.la \
spicelib/devices/mos1/libmos1.la \
spicelib/devices/mos2/libmos2.la \
spicelib/devices/mos3/libmos3.la \
spicelib/devices/mos6/libmos6.la \
spicelib/devices/mos9/libmos9.la \
spicelib/devices/res/libres.la \
spicelib/devices/soi3/libsoi3.la \
spicelib/devices/sw/libsw.la \
spicelib/devices/txl/libtxl.la \
spicelib/devices/tra/libtra.la \
spicelib/devices/urc/liburc.la \
spicelib/devices/vccs/libvccs.la \
spicelib/devices/vcvs/libvcvs.la \
spicelib/devices/vsrc/libvsrc.la
## Build ngspice first:
@ -67,75 +70,80 @@ ngspice_SOURCES = \
ngspice_LDADD = \
spice.o \
frontend/libfte.a \
$(DYNAMIC_DEVICELIBS) \
analysis/libckt.a \
parser/libparser.a \
hlp/libhlp.a \
circuit/libinp.a \
frontend/plotting/libplotting.a \
@XSPICELIB1@ \
spicelib/devices/dev.o \
$(DYNAMIC_DEVICELIBS) \
spicelib/analysis/libckt.a \
spicelib/devices/libdev.a \
@XSPICELIB2@ \
frontend/parser/libparser.a \
frontend/help/libhlp.a \
spicelib/parser/libinp.a \
maths/deriv/libderiv.a \
maths/cmaths/libcmaths.a \
maths/poly/libpoly.a \
maths/ni/libni.a \
maths/sparse/libsparse.a \
misc/libmisc.a
misc/libmisc.a
spice.o: main.c
$(COMPILE) -DSIMULATOR -o spice.o -c $(srcdir)/main.c
## nutmeg:
nutmeg_SOURCES = \
ngnutmeg_SOURCES = \
main.c \
conf.c \
conf.h \
nutmeg.c
ngnutmeg.c
nutmeg_LDADD = \
ngnutmeg_LDADD = \
frontend/libfte.a \
parser/libparser.a \
hlp/libhlp.a \
frontend/plotting/libplotting.a \
frontend/parser/libparser.a \
frontend/help/libhlp.a \
maths/cmaths/libcmaths.a \
maths/poly/libpoly.a \
misc/libmisc.a
## help:
help_SOURCES = help.c
nghelp_SOURCES = nghelp.c
help_LDADD = \
hlp/libhlp.a \
parser/libparser.a \
nghelp_LDADD = \
frontend/help/libhlp.a \
frontend/parser/libparser.a \
frontend/libfte.a \
misc/libmisc.a
## sconvert:
sconvert_SOURCES = sconvert.c
ngsconvert_SOURCES = ngsconvert.c
sconvert_LDADD = \
ngsconvert_LDADD = \
frontend/libfte.a \
parser/libparser.a \
misc/libmisc.a
frontend/parser/libparser.a \
misc/libmisc.a
## proc2mod:
proc2mod_SOURCES = proc2mod.c
ngproc2mod_SOURCES = ngproc2mod.c
proc2mod_LDADD = \
parser/libparser.a \
circuit/libinp.a \
ngproc2mod_LDADD = \
frontend/parser/libparser.a \
spicelib/parser/libinp.a \
misc/libmisc.a
## multidec:
multidec_SOURCES = multidec.c
ngmultidec_SOURCES = ngmultidec.c
multidec_LDADD = \
ngmultidec_LDADD = \
maths/sparse/libsparse.a \
misc/libmisc.a
@ -155,8 +163,57 @@ all:
## General Includes and libraries:
INCLUDES = -I$(top_srcdir)/src/include -I$(top_srcdir)/src/devices @X_CFLAGS@
INCLUDES = -I$(top_srcdir)/src/include -I$(top_srcdir)/src/spicelib/devices @X_CFLAGS@
LIBS = @LIBS@ @X_LIBS@ @X_PRE_LIBS@ @X_EXTRA_LIBS@
MAINTAINERCLEANFILES = Makefile.in
CLEANFILES = pkgIndex.tcl libspice.so
TCL_PKG_PATH = @TCL_PACKAGE_PATH@
TCLSPICE_VERSION = 0.2.7
TCL_FILES = libspice.so pkgIndex.tcl
LIBSPICE_OBJS = tclspice.o
pkgIndex.tcl: pkgIndex.tcl.in
rm -f pkgIndex.tcl
sed -e 's;%LIB_DIR%;$(TCL_PKG_PATH);g' pkgIndex.tcl.in | \
sed -e 's;%VERSION%;$(TCLSPICE_VERSION);g' > pkgIndex.tcl
tcl_install: tcl-install-recursive install-tclspice
tcl-install-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) install) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done;
install-tclspice: ${TCL_FILES}
install -c -m 644 libspice.so $(TCL_PKG_PATH)
mkdir -p $(TCL_PKG_PATH)/spice
install -c -m 644 pkgIndex.tcl $(TCL_PKG_PATH)/spice
tclspice.o: tclspice.c
$(COMPILE) -c -fpic tclspice.c -DTCLSPICE_version="\"$(TCLSPICE_VERSION)\""
libspice.so: $(ngspice_OBJECTS) $(LIBSPICE_OBJS) $(ngspice_DEPENDENCIES)
$(LINK) $(ngspice_LDFLAGS) $(ngspice_OBJECTS) $(ngspice_LDADD) $(LIBS) $(LIBSPICE_OBJS) -shared -lpthread
if test -f .libs/$@ ; then \
mv .libs/$@ ./ ;\
rmdir .libs ;\
fi
tcl: tcl-recursive
tcl-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) all) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done;
make ${TCL_FILES}

View File

@ -1,31 +1,230 @@
2001-11-25 Emmanuel Rouat <emmanuel.rouat@wanadoo.fr>
* circuits.h: transfered definition of sstructire 'circ' to ftedefs.h
2001-02-07 Paolo Nenzi <p.nenzi@ieee.org>
* outitf.c: From a message Alan sento to the mailing list:
---------- Forwarded message ----------
Date: Tue, 6 Feb 2001 11:11:56 -0000
From: "Gillespie, Alan" <Alan.Gillespie@analog.com>
Reply-To: ng-spice-devel@ieee.ing.uniroma1.it
To: "Ng-Spice-Devel (E-mail)" <ng-spice-devel@ieee.ing.uniroma1.it>
Subject: [ng-spice-devel] Reference variable update in interactive mode
I've tweaked outitf.c so that the reference variable value
is updated to the screen in interactive mode. I forgot to
save the old version first, though, so I couldn't do a diff,
so I'm just attaching the whole new outitf.c file. Also, I've
updated the documentation as follows :-
Modifications to "outitf.c"
---------------------------
A number of modifications have been applied to outitf.c in
order to achieve the following "improvements" :-
1) Spice3, by default, saved all node voltages, including
nodes internal to the devices. These extra nodes add
dramatically to the amount of data saved, but don't add
significantly to the useful information about the circuit.
So, instead of saving these nodes, a "hack" has been
introduced which checks a new spice option, and either
discards the internal node, or saves some device currents
instead.
2) During long simulations, spice would sit "staring back
blankly", giving no clue as to how well the simulation
was, or wasn't, proceeding. In order to give a little
more feedback, another "hack", in the data writing routine,
writes the value of the reference variable to the error
stream, which is usually the screen. In order to minimize
the CPU time "wasted" doing this, the routine will only
reprint the value if more than a quarter of a second since
the last screen update. The result is that this feedback
adds no significant extra time to performance of the
simulation.
3) The original file writing routines used to write each data
value to the file individually. A buffering scheme was added,
which collects each row of data in a buffer, and the writes
the whole buffer in one call. This gave a significant
performance improvement (up to 20%) on HPUX, with all currents
saved in large circuits, although there was no significant
difference on Windows 95. The improvement has not been
measured on Linux.
4) A check was added to make sure the file write was successful.
Spice3 could easily fill the hard disk, but would continue to
churn away, producing no more useful data. Now it will exit
gracefully. I can't remember why I thought this was important,
but at least it means that a PC with power management will be
able to power down after a long overnight simulation has
ceased to produce any more useful data.
Changes
-------
The routine beginPlot is called at the beginning of the simulation
to select which nodes and variables will be saved. The first
modification is at the point where it checks the "save" list. This
is the list of tokens attached to the .save lines read from the
spice source file. The routine now checks for "allv" and "alli"
as well as "all". "allv" is treated as a synonym for "all". If
"all" or "allv" is found, then a saveall flag is set, and if "alli"
is found then a new savealli flag is set.
Next, the addDataDesc routine is called for every variable to be
saved. This is done by stepping through an array called dataNames[].
I'm not quite sure where this array comes from, but it was quite
easy to add an if statement to stop it calling addDataDesc if
dataNames[i] points to a string containing any of the following -
#internal
#source
#drain
#collector
#emitter
#base
That seems to catch all the internal device nodes.
The next addition is a new pass through the dataNames[] array
specifically looking for those strings. (This pass is only performed
if the savealli flag has been set). When one of the strings is found,
a bunch of if-then-else statements creates a corresponding string
which is submitted to the add addSpecialDesc routine. This saves the
relevant device current. Note that since mosfets have only two
internal nodes, but four terminal currents, and bipolars have three
internal nodes and four terminal currents, some internal nodes have
to save more than one terminal current.
This last change is a clumsy hack, and only works if the devices in
question actually have internal nodes. Resistors and capacitors, for
instance, never have internal nodes, and so their terminal currents
will not cannot be saved with the .save alli card. Also, any bipolar,
mosfet or diodes with zero valued parasitic resistances (rd, rs, rc,
rb, re) will not be allocated internal nodes, and so their terminal
currents will not be saved by this hack, either.
Further down outitf.c, the OUTpData routine is called whenever a
new row of data is ready to be written to file. Near the top of this,
the reference variable is written to file separately from the rest of
the variables. This is a convenient point for a couple of statements
which check the elapsed time since the last update, and write the
reference value to stderr if it's time. Slightly further down the
routine is the section for writing data to a "plot", i.e. retaining
it in memory. A similar statement or two writes the reference value
to the screen for this case, i.e. interactive mode. At the end of the
OUTpData routine, a new check has been added to see if there was an
error writing to the rawfile. If so, the shouldstop flag is set to
TRUE, and the simulation will abort.
Scanning down outitf.c, the next modification is in the fileInit
routine. The first statement initialises the lastclock variable.
This is used later when deciding if it's time to write the reference
value to the screen.
Next, the fileInit_pass2 routine writes the name strings to the start
of the rawfile. At the end of this routine there is now a statement
which checks if this will be a binary rawfile, and if so, it allocates
a row buffer of the correct length.
The fileStartPoint routine seems to be called before each row of data
is written, and so this is a convenient point to reset the buffer
pointer to zero.
The fileAddRealValue and fileAddComplexValue routines now simply write
the relevant values to the buffer, and increment the buffer pointer.
Previously they called the fwrite library routine to actually write
the data. If the rawfile is not a binary one, however, they just write
the text as before.
The fileEndPoint routine was previously empty. Now it actually calls
fwrite to write the whole buffer to the file (if it's a binary file).
Finally the fileEnd routine prints the total number of data points to
the screen, and de-allocates the row buffer (if it was a binary
rawfile).
Congratulations to whoever put these dummy routines in in the first
place, since that allowed the buffering to be added very easily.
2001-01-23 Paolo Nenzi <p.nenzi@ieee.org>
* subckt.c: added some code (very, very experimental)
to support mos devices with variable number of nodes
(5 to 7) in subcircuit expansion. This hack is necessary
since SOI devices can have up to 7 nodes.
2000-11-07 Arno W. Peters <A.W.Peters@ieee.org>
* com_history, com_alias, parser/cshpar.c, parser/complete.c:
Applied patch by Michael Widlok. It fixes command completion and
history list. In the process, Michael also fixed a memory leak.
2000-09-09 Arno W. Peters <A.W.Peters@ieee.org>
* commands.c: Use fourier.h.
* dotcards.c: Update to prevent segfault.
* fourier.c, fourier.h: com_fourier is now calling fourier(), a
function with more parameters.
* dotcards.c: Added assertions to guard a double indirection, now
ngspice will bomb out on an assertion instead of a segfault.
2000-07-18 Arno W. Peters <A.W.Peters@ieee.org>
* com_ahelp.c, com_help.c, com_plot.c, com_set.c, com_unset.c:
Updated header file includes.
* quote.c: Code formatting changes.
2000-07-16 Arno W. Peters <A.W.Peters@ieee.org>
* com_set.h: New header file.
* com_state.c, com_state.h: Separated from debugcom.c.
* com_dump.c, com_dump.h: Separated from debugcom.c.
* debugcom.c, debugcom.h: Removed.
* Makefile.am: Updates for added/removed files.
2000-03-22 Paolo Nenzi <p.nenzi@ieee.org>
* rawfile.c: Applied Michael Widlok patch.
* spiceif.c: Applied Michael Widlok patch.
* rawfile.c: Applied Michael Widlok patch.
* spiceif.c: Applied Michael Widlok patch.
2000-03-12 Paolo Nenzi <p.nenzi@ieee.org>
* x11.c: Cleared the code. Rewmoved some empty return on void functions.
* x11.c: Cleared the code. Rewmoved some empty return on void
functions.
1999-12-20 Paolo Nenzi <p.nenzi@ieee.org>
outif.c:
To fix various "save"-related segmentation faults, make this one-line patch
to outitf.c: line 356, change
unique = devname; to unique = copy(devname);
* outif.c: To fix various "save"-related segmentation faults, make
this one-line patch to outitf.c: line 356, change unique =
devname; to unique = copy(devname);
1999-12-20 Paolo Nenzi <p.nenzi@ieee.org>
subckt.c:
Bug: Current controlled switch subcircuit does not expand
the controlling source correctly: vsrc expands to name:vsrc,
not to v:name:src.
Fix: changed this file to indicate that w device has only 2
not 3 nodes and 1 not zero controlling sources.
* subckt.c: Bug: Current controlled switch subcircuit does not
expand the controlling source correctly: vsrc expands to
name:vsrc, not to v:name:src.
Fix: changed this file to indicate that w device has only 2 not 3
nodes and 1 not zero controlling sources.
1999-09-07 Emmanuel Rouat <emmanuel.rouat@wanadoo.fr>
* *.c: put back static functions declarations back in the .c files (shouldn't
be in .h files!)
* *.c: put back static functions declarations back in the .c files
(shouldn't be in .h files!)
1999-09-07 Arno <A.W.Peters@ieee.org>
@ -34,7 +233,7 @@
* cmath1.c:
* cmath2.c: removed most warnings about possible use of
uninitialized variables. Only two remain in cx_sqrt().
uninitialized variables. Only two remain in cx_sqrt().
1999-09-06 Arno Peters <A.W.Peters@ieee.org>
@ -104,16 +303,14 @@
* resource.c: removed tests on HAS_UNIX_SEGMENT_HACK
* xgraph.c (ft_xgraph):
* options.c (cp_usrset):
* misccoms.c: removed tests on HAS_SYSTEM
* xgraph.c (ft_xgraph), options.c (cp_usrset), misccoms.c: removed
tests on HAS_SYSTEM
* nutinp.c:
* inp.c (com_source):
(doedit): removed tests on HAS_SYSTEM (always true?)
* nutinp.c, inp.c (com_source, doedit): removed tests on
HAS_SYSTEM (always true?)
* doplot.c (com_hardcopy): removed tests on HAS_UNLINK (always true)
(com_hardcopy): removed tests on HAS_SYSTEM (always true?)
* doplot.c (com_hardcopy): removed tests on HAS_UNLINK (always
true), removed tests on HAS_SYSTEM (always true?)
* signal.c:
* evaluate.c (doop):
@ -127,28 +324,22 @@
* aspice.c: changed HAS_WAIT into HAVE_SYS_WAIT_H
* inpcom.c:
* breakp.c: changed HAS_CTYPE into HAVE_CTYPE_H
* inpcom.c, breakp.c: changed HAS_CTYPE into HAVE_CTYPE_H
1999-08-03 Emmanuel Rouat <emmanuel.rouat@wanadoo.fr>
* signal.c:
* resource.c:
* evaluate.c:
* aspice.c: changed SIGNAL_TYPE into RETSIGTYPE
* signal.c, resource.c, evaluate.c, aspice.c: changed SIGNAL_TYPE
into RETSIGTYPE
1999-07-31 Emmanuel Rouat <emmanuel.rouat@wanadoo.fr>
* Makefile.am: added @X_CFLAGS@ (X11 header files) to INCLUDES and removed
unused LIBS list.
* Makefile.am: added @X_CFLAGS@ (X11 header files) to INCLUDES and
removed unused LIBS list.
28-07-1999 emmanuel.rouat@wanadoo.fr (Manu Rouat)
* graf.c:
* display.c:
* doplot.c:
* x11.c: changed HAS_X11 define to X_DISPLAY_MISSING, which is supplied
by autoconf in config.h
* graf.c, display.c, doplot.c, x11.c: changed HAS_X11 define
to X_DISPLAY_MISSING, which is supplied by autoconf in config.h
* removed -DWANT_X11 in Makefile.am
* Makefile.am: removed -DWANT_X11

View File

@ -1,125 +1,173 @@
## Process this file with automake to produce Makefile.in
SUBDIRS = plotting help parser
noinst_LIBRARIES = libfte.a
libfte_a_SOURCES = \
agraf.c \
agraf.h \
arg.c \
arg.h \
aspice.c \
aspice.h \
breakp.c \
breakp.h \
breakp2.c \
breakp2.h \
circuits.c \
circuits.h \
clip.c \
clip.h \
compose.c \
compose.h \
cpitf.c \
cpitf.h \
debugcom.c \
debugcom.h \
define.c \
define.h \
device.c \
device.h \
diff.c \
diff.h \
dimens.c \
dimens.h \
display.c \
display.h \
doplot.c \
doplot.h \
dotcards.c \
dotcards.h \
error.c \
error.h \
evaluate.c \
evaluate.h \
fourier.c \
fourier.h \
gens.c \
gens.h \
graf.c \
graf.h \
graphdb.c \
graphdb.h \
grid.c \
grid.h \
inp.c \
inp.h \
inpcom.c \
inpcom.h \
interp.c \
interp.h \
linear.c \
linear.h \
misccoms.c \
misccoms.h \
miscvars.c \
miscvars.h \
mw_coms.c \
mw_coms.h \
newcoms.c \
newcoms.h \
nutctab.c \
nutctab.h \
nutinp.c \
nutinp.h \
nutmegif.c \
nutmegif.h \
options.c \
options.h \
outitf.c \
outitf.h \
parse.c \
parse.h \
plot5.c \
plot5.h \
plotcurv.c \
plotcurv.h \
points.c \
points.h \
postcoms.c \
postcoms.h \
postsc.c \
postsc.h \
rawfile.c \
rawfile.h \
resource.c \
resource.h \
runcoms.c \
runcoms.h \
runcoms2.c \
runcoms2.h \
shyu.c \
shyu.h \
signal_handler.c\
signal_handler.h\
spec.c \
spec.h \
spcmdtab.c \
spiceif.c \
spiceif.h \
subckt.c \
subckt.h \
typesdef.c \
typesdef.h \
vectors.c \
vectors.h \
where.c \
where.h \
x11.c \
x11.h \
xgraph.c \
xgraph.h
commands.c \
commands.h \
com_ahelp.c \
com_ahelp.h \
com_alias.c \
com_alias.h \
com_asciiplot.c \
com_asciiplot.h \
com_cdump.c \
com_cdump.h \
com_chdir.c \
com_compose.c \
com_compose.h \
com_display.c \
com_display.h \
com_dump.c \
com_dump.h \
com_echo.c \
com_ghelp.c \
com_ghelp.h \
com_hardcopy.c \
com_hardcopy.h \
com_help.c \
com_help.h \
com_history.c \
com_history.h \
com_let.c \
com_let.h \
com_option.c \
com_option.h \
com_dl.c \
com_dl.h \
com_plot.c \
com_plot.h \
com_rehash.c \
com_set.c \
com_set.h \
com_setscale.c \
com_setscale.h \
com_shell.c \
com_shift.c \
com_state.c \
com_state.h \
com_strcmp.c \
com_strcmp.h \
com_unset.c \
com_xgraph.c \
com_xgraph.h \
completion.h \
control.h \
control.c \
ftehelp.h \
hcomp.c \
hcomp.h \
init.c \
init.h \
quote.c \
quote.h \
streams.h \
streams.c \
terminal.c \
terminal.h \
variable.c \
variable.h \
\
arg.c \
arg.h \
aspice.c \
aspice.h \
breakp.c \
breakp.h \
breakp2.c \
breakp2.h \
circuits.c \
circuits.h \
cpitf.c \
cpitf.h \
define.c \
define.h \
device.c \
device.h \
diff.c \
diff.h \
dimens.c \
dimens.h \
display.c \
display.h \
dotcards.c \
dotcards.h \
error.c \
error.h \
evaluate.c \
evaluate.h \
fourier.c \
fourier.h \
gens.c \
gens.h \
inp.c \
inp.h \
inpcom.c \
inpcom.h \
interp.c \
interp.h \
linear.c \
linear.h \
misccoms.c \
misccoms.h \
miscvars.c \
miscvars.h \
mw_coms.c \
mw_coms.h \
newcoms.c \
newcoms.h \
nutinp.c \
nutinp.h \
nutmegif.c \
nutmegif.h \
options.c \
options.h \
outitf.c \
outitf.h \
parse.c \
parse.h \
points.c \
points.h \
postcoms.c \
postcoms.h \
postsc.c \
postsc.h \
rawfile.c \
rawfile.h \
resource.c \
resource.h \
runcoms.c \
runcoms.h \
runcoms2.c \
runcoms2.h \
shyu.c \
shyu.h \
signal_handler.c\
signal_handler.h\
spec.c \
spec.h \
spiceif.c \
spiceif.h \
subckt.c \
subckt.h \
typesdef.c \
typesdef.h \
vectors.c \
vectors.h \
where.c \
where.h
# TESTS = testcommands
#
# bin_PROGRAMS = testcommands
#
# testcommands_SOURCES = \
# testcommands.c \
# testcommands.h
#
# testcommands_LDADD = libfte.a plotting/libplotting.a ../misc/libmisc.a
INCLUDES = -I$(top_srcdir)/src/include @X_CFLAGS@

View File

@ -8,12 +8,13 @@ Author: 1987 Jeffrey M. Hsu
and prompt the user if necessary.
*/
#include "ngspice.h"
#include "fteinput.h"
#include "cpdefs.h"
#include "fteext.h"
#include "arg.h"
#include <ngspice.h>
#include <fteinput.h>
#include <cpdefs.h>
#include <fteext.h>
#include "arg.h"
#include "variable.h"
static void common(char *string, struct wordlist *wl, struct comm *command);

View File

@ -10,8 +10,10 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
#include "ngspice.h"
#include "cpdefs.h"
#include "ftedefs.h"
#include "aspice.h"
#include "aspice.h"
#include "variable.h"
#include "circuits.h"
# ifdef HAVE_SYS_WAIT_H
/* should be more tests here I think */
@ -31,7 +33,7 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
#include <signal.h>
#include "fteinp.h"
#include "ftedata.h"
#include "dvec.h"
#ifndef SEEK_SET
@ -174,13 +176,21 @@ sigchild(void)
* whether the exit was normal or not.
*/
#if defined(__NetBSD__)
pid_t status;
#else
union wait status;
#endif
void
ft_checkkids(void)
{
struct proc *p, *lp;
struct proc *p = NULL, *lp = NULL;
char buf[BSIZE_SP];
FILE *fp;
int pid;
int pid = 0;
static bool here = FALSE; /* Don't want to be re-entrant. */
if (!numchanged || here)
@ -189,10 +199,10 @@ ft_checkkids(void)
here = TRUE;
while (numchanged > 0) {
pid = wait((union wait *) NULL);
pid = wait(&status);
if (pid == -1) {
fprintf(cp_err,
"ft_checkkids: Internal Error: should be %d jobs done but there aren't any.\n",
fprintf(cp_err,
"ft_checkkids: Internal Error: should be %d jobs done but there aren't any.\n",
numchanged);
numchanged = 0;
running = NULL;
@ -293,12 +303,6 @@ com_rspice(wordlist *wl)
pid = fork( );
if (pid == 0) {
#ifdef notdef
char com_buf[200];
sprintf(com_buf, "%s %s %s -s", remote_shell, rhost, program);
printf("executing: \"%s\"\n", com_buf);
#endif
/* I am the "server" process */
close(to_serv[1]);
close(from_serv[0]);
@ -381,10 +385,6 @@ com_rspice(wordlist *wl)
fprintf(stderr, "Error reading rawdata: %s\n", buf);
continue;
}
#ifdef notdef
fprintf(stderr, "adjusting rawfile: write \"%d\" at %ld\n",
num, pos);
#endif
if (fseek(out, pos, SEEK_SET))
fprintf(stderr,
"Error adjusting rawfile: write \"%d\" at %ld\n",

View File

@ -10,10 +10,11 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
#include "ngspice.h"
#include "cpdefs.h"
#include "ftedefs.h"
#include "ftedata.h"
#include "dvec.h"
#include "ftedebug.h"
#include "breakp.h"
#include "completion.h"
static bool satisfied(struct dbcomm *d, struct plot *plot);
static void printcond(struct dbcomm *d, FILE *fp);
@ -164,6 +165,7 @@ com_iplot(wordlist *wl)
d->db_type = DB_IPLOT;
d->db_nodename1 = copy(s);
}
tfree(s);/*DG: avoid memory leak */
d->db_also = currentdb;
currentdb = d;
wl = wl->wl_next;

View File

@ -10,8 +10,10 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
#include "ngspice.h"
#include "cpdefs.h"
#include "ftedefs.h"
#include "ftedata.h"
#include "dvec.h"
#include "ftedebug.h"
#include "quote.h"
#include "breakp2.h"
@ -83,6 +85,7 @@ settrace(wordlist *wl, int what, char *name)
d->db_nodename1 = copy(s);
/* wrd_chtrace(s, TRUE, what); */
}
tfree(s);/*DG avoid memoy leak */
if (dbs) {
for (td = dbs; td->db_next; td = td->db_next)
;

View File

@ -3,32 +3,22 @@ Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
**********/
/*
*
* Routines for dealing with the circuit database. This is currently
* unimplemented.
*/
/* Routines for dealing with the circuit database. This is currently
* unimplemented. */
#include "ngspice.h"
#include "cpdefs.h"
#include "ftedefs.h"
#include "ftedata.h"
#include "dvec.h"
#include "circuits.h"
struct circ *ft_curckt = NULL; /* The default active circuit. */
struct circ *ft_circuits = NULL;
struct subcirc *ft_subcircuits = NULL;
/* Now stuff to deal with circuits */
void
ft_setccirc(char *name)
{
}
/* Add a circuit to the circuit list */
void
@ -38,12 +28,3 @@ ft_newcirc(struct circ *ckt)
ft_circuits = ckt;
return;
}
/* Add a new subcircuit to the subcircuit list */
void
ft_newsubcirc(struct subcirc *sckt)
{
}

View File

@ -7,9 +7,16 @@
#define CIRCUITS_H_INCLUDED
void ft_setccirc(char *name);
struct subcirc {
char *sc_name; /* Whatever... */
} ;
extern struct circ *ft_curckt; /* The default active circuit. */
void ft_newcirc(struct circ *ckt);
void ft_newsubcirc(struct subcirc *sckt);
#endif

View File

@ -3,13 +3,22 @@ Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
**********/
/*
* SJB 22 May 2001
* Corrected freeing of memory in ft_cpinit()
*/
#include "ngspice.h"
#include "cpdefs.h"
#include "ftedefs.h"
#include "ftedata.h"
#include "dvec.h"
#include "fteparse.h"
#include "cpitf.h"
#include <terminal.h>
#include "completion.h"
#include "variable.h"
/* Set some standard variables and aliases, etc, and init the ccom stuff. */
@ -19,7 +28,7 @@ ft_cpinit(void)
wordlist *wl;
wordlist wl1, wl2, wl3;
bool found = FALSE, t = TRUE;
char buf[BSIZE_SP], **x, *s, *r;
char buf[BSIZE_SP], **x, *s, *r,*copys;
struct comm *c;
int i;
FILE *fp;
@ -202,11 +211,12 @@ ft_cpinit(void)
/* Now source the standard startup file. */
/* XXX strange */
for (s = cp_tildexpand(Lib_Path); s && *s; ) {
for (copys=s=cp_tildexpand(Lib_Path); s && *s; ) {/*DG*/
while (isspace(*s))
s++;
for (r = buf; *s && !isspace(*s); r++, s++)
*r = *s;
tfree(copys); /* sjb - it's safe to free this here */
(void) strcpy(r, DIR_PATHSEP);
(void) strcat(r, "spinit");
if ((fp = fopen(buf, "r"))) {
@ -232,14 +242,15 @@ ft_cpinit(void)
}
tcap_init( );
/* tfree(copys);*/ /*DG Avoid memory leak*/
/* SJB - must not free here as cp_tildexpande() can return NULL */
return;
}
/* Decide whether a condition is TRUE or not. */
bool
cp_isTRUE(wordlist *wl)
cp_istrue(wordlist *wl)
{
int i;
struct dvec *v;

View File

@ -17,10 +17,11 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
#include "ngspice.h"
#include "cpdefs.h"
#include "ftedefs.h"
#include "ftedata.h"
#include "dvec.h"
#include "fteparse.h"
#include "define.h"
#include "completion.h"
/* static declarations */
static void savetree(struct pnode *pn);
@ -265,7 +266,7 @@ ft_substdef(char *name, struct pnode *args)
struct udfunc *udf;
struct pnode *tp;
char *s;
int arity = 0, rarity;
int arity = 0, rarity = 0;
bool found = FALSE;
if (args)
@ -439,7 +440,7 @@ com_undefine(wordlist *wlist)
*/
void
ft_pnode(struct pn *pn)
ft_pnode(struct pnode *pn)
{
prtree1(pn, cp_err);
}

View File

@ -1,6 +1,7 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1986 Wayne A. Christopher, U. C. Berkeley CAD Group
Modified: 2000 AlansFixes
**********/
/*
@ -13,8 +14,10 @@ Author: 1986 Wayne A. Christopher, U. C. Berkeley CAD Group
#include "cpdefs.h"
#include "ftedefs.h"
#include "dgen.h"
#include "device.h"
#include "circuits.h"
#include "device.h"
#include "variable.h"
static wordlist *devexpand(char *name);
@ -74,7 +77,7 @@ all_show(wordlist *wl, int mode)
if (!cp_getvar("width", VT_NUM, (char *) &screen_width))
screen_width = DEF_WIDTH;
count = screen_width / 11 - 1;
count = (screen_width - LEFT_WIDTH) / (DEV_WIDTH + 1);
n = 0;
do {
@ -166,7 +169,7 @@ all_show(wordlist *wl, int mode)
i = 0;
do {
printf(" device ");
printf("%*s", LEFT_WIDTH, "device");
j = dgen_for_n(dg, count, printstr, "n", i);
i += 1;
printf("\n");
@ -175,7 +178,7 @@ all_show(wordlist *wl, int mode)
if (ft_sim->devices[dg->dev_type_no]->numModelParms) {
i = 0;
do {
printf(" model ");
printf("%*s", LEFT_WIDTH, "model");
j = dgen_for_n(dg, count, printstr, "m", i);
i += 1;
printf("\n");
@ -188,7 +191,7 @@ all_show(wordlist *wl, int mode)
else if (!params)
param_forall(dg, DGEN_DEFPARAMS);
if (params)
wl_forall(params, listparam, dg);
wl_forall(params, (void *)listparam, (void *)dg);
printf("\n");
} else if (ft_sim->devices[dg->dev_type_no]->numModelParms) {
@ -198,7 +201,7 @@ all_show(wordlist *wl, int mode)
n += 1;
i = 0;
do {
printf(" model ");
printf("%*s", LEFT_WIDTH, "model");
j = dgen_for_n(dg, count, printstr, "m", i);
i += 1;
printf("\n");
@ -210,7 +213,7 @@ all_show(wordlist *wl, int mode)
else if (!params)
param_forall(dg, DGEN_DEFPARAMS);
if (params)
wl_forall(params, listparam, dg);
wl_forall(params, (void *) listparam, (void *)dg);
printf("\n");
}
}
@ -234,16 +237,16 @@ printstr(dgen *dg, char *name)
{
if (*name == 'n') {
if (dg->instance)
printf(" %9.9s", dg->instance->GENname);
printf(" % *.*s", DEV_WIDTH, DEV_WIDTH, dg->instance->GENname);
else
printf(" <???????>");
printf(" %*s", DEV_WIDTH, "<???????>");
} else if (*name == 'm') {
if (dg->model)
printf(" %9.9s", dg->model->GENmodName);
printf(" % *.*s", DEV_WIDTH, DEV_WIDTH, dg->model->GENmodName);
else
printf(" <???????>");
printf(" %*s", DEV_WIDTH, "<???????>");
} else
printf(" <error> ");
printf(" %*s", DEV_WIDTH, "<error>");
return 0;
}
@ -276,9 +279,10 @@ param_forall(dgen *dg, int flags)
j = 0;
do {
if (!j)
printf("%10.10s", plist[i].keyword);
printf("%*.*s", LEFT_WIDTH, LEFT_WIDTH,
plist[i].keyword);
else
printf(" ");
printf("%*.*s", LEFT_WIDTH, LEFT_WIDTH, " ");
k = dgen_for_n(dg, count, printvals,
(char *) (plist + i), j);
printf("\n");
@ -321,10 +325,10 @@ listparam(wordlist *p, dgen *dg)
j = 0;
do {
if (!j)
printf("%10.10s", p->wl_word);
printf("%*.*s", LEFT_WIDTH, LEFT_WIDTH, p->wl_word);
else
printf(" ");
k = dgen_for_n(dg, count, printvals, plist + i, j);
printf("%*.*s", LEFT_WIDTH, LEFT_WIDTH, " ");
k = dgen_for_n(dg, count, printvals, (void *)(plist + i), j);
printf("\n");
j += 1;
} while (k > 0);
@ -332,9 +336,9 @@ listparam(wordlist *p, dgen *dg)
j = 0;
do {
if (!j)
printf("%10.10s", p->wl_word);
printf("%*.*s", LEFT_WIDTH, LEFT_WIDTH, p->wl_word);
else
printf(" ");
printf("%*s", LEFT_WIDTH, " ");
k = dgen_for_n(dg, count, bogus1, 0, j);
printf("\n");
j += 1;
@ -344,9 +348,9 @@ listparam(wordlist *p, dgen *dg)
j = 0;
do {
if (!j)
printf("%10.10s", p->wl_word);
printf("%*.*s", LEFT_WIDTH, LEFT_WIDTH, p->wl_word);
else
printf(" ");
printf("%*s", LEFT_WIDTH, " ");
k = dgen_for_n(dg, count, bogus2, 0, j);
printf("\n");
j += 1;
@ -356,13 +360,13 @@ listparam(wordlist *p, dgen *dg)
int bogus1(dgen *dg)
{
printf(" ---------");
printf(" %*s", DEV_WIDTH, "---------");
return 0;
}
int bogus2(dgen *dg)
{
printf(" ?????????");
printf(" %*s", DEV_WIDTH, "?????????");
return 0;
}
@ -398,54 +402,54 @@ printvals(dgen *dg, IFparm *p, int i)
if (p->dataType & IF_VECTOR) {
switch ((p->dataType & IF_VARTYPES) & ~IF_VECTOR) {
case IF_FLAG:
printf(" % 9d", val.v.vec.iVec[i]);
printf(" % *d", DEV_WIDTH, val.v.vec.iVec[i]);
break;
case IF_INTEGER:
printf(" % 9d", val.v.vec.iVec[i]);
printf(" % *d", DEV_WIDTH, val.v.vec.iVec[i]);
break;
case IF_REAL:
printf(" % 9.3g", val.v.vec.rVec[i]);
printf(" % *.6g", DEV_WIDTH, val.v.vec.rVec[i]);
break;
case IF_COMPLEX:
if (!(i % 2))
printf(" % 9.3g", val.v.vec.cVec[i / 2].real);
printf(" % *.6g", DEV_WIDTH, val.v.vec.cVec[i / 2].real);
else
printf(" % 9.3g", val.v.vec.cVec[i / 2].imag);
printf(" % *.6g", DEV_WIDTH, val.v.vec.cVec[i / 2].imag);
break;
case IF_STRING:
printf(" %9.9s", val.v.vec.sVec[i]);
printf(" % *.*s", DEV_WIDTH, DEV_WIDTH, val.v.vec.sVec[i]);
break;
case IF_INSTANCE:
printf(" %9.9s", val.v.vec.uVec[i]);
printf(" % *.*s", DEV_WIDTH, DEV_WIDTH, val.v.vec.uVec[i]);
break;
default:
printf(" ******** ");
printf(" % *.*s", DEV_WIDTH, DEV_WIDTH, " ******** ");
}
} else {
switch ((p->dataType & IF_VARTYPES) & ~IF_VECTOR) {
case IF_FLAG:
printf(" % 9d", val.iValue);
printf(" % *d", DEV_WIDTH, val.iValue);
break;
case IF_INTEGER:
printf(" % 9d", val.iValue);
printf(" % *d", DEV_WIDTH, val.iValue);
break;
case IF_REAL:
printf(" % 9.3g", val.rValue);
printf(" % *.6g", DEV_WIDTH, val.rValue);
break;
case IF_COMPLEX:
if (i % 2)
printf(" % 9.3g", val.cValue.real);
printf(" % *.6g", DEV_WIDTH, val.cValue.real);
else
printf(" % 9.3g", val.cValue.imag);
printf(" % *.6g", DEV_WIDTH, val.cValue.imag);
break;
case IF_STRING:
printf(" %9.9s", val.sValue);
printf(" % *.*s", DEV_WIDTH, DEV_WIDTH, val.sValue);
break;
case IF_INSTANCE:
printf(" %9.9s ", val.uValue);
printf(" % *.*s", DEV_WIDTH, DEV_WIDTH, val.uValue);
break;
default:
printf(" ******** ");
printf(" % *.*s", DEV_WIDTH, DEV_WIDTH, " ******** ");
}
}
@ -566,10 +570,6 @@ com_altermod(wordlist *wl)
void
com_alter_common(wordlist *wl, int do_model)
{
#ifdef notdef
struct variable var, *nv, *prev;
double *dd;
#endif
wordlist *eqword, *words;
char *dev, *p;
char *param;
@ -650,78 +650,6 @@ com_alter_common(wordlist *wl, int do_model)
/* Vector data (dv) should get garbage-collected. */
return;
#ifdef notdef
while (wl) {
param = wl->wl_word;
wl = wl->wl_next;
if (!wl) {
val = param;
param = NULL;
} else {
val = wl->wl_word;
wl = wl->wl_next;
}
/* Now figure out what the value should be... */
if (eq(val, "TRUE")) {
var.va_type = VT_BOOL;
var.va_bool = TRUE;
} else if (eq(val, "FALSE")) {
var.va_type = VT_BOOL;
var.va_bool = FALSE;
} else if (eq(val, "[")) {
var.va_type = VT_LIST;
prev = NULL;
while (wl && !eq(wl->wl_word, "]")) {
val = wl->wl_word;
nv = alloc(struct variable);
if (dd = ft_numparse(&val, FALSE)) {
nv->va_type = VT_REAL;
nv->va_real = *dd;
} else {
fprintf(cp_err, "Error: \"%s\" is not a number\n", val);
break;
}
if (!prev)
var.va_vlist = nv;
else
prev->va_next = nv;
nv->va_next = NULL;
wl = wl->wl_next;
prev = nv;
}
if (wl && eq(wl->wl_word, "]")) {
wl = wl->wl_next;
} else {
while (nv) {
prev = nv->va_next;
tfree(nv);
nv = prev;
}
return;
}
} else if (dd = ft_numparse(&val, FALSE)) {
var.va_type = VT_REAL;
var.va_real = *dd;
} else {
var.va_type = VT_STRING;
var.va_string = val;
}
if_setparam(ft_curckt->ci_ckt, &dev, param, &var, do_model);
if (var.va_type == VT_LIST) {
for (nv = var.va_vlist; nv; nv = prev) {
prev = nv->va_next;
tfree(nv);
}
}
}
#endif
}
/* Given a device name, possibly with wildcards, return the matches. */

View File

@ -1,11 +1,15 @@
/*************
* Header file for device.c
* 1999 E. Rouat
* Modified: 2000 AlansFixes
************/
#ifndef DEVICE_H_INCLUDED
#define DEVICE_H_INCLUDED
#define LEFT_WIDTH 11
#define DEV_WIDTH 21
void com_showmod(wordlist *wl);
void com_show(wordlist *wl);
int printstr(dgen *dg, char *name);

View File

@ -1,18 +1,20 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
Modified: 2001 Paolo Nenzi (printnum)
**********/
/*
* Do a 'diff' of two plots.
*/
#include "ngspice.h"
#include "cpdefs.h"
#include "ftedefs.h"
#include "ftedata.h"
#include "ftecmath.h"
#include <ngspice.h>
#include <ftedefs.h>
#include <dvec.h>
#include <sim.h>
#include "diff.h"
#include "variable.h"
/* Determine if two vectors have the 'same' name. */
@ -21,6 +23,7 @@ static bool
nameeq(char *n1, char *n2)
{
char buf1[BSIZE_SP], buf2[BSIZE_SP];
int i;
if (eq(n1, n2))
@ -50,8 +53,9 @@ com_diff(wordlist *wl)
struct dvec *v1, *v2;
double d1, d2;
complex c1, c2, c3;
register int i, j;
int i, j;
wordlist *tw;
char numbuf[BSIZE_SP],numbuf2[BSIZE_SP] ,numbuf3[BSIZE_SP], numbuf4[BSIZE_SP]; /* For printnum */
if (!cp_getvar("diff_vntol", VT_REAL, (char *) &vntol))
vntol = 1.0e-6;
@ -203,14 +207,16 @@ com_diff(wordlist *wl)
d2 = v2->v_realdata[i];
if (MAX(fabs(d1), fabs(d2)) * reltol +
tol < fabs(d1 - d2)) {
printnum(numbuf, d1);
fprintf(cp_out,
"%s.%s[%d] = %-15s ",
p1->pl_typename, v1->v_name, i,
printnum(d1));
numbuf);
printnum(numbuf, d2);
fprintf(cp_out,
"%s.%s[%d] = %s\n",
p2->pl_typename, v2->v_name, i,
printnum(d2));
numbuf);
}
} else {
c1 = v1->v_compdata[i];
@ -223,14 +229,20 @@ com_diff(wordlist *wl)
cmax = MAX(cm1, cm2);
if (cmax * reltol +
tol < cmag(&c3)) {
printnum(numbuf, realpart(&c1));
printnum(numbuf2, imagpart(&c1));
printnum(numbuf3, realpart(&c2));
printnum(numbuf4, imagpart(&c2));
fprintf(cp_out,
"%s.%s[%d] = %-10s, %-10s %s.%s[%d] = %-10s, %s\n",
p1->pl_typename, v1->v_name, i,
copy(printnum(realpart(&c1))),
copy(printnum(imagpart(&c1))),
numbuf,
numbuf2,
p2->pl_typename, v2->v_name, i,
copy(printnum(realpart(&c2))),
copy(printnum(imagpart(&c2))));
numbuf3,
numbuf4);
}
}
}

View File

@ -3,12 +3,12 @@
* 1999 E. Rouat
************/
#ifndef DIFF_H_INCLUDED
#define DIFF_H_INCLUDED
#ifndef _DIFF_H
#define _DIFF_H
#include <wordlist.h>
void com_diff(wordlist *wl);
#endif

View File

@ -8,21 +8,22 @@ Author: 1992 David A. Gates, U. C. Berkeley CAD Group
*/
#include "ngspice.h"
#include "ftedata.h" /* For MAXDIMS */
#include "dvec.h" /* For MAXDIMS */
#include "dimens.h"
/*
* Create a string of the form "12,1,10".
*/
char *
dimstring(int *data, int length)
void
dimstring(int *data, int length, char *retstring)
{
int i;
char buf[BSIZE_SP];
if (!data || length < 1)
return NULL;
retstring = "";
buf[0] = '\0';
for (i=0; i < length; i++) {
@ -30,26 +31,27 @@ dimstring(int *data, int length)
(i < length - 1) ? "," : "");
}
/* XXX Should I return a copy instead? */
return(buf);
/* qui ci devo fare una copia */
strcpy(retstring, buf);
}
/*
* Create a string of the form "[12][1][10]".
*/
char *
indexstring(int *data, int length)
void
indexstring(int *data, int length, char *retstring)
{
int i;
char buf[BSIZE_SP];
if (!data || length < 1)
return NULL;
retstring = "";
buf[0] = '\0';
for (i=0; i < length; i++) {
sprintf(buf + strlen(buf), "[%d]", data[i]);
}
return(buf);
strcpy(retstring, buf);
}
/*

View File

@ -6,8 +6,8 @@
#ifndef DIMENS_H_INCLUDED
#define DIMENS_H_INCLUDED
char * dimstring(int *data, int length);
char * indexstring(int *data, int length);
void dimstring(int *data, int length, char *retstring);
void indexstring(int *data, int length, char *retstring);
int incindex(int *counts, int numcounts, int *dims, int numdims);
int emptydims(int *data, int length);
int atodims(char *p, int *data, int *outlength);

View File

@ -3,19 +3,22 @@ Copyright 1990 Regents of the University of California. All rights reserved.
**********/
#include "ngspice.h"
#include "ftegraph.h"
#include "ftedev.h"
#include "fteinput.h"
#include "cpdefs.h" /* for VT_STRING */
#include "ftedefs.h" /* for mylog() */
#include <ngspice.h>
#include <graph.h>
#include <ftedev.h>
#include <fteinput.h>
#include <cpdefs.h> /* for VT_STRING */
#include <ftedefs.h> /* for mylog() */
#ifdef TCL_MODULE
#include <tclspice.h>
#endif
#include "display.h"
#include "variable.h"
/* static declarations */
static int gen_DatatoScreen(GRAPH *graph, double x, double y, int *screenx, int *screeny);
static void gen_DatatoScreen(GRAPH *graph, double x, double y, int *screenx, int *screeny);
static int gen_Input(REQUEST *request, RESPONSE *response);
static int nop(void);
static int nodev(void);
@ -52,7 +55,7 @@ DISPDEVICE device[] = {
nop, nop, nop, nop, nop,
nop, nop, nop,
nop, nop, nop, gen_Input,
nop,},
(void *)nop,},
#ifndef X_DISPLAY_MISSING
{"X11", 0, 0, 1024, 864, 0, 0, X11_Init, X11_NewViewport,
@ -63,6 +66,14 @@ DISPDEVICE device[] = {
gen_DatatoScreen,},
#endif
#ifdef TCL_MODULE
{"Tk", 0, 0, 1024, 864, 0, 0, sp_Tk_Init, sp_Tk_NewViewport,
sp_Tk_Close, sp_Tk_Clear,
sp_Tk_DrawLine, sp_Tk_Arc, sp_Tk_Text, sp_Tk_DefineColor, sp_Tk_DefineLinestyle,
sp_Tk_SetLinestyle, sp_Tk_SetColor, sp_Tk_Update,
nodev, nodev, nodev, nodev,
gen_DatatoScreen,},
#endif
{"plot5", 0, 0, 1000, 1000, 0, 0, Plt5_Init, Plt5_NewViewport,
Plt5_Close, Plt5_Clear,
@ -83,7 +94,7 @@ DISPDEVICE device[] = {
nodev, nodev, nodev, nodev, nodev,
nodev, nodev, nodev,
nodev, nodev, nodev, gen_Input,
nodev,},
(void *)nodev,},
};
@ -135,7 +146,9 @@ DevInit(void)
}
#endif
#ifdef TCL_MODULE
dispdev = FindDev("Tk");
#endif
if (!dispdev) {
externalerror(
@ -230,7 +243,7 @@ void Update(void)
/* note: screen coordinates are relative to window
so need to add viewport offsets */
static int
static void
gen_DatatoScreen(GRAPH *graph, double x, double y, int *screenx, int *screeny)
{
@ -276,19 +289,6 @@ void DatatoScreen(GRAPH *graph, double x, double y, int *screenx, int *screeny)
}
#ifdef notdef
/*
NDCtoScreen(x0, y0, px, py)
double x0, y0;
int *px, *py;
{
(*(dispdev->NDCtoScreen))(x0, y0, px, py);
}
*/
#endif
void Input(REQUEST *request, RESPONSE *response)
{
@ -311,6 +311,7 @@ gen_Input(REQUEST *request, RESPONSE *response)
response->option = error_option;
break;
}
return 0;
}
/* no operation, do nothing */
@ -335,7 +336,7 @@ void SaveText(GRAPH *graph, char *text, int x, int y)
struct _keyed *keyed;
keyed = (struct _keyed *) calloc(1, sizeof(struct _keyed));
keyed = (struct _keyed *) tmalloc(sizeof(struct _keyed));
if (!graph->keyed) {
graph->keyed = keyed;

View File

@ -1,32 +1,54 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
Modified: 2000 AlansFixes
**********/
/*
* Spice-2 compatibility stuff for .plot, .print, .four, and .width.
*/
#include <config.h>
#include <ngspice.h>
#include <assert.h>
#include "ngspice.h"
#include "cpdefs.h"
#include "ftedefs.h"
#include "ftedata.h"
#include "dvec.h"
#include "fteinp.h"
#include <sim.h>
#include "circuits.h"
#include "dotcards.h"
#include "variable.h"
#include "fourier.h"
/* Extract all the .save lines */
static void fixdotplot(wordlist *wl);
static void fixdotprint(wordlist *wl);
static char * fixem(char *string);
static bool setcplot(char *name);
static wordlist * gettoks(char *s);
extern void com_save2 (wordlist *wl, char *name);
static struct plot *
setcplot(char *name)
{
struct plot *pl;
for (pl = plot_list; pl; pl = pl->pl_next) {
if (ciprefix(name, pl->pl_typename)) {
return pl;
}
}
return NULL;
}
void
ft_dotsaves(void)
{
@ -145,61 +167,65 @@ ft_cktcoms(bool terse)
static wordlist twl = { "col", NULL, NULL } ;
struct plot *pl;
int i, found;
char numbuf[BSIZE_SP]; /* For printnum*/
all.wl_next = NULL;
all.wl_word = "all";
if (!ft_curckt)
return 1;
if (!ft_curckt->ci_commands)
plot_cur = setcplot("op");
if (!ft_curckt->ci_commands && !plot_cur)
goto nocmds;
coms = ft_curckt->ci_commands;
cp_interactive = FALSE;
/* Circuit name */
fprintf(cp_out, "Circuit: %s\nDate: %s\n\n", ft_curckt->ci_name,
datestring());
fprintf(cp_out, "\n");
/* Listing */
if (ft_listprint) {
if (terse)
fprintf(cp_err, ".options: no listing, rawfile was generated.\n");
else
inp_list(cp_out, ft_curckt->ci_deck, ft_curckt->ci_options,
LS_DECK);
LS_DECK);
}
/* If there was a .op line, then we have to do the .op output. */
if (setcplot("op")) {
if (terse) {
fprintf(cp_out, "OP information in rawfile.\n");
} else {
fprintf(cp_out, "\nOperating point information:\n\n");
fprintf(cp_out, "\tNode\tVoltage\n");
fprintf(cp_out, "\t----\t-------\n");
for (v = plot_cur->pl_dvecs; v; v = v->v_next) {
if (!isreal(v)) {
fprintf(cp_err,
"Internal error: op vector %s not real\n",
v->v_name);
continue;
plot_cur = setcplot("op");
if (plot_cur != NULL) {
assert(plot_cur->pl_dvecs != NULL);
if (plot_cur->pl_dvecs->v_realdata!=NULL) {
if (terse) {
fprintf(cp_out, "OP information in rawfile.\n");
} else {
fprintf(cp_out, "\t%-30s%15s\n", "Node", "Voltage");
fprintf(cp_out, "\t%-30s%15s\n", "----", "-------");
fprintf(cp_out, "\t----\t-------\n");
for (v = plot_cur->pl_dvecs; v; v = v->v_next) {
if (!isreal(v)) {
fprintf(cp_err,
"Internal error: op vector %s not real\n",
v->v_name);
continue;
}
if ((v->v_type == SV_VOLTAGE) && (*(v->v_name)!='@')) {
printnum(numbuf, v->v_realdata[0]);
fprintf(cp_out, "\t%-30s%15s\n", v->v_name, numbuf);
}
}
if (v->v_type == SV_VOLTAGE)
fprintf(cp_out, "\t%s\t%s\n", v->v_name,
printnum(v->v_realdata[0]));
}
fprintf(cp_out, "\n\tSource\tCurrent\n");
fprintf(cp_out, "\t------\t-------\n\n");
for (v = plot_cur->pl_dvecs; v; v = v->v_next)
if (v->v_type == SV_CURRENT)
fprintf(cp_out, "\t%s\t%s\n", v->v_name,
printnum(v->v_realdata[0]));
fprintf(cp_out, "\n");
fprintf(cp_out, "\n\tSource\tCurrent\n");
fprintf(cp_out, "\t------\t-------\n\n");
for (v = plot_cur->pl_dvecs; v; v = v->v_next)
if (v->v_type == SV_CURRENT) {
printnum(numbuf, v->v_realdata[0]);
fprintf(cp_out, "\t%-30s%15s\n", v->v_name, numbuf);
}
fprintf(cp_out, "\n");
if (!ft_nomod)
com_showmod(&all);
com_show(&all);
if (!ft_nomod)
com_showmod(&all);
com_show(&all);
}
}
}
@ -238,7 +264,7 @@ ft_cktcoms(bool terse)
} else if (eq(command->wl_word, ".print")) {
if (terse) {
fprintf(cp_out,
".print line ignored since rawfile was produced.\n");
".print line ignored since rawfile was produced.\n");
} else {
command = command->wl_next;
if (!command) {
@ -261,12 +287,12 @@ ft_cktcoms(bool terse)
}
if (!found)
fprintf(cp_err, "Error: .print: no %s analysis found.\n",
plottype);
plottype);
}
} else if (eq(command->wl_word, ".plot")) {
if (terse) {
fprintf(cp_out,
".plot line ignored since rawfile was produced.\n");
".plot line ignored since rawfile was produced.\n");
} else {
command = command->wl_next;
if (!command) {
@ -289,35 +315,40 @@ ft_cktcoms(bool terse)
}
if (!found)
fprintf(cp_err, "Error: .plot: no %s analysis found.\n",
plottype);
plottype);
}
} else if (ciprefix(".four", command->wl_word)) {
if (terse) {
fprintf(cp_out,
".fourier line ignored since rawfile was produced.\n");
} else if (setcplot("tran")) {
com_fourier(command->wl_next);
fprintf(cp_out, "\n\n");
} else
fprintf(cp_err,
"No transient data available for fourier analysis");
".fourier line ignored since rawfile was produced.\n");
} else {
int err;
plot_cur = setcplot("tran");
err = fourier(command->wl_next, plot_cur);
if (!err)
fprintf(cp_out, "\n\n");
else
fprintf(cp_err, "No transient data available for "
"fourier analysis");
}
} else if (!eq(command->wl_word, ".save")
&& !eq(command->wl_word, ".op")
&& !eq(command->wl_word, ".tf"))
&& !eq(command->wl_word, ".op")
&& !eq(command->wl_word, ".tf"))
{
goto bad;
}
coms = coms->wl_next;
}
nocmds:
nocmds:
/* Now the node table */
if (ft_nodesprint)
;
/* The options */
if (ft_optsprint) {
fprintf(cp_err, "Options:\n\n");
fprintf(cp_out, "Options:\n\n");
cp_vprint();
(void) putc('\n', cp_out);
}
@ -329,10 +360,11 @@ nocmds:
} else
com_rusage((wordlist *) NULL);
(void) putc('\n', cp_out);
putc('\n', cp_out);
return 0;
bad: fprintf(cp_err, "Internal Error: ft_cktcoms: bad commands\n");
bad:
fprintf(cp_err, "Internal Error: ft_cktcoms: bad commands\n");
return 1;
}
@ -349,6 +381,7 @@ static void
fixdotplot(wordlist *wl)
{
char buf[BSIZE_SP], *s;
char numbuf[128]; /* Printnum Fix */
double *d, d1, d2;
while (wl) {
@ -379,13 +412,14 @@ fixdotplot(wordlist *wl)
wl->wl_next = alloc(struct wordlist);
wl->wl_next->wl_prev = wl;
wl = wl->wl_next;
(void) strcpy(buf, printnum(d1));
wl->wl_word = copy(buf);
printnum(numbuf, d1);
wl->wl_word = copy(numbuf);
wl->wl_next = alloc(struct wordlist);
wl->wl_next->wl_prev = wl;
wl = wl->wl_next;
(void) strcpy(buf, printnum(d2));
wl->wl_word = copy(buf);
printnum(numbuf, d2);
wl->wl_word = copy(numbuf);
}
wl = wl->wl_next;
}
@ -405,7 +439,8 @@ fixdotprint(wordlist *wl)
static char *
fixem(char *string)
{
char buf[BSIZE_SP], *s, *t, *ss = string;
char buf[BSIZE_SP], *s, *t;
char *ss = string; /* Get rid of ss ? */
if (ciprefix("v(", string) &&strchr(string, ',')) {
for (s = string; *s && (*s != ','); s++)
@ -469,94 +504,6 @@ fixem(char *string)
return (string);
}
/* Don't bother with ccom strangeness here. */
static bool
setcplot(char *name)
{
struct plot *pl;
for (pl = plot_list; pl; pl = pl->pl_next) {
if (ciprefix(name, pl->pl_typename)) {
plot_cur = pl;
return (TRUE);
}
}
return (FALSE);
}
#ifdef notdef
static wordlist *
gettoks(s)
char *s;
{
char *t, *r, buf[64];
wordlist *wl = NULL, *end = NULL;
bool iflag;
while (t = gettok(&s)) {
if (*t == '(' /* ) */) {
/* This is a (upper, lower) thing -- ignore. */
continue;
} else if (!index(t, '(' /*)*/ )) {
if (end) {
end->wl_next = alloc(struct wordlist);
end->wl_next->wl_prev = end;
end = end->wl_next;
} else
wl = end = alloc(struct wordlist);
end->wl_word = copy(t);
} else if (!index(t, ',')) {
iflag = ((*t == 'i') || (*t == 'I')) ? TRUE : FALSE;
while (*t != '(' /*)*/)
t++;
t++;
for (r = t; *r && *r != /*(*/ ')'; r++)
;
*r = '\0';
if (end) {
end->wl_next = alloc(struct wordlist);
end->wl_next->wl_prev = end;
end = end->wl_next;
} else
wl = end = alloc(struct wordlist);
if (iflag) {
(void) sprintf(buf, "%s#branch", t);
t = buf;
}
end->wl_word = copy(t);
} else {
/* The painful case */
while (*t != '(' /*)*/)
t++;
t++;
for (r = t; *r && *r != ','; r++)
;
*r = '\0';
if (end) {
end->wl_next = alloc(struct wordlist);
end->wl_next->wl_prev = end;
end = end->wl_next;
} else
wl = end = alloc(struct wordlist);
end->wl_word = copy(t);
t = r + 1;
for (r = t; *r && *r != /*(*/ ')'; r++)
;
*r = '\0';
if (end) {
end->wl_next = alloc(struct wordlist);
end->wl_next->wl_prev = end;
end = end->wl_next;
} else
wl = end = alloc(struct wordlist);
end->wl_word = copy(t);
}
}
return (wl);
}
#endif
static wordlist *
gettoks(char *s)
{

View File

@ -7,14 +7,13 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
* Convert a parse tree to a list of data vectors.
*/
#include "ngspice.h"
#include "cpdefs.h"
#include "ftedefs.h"
#include "ftedata.h"
#include "fteparse.h"
#include "ftecmath.h"
#include <setjmp.h>
#include <signal.h>
#include <ngspice.h>
#include <ftedefs.h>
#include <dvec.h>
#include "evaluate.h"
@ -22,9 +21,6 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
static RETSIGTYPE sig_matherr(void);
static struct dvec * apply_func(struct func *func, struct pnode *arg);
static char * mkcname(char what, char *v1, char *v2);
static struct dvec * doop(char what, void *(*func) (/* ??? */),
struct pnode *arg1, struct pnode *arg2);
/* We are careful here to catch SIGILL and recognise them as math errors.
@ -47,7 +43,7 @@ sig_matherr(void)
struct dvec *
ft_evaluate(struct pnode *node)
{
struct dvec *d;
struct dvec *d = NULL;
if (!node)
return (NULL);
@ -81,8 +77,226 @@ ft_evaluate(struct pnode *node)
return (d);
}
/* The binary operations. */
/* Operate on two vectors, and return a third with the data, length, and flags
* fields filled in. Add it to the current plot and get rid of the two args.
*/
static struct dvec *
doop(char what,
void*(*func) (void *data1, void *data2,
short int datatype1, short int datatype2,
int length),
struct pnode *arg1,
struct pnode *arg2)
{
struct dvec *v1, *v2, *res;
complex *c1 = NULL, *c2 = NULL , lc;
double *d1 = NULL, *d2 = NULL, ld;
int length = 0, i;
void *data;
bool free1 = FALSE, free2 = FALSE, relflag = FALSE;
v1 = ft_evaluate(arg1);
v2 = ft_evaluate(arg2);
if (!v1 || !v2)
return (NULL);
/* Now the question is, what do we do when one or both of these
* has more than one vector? This is definitely not a good
* thing. For the time being don't do anything.
*/
if (v1->v_link2 || v2->v_link2) {
fprintf(cp_err, "Warning: no operations on wildcards yet.\n");
if (v1->v_link2 && v2->v_link2)
fprintf(cp_err, "\t(You couldn't do that one anyway)\n");
return (NULL);
}
/* How do we handle operations on multi-dimensional vectors?
* For now, we only allow operations between one-D vectors,
* equivalently shaped multi-D vectors, or a multi-D vector and
* a one-D vector. It's not at all clear what to do in the other cases.
* So only check shape requirement if its an operation between two multi-D
* arrays.
*/
if ((v1->v_numdims > 1) && (v2->v_numdims > 1)) {
if (v1->v_numdims != v2->v_numdims) {
fprintf(cp_err,
"Warning: operands %s and %s have incompatible shapes.\n",
v1->v_name, v2->v_name);
return (NULL);
}
for (i = 1; i < v1->v_numdims; i++) {
if ((v1->v_dims[i] != v2->v_dims[i])) {
fprintf(cp_err,
"Warning: operands %s and %s have incompatible shapes.\n",
v1->v_name, v2->v_name);
return (NULL);
}
}
}
/* This is a bad way to do this. */
switch (what) {
case '=':
case '>':
case '<':
case 'G':
case 'L':
case 'N':
case '&':
case '|':
case '~':
relflag = TRUE;
}
/* Don't bother to do type checking. Maybe this should go in at
* some point.
*/
/* Make sure we have data of the same length. */
length = ((v1->v_length > v2->v_length) ? v1->v_length : v2->v_length);
if (v1->v_length < length) {
free1 = TRUE;
if (isreal(v1)) {
ld = 0.0;
d1 = (double *) tmalloc(length * sizeof (double));
for (i = 0; i < v1->v_length; i++)
d1[i] = v1->v_realdata[i];
if (length > 0)
ld = v1->v_realdata[v1->v_length - 1];
for ( ; i < length; i++)
d1[i] = ld;
} else {
realpart(&lc) = 0.0;
imagpart(&lc) = 0.0;
c1 = (complex *) tmalloc(length * sizeof (complex));
for (i = 0; i < v1->v_length; i++)
c1[i] = v1->v_compdata[i];
if (length > 0)
lc = v1->v_compdata[v1->v_length - 1];
for ( ; i < length; i++)
c1[i] = lc;
}
} else
if (isreal(v1))
d1 = v1->v_realdata;
else
c1 = v1->v_compdata;
if (v2->v_length < length) {
free2 = TRUE;
if (isreal(v2)) {
ld = 0.0;
d2 = (double *) tmalloc(length * sizeof (double));
for (i = 0; i < v2->v_length; i++)
d2[i] = v2->v_realdata[i];
if (length > 0)
ld = v2->v_realdata[v2->v_length - 1];
for ( ; i < length; i++)
d2[i] = ld;
} else {
realpart(&lc) = 0.0;
imagpart(&lc) = 0.0;
c2 = (complex *) tmalloc(length * sizeof (complex));
for (i = 0; i < v2->v_length; i++)
c2[i] = v2->v_compdata[i];
if (length > 0)
lc = v2->v_compdata[v1->v_length - 1];
for ( ; i < length; i++)
c2[i] = lc;
}
} else
if (isreal(v2))
d2 = v2->v_realdata;
else
c2 = v2->v_compdata;
/* Some of the math routines generate SIGILL if the argument is
* out of range. Catch this here.
*/
if (setjmp(matherrbuf)) {
return (NULL);
}
(void) signal(SIGILL, (SIGNAL_FUNCTION) sig_matherr);
/* Now pass the vectors to the appropriate function. */
data = ((*func) ((isreal(v1) ? (void *) d1 : (void *) c1),
(isreal(v2) ? (void *) d2 : (void *) c2),
(isreal(v1) ? VF_REAL : VF_COMPLEX),
(isreal(v2) ? VF_REAL : VF_COMPLEX),
length));
/* Back to normal */
(void) signal(SIGILL, SIG_DFL);
if (!data)
return (NULL);
/* Make up the new vector. */
res = alloc(struct dvec);
ZERO(res,struct dvec);
if (relflag || (isreal(v1) && isreal(v2) && (func != cx_comma))) {
res->v_flags = (v1->v_flags | v2->v_flags |
VF_REAL) & ~ VF_COMPLEX;
res->v_realdata = (double *) data;
} else {
res->v_flags = (v1->v_flags | v2->v_flags |
VF_COMPLEX) & ~ VF_REAL;
res->v_compdata = (complex *) data;
}
res->v_name = mkcname(what, v1->v_name, v2->v_name);
res->v_length = length;
/* This is a non-obvious thing */
if (v1->v_scale != v2->v_scale) {
fprintf(cp_err, "Warning: scales of %s and %s are different.\n",
v1->v_name, v2->v_name);
res->v_scale = NULL;
} else
res->v_scale = v1->v_scale;
/* Copy a few useful things */
res->v_defcolor = v1->v_defcolor;
res->v_gridtype = v1->v_gridtype;
res->v_plottype = v1->v_plottype;
/* Copy dimensions. */
if (v1->v_numdims > v2->v_numdims) {
res->v_numdims = v1->v_numdims;
for (i = 0; i < v1->v_numdims; i++)
res->v_dims[i] = v1->v_dims[i];
} else {
res->v_numdims = v2->v_numdims;
for (i = 0; i < v2->v_numdims; i++)
res->v_dims[i] = v2->v_dims[i];
}
/* This depends somewhat on what the operation is. XXX Should fix */
res->v_type = v1->v_type;
vec_new(res);
/* Free the temporary data areas we used, if we allocated any. */
if (free1) {
if (isreal(v1)) {
tfree(d1);
} else {
tfree(c1);
}
}
if (free2) {
if (isreal(v2)) {
tfree(d2);
} else {
tfree(c2);
}
}
return (res);
}
/* The binary operations. */
struct dvec *
op_plus(struct pnode *arg1, struct pnode *arg2)
{
@ -476,6 +690,11 @@ apply_func(struct func *func, struct pnode *arg)
}
(void) signal(SIGILL, (SIGNAL_FUNCTION) sig_matherr);
#if 0
/* FIXME: The call to (*func->fu_func) has too many arguments;
hence the compiler quits. How to circumvent this (without
losing function prototypes)? For now, these functions have
been disabled. */
if (eq(func->fu_name, "interpolate")
|| eq(func->fu_name, "deriv")) /* Ack */
{
@ -487,13 +706,16 @@ apply_func(struct func *func, struct pnode *arg)
v->v_length, &len, &type,
v->v_plot, plot_cur, v->v_dims[0]));
} else {
#endif
data = ((*func->fu_func) ((isreal(v) ? (void *)
v->v_realdata :
(void *) v->v_compdata),
(short) (isreal(v) ? VF_REAL :
VF_COMPLEX),
v->v_length, &len, &type));
#if 0
}
#endif
/* Back to normal */
(void) signal(SIGILL, SIG_DFL);
@ -586,215 +808,3 @@ mkcname(char what, char *v1, char *v2)
return (s);
}
/* Operate on two vectors, and return a third with the data, length, and flags
* fields filled in. Add it to the current plot and get rid of the two args.
*/
static struct dvec *
doop(char what, void*(*func) (/* ??? */), struct pnode *arg1,
struct pnode *arg2)
{
struct dvec *v1, *v2, *res;
complex *c1, *c2, lc;
double *d1, *d2, ld;
int length, i;
void *data;
bool free1 = FALSE, free2 = FALSE, relflag = FALSE;
v1 = ft_evaluate(arg1);
v2 = ft_evaluate(arg2);
if (!v1 || !v2)
return (NULL);
/* Now the question is, what do we do when one or both of these
* has more than one vector? This is definitely not a good
* thing. For the time being don't do anything.
*/
if (v1->v_link2 || v2->v_link2) {
fprintf(cp_err, "Warning: no operations on wildcards yet.\n");
if (v1->v_link2 && v2->v_link2)
fprintf(cp_err, "\t(You couldn't do that one anyway)\n");
return (NULL);
}
/* How do we handle operations on multi-dimensional vectors?
* For now, we only allow operations between one-D vectors,
* equivalently shaped multi-D vectors, or a multi-D vector and
* a one-D vector. It's not at all clear what to do in the other cases.
* So only check shape requirement if its an operation between two multi-D
* arrays.
*/
if ((v1->v_numdims > 1) && (v2->v_numdims > 1)) {
if (v1->v_numdims != v2->v_numdims) {
fprintf(cp_err,
"Warning: operands %s and %s have incompatible shapes.\n",
v1->v_name, v2->v_name);
return (NULL);
}
for (i = 1; i < v1->v_numdims; i++) {
if ((v1->v_dims[i] != v2->v_dims[i])) {
fprintf(cp_err,
"Warning: operands %s and %s have incompatible shapes.\n",
v1->v_name, v2->v_name);
return (NULL);
}
}
}
/* This is a bad way to do this. */
switch (what) {
case '=':
case '>':
case '<':
case 'G':
case 'L':
case 'N':
case '&':
case '|':
case '~':
relflag = TRUE;
}
/* Don't bother to do type checking. Maybe this should go in at
* some point.
*/
/* Make sure we have data of the same length. */
length = ((v1->v_length > v2->v_length) ? v1->v_length : v2->v_length);
if (v1->v_length < length) {
free1 = TRUE;
if (isreal(v1)) {
ld = 0.0;
d1 = (double *) tmalloc(length * sizeof (double));
for (i = 0; i < v1->v_length; i++)
d1[i] = v1->v_realdata[i];
if (length > 0)
ld = v1->v_realdata[v1->v_length - 1];
for ( ; i < length; i++)
d1[i] = ld;
} else {
realpart(&lc) = 0.0;
imagpart(&lc) = 0.0;
c1 = (complex *) tmalloc(length * sizeof (complex));
for (i = 0; i < v1->v_length; i++)
c1[i] = v1->v_compdata[i];
if (length > 0)
lc = v1->v_compdata[v1->v_length - 1];
for ( ; i < length; i++)
c1[i] = lc;
}
} else
if (isreal(v1))
d1 = v1->v_realdata;
else
c1 = v1->v_compdata;
if (v2->v_length < length) {
free2 = TRUE;
if (isreal(v2)) {
ld = 0.0;
d2 = (double *) tmalloc(length * sizeof (double));
for (i = 0; i < v2->v_length; i++)
d2[i] = v2->v_realdata[i];
if (length > 0)
ld = v2->v_realdata[v2->v_length - 1];
for ( ; i < length; i++)
d2[i] = ld;
} else {
realpart(&lc) = 0.0;
imagpart(&lc) = 0.0;
c2 = (complex *) tmalloc(length * sizeof (complex));
for (i = 0; i < v2->v_length; i++)
c2[i] = v2->v_compdata[i];
if (length > 0)
lc = v2->v_compdata[v1->v_length - 1];
for ( ; i < length; i++)
c2[i] = lc;
}
} else
if (isreal(v2))
d2 = v2->v_realdata;
else
c2 = v2->v_compdata;
/* Some of the math routines generate SIGILL if the argument is
* out of range. Catch this here.
*/
if (setjmp(matherrbuf)) {
return (NULL);
}
(void) signal(SIGILL, (SIGNAL_FUNCTION) sig_matherr);
/* Now pass the vectors to the appropriate function. */
data = ((*func) ((isreal(v1) ? (void *) d1 : (void *) c1),
(isreal(v2) ? (void *) d2 : (void *) c2),
(isreal(v1) ? VF_REAL : VF_COMPLEX),
(isreal(v2) ? VF_REAL : VF_COMPLEX),
length));
/* Back to normal */
(void) signal(SIGILL, SIG_DFL);
if (!data)
return (NULL);
/* Make up the new vector. */
res = alloc(struct dvec);
ZERO(res,struct dvec);
if (relflag || (isreal(v1) && isreal(v2) && (func != cx_comma))) {
res->v_flags = (v1->v_flags | v2->v_flags |
VF_REAL) & ~ VF_COMPLEX;
res->v_realdata = (double *) data;
} else {
res->v_flags = (v1->v_flags | v2->v_flags |
VF_COMPLEX) & ~ VF_REAL;
res->v_compdata = (complex *) data;
}
res->v_name = mkcname(what, v1->v_name, v2->v_name);
res->v_length = length;
/* This is a non-obvious thing */
if (v1->v_scale != v2->v_scale) {
fprintf(cp_err, "Warning: scales of %s and %s are different.\n",
v1->v_name, v2->v_name);
res->v_scale = NULL;
} else
res->v_scale = v1->v_scale;
/* Copy a few useful things */
res->v_defcolor = v1->v_defcolor;
res->v_gridtype = v1->v_gridtype;
res->v_plottype = v1->v_plottype;
/* Copy dimensions. */
if (v1->v_numdims > v2->v_numdims) {
res->v_numdims = v1->v_numdims;
for (i = 0; i < v1->v_numdims; i++)
res->v_dims[i] = v1->v_dims[i];
} else {
res->v_numdims = v2->v_numdims;
for (i = 0; i < v2->v_numdims; i++)
res->v_dims[i] = v2->v_dims[i];
}
/* This depends somewhat on what the operation is. XXX Should fix */
res->v_type = v1->v_type;
vec_new(res);
/* Free the temporary data areas we used, if we allocated any. */
if (free1) {
if (isreal(v1)) {
tfree(d1);
} else {
tfree(c1);
}
}
if (free2) {
if (isreal(v2)) {
tfree(d2);
} else {
tfree(c2);
}
}
return (res);
}

View File

@ -3,8 +3,11 @@
* 1999 E. Rouat
************/
#ifndef EVALUATE_H_INCLUDED
#define EVALUATE_H_INCLUDED
#ifndef _EVALUATE_H
#define _EVALUATE_H
#include <dvec.h>
#include <pnode.h>
struct dvec * ft_evaluate(struct pnode *node);
struct dvec * op_plus(struct pnode *arg1, struct pnode *arg2);

View File

@ -12,11 +12,13 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
#include "ngspice.h"
#include "cpdefs.h"
#include "ftedefs.h"
#include "ftedata.h"
#include "dvec.h"
#include "fteparse.h"
#include "sperror.h"
#include "const.h"
#include "fourier.h"
#include "variable.h"
/* static declarations */
@ -29,12 +31,15 @@ static int CKTfour(int ndata, int numFreq, double *thd, double *Time, double *Va
#define DEF_FOURGRIDSIZE 200
/* CKTfour(ndata,numFreq,thd,Time,Value,FundFreq,Freq,Mag,Phase,nMag,nPhase)
* len 10 ? inp inp inp out out out out out
*/
void
com_fourier(wordlist *wl)
/* FIXME: This function leaks memory due to non local exit bypassing
freeing of memory at the end of the function. */
int
fourier(wordlist *wl, struct plot *current_plot)
{
struct dvec *time, *vec;
struct pnode *names, *first_name;
@ -47,11 +52,14 @@ com_fourier(wordlist *wl)
char xbuf[20];
int shift;
if (!current_plot)
return 1;
sprintf(xbuf, "%1.1e", 0.0);
shift = strlen(xbuf) - 7;
if (!plot_cur || !plot_cur->pl_scale) {
if (!current_plot || !current_plot->pl_scale) {
fprintf(cp_err, "Error: no vectors loaded.\n");
return;
return 1;
}
if ((!cp_getvar("nfreqs", VT_NUM, (char *) &nfreqs)) || (nfreqs < 1))
@ -63,15 +71,15 @@ com_fourier(wordlist *wl)
(fourgridsize < 1))
fourgridsize = DEF_FOURGRIDSIZE;
time = plot_cur->pl_scale;
time = current_plot->pl_scale;
if (!isreal(time)) {
fprintf(cp_err, "Error: fourier needs real time scale\n");
return;
return 1;
}
s = wl->wl_word;
if (!(ff = ft_numparse(&s, FALSE)) || (*ff <= 0.0)) {
fprintf(cp_err, "Error: bad fund freq %s\n", wl->wl_word);
return;
return 1;
}
fundfreq = *ff;
@ -112,8 +120,8 @@ com_fourier(wordlist *wl)
d = 1 / fundfreq; /* The wavelength... */
if (dp[1] - dp[0] < d) {
fprintf(cp_err,
"Error: wavelength longer than time span\n");
return;
"Error: wavelength longer than time span\n");
return 1;
} else if (dp[1] - dp[0] > d) {
dp[0] = dp[1] - d;
}
@ -129,7 +137,7 @@ com_fourier(wordlist *wl)
polydegree)) {
fprintf(cp_err,
"Error: can't interpolate\n");
return;
return 1;
}
timescale = grid;
} else {
@ -143,7 +151,7 @@ com_fourier(wordlist *wl)
nphase);
if (err != OK) {
ft_sperror(err, "fourier");
return;
return 1;
}
fprintf(cp_out, "Fourier analysis for %s:\n",
@ -183,9 +191,18 @@ com_fourier(wordlist *wl)
tfree(phase);
tfree(nmag);
tfree(nphase);
return;
return 0;
}
void
com_fourier(wordlist *wl)
{
fourier(wl, plot_cur);
}
static char *
pn(double num)
{
@ -196,50 +213,54 @@ pn(double num)
i = 6;
if (num < 0.0)
(void) sprintf(buf, "%.*g", i - 1, num);
sprintf(buf, "%.*g", i - 1, num);
else
(void) sprintf(buf, "%.*g", i, num);
sprintf(buf, "%.*g", i, num);
return (copy(buf));
}
/*
* CKTfour() - perform fourier analysis of an output vector.
* Due to the construction of the program which places all the
* output data in the post-processor, the fourier analysis can not
* be done directly. This function allows the post processor to
* hand back vectors of time and data values to have the fourier analysis
* performed on them.
/* CKTfour() - perform fourier analysis of an output vector.
*
*/
* Due to the construction of the program which places all the output
* data in the post-processor, the fourier analysis can not be done
* directly. This function allows the post processor to hand back
* vectors of time and data values to have the fourier analysis
* performed on them. */
static int
CKTfour(int ndata, int numFreq, double *thd, double *Time, double *Value, double FundFreq, double *Freq, double *Mag, double *Phase, double *nMag, double *nPhase)
/* number of entries in the Time and Value arrays */
/* number of harmonics to calculate */
/* total harmonic distortion (percent) to be returned */
/* times at which the voltage/current values were measured*/
/* voltage or current vector whose transform is desired */
/* the fundamental frequency of the analysis */
/* the frequency value of the various harmonics */
/* the Magnitude of the fourier transform */
/* the Phase of the fourier transform */
/* the normalized magnitude of the transform: nMag(fund)=1*/
/* the normalized phase of the transform: Nphase(fund)=0 */
/* note we can consider these as a set of arrays: The sizes are:
* Time[ndata], Value[ndata]
* Freq[numFreq],Mag[numfreq],Phase[numfreq],nMag[numfreq],nPhase[numfreq]
CKTfour(int ndata, /* number of entries in the Time and
Value arrays */
int numFreq, /* number of harmonics to calculate */
double *thd, /* total harmonic distortion (percent)
to be returned */
double *Time, /* times at which the voltage/current
values were measured*/
double *Value, /* voltage or current vector whose
transform is desired */
double FundFreq, /* the fundamental frequency of the
analysis */
double *Freq, /* the frequency value of the various
harmonics */
double *Mag, /* the Magnitude of the fourier
transform */
double *Phase, /* the Phase of the fourier transform */
double *nMag, /* the normalized magnitude of the
transform: nMag(fund)=1*/
double *nPhase) /* the normalized phase of the
transform: Nphase(fund)=0 */
{
/* Note: we can consider these as a set of arrays. The sizes are:
* Time[ndata], Value[ndata], Freq[numFreq], Mag[numfreq],
* Phase[numfreq], nMag[numfreq], nPhase[numfreq]
*
* The arrays must all be allocated by the caller.
* The Time and Value array must be reasonably distributed over at
* least one full period of the fundamental Frequency for the
* fourier transform to be useful. The function will take the
* last period of the frequency as data for the transform.
*/
{
/* we are assuming that the caller has provided exactly one period
* of the fundamental frequency.
*/
*
* We are assuming that the caller has provided exactly one period
* of the fundamental frequency. */
int i;
int j;
double tmp;
@ -272,112 +293,3 @@ CKTfour(int ndata, int numFreq, double *thd, double *Time, double *Value, double
*thd = 100*sqrt(*thd);
return(OK);
}
#ifdef notdef
/* What is this code? An old DFT? */
double initial; /* starting time */
double final; /* final time */
double elapsed; /* elapsed time */
double tmp;
int start=0;
int n;
int m;
int edge;
*thd = 0;
final = Time[ndata-1];
initial = Time[0];
elapsed = final - initial;
if( (elapsed-1/FundFreq)< -.01/FundFreq ){
/* not enough data for a full period */
return(E_BADPARM);
}
elapsed = 1/FundFreq; /* set to desired elapsed time */
initial = final - elapsed; /* set to desired starting time */
while(Time[start]<initial) { start++; } /* to find first time in interval*/
start++; /* throw away one more point - come back to it later */
for(m=0;m<numFreq;m++) {
Mag[m]=0;
Phase[m]=0;
}
/* ok - here's the hard part - compute the dft of Data[start::ndata]
* temporarily, put the real/imag. parts of the DFT in Mag[] and Phase[]
* later we will convert each term to phase-magnitude
*/
for(n=start;n<ndata-1;n++) {
for(m=0;m<numFreq;m++) {
Mag[m] += .5 * (Time[n+1]-Time[n-1]) * Value[n] *
sin(2.0*M_PI*m*((Time[n]-initial)/elapsed));
Phase[m] += .5 * (Time[n+1]-Time[n-1]) * Value[n] *
cos(2.0*M_PI*m*((Time[n]-initial)/elapsed));
/* know Time[n+-1] exists because stop at = ndata-2, */
/* and did a start++ earlier - come back and clean up ends later */
}
}
/* now to deal with the endpoints. The (ndata-1)th point has a smaller
* interval
*/
for(m=0;m<numFreq;m++) {
Mag[m] += 0.5 * (Time[n]-Time[n-1]) * Value[n] *
sin(2.0*M_PI*m*((Time[n]-initial)/elapsed));
Phase[m] += 0.5 * (Time[n]-Time[n-1]) * Value[n] *
cos(2.0*M_PI*m*((Time[n]-initial)/elapsed));
}
/* now to deal with the start of the interval. first, deal with
* the start-1'th point - exactly the same regardless of case
* because of the extra start++ earlier.
*/
for(m=0;m<numFreq;m++) {
Mag[m] += 0.5 * (Time[start]-initial) * Value[start-1] *
sin(2.0*M_PI*m*((Time[start-1]-initial)/elapsed));
Phase[m] += 0.5 * (Time[start]-initial) * Value[start-1] *
cos(2.0*M_PI*m*((Time[start-1]-initial)/elapsed));
}
/* now deal with the possibility that the above point, which was
* the first one contained within the interval may have been
* inside the interval, or ON the boundry - in the latter case,
* we don't want to deal with the previous point at all.
*/
if(Time[start-1]> initial) {
/* interesting case - need to handle previous point */
/* first, make sure that there is a point on the other side of
* the beginning of time.
*/
if(start-2 < 0) {
/* point doesn't exist, so we have to fudge
* things slightly - by bumping edge up, we re-use the first
* point in the interval for the last point before the
* interval - should be only for very small error in
* interval boundaries, so shouldn't be significant, and is
* better than ignoring the interval
*/
edge = start-1;
} else {
edge = start-2;
}
for(m=0;m<numFreq;m++) {
Mag[m] += .5 * (Time[start-1]-initial) * Value[edge] *
sin(2.0*M_PI*m*((Time[edge]-initial)/elapsed));
Phase[m] += .5 * (Time[start-1]-initial) * Value[edge] *
cos(2.0*M_PI*m*((Time[edge]-initial)/elapsed));
}
}
Mag[0]=Phase[0]/elapsed;
Phase[0]=nMag[0]=nPhase[0]=Freq[0]=0;
for(m=1;m<numFreq;m++) {
tmp = Mag[m] * 2.0 / (elapsed);
Phase[m] *= 2.0 / (elapsed);
Freq[m] = m * FundFreq;
Mag[m] = sqrt(tmp * tmp + Phase[m] * Phase[m]);
Phase[m] = atan2(Phase[m],tmp) * 180.0/M_PI;
nMag[m] = Mag[m] / Mag[1];
nPhase[m] = Phase[m] - Phase[1];
if(m>1) *thd += nMag[m] * nMag[m];
}
*thd = 100 * sqrt(*thd);
return(OK);
#endif

View File

@ -7,7 +7,6 @@
#define FOURIER_H_INCLUDED
void com_fourier(wordlist *wl);
int fourier(wordlist *wl, struct plot *current);
#endif

View File

@ -16,7 +16,7 @@ static void dgen_next(dgen **dgx);
void
wl_forall(wordlist *wl, int (*fn) (/* ??? */), char *data)
wl_forall(wordlist *wl, void (*fn) (/* ??? */), void *data)
{
while (wl) {
(*fn)(wl, data);
@ -40,27 +40,6 @@ dgen_init(GENcircuit *ckt, wordlist *wl, int nomix, int flag, int model)
prevp = &wl;
#ifdef notdef
for (w = wl; w; w = w->wl_next) {
if (!strcmp(w->wl_word, "#")) {
model = 1;
*prevp = w->wl_next;
flag |= DGEN_DEFDEVS;
} else if (index(w->wl_word, '#'))
model = 1;
else
instance = 1;
prevp = &w->wl_next;
}
if (instance && model) {
fprintf(stderr,
"Error: can't mix instances and models");
tfree(dg);
return NULL;
}
#endif
if (model)
dg->flags = (DGEN_ALL & ~ DGEN_INSTANCE) | DGEN_INIT;
else
@ -77,7 +56,7 @@ dgen_init(GENcircuit *ckt, wordlist *wl, int nomix, int flag, int model)
}
int
dgen_for_n(dgen *dg, int n, int (*fn) (/* ??? */), char *data, int subindex)
dgen_for_n(dgen *dg, int n, int (*fn) (/* ??? */), void *data, int subindex)
{
dgen dgx, *dgxp;
int dnum, i, j, k;
@ -172,15 +151,7 @@ dgen_next(dgen **dgx)
if (need & DGEN_MODEL && !dg->model)
continue;
#ifdef notdef
if (dg->instance)
printf("Maybe : %s\n", dg->instance->GENname);
if (dg->model)
printf("Maybe mod : %s\n", dg->model->GENmodName);
#endif
/* Filter */
if (!dg->dev_list) {
if ((dg->flags & DGEN_ALLDEVS)
|| ((dg->flags & DGEN_DEFDEVS)
@ -263,11 +234,6 @@ dgen_next(dgen **dgx)
}
/* Now compare */
#ifdef notdef
printf("Type: %c, subckt: %s, name: %s\n",
type ? type : '0', subckt, device);
#endif
if (dg->instance)
dev_name = dg->instance->GENname;
else
@ -334,13 +300,6 @@ dgen_next(dgen **dgx)
break;
}
#ifdef notdef
if (done == 1)
printf("Accepted\n");
else
printf("Skipped\n");
#endif
}
if (done == 2)

View File

@ -6,9 +6,9 @@
#ifndef GENS_H_INCLUDED
#define GENS_H_INCLUDED
void wl_forall(wordlist *wl, int (*fn) (/* ??? */), char *data);
void wl_forall(wordlist *wl, void (*fn) (/* ??? */), void *data);
dgen * dgen_init(GENcircuit *ckt, wordlist *wl, int nomix, int flag, int model);
int dgen_for_n(dgen *dg, int n, int (*fn) (/* ??? */), char *data, int subindex);
int dgen_for_n(dgen *dg, int n, int (*fn) (/* ??? */), void *data, int subindex);
void dgen_nth_next(dgen **dg, int n);

View File

@ -3,6 +3,12 @@ Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Wayne A. Christopher
**********/
/*
* SJB 22 May 2001
* Fixed memory leaks accociated with freeing memory used by lines in the input deck
* in inp_spsource(). New line_free() routine added to help with this.
*/
/*
* Stuff for dealing with spice input decks and command scripts, and
* the listing routines.
@ -12,11 +18,20 @@ Author: 1985 Wayne A. Christopher
#include "cpdefs.h"
#include "inpdefs.h"
#include "ftedefs.h"
#include "ftedata.h"
#include "dvec.h"
#include "fteinp.h"
#include "inp.h"
#include "circuits.h"
#include "completion.h"
#include "variable.h"
#ifdef XSPICE
/* gtri - add - 12/12/90 - wbk - include new stuff */
#include "ipctiein.h"
#include "enh.h"
/* gtri - end - 12/12/90 */
#endif
/* static declarations */
static char * upper(register char *string);
@ -71,8 +86,9 @@ com_listing(wordlist *wl)
return;
}
static char *
upper(register char *string)
upper(char *string)
{
static char buf[BSIZE_SP];
@ -89,11 +105,10 @@ upper(register char *string)
}
/* Provide an input listing on the specified file of the given
* card deck. The listing should be of either LS_PHYSICAL or LS_LOGICAL
* or LS_DECK lines as specified by the type parameter.
*/
/* Provide an input listing on the specified file of the given card
* deck. The listing should be of either LS_PHYSICAL or LS_LOGICAL or
* LS_DECK lines as specified by the type parameter. */
void
inp_list(FILE *file, struct line *deck, struct line *extras, int type)
{
@ -102,12 +117,20 @@ inp_list(FILE *file, struct line *deck, struct line *extras, int type)
bool renumber;
bool useout = (file == cp_out);
int i = 1;
/* gtri - wbk - 03/07/91 - Don't use 'more' type output if ipc enabled */
#ifdef XSPICE
if(g_ipc.enabled) {
useout = FALSE;
}
#endif
/* gtri - end - 03/07/91 */
if (useout)
out_init();
(void) cp_getvar("renumber", VT_BOOL, (char *) &renumber);
cp_getvar("renumber", VT_BOOL, (char *) &renumber);
if (type == LS_LOGICAL) {
top1: for (here = deck; here; here = here->li_next) {
top1:
for (here = deck; here; here = here->li_next) {
if (renumber)
here->li_linenum = i;
i++;
@ -119,10 +142,7 @@ top1: for (here = deck; here; here = here->li_next) {
sprintf(out_pbuf, "%6d : %s\n",
here->li_linenum,
upper(here->li_line));
out_send(out_pbuf);
/* out_printf("%6d : %s\n",
here->li_linenum,
upper(here->li_line)); */
out_send(out_pbuf);
} else
fprintf(file, "%6d : %s\n",
here->li_linenum,
@ -141,13 +161,13 @@ top1: for (here = deck; here; here = here->li_next) {
goto top1;
}
if (useout) {
/* out_printf("%6d : .end\n", i); */
sprintf(out_pbuf, "%6d : .end\n", i);
out_send(out_pbuf);
} else
fprintf(file, "%6d : .end\n", i);
} else if ((type == LS_PHYSICAL) || (type == LS_DECK)) {
top2: for (here = deck; here; here = here->li_next) {
top2:
for (here = deck; here; here = here->li_next) {
if ((here->li_actual == NULL) || (here == deck)) {
if (renumber)
here->li_linenum = i;
@ -158,28 +178,28 @@ top2: for (here = deck; here; here = here->li_next) {
if (type == LS_PHYSICAL) {
if (useout) {
sprintf(out_pbuf, "%6d : %s\n",
here->li_linenum,
upper(here->li_line));
out_send(out_pbuf);
here->li_linenum,
upper(here->li_line));
out_send(out_pbuf);
} else
fprintf(file, "%6d : %s\n",
here->li_linenum,
upper(here->li_line));
here->li_linenum,
upper(here->li_line));
} else {
if (useout)
out_printf("%s\n",
upper(here->li_line));
upper(here->li_line));
else
fprintf(file, "%s\n",
upper(here->li_line));
upper(here->li_line));
}
if (here->li_error && (type == LS_PHYSICAL)) {
if (useout)
out_printf("%s\n",
here->li_error);
here->li_error);
else
fprintf(file, "%s\n",
here->li_error);
here->li_error);
}
} else {
for (there = here->li_actual; there;
@ -191,13 +211,13 @@ top2: for (here = deck; here; here = here->li_next) {
if (type == LS_PHYSICAL) {
if (useout) {
sprintf(out_pbuf, "%6d : %s\n",
there->li_linenum,
upper(there->li_line));
out_send(out_pbuf);
there->li_linenum,
upper(there->li_line));
out_send(out_pbuf);
} else
fprintf(file, "%6d : %s\n",
there->li_linenum,
upper(there->li_line));
there->li_linenum,
upper(there->li_line));
} else {
if (useout)
out_printf("%s\n",
@ -242,18 +262,36 @@ top2: for (here = deck; here; here = here->li_next) {
return;
}
/* The routine to source a spice input deck. We read the deck in, take out
* the front-end commands, and create a CKT structure. Also we filter out
* the following cards: .save, .width, .four, .print, and .plot, to perform
* after the run is over.
/*
* Free memory used by a line.
* If recure is TRUE then recursivly free all lines linked via the li_next field.
* If recurse is FALSE free only this line.
* All lines linked via the li_actual field are always recursivly freed.
* SJB - 22nd May 2001
*/
void
line_free(struct line * deck, bool recurse) {
if(!deck)
return;
tfree(deck->li_line);
tfree(deck->li_error);
if(recurse)
line_free(deck->li_next,TRUE);
line_free(deck->li_actual,TRUE);
tfree(deck);
}
/* The routine to source a spice input deck. We read the deck in, take
* out the front-end commands, and create a CKT structure. Also we
* filter out the following cards: .save, .width, .four, .print, and
* .plot, to perform after the run is over. */
void
inp_spsource(FILE *fp, bool comfile, char *filename)
{
struct line *deck, *dd, *ld;
struct line *realdeck, *options;
char *tt, name[BSIZE_SP], *s, *t;
struct line *realdeck, *options = NULL;
char *tt = NULL, name[BSIZE_SP], *s, *t;
bool nosubckts, commands = FALSE;
wordlist *wl = NULL, *end = NULL, *wl_first = NULL;
wordlist *controls = NULL;
@ -263,7 +301,7 @@ inp_spsource(FILE *fp, bool comfile, char *filename)
inp_readall(fp, &deck);
if (!deck) { /* MW. We must close fp always when returning */
(void) fclose(fp);
fclose(fp);
return;
}
@ -280,11 +318,10 @@ inp_spsource(FILE *fp, bool comfile, char *filename)
}
fclose(fp);
/* Now save the IO context and start a new control set. After
* we are done with the source we'll put the old file descriptors
* back. I guess we could use a FILE stack, but since this routine
* is recursive anyway.
*/
/* Now save the IO context and start a new control set. After we
* are done with the source we'll put the old file descriptors
* back. I guess we could use a FILE stack, but since this
* routine is recursive anyway. */
lastin = cp_curin;
lastout = cp_curout;
lasterr = cp_curerr;
@ -294,13 +331,11 @@ inp_spsource(FILE *fp, bool comfile, char *filename)
cp_pushcontrol();
/* We should now go through the deck and execute front-end
/* We should now go through the deck and execute front-end
* commands and remove them. Front-end commands are enclosed by
* the cards .control and .endc, unless comfile
* is TRUE, in which case every line must be a front-end command.
* There are too many problems with matching the first word on
* the line.
*/
* the cards .control and .endc, unless comfile is TRUE, in which
* case every line must be a front-end command. There are too
* many problems with matching the first word on the line. */
ld = deck;
if (comfile) {
/* This is easy. */
@ -311,12 +346,13 @@ inp_spsource(FILE *fp, bool comfile, char *filename)
if (!ciprefix(".control", dd->li_line) &&
!ciprefix(".endc", dd->li_line)) {
if (dd->li_line[0] == '*')
(void) cp_evloop(dd->li_line + 2);
cp_evloop(dd->li_line + 2);
else
(void) cp_evloop(dd->li_line);
cp_evloop(dd->li_line);
}
tfree(dd->li_line);
tfree(dd);
line_free(dd,FALSE); /* SJB - free this line's memory */
/* tfree(dd->li_line);
tfree(dd); */
}
} else {
for (dd = deck->li_next; dd; dd = ld->li_next) {
@ -326,7 +362,7 @@ inp_spsource(FILE *fp, bool comfile, char *filename)
ld = dd;
continue;
}
(void) strncpy(name, dd->li_line, BSIZE_SP);
strncpy(name, dd->li_line, BSIZE_SP);
for (s = name; *s && isspace(*s); s++)
;
for (t = s; *t && !isspace(*t); t++)
@ -335,17 +371,19 @@ inp_spsource(FILE *fp, bool comfile, char *filename)
if (ciprefix(".control", dd->li_line)) {
ld->li_next = dd->li_next;
tfree(dd->li_line);
tfree(dd);
line_free(dd,FALSE); /* SJB - free this line's memory */
/* tfree(dd->li_line);
tfree(dd); */
if (commands)
fprintf(cp_err,
"Warning: redundant .control card\n");
fprintf(cp_err,
"Warning: redundant .control card\n");
else
commands = TRUE;
} else if (ciprefix(".endc", dd->li_line)) {
ld->li_next = dd->li_next;
tfree(dd->li_line);
tfree(dd);
line_free(dd,FALSE); /* SJB - free this line's memory */
/* tfree(dd->li_line);
tfree(dd); */
if (commands)
commands = FALSE;
else
@ -361,23 +399,30 @@ inp_spsource(FILE *fp, bool comfile, char *filename)
controls = wl;
if (prefix("*#", dd->li_line))
wl->wl_word = copy(dd->li_line + 2);
else
else {
wl->wl_word = dd->li_line;
dd->li_line = 0; /* SJB - prevent line_free() freeing the string (now pointed at by wl->wl_word) */
}
ld->li_next = dd->li_next;
tfree(dd);
line_free(dd,FALSE); /* SJB - free this line's memory */
/* tfree(dd); */
} else if (!*dd->li_line) {
/* So blank lines in com files don't get
* considered as circuits.
*/
/* So blank lines in com files don't get considered as
* circuits. */
ld->li_next = dd->li_next;
tfree(dd->li_line);
tfree(dd);
line_free(dd,FALSE); /* SJB - free this line's memory */
/* tfree(dd->li_line);
tfree(dd); */
} else {
inp_casefix(s);
inp_casefix(dd->li_line);
if (eq(s, ".width") || ciprefix(".four", s) || eq(s, ".plot")
|| eq(s, ".print") || eq(s, ".save")
|| eq(s, ".op") || eq(s, ".tf"))
if (eq(s, ".width")
|| ciprefix(".four", s)
|| eq(s, ".plot")
|| eq(s, ".print")
|| eq(s, ".save")
|| eq(s, ".op")
|| eq(s, ".tf"))
{
if (end) {
end->wl_next = alloc(struct wordlist);
@ -389,8 +434,9 @@ inp_spsource(FILE *fp, bool comfile, char *filename)
if (!eq(s, ".op") && !eq(s, ".tf")) {
ld->li_next = dd->li_next;
tfree(dd->li_line);
tfree(dd);
line_free(dd,FALSE); /* SJB - free this line's memory */
/* tfree(dd->li_line);
tfree(dd); */
} else
ld = dd;
} else
@ -401,33 +447,41 @@ inp_spsource(FILE *fp, bool comfile, char *filename)
/* There is something left after the controls. */
fprintf(cp_out, "\nCircuit: %s\n\n", tt);
/* Now expand subcircuit macros. Note that we have to
* fix the case before we do this but after we
* deal with the commands.
*/
if (!cp_getvar("nosubckt", VT_BOOL, (char *)
&nosubckts))
deck->li_next = inp_subcktexpand(deck->
li_next);
#ifdef XSPICE
/* gtri - wbk - Translate all SPICE 2G6 polynomial type sources */
deck->li_next = ENHtranslate_poly(deck->li_next);
/* gtri - end - Translate all SPICE 2G6 polynomial type sources */
#endif
/* Now expand subcircuit macros. Note that we have to fix
* the case before we do this but after we deal with the
* commands. */
if (!cp_getvar("nosubckt", VT_BOOL, (char *) &nosubckts))
if((deck->li_next = inp_subcktexpand(deck->li_next)) == NULL){
line_free(realdeck,TRUE);
line_free(deck->li_actual, TRUE);
return;
}
line_free(deck->li_actual,FALSE); /* SJB - free memory used by old li_actual (if any) */
deck->li_actual = realdeck;
inp_dodeck(deck, tt, wl_first, FALSE, options, filename);
}
/* Now that the deck is loaded, do the commands */
if (controls) {
for (end = wl = wl_reverse(controls); wl;
wl = wl->wl_next)
(void) cp_evloop(wl->wl_word);
for (end = wl = wl_reverse(controls); wl; wl = wl->wl_next)
cp_evloop(wl->wl_word);
wl_free(end);
/* MW. Memory leak fixed here */
}
}
/*saj, to process save commands always, not just in batch mode
*(breaks encapsulation of frountend and parsing commands slightly)*/
ft_dotsaves();
/* Now reset everything. Pop the control stack, and fix up the IO
* as it was before the source.
*/
* as it was before the source. */
cp_popcontrol();
cp_curin = lastin;
@ -436,14 +490,14 @@ inp_spsource(FILE *fp, bool comfile, char *filename)
return;
}
/* This routine is cut in half here because com_rset has to do what follows
* also. End is the list of commands we execute when the job is finished:
* we only bother with this if we might be running in batch mode, since
* it isn't much use otherwise.
*/
/* This routine is cut in half here because com_rset has to do what
* follows also. End is the list of commands we execute when the job
* is finished: we only bother with this if we might be running in
* batch mode, since it isn't much use otherwise. */
void
inp_dodeck(struct line *deck, char *tt, wordlist *end, bool reuse, struct line *options, char *filename)
inp_dodeck(struct line *deck, char *tt, wordlist *end, bool reuse,
struct line *options, char *filename)
{
struct circ *ct;
struct line *dd;
@ -454,8 +508,7 @@ inp_dodeck(struct line *deck, char *tt, wordlist *end, bool reuse, struct line *
bool noparse, ii;
/* First throw away any old error messages there might be and fix
* the case of the lines.
*/
* the case of the lines. */
for (dd = deck; dd; dd = dd->li_next) {
if (dd->li_error) {
tfree(dd->li_error);
@ -473,7 +526,7 @@ inp_dodeck(struct line *deck, char *tt, wordlist *end, bool reuse, struct line *
}
ft_curckt = ct = alloc(struct circ);
}
(void) cp_getvar("noparse", VT_BOOL, (char *) &noparse);
cp_getvar("noparse", VT_BOOL, (char *) &noparse);
if (!noparse)
ckt = if_inpdeck(deck, &tab);
else
@ -483,6 +536,10 @@ inp_dodeck(struct line *deck, char *tt, wordlist *end, bool reuse, struct line *
for (dd = deck; dd; dd = dd->li_next)
if (dd->li_error) {
char *p, *q;
#ifdef XSPICE
/* gtri - modify - 12/12/90 - wbk - add setting of ipc syntax error flag */ g_ipc.syntax_error = IPC_TRUE;
#endif
/* gtri - end - 12/12/90 */
p = dd->li_error;
do {
q =strchr(p, '\n');
@ -501,25 +558,18 @@ inp_dodeck(struct line *deck, char *tt, wordlist *end, bool reuse, struct line *
} while (p && *p);
}
/* Add this circuit to the circuit list. If reuse is TRUE then
* use the ft_curckt structure.
*/
/* Add this circuit to the circuit list. If reuse is TRUE then use
* the ft_curckt structure. */
if (!reuse) {
#ifdef notdef
/* Unused time-waster. */
for (dd = deck->li_next; dd; dd = dd->li_next)
if_setndnames(dd->li_line);
#endif
/* Be sure that ci_devices and ci_nodes are valid */
ft_curckt->ci_devices = cp_kwswitch(CT_DEVNAMES,
(char *) NULL);
(void) cp_kwswitch(CT_DEVNAMES, ft_curckt->ci_devices);
cp_kwswitch(CT_DEVNAMES, ft_curckt->ci_devices);
ft_curckt->ci_nodes = cp_kwswitch(CT_NODENAMES, (char *) NULL);
(void) cp_kwswitch(CT_NODENAMES, ft_curckt->ci_nodes);
cp_kwswitch(CT_NODENAMES, ft_curckt->ci_nodes);
ft_newcirc(ct);
/* ft_setccirc(); */ ft_curckt = ct;
/* Assign current circuit */
ft_curckt = ct;
}
ct->ci_name = tt;
ct->ci_deck = deck;
@ -582,11 +632,10 @@ inp_dodeck(struct line *deck, char *tt, wordlist *end, bool reuse, struct line *
return;
}
/* Edit and re-load the current input deck. Note that if these commands are
* used on a non-unix machine, they will leave spice.tmp junk files lying
* around.
*/
/* Edit and re-load the current input deck. Note that if these
* commands are used on a non-unix machine, they will leave spice.tmp
* junk files lying around. */
void
com_edit(wordlist *wl)
{
@ -626,8 +675,9 @@ com_edit(wordlist *wl)
inp_list(fp, ft_curckt->ci_deck, ft_curckt->ci_options,
LS_DECK);
fprintf(cp_err,
"Warning: editing a temporary file -- circuit not saved\n");
(void) fclose(fp);
"Warning: editing a temporary file -- "
"circuit not saved\n");
fclose(fp);
} else if (!ft_curckt) {
if (!(fp = fopen(filename, "w"))) {
perror(filename);
@ -635,7 +685,7 @@ com_edit(wordlist *wl)
return;
}
fprintf(fp, "SPICE 3 test deck\n");
(void) fclose(fp);
fclose(fp);
}
if (!doedit(filename)) {
cp_interactive = inter;
@ -649,11 +699,11 @@ com_edit(wordlist *wl)
}
inp_spsource(fp, FALSE, permfile ? filename : (char *) NULL);
/* (void) fclose(fp); */
/* fclose(fp); */
/* MW. inp_spsource already closed fp */
if (ft_curckt && !ft_curckt->ci_filename)
(void) unlink(filename);
unlink(filename);
}
cp_interactive = inter;
@ -662,7 +712,7 @@ com_edit(wordlist *wl)
fprintf(cp_out, "run circuit? ");
fflush(cp_out);
(void) fgets(buf, BSIZE_SP, stdin);
fgets(buf, BSIZE_SP, stdin);
if (buf[0] != 'n') {
fprintf(cp_out, "running circuit\n");
com_run(NULL);
@ -683,10 +733,10 @@ doedit(char *filename)
if (Def_Editor && *Def_Editor)
editor = Def_Editor;
else
editor = "/usr/ucb/vi";
editor = "/usr/bin/vi";
}
}
(void) sprintf(buf, "%s %s", editor, filename);
sprintf(buf, "%s %s", editor, filename);
return (system(buf) ? FALSE : TRUE);
}
@ -716,17 +766,17 @@ com_source(wordlist *wl)
while (wl) {
if (!(tp = inp_pathopen(wl->wl_word, "r"))) {
perror(wl->wl_word);
(void) fclose(fp);
fclose(fp);
cp_interactive = TRUE;
(void) unlink(tempfile);
unlink(tempfile);
return;
}
while ((i = fread(buf, 1, BSIZE_SP, tp)) > 0)
(void) fwrite(buf, 1, i, fp);
(void) fclose(tp);
fwrite(buf, 1, i, fp);
fclose(tp);
wl = wl->wl_next;
}
(void) fseek(fp, (long) 0, 0);
fseek(fp, (long) 0, 0);
} else
fp = inp_pathopen(wl->wl_word, "r");
if (fp == NULL) {
@ -743,7 +793,7 @@ com_source(wordlist *wl)
inp_spsource(fp, FALSE, tempfile ? (char *) NULL : wl->wl_word);
cp_interactive = inter;
if (tempfile)
(void) unlink(tempfile);
unlink(tempfile);
return;
}

View File

@ -6,16 +6,32 @@ Author: 1985 Wayne A. Christopher
/*
* For dealing with spice input decks and command scripts
*/
/*
* SJB 22 May 2001
* Fixed memory leaks in inp_readall() when first(?) line of input begins with a '@'.
* Fixed memory leaks in inp_readall() when .include lines have errors
* Fixed crash where a NULL pointer gets freed in inp_readall()
*/
#include <config.h>
#include "ngspice.h"
#include "cpdefs.h"
#include "ftedefs.h"
#include "ftedata.h"
#include "dvec.h"
#include "fteinp.h"
#include "inpcom.h"
#include "inpcom.h"
#include "variable.h"
#ifdef XSPICE
/* gtri - add - 12/12/90 - wbk - include new stuff */
#include "ipctiein.h"
#include "enh.h"
/* gtri - end - 12/12/90 */
#endif
/* This routine reads a line (of arbitrary length), up to a '\n' or 'EOF'
* and returns a pointer to the resulting null terminated string.
* The '\n' if found, is included in the returned string.
@ -54,7 +70,7 @@ readline(FILE *fd)
}
}
if (!strlen) {
free(strptr);
tfree(strptr);
return (NULL);
}
strptr[strlen] = '\0';
@ -108,14 +124,54 @@ inp_pathopen(char *name, char *mode)
void
inp_readall(FILE *fp, struct line **data)
{
struct line *end = NULL, *cc, *prev = NULL, *working, *newcard;
struct line *end = NULL, *cc = NULL, *prev = NULL, *working, *newcard;
char *buffer, *s, *t, c;
/* segfault fix */
char *copys=NULL;
int line = 1;
FILE *newfp;
/* gtri - modify - 12/12/90 - wbk - read from mailbox if ipc enabled */
#ifdef XSPICE
Ipc_Status_t ipc_status;
char ipc_buffer[1025]; /* Had better be big enough */
int ipc_len;
while (1) {
/* If IPC is not enabled, do equivalent of what SPICE did before */
if(! g_ipc.enabled) {
buffer = readline(fp);
if(! buffer)
break;
}
else {
/* else, get the line from the ipc channel. */
/* We assume that newlines are not sent by the client */
/* so we add them here */
ipc_status = ipc_get_line(ipc_buffer, &ipc_len, IPC_WAIT);
if(ipc_status == IPC_STATUS_END_OF_DECK) {
buffer = NULL;
break;
}
else if(ipc_status == IPC_STATUS_OK) {
buffer = (void *) MALLOC(strlen(ipc_buffer) + 3);
strcpy(buffer, ipc_buffer);
strcat(buffer, "\n");
}
else { /* No good way to report this so just die */
exit(1);
}
}
/* gtri - end - 12/12/90 */
#else
while ((buffer = readline(fp))) {
if (*buffer == '@')
#endif
if (*buffer == '@') {
tfree(buffer); /* was allocated by readline() */
break;
}
for (s = buffer; *s && (*s != '\n'); s++)
;
if (!*s) {
@ -129,19 +185,34 @@ inp_readall(FILE *fp, struct line **data)
while (isspace(*s))
s++;
if (!*s) {
fprintf(cp_err,
"Error: .include filename missing\n");
fprintf(cp_err, "Error: .include filename missing\n");
tfree(buffer); /* was allocated by readline() */
continue;
}
for (t = s; *t && !isspace(*t); t++)
;
*t = '\0';
if (*s == '~')
s = cp_tildexpand(s);
if (*s == '~') {
copys = cp_tildexpand(s); /* allocates memory, but can also return NULL */
if(copys != NULL) {
s = copys; /* reuse s, but remember, buffer still points to allocated memory */
}
}
if (!(newfp = inp_pathopen(s, "r"))) {
perror(s);
if(copys) {
tfree(copys); /* allocated by the cp_tildexpand() above */
}
tfree(buffer); /* allocated by readline() above */
continue;
}
if(copys) {
tfree(copys); /* allocated by the cp_tildexpand() above */
}
inp_readall(newfp, &newcard);
(void) fclose(newfp);
@ -242,8 +313,9 @@ inp_readall(FILE *fp, struct line **data)
return;
}
void
inp_casefix(register char *string)
inp_casefix(char *string)
{
#ifdef HAVE_CTYPE_H
if (string)
@ -254,8 +326,10 @@ inp_casefix(register char *string)
#endif
if (*string == '"') {
*string++ = ' ';
while (*string && *string != '"') string++;
if (*string == '"') *string = ' ';
while (*string && *string != '"')
string++;
if (*string == '"')
*string = ' ';
}
if (!isspace(*string) && !isprint(*string))
*string = '_';

View File

@ -10,338 +10,10 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
#include "ngspice.h"
#include "cpdefs.h"
#include "ftedefs.h"
#include "ftedata.h"
#include "dvec.h"
#include "interp.h"
/* Interpolate data from oscale to nscale. data is assumed to be olen long,
* ndata will be nlen long. Returns FALSE if the scales are too strange
* to deal with. Note that we are guaranteed that either both scales are
* strictly increasing or both are strictly decreasing.
*/
/* static declarations */
static int putinterval(double *poly, int degree, double *nvec, int last, double *nscale,
int nlen, double oval, int sign);
static void printmat(char *name, double *mat, int m, int n);
bool
ft_interpolate(double *data, double *ndata, double *oscale, int olen, double *nscale, int nlen, int degree)
{
double *result, *scratch, *xdata, *ydata;
int sign, lastone, i, l;
if ((olen < 2) || (nlen < 2)) {
fprintf(cp_err, "Error: lengths too small to interpolate.\n");
return (FALSE);
}
if ((degree < 1) || (degree > olen)) {
fprintf(cp_err, "Error: degree is %d, can't interpolate.\n",
degree);
return (FALSE);
}
if (oscale[1] < oscale[0])
sign = -1;
else
sign = 1;
scratch = (double *) tmalloc((degree + 1) * (degree + 2) *
sizeof (double));
result = (double *) tmalloc((degree + 1) * sizeof (double));
xdata = (double *) tmalloc((degree + 1) * sizeof (double));
ydata = (double *) tmalloc((degree + 1) * sizeof (double));
/* Deal with the first degree pieces. */
bcopy((char *) data, (char *) ydata, (degree + 1) * sizeof (double));
bcopy((char *) oscale, (char *) xdata, (degree + 1) * sizeof (double));
while (!ft_polyfit(xdata, ydata, result, degree, scratch)) {
/* If it doesn't work this time, bump the interpolation
* degree down by one.
*/
if (--degree == 0) {
fprintf(cp_err, "ft_interpolate: Internal Error.\n");
return (FALSE);
}
}
/* Add this part of the curve. What we do is evaluate the polynomial
* at those points between the last one and the one that is greatest,
* without being greater than the leftmost old scale point, or least
* if the scale is decreasing at the end of the interval we are looking
* at.
*/
lastone = -1;
for (i = 0; i < degree; i++) {
lastone = putinterval(result, degree, ndata, lastone,
nscale, nlen, xdata[i], sign);
}
/* Now plot the rest, piece by piece. l is the
* last element under consideration.
*/
for (l = degree + 1; l < olen; l++) {
/* Shift the old stuff by one and get another value. */
for (i = 0; i < degree; i++) {
xdata[i] = xdata[i + 1];
ydata[i] = ydata[i + 1];
}
ydata[i] = data[l];
xdata[i] = oscale[l];
while (!ft_polyfit(xdata, ydata, result, degree, scratch)) {
if (--degree == 0) {
fprintf(cp_err,
"interpolate: Internal Error.\n");
return (FALSE);
}
}
lastone = putinterval(result, degree, ndata, lastone,
nscale, nlen, xdata[i], sign);
}
if (lastone < nlen - 1) /* ??? */
ndata[nlen - 1] = data[olen - 1];
tfree(scratch);
tfree(xdata);
tfree(ydata);
tfree(result);
return (TRUE);
}
/* Takes n = (degree+1) doubles, and fills in result with the n coefficients
* of the polynomial that will fit them. It also takes a pointer to an
* array of n ^ 2 + n doubles to use for scratch -- we want to make this
* fast and avoid doing mallocs for each call.
*/
bool
ft_polyfit(double *xdata, double *ydata, double *result, int degree, double *scratch)
{
register double *mat1 = scratch;
register int l, k, j, i;
register int n = degree + 1;
register double *mat2 = scratch + n * n; /* XXX These guys are hacks! */
double d;
/*
fprintf(cp_err, "n = %d, xdata = ( ", n);
for (i = 0; i < n; i++)
fprintf(cp_err, "%G ", xdata[i]);
fprintf(cp_err, ")\n");
fprintf(cp_err, "ydata = ( ");
for (i = 0; i < n; i++)
fprintf(cp_err, "%G ", ydata[i]);
fprintf(cp_err, ")\n");
*/
bzero((char *) result, n * sizeof(double));
bzero((char *) mat1, n * n * sizeof (double));
bcopy((char *) ydata, (char *) mat2, n * sizeof (double));
/* Fill in the matrix with x^k for 0 <= k <= degree for each point */
l = 0;
for (i = 0; i < n; i++) {
d = 1.0;
for (j = 0; j < n; j++) {
mat1[l] = d;
d *= xdata[i];
l += 1;
}
}
/* Do Gauss-Jordan elimination on mat1. */
for (i = 0; i < n; i++) {
int lindex;
double largest;
/* choose largest pivot */
for (j=i, largest = mat1[i * n + i], lindex = i; j < n; j++) {
if (fabs(mat1[j * n + i]) > largest) {
largest = fabs(mat1[j * n + i]);
lindex = j;
}
}
if (lindex != i) {
/* swap rows i and lindex */
for (k = 0; k < n; k++) {
d = mat1[i * n + k];
mat1[i * n + k] = mat1[lindex * n + k];
mat1[lindex * n + k] = d;
}
d = mat2[i];
mat2[i] = mat2[lindex];
mat2[lindex] = d;
}
#ifdef notdef
if (mat1[i * n + i] == 0.0)
for (j = i; j < n; j++)
if (mat1[j * n + i] != 0.0) {
/* Swap rows i and j. */
for (k = 0; k < n; k++) {
d = mat1[i * n + k];
mat1[i * n + k] =
mat1[j * n + k];
mat1[j * n + k] = d;
}
d = mat2[i];
mat2[i] = mat2[j];
mat2[j] = d;
break;
}
#endif
/* Make sure we have a non-zero pivot. */
if (mat1[i * n + i] == 0.0) {
/* this should be rotated. */
return (FALSE);
}
for (j = i + 1; j < n; j++) {
d = mat1[j * n + i] / mat1[i * n + i];
for (k = 0; k < n; k++)
mat1[j * n + k] -= d * mat1[i * n + k];
mat2[j] -= d * mat2[i];
}
}
for (i = n - 1; i > 0; i--)
for (j = i - 1; j >= 0; j--) {
d = mat1[j * n + i] / mat1[i * n + i];
for (k = 0; k < n; k++)
mat1[j * n + k] -=
d * mat1[i * n + k];
mat2[j] -= d * mat2[i];
}
/* Now write the stuff into the result vector. */
for (i = 0; i < n; i++) {
result[i] = mat2[i] / mat1[i * n + i];
/* printf(cp_err, "result[%d] = %G\n", i, result[i]);*/
}
#define ABS_TOL 0.001
#define REL_TOL 0.001
/* Let's check and make sure the coefficients are ok. If they aren't,
* just return FALSE. This is not the best way to do it.
*/
for (i = 0; i < n; i++) {
d = ft_peval(xdata[i], result, degree);
if (fabs(d - ydata[i]) > ABS_TOL) {
/*
fprintf(cp_err,
"Error: polyfit: x = %le, y = %le, int = %le\n",
xdata[i], ydata[i], d);
printmat("mat1", mat1, n, n);
printmat("mat2", mat2, n, 1);
*/
return (FALSE);
} else if (fabs(d - ydata[i]) / (fabs(d) > ABS_TOL ? fabs(d) :
ABS_TOL) > REL_TOL) {
/*
fprintf(cp_err,
"Error: polyfit: x = %le, y = %le, int = %le\n",
xdata[i], ydata[i], d);
printmat("mat1", mat1, n, n);
printmat("mat2", mat2, n, 1);
*/
return (FALSE);
}
}
return (TRUE);
}
/* Returns thestrchr of the last element that was calculated. oval is the
* value of the old scale at the end of the interval that is being interpolated
* from, and sign is 1 if the old scale was increasing, and -1 if it was
* decreasing.
*/
static int
putinterval(double *poly, int degree, double *nvec, int last, double *nscale, int nlen, double oval, int sign)
{
int end, i;
/* See how far we have to go. */
for (end = last + 1; end < nlen; end++)
if (nscale[end] * sign > oval * sign)
break;
end--;
for (i = last + 1; i <= end; i++)
nvec[i] = ft_peval(nscale[i], poly, degree);
return (end);
}
static void
printmat(char *name, double *mat, int m, int n)
{
int i, j;
printf("\n\r=== Matrix: %s ===\n\r", name);
for (i = 0; i < m; i++) {
printf(" | ");
for (j = 0; j < n; j++)
printf("%G ", mat[i * n + j]);
printf("|\n\r");
}
printf("===\n\r");
return;
}
double
ft_peval(double x, double *coeffs, int degree)
{
double y;
int i;
if (!coeffs)
return 0.0; /* XXX Should not happen */
y = coeffs[degree]; /* there are (degree+1) coeffs */
for (i = degree - 1; i >= 0; i--) {
y *= x;
y += coeffs[i];
}
return y;
}
#ifdef notdef
XXX The following code is rediculous
/* This should be a macro or be asm coded if possible. */
double
ft_peval(pt, coeffs, degree)
double pt, *coeffs;
register int degree;
{
register int i, j;
double d = 0.0, f;
/* fprintf(cp_err, "peval ");
for (i = 0; i <= degree; i++)
fprintf(cp_err, "%G ", coeffs[i]);
fprintf(cp_err, "at %G", pt);
*/
for (i = 0; i <= degree; i++) {
f = 1.0;
for (j = 0; j < i; j++)
f *= pt;
d += f * coeffs[i];
}
/* fprintf(cp_err, " = %G\n", d);*/
return (d);
}
#endif
void
lincopy(struct dvec *ov, double *newscale, int newlen, struct dvec *oldscale)
{
@ -374,12 +46,3 @@ lincopy(struct dvec *ov, double *newscale, int newlen, struct dvec *oldscale)
return;
}
void
ft_polyderiv(double *coeffs, int degree)
{
int i;
for (i = 0; i < degree; i++) {
coeffs[i] = (i + 1) * coeffs[i + 1];
}
}

View File

@ -6,7 +6,9 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
#include "ngspice.h"
#include "cpdefs.h"
#include "ftedefs.h"
#include "ftedata.h"
#include "dvec.h"
#include "circuits.h"
#include "linear.h"

View File

@ -6,234 +6,18 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
#include "ngspice.h"
#include "cpdefs.h"
#include "ftedefs.h"
#include "ftedata.h"
#include "dvec.h"
#include "ftehelp.h"
#include "hlpdefs.h"
#include "misccoms.h"
#include "circuits.h"
#include "hcomp.h"
#include "variable.h"
static void byemesg(void);
void
com_help(wordlist *wl)
{
struct comm *c;
struct comm *ccc[512]; /* Should be enough. */
int numcoms, i;
bool allflag = FALSE;
if (wl && eq(wl->wl_word, "all")) {
allflag = TRUE;
wl = NULL; /* XXX Probably right */
}
/* We want to use more mode whether "moremode" is set or not. */
out_moremode = TRUE;
out_init();
out_moremode = FALSE;
if (wl == NULL) {
out_printf(
"For a complete description read the Spice3 User's Manual manual.\n");
if (!allflag) {
out_printf(
"For a list of all commands type \"help all\", for a short\n");
out_printf(
"description of \"command\", type \"help command\".\n");
}
/* Sort the commands */
for (numcoms = 0; cp_coms[numcoms].co_func != NULL; numcoms++)
ccc[numcoms] = &cp_coms[numcoms];
qsort((char *) ccc, numcoms, sizeof (struct comm *), hcomp);
for (i = 0; i < numcoms; i++) {
if ((ccc[i]->co_spiceonly && ft_nutmeg) ||
(ccc[i]->co_help == NULL) ||
(!allflag && !ccc[i]->co_major))
continue;
out_printf("%s ", ccc[i]->co_comname);
out_printf(ccc[i]->co_help, cp_program);
out_send("\n");
}
} else {
while (wl != NULL) {
for (c = &cp_coms[0]; c->co_func != NULL; c++)
if (eq(wl->wl_word, c->co_comname)) {
out_printf("%s ", c->co_comname);
out_printf(c->co_help, cp_program);
if (c->co_spiceonly && ft_nutmeg)
out_send(
" (Not available in nutmeg)");
out_send("\n");
break;
}
if (c->co_func == NULL) {
/* See if this is aliased. */
struct alias *al;
for (al = cp_aliases; al; al = al->al_next)
if (eq(al->al_name, wl->wl_word))
break;
if (al == NULL)
fprintf(cp_out,
"Sorry, no help for %s.\n",
wl->wl_word);
else {
out_printf("%s is aliased to ",
wl->wl_word);
/* Minor badness here... */
wl_print(al->al_text, cp_out);
out_send("\n");
}
}
wl = wl->wl_next;
}
}
out_send("\n");
return;
}
void
com_ahelp(wordlist *wl)
{
int i, n;
/* assert: number of commands must be less than 512 */
struct comm *cc[512];
int env = 0;
struct comm *com;
int level;
char slevel[256];
if (wl) {
com_help(wl);
return;
}
out_init();
/* determine environment */
if (plot_list->pl_next) { /* plots load */
env |= E_HASPLOTS;
} else {
env |= E_NOPLOTS;
}
/* determine level */
if (cp_getvar("level", VT_STRING, slevel)) {
switch (*slevel) {
case 'b': level = 1;
break;
case 'i': level = 2;
break;
case 'a': level = 4;
break;
default: level = 1;
break;
}
} else {
level = 1;
}
out_printf(
"For a complete description read the Spice3 User's Manual manual.\n");
out_printf(
"For a list of all commands type \"help all\", for a short\n");
out_printf(
"description of \"command\", type \"help command\".\n");
/* sort the commands */
for (n = 0; cp_coms[n].co_func != (void (*)()) NULL; n++) {
cc[n] = &cp_coms[n];
}
qsort((char *) cc, n, sizeof(struct comm *), hcomp);
/* filter the commands */
for (i=0; i< n; i++) {
com = cc[i];
if ((com->co_env < (level << 13)) && (!(com->co_env & 4095) ||
(env & com->co_env))) {
if ((com->co_spiceonly && ft_nutmeg) ||
(com->co_help == (char *) NULL)) {
continue;
}
out_printf("%s ", com->co_comname);
out_printf(com->co_help, cp_program);
out_send("\n");
}
}
out_send("\n");
return;
}
void
com_ghelp(wordlist *wl)
{
char *npath, *path = Help_Path, buf[BSIZE_SP];
int i;
if (cp_getvar("helppath", VT_STRING, buf))
path = copy(buf);
if (!path) {
fprintf(cp_err, "Note: defaulting to old help.\n\n");
com_help(wl);
return;
}
if (!(npath = cp_tildexpand(path))) {
fprintf(cp_err, "Note: can't find help dir %s\n", path);
fprintf(cp_err, "Defaulting to old help.\n\n");
com_help(wl);
return;
}
path = npath;
if (cp_getvar("helpregfont", VT_STRING, buf))
hlp_regfontname = copy(buf);
if (cp_getvar("helpboldfont", VT_STRING, buf))
hlp_boldfontname = copy(buf);
if (cp_getvar("helpitalicfont", VT_STRING, buf))
hlp_italicfontname = copy(buf);
if (cp_getvar("helptitlefont", VT_STRING, buf))
hlp_titlefontname = copy(buf);
if (cp_getvar("helpbuttonfont", VT_STRING, buf))
hlp_buttonfontname = copy(buf);
if (cp_getvar("helpinitxpos", VT_NUM, (char *) &i))
hlp_initxpos = i;
if (cp_getvar("helpinitypos", VT_NUM, (char *) &i))
hlp_initypos = i;
if (cp_getvar("helpbuttonstyle", VT_STRING, buf)) {
if (cieq(buf, "left"))
hlp_buttonstyle = BS_LEFT;
else if (cieq(buf, "center"))
hlp_buttonstyle = BS_CENTER;
else if (cieq(buf, "unif"))
hlp_buttonstyle = BS_UNIF;
else
fprintf(cp_err, "Warning: no such button style %s\n",
buf);
}
if (cp_getvar("width", VT_NUM, (char *) &i))
hlp_width = i;
if (cp_getvar("display", VT_STRING, buf))
hlp_displayname = copy(buf);
else if (cp_getvar("device", VT_STRING, buf))
hlp_displayname = copy(buf);
else
hlp_displayname = NULL;
hlp_main(path, wl);
return;
}
int
hcomp(struct comm **c1, struct comm **c2)
{
return (strcmp((*c1)->co_comname, (*c2)->co_comname));
}
void
com_quit(wordlist *wl)
{
@ -302,11 +86,6 @@ com_quit(wordlist *wl)
#ifdef SYSTEM_MAIL
#define MAIL_BUGS_
#endif
#ifdef MAIL_BUGS_
void
com_bug(wordlist *wl)

View File

@ -9,7 +9,6 @@
void com_help(wordlist *wl);
void com_ahelp(wordlist *wl);
void com_ghelp(wordlist *wl);
int hcomp(struct comm **c1, struct comm **c2);
void com_quit(wordlist *wl);
void com_bug(wordlist *wl);
void com_version(wordlist *wl);

View File

@ -6,7 +6,7 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
#include "ngspice.h"
#include "cpdefs.h"
#include "ftedefs.h"
#include "ftedata.h"
#include "dvec.h"
#include "fteinp.h"
#include "miscvars.h"

View File

@ -7,9 +7,11 @@
#include "ftedefs.h"
#include "ftedev.h"
#include "ftedebug.h"
#include "ftedata.h"
#include "mw_coms.h"
#include "dvec.h"
#include "circuits.h"
#include "mw_coms.h"
#include "variable.h"
extern FILE *rawfileFp;
extern bool rawfileBinary;

View File

@ -10,9 +10,10 @@ Copyright 1992 Regents of the University of California. All rights reserved.
#include "cpdefs.h"
#include "ftedefs.h"
#include "fteparse.h"
#include "ftedata.h"
#include "newcoms.h"
#include "dvec.h"
#include "newcoms.h"
#include "quote.h"
/*
* reshape v(1) vxx#branch [10]

View File

@ -10,10 +10,11 @@ Author: 1985 Wayne A. Christopher
#include "ngspice.h"
#include "cpdefs.h"
#include "ftedefs.h"
#include "ftedata.h"
#include "dvec.h"
#include "fteinp.h"
#include "nutinp.h"
#include "nutinp.h"
#include "variable.h"
/* The routine to source a spice input deck. We read the deck in, take out
* the front-end commands, and create a CKT structure. Also we filter out
@ -28,8 +29,8 @@ void
inp_nutsource(FILE *fp, bool comfile, char *filename)
{
struct line *deck, *dd, *ld;
struct line *realdeck, *options;
char *tt, name[BSIZE_SP], *s, *t;
struct line *realdeck, *options = NULL;
char *tt = NULL, name[BSIZE_SP], *s, *t;
bool nosubckts, commands = FALSE;
wordlist *wl = NULL, *end = NULL;
wordlist *controls = NULL;

View File

@ -13,10 +13,12 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
#include "ngspice.h"
#include "cpdefs.h"
#include "ftedefs.h"
#include "ftedata.h"
#include "dvec.h"
#include "fteinp.h"
#include "options.h"
#include "circuits.h"
#include "options.h"
#include "variable.h"
/* static declarations */

View File

@ -1,6 +1,7 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1988 Wayne A. Christopher, U. C. Berkeley CAD Group
Modified: 2000 AlansFixes
**********/
/*
@ -13,17 +14,25 @@ Author: 1988 Wayne A. Christopher, U. C. Berkeley CAD Group
#include "ngspice.h"
#include "cpdefs.h"
#include "ftedefs.h"
#include "ftedata.h"
#include "fteconst.h"
#include "dvec.h"
#include "plot.h"
#include "sim.h"
#include "inpdefs.h" /* for INPtables */
#include "ifsim.h"
#include "jobdefs.h"
#include "iferrmsg.h"
#include "circuits.h"
#include "outitf.h"
#include "variable.h"
#include <fcntl.h>
#include <time.h>
#include "cktdefs.h"
#include <inpdefs.h>
extern void gr_end_iplot(void);
extern SPICEanalysis *analInfo[];
extern char *spice_analysis_get_name(int index);
extern char *spice_analysis_get_description(int index);
/* static declarations */
static int beginPlot(void *analysisPtr, void *circuitPtr, char *cktName, char *analName,
@ -47,16 +56,23 @@ static bool name_eq(char *n1, char *n2);
static bool getSpecial(dataDesc *desc, runDesc *run, IFvalue *val);
static void freeRun(runDesc *run);
/*Output data to spice module saj*/
#ifdef TCL_MODULE
#include "tclspice.h"
#endif
/*saj*/
#define DOUBLE_PRECISION 15
static clock_t lastclock, currclock;
static double *rowbuf;
static int column, rowbuflen;
static bool shouldstop = FALSE; /* Tell simulator to stop next time it asks. */
static bool printinfo = FALSE; /* Print informational "error messages". */
/* The two "begin plot" routines share all their internals... */
@ -66,22 +82,21 @@ extern bool ft_getOutReq (FILE **fpp, struct plot **plotp, bool *binp, char *nam
int
OUTpBeginPlot(void *circuitPtr, void *analysisPtr, IFuid analName, IFuid refName, int refType, int numNames, IFuid *dataNames, int dataType, void **plotPtr)
{
char *name;
char *name;
#ifdef PARALLEL_ARCH
if (ARCHme != 0) return(OK);
#endif /* PARALLEL_ARCH */
if (ft_curckt->ci_ckt == circuitPtr)
name = ft_curckt->ci_name;
else
name = "circuit name";
return (beginPlot(analysisPtr, circuitPtr, name,
(char *) analName, (char *) refName, refType, numNames,
(char **) dataNames, dataType, FALSE,
(runDesc **) plotPtr));
if (ft_curckt->ci_ckt == circuitPtr)
name = ft_curckt->ci_name;
else
name = "circuit name";
return (beginPlot(analysisPtr, circuitPtr, name,
(char *) analName, (char *) refName, refType, numNames,
(char **) dataNames, dataType, FALSE,
(runDesc **) plotPtr));
}
int
@ -102,12 +117,24 @@ beginPlot(void *analysisPtr, void *circuitPtr, char *cktName, char *analName, ch
{
runDesc *run;
struct save_info *saves;
bool *savesused;
bool *savesused = NULL;
int numsaves;
int i, j, depind;
int i, j, depind = 0;
char namebuf[BSIZE_SP], parambuf[BSIZE_SP], depbuf[BSIZE_SP];
bool saveall = TRUE;
char *ch, tmpname[BSIZE_SP];
bool saveall = TRUE;
bool savealli = FALSE;
char *an_name;
/*to resume a run saj
*All it does is reassign the file pointer and return (requires *runp to be NULL if this is not needed)
*/
if(dataType == 666 && numNames == 666){
run = *runp;
run->writeOut = ft_getOutReq(&run->fp, &run->runPlot, &run->binary,
run->type, run->name);
} else {
/*end saj*/
/* Check to see if we want to print informational data. */
if (cp_getvar("printinfo", VT_BOOL, (char *) &printinfo))
@ -123,7 +150,7 @@ beginPlot(void *analysisPtr, void *circuitPtr, char *cktName, char *analName, ch
run->windowed = windowed;
run->numData = 0;
an_name = analInfo[((JOB *) analysisPtr)->JOBtype]->public.name;
an_name = spice_analysis_get_name(((JOB *) analysisPtr)->JOBtype);
/* Now let's see which of these things we need. First toss in the
* reference vector. Then toss in anything that getSaves() tells
@ -135,17 +162,29 @@ beginPlot(void *analysisPtr, void *circuitPtr, char *cktName, char *analName, ch
savesused = (bool *) tmalloc(sizeof (bool) * numsaves);
saveall = FALSE;
for (i = 0; i < numsaves; i++) {
if (saves[i].analysis && !cieq(saves[i].analysis, an_name)) {
if (saves[i].analysis && !cieq((char *)saves[i].analysis, an_name)) {
/* ignore this one this time around */
savesused[i] = TRUE;
savesused[i] = TRUE;
continue;
}
if (cieq(saves[i].name, "all")) {
/* Check for ".save all" and new synonym ".save allv" */
if (cieq(saves[i].name, "all") || cieq(saves[i].name, "allv")) {
saveall = TRUE;
savesused[i] = TRUE;
saves[i].used = 1;
continue;
}
/* And now for the new ".save alli" option */
if (cieq(saves[i].name, "alli")) {
savealli = TRUE;
savesused[i] = TRUE;
saves[i].used = 1;
continue;
}
}
}
@ -179,10 +218,80 @@ beginPlot(void *analysisPtr, void *circuitPtr, char *cktName, char *analName, ch
} else {
for (i = 0; i < numNames; i++)
if (!refName || !name_eq(dataNames[i], refName)) {
addDataDesc(run, dataNames[i], dataType, i);
/* Save the node as long as it's an internal device node */
if (!strstr(dataNames[i], "#internal") &&
!strstr(dataNames[i], "#source") &&
!strstr(dataNames[i], "#drain") &&
!strstr(dataNames[i], "#collector") &&
!strstr(dataNames[i], "#emitter") &&
!strstr(dataNames[i], "#base")) {
addDataDesc(run, dataNames[i], dataType, i);
}
}
}
/* Pass 1 and a bit.
This is a new pass which searches for all the internal device
nodes, and saves the terminal currents instead */
if (savealli) {
depind=0;
for (i = 0; i < numNames; i++) {
if (strstr(dataNames[i], "#internal") ||
strstr(dataNames[i], "#source") ||
strstr(dataNames[i], "#drain") ||
strstr(dataNames[i], "#collector") ||
strstr(dataNames[i], "#emitter") ||
strstr(dataNames[i], "#base")) {
tmpname[0]='@';
tmpname[1]='\0';
strncat(tmpname, dataNames[i], BSIZE_SP-1);
ch=strchr(tmpname, '#');
if (strstr(ch, "#collector")!=NULL) {
strcpy(ch, "[ic]");
} else if (strstr(ch, "#base")!=NULL) {
strcpy(ch, "[ib]");
} else if (strstr(ch, "#emitter")!=NULL) {
strcpy(ch, "[ie]");
if (parseSpecial(tmpname, namebuf, parambuf, depbuf)) {
addSpecialDesc(run, tmpname, namebuf, parambuf, depind);
};
strcpy(ch, "[is]");
} else if (strstr(ch, "#drain")!=NULL) {
strcpy(ch, "[id]");
if (parseSpecial(tmpname, namebuf, parambuf, depbuf)) {
addSpecialDesc(run, tmpname, namebuf, parambuf, depind);
};
strcpy(ch, "[ig]");
} else if (strstr(ch, "#source")!=NULL) {
strcpy(ch, "[is]");
if (parseSpecial(tmpname, namebuf, parambuf, depbuf)) {
addSpecialDesc(run, tmpname, namebuf, parambuf, depind);
};
strcpy(ch, "[ib]");
} else
if ((strstr(ch, "#internal")!=NULL)&&(tmpname[1]=='d')) {
strcpy(ch, "[id]");
} else {
fprintf(cp_err,
"Debug: could output current for %s\n", tmpname);
continue;
};
if (parseSpecial(tmpname, namebuf, parambuf, depbuf)) {
if (*depbuf) { fprintf( stderr,
"Warning : unexpected dependant variable on %s\n", tmpname);
} else {
addSpecialDesc(run, tmpname, namebuf, parambuf, depind);
}
}
}
}
}
/* Pass 2. */
for (i = 0; i < numsaves; i++) {
if (savesused[i])
@ -227,14 +336,14 @@ beginPlot(void *analysisPtr, void *circuitPtr, char *cktName, char *analName, ch
tfree(savesused);
}
if (numNames
&& (run->numData == 1
&& (run->refIndex != -1
|| run->numData == 0)
&& run->refIndex == -1))
if (numNames &&
(run->numData == 1
&& run->refIndex != -1
|| run->numData == 0
&& run->refIndex == -1))
{
fprintf(cp_err, "Error: no data saved for %s; analysis not run\n",
analInfo[((JOB *) analysisPtr)->JOBtype]->public.description);
spice_analysis_get_description(((JOB *) analysisPtr)->JOBtype));
return E_NOTFOUND;
}
@ -252,6 +361,12 @@ beginPlot(void *analysisPtr, void *circuitPtr, char *cktName, char *analName, ch
run->runPlot->pl_ndims = 1;
}
/*Start BLT, initilises the blt vectors saj*/
#ifdef TCL_MODULE
blt_init(run);
#endif
}
/*end saj*/
return (OK);
}
@ -320,7 +435,6 @@ addSpecialDesc(runDesc *run, char *name, char *devname, char *param, int depind)
return (OK);
}
int
OUTpData(void *plotPtr, IFvalue *refValue, IFvalue *valuePtr)
@ -333,23 +447,48 @@ OUTpData(void *plotPtr, IFvalue *refValue, IFvalue *valuePtr)
#endif /* PARALLEL_ARCH */
run->pointCount++;
#ifdef TCL_MODULE
steps_completed = run->pointCount;
#endif
if (run->writeOut) {
if (run->pointCount == 1)
fileInit_pass2(plotPtr);
fileStartPoint(run->fp, run->binary, run->pointCount);
if (run->refIndex != -1) {
if (run->isComplex)
if (run->isComplex){
fileAddComplexValue(run->fp, run->binary, refValue->cValue);
else
fileAddRealValue(run->fp, run->binary, refValue->rValue);
}
/* While we're looking at the reference value, print it to the screen
every quarter of a second, to give some feedback without using
too much CPU time */
currclock = clock();
if ((currclock-lastclock)>(0.25*CLOCKS_PER_SEC)) {
fprintf(stderr, " Reference value : % 12.5e\r",
refValue->cValue.real);
lastclock = currclock;
}
} else {
/* And the same for a non-complex value */
fileAddRealValue(run->fp, run->binary, refValue->rValue);
currclock = clock();
if ((currclock-lastclock)>(0.25*CLOCKS_PER_SEC)) {
fprintf(stderr, " Reference value : % 12.5e\r", refValue->rValue);
lastclock = currclock;
}
}
}
for (i = 0; i < run->numData; i++) {
/* we've already printed reference vec first */
if (run->data[i].outIndex == -1) continue;
if (run->data[i].outIndex == -1){
#ifdef TCL_MODULE
blt_add(i,refValue->rValue);
#endif
continue;
}
if (run->data[i].regular) {
if(run->data[i].type == IF_REAL)
fileAddRealValue(run->fp, run->binary,
@ -364,7 +503,27 @@ OUTpData(void *plotPtr, IFvalue *refValue, IFvalue *valuePtr)
} else {
/* should pre-check instance */
if (!getSpecial(&run->data[i], run, &val))
{
/* If this is the first data point, print a warning for any unrecognized
variables, since this has not already been checked */
if (run->pointCount==1)
fprintf(stderr, "Warning: unrecognized variable - %s\n",
run->data[i].name);
if (run->isComplex) {
val.cValue.real=0;
val.cValue.imag=0;
fileAddComplexValue(run->fp, run->binary,
val.cValue);
} else {
val.rValue=0;
fileAddRealValue(run->fp, run->binary,
val.rValue);
};
continue;
};
if (run->data[i].type == IF_REAL)
fileAddRealValue(run->fp, run->binary,
val.rValue);
@ -374,50 +533,88 @@ OUTpData(void *plotPtr, IFvalue *refValue, IFvalue *valuePtr)
else
fprintf(stderr, "OUTpData: unsupported data type\n");
}
#ifdef TCL_MODULE
blt_add(i,valuePtr->v.vec.rVec
[run->data[i].outIndex]);
#endif
}
fileEndPoint(run->fp, run->binary);
/* Check that the write to disk completed successfully, otherwise abort */
if (ferror(run->fp)) {
fprintf(stderr, "Warning: rawfile write error !!\n");
shouldstop = TRUE;
};
} else {
for (i = 0; i < run->numData; i++) {
if (run->data[i].outIndex == -1) {
if (run->data[i].type == IF_REAL)
plotAddRealValue(&run->data[i],
/* This is interactive mode. Update the screen with the reference
variable just the same */
currclock = clock();
if ((currclock-lastclock)>(0.25*CLOCKS_PER_SEC)) {
if (run->isComplex) {
fprintf(stderr, " Reference value : % 12.5e\r",
refValue->cValue.real);
} else {
fprintf(stderr, " Reference value : % 12.5e\r",
refValue->rValue);
else if (run->data[i].type == IF_COMPLEX)
plotAddComplexValue(&run->data[i],
refValue->cValue);
}
lastclock = currclock;
}
for (i = 0; i < run->numData; i++) {
#ifdef TCL_MODULE
/*Locks the blt vector to stop access*/
blt_lockvec(i);
#endif
if (run->data[i].outIndex == -1) {
if (run->data[i].type == IF_REAL)
plotAddRealValue(&run->data[i],
refValue->rValue);
else if (run->data[i].type == IF_COMPLEX)
plotAddComplexValue(&run->data[i],
refValue->cValue);
} else if (run->data[i].regular) {
if (run->data[i].type == IF_REAL)
plotAddRealValue(&run->data[i],
valuePtr->v.vec.rVec
[run->data[i].outIndex]);
else if (run->data[i].type == IF_COMPLEX)
plotAddComplexValue(&run->data[i],
valuePtr->v.vec.cVec
[run->data[i].outIndex]);
if (run->data[i].type == IF_REAL)
plotAddRealValue(&run->data[i],
valuePtr->v.vec.rVec
[run->data[i].outIndex]);
else if (run->data[i].type == IF_COMPLEX)
plotAddComplexValue(&run->data[i],
valuePtr->v.vec.cVec
[run->data[i].outIndex]);
} else {
/* should pre-check instance */
if (!getSpecial(&run->data[i], run, &val))
continue;
if (run->data[i].type == IF_REAL)
plotAddRealValue(&run->data[i],
val.rValue);
else if (run->data[i].type == IF_COMPLEX)
plotAddComplexValue(&run->data[i],
/* should pre-check instance */
if (!getSpecial(&run->data[i], run, &val))
continue;
if (run->data[i].type == IF_REAL)
plotAddRealValue(&run->data[i],
val.rValue);
else if (run->data[i].type == IF_COMPLEX)
plotAddComplexValue(&run->data[i],
val.cValue);
else
fprintf(stderr, "OUTpData: unsupported data type\n");
else
fprintf(stderr, "OUTpData: unsupported data type\n");
}
#ifdef TCL_MODULE
/*relinks and unlocks vector*/
blt_relink(i,(run->data[i]).vec);
#endif
}
gr_iplot(run->runPlot);
}
if (ft_bpcheck(run->runPlot, run->pointCount) == FALSE)
shouldstop = TRUE;
shouldstop = TRUE;
#ifdef TCL_MODULE
Tcl_ExecutePerLoop();
#endif
return (OK);
}
/* ARGSUSED */ /* until some code gets written */
int
@ -526,6 +723,8 @@ fileInit(runDesc *run)
{
char buf[513];
int i;
lastclock = clock();
/* This is a hack. */
run->isComplex = FALSE;
@ -551,15 +750,17 @@ fileInit(runDesc *run)
fputs(buf, run->fp);
sprintf(buf, "No. Points: ");
i += strlen(buf);
fputs(buf, run->fp);
fputs(buf, run->fp);
fflush(run->fp); /* Gotta do this for LATTICE. */
if (run->fp == stdout || (run->pointPos = ftell(run->fp)) <= 0)
run->pointPos = i;
run->pointPos = i;
fprintf(run->fp, "0 \n"); /* Save 8 spaces here. */
fprintf(run->fp, "Command: version %s\n", ft_sim->version);
fprintf(run->fp, "Variables:\n");
fprintf(run->fp, "Variables:\n");
fprintf(stderr, "No. of Data Columns : %d \n", run->numData);
return;
}
@ -571,6 +772,7 @@ fileInit_pass2(runDesc *run)
char *name, buf[BSIZE_SP];
for (i = 0; i < run->numData; i++) {
if (isdigit(*run->data[i].name)) {
(void) sprintf(buf, "V(%s)", run->data[i].name);
name = buf;
@ -583,20 +785,31 @@ fileInit_pass2(runDesc *run)
type = SV_TIME;
else if (cieq(name, "frequency"))
type = SV_FREQUENCY;
else
else
type = SV_VOLTAGE;
fprintf(run->fp, "\t%d\t%s\t%s", i, name,
ft_typenames(type));
if (run->data[i].gtype == GRID_XLOG)
fprintf(run->fp, "\tgrid=3");
fprintf(run->fp, "\n");
if (run->data[i].gtype == GRID_XLOG)
fprintf(run->fp, "\tgrid=3");
fprintf(run->fp, "\n");
}
fprintf(run->fp, "%s:\n", run->binary ? "Binary" : "Values");
fprintf(run->fp, "%s:\n", run->binary ? "Binary" : "Values");
fflush(run->fp); /* Make all sure this gets to disk */
/* Allocate Row buffer */
if (run->binary) {
rowbuflen=(run->numData)*sizeof(double);
if (run->isComplex) rowbuflen *=2;
rowbuf=(double *)tmalloc(rowbuflen);
} else rowbuf=NULL;
return;
}
static void
@ -604,6 +817,10 @@ fileStartPoint(FILE *fp, bool bin, int num)
{
if (!bin)
fprintf(fp, "%d\t", num - 1);
/* reset buffer pointer to zero */
column = 0;
return;
}
@ -612,11 +829,11 @@ static void
fileAddRealValue(FILE *fp, bool bin, double value)
{
if (bin)
fwrite((char *) &value, sizeof (double), 1, fp);
rowbuf[column++]=value;
else
fprintf(fp, "\t%.*e\n", DOUBLE_PRECISION, value);
return;
fprintf(fp, "\t%.*e\n", DOUBLE_PRECISION, value);
return;
}
static void
@ -624,8 +841,8 @@ fileAddComplexValue(FILE *fp, bool bin, IFcomplex value)
{
if (bin) {
fwrite((char *) &value.real, sizeof (double), 1, fp);
fwrite((char *) &value.imag, sizeof (double), 1, fp);
rowbuf[column++]=value.real;
rowbuf[column++]=value.imag;
} else {
fprintf(fp, "\t%.*e,%.*e\n", DOUBLE_PRECISION, value.real,
DOUBLE_PRECISION, value.imag);
@ -637,7 +854,11 @@ fileAddComplexValue(FILE *fp, bool bin, IFcomplex value)
static void
fileEndPoint(FILE *fp, bool bin)
{
return;
if (bin) {
/* write row buffer to file */
fwrite((char *)rowbuf, rowbuflen, 1, fp);
}; /* otherwise the data has already been written */
return;
}
/* Here's the hack... Run back and fill in the number of points. */
@ -650,7 +871,8 @@ fileEnd(runDesc *run)
if (run->fp != stdout) {
place = ftell(run->fp);
fseek(run->fp, run->pointPos, 0);
fprintf(run->fp, "%d", run->pointCount);
fprintf(run->fp, "%d", run->pointCount);
fprintf(stderr, "\nNo. of Data Rows : %d\n", run->pointCount);
fseek(run->fp, place, 0);
} else {
/* Yet another hack-around */
@ -658,6 +880,11 @@ fileEnd(runDesc *run)
}
fflush(run->fp);
if (run->binary) {
/* deallocate row buffer */
tfree(rowbuf);
}
return;
}
@ -761,7 +988,7 @@ plotAddComplexValue(dataDesc *desc, IFcomplex value)
static void
plotEnd(runDesc *run)
{
fprintf(stderr, "\nNo. of Data Rows : %d\n", run->pointCount);
return;
}
@ -779,7 +1006,7 @@ parseSpecial(char *name, char *dev, char *param, char *ind)
*dev = *param = *ind = '\0';
if (*name != '@')
return (FALSE);
return FALSE;
name++;
s = dev;
@ -787,7 +1014,7 @@ parseSpecial(char *name, char *dev, char *param, char *ind)
*s++ = *name++;
*s = '\0';
if (!*name)
return (TRUE);
return TRUE;
name++;
s = param;
@ -797,7 +1024,7 @@ parseSpecial(char *name, char *dev, char *param, char *ind)
if (*name == ']')
return (!name[1] ? TRUE : FALSE);
else if (!*name)
return (FALSE);
return FALSE;
name++;
s = ind;
@ -805,9 +1032,9 @@ parseSpecial(char *name, char *dev, char *param, char *ind)
*s++ = *name++;
*s = '\0';
if (*name && !name[1])
return (TRUE);
return TRUE;
else
return (FALSE);
return FALSE;
}
/* This routine must match two names with or without a V() around them. */
@ -820,14 +1047,14 @@ name_eq(char *n1, char *n2)
if ((s =strchr(n1, '('))) {
strcpy(buf1, s);
if (!(s =strchr(buf1, ')')))
return (FALSE);
return FALSE;
*s = '\0';
n1 = buf1;
}
if ((s =strchr(n2, '('))) {
strcpy(buf2, s);
if (!(s =strchr(buf2, ')')))
return (FALSE);
return FALSE;
*s = '\0';
n2 = buf2;
}
@ -846,7 +1073,7 @@ getSpecial(dataDesc *desc, runDesc *run, IFvalue *val)
desc->specName, &desc->specFast, ft_sim, &desc->type,
&selector) == OK) {
desc->type &= (IF_REAL | IF_COMPLEX); /* mask out other bits */
return(TRUE);
return TRUE;
} else if ((vv = if_getstat(run->circuit, &desc->name[1]))) {
/* skip @ sign */
desc->type = IF_REAL;
@ -857,13 +1084,13 @@ getSpecial(dataDesc *desc, runDesc *run, IFvalue *val)
else if (vv->va_type == VT_BOOL)
val->rValue = (vv->va_bool ? 1.0 : 0.0);
else {
return (FALSE); /* not a real */
return FALSE; /* not a real */
}
tfree(vv);
return(TRUE);
return TRUE;
}
return (FALSE);
return FALSE;
}
static void
@ -873,17 +1100,14 @@ freeRun(runDesc *run)
int i;
for (i=0; i < run->numData; i++) {
/* vec_free(run->data[i].vec); */ /* kill run, leave plot */
tfree(run->data[i].name);
tfree(run->data[i].specParamName);
}
tfree(run->data);
/* killplot(run->runPlot); */ /* kill run, leave plot */
free(run->type);
free(run->name);
free(run);
tfree(run->type);
tfree(run->name);
tfree(run);
}

View File

@ -8,12 +8,12 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
* This also handles relational and logical expressions.
*/
#include "ngspice.h"
#include "cpdefs.h"
#include "ftedefs.h"
#include "fteparse.h"
#include "ftedata.h"
#include "ftecmath.h"
#include <ngspice.h>
#include <bool.h>
#include <fteparse.h>
#include <fteext.h>
#include <sim.h>
#include "parse.h"
@ -598,8 +598,15 @@ struct func ft_funcs[] = {
{ "vector", cx_vector } ,
{ "unitvec", cx_unitvec } ,
{ "length", cx_length } ,
{ "vecmin", cx_min } ,
{ "vecmax", cx_max } ,
{ "vecd", cx_d } ,
#if 0
/* These functions have been temporarily been disabled. See
their definitions for the reason. */
{ "interpolate",cx_interpolate } ,
{ "deriv", cx_deriv } ,
#endif
{ "v", NULL } ,
{ NULL, NULL }
} ;

View File

@ -3,8 +3,11 @@
* 1999 E. Rouat
************/
#ifndef PARSE_H_INCLUDED
#define PARSE_H_INCLUDED
#ifndef _PARSE_H
#define _PARSE_H
#include <pnode.h>
#include <wordlist.h>
struct pnode * ft_getpnames(wordlist *wl, bool check);
void free_pnode(struct pnode *t);

View File

@ -3,19 +3,19 @@ Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
**********/
#include "ngspice.h"
#include "cpdefs.h"
#include "ftedefs.h"
#include "ftedata.h"
#include "ftegraph.h"
#include "ftedbgra.h"
#include <ngspice.h>
#include <cpdefs.h>
#include <ftedefs.h>
#include <dvec.h>
#include <graph.h>
#include <ftedbgra.h>
#include "points.h"
/* Returns the minimum and maximum values of a dvec. Returns a pointer to
* static data. If real is TRUE look at the real parts, otherwise the imag
* parts.
*/
/* Returns the minimum and maximum values of a dvec. Returns a pointer
* to static data. If real is TRUE look at the real parts, otherwise
* the imag parts. */

View File

@ -7,256 +7,22 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
* Various post-processor commands having to do with vectors.
*/
#include "ngspice.h"
#include "cpdefs.h"
#include "ftedefs.h"
#include "fteparse.h"
#include "ftedata.h"
#include "postcoms.h"
#include <ngspice.h>
#include <cpdefs.h>
#include <ftedefs.h>
#include <dvec.h>
#include <sim.h>
#include <plot.h>
#include "completion.h"
#include "postcoms.h"
#include "quote.h"
#include "variable.h"
/* static declarations */
static void pvec(struct dvec *d);
static int dcomp(struct dvec **v1, struct dvec **v2);
static void killplot(struct plot *pl);
void
com_let(wordlist *wl)
{
char *p, *q, *s;
int indices[MAXDIMS];
int numdims;
wordlist fake_wl;
int need_open;
int offset, length;
struct pnode *nn;
struct dvec *n, *t;
int i, cube;
int depth;
int newvec;
char *rhs;
fake_wl.wl_next = NULL;
if (!wl) {
com_display((wordlist *) NULL);
return;
}
p = wl_flatten(wl);
/* extract indices */
numdims = 0;
if ((rhs =strchr(p, '='))) {
*rhs++ = 0;
} else {
fprintf(cp_err, "Error: bad let syntax\n");
return;
}
if ((s =strchr(p, '['))) {
need_open = 0;
*s++ = 0;
while (!need_open || *s == '[') {
depth = 0;
if (need_open)
s++;
for (q = s; *q && (*q != ']' && (*q != ',' || depth > 0)); q++) {
switch (*q) {
case '[':
depth += 1;
break;
case ']':
depth -= 1;
break;
}
}
if (depth != 0 || !*q) {
printf("syntax error specifyingstrchr\n");
return;
}
if (*q == ']')
need_open = 1;
else
need_open = 0;
if (*q)
*q++ = 0;
/* MW. let[x,y] is not supported - we don't need this code
* evaluate expression between s and q
fake_wl.wl_word = s;
nn = ft_getpnames(&fake_wl, TRUE);
t = ft_evaluate(nn);
free_pnode(nn);
if (!t) {
fprintf(cp_err, "Error: badstrchr.\n"); // MW. When t == NULL something is wrong
tfree(p);
return;
}
if (!isreal(t) || t->v_link2 || t->v_length != 1 || !t->v_realdata)
{
fprintf(cp_err, "Error:strchr is not a scalar.\n");
tfree(p);
return;
}
j = t->v_realdata[0];
* ignore sanity checks for now
if (j < 0) {
printf("negativestrchr (%d) is not allowed\n", j);
tfree(p);
return;
}
indices[numdims++] = j;
* MW. Next line does not hurt. I don't know what it is doing
*/
for (s = q; *s && isspace(*s); s++)
;
}
}
/* vector name at p */
for (q = p + strlen(p) - 1; *q <= ' ' && p <= q; q--)
;
*++q = 0;
/* sanity check */
if (eq(p, "all") ||strchr(p, '@')) {
fprintf(cp_err, "Error: bad variable name %s\n", p);
return;
}
/* evaluate rhs */
fake_wl.wl_word = rhs;
nn = ft_getpnames(&fake_wl, TRUE);
if (nn == NULL) {
/* XXX error message */
tfree(p);
return;
}
t = ft_evaluate(nn);
if (!t) {
fprintf(cp_err, "Error: Can't evaluate %s\n", rhs);
tfree(p);
return;
}
if (t->v_link2)
fprintf(cp_err, "Warning: extra wildcard values ignored\n");
n = vec_get(p);
if (n) {
/* re-allocate? */
/* vec_free(n); */
newvec = 0;
} else {
if (numdims) {
fprintf(cp_err, "Can't assign into a subindex of a new vector\n");
tfree(p);
return;
}
/* create and assign a new vector */
n = alloc(struct dvec);
ZERO(n, struct dvec);
n->v_name = copy(p);
n->v_type = t->v_type;
n->v_flags = (t->v_flags | VF_PERMANENT);
n->v_length = t->v_length;
if (!t->v_numdims) {
n->v_numdims = 1;
n->v_dims[0] = n->v_length;
} else {
n->v_numdims = t->v_numdims;
for (i = 0; i < t->v_numdims; i++)
n->v_dims[i] = t->v_dims[i];
}
if (isreal(t))
n->v_realdata = (double *) tmalloc(n->v_length * sizeof(double));
else
n->v_compdata = (complex *) tmalloc(n->v_length * sizeof(complex));
newvec = 1;
vec_new(n);
}
/* fix-up dimensions */
if (n->v_numdims < 1) {
n->v_numdims = 1;
n->v_dims[0] = n->v_length;
}
/* Compare dimensions */
offset = 0;
length = n->v_length;
cube = 1;
for (i = n->v_numdims - 1; i >= numdims; i--)
cube *= n->v_dims[i];
for (i = numdims - 1; i >= 0; i--) {
offset += cube * indices[i];
if (i < n->v_numdims) {
cube *= n->v_dims[i];
length /= n->v_dims[i];
}
}
/* length is the size of the unit refered to */
/* cube ends up being the length */
if (length > t->v_length) {
fprintf(cp_err, "left-hand expression is too small (need %d)\n",
length * cube);
if (newvec)
n->v_flags &= ~VF_PERMANENT;
tfree(p);
return;
}
if (isreal(t) != isreal(n)) {
fprintf(cp_err,
"Types of vectors are not the same (real vs. complex)\n");
if (newvec)
n->v_flags &= ~VF_PERMANENT;
tfree(p);
return;
} else if (isreal(t)) {
bcopy((char *) t->v_realdata, (char *) (n->v_realdata + offset),
length * sizeof (double));
} else {
bcopy((char *) t->v_compdata, (char *) (n->v_compdata + offset),
length * sizeof (complex));
}
n->v_minsignal = 0.0; /* How do these get reset ??? */
n->v_maxsignal = 0.0;
n->v_scale = t->v_scale;
if (newvec)
cp_addkword(CT_VECTOR, n->v_name);
/* XXXX Free t !?! */
tfree(p);
return;
}
/* Undefine vectors. */
void
@ -274,12 +40,15 @@ com_unlet(wordlist *wl)
void
com_load(wordlist *wl)
{
char *copypath;
if (!wl)
ft_loadfile(ft_rawfile);
else
while (wl) {
ft_loadfile(cp_unquote(wl->wl_word));
/*ft_loadfile(cp_unquote(wl->wl_word)); DG: bad memory leak*/
copypath=cp_unquote(wl->wl_word);/*DG*/
ft_loadfile(copypath);
tfree(copypath);
wl = wl->wl_next;
}
@ -298,17 +67,19 @@ com_load(wordlist *wl)
void
com_print(wordlist *wl)
{
struct dvec *v, *lv, *bv, *nv, *vecs = NULL;
struct dvec *v, *lv = NULL, *bv, *nv, *vecs = NULL;
int i, j, ll, width = DEF_WIDTH, height = DEF_HEIGHT, npoints, lineno;
struct pnode *nn;
struct plot *p;
bool col = TRUE, nobreak = FALSE, noprintscale, plotnames = FALSE;
bool optgiven = FALSE;
char *s, buf[BSIZE_SP], buf2[BSIZE_SP];
char numbuf[BSIZE_SP], numbuf2[BSIZE_SP]; /* Printnum buffers */
int ngood;
if (wl == NULL)
return;
if (eq(wl->wl_word, "col")) {
col = TRUE;
optgiven = TRUE;
@ -371,19 +142,30 @@ com_print(wordlist *wl)
ll = 10;
if (v->v_length == 1) {
if (isreal(v)) {
out_printf("%s = %s\n", buf,
printnum(*v->v_realdata));
printnum(numbuf, *v->v_realdata);
out_printf("%s = %s\n", buf, numbuf);
} else {
/*DG: memory leak here copy of the string returned by printnum will never be freed
out_printf("%s = %s,%s\n", buf,
copy(printnum(realpart(v->v_compdata))),
copy(printnum(imagpart(v->v_compdata))));
copy(printnum(imagpart(v->v_compdata)))); */
printnum(numbuf, realpart(v->v_compdata));
printnum(numbuf2, imagpart(v->v_compdata));
out_printf("%s = %s,%s\n", buf,
numbuf,
numbuf2);
}
} else {
out_printf("%s = ( ", buf);
for (i = 0; i < v->v_length; i++)
if (isreal(v)) {
(void) strcpy(buf,
printnum(v->v_realdata[i]));
printnum(numbuf, v->v_realdata[i]);
(void) strcpy(buf, numbuf);
out_send(buf);
ll += strlen(buf);
ll = (ll + 7) / 8;
@ -394,9 +176,12 @@ com_print(wordlist *wl)
} else
out_send("\t");
} else {
/*DG*/
printnum(numbuf, realpart(&v->v_compdata[i]));
printnum(numbuf2, imagpart(&v->v_compdata[i]));
(void) sprintf(buf, "%s,%s",
copy(printnum(realpart(&v->v_compdata[i]))),
copy(printnum(imagpart(&v->v_compdata[i]))));
numbuf,
numbuf2);
out_send(buf);
ll += strlen(buf);
ll = (ll + 7) / 8;
@ -694,6 +479,7 @@ com_transpose(wordlist *wl)
while (wl) {
s = cp_unquote(wl->wl_word);
d = vec_get(s);
tfree(s); /*DG: Avoid Memory Leak */
if (d == NULL)
fprintf(cp_err, "Error: no such vector as %s.\n",
wl->wl_word);
@ -708,259 +494,7 @@ com_transpose(wordlist *wl)
}
}
/* Set the default scale to the named vector. If no vector named,
* find and print the default scale.
*/
void
com_setscale(wordlist *wl)
{
struct dvec *d;
char *s;
if (plot_cur) {
if (wl) {
s = cp_unquote(wl->wl_word);
d = vec_get(s);
if (d == NULL)
fprintf(cp_err, "Error: no such vector as %s.\n",
wl->wl_word);
else
plot_cur->pl_scale = d;
} else if (plot_cur->pl_scale) {
pvec(plot_cur->pl_scale);
}
} else {
fprintf(cp_err, "Error: no current plot.\n");
}
}
/* Display vector status, etc. Note that this only displays stuff from the
* current plot, and you must do a setplot to see the rest of it.
*/
void
com_display(wordlist *wl)
{
struct dvec *d;
struct dvec **dvs;
int len = 0, i = 0;
bool b;
char *s;
/* Maybe he wants to know about just a few vectors. */
out_init();
while (wl) {
s = cp_unquote(wl->wl_word);
d = vec_get(s);
if (d == NULL)
fprintf(cp_err, "Error: no such vector as %s.\n",
wl->wl_word);
else
while (d) {
pvec(d);
d = d->v_link2;
}
if (wl->wl_next == NULL)
return;
wl = wl->wl_next;
}
if (plot_cur)
for (d = plot_cur->pl_dvecs; d; d = d->v_next)
len++;
if (len == 0) {
fprintf(cp_out, "There are no vectors currently active.\n");
return;
}
out_printf("Here are the vectors currently active:\n\n");
dvs = (struct dvec **) tmalloc(len * (sizeof (struct dvec *)));
for (d = plot_cur->pl_dvecs, i = 0; d; d = d->v_next, i++)
dvs[i] = d;
if (!cp_getvar("nosort", VT_BOOL, (char *) &b))
qsort((char *) dvs, len, sizeof (struct dvec *), dcomp);
out_printf("Title: %s\n", plot_cur->pl_title);
out_printf("Name: %s (%s)\nDate: %s\n\n",
plot_cur->pl_typename, plot_cur->pl_name,
plot_cur->pl_date);
for (i = 0; i < len; i++) {
d = dvs[i];
pvec(d);
}
return;
}
static void
pvec(struct dvec *d)
{
char buf[BSIZE_SP], buf2[BSIZE_SP];
sprintf(buf, " %-20s: %s, %s, %d long", d->v_name,
ft_typenames(d->v_type), isreal(d) ? "real" :
"complex", d->v_length);
if (d->v_flags & VF_MINGIVEN) {
sprintf(buf2, ", min = %g", d->v_minsignal);
strcat(buf, buf2);
}
if (d->v_flags & VF_MAXGIVEN) {
sprintf(buf2, ", max = %g", d->v_maxsignal);
strcat(buf, buf2);
}
switch (d->v_gridtype) {
case GRID_LOGLOG:
strcat(buf, ", grid = loglog");
break;
case GRID_XLOG:
strcat(buf, ", grid = xlog");
break;
case GRID_YLOG:
strcat(buf, ", grid = ylog");
break;
case GRID_POLAR:
strcat(buf, ", grid = polar");
break;
case GRID_SMITH:
strcat(buf, ", grid = smith (xformed)");
break;
case GRID_SMITHGRID:
strcat(buf, ", grid = smithgrid (not xformed)");
break;
}
switch (d->v_plottype) {
case PLOT_COMB:
strcat(buf, ", plot = comb");
break;
case PLOT_POINT:
strcat(buf, ", plot = point");
break;
}
if (d->v_defcolor) {
sprintf(buf2, ", color = %s", d->v_defcolor);
strcat(buf, buf2);
}
if (d->v_scale) {
sprintf(buf2, ", scale = %s", d->v_scale->v_name);
strcat(buf, buf2);
}
if (d->v_numdims > 1) {
sprintf(buf2, ", dims = [%s]", dimstring(d->v_dims, d->v_numdims));
strcat(buf, buf2);
}
if (d->v_plot->pl_scale == d) {
strcat(buf, " [default scale]\n");
} else {
strcat(buf, "\n");
}
out_send(buf);
return;
}
#ifdef notdef
/* Set the current working plot. */
void
com_splot(wl)
wordlist *wl;
{
struct plot *p;
char buf[BSIZE_SP], *s;
if (wl == NULL) {
fprintf(cp_out, "\tType the name of the desired plot:\n\n");
fprintf(cp_out, "\tnew\tNew plot\n");
for (p = plot_list; p; p = p->pl_next) {
if (plot_cur == p)
fprintf(cp_out, "Current");
fprintf(cp_out, "\t%s\t%s (%s)\n",
p->pl_typename, p->pl_title, p->pl_name);
}
fprintf(cp_out, "? ");
(void) fflush(cp_out);
(void) fgets(buf, BSIZE_SP, cp_in);
clearerr(cp_in);
for (s = buf; *s && !isspace(*s); s++)
;
*s = '\0';
} else {
(void) strcpy(buf, wl->wl_word);
}
if (prefix("new", buf)) {
p = plot_alloc("unknown");
p->pl_title = copy("Anonymous");
p->pl_name = copy("unknown");
p->pl_next = plot_list;
plot_list = p;
} else {
for (p = plot_list; p; p = p->pl_next)
if (plot_prefix(buf, p->pl_typename))
break;
if (!p) {
fprintf(cp_err, "Error: no such plot.\n");
return;
}
}
plot_cur->pl_ccom = cp_kwswitch(CT_VECTOR, p->pl_ccom);
plot_cur = p;
plot_docoms(plot_cur->pl_commands);
if (wl)
fprintf(cp_out, "%s %s (%s)\n", p->pl_typename, p->pl_title,
p->pl_name);
return;
}
#endif
/* For the sort in display. */
static int
dcomp(struct dvec **v1, struct dvec **v2)
{
return (strcmp((*v1)->v_name, (*v2)->v_name));
}
#ifdef notdef
/* Figure out what the name of this vector should be (if it is a number,
* then make it 'V' or 'I')... Note that the data is static.
*/
static char *
dname(d)
struct dvec *d;
{
static char buf[128];
char *s;
for (s = d->v_name; *s; s++)
if (!isdigit(*s))
return (d->v_name);
switch (d->v_type) {
case SV_VOLTAGE:
(void) sprintf(buf, "V(%s)", d->v_name);
return (buf);
case SV_CURRENT:
(void) sprintf(buf, "I(%s)", d->v_name);
return (buf);
}
return (d->v_name);
}
#endif
/* Take a set of vectors and form a new vector of the nth elements of each. */
void
com_cross(wordlist *wl)
{

View File

@ -9,12 +9,13 @@ Author: 1988 Jeffrey M. Hsu
#include "ngspice.h"
#include "cpdefs.h"
#include "ftegraph.h"
#include "graph.h"
#include "ftedbgra.h"
#include "ftedev.h"
#include "fteinput.h"
#include "postsc.h"
#include "postsc.h"
#include "variable.h"
#define RAD_TO_DEG (180.0 / M_PI)
#define DEVDEP(g) (*((PSdevdep *) (g)->devdep))
@ -115,16 +116,6 @@ PS_Init(void)
ytadj = YTADJ * scale * fontsize / 10;
}
#ifdef notdef
if (fontsize > 11)
gridsize = GRIDSIZES;
else
gridsize = GRIDSIZE;
dispdev->width = gridsize+16*fontwidth; /* was 612, p.w.h. */
dispdev->height = gridsize+8*fontheight; /* was 612, p.w.h. */
#endif
screenflag = 0;
dispdev->minx = XOFF / scale;
dispdev->miny = YOFF / scale;
@ -149,40 +140,6 @@ PS_NewViewport(GRAPH *graph)
/* hardcopying from the screen */
screenflag = 1;
/* scale to fit on 8 1/2 square */
#ifdef notdef
/* Face it, this is bogus */
#ifdef notdef
fprintf(plotfile, "%g %g scale\n",
(double) dispdev->width / graph->absolute.width,
(double) dispdev->height / graph->absolute.height);
#endif
scalex = (double) graph->absolute.width / dispdev->width;
scaley = (double) graph->absolute.height / dispdev->width;
/* scale left and bottom printer margin */
scaleps = ((scalex > scaley) ? scalex : scaley) / scale;
xoff = (int) (scaleps * (double) XOFF);
yoff = (int) (scaleps * (double) YOFF);
xtadj = 0;
ytadj = 0;
scalex = (double) dispdev->width / graph->absolute.width;
scaley = (double) dispdev->width / graph->absolute.height;
if (gtype == GRID_SMITH || gtype == GRID_SMITHGRID
|| gtype == GRID_POLAR)
{
scaleps = scale * ((scalex < scaley) ? scalex : scaley);
fprintf(plotfile, "%g %g scale\n", scaleps, scaleps);
} else {
fprintf(plotfile, "%g %g scale\n", scale*scalex, scale*scaley);
}
/* re-scale linestyles */
gr_relinestyle(graph);
#endif
}
/* reasonable values, used in gr_ for placement */
@ -202,17 +159,14 @@ PS_NewViewport(GRAPH *graph)
fprintf(plotfile, "%%!PS-Adobe-3.0 EPSF-3.0\n");
fprintf(plotfile, "%%%%Creator: nutmeg\n");
fprintf(plotfile, "%%%%BoundingBox: %d %d %d %d\n",
(int) (.75 * 72), (int) (.75 * 72),
(int) (8.5 * 72), (int) (8.5 * 72));
(int) (.75 * 72), (int) (.75 * 72),
(int) (8.5 * 72), (int) (8.5 * 72));
#ifdef notdef
if (!screenflag)
#endif
fprintf(plotfile, "%g %g scale\n", 1.0 / scale, 1.0 / scale);
fprintf(plotfile, "%g %g scale\n", 1.0 / scale, 1.0 / scale);
/* set up a reasonable font */
fprintf(plotfile, "/%s findfont %d scalefont setfont\n",
psfont, (int) (fontsize * scale));
psfont, (int) (fontsize * scale));
graph->devdep = tmalloc(sizeof(PSdevdep));
DEVDEP(graph).lastlinestyle = -1;

View File

@ -11,9 +11,10 @@ Author: 1986 Wayne A. Christopher, U. C. Berkeley CAD Group
#include "ngspice.h"
#include "cpdefs.h"
#include "ftedefs.h"
#include "ftedata.h"
#include "rawfile.h"
#include "dvec.h"
#include "rawfile.h"
#include "variable.h"
/* static declarations */
static void fixdims(struct dvec *v, char *s);
@ -37,6 +38,7 @@ raw_write(char *name, struct plot *pl, bool app, bool binary)
wordlist *wl;
struct variable *vv;
double dd;
char buf[BSIZE_SP];
if (!cp_getvar("nopadding", VT_BOOL, (char *) &raw_padding))
raw_padding = FALSE;
@ -90,7 +92,8 @@ raw_write(char *name, struct plot *pl, bool app, bool binary)
fprintf(fp, "No. Variables: %d\n", nvars);
fprintf(fp, "No. Points: %d\n", length);
if (numdims > 1) {
fprintf(fp, "Dimensions: %s\n", dimstring(dims, numdims));
dimstring(dims, numdims, buf);
fprintf(fp, "Dimensions: %s\n", buf);
}
for (wl = pl->pl_commands; wl; wl = wl->wl_next)
@ -146,7 +149,8 @@ raw_write(char *name, struct plot *pl, bool app, bool binary)
writedims = TRUE;
}
if (writedims) {
fprintf(fp, " dims=%s", dimstring(v->v_dims, v->v_numdims));
dimstring(v->v_dims, v->v_numdims, buf);
fprintf(fp, " dims=%s",buf);
}
(void) putc('\n', fp);
}
@ -241,7 +245,7 @@ raw_read(char *name)
char *date = 0;
struct plot *plots = NULL, *curpl = NULL;
char buf[BSIZE_SP], buf2[BSIZE_SP], *s, *t, *r;
int flags, nvars, npoints, i, j;
int flags = 0, nvars = 0, npoints = 0, i, j;
int ndimpoints, numdims=0, dims[MAXDIMS];
bool raw_padded = TRUE;
double junk;
@ -303,7 +307,7 @@ raw_read(char *name)
} else if (ciprefix("flags:", buf)) {
s = buf;
skip(s);
while (t = gettok(&s)) {
while ((t = gettok(&s))) {
if (cieq(t, "real"))
flags |= VF_REAL;
else if (cieq(t, "complex"))
@ -453,7 +457,7 @@ raw_read(char *name)
v->v_name = copy(buf2);
}
/* Now come the strange options... */
while (t = gettok(&s)) {
while ((t = gettok(&s))) {
if (ciprefix("min=", t)) {
if (sscanf(t + 4, "%lf",
&v->v_minsignal) != 1)

View File

@ -11,10 +11,11 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
#include "ngspice.h"
#include "cpdefs.h"
#include "ftedefs.h"
#include "circuits.h"
#include "quote.h"
#include "resource.h"
#include "variable.h"
/* static declarations */
static void printres(char *name);
@ -31,10 +32,13 @@ char *enddata;
void
init_rlimits(void)
{
#ifndef __MINGW32__
startdata = (char *) baseaddr( );
enddata = sbrk(0);
#else
startdata = 0;
enddata = 0;
#endif
}
void
@ -57,13 +61,17 @@ init_time(void)
void
com_rusage(wordlist *wl)
{
char* copyword;
/* Fill in the SPICE accounting structure... */
if (wl && (eq(wl->wl_word, "everything") || eq(wl->wl_word, "all"))) {
printres((char *) NULL);
} else if (wl) {
for (; wl; wl = wl->wl_next) {
printres(cp_unquote(wl->wl_word));
/* printres(cp_unquote(wl->wl_word)); DG: bad, memory leak*/
copyword=cp_unquote(wl->wl_word);/*DG*/
printres(copyword);
tfree(copyword);
if (wl->wl_next)
(void) putc('\n', cp_out);
}
@ -86,7 +94,7 @@ ft_ckspace(void)
static long old_usage = 0;
char *hi;
#ifndef __MINGW32__
# ifdef HAVE_GETRLIMIT
struct rlimit rld;
@ -103,8 +111,10 @@ ft_ckspace(void)
# endif
hi=sbrk(0);
usage = (long) (hi - enddata);
#else
usage = 0;
limit = 0;
#endif
if (limit < 0)
return; /* what else do you do? */
@ -304,7 +314,7 @@ fault(void)
signal(SIGSEGV, (SIGNAL_FUNCTION) fault); /* SysV style */
longjmp(env, 1);
}
#ifndef __MINGW32__
static void *
baseaddr(void)
{
@ -326,16 +336,6 @@ baseaddr(void)
at = (char *) ((((long)low >> LOG2_PAGESIZE)
+ ((long)high >> LOG2_PAGESIZE))
<< (LOG2_PAGESIZE - 1));
# ifdef notdef
at = (char *) ((((int) low + (int) high) / 2 + 0x7ff)
& ~(long) 0xfff);
/* nearest page */
# endif
# ifdef notdef
printf(
"high = %#8x low = %#8x at = %#8x\n",
high, low, at);
# endif
if (at == low || at == high) {
break;
@ -357,13 +357,10 @@ baseaddr(void)
} while (1);
# ifdef notdef
printf ("start is at %#x, end is at %#x\n", high, sbrk(0));
# endif
(void) signal(SIGSEGV, (SIGNAL_FUNCTION) orig_signal);
return (void *) high;
}
#endif
# ifdef notdef
main( )
{

View File

@ -1,6 +1,7 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
Modified: 2000 AlansFixes
**********/
/*
@ -12,8 +13,18 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
#include "ftedefs.h"
#include "ftedev.h"
#include "ftedebug.h"
#include "ftedata.h"
#include "dvec.h"
#include "circuits.h"
#include "completion.h"
#include "runcoms.h"
#include "variable.h"
#ifdef XSPICE
/* gtri - add - 12/12/90 - wbk - include ipc stuff */
#include "ipctiein.h"
/* gtri - end - 12/12/90 */
#endif
/* static declarations */
static int dosim(char *what, wordlist *wl);
@ -30,6 +41,11 @@ extern struct dbcomm *dbs;
FILE *rawfileFp;
bool rawfileBinary;
#define RAWBUF_SIZE 32768
char rawfileBuf[RAWBUF_SIZE];
/*To tell resume the rawfile name saj*/
char *last_used_rawfile = NULL;
/*end saj */
void
com_scirc(wordlist *wl)
@ -144,7 +160,7 @@ com_noise(wordlist *wl)
static int
dosim(char *what, wordlist *wl)
{
wordlist *ww;
wordlist *ww = NULL;
bool dofile = FALSE;
char buf[BSIZE_SP];
struct circ *ct;
@ -194,10 +210,6 @@ dosim(char *what, wordlist *wl)
ft_setflag = FALSE;
return 0;
}
#ifdef notdef
if (ft_curckt->ci_runonce)
com_rset((wordlist *) NULL);
#endif
/* From now on until the next prompt, an interrupt will just
* set a flag and let spice finish up, then control will be
@ -212,9 +224,10 @@ dosim(char *what, wordlist *wl)
if (!*wl->wl_word)
rawfileFp = stdout;
else if (!(rawfileFp = fopen(wl->wl_word, "w"))) {
perror(wl->wl_word);
ft_setflag = FALSE;
return 1;
setvbuf(rawfileFp, rawfileBuf, _IOFBF, RAWBUF_SIZE);
perror(wl->wl_word);
ft_setflag = FALSE;
return 1;
}
rawfileBinary = !ascii;
#ifdef PARALLEL_ARCH
@ -224,12 +237,16 @@ dosim(char *what, wordlist *wl)
#endif /* PARALLEL_ARCH */
} else {
rawfileFp = NULL;
#ifdef notdef
XXX why?
plot_num++; /* There should be a better way */
#endif
}
/*save rawfile name saj*/
if(last_used_rawfile) free((void *)last_used_rawfile);
if(rawfileFp){
last_used_rawfile = copy(wl->wl_word);
}else {
last_used_rawfile = NULL;
}
/*end saj*/
/* Spice calls wrd_init and wrd_end itself */
ft_curckt->ci_inprogress = TRUE;
if (eq(what,"sens2")) {
@ -237,6 +254,13 @@ dosim(char *what, wordlist *wl)
/* The circuit was interrupted somewhere. */
fprintf(cp_err, "%s simulation interrupted\n", what);
#ifdef XSPICE
/* gtri - add - 12/12/90 - wbk - record error and return errchk */
g_ipc.run_error = IPC_TRUE;
if(g_ipc.enabled)
ipc_send_errchk();
/* gtri - end - 12/12/90 */
#endif
} else
ft_curckt->ci_inprogress = FALSE;
} else {
@ -244,6 +268,13 @@ dosim(char *what, wordlist *wl)
if (err == 1) {
/* The circuit was interrupted somewhere. */
fprintf(cp_err, "%s simulation interrupted\n", what);
#ifdef XSPICE
/* gtri - add - 12/12/90 - wbk - record error and return errchk */
g_ipc.run_error = IPC_TRUE;
if(g_ipc.enabled)
ipc_send_errchk();
/* gtri - end - 12/12/90 */
#endif
err = 0;
} else if (err == 2) {
fprintf(cp_err, "%s simulation(s) aborted\n", what);
@ -252,8 +283,14 @@ dosim(char *what, wordlist *wl)
} else
ft_curckt->ci_inprogress = FALSE;
}
if (rawfileFp)
(void) fclose(rawfileFp);
if (rawfileFp){
if (ftell(rawfileFp)==0) {
(void) fclose(rawfileFp);
(void) remove(wl->wl_word);
} else {
(void) fclose(rawfileFp);
}
}
ft_curckt->ci_runonce = TRUE;
ft_setflag = FALSE;
return err;
@ -288,6 +325,13 @@ bool
ft_getOutReq(FILE **fpp, struct plot **plotp, bool *binp, char *name, char *title)
{
/*struct plot *pl;*/
#ifndef BATCH
if ( (strcmp(name, "Operating Point")==0) ||
(strcmp(name, "AC Operating Point")==0) ) {
return (FALSE);
};
#endif
if (rawfileFp) {
*fpp = rawfileFp;

View File

@ -12,12 +12,19 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
#include "ftedefs.h"
#include "ftedev.h"
#include "ftedebug.h"
#include "ftedata.h"
#include "runcoms2.h"
#include "dvec.h"
#include "circuits.h"
#include "runcoms2.h"
#include "variable.h"
extern FILE *rawfileFp;
extern bool rawfileBinary;
/*rawfile output saj*/
extern char *last_used_rawfile;
#define RAWBUF_SIZE 32768
char rawfileBuf[RAWBUF_SIZE];
/*end saj*/
extern struct dbcomm *dbs;
/* Continue a simulation. If there is non in progress, this is the
@ -40,6 +47,22 @@ com_resume(wordlist *wl)
{
struct dbcomm *db;
int err;
/*rawfile output saj*/
bool dofile = FALSE;
char buf[BSIZE_SP];
bool ascii = AsciiRawFile;
/*end saj*/
/*saj fix segment*/
if (!ft_curckt) {
fprintf(cp_err, "Error: there aren't any circuits loaded.\n");
return;
} else if (ft_curckt->ci_ckt == NULL) { /* Set noparse? */
fprintf(cp_err, "Error: circuit not parsed.\n");
return;
}
/*saj*/
if (ft_curckt->ci_inprogress == FALSE) {
fprintf(cp_err, "Note: run starting\n");
@ -49,13 +72,70 @@ com_resume(wordlist *wl)
ft_curckt->ci_inprogress = TRUE;
ft_setflag = TRUE;
reset_trace( );
for ( db = dbs, resumption = FALSE; db; db = db->db_next )
if( db->db_type == DB_IPLOT || db->db_type == DB_IPLOTALL ) {
resumption = TRUE;
}
/*rawfile output saj*/
if (last_used_rawfile)
dofile = TRUE;
if (cp_getvar("filetype", VT_STRING, buf)) {
if (eq(buf, "binary"))
ascii = FALSE;
else if (eq(buf, "ascii"))
ascii = TRUE;
else
fprintf(cp_err,
"Warning: strange file type \"%s\" (using \"ascii\")\n",
buf);
}
if (dofile) {
#ifdef PARALLEL_ARCH
if (ARCHme == 0) {
#endif /* PARALLEL_ARCH */
if (!last_used_rawfile)
rawfileFp = stdout;
else if (!(rawfileFp = fopen(last_used_rawfile, "a"))) {
setvbuf(rawfileFp, rawfileBuf, _IOFBF, RAWBUF_SIZE);
perror(last_used_rawfile);
ft_setflag = FALSE;
return;
}
rawfileBinary = !ascii;
#ifdef PARALLEL_ARCH
} else {
rawfileFp = NULL;
}
#endif /* PARALLEL_ARCH */
} else {
rawfileFp = NULL;
}
/*end saj*/
err = if_run(ft_curckt->ci_ckt, "resume", (wordlist *) NULL,
ft_curckt->ci_symtab);
ft_curckt->ci_symtab);
/*close rawfile saj*/
if (rawfileFp){
if (ftell(rawfileFp)==0) {
(void) fclose(rawfileFp);
(void) remove(last_used_rawfile);
} else {
(void) fclose(rawfileFp);
}
}
/*end saj*/
if (err == 1) {
/* The circuit was interrupted somewhere. */

View File

@ -14,11 +14,13 @@ Copyright 1990 Regents of the University of California. All rights reserved.
#include "cpdefs.h"
#include "ftedefs.h"
#include "fteinp.h"
#include "fteconst.h"
#include "sim.h"
#include "devdefs.h"
#include "inpdefs.h"
#include "iferrmsg.h"
#include "ifsim.h"
#include "circuits.h"
#include "shyu.h"

View File

@ -9,9 +9,11 @@ Author: 1994 Anthony E. Parker, Department of Electronics, Macquarie Uni.
#include "ngspice.h"
#include "ftedefs.h"
#include "ftedata.h"
#include "spec.h"
#include "dvec.h"
#include "sim.h"
#include "spec.h"
#include "variable.h"
void
com_spec(wordlist *wl)
@ -23,7 +25,7 @@ com_spec(wordlist *wl)
int fpts, i, j, k, tlen, ngood;
bool trace;
char *s;
struct dvec *f, *vlist, *lv, *vec;
struct dvec *f, *vlist, *lv = NULL, *vec;
struct pnode *names, *first_name;
if (!plot_cur || !plot_cur->pl_scale) {

View File

@ -1,6 +1,7 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
Modified: 2000 AlansFixes
**********/
/*
@ -13,14 +14,27 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
#include "ngspice.h"
#include "cpdefs.h"
#include "tskdefs.h" /* Is really needed ? */
#include "ftedefs.h"
#include "fteinp.h"
#include "fteconst.h"
#include "inpdefs.h"
#include "iferrmsg.h"
#include "ifsim.h"
#include "spiceif.h"
#include "circuits.h"
#include "spiceif.h"
#include "variable.h"
#ifdef XSPICE
/* gtri - add - wbk - 11/9/90 - include MIF function prototypes */
#include "mifproto.h"
/* gtri - end - wbk - 11/9/90 */
/* gtri - evt - wbk - 5/20/91 - Add stuff for user-defined nodes */
#include "evtproto.h"
#include "evtudn.h"
/* gtri - end - wbk - 5/20/91 - Add stuff for user-defined nodes */
#endif
/* static declarations */
static struct variable * parmtovar(IFvalue *pv, IFparm *opt);
@ -49,27 +63,32 @@ if_inpdeck(struct line *deck, INPtables **tab)
i++;
*tab = INPtabInit(i);
ft_curckt->ci_symtab = *tab;
if ((err = (*(ft_sim->newCircuit))(&ckt))
!= OK) {
err = (*(ft_sim->newCircuit))(&ckt);
if (err != OK) {
ft_sperror(err, "CKTinit");
return (NULL);
}
err = IFnewUid(ckt,&taskUid,(IFuid)NULL,"default",UID_TASK,(void**)NULL);
if(err) {
ft_sperror(err,"newUid");
return(NULL);
}
err = (*(ft_sim->newTask))(ckt,(void**)&(ft_curckt->ci_defTask),taskUid);
if(err) {
ft_sperror(err,"newTask");
return(NULL);
}
for(j=0;j<ft_sim->numAnalyses;j++) {
if(strcmp(ft_sim->analyses[j]->name,"options")==0) {
which = j;
break;
}
}
if(which != -1) {
err = IFnewUid(ckt,&optUid,(IFuid)NULL,"options",UID_ANALYSIS,
(void**)NULL);
@ -77,6 +96,7 @@ if_inpdeck(struct line *deck, INPtables **tab)
ft_sperror(err,"newUid");
return(NULL);
}
err = (*(ft_sim->newAnalysis))(ft_curckt->ci_ckt,which,optUid,
(void**)&(ft_curckt->ci_defOpt),
(void*)ft_curckt->ci_defTask);
@ -84,24 +104,44 @@ if_inpdeck(struct line *deck, INPtables **tab)
ft_sperror(err,"createOptions");
return(NULL);
}
ft_curckt->ci_curOpt = ft_curckt->ci_defOpt;
}
ft_curckt->ci_curTask = ft_curckt->ci_defTask;
INPpas1((void *) ckt, (card *) deck->li_next,(INPtables *)*tab);
INPpas2((void *) ckt, (card *) deck->li_next,
(INPtables *) *tab,ft_curckt->ci_defTask);
INPkillMods();
/* INPpas2 has been modified to ignore .NODESET and .IC
* cards. These are left till INPpas3 so that we can check for
* nodeset/ic of non-existant nodes. */
INPpas3((void *) ckt, (card *) deck->li_next,
(INPtables *) *tab,ft_curckt->ci_defTask, ft_sim->nodeParms,
ft_sim->numNodeParms);
#ifdef XSPICE
/* gtri - begin - wbk - 6/6/91 - Finish initialization of event driven structures */
err = EVTinit((void *) ckt);
if(err) {
ft_sperror(err,"EVTinit");
return(NULL);
}
/* gtri - end - wbk - 6/6/91 - Finish initialization of event driven structures */
#endif
return (ckt);
}
/* Do a run of the circuit, of the given type. Type "resume" is special --
* it means to resume whatever simulation that was in progress. The
* return value of this routine is 0 if the exit was ok, and 1 if there was
* a reason to interrupt the circuit (interrupt typed at the keyboard,
* error in the simulation, etc). args should be the entire command line,
* e.g. "tran 1 10 20 uic"
*/
/* Do a run of the circuit, of the given type. Type "resume" is
* special -- it means to resume whatever simulation that was in
* progress. The return value of this routine is 0 if the exit was ok,
* and 1 if there was a reason to interrupt the circuit (interrupt
* typed at the keyboard, error in the simulation, etc). args should
* be the entire command line, e.g. "tran 1 10 20 uic" */
int
if_run(char *t, char *what, wordlist *args, char *tab)
{
@ -112,17 +152,26 @@ if_run(char *t, char *what, wordlist *args, char *tab)
int j;
int which = -1;
IFuid specUid,optUid;
/* First parse the line... */
if (eq(what, "tran") || eq(what, "ac") || eq(what, "dc")
|| eq(what, "op") || eq(what, "pz") || eq(what,"disto")
|| eq(what, "adjsen") || eq(what, "sens") || eq(what,"tf")
|| eq(what, "noise")) {
if (eq(what, "tran")
|| eq(what, "ac")
|| eq(what, "dc")
|| eq(what, "op")
|| eq(what, "pz")
|| eq(what,"disto")
|| eq(what, "adjsen")
|| eq(what, "sens")
|| eq(what,"tf")
|| eq(what, "noise"))
{
(void) sprintf(buf, ".%s", wl_flatten(args));
deck.li_next = deck.li_actual = NULL;
deck.li_error = NULL;
deck.li_linenum = 0;
deck.li_line = buf;
if(ft_curckt->ci_specTask) {
err=(*(ft_sim->deleteTask))(ft_curckt->ci_ckt,
ft_curckt->ci_specTask);
@ -139,10 +188,14 @@ if_run(char *t, char *what, wordlist *args, char *tab)
}
err = (*(ft_sim->newTask))(ft_curckt->ci_ckt,
(void**)&(ft_curckt->ci_specTask),specUid);
if(err) {
ft_sperror(err,"newTask");
return(2);
}
for(j=0;j<ft_sim->numAnalyses;j++) {
if(strcmp(ft_sim->analyses[j]->name,"options")==0) {
which = j;
@ -163,29 +216,89 @@ if_run(char *t, char *what, wordlist *args, char *tab)
ft_sperror(err,"createOptions");
return(2);
}
ft_curckt->ci_curOpt = ft_curckt->ci_specOpt;
ft_curckt->ci_curOpt = ft_curckt->ci_specOpt;
/* This is a very dirty hack but it is the only one I
was able to find without intervening on all the code
It will be changed in the future. */
((TSKtask *)(ft_curckt->ci_specOpt))->TSKtemp = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKtemp;
((TSKtask *)(ft_curckt->ci_specOpt))->TSKnomTemp = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKnomTemp;
((TSKtask *)(ft_curckt->ci_specOpt))->TSKgmin = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKgmin;
((TSKtask *)(ft_curckt->ci_specOpt))->TSKgshunt = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKgshunt;
((TSKtask *)(ft_curckt->ci_specOpt))->TSKabstol = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKabstol;
((TSKtask *)(ft_curckt->ci_specOpt))->TSKreltol = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKreltol;
((TSKtask *)(ft_curckt->ci_specOpt))->TSKchgtol = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKchgtol;
((TSKtask *)(ft_curckt->ci_specOpt))->TSKvoltTol = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKvoltTol;
#ifdef NEWTRUNC
((TSKtask *)(ft_curckt->ci_specOpt))->TSKlteReltol = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKlteReltol;
((TSKtask *)(ft_curckt->ci_specOpt))->TSKlteAbstol = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKlteAbstol;
#endif
((TSKtask *)(ft_curckt->ci_specOpt))->TSKtrtol = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKtrtol;
((TSKtask *)(ft_curckt->ci_specOpt))->TSKbypass = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKbypass;
((TSKtask *)(ft_curckt->ci_specOpt))->TSKtranMaxIter = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKtranMaxIter;
((TSKtask *)(ft_curckt->ci_specOpt))->TSKdcMaxIter = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKdcMaxIter;
((TSKtask *)(ft_curckt->ci_specOpt))->TSKdcTrcvMaxIter = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKdcTrcvMaxIter;
((TSKtask *)(ft_curckt->ci_specOpt))->TSKintegrateMethod = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKintegrateMethod;
((TSKtask *)(ft_curckt->ci_specOpt))->TSKmaxOrder = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKmaxOrder;
((TSKtask *)(ft_curckt->ci_specOpt))->TSKnumSrcSteps = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKnumSrcSteps;
((TSKtask *)(ft_curckt->ci_specOpt))->TSKnumGminSteps = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKnumGminSteps;
((TSKtask *)(ft_curckt->ci_specOpt))->TSKgminFactor = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKgminFactor;
((TSKtask *)(ft_curckt->ci_specOpt))->TSKpivotAbsTol = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKpivotAbsTol;
((TSKtask *)(ft_curckt->ci_specOpt))->TSKpivotRelTol = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKpivotRelTol;
((TSKtask *)(ft_curckt->ci_specOpt))->TSKdefaultMosM = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKdefaultMosM;
((TSKtask *)(ft_curckt->ci_specOpt))->TSKdefaultMosL = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKdefaultMosL;
((TSKtask *)(ft_curckt->ci_specOpt))->TSKdefaultMosW = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKdefaultMosW;
((TSKtask *)(ft_curckt->ci_specOpt))->TSKdefaultMosAD = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKdefaultMosAD;
((TSKtask *)(ft_curckt->ci_specOpt))->TSKdefaultMosAS = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKdefaultMosAS;
((TSKtask *)(ft_curckt->ci_specOpt))->TSKnoOpIter = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKnoOpIter;
((TSKtask *)(ft_curckt->ci_specOpt))->TSKtryToCompact = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKtryToCompact;
((TSKtask *)(ft_curckt->ci_specOpt))->TSKbadMos3 = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKbadMos3;
((TSKtask *)(ft_curckt->ci_specOpt))->TSKkeepOpInfo = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKkeepOpInfo;
((TSKtask *)(ft_curckt->ci_specOpt))->TSKcopyNodesets = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKcopyNodesets;
((TSKtask *)(ft_curckt->ci_specOpt))->TSKnodeDamping = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKnodeDamping;
((TSKtask *)(ft_curckt->ci_specOpt))->TSKabsDv = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKabsDv;
((TSKtask *)(ft_curckt->ci_specOpt))->TSKrelDv = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKrelDv;
}
ft_curckt->ci_curTask = ft_curckt->ci_specTask;
INPpas2(ckt, (card *) &deck, (INPtables *)tab, ft_curckt->ci_specTask);
INPpas2(ckt, (card *) &deck, (INPtables *)tab, ft_curckt->ci_specTask);
if (deck.li_error) {
fprintf(cp_err, "Warning: %s\n", deck.li_error);
return 2;
}
}
/* -- *** BUG! ****/
/* -- A bug fix suggested by Cecil Aswell (aswell@netcom.com) to let */
/* -- the interactive analysis commands get the current temperature */
/* -- and other options. */
if( eq(what,"run") ) {
ft_curckt->ci_curTask = ft_curckt->ci_defTask;
ft_curckt->ci_curOpt = ft_curckt->ci_defOpt;
}
if ( (eq(what, "tran")) ||
(eq(what, "ac")) ||
(eq(what, "dc")) ||
(eq(what, "op")) ||
(eq(what, "pz")) ||
(eq(what, "disto")) ||
(eq(what, "noise")) ||
eq(what, "adjsen") || eq(what, "sens") || eq(what,"tf") ||
(eq(what, "run")) ) {
/* -- Find out what we are supposed to do. */
if ( (eq(what, "tran"))
||(eq(what, "ac"))
||(eq(what, "dc"))
||(eq(what, "op"))
||(eq(what, "pz"))
||(eq(what, "disto"))
||(eq(what, "noise"))
||(eq(what, "adjsen"))
||(eq(what, "sens"))
||(eq(what,"tf"))
||(eq(what, "run")) ) {
if ((err = (*(ft_sim->doAnalyses))(ckt, 1, ft_curckt->ci_curTask))!=OK){
ft_sperror(err, "doAnalyses");
/* wrd_end(); */
@ -725,44 +838,6 @@ finddev(void *ck, char *name, void **devptr, void **modptr)
}
#ifdef notdef
/* XXX Not useful */
/* Extract the node and device names from the line and add them to the command
* completion structure. This is probably not a good thing to do if it
* takes too much time.
*/
/* BLOW THIS AWAY */
void
if_setndnames(line)
char *line;
{
char *t;
int i;
while (isspace(*line))
line++;
if (!*line || (*line == '*') || (*line == '.'))
return;
t = gettok(&line);
if (!(i = inp_numnodes(*t)))
return;
if ((*t == 'q') || (*t == 'Q'))
i = 3;
cp_addkword(CT_DEVNAMES, t);
while (i-- > 0) {
t = gettok(&line);
if (t)
cp_addkword(CT_NODENAMES, t);
}
return;
}
#endif
/* get an analysis parameter by name instead of id */
int
@ -806,7 +881,7 @@ if_tranparams(struct circ *ci, double *start, double *stop, double *step)
UID_ANALYSIS, (void**)NULL);
if(err != OK) return(FALSE);
err =(*(ft_sim->findAnalysis))(ci->ci_ckt,&which, &anal,tranUid,
ci->ci_curTask,(IFuid *)NULL);
ci->ci_curTask,(IFuid )NULL);
if(err != OK) return(FALSE);
err = if_analQbyName(ci->ci_ckt,which,anal,"tstart",&tmp);
if(err != OK) return(FALSE);
@ -884,3 +959,381 @@ if_getstat(void *ckt, char *name)
}
}
#ifdef EXPERIMENTAL_CODE
#include <cktdefs.h>
#include <trandefs.h>
/* arg0: circuit file, arg1: data file */
void com_loadsnap(wordlist *wl) {
int error = 0;
FILE *file;
int tmpI, i, size;
CKTcircuit *my_ckt, *ckt;
/*
Phesudo code:
source(file_name);
This should setup all the device structs, voltage nodes, etc.
call cktsetup;
This is needed to setup vector mamory allocation for vectors and branch nodes
load_binary_data(info);
Overwrite the allocated numbers, rhs etc, with saved data
*/
if (ft_curckt) {
fprintf(cp_err, "Error: there is already a circuit loaded.\n");
return;
}
/* source the circuit */
inp_source(wl->wl_word);
if (!ft_curckt) {
return;
}
/* allocate all the vectors, with luck! */
if (!error)
error = CKTsetup((CKTcircuit *)ft_curckt->ci_ckt);
if (!error)
error = CKTtemp((CKTcircuit *)ft_curckt->ci_ckt);
if(error) {
fprintf(cp_err,"Some error in the CKT setup fncts!\n");
return;
}
/* so it resumes ... */
ft_curckt->ci_inprogress = TRUE;
/* now load the binary file */
ckt = (CKTcircuit *)ft_curckt->ci_ckt;
file = fopen(wl->wl_next->wl_word,"rb");
if(!file) {
fprintf(cp_err,
"Error: Couldn't open \"%s\" for reading\n",
wl->wl_next->wl_word);
return;
}
fread(&tmpI,sizeof(int),1,file);
if(tmpI != sizeof(CKTcircuit) ) {
fprintf(cp_err,"loaded num: %d, expected num: %d\n",tmpI,sizeof(CKTcircuit));
fprintf(cp_err,
"Error: snapshot saved with different version of spice\n");
fclose(file);
return;
}
my_ckt = (CKTcircuit *)tmalloc(sizeof(CKTcircuit));
fread(my_ckt,sizeof(CKTcircuit),1,file);
#define _t(name) ckt->name = my_ckt->name
#define _ta(name,size)\
do{ int __i; for(__i=0;__i<size;__i++) _t(name[__i]); } while(0)
_t(CKTtime);
_t(CKTdelta);
_ta(CKTdeltaOld,7);
_t(CKTtemp);
_t(CKTnomTemp);
_t(CKTvt);
_ta(CKTag,7);
_t(CKTorder);
_t(CKTmaxOrder);
_t(CKTintegrateMethod);
_t(CKTniState);
_t(CKTmaxEqNum);
_t(CKTcurrentAnalysis);
_t(CKTnumStates);
_t(CKTmode);
_t(CKTbypass);
_t(CKTdcMaxIter);
_t(CKTdcTrcvMaxIter);
_t(CKTtranMaxIter);
_t(CKTbreakSize);
_t(CKTbreak);
_t(CKTsaveDelta);
_t(CKTminBreak);
_t(CKTabstol);
_t(CKTpivotAbsTol);
_t(CKTpivotRelTol);
_t(CKTreltol);
_t(CKTchgtol);
_t(CKTvoltTol);
_t(CKTgmin);
_t(CKTgshunt);
_t(CKTdelmin);
_t(CKTtrtol);
_t(CKTfinalTime);
_t(CKTstep);
_t(CKTmaxStep);
_t(CKTinitTime);
_t(CKTomega);
_t(CKTsrcFact);
_t(CKTdiagGmin);
_t(CKTnumSrcSteps);
_t(CKTnumGminSteps);
_t(CKTgminFactor);
_t(CKTnoncon);
_t(CKTdefaultMosM);
_t(CKTdefaultMosL);
_t(CKTdefaultMosW);
_t(CKTdefaultMosAD);
_t(CKTdefaultMosAS);
_t(CKThadNodeset);
_t(CKTfixLimit);
_t(CKTnoOpIter);
_t(CKTisSetup);
_t(CKTtimeListSize);
_t(CKTtimeIndex);
_t(CKTsizeIncr);
_t(CKTtryToCompact);
_t(CKTbadMos3);
_t(CKTkeepOpInfo);
_t(CKTcopyNodesets);
_t(CKTnodeDamping);
_t(CKTabsDv);
_t(CKTrelDv);
_t(CKTtroubleNode);
/* if(name) {\
tfree(name);\
name = NULL;\
}\*/
#undef _foo
#define _foo(name,type,_size)\
do {\
int __i;\
fread(&__i,sizeof(int),1,file);\
if(__i) {\
if(name)\
tfree(name);\
name = (type *)tmalloc(__i);\
fread(name,1,__i,file);\
} else {\
fprintf(cp_err, "size for vector " #name " is 0\n");\
}\
if((_size) != -1 && __i != (_size) * sizeof(type)) {\
fprintf(cp_err,"expected %d, but got %d for "#name"\n",(_size)*sizeof(type),__i);\
}\
} while(0)
for(i=0;i<=ckt->CKTmaxOrder+1;i++) {
_foo(ckt->CKTstates[i],double,ckt->CKTnumStates);
}
size = SMPmatSize(ckt->CKTmatrix) + 1;
_foo(ckt->CKTrhs, double,size);
_foo(ckt->CKTrhsOld, double,size);
_foo(ckt->CKTrhsSpare, double,size);
_foo(ckt->CKTirhs, double,size);
_foo(ckt->CKTirhsOld, double,size);
_foo(ckt->CKTirhsSpare, double,size);
_foo(ckt->CKTrhsOp, double,size);
_foo(ckt->CKTsenRhs, double,size);
_foo(ckt->CKTseniRhs, double,size);
_foo(ckt->CKTtimePoints,double,-1);
_foo(ckt->CKTdeltaList,double,-1);
_foo(ckt->CKTbreaks,double,ckt->CKTbreakSize);
_foo((TSKtask *)ft_curckt->ci_curTask,TSKtask,1);
/* To stop the Free */
((TSKtask *)ft_curckt->ci_curTask)->TSKname = NULL;
((TSKtask *)ft_curckt->ci_curTask)->jobs = NULL;
_foo(((TSKtask *)ft_curckt->ci_curTask)->TSKname,char,-1);
_foo(((TRANan *)((TSKtask *)ft_curckt->ci_curTask)->jobs),TRANan,1);
((TSKtask *)ft_curckt->ci_curTask)->jobs->JOBname = NULL;
ckt->CKTcurJob = (JOB *)((TSKtask *)ft_curckt->ci_curTask)->jobs;
_foo(((TSKtask *)ft_curckt->ci_curTask)->jobs->JOBname,char,-1);
((TSKtask *)ft_curckt->ci_curTask)->jobs->JOBnextJob = NULL;
((TRANan *)((TSKtask *)ft_curckt->ci_curTask)->jobs)->TRANplot = NULL;
_foo(ckt->CKTstat,STATistics,1);
tfree(my_ckt);
fclose(file);
/* Finally to resume the plot in some fashion */
/* a worked out version of this should be enough */
{
IFuid *nameList;
int numNames;
IFuid timeUid;
error = CKTnames(ckt,&numNames,&nameList);
if(error){
fprintf(cp_err,"error in CKTnames\n");
return;
}
(*(SPfrontEnd->IFnewUid))((void *)ckt,&timeUid,(IFuid)NULL,
"time", UID_OTHER, (void **)NULL);
error = (*(SPfrontEnd->OUTpBeginPlot))((void *)ckt,
(void*)ckt->CKTcurJob,
ckt->CKTcurJob->JOBname,timeUid,IF_REAL,numNames,nameList,
IF_REAL,&(((TRANan*)ckt->CKTcurJob)->TRANplot));
if(error) {
fprintf(cp_err,"error in CKTnames\n");
return;
}
}
return ;
}
void com_savesnap(wordlist *wl) {
FILE *file;
int i, size;
CKTcircuit *ckt;
TSKtask *task;
if (!ft_curckt) {
fprintf(cp_err, "Error: there is no circuit loaded.\n");
return;
} else if (ft_curckt->ci_ckt == NULL) { /* Set noparse? */
fprintf(cp_err, "Error: circuit not parsed.\n");
return;
}
/* save the data */
ckt = (CKTcircuit *)ft_curckt->ci_ckt;
task = (TSKtask *)ft_curckt->ci_curTask;
if(task->jobs->JOBtype != 4) {
fprintf(cp_err,"Only saving of tran analysis is implemented\n");
return;
}
file = fopen(wl->wl_word,"wb");
if(!file) {
fprintf(cp_err,
"Error: Couldn't open \"%s\" for writing\n",wl->wl_word);
return;
}
#undef _foo
#define _foo(name,type,num)\
do {\
int __i;\
if(name) {\
__i = (num) * sizeof(type); fwrite(&__i,sizeof(int),1,file);\
if((num))\
fwrite(name,sizeof(type),(num),file);\
} else {\
__i = 0;\
fprintf(cp_err,#name " is NULL, zero written\n");\
fwrite(&__i,sizeof(int),1,file);\
}\
} while(0)
_foo(ckt,CKTcircuit,1);
/* To save list
double *(CKTstates[8]);
double *CKTrhs;
double *CKTrhsOld;
double *CKTrhsSpare;
double *CKTirhs;
double *CKTirhsOld;
double *CKTirhsSpare;
double *CKTrhsOp;
double *CKTsenRhs;
double *CKTseniRhs;
double *CKTtimePoints; list of all accepted timepoints in
the current transient simulation
double *CKTdeltaList; list of all timesteps in the
current transient simulation
*/
for(i=0;i<=ckt->CKTmaxOrder+1;i++) {
_foo(ckt->CKTstates[i],double,ckt->CKTnumStates);
}
size = SMPmatSize(ckt->CKTmatrix) + 1;
_foo(ckt->CKTrhs,double,size);
_foo(ckt->CKTrhsOld,double,size);
_foo(ckt->CKTrhsSpare,double,size);
_foo(ckt->CKTirhs,double,size);
_foo(ckt->CKTirhsOld,double,size);
_foo(ckt->CKTirhsSpare,double,size);
_foo(ckt->CKTrhsOp,double,size);
_foo(ckt->CKTsenRhs,double,size);
_foo(ckt->CKTseniRhs,double,size);
_foo(ckt->CKTtimePoints,double,ckt->CKTtimeListSize);
_foo(ckt->CKTdeltaList,double,ckt->CKTtimeListSize);
/* need to save the breakpoints, or something */
_foo(ckt->CKTbreaks,double,ckt->CKTbreakSize);
/* now save the TSK struct, ft_curckt->ci_curTask*/
_foo(task,TSKtask,1);
_foo(task->TSKname,char,(strlen(task->TSKname)+1));
/* now save the JOB struct task->jobs */
/* lol, only allow one job, tough! */
/* Note that JOB is a base class, need to save actual type!! */
_foo(task->jobs,TRANan,1);
_foo(task->jobs->JOBname,char,(strlen(task->jobs->JOBname)+1));
/* Finally the stats */
_foo(ckt->CKTstat,STATistics,1);
fclose(file);
return;
}
#endif

View File

@ -18,6 +18,10 @@ int if_analQbyName(void *ckt, int which, void *anal, char *name, IFvalue *parm)
bool if_tranparams(struct circ *ci, double *start, double *stop, double *step);
struct variable * if_getstat(void *ckt, char *name);
#ifdef EXPERIMENTAL_CODE
void if_loadsnap(wordlist *wl);
void if_savesnap(wordlist *wl);
#endif
#endif

View File

@ -1,6 +1,7 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
Modified: 2000 AlansFixes
**********/
/*
@ -12,8 +13,15 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
#include "cpdefs.h"
#include "ftedefs.h"
#include "fteinp.h"
#include "subckt.h"
#ifdef XSPICE
/* gtri - add - wbk - 11/9/90 - include MIF function prototypes */
#include "mifproto.h"
/* gtri - end - wbk - 11/9/90 */
#endif
#include "subckt.h"
#include "variable.h"
/* static declarations */
static struct line * doit(struct line *deck);
@ -113,6 +121,14 @@ inp_subcktexpand(struct line *deck)
ll = doit(deck);
/* Now check to see if there are still subckt instances undefined... */
if (ll!=NULL) for (c = ll; c; c = c->li_next)
if (ciprefix(invoke, c->li_line)) {
fprintf(cp_err, "Error: unknown subckt: %s\n",
c->li_line);
return NULL;
}
return (ll);
}
@ -293,13 +309,6 @@ doit(struct line *deck)
return (NULL);
}
/* Now check to see if there are still subckt instances undefined... */
for (c = deck; c; c = c->li_next)
if (ciprefix(invoke, c->li_line)) {
fprintf(cp_err, "Error: unknown subckt: %s\n",
c->li_line);
error = 1;
}
if (error)
return NULL; /* error message already reported; should free( ) */
@ -348,6 +357,14 @@ translate(struct line *deck, char *formal, char *actual, char *scname, char *sub
char *buffer, *name, *s, *t, ch;
int nnodes, i;
#ifdef XSPICE
/* gtri - add - wbk - 10/23/90 - add new local variables */
char *next_name; /* for look-ahead during tokenizing */
/* gtri - end - wbk - 10/23/90 */
#endif
i = settrans(formal, actual, subname);
if (i < 0) {
fprintf(stderr,
@ -370,6 +387,102 @@ translate(struct line *deck, char *formal, char *actual, char *scname, char *sub
/* Nothing any good here. */
continue;
#ifdef XSPICE
/* gtri - add - wbk - 10/23/90 - process A devices specially */
/* since they have a more involved and variable length node syntax */
case 'a':
case 'A':
/* translate the instance name according to normal rules */
buffer = tmalloc(10000); /* XXXXX */
s = c->li_line;
name = MIFgettok(&s);
/* maschmann
sprintf(buffer, "%s:%s ", name, scname); */
sprintf(buffer, "a:%s:%s ", scname, name+1 );
/* Now translate the nodes, looking ahead one token to recognize */
/* when we reach the model name which should not be translated */
/* here. */
next_name = MIFgettok(&s);
while(1) {
/* rotate the tokens and get the the next one */
name = next_name;
next_name = MIFgettok(&s);
/* if next token is NULL, name holds the model name, so exit */
if(next_name == NULL)
break;
/* Process the token in name. If it is special, then don't */
/* translate it. */
switch(*name) {
case '[':
case ']':
case '~':
sprintf(buffer + strlen(buffer), "%s ", name);
break;
case '%':
sprintf(buffer + strlen(buffer), "%%");
/* don't translate the port type identifier */
name = next_name;
next_name = MIFgettok(&s);
sprintf(buffer + strlen(buffer), "%s ", name);
break;
default:
/* must be a node name at this point, so translate it */
t = gettrans(name);
if (t)
sprintf(buffer + strlen(buffer), "%s ", t);
else
/* maschmann: changed order
sprintf(buffer + strlen(buffer), "%s:%s ", name, scname); */
if(name[0]=='v' || name[0]=='V') sprintf(buffer + strlen(buffer), "v:%s:%s ", scname, name+1);
else sprintf(buffer + strlen(buffer), "%s:%s ", scname, name);
break;
} /* switch */
} /* while */
/* copy in the last token, which is the model name */
if(name)
sprintf(buffer + strlen(buffer), "%s ", name);
/* Set s to null string for compatibility with code */
/* after switch statement */
s = "";
break;
/* gtri - end - wbk - 10/23/90 */
#endif
default:
s = c->li_line;
name = gettok(&s);
@ -566,6 +679,13 @@ gettrans(char *name)
{
int i;
#ifdef XSPICE
/* gtri - wbk - 2/27/91 - don't translate the reserved word 'null' */
if (eq(name, "null"))
return (name);
/* gtri - end */
#endif
if (eq(name, "0"))
return (name);
for (i = 0; table[i].t_old; i++)
@ -577,11 +697,17 @@ gettrans(char *name)
static int
numnodes(char *name)
{
/* gtri - comment - wbk - 10/23/90 - Do not modify this routine for */
/* 'A' type devices since the callers will not know how to find the */
/* nodes even if they know how many there are. Modify the callers */
/* instead. */
/* gtri - end - wbk - 10/23/90 */
char c;
struct subs *sss;
char *s, *t, buf[4 * BSIZE_SP];
wordlist *wl;
int n, i;
int n, i, gotit;
while (*name && isspace(*name))
name++;
@ -609,6 +735,41 @@ numnodes(char *name)
return (sss->su_numargs);
}
n = inp_numnodes(c);
/* Added this code for variable number of nodes on BSIM3SOI devices */
/* The consequence of this code is that the value returned by the */
/* inp_numnodes(c) call must be regarded as "maximun number of nodes */
/* for a given device type. */
/* Paolo Nenzi Jan-2001 */
/* I hope that works, this code is very very untested */
if (c=='m') { /* IF this is a mos */
i = 0;
s = buf;
gotit = 0;
t = gettok(&s); /* Skip component name */
while ((i < n) && (*s) && !gotit) {
t = gettok(&s);
for (wl = modnames; wl; wl = wl->wl_next)
if (eq(t, wl->wl_word))
gotit = 1;
i++;
}
/* Note: node checks must be done on #_of_node-1 because the */
/* "while" cicle increments the counter even when a model is */
/* recognized. This code may be better! */
if (i < 5) {
fprintf(cp_err, "Error: too few nodes for MOS: %s\n", name);
return(0);
}
return(i-1); /* compesate the unnecessary inrement in the while cicle */
}
if (nobjthack || (c != 'q'))
return (n);
for (s = buf, i = 0; *s && (i < 4); i++)
@ -928,7 +1089,7 @@ inp_numnodes(char c)
case 'j': return (3);
case 'k': return (0);
case 'l': return (2);
case 'm': return (4);
case 'm': return (7); /* This means that 7 is the maximun number of nodes */
case 'o': return (4);
case 'q': return (4);
case 'r': return (2);

View File

@ -10,7 +10,7 @@ Author: 1986 Wayne A. Christopher, U. C. Berkeley CAD Group
#include "ngspice.h"
#include "cpdefs.h"
#include "ftedefs.h"
#include "ftedata.h"
#include "dvec.h"
#include "typesdef.h"
@ -32,7 +32,7 @@ struct plotab {
/* note: This should correspond to SV_ defined in FTEconstant.h */
struct type types[NUMTYPES] = {
{ "notype", NULL } ,
{ "time", "S" } ,
{ "time", "s" } ,
{ "frequency", "Hz" } ,
{ "voltage", "V" } ,
{ "current", "A" } ,
@ -42,13 +42,6 @@ struct type types[NUMTYPES] = {
{ "inoise-integrated", "V or A" } ,
{ "output-noise", NULL } ,
{ "input-noise", NULL } ,
#ifdef notdef
{ "HD2", NULL } ,
{ "HD3", NULL } ,
{ "DIM2", NULL } ,
{ "SIM2", NULL } ,
{ "DIM3", NULL } ,
#endif
{ "pole", NULL } ,
{ "zero", NULL } ,
{ "s-param", NULL } ,

View File

@ -7,35 +7,153 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
* Routines for dealing with the vector database.
*/
#include "ngspice.h"
#include "cpdefs.h"
#include "ftedefs.h"
#include "ftedata.h"
#include <ngspice.h>
#include <cpdefs.h>
#include <ftedefs.h>
#include <dvec.h>
#include <sim.h>
#include "circuits.h"
#include "completion.h"
#include "variable.h"
#include "vectors.h"
#include "plotting/plotting.h"
/* static declarations */
#ifdef XSPICE
/* gtri - begin - add function prototype for EVTfindvec */
struct dvec *EVTfindvec(char *node);
/* gtri - end - add function prototype for EVTfindvec */
#endif
static struct dvec * findvec(char *word, struct plot *pl);
static struct dvec * sortvecs(struct dvec *d);
static int veccmp(struct dvec **d1, struct dvec **d2);
static int namecmp(char *s, char *t);
/* Find a named vector in a plot. We are careful to copy the vector if
* v_link2 is set, because otherwise we will get screwed up. */
static struct dvec *
findvec(char *word, struct plot *pl)
{
struct dvec *d, *newv = NULL, *end = NULL, *v;
char buf[BSIZE_SP];
if (pl == NULL)
return (NULL);
if (cieq(word, "all")) {
for (d = pl->pl_dvecs; d; d = d->v_next) {
if (d->v_flags & VF_PERMANENT) {
if (d->v_link2) {
v = vec_copy(d);
vec_new(v);
} else
v = d;
if (end)
end->v_link2 = v;
else
newv = v;
end = v;
}
}
return (newv);
}
for (d = pl->pl_dvecs; d; d = d->v_next)
if (cieq(word, d->v_name) && (d->v_flags & VF_PERMANENT))
break;
if (!d) {
(void) sprintf(buf, "v(%s)", word);
for (d = pl->pl_dvecs; d; d = d->v_next)
if (cieq(buf, d->v_name) && (d->v_flags & VF_PERMANENT))
break;
}
#ifdef XSPICE
/* gtri - begin - Add processing for getting event-driven vector */
if(!d)
d = EVTfindvec(word);
/* gtri - end - Add processing for getting event-driven vector */
#endif
if (d && d->v_link2) {
d = vec_copy(d);
vec_new(d);
}
return (d);
}
/* Where 'constants' go when defined on initialization. */
/* If there are imbedded numeric strings, compare them numerically, not
* alphabetically.
*/
static int
namecmp(const void *a, const void *b)
{
int i, j;
static struct plot constantplot = {
"Constant values", "Sat Aug 16 10:55:15 PDT 1986", "constants",
"const", NULL, NULL, NULL, NULL, NULL, NULL, TRUE
} ;
char *s = (char *) a;
char *t = (char *) b;
for (;;) {
while ((*s == *t) && !isdigit(*s) && *s)
s++, t++;
if (!*s)
return (0);
if ((*s != *t) && (!isdigit(*s) || !isdigit(*t)))
return (*s - *t);
/* The beginning of a number... Grab the two numbers and then
* compare them... */
for (i = 0; isdigit(*s); s++)
i = i * 10 + *s - '0';
for (j = 0; isdigit(*t); t++)
j = j * 10 + *t - '0';
if (i != j)
return (i - j);
}
}
struct plot *plot_cur = &constantplot;
struct plot *plot_list = &constantplot;
int plotl_changed; /* TRUE after a load */
int plot_num = 1;
static int
veccmp(const void *a, const void *b)
{
int i;
struct dvec **d1 = (struct dvec **) a;
struct dvec **d2 = (struct dvec **) b;
if ((i = namecmp((*d1)->v_plot->pl_typename,
(*d2)->v_plot->pl_typename)) != 0)
return (i);
return (namecmp((*d1)->v_name, (*d2)->v_name));
}
/* Sort all the vectors in d, first by plot name and then by vector
* name. Do the right thing with numbers. */
static struct dvec *
sortvecs(struct dvec *d)
{
struct dvec **array, *t;
int i, j;
for (t = d, i = 0; t; t = t->v_link2)
i++;
if (i < 2)
return (d);
array = (struct dvec **) tmalloc(i * sizeof (struct dvec *));
for (t = d, i = 0; t; t = t->v_link2)
array[i++] = t;
qsort((char *) array, i, sizeof (struct dvec *), veccmp);
/* Now string everything back together... */
for (j = 0; j < i - 1; j++)
array[j]->v_link2 = array[j + 1];
array[j]->v_link2 = NULL;
d = array[0];
tfree(array);
return (d);
}
/* Load in a rawfile. */
void
ft_loadfile(char *file)
{
@ -304,54 +422,6 @@ vec_get(char *word)
return (sortvecs(d));
}
/* Find a named vector in a plot. We are careful to copy the vector
* if v_link2 is set, because otherwise we will get screwed up.
*/
static struct dvec *
findvec(char *word, struct plot *pl)
{
struct dvec *d, *newv = NULL, *end = NULL, *v;
char buf[BSIZE_SP];
if (pl == NULL)
return (NULL);
if (cieq(word, "all")) {
for (d = pl->pl_dvecs; d; d = d->v_next) {
if (d->v_flags & VF_PERMANENT) {
if (d->v_link2) {
v = vec_copy(d);
vec_new(v);
} else
v = d;
if (end)
end->v_link2 = v;
else
newv = v;
end = v;
}
}
return (newv);
}
for (d = pl->pl_dvecs; d; d = d->v_next)
if (cieq(word, d->v_name) && (d->v_flags & VF_PERMANENT))
break;
if (!d) {
(void) sprintf(buf, "v(%s)", word);
for (d = pl->pl_dvecs; d; d = d->v_next)
if (cieq(buf, d->v_name) && (d->v_flags & VF_PERMANENT))
break;
}
if (d && d->v_link2) {
d = vec_copy(d);
vec_new(d);
}
return (d);
}
/* Execute the commands for a plot. This is done whenever a plot becomes
* the current plot.
*/
@ -615,75 +685,7 @@ vec_basename(struct dvec *v)
return (copy(s));
}
/* Sort all the vectors in d, first by plot name and then by vector name.
* Do the right thing with numbers.
*/
static struct dvec *
sortvecs(struct dvec *d)
{
struct dvec **array, *t;
int i, j;
for (t = d, i = 0; t; t = t->v_link2)
i++;
if (i < 2)
return (d);
array = (struct dvec **) tmalloc(i * sizeof (struct dvec *));
for (t = d, i = 0; t; t = t->v_link2)
array[i++] = t;
qsort((char *) array, i, sizeof (struct dvec *), veccmp);
/* Now string everything back together... */
for (j = 0; j < i - 1; j++)
array[j]->v_link2 = array[j + 1];
array[j]->v_link2 = NULL;
d = array[0];
tfree(array);
return (d);
}
static int
veccmp(struct dvec **d1, struct dvec **d2)
{
int i;
if ((i = namecmp((*d1)->v_plot->pl_typename,
(*d2)->v_plot->pl_typename)) != 0)
return (i);
return (namecmp((*d1)->v_name, (*d2)->v_name));
}
/* If there are imbedded numeric strings, compare them numerically, not
* alphabetically.
*/
static int
namecmp(char *s, char *t)
{
int i, j;
for (;;) {
while ((*s == *t) && !isdigit(*s) && *s)
s++, t++;
if (!*s)
return (0);
if ((*s != *t) && (!isdigit(*s) || !isdigit(*t)))
return (*s - *t);
/* The beginning of a number... Grab the two numbers
* and then compare them...
*/
for (i = 0; isdigit(*s); s++)
i = i * 10 + *s - '0';
for (j = 0; isdigit(*t); t++)
j = j * 10 + *t - '0';
if (i != j)
return (i - j);
}
}
/* Make a plot the current one. This gets called by cp_usrset() when one
@ -818,7 +820,7 @@ vec_mkfamily(struct dvec *v)
int size, numvecs, i, j, count[MAXDIMS];
int totalsize;
struct dvec *vecs, *d;
char buf[BSIZE_SP];
char buf[BSIZE_SP], buf2[BSIZE_SP];
if (v->v_numdims < 2)
return (v);
@ -838,8 +840,8 @@ vec_mkfamily(struct dvec *v)
for (i = 0; i < MAXDIMS; i++)
count[i] = 0;
for (d = vecs, j = 0; d; j++, d = d->v_link2) {
(void) sprintf(buf, "%s%s", v->v_name,
indexstring(count, v->v_numdims - 1));
indexstring(count, v->v_numdims - 1, buf2);
(void) sprintf(buf, "%s%s", v->v_name, buf2);
d->v_name = copy(buf);
d->v_type = v->v_type;
d->v_flags = v->v_flags;

View File

@ -6,21 +6,40 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
#include "ngspice.h"
#include "cpdefs.h"
#include "ftedefs.h"
#include "ftedata.h"
#include "dvec.h"
#include "ftehelp.h"
#include "hlpdefs.h"
#include "where.h"
#include "circuits.h"
#include "where.h"
void
com_where(void)
{
char *msg;
/*CDHW typing where with no current circuit caused crashes CDHW*/
if (!ft_curckt) {
fprintf(cp_err, "There is no current circuit\n");
return; }
else if (ft_curckt->ci_ckt != "") {
fprintf(cp_err, "No unconverged node found.\n");
return;
}
msg = (*ft_sim->nonconvErr)((void *) (ft_curckt->ci_ckt), 0);
printf("%s", msg);
/*
if (ft_curckt) {
msg = (*ft_sim->nonconvErr)((void *) (ft_curckt->ci_ckt), 0);
fprintf(cp_out, "%s", msg);
} else {
fprintf(cp_err, "Error: no circuit loaded.\n");
}
*/
}

View File

@ -1,3 +1,26 @@
2001-11-25 Emmanuel Rouat <emmanuel.rouat@wanadoo.fr>
* ftedefs.h: added definition of structure circ (taken from circuits.h)
2000-09-09 Arno W. Peters <A.W.Peters@ieee.org>
* fteext.h: Removed prototype for com_fourier(). Use
src/frontend/fourier.h for the proper prototype.
2000-07-18 Arno W. Peters <A.W.Peters@ieee.org>
* cpdefs.h: Moved quote() and strip() macro's to ...
* wordlist.h: ... here. Also added ANSI C prototypes for all
functions that manipulate wordlists.
* defines.h: Removed CAPZEROBYPASS, NEWCONV and CAPBYPASS as they
are no longer used in the code.
2000-05-22 Paolo Nenzi <p.nenzi@ieee.org>
* inpptree.h: Applied Widlok patch (u2 function).
1999-11-30 Emmanuel Rouat <emmanuel.rouat@wanadoo.fr>
* ngspice.h: substitutes spice.h

View File

@ -1,59 +1,60 @@
## Process this file with automake to produce Makefile.in
noinst_HEADERS = \
acdefs.h \
arch.h \
cktdefs.h \
complex.h \
const.h \
cpdefs.h \
cpextern.h \
cpstd.h \
defines.h \
devdefs.h \
dgen.h \
distodef.h \
ftecmath.h \
fteconst.h \
ftedata.h \
ftedbgra.h \
ftedebug.h \
ftedefs.h \
ftedev.h \
fteext.h \
ftegraf.h \
ftegraph.h \
ftehelp.h \
fteinp.h \
fteinput.h \
fteparse.h \
gendefs.h \
hlpdefs.h \
iferrmsg.h \
ifsim.h \
inpdefs.h \
inpmacs.h \
inpptree.h \
jobdefs.h \
macros.h \
missing_math.h \
ngspice.h \
noisedef.h \
opdefs.h \
optdefs.h \
pzdefs.h \
sen2defs.h \
sensdefs.h \
sensgen.h \
smpdefs.h \
spconfig.h \
sperror.h \
spmatrix.h \
struct.h \
suffix.h \
tfdefs.h \
trandefs.h \
trcvdefs.h \
tskdefs.h
acdefs.h \
bool.h \
cktdefs.h \
complex.h \
const.h \
cpdefs.h \
cpextern.h \
cpstd.h \
defines.h \
devdefs.h \
dgen.h \
distodef.h \
dvec.h \
ftedbgra.h \
ftedebug.h \
ftedefs.h \
ftedev.h \
fteext.h \
fteinp.h \
fteinput.h \
fteparse.h \
gendefs.h \
graph.h \
grid.h \
hlpdefs.h \
iferrmsg.h \
ifsim.h \
inpdefs.h \
inpmacs.h \
inpptree.h \
jobdefs.h \
macros.h \
memory.h \
missing_math.h \
ngspice.h \
noisedef.h \
opdefs.h \
optdefs.h \
plot.h \
pnode.h \
pzdefs.h \
sen2defs.h \
sensdefs.h \
sensgen.h \
sim.h \
smpdefs.h \
sperror.h \
spmatrix.h \
suffix.h \
terminal.h \
tfdefs.h \
trandefs.h \
trcvdefs.h \
tskdefs.h \
wordlist.h
MAINTAINERCLEANFILES = Makefile.in

View File

@ -1,14 +1,23 @@
/*
* Copyright (c) 1985 Thomas L. Quarles
* Modified 1999 Paolo Nenzi - Removed non STDC definitions
* Modified 2000 AlansFixes
*/
#ifndef CKT
#define CKT "CKTdefs.h $Revision$ on $Date$ "
#define MAXNUMDEVS 32 /* Max number of possible devices; */
extern int DEVmaxnum; /* Not sure if still used */
#define MAXNUMDEVNODES 4 /* Max No. of nodes per device */
/* Need to change for SOI devs ? */
/* gtri - evt - wbk - 5/20/91 - add event-driven and enhancements data */
#ifdef XSPICE
#include "evt.h"
#include "enh.h"
#endif
/* gtri - evt - wbk - 5/20/91 - add event-driven and enhancements data */
#define MAXNUMDEVS 40 /* Max number of possible devices PN:XXX may cause toubles*/
extern int DEVmaxnum; /* Not sure if still used */
#define MAXNUMDEVNODES 4 /* Max No. of nodes per device */
/* Need to change for SOI devs ? */
#include "smpdefs.h"
#include "ifsim.h"
@ -31,13 +40,13 @@ typedef struct sCKTnode {
#define NODE_VOLTAGE SP_VOLTAGE
#define NODE_CURRENT SP_CURRENT
int number; /* Number of the node */
double ic; /* Value of the initial condition */
double nodeset; /* Value of the .nodeset option */
double *ptr; /* ??? */
struct sCKTnode *next; /* pointer to the next node */
unsigned int icGiven:1; /* FLAG ic given */
unsigned int nsGiven:1; /* FLAG nodeset given */
int number; /* Number of the node */
double ic; /* Value of the initial condition */
double nodeset; /* Value of the .nodeset option */
double *ptr; /* ??? */
struct sCKTnode *next; /* pointer to the next node */
unsigned int icGiven:1; /* FLAG ic given */
unsigned int nsGiven:1; /* FLAG nodeset given */
} CKTnode;
/* defines for node parameters */
@ -48,11 +57,23 @@ typedef struct sCKTnode {
typedef struct {
GENmodel *CKThead[MAXNUMDEVS]; /* The max number of loadable devices */
STATistics *CKTstat; /* The STATistics structure */
double *(CKTstates[8]); /* Used as memory of past steps ??? */
/* Some shortcut for CKTstates */
/* gtri - begin - wbk - change declaration to allow dynamic sizing */
/* An associated change is made in CKTinit.c to alloc the space */
/* required for the pointers. No changes are needed to the source */
/* code at the 3C1 level, although the compiler will generate */
/* slightly different code for references to this data. */
GENmodel **CKThead; /*The max number of loadable devices */
/* gtri - end - wbk - change declaration to allow dynamic sizing */
STATistics *CKTstat; /* The STATistics structure */
double *(CKTstates[8]); /* Used as memory of past steps ??? */
/* Some shortcut for CKTstates */
#define CKTstate0 CKTstates[0]
#define CKTstate1 CKTstates[1]
#define CKTstate2 CKTstates[2]
@ -61,40 +82,44 @@ typedef struct {
#define CKTstate5 CKTstates[5]
#define CKTstate6 CKTstates[6]
#define CKTstate7 CKTstates[7]
double CKTtime; /* ??? */
double CKTdelta; /* ??? */
double CKTdeltaOld[7]; /* Memory for ??? */
double CKTtemp; /* Actual temperature of CKT */
double CKTnomTemp; /* Reference temperature 27 C ? */
double CKTvt; /* Thernmal voltage at CKTtemp */
double CKTag[7]; /* the gear variable coefficient matrix */
double CKTtime; /* ??? */
double CKTdelta; /* ??? */
double CKTdeltaOld[7]; /* Memory for ??? */
double CKTtemp; /* Actual temperature of CKT */
double CKTnomTemp; /* Reference temperature 27 C ? */
double CKTvt; /* Thernmal voltage at CKTtemp */
double CKTag[7]; /* the gear variable coefficient matrix */
#ifdef PREDICTOR
double CKTagp[7]; /* the gear predictor variable coefficient matrix */
double CKTagp[7]; /* the gear predictor variable
coefficient matrix */
#endif /*PREDICTOR*/
int CKTorder; /* the integration method order */
int CKTmaxOrder; /* maximum integration method order */
int CKTintegrateMethod; /* the integration method to be used */
int CKTorder; /* the integration method order */
int CKTmaxOrder; /* maximum integration method order */
int CKTintegrateMethod; /* the integration method to be used */
/* known integration methods */
#define TRAPEZOIDAL 1
#define GEAR 2
SMPmatrix *CKTmatrix; /* pointer to sparse matrix */
int CKTniState; /* internal state */
double *CKTrhs; /* current rhs value - being loaded */
double *CKTrhsOld; /* previous rhs value for convergence testing */
double *CKTrhsSpare; /* spare rhs value for reordering */
double *CKTirhs; /* current rhs value - being loaded (imag) */
double *CKTirhsOld; /* previous rhs value (imaginary)*/
double *CKTirhsSpare; /* spare rhs value (imaginary)*/
SMPmatrix *CKTmatrix; /* pointer to sparse matrix */
int CKTniState; /* internal state */
double *CKTrhs; /* current rhs value - being loaded */
double *CKTrhsOld; /* previous rhs value for convergence
testing */
double *CKTrhsSpare; /* spare rhs value for reordering */
double *CKTirhs; /* current rhs value - being loaded
(imag) */
double *CKTirhsOld; /* previous rhs value (imaginary)*/
double *CKTirhsSpare; /* spare rhs value (imaginary)*/
#ifdef PREDICTOR
double *CKTpred; /* predicted solution vector */
double *CKTsols[8]; /* previous 8 solutions */
double *CKTpred; /* predicted solution vector */
double *CKTsols[8]; /* previous 8 solutions */
#endif /* PREDICTOR */
double *CKTrhsOp; /* opearating point values */
double *CKTsenRhs; /* current sensitivity rhs values */
double *CKTseniRhs; /* current sensitivity rhs values (imag)*/
double *CKTrhsOp; /* opearating point values */
double *CKTsenRhs; /* current sensitivity rhs values */
double *CKTseniRhs; /* current sensitivity rhs values
(imag)*/
/*
@ -112,19 +137,21 @@ typedef struct {
#define NIDIDPREORDER 0x100
#define NIPZSHOULDREORDER 0x200
int CKTmaxEqNum; /* And this ? */
int CKTcurrentAnalysis; /* the analysis in progress (if any) */
int CKTmaxEqNum; /* And this ? */
int CKTcurrentAnalysis; /* the analysis in progress (if any) */
/* defines for the value of CKTcurrentAnalysis */
/* are in TSKdefs.h */
CKTnode *CKTnodes; /* ??? */
CKTnode *CKTlastNode; /* ??? */
CKTnode *CKTnodes; /* ??? */
CKTnode *CKTlastNode; /* ??? */
/* This define should be somewhere else ??? */
/* This define should be somewhere else ??? */
#define NODENAME(ckt,nodenum) CKTnodName(ckt,nodenum)
int CKTnumStates; /* Number of sates effectively valid ??? */
long CKTmode; /* Mode of operation of the circuit ??? */
int CKTnumStates; /* Number of sates effectively valid
??? */
long CKTmode; /* Mode of operation of the circuit
??? */
/* defines for CKTmode */
@ -151,68 +178,85 @@ typedef struct {
/* old 'nosolv' paramater */
#define MODEUIC 0x10000l
int CKTbypass; /* bypass option, how does it work ? */
int CKTdcMaxIter; /* iteration limit for dc op. (itl1) */
int CKTdcTrcvMaxIter; /* iteration limit for dc tran. curv (itl2) */
int CKTtranMaxIter; /* iteration limit for each timepoint for tran*/
/* (itl4) */
int CKTbreakSize; /* ??? */
int CKTbreak; /* ??? */
double CKTsaveDelta; /* ??? */
double CKTminBreak; /* ??? */
double *CKTbreaks; /* List of breakpoints ??? */
double CKTabstol; /* --- */
double CKTpivotAbsTol; /* --- */
double CKTpivotRelTol; /* --- */
double CKTreltol; /* --- */
double CKTchgtol; /* --- */
double CKTvoltTol; /* --- */
/* What is this define for ? */
int CKTbypass; /* bypass option, how does it work ? */
int CKTdcMaxIter; /* iteration limit for dc op. (itl1) */
int CKTdcTrcvMaxIter; /* iteration limit for dc tran. curv
(itl2) */
int CKTtranMaxIter; /* iteration limit for each timepoint
for tran*/
/* (itl4) */
int CKTbreakSize; /* ??? */
int CKTbreak; /* ??? */
double CKTsaveDelta; /* ??? */
double CKTminBreak; /* ??? */
double *CKTbreaks; /* List of breakpoints ??? */
double CKTabstol; /* --- */
double CKTpivotAbsTol; /* --- */
double CKTpivotRelTol; /* --- */
double CKTreltol; /* --- */
double CKTchgtol; /* --- */
double CKTvoltTol; /* --- */
/* What is this define for ? */
#ifdef NEWTRUNC
double CKTlteReltol;
double CKTlteAbstol;
#endif /* NEWTRUNC */
double CKTgmin; /* Parallel Conductance --- */
double CKTdelmin; /* ??? */
double CKTtrtol; /* ??? */
double CKTfinalTime; /* ??? */
double CKTstep; /* ??? */
double CKTmaxStep; /* ??? */
double CKTinitTime; /* ??? */
double CKTomega; /* ??? */
double CKTsrcFact; /* ??? */
double CKTdiagGmin; /* ??? */
int CKTnumSrcSteps; /* ??? */
int CKTnumGminSteps; /* ??? */
int CKTnoncon; /* ??? */
double CKTdefaultMosL; /* Default Channel Lenght of MOS devices */
double CKTdefaultMosW; /* Default Channel Width of MOS devics */
double CKTdefaultMosAD; /* Default Drain Area of MOS */
double CKTdefaultMosAS; /* Default Source Area of MOS */
unsigned int CKThadNodeset:1; /* ??? */
unsigned int CKTfixLimit:1; /* flag to indicate that the limiting of
* MOSFETs should be done as in SPICE2 */
unsigned int CKTnoOpIter:1; /* flag to indicate not to try the operating
* point brute force, but to use gmin stepping
* first */
unsigned int CKTisSetup:1; /* flag to indicate if CKTsetup done */
JOB *CKTcurJob; /* Next analysis to be performed ??? */
double CKTgmin; /* Parallel Conductance --- */
double CKTgshunt;
double CKTdelmin; /* ??? */
double CKTtrtol; /* ??? */
double CKTfinalTime; /* ??? */
double CKTstep; /* ??? */
double CKTmaxStep; /* ??? */
double CKTinitTime; /* ??? */
double CKTomega; /* ??? */
double CKTsrcFact; /* ??? */
double CKTdiagGmin; /* ??? */
int CKTnumSrcSteps; /* ??? */
int CKTnumGminSteps; /* ??? */
double CKTgminFactor;
int CKTnoncon; /* ??? */
double CKTdefaultMosM;
double CKTdefaultMosL; /* Default Channel Lenght of MOS devices */
double CKTdefaultMosW; /* Default Channel Width of MOS devics */
double CKTdefaultMosAD; /* Default Drain Area of MOS */
double CKTdefaultMosAS; /* Default Source Area of MOS */
unsigned int CKThadNodeset:1; /* ??? */
unsigned int CKTfixLimit:1; /* flag to indicate that the limiting
of MOSFETs should be done as in
SPICE2 */
unsigned int CKTnoOpIter:1; /* flag to indicate not to try the operating
point brute force, but to use gmin stepping
first */
unsigned int CKTisSetup:1; /* flag to indicate if CKTsetup done */
JOB *CKTcurJob; /* Next analysis to be performed ??? */
SENstruct *CKTsenInfo; /* the sensitivity information */
double *CKTtimePoints; /* list of all accepted timepoints in the
SENstruct *CKTsenInfo; /* the sensitivity information */
double *CKTtimePoints; /* list of all accepted timepoints in
the current transient simulation */
double *CKTdeltaList; /* list of all timesteps in the
current transient simulation */
double *CKTdeltaList; /* list of all timesteps in the current
transient simulation */
int CKTtimeListSize; /* size of above lists */
int CKTtimeIndex; /* current position in above lists */
int CKTsizeIncr; /* amount to increment size of above arrays
when you run out of space */
unsigned int CKTtryToCompact:1; /* try to compact past history for LTRA
lines */
unsigned int CKTbadMos3:1; /* Use old, unfixed MOS3 equations */
unsigned int CKTkeepOpInfo:1; /* flag for small signal analyses */
int CKTtroubleNode; /* Non-convergent node number */
GENinstance *CKTtroubleElt; /* Non-convergent device instance */
int CKTtimeListSize; /* size of above lists */
int CKTtimeIndex; /* current position in above lists */
int CKTsizeIncr; /* amount to increment size of above
arrays when you run out of space */
unsigned int CKTtryToCompact:1; /* try to compact past history for LTRA
lines */
unsigned int CKTbadMos3:1; /* Use old, unfixed MOS3 equations */
unsigned int CKTkeepOpInfo:1; /* flag for small signal analyses */
unsigned int CKTcopyNodesets:1; /* NodesetFIX */
unsigned int CKTnodeDamping:1; /* flag for node damping fix */
double CKTabsDv; /* abs limit for iter-iter voltage change */
double CKTrelDv; /* rel limit for iter-iter voltage change */
int CKTtroubleNode; /* Non-convergent node number */
GENinstance *CKTtroubleElt; /* Non-convergent device instance */
/* gtri - evt - wbk - 5/20/91 - add event-driven and enhancements data */
#ifdef XSPICE
Evt_Ckt_Data_t *evt; /* all data about event driven stuff */
Enh_Ckt_Data_t *enh; /* data used by general enhancements */
#endif
/* gtri - evt - wbk - 5/20/91 - add event-driven and enhancements data */
} CKTcircuit;
@ -241,6 +285,7 @@ extern int CKTdltMod( void *, void *);
extern int CKTdltNod( void *, void *);
extern int CKTdoJob( void *, int , void *);
extern void CKTdump( CKTcircuit *, double, void *);
extern void CKTncDump(CKTcircuit *);
extern int CKTfndAnal( void *, int *, void **, IFuid , void *, IFuid );
extern int CKTfndBranch( CKTcircuit *, IFuid);
extern int CKTfndDev( void *, int *, void **, IFuid , void *, IFuid );
@ -289,7 +334,7 @@ extern int CKTsetBreak( CKTcircuit *, double );
extern int CKTsetNodPm( void *, void *, int , IFvalue *, IFvalue *);
extern int CKTsetOpt( void *, void *, int , IFvalue *);
extern int CKTsetup( CKTcircuit *);
extern int CKTunsetup(CKTcircuit *ckt);
extern int CKTunsetup(CKTcircuit *);
extern int CKTtemp( CKTcircuit *);
extern char *CKTtrouble(void *, char *);
extern void CKTterr( int , CKTcircuit *, double *);
@ -314,7 +359,6 @@ extern void SENdestroy( SENstruct *);
extern int SENsetParm( CKTcircuit *, void *, int , IFvalue *);
extern int SENstartup( CKTcircuit *);
extern int SPIinit( IFfrontEnd *, IFsimulator **);
extern char * SPerror( int );
extern int TFanal( CKTcircuit *, int );
extern int TFaskQuest( CKTcircuit *, void *, int , IFvalue *);
extern int TFsetParm( CKTcircuit *, void *, int , IFvalue *);
@ -334,6 +378,7 @@ extern int NIpzSym(PZtrial **, PZtrial *);
extern int NIpzSym2(PZtrial **, PZtrial *);
extern int NIreinit( CKTcircuit *);
extern int NIsenReinit( CKTcircuit *);
extern int NIdIter (CKTcircuit *);
extern IFfrontEnd *SPfrontEnd;
#endif /*CKT*/

View File

@ -1,12 +1,24 @@
/*
* Copyright (c) 1985 Thomas L. Quarles
* Modified: Paolo Nenzi 1999
* Modified: 1999 Paolo Nenzi, 2000 Arno W. Peters
*/
#ifndef CMPLX
#define CMPLX "complex.h $Revision$ on $Date$ "
#ifndef _COMPLEX_H
#define _COMPLEX_H
/* header file containing definitions for complex functions
*
/* Complex numbers. */
struct _complex1 { /* IBM portability... */
double cx_real;
double cx_imag;
} ;
typedef struct _complex1 complex;
#define realpart(cval) ((struct _complex1 *) (cval))->cx_real
#define imagpart(cval) ((struct _complex1 *) (cval))->cx_imag
/*
* Each expects two arguments for each complex number - a real and an
* imaginary part.
*/
@ -15,26 +27,62 @@ typedef struct {
double imag;
} SPcomplex;
/*
* COMPLEX NUMBER DATA STRUCTURE
*
* >>> Structure fields:
* Real (RealNumber)
* The real portion of the number. Real must be the first
* field in this structure.
* Imag (RealNumber)
* The imaginary portion of the number. This field must follow
* immediately after Real.
*/
#define spREAL double
/* Begin `RealNumber'. */
typedef spREAL RealNumber, *RealVector;
/* Begin `ComplexNumber'. */
typedef struct
{ RealNumber Real;
RealNumber Imag;
} ComplexNumber, *ComplexVector;
/* Some defines used mainly in cmath.c. */
#define FTEcabs(d) (((d) < 0.0) ? - (d) : (d))
#define cph(c) (atan2(imagpart(c), (realpart(c))))
#define cmag(c) (sqrt(imagpart(c) * imagpart(c) + realpart(c) * realpart(c)))
#define radtodeg(c) (cx_degrees ? ((c) / 3.14159265358979323846 * 180) : (c))
#define degtorad(c) (cx_degrees ? ((c) * 3.14159265358979323846 / 180) : (c))
#define rcheck(cond, name) if (!(cond)) { \
fprintf(cp_err, "Error: argument out of range for %s\n", name); \
return (NULL); }
#define cdiv(r1, i1, r2, i2, r3, i3) \
{ \
double r, s; \
if (FTEcabs(r2) > FTEcabs(i2)) { \
r = (i2) / (r2); \
s = (r2) + r * (i2); \
(r3) = ((r1) + r * (i1)) / s; \
(i3) = ((i1) - r * (r1)) / s; \
} else { \
r = (r2) / (i2); \
s = (i2) + r * (r2); \
(r3) = (r * (r1) + (i1)) / s; \
(i3) = (r * (i1) - (r1)) / s; \
} \
}
#define DC_ABS(a,b) (fabs(a) + fabs(b))
/* Why that ??? */
#ifdef notdef
#define DC_DIV(a,b,c,d,x,y) { \
double r,s;\
if(fabs(c)>fabs(d)) { \
r=(d)/(c);\
s=(c)+r*(d);\
x=((a)+(b)*r)/s;\
y=((b)-(a)*r)/s;\
} else { \
r=(c)/(d);\
s=(d)+r*(c);\
x=((a)*r+(b))/s;\
y=((b)*r-(a))/s;\
}\
}
#endif /*notdef */
/*
* Division among complex numbers
@ -67,14 +115,6 @@ typedef struct {
}
/* Why that ??? */
#ifdef notdef
#define DC_MINUS(a,b,c,d,x,y) { \
(x) = (a) - (c) ;\
(y) = (b) - (d) ;\
}
#endif /*notdef*/
/*
* Difference among complex numbers a+jb and c+jd
* a = a - c amd b = b - d
@ -227,6 +267,225 @@ typedef struct {
(A).imag = (B.imag) - (C.imag); \
}
/* Macro function that returns the approx absolute value of a complex
number. */
#define ELEMENT_MAG(ptr) (ABS((ptr)->Real) + ABS((ptr)->Imag))
/* Complex assignment statements. */
#define CMPLX_ASSIGN(to,from) \
{ (to).Real = (from).Real; \
(to).Imag = (from).Imag; \
}
#define CMPLX_CONJ_ASSIGN(to,from) \
{ (to).Real = (from).Real; \
(to).Imag = -(from).Imag; \
}
#define CMPLX_NEGATE_ASSIGN(to,from) \
{ (to).Real = -(from).Real; \
(to).Imag = -(from).Imag; \
}
#define CMPLX_CONJ_NEGATE_ASSIGN(to,from) \
{ (to).Real = -(from).Real; \
(to).Imag = (from).Imag; \
}
#define CMPLX_CONJ(a) (a).Imag = -(a).Imag
#define CMPLX_NEGATE(a) \
{ (a).Real = -(a).Real; \
(a).Imag = -(a).Imag; \
}
/* Macro that returns the approx magnitude (L-1 norm) of a complex number. */
#define CMPLX_1_NORM(a) (ABS((a).Real) + ABS((a).Imag))
/* Macro that returns the approx magnitude (L-infinity norm) of a complex. */
#define CMPLX_INF_NORM(a) (MAX (ABS((a).Real),ABS((a).Imag)))
/* Macro function that returns the magnitude (L-2 norm) of a complex number. */
#define CMPLX_2_NORM(a) (sqrt((a).Real*(a).Real + (a).Imag*(a).Imag))
/* Macro function that performs complex addition. */
#define CMPLX_ADD(to,from_a,from_b) \
{ (to).Real = (from_a).Real + (from_b).Real; \
(to).Imag = (from_a).Imag + (from_b).Imag; \
}
/* Macro function that performs complex subtraction. */
#define CMPLX_SUBT(to,from_a,from_b) \
{ (to).Real = (from_a).Real - (from_b).Real; \
(to).Imag = (from_a).Imag - (from_b).Imag; \
}
/* Macro function that is equivalent to += operator for complex numbers. */
#define CMPLX_ADD_ASSIGN(to,from) \
{ (to).Real += (from).Real; \
(to).Imag += (from).Imag; \
}
/* Macro function that is equivalent to -= operator for complex numbers. */
#define CMPLX_SUBT_ASSIGN(to,from) \
{ (to).Real -= (from).Real; \
(to).Imag -= (from).Imag; \
}
/* Macro function that multiplies a complex number by a scalar. */
#define SCLR_MULT(to,sclr,cmplx) \
{ (to).Real = (sclr) * (cmplx).Real; \
(to).Imag = (sclr) * (cmplx).Imag; \
}
/* Macro function that multiply-assigns a complex number by a scalar. */
#define SCLR_MULT_ASSIGN(to,sclr) \
{ (to).Real *= (sclr); \
(to).Imag *= (sclr); \
}
/* Macro function that multiplies two complex numbers. */
#define CMPLX_MULT(to,from_a,from_b) \
{ (to).Real = (from_a).Real * (from_b).Real - \
(from_a).Imag * (from_b).Imag; \
(to).Imag = (from_a).Real * (from_b).Imag + \
(from_a).Imag * (from_b).Real; \
}
/* Macro function that implements to *= from for complex numbers. */
#define CMPLX_MULT_ASSIGN(to,from) \
{ RealNumber to_real_ = (to).Real; \
(to).Real = to_real_ * (from).Real - \
(to).Imag * (from).Imag; \
(to).Imag = to_real_ * (from).Imag + \
(to).Imag * (from).Real; \
}
/* Macro function that multiplies two complex numbers, the first of which is
* conjugated. */
#define CMPLX_CONJ_MULT(to,from_a,from_b) \
{ (to).Real = (from_a).Real * (from_b).Real + \
(from_a).Imag * (from_b).Imag; \
(to).Imag = (from_a).Real * (from_b).Imag - \
(from_a).Imag * (from_b).Real; \
}
/* Macro function that multiplies two complex numbers and then adds them
* to another. to = add + mult_a * mult_b */
#define CMPLX_MULT_ADD(to,mult_a,mult_b,add) \
{ (to).Real = (mult_a).Real * (mult_b).Real - \
(mult_a).Imag * (mult_b).Imag + (add).Real; \
(to).Imag = (mult_a).Real * (mult_b).Imag + \
(mult_a).Imag * (mult_b).Real + (add).Imag; \
}
/* Macro function that subtracts the product of two complex numbers from
* another. to = subt - mult_a * mult_b */
#define CMPLX_MULT_SUBT(to,mult_a,mult_b,subt) \
{ (to).Real = (subt).Real - (mult_a).Real * (mult_b).Real + \
(mult_a).Imag * (mult_b).Imag; \
(to).Imag = (subt).Imag - (mult_a).Real * (mult_b).Imag - \
(mult_a).Imag * (mult_b).Real; \
}
/* Macro function that multiplies two complex numbers and then adds them
* to another. to = add + mult_a* * mult_b where mult_a* represents mult_a
* conjugate. */
#define CMPLX_CONJ_MULT_ADD(to,mult_a,mult_b,add) \
{ (to).Real = (mult_a).Real * (mult_b).Real + \
(mult_a).Imag * (mult_b).Imag + (add).Real; \
(to).Imag = (mult_a).Real * (mult_b).Imag - \
(mult_a).Imag * (mult_b).Real + (add).Imag; \
}
/* Macro function that multiplies two complex numbers and then adds them
* to another. to += mult_a * mult_b */
#define CMPLX_MULT_ADD_ASSIGN(to,from_a,from_b) \
{ (to).Real += (from_a).Real * (from_b).Real - \
(from_a).Imag * (from_b).Imag; \
(to).Imag += (from_a).Real * (from_b).Imag + \
(from_a).Imag * (from_b).Real; \
}
/* Macro function that multiplies two complex numbers and then subtracts them
* from another. */
#define CMPLX_MULT_SUBT_ASSIGN(to,from_a,from_b) \
{ (to).Real -= (from_a).Real * (from_b).Real - \
(from_a).Imag * (from_b).Imag; \
(to).Imag -= (from_a).Real * (from_b).Imag + \
(from_a).Imag * (from_b).Real; \
}
/* Macro function that multiplies two complex numbers and then adds them
* to the destination. to += from_a* * from_b where from_a* represents from_a
* conjugate. */
#define CMPLX_CONJ_MULT_ADD_ASSIGN(to,from_a,from_b) \
{ (to).Real += (from_a).Real * (from_b).Real + \
(from_a).Imag * (from_b).Imag; \
(to).Imag += (from_a).Real * (from_b).Imag - \
(from_a).Imag * (from_b).Real; \
}
/* Macro function that multiplies two complex numbers and then subtracts them
* from the destination. to -= from_a* * from_b where from_a* represents from_a
* conjugate. */
#define CMPLX_CONJ_MULT_SUBT_ASSIGN(to,from_a,from_b) \
{ (to).Real -= (from_a).Real * (from_b).Real + \
(from_a).Imag * (from_b).Imag; \
(to).Imag -= (from_a).Real * (from_b).Imag - \
(from_a).Imag * (from_b).Real; \
}
/*
* Macro functions that provide complex division.
*/
/* Complex division: to = num / den */
#define CMPLX_DIV(to,num,den) \
{ RealNumber r_, s_; \
if (((den).Real >= (den).Imag AND (den).Real > -(den).Imag) OR \
((den).Real < (den).Imag AND (den).Real <= -(den).Imag)) \
{ r_ = (den).Imag / (den).Real; \
s_ = (den).Real + r_*(den).Imag; \
(to).Real = ((num).Real + r_*(num).Imag)/s_; \
(to).Imag = ((num).Imag - r_*(num).Real)/s_; \
} \
else \
{ r_ = (den).Real / (den).Imag; \
s_ = (den).Imag + r_*(den).Real; \
(to).Real = (r_*(num).Real + (num).Imag)/s_; \
(to).Imag = (r_*(num).Imag - (num).Real)/s_; \
} \
}
/* Complex division and assignment: num /= den */
#define CMPLX_DIV_ASSIGN(num,den) \
{ RealNumber r_, s_, t_; \
if (((den).Real >= (den).Imag AND (den).Real > -(den).Imag) OR \
((den).Real < (den).Imag AND (den).Real <= -(den).Imag)) \
{ r_ = (den).Imag / (den).Real; \
s_ = (den).Real + r_*(den).Imag; \
t_ = ((num).Real + r_*(num).Imag)/s_; \
(num).Imag = ((num).Imag - r_*(num).Real)/s_; \
(num).Real = t_; \
} \
else \
{ r_ = (den).Real / (den).Imag; \
s_ = (den).Imag + r_*(den).Real; \
t_ = (r_*(num).Real + (num).Imag)/s_; \
(num).Imag = (r_*(num).Imag - (num).Real)/s_; \
(num).Real = t_; \
} \
}
/* Complex reciprocation: to = 1.0 / den */
#define CMPLX_RECIPROCAL(to,den) \
{ RealNumber r_; \
if (((den).Real >= (den).Imag && (den).Real > -(den).Imag) || \
((den).Real < (den).Imag && (den).Real <= -(den).Imag)) \
{ r_ = (den).Imag / (den).Real; \
(to).Imag = -r_*((to).Real = 1.0/((den).Real + r_*(den).Imag)); \
} \
else \
{ r_ = (den).Real / (den).Imag; \
(to).Real = -r_*((to).Imag = -1.0/((den).Imag + r_*(den).Real));\
} \
}
#endif /*CMPLX*/
#endif /*_COMPLEX_H */

View File

@ -18,17 +18,38 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
/* Information about spice commands. */
struct comm {
char *co_comname; /* The name of the command. */
void (*co_func) (); /* The function that handles the command. */
bool co_stringargs; /* Collapse the arguments into a string. */
bool co_spiceonly; /* These can't be used from nutmeg. */
bool co_major; /* Is this a "major" command? */
long co_cctypes[4]; /* Bitmasks for command completion. */
unsigned int co_env;/* print help message on this environment mask */
int co_minargs; /* minimum number of arguments required */
int co_maxargs; /* maximum number of arguments allowed */
int (*co_argfn) (); /* The fn that prompts the user. */
char *co_help; /* When these are printed, printf(string, av[0]) .. */
/* The name of the command. */
char *co_comname;
/* The function that handles the command. */
void (*co_func) (wordlist *wl);
/* Collapse the arguments into a string. */
bool co_stringargs;
/* These can't be used from nutmeg. */
bool co_spiceonly;
/* Is this a "major" command? */
bool co_major;
/* Bitmasks for command completion. */
long co_cctypes[4];
/* print help message on this environment mask */
unsigned int co_env;
/* minimum number of arguments required */
int co_minargs;
/* maximum number of arguments allowed */
int co_maxargs;
/* The fn that prompts the user. */
void (*co_argfn) (wordlist *wl, struct comm *command);
/* When these are printed, printf(string, av[0]) .. */
char *co_help;
};
#define LOTS 1000
@ -44,34 +65,7 @@ struct histent {
struct histent *hi_prev;
};
/* Variables that are accessible to the parser via $varname expansions.
* If the type is VT_LIST the value is a pointer to a list of the elements.
*/
struct variable {
char va_type;
char *va_name;
union {
bool vV_bool;
int vV_num;
double vV_real;
char *vV_string;
struct variable *vV_list;
} va_V;
struct variable *va_next; /* Link. */
} ;
#define va_bool va_V.vV_bool
#define va_num va_V.vV_num
#define va_real va_V.vV_real
#define va_string va_V.vV_string
#define va_vlist va_V.vV_list
#define VT_BOOL 1
#define VT_NUM 2
#define VT_REAL 3
#define VT_STRING 4
#define VT_LIST 5
/* The values returned by cp_userset(). */
@ -97,14 +91,6 @@ struct alias {
#define CPC_BRR 004 /* Break word to right of character. */
#define CPC_BRL 010 /* Break word to left of character. */
/* For quoting individual characters. '' strings are all quoted, but `` and
* "" strings are maintained as single words with the quotes around them.
* Note that this won't work on non-ascii machines.
*/
#define quote(c) ((c) | 0200)
#define strip(c) ((c) & 0177)
#define CT_ALIASES 1
#define CT_LABEL 15

View File

@ -1,6 +1,7 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1986 Wayne A. Christopher, U. C. Berkeley CAD Group
Modified: 2000 AlansFixes
**********/
/*
@ -10,6 +11,10 @@ Author: 1986 Wayne A. Christopher, U. C. Berkeley CAD Group
#ifndef CPEXTERN_H
#define CPEXTERN_H
#include "wordlist.h"
#include "bool.h"
/* alias.c */
extern struct alias *cp_aliases;
@ -18,6 +23,7 @@ extern void com_unalias();
extern void cp_paliases();
extern void cp_setalias();
extern void cp_unalias();
extern wordlist *cp_doalias();
/* backquote.c */
@ -95,7 +101,7 @@ extern int cp_maxhistlength;
extern struct histent *cp_lastone;
extern void com_history();
extern void cp_addhistent();
extern void cp_hprint();
void cp_hprint(int eventhi, int eventlo, bool rev);
extern wordlist *cp_histsubst();
/* lexical.c */
@ -123,6 +129,7 @@ extern bool out_isatty;
extern void out_init();
#ifndef out_printf
/* don't want to declare it if we have #define'ed it */
extern void out_printf();
#endif
extern void out_send();
@ -141,7 +148,7 @@ extern void cp_printword(char *string, FILE *fp);
extern bool cp_unixcom();
extern void cp_hstat();
extern void cp_rehash();
void cp_rehash(char *pathlist, bool docc);
/* variable.c */
@ -153,33 +160,30 @@ extern bool cp_nonomatch;
extern char cp_dol;
extern void cp_remvar(char *varname);
extern void cp_vset(char *varname, char type, char *value);
extern wordlist *cp_varwl(struct variable *var);
extern struct variable *cp_setparse(wordlist *wl);
/* var2.c */
extern wordlist *vareval(char *string);
extern wordlist *cp_variablesubst(wordlist *wlist);
extern void cp_vprint(void);
extern void com_set(wordlist *wl);
extern void com_option(wordlist *wl);
extern void com_state(wordlist *wl);
extern void com_unset(wordlist *wl);
extern void com_shift(wordlist *wl);
extern bool cp_getvar(char *name, int type, char *retval);
extern wordlist *cp_variablesubst(wordlist *wlist);
extern bool cp_getvar(char *name, int type, void *retval);
/* cpinterface.c etc -- stuff CP needs from FTE */
extern bool cp_istrue();
extern bool cp_istrue(wordlist *wl);
extern bool cp_oddcomm();
extern void cp_doquit();
extern void cp_periodic();
extern void ft_cpinit();
extern struct comm *cp_coms;
extern double *ft_numparse();
extern char *cp_program;
extern bool ft_nutmeg;
extern struct variable *cp_enqvar();
extern void cp_usrvars();
extern int cp_usrset();
int cp_usrset(struct variable *var, bool isset);
extern void fatal();
#endif

View File

@ -11,63 +11,30 @@ Author: 1986 Wayne A. Christopher, U. C. Berkeley CAD Group
#ifndef _STD_H_
#define _STD_H_
typedef int bool;
#ifndef FILE
/* XXX Bogus */
# include <stdio.h>
#endif
/* Doubly linked lists of words. */
/* FIXME: Split this file and adjust all callers to use new header files */
#if 0
#warning "Please use bool.h, wordlist.h or complex.h rather than cpstd.h"
#endif
struct wordlist {
char *wl_word;
struct wordlist *wl_next;
struct wordlist *wl_prev;
} ;
typedef struct wordlist wordlist;
/* Complex numbers. */
struct _complex { /* IBM portability... */
double cx_real;
double cx_imag;
} ;
typedef struct _complex complex;
#define realpart(cval) ((struct _complex *) (cval))->cx_real
#define imagpart(cval) ((struct _complex *) (cval))->cx_imag
#include "bool.h"
#include "wordlist.h"
#include "complex.h"
/* Externs defined in std.c */
extern char *getusername();
extern char *gethome();
extern char *tildexpand();
extern char *printnum();
extern void printnum();
extern int cp_numdgt;
extern void fatal();
/* extern void setenv(); */
extern void cp_printword();
/* Externs from wlist.c */
extern char **wl_mkvec();
extern char *wl_flatten();
extern int wl_length();
extern void wl_free();
extern void wl_print();
extern void wl_sort();
extern wordlist *wl_append();
extern wordlist *wl_build();
extern wordlist *wl_copy();
extern wordlist *wl_range();
extern wordlist *wl_nthelem();
extern wordlist *wl_reverse();
extern wordlist *wl_splice();
#endif /* _STD_H_*/

View File

@ -80,11 +80,6 @@
* #define-s that are always on
*/
#define CAPZEROBYPASS
#define NEWCONV
/* #define CAPBYPASS Internal use only */
/* On Unix the following should always be true, so they should jump out */
#define HAS_ASCII

View File

@ -13,7 +13,6 @@ Author: 1985 Thomas L. Quarles
#include "noisedef.h"
#include "complex.h"
#ifdef __STDC__
double DEVlimvds(double,double);
double DEVpnjlim(double,double,double,double,int*);
double DEVfetlim(double,double,double);
@ -21,30 +20,11 @@ void DEVcmeyer(double,double,double,double,double,double,double,double,double,
double,double,double*,double*,double*,double,double,double,double);
void DEVqmeyer(double,double,double,double,double,double*,double*,double*,
double,double);
#ifdef notdef
void DEVcap(CKTcircuit*, double, double, double, double, double, double,
double, double, double, double, double, double, double, double,
double*, double*, double*, double*, double*, double*, double*,
double*, double*, double*, double*, double*, double, double,
double, double*, double*, double);
#endif
double DEVpred(CKTcircuit*,int);
#else /* stdc */
double DEVlimvds();
double DEVpnjlim();
double DEVfetlim();
void DEVcmeyer();
void DEVqmeyer();
#ifdef notdef
void DEVcap();
#endif
double DEVpred();
#endif /* stdc */
typedef struct SPICEdev {
IFdevice DEVpublic;
#ifdef __STDC__
int (*DEVparam)(int,IFvalue*,GENinstance*,IFvalue *);
/* routine to input a parameter to a device instance */
int (*DEVmodParam)(int,IFvalue*,GENmodel*);
@ -100,50 +80,13 @@ typedef struct SPICEdev {
/* procedure to do distortion operations */
int (*DEVnoise)(int, int, GENmodel*,CKTcircuit*, Ndata *, double *);
/* noise routine */
#else /* stdc */
int (*DEVparam)(); /* routine to input a parameter to a device instance */
int (*DEVmodParam)(); /* routine to input a paramater to a model */
int (*DEVload)(); /* routine to load the device into the matrix */
int (*DEVsetup)(); /* setup routine to preprocess devices once before
* soloution begins */
int (*DEVunsetup)(); /* clean up before running again */
int (*DEVpzSetup)(); /* setup routine to process devices specially for
* pz analysis */
int (*DEVtemperature)(); /* subroutine to do temperature dependent
* setup processing */
int (*DEVtrunc)(); /* subroutine to perform truncation error calc. */
int (*DEVfindBranch)(); /* subroutine to search for device branch eq.s */
int (*DEVacLoad)(); /* ac analysis loading function */
int (*DEVaccept)(); /* subroutine to call on acceptance of a timepoint */
void (*DEVdestroy)(); /* subroutine to destroy all models and instances */
int (*DEVmodDelete)(); /* subroutine to delete a model and all instances */
int (*DEVdelete)(); /* subroutine to delete an instance */
int (*DEVsetic)(); /* routine to pick up device init conds from rhs */
int (*DEVask)(); /* routine to ask about device details*/
int (*DEVmodAsk)(); /* routine to ask about model details*/
int (*DEVpzLoad)(); /* routine to load for pole-zero analysis */
int (*DEVconvTest)(); /* convergence test function */
int (*DEVsenSetup)(); /* routine to setup the device sensitivity info */
int (*DEVsenLoad)(); /* routine to load the device sensitivity info */
int (*DEVsenUpdate)(); /* routine to update the device sensitivity info */
int (*DEVsenAcLoad)(); /* routine to load the device ac sensitivity info*/
void (*DEVsenPrint)(); /* subroutine to print out sensitivity info */
int (*DEVsenTrunc)(); /* subroutine to print out sensitivity info */
int (*DEVdisto)(); /* distortion routine */
int (*DEVnoise)(); /* noise routine */
#endif /* stdc */
int *DEVinstSize; /* size of an instance */
int *DEVmodSize; /* size of a model */
} SPICEdev; /* instance of structure for each possible type of device */
/* IOP( ) Input/output parameter
/* IOP( ) Input/output parameter
* IOPP( ) IO parameter which the principle value of a device (used
* for naming output variables in sensetivity)
* IOPA( ) IO parameter significant for time-varying (non-dc) analyses

View File

@ -1,6 +1,7 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1988 Jaijeet S Roychowdhury
Modified: 2000 AlansFixes
**********/
#ifndef DISTODEF
@ -198,18 +199,18 @@ extern double DFiF12(double, double, double, double,
extern double DFn2F12(DpassStr*);
extern double DFi2F12(DpassStr*);
extern void EqualDeriv(Dderivs *new, Dderivs *old);
extern void TimesDeriv(Dderivs *new, Dderivs *old, double k);
extern void InvDeriv(Dderivs *new, Dderivs *old);
extern void MultDeriv(Dderivs *new, Dderivs *old1, Dderivs *old2);
extern void CubeDeriv(Dderivs *new, Dderivs *old);
extern void PlusDeriv(Dderivs *new, Dderivs *old1, Dderivs *old2);
extern void SqrtDeriv(Dderivs *new, Dderivs *old);
extern void DivDeriv(Dderivs *new, Dderivs *old1, Dderivs *old2);
extern void PowDeriv(Dderivs *new, Dderivs *old, double emm);
extern void AtanDeriv(Dderivs *new, Dderivs *old);
extern void CosDeriv(Dderivs *new, Dderivs *old);
extern void ExpDeriv(Dderivs *new, Dderivs *old);
extern void EqualDeriv(Dderivs *, Dderivs *);
extern void TimesDeriv(Dderivs *, Dderivs *, double);
extern void InvDeriv(Dderivs *, Dderivs *);
extern void MultDeriv(Dderivs *, Dderivs *, Dderivs *);
extern void CubeDeriv(Dderivs *, Dderivs *);
extern void PlusDeriv(Dderivs *, Dderivs *, Dderivs *);
extern void SqrtDeriv(Dderivs *, Dderivs *);
extern void DivDeriv(Dderivs *, Dderivs *, Dderivs *);
extern void PowDeriv(Dderivs *, Dderivs *, double);
extern void AtanDeriv(Dderivs *, Dderivs *);
extern void CosDeriv(Dderivs *, Dderivs *);
extern void ExpDeriv(Dderivs *, Dderivs *);

View File

@ -16,6 +16,12 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
#include "fteparse.h"
#include "fteinp.h"
struct save_info {
char *name;
IFuid *analysis;
int used;
};
/* The curcuits that are currently available to the user. */
struct circ {
@ -41,15 +47,6 @@ struct circ {
char *ci_curOpt; /* the most recent options anal. for the circuit */
} ;
struct subcirc {
char *sc_name; /* Whatever... */
} ;
struct save_info {
char *name;
IFuid *analysis;
int used;
};
#define mylog10(xx) (((xx) > 0.0) ? log10(xx) : (- log10(HUGE)))

View File

@ -31,7 +31,7 @@ typedef struct {
int (*MakeMenu)();
int (*MakeDialog)();
int (*Input)();
int (*DatatoScreen)();
void (*DatatoScreen)();
} DISPDEVICE;
extern DISPDEVICE *dispdev;

View File

@ -1,7 +1,7 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1986 Wayne A. Christopher, U. C. Berkeley CAD Group
Modified: 1999 Paolo Nenzi
Modified: 1999 Paolo Nenzi - 2000 AlansFixes
**********/
/*
@ -15,15 +15,12 @@ Modified: 1999 Paolo Nenzi
/* needed to find out what the interface structures look like */
#include "ifsim.h"
#include "fteparse.h"
#include "dvec.h"
#include "plot.h"
#include "cpdefs.h"
#include "ftedefs.h"
#include "fteinp.h"
/* agraf.c */
extern void ft_agraf();
/* arg.c */
extern void arg_plot();
@ -52,6 +49,7 @@ extern bool ft_bpcheck();
extern void com_delete();
extern void com_iplot();
extern void com_save();
extern void com_save2(wordlist *, char *);
extern void com_step();
extern void com_stop();
extern void com_sttus();
@ -59,14 +57,18 @@ extern void com_trce();
extern void ft_trquery();
extern void dbfree( );
/* breakp2.c */
extern int ft_getSaves(struct save_info **);
/* circuits.c */
extern struct circ *ft_curckt;
extern struct circ *ft_circuits;
extern struct subcirc *ft_subcircuits;
extern void ft_setccirc();
extern void ft_newcirc();
extern void ft_newsubcirc();
/* clip.c */
@ -101,6 +103,11 @@ extern void *cx_mean(void *, short int , int , int *, short int *);
extern void *cx_length(void *, short int , int , int *, short int *);
extern void *cx_vector(void *, short int , int , int *, short int *);
extern void *cx_unitvec(void *, short int , int , int *, short int *);
/* Routoure JM : somme useful functions */
extern void *cx_min(void *, short int , int , int *, short int *);
extern void *cx_max(void *, short int , int , int *, short int *);
extern void *cx_d(void *, short int , int , int *, short int *);
extern void *cx_plus(void *, void *, short int , short int , int );
extern void *cx_minus(void *, void *, short int , short int , int );
@ -175,7 +182,7 @@ extern bool ft_nopage;
extern bool ft_nomod;
extern bool ft_nodesprint;
extern bool ft_optsprint;
extern int ft_cktcoms();
extern int ft_cktcoms(bool terse);
extern void ft_dotsaves();
extern int ft_savedotargs();
@ -185,6 +192,10 @@ extern void fatal();
extern void fperror();
extern void ft_sperror();
extern char ErrorMessage[];
extern void internalerror(char *);
extern void externalerror(char *);
/* evaluate.c */
@ -209,9 +220,6 @@ extern struct dvec *op_times();
extern struct dvec *op_uminus();
extern struct dvec *op_range();
/* fourier.c */
extern void com_fourier();
/* spec.c */
@ -244,7 +252,6 @@ extern void gi_update();
extern bool gr_gmode;
extern bool gr_hmode;
extern bool gr_init();
extern void gr_clean();
extern void gr_end();
extern void gr_iplot();
@ -270,9 +277,10 @@ extern void gr_fixgrid();
extern void com_edit();
extern void com_listing();
extern void com_source();
extern void inp_dodeck();
void inp_dodeck(struct line *deck, char *tt, wordlist *end, bool reuse,
struct line *options, char *filename);
extern void inp_source();
extern void inp_spsource();
void inp_spsource(FILE *fp, bool comfile, char *filename);
extern void inp_casefix();
extern void inp_list();
extern void inp_readall();
@ -280,8 +288,9 @@ extern FILE *inp_pathopen();
/* nutinp.c */
extern void inp_nutsource();
extern void nutinp_dodeck();
void inp_nutsource(FILE *fp, bool comfile, char *filename);
void nutinp_dodeck(struct line *deck, char *tt, wordlist *end, bool reuse,
struct line *options, char *filename);
extern void nutcom_source();
/* interpolate.c */
@ -313,13 +322,13 @@ extern void com_ghelp();
extern void com_help();
extern void com_quit();
extern void com_version();
extern int hcomp();
extern int hcomp();
extern void com_where();
/* numparse.c */
extern bool ft_strictnumparse;
extern double *ft_numparse();
double * ft_numparse(char **s, bool whole);
/* options.c */
@ -342,14 +351,14 @@ extern int cp_userset();
extern struct func ft_funcs[];
extern struct func func_not;
extern struct func func_uminus;
extern struct pnode *ft_getpnames();
extern struct pnode * ft_getpnames(wordlist *wl, bool check);
extern void free_pnode();
/* plotcurve.c */
extern int ft_findpoint();
extern double *ft_minmax();
extern void ft_graf();
extern int ft_findpoint(double pt, double *lims, int maxp, int minp, bool islog);
extern double * ft_minmax(struct dvec *v, bool real);
extern void ft_graf(struct dvec *v, struct dvec *xs, bool nostart);
/* plotinterface.c */
@ -379,9 +388,8 @@ extern void com_setscale();
extern void com_transpose();
/* rawfile.c */
extern int raw_prec;
extern void raw_write();
extern void raw_write(char *name, struct plot *pl, bool app, bool binary);
extern struct plot *raw_read();
/* resource.c */
@ -407,6 +415,8 @@ extern void com_disto();
extern void com_noise();
extern int ft_dorun();
extern bool ft_getOutReq(FILE **, struct plot **, bool *, char *, char *);
/* spice.c & nutmeg.c */
extern bool ft_nutmeg;
@ -523,9 +533,9 @@ extern void com_clearplot();
extern void com_reshape();
/* dimens.c */
extern char *dimstring();
extern void dimstring();
extern int atodims();
extern char *indexstring();
extern void indexstring();
extern int incindex( );
#endif /* FTEext_h */

View File

@ -4,8 +4,6 @@ Author: 1988 Jeffrey M. Hsu
**********/
/*
$Header$
Defs to use the Input routine.
char_option is used by the lexer and the command interpreter
@ -22,7 +20,7 @@ Author: 1988 Jeffrey M. Hsu
#include <stdio.h>
#include "ftegraph.h"
#include "graph.h"
typedef enum {
error_option, /* a reply option only */

View File

@ -12,17 +12,15 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
#define FTEPARSE
#include "ftedata.h"
#include "cpstd.h"
#include "dvec.h"
#include "plot.h"
struct pnode {
char *pn_name; /* If non-NULL, the name. */
struct dvec *pn_value; /* Non-NULL in a terminal node. */
struct func *pn_func; /* Non-NULL is a function. */
struct op *pn_op; /* Operation if the above two NULL. */
struct pnode *pn_left; /* Left branch or function argument. */
struct pnode *pn_right; /* Right branch. */
struct pnode *pn_next; /* For expression lists. */
} ;
/* FIXME: Split this file and adjust all callers. */
#if 0
#warning "Please use a more specific header than fteparse.h"
#endif
#include "pnode.h"
/* Operations. These should really be considered functions. */
@ -36,8 +34,12 @@ struct op {
/* The functions that are available. */
struct func {
char *fu_name; /* The print name of the function. */
void *(*fu_func)(); /* The function. */
/* The print name of the function. */
char *fu_name;
/* The function. */
void *(*fu_func)(void *data, short int type, int length,
int *newlength, short int *newtype);
} ;
/* User-definable functions. The idea of ud_name is that the args are

View File

@ -24,6 +24,8 @@ typedef struct sGENinstance {
int GENnode3; /* appropriate node numbers */
int GENnode4; /* appropriate node numbers */
int GENnode5; /* appropriate node numbers */
int GENnode6; /* added to create body node 01/06/99 */
int GENnode7; /* added to create temp node 2/03/99 */
} GENinstance ;

View File

@ -1,7 +1,7 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1986 Wayne A. Christopher, U. C. Berkeley CAD Group
Modified 1999 Emmanuel Rouat
Modified 1999 Emmanuel Rouat - 2000 AlansFixes
**********/
/*
@ -118,6 +118,7 @@ extern void hlp_pathfix(char *buf);
extern topic *hlp_read(fplace *place);
extern void hlp_free(void);
extern long findsubject(char *filename, char *subject);
extern bool hlp_approvedfile();
/* provide.c */

View File

@ -44,13 +44,13 @@ Author: 1986 Thomas L. Quarles
/* changed in the future */
extern char *errMsg; /* descriptive message about what went wrong */
/* MUST be malloc()'d - front end will free() */
/* MUST be tmalloc()'d - front end will tfree() */
/* this should be a detailed message,and is assumed */
/* malloc()'d so that you will feel free to add */
/* tmalloc()'d so that you will feel free to add */
/* lots of descriptive information with sprintf*/
extern char *errRtn; /* name of the routine declaring error */
/* should not be malloc()'d, will not be free()'d */
/* should not be tmalloc()'d, will not be free()'d */
/* This should be a simple constant in your routine */
/* and thus can be set correctly even if we run out */
/* of memory */

View File

@ -6,14 +6,14 @@ Author: 1986 Thomas L. Quarles
#ifndef IFSIMULATOR
#define IFSIMULATOR
/*
* We don't always have access to an ANSI C compiler yet, so we
* make the following convenient definition
*/
/* gtri - add - wbk - 10/11/90 - for structs referenced in IFdevice */
#ifdef XSPICE
#include "mifparse.h"
#include "mifcmdat.h"
#endif
/* gtri - end - wbk - 10/11/90 */
/* Removed code for non STDC compilers Paolo Nenzi 2000*/
/*
* structure: IFparm
*
@ -180,14 +180,14 @@ typedef struct sIFparseTree {
* should arrange to free it when appropriate.
*
* The responsibilities of the data supplier are:
* Any vectors referenced by the structure are to be malloc()'d
* Any vectors referenced by the structure are to be tmalloc()'d
* and are assumed to have been turned over to the recipient and
* thus should not be re-used or free()'d.
* thus should not be re-used or tfree()'d.
*
* The responsibilities of the data recipient are:
* scalar valued data is to be copied by the recipient
* vector valued data is now the property of the recipient,
* and must be free()'d when no longer needed.
* and must be tfree()'d when no longer needed.
*
* Character strings are a special case: Since it is assumed
* that all character strings are directly descended from input
@ -276,8 +276,22 @@ typedef struct sIFdevice {
int *numModelParms; /* number of model parameter descriptors */
IFparm *modelParms; /* array of model parameter descriptors */
int flags; /* DEV_ */
/* gtri - modify - wbk - 10/11/90 - add entries to hold data required */
/* by new parser */
#ifdef XSPICE
void ((*cm_func)(Mif_Private_t *)); /* pointer to code model function */
int num_conn; /* number of code model connections */
Mif_Conn_Info_t *conn; /* array of connection info for mif parser */
int num_param; /* number of parameters = numModelParms */
Mif_Param_Info_t *param; /* array of parameter info for mif parser */
int num_inst_var; /* number of instance vars = numInstanceParms */
Mif_Inst_Var_Info_t *inst_var; /* array of instance var info for mif parser */
/* gtri - end - wbk - 10/11/90 */
#endif
int flags; /* DEV_ */
} IFdevice;
@ -321,7 +335,6 @@ typedef struct sIFsimulator {
char *description; /* description of this simulator */
char *version; /* version or revision level of simulator*/
#ifdef __STDC__
int ((*newCircuit)(void **));
/* create new circuit */
int ((*deleteCircuit)(void *));
@ -383,42 +396,6 @@ typedef struct sIFsimulator {
int ((*doAnalyses)(void*,int,void*));
char *((*nonconvErr)(void*,char *)); /* return nonconvergence error */
#else
int ((*newCircuit)()); /* create new circuit */
int ((*deleteCircuit)()); /* destroy old circuit's data structures */
int ((*newNode)()); /* create new node */
int ((*groundNode)()); /* create ground node */
int ((*bindNode)()); /* bind a node to a terminal */
int ((*findNode)()); /* find a node by name */
int ((*instToNode)()); /* find the node attached to a terminal */
int ((*setNodeParm)()); /* set a parameter on a node */
int ((*askNodeQuest)()); /* ask a question about a node */
int ((*deleteNode)()); /* delete a node from the circuit */
int ((*newInstance)()); /* create new instance */
int ((*setInstanceParm)()); /* set a parameter on an instance */
int ((*askInstanceQuest)()); /* ask a question about an instance */
int ((*findInstance)()); /* find a specific instance */
int ((*deleteInstance)()); /* delete an instance from the circuit */
int ((*newModel)()); /* create new model */
int ((*setModelParm)()); /* set a parameter on a model */
int ((*askModelQuest)()); /* ask a questions about a model */
int ((*findModel)()); /* find a specific model */
int ((*deleteModel)()); /* delete a model from the circuit*/
int ((*newTask)()); /* create a new task */
int ((*newAnalysis)()); /* create new analysis within a task */
int ((*setAnalysisParm)()); /* set a parameter on an analysis */
int ((*askAnalysisQuest)()); /* ask a question about an analysis */
int ((*findAnalysis)()); /* find a specific analysis */
int ((*findTask)()); /* find a specific task */
int ((*deleteTask)()); /* delete a task */
int ((*doAnalyses)()); /* run a specified task */
char *((*nonconvErr)()); /* return nonconvergence error */
#endif /* STDC */
int numDevices; /* number of device types supported */
IFdevice **devices; /* array of device type descriptors */
@ -445,7 +422,6 @@ typedef struct sIFsimulator {
*/
typedef struct sIFfrontEnd {
#ifdef __STDC__
int ((*IFnewUid)(void*,IFuid*,IFuid,char*,int,void**));
/* create a new UID in the circuit */
int ((*IFdelUid)(void*,IFuid,int));
@ -478,23 +454,6 @@ typedef struct sIFfrontEnd {
/* end nested domain */
int ((*OUTattributes)(void *,IFuid*,int,IFvalue*));
/* specify output attributes of node */
#else /* not STDC */
int ((*IFnewUid)()); /* create a new UID in the circuit */
int ((*IFdelUid)()); /* create a new UID in the circuit */
int ((*IFpauseTest)()); /* should we stop now? */
double ((*IFseconds)()); /* what time is it? */
int ((*IFerror)()); /* output an error or warning message */
int ((*OUTpBeginPlot)()); /* start pointwise output plot */
int ((*OUTpData)()); /* data for pointwise plot */
int ((*OUTwBeginPlot)()); /* start windowed output plot */
int ((*OUTwReference)()); /* independent vector for windowed plot */
int ((*OUTwData)()); /* data for windowed plot */
int ((*OUTwEnd)()); /* signal end of windows */
int ((*OUTendPlot)()); /* end of plot */
int ((*OUTbeginDomain)()); /* start nested domain */
int ((*OUTendDomain)()); /* end nested domain */
int ((*OUTattributes)()); /* specify output attributes of node */
#endif /* STDC */
} IFfrontEnd;
/* flags for the first argument to IFerror */

View File

@ -1,6 +1,7 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
Modified: 2000 AlansFixes
**********/
#ifndef INP
@ -77,7 +78,6 @@ typedef struct sINPmodel{
#define LOGICAL 1
#define PHYSICAL 2
#ifdef __STDC__
int IFnewUid(void*,IFuid*,IFuid,char*,int,void**);
int IFdelUid(void*,IFuid,int);
int INPaName(char*,IFvalue*,void*,int*,char*,void**,IFsimulator*,int*,
@ -96,6 +96,7 @@ int INPgetTok(char**,char**,int);
void INPgetTree(char**,INPparseTree**,void*,INPtables*);
IFvalue * INPgetValue(void*,char**,int,INPtables*);
int INPgndInsert(void*,char**,INPtables*,void**);
int INPinsertNofree(char **token, INPtables *tab);
int INPinsert(char**,INPtables*);
int INPretrieve(char**,INPtables*);
int INPremove(char*,INPtables*);
@ -104,6 +105,7 @@ int INPmakeMod(char*,int,card*);
char *INPmkTemp(char*);
void INPpas1(void*,card*,INPtables*);
void INPpas2(void*,card*,INPtables*,void *);
void INPpas3(void*,card*,INPtables*,void *,IFparm*,int);
int INPpName(char*,IFvalue*,void*,int,void*);
int INPtermInsert(void*,char**,INPtables*,void**);
int INPmkTerm(void*,char**,INPtables*,void**);
@ -121,6 +123,7 @@ void INP2K(void*,INPtables*,card*);
void INP2L(void*,INPtables*,card*);
void INP2M(void*,INPtables*,card*);
void INP2O(void*,INPtables*,card*);
void INP2P(void*,INPtables*,card*);
void INP2Q(void*,INPtables*,card*,void*);
void INP2R(void*,INPtables*,card*);
void INP2S(void*,INPtables*,card*);
@ -128,70 +131,10 @@ void INP2T(void*,INPtables*,card*);
void INP2U(void*,INPtables*,card*);
void INP2V(void*,INPtables*,card*);
void INP2W(void*,INPtables*,card*);
void INP2Y(void*,INPtables*,card*);
void INP2Z(void*,INPtables*,card*);
int INP2dot(void*,INPtables*,card*,void*,void*);
INPtables *INPtabInit(int);
void INPkillMods(void);
void INPtabEnd(INPtables *);
#else /* stdc */
int IFnewUid();
int IFdelUid();
int INPaName();
IFvalue * INPgetValue();
INPtables *INPtabInit();
char * INPdevParse();
char * INPdomodel();
char * INPerrCat();
char * INPfindLev();
char * INPgetMod();
char *INPerror();
char *INPmkTemp();
double INPevaluate();
int INPapName();
int INPgetTitle();
int INPgetTok();
int INPgndInsert();
int INPlookMod();
int INPmakeMod();
int INPpName();
int INPreadAll();
int INPtermInsert();
int INPmkTerm();
int INPtypelook();
void INPcaseFix();
void INPdoOpts();
int INPinsert();
int INPretrieve();
int INPremove();
void INPkillMods();
void INPlist();
void INPpas1() ;
void INPpas2() ;
void INPtabEnd();
void INPptPrint();
void INPgetTree();
void INP2B();
void INP2C();
void INP2D();
void INP2E();
void INP2F();
void INP2G();
void INP2H();
void INP2I();
void INP2J();
void INP2K();
void INP2L();
void INP2M();
void INP2O();
void INP2Q();
void INP2R();
void INP2S();
void INP2T();
void INP2U();
void INP2V();
void INP2W();
void INP2Z();
int INP2dot();
#endif /* stdc */
#endif /*INP*/

View File

@ -92,6 +92,9 @@ typedef struct INPparseNode {
#define PTF_SGN 18
#define PTF_USTEP 19
#define PTF_URAMP 20
/* MW. PTF_CIF - next function */
#define PTF_USTEP2 21
/* The following things are used by the parser -- these are the token types the
* lexer returns.
@ -155,6 +158,8 @@ extern double PTsqrt();
extern double PTtan();
extern double PTtanh();
extern double PTustep();
/* MW. PTcif declaration */
extern double PTustep2();
extern double PTuramp();
extern double PTuminus();

View File

@ -16,17 +16,6 @@ typedef struct sJOB{
} JOB;
typedef struct {
IFanalysis public;
int size;
int domain;
int do_ic;
int (*(setParm))( );
int (*(askQuest))( );
int (*an_init)( );
int (*an_func)( );
} SPICEanalysis;
#define NODOMAIN 0
#define TIMEDOMAIN 1
#define FREQUENCYDOMAIN 2

View File

@ -14,46 +14,6 @@
#define NUMELEMS(ARRAY) (sizeof(ARRAY)/sizeof(*ARRAY))
/*
* Macros for complex mathematical functions.
*/
/* Some defines used mainly in cmath.c. */
#define alloc_c(len) ((complex *) tmalloc((len) * sizeof (complex)))
#define alloc_d(len) ((double *) tmalloc((len) * sizeof (double)))
#define FTEcabs(d) (((d) < 0.0) ? - (d) : (d))
#define cph(c) (atan2(imagpart(c), (realpart(c))))
#define cmag(c) (sqrt(imagpart(c) * imagpart(c) + realpart(c) * realpart(c)))
#define radtodeg(c) (cx_degrees ? ((c) / 3.14159265358979323846 * 180) : (c))
#define degtorad(c) (cx_degrees ? ((c) * 3.14159265358979323846 / 180) : (c))
#define rcheck(cond, name) if (!(cond)) { \
fprintf(cp_err, "Error: argument out of range for %s\n", name); \
return (NULL); }
#define cdiv(r1, i1, r2, i2, r3, i3) \
{ \
double r, s; \
if (FTEcabs(r2) > FTEcabs(i2)) { \
r = (i2) / (r2); \
s = (r2) + r * (i2); \
(r3) = ((r1) + r * (i1)) / s; \
(i3) = ((i1) - r * (r1)) / s; \
} else { \
r = (r2) / (i2); \
s = (i2) + r * (r2); \
(r3) = (r * (r1) + (i1)) / s; \
(i3) = (r * (i1) - (r1)) / s; \
} \
}
#define tfree(x) (txfree(x), x = 0)
#define alloc(TYPE) ((TYPE *) tmalloc(sizeof(TYPE)))
#define eq(a,b) (!strcmp((a), (b)))
#define eqc(a,b) (cieq((a), (b)))
#define isalphanum(c) (isalpha(c) || isdigit(c))
@ -61,11 +21,6 @@
'a') && ((c) <= 'f')) ? ((c) - 'a' + 10) : ((((c) >= 'A') && \
((c) <= 'F')) ? ((c) - 'A' + 10) : 0)))
#define MALLOC(x) tmalloc((unsigned)(x))
#define FREE(x) {if (x) {free((char *)(x));(x) = 0;}}
#define REALLOC(x,y) trealloc((char *)(x),(unsigned)(y))
#define ZERO(PTR,TYPE) (bzero((PTR),sizeof(TYPE)))
#define MIN(a,b) ((a) < (b) ? (a) : (b))
#define MAX(a,b) ((a) > (b) ? (a) : (b))
@ -73,29 +28,29 @@
#define ABORT() fflush(stderr);fflush(stdout);abort();
#define ERROR(CODE,MESSAGE) { \
errMsg = MALLOC(strlen(MESSAGE) + 1); \
strcpy(errMsg, (MESSAGE)); \
return (CODE); \
#define ERROR(CODE,MESSAGE) { \
errMsg = (char *) tmalloc(strlen(MESSAGE) + 1); \
strcpy(errMsg, (MESSAGE)); \
return (CODE); \
}
#define NEW(TYPE) ((TYPE *) MALLOC(sizeof(TYPE)))
#define NEWN(TYPE,COUNT) ((TYPE *) MALLOC(sizeof(TYPE) * (COUNT)))
#define NEW(TYPE) ((TYPE *) tmalloc(sizeof(TYPE)))
#define NEWN(TYPE,COUNT) ((TYPE *) tmalloc(sizeof(TYPE) * (COUNT)))
#define R_NORM(A,B) { \
if ((A) == 0.0) { \
(B) = 0; \
} else { \
while (fabs(A) > 1.0) { \
(B) += 1; \
(A) /= 2.0; \
} \
while (fabs(A) < 0.5) { \
(B) -= 1; \
(A) *= 2.0; \
} \
} \
#define R_NORM(A,B) { \
if ((A) == 0.0) { \
(B) = 0; \
} else { \
while (fabs(A) > 1.0) { \
(B) += 1; \
(A) /= 2.0; \
} \
while (fabs(A) < 0.5) { \
(B) -= 1; \
(A) *= 2.0; \
} \
} \
}
@ -105,10 +60,4 @@
#define DEBUGMSG(testargs)
#endif
#define realpart(cval) ((struct _complex *) (cval))->cx_real
#define imagpart(cval) ((struct _complex *) (cval))->cx_imag
#endif /* _MACROS_H_ */

View File

@ -7,17 +7,25 @@
* This file will eventually replace spice.h and lots of other
* files in src/include
*/
#define _GNU_SOURCE
#include <config.h>
#include <math.h>
#include <stdio.h>
#include <stddef.h>
#ifdef HAVE_LIMITS_H
# include <limits.h>
#endif
#include "memory.h"
#include "defines.h"
#include "macros.h"
#include <math.h>
#include <stdio.h>
#ifndef HUGE
#define HUGE HUGE_VAL
#endif
#ifdef STDC_HEADERS
# include <stdlib.h>
@ -95,22 +103,14 @@ struct timeb timebegin;
#endif
#ifdef HAS_TIME_
# ifdef HAVE_GETTIMEOFDAY
/* extern char *timezone(); */ /* never used ? (ER) */
# endif
extern char *asctime();
extern struct tm *localtime();
#include <time.h>
#endif
extern char *sbrk();
/* Functions declarations from src/misc/[].c */
extern void *tmalloc(size_t num);
extern void *trealloc(void *str, size_t num);
extern void txfree(void *ptr);
#ifdef __MINGW32__
#define srandom srand
#define random rand
#define index strchr
#endif
extern char *gettok(char **s);
extern void appendc(char *s, char c);
@ -122,12 +122,12 @@ extern char *tilde_expand(char *string);
extern char *smktemp(char *id);
extern char *copy();
extern int prefix();
extern int substring();
extern void cp_printword();
extern char *copy(char *str);
extern int prefix(char *p, char *str);
extern int substring(char *sub, char *str);
extern void cp_printword(char *string, FILE *fp);
extern char *datestring();
extern char *datestring(void);
extern double seconds(void);
/* Some external variables */

View File

@ -1,6 +1,7 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
Modified: 2000 AlansFixes
**********/
#ifndef OPT
@ -104,4 +105,29 @@ typedef struct {
#define OPT_TRANSYNC 59
#define OPT_ACSYNC 60
/* AlansFixes: It is not possible to use the same numbers of the
original Alan code. The following options are all AlansFixes */
#define OPT_GSHUNT 61 /* Original: 48 */
#define OPT_DEFM 62 /* Original: 46 */
#define OPT_GMINFACT 63 /* Original: 47 */
#define OPT_COPYNODESETS 64 /* Original: 49 (NodesetFix) */
#define OPT_NODEDAMPING 65 /* Original: 50 (Node_Damping) */
#define OPT_ABSDV 66 /* Original: 51 (Node_Damping) */
#define OPT_RELDV 67 /* Original: 52 (Node_Damping) */
#ifdef XSPICE
/* gtri - begin - wbk - add new options */
#define OPT_ENH_NOOPALTER 100
#define OPT_ENH_RAMPTIME 101
#define OPT_EVT_MAX_EVT_PASSES 102
#define OPT_EVT_MAX_OP_ALTER 103
#define OPT_ENH_CONV_LIMIT 104
#define OPT_ENH_CONV_ABS_STEP 105
#define OPT_ENH_CONV_STEP 106
#define OPT_MIF_AUTO_PARTIAL 107
#define OPT_ENH_RSHUNT 108
/* gtri - end - wbk - add new options */
#endif
#endif /*OPT*/

View File

@ -18,3 +18,4 @@ struct s_sgen {
extern sgen *sgen_init( );
extern int sgen_next( );
extern int sgen_setp(sgen*, CKTcircuit*, IFvalue* ); /* AlansFixes */

View File

@ -1,63 +1,47 @@
#ifndef SMP
#define SMP
typedef char SMPmatrix;
typedef void SMPmatrix;
typedef struct MatrixElement *SMPelement;
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
Modified: 2000 AlansFixes
**********/
#include "complex.h"
#include <stdio.h>
#ifdef __STDC__
int SMPaddElt( SMPmatrix *, int , int , double );
void SMPcClear( SMPmatrix *);
int SMPcLUfac( SMPmatrix *, double );
int SMPcProdDiag( SMPmatrix *, SPcomplex *, int *);
int SMPcReorder( SMPmatrix * , double , double , int *);
void SMPcSolve( SMPmatrix *, double [], double [], double [], double []);
void SMPclear( SMPmatrix *);
void SMPcolSwap( SMPmatrix * , int , int );
void SMPdestroy( SMPmatrix *);
int SMPfillup( SMPmatrix * );
SMPelement * SMPfindElt( SMPmatrix *, int , int , int );
void SMPgetError( SMPmatrix *, int *, int *);
int SMPluFac( SMPmatrix *, double , double );
double * SMPmakeElt( SMPmatrix * , int , int );
void SMPcClear( SMPmatrix *);
void SMPclear( SMPmatrix *);
int SMPcLUfac( SMPmatrix *, double );
int SMPluFac( SMPmatrix *, double , double );
int SMPcReorder( SMPmatrix * , double , double , int *);
int SMPreorder( SMPmatrix * , double , double , double );
void SMPcaSolve(SMPmatrix *Matrix, double RHS[], double iRHS[],
double Spare[], double iSpare[]);
void SMPcSolve( SMPmatrix *, double [], double [], double [], double []);
void SMPsolve( SMPmatrix *, double [], double []);
int SMPmatSize( SMPmatrix *);
int SMPnewMatrix( SMPmatrix ** );
int SMPnewNode( int , SMPmatrix *);
void SMPdestroy( SMPmatrix *);
int SMPpreOrder( SMPmatrix *);
void SMPprint( SMPmatrix * , FILE *);
int SMPreorder( SMPmatrix * , double , double , double );
void SMProwSwap( SMPmatrix * , int , int );
void SMPsolve( SMPmatrix *, double [], double []);
#else /* stdc */
int SMPaddElt();
void SMPcClear();
int SMPcLUfac();
int SMPcProdDiag();
int SMPcReorder();
void SMPcSolve();
void SMPclear();
void SMPcolSwap();
void SMPdestroy();
int SMPfillup();
SMPelement * SMPfindElt();
void SMPgetError();
int SMPluFac();
double * SMPmakeElt();
int SMPmatSize();
int SMPnewMatrix();
int SMPnewNode();
int SMPpreOrder();
void SMPprint();
int SMPreorder();
void SMProwSwap();
void SMPsolve();
#endif /* stdc */
void SMPgetError( SMPmatrix *, int *, int *);
int SMPcProdDiag( SMPmatrix *, SPcomplex *, int *);
int SMPcDProd(SMPmatrix *Matrix, SPcomplex *pMantissa, int *pExponent);
SMPelement * SMPfindElt( SMPmatrix *, int , int , int );
int SMPcZeroCol(SMPmatrix *eMatrix, int Col);
int SMPcAddCol(SMPmatrix *eMatrix, int Accum_Col, int Addend_Col);
int SMPzeroRow(SMPmatrix *eMatrix, int Row);
void spConstMult(SMPmatrix*, double);
#ifdef PARALLEL_ARCH
void SMPcombine(SMPmatrix *Matrix, double RHS[], double Spare[]);
void SMPcCombine(SMPmatrix *Matrix, double RHS[], double Spare[],
double iRHS[], double iSpare[]);
#endif
#endif /*SMP*/

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