Integrated code from tclspice, brorson xspice and Vera memleak.
This commit is contained in:
parent
0a0b64d23f
commit
8362dec274
106
ChangeLog
106
ChangeLog
|
|
@ -1,3 +1,109 @@
|
|||
2003-07-18 Vera Albrecht <albrecht@danalyse.de>
|
||||
|
||||
* src/{main.c,tclspice.c}
|
||||
src/frontend/{Makefile.am,control.c,control.h,display.c,dotcards.c,
|
||||
hcomp.c,hpgl.c,outitf.c,parse.c,postcoms.c,postsc.c,runcoms.c,
|
||||
spiceif.c,variable.c,variable.h,parser/complete.c,plotting/pvec.c}
|
||||
src/include/{cktdefs.h,ngspice.h}
|
||||
src/misc/{ivars.c,string.c,stringutil.h}
|
||||
src/spicelib/analysis/{acan.c,ckt.h,dcop.c}
|
||||
src/spicelib/devices/bsim3/b3temp.c
|
||||
src/spicelib/parser/{ifnewuid.c,inp2dot.c,inperror.c} :
|
||||
Memory leaks and some WINDOWS compile fixes.
|
||||
|
||||
2003-07-17 Stefan Jones <stefan.jones@multigig.com>
|
||||
|
||||
* src/frontend/{subckt.c,vectors.c}
|
||||
src/spicelib/analysis/dctran.c
|
||||
src/spicelib/parser/inperror.c
|
||||
src/xspice/idn/idndig.c src/xspice/mif/mif_inp2.c :
|
||||
More memory leak fixes
|
||||
|
||||
* configure.in src/xspice/xspice.c :
|
||||
Fix compile problems with garbage collector
|
||||
|
||||
* configure.in :
|
||||
Change --enable-tcl to --with-tcl[=dir] for non-std
|
||||
install setup.
|
||||
|
||||
2003-07-17 Steven Borley <sjb@salix.demon.co.uk>
|
||||
|
||||
* src/frontend/resource.c src/frontend/parser/complete.c
|
||||
src/spicelib/devices/txl/txlload.c :
|
||||
#ifdef fixes to get ngspice to compile on Mac OSX
|
||||
|
||||
2003-07-16 Vera Albrecht <albrecht@danalyse.de>
|
||||
|
||||
* frontend/{device.c,parse.c,vectors.c,com_compose.c} :
|
||||
More memory leaks closed in utility commands and functions.
|
||||
|
||||
2003-07-16 Stefan Jones <stefan.jones@multigig.com>
|
||||
|
||||
* src/frontend/{com_compose.c,cpitf.c,device.c,subckt.c,vectors.c}
|
||||
src/frontend/plotting/plotit.c src/include/ngspice.h
|
||||
src/spicelib/parser/{inp2dot.c,inp2r.c,inpdomod.c,inpdpar.c,inpgmod.c,inppas3.c} :
|
||||
Rest of the serious deck reader leaks, plus fixes for the last batch.
|
||||
|
||||
2003-07-15 Stefan Jones <stefan.jones@multigig.com>
|
||||
|
||||
* /src/frontend/{com_let.c,com_set.c,evaluate.c,parse.c,variable.c}
|
||||
src/frontend/parser/complete.c :
|
||||
Memory leaks plugged
|
||||
|
||||
2003-04-14 Stefan Jones <stefan.jones@multigig.com>
|
||||
|
||||
* Make all the devices in src/spicelib/devices be built as
|
||||
archives not shared libraries, and don't install them
|
||||
|
||||
2003-06-22 Stuart Brorson <sdb@cloud9.net>
|
||||
|
||||
* Finally got SPICE2 POLY stuff working. This involved lots of changes
|
||||
in src/xspice/mif and src/xspice/enh. Particular changes were made in:
|
||||
-- MIF_INP2A: re-arranged logic to fix parsing problems.
|
||||
-- two2three_translate: fixed some stupid pointer problems.
|
||||
-- etc.
|
||||
|
||||
* Revamped src/xspice/icm/ and src/xspice/icm/icm_spice2poly
|
||||
directories to enable build of POLY codemodel. Makefiles were
|
||||
fixed, and some stuff was added to enable cmpp (from SPICE Opus)
|
||||
to build the codemodel precursors correctly. (Note that you need
|
||||
to download and install SPICE Opus to rebuild the codemodel
|
||||
stuff. See src/xspice/icm/README for more details.)
|
||||
|
||||
* Hacked Makefile.am's for much of the directory hierarchy, particularly
|
||||
for src/xspice/icm and src/xspice/icm/icm_spice2poly to build the POLY
|
||||
codemodel correctly. Note that top level make still doesn't detect
|
||||
changes in the xspice hierarchy; read the NOTES file for a workaround.
|
||||
|
||||
* Added a SPICE netlist incorporating vendor models with SPICE2
|
||||
POLYs in tests/TransImpedanceAmp/. Running this model
|
||||
successfully demonstrates that you have built the XSpice POLY
|
||||
codemodel correctly and that life is good . . . .
|
||||
|
||||
* Moved #define TRACE out of src/ngspice.h and made it a compiler
|
||||
option (-DTRACE) invoked in src/Makefile when making spice.o.
|
||||
|
||||
2003-05-02 Stuart Brorson <sdb@cloud9.net>
|
||||
|
||||
* Added #define TRACE to main.c for use in debugging. Added lots
|
||||
of printf's in the code which are turned on by defining TRACE.
|
||||
This is used to help figure out what the program is doing at each
|
||||
step . . . . .
|
||||
|
||||
* Added lots of comments all over the source tree. This should
|
||||
help explain what the prog is doing for future hackers.
|
||||
|
||||
* Fixed parser to allow POLY attributes in dependent sources
|
||||
(major changes in src/frontend/subckt.c, as well as move location
|
||||
of call to ENHtranslate_poly in src/frontend/inp.c)
|
||||
|
||||
* Fixed bug in device init files (src/spicelib/devices/*init.c)
|
||||
so that Deviceinfo structures operated with XSPICE.
|
||||
|
||||
* Fixed nasty malloc problem in src/xspice/mif/mifgetmod.c which
|
||||
casuedfrequent segfaults (when compiled with XSPICE).
|
||||
|
||||
|
||||
2002-01-03 Paolo Nenzi <p.nenzi@ieee.org>
|
||||
|
||||
* acconfig.h: added define needed for Windows and some aesthetic
|
||||
|
|
|
|||
|
|
@ -13,3 +13,6 @@ 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`
|
||||
|
||||
codemodels:
|
||||
cd src/xspice/icm && make
|
||||
|
|
|
|||
28
NOTES
28
NOTES
|
|
@ -1,3 +1,31 @@
|
|||
SPICE 2 POLY CODEMODEL
|
||||
|
||||
SPICE2 POLY attributes are now available for controlled sources. To
|
||||
use POLY attributes, configure tclspice/ngspice with the
|
||||
--enable-xspice flag set as described above. After compilation of
|
||||
ngspice, cd into $(top_srcdir)/src/xspice/icm and read the README file
|
||||
there for instructions about how to get POLY support. (Hint: you have
|
||||
to download some stuff from http://www.fe.uni-lj.si/ and edit the
|
||||
Makefiles before you can do "make && make install" of the codemodel
|
||||
stuff.)
|
||||
|
||||
-- SDB 6.22.2003.
|
||||
|
||||
--------------------------------------------------------------------
|
||||
COMPILING XSPICE CHANGES
|
||||
|
||||
The dependencies in the Makefile don't seem to work when you are
|
||||
compiling changes in the xspice stuff. Obviously, the best thing to
|
||||
do is fix Makefile.am, but since I am not an expert at this, I have
|
||||
been using the following workaround when making:
|
||||
|
||||
touch src/main.c && make && make install
|
||||
|
||||
I recommend you also do this if you hack anything under src/xspice.
|
||||
|
||||
-- SDB 6.19.2003.
|
||||
|
||||
---------------------------------------------------------------------
|
||||
DEBUGGING SPICE
|
||||
|
||||
To avoid a segmentation fault in the initial run, use the following
|
||||
|
|
|
|||
|
|
@ -38,6 +38,12 @@
|
|||
/* We do not want spurios debug info into non-developer code */
|
||||
#undef FTEDEBUG
|
||||
|
||||
/*The xspice enhancements*/
|
||||
#undef XSPICE
|
||||
|
||||
/* Spice cluster support */
|
||||
#undef CLUSTER
|
||||
|
||||
/* Generate MS WINDOWS executable */
|
||||
#undef HAS_WINDOWS
|
||||
|
||||
|
|
|
|||
106
configure.in
106
configure.in
|
|
@ -1,9 +1,6 @@
|
|||
dnl Process this file with autoconf to produce a configure script.
|
||||
AC_INIT(src/main.c)
|
||||
|
||||
dnl Keep old autoconf version, procedure is not compatible to new 2.5.2
|
||||
AC_PREREQ(2.13)
|
||||
|
||||
dnl Create a configuration header
|
||||
AM_CONFIG_HEADER(config.h)
|
||||
|
||||
|
|
@ -54,6 +51,14 @@ 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 --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-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
|
||||
|
||||
|
|
@ -108,7 +113,7 @@ dnl Checks for programs
|
|||
|
||||
AC_LIBTOOL_DLOPEN
|
||||
AM_PROG_LIBTOOL
|
||||
|
||||
AC_PROG_LIBTOOL
|
||||
|
||||
dnl --with-windows : the user wants to use generate the MS WINDOWS executable
|
||||
AC_ARG_WITH(windows,
|
||||
|
|
@ -123,7 +128,7 @@ case $with_windows in
|
|||
yes )
|
||||
AC_DEFINE(X_DISPLAY_MISSING)
|
||||
AC_MSG_RESULT(No X display!)
|
||||
CFLAGS="$CFLAGS -mwindows";;
|
||||
CFLAGS="$CFLAGS -mwindows";
|
||||
*)
|
||||
|
||||
dnl Checks for X11 header files and libraries - X11 support can be disabled
|
||||
|
|
@ -141,12 +146,13 @@ dnl In CYGWIN library ordering has to be changed. Is this compatible to LINUX?
|
|||
dnl XShmAttach is a struct in CYGWIN, not a function
|
||||
|
||||
if test ! "$no_x" = "yes" ; then
|
||||
AC_CHECK_LIB(Xaw,main,X_LIBS="$X_LIBS -lXaw",AC_MSG_ERROR(Couldn't find Xaw librairies),$X_LIBS $X_EXTRA_LIBS)
|
||||
X_LIBS="$X_LIBS -lXt"
|
||||
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(Xmu,main,X_LIBS="$X_LIBS -lXmu",AC_MSG_ERROR(Couldn't find Xmu librairies), $X_LIBS $X_EXTRA_LIBS)
|
||||
AC_CHECK_LIB(Xext,main,X_LIBS="$X_LIBS -lXext",AC_MSG_ERROR(Couldn't find Xext librairies), $X_LIBS $X_EXTRA_LIBS)
|
||||
X_LIBS="$X_LIBS -lX11 -lXpm"
|
||||
fi ;;
|
||||
AC_CHECK_LIB(Xaw,main,X_LIBS="$X_LIBS -lXaw",AC_MSG_ERROR(Couldn't find Xaw librairies),$X_LIBS $X_EXTRA_LIBS)
|
||||
|
||||
|
||||
fi
|
||||
|
||||
esac
|
||||
|
||||
|
|
@ -157,8 +163,8 @@ AC_TYPE_SIGNAL
|
|||
dnl Check for a few libraries and headers:
|
||||
|
||||
dnl Look for ncurses first, then termcap
|
||||
#AC_SEARCH_LIBS(tputs,ncurses termcap,AC_DEFINE(HAVE_TERMCAP),
|
||||
# AC_MSG_ERROR(Found neither ncurses or termcap))
|
||||
AC_SEARCH_LIBS(tputs,ncurses termcap,AC_DEFINE(HAVE_TERMCAP),
|
||||
AC_MSG_ERROR(Found neither ncurses or termcap))
|
||||
|
||||
|
||||
AC_HEADER_DIRENT
|
||||
|
|
@ -175,11 +181,11 @@ AC_CHECK_FUNCS(localtime)
|
|||
case $host_os in
|
||||
*cygwin* )
|
||||
AC_CHECK_FUNCS(ftime)
|
||||
AC_DEFINE(HAVE__MEMAVL) ;;
|
||||
AC_DEFINE(HAVE__MEMAVL) ;
|
||||
* )
|
||||
AC_CHECK_FUNCS(gettimeofday time ftime , break)
|
||||
AC_CHECK_FUNCS(getrusage utimes, break)
|
||||
AC_CHECK_FUNCS(getrlimit ulimit, break) ;;
|
||||
AC_CHECK_FUNCS(getrlimit ulimit, break) ;
|
||||
esac
|
||||
|
||||
dnl Look for termios first (posix)
|
||||
|
|
@ -208,6 +214,33 @@ AC_CHECK_LIB(gc,GC_malloc,AC_DEFINE(HAVE_LIBGC) LIBS="$LIBS -lgc")
|
|||
dnl Check for the asprintf function:
|
||||
AC_CHECK_FUNCS(asprintf,,AC_CHECK_LIB(iberty,asprintf,AC_DEFINE(HAVE_ASPRINTF) LIBS="$LIBS -liberty"))
|
||||
|
||||
dnl Check for va_copy
|
||||
AC_CACHE_CHECK([for va_copy], ac_cv_c_va_copy,
|
||||
AC_TRY_LINK(
|
||||
[#include <stdarg.h>],
|
||||
[va_list ap1, ap2;
|
||||
va_copy(ap1,ap2);
|
||||
],
|
||||
[ac_cv_c_va_copy="yes"],
|
||||
[ac_cv_c_va_copy="no"])
|
||||
)
|
||||
if test "$ac_cv_c_va_copy" = "yes"
|
||||
then
|
||||
AC_DEFINE(HAVE_VA_COPY, 1, [Define if we have va_copy])
|
||||
fi
|
||||
AC_CACHE_CHECK([for __va_copy], ac_cv_c___va_copy,
|
||||
AC_TRY_LINK(
|
||||
[#include <stdarg.h>],
|
||||
[va_list ap1, ap2;
|
||||
__va_copy(ap1,ap2);
|
||||
],
|
||||
[ac_cv_c___va_copy="yes"],
|
||||
[ac_cv_c___va_copy="no"])
|
||||
)
|
||||
if test "$ac_cv_c___va_copy" = "yes"
|
||||
then
|
||||
AC_DEFINE(HAVE___VA_COPY, 1, [Define if we have __va_copy])
|
||||
fi
|
||||
|
||||
# AC_CHECK_FUNC(getopt_long, getopt_long=true)
|
||||
# AM_CONDITIONAL(HAVE_GETOPT_LONG, test "$getopt_long" = "true")
|
||||
|
|
@ -277,6 +310,35 @@ fi
|
|||
AC_SUBST(EKVDIR)
|
||||
AC_SUBST(EKVLIB)
|
||||
|
||||
dnl Add new code models to the build by pointing to them here.
|
||||
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 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,
|
||||
|
|
@ -312,6 +374,7 @@ 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 \
|
||||
|
|
@ -332,6 +395,7 @@ 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 \
|
||||
|
|
@ -350,6 +414,15 @@ src/maths/deriv/Makefile \
|
|||
src/maths/poly/Makefile \
|
||||
src/maths/sparse/Makefile \
|
||||
src/misc/Makefile \
|
||||
src/xspice/Makefile \
|
||||
src/xspice/cm/Makefile \
|
||||
src/xspice/icm/Makefile \
|
||||
src/xspice/icm/icm_spice2poly/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 \
|
||||
|
|
@ -357,6 +430,7 @@ tests/resistance/Makefile \
|
|||
tests/bsim3soipd/Makefile \
|
||||
tests/bsim3soifd/Makefile \
|
||||
tests/bsim3soidd/Makefile \
|
||||
tests/bsim4/Makefile \
|
||||
tests/mesa/Makefile
|
||||
tests/bsim4/Makefile \
|
||||
tests/mesa/Makefile \
|
||||
tests/TransImpedanceAmp/Makefile
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
SUBDIRS = misc maths frontend spicelib include
|
||||
SUBDIRS = misc maths frontend spicelib include @XSPICEDIR@
|
||||
|
||||
bin_PROGRAMS = ngspice ngnutmeg nghelp ngsconvert ngproc2mod ngmultidec makeidx
|
||||
|
||||
|
|
@ -18,7 +18,6 @@ initdata_DATA = spinit setplot spectrum
|
|||
DYNAMIC_DEVICELIBS = \
|
||||
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 \
|
||||
|
|
@ -32,6 +31,7 @@ DYNAMIC_DEVICELIBS = \
|
|||
spicelib/devices/cccs/libcccs.la \
|
||||
spicelib/devices/ccvs/libccvs.la \
|
||||
spicelib/devices/ccvs/libccvs.la \
|
||||
spicelib/devices/cpl/libcpl.a \
|
||||
spicelib/devices/csw/libcsw.la \
|
||||
spicelib/devices/dio/libdio.la \
|
||||
@EKVLIB@ \
|
||||
|
|
@ -52,12 +52,22 @@ DYNAMIC_DEVICELIBS = \
|
|||
spicelib/devices/res/libres.la \
|
||||
spicelib/devices/soi3/libsoi3.la \
|
||||
spicelib/devices/sw/libsw.la \
|
||||
spicelib/devices/txl/libtxl.a \
|
||||
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
|
||||
|
||||
|
||||
## ----- Note that I moved this stuff to here because it was causing automake
|
||||
## to choke when it was in the DYNAMIC_DEVICELIBS list above -----
|
||||
## This lib deleted from DYNAMIC_DEVICELIBS by sdb 'cause there's no source for it.
|
||||
## spicelib/devices/bjt2/libbjt2.a \
|
||||
## poly added to dynamic libs by SDB on 6.1.2003
|
||||
## xspice/icm/poly/libpoly.a
|
||||
|
||||
|
||||
## Build ngspice first:
|
||||
|
||||
ngspice_SOURCES = \
|
||||
|
|
@ -71,10 +81,12 @@ ngspice_LDADD = \
|
|||
frontend/libfte.a \
|
||||
frontend/wdisp/libwindisp.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 \
|
||||
|
|
|
|||
|
|
@ -1,3 +1,22 @@
|
|||
2003-07-08 Stefan Jones <stefan.jones@multigig.com>
|
||||
* quote.c: return the pointer to the start of malloced
|
||||
memory so it can be freeded
|
||||
|
||||
2003-05-02 Stuart Brorson <SDB@cloud9.net>
|
||||
* Major changes in subckt.c to handle POLY attributes in
|
||||
dependent sources. Added new case to switch in "translate" to
|
||||
handle E, F, G, H sources. Many other fixes.
|
||||
|
||||
* Moved location of call to ENHtranslate_poly in inp.c. This was
|
||||
necessary to correctly process POLY attributes and the associated
|
||||
netlists and voltage sources.
|
||||
|
||||
2003-04-10 Stuart Brorson <sdb@cloud9.net>
|
||||
* modified inp_readall (inpcom.c) to ignore blank
|
||||
lines terminated by \r\n *and * \n. This fixes problems
|
||||
associated with importing files from Windozeland.
|
||||
* Added explanatory comments to many modules.
|
||||
|
||||
2002-01-03 Paolo Nenzi <p.nenzi@ieee.org>
|
||||
|
||||
* wdisp: added an entire directory containing windows frontend code
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@ libfte_a_SOURCES = \
|
|||
com_chdir.c \
|
||||
com_compose.c \
|
||||
com_compose.h \
|
||||
com_dl.c \
|
||||
com_dl.h \
|
||||
com_display.c \
|
||||
com_display.h \
|
||||
com_dump.c \
|
||||
|
|
@ -100,6 +102,7 @@ libfte_a_SOURCES = \
|
|||
fourier.h \
|
||||
gens.c \
|
||||
gens.h \
|
||||
hpgl.c \
|
||||
inp.c \
|
||||
inp.h \
|
||||
inpcom.c \
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ com_compose(wordlist *wl)
|
|||
bool realflag = TRUE;
|
||||
int dims[MAXDIMS];
|
||||
struct dvec *result, *vecs = NULL, *v, *lv = NULL;
|
||||
struct pnode *pn, *first_pn;
|
||||
struct pnode *pn, *first_pn=NULL;
|
||||
bool reverse = FALSE;
|
||||
|
||||
resname = cp_unquote(wl->wl_word);
|
||||
|
|
@ -141,7 +141,6 @@ com_compose(wordlist *wl)
|
|||
;
|
||||
pn = pn->pn_next;
|
||||
}
|
||||
free_pnode(first_pn);
|
||||
/* Now make sure these are all of the same dimensionality. We
|
||||
* can coerce the sizes...
|
||||
*/
|
||||
|
|
@ -479,6 +478,7 @@ com_compose(wordlist *wl)
|
|||
result->v_dims[0] = length;
|
||||
vec_new(result);
|
||||
cp_addkword(CT_VECTOR, result->v_name);
|
||||
free_pnode(first_pn);
|
||||
tfree(resname);/*DG: resname has been copied so its remains allocated: memory leak One can remove this and not copy resname*/
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ com_let(wordlist *wl)
|
|||
*rhs++ = 0;
|
||||
} else {
|
||||
fprintf(cp_err, "Error: bad let syntax\n");
|
||||
tfree(p);
|
||||
return;
|
||||
}
|
||||
if ((s =strchr(p, '['))) {
|
||||
|
|
@ -63,6 +64,7 @@ com_let(wordlist *wl)
|
|||
|
||||
if (depth != 0 || !*q) {
|
||||
printf("syntax error specifyingstrchr\n");
|
||||
tfree(p);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -86,6 +88,7 @@ com_let(wordlist *wl)
|
|||
/* sanity check */
|
||||
if (eq(p, "all") ||strchr(p, '@')) {
|
||||
fprintf(cp_err, "Error: bad variable name %s\n", p);
|
||||
tfree(p);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -100,7 +103,8 @@ com_let(wordlist *wl)
|
|||
t = ft_evaluate(nn);
|
||||
if (!t) {
|
||||
fprintf(cp_err, "Error: Can't evaluate %s\n", rhs);
|
||||
tfree(p);
|
||||
free_pnode(nn);
|
||||
tfree(p);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -116,8 +120,7 @@ com_let(wordlist *wl)
|
|||
} else {
|
||||
if (numdims) {
|
||||
fprintf(cp_err, "Can't assign into a subindex of a new vector\n");
|
||||
tfree(p);
|
||||
return;
|
||||
goto quit;
|
||||
}
|
||||
|
||||
/* create and assign a new vector */
|
||||
|
|
@ -175,16 +178,14 @@ com_let(wordlist *wl)
|
|||
length * cube);
|
||||
if (newvec)
|
||||
n->v_flags &= ~VF_PERMANENT;
|
||||
tfree(p);
|
||||
return;
|
||||
goto quit;
|
||||
}
|
||||
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;
|
||||
goto quit;
|
||||
} else if (isreal(t)) {
|
||||
bcopy((char *) t->v_realdata, (char *) (n->v_realdata + offset),
|
||||
length * sizeof (double));
|
||||
|
|
@ -201,7 +202,10 @@ com_let(wordlist *wl)
|
|||
if (newvec)
|
||||
cp_addkword(CT_VECTOR, n->v_name);
|
||||
|
||||
/* XXXX Free t !?! */
|
||||
quit:
|
||||
/* va: garbage collection for t, if pnode nn is no simple value */
|
||||
if (nn->pn_value==NULL && t!=NULL) vec_free(t);
|
||||
free_pnode(nn); /* frees also t, if pnode nn is simple value */
|
||||
tfree(p);
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
void
|
||||
com_set(wordlist *wl)
|
||||
{
|
||||
struct variable *vars;
|
||||
struct variable *vars, *oldvar;
|
||||
char *s;
|
||||
|
||||
if (wl == NULL) {
|
||||
|
|
@ -44,8 +44,16 @@ com_set(wordlist *wl)
|
|||
s = (char *) NULL;
|
||||
}
|
||||
cp_vset(vars->va_name, vars->va_type, s);
|
||||
oldvar = vars;
|
||||
vars = vars->va_next;
|
||||
/* va: avoid memory leak: free oldvar carefully */
|
||||
tfree(oldvar->va_name);
|
||||
if (oldvar->va_type==VT_STRING)
|
||||
tfree(oldvar->va_string); /* copied in cp_vset */
|
||||
/* don't free oldvar->va_list! This structure is used furthermore! */
|
||||
tfree(oldvar);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -52,6 +52,16 @@
|
|||
|
||||
#ifdef EXPERIMENTAL_CODE
|
||||
#include "com_option.h"
|
||||
void com_loadsnap(wordlist *wl);
|
||||
void com_savesnap(wordlist *wl);
|
||||
#endif
|
||||
|
||||
#include "com_dl.h"
|
||||
|
||||
#ifdef XSPICE
|
||||
/* gtri - begin - wbk - add include files */
|
||||
#include "evtproto.h"
|
||||
/* gtri - end - wbk - add include files */
|
||||
#endif
|
||||
|
||||
/* FIXME: Integrate spcp_coms and nutcp_coms into one variable. */
|
||||
|
|
@ -83,6 +93,14 @@ struct comm spcp_coms[] = {
|
|||
{ 020000, 020000, 020000, 020000 }, E_DEFHMASK, 0, LOTS,
|
||||
arg_set,
|
||||
"[option] [option = value] ... : Set a simulator option." } ,
|
||||
{ "savesnap", com_savesnap, FALSE, FALSE, TRUE,
|
||||
{ 1, 040000, 040000, 040000 }, E_DEFHMASK, 1, 1,
|
||||
(void (*)()) NULL,
|
||||
"file : Save a snapshot." } ,
|
||||
{ "loadsnap", com_loadsnap, FALSE, FALSE, TRUE,
|
||||
{ 1, 040000, 040000, 040000 }, E_DEFHMASK, 2, 2,
|
||||
(void (*)()) NULL,
|
||||
"file : Load a snapshot." } ,
|
||||
#endif
|
||||
|
||||
{ "alias", com_alias, FALSE, FALSE, FALSE,
|
||||
|
|
@ -149,6 +167,24 @@ struct comm spcp_coms[] = {
|
|||
{ 040000, 040000, 040000, 040000 }, E_BEGINNING, 1, LOTS,
|
||||
arg_print,
|
||||
"[col] expr ... : Print vector values." } ,
|
||||
#ifdef XSPICE
|
||||
/* gtri - begin - wbk - add event print command */
|
||||
{ "eprint", EVTprint, FALSE, FALSE, TRUE,
|
||||
{ 040000, 040000, 040000, 040000 }, E_BEGINNING, 1, LOTS,
|
||||
(void (*)()) NULL,
|
||||
"node node ... : Print event values." } ,
|
||||
/* gtri - end - wbk - add event print command */
|
||||
{ "codemodel", com_codemodel, FALSE, FALSE, TRUE,
|
||||
{ 040000, 040000, 040000, 040000 }, E_BEGINNING, 1, LOTS,
|
||||
(void (*)()) NULL,
|
||||
"library library ... : Loads the opus librarys." } ,
|
||||
#endif
|
||||
#ifdef DEVLIB
|
||||
{ "use", com_use, FALSE, FALSE, TRUE,
|
||||
{ 040000, 040000, 040000, 040000 }, E_BEGINNING, 1, LOTS,
|
||||
(void (*)()) NULL,
|
||||
"library library ... : Loads the device librarys." } ,
|
||||
#endif
|
||||
{ "load", com_load, FALSE, FALSE, TRUE,
|
||||
{ 1, 1, 1, 1 }, E_BEGINNING | E_NOPLOTS, 1, LOTS,
|
||||
arg_load,
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ int stackp = 0;
|
|||
|
||||
/* Notes by CDHW:
|
||||
* This routine leaked like a sieve because each getcommand() created a
|
||||
* wordlist that was never freed becuase it might have been added into
|
||||
* wordlist that was never freed because it might have been added into
|
||||
* the control structure. I've tackled this by making sure that everything
|
||||
* put into the cend[stackp] is a copy. This means that wlist can be
|
||||
* destroyed safely
|
||||
|
|
@ -372,6 +372,8 @@ doblock(struct control *bl, int *num)
|
|||
/*...CDHW*/
|
||||
while ((bl->co_timestodo > 0) ||
|
||||
(bl->co_timestodo == -1)) {
|
||||
if (bl->co_numtimes != -1)
|
||||
bl->co_numtimes--;
|
||||
|
||||
if (!bl->co_children) cp_periodic(); /*CDHW*/
|
||||
|
||||
|
|
@ -569,7 +571,7 @@ getcommand(char *string)
|
|||
return (wlist);
|
||||
}
|
||||
|
||||
|
||||
/* va: TODO: free control structure(s) before overwriting (memory leakage) */
|
||||
int
|
||||
cp_evloop(char *string)
|
||||
{
|
||||
|
|
@ -616,7 +618,7 @@ cp_evloop(char *string)
|
|||
* CO_UNFILLED, the last line was the beginning of a block,
|
||||
* and this is the unfilled first statement.
|
||||
*/
|
||||
|
||||
/* va: TODO: free old structure and its content, before overwriting */
|
||||
if (cend[stackp] && (cend[stackp]->co_type != CO_UNFILLED)) {
|
||||
cend[stackp]->co_next = alloc(struct control);
|
||||
ZERO(cend[stackp]->co_next, struct control);
|
||||
|
|
@ -641,8 +643,9 @@ cp_evloop(char *string)
|
|||
cend[stackp]->co_type = CO_DOWHILE;
|
||||
cend[stackp]->co_cond = wlist->wl_next;
|
||||
if (!cend[stackp]->co_cond) {
|
||||
/* va: prevent misinterpretation as trigraph sequence with \-sign */
|
||||
fprintf(stderr,
|
||||
"Error: missing dowhile condition, '???' will be assumed.\n");
|
||||
"Error: missing dowhile condition, '\?\?\?' will be assumed.\n");
|
||||
}
|
||||
newblock;
|
||||
} else if (eq(wlist->wl_word, "repeat")) {
|
||||
|
|
@ -788,11 +791,11 @@ cp_evloop(char *string)
|
|||
break;
|
||||
case BROKEN:
|
||||
fprintf(cp_err,
|
||||
"Error: break not in loop (or too many break levels given)\n");
|
||||
"Error: break not in loop or too many break levels given\n");
|
||||
break;
|
||||
case CONTINUED:
|
||||
fprintf(cp_err,
|
||||
"Error: continue not in loop (or too many continue levels given)\n");
|
||||
"Error: continue not in loop or too many continue levels given\n");
|
||||
break;
|
||||
default:
|
||||
x = findlabel(i, control[stackp]);
|
||||
|
|
@ -808,6 +811,7 @@ cp_evloop(char *string)
|
|||
return (1); /* The return value is irrelevant. */
|
||||
}
|
||||
wl_free(wlist); wlist = NULL;
|
||||
return (0); /* va: which value? */
|
||||
}
|
||||
|
||||
/* This blows away the control structures... */
|
||||
|
|
|
|||
|
|
@ -265,23 +265,27 @@ cp_istrue(wordlist *wl)
|
|||
|
||||
pn = ft_getpnames(wl, TRUE);
|
||||
v = ft_evaluate(pn);
|
||||
free_pnode(pn);
|
||||
|
||||
/* It makes no sense to say while (all), but what the heck... */
|
||||
while (v) {
|
||||
if (isreal(v)) {
|
||||
for (i = 0; i < v->v_length; i++)
|
||||
if (v->v_realdata[i] != 0.0)
|
||||
return (TRUE);
|
||||
if (v->v_realdata[i] != 0.0) {
|
||||
free_pnode(pn);
|
||||
return (TRUE);
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < v->v_length; i++)
|
||||
if ((realpart(&v->v_compdata[i]) != 0.0) ||
|
||||
(imagpart(&v->v_compdata[i]) != 0.0))
|
||||
(imagpart(&v->v_compdata[i]) != 0.0)) {
|
||||
free_pnode(pn);
|
||||
return (TRUE);
|
||||
}
|
||||
}
|
||||
v = v->v_link2;
|
||||
}
|
||||
return (FALSE);
|
||||
free_pnode(pn);
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
/* This gets called before every command is executed... */
|
||||
|
|
|
|||
|
|
@ -235,16 +235,17 @@ all_show(wordlist *wl, int mode)
|
|||
int
|
||||
printstr(dgen *dg, char *name)
|
||||
{
|
||||
/* va: ' ' is no flag for %s; \? avoids trigraph warning */
|
||||
if (*name == 'n') {
|
||||
if (dg->instance)
|
||||
printf(" % *.*s", DEV_WIDTH, DEV_WIDTH, dg->instance->GENname);
|
||||
printf(" %*.*s", DEV_WIDTH, DEV_WIDTH, dg->instance->GENname);
|
||||
else
|
||||
printf(" %*s", DEV_WIDTH, "<???????>");
|
||||
printf(" %*s", DEV_WIDTH, "<\?\?\?\?\?\?\?>");
|
||||
} else if (*name == 'm') {
|
||||
if (dg->model)
|
||||
printf(" % *.*s", DEV_WIDTH, DEV_WIDTH, dg->model->GENmodName);
|
||||
printf(" %*.*s", DEV_WIDTH, DEV_WIDTH, dg->model->GENmodName);
|
||||
else
|
||||
printf(" %*s", DEV_WIDTH, "<???????>");
|
||||
printf(" %*s", DEV_WIDTH, "<\?\?\?\?\?\?\?>");
|
||||
} else
|
||||
printf(" %*s", DEV_WIDTH, "<error>");
|
||||
|
||||
|
|
@ -400,6 +401,7 @@ printvals(dgen *dg, IFparm *p, int i)
|
|||
}
|
||||
|
||||
if (p->dataType & IF_VECTOR) {
|
||||
/* va: ' ' is no flag for %s */
|
||||
switch ((p->dataType & IF_VARTYPES) & ~IF_VECTOR) {
|
||||
case IF_FLAG:
|
||||
printf(" % *d", DEV_WIDTH, val.v.vec.iVec[i]);
|
||||
|
|
@ -417,13 +419,13 @@ printvals(dgen *dg, IFparm *p, int i)
|
|||
printf(" % *.6g", DEV_WIDTH, val.v.vec.cVec[i / 2].imag);
|
||||
break;
|
||||
case IF_STRING:
|
||||
printf(" % *.*s", DEV_WIDTH, DEV_WIDTH, val.v.vec.sVec[i]);
|
||||
printf(" %*.*s", DEV_WIDTH, DEV_WIDTH, val.v.vec.sVec[i]);
|
||||
break;
|
||||
case IF_INSTANCE:
|
||||
printf(" % *.*s", DEV_WIDTH, DEV_WIDTH, val.v.vec.uVec[i]);
|
||||
printf(" %*.*s", DEV_WIDTH, DEV_WIDTH, val.v.vec.uVec[i]);
|
||||
break;
|
||||
default:
|
||||
printf(" % *.*s", DEV_WIDTH, DEV_WIDTH, " ******** ");
|
||||
printf(" %*.*s", DEV_WIDTH, DEV_WIDTH, " ******** ");
|
||||
}
|
||||
} else {
|
||||
switch ((p->dataType & IF_VARTYPES) & ~IF_VECTOR) {
|
||||
|
|
@ -443,13 +445,13 @@ printvals(dgen *dg, IFparm *p, int i)
|
|||
printf(" % *.6g", DEV_WIDTH, val.cValue.imag);
|
||||
break;
|
||||
case IF_STRING:
|
||||
printf(" % *.*s", DEV_WIDTH, DEV_WIDTH, val.sValue);
|
||||
printf(" %*.*s", DEV_WIDTH, DEV_WIDTH, val.sValue);
|
||||
break;
|
||||
case IF_INSTANCE:
|
||||
printf(" % *.*s", DEV_WIDTH, DEV_WIDTH, val.uValue);
|
||||
printf(" %*.*s", DEV_WIDTH, DEV_WIDTH, val.uValue);
|
||||
break;
|
||||
default:
|
||||
printf(" % *.*s", DEV_WIDTH, DEV_WIDTH, " ******** ");
|
||||
printf(" %*.*s", DEV_WIDTH, DEV_WIDTH, " ******** ");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -575,6 +577,7 @@ com_alter_common(wordlist *wl, int do_model)
|
|||
char *param;
|
||||
struct dvec *dv;
|
||||
struct pnode *names;
|
||||
char *hlp=NULL;
|
||||
|
||||
if (!ft_curckt) {
|
||||
fprintf(cp_err, "Error: no circuit loaded\n");
|
||||
|
|
@ -637,7 +640,6 @@ com_alter_common(wordlist *wl, int do_model)
|
|||
return;
|
||||
}
|
||||
dv = ft_evaluate(names);
|
||||
free_pnode(names);
|
||||
if (!dv)
|
||||
return;
|
||||
if (dv->v_length < 1) {
|
||||
|
|
@ -647,8 +649,9 @@ com_alter_common(wordlist *wl, int do_model)
|
|||
|
||||
if_setparam(ft_curckt->ci_ckt, &dev, param, dv, do_model);
|
||||
|
||||
/* Vector data (dv) should get garbage-collected. */
|
||||
|
||||
/* va: garbage collection for dv, if pnode names is no simple value */
|
||||
if (names->pn_value==NULL && dv!=NULL) vec_free(dv);
|
||||
free_pnode(names); /* free also dv, if pnode names is simple value */
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -55,6 +55,11 @@ extern int PS_Init(void), PS_NewViewport(GRAPH *graph), PS_Close(void), PS_Clea
|
|||
PS_DefineLinestyle(), PS_SetLinestyle(int linestyleid), PS_SetColor(int colorid),
|
||||
PS_Update(void);
|
||||
|
||||
extern int GL_Init(void), GL_NewViewport(GRAPH *graph), GL_Close(void), GL_Clear(void),
|
||||
GL_DrawLine(int x1, int y1, int x2, int y2), GL_Arc(int x0, int y0, int r, double theta1, double theta2), GL_Text(char *text, int x, int y),
|
||||
GL_DefineLinestyle(), GL_SetLinestyle(int linestyleid), GL_SetColor(int colorid),
|
||||
GL_Update(void);
|
||||
|
||||
DISPDEVICE device[] = {
|
||||
|
||||
{"error", 0, 0, 0, 0, 0, 0, nop, nop,
|
||||
|
|
@ -106,6 +111,13 @@ DISPDEVICE device[] = {
|
|||
nodev, nodev, nodev, nodev,
|
||||
gen_DatatoScreen,},
|
||||
|
||||
{"hpgl", 0, 0, 1000, 1000, 0, 0, GL_Init, GL_NewViewport,
|
||||
GL_Close, GL_Clear,
|
||||
GL_DrawLine, GL_Arc, GL_Text, nodev, nodev,
|
||||
GL_SetLinestyle, GL_SetColor, GL_Update,
|
||||
nodev, nodev, nodev, nodev,
|
||||
gen_DatatoScreen,},
|
||||
|
||||
{"printf", 0, 0, 24, 80, 0, 0, nodev, nodev,
|
||||
nodev, nodev,
|
||||
nodev, nodev, nodev, nodev, nodev,
|
||||
|
|
@ -142,8 +154,9 @@ DISPDEVICE *FindDev(char *name)
|
|||
void
|
||||
DevInit(void)
|
||||
{
|
||||
|
||||
char buf[128];
|
||||
#ifndef X_DISPLAY_MISSING
|
||||
char buf[128]; /* va: used with NOT X_DISPLAY_MISSING only */
|
||||
#endif /* X_DISPLAY_MISSING */
|
||||
|
||||
/* note: do better determination */
|
||||
|
||||
|
|
@ -157,10 +170,7 @@ DevInit(void)
|
|||
#ifndef X_DISPLAY_MISSING
|
||||
/* determine display type */
|
||||
if (getenv("DISPLAY") || cp_getvar("display", VT_STRING, buf)) {
|
||||
|
||||
#ifndef X_DISPLAY_MISSING
|
||||
dispdev = FindDev("X11");
|
||||
#endif
|
||||
dispdev = FindDev("X11");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -39,14 +39,16 @@ sig_matherr(void)
|
|||
|
||||
|
||||
/* Note that ft_evaluate will return NULL on invalid expressions. */
|
||||
|
||||
/* va: NOTE: ft_evaluate returns a new vector for expressions (func, op, ...)
|
||||
and an existing vector (node->pn_value) when node->pn_value != NULL.
|
||||
For garbage collection caller must vec_free() expression-vector. */
|
||||
struct dvec *
|
||||
ft_evaluate(struct pnode *node)
|
||||
{
|
||||
struct dvec *d = NULL;
|
||||
|
||||
if (!node)
|
||||
return (NULL);
|
||||
d = NULL;
|
||||
else if (node->pn_value)
|
||||
d = node->pn_value;
|
||||
else if (node->pn_func)
|
||||
|
|
@ -60,15 +62,18 @@ ft_evaluate(struct pnode *node)
|
|||
(node->pn_left, node->pn_right));
|
||||
} else {
|
||||
fprintf(cp_err, "ft_evaluate: Internal Error: bad node\n");
|
||||
return (NULL);
|
||||
d = NULL;
|
||||
}
|
||||
|
||||
if (!d) {
|
||||
if (d == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (node->pn_name && !ft_evdb && d && !d->v_link2)
|
||||
if (node->pn_name && !ft_evdb && d && !d->v_link2) {
|
||||
if(d->v_name)
|
||||
tfree(d->v_name);
|
||||
d->v_name = copy(node->pn_name);
|
||||
}
|
||||
|
||||
if (!d->v_length) {
|
||||
fprintf(cp_err, "Error: no such vector %s\n", d->v_name);
|
||||
|
|
@ -291,6 +296,9 @@ doop(char what,
|
|||
}
|
||||
}
|
||||
|
||||
/* va: garbage collection */
|
||||
if (arg1->pn_value==NULL && v1!=NULL) vec_free(v1);
|
||||
if (arg2->pn_value==NULL && v2!=NULL) vec_free(v2);
|
||||
return (res);
|
||||
}
|
||||
|
||||
|
|
@ -490,6 +498,10 @@ op_range(struct pnode *arg1, struct pnode *arg2)
|
|||
*/
|
||||
|
||||
vec_new(res);
|
||||
|
||||
/* va: garbage collection */
|
||||
if (arg1->pn_value==NULL && v!=NULL) vec_free(v);
|
||||
if (arg1->pn_value==NULL && ind!=NULL) vec_free(ind);
|
||||
return (res);
|
||||
}
|
||||
|
||||
|
|
@ -639,6 +651,10 @@ op_ind(struct pnode *arg1, struct pnode *arg2)
|
|||
*/
|
||||
|
||||
vec_new(res);
|
||||
|
||||
/* va: garbage collection */
|
||||
if (arg1->pn_value==NULL && v!=NULL) vec_free(v);
|
||||
if (arg1->pn_value==NULL && ind!=NULL) vec_free(ind);
|
||||
return (res);
|
||||
}
|
||||
|
||||
|
|
@ -765,6 +781,8 @@ apply_func(struct func *func, struct pnode *arg)
|
|||
end = t;
|
||||
}
|
||||
|
||||
/* va: garbage collection */
|
||||
if (arg->pn_value==NULL && v!=NULL) vec_free(v);
|
||||
return (newv);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ dgen_for_n(dgen *dg, int n, int (*fn) (/* ??? */), void *data, int subindex)
|
|||
int dnum, i, j, k;
|
||||
|
||||
dgxp = &dgx;
|
||||
bcopy(dg, dgxp, sizeof(dgx));
|
||||
bcopy((void *)dg, (void *)dgxp, sizeof(dgx)); /* va: compatible pointer types */
|
||||
|
||||
dnum = dgxp->dev_type_no;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#include <cpdefs.h>
|
||||
#include <string.h>
|
||||
|
||||
int
|
||||
hcomp(const void *a, const void *b)
|
||||
|
|
|
|||
|
|
@ -26,6 +26,12 @@ Author: 1985 Wayne A. Christopher
|
|||
#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);
|
||||
|
|
@ -44,7 +50,7 @@ com_listing(wordlist *wl)
|
|||
bool expand = FALSE;
|
||||
char *s;
|
||||
|
||||
if (ft_curckt) {
|
||||
if (ft_curckt) { /* if there is a current circuit . . . . */
|
||||
while (wl) {
|
||||
s = wl->wl_word;
|
||||
switch (*s) {
|
||||
|
|
@ -111,6 +117,13 @@ 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();
|
||||
|
|
@ -272,9 +285,15 @@ line_free(struct line * deck, bool recurse) {
|
|||
/* 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. */
|
||||
* .plot, to perform after the run is over.
|
||||
* Then, we run dodeck, which parses up the deck. */
|
||||
void
|
||||
inp_spsource(FILE *fp, bool comfile, char *filename)
|
||||
/* arguments:
|
||||
* *fp = pointer to the input file
|
||||
* comfile = whether it is a command file. Values are TRUE/FALSE
|
||||
* *filename =
|
||||
*/
|
||||
{
|
||||
struct line *deck, *dd, *ld;
|
||||
struct line *realdeck, *options = NULL;
|
||||
|
|
@ -285,8 +304,10 @@ inp_spsource(FILE *fp, bool comfile, char *filename)
|
|||
FILE *lastin, *lastout, *lasterr;
|
||||
char c;
|
||||
|
||||
/* read in the deck from a file */
|
||||
inp_readall(fp, &deck);
|
||||
|
||||
|
||||
/* if nothing came back from inp_readall, just close fp and return to caller */
|
||||
if (!deck) { /* MW. We must close fp always when returning */
|
||||
fclose(fp);
|
||||
return;
|
||||
|
|
@ -341,8 +362,10 @@ inp_spsource(FILE *fp, bool comfile, char *filename)
|
|||
/* tfree(dd->li_line);
|
||||
tfree(dd); */
|
||||
}
|
||||
} else {
|
||||
for (dd = deck->li_next; dd; dd = ld->li_next) {
|
||||
} /* end if(comfile) */
|
||||
|
||||
else { /* must be regular deck . . . . */
|
||||
for (dd = deck->li_next; dd; dd = ld->li_next) { /* loop through deck and handle control cards */
|
||||
for (s = dd->li_line; (c = *s) && c <= ' '; s++)
|
||||
;
|
||||
if (c == '*' && (s != deck->li_line || s[1] != '#')) {
|
||||
|
|
@ -359,8 +382,10 @@ inp_spsource(FILE *fp, bool comfile, char *filename)
|
|||
if (ciprefix(".control", dd->li_line)) {
|
||||
ld->li_next = dd->li_next;
|
||||
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");
|
||||
|
|
@ -369,8 +394,10 @@ inp_spsource(FILE *fp, bool comfile, char *filename)
|
|||
} else if (ciprefix(".endc", dd->li_line)) {
|
||||
ld->li_next = dd->li_next;
|
||||
line_free(dd,FALSE); /* SJB - free this line's memory */
|
||||
|
||||
/* tfree(dd->li_line);
|
||||
tfree(dd); */
|
||||
|
||||
if (commands)
|
||||
commands = FALSE;
|
||||
else
|
||||
|
|
@ -429,34 +456,67 @@ inp_spsource(FILE *fp, bool comfile, char *filename)
|
|||
} else
|
||||
ld = dd;
|
||||
}
|
||||
}
|
||||
if (deck->li_next) {
|
||||
} /* end for(dd=deck->li_next . . . . */
|
||||
|
||||
|
||||
/* we are done handling the control stuff. Now process remainder of deck */
|
||||
if (deck->li_next) {
|
||||
/* There is something left after the controls. */
|
||||
fprintf(cp_out, "\nCircuit: %s\n\n", tt);
|
||||
|
||||
/* Old location of ENHtranslate_poly. This didn't work, because it
|
||||
* didn't handle models in .SUBCKTs correctly. Moved to new location below
|
||||
* by SDB on 4.13.2003
|
||||
*/
|
||||
|
||||
/* 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;
|
||||
}
|
||||
if( (deck->li_next = inp_subcktexpand(deck->li_next)) == NULL ){
|
||||
line_free(realdeck,TRUE);
|
||||
line_free(deck->li_actual, TRUE);
|
||||
return;
|
||||
} /* done expanding subcircuit macros */
|
||||
|
||||
|
||||
/* Now handle translation of spice2c6 POLYs. */
|
||||
/* New location of ENHtranslate_poly. This should handle .SUBCKTs better . . . .
|
||||
* SDB 4.13.2003. Comments? mailto:sdb@cloud9.net
|
||||
*/
|
||||
#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
|
||||
|
||||
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) {
|
||||
/* now call inp_dodeck, which loads deck into ft_curckt -- the current circuit. */
|
||||
inp_dodeck(deck, tt, wl_first, FALSE, options, filename);
|
||||
|
||||
} /* if (deck->li_next) */
|
||||
|
||||
|
||||
#ifdef TRACE
|
||||
/* SDB debug statement */
|
||||
printf("In inp_spsource, done with dodeck.\n");
|
||||
#endif
|
||||
|
||||
/* Now that the deck is loaded, do the commands, if there are any */
|
||||
if (controls) {
|
||||
for (end = wl = wl_reverse(controls); wl; wl = wl->wl_next)
|
||||
cp_evloop(wl->wl_word);
|
||||
|
||||
wl_free(end);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*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. */
|
||||
cp_popcontrol();
|
||||
|
|
@ -472,9 +532,21 @@ inp_spsource(FILE *fp, bool comfile, char *filename)
|
|||
* 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. */
|
||||
/*------------------------------------------------------------------
|
||||
* It appears that inp_dodeck adds the circuit described by *deck
|
||||
* to the current circuit (ft_curckt).
|
||||
*-----------------------------------------------------------------*/
|
||||
void
|
||||
inp_dodeck(struct line *deck, char *tt, wordlist *end, bool reuse,
|
||||
struct line *options, char *filename)
|
||||
/*fcn arguments:
|
||||
* *deck = the spice deck
|
||||
* *tt = the title of the deck
|
||||
* *end = pointer to the wordlist
|
||||
* reuse
|
||||
* *options
|
||||
* *filename
|
||||
*/
|
||||
{
|
||||
struct circ *ct;
|
||||
struct line *dd;
|
||||
|
|
@ -504,15 +576,39 @@ inp_dodeck(struct line *deck, char *tt, wordlist *end, bool reuse,
|
|||
ft_curckt = ct = alloc(struct circ);
|
||||
}
|
||||
cp_getvar("noparse", VT_BOOL, (char *) &noparse);
|
||||
|
||||
/*----------------------------------------------------
|
||||
* Now assuming that we wanna parse this deck, we call
|
||||
* if_inpdeck which takes the deck and returns a
|
||||
* a pointer to the circuit ckt.
|
||||
*---------------------------------------------------*/
|
||||
if (!noparse)
|
||||
ckt = if_inpdeck(deck, &tab);
|
||||
else
|
||||
ckt = NULL;
|
||||
|
||||
out_init();
|
||||
for (dd = deck; dd; dd = dd->li_next)
|
||||
if (dd->li_error) {
|
||||
char *p, *q;
|
||||
|
||||
/*----------------------------------------------------
|
||||
* Now run throuh the deck and look to see if there are
|
||||
* errors on any line.
|
||||
*---------------------------------------------------*/
|
||||
for (dd = deck; dd; dd = dd->li_next) {
|
||||
|
||||
#ifdef TRACE
|
||||
/* SDB debug statement */
|
||||
printf("In inp_dodeck, looking for errors and examining line %s . . . \n", dd->li_line);
|
||||
#endif
|
||||
|
||||
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');
|
||||
|
|
@ -529,7 +625,10 @@ inp_dodeck(struct line *deck, char *tt, wordlist *end, bool reuse,
|
|||
*q++ = '\n';
|
||||
p = q;
|
||||
} while (p && *p);
|
||||
}
|
||||
} /* end if (dd->li_error) */
|
||||
|
||||
} /* for (dd = deck; dd; dd = dd->li_next) */
|
||||
|
||||
|
||||
/* Add this circuit to the circuit list. If reuse is TRUE then use
|
||||
* the ft_curckt structure. */
|
||||
|
|
@ -542,7 +641,7 @@ inp_dodeck(struct line *deck, char *tt, wordlist *end, bool reuse,
|
|||
cp_kwswitch(CT_NODENAMES, ft_curckt->ci_nodes);
|
||||
ft_newcirc(ct);
|
||||
/* Assign current circuit */
|
||||
ft_curckt = ct;
|
||||
ft_curckt = ct;
|
||||
}
|
||||
ct->ci_name = tt;
|
||||
ct->ci_deck = deck;
|
||||
|
|
@ -551,7 +650,7 @@ inp_dodeck(struct line *deck, char *tt, wordlist *end, bool reuse,
|
|||
ct->ci_origdeck = deck->li_actual;
|
||||
else
|
||||
ct->ci_origdeck = ct->ci_deck;
|
||||
ct->ci_ckt = ckt;
|
||||
ct->ci_ckt = ckt; /* attach the input ckt to the list of circuits */
|
||||
ct->ci_symtab = tab;
|
||||
ct->ci_inprogress = FALSE;
|
||||
ct->ci_runonce = FALSE;
|
||||
|
|
@ -582,24 +681,24 @@ inp_dodeck(struct line *deck, char *tt, wordlist *end, bool reuse,
|
|||
static int one = 1;
|
||||
switch (eev->va_type) {
|
||||
case VT_BOOL:
|
||||
if_option(ct->ci_ckt, eev->va_name,
|
||||
eev->va_type, &one);
|
||||
break;
|
||||
if_option(ct->ci_ckt, eev->va_name,
|
||||
eev->va_type, &one);
|
||||
break;
|
||||
case VT_NUM:
|
||||
if_option(ct->ci_ckt, eev->va_name,
|
||||
eev->va_type, (char *) &eev->va_num);
|
||||
break;
|
||||
if_option(ct->ci_ckt, eev->va_name,
|
||||
eev->va_type, (char *) &eev->va_num);
|
||||
break;
|
||||
case VT_REAL:
|
||||
if_option(ct->ci_ckt, eev->va_name,
|
||||
eev->va_type, (char *) &eev->va_real);
|
||||
break;
|
||||
if_option(ct->ci_ckt, eev->va_name,
|
||||
eev->va_type, (char *) &eev->va_real);
|
||||
break;
|
||||
case VT_STRING:
|
||||
if_option(ct->ci_ckt, eev->va_name,
|
||||
eev->va_type, eev->va_string);
|
||||
break;
|
||||
}
|
||||
if_option(ct->ci_ckt, eev->va_name,
|
||||
eev->va_type, eev->va_string);
|
||||
break;
|
||||
} /* switch . . . */
|
||||
}
|
||||
}
|
||||
} /* if (!noparse) . . . */
|
||||
|
||||
cp_addkword(CT_CKTNAMES, tt);
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -25,14 +25,21 @@ Author: 1985 Wayne A. Christopher
|
|||
#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.
|
||||
* From: jason@ucbopal.BERKELEY.EDU (Jason Venner)
|
||||
* Newsgroups: net.sources
|
||||
*/
|
||||
|
||||
/*-------------------------------------------------------------------------*
|
||||
* 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. *
|
||||
* From: jason@ucbopal.BERKELEY.EDU (Jason Venner) *
|
||||
* Newsgroups: net.sources *
|
||||
*-------------------------------------------------------------------------*/
|
||||
#define STRGROW 256
|
||||
|
||||
static char *
|
||||
|
|
@ -73,10 +80,11 @@ readline(FILE *fd)
|
|||
return (strptr);
|
||||
}
|
||||
|
||||
/* Look up the variable sourcepath and try everything in the list in order
|
||||
* if the file isn't in . and it isn't an abs path name.
|
||||
*/
|
||||
|
||||
/*-------------------------------------------------------------------------*
|
||||
* Look up the variable sourcepath and try everything in the list in order *
|
||||
* if the file isn't in . and it isn't an abs path name. *
|
||||
*-------------------------------------------------------------------------*/
|
||||
FILE *
|
||||
inp_pathopen(char *name, char *mode)
|
||||
{
|
||||
|
|
@ -111,43 +119,103 @@ inp_pathopen(char *name, char *mode)
|
|||
return (NULL);
|
||||
}
|
||||
|
||||
/* Read the entire input file and return a pointer to the first line of
|
||||
* the linked list of 'card' records in data.
|
||||
*/
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Read the entire input file and return a pointer to the first line of
|
||||
* the linked list of 'card' records in data. The pointer is stored in
|
||||
* *data.
|
||||
*-------------------------------------------------------------------------*/
|
||||
void
|
||||
inp_readall(FILE *fp, struct line **data)
|
||||
{
|
||||
struct line *end = NULL, *cc = NULL, *prev = NULL, *working, *newcard;
|
||||
char *buffer, *s, *t, c,*copys;
|
||||
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;
|
||||
|
||||
/* First read in all lines & put them in the struct cc */
|
||||
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))) {
|
||||
#endif
|
||||
|
||||
#ifdef TRACE
|
||||
/* SDB debug statement */
|
||||
printf ("in inp_readall, just read %s . . .\n", buffer);
|
||||
#endif
|
||||
|
||||
/* OK -- now we have loaded the next line into 'buffer'. Process it. */
|
||||
/* If input line is blank, ignore it & continue looping. */
|
||||
if ( (strcmp(buffer,"\n") == 0)
|
||||
|| (strcmp(buffer,"\r\n") == 0) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (*buffer == '@') {
|
||||
tfree(buffer); /* was allocated by readline() */
|
||||
break;
|
||||
}
|
||||
for (s = buffer; *s && (*s != '\n'); s++)
|
||||
;
|
||||
/* loop through 'buffer' until end is reached. Then test for
|
||||
premature end. If premature end is reached, spew
|
||||
error and zap the line. */
|
||||
for (s = buffer; *s && (*s != '\n'); s++);
|
||||
if (!*s) {
|
||||
fprintf(cp_err, "Warning: premature EOF\n");
|
||||
}
|
||||
*s = '\0'; /* Zap the newline. */
|
||||
|
||||
if(*(s-1) == '\r') /* Zop the carriage return under windows */
|
||||
*(s-1) = '\0';
|
||||
|
||||
/* now handle .include statements */
|
||||
if (ciprefix(".include", buffer)) {
|
||||
for (s = buffer; *s && !isspace(*s); s++)
|
||||
for (s = buffer; *s && !isspace(*s); s++)/* advance past non-space chars */
|
||||
;
|
||||
while (isspace(*s))
|
||||
while (isspace(*s)) /* now advance past space chars */
|
||||
s++;
|
||||
if (!*s) {
|
||||
if (!*s) { /* if at end of line, error */
|
||||
fprintf(cp_err, "Error: .include filename missing\n");
|
||||
tfree(buffer); /* was allocated by readline() */
|
||||
continue;
|
||||
}
|
||||
for (t = s; *t && !isspace(*t); t++)
|
||||
} /* Now s points to first char after .include */
|
||||
for (t = s; *t && !isspace(*t); t++) /* now advance past non-space chars */
|
||||
;
|
||||
*t = '\0';
|
||||
*t = '\0'; /* place \0 and end of file name in buffer */
|
||||
|
||||
if (*s == '~') {
|
||||
copys = cp_tildexpand(s); /* allocates memory, but can also return NULL */
|
||||
|
|
@ -155,7 +223,8 @@ inp_readall(FILE *fp, struct line **data)
|
|||
s = copys; /* reuse s, but remember, buffer still points to allocated memory */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* open file specified by .include statement */
|
||||
if (!(newfp = inp_pathopen(s, "r"))) {
|
||||
perror(s);
|
||||
if(copys) {
|
||||
|
|
@ -169,17 +238,22 @@ inp_readall(FILE *fp, struct line **data)
|
|||
tfree(copys); /* allocated by the cp_tildexpand() above */
|
||||
}
|
||||
|
||||
inp_readall(newfp, &newcard);
|
||||
inp_readall(newfp, &newcard); /* read stuff in include file into netlist */
|
||||
(void) fclose(newfp);
|
||||
|
||||
/* Make the .include a comment */
|
||||
*buffer = '*';
|
||||
if (end) {
|
||||
end->li_next = alloc(struct line);
|
||||
end = end->li_next;
|
||||
/* now check if this is the first pass (i.e. end points to null) */
|
||||
if (end) { /* end already exists */
|
||||
end->li_next = alloc(struct line); /* create next card */
|
||||
end = end->li_next; /* make end point to next card */
|
||||
} else {
|
||||
end = cc = alloc(struct line);
|
||||
end = cc = alloc(struct line); /* create the deck & end. cc will
|
||||
point to beginning of deck, end to
|
||||
the end */
|
||||
}
|
||||
|
||||
/* now fill out rest of struct end. */
|
||||
end->li_next = NULL;
|
||||
end->li_error = NULL;
|
||||
end->li_actual = NULL;
|
||||
|
|
@ -193,14 +267,18 @@ inp_readall(FILE *fp, struct line **data)
|
|||
|
||||
/* Fix the buffer up a bit. */
|
||||
(void) strncpy(buffer + 1, "end of:", 7);
|
||||
}
|
||||
} /* end of .include handling */
|
||||
|
||||
if (end) {
|
||||
end->li_next = alloc(struct line);
|
||||
end = end->li_next;
|
||||
} else {
|
||||
end = cc = alloc(struct line);
|
||||
/* now check if this is the first pass (i.e. end points to null) */
|
||||
if (end) { /* end already exists */
|
||||
end->li_next = alloc(struct line); /* create next card */
|
||||
end = end->li_next; /* point to next card */
|
||||
} else { /* End doesn't exist. Create it. */
|
||||
end = cc = alloc(struct line); /* note that cc points to beginning
|
||||
of deck, end to the end */
|
||||
}
|
||||
|
||||
/* now put buffer into li */
|
||||
end->li_next = NULL;
|
||||
end->li_error = NULL;
|
||||
end->li_actual = NULL;
|
||||
|
|
@ -210,31 +288,44 @@ inp_readall(FILE *fp, struct line **data)
|
|||
if (!end) { /* No stuff here */
|
||||
*data = NULL;
|
||||
return;
|
||||
}
|
||||
} /* end while ((buffer = readline(fp))) */
|
||||
|
||||
/* This should be freed because we are done with it. */
|
||||
/* tfree(buffer); */
|
||||
|
||||
|
||||
/* Now clean up li: remove comments & stitch together continuation lines. */
|
||||
working = cc->li_next; /* cc points to head of deck. Start with the
|
||||
next card (skip title). */
|
||||
|
||||
/* Now make logical lines. */
|
||||
working = cc->li_next; /* Skip title. */
|
||||
|
||||
while (working) {
|
||||
for (s = working->li_line; (c = *s) && c <= ' '; s++)
|
||||
;
|
||||
|
||||
#ifdef TRACE
|
||||
/* SDB debug statement */
|
||||
printf("In inp_readall, processing linked list element s = %s . . . \n", s);
|
||||
#endif
|
||||
|
||||
switch (c) {
|
||||
case '#':
|
||||
case '$':
|
||||
case '*':
|
||||
case '\0':
|
||||
/*
|
||||
prev = NULL;
|
||||
*/
|
||||
working = working->li_next;
|
||||
/* this used to be commented out. Why? */
|
||||
/* prev = NULL; */
|
||||
working = working->li_next; /* for these chars, go to next card */
|
||||
break;
|
||||
case '+':
|
||||
case '+': /* handle continuation */
|
||||
if (!prev) {
|
||||
working->li_error = copy(
|
||||
"Illegal continuation line: ignored.");
|
||||
working = working->li_next;
|
||||
break;
|
||||
}
|
||||
|
||||
/* create buffer and write last and current line into it. */
|
||||
buffer = tmalloc(strlen(prev->li_line) + strlen(s) + 2);
|
||||
(void) sprintf(buffer, "%s %s", prev->li_line, s + 1);
|
||||
s = prev->li_line;
|
||||
|
|
@ -258,7 +349,7 @@ inp_readall(FILE *fp, struct line **data)
|
|||
}
|
||||
working = prev->li_next;
|
||||
break;
|
||||
default:
|
||||
default: /* regular one-line card */
|
||||
prev = working;
|
||||
working = working->li_next;
|
||||
break;
|
||||
|
|
@ -270,6 +361,9 @@ inp_readall(FILE *fp, struct line **data)
|
|||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*
|
||||
* *
|
||||
*-------------------------------------------------------------------------*/
|
||||
void
|
||||
inp_casefix(char *string)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -122,7 +122,17 @@ beginPlot(void *analysisPtr, void *circuitPtr, char *cktName, char *analName, ch
|
|||
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))
|
||||
fprintf(cp_err, "(debug printing enabled)\n");
|
||||
|
|
@ -324,10 +334,8 @@ beginPlot(void *analysisPtr, void *circuitPtr, char *cktName, char *analName, ch
|
|||
}
|
||||
|
||||
if (numNames &&
|
||||
(run->numData == 1
|
||||
&& run->refIndex != -1
|
||||
|| run->numData == 0
|
||||
&& run->refIndex == -1))
|
||||
( (run->numData == 1 && run->refIndex != -1)
|
||||
|| (run->numData == 0 && run->refIndex == -1)) ) /* va: suggested parentheses */
|
||||
{
|
||||
fprintf(cp_err, "Error: no data saved for %s; analysis not run\n",
|
||||
spice_analysis_get_description(((JOB *) analysisPtr)->JOBtype));
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ static struct pnode * mkunode(int op, struct pnode *arg);
|
|||
static struct pnode * mkfnode(char *func, struct pnode *arg);
|
||||
static struct pnode * mknnode(double number);
|
||||
static struct pnode * mksnode(char *string);
|
||||
|
||||
void print_elem(struct element *elem); /* va: for debugging */
|
||||
|
||||
static int lasttoken = END, lasttype;
|
||||
static char *sbuf;
|
||||
|
|
@ -115,7 +115,8 @@ checkvalid(struct pnode *pn)
|
|||
/* Everything else is a string or a number. Quoted strings are kept in
|
||||
* the form "string", and the lexer strips off the quotes...
|
||||
*/
|
||||
|
||||
/* va: the structure returned is static, e_string is a copy
|
||||
(in case of e_token==VALUE,e_type==STRING) */
|
||||
static struct element *
|
||||
lexer(void)
|
||||
{
|
||||
|
|
@ -405,13 +406,16 @@ static struct pnode *
|
|||
parse(void)
|
||||
{
|
||||
struct element stack[STACKSIZE];
|
||||
int sp = 0, st, i;
|
||||
char *stringStack[STACKSIZE];
|
||||
int sp = 0, st, i, fsp = 0;
|
||||
struct element *top, *next;
|
||||
struct pnode *pn, *lpn, *rpn;
|
||||
char rel;
|
||||
|
||||
stack[0].e_token = END;
|
||||
next = lexer();
|
||||
if(next->e_token == VALUE && next->e_type == STRING)
|
||||
stringStack[fsp++] = next->e_string;
|
||||
|
||||
while ((sp > 1) || (next->e_token != END)) {
|
||||
/* Find the top-most terminal. */
|
||||
|
|
@ -423,14 +427,16 @@ parse(void)
|
|||
switch (rel) {
|
||||
case L:
|
||||
case E:
|
||||
/* Push the token read. */
|
||||
if (sp == (STACKSIZE - 1)) {
|
||||
/* Push the token read. */
|
||||
if (sp == (STACKSIZE - 1) || fsp == (STACKSIZE-1)) {
|
||||
fprintf(cp_err, "Error: stack overflow\n");
|
||||
return (NULL);
|
||||
}
|
||||
bcopy((char *) next, (char *) &stack[++sp],
|
||||
sizeof (struct element));
|
||||
next = lexer();
|
||||
if(next->e_token == VALUE && next->e_type == STRING)
|
||||
stringStack[fsp++] = next->e_string;
|
||||
continue;
|
||||
|
||||
case R:
|
||||
|
|
@ -491,6 +497,19 @@ parse(void)
|
|||
goto err;
|
||||
if (!(pn = mkfnode(stack[sp].e_string, lpn)))
|
||||
return (NULL);
|
||||
/* va: avoid memory leakage:
|
||||
in case of variablenames (i.e. i(vd)) mkfnode makes in
|
||||
reality a snode, the old lpn (and its plotless vector) is
|
||||
then a memory leak */
|
||||
if (pn->pn_func==NULL && pn->pn_value!=NULL) /* a snode */
|
||||
{
|
||||
if (lpn->pn_value && lpn->pn_value->v_plot==NULL)
|
||||
{
|
||||
tfree(lpn->pn_value->v_name);
|
||||
tfree(lpn->pn_value);
|
||||
}
|
||||
free_pnode(lpn);
|
||||
}
|
||||
} else { /* node op node */
|
||||
lpn = makepnode(&stack[sp]);
|
||||
rpn = makepnode(&stack[st]);
|
||||
|
|
@ -506,6 +525,8 @@ parse(void)
|
|||
}
|
||||
}
|
||||
pn = makepnode(&stack[1]);
|
||||
for(i=0;i<fsp;i++)
|
||||
tfree(stringStack[i]);
|
||||
if (pn)
|
||||
return (pn);
|
||||
err:
|
||||
|
|
@ -535,6 +556,27 @@ makepnode(struct element *elem)
|
|||
}
|
||||
}
|
||||
|
||||
void print_elem(struct element *elem)
|
||||
{
|
||||
printf("e_token = %d", elem->e_token);
|
||||
if (elem->e_token == VALUE) {
|
||||
printf(", e_type = %d", elem->e_type);
|
||||
switch (elem->e_type) {
|
||||
case STRING:
|
||||
printf(", e_string = %s(%p)", elem->e_string,elem->e_string);
|
||||
break;
|
||||
case NUM:
|
||||
printf(", e_double = %g", elem->e_double); break;
|
||||
case PNODE:
|
||||
printf(", e_pnode = %p", elem->e_pnode); break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
||||
/* Some auxiliary functions for building the parse tree. */
|
||||
|
||||
static
|
||||
|
|
@ -803,6 +845,12 @@ mksnode(char *string)
|
|||
end = nv;
|
||||
}
|
||||
p->pn_value = newv;
|
||||
|
||||
/* va: tfree v in case of @xxx[par], because vec_get created a new vec and
|
||||
nobody will free it elsewhere */
|
||||
if (v && v->v_name && *v->v_name=='@' && isreal(v) && v->v_realdata) {
|
||||
vec_free(v);
|
||||
}
|
||||
return (p);
|
||||
}
|
||||
|
||||
|
|
@ -815,6 +863,14 @@ free_pnode(struct pnode *t)
|
|||
free_pnode(t->pn_left);
|
||||
free_pnode(t->pn_right);
|
||||
free_pnode(t->pn_next);
|
||||
tfree(t->pn_name); /* va: it is a copy() of original string, can be free'd */
|
||||
/* va: tfree struct func, allocated within parser */
|
||||
if (t->pn_func!=NULL) {
|
||||
tfree(t->pn_func->fu_name); /* va: name is a copy of original string */
|
||||
tfree(t->pn_func); /* va: t->pn_func->fu_func must not tfree'd */
|
||||
}
|
||||
if (t->pn_value)
|
||||
vec_free(t->pn_value); /* patch by Stefan Jones */
|
||||
tfree(t);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -517,7 +517,7 @@ cp_addkword(int class, char *word)
|
|||
class);
|
||||
return;
|
||||
}
|
||||
word = copy(word);
|
||||
/* word = copy(word); va: not necessary, clookup copies itself (memory leak) */
|
||||
cc = clookup(word, &keywords[class], FALSE, TRUE);
|
||||
cc->cc_invalid = 0;
|
||||
return;
|
||||
|
|
@ -574,10 +574,12 @@ cp_ccrestart(bool kwords)
|
|||
void
|
||||
throwaway(struct ccom *dbase)
|
||||
{
|
||||
if (!dbase) return; /* va: security first */
|
||||
if (dbase->cc_child)
|
||||
throwaway(dbase->cc_child);
|
||||
if (dbase->cc_sibling)
|
||||
throwaway(dbase->cc_sibling);
|
||||
tfree(dbase->cc_name); /* va: also tfree dbase->cc_name (memory leak) */
|
||||
tfree(dbase);
|
||||
return;
|
||||
}
|
||||
|
|
@ -727,8 +729,8 @@ cdelete(struct ccom *node, struct ccom **top)
|
|||
/* now free() everything and check the top */
|
||||
if (node == *top)
|
||||
*top = node->cc_sibling;
|
||||
free(node->cc_name);
|
||||
free(node);
|
||||
tfree(node->cc_name); /* va: we should allways use tfree */
|
||||
tfree(node);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ GRAPH *CopyGraph(GRAPH *graph)
|
|||
struct dveclist *link, *newlink;
|
||||
|
||||
ret = NewGraph();
|
||||
bcopy(graph, ret, sizeof(struct graph));
|
||||
bcopy((void *)graph, (void *)ret, sizeof(GRAPH)); /* va: compatible pointer types */
|
||||
|
||||
ret->graphid = RunningId - 1; /* restore id */
|
||||
|
||||
|
|
|
|||
|
|
@ -250,9 +250,12 @@ plotit(wordlist *wl, char *hcopy, char *devname)
|
|||
struct dvec *v, *newv_scale;
|
||||
double *newdata, *newscale;
|
||||
double tstep, tstart, tstop, ttime;
|
||||
|
||||
/* return value, error by default */
|
||||
bool rtn = FALSE;
|
||||
|
||||
if (!wl)
|
||||
return FALSE;
|
||||
goto quit1;
|
||||
wl_root = wl;
|
||||
|
||||
/* First get the command line, without the limits. */
|
||||
|
|
@ -261,7 +264,9 @@ plotit(wordlist *wl, char *hcopy, char *devname)
|
|||
(void) getlims(wwl, "xlimit", 2);
|
||||
(void) getlims(wwl, "yl", 2);
|
||||
(void) getlims(wwl, "ylimit", 2);
|
||||
(void) sprintf(cline, "plot %s", wl_flatten(wwl));
|
||||
pname = wl_flatten(wwl);
|
||||
(void) sprintf(cline, "plot %s", pname);
|
||||
tfree(pname);
|
||||
|
||||
wl_free(wwl);
|
||||
|
||||
|
|
@ -513,9 +518,10 @@ plotit(wordlist *wl, char *hcopy, char *devname)
|
|||
nointerp = TRUE;
|
||||
|
||||
wl = wl->wl_next;
|
||||
tfree(tw);
|
||||
if (!wl) {
|
||||
fprintf(cp_err, "Error: no vectors given\n");
|
||||
return (FALSE);
|
||||
goto quit1;
|
||||
}
|
||||
|
||||
wl->wl_prev = NULL;
|
||||
|
|
@ -531,7 +537,7 @@ plotit(wordlist *wl, char *hcopy, char *devname)
|
|||
|
||||
names = ft_getpnames(wl, FALSE);
|
||||
if (names == NULL)
|
||||
return (FALSE);
|
||||
goto quit1;
|
||||
|
||||
/* Now evaluate the names. */
|
||||
for (n = names, lv = NULL; n; n = n->pn_next) {
|
||||
|
|
@ -539,16 +545,16 @@ plotit(wordlist *wl, char *hcopy, char *devname)
|
|||
eq(n->pn_value->v_name, "vs")) {
|
||||
if (!lv) {
|
||||
fprintf(cp_err, "Error: misplaced vs arg\n");
|
||||
return (FALSE);
|
||||
goto quit;
|
||||
} else {
|
||||
if (!(n = n->pn_next)) {
|
||||
fprintf(cp_err,
|
||||
"Error: missing vs arg\n");
|
||||
return (FALSE);
|
||||
goto quit;
|
||||
}
|
||||
dv = ft_evaluate(n);
|
||||
if (!dv)
|
||||
return (FALSE);
|
||||
goto quit;
|
||||
if (lastvs)
|
||||
lv = lastvs->v_link2;
|
||||
else
|
||||
|
|
@ -563,7 +569,7 @@ plotit(wordlist *wl, char *hcopy, char *devname)
|
|||
}
|
||||
dv = ft_evaluate(n);
|
||||
if (!dv)
|
||||
return (FALSE);
|
||||
goto quit;
|
||||
if (!d)
|
||||
vecs = dv;
|
||||
else
|
||||
|
|
@ -572,7 +578,7 @@ plotit(wordlist *wl, char *hcopy, char *devname)
|
|||
;
|
||||
lv = dv;
|
||||
}
|
||||
free_pnode(names);
|
||||
/* free_pnode(names); pn:really should be commented out ? */
|
||||
d->v_link2 = NULL;
|
||||
|
||||
/* Now check for 0-length vectors. */
|
||||
|
|
@ -580,7 +586,7 @@ plotit(wordlist *wl, char *hcopy, char *devname)
|
|||
if (!d->v_length) {
|
||||
fprintf(cp_err, "Error: %s: no such vector\n",
|
||||
d->v_name);
|
||||
return (FALSE);
|
||||
goto quit;
|
||||
}
|
||||
|
||||
/* If there are higher dimensional vectors, transform them into a
|
||||
|
|
@ -655,7 +661,7 @@ plotit(wordlist *wl, char *hcopy, char *devname)
|
|||
oneval ? 1 : 0) {
|
||||
fprintf(cp_err,
|
||||
"Error: plot must be either all pole-zero or contain no poles or zeros\n");
|
||||
return (FALSE);
|
||||
goto quit;
|
||||
}
|
||||
|
||||
if ((gtype == GRID_POLAR) || (gtype == GRID_SMITH
|
||||
|
|
@ -837,13 +843,13 @@ plotit(wordlist *wl, char *hcopy, char *devname)
|
|||
(gtype == GRID_LOGLOG))) {
|
||||
fprintf(cp_err,
|
||||
"Error: X values must be > 0 for log scale\n");
|
||||
return (FALSE);
|
||||
goto quit;
|
||||
}
|
||||
if ((ylims[0] <= 0.0) && ((gtype == GRID_YLOG) ||
|
||||
(gtype == GRID_LOGLOG))) {
|
||||
fprintf(cp_err,
|
||||
"Error: Y values must be > 0 for log scale\n");
|
||||
return (FALSE);
|
||||
goto quit;
|
||||
}
|
||||
|
||||
/* Fix the plot limits for smith and polar grids. */
|
||||
|
|
@ -904,7 +910,7 @@ plotit(wordlist *wl, char *hcopy, char *devname)
|
|||
newscale, newlen, 1)) {
|
||||
fprintf(cp_err,
|
||||
"Error: can't interpolate %s\n", v->v_name);
|
||||
return(FALSE);
|
||||
goto quit;
|
||||
}
|
||||
|
||||
tfree(v->v_realdata);
|
||||
|
|
@ -922,7 +928,8 @@ plotit(wordlist *wl, char *hcopy, char *devname)
|
|||
((gtype == GRID_XLOG) || (gtype == GRID_LOGLOG)),
|
||||
((gtype == GRID_YLOG) || (gtype == GRID_LOGLOG)),
|
||||
nointerp);
|
||||
return (TRUE);
|
||||
rtn = TRUE;
|
||||
goto quit;
|
||||
}
|
||||
|
||||
/* See if there is one type we can give for the y scale... */
|
||||
|
|
@ -939,7 +946,8 @@ plotit(wordlist *wl, char *hcopy, char *devname)
|
|||
xlabel ? xlabel : ft_typabbrev(vecs->v_scale->v_type),
|
||||
ylabel ? ylabel : ft_typabbrev(j),
|
||||
gtype, ptype, vecs);
|
||||
return (TRUE);
|
||||
rtn = TRUE;
|
||||
goto quit;
|
||||
}
|
||||
for (d = vecs, i = 0; d; d = d->v_link2)
|
||||
i++;
|
||||
|
|
@ -954,7 +962,7 @@ plotit(wordlist *wl, char *hcopy, char *devname)
|
|||
title ? title : vecs->v_plot->pl_title, hcopy, i,
|
||||
xdelta ? *xdelta : 0.0, ydelta ? *ydelta : 0.0, gtype,
|
||||
ptype, xlabel, ylabel, xt, j, pname, cline))
|
||||
return (FALSE);
|
||||
goto quit;
|
||||
|
||||
/* Now plot all the graphs. */
|
||||
for (d = vecs; d; d = d->v_link2)
|
||||
|
|
@ -962,6 +970,10 @@ plotit(wordlist *wl, char *hcopy, char *devname)
|
|||
|
||||
gr_clean();
|
||||
|
||||
return (TRUE);
|
||||
rtn = TRUE;
|
||||
quit:
|
||||
free_pnode(names);
|
||||
quit1:
|
||||
return rtn;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -47,8 +47,9 @@ pvec(struct dvec *d)
|
|||
case GRID_SMITHGRID:
|
||||
strcat(buf, ", grid = smithgrid (not xformed)");
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
default: /* va: GRID_NONE or GRID_LIN */
|
||||
break;
|
||||
}
|
||||
|
||||
switch (d->v_plottype) {
|
||||
|
|
@ -61,8 +62,10 @@ pvec(struct dvec *d)
|
|||
strcat(buf, ", plot = point");
|
||||
break;
|
||||
|
||||
default:
|
||||
default: /* va: PLOT_LIN, */
|
||||
break;
|
||||
}
|
||||
|
||||
if (d->v_defcolor) {
|
||||
sprintf(buf2, ", color = %s", d->v_defcolor);
|
||||
strcat(buf, buf2);
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
|
|||
#include "postcoms.h"
|
||||
#include "quote.h"
|
||||
#include "variable.h"
|
||||
#include "parser/complete.h" /* va: throwaway */
|
||||
|
||||
/* static declarations */
|
||||
static void killplot(struct plot *pl);
|
||||
|
|
@ -602,6 +603,7 @@ com_destroy(wordlist *wl)
|
|||
static void
|
||||
killplot(struct plot *pl)
|
||||
{
|
||||
|
||||
struct dvec *v, *nv = NULL;
|
||||
struct plot *op;
|
||||
|
||||
|
|
@ -609,10 +611,12 @@ killplot(struct plot *pl)
|
|||
fprintf(cp_err, "Error: can't destroy the constant plot\n");
|
||||
return;
|
||||
}
|
||||
/* pl_dvecs, pl_scale */
|
||||
for (v = pl->pl_dvecs; v; v = nv) {
|
||||
nv = v->v_next;
|
||||
vec_free(v);
|
||||
}
|
||||
/* unlink from plot_list (linked via pl_next) */
|
||||
if (pl == plot_list) {
|
||||
plot_list = pl->pl_next;
|
||||
if (pl == plot_cur)
|
||||
|
|
@ -632,9 +636,18 @@ killplot(struct plot *pl)
|
|||
tfree(pl->pl_name);
|
||||
tfree(pl->pl_typename);
|
||||
wl_free(pl->pl_commands);
|
||||
|
||||
/* Never mind about the rest... */
|
||||
|
||||
tfree(pl->pl_date); /* va: also tfree (memory leak) */
|
||||
if (pl->pl_ccom) /* va: also tfree (memory leak) */
|
||||
{
|
||||
throwaway((struct ccom *)pl->pl_ccom);
|
||||
}
|
||||
if (pl->pl_env) /* The 'environment' for this plot. */
|
||||
{
|
||||
/* va: HOW to do? */
|
||||
printf("va: killplot should tfree pl->pl_env=(%p)\n", pl->pl_env); fflush(stdout);
|
||||
}
|
||||
tfree(pl); /* va: also tfree pl itself (memory leak) */
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,351 +1,472 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1988 Jeffrey M. Hsu
|
||||
**********/
|
||||
|
||||
/*
|
||||
Postscript driver
|
||||
*/
|
||||
|
||||
#include "ngspice.h"
|
||||
#include "cpdefs.h"
|
||||
#include "graph.h"
|
||||
#include "ftedbgra.h"
|
||||
#include "ftedev.h"
|
||||
#include "fteinput.h"
|
||||
|
||||
#include "postsc.h"
|
||||
#include "variable.h"
|
||||
|
||||
#define RAD_TO_DEG (180.0 / M_PI)
|
||||
#define DEVDEP(g) (*((PSdevdep *) (g)->devdep))
|
||||
#define MAX_PS_LINES 1000
|
||||
#define SOLID 0
|
||||
#define DOTTED 1
|
||||
|
||||
#define gtype graph->grid.gridtype
|
||||
#define xoff dispdev->minx
|
||||
#define yoff dispdev->miny
|
||||
#define XOFF 48 /* printer left margin */
|
||||
#define YOFF 48 /* printer bottom margin */
|
||||
#define XTADJ 0 /* printer text adjustment x */
|
||||
#define YTADJ 4 /* printer text adjustment y */
|
||||
|
||||
#define GRIDSIZE 420 /* printer gridsize divisible by 10, [7-2] */
|
||||
#define GRIDSIZES 360 /* printer gridsize divisible by [10-8], [6-2] */
|
||||
|
||||
#define FONTSIZE 10 /* printer default fontsize */
|
||||
#define FONTWIDTH 6 /* printer default fontwidth */
|
||||
#define FONTHEIGHT 14 /* printer default fontheight */
|
||||
|
||||
typedef struct {
|
||||
int lastlinestyle; /* initial invalid value */
|
||||
int lastx, lasty, linecount;
|
||||
} PSdevdep;
|
||||
|
||||
static char *linestyle[] = {
|
||||
"[]", /* solid */
|
||||
"[1 2]", /* dotted */
|
||||
"[7 7]", /* longdashed */
|
||||
"[3 3]", /* shortdashed */
|
||||
"[7 2 2 2]", /* longdotdashed */
|
||||
"[3 2 1 2]", /* shortdotdashed */
|
||||
"[8 3 2 3]",
|
||||
"[14 2]",
|
||||
"[3 5 1 5]" /* dotdashed */
|
||||
};
|
||||
|
||||
static FILE *plotfile;
|
||||
char psfont[128], psfontsize[32], psscale[32];
|
||||
static int fontsize = FONTSIZE;
|
||||
static int fontwidth = FONTWIDTH;
|
||||
static int fontheight = FONTHEIGHT;
|
||||
static int screenflag = 0;
|
||||
static double scale; /* Used for fine tuning */
|
||||
static int xtadj; /* text adjustment x */
|
||||
static int ytadj; /* text adjustment y */
|
||||
static int hcopygraphid;
|
||||
|
||||
|
||||
extern int DestroyGraph (int id);
|
||||
int PS_SetLinestyle (int linestyleid);
|
||||
extern void internalerror (char *message);
|
||||
|
||||
int
|
||||
PS_Init(void)
|
||||
{
|
||||
if (!cp_getvar("hcopyscale", VT_STRING, psscale)) {
|
||||
scale = 1.0;
|
||||
} else {
|
||||
sscanf(psscale, "%lf", &scale);
|
||||
if ((scale <= 0) || (scale > 10))
|
||||
scale = 1.0;
|
||||
}
|
||||
|
||||
dispdev->numlinestyles = NUMELEMS(linestyle);
|
||||
dispdev->numcolors = 2;
|
||||
|
||||
dispdev->width = 7.75 * 72.0 * scale; /* (8 1/2 - 3/4) * 72 */
|
||||
dispdev->height = dispdev->width;
|
||||
|
||||
/* The following side effects have to be considered
|
||||
* when the printer is called by com_hardcopy !
|
||||
* gr_init:
|
||||
* viewportxoff = 8 * fontwidth
|
||||
* viewportyoff = 4 * fontheight
|
||||
* gr_resize_internal:
|
||||
* viewport.width = absolute.width - 2 * viewportxoff
|
||||
* viewport.height = absolute.height - 2 * viewportyoff
|
||||
*/
|
||||
|
||||
if (!cp_getvar("hcopyfont", VT_STRING, psfont))
|
||||
strcpy(psfont, "Helvetica");
|
||||
if (!cp_getvar("hcopyfontsize", VT_STRING, psfontsize)) {
|
||||
fontsize = 10;
|
||||
fontwidth = 6;
|
||||
fontheight = 14;
|
||||
xtadj = XTADJ * scale;
|
||||
ytadj = YTADJ * scale;
|
||||
} else {
|
||||
sscanf(psfontsize, "%d", &fontsize);
|
||||
if ((fontsize < 10) || (fontsize > 14))
|
||||
fontsize = 10;
|
||||
fontwidth = 0.5 + 0.6 * fontsize;
|
||||
fontheight = 2.5 + 1.2 * fontsize;
|
||||
xtadj = XTADJ * scale * fontsize / 10;
|
||||
ytadj = YTADJ * scale * fontsize / 10;
|
||||
}
|
||||
|
||||
screenflag = 0;
|
||||
dispdev->minx = XOFF / scale;
|
||||
dispdev->miny = YOFF / scale;
|
||||
|
||||
return(0);
|
||||
|
||||
}
|
||||
|
||||
/* devdep initially contains name of output file */
|
||||
int
|
||||
PS_NewViewport(GRAPH *graph)
|
||||
{
|
||||
hcopygraphid = graph->graphid;
|
||||
|
||||
if (!(plotfile = fopen(graph->devdep, "w"))) {
|
||||
perror(graph->devdep);
|
||||
graph->devdep = (char *) NULL;
|
||||
return(1);
|
||||
}
|
||||
|
||||
if (graph->absolute.width) {
|
||||
/* hardcopying from the screen */
|
||||
|
||||
screenflag = 1;
|
||||
}
|
||||
|
||||
/* reasonable values, used in gr_ for placement */
|
||||
graph->fontwidth = fontwidth * scale; /* was 12, p.w.h. */
|
||||
graph->fontheight = fontheight * scale; /* was 24, p.w.h. */
|
||||
|
||||
graph->absolute.width = dispdev->width;
|
||||
graph->absolute.height = dispdev->height;
|
||||
/* Also done in gr_init, if called . . . */
|
||||
graph->viewportxoff = 8 * fontwidth;
|
||||
graph->viewportyoff = 4 * fontheight;
|
||||
|
||||
xoff = scale * XOFF;
|
||||
yoff = scale * YOFF;
|
||||
|
||||
/* start file off with a % */
|
||||
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));
|
||||
|
||||
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));
|
||||
|
||||
graph->devdep = tmalloc(sizeof(PSdevdep));
|
||||
DEVDEP(graph).lastlinestyle = -1;
|
||||
DEVDEP(graph).lastx = -1;
|
||||
DEVDEP(graph).lasty = -1;
|
||||
DEVDEP(graph).linecount = 0;
|
||||
graph->linestyle = -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
PS_Close(void)
|
||||
{
|
||||
|
||||
/* in case PS_Close is called as part of an abort,
|
||||
w/o having reached PS_NewViewport */
|
||||
if (plotfile) {
|
||||
if (DEVDEP(currentgraph).lastlinestyle != -1) {
|
||||
/* haven't stroked last path */
|
||||
fprintf(plotfile, "stroke\n");
|
||||
DEVDEP(currentgraph).linecount = 0;
|
||||
}
|
||||
fprintf(plotfile, "showpage\n");
|
||||
fclose(plotfile);
|
||||
plotfile = NULL;
|
||||
}
|
||||
/* In case of hardcopy command destroy the hardcopy graph
|
||||
* and reset currentgraph to graphid 1, if possible
|
||||
*/
|
||||
if (!screenflag) {
|
||||
DestroyGraph(hcopygraphid);
|
||||
currentgraph = FindGraph(1);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PS_Clear(void)
|
||||
{
|
||||
|
||||
/* do nothing */
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
PS_DrawLine(int x1, int y1, int x2, int y2)
|
||||
{
|
||||
|
||||
/* note: this is not extendible to more than one graph
|
||||
=> will have to give NewViewport a writeable graph XXX */
|
||||
|
||||
if (DEVDEP(currentgraph).lastlinestyle != currentgraph->linestyle
|
||||
|| DEVDEP(currentgraph).linecount > MAX_PS_LINES)
|
||||
{
|
||||
fprintf(plotfile, "stroke\n");
|
||||
fprintf(plotfile, "newpath\n");
|
||||
DEVDEP(currentgraph).linecount = 0;
|
||||
}
|
||||
|
||||
if (DEVDEP(currentgraph).linecount == 0
|
||||
|| x1 != DEVDEP(currentgraph).lastx
|
||||
|| y1 != DEVDEP(currentgraph).lasty)
|
||||
{
|
||||
fprintf(plotfile, "%d %d moveto ", x1 + xoff, y1 + yoff);
|
||||
}
|
||||
if (x1 != x2 || y1 != y2) {
|
||||
fprintf(plotfile, "%d %d lineto\n", x2 + xoff, y2 + yoff);
|
||||
DEVDEP(currentgraph).linecount += 1;
|
||||
}
|
||||
|
||||
DEVDEP(currentgraph).lastx = x2;
|
||||
DEVDEP(currentgraph).lasty = y2;
|
||||
DEVDEP(currentgraph).lastlinestyle = currentgraph->linestyle;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PS_Arc(int x0, int y0, int r, double theta1, double theta2)
|
||||
{
|
||||
double x1, y1;
|
||||
double angle1, angle2;
|
||||
|
||||
while (theta1 >= theta2)
|
||||
theta2 += 2 * M_PI;
|
||||
|
||||
angle1 = (double) (RAD_TO_DEG * theta1);
|
||||
angle2 = (double) (RAD_TO_DEG * theta2);
|
||||
x1 = (double) x0 + r * cos(theta1);
|
||||
y1 = (double) y0 + r * sin(theta1);
|
||||
|
||||
fprintf(plotfile, "%f %f moveto ", x1+(double)xoff, y1+(double)yoff);
|
||||
fprintf(plotfile, "%d %d %d %f %f arc\n", x0+xoff, y0+yoff, r,
|
||||
angle1, angle2);
|
||||
fprintf(plotfile, "stroke\n");
|
||||
|
||||
DEVDEP(currentgraph).linecount = 0;
|
||||
}
|
||||
|
||||
void
|
||||
PS_Text(char *text, int x, int y)
|
||||
{
|
||||
|
||||
int savedlstyle;
|
||||
|
||||
/* set linestyle to solid
|
||||
or may get funny color text on some plotters */
|
||||
savedlstyle = currentgraph->linestyle;
|
||||
PS_SetLinestyle(SOLID);
|
||||
|
||||
if (DEVDEP(currentgraph).linecount) {
|
||||
fprintf(plotfile, "stroke\n");
|
||||
fprintf(plotfile, "newpath\n");
|
||||
DEVDEP(currentgraph).linecount = 0;
|
||||
}
|
||||
/* move to (x, y) */
|
||||
fprintf(plotfile, "%d %d moveto\n", x + xoff + xtadj, y + yoff + ytadj);
|
||||
fprintf(plotfile, "(%s) show\n", text);
|
||||
|
||||
DEVDEP(currentgraph).lastx = -1;
|
||||
DEVDEP(currentgraph).lasty = -1;
|
||||
|
||||
/* restore old linestyle */
|
||||
PS_SetLinestyle(savedlstyle);
|
||||
|
||||
}
|
||||
|
||||
int
|
||||
PS_SetLinestyle(int linestyleid)
|
||||
{
|
||||
|
||||
/* special case
|
||||
get it when PS_Text restores a -1 linestyle */
|
||||
if (linestyleid == -1) {
|
||||
currentgraph->linestyle = -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (linestyleid < 0 || linestyleid > dispdev->numlinestyles) {
|
||||
internalerror("bad linestyleid");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (currentgraph->linestyle != linestyleid) {
|
||||
if (DEVDEP(currentgraph).lastlinestyle != -1) {
|
||||
fprintf(plotfile, "stroke\n");
|
||||
fprintf(plotfile, "newpath\n");
|
||||
DEVDEP(currentgraph).linecount = 0;
|
||||
}
|
||||
fprintf(plotfile, "%s 0 setdash\n", linestyle[linestyleid]);
|
||||
currentgraph->linestyle = linestyleid;
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PS_SetColor(int colorid)
|
||||
{
|
||||
static int flag = 0; /* A hack */
|
||||
|
||||
/* XXXX Set line style dotted for smith grids */
|
||||
if ((colorid == 18) || (colorid == 19)) {
|
||||
PS_SetLinestyle(DOTTED);
|
||||
flag = 1;
|
||||
}
|
||||
if (flag && (colorid == 1)) {
|
||||
PS_SetLinestyle(SOLID);
|
||||
flag = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
PS_Update(void)
|
||||
{
|
||||
|
||||
fflush(plotfile);
|
||||
|
||||
}
|
||||
|
||||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1988 Jeffrey M. Hsu
|
||||
**********/
|
||||
|
||||
/*
|
||||
Postscript driver
|
||||
*/
|
||||
|
||||
#include "ngspice.h"
|
||||
#include "cpdefs.h"
|
||||
#include "graph.h"
|
||||
#include "ftedbgra.h"
|
||||
#include "ftedev.h"
|
||||
#include "fteinput.h"
|
||||
|
||||
#include "postsc.h"
|
||||
#include "variable.h"
|
||||
|
||||
#define RAD_TO_DEG (180.0 / M_PI)
|
||||
#define DEVDEP(g) (*((PSdevdep *) (g)->devdep))
|
||||
#define MAX_PS_LINES 1000
|
||||
#define SOLID 0
|
||||
#define DOTTED 1
|
||||
|
||||
#define gtype graph->grid.gridtype
|
||||
#define xoff dispdev->minx
|
||||
#define yoff dispdev->miny
|
||||
#define XOFF 48 /* printer left margin */
|
||||
#define YOFF 48 /* printer bottom margin */
|
||||
#define XTADJ 0 /* printer text adjustment x */
|
||||
#define YTADJ 4 /* printer text adjustment y */
|
||||
|
||||
#define GRIDSIZE 420 /* printer gridsize divisible by 10, [7-2] */
|
||||
#define GRIDSIZES 360 /* printer gridsize divisible by [10-8], [6-2] */
|
||||
|
||||
#define FONTSIZE 10 /* printer default fontsize */
|
||||
#define FONTWIDTH 6 /* printer default fontwidth */
|
||||
#define FONTHEIGHT 14 /* printer default fontheight */
|
||||
|
||||
typedef struct {
|
||||
int lastlinestyle, lastcolor; /* initial invalid value */
|
||||
int lastx, lasty, linecount;
|
||||
} PSdevdep;
|
||||
|
||||
static char *linestyle[] = {
|
||||
"[]", /* solid */
|
||||
"[1 2]", /* dotted */
|
||||
"[7 7]", /* longdashed */
|
||||
"[3 3]", /* shortdashed */
|
||||
"[7 2 2 2]", /* longdotdashed */
|
||||
"[3 2 1 2]", /* shortdotdashed */
|
||||
"[8 3 2 3]",
|
||||
"[14 2]",
|
||||
"[3 5 1 5]" /* dotdashed */
|
||||
};
|
||||
|
||||
static FILE *plotfile;
|
||||
char psfont[128], psfontsize[32], psscale[32], pscolor[32];
|
||||
static int fontsize = FONTSIZE;
|
||||
static int fontwidth = FONTWIDTH;
|
||||
static int fontheight = FONTHEIGHT;
|
||||
static int screenflag = 0;
|
||||
static int colorflag = 0;
|
||||
static double scale; /* Used for fine tuning */
|
||||
static int xtadj; /* text adjustment x */
|
||||
static int ytadj; /* text adjustment y */
|
||||
static int hcopygraphid;
|
||||
|
||||
|
||||
extern int DestroyGraph (int id);
|
||||
extern void internalerror (char *message);
|
||||
void PS_LinestyleColor(int linestyleid, int colorid);
|
||||
void PS_SelectColor(int colorid);
|
||||
void PS_Stroke(void);
|
||||
|
||||
int
|
||||
PS_Init(void)
|
||||
{
|
||||
char pswidth[30], psheight[30];
|
||||
|
||||
if (!cp_getvar("hcopyscale", VT_STRING, psscale)) {
|
||||
scale = 1.0;
|
||||
} else {
|
||||
sscanf(psscale, "%lf", &scale);
|
||||
if ((scale <= 0) || (scale > 10))
|
||||
scale = 1.0;
|
||||
}
|
||||
|
||||
if (!cp_getvar("hcopypscolor", VT_STRING, pscolor)) {
|
||||
colorflag = 0;
|
||||
dispdev->numcolors = 2;
|
||||
dispdev->numlinestyles = NUMELEMS(linestyle);
|
||||
} else {
|
||||
colorflag = 1;
|
||||
dispdev->numcolors = 18; /* don't know what the maximum should be */
|
||||
dispdev->numlinestyles = 1;
|
||||
}
|
||||
pscolor[0]='\0';
|
||||
|
||||
if (!cp_getvar("hcopywidth", VT_STRING, pswidth)) {
|
||||
dispdev->width = 7.75 * 72.0 * scale; /* (8 1/2 - 3/4) * 72 */
|
||||
} else {
|
||||
sscanf(pswidth, "%d", &(dispdev->width));
|
||||
if (dispdev->width <= 100)
|
||||
dispdev->width = 100;
|
||||
if (dispdev->width >= 10000)
|
||||
dispdev->width = 10000;
|
||||
}
|
||||
if (!cp_getvar("hcopyheight", VT_STRING, psheight)) {
|
||||
dispdev->height = dispdev->width;
|
||||
} else {
|
||||
sscanf(psheight, "%d", &(dispdev->height));
|
||||
if (dispdev->height <= 100)
|
||||
dispdev->height = 100;
|
||||
if (dispdev->height >= 10000)
|
||||
dispdev->height = 10000;
|
||||
}
|
||||
|
||||
/* The following side effects have to be considered
|
||||
* when the printer is called by com_hardcopy !
|
||||
* gr_init:
|
||||
* viewportxoff = 8 * fontwidth
|
||||
* viewportyoff = 4 * fontheight
|
||||
* gr_resize_internal:
|
||||
* viewport.width = absolute.width - 2 * viewportxoff
|
||||
* viewport.height = absolute.height - 2 * viewportyoff
|
||||
*/
|
||||
|
||||
if (!cp_getvar("hcopyfont", VT_STRING, psfont))
|
||||
strcpy(psfont, "Helvetica");
|
||||
if (!cp_getvar("hcopyfontsize", VT_STRING, psfontsize)) {
|
||||
fontsize = 10;
|
||||
fontwidth = 6;
|
||||
fontheight = 14;
|
||||
xtadj = XTADJ * scale;
|
||||
ytadj = YTADJ * scale;
|
||||
} else {
|
||||
sscanf(psfontsize, "%d", &fontsize);
|
||||
if ((fontsize < 10) || (fontsize > 14))
|
||||
fontsize = 10;
|
||||
fontwidth = 0.5 + 0.6 * fontsize;
|
||||
fontheight = 2.5 + 1.2 * fontsize;
|
||||
xtadj = XTADJ * scale * fontsize / 10;
|
||||
ytadj = YTADJ * scale * fontsize / 10;
|
||||
}
|
||||
|
||||
screenflag = 0;
|
||||
dispdev->minx = XOFF / scale;
|
||||
dispdev->miny = YOFF / scale;
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* devdep initially contains name of output file */
|
||||
int
|
||||
PS_NewViewport(GRAPH *graph)
|
||||
{
|
||||
int x1,x2,y1,y2;
|
||||
hcopygraphid = graph->graphid;
|
||||
|
||||
if (!(plotfile = fopen(graph->devdep, "w"))) {
|
||||
perror(graph->devdep);
|
||||
graph->devdep = (char *) NULL;
|
||||
return(1);
|
||||
}
|
||||
|
||||
if (graph->absolute.width) {
|
||||
/* hardcopying from the screen */
|
||||
|
||||
screenflag = 1;
|
||||
}
|
||||
|
||||
/* reasonable values, used in gr_ for placement */
|
||||
graph->fontwidth = fontwidth * scale; /* was 12, p.w.h. */
|
||||
graph->fontheight = fontheight * scale; /* was 24, p.w.h. */
|
||||
|
||||
graph->absolute.width = dispdev->width;
|
||||
graph->absolute.height = dispdev->height;
|
||||
/* Also done in gr_init, if called . . . */
|
||||
graph->viewportxoff = 8 * fontwidth;
|
||||
graph->viewportyoff = 4 * fontheight;
|
||||
|
||||
xoff = scale * XOFF;
|
||||
yoff = scale * YOFF;
|
||||
|
||||
x1 = 0.75 * 72;
|
||||
y1 = x1;
|
||||
x2 = graph->absolute.width + .75 * 72;
|
||||
y2 = graph->absolute.height + .75 * 72;
|
||||
/* start file off with a % */
|
||||
fprintf(plotfile, "%%!PS-Adobe-3.0 EPSF-3.0\n");
|
||||
fprintf(plotfile, "%%%%Creator: nutmeg\n");
|
||||
fprintf(plotfile, "%%%%BoundingBox: %d %d %d %d\n",x1,y1,x2,y2);
|
||||
|
||||
fprintf(plotfile, "%g %g scale\n", 1.0 / scale, 1.0 / scale);
|
||||
|
||||
if (colorflag == 1){ /* set the background to color0 */
|
||||
PS_SelectColor(0);
|
||||
fprintf(plotfile,"%s setrgbcolor\n",pscolor);
|
||||
fprintf(plotfile,"newpath\n");
|
||||
fprintf(plotfile,"%d %d moveto %d %d lineto\n",x1,y1,x2,y1);
|
||||
fprintf(plotfile,"%d %d lineto %d %d lineto\n",x2,y2,x1,y2);
|
||||
fprintf(plotfile,"closepath fill\n");
|
||||
}
|
||||
|
||||
/* set up a reasonable font */
|
||||
fprintf(plotfile, "/%s findfont %d scalefont setfont\n\n",
|
||||
psfont, (int) (fontsize * scale));
|
||||
|
||||
graph->devdep = tmalloc(sizeof(PSdevdep));
|
||||
DEVDEP(graph).lastlinestyle = -1;
|
||||
DEVDEP(graph).lastcolor = -1;
|
||||
DEVDEP(graph).lastx = -1;
|
||||
DEVDEP(graph).lasty = -1;
|
||||
DEVDEP(graph).linecount = 0;
|
||||
PS_SelectColor(0);
|
||||
graph->linestyle = -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
PS_Close(void)
|
||||
{
|
||||
/* in case PS_Close is called as part of an abort,
|
||||
w/o having reached PS_NewViewport */
|
||||
if (plotfile){
|
||||
PS_Stroke();
|
||||
fprintf(plotfile, "showpage\n%%%%EOF\n");
|
||||
fclose(plotfile);
|
||||
plotfile = NULL;
|
||||
}
|
||||
|
||||
/* In case of hardcopy command destroy the hardcopy graph
|
||||
* and reset currentgraph to graphid 1, if possible
|
||||
*/
|
||||
if (!screenflag) {
|
||||
DestroyGraph(hcopygraphid);
|
||||
currentgraph = FindGraph(1);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PS_Clear(void)
|
||||
{
|
||||
/* do nothing */
|
||||
}
|
||||
|
||||
void
|
||||
PS_DrawLine(int x1, int y1, int x2, int y2)
|
||||
{
|
||||
/* note: this is not extendible to more than one graph
|
||||
=> will have to give NewViewport a writeable graph XXX */
|
||||
|
||||
if (DEVDEP(currentgraph).linecount > MAX_PS_LINES
|
||||
|| DEVDEP(currentgraph).linecount == 0
|
||||
|| x1 != DEVDEP(currentgraph).lastx
|
||||
|| y1 != DEVDEP(currentgraph).lasty){
|
||||
PS_Stroke();
|
||||
fprintf(plotfile, "newpath\n");
|
||||
fprintf(plotfile, "%d %d moveto\n", x1 + xoff, y1 + yoff);
|
||||
DEVDEP(currentgraph).linecount += 1;
|
||||
}
|
||||
if (x1 != x2 || y1 != y2) {
|
||||
fprintf(plotfile, "%d %d lineto\n", x2 + xoff, y2 + yoff);
|
||||
DEVDEP(currentgraph).linecount += 1;
|
||||
}
|
||||
|
||||
DEVDEP(currentgraph).lastx = x2;
|
||||
DEVDEP(currentgraph).lasty = y2;
|
||||
}
|
||||
|
||||
void
|
||||
PS_Arc(int x0, int y0, int r, double theta1, double theta2)
|
||||
{
|
||||
double x1, y1;
|
||||
double angle1, angle2;
|
||||
PS_Stroke();
|
||||
while (theta1 >= theta2)
|
||||
theta2 += 2 * M_PI;
|
||||
|
||||
angle1 = (double) (RAD_TO_DEG * theta1);
|
||||
angle2 = (double) (RAD_TO_DEG * theta2);
|
||||
x1 = (double) x0 + r * cos(theta1);
|
||||
y1 = (double) y0 + r * sin(theta1);
|
||||
|
||||
fprintf(plotfile, "%f %f moveto ", x1+(double)xoff, y1+(double)yoff);
|
||||
fprintf(plotfile, "%d %d %d %f %f arc\n", x0+xoff, y0+yoff, r,
|
||||
angle1, angle2);
|
||||
fprintf(plotfile, "stroke\n");
|
||||
|
||||
DEVDEP(currentgraph).linecount = 0;
|
||||
}
|
||||
|
||||
void
|
||||
PS_Text(char *text, int x, int y)
|
||||
{
|
||||
int savedlstyle, savedcolor;
|
||||
|
||||
/* set linestyle to solid
|
||||
or may get funny color text on some plotters */
|
||||
savedlstyle = currentgraph->linestyle;
|
||||
savedcolor = currentgraph->currentcolor;
|
||||
|
||||
PS_SetLinestyle(SOLID);
|
||||
PS_SetColor(1);
|
||||
|
||||
/* stroke the path if there's an open one */
|
||||
PS_Stroke();
|
||||
/* move to (x, y) */
|
||||
fprintf(plotfile, "%d %d moveto\n", x + xoff + xtadj, y + yoff + ytadj);
|
||||
fprintf(plotfile, "(%s) show\n", text);
|
||||
|
||||
DEVDEP(currentgraph).lastx = -1;
|
||||
DEVDEP(currentgraph).lasty = -1;
|
||||
|
||||
/* restore old linestyle */
|
||||
|
||||
PS_SetColor(savedcolor);
|
||||
PS_SetLinestyle(savedlstyle);
|
||||
}
|
||||
|
||||
/* PS_DefineColor */
|
||||
/* PS_DefineLinestyle */
|
||||
|
||||
int
|
||||
PS_SetLinestyle(int linestyleid)
|
||||
{
|
||||
/* special case
|
||||
get it when PS_Text restores a -1 linestyle */
|
||||
if (linestyleid == -1) {
|
||||
currentgraph->linestyle = -1;
|
||||
return 0;
|
||||
}
|
||||
if (linestyleid < 0 || linestyleid > dispdev->numlinestyles) {
|
||||
internalerror("bad linestyleid inside PS_SetLinestyle");
|
||||
return 0;
|
||||
}
|
||||
PS_LinestyleColor(linestyleid, currentgraph->currentcolor);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
PS_SetColor(int colorid)
|
||||
{
|
||||
PS_LinestyleColor(currentgraph->linestyle, colorid);
|
||||
}
|
||||
|
||||
void
|
||||
PS_Update(void)
|
||||
{
|
||||
fflush(plotfile);
|
||||
}
|
||||
|
||||
/**************** PRIVAT FUNCTIONS OF PS FRONTEND *****************************/
|
||||
|
||||
void
|
||||
PS_SelectColor(int colorid) /* should be replaced by PS_DefineColor */
|
||||
{
|
||||
char colorN[30]="", colorstring[30]="";
|
||||
char rgb[30], s_red[30]="0x", s_green[30]="0x", s_blue[30]="0x";
|
||||
long red=0, green=0, blue=0, scale=1;
|
||||
int i;
|
||||
typedef struct { int red, green, blue;} COLOR;
|
||||
/* duplicated colors from src/frontend/plotting/x11.c in rgb-style */
|
||||
const COLOR colors[]= {{ 0, 0, 0}, /*0: black */
|
||||
{255, 255, 255}, /*1: white */
|
||||
{255, 0, 0}, /*2: red */
|
||||
{ 0, 0, 255}, /*3: blue */
|
||||
{255, 165, 0}, /*4: orange */
|
||||
{ 0, 255, 0}, /*5: green */
|
||||
{255, 192, 203}, /*6: pink */
|
||||
{165, 42, 42}, /*7: brown */
|
||||
{240, 230, 140}, /*8: khaki */
|
||||
{221, 160, 221}, /*9: plum */
|
||||
{218, 112, 214}, /*10: orchid */
|
||||
{238, 130, 238}, /*11: violet */
|
||||
{176, 48, 96}, /*12: maroon */
|
||||
{ 64, 224, 208}, /*13: turqoise */
|
||||
{160, 82, 45}, /*14: sienna */
|
||||
{255, 127, 80}, /*15: coral */
|
||||
{ 0, 255, 255}, /*16: cyan */
|
||||
{255, 0, 255}, /*17: magenta */
|
||||
/*{255, 215, 0}, 18: gold */
|
||||
{ 96, 96, 96}, /*18: gray for smith grid */
|
||||
/*{255, 255, 0}, 19: yello */
|
||||
{150, 150, 150}, /*19: gray for smith grid */
|
||||
{128, 128, 128}}; /*20: gray for normal grid */
|
||||
|
||||
/* Extract the rgbcolor, format is: "rgb:<red>/<green>/<blue>" */
|
||||
sprintf(colorN, "color%d",colorid);
|
||||
if (cp_getvar(colorN, VT_STRING, colorstring)){
|
||||
for (i=0; colorstring[i]; i++)
|
||||
if (colorstring[i] == '/' || colorstring[i] == ':')
|
||||
colorstring[i] = ' ';
|
||||
|
||||
sscanf(colorstring,"%s %s %s %s",rgb, &(s_red[2]), &(s_green[2]), &(s_blue[2]));
|
||||
|
||||
if ((strlen(s_blue) == strlen(s_red) && strlen(s_green) == strlen(s_red))
|
||||
&& (strlen(s_blue) > 2) && (strlen(s_blue) < 7)){
|
||||
sscanf(s_red,"%lx",&red);
|
||||
sscanf(s_green,"%lx",&green);
|
||||
sscanf(s_blue,"%lx",&blue);
|
||||
scale= (1 << (strlen(s_blue) - 2) * 4) - 1;
|
||||
sprintf(colorstring,"%1.3f %1.3f %1.3f",
|
||||
(float) red/scale, (float) green/scale, (float) blue/scale);
|
||||
strcpy(pscolor, colorstring);
|
||||
}
|
||||
}
|
||||
if (colorid < 0 || colorid > 20) {
|
||||
internalerror("bad colorid inside PS_SelectColor");
|
||||
}else if (scale == 1){ /* colorN is not an rgbstring, use default color */
|
||||
sprintf(colorstring,"%1.3f %1.3f %1.3f",colors[colorid].red/255.0,
|
||||
colors[colorid].green/255.0, colors[colorid].blue/255.0) ;
|
||||
strcpy(pscolor, colorstring);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PS_LinestyleColor(int linestyleid, int colorid)
|
||||
{
|
||||
/* we have some different linestyles and colors:
|
||||
- color and linestyle we got via function call
|
||||
- color and linestyle we used last time for drawing
|
||||
- generated color and linestyle we'll use for drawing this time */
|
||||
/* these are the rules:
|
||||
DOTTED and colored ps -> color20 (used for grid) and SOLID
|
||||
color18 or 19 and black-white -> linestyle is DOTTED */
|
||||
|
||||
int gencolor=0,genstyle=0;
|
||||
|
||||
if (colorflag == 1){
|
||||
genstyle = SOLID;
|
||||
if (linestyleid==DOTTED)
|
||||
gencolor = 20;
|
||||
else
|
||||
gencolor = colorid;
|
||||
} else { /* colorflag == 0 -> mono*/
|
||||
if ((colorid == 18) || (colorid == 19))
|
||||
genstyle=DOTTED;
|
||||
else
|
||||
genstyle=linestyleid;
|
||||
}
|
||||
|
||||
/* change color if nessecary */
|
||||
if (colorflag == 1 && gencolor != DEVDEP(currentgraph).lastcolor){
|
||||
PS_SelectColor(gencolor);
|
||||
PS_Stroke();
|
||||
fprintf(plotfile,"%s setrgbcolor\n",pscolor);
|
||||
DEVDEP(currentgraph).lastcolor = gencolor;
|
||||
}
|
||||
currentgraph->currentcolor = colorid;
|
||||
|
||||
/* change linestyle if nessecary */
|
||||
if (colorflag == 0 && genstyle != DEVDEP(currentgraph).lastlinestyle){
|
||||
PS_Stroke();
|
||||
fprintf(plotfile, "%s 0 setdash\n", linestyle[genstyle]);
|
||||
DEVDEP(currentgraph).lastlinestyle= genstyle;
|
||||
}
|
||||
currentgraph->linestyle = linestyleid;
|
||||
}
|
||||
|
||||
void
|
||||
PS_Stroke(void)
|
||||
{
|
||||
/* strokes an open path */
|
||||
if (DEVDEP(currentgraph).linecount > 0) {
|
||||
fprintf(plotfile, "stroke\n");
|
||||
DEVDEP(currentgraph).linecount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -78,14 +78,15 @@ cp_unquote(char *string)
|
|||
char *s;
|
||||
int l;
|
||||
if (string) {
|
||||
s = copy(string);
|
||||
l = strlen(string);
|
||||
s = MALLOC(l+1);
|
||||
|
||||
if (*string == '"' && string[l-1] == '"') {
|
||||
strncpy(s,string+1,l-2);
|
||||
s[l-2] = '\0';
|
||||
} else
|
||||
strcpy(s,string);
|
||||
|
||||
if (*s == '"')
|
||||
s++;
|
||||
|
||||
l = strlen(s) - 1;
|
||||
if (s[l] == '"')
|
||||
s[l] = '\0';
|
||||
return (s);
|
||||
} else
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -20,6 +20,12 @@ Modified: 2000 AlansFixes
|
|||
#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);
|
||||
|
||||
|
|
@ -37,6 +43,9 @@ 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)
|
||||
|
|
@ -250,7 +259,16 @@ dosim(char *what, wordlist *wl)
|
|||
} else {
|
||||
rawfileFp = NULL;
|
||||
}
|
||||
|
||||
/*save rawfile name saj*/
|
||||
if(last_used_rawfile)
|
||||
tfree(last_used_rawfile); /* va: we should allways use tfree */
|
||||
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")) {
|
||||
|
|
@ -258,6 +276,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 {
|
||||
|
|
@ -265,6 +290,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);
|
||||
|
|
@ -283,6 +315,14 @@ dosim(char *what, wordlist *wl)
|
|||
}
|
||||
ft_curckt->ci_runonce = TRUE;
|
||||
ft_setflag = FALSE;
|
||||
|
||||
/* va: garbage collection: unlink first word (inserted here) and tfree it */
|
||||
if (!dofile) {
|
||||
tfree(ww->wl_word);
|
||||
if (wl)
|
||||
wl->wl_prev = NULL;
|
||||
tfree(ww);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,6 +20,11 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
|
|||
|
||||
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
|
||||
|
|
@ -42,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");
|
||||
|
|
@ -51,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. */
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,17 @@ Modified: 2000 AlansFixes
|
|||
#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);
|
||||
static IFparm * parmlookup(IFdevice *dev, GENinstance **inptr, char *param,
|
||||
|
|
@ -98,6 +109,7 @@ if_inpdeck(struct line *deck, INPtables **tab)
|
|||
}
|
||||
|
||||
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);
|
||||
|
|
@ -111,6 +123,16 @@ if_inpdeck(struct line *deck, INPtables **tab)
|
|||
(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);
|
||||
}
|
||||
|
||||
|
|
@ -131,6 +153,7 @@ if_run(char *t, char *what, wordlist *args, char *tab)
|
|||
int j;
|
||||
int which = -1;
|
||||
IFuid specUid,optUid;
|
||||
char *s;
|
||||
|
||||
|
||||
/* First parse the line... */
|
||||
|
|
@ -145,7 +168,9 @@ if_run(char *t, char *what, wordlist *args, char *tab)
|
|||
|| eq(what,"tf")
|
||||
|| eq(what, "noise"))
|
||||
{
|
||||
(void) sprintf(buf, ".%s", wl_flatten(args));
|
||||
s = wl_flatten(args); /* va: tfree char's tmalloc'ed in wl_flatten */
|
||||
(void) sprintf(buf, ".%s", s);
|
||||
tfree(s);
|
||||
deck.li_next = deck.li_actual = NULL;
|
||||
deck.li_error = NULL;
|
||||
deck.li_linenum = 0;
|
||||
|
|
@ -259,7 +284,9 @@ if_run(char *t, char *what, wordlist *args, char *tab)
|
|||
/* -- A bug fix suggested by Cecil Aswell (aswell@netcom.com) to let */
|
||||
/* -- the interactive analysis commands get the current temperature */
|
||||
/* -- and other options. */
|
||||
|
||||
/*dw Hiermit wird auf der Eingabezeile mit "run" die letzte Simulation
|
||||
wiederholt, sowie die letzte gültige Temperatur genutzt. (Warum die
|
||||
in defOpt drin steht, steht in den Sternen!) */
|
||||
if( eq(what,"run") ) {
|
||||
ft_curckt->ci_curTask = ft_curckt->ci_defTask;
|
||||
ft_curckt->ci_curOpt = ft_curckt->ci_defOpt;
|
||||
|
|
@ -278,6 +305,8 @@ if_run(char *t, char *what, wordlist *args, char *tab)
|
|||
||(eq(what, "sens"))
|
||||
||(eq(what,"tf"))
|
||||
||(eq(what, "run")) ) {
|
||||
/*dw Nutzung der letzten gültigen Temperatur, z.B. nach "set temp" s.o. */
|
||||
ft_curckt->ci_curOpt = ft_curckt->ci_defOpt;
|
||||
if ((err = (*(ft_sim->doAnalyses))(ckt, 1, ft_curckt->ci_curTask))!=OK){
|
||||
ft_sperror(err, "doAnalyses");
|
||||
/* wrd_end(); */
|
||||
|
|
@ -938,3 +967,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
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -216,9 +216,20 @@ cp_vset(char *varname, char type, char *value)
|
|||
v->va_next = ft_curckt->ci_vars;
|
||||
ft_curckt->ci_vars = v;
|
||||
} else {
|
||||
/* va: avoid memory leak within bcopy */
|
||||
if (u->va_type==VT_STRING) tfree(u->va_string);
|
||||
else if (u->va_type==VT_LIST) tfree(u->va_vlist);
|
||||
u->va_V = v->va_V;
|
||||
/* va_name is the same string */
|
||||
u->va_type = v->va_type;
|
||||
/* va_next left unchanged */
|
||||
tfree(v->va_name);
|
||||
tfree(v);
|
||||
/* va: old version with memory leaks
|
||||
w = u->va_next;
|
||||
bcopy(v, u, sizeof(*u));
|
||||
u->va_next = w;
|
||||
*/
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
@ -241,13 +252,15 @@ cp_vset(char *varname, char type, char *value)
|
|||
struct variable *
|
||||
cp_setparse(wordlist *wl)
|
||||
{
|
||||
char *name, *val, *copyval, *s, *ss;
|
||||
char *name=NULL, *val, *copyval, *s, *ss;
|
||||
double *td;
|
||||
struct variable *listv = NULL, *vv, *lv = NULL;
|
||||
struct variable *vars = NULL;
|
||||
int balance;
|
||||
|
||||
while (wl) {
|
||||
if(name)
|
||||
tfree(name);
|
||||
name = cp_unquote(wl->wl_word);
|
||||
wl = wl->wl_next;
|
||||
if (((wl == NULL) || (*wl->wl_word != '=')) &&
|
||||
|
|
@ -330,6 +343,7 @@ cp_setparse(wordlist *wl)
|
|||
}
|
||||
if (balance && !wl) {
|
||||
fprintf(cp_err, "Error: bad set form.\n");
|
||||
tfree(name); /* va: cp_unquote memory leak: free name before exiting */
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
|
|
@ -359,7 +373,10 @@ cp_setparse(wordlist *wl)
|
|||
vv->va_string = copy(val);
|
||||
}
|
||||
tfree(copyval);/*DG: must free ss any way to avoid cp_unquote memory leak */
|
||||
tfree(name); /* va: cp_unquote memory leak: free name for every loop */
|
||||
}
|
||||
if(name)
|
||||
tfree(name);
|
||||
return (vars);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,6 +19,11 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
|
|||
#include "vectors.h"
|
||||
#include "plotting/plotting.h"
|
||||
|
||||
#ifdef XSPICE
|
||||
/* gtri - begin - add function prototype for EVTfindvec */
|
||||
struct dvec *EVTfindvec(char *node);
|
||||
/* gtri - end - add function prototype for EVTfindvec */
|
||||
#endif
|
||||
|
||||
/* 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. */
|
||||
|
|
@ -58,6 +63,14 @@ findvec(char *word, struct plot *pl)
|
|||
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);
|
||||
|
|
@ -341,11 +354,9 @@ vec_get(char *word)
|
|||
d = newv;
|
||||
if (!d) {
|
||||
fprintf(cp_err,
|
||||
"Error: plot wildcard (name %s) matches nothing\n",
|
||||
"Error: plot wildcard (name %s) matches nothing\n",
|
||||
word);
|
||||
|
||||
/* MW. I don't want core leaks here */
|
||||
tfree(wd);
|
||||
tfree(wd); /* MW. I don't want core leaks here */
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
|
|
@ -354,13 +365,12 @@ vec_get(char *word)
|
|||
/* This is a special quantity... */
|
||||
if (ft_nutmeg) {
|
||||
fprintf(cp_err,
|
||||
"Error: circuit parameters only available with spice\n");
|
||||
|
||||
tfree(wd); /* MW. Memory leak fixed again */
|
||||
return (FALSE);
|
||||
"Error: circuit parameters only available with spice\n");
|
||||
tfree(wd); /* MW. Memory leak fixed again */
|
||||
return (NULL); /* va: use NULL */
|
||||
}
|
||||
|
||||
whole=copy(word);
|
||||
whole=copy(word);
|
||||
name = ++word;
|
||||
for (param = name; *param && (*param != '['); param++)
|
||||
;
|
||||
|
|
@ -398,10 +408,11 @@ vec_get(char *word)
|
|||
d->v_length = 1;
|
||||
*d->v_realdata = vv->va_real;
|
||||
|
||||
tfree(vv->va_name);
|
||||
tfree(vv); /* va: tfree vv->va_name and vv (avoid memory leakages) */
|
||||
tfree(wd);
|
||||
vec_new(d);
|
||||
tfree(whole);
|
||||
tfree(wd);
|
||||
return (d);
|
||||
}
|
||||
|
||||
|
|
@ -504,9 +515,11 @@ plot_alloc(char *name)
|
|||
} while (tp);
|
||||
pl->pl_typename = copy(buf);
|
||||
cp_addkword(CT_PLOT, buf);
|
||||
/* va: create a new, empty keyword tree for class CT_VECTOR, s=old tree */
|
||||
s = cp_kwswitch(CT_VECTOR, (char *) NULL);
|
||||
cp_addkword(CT_VECTOR, "all");
|
||||
pl->pl_ccom = cp_kwswitch(CT_VECTOR, s);
|
||||
/* va: keyword tree is old tree again, new tree is linked to pl->pl_ccom */
|
||||
return (pl);
|
||||
}
|
||||
|
||||
|
|
@ -587,8 +600,7 @@ vec_free(struct dvec *v)
|
|||
pl = v->v_plot;
|
||||
|
||||
/* Now we have to take this dvec out of the plot list. */
|
||||
if (pl == NULL)
|
||||
fprintf(cp_err, "vec_free: Internal Error: plot ptr is 0\n");
|
||||
if (pl != NULL) {
|
||||
if (pl->pl_dvecs == v)
|
||||
pl->pl_dvecs = v->v_next;
|
||||
else {
|
||||
|
|
@ -607,12 +619,15 @@ vec_free(struct dvec *v)
|
|||
else
|
||||
pl->pl_scale = NULL;
|
||||
}
|
||||
}
|
||||
tfree(v->v_name);
|
||||
if(v->v_length) {
|
||||
if (isreal(v)) {
|
||||
tfree(v->v_realdata);
|
||||
} else {
|
||||
tfree(v->v_compdata);
|
||||
}
|
||||
}
|
||||
tfree(v);
|
||||
return;
|
||||
}
|
||||
|
|
@ -625,6 +640,7 @@ bool
|
|||
vec_eq(struct dvec *v1, struct dvec *v2)
|
||||
{
|
||||
char *s1, *s2;
|
||||
bool rtn;
|
||||
|
||||
if (v1->v_plot != v2->v_plot)
|
||||
return (FALSE);
|
||||
|
|
@ -633,9 +649,13 @@ vec_eq(struct dvec *v1, struct dvec *v2)
|
|||
s2 = vec_basename(v2);
|
||||
|
||||
if (cieq(s1, s2))
|
||||
return (TRUE);
|
||||
rtn = TRUE;
|
||||
else
|
||||
return (FALSE);
|
||||
rtn = FALSE;
|
||||
|
||||
tfree(s1);
|
||||
tfree(s2);
|
||||
return rtn;
|
||||
}
|
||||
|
||||
/* Return the name of the vector with the plot prefix stripped off. This
|
||||
|
|
@ -677,6 +697,8 @@ vec_basename(struct dvec *v)
|
|||
|
||||
/* Make a plot the current one. This gets called by cp_usrset() when one
|
||||
* does a 'set curplot = name'.
|
||||
* va: ATTENTION: has unlinked old keyword-class-tree from keywords[CT_VECTOR]
|
||||
* (potentially memory leak)
|
||||
*/
|
||||
|
||||
void
|
||||
|
|
@ -700,8 +722,15 @@ plot_setcur(char *name)
|
|||
fprintf(cp_err, "Error: no such plot named %s\n", name);
|
||||
return;
|
||||
}
|
||||
/* va: we skip cp_kwswitch, because it confuses the keyword-tree management for
|
||||
* repeated op-commands. When however cp_kwswitch is necessary for other
|
||||
* reasons, we should hold the original keyword table pointer in an
|
||||
* permanent variable, since it will lost here, and can never tfree'd.
|
||||
if (plot_cur)
|
||||
{
|
||||
plot_cur->pl_ccom = cp_kwswitch(CT_VECTOR, pl->pl_ccom);
|
||||
}
|
||||
*/
|
||||
plot_cur = pl;
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
2003.4.10 Stuart Brorson <sdb@cloud9.net>
|
||||
* Added declaration for INPgetNetTok to inpdefs.h
|
||||
|
||||
2002-01-03 Paolo Nenzi <p.nenzi@ieee.org>
|
||||
|
||||
* wstdio.h: Standard input/output for Windows (Holger Vogt patch).
|
||||
|
|
|
|||
|
|
@ -6,6 +6,14 @@
|
|||
#ifndef CKT
|
||||
#define CKT "CKTdefs.h $Revision$ on $Date$ "
|
||||
|
||||
/* 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 */
|
||||
|
|
@ -247,6 +255,13 @@ typedef struct {
|
|||
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;
|
||||
|
||||
/* Now function prottypes */
|
||||
|
|
@ -271,6 +286,7 @@ extern int CKTdestroy( void *);
|
|||
extern int CKTdltAnal( void *, void *, void *);
|
||||
extern int CKTdltInst( void *, void *);
|
||||
extern int CKTdltMod( void *, void *);
|
||||
extern int CKTdltNNum(void *, int );
|
||||
extern int CKTdltNod( void *, void *);
|
||||
extern int CKTdoJob( void *, int , void *);
|
||||
extern void CKTdump( CKTcircuit *, double, void *);
|
||||
|
|
@ -333,7 +349,7 @@ extern int DCOaskQuest( CKTcircuit *, void *, int , IFvalue *);
|
|||
extern int DCOsetParm( CKTcircuit *, void *, int , IFvalue *);
|
||||
extern int DCTaskQuest( CKTcircuit *, void *, int , IFvalue *);
|
||||
extern int DCTsetParm( CKTcircuit *, void *, int , IFvalue *);
|
||||
extern int DCop( CKTcircuit *);
|
||||
extern int DCop( CKTcircuit *, int ); /* va: int avoids "init from incompatible pointer type" */
|
||||
extern int DCtrCurv( CKTcircuit *, int );
|
||||
extern int DCtran( CKTcircuit *, int );
|
||||
extern int DISTOan(CKTcircuit *, int);
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
|
|||
|
||||
#include "inpdefs.h"
|
||||
|
||||
/* This struct defines a linked list of lines from a SPICE file. */
|
||||
struct line {
|
||||
int li_linenum;
|
||||
char *li_line;
|
||||
|
|
|
|||
|
|
@ -6,6 +6,13 @@ Author: 1986 Thomas L. Quarles
|
|||
#ifndef IFSIMULATOR
|
||||
#define IFSIMULATOR
|
||||
|
||||
/* 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 */
|
||||
|
||||
|
||||
/*
|
||||
* structure: IFparm
|
||||
|
|
@ -269,6 +276,21 @@ typedef struct sIFdevice {
|
|||
int *numModelParms; /* number of model parameter descriptors */
|
||||
IFparm *modelParms; /* array of model parameter descriptors */
|
||||
|
||||
/* 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;
|
||||
|
|
|
|||
|
|
@ -74,6 +74,11 @@ typedef struct sINPmodel{
|
|||
void *INPmodfast; /* high speed pointer to model for access */
|
||||
} INPmodel;
|
||||
|
||||
|
||||
/* global input model table. */
|
||||
extern INPmodel *modtab;
|
||||
|
||||
|
||||
/* listing types - used for debug listings */
|
||||
#define LOGICAL 1
|
||||
#define PHYSICAL 2
|
||||
|
|
@ -93,6 +98,7 @@ double INPevaluate(char**,int*,int);
|
|||
char * INPfindLev(char*,int*);
|
||||
char * INPgetMod(void*,char*,INPmodel**,INPtables*);
|
||||
int INPgetTok(char**,char**,int);
|
||||
int INPgetNetTok(char**,char**,int);
|
||||
void INPgetTree(char**,INPparseTree**,void*,INPtables*);
|
||||
IFvalue * INPgetValue(void*,char**,int,INPtables*);
|
||||
int INPgndInsert(void*,char**,INPtables*,void**);
|
||||
|
|
@ -123,6 +129,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*);
|
||||
|
|
@ -130,6 +137,7 @@ 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);
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@ extern void txfree(void *ptr);
|
|||
#define txfree(m)
|
||||
#endif
|
||||
|
||||
#include "../misc/stringutil.h" /* va: spice3 internally bzero */
|
||||
|
||||
#define alloc(TYPE) ((TYPE *) tmalloc(sizeof(TYPE)))
|
||||
#define MALLOC(x) tmalloc((unsigned)(x))
|
||||
#define FREE(x) {if (x) {txfree((char *)(x));(x) = 0;}}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,12 @@
|
|||
* Main header file for ngspice
|
||||
* 1999 E. Rouat
|
||||
************/
|
||||
#ifndef NGSPICE_H_INCLUDED /* va */
|
||||
#define NGSPICE_H_INCLUDED
|
||||
|
||||
/* #include "memwatch.h"
|
||||
#define MEMWATCH */
|
||||
|
||||
|
||||
/*
|
||||
* This file will eventually replace spice.h and lots of other
|
||||
|
|
@ -97,6 +103,11 @@ struct timeb timebegin;
|
|||
#ifdef HAVE_INDEX
|
||||
# define strchr index
|
||||
# define strrchr rindex
|
||||
#else /* va: no index, but strchr */
|
||||
#ifdef HAVE_STRCHR
|
||||
#define index strchr
|
||||
#define rindex strrchr
|
||||
#endif /* va: no index, but strchr */
|
||||
#endif
|
||||
|
||||
#ifdef HAS_TIME_
|
||||
|
|
@ -113,6 +124,9 @@ struct timeb timebegin;
|
|||
#endif
|
||||
|
||||
extern char *gettok(char **s);
|
||||
extern char *gettok_noparens(char **s);
|
||||
extern int get_l_paren(char **s);
|
||||
extern int get_r_paren(char **s);
|
||||
extern void appendc(char *s, char c);
|
||||
extern int scannum(char *str);
|
||||
extern int ciprefix(register char *p, register char *s);
|
||||
|
|
@ -152,3 +166,5 @@ extern char *Lib_Path;
|
|||
|
||||
extern int ARCHme; /* My logical process number */
|
||||
extern int ARCHsize; /* Total number of processes */
|
||||
|
||||
#endif /* NGSPICE_H_INCLUDED */
|
||||
|
|
|
|||
|
|
@ -116,4 +116,18 @@ typedef struct {
|
|||
#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*/
|
||||
|
|
|
|||
92
src/main.c
92
src/main.c
|
|
@ -11,6 +11,9 @@
|
|||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#endif /* HAVE_STRING_H */
|
||||
#ifdef __MINGW32__
|
||||
#define srandom(a) srand(a) /* srandom */
|
||||
#endif /* __MINGW32__ */
|
||||
#include <setjmp.h>
|
||||
#include <signal.h>
|
||||
|
||||
|
|
@ -23,11 +26,17 @@
|
|||
#include <spicelib/devices/dev.h>
|
||||
#include <spicelib/analysis/analysis.h>
|
||||
#include <misc/ivars.h>
|
||||
#if !defined(__CYGWIN__)
|
||||
#include <misc/getopt.h>
|
||||
#endif
|
||||
#include <frontend/resource.h>
|
||||
#include <frontend/variable.h>
|
||||
#include "frontend/display.h" /* va */
|
||||
|
||||
/* saj xspice headers */
|
||||
#ifdef XSPICE
|
||||
#include "ipctiein.h"
|
||||
#include "mif.h"
|
||||
#include "enh.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_PWD_H
|
||||
#include <pwd.h>
|
||||
|
|
@ -39,6 +48,8 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
extern void DevInit(void);
|
||||
|
||||
/* Main options */
|
||||
static bool ft_servermode = FALSE;
|
||||
static bool ft_batchmode = FALSE;
|
||||
|
|
@ -151,6 +162,40 @@ if_getstat(char *n, char *c)
|
|||
return (NULL);
|
||||
}
|
||||
|
||||
#ifdef EXPERIMENTAL_CODE
|
||||
void com_loadsnap(wordlist *wl) { return; }
|
||||
void com_savesnap(wordlist *wl) { return; }
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef XSPICE
|
||||
/* saj to get nutmeg to compile, not nice but necessary */
|
||||
Ipc_Tiein_t g_ipc;
|
||||
Ipc_Status_t ipc_send_errchk(void ) {
|
||||
Ipc_Status_t x=0;
|
||||
return(x);
|
||||
}
|
||||
Ipc_Status_t ipc_get_line(char *str , int *len , Ipc_Wait_t wait ){
|
||||
Ipc_Status_t x=0;
|
||||
return(x);
|
||||
}
|
||||
struct line *ENHtranslate_poly(struct line *deck){
|
||||
return(NULL);
|
||||
}
|
||||
int load_opus(char *name){
|
||||
return(1);
|
||||
}
|
||||
char *MIFgettok(char **s){
|
||||
return(NULL);
|
||||
}
|
||||
void EVTprint(wordlist *wl){
|
||||
return;
|
||||
}
|
||||
struct dvec *EVTfindvec(char *node){
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SIMULATOR */
|
||||
|
||||
char *hlp_filelist[] = { "ngspice", 0 };
|
||||
|
|
@ -173,7 +218,9 @@ int SIMinit(IFfrontEnd *frontEnd, IFsimulator **simulator)
|
|||
SIMinfo.numDevices = DEVmaxnum = num_devices();
|
||||
SIMinfo.devices = devices_ptr();
|
||||
SIMinfo.numAnalyses = spice_num_analysis();
|
||||
SIMinfo.analyses = spice_analysis_ptr();
|
||||
SIMinfo.analyses = (IFanalysis **)spice_analysis_ptr(); /* va: we recast, because we use
|
||||
* only the public part
|
||||
*/
|
||||
#endif /* SIMULATOR */
|
||||
|
||||
SPfrontEnd = frontEnd;
|
||||
|
|
@ -227,11 +274,11 @@ show_version(void)
|
|||
{
|
||||
printf("%s compiled from %s revision %s\n"
|
||||
"Written originally by Berkeley University\n"
|
||||
"Currently maintained by the NG-Spice Project\n\n"
|
||||
"Currently maintained by the NGSpice Project\n\n"
|
||||
"Copyright (C) 1985-1996,"
|
||||
" The Regents of the University of California\n"
|
||||
"Copyright (C) 1999-2000,"
|
||||
" The NG-Spice Project\n", cp_program, PACKAGE, VERSION);
|
||||
" The NGSpice Project\n", cp_program, PACKAGE, VERSION);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -292,6 +339,17 @@ main(int argc, char **argv)
|
|||
FILE *fp;
|
||||
FILE *circuit_file;
|
||||
|
||||
#ifdef TRACE
|
||||
/* this is used to detect memory leaks during debugging */
|
||||
/* added by SDB during debug . . . . */
|
||||
/* mtrace(); */
|
||||
#endif
|
||||
|
||||
#ifdef TRACE
|
||||
/* this is also used for memory leak plugging . . . */
|
||||
/* added by SDB during debug . . . . */
|
||||
/* mwDoFlush(1); */
|
||||
#endif
|
||||
|
||||
/* MFB tends to jump to 0 on errors. This tends to catch it. */
|
||||
if (started) {
|
||||
|
|
@ -408,11 +466,12 @@ main(int argc, char **argv)
|
|||
#else
|
||||
sprintf (buf, "%s", optarg);
|
||||
#endif
|
||||
/* if (!(freopen (buf, "w", stdout))) {
|
||||
#ifdef HAS_WINDOWS
|
||||
if (!(freopen (buf, "w", stdout))) {
|
||||
perror (buf);
|
||||
shutdown (EXIT_BAD);
|
||||
}
|
||||
*/
|
||||
#endif
|
||||
// *** Log-File öffnen *******
|
||||
if (!(flogp = fopen(buf, "w"))) {
|
||||
perror(buf);
|
||||
|
|
@ -422,7 +481,7 @@ main(int argc, char **argv)
|
|||
com_version(NULL); // hvogt 11.11.2001
|
||||
fprintf(stdout, "\nBatch mode\n\n");
|
||||
fprintf(stdout, "Simulation output goes to rawfile: %s\n\n", ft_rawfile);
|
||||
fprintf(stdout, "Comments and warnigs go to log-file: %s\n", buf);
|
||||
fprintf(stdout, "Comments and warnings go to log-file: %s\n", buf);
|
||||
oflag = TRUE;
|
||||
}
|
||||
break;
|
||||
|
|
@ -507,7 +566,9 @@ main(int argc, char **argv)
|
|||
signal(SIGBUS, sigbus);
|
||||
#endif
|
||||
#ifdef SIGSEGV
|
||||
signal(SIGSEGV, sigsegv);
|
||||
/* Want core files!
|
||||
* signal(SIGSEGV, sigsegv);
|
||||
*/
|
||||
#endif
|
||||
#ifdef SIGSYS
|
||||
signal(SIGSYS, sig_sys);
|
||||
|
|
@ -525,14 +586,11 @@ main(int argc, char **argv)
|
|||
|
||||
pw = getpwuid(getuid());
|
||||
|
||||
#ifdef HAVE_ASPRINTF
|
||||
asprintf(&s, "%s/.spiceinit", pw->pw_dir);
|
||||
#else /* ~ HAVE_ASPRINTF */
|
||||
#define INITSTR "/.spiceinit"
|
||||
if ( (s=(char *) malloc(1 + strlen(pw->pw_dir)+strlen(INITSTR))) == NULL){
|
||||
fprintf(stderr,"malloc failed\n");
|
||||
exit(1);
|
||||
}
|
||||
#ifdef HAVE_ASPRINTF
|
||||
asprintf(&s, "%s%s", pw->pw_dir,INITSTR);
|
||||
#else /* ~ HAVE_ASPRINTF */ /* va: we use tmalloc */
|
||||
s=(char *) tmalloc(1 + strlen(pw->pw_dir)+strlen(INITSTR));
|
||||
sprintf(s,"%s%s",pw->pw_dir,INITSTR);
|
||||
#endif /* HAVE_ASPRINTF */
|
||||
|
||||
|
|
@ -648,7 +706,7 @@ evl:
|
|||
* save too much. */
|
||||
cp_interactive = FALSE;
|
||||
if (rflag) {
|
||||
ft_dotsaves();
|
||||
/* saj done already in inp_spsource ft_dotsaves();*/
|
||||
error2 = ft_dorun(ft_rawfile);
|
||||
if (ft_cktcoms(TRUE) || error2)
|
||||
shutdown(EXIT_BAD);
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ NIiter(register CKTcircuit *ckt, int maxIter)
|
|||
|
||||
|
||||
CKTnode *node; /* current matrix entry */
|
||||
double diff, maxdiff, damp_factor, *OldCKTstate0;
|
||||
double diff, maxdiff, damp_factor, *OldCKTstate0=NULL;
|
||||
|
||||
iterno=0;
|
||||
ipass=0;
|
||||
|
|
@ -157,7 +157,10 @@ NIiter(register CKTcircuit *ckt, int maxIter)
|
|||
return(error);
|
||||
}
|
||||
}
|
||||
|
||||
/*moved it to here as if xspice is included then CKTload changes
|
||||
CKTnumStates the first time it is run */
|
||||
if(!OldCKTstate0)
|
||||
OldCKTstate0=(double *)MALLOC((ckt->CKTnumStates+1)*sizeof(double));
|
||||
for(i=0;i<ckt->CKTnumStates;i++) {
|
||||
*(OldCKTstate0+i) = *(ckt->CKTstate0+i);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -40,21 +40,15 @@ mkvar(char **p, char *path_prefix, char *var_dir, char *env_var)
|
|||
asprintf(p, "%s", buffer);
|
||||
else
|
||||
asprintf(p, "%s%s%s", path_prefix, DIR_PATHSEP, var_dir);
|
||||
#else /* ~ HAVE_ASPRINTF */
|
||||
#else /* ~ HAVE_ASPRINTF */ /* va: we use tmalloc */
|
||||
if (buffer){
|
||||
if ( (*p = (char *) malloc(strlen(buffer)+1)) == NULL){
|
||||
fprintf(stderr,"malloc failed\n");
|
||||
exit(1);
|
||||
}
|
||||
*p = (char *) tmalloc(strlen(buffer)+1);
|
||||
sprintf(*p,"%s",buffer);
|
||||
/* asprintf(p, "%s", buffer); */
|
||||
}
|
||||
else{
|
||||
if ( (*p = (char *) malloc(strlen(path_prefix) +
|
||||
strlen(DIR_PATHSEP) + strlen(var_dir) + 1)) == NULL){
|
||||
fprintf(stderr,"malloc failed\n");
|
||||
exit(1);
|
||||
}
|
||||
*p = (char *) tmalloc(strlen(path_prefix) +
|
||||
strlen(DIR_PATHSEP) + strlen(var_dir) + 1);
|
||||
sprintf(*p, "%s%s%s", path_prefix, DIR_PATHSEP, var_dir);
|
||||
/* asprintf(p, "%s%s%s", path_prefix, DIR_PATHSEP, var_dir); */
|
||||
}
|
||||
|
|
@ -89,9 +83,9 @@ ivars(void)
|
|||
void
|
||||
cleanvars(void)
|
||||
{
|
||||
free(News_File);
|
||||
free(Default_MFB_Cap);
|
||||
free(Help_Path);
|
||||
free(Lib_Path);
|
||||
free(Spice_Path);
|
||||
tfree(News_File);
|
||||
tfree(Default_MFB_Cap);
|
||||
tfree(Help_Path);
|
||||
tfree(Lib_Path);
|
||||
tfree(Spice_Path);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -159,14 +159,86 @@ gettok(char **s)
|
|||
return (copy(buf));
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*
|
||||
* gettok_noparens was added by SDB on 4.21.2003.
|
||||
* It acts like gettok, except that it stops parsing when it hits a paren
|
||||
* (i.e. it treats parens like whitespace). It is used in translate (subckt.c)
|
||||
* while looking for the POLY token.
|
||||
*-------------------------------------------------------------------------*/
|
||||
char *
|
||||
gettok_noparens(char **s)
|
||||
{
|
||||
char buf[BSIZE_SP];
|
||||
int i = 0;
|
||||
char c;
|
||||
|
||||
while (isspace(**s))
|
||||
(*s)++;
|
||||
if (!**s)
|
||||
return (NULL);
|
||||
while ((c = **s) && !isspace(c) &&
|
||||
( **s != '(' ) && ( **s != ')' ) ) {
|
||||
buf[i++] = *(*s)++;
|
||||
}
|
||||
buf[i] = '\0';
|
||||
while (isspace(**s))
|
||||
(*s)++;
|
||||
return (copy(buf));
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*
|
||||
* get_l_paren iterates the pointer forward in a string until it hits
|
||||
* the position after the next left paren "(". It returns 0 if it found a left
|
||||
* paren, and 1 if no left paren is found.
|
||||
*-------------------------------------------------------------------------*/
|
||||
int
|
||||
get_l_paren(char **s)
|
||||
{
|
||||
while (**s && ( **s != '(' ) )
|
||||
(*s)++;
|
||||
if (!**s)
|
||||
return (1);
|
||||
|
||||
(*s)++;
|
||||
|
||||
if (!**s)
|
||||
return (1);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*
|
||||
* get_r_paren iterates the pointer forward in a string until it hits
|
||||
* the position after the next right paren ")". It returns 0 if it found a right
|
||||
* paren, and 1 if no right paren is found.
|
||||
*-------------------------------------------------------------------------*/
|
||||
int
|
||||
get_r_paren(char **s)
|
||||
{
|
||||
while (**s && ( **s != ')' ) )
|
||||
(*s)++;
|
||||
if (!**s)
|
||||
return (1);
|
||||
|
||||
(*s)++;
|
||||
|
||||
if (!**s)
|
||||
return (1);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifndef HAVE_BCOPY
|
||||
|
||||
#ifndef bcopy
|
||||
void
|
||||
bcopy(register char *from, register char *to, register int num)
|
||||
bcopy(const void *vfrom, void *vto, size_t num)
|
||||
{
|
||||
register const char *from = vfrom;
|
||||
register char *to = vto;
|
||||
while (num-- > 0)
|
||||
*to++ = *from++;
|
||||
return;
|
||||
|
|
@ -176,12 +248,13 @@ bcopy(register char *from, register char *to, register int num)
|
|||
#ifndef bzero
|
||||
/* can't declare void here, because we've already used it in this file */
|
||||
/* and haven't declared it void before the use */
|
||||
int
|
||||
bzero(register char *ptr, register int num)
|
||||
void
|
||||
bzero(void *vptr, size_t num)
|
||||
{
|
||||
register char *ptr=vptr;
|
||||
while (num-- > 0)
|
||||
*ptr++ = '\0';
|
||||
return (0);
|
||||
return;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -25,8 +25,8 @@ char * rindex(register char *s,register char c );
|
|||
|
||||
#ifndef HAVE_BCOPY
|
||||
|
||||
void bcopy(register char *from, register char *to, register int num);
|
||||
int bzero(register char *ptr, register int num);
|
||||
void bcopy(const void *from, void *to, size_t num);
|
||||
void bzero(void *ptr, size_t num);
|
||||
|
||||
#endif /* HAVE_BCOPY */
|
||||
|
||||
|
|
|
|||
|
|
@ -96,6 +96,7 @@ libckt_a_SOURCES = \
|
|||
tranaskq.c \
|
||||
traninit.c \
|
||||
transetp.c \
|
||||
cluster.c \
|
||||
ckt.h
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,13 @@ Modified 2001: AlansFixes
|
|||
#include "devdefs.h"
|
||||
#include "sperror.h"
|
||||
|
||||
#ifdef XSPICE
|
||||
/* gtri - add - wbk - 12/19/90 - Add headers */
|
||||
#include "mif.h"
|
||||
#include "evtproto.h"
|
||||
#include "ipctiein.h"
|
||||
/* gtri - end - wbk */
|
||||
|
||||
#ifdef HAS_WINDOWS
|
||||
void SetAnalyse( char * Analyse, int Percent);
|
||||
#endif
|
||||
|
|
@ -30,10 +37,22 @@ ACan(CKTcircuit *ckt, int restart)
|
|||
double startTime;
|
||||
int error;
|
||||
int numNames;
|
||||
IFuid *nameList;
|
||||
IFuid *nameList; /* va: tmalloc'ed list of names */
|
||||
IFuid freqUid;
|
||||
static void *acPlot;
|
||||
void *plot;
|
||||
static void *acPlot = NULL;
|
||||
void *plot = NULL;
|
||||
|
||||
/* gtri - add - wbk - 12/19/90 - Add IPC stuff and anal_init and anal_type */
|
||||
#ifdef XSPICE
|
||||
/* Tell the beginPlot routine what mode we're in */
|
||||
g_ipc.anal_type = IPC_ANAL_AC;
|
||||
|
||||
/* Tell the code models what mode we're in */
|
||||
g_mif_info.circuit.anal_type = MIF_DC;
|
||||
|
||||
g_mif_info.circuit.anal_init = MIF_TRUE;
|
||||
#endif
|
||||
/* gtri - end - wbk */
|
||||
|
||||
if(((ACAN*)ckt->CKTcurJob)->ACsaveFreq == 0 || restart) {
|
||||
/* start at beginning */
|
||||
|
|
@ -66,6 +85,30 @@ ACan(CKTcircuit *ckt, int restart)
|
|||
default:
|
||||
return(E_BADPARM);
|
||||
}
|
||||
#ifdef XSPICE
|
||||
/* gtri - begin - wbk - Call EVTop if event-driven instances exist */
|
||||
if(ckt->evt->counts.num_insts == 0) {
|
||||
/* If no event-driven instances, do what SPICE normally does */
|
||||
error = CKTop(ckt,
|
||||
(ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITJCT,
|
||||
(ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITFLOAT,
|
||||
ckt->CKTdcMaxIter);
|
||||
if(error) return(error);
|
||||
}
|
||||
else {
|
||||
/* Else, use new DCOP algorithm */
|
||||
error = EVTop(ckt,
|
||||
(ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITJCT,
|
||||
(ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITFLOAT,
|
||||
ckt->CKTdcMaxIter,
|
||||
MIF_TRUE);
|
||||
EVTdump(ckt, IPC_ANAL_DCOP, 0.0);
|
||||
EVTop_save(ckt, MIF_TRUE, 0.0);
|
||||
if(error)
|
||||
return(error);
|
||||
}
|
||||
/* gtri - end - wbk - Call EVTop if event-driven instances exist */
|
||||
#else
|
||||
error = CKTop(ckt,
|
||||
(ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITJCT,
|
||||
(ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITFLOAT,
|
||||
|
|
@ -75,7 +118,36 @@ ACan(CKTcircuit *ckt, int restart)
|
|||
CKTncDump(ckt);
|
||||
return(error);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef XSPICE
|
||||
/* gtri - add - wbk - 12/19/90 - Add IPC stuff */
|
||||
|
||||
/* Send the operating point results for Mspice compatibility */
|
||||
if(g_ipc.enabled)
|
||||
{
|
||||
/* Call CKTnames to get names of nodes/branches used by BeginPlot */
|
||||
/* Probably should free nameList after this block since called again... */
|
||||
error = CKTnames(ckt,&numNames,&nameList);
|
||||
if(error) return(error);
|
||||
|
||||
/* We have to do a beginPlot here since the data to return is */
|
||||
/* different for the DCOP than it is for the AC analysis. Moreover */
|
||||
/* the begin plot has not even been done yet at this point... */
|
||||
(*(SPfrontEnd->OUTpBeginPlot))((void *)ckt,(void*)ckt->CKTcurJob,
|
||||
ckt->CKTcurJob->JOBname,(IFuid)NULL,IF_REAL,numNames,nameList,
|
||||
IF_REAL,&acPlot);
|
||||
tfree(nameList);
|
||||
|
||||
ipc_send_dcop_prefix();
|
||||
CKTdump(ckt,(double)0,acPlot);
|
||||
ipc_send_dcop_suffix();
|
||||
|
||||
(*(SPfrontEnd->OUTendPlot))(acPlot);
|
||||
}
|
||||
|
||||
/* gtri - end - wbk */
|
||||
#endif
|
||||
ckt->CKTmode = (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITSMSIG;
|
||||
error = CKTload(ckt);
|
||||
if(error) return(error);
|
||||
|
|
@ -91,6 +163,7 @@ ACan(CKTcircuit *ckt, int restart)
|
|||
if(error) return(error);
|
||||
CKTdump(ckt,(double)0,plot);
|
||||
(*(SPfrontEnd->OUTendPlot))(plot);
|
||||
plot = NULL;
|
||||
}
|
||||
|
||||
(*(SPfrontEnd->IFnewUid))((void *)ckt,&freqUid,(IFuid)NULL,
|
||||
|
|
@ -99,6 +172,7 @@ ACan(CKTcircuit *ckt, int restart)
|
|||
(void*)ckt->CKTcurJob,
|
||||
ckt->CKTcurJob->JOBname,freqUid,IF_REAL,numNames,nameList,
|
||||
IF_COMPLEX,&acPlot);
|
||||
tfree(nameList);
|
||||
if(error) return(error);
|
||||
|
||||
if (((ACAN*)ckt->CKTcurJob)->ACstepType != LINEAR) {
|
||||
|
|
@ -110,7 +184,14 @@ ACan(CKTcircuit *ckt, int restart)
|
|||
} else { /* continue previous analysis */
|
||||
freq = ((ACAN*)ckt->CKTcurJob)->ACsaveFreq;
|
||||
((ACAN*)ckt->CKTcurJob)->ACsaveFreq = 0; /* clear the 'old' frequency */
|
||||
/* fix resume? saj*/
|
||||
error = (*(SPfrontEnd->OUTpBeginPlot))((void *)ckt,
|
||||
(void*)ckt->CKTcurJob,
|
||||
ckt->CKTcurJob->JOBname,freqUid,IF_REAL,numNames,nameList,
|
||||
IF_COMPLEX,&acPlot);
|
||||
/* saj*/
|
||||
}
|
||||
|
||||
switch(((ACAN*)ckt->CKTcurJob)->ACstepType) {
|
||||
case DECADE:
|
||||
case OCTAVE:
|
||||
|
|
@ -124,6 +205,15 @@ ACan(CKTcircuit *ckt, int restart)
|
|||
return(E_BADPARM);
|
||||
}
|
||||
|
||||
/* gtri - add - wbk - 12/19/90 - Set anal_init and anal_type */
|
||||
#ifdef XSPICE
|
||||
g_mif_info.circuit.anal_init = MIF_TRUE;
|
||||
|
||||
/* Tell the code models what mode we're in */
|
||||
g_mif_info.circuit.anal_type = MIF_AC;
|
||||
#endif
|
||||
/* gtri - end - wbk */
|
||||
|
||||
startTime = SPfrontEnd->IFseconds();
|
||||
startdTime = ckt->CKTstat->STATdecompTime;
|
||||
startsTime = ckt->CKTstat->STATsolveTime;
|
||||
|
|
@ -177,8 +267,20 @@ ACan(CKTcircuit *ckt, int restart)
|
|||
ckt->CKTsenInfo->SENmode = save1;
|
||||
}
|
||||
#endif
|
||||
/* gtri - modify - wbk - 12/19/90 - Send IPC stuff */
|
||||
#ifdef XSPICE
|
||||
if(g_ipc.enabled)
|
||||
ipc_send_data_prefix(freq);
|
||||
|
||||
error = CKTacDump(ckt,freq,acPlot);
|
||||
|
||||
if(g_ipc.enabled)
|
||||
ipc_send_data_suffix();
|
||||
|
||||
/* gtri - modify - wbk - 12/19/90 - Send IPC stuff */
|
||||
#else
|
||||
error = CKTacDump(ckt,freq,acPlot);
|
||||
#endif
|
||||
if (error) {
|
||||
ckt->CKTcurrentAnalysis = DOING_AC;
|
||||
ckt->CKTstat->STATacTime += SPfrontEnd->IFseconds() - startTime;
|
||||
|
|
@ -239,6 +341,7 @@ ACan(CKTcircuit *ckt, int restart)
|
|||
}
|
||||
endsweep:
|
||||
(*(SPfrontEnd->OUTendPlot))(acPlot);
|
||||
acPlot = NULL;
|
||||
ckt->CKTcurrentAnalysis = 0;
|
||||
ckt->CKTstat->STATacTime += SPfrontEnd->IFseconds() - startTime;
|
||||
ckt->CKTstat->STATacDecompTime += ckt->CKTstat->STATdecompTime -
|
||||
|
|
@ -265,7 +368,7 @@ endsweep:
|
|||
int
|
||||
CKTacLoad(CKTcircuit *ckt)
|
||||
{
|
||||
extern SPICEdev *DEVices[];
|
||||
extern SPICEdev **DEVices;
|
||||
int i;
|
||||
int size;
|
||||
int error;
|
||||
|
|
@ -292,6 +395,35 @@ CKTacLoad(CKTcircuit *ckt)
|
|||
#endif /* PARALLEL_ARCH */
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef XSPICE
|
||||
/* gtri - begin - Put resistors to ground at all nodes. */
|
||||
/* Value of resistor is set by new "rshunt" option. */
|
||||
|
||||
if(ckt->enh->rshunt_data.enabled) {
|
||||
for(i = 0; i < ckt->enh->rshunt_data.num_nodes; i++) {
|
||||
*(ckt->enh->rshunt_data.diag[i]) +=
|
||||
ckt->enh->rshunt_data.gshunt;
|
||||
}
|
||||
}
|
||||
|
||||
/* gtri - end - Put resistors to ground at all nodes */
|
||||
|
||||
|
||||
|
||||
/* gtri - add - wbk - 11/26/90 - reset the MIF init flags */
|
||||
|
||||
/* init is set by CKTinit and should be true only for first load call */
|
||||
g_mif_info.circuit.init = MIF_FALSE;
|
||||
|
||||
/* anal_init is set by CKTdoJob and is true for first call */
|
||||
/* of a particular analysis type */
|
||||
g_mif_info.circuit.anal_init = MIF_FALSE;
|
||||
|
||||
/* gtri - end - wbk - 11/26/90 */
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef PARALLEL_ARCH
|
||||
combine:
|
||||
ckt->CKTstat->STATloadTime += SPfrontEnd->IFseconds() - startTime;
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ int DCOaskQuest( CKTcircuit *, void *, int , IFvalue *);
|
|||
int DCOsetParm( CKTcircuit *, void *, int , IFvalue *);
|
||||
int DCTaskQuest( CKTcircuit *, void *, int , IFvalue *);
|
||||
int DCTsetParm( CKTcircuit *, void *, int , IFvalue *);
|
||||
int DCop( CKTcircuit *);
|
||||
int DCop( CKTcircuit *, int);
|
||||
int DCtrCurv( CKTcircuit *, int );
|
||||
int DCtran( CKTcircuit *, int );
|
||||
int DISTOan(CKTcircuit *, int);
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ Author: 1985 Thomas L. Quarles
|
|||
|
||||
|
||||
|
||||
extern SPICEdev *DEVices[];
|
||||
extern SPICEdev **DEVices;
|
||||
int
|
||||
CKTdestroy(void *inCkt)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ Author: 1988 Jaijeet S Roychowdhury
|
|||
int
|
||||
CKTdisto (CKTcircuit *ckt, int mode)
|
||||
{
|
||||
extern SPICEdev *DEVices[];
|
||||
extern SPICEdev **DEVices;
|
||||
DISTOAN* cv = (DISTOAN*) (ckt->CKTcurJob);
|
||||
int i;
|
||||
int error=0;
|
||||
|
|
|
|||
|
|
@ -12,6 +12,13 @@ Modified: 2000 AlansFixes
|
|||
|
||||
#include "analysis.h"
|
||||
|
||||
#ifdef XSPICE
|
||||
/* gtri - add - wbk - 11/26/90 - add include for MIF and EVT global data */
|
||||
#include "mif.h"
|
||||
#include "evtproto.h"
|
||||
/* gtri - end - wbk - 11/26/90 */
|
||||
#endif
|
||||
|
||||
extern SPICEanalysis *analInfo[];
|
||||
|
||||
int
|
||||
|
|
@ -139,8 +146,19 @@ printf("Doing analysis at TEMP = %f and TNOM = %f\n",
|
|||
error = (*(analInfo[i]->an_init))(ckt, job);
|
||||
if (!error && analInfo[i]->do_ic)
|
||||
error = CKTic(ckt);
|
||||
if (!error)
|
||||
if (!error){
|
||||
#ifdef XSPICE
|
||||
/* gtri - begin - 6/10/91 - wbk - Setup event-driven data */
|
||||
error = EVTsetup(ckt);
|
||||
if(error) {
|
||||
ckt->CKTstat->STATtotAnalTime +=
|
||||
(*(SPfrontEnd->IFseconds))()-startTime;
|
||||
return(error);
|
||||
}
|
||||
/* gtri - end - 6/10/91 - wbk - Setup event-driven data */
|
||||
#endif
|
||||
error = (*(analInfo[i]->an_func))(ckt, reset);
|
||||
}
|
||||
if (error)
|
||||
error2 = error;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ Author: 1985 Thomas L. Quarles
|
|||
int
|
||||
CKTfndBranch(CKTcircuit *ckt, IFuid name)
|
||||
{
|
||||
extern SPICEdev *DEVices[];
|
||||
extern SPICEdev **DEVices;
|
||||
|
||||
int i;
|
||||
int j;
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ Author: 1985 Thomas L. Quarles
|
|||
|
||||
|
||||
|
||||
extern SPICEdev *DEVices[];
|
||||
extern SPICEdev **DEVices;
|
||||
|
||||
int
|
||||
CKTinst2Node(void *ckt, void *instPtr, int terminal, void **node, IFuid *nodeName)
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ Author: 1985 Thomas L. Quarles
|
|||
|
||||
|
||||
|
||||
extern SPICEdev *DEVices[];
|
||||
extern SPICEdev **DEVices;
|
||||
|
||||
int
|
||||
CKTic(CKTcircuit *ckt)
|
||||
|
|
|
|||
|
|
@ -19,13 +19,18 @@ Modified: 2000 AlansFixes
|
|||
#include "devdefs.h"
|
||||
#include "sperror.h"
|
||||
|
||||
#ifdef XSPICE
|
||||
/* gtri - add - wbk - 11/26/90 - add include for MIF global data */
|
||||
#include "mif.h"
|
||||
/* gtri - end - wbk - 11/26/90 */
|
||||
#endif
|
||||
|
||||
static int ZeroNoncurRow(SMPmatrix *matrix, CKTnode *nodes, int rownum);
|
||||
|
||||
int
|
||||
CKTload(CKTcircuit *ckt)
|
||||
{
|
||||
extern SPICEdev *DEVices[];
|
||||
extern SPICEdev **DEVices;
|
||||
int i;
|
||||
int size;
|
||||
double startTime;
|
||||
|
|
@ -39,6 +44,16 @@ CKTload(CKTcircuit *ckt)
|
|||
int noncon;
|
||||
#endif /* STEPDEBUG */
|
||||
|
||||
#ifdef XSPICE
|
||||
/* gtri - begin - Put resistors to ground at all nodes */
|
||||
/* SMPmatrix *matrix; maschmann : deleted , because unused */
|
||||
|
||||
double gshunt;
|
||||
int num_nodes;
|
||||
|
||||
/* gtri - begin - Put resistors to ground at all nodes */
|
||||
#endif
|
||||
|
||||
startTime = (*(SPfrontEnd->IFseconds))();
|
||||
size = SMPmatSize(ckt->CKTmatrix);
|
||||
for (i=0;i<=size;i++) {
|
||||
|
|
@ -68,6 +83,31 @@ CKTload(CKTcircuit *ckt)
|
|||
#endif /* PARALLEL_ARCH */
|
||||
}
|
||||
}
|
||||
|
||||
/* gtri - add - wbk - 11/26/90 - reset the MIF init flags */
|
||||
#ifdef XSPICE
|
||||
/* init is set by CKTinit and should be true only for first load call */
|
||||
g_mif_info.circuit.init = MIF_FALSE;
|
||||
|
||||
/* anal_init is set by CKTdoJob and is true for first call */
|
||||
/* of a particular analysis type */
|
||||
g_mif_info.circuit.anal_init = MIF_FALSE;
|
||||
|
||||
/* gtri - end - wbk - 11/26/90 */
|
||||
|
||||
/* gtri - begin - Put resistors to ground at all nodes. */
|
||||
/* Value of resistor is set by new "rshunt" option. */
|
||||
|
||||
if(ckt->enh->rshunt_data.enabled) {
|
||||
gshunt = ckt->enh->rshunt_data.gshunt;
|
||||
num_nodes = ckt->enh->rshunt_data.num_nodes;
|
||||
for(i = 0; i < num_nodes; i++) {
|
||||
*(ckt->enh->rshunt_data.diag[i]) += gshunt;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/* gtri - end - Put resistors to ground at all nodes */
|
||||
|
||||
if(ckt->CKTmode & MODEDC) {
|
||||
/* consider doing nodeset & ic assignments */
|
||||
if(ckt->CKTmode & (MODEINITJCT | MODEINITFIX)) {
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ Author: 1985 Thomas L. Quarles
|
|||
#include "sperror.h"
|
||||
|
||||
|
||||
extern SPICEdev *DEVices[];
|
||||
extern SPICEdev **DEVices;
|
||||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
|
|
|
|||
|
|
@ -21,13 +21,13 @@ Author: 1985 Thomas L. Quarles
|
|||
int
|
||||
CKTmodCrt(void *ckt, int type, void **modfast, IFuid name)
|
||||
{
|
||||
extern SPICEdev *DEVices[];
|
||||
extern SPICEdev **DEVices;
|
||||
GENmodel *mymodfast = NULL;
|
||||
int error;
|
||||
|
||||
error = CKTfndMod(ckt,&type,(void**)&mymodfast,name);
|
||||
if(error == E_NOMOD) {
|
||||
mymodfast = (GENmodel *)MALLOC(*DEVices[type]->DEVmodSize);
|
||||
mymodfast = (GENmodel *)MALLOC(*(DEVices[type]->DEVmodSize));
|
||||
if(mymodfast == (GENmodel *)NULL) return(E_NOMEM);
|
||||
mymodfast->GENmodType = type;
|
||||
mymodfast->GENmodName = name;
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ Author: 1985 Thomas L. Quarles
|
|||
#include "sperror.h"
|
||||
|
||||
|
||||
extern SPICEdev *DEVices[];
|
||||
extern SPICEdev **DEVices;
|
||||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ CKTnoise (CKTcircuit *ckt, int mode, int operation, Ndata *data)
|
|||
{
|
||||
double outNdens;
|
||||
int i;
|
||||
extern SPICEdev *DEVices[];
|
||||
extern SPICEdev **DEVices;
|
||||
IFvalue outData; /* output variable (points to list of outputs)*/
|
||||
IFvalue refVal; /* reference variable (always 0)*/
|
||||
int error;
|
||||
|
|
|
|||
|
|
@ -354,7 +354,7 @@ CKTop(CKTcircuit *ckt, long int firstmode, long int continuemode, int iterlim)
|
|||
int
|
||||
CKTconvTest(CKTcircuit *ckt)
|
||||
{
|
||||
extern SPICEdev *DEVices[];
|
||||
extern SPICEdev **DEVices;
|
||||
int i;
|
||||
int error = OK;
|
||||
#ifdef PARALLEL_ARCH
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ Author: 1985 Thomas L. Quarles
|
|||
|
||||
|
||||
|
||||
extern SPICEdev *DEVices[];
|
||||
extern SPICEdev **DEVices;
|
||||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
|
|
|
|||
|
|
@ -18,7 +18,10 @@ Author: 1992 David A. Gates, UC Berkeley CADgroup
|
|||
|
||||
|
||||
|
||||
extern SPICEdev *DEVices[];
|
||||
extern SPICEdev **DEVices;
|
||||
#ifdef XSPICE
|
||||
extern int *DEVicesfl;
|
||||
#endif
|
||||
|
||||
int
|
||||
CKTpartition(CKTcircuit *ckt)
|
||||
|
|
@ -28,7 +31,11 @@ CKTpartition(CKTcircuit *ckt)
|
|||
GENinstance *inst;
|
||||
|
||||
for (i=0;i<DEVmaxnum;i++) {
|
||||
if ( (ckt->CKThead[i] != NULL) ) {
|
||||
if ( (ckt->CKThead[i] != NULL)
|
||||
#ifdef XSPICE
|
||||
&& DEVicesfl[i] == 0
|
||||
#endif
|
||||
){
|
||||
for (model = ckt->CKThead[i]; model; model = model->GENnextModel) {
|
||||
for (inst = model->GENinstances; inst;
|
||||
inst = inst->GENnextInstance) {
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ Author: 1985 Thomas L. Quarles
|
|||
|
||||
|
||||
|
||||
extern SPICEdev *DEVices[];
|
||||
extern SPICEdev **DEVices;
|
||||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ Author: 1985 Thomas L. Quarles
|
|||
|
||||
|
||||
|
||||
extern SPICEdev *DEVices[];
|
||||
extern SPICEdev **DEVices;
|
||||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ Copyright 1990 Regents of the University of California. All rights reserved.
|
|||
#include "sperror.h"
|
||||
|
||||
|
||||
extern SPICEdev *DEVices[];
|
||||
extern SPICEdev **DEVices;
|
||||
|
||||
int
|
||||
CKTpzLoad(CKTcircuit *ckt, SPcomplex *s)
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ Copyright 1990 Regents of the University of California. All rights reserved.
|
|||
int
|
||||
CKTpzSetup(CKTcircuit *ckt, int type)
|
||||
{
|
||||
extern SPICEdev *DEVices[];
|
||||
extern SPICEdev **DEVices;
|
||||
PZAN *pzan = (PZAN *) ckt->CKTcurJob;
|
||||
SMPmatrix *matrix;
|
||||
int error;
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ static int sens_temp(sgen *sg, CKTcircuit *ckt);
|
|||
static int count_steps(int type, double low, double high, int steps, double *stepsize);
|
||||
static double inc_freq(double freq, int type, double step_size);
|
||||
|
||||
extern SPICEdev *DEVices[];
|
||||
extern SPICEdev **DEVices;
|
||||
|
||||
/*
|
||||
* Procedure:
|
||||
|
|
@ -70,8 +70,8 @@ int sens_sens(CKTcircuit *ckt, int restart)
|
|||
int (*fn)( );
|
||||
static int is_dc;
|
||||
int k, j, n;
|
||||
int num_vars, branch_eq;
|
||||
char *sen_data;
|
||||
int num_vars, branch_eq=0;
|
||||
char *sen_data=NULL;
|
||||
char namebuf[513];
|
||||
IFuid *output_names, freq_name;
|
||||
int bypass;
|
||||
|
|
@ -600,7 +600,7 @@ inc_freq(double freq, int type, double step_size)
|
|||
double
|
||||
next_freq(int type, double freq, double stepsize)
|
||||
{
|
||||
double s;
|
||||
double s=0;
|
||||
|
||||
switch (type) {
|
||||
case SENS_DC:
|
||||
|
|
|
|||
|
|
@ -23,14 +23,19 @@ Author: 1985 Thomas L. Quarles
|
|||
return(E_NOMEM);\
|
||||
}
|
||||
|
||||
extern SPICEdev *DEVices[];
|
||||
extern SPICEdev **DEVices;
|
||||
|
||||
int
|
||||
CKTsetup(CKTcircuit *ckt)
|
||||
{
|
||||
int i;
|
||||
int error;
|
||||
|
||||
#ifdef XSPICE
|
||||
/* gtri - begin - Setup for adding rshunt option resistors */
|
||||
CKTnode *node;
|
||||
int num_nodes;
|
||||
/* gtri - end - Setup for adding rshunt option resistors */
|
||||
#endif
|
||||
SMPmatrix *matrix;
|
||||
ckt->CKTnumStates=0;
|
||||
|
||||
|
|
@ -74,7 +79,38 @@ CKTsetup(CKTcircuit *ckt)
|
|||
error = NIreinit(ckt);
|
||||
if(error) return(error);
|
||||
}
|
||||
#ifdef XSPICE
|
||||
/* gtri - begin - Setup for adding rshunt option resistors */
|
||||
|
||||
if(ckt->enh->rshunt_data.enabled) {
|
||||
|
||||
/* Count number of voltage nodes in circuit */
|
||||
for(num_nodes = 0, node = ckt->CKTnodes; node; node = node->next)
|
||||
if((node->type == NODE_VOLTAGE) && (node->number != 0))
|
||||
num_nodes++;
|
||||
|
||||
/* Allocate space for the matrix diagonal data */
|
||||
if(num_nodes > 0) {
|
||||
ckt->enh->rshunt_data.diag =
|
||||
(double **) MALLOC(num_nodes * sizeof(double *));
|
||||
}
|
||||
|
||||
/* Set the number of nodes in the rshunt data */
|
||||
ckt->enh->rshunt_data.num_nodes = num_nodes;
|
||||
|
||||
/* Get/create matrix diagonal entry following what RESsetup does */
|
||||
for(i = 0, node = ckt->CKTnodes; node; node = node->next) {
|
||||
if((node->type == NODE_VOLTAGE) && (node->number != 0)) {
|
||||
ckt->enh->rshunt_data.diag[i] =
|
||||
SMPmakeElt(matrix,node->number,node->number);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* gtri - end - Setup for adding rshunt option resistors */
|
||||
#endif
|
||||
return(OK);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,8 @@ Copyright 1991 Regents of the University of California. All rights reserved.
|
|||
#include "sensgen.h"
|
||||
#include <stdio.h>
|
||||
|
||||
extern SPICEdev *DEVices[]; /* XXX */
|
||||
extern SPICEdev **DEVices;
|
||||
/* XXX */
|
||||
extern char *Sfilter;
|
||||
|
||||
sgen *
|
||||
|
|
|
|||
|
|
@ -21,6 +21,13 @@ Modified: 2000 AlansFixes
|
|||
|
||||
#include "analysis.h"
|
||||
|
||||
#ifdef XSPICE
|
||||
/* gtri - begin - wbk - add includes */
|
||||
#include "mif.h"
|
||||
/* gtri - end - wbk - add includes */
|
||||
#endif
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
CKTsetOpt(void *ckt, void *anal, int opt, IFvalue *val)
|
||||
|
|
@ -142,12 +149,72 @@ CKTsetOpt(void *ckt, void *anal, int opt, IFvalue *val)
|
|||
case OPT_RELDV:
|
||||
task->TSKrelDv = val->rValue;
|
||||
break;
|
||||
/* gtri - begin - wbk - add new options */
|
||||
#ifdef XSPICE
|
||||
case OPT_EVT_MAX_OP_ALTER:
|
||||
((CKTcircuit *) ckt)->evt->limits.max_op_alternations = val->iValue;
|
||||
break;
|
||||
|
||||
case OPT_EVT_MAX_EVT_PASSES:
|
||||
((CKTcircuit *) ckt)->evt->limits.max_event_passes = val->iValue;
|
||||
break;
|
||||
|
||||
case OPT_ENH_NOOPALTER:
|
||||
((CKTcircuit *) ckt)->evt->options.op_alternate = MIF_FALSE;
|
||||
break;
|
||||
|
||||
case OPT_ENH_RAMPTIME:
|
||||
((CKTcircuit *) ckt)->enh->ramp.ramptime = val->rValue;
|
||||
break;
|
||||
|
||||
case OPT_ENH_CONV_LIMIT:
|
||||
((CKTcircuit *) ckt)->enh->conv_limit.enabled = MIF_TRUE;
|
||||
break;
|
||||
|
||||
case OPT_ENH_CONV_STEP:
|
||||
((CKTcircuit *) ckt)->enh->conv_limit.step = val->rValue;
|
||||
((CKTcircuit *) ckt)->enh->conv_limit.enabled = MIF_TRUE;
|
||||
break;
|
||||
|
||||
case OPT_ENH_CONV_ABS_STEP:
|
||||
((CKTcircuit *) ckt)->enh->conv_limit.abs_step = val->rValue;
|
||||
((CKTcircuit *) ckt)->enh->conv_limit.enabled = MIF_TRUE;
|
||||
break;
|
||||
|
||||
case OPT_MIF_AUTO_PARTIAL:
|
||||
g_mif_info.auto_partial.global = MIF_TRUE;
|
||||
break;
|
||||
|
||||
case OPT_ENH_RSHUNT:
|
||||
if(val->rValue > 1.0e-30) {
|
||||
((CKTcircuit *) ckt)->enh->rshunt_data.enabled = MIF_TRUE;
|
||||
((CKTcircuit *) ckt)->enh->rshunt_data.gshunt = 1.0 / val->rValue;
|
||||
}
|
||||
else {
|
||||
printf("WARNING - Rshunt option too small. Ignored.\n");
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
/* gtri - end - wbk - add new options */
|
||||
default:
|
||||
return(-1);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
static IFparm OPTtbl[] = {
|
||||
#ifdef XSPICE
|
||||
/* gtri - begin - wbk - add new options */
|
||||
{ "maxopalter", OPT_EVT_MAX_OP_ALTER, IF_SET|IF_INTEGER, "Maximum analog/event alternations in DCOP" },
|
||||
{ "maxevtiter", OPT_EVT_MAX_EVT_PASSES, IF_SET|IF_INTEGER, "Maximum event iterations at analysis point" },
|
||||
{ "noopalter", OPT_ENH_NOOPALTER, IF_SET|IF_FLAG, "Do not do analog/event alternation in DCOP" },
|
||||
{ "ramptime", OPT_ENH_RAMPTIME, IF_SET|IF_REAL, "Transient analysis supply ramping time" },
|
||||
{ "convlimit", OPT_ENH_CONV_LIMIT, IF_SET|IF_FLAG, "Enable convergence assistance on code models" },
|
||||
{ "convstep", OPT_ENH_CONV_STEP, IF_SET|IF_REAL, "Fractional step allowed by code model inputs between iterations" },
|
||||
{ "convabsstep", OPT_ENH_CONV_ABS_STEP, IF_SET|IF_REAL, "Absolute step allowed by code model inputs between iterations" },
|
||||
{ "autopartial", OPT_MIF_AUTO_PARTIAL, IF_SET|IF_FLAG, "Use auto-partial computation for all models" },
|
||||
{ "rshunt", OPT_ENH_RSHUNT, IF_SET|IF_REAL, "Shunt resistance from analog nodes to ground" },
|
||||
/* gtri - end - wbk - add new options */
|
||||
#endif
|
||||
{ "noopiter", OPT_NOOPITER,IF_SET|IF_FLAG,"Go directly to gmin stepping" },
|
||||
{ "gmin", OPT_GMIN,IF_SET|IF_REAL,"Minimum conductance" },
|
||||
{ "gshunt", OPT_GSHUNT,IF_SET|IF_REAL,"Shunt conductance" },
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ Author: 1985 Thomas L. Quarles
|
|||
|
||||
|
||||
|
||||
extern SPICEdev *DEVices[];
|
||||
extern SPICEdev **DEVices;
|
||||
|
||||
int
|
||||
CKTtemp(CKTcircuit *ckt)
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ CKTterr(int qcap, CKTcircuit *ckt, double *timeStep)
|
|||
double del;
|
||||
double diff[8];
|
||||
double deltmp[8];
|
||||
double factor;
|
||||
double factor=0;
|
||||
int i;
|
||||
int j;
|
||||
static double gearCoeff[] = {
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ Copyright 1990 Regents of the University of California. All rights reserved.
|
|||
|
||||
#include "analysis.h"
|
||||
|
||||
extern SPICEdev *DEVices[];
|
||||
extern SPICEdev **DEVices;
|
||||
extern SPICEanalysis *analInfo[];
|
||||
|
||||
char *
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ Author: 1985 Thomas L. Quarles
|
|||
|
||||
|
||||
|
||||
extern SPICEdev *DEVices[];
|
||||
extern SPICEdev **DEVices;
|
||||
|
||||
int
|
||||
CKTtrunc(CKTcircuit *ckt, double *timeStep)
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ Author: 1985 Thomas L. Quarles
|
|||
|
||||
|
||||
|
||||
extern SPICEdev *DEVices[];
|
||||
extern SPICEdev **DEVices;
|
||||
|
||||
int
|
||||
CKTtypelook(char *type)
|
||||
|
|
|
|||
|
|
@ -12,20 +12,21 @@ Modified: 2000 AlansFixes
|
|||
|
||||
|
||||
int
|
||||
DCop(CKTcircuit *ckt)
|
||||
DCop(CKTcircuit *ckt, int notused)
|
||||
{
|
||||
int CKTload(CKTcircuit *ckt);
|
||||
int converged;
|
||||
int error;
|
||||
IFuid *nameList;
|
||||
IFuid *nameList; /* va: tmalloc'ed list */
|
||||
int numNames;
|
||||
void *plot;
|
||||
void *plot = NULL;
|
||||
|
||||
error = CKTnames(ckt,&numNames,&nameList);
|
||||
if(error) return(error);
|
||||
error = (*(SPfrontEnd->OUTpBeginPlot))((void *)ckt,
|
||||
(void*)ckt->CKTcurJob, ckt->CKTcurJob->JOBname,
|
||||
(IFuid)NULL,IF_REAL,numNames,nameList, IF_REAL,&plot);
|
||||
tfree(nameList); /* va: nameList not used any longer, it was a memory leak */
|
||||
if(error) return(error);
|
||||
|
||||
converged = CKTop(ckt,
|
||||
|
|
|
|||
|
|
@ -13,6 +13,21 @@ Modified: 2000 AlansFixes
|
|||
#include <trandefs.h>
|
||||
#include <sperror.h>
|
||||
|
||||
#ifdef XSPICE
|
||||
/* gtri - add - wbk - Add headers */
|
||||
#include "miftypes.h"
|
||||
/* gtri - end - wbk - Add headers */
|
||||
|
||||
/* gtri - add - wbk - Add headers */
|
||||
#include "evt.h"
|
||||
#include "mif.h"
|
||||
#include "evtproto.h"
|
||||
#include "ipctiein.h"
|
||||
/* gtri - end - wbk - Add headers */
|
||||
#endif
|
||||
|
||||
#ifdef CLUSTER
|
||||
#include "cluster.h"
|
||||
|
||||
#ifdef HAS_WINDOWS /* hvogt 10.03.99, nach W. Mues */
|
||||
void SetAnalyse( char * Analyse, int Percent);
|
||||
|
|
@ -55,7 +70,18 @@ DCtran(CKTcircuit *ckt,
|
|||
#ifdef PARALLEL_ARCH
|
||||
long type = MT_TRANAN, length = 1;
|
||||
#endif /* PARALLEL_ARCH */
|
||||
|
||||
#ifdef XSPICE
|
||||
/* gtri - add - wbk - 12/19/90 - Add IPC stuff */
|
||||
Ipc_Boolean_t ipc_firsttime = IPC_TRUE;
|
||||
Ipc_Boolean_t ipc_secondtime = IPC_FALSE;
|
||||
Ipc_Boolean_t ipc_delta_cut = IPC_FALSE;
|
||||
double ipc_last_time = 0.0;
|
||||
double ipc_last_delta = 0.0;
|
||||
/* gtri - end - wbk - 12/19/90 - Add IPC stuff */
|
||||
#endif
|
||||
#ifdef CLUSTER
|
||||
int redostep;
|
||||
#endif
|
||||
if(restart || ckt->CKTtime == 0) {
|
||||
delta=MIN(ckt->CKTfinalTime/200,ckt->CKTstep)/10;
|
||||
|
||||
|
|
@ -83,7 +109,19 @@ DCtran(CKTcircuit *ckt,
|
|||
*(ckt->CKTbreaks+1)=ckt->CKTfinalTime;
|
||||
ckt->CKTbreakSize=2;
|
||||
if(ckt->CKTminBreak==0) ckt->CKTminBreak=ckt->CKTmaxStep*5e-5;
|
||||
#ifdef XSPICE
|
||||
/* gtri - add - wbk - 12/19/90 - Add IPC stuff and set anal_init and anal_type */
|
||||
|
||||
/* Tell the beginPlot routine what mode we're in */
|
||||
g_ipc.anal_type = IPC_ANAL_TRAN;
|
||||
|
||||
/* Tell the code models what mode we're in */
|
||||
g_mif_info.circuit.anal_type = MIF_DC;
|
||||
|
||||
g_mif_info.circuit.anal_init = MIF_TRUE;
|
||||
|
||||
/* gtri - end - wbk */
|
||||
#endif
|
||||
error = CKTnames(ckt,&numNames,&nameList);
|
||||
if(error) return(error);
|
||||
(*(SPfrontEnd->IFnewUid))((void *)ckt,&timeUid,(IFuid)NULL,
|
||||
|
|
@ -92,6 +130,7 @@ DCtran(CKTcircuit *ckt,
|
|||
(void*)ckt->CKTcurJob,
|
||||
ckt->CKTcurJob->JOBname,timeUid,IF_REAL,numNames,nameList,
|
||||
IF_REAL,&(((TRANan*)ckt->CKTcurJob)->TRANplot));
|
||||
tfree(nameList);
|
||||
if(error) return(error);
|
||||
|
||||
ckt->CKTtime = 0;
|
||||
|
|
@ -100,6 +139,28 @@ DCtran(CKTcircuit *ckt,
|
|||
firsttime = 1;
|
||||
save_mode = (ckt->CKTmode&MODEUIC)|MODETRANOP | MODEINITJCT;
|
||||
save_order = ckt->CKTorder;
|
||||
#ifdef XSPICE
|
||||
/* gtri - begin - wbk - set a breakpoint at end of supply ramping time */
|
||||
/* must do this after CKTtime set to 0 above */
|
||||
if(ckt->enh->ramp.ramptime > 0.0)
|
||||
CKTsetBreak(ckt, ckt->enh->ramp.ramptime);
|
||||
/* gtri - end - wbk - set a breakpoint at end of supply ramping time */
|
||||
|
||||
/* gtri - begin - wbk - Call EVTop if event-driven instances exist */
|
||||
if(ckt->evt->counts.num_insts != 0){
|
||||
/* use new DCOP algorithm */
|
||||
converged = EVTop(ckt,
|
||||
(ckt->CKTmode & MODEUIC) | MODETRANOP | MODEINITJCT,
|
||||
(ckt->CKTmode & MODEUIC)|MODETRANOP| MODEINITFLOAT,
|
||||
ckt->CKTdcMaxIter,
|
||||
MIF_TRUE);
|
||||
EVTdump(ckt, IPC_ANAL_DCOP, 0.0);
|
||||
|
||||
EVTop_save(ckt, MIF_FALSE, 0.0);
|
||||
|
||||
/* gtri - end - wbk - Call EVTop if event-driven instances exist */
|
||||
} else
|
||||
#endif
|
||||
converged = CKTop(ckt,
|
||||
(ckt->CKTmode & MODEUIC)|MODETRANOP| MODEINITJCT,
|
||||
(ckt->CKTmode & MODEUIC)|MODETRANOP| MODEINITFLOAT,
|
||||
|
|
@ -152,6 +213,36 @@ DCtran(CKTcircuit *ckt,
|
|||
fprintf(stdout,"\n");
|
||||
fflush(stdout);
|
||||
if(converged != 0) return(converged);
|
||||
#ifdef XSPICE
|
||||
/* gtri - add - wbk - 12/19/90 - Add IPC stuff */
|
||||
|
||||
/* Send the operating point results for Mspice compatibility */
|
||||
if(g_ipc.enabled) {
|
||||
ipc_send_dcop_prefix();
|
||||
CKTdump(ckt,(double)0,(((TRANan*)ckt->CKTcurJob)->TRANplot));
|
||||
ipc_send_dcop_suffix();
|
||||
}
|
||||
|
||||
/* gtri - end - wbk */
|
||||
|
||||
|
||||
/* gtri - add - wbk - 12/19/90 - set anal_init and anal_type */
|
||||
|
||||
g_mif_info.circuit.anal_init = MIF_TRUE;
|
||||
|
||||
/* Tell the code models what mode we're in */
|
||||
g_mif_info.circuit.anal_type = MIF_TRAN;
|
||||
|
||||
/* gtri - end - wbk */
|
||||
|
||||
/* gtri - begin - wbk - Add Breakpoint stuff */
|
||||
|
||||
/* Initialize the temporary breakpoint variables to infinity */
|
||||
g_mif_info.breakpoint.current = 1.0e30;
|
||||
g_mif_info.breakpoint.last = 1.0e30;
|
||||
|
||||
/* gtri - end - wbk - Add Breakpoint stuff */
|
||||
#endif
|
||||
ckt->CKTstat->STATtimePts ++;
|
||||
ckt->CKTorder=1;
|
||||
for(i=0;i<7;i++) {
|
||||
|
|
@ -202,7 +293,13 @@ DCtran(CKTcircuit *ckt,
|
|||
startlTime = ckt->CKTstat->STATloadTime;
|
||||
startcTime = ckt->CKTstat->STATcombineTime;
|
||||
startkTime = ckt->CKTstat->STATsyncTime;
|
||||
#ifdef CLUSTER
|
||||
CLUsetup(ckt);
|
||||
#endif
|
||||
} else {
|
||||
/*saj As traninit resets CKTmode */
|
||||
ckt->CKTmode = (ckt->CKTmode&MODEUIC)|MODETRAN | MODEINITPRED;
|
||||
/* saj */
|
||||
startTime=(*(SPfrontEnd->IFseconds))();
|
||||
startIters = ckt->CKTstat->STATnumIter;
|
||||
startdTime = ckt->CKTstat->STATdecompTime;
|
||||
|
|
@ -212,6 +309,15 @@ DCtran(CKTcircuit *ckt,
|
|||
startkTime = ckt->CKTstat->STATsyncTime;
|
||||
if(ckt->CKTminBreak==0) ckt->CKTminBreak=ckt->CKTmaxStep*5e-5;
|
||||
firsttime=0;
|
||||
/* To get rawfile working saj*/
|
||||
error = (*(SPfrontEnd->OUTpBeginPlot))((void *)ckt, (void*)ckt->CKTcurJob,
|
||||
ckt->CKTcurJob->JOBname,timeUid,IF_REAL,666,nameList,
|
||||
666,&(((TRANan*)ckt->CKTcurJob)->TRANplot));/*magic 666 nums as flags */
|
||||
if(error) {
|
||||
fprintf(stderr, "Couldn't relink rawfile\n");
|
||||
return error;
|
||||
}
|
||||
/*end saj*/
|
||||
goto resume;
|
||||
}
|
||||
|
||||
|
|
@ -275,8 +381,67 @@ nextTime:
|
|||
startkTime;
|
||||
return(error);
|
||||
}
|
||||
#ifdef XSPICE
|
||||
/* gtri - modify - wbk - 12/19/90 - Send IPC stuff */
|
||||
|
||||
if(g_ipc.enabled) {
|
||||
|
||||
/* Send event-driven results */
|
||||
EVTdump(ckt, IPC_ANAL_TRAN, 0.0);
|
||||
|
||||
/* Then follow with analog results... */
|
||||
|
||||
/* Test to see if delta was cut by a breakpoint, */
|
||||
/* a non-convergence, or a too large truncation error */
|
||||
if(ipc_firsttime)
|
||||
ipc_delta_cut = IPC_FALSE;
|
||||
else if(ckt->CKTtime < (ipc_last_time + (0.999 * ipc_last_delta)))
|
||||
ipc_delta_cut = IPC_TRUE;
|
||||
else
|
||||
ipc_delta_cut = IPC_FALSE;
|
||||
|
||||
/* Record the data required to check for delta cuts */
|
||||
ipc_last_time = ckt->CKTtime;
|
||||
ipc_last_delta = MIN(ckt->CKTdelta, ckt->CKTmaxStep);
|
||||
|
||||
/* Send results data if time since last dump is greater */
|
||||
/* than 'mintime', or if first or second timepoints, */
|
||||
/* or if delta was cut */
|
||||
if( (ckt->CKTtime >= (g_ipc.mintime + g_ipc.last_time)) ||
|
||||
ipc_firsttime || ipc_secondtime || ipc_delta_cut ) {
|
||||
|
||||
ipc_send_data_prefix(ckt->CKTtime);
|
||||
CKTdump(ckt,ckt->CKTtime,
|
||||
(((TRANan*)ckt->CKTcurJob)->TRANplot));
|
||||
ipc_send_data_suffix();
|
||||
|
||||
if(ipc_firsttime) {
|
||||
ipc_firsttime = IPC_FALSE;
|
||||
ipc_secondtime = IPC_TRUE;
|
||||
}
|
||||
else if(ipc_secondtime)
|
||||
ipc_secondtime = IPC_FALSE;
|
||||
|
||||
g_ipc.last_time = ckt->CKTtime;
|
||||
}
|
||||
}
|
||||
else
|
||||
/* gtri - modify - wbk - 12/19/90 - Send IPC stuff */
|
||||
#endif
|
||||
#ifdef CLUSTER
|
||||
CLUoutput(ckt);
|
||||
#endif
|
||||
if(ckt->CKTtime >= ckt->CKTinitTime) CKTdump(ckt,ckt->CKTtime,
|
||||
(((TRANan*)ckt->CKTcurJob)->TRANplot));
|
||||
#ifdef XSPICE
|
||||
/* gtri - begin - wbk - Update event queues/data for accepted timepoint */
|
||||
|
||||
/* Note: this must be done AFTER sending results to SI so it can't */
|
||||
/* go next to CKTaccept() above */
|
||||
if(ckt->evt->counts.num_insts > 0)
|
||||
EVTaccept(ckt, ckt->CKTtime);
|
||||
/* gtri - end - wbk - Update event queues/data for accepted timepoint */
|
||||
#endif
|
||||
ckt->CKTstat->STAToldIter = ckt->CKTstat->STATnumIter;
|
||||
if(fabs(ckt->CKTtime - ckt->CKTfinalTime) < ckt->CKTminBreak) {
|
||||
/*printf(" done: time is %g, final time is %g, and tol is %g\n",*/
|
||||
|
|
@ -381,11 +546,59 @@ resume:
|
|||
#endif
|
||||
ckt->CKTbreak = 1; /* why? the current pt. is not a bkpt. */
|
||||
}
|
||||
|
||||
#ifdef CLUSTER
|
||||
if(!CLUsync(ckt->CKTtime,&ckt->CKTdelta,0)){
|
||||
printf("Sync error!\n");
|
||||
exit(0);
|
||||
}
|
||||
#endif
|
||||
#ifdef PARALLEL_ARCH
|
||||
DGOP_( &type, &(ckt->CKTdelta), &length, "min" );
|
||||
#endif /* PARALLEL_ARCH */
|
||||
#ifdef XSPICE
|
||||
/* gtri - begin - wbk - Do event solution */
|
||||
|
||||
if(ckt->evt->counts.num_insts > 0) {
|
||||
|
||||
/* if time = 0 and op_alternate was specified as false during */
|
||||
/* dcop analysis, call any changed instances to let them */
|
||||
/* post their outputs with their associated delays */
|
||||
if((ckt->CKTtime == 0.0) && (! ckt->evt->options.op_alternate))
|
||||
EVTiter(ckt);
|
||||
|
||||
/* while there are events on the queue with event time <= next */
|
||||
/* projected analog time, process them */
|
||||
while((g_mif_info.circuit.evt_step = EVTnext_time(ckt))
|
||||
<= (ckt->CKTtime + ckt->CKTdelta)) {
|
||||
|
||||
/* Initialize temp analog bkpt to infinity */
|
||||
g_mif_info.breakpoint.current = 1e30;
|
||||
|
||||
/* Pull items off queue and process them */
|
||||
EVTdequeue(ckt, g_mif_info.circuit.evt_step);
|
||||
EVTiter(ckt);
|
||||
|
||||
/* If any instances have forced an earlier */
|
||||
/* next analog time, cut the delta */
|
||||
if(*(ckt->CKTbreaks) < g_mif_info.breakpoint.current)
|
||||
if(*(ckt->CKTbreaks) > (ckt->CKTtime + ckt->CKTminBreak))
|
||||
g_mif_info.breakpoint.current = *(ckt->CKTbreaks);
|
||||
if(g_mif_info.breakpoint.current < (ckt->CKTtime + ckt->CKTdelta)) {
|
||||
/* Breakpoint must be > last accepted timepoint */
|
||||
/* and >= current event time */
|
||||
if(g_mif_info.breakpoint.current > (ckt->CKTtime + ckt->CKTminBreak)
|
||||
&& (g_mif_info.breakpoint.current >= g_mif_info.circuit.evt_step)) {
|
||||
ckt->CKTsaveDelta = ckt->CKTdelta;
|
||||
ckt->CKTdelta = g_mif_info.breakpoint.current - ckt->CKTtime;
|
||||
g_mif_info.breakpoint.last = ckt->CKTtime + ckt->CKTdelta;
|
||||
}
|
||||
}
|
||||
|
||||
} /* end while next event time <= next analog time */
|
||||
} /* end if there are event instances */
|
||||
|
||||
/* gtri - end - wbk - Do event solution */
|
||||
#endif
|
||||
for(i=5;i>=0;i--) {
|
||||
ckt->CKTdeltaOld[i+1]=ckt->CKTdeltaOld[i];
|
||||
}
|
||||
|
|
@ -399,9 +612,25 @@ resume:
|
|||
|
||||
/* 600 */
|
||||
while (1) {
|
||||
#ifdef CLUSTER
|
||||
redostep = 1;
|
||||
#endif
|
||||
#ifdef XSPICE
|
||||
/* gtri - add - wbk - 4/17/91 - Fix Berkeley bug */
|
||||
/* This is needed here to allow CAPask to output currents */
|
||||
/* during Transient analysis. A grep for CKTcurrentAnalysis */
|
||||
/* indicates that it should not hurt anything else ... */
|
||||
|
||||
ckt->CKTcurrentAnalysis = DOING_TRAN;
|
||||
|
||||
/* gtri - end - wbk - 4/17/91 - Fix Berkeley bug */
|
||||
#endif
|
||||
olddelta=ckt->CKTdelta;
|
||||
/* time abort? */
|
||||
ckt->CKTtime += ckt->CKTdelta;
|
||||
#ifdef CLUSTER
|
||||
CLUinput(ckt);
|
||||
#endif
|
||||
ckt->CKTdeltaOld[0]=ckt->CKTdelta;
|
||||
NIcomCof(ckt);
|
||||
#ifdef PREDICTOR
|
||||
|
|
@ -409,7 +638,46 @@ resume:
|
|||
#endif /* PREDICTOR */
|
||||
save_mode = ckt->CKTmode;
|
||||
save_order = ckt->CKTorder;
|
||||
#ifdef XSPICE
|
||||
/* gtri - begin - wbk - Add Breakpoint stuff */
|
||||
|
||||
/* Initialize temporary breakpoint to infinity */
|
||||
g_mif_info.breakpoint.current = 1.0e30;
|
||||
|
||||
/* gtri - end - wbk - Add Breakpoint stuff */
|
||||
|
||||
|
||||
/* gtri - begin - wbk - add convergence problem reporting flags */
|
||||
/* delta is forced to equal delmin on last attempt near line 650 */
|
||||
if(ckt->CKTdelta <= ckt->CKTdelmin)
|
||||
ckt->enh->conv_debug.last_NIiter_call = MIF_TRUE;
|
||||
else
|
||||
ckt->enh->conv_debug.last_NIiter_call = MIF_FALSE;
|
||||
/* gtri - begin - wbk - add convergence problem reporting flags */
|
||||
|
||||
|
||||
|
||||
/* gtri - begin - wbk - Call all hybrids */
|
||||
|
||||
/* gtri - begin - wbk - Set evt_step */
|
||||
|
||||
if(ckt->evt->counts.num_insts > 0) {
|
||||
g_mif_info.circuit.evt_step = ckt->CKTtime;
|
||||
}
|
||||
/* gtri - end - wbk - Set evt_step */
|
||||
#endif
|
||||
|
||||
converged = NIiter(ckt,ckt->CKTtranMaxIter);
|
||||
|
||||
#ifdef XSPICE
|
||||
if(ckt->evt->counts.num_insts > 0)
|
||||
{
|
||||
g_mif_info.circuit.evt_step = ckt->CKTtime;
|
||||
EVTcall_hybrids(ckt);
|
||||
}
|
||||
/* gtri - end - wbk - Call all hybrids */
|
||||
|
||||
#endif
|
||||
ckt->CKTstat->STATtimePts ++;
|
||||
ckt->CKTmode = (ckt->CKTmode&MODEUIC)|MODETRAN | MODEINITPRED;
|
||||
if(firsttime) {
|
||||
|
|
@ -419,8 +687,10 @@ resume:
|
|||
}
|
||||
}
|
||||
if(converged != 0) {
|
||||
#ifndef CLUSTER
|
||||
ckt->CKTtime = ckt->CKTtime -ckt->CKTdelta;
|
||||
ckt->CKTstat->STATrejected ++;
|
||||
#endif
|
||||
ckt->CKTdelta = ckt->CKTdelta/8;
|
||||
#ifdef STEPDEBUG
|
||||
(void)printf("delta cut to %g for non-convergance\n",ckt->CKTdelta);
|
||||
|
|
@ -444,9 +714,14 @@ resume:
|
|||
}
|
||||
#endif
|
||||
firsttime =0;
|
||||
#ifndef CLUSTER
|
||||
goto nextTime; /* no check on
|
||||
* first time point
|
||||
*/
|
||||
#else
|
||||
redostep = 0;
|
||||
goto chkStep;
|
||||
#endif
|
||||
}
|
||||
new = ckt->CKTdelta;
|
||||
error = CKTtrunc(ckt,&new);
|
||||
|
|
@ -514,11 +789,18 @@ resume:
|
|||
ckt->CKTorder = save2;
|
||||
}
|
||||
#endif
|
||||
/* go to 650 - trapezoidal */
|
||||
#ifndef CLUSTER
|
||||
/* go to 650 - trapezoidal */
|
||||
goto nextTime;
|
||||
#else
|
||||
redostep = 0;
|
||||
goto chkStep;
|
||||
#endif
|
||||
} else {
|
||||
#ifndef CLUSTER
|
||||
ckt->CKTtime = ckt->CKTtime -ckt->CKTdelta;
|
||||
ckt->CKTstat->STATrejected ++;
|
||||
#endif
|
||||
ckt->CKTdelta = new;
|
||||
#ifdef STEPDEBUG
|
||||
(void)printf(
|
||||
|
|
@ -556,6 +838,23 @@ resume:
|
|||
return(E_TIMESTEP);
|
||||
}
|
||||
}
|
||||
#ifdef XSPICE
|
||||
/* gtri - begin - wbk - Do event backup */
|
||||
|
||||
if(ckt->evt->counts.num_insts > 0)
|
||||
EVTbackup(ckt, ckt->CKTtime + ckt->CKTdelta);
|
||||
|
||||
/* gtri - end - wbk - Do event backup */
|
||||
#endif
|
||||
#ifdef CLUSTER
|
||||
chkStep:
|
||||
if(CLUsync(ckt->CKTtime,&ckt->CKTdelta,redostep)){
|
||||
goto nextTime;
|
||||
} else {
|
||||
ckt->CKTtime -= olddelta;
|
||||
ckt->CKTstat->STATrejected ++;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,8 @@ Modified: 1999 Paolo Nenzi
|
|||
#include "const.h"
|
||||
#include "sperror.h"
|
||||
|
||||
#include <devdefs.h>
|
||||
extern SPICEdev **DEVices;
|
||||
|
||||
int
|
||||
DCtrCurv(CKTcircuit *ckt, int restart)
|
||||
|
|
@ -34,7 +36,7 @@ DCtrCurv(CKTcircuit *ckt, int restart)
|
|||
IFuid *nameList;
|
||||
int numNames;
|
||||
int firstTime=1;
|
||||
static void *plot;
|
||||
static void *plot=NULL;
|
||||
|
||||
#ifdef WANT_SENSE2
|
||||
#ifdef SENSDEBUG
|
||||
|
|
@ -52,6 +54,10 @@ DCtrCurv(CKTcircuit *ckt, int restart)
|
|||
if(!restart && cv->TRCVnestState >= 0) {
|
||||
/* continuing */
|
||||
i = cv->TRCVnestState;
|
||||
/* resume to work? saj*/
|
||||
error = (*(SPfrontEnd->OUTpBeginPlot))((void *)ckt,
|
||||
(void*)ckt->CKTcurJob, ckt->CKTcurJob->JOBname,
|
||||
varUid,IF_REAL,666,nameList, 666,&plot);
|
||||
goto resume;
|
||||
}
|
||||
ckt->CKTtime = 0;
|
||||
|
|
@ -259,7 +265,11 @@ resume:
|
|||
1/(((RESinstance *)(cv->TRCVvElt[i]))->RESresist);
|
||||
/* Note: changing the resistance does nothing */
|
||||
/* changing the conductance 1/r instead */
|
||||
RESload((GENmodel*)(cv->TRCVvElt[i]->GENmodPtr),ckt);
|
||||
DEVices[rcode]->DEVload((GENmodel*)(cv->TRCVvElt[i]->GENmodPtr),ckt);
|
||||
|
||||
/*
|
||||
* RESload((GENmodel*)(cv->TRCVvElt[i]->GENmodPtr),ckt);
|
||||
*/
|
||||
|
||||
|
||||
} /* else not possible */
|
||||
|
|
@ -357,7 +367,10 @@ nextstep:;
|
|||
/* This code should update resistance and conductance */
|
||||
((RESinstance*)(cv->TRCVvElt[i]))->RESconduct =
|
||||
1/(((RESinstance*)(cv->TRCVvElt[i]))->RESresist);
|
||||
RESload((GENmodel*)(cv->TRCVvElt[i]->GENmodPtr),ckt);
|
||||
DEVices[rcode]->DEVload((GENmodel*)(cv->TRCVvElt[i]->GENmodPtr),ckt);
|
||||
/*
|
||||
* RESload((GENmodel*)(cv->TRCVvElt[i]->GENmodPtr),ckt);
|
||||
*/
|
||||
}
|
||||
/* PN Temp Sweep - serban */
|
||||
else if (cv->TRCVvType[i]==TEMP_CODE)
|
||||
|
|
@ -392,7 +405,11 @@ nextstep:;
|
|||
1/(((RESinstance*)(cv->TRCVvElt[i]))->RESresist);
|
||||
|
||||
((RESinstance*)(cv->TRCVvElt[i]))->RESresGiven = cv->TRCVgSave[i];
|
||||
RESload((GENmodel*)(cv->TRCVvElt[i]->GENmodPtr),ckt);
|
||||
DEVices[rcode]->DEVload((GENmodel*)(cv->TRCVvElt[i]->GENmodPtr),ckt);
|
||||
|
||||
/*
|
||||
* RESload((GENmodel*)(cv->TRCVvElt[i]->GENmodPtr),ckt);
|
||||
*/
|
||||
}
|
||||
else if(cv->TRCVvType[i] == TEMP_CODE) {
|
||||
ckt->CKTtemp = cv->TRCVvSave[i];
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ DISTOan(CKTcircuit *ckt, int restart)
|
|||
int numNames;
|
||||
IFuid *nameList;
|
||||
IFuid freqUid;
|
||||
void *acPlot;
|
||||
void *acPlot=NULL;
|
||||
DISTOAN* job = (DISTOAN *) (ckt->CKTcurJob);
|
||||
static char *nof2src = "No source with f2 distortion input";
|
||||
#ifdef DISTODEBUG
|
||||
|
|
@ -120,6 +120,7 @@ time1 = (*(SPfrontEnd->IFseconds))();
|
|||
if(error) return(error);
|
||||
CKTdump(ckt,(double)0,acPlot);
|
||||
(*(SPfrontEnd->OUTendPlot))(acPlot);
|
||||
acPlot=NULL;
|
||||
}
|
||||
|
||||
#ifdef D_DBG_BLOCKTIMES
|
||||
|
|
@ -540,6 +541,7 @@ time1 = (*(SPfrontEnd->IFseconds))();
|
|||
if(error) return(error);
|
||||
}
|
||||
(*(SPfrontEnd->OUTendPlot))(acPlot);
|
||||
acPlot=NULL;
|
||||
|
||||
error = CKTnames(ckt,&numNames,&nameList);
|
||||
if(error) return(error);
|
||||
|
|
@ -558,6 +560,7 @@ time1 = (*(SPfrontEnd->IFseconds))();
|
|||
error = CKTacDump(ckt,ckt->CKTrhsOld[0],acPlot);
|
||||
}
|
||||
(*(SPfrontEnd->OUTendPlot))(acPlot);
|
||||
acPlot=NULL;
|
||||
|
||||
} else {
|
||||
|
||||
|
|
@ -580,6 +583,7 @@ time1 = (*(SPfrontEnd->IFseconds))();
|
|||
if(error) return(error);
|
||||
}
|
||||
(*(SPfrontEnd->OUTendPlot))(acPlot);
|
||||
acPlot=NULL;
|
||||
|
||||
error = CKTnames(ckt,&numNames,&nameList);
|
||||
if(error) return(error);
|
||||
|
|
@ -600,6 +604,7 @@ time1 = (*(SPfrontEnd->IFseconds))();
|
|||
if(error) return(error);
|
||||
}
|
||||
(*(SPfrontEnd->OUTendPlot))(acPlot);
|
||||
acPlot=NULL;
|
||||
|
||||
error = CKTnames(ckt,&numNames,&nameList);
|
||||
if(error) return(error);
|
||||
|
|
@ -620,6 +625,7 @@ time1 = (*(SPfrontEnd->IFseconds))();
|
|||
if(error) return(error);
|
||||
}
|
||||
(*(SPfrontEnd->OUTendPlot))(acPlot);
|
||||
acPlot=NULL;
|
||||
|
||||
}
|
||||
FREE(job->r1H1ptr);
|
||||
|
|
|
|||
|
|
@ -164,6 +164,12 @@ NOISEan (CKTcircuit *ckt, int restart)
|
|||
job->NsavFstp = 0;
|
||||
data->outNoiz = job->NsavOnoise;
|
||||
data->inNoise = job->NsavInoise;
|
||||
/* saj resume rawfile fix*/
|
||||
error = (*(SPfrontEnd->OUTpBeginPlot))(ckt,(void *)(ckt->CKTcurJob),
|
||||
"Noise Spectral Density Curves - (V^2 or A^2)/Hz",
|
||||
freqUid,IF_REAL,666,data->namelist,666,
|
||||
&(data->NplotPtr));
|
||||
/*saj*/
|
||||
}
|
||||
|
||||
switch (job->NstpType) {
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ PZan(CKTcircuit *ckt, int reset)
|
|||
int error;
|
||||
int numNames;
|
||||
IFuid *nameList;
|
||||
void *plot;
|
||||
void *plot=NULL;
|
||||
|
||||
error = PZinit(ckt);
|
||||
if (error != OK) return error;
|
||||
|
|
@ -123,7 +123,7 @@ int
|
|||
PZpost(CKTcircuit *ckt)
|
||||
{
|
||||
PZAN *pzan = (PZAN *) ckt->CKTcurJob;
|
||||
void *pzPlotPtr; /* the plot pointer for front end */
|
||||
void *pzPlotPtr=NULL; /* the plot pointer for front end */
|
||||
IFcomplex *out_list;
|
||||
IFvalue outData; /* output variable (points to out_list) */
|
||||
IFuid *namelist;
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ TFanal(CKTcircuit *ckt, int restart)
|
|||
int error;
|
||||
int converged;
|
||||
int i;
|
||||
void *plotptr; /* pointer to out plot */
|
||||
void *plotptr=NULL; /* pointer to out plot */
|
||||
void *ptr = NULL;
|
||||
IFuid uids[3];
|
||||
int Itype;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,8 @@
|
|||
5.2.2003 -- Stuart Brorson <SDB@cloud9.net)
|
||||
* Added stuff to all deviceinit.c files to make deviceinfo
|
||||
structure line up with the def of the structure when XSPICE is
|
||||
enabled. This fixed a major bug with XSPICE operation.
|
||||
|
||||
2002-01-03 Paolo Nenzi <p.nenzi@ieee.org>
|
||||
|
||||
* bsim3v1/b3v1noi.c, bsim3v2/b3v2noi.c: Both models had a
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
SUBDIRS = \
|
||||
asrc \
|
||||
bjt \
|
||||
## bjt2 \
|
||||
bsim1 \
|
||||
bsim2 \
|
||||
bsim3 \
|
||||
|
|
@ -16,6 +15,7 @@ SUBDIRS = \
|
|||
cap \
|
||||
cccs \
|
||||
ccvs \
|
||||
cpl \
|
||||
csw \
|
||||
dio \
|
||||
@EKVDIR@ \
|
||||
|
|
@ -37,12 +37,18 @@ SUBDIRS = \
|
|||
soi3 \
|
||||
sw \
|
||||
tra \
|
||||
txl \
|
||||
urc \
|
||||
vccs \
|
||||
vcvs \
|
||||
vsrc
|
||||
|
||||
lib_LIBRARIES = libdev.a
|
||||
## This line move to here 'cause it was causing automake to choke
|
||||
## when it was in the list of subdirs
|
||||
## bjt2 \
|
||||
|
||||
|
||||
noinst_LIBRARIES = libdev.a
|
||||
|
||||
libdev_a_SOURCES = \
|
||||
dev.c \
|
||||
|
|
@ -56,6 +62,6 @@ libdev_a_SOURCES = \
|
|||
cktfinddev.c \
|
||||
cktinit.c
|
||||
|
||||
INCLUDES = -I$(top_srcdir)/src/include
|
||||
INCLUDES = -I$(top_srcdir)/src/include -I$(top_srcdir)/src/spicelib/devices
|
||||
|
||||
MAINTAINERCLEANFILES = Makefile.in
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
pkglib_LTLIBRARIES = libasrc.la
|
||||
noinst_LIBRARIES = libasrc.a
|
||||
|
||||
libasrc_la_SOURCES = \
|
||||
libasrc_a_SOURCES = \
|
||||
asrc.c \
|
||||
asrcacld.c \
|
||||
asrcask.c \
|
||||
|
|
|
|||
|
|
@ -21,6 +21,23 @@ SPICEdev ASRCinfo = {
|
|||
|
||||
0,
|
||||
NULL,
|
||||
|
||||
#ifdef XSPICE
|
||||
/*---- Fixed by SDB 5.2.2003 to enable XSPICE/tclspice integration -----*/
|
||||
NULL, /* This is a SPICE device, it has no MIF info data */
|
||||
|
||||
0, /* This is a SPICE device, it has no MIF info data */
|
||||
NULL, /* This is a SPICE device, it has no MIF info data */
|
||||
|
||||
0, /* This is a SPICE device, it has no MIF info data */
|
||||
NULL, /* This is a SPICE device, it has no MIF info data */
|
||||
|
||||
0, /* This is a SPICE device, it has no MIF info data */
|
||||
NULL, /* This is a SPICE device, it has no MIF info data */
|
||||
/*--------------------------- End of SDB fix -------------------------*/
|
||||
#endif
|
||||
|
||||
|
||||
DEV_DEFAULT
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
pkglib_LTLIBRARIES = libbjt.la
|
||||
noinst_LIBRARIES = libbjt.a
|
||||
|
||||
libbjt_la_SOURCES = \
|
||||
libbjt_a_SOURCES = \
|
||||
bjt.c \
|
||||
bjtacld.c \
|
||||
bjtask.c \
|
||||
|
|
|
|||
|
|
@ -24,21 +24,21 @@ BJTdisto(int mode, GENmodel *genmodel, CKTcircuit *ckt)
|
|||
DISTOAN* job = (DISTOAN*) ckt->CKTcurJob;
|
||||
double td;
|
||||
DpassStr pass;
|
||||
double r1h1x,i1h1x;
|
||||
double r1h1y,i1h1y;
|
||||
double r1h1z, i1h1z;
|
||||
double r1h2x, i1h2x;
|
||||
double r1h2y, i1h2y;
|
||||
double r1h2z, i1h2z;
|
||||
double r1hm2x,i1hm2x;
|
||||
double r1hm2y,i1hm2y;
|
||||
double r1hm2z, i1hm2z;
|
||||
double r2h11x,i2h11x;
|
||||
double r2h11y,i2h11y;
|
||||
double r2h11z, i2h11z;
|
||||
double r2h1m2x,i2h1m2x;
|
||||
double r2h1m2y,i2h1m2y;
|
||||
double r2h1m2z, i2h1m2z;
|
||||
double r1h1x = 0, i1h1x = 0;
|
||||
double r1h1y = 0, i1h1y = 0;
|
||||
double r1h1z = 0, i1h1z = 0;
|
||||
double r1h2x = 0, i1h2x = 0;
|
||||
double r1h2y = 0, i1h2y = 0;
|
||||
double r1h2z = 0, i1h2z = 0;
|
||||
double r1hm2x = 0, i1hm2x = 0;
|
||||
double r1hm2y = 0, i1hm2y = 0;
|
||||
double r1hm2z = 0, i1hm2z = 0;
|
||||
double r2h11x = 0, i2h11x = 0;
|
||||
double r2h11y = 0, i2h11y = 0;
|
||||
double r2h11z = 0, i2h11z = 0;
|
||||
double r2h1m2x = 0, i2h1m2x = 0;
|
||||
double r2h1m2y = 0, i2h1m2y = 0;
|
||||
double r2h1m2z = 0, i2h1m2z = 0;
|
||||
double temp, itemp;
|
||||
BJTinstance *here;
|
||||
#ifdef DISTODEBUG
|
||||
|
|
|
|||
|
|
@ -28,9 +28,9 @@ BJTdSetup(GENmodel *inModel, CKTcircuit *ckt)
|
|||
double arg;
|
||||
double c2;
|
||||
double c4;
|
||||
double lcapbe1,lcapbe2,lcapbe3;
|
||||
double lcapbx1,lcapbx2,lcapbx3;
|
||||
double cb;
|
||||
double lcapbe1, lcapbe2, lcapbe3;
|
||||
double lcapbx1, lcapbx2, lcapbx3;
|
||||
double cb = 0;
|
||||
double cbc;
|
||||
double cbcn;
|
||||
double cbe;
|
||||
|
|
@ -54,16 +54,16 @@ BJTdSetup(GENmodel *inModel, CKTcircuit *ckt)
|
|||
double f3;
|
||||
double fcpc;
|
||||
double fcpe;
|
||||
double gbb1;
|
||||
double gbb1 = 0;
|
||||
double gbc;
|
||||
double gbcn;
|
||||
double gbe;
|
||||
double gbe2,gbe3;
|
||||
double gbe2, gbe3;
|
||||
double gbc2,gbc3;
|
||||
double gben2,gben3;
|
||||
double gbcn2,gbcn3;
|
||||
double gben;
|
||||
double gbb2, gbb3;
|
||||
double gbb2 = 0, gbb3 = 0;
|
||||
double oik;
|
||||
double oikr;
|
||||
double ovtf;
|
||||
|
|
|
|||
|
|
@ -7,23 +7,39 @@
|
|||
#include "bjtinit.h"
|
||||
|
||||
|
||||
SPICEdev BJTinfo = {
|
||||
SPICEdev BJTinfo = { /* description from struct IFdevice */
|
||||
{
|
||||
"BJT",
|
||||
"Bipolar Junction Transistor",
|
||||
"BJT", /* char *name */
|
||||
"Bipolar Junction Transistor", /* char *description */
|
||||
|
||||
&BJTnSize, /* int *terms */
|
||||
&BJTnSize, /* int *numNames */
|
||||
BJTnames, /* char **termnames */
|
||||
|
||||
&BJTpTSize, /* int *numInstanceparms */
|
||||
BJTpTable, /* IFparm *instanceParms */
|
||||
|
||||
&BJTmPTSize, /* int *numModelparms */
|
||||
BJTmPTable, /* IFparm *modelParms */
|
||||
|
||||
&BJTnSize,
|
||||
&BJTnSize,
|
||||
BJTnames,
|
||||
#ifdef XSPICE
|
||||
/*---- Fixed by SDB 5.2.2003 to enable XSPICE/tclspice integration -----*/
|
||||
NULL, /* This is a SPICE device, it has no MIF info data */
|
||||
|
||||
&BJTpTSize,
|
||||
BJTpTable,
|
||||
0, /* This is a SPICE device, it has no MIF info data */
|
||||
NULL, /* This is a SPICE device, it has no MIF info data */
|
||||
|
||||
&BJTmPTSize,
|
||||
BJTmPTable,
|
||||
DEV_DEFAULT
|
||||
0, /* This is a SPICE device, it has no MIF info data */
|
||||
NULL, /* This is a SPICE device, it has no MIF info data */
|
||||
|
||||
0, /* This is a SPICE device, it has no MIF info data */
|
||||
NULL, /* This is a SPICE device, it has no MIF info data */
|
||||
/*--------------------------- End of SDB fix -------------------------*/
|
||||
#endif
|
||||
|
||||
DEV_DEFAULT /* int flags */
|
||||
},
|
||||
|
||||
|
||||
DEVparam : BJTparam,
|
||||
DEVmodParam : BJTmParam,
|
||||
DEVload : BJTload,
|
||||
|
|
|
|||
|
|
@ -114,9 +114,9 @@ BJTload(inModel,ckt)
|
|||
double tr;
|
||||
double vbc;
|
||||
double vbe;
|
||||
double vbx;
|
||||
double vbx=0;
|
||||
double vce;
|
||||
double vcs;
|
||||
double vcs=0;
|
||||
double vt;
|
||||
double vtc;
|
||||
double vte;
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
pkglib_LTLIBRARIES = libbsim1.la
|
||||
noinst_LIBRARIES = libbsim1.a
|
||||
|
||||
libbsim1_la_SOURCES = \
|
||||
libbsim1_a_SOURCES = \
|
||||
b1.c \
|
||||
b1acld.c \
|
||||
b1ask.c \
|
||||
|
|
|
|||
|
|
@ -21,6 +21,22 @@ SPICEdev B1info = {
|
|||
|
||||
&B1mPTSize,
|
||||
B1mPTable,
|
||||
|
||||
#ifdef XSPICE
|
||||
/*---- Fixed by SDB 5.2.2003 to enable XSPICE/tclspice integration -----*/
|
||||
NULL, /* This is a SPICE device, it has no MIF info data */
|
||||
|
||||
0, /* This is a SPICE device, it has no MIF info data */
|
||||
NULL, /* This is a SPICE device, it has no MIF info data */
|
||||
|
||||
0, /* This is a SPICE device, it has no MIF info data */
|
||||
NULL, /* This is a SPICE device, it has no MIF info data */
|
||||
|
||||
0, /* This is a SPICE device, it has no MIF info data */
|
||||
NULL, /* This is a SPICE device, it has no MIF info data */
|
||||
/*--------------------------- End of SDB fix -------------------------*/
|
||||
#endif
|
||||
|
||||
DEV_DEFAULT
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
pkglib_LTLIBRARIES = libbsim2.la
|
||||
noinst_LIBRARIES = libbsim2.a
|
||||
|
||||
libbsim2_la_SOURCES = \
|
||||
libbsim2_a_SOURCES = \
|
||||
b2.c \
|
||||
b2acld.c \
|
||||
b2ask.c \
|
||||
|
|
|
|||
|
|
@ -21,6 +21,22 @@ SPICEdev B2info = {
|
|||
|
||||
&B2mPTSize,
|
||||
B2mPTable,
|
||||
|
||||
#ifdef XSPICE
|
||||
/*---- Fixed by SDB 5.2.2003 to enable XSPICE/tclspice integration -----*/
|
||||
NULL, /* This is a SPICE device, it has no MIF info data */
|
||||
|
||||
0, /* This is a SPICE device, it has no MIF info data */
|
||||
NULL, /* This is a SPICE device, it has no MIF info data */
|
||||
|
||||
0, /* This is a SPICE device, it has no MIF info data */
|
||||
NULL, /* This is a SPICE device, it has no MIF info data */
|
||||
|
||||
0, /* This is a SPICE device, it has no MIF info data */
|
||||
NULL, /* This is a SPICE device, it has no MIF info data */
|
||||
/*--------------------------- End of SDB fix -------------------------*/
|
||||
#endif
|
||||
|
||||
DEV_DEFAULT
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
pkglib_LTLIBRARIES = libbsim3.la
|
||||
noinst_LIBRARIES = libbsim3.a
|
||||
|
||||
libbsim3_la_SOURCES = \
|
||||
libbsim3_a_SOURCES = \
|
||||
b3.c \
|
||||
b3acld.c \
|
||||
b3ask.c \
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue