tclspice 0.2.7 import
This commit is contained in:
parent
2d7004cb81
commit
d06b4a9f05
75
AUTHORS
75
AUTHORS
|
|
@ -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
235
ChangeLog
|
|
@ -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
167
DEVICES
|
|
@ -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
530
FAQ
|
|
@ -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.
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
224
NEWS
|
|
@ -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
69
README
|
|
@ -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)
|
||||
|
|
|
|||
24
acconfig.h
24
acconfig.h
|
|
@ -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
|
||||
|
|
|
|||
28
autogen.sh
28
autogen.sh
|
|
@ -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."
|
||||
|
||||
|
|
|
|||
329
configure.in
329
configure.in
|
|
@ -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
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -1,3 +1,10 @@
|
|||
-------------------------------
|
||||
MW. 01-10-2000
|
||||
Bugs Fixes -
|
||||
-----------
|
||||
.subckt inside another parametrized .subckt works right now.
|
||||
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Version 0.11 January 2, 1996
|
||||
----------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -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($_);
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
861
doc/ngspice.texi
861
doc/ngspice.texi
File diff suppressed because it is too large
Load Diff
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
213
src/Makefile.am
213
src/Makefile.am
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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@
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. */
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@
|
|||
#define FOURIER_H_INCLUDED
|
||||
|
||||
void com_fourier(wordlist *wl);
|
||||
|
||||
|
||||
int fourier(wordlist *wl, struct plot *current);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 = '_';
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 }
|
||||
} ;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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. */
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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( )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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. */
|
||||
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 } ,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
|
||||
*/
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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*/
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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_*/
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 *);
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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)))
|
||||
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ typedef struct {
|
|||
int (*MakeMenu)();
|
||||
int (*MakeDialog)();
|
||||
int (*Input)();
|
||||
int (*DatatoScreen)();
|
||||
void (*DatatoScreen)();
|
||||
} DISPDEVICE;
|
||||
|
||||
extern DISPDEVICE *dispdev;
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 ;
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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*/
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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_ */
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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*/
|
||||
|
|
|
|||
|
|
@ -18,3 +18,4 @@ struct s_sgen {
|
|||
|
||||
extern sgen *sgen_init( );
|
||||
extern int sgen_next( );
|
||||
extern int sgen_setp(sgen*, CKTcircuit*, IFvalue* ); /* AlansFixes */
|
||||
|
|
|
|||
|
|
@ -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
Loading…
Reference in New Issue