Merge remote branch 'origin/new_kirchhoff-4' into KLU-kirchhoff-4
Conflicts: configure.ac src/include/ngspice/devdefs.h src/include/ngspice/smpdefs.h src/maths/sparse/spsmp.c src/spicelib/devices/asrc/asrcinit.c src/spicelib/devices/bjt/Makefile.am src/spicelib/devices/bjt/bjtinit.c src/spicelib/devices/bsim1/Makefile.am src/spicelib/devices/bsim1/bsim1ext.h src/spicelib/devices/bsim1/bsim1init.c src/spicelib/devices/bsim2/Makefile.am src/spicelib/devices/bsim2/bsim2ext.h src/spicelib/devices/bsim2/bsim2init.c src/spicelib/devices/bsim3/Makefile.am src/spicelib/devices/bsim3/bsim3ext.h src/spicelib/devices/bsim3/bsim3init.c src/spicelib/devices/bsim3soi_dd/Makefile.am src/spicelib/devices/bsim3soi_dd/b3soiddext.h src/spicelib/devices/bsim3soi_dd/b3soiddinit.c src/spicelib/devices/bsim3soi_dd/b3soiddset.c src/spicelib/devices/bsim3soi_fd/Makefile.am src/spicelib/devices/bsim3soi_fd/b3soifdext.h src/spicelib/devices/bsim3soi_fd/b3soifdinit.c src/spicelib/devices/bsim3soi_pd/Makefile.am src/spicelib/devices/bsim3soi_pd/b3soipdext.h src/spicelib/devices/bsim3soi_pd/b3soipdinit.c src/spicelib/devices/bsim3soi_pd/b3soipdset.c src/spicelib/devices/bsim3v0/Makefile.am src/spicelib/devices/bsim3v0/bsim3v0ext.h src/spicelib/devices/bsim3v0/bsim3v0init.c src/spicelib/devices/bsim3v1/Makefile.am src/spicelib/devices/bsim3v1/bsim3v1ext.h src/spicelib/devices/bsim3v1/bsim3v1init.c src/spicelib/devices/bsim3v32/Makefile.am src/spicelib/devices/bsim3v32/bsim3v32ext.h src/spicelib/devices/bsim3v32/bsim3v32init.c src/spicelib/devices/bsim4/Makefile.am src/spicelib/devices/bsim4/bsim4def.h src/spicelib/devices/bsim4/bsim4ext.h src/spicelib/devices/bsim4/bsim4init.c src/spicelib/devices/bsim4v4/Makefile.am src/spicelib/devices/bsim4v4/bsim4v4ext.h src/spicelib/devices/bsim4v4/bsim4v4init.c src/spicelib/devices/bsim4v5/Makefile.am src/spicelib/devices/bsim4v5/b4v5set.c src/spicelib/devices/bsim4v5/bsim4v5ext.h src/spicelib/devices/bsim4v5/bsim4v5init.c src/spicelib/devices/bsim4v6/Makefile.am src/spicelib/devices/bsim4v6/bsim4v6ext.h src/spicelib/devices/bsim4v6/bsim4v6init.c src/spicelib/devices/bsimsoi/Makefile.am src/spicelib/devices/bsimsoi/b4soiext.h src/spicelib/devices/bsimsoi/b4soiinit.c src/spicelib/devices/bsimsoi/b4soiset.c src/spicelib/devices/cap/Makefile.am src/spicelib/devices/cap/capdefs.h src/spicelib/devices/cap/capext.h src/spicelib/devices/cap/capinit.c src/spicelib/devices/cccs/cccsext.h src/spicelib/devices/cccs/cccsinit.c src/spicelib/devices/ccvs/ccvsinit.c src/spicelib/devices/cpl/cplinit.c src/spicelib/devices/csw/cswinit.c src/spicelib/devices/dio/Makefile.am src/spicelib/devices/dio/diodefs.h src/spicelib/devices/dio/dioext.h src/spicelib/devices/dio/dioinit.c src/spicelib/devices/hfet1/Makefile.am src/spicelib/devices/hfet1/hfetext.h src/spicelib/devices/hfet1/hfetinit.c src/spicelib/devices/hfet2/Makefile.am src/spicelib/devices/hfet2/hfet2ext.h src/spicelib/devices/hfet2/hfet2init.c src/spicelib/devices/hisim2/Makefile.am src/spicelib/devices/hisim2/hsm2ext.h src/spicelib/devices/hisim2/hsm2init.c src/spicelib/devices/hisimhv1/hsmhvext.h src/spicelib/devices/hisimhv1/hsmhvinit.c src/spicelib/devices/ind/Makefile.am src/spicelib/devices/ind/inddefs.h src/spicelib/devices/ind/indinit.c src/spicelib/devices/isrc/isrcinit.c src/spicelib/devices/jfet/Makefile.am src/spicelib/devices/jfet/jfetext.h src/spicelib/devices/jfet/jfetinit.c src/spicelib/devices/jfet/jfetset.c src/spicelib/devices/jfet2/Makefile.am src/spicelib/devices/jfet2/jfet2ext.h src/spicelib/devices/jfet2/jfet2init.c src/spicelib/devices/jfet2/jfet2set.c src/spicelib/devices/ltra/ltrainit.c src/spicelib/devices/mes/Makefile.am src/spicelib/devices/mes/mesext.h src/spicelib/devices/mes/mesinit.c src/spicelib/devices/mes/messetup.c src/spicelib/devices/mesa/Makefile.am src/spicelib/devices/mesa/mesaext.h src/spicelib/devices/mesa/mesainit.c src/spicelib/devices/mos1/Makefile.am src/spicelib/devices/mos1/mos1ext.h src/spicelib/devices/mos1/mos1init.c src/spicelib/devices/mos2/Makefile.am src/spicelib/devices/mos2/mos2ext.h src/spicelib/devices/mos2/mos2init.c src/spicelib/devices/mos3/Makefile.am src/spicelib/devices/mos3/mos3ext.h src/spicelib/devices/mos3/mos3init.c src/spicelib/devices/mos6/Makefile.am src/spicelib/devices/mos6/mos6ext.h src/spicelib/devices/mos6/mos6init.c src/spicelib/devices/mos9/Makefile.am src/spicelib/devices/mos9/mos9ext.h src/spicelib/devices/mos9/mos9init.c src/spicelib/devices/res/Makefile.am src/spicelib/devices/res/resdefs.h src/spicelib/devices/res/resext.h src/spicelib/devices/res/resinit.c src/spicelib/devices/soi3/Makefile.am src/spicelib/devices/soi3/soi3ext.h src/spicelib/devices/soi3/soi3init.c src/spicelib/devices/sw/swinit.c src/spicelib/devices/tra/trainit.c src/spicelib/devices/txl/txlinit.c src/spicelib/devices/txl/txlsetup.c src/spicelib/devices/urc/urcinit.c src/spicelib/devices/vbic/Makefile.am src/spicelib/devices/vbic/vbicinit.c src/spicelib/devices/vccs/vccsinit.c src/spicelib/devices/vcvs/vcvsext.h src/spicelib/devices/vcvs/vcvsinit.c src/spicelib/devices/vsrc/Makefile.am src/spicelib/devices/vsrc/vsrcdefs.h src/spicelib/devices/vsrc/vsrcext.h src/spicelib/devices/vsrc/vsrcinit.c
This commit is contained in:
commit
f5aefd7db8
10
INSTALL
10
INSTALL
|
|
@ -250,6 +250,14 @@ Most of the options now following are not well maintained, are not tested or eve
|
||||||
"tclspice" is compiled and installed instead of
|
"tclspice" is compiled and installed instead of
|
||||||
plain ngspice.
|
plain ngspice.
|
||||||
|
|
||||||
|
--with-ngshared
|
||||||
|
This option let you compile ngspice as a shared
|
||||||
|
library or dll, allowing an application controlling
|
||||||
|
ngspice. This option excludes using --with-x or
|
||||||
|
--with-wingui. Useful additional options are
|
||||||
|
--enable-xspice --enable-cider --enable-openmp.
|
||||||
|
No graphics inetrface is provided, this has to be
|
||||||
|
handled by the controlling application.
|
||||||
|
|
||||||
1.4.3 Options Useful for Debugging Ngspice
|
1.4.3 Options Useful for Debugging Ngspice
|
||||||
|
|
||||||
|
|
@ -538,7 +546,7 @@ Most of the options now following are not well maintained, are not tested or eve
|
||||||
|
|
||||||
9.2 make ngspice with MS Visual Studio 2008
|
9.2 make ngspice with MS Visual Studio 2008
|
||||||
|
|
||||||
ngspice may be compiled with MS Visual Studio 2008.
|
ngspice may be compiled with MS Visual Studio 2008 or 2010.
|
||||||
|
|
||||||
CIDER and XSPICE are included, but the code models for XSPICE
|
CIDER and XSPICE are included, but the code models for XSPICE
|
||||||
(*.cm) are not (yet) made. You may however use the code models
|
(*.cm) are not (yet) made. You may however use the code models
|
||||||
|
|
|
||||||
14
README.adms
14
README.adms
|
|
@ -22,6 +22,20 @@
|
||||||
* 02110-1301 USA *
|
* 02110-1301 USA *
|
||||||
***************************************************************************
|
***************************************************************************
|
||||||
|
|
||||||
|
WARNING!
|
||||||
|
|
||||||
|
The text in this document has been prepared in 2006 and is outdated. It is
|
||||||
|
provided here only for reference and may provide some (historical)
|
||||||
|
information.
|
||||||
|
|
||||||
|
Please refer to the ngspice adms web page at
|
||||||
|
http://ngspice.sourceforge.net/admshowto.html
|
||||||
|
for actual information on how to integrate Verilog A device models into
|
||||||
|
ngspice.
|
||||||
|
|
||||||
|
Holger Vogt, May 2013
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
INTRODUCTION
|
INTRODUCTION
|
||||||
|
|
||||||
|
|
|
||||||
16
configure.ac
16
configure.ac
|
|
@ -182,6 +182,10 @@ AC_ARG_WITH([tcl],
|
||||||
AC_ARG_WITH([ngshared],
|
AC_ARG_WITH([ngshared],
|
||||||
[AS_HELP_STRING([--with-ngshared], [Compiles ngspice as shared library (dll)])])
|
[AS_HELP_STRING([--with-ngshared], [Compiles ngspice as shared library (dll)])])
|
||||||
|
|
||||||
|
# --enable-kirchhoff: enable KCL
|
||||||
|
AC_ARG_ENABLE([kirchhoff],
|
||||||
|
[AS_HELP_STRING([--enable-kirchhoff], [Enables the Kirchhoff Current Law Verification])])
|
||||||
|
|
||||||
# readline and editline cannot both be enabled
|
# readline and editline cannot both be enabled
|
||||||
if test "x$with_editline" = xyes; then
|
if test "x$with_editline" = xyes; then
|
||||||
if test "x$with_readline" = xyes; then
|
if test "x$with_readline" = xyes; then
|
||||||
|
|
@ -801,6 +805,7 @@ AC_MSG_RESULT([Settings which were chosen:])
|
||||||
if test "x$enable_sense2" = xyes; then
|
if test "x$enable_sense2" = xyes; then
|
||||||
AC_DEFINE([WANT_SENSE2], [], [Define if we want spice2 sensitivity analysis])
|
AC_DEFINE([WANT_SENSE2], [], [Define if we want spice2 sensitivity analysis])
|
||||||
AC_MSG_RESULT([Spice2 sensitivity analysis enabled])
|
AC_MSG_RESULT([Spice2 sensitivity analysis enabled])
|
||||||
|
AC_MSG_WARN([This feature is UNSUPPORTED])
|
||||||
fi
|
fi
|
||||||
if test "x$enable_nobypass" = xyes; then
|
if test "x$enable_nobypass" = xyes; then
|
||||||
AC_DEFINE([NOBYPASS], [], [Define if we want NOBYPASS])
|
AC_DEFINE([NOBYPASS], [], [Define if we want NOBYPASS])
|
||||||
|
|
@ -856,7 +861,7 @@ if test "x$enable_pzdebug" = xyes; then
|
||||||
fi
|
fi
|
||||||
if test "x$enable_pss" = xyes; then
|
if test "x$enable_pss" = xyes; then
|
||||||
AC_DEFINE([WITH_PSS], [], [Define if you want PSS analysis])
|
AC_DEFINE([WITH_PSS], [], [Define if you want PSS analysis])
|
||||||
AC_MSG_RESULT(WARNING: PSS analysis enabled)
|
AC_MSG_RESULT([WARNING: PSS analysis enabled])
|
||||||
fi
|
fi
|
||||||
if test "x$enable_blktmsdebug" = xyes; then
|
if test "x$enable_blktmsdebug" = xyes; then
|
||||||
AC_DEFINE([D_DBG_BLOCKTIMES], [], [Define if we want debug distortion analysis (BLOCKTIMES)])
|
AC_DEFINE([D_DBG_BLOCKTIMES], [], [Define if we want debug distortion analysis (BLOCKTIMES)])
|
||||||
|
|
@ -879,6 +884,12 @@ fi
|
||||||
AC_SUBST([XGRAPHDIR])
|
AC_SUBST([XGRAPHDIR])
|
||||||
AC_SUBST([NOTXGRAPH])
|
AC_SUBST([NOTXGRAPH])
|
||||||
|
|
||||||
|
if test "x$enable_kirchhoff" = xyes; then
|
||||||
|
AC_DEFINE([KIRCHHOFF], [], [Define if we want to enable the Kirchhoff Current Law Verification])
|
||||||
|
AC_MSG_RESULT([WARNING: Kirchhoff Current Law Verification Enabled (experimental)])
|
||||||
|
fi
|
||||||
|
AM_CONDITIONAL([KIRCHHOFF_WANTED], [test "x$enable_kirchhoff" = xyes])
|
||||||
|
|
||||||
AC_CHECK_PROGS([YACC], ['bison -y' byacc yacc])
|
AC_CHECK_PROGS([YACC], ['bison -y' byacc yacc])
|
||||||
|
|
||||||
################# XSPICE ##################################################
|
################# XSPICE ##################################################
|
||||||
|
|
@ -945,6 +956,8 @@ AM_CONDITIONAL([NUMDEV_WANTED], [test "x$enable_cider" = xyes])
|
||||||
|
|
||||||
AM_CONDITIONAL([PSS_WANTED], [test "x$enable_pss" = xyes])
|
AM_CONDITIONAL([PSS_WANTED], [test "x$enable_pss" = xyes])
|
||||||
|
|
||||||
|
AM_CONDITIONAL([SENSE2_WANTED], [test "x$enable_sense2" = xyes])
|
||||||
|
|
||||||
# adms option
|
# adms option
|
||||||
if test "x$enable_adms" = xyes ; then
|
if test "x$enable_adms" = xyes ; then
|
||||||
AC_MSG_RESULT([**********************************
|
AC_MSG_RESULT([**********************************
|
||||||
|
|
@ -1216,6 +1229,7 @@ AC_CONFIG_FILES([Makefile
|
||||||
src/xspice/enh/Makefile
|
src/xspice/enh/Makefile
|
||||||
src/xspice/ipc/Makefile
|
src/xspice/ipc/Makefile
|
||||||
src/xspice/idn/Makefile
|
src/xspice/idn/Makefile
|
||||||
|
src/unsupported/Makefile
|
||||||
tests/Makefile
|
tests/Makefile
|
||||||
tests/bsim1/Makefile
|
tests/bsim1/Makefile
|
||||||
tests/bsim2/Makefile
|
tests/bsim2/Makefile
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
DBj_gidl_n
|
||||||
|
|
||||||
|
.INCLUDE 45nm_MGK_car2_gidlgisl.pm
|
||||||
|
.OPTIONS GMIN=1e-18 abstol=1e-19
|
||||||
|
|
||||||
|
*Definizione dei parametri
|
||||||
|
.PARAM Lmin=45n
|
||||||
|
.PARAM Wmin=45n
|
||||||
|
.PARAM Ldiff=90n
|
||||||
|
|
||||||
|
*Descrizione della cella
|
||||||
|
Mp drain gate source body nmos W={Wmin} L={Lmin} AS={Wmin*Ldiff} AD={Wmin*Ldiff} PS={2*(Ldiff+Wmin)} PD={2*(Ldiff+Wmin)}
|
||||||
|
Vd drain alim 0V
|
||||||
|
Vg gate 0 0V
|
||||||
|
Vs source alim 0V
|
||||||
|
Vb body 0 0V
|
||||||
|
Vdd alim 0 0.05V
|
||||||
|
|
||||||
|
*Definizione del tipo di analisi
|
||||||
|
.dc Vdd 0.0 1.2 0.1
|
||||||
|
.print all
|
||||||
|
.END
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
DBj_gidl_p
|
||||||
|
|
||||||
|
.INCLUDE 45nm_MGK_car2_gidlgisl.pm
|
||||||
|
.OPTIONS GMIN=1e-18 abstol=1e-24 vntol=1e-24
|
||||||
|
|
||||||
|
*Definizione dei parametri
|
||||||
|
.PARAM Lmin=45n
|
||||||
|
.PARAM Wmin=45n
|
||||||
|
.PARAM Ldiff=90n
|
||||||
|
|
||||||
|
*Descrizione della cella
|
||||||
|
Mp drain gate source body pmos W={Wmin} L={Lmin} AS={Wmin*Ldiff} AD={Wmin*Ldiff} PS={2*(Ldiff+Wmin)} PD={2*(Ldiff+Wmin)}
|
||||||
|
Vd drain 0 0V
|
||||||
|
Vg gate alim 0V
|
||||||
|
Vs source 0 0V
|
||||||
|
Vb body alim 0V
|
||||||
|
Vdd alim 0 0.05V
|
||||||
|
|
||||||
|
*Definizione del tipo di analisi
|
||||||
|
.dc Vdd 0.0 1.2 0.1
|
||||||
|
.print all
|
||||||
|
.END
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
DBj_gidl_p
|
||||||
|
|
||||||
|
.INCLUDE 45nm_MGK_car2_gidlgisl.pm
|
||||||
|
.OPTIONS GMIN=1e-18 abstol=1e-19
|
||||||
|
|
||||||
|
*Definizione dei parametri
|
||||||
|
.PARAM Lmin=45n
|
||||||
|
.PARAM Wmin=45n
|
||||||
|
.PARAM Ldiff=90n
|
||||||
|
|
||||||
|
*Descrizione della cella
|
||||||
|
Mp drain gate source body pmos W={Wmin} L={Lmin} AS={Wmin*Ldiff} AD={Wmin*Ldiff} PS={2*(Ldiff+Wmin)} PD={2*(Ldiff+Wmin)}
|
||||||
|
Vd drain 0 -1V
|
||||||
|
Vg gate alim 0V
|
||||||
|
Vs source 0 -1V
|
||||||
|
Vb body alim 0V
|
||||||
|
Vdd alim 0 -1.05V
|
||||||
|
|
||||||
|
*Definizione del tipo di analisi
|
||||||
|
.dc Vdd 0.0 1.2 0.1
|
||||||
|
.print all
|
||||||
|
.END
|
||||||
|
|
@ -0,0 +1,120 @@
|
||||||
|
.model nmos nmos level=54
|
||||||
|
+version = 4.7.0 binunit = 1 paramchk= 1 mobmod = 0
|
||||||
|
+capmod = 2 igcmod = 0 igbmod = 0 geomod = 1
|
||||||
|
+diomod = 1 rdsmod = 0 rbodymod= 1 rgatemod= 1
|
||||||
|
+permod = 1 acnqsmod= 0 trnqsmod= 0
|
||||||
|
+tnom = 27 toxe = 9e-010 toxp = 6.5e-010 toxm = 9e-010
|
||||||
|
+dtox = 2.5e-010 epsrox = 3.9 wint = 5e-009 lint = 2.7e-009
|
||||||
|
+ll = 0 wl = 0 lln = 1 wln = 1
|
||||||
|
+lw = 0 ww = 0 lwn = 1 wwn = 1
|
||||||
|
+lwl = 0 wwl = 0 xpart = 0 toxref = 9e-010 xl = -20e-9
|
||||||
|
+dlcig = 2.7e-009
|
||||||
|
+vth0 = 0.3423 k1 = 0.2 k2 = 0 k3 = 0
|
||||||
|
+k3b = 0 w0 = 2.5e-006 dvt0 = 1 dvt1 = 2
|
||||||
|
+dvt2 = 0 dvt0w = 0 dvt1w = 0 dvt2w = 0
|
||||||
|
+dsub = 0.078 minv = 0.05 voffl = 0 dvtp0 = 1e-010
|
||||||
|
+dvtp1 = 0.1 lpe0 = 0 lpeb = 0 xj = 1.4e-008
|
||||||
|
+ngate = 1e+023 ndep = 6.5e+018 nsd = 2e+020 phin = 0
|
||||||
|
+cdsc = 0 cdscb = 0 cdscd = 0 cit = 0
|
||||||
|
+voff = -0.13 nfactor = 1.9 eta0 = 0.0055 etab = 0
|
||||||
|
+vfb = -1.058 u0 = 0.02947 ua = -5e-010 ub = 1.7e-018
|
||||||
|
+uc = 0 vsat = 159550 a0 = 1 ags = 0
|
||||||
|
+a1 = 0 a2 = 1 b0 = 0 b1 = 0
|
||||||
|
+keta = 0.04 dwg = 0 dwb = 0 pclm = 0.06
|
||||||
|
+pdiblc1 = 0.001 pdiblc2 = 0.001 pdiblcb = -0.005 drout = 0.5
|
||||||
|
+pvag = 1e-020 delta = 0.01 pscbe1 = 2.0e+009 pscbe2 = 1e-007
|
||||||
|
+fprout = 0.2 pdits = 0.01 pditsd = 0.23 pditsl = 2300000
|
||||||
|
+rsh = 5 rdsw = 105 rsw = 52.5 rdw = 52.5
|
||||||
|
+rdswmin = 0 rdwmin = 0 rswmin = 0 prwg = 0
|
||||||
|
+prwb = 0 wr = 1 alpha0 = 0.0 alpha1 = 0.00
|
||||||
|
+beta0 = 30 agidl = 0.0002 bgidl = 2.1e+009 cgidl = 0.0002
|
||||||
|
+egidl = 0.8 aigbacc = 0.012 bigbacc = 0.0028 cigbacc = 0.002
|
||||||
|
+nigbacc = 1 aigbinv = 0.014 bigbinv = 0.004 cigbinv = 0.004
|
||||||
|
+eigbinv = 1.1 nigbinv = 3 aigc = 0.018029 bigc = 0.0029
|
||||||
|
+cigc = 0.002 aigsd = 0.018029 bigsd = 0.0029 cigsd = 0.002
|
||||||
|
+nigc = 1 poxedge = 1 pigcd = 1 ntox = 1
|
||||||
|
+xrcrg1 = 12 xrcrg2 = 5
|
||||||
|
+cgso = 1e-010 cgdo = 1e-010 cgbo = 0 cgdl = 7.5e-013
|
||||||
|
+cgsl = 7.5e-013 clc = 1e-007 cle = 0.6 cf = 1.1e-010
|
||||||
|
+ckappas = 0.6 ckappad = 0.6 vfbcv = -1 acde = 1
|
||||||
|
+moin = 15 noff = 1 voffcv = 0
|
||||||
|
+kt1 = -0.154 kt1l = 0 kt2 = 0.022 ute = -1.1
|
||||||
|
+ua1 = 1e-009 ub1 = -1e-018 uc1 = -5.6e-011 prt = 0
|
||||||
|
+at = 33000
|
||||||
|
+fnoimod = 1 tnoimod = 0 noia = 6.25e+041 noib = 3.125e+026
|
||||||
|
+noic = 8.75e+009 em = 41000000 af = 1 ef = 1
|
||||||
|
+kf = 0 tnoia = 1.5 tnoib = 3.5 ntnoi = 1
|
||||||
|
+jss = 0.0 jsws = 0.0 jswgs = 0.0 njs = 1
|
||||||
|
+ijthsfwd= 0.1 ijthsrev= 0.1 bvs = 10 xjbvs = 1
|
||||||
|
+jsd = 0.0 jswd = 0.0 jswgd = 0.0 xjbvd = 1
|
||||||
|
+pbs = 1 cjs = 0.0018 mjs = 0.5 pbsws = 1
|
||||||
|
+cjsws = 1.2e-010 mjsws = 0.33 cjswgs = 2.1e-010 cjd = 0.0018
|
||||||
|
+cjswd = 1.2e-010 mjswd = 0.33 pbswgd = 1 cjswgd = 2.1e-010
|
||||||
|
+mjswgd = 0.33 tpb = 0 tcj = 0 tpbsw = 0
|
||||||
|
+tcjsw = 0 tpbswg = 0 tcjswg = 0 xtis = 3
|
||||||
|
+dmcg = 0 dmci = 0 dmdg = 0 dmcgt = 0
|
||||||
|
+dwj = 0 xgw = 0 xgl = 0
|
||||||
|
+rshg = 0.4 gbmin = 1e-010 rbpb = 5 rbpd = 15
|
||||||
|
+rbps = 15 rbdb = 15 rbsb = 15 ngcon = 1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.model pmos pmos level = 54
|
||||||
|
+version = 4.7.0 binunit = 1 paramchk= 1 mobmod = 0
|
||||||
|
+capmod = 2 igcmod = 0 igbmod = 0 geomod = 1
|
||||||
|
+diomod = 1 rdsmod = 0 rbodymod= 1 rgatemod= 1
|
||||||
|
+permod = 1 acnqsmod= 0 trnqsmod= 0
|
||||||
|
+tnom = 27 toxe = 9.2e-010 toxp = 6.5e-010 toxm = 9.2e-010
|
||||||
|
+dtox = 2.7e-010 epsrox = 3.9 wint = 5e-009 lint = 2.7e-009
|
||||||
|
+ll = 0 wl = 0 lln = 1 wln = 1
|
||||||
|
+lw = 0 ww = 0 lwn = 1 wwn = 1
|
||||||
|
+lwl = 0 wwl = 0 xpart = 0 toxref = 9.2e-010 xl = -20e-9
|
||||||
|
+dlcig = 2.7e-009
|
||||||
|
+vth0 = -0.23122 k1 = 0.2 k2 = -0.01 k3 = 0
|
||||||
|
+k3b = 0 w0 = 2.5e-006 dvt0 = 1 dvt1 = 2
|
||||||
|
+dvt2 = -0.032 dvt0w = 0 dvt1w = 0 dvt2w = 0
|
||||||
|
+dsub = 0.1 minv = 0.05 voffl = 0 dvtp0 = 1e-011
|
||||||
|
+dvtp1 = 0.05 lpe0 = 0 lpeb = 0 xj = 1.4e-008
|
||||||
|
+ngate = 1e+023 ndep = 2.8e+018 nsd = 2e+020 phin = 0
|
||||||
|
+cdsc = 0 cdscb = 0 cdscd = 0 cit = 0
|
||||||
|
+voff = -0.13 nfactor = 1.9 eta0 = 0.0049 etab = 0
|
||||||
|
+vfb = -1.058 u0 = 0.00391 ua = -5e-010 ub = 1.6e-018
|
||||||
|
+uc = 0 vsat = 78000 a0 = 1 ags = 1e-020
|
||||||
|
+a1 = 0 a2 = 1 b0 = 0 b1 = 0
|
||||||
|
+keta = -0.047 dwg = 0 dwb = 0 pclm = 0.1
|
||||||
|
+pdiblc1 = 0.001 pdiblc2 = 0.001 pdiblcb = 3.4e-008 drout = 0.6
|
||||||
|
+pvag = 1e-020 delta = 0.01 pscbe1 = 2e+009 pscbe2 = 9.58e-007
|
||||||
|
+fprout = 0.2 pdits = 0.08 pditsd = 0.23 pditsl = 2300000
|
||||||
|
+rsh = 5 rdsw = 105 rsw = 52.5 rdw = 52.5
|
||||||
|
+rdswmin = 0 rdwmin = 0 rswmin = 0 prwg = 0
|
||||||
|
+prwb = 0 wr = 1 alpha0 = 0.0 alpha1 = 0.00
|
||||||
|
+beta0 = 30 agidl = 0.0002 bgidl = 2.1e+009 cgidl = 0.0002
|
||||||
|
+egidl = 0.8 aigbacc = 0.012 bigbacc = 0.0028 cigbacc = 0.002
|
||||||
|
+nigbacc = 1 aigbinv = 0.014 bigbinv = 0.004 cigbinv = 0.004
|
||||||
|
+eigbinv = 1.1 nigbinv = 3 aigc = 0.010687 bigc = 0.0012607
|
||||||
|
+cigc = 0.0008 aigsd = 0.010687 bigsd = 0.0012607 cigsd = 0.0008
|
||||||
|
+nigc = 1 poxedge = 1 pigcd = 1 ntox = 1
|
||||||
|
+xrcrg1 = 12 xrcrg2 = 5
|
||||||
|
+cgso = 1e-010 cgdo = 1e-010 cgbo = 0 cgdl = 3e-011
|
||||||
|
+cgsl = 3e-011 clc = 1e-007 cle = 0.6 cf = 1.1e-010
|
||||||
|
+ckappas = 0.6 ckappad = 0.6 vfbcv = -1 acde = 1
|
||||||
|
+moin = 15 noff = 1 voffcv = 0
|
||||||
|
+kt1 = -0.14 kt1l = 0 kt2 = 0.022 ute = -1.1
|
||||||
|
+ua1 = 1e-009 ub1 = -1e-018 uc1 = -5.6e-011 prt = 0
|
||||||
|
+at = 33000
|
||||||
|
+fnoimod = 1 tnoimod = 0 noia = 6.25e+041 noib = 3.125e+026
|
||||||
|
+noic = 8.75e+009 em = 41000000 af = 1 ef = 1
|
||||||
|
+kf = 0 tnoia = 1.5 tnoib = 3.5 ntnoi = 1
|
||||||
|
+jss = 0.0 jsws = 0.0 jswgs = 0.0 njs = 1
|
||||||
|
+ijthsfwd= 0.1 ijthsrev= 0.1 bvs = 10 xjbvs = 1
|
||||||
|
+jsd = 0.0 jswd = 0.0 jswgd = 0.0 xjbvd = 1
|
||||||
|
+pbs = 1 cjs = 0.0015 mjs = 0.5 pbsws = 1
|
||||||
|
+cjsws = 9.4e-011 mjsws = 0.33 cjswgs = 2e-010 cjd = 0.0015
|
||||||
|
+cjswd = 9.4e-011 mjswd = 0.33 pbswgd = 1 cjswgd = 2e-010
|
||||||
|
+mjswgd = 0.33 tpb = 0 tcj = 0 tpbsw = 0
|
||||||
|
+tcjsw = 0 tpbswg = 0 tcjswg = 0 xtis = 3
|
||||||
|
+dmcg = 0 dmdg = 0 dmcgt = 0 xgw = 0
|
||||||
|
+xgl = 0
|
||||||
|
+rshg = 0.1 gbmin = 1e-012 rbpb = 50 rbpd = 50
|
||||||
|
+rbps = 50 rbdb = 50 rbsb = 50 ngcon = 1
|
||||||
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
## Process this file with automake to produce Makefile.in
|
## Process this file with automake to produce Makefile.in
|
||||||
|
|
||||||
SUBDIRS = misc maths frontend spicelib include/ngspice
|
SUBDIRS = misc maths frontend spicelib include/ngspice
|
||||||
DIST_SUBDIRS = misc maths frontend spicelib include/ngspice xspice ciderlib
|
DIST_SUBDIRS = misc maths frontend spicelib include/ngspice xspice ciderlib unsupported
|
||||||
|
|
||||||
if XSPICE_WANTED
|
if XSPICE_WANTED
|
||||||
SUBDIRS += xspice
|
SUBDIRS += xspice
|
||||||
|
|
@ -11,6 +11,10 @@ if CIDER_WANTED
|
||||||
SUBDIRS += ciderlib
|
SUBDIRS += ciderlib
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if SENSE2_WANTED
|
||||||
|
SUBDIRS += unsupported
|
||||||
|
endif
|
||||||
|
|
||||||
if !TCL_MODULE
|
if !TCL_MODULE
|
||||||
if !SHARED_MODULE
|
if !SHARED_MODULE
|
||||||
bin_PROGRAMS = ngspice ngnutmeg
|
bin_PROGRAMS = ngspice ngnutmeg
|
||||||
|
|
@ -27,7 +31,7 @@ endif !SHARED_MODULE
|
||||||
endif !TCL_MODULE
|
endif !TCL_MODULE
|
||||||
|
|
||||||
EXTRA_DIST = ngspice.txt setplot spectrum \
|
EXTRA_DIST = ngspice.txt setplot spectrum \
|
||||||
devload devaxis ciderinit winmain.c winmain.h unsupported \
|
devload devaxis ciderinit winmain.c winmain.h \
|
||||||
tclspice.c tclspice.map pkgIndex.tcl.in spinit.in tclspinit.in \
|
tclspice.c tclspice.map pkgIndex.tcl.in spinit.in tclspinit.in \
|
||||||
main.c sharedspice.c
|
main.c sharedspice.c
|
||||||
|
|
||||||
|
|
@ -137,6 +141,10 @@ ngspice_LDADD += \
|
||||||
spicelib/analysis/libckt.la \
|
spicelib/analysis/libckt.la \
|
||||||
spicelib/devices/libdev.la
|
spicelib/devices/libdev.la
|
||||||
|
|
||||||
|
if SENSE2_WANTED
|
||||||
|
ngspice_LDADD += unsupported/libunsupported.la
|
||||||
|
endif
|
||||||
|
|
||||||
if XSPICE_WANTED
|
if XSPICE_WANTED
|
||||||
ngspice_LDADD += \
|
ngspice_LDADD += \
|
||||||
xspice/cm/libcmxsp.la \
|
xspice/cm/libcmxsp.la \
|
||||||
|
|
|
||||||
|
|
@ -50,9 +50,10 @@ static char *upper(register char *string);
|
||||||
static bool doedit(char *filename);
|
static bool doedit(char *filename);
|
||||||
static struct line *com_options = NULL;
|
static struct line *com_options = NULL;
|
||||||
static void cktislinear(CKTcircuit *ckt, struct line *deck);
|
static void cktislinear(CKTcircuit *ckt, struct line *deck);
|
||||||
|
static void dotifeval(struct line *deck);
|
||||||
|
|
||||||
void line_free_x(struct line *deck, bool recurse);
|
void line_free_x(struct line *deck, bool recurse);
|
||||||
|
void create_circbyline(char *line);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -547,6 +548,9 @@ inp_spsource(FILE *fp, bool comfile, char *filename, bool intfile)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* handle .if ... .elseif ... .else ... .endif statements. */
|
||||||
|
dotifeval(deck);
|
||||||
|
|
||||||
/*merge the two option line structs*/
|
/*merge the two option line structs*/
|
||||||
if (!options && com_options)
|
if (!options && com_options)
|
||||||
options = com_options;
|
options = com_options;
|
||||||
|
|
@ -1199,3 +1203,71 @@ com_circbyline(wordlist *wl)
|
||||||
char *newline = wl_flatten(wl);
|
char *newline = wl_flatten(wl);
|
||||||
create_circbyline(newline);
|
create_circbyline(newline);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* handle .if('expr') ... .elseif('expr') ... .else ... .endif statements.
|
||||||
|
numparam has evaluated .if('boolean expression') to
|
||||||
|
.if ( 1.000000000e+000 ) or .elseif ( 0.000000000e+000 ) */
|
||||||
|
static void
|
||||||
|
dotifeval(struct line *deck)
|
||||||
|
{
|
||||||
|
int iftrue = 0, elseiftrue = 0, elsetrue = 0, iffound = 0, elseiffound = 0, elsefound = 0;
|
||||||
|
struct line *dd;
|
||||||
|
char *dottoken;
|
||||||
|
char *s, *t;
|
||||||
|
|
||||||
|
/* skip the first line (title line) */
|
||||||
|
for (dd = deck->li_next; dd; dd = dd->li_next) {
|
||||||
|
|
||||||
|
s = t = dd->li_line;
|
||||||
|
|
||||||
|
if (*s == '*')
|
||||||
|
continue;
|
||||||
|
|
||||||
|
dottoken = gettok(&t);
|
||||||
|
/* find '.if' and read its parameter */
|
||||||
|
if (cieq(dottoken, ".if")) {
|
||||||
|
elsefound = 0;
|
||||||
|
elseiffound = 0;
|
||||||
|
iffound = 1;
|
||||||
|
*s = '*';
|
||||||
|
s = dd->li_line + 3;
|
||||||
|
iftrue = atoi(s);
|
||||||
|
}
|
||||||
|
else if (cieq(dottoken, ".elseif")) {
|
||||||
|
elsefound = 0;
|
||||||
|
elseiffound = 1;
|
||||||
|
iffound = 0;
|
||||||
|
*s = '*';
|
||||||
|
if (!iftrue) {
|
||||||
|
s = dd->li_line + 7;
|
||||||
|
elseiftrue = atoi(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (cieq(dottoken, ".else")) {
|
||||||
|
elsefound = 1;
|
||||||
|
elseiffound = 0;
|
||||||
|
iffound = 0;
|
||||||
|
if (!iftrue && !elseiftrue)
|
||||||
|
elsetrue = 1;
|
||||||
|
*s = '*';
|
||||||
|
}
|
||||||
|
else if (cieq(dottoken, ".endif")) {
|
||||||
|
elsefound = elseiffound = iffound = 0;
|
||||||
|
elsetrue = elseiftrue = iftrue = 0;
|
||||||
|
*s = '*';
|
||||||
|
// inp_subcktexpand(dd);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (iffound && !iftrue) {
|
||||||
|
*s = '*';
|
||||||
|
}
|
||||||
|
else if (elseiffound && !elseiftrue) {
|
||||||
|
*s = '*';
|
||||||
|
}
|
||||||
|
else if (elsefound && !elsetrue) {
|
||||||
|
*s = '*';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tfree(dottoken);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -239,6 +239,14 @@ do_measure(
|
||||||
return (measures_passed);
|
return (measures_passed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* don't allow autostop if no .meas commands are given in the input file */
|
||||||
|
if ((cp_getvar("autostop", CP_BOOL, NULL)) && (ft_curckt->ci_meas == NULL)) {
|
||||||
|
fprintf(cp_err, "\nWarning: No .meas commands found!\n");
|
||||||
|
fprintf(cp_err, " Option autostop is not available, ignored!\n\n");
|
||||||
|
cp_remvar("autostop");
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
/* Evaluating the linked list of .meas cards, assembled from the input deck
|
/* Evaluating the linked list of .meas cards, assembled from the input deck
|
||||||
by fcn inp_spsource() in inp.c:575.
|
by fcn inp_spsource() in inp.c:575.
|
||||||
A typical .meas card will contain:
|
A typical .meas card will contain:
|
||||||
|
|
|
||||||
|
|
@ -189,6 +189,11 @@ com_version(wordlist *wl)
|
||||||
fprintf(cp_out, "** %s\n", Spice_Notice);
|
fprintf(cp_out, "** %s\n", Spice_Notice);
|
||||||
if (Spice_Build_Date != NULL && *Spice_Build_Date != 0)
|
if (Spice_Build_Date != NULL && *Spice_Build_Date != 0)
|
||||||
fprintf(cp_out, "** Creation Date: %s\n", Spice_Build_Date);
|
fprintf(cp_out, "** Creation Date: %s\n", Spice_Build_Date);
|
||||||
|
|
||||||
|
#ifdef KIRCHHOFF
|
||||||
|
fprintf(cp_out, "** KCL Verification enabled.\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
fprintf(cp_out, "******\n");
|
fprintf(cp_out, "******\n");
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -279,6 +284,9 @@ com_version(wordlist *wl)
|
||||||
#endif
|
#endif
|
||||||
#ifdef EXP_DEV
|
#ifdef EXP_DEV
|
||||||
fprintf(cp_out, "** Experimental devices enabled.\n");
|
fprintf(cp_out, "** Experimental devices enabled.\n");
|
||||||
|
#endif
|
||||||
|
#ifdef KIRCHHOFF
|
||||||
|
fprintf(cp_out, "** KCL Verification enabled.\n");
|
||||||
#endif
|
#endif
|
||||||
fprintf(cp_out, "******\n");
|
fprintf(cp_out, "******\n");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ typedef enum {Nodekey = '#'} _nNodekey; /* Introduces node symbol */
|
||||||
typedef enum {Intro = '&'} _nIntro; /* Introduces preprocessor tokens */
|
typedef enum {Intro = '&'} _nIntro; /* Introduces preprocessor tokens */
|
||||||
typedef enum {Comment = '*'} _nComment; /* Spice Comment lines */
|
typedef enum {Comment = '*'} _nComment; /* Spice Comment lines */
|
||||||
typedef enum {Psp = '{'} _nPsp; /* Ps expression */
|
typedef enum {Psp = '{'} _nPsp; /* Ps expression */
|
||||||
typedef enum {Defd = 15} _nDefd; /* serial numb. of 'defined' keyword.
|
typedef enum {Defd = 6} _nDefd; /* serial numb. of 'defined' keyword.
|
||||||
The others are not used (yet) */
|
The others are not used (yet) */
|
||||||
|
|
||||||
typedef char *auxtable; /* dummy */
|
typedef char *auxtable; /* dummy */
|
||||||
|
|
|
||||||
|
|
@ -243,6 +243,11 @@ modernizeex(SPICE_DSTRINGPTR dstr_p)
|
||||||
state = 0;
|
state = 0;
|
||||||
ls = spice_dstring_length(dstr_p);
|
ls = spice_dstring_length(dstr_p);
|
||||||
s = spice_dstring_value(dstr_p);
|
s = spice_dstring_value(dstr_p);
|
||||||
|
|
||||||
|
/* check if string might need modernizing */
|
||||||
|
if (!memchr(s, Intro, (size_t) ls))
|
||||||
|
return;
|
||||||
|
|
||||||
spice_dstring_init(&t);
|
spice_dstring_init(&t);
|
||||||
|
|
||||||
while (i < ls) {
|
while (i < ls) {
|
||||||
|
|
|
||||||
|
|
@ -88,8 +88,7 @@ initkeys(void)
|
||||||
{
|
{
|
||||||
spice_dstring_init(&keyS);
|
spice_dstring_init(&keyS);
|
||||||
scopy_up(&keyS,
|
scopy_up(&keyS,
|
||||||
"and or not div mod if else end while macro funct defined"
|
"and or not div mod defined");
|
||||||
" include for to downto is var");
|
|
||||||
scopy_up(&fmathS,
|
scopy_up(&fmathS,
|
||||||
"sqr sqrt sin cos exp ln arctan abs pow pwr max min int log sinh cosh"
|
"sqr sqrt sin cos exp ln arctan abs pow pwr max min int log sinh cosh"
|
||||||
" tanh ternary_fcn v agauss sgn gauss unif aunif limit ceil floor");
|
" tanh ternary_fcn v agauss sgn gauss unif aunif limit ceil floor");
|
||||||
|
|
@ -935,7 +934,7 @@ opfunctkey(tdico *dico,
|
||||||
/*if kw operator keyword, c=token*/
|
/*if kw operator keyword, c=token*/
|
||||||
switch (kw)
|
switch (kw)
|
||||||
{
|
{
|
||||||
/* & | ~ DIV MOD Defined */
|
/* & | ~ DIV MOD Defined */
|
||||||
case 1:
|
case 1:
|
||||||
c = '&';
|
c = '&';
|
||||||
state = 2;
|
state = 2;
|
||||||
|
|
|
||||||
|
|
@ -81,10 +81,10 @@ static IFvalue *doask(CKTcircuit *ckt, int typecode, GENinstance *dev, GENmodel
|
||||||
IFparm *opt, int ind);
|
IFparm *opt, int ind);
|
||||||
static int doset(CKTcircuit *ckt, int typecode, GENinstance *dev, GENmodel *mod,
|
static int doset(CKTcircuit *ckt, int typecode, GENinstance *dev, GENmodel *mod,
|
||||||
IFparm *opt, struct dvec *val);
|
IFparm *opt, struct dvec *val);
|
||||||
static int finddev(CKTcircuit *ck, char *name, GENinstance **devptr, GENmodel **modptr);
|
static int finddev(CKTcircuit *ckt, char *name, GENinstance **devptr, GENmodel **modptr);
|
||||||
|
|
||||||
/* espice fix integration */
|
/* espice fix integration */
|
||||||
static int finddev_special(CKTcircuit *ck, char *name, GENinstance **devptr, GENmodel **modptr, int *device_or_model);
|
static int finddev_special(CKTcircuit *ckt, char *name, GENinstance **devptr, GENmodel **modptr, int *device_or_model);
|
||||||
|
|
||||||
|
|
||||||
/* Input a single deck, and return a pointer to the circuit. */
|
/* Input a single deck, and return a pointer to the circuit. */
|
||||||
|
|
@ -252,8 +252,7 @@ if_run(CKTcircuit *ckt, char *what, wordlist *args, INPtables *tab)
|
||||||
/*CDHW Create an interactive task AAA with a new UID.
|
/*CDHW Create an interactive task AAA with a new UID.
|
||||||
ci_specTask will point to it CDHW*/
|
ci_specTask will point to it CDHW*/
|
||||||
|
|
||||||
err = IFnewUid(ft_curckt->ci_ckt, &specUid, NULL, "special",
|
err = IFnewUid(ft_curckt->ci_ckt, &specUid, NULL, "special", UID_TASK, NULL);
|
||||||
UID_TASK, NULL);
|
|
||||||
if (err) {
|
if (err) {
|
||||||
ft_sperror(err, "newUid");
|
ft_sperror(err, "newUid");
|
||||||
return (2);
|
return (2);
|
||||||
|
|
@ -281,8 +280,7 @@ if_run(CKTcircuit *ckt, char *what, wordlist *args, INPtables *tab)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (which != -1) { /*CDHW options are available CDHW*/
|
if (which != -1) { /*CDHW options are available CDHW*/
|
||||||
err = IFnewUid(ft_curckt->ci_ckt, &optUid, NULL, "options",
|
err = IFnewUid(ft_curckt->ci_ckt, &optUid, NULL, "options", UID_ANALYSIS, NULL);
|
||||||
UID_ANALYSIS, NULL);
|
|
||||||
if (err) {
|
if (err) {
|
||||||
ft_sperror(err, "newUid");
|
ft_sperror(err, "newUid");
|
||||||
return (2);
|
return (2);
|
||||||
|
|
@ -616,7 +614,7 @@ finddev_special(
|
||||||
int err;
|
int err;
|
||||||
int type = -1;
|
int type = -1;
|
||||||
|
|
||||||
err = ft_sim->findInstance (ckt, &type, devptr, name, NULL, NULL);
|
err = ft_sim->findInstance (ckt, &type, devptr, name, NULL);
|
||||||
if (err == OK) {
|
if (err == OK) {
|
||||||
*device_or_model = 0;
|
*device_or_model = 0;
|
||||||
return (type);
|
return (type);
|
||||||
|
|
@ -1212,19 +1210,19 @@ doset(CKTcircuit *ckt, int typecode, GENinstance *dev, GENmodel *mod, IFparm *op
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int
|
static int
|
||||||
finddev(CKTcircuit *ck, char *name, GENinstance **devptr, GENmodel **modptr)
|
finddev(CKTcircuit *ckt, char *name, GENinstance **devptr, GENmodel **modptr)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
int type = -1;
|
int type = -1;
|
||||||
|
|
||||||
err = ft_sim->findInstance (ck, &type, devptr, name, NULL, NULL);
|
err = ft_sim->findInstance (ckt, &type, devptr, name, NULL);
|
||||||
if (err == OK)
|
if (err == OK)
|
||||||
return (type);
|
return (type);
|
||||||
|
|
||||||
type = -1;
|
type = -1;
|
||||||
*devptr = NULL;
|
*devptr = NULL;
|
||||||
|
|
||||||
err = ft_sim->findModel (ck, &type, modptr, name);
|
err = ft_sim->findModel (ckt, &type, modptr, name);
|
||||||
if (err == OK)
|
if (err == OK)
|
||||||
return (type);
|
return (type);
|
||||||
|
|
||||||
|
|
@ -1273,8 +1271,7 @@ if_tranparams(struct circ *ci, double *start, double *stop, double *step)
|
||||||
if (which == -1)
|
if (which == -1)
|
||||||
return (FALSE);
|
return (FALSE);
|
||||||
|
|
||||||
err = IFnewUid(ci->ci_ckt, &tranUid, NULL, "Transient Analysis",
|
err = IFnewUid(ci->ci_ckt, &tranUid, NULL, "Transient Analysis", UID_ANALYSIS, NULL);
|
||||||
UID_ANALYSIS, NULL);
|
|
||||||
if (err != OK)
|
if (err != OK)
|
||||||
return (FALSE);
|
return (FALSE);
|
||||||
|
|
||||||
|
|
@ -1616,11 +1613,11 @@ void com_snload(wordlist *wl)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SPfrontEnd->IFnewUid (ckt, &timeUid, NULL, "time", UID_OTHER, NULL);
|
SPfrontEnd->IFnewUid (ckt, &timeUid, NULL, "time", UID_OTHER, NULL);
|
||||||
error = SPfrontEnd->OUTpBeginPlot (
|
error = SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
|
||||||
ckt, ckt->CKTcurJob,
|
ckt->CKTcurJob->JOBname,
|
||||||
ckt->CKTcurJob->JOBname,
|
timeUid, IF_REAL,
|
||||||
timeUid, IF_REAL,
|
numNames, nameList, IF_REAL,
|
||||||
numNames, nameList, IF_REAL, &(((TRANan*)ckt->CKTcurJob)->TRANplot));
|
&(((TRANan*)ckt->CKTcurJob)->TRANplot));
|
||||||
if (error) {
|
if (error) {
|
||||||
fprintf(cp_err, "error in CKTnames\n");
|
fprintf(cp_err, "error in CKTnames\n");
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -1815,6 +1815,7 @@ devmodtranslate(struct line *deck, char *subname, wordlist * const submod)
|
||||||
|
|
||||||
case 'r':
|
case 'r':
|
||||||
case 'c':
|
case 'c':
|
||||||
|
case 'l':
|
||||||
name = gettok(&t); /* get refdes */
|
name = gettok(&t); /* get refdes */
|
||||||
(void) sprintf(buffer, "%s ", name);
|
(void) sprintf(buffer, "%s ", name);
|
||||||
tfree(name);
|
tfree(name);
|
||||||
|
|
@ -1967,7 +1968,7 @@ devmodtranslate(struct line *deck, char *subname, wordlist * const submod)
|
||||||
name = gettok(&t);
|
name = gettok(&t);
|
||||||
|
|
||||||
found = 0;
|
found = 0;
|
||||||
while (*t && !found) {
|
while (!found) {
|
||||||
/* Now, is this a subcircuit model? */
|
/* Now, is this a subcircuit model? */
|
||||||
for (wlsub = submod; wlsub; wlsub = wlsub->wl_next) {
|
for (wlsub = submod; wlsub; wlsub = wlsub->wl_next) {
|
||||||
/* FIXME, probably too unspecific */
|
/* FIXME, probably too unspecific */
|
||||||
|
|
@ -1994,6 +1995,10 @@ devmodtranslate(struct line *deck, char *subname, wordlist * const submod)
|
||||||
(void) sprintf(buffer + strlen(buffer), "%s ", name);
|
(void) sprintf(buffer + strlen(buffer), "%s ", name);
|
||||||
tfree(name);
|
tfree(name);
|
||||||
name = gettok(&t);
|
name = gettok(&t);
|
||||||
|
if (name == NULL) {
|
||||||
|
name = copy(""); /* allow 'tfree' */
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} /* while */
|
} /* while */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,12 @@ struct CKTnode {
|
||||||
#define PARM_IC 2
|
#define PARM_IC 2
|
||||||
#define PARM_NODETYPE 3
|
#define PARM_NODETYPE 3
|
||||||
|
|
||||||
|
#ifdef KIRCHHOFF
|
||||||
|
typedef struct sCKTmkCurKCLnode {
|
||||||
|
double KCLcurrent ;
|
||||||
|
struct sCKTmkCurKCLnode *next ;
|
||||||
|
} CKTmkCurKCLnode ;
|
||||||
|
#endif
|
||||||
|
|
||||||
struct CKTcircuit {
|
struct CKTcircuit {
|
||||||
|
|
||||||
|
|
@ -110,6 +116,13 @@ struct CKTcircuit {
|
||||||
double *CKTrhs; /* current rhs value - being loaded */
|
double *CKTrhs; /* current rhs value - being loaded */
|
||||||
double *CKTrhsOld; /* previous rhs value for convergence
|
double *CKTrhsOld; /* previous rhs value for convergence
|
||||||
testing */
|
testing */
|
||||||
|
|
||||||
|
#ifdef KIRCHHOFF
|
||||||
|
double *CKTfvk ; /* KCL Verification array */
|
||||||
|
int *CKTnodeIsLinear ; /* Flag to indicate if a node is linear or non-linear */
|
||||||
|
CKTmkCurKCLnode **CKTmkCurKCLarray ; /* Array of KCL Currents */
|
||||||
|
#endif
|
||||||
|
|
||||||
double *CKTrhsSpare; /* spare rhs value for reordering */
|
double *CKTrhsSpare; /* spare rhs value for reordering */
|
||||||
double *CKTirhs; /* current rhs value - being loaded
|
double *CKTirhs; /* current rhs value - being loaded
|
||||||
(imag) */
|
(imag) */
|
||||||
|
|
@ -289,7 +302,11 @@ struct CKTcircuit {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* Now function prottypes */
|
/* Now function prototypes */
|
||||||
|
|
||||||
|
#ifdef KIRCHHOFF
|
||||||
|
extern int CKTmkCurKCL (CKTcircuit *, int, double **) ;
|
||||||
|
#endif
|
||||||
|
|
||||||
extern int ACan(CKTcircuit *, int);
|
extern int ACan(CKTcircuit *, int);
|
||||||
extern int ACaskQuest(CKTcircuit *, JOB *, int , IFvalue *);
|
extern int ACaskQuest(CKTcircuit *, JOB *, int , IFvalue *);
|
||||||
|
|
@ -321,7 +338,7 @@ extern void NDEVacct(CKTcircuit *ckt, FILE *file);
|
||||||
extern void CKTncDump(CKTcircuit *);
|
extern void CKTncDump(CKTcircuit *);
|
||||||
extern int CKTfndAnal(CKTcircuit *, int *, JOB **, IFuid , TSKtask *, IFuid);
|
extern int CKTfndAnal(CKTcircuit *, int *, JOB **, IFuid , TSKtask *, IFuid);
|
||||||
extern int CKTfndBranch(CKTcircuit *, IFuid);
|
extern int CKTfndBranch(CKTcircuit *, IFuid);
|
||||||
extern int CKTfndDev(CKTcircuit *, int *, GENinstance **, IFuid , GENmodel *, IFuid);
|
extern int CKTfndDev(CKTcircuit *, int *, GENinstance **, IFuid , GENmodel *);
|
||||||
extern int CKTfndMod(CKTcircuit *, int *, GENmodel **, IFuid);
|
extern int CKTfndMod(CKTcircuit *, int *, GENmodel **, IFuid);
|
||||||
extern int CKTfndNode(CKTcircuit *, CKTnode **, IFuid);
|
extern int CKTfndNode(CKTcircuit *, CKTnode **, IFuid);
|
||||||
extern int CKTfndTask(CKTcircuit *, TSKtask **, IFuid );
|
extern int CKTfndTask(CKTcircuit *, TSKtask **, IFuid );
|
||||||
|
|
@ -387,10 +404,14 @@ extern int PZinit(CKTcircuit *);
|
||||||
extern int PZpost(CKTcircuit *);
|
extern int PZpost(CKTcircuit *);
|
||||||
extern int PZaskQuest(CKTcircuit *, JOB *, int , IFvalue *);
|
extern int PZaskQuest(CKTcircuit *, JOB *, int , IFvalue *);
|
||||||
extern int PZsetParm(CKTcircuit *, JOB *, int , IFvalue *);
|
extern int PZsetParm(CKTcircuit *, JOB *, int , IFvalue *);
|
||||||
|
|
||||||
|
#ifdef WANT_SENSE2
|
||||||
extern int SENaskQuest(CKTcircuit *, JOB *, int , IFvalue *);
|
extern int SENaskQuest(CKTcircuit *, JOB *, int , IFvalue *);
|
||||||
extern void SENdestroy(SENstruct *);
|
extern void SENdestroy(SENstruct *);
|
||||||
extern int SENsetParm(CKTcircuit *, JOB *, int , IFvalue *);
|
extern int SENsetParm(CKTcircuit *, JOB *, int , IFvalue *);
|
||||||
extern int SENstartup(CKTcircuit *);
|
extern int SENstartup(CKTcircuit *, int);
|
||||||
|
#endif
|
||||||
|
|
||||||
extern int SPIinit(IFfrontEnd *, IFsimulator **);
|
extern int SPIinit(IFfrontEnd *, IFsimulator **);
|
||||||
extern int TFanal(CKTcircuit *, int);
|
extern int TFanal(CKTcircuit *, int);
|
||||||
extern int TFaskQuest(CKTcircuit *, JOB *, int , IFvalue *);
|
extern int TFaskQuest(CKTcircuit *, JOB *, int , IFvalue *);
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,7 @@
|
||||||
/* Alternate initialisation file name */
|
/* Alternate initialisation file name */
|
||||||
#define ALT_INITSTR "spice.rc"
|
#define ALT_INITSTR "spice.rc"
|
||||||
|
|
||||||
#if defined(__MINGW32__) || defined(_MSC_VER)
|
#if defined(__MINGW32__) || defined(_MSC_VER) || defined (HAS_WINGUI)
|
||||||
#define DIR_PATHSEP "\\"
|
#define DIR_PATHSEP "\\"
|
||||||
#define DIR_TERM '\\'
|
#define DIR_TERM '\\'
|
||||||
#define DIR_PATHSEP_LINUX "/"
|
#define DIR_PATHSEP_LINUX "/"
|
||||||
|
|
|
||||||
|
|
@ -29,9 +29,20 @@ double limitVbe( double, double, int * );
|
||||||
double limitVce( double, double, int * );
|
double limitVce( double, double, int * );
|
||||||
double limitVgb( double, double, int * );
|
double limitVgb( double, double, int * );
|
||||||
|
|
||||||
|
/* Area Calculation Method (ACM) for MOS models (devsup.c) */
|
||||||
|
int
|
||||||
|
ACM_SourceDrainResistances(int, double, double, double, double, double,
|
||||||
|
double, double, int, double, double, double,
|
||||||
|
int, double, double, double, double *, double *);
|
||||||
|
int
|
||||||
|
ACM_saturationCurrents(int, int, int, double, double, double, double, double,
|
||||||
|
double, int, double, int, double, int, double, int,
|
||||||
|
double, double *, double *);
|
||||||
|
int
|
||||||
|
ACM_junctionCapacitances(int, int, int, double, double, double, double, int,
|
||||||
|
double, int, double, int, double, int, double,
|
||||||
|
double, double, double, double *, double *,
|
||||||
|
double *, double *, double *, double *);
|
||||||
|
|
||||||
typedef struct SPICEdev {
|
typedef struct SPICEdev {
|
||||||
IFdevice DEVpublic;
|
IFdevice DEVpublic;
|
||||||
|
|
@ -110,6 +121,12 @@ typedef struct SPICEdev {
|
||||||
/* routine to convert Complex CSC array to Real CSC array */
|
/* routine to convert Complex CSC array to Real CSC array */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef KIRCHHOFF
|
||||||
|
/* Francesco Lannutti */
|
||||||
|
int (*DEVnodeIsNonLinear)(GENmodel *, CKTcircuit *) ;
|
||||||
|
/* Routine to declare a node as NonLinear */
|
||||||
|
#endif
|
||||||
|
|
||||||
} SPICEdev; /* instance of structure for each possible type of device */
|
} SPICEdev; /* instance of structure for each possible type of device */
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -370,7 +370,7 @@ struct IFsimulator {
|
||||||
/* set a parameter on an instance */
|
/* set a parameter on an instance */
|
||||||
int (*askInstanceQuest) (CKTcircuit *, GENinstance *, int, IFvalue *, IFvalue *);
|
int (*askInstanceQuest) (CKTcircuit *, GENinstance *, int, IFvalue *, IFvalue *);
|
||||||
/* ask a question about an instance */
|
/* ask a question about an instance */
|
||||||
int (*findInstance) (CKTcircuit *, int *, GENinstance **, IFuid, GENmodel *, IFuid);
|
int (*findInstance) (CKTcircuit *, int *, GENinstance **, IFuid, GENmodel *);
|
||||||
/* find a specific instance */
|
/* find a specific instance */
|
||||||
int (*deleteInstance) (CKTcircuit *, void *);
|
int (*deleteInstance) (CKTcircuit *, void *);
|
||||||
/* delete an instance from the circuit */
|
/* delete an instance from the circuit */
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
/**********
|
/**********
|
||||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||||
**********/
|
**********/
|
||||||
|
|
||||||
/* a couple of macros to make much of the input code
|
/* a couple of macros to make much of the input code
|
||||||
* much much shorter and easier to handle.
|
* much much shorter and easier to handle.
|
||||||
*
|
*
|
||||||
|
|
@ -9,25 +10,42 @@ Copyright 1990 Regents of the University of California. All rights reserved.
|
||||||
* If necessary, get the proper error message and tack it on the current
|
* If necessary, get the proper error message and tack it on the current
|
||||||
* error
|
* error
|
||||||
*/
|
*/
|
||||||
#define IFC(func,args)\
|
|
||||||
error=(*(ft_sim->func))args;\
|
#define IFC(func, args) \
|
||||||
if(error)current->error = INPerrCat(current->error,INPerror(error));
|
do { \
|
||||||
|
error = (*(ft_sim->func)) args; \
|
||||||
|
if (error) \
|
||||||
|
current->error = INPerrCat(current->error, INPerror(error)); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
/* and one for calling more General functions that still return an
|
/* and one for calling more General functions that still return an
|
||||||
* error code as above
|
* error code as above
|
||||||
*/
|
*/
|
||||||
#define GCA(func,args)\
|
|
||||||
error=func args;\
|
#define GCA(func, args) \
|
||||||
if(error)current->error = INPerrCat(current->error,INPerror(error));
|
do { \
|
||||||
|
error = func args; \
|
||||||
|
if (error) \
|
||||||
|
current->error = INPerrCat(current->error, INPerror(error)); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
/* and one for putting our own error messages onto the current
|
/* and one for putting our own error messages onto the current
|
||||||
* line's error string
|
* line's error string
|
||||||
*/
|
*/
|
||||||
#define LITERR(text) current->error=INPerrCat(current->error,INPmkTemp(text));
|
|
||||||
|
#define LITERR(text) \
|
||||||
|
do { \
|
||||||
|
current->error = INPerrCat(current->error, INPmkTemp(text)); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
/* and now a special one for calling INPdevParse which returns an
|
/* and now a special one for calling INPdevParse which returns an
|
||||||
* already concatenated list of error messages or NUL
|
* already concatenated list of error messages or NUL
|
||||||
*/
|
*/
|
||||||
#define PARSECALL(args)\
|
|
||||||
current->error = INPerrCat(current->error,INPdevParse args );
|
#define PARSECALL(args) \
|
||||||
|
do { \
|
||||||
|
current->error = INPerrCat(current->error, INPdevParse args); \
|
||||||
|
} while(0)
|
||||||
|
|
|
||||||
|
|
@ -123,10 +123,11 @@ void INPptPrint(char *str, IFparseTree * ptree);
|
||||||
#define PTF_GE0 28
|
#define PTF_GE0 28
|
||||||
#define PTF_LE0 29
|
#define PTF_LE0 29
|
||||||
#define PTF_POW 30
|
#define PTF_POW 30
|
||||||
#define PTF_MIN 31
|
#define PTF_PWR 31
|
||||||
#define PTF_MAX 32
|
#define PTF_MIN 32
|
||||||
#define PTF_CEIL 33
|
#define PTF_MAX 33
|
||||||
#define PTF_FLOOR 34
|
#define PTF_CEIL 34
|
||||||
|
#define PTF_FLOOR 35
|
||||||
|
|
||||||
/* The following things are used by the parser -- these are the token types the
|
/* The following things are used by the parser -- these are the token types the
|
||||||
* lexer returns.
|
* lexer returns.
|
||||||
|
|
|
||||||
|
|
@ -43,11 +43,12 @@
|
||||||
#define NIL(type) ((type *)0)
|
#define NIL(type) ((type *)0)
|
||||||
#define ABORT() fflush(stderr);fflush(stdout);abort();
|
#define ABORT() fflush(stderr);fflush(stdout);abort();
|
||||||
|
|
||||||
#define MERROR(CODE,MESSAGE) { \
|
#define MERROR(CODE, MESSAGE) \
|
||||||
errMsg = TMALLOC(char, strlen(MESSAGE) + 1); \
|
do { \
|
||||||
strcpy(errMsg, (MESSAGE)); \
|
errMsg = TMALLOC(char, strlen(MESSAGE) + 1); \
|
||||||
return (CODE); \
|
strcpy(errMsg, (MESSAGE)); \
|
||||||
}
|
return (CODE); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
#define NEW(TYPE) (TMALLOC(TYPE, 1))
|
#define NEW(TYPE) (TMALLOC(TYPE, 1))
|
||||||
#define NEWN(TYPE,COUNT) (TMALLOC(TYPE, COUNT))
|
#define NEWN(TYPE,COUNT) (TMALLOC(TYPE, COUNT))
|
||||||
|
|
|
||||||
|
|
@ -112,7 +112,9 @@ struct ngcomplex {
|
||||||
typedef struct ngcomplex ngcomplex_t;
|
typedef struct ngcomplex ngcomplex_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* vector info obtained from any vector in ngspice.dll */
|
/* vector info obtained from any vector in ngspice.dll.
|
||||||
|
Allows direct access to the ngspice internal vector structure,
|
||||||
|
as defined in include/ngspice/devc.h .*/
|
||||||
typedef struct vector_info {
|
typedef struct vector_info {
|
||||||
char *v_name; /* Same as so_vname. */
|
char *v_name; /* Same as so_vname. */
|
||||||
int v_type; /* Same as so_vtype. */
|
int v_type; /* Same as so_vtype. */
|
||||||
|
|
@ -123,16 +125,17 @@ typedef struct vector_info {
|
||||||
} vector_info, *pvector_info;
|
} vector_info, *pvector_info;
|
||||||
|
|
||||||
typedef struct vecvalues {
|
typedef struct vecvalues {
|
||||||
char* name;
|
char* name; /* name of a specific vector */
|
||||||
double creal;
|
double creal; /* actual data value */
|
||||||
double cimag;
|
double cimag; /* actual data value */
|
||||||
bool is_scale;
|
bool is_scale;/* if 'name' is the scale vector */
|
||||||
bool is_complex;
|
bool is_complex;/* if the data are complex numbers */
|
||||||
} vecvalues, *pvecvalues;
|
} vecvalues, *pvecvalues;
|
||||||
|
|
||||||
typedef struct vecvaluesall {
|
typedef struct vecvaluesall {
|
||||||
int veccount;
|
int veccount; /* number of vectors in plot */
|
||||||
pvecvalues *vecsa;
|
int vecindex; /* index of actual set of vectors. i.e. the number of accepted data points */
|
||||||
|
pvecvalues *vecsa; /* values of actual set of vectors, indexed from 0 to veccount - 1 */
|
||||||
} vecvaluesall, *pvecvaluesall;
|
} vecvaluesall, *pvecvaluesall;
|
||||||
|
|
||||||
/* info for a specific vector */
|
/* info for a specific vector */
|
||||||
|
|
@ -206,6 +209,18 @@ typedef int (BGThreadRunning)(bool, void*);
|
||||||
void* return pointer received from caller
|
void* return pointer received from caller
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* callback functions
|
||||||
|
addresses received from caller with ngSpice_Init_Sync() function
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* ask for VSRC EXTERNAL value */
|
||||||
|
typedef int (GetVSRCData)(double*, double, char*, void*);
|
||||||
|
/*
|
||||||
|
double* return voltage value
|
||||||
|
double actual time
|
||||||
|
char* node name
|
||||||
|
void* return pointer received from caller
|
||||||
|
*/
|
||||||
|
|
||||||
/* ngspice initialization,
|
/* ngspice initialization,
|
||||||
printfcn: pointer to callback function for reading printf, fprintf
|
printfcn: pointer to callback function for reading printf, fprintf
|
||||||
|
|
@ -220,6 +235,12 @@ IMPEXP
|
||||||
int ngSpice_Init(SendChar* printfcn, SendStat* statfcn, ControlledExit* ngexit,
|
int ngSpice_Init(SendChar* printfcn, SendStat* statfcn, ControlledExit* ngexit,
|
||||||
SendData* sdata, SendInitData* sinitdata, BGThreadRunning* bgtrun, void* userData);
|
SendData* sdata, SendInitData* sinitdata, BGThreadRunning* bgtrun, void* userData);
|
||||||
|
|
||||||
|
/* initialization of synchronizing functions
|
||||||
|
vsrcdat: pointer to callback function for retrieving a voltage source value
|
||||||
|
ident: pointer to integer unique to this shared library (defaults to 0)
|
||||||
|
*/
|
||||||
|
IMPEXP
|
||||||
|
int ngSpice_Init_Sync(GetVSRCData* vsrcdat, int* ident, void* userData);
|
||||||
|
|
||||||
/* Caller may send ngspice commands to ngspice.dll.
|
/* Caller may send ngspice commands to ngspice.dll.
|
||||||
Commands are executed immediately */
|
Commands are executed immediately */
|
||||||
|
|
@ -260,6 +281,10 @@ char** ngSpice_AllVecs(char* plotname);
|
||||||
IMPEXP
|
IMPEXP
|
||||||
bool ngSpice_running(void);
|
bool ngSpice_running(void);
|
||||||
|
|
||||||
|
/* set a breakpoint in ngspice */
|
||||||
|
IMPEXP
|
||||||
|
bool ngSpice_SetBkpt(double time);
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -122,8 +122,8 @@ void SMPgetError( SMPmatrix *, int *, int *);
|
||||||
int SMPcProdDiag( SMPmatrix *, SPcomplex *, int *);
|
int SMPcProdDiag( SMPmatrix *, SPcomplex *, int *);
|
||||||
int SMPcDProd(SMPmatrix *Matrix, SPcomplex *pMantissa, int *pExponent);
|
int SMPcDProd(SMPmatrix *Matrix, SPcomplex *pMantissa, int *pExponent);
|
||||||
SMPelement * SMPfindElt( SMPmatrix *, int , int , int );
|
SMPelement * SMPfindElt( SMPmatrix *, int , int , int );
|
||||||
int SMPcZeroCol(SMPmatrix *eMatrix, int Col);
|
int SMPcZeroCol(SMPmatrix *Matrix, int Col);
|
||||||
int SMPcAddCol(SMPmatrix *eMatrix, int Accum_Col, int Addend_Col);
|
int SMPcAddCol(SMPmatrix *Matrix, int Accum_Col, int Addend_Col);
|
||||||
int SMPzeroRow(SMPmatrix *eMatrix, int Row);
|
int SMPzeroRow(SMPmatrix *Matrix, int Row);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -263,7 +263,7 @@ extern int spFileMatrix( MatrixPtr, char *, char *, int, int, int );
|
||||||
extern int spFileStats( MatrixPtr, char *, char * );
|
extern int spFileStats( MatrixPtr, char *, char * );
|
||||||
extern int spFillinCount( MatrixPtr );
|
extern int spFillinCount( MatrixPtr );
|
||||||
extern int spGetAdmittance( MatrixPtr, int, int, struct spTemplate* );
|
extern int spGetAdmittance( MatrixPtr, int, int, struct spTemplate* );
|
||||||
extern spREAL *spFindElement(MatrixPtr eMatrix, int Row, int Col );
|
extern spREAL *spFindElement(MatrixPtr Matrix, int Row, int Col );
|
||||||
extern spREAL *spGetElement(MatrixPtr, int, int );
|
extern spREAL *spGetElement(MatrixPtr, int, int );
|
||||||
extern void *spGetInitInfo( spREAL* );
|
extern void *spGetInitInfo( spREAL* );
|
||||||
extern int spGetOnes( MatrixPtr, int, int, int, struct spTemplate* );
|
extern int spGetOnes( MatrixPtr, int, int, int, struct spTemplate* );
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,11 @@ bool AlmostEqualUlps(double A, double B, int maxUlps)
|
||||||
{
|
{
|
||||||
int64_t aInt, bInt, intDiff;
|
int64_t aInt, bInt, intDiff;
|
||||||
|
|
||||||
|
union {
|
||||||
|
double d;
|
||||||
|
int64_t i;
|
||||||
|
} uA, uB;
|
||||||
|
|
||||||
if (A == B)
|
if (A == B)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
|
@ -34,12 +39,14 @@ bool AlmostEqualUlps(double A, double B, int maxUlps)
|
||||||
/* default NAN won't compare as equal to anything. */
|
/* default NAN won't compare as equal to anything. */
|
||||||
assert(maxUlps > 0 && maxUlps < 4 * 1024 * 1024);
|
assert(maxUlps > 0 && maxUlps < 4 * 1024 * 1024);
|
||||||
|
|
||||||
aInt = *(int64_t*)&A;
|
uA.d = A;
|
||||||
|
aInt = uA.i;
|
||||||
/* Make aInt lexicographically ordered as a twos-complement int */
|
/* Make aInt lexicographically ordered as a twos-complement int */
|
||||||
if (aInt < 0)
|
if (aInt < 0)
|
||||||
aInt = int64_min - aInt;
|
aInt = int64_min - aInt;
|
||||||
|
|
||||||
bInt = *(int64_t*)&B;
|
uB.d = B;
|
||||||
|
bInt = uB.i;
|
||||||
/* Make bInt lexicographically ordered as a twos-complement int */
|
/* Make bInt lexicographically ordered as a twos-complement int */
|
||||||
if (bInt < 0)
|
if (bInt < 0)
|
||||||
bInt = int64_min - bInt;
|
bInt = int64_min - bInt;
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,9 @@ Author: 1985 Thomas L. Quarles
|
||||||
#include "ngspice/cktdefs.h"
|
#include "ngspice/cktdefs.h"
|
||||||
#include "ngspice/sperror.h"
|
#include "ngspice/sperror.h"
|
||||||
|
|
||||||
|
/* xmu=0: Backward Euler, xmu=0.5: trapezoidal (standard),
|
||||||
|
xmu=0.48: good damping of current ringing, e.g. in R.O.s. */
|
||||||
|
#define xmu 0.5
|
||||||
|
|
||||||
int
|
int
|
||||||
NIcomCof(CKTcircuit *ckt)
|
NIcomCof(CKTcircuit *ckt)
|
||||||
|
|
@ -17,6 +20,7 @@ NIcomCof(CKTcircuit *ckt)
|
||||||
double arg;
|
double arg;
|
||||||
double arg1;
|
double arg1;
|
||||||
|
|
||||||
|
|
||||||
/* this routine calculates the timestep-dependent terms used in the
|
/* this routine calculates the timestep-dependent terms used in the
|
||||||
* numerical integration.
|
* numerical integration.
|
||||||
*/
|
*/
|
||||||
|
|
@ -35,10 +39,8 @@ NIcomCof(CKTcircuit *ckt)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
ckt->CKTag[0]=1.0/ckt->CKTdelta/(1.0-0.5) ;
|
ckt->CKTag[0] = 1.0 / ckt->CKTdelta/(1.0 - xmu) ;
|
||||||
ckt->CKTag[1]=0.5/(1.0 - 0.5) ;
|
ckt->CKTag[1] = xmu / (1.0 - xmu) ;
|
||||||
/* above lines should have 'xmu' instead of .5 eventually */
|
|
||||||
/* (in all three places) */
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
||||||
|
|
@ -15,62 +15,124 @@ Author: 1985 Thomas L. Quarles
|
||||||
#include "ngspice/smpdefs.h"
|
#include "ngspice/smpdefs.h"
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
NIconvTest(CKTcircuit *ckt)
|
|
||||||
{
|
|
||||||
int i; /* generic loop variable */
|
|
||||||
int size; /* size of the matrix */
|
|
||||||
CKTnode *node; /* current matrix entry */
|
|
||||||
double old;
|
|
||||||
double new;
|
|
||||||
double tol;
|
|
||||||
|
|
||||||
node = ckt->CKTnodes;
|
int
|
||||||
size = SMPmatSize(ckt->CKTmatrix);
|
NIconvTest (CKTcircuit *ckt)
|
||||||
|
{
|
||||||
|
int i ; /* generic loop variable */
|
||||||
|
int size ; /* size of the matrix */
|
||||||
|
CKTnode *node ; /* current matrix entry */
|
||||||
|
|
||||||
|
#ifdef KIRCHHOFF
|
||||||
|
double maximum ;
|
||||||
|
CKTmkCurKCLnode *ptr ;
|
||||||
|
|
||||||
#ifdef STEPDEBUG
|
#ifdef STEPDEBUG
|
||||||
for (i=1;i<=size;i++) {
|
int j ;
|
||||||
new = ckt->CKTrhs [i] ;
|
#endif
|
||||||
old = ckt->CKTrhsOld [i] ;
|
#else
|
||||||
printf("chk for convergence: %s new: %g old: %g\n",CKTnodName(ckt,i),new,old);
|
double old, new, tol ;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
size = SMPmatSize (ckt->CKTmatrix) ;
|
||||||
|
node = ckt->CKTnodes ;
|
||||||
|
|
||||||
|
#ifndef KIRCHHOFF
|
||||||
|
#ifdef STEPDEBUG
|
||||||
|
for (i = 1 ; i <= size ; i++)
|
||||||
|
{
|
||||||
|
new = ckt->CKTrhs [i] ;
|
||||||
|
old = ckt->CKTrhsOld [i] ;
|
||||||
|
fprintf (err, "chk for convergence: %s new: %g old: %g\n", CKTnodName (ckt, i), new, old) ;
|
||||||
}
|
}
|
||||||
#endif /* STEPDEBUG */
|
#endif /* STEPDEBUG */
|
||||||
for (i=1;i<=size;i++) {
|
#endif
|
||||||
node = node->next;
|
|
||||||
new = ckt->CKTrhs [i] ;
|
for (i = 1 ; i <= size ; i++)
|
||||||
old = ckt->CKTrhsOld [i] ;
|
{
|
||||||
if(node->type == SP_VOLTAGE) {
|
node = node->next ;
|
||||||
tol = ckt->CKTreltol * (MAX(fabs(old),fabs(new))) +
|
|
||||||
ckt->CKTvoltTol;
|
#ifdef KIRCHHOFF
|
||||||
if (fabs(new-old) >tol ) {
|
/* KCL Verification */
|
||||||
|
if ((node->type == SP_VOLTAGE) && (!ckt->CKTnodeIsLinear [i]))
|
||||||
|
{
|
||||||
|
maximum = 0 ;
|
||||||
|
ptr = ckt->CKTmkCurKCLarray [i] ;
|
||||||
|
|
||||||
#ifdef STEPDEBUG
|
#ifdef STEPDEBUG
|
||||||
printf(" non-convergence at node (type=3) %s (fabs(new-old)>tol --> fabs(%g-%g)>%g)\n",CKTnodName(ckt,i),new,old,tol);
|
j = 0 ;
|
||||||
printf(" reltol: %g voltTol: %g (tol=reltol*(MAX(fabs(old),fabs(new))) + voltTol)\n",ckt->CKTreltol,ckt->CKTvoltTol);
|
#endif
|
||||||
|
|
||||||
|
while (ptr != NULL)
|
||||||
|
{
|
||||||
|
if (maximum < fabs (ptr->KCLcurrent))
|
||||||
|
maximum = fabs (ptr->KCLcurrent) ;
|
||||||
|
|
||||||
|
#ifdef STEPDEBUG
|
||||||
|
fprintf (stderr, "Index KCL Array: %d\tValue: %-.9g\tMaximum: %-.9g\n", j, fabs (ptr->KCLcurrent), maximum) ;
|
||||||
|
j++ ;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ptr = ptr->next ;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef STEPDEBUG
|
||||||
|
fprintf (stderr, "Index: %d\tValue: %-.9g\tThreshold: %-.9g\tMaximum: %-.9g\n", i, fabs (ckt->CKTfvk [i]),
|
||||||
|
ckt->CKTreltol * maximum + ckt->CKTabstol, maximum) ;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Check Convergence */
|
||||||
|
if (fabs (ckt->CKTfvk [i]) > (ckt->CKTreltol * maximum + ckt->CKTabstol))
|
||||||
|
return 1 ;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
new = ckt->CKTrhs [i] ;
|
||||||
|
old = ckt->CKTrhsOld [i] ;
|
||||||
|
if (node->type == SP_VOLTAGE)
|
||||||
|
{
|
||||||
|
tol = ckt->CKTreltol * (MAX (fabs (old), fabs (new))) + ckt->CKTvoltTol ;
|
||||||
|
if (fabs (new - old) > tol)
|
||||||
|
{
|
||||||
|
|
||||||
|
#ifdef STEPDEBUG
|
||||||
|
fprintf (err, " non-convergence at node (type=3) %s (fabs(new-old)>tol --> fabs(%g-%g)>%g)\n", CKTnodName (ckt, i), new, old, tol) ;
|
||||||
|
fprintf (err, " reltol: %g voltTol: %g (tol=reltol*(MAX(fabs(old),fabs(new))) + voltTol)\n", ckt->CKTreltol, ckt->CKTvoltTol) ;
|
||||||
#endif /* STEPDEBUG */
|
#endif /* STEPDEBUG */
|
||||||
ckt->CKTtroubleNode = i;
|
|
||||||
ckt->CKTtroubleElt = NULL;
|
ckt->CKTtroubleNode = i ;
|
||||||
return(1);
|
ckt->CKTtroubleElt = NULL ;
|
||||||
|
return 1 ;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
tol = ckt->CKTreltol * (MAX(fabs(old),fabs(new))) +
|
tol = ckt->CKTreltol * (MAX (fabs (old), fabs (new))) + ckt->CKTabstol ;
|
||||||
ckt->CKTabstol;
|
if (fabs (new - old) > tol)
|
||||||
if (fabs(new-old) >tol ) {
|
{
|
||||||
|
|
||||||
#ifdef STEPDEBUG
|
#ifdef STEPDEBUG
|
||||||
printf(" non-convergence at node (type=%d) %s (fabs(new-old)>tol --> fabs(%g-%g)>%g)\n",node->type,CKTnodName(ckt,i),new,old,tol);
|
fprintf (err, " non-convergence at node (type=%d) %s (fabs(new-old)>tol --> fabs(%g-%g)>%g)\n", node->type,
|
||||||
printf(" reltol: %g abstol: %g (tol=reltol*(MAX(fabs(old),fabs(new))) + abstol)\n",ckt->CKTreltol,ckt->CKTabstol);
|
CKTnodName (ckt, i), new, old, tol) ;
|
||||||
|
fprintf (err, " reltol: %g abstol: %g (tol=reltol*(MAX(fabs(old),fabs(new))) + abstol)\n", ckt->CKTreltol, ckt->CKTabstol) ;
|
||||||
#endif /* STEPDEBUG */
|
#endif /* STEPDEBUG */
|
||||||
ckt->CKTtroubleNode = i;
|
|
||||||
ckt->CKTtroubleElt = NULL;
|
ckt->CKTtroubleNode = i ;
|
||||||
return(1);
|
ckt->CKTtroubleElt = NULL ;
|
||||||
|
return 1 ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef KIRCHHOFF
|
||||||
|
return 0 ;
|
||||||
|
#else
|
||||||
#ifdef NEWCONV
|
#ifdef NEWCONV
|
||||||
i = CKTconvTest(ckt);
|
i = CKTconvTest (ckt) ;
|
||||||
if (i)
|
if (i)
|
||||||
ckt->CKTtroubleNode = 0;
|
ckt->CKTtroubleNode = 0 ;
|
||||||
return(i);
|
return i ;
|
||||||
#else /* NEWCONV */
|
#else /* NEWCONV */
|
||||||
return(0);
|
return 0 ;
|
||||||
#endif /* NEWCONV */
|
#endif /* NEWCONV */
|
||||||
|
#endif /* KIRCHHOFF */
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,8 @@ int
|
||||||
NIreinit( CKTcircuit *ckt)
|
NIreinit( CKTcircuit *ckt)
|
||||||
{
|
{
|
||||||
int size;
|
int size;
|
||||||
#ifdef PREDICTOR
|
|
||||||
|
#if defined(PREDICTOR) || defined(KIRCHHOFF)
|
||||||
int i;
|
int i;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -33,6 +34,17 @@ NIreinit( CKTcircuit *ckt)
|
||||||
CKALLOC(CKTirhs,size+1,double);
|
CKALLOC(CKTirhs,size+1,double);
|
||||||
CKALLOC(CKTirhsOld,size+1,double);
|
CKALLOC(CKTirhsOld,size+1,double);
|
||||||
CKALLOC(CKTirhsSpare,size+1,double);
|
CKALLOC(CKTirhsSpare,size+1,double);
|
||||||
|
|
||||||
|
#ifdef KIRCHHOFF
|
||||||
|
CKALLOC(CKTfvk,size+1,double);
|
||||||
|
CKALLOC(CKTnodeIsLinear,size+1,int);
|
||||||
|
for (i = 0 ; i <= size ; i++)
|
||||||
|
ckt->CKTnodeIsLinear [i] = 1 ;
|
||||||
|
CKALLOC(CKTmkCurKCLarray,size+1,CKTmkCurKCLnode*);
|
||||||
|
for (i = 0 ; i <= size ; i++)
|
||||||
|
ckt->CKTmkCurKCLarray [i] = NULL ;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef PREDICTOR
|
#ifdef PREDICTOR
|
||||||
CKALLOC(CKTpred,size+1,double);
|
CKALLOC(CKTpred,size+1,double);
|
||||||
for( i=0;i<8;i++) {
|
for( i=0;i<8;i++) {
|
||||||
|
|
|
||||||
|
|
@ -190,7 +190,7 @@ spCreate(int Size, int Complex, int *pError)
|
||||||
Matrix->ElementsRemaining = 0;
|
Matrix->ElementsRemaining = 0;
|
||||||
Matrix->FillinsRemaining = 0;
|
Matrix->FillinsRemaining = 0;
|
||||||
|
|
||||||
RecordAllocation( Matrix, (void *)Matrix );
|
RecordAllocation( Matrix, Matrix );
|
||||||
if (Matrix->Error == spNO_MEMORY) goto MemoryError;
|
if (Matrix->Error == spNO_MEMORY) goto MemoryError;
|
||||||
|
|
||||||
/* Take out the trash. */
|
/* Take out the trash. */
|
||||||
|
|
@ -311,7 +311,7 @@ spcGetElement(MatrixPtr Matrix)
|
||||||
/* Allocate block of MatrixElements if necessary. */
|
/* Allocate block of MatrixElements if necessary. */
|
||||||
if (Matrix->ElementsRemaining == 0) {
|
if (Matrix->ElementsRemaining == 0) {
|
||||||
pElements = SP_MALLOC(struct MatrixElement, ELEMENTS_PER_ALLOCATION);
|
pElements = SP_MALLOC(struct MatrixElement, ELEMENTS_PER_ALLOCATION);
|
||||||
RecordAllocation( Matrix, (void *)pElements );
|
RecordAllocation( Matrix, pElements );
|
||||||
if (Matrix->Error == spNO_MEMORY) return NULL;
|
if (Matrix->Error == spNO_MEMORY) return NULL;
|
||||||
Matrix->ElementsRemaining = ELEMENTS_PER_ALLOCATION;
|
Matrix->ElementsRemaining = ELEMENTS_PER_ALLOCATION;
|
||||||
Matrix->NextAvailElement = pElements;
|
Matrix->NextAvailElement = pElements;
|
||||||
|
|
@ -331,14 +331,14 @@ spcGetElement(MatrixPtr Matrix)
|
||||||
} else {
|
} else {
|
||||||
/* Allocate block of elements. */
|
/* Allocate block of elements. */
|
||||||
pElements = SP_MALLOC(struct MatrixElement, ELEMENTS_PER_ALLOCATION);
|
pElements = SP_MALLOC(struct MatrixElement, ELEMENTS_PER_ALLOCATION);
|
||||||
RecordAllocation( Matrix, (void *)pElements );
|
RecordAllocation( Matrix, pElements );
|
||||||
if (Matrix->Error == spNO_MEMORY) return NULL;
|
if (Matrix->Error == spNO_MEMORY) return NULL;
|
||||||
Matrix->ElementsRemaining = ELEMENTS_PER_ALLOCATION;
|
Matrix->ElementsRemaining = ELEMENTS_PER_ALLOCATION;
|
||||||
Matrix->NextAvailElement = pElements;
|
Matrix->NextAvailElement = pElements;
|
||||||
|
|
||||||
/* Allocate an element list structure. */
|
/* Allocate an element list structure. */
|
||||||
pListNode->Next = SP_MALLOC(struct ElementListNodeStruct,1);
|
pListNode->Next = SP_MALLOC(struct ElementListNodeStruct,1);
|
||||||
RecordAllocation( Matrix, (void *)pListNode->Next );
|
RecordAllocation( Matrix, pListNode->Next );
|
||||||
if (Matrix->Error == spNO_MEMORY)
|
if (Matrix->Error == spNO_MEMORY)
|
||||||
return NULL;
|
return NULL;
|
||||||
Matrix->LastElementListNode = pListNode = pListNode->Next;
|
Matrix->LastElementListNode = pListNode = pListNode->Next;
|
||||||
|
|
@ -402,14 +402,14 @@ InitializeElementBlocks(MatrixPtr Matrix, int InitialNumberOfElements,
|
||||||
|
|
||||||
/* Allocate block of MatrixElements for elements. */
|
/* Allocate block of MatrixElements for elements. */
|
||||||
pElement = SP_MALLOC(struct MatrixElement, InitialNumberOfElements);
|
pElement = SP_MALLOC(struct MatrixElement, InitialNumberOfElements);
|
||||||
RecordAllocation( Matrix, (void *)pElement );
|
RecordAllocation( Matrix, pElement );
|
||||||
if (Matrix->Error == spNO_MEMORY) return;
|
if (Matrix->Error == spNO_MEMORY) return;
|
||||||
Matrix->ElementsRemaining = InitialNumberOfElements;
|
Matrix->ElementsRemaining = InitialNumberOfElements;
|
||||||
Matrix->NextAvailElement = pElement;
|
Matrix->NextAvailElement = pElement;
|
||||||
|
|
||||||
/* Allocate an element list structure. */
|
/* Allocate an element list structure. */
|
||||||
Matrix->FirstElementListNode = SP_MALLOC(struct ElementListNodeStruct,1);
|
Matrix->FirstElementListNode = SP_MALLOC(struct ElementListNodeStruct,1);
|
||||||
RecordAllocation( Matrix, (void *)Matrix->FirstElementListNode );
|
RecordAllocation( Matrix, Matrix->FirstElementListNode );
|
||||||
if (Matrix->Error == spNO_MEMORY) return;
|
if (Matrix->Error == spNO_MEMORY) return;
|
||||||
Matrix->LastElementListNode = Matrix->FirstElementListNode;
|
Matrix->LastElementListNode = Matrix->FirstElementListNode;
|
||||||
|
|
||||||
|
|
@ -420,14 +420,14 @@ InitializeElementBlocks(MatrixPtr Matrix, int InitialNumberOfElements,
|
||||||
|
|
||||||
/* Allocate block of MatrixElements for fill-ins. */
|
/* Allocate block of MatrixElements for fill-ins. */
|
||||||
pElement = SP_MALLOC(struct MatrixElement, NumberOfFillinsExpected);
|
pElement = SP_MALLOC(struct MatrixElement, NumberOfFillinsExpected);
|
||||||
RecordAllocation( Matrix, (void *)pElement );
|
RecordAllocation( Matrix, pElement );
|
||||||
if (Matrix->Error == spNO_MEMORY) return;
|
if (Matrix->Error == spNO_MEMORY) return;
|
||||||
Matrix->FillinsRemaining = NumberOfFillinsExpected;
|
Matrix->FillinsRemaining = NumberOfFillinsExpected;
|
||||||
Matrix->NextAvailFillin = pElement;
|
Matrix->NextAvailFillin = pElement;
|
||||||
|
|
||||||
/* Allocate a fill-in list structure. */
|
/* Allocate a fill-in list structure. */
|
||||||
Matrix->FirstFillinListNode = SP_MALLOC(struct FillinListNodeStruct,1);
|
Matrix->FirstFillinListNode = SP_MALLOC(struct FillinListNodeStruct,1);
|
||||||
RecordAllocation( Matrix, (void *)Matrix->FirstFillinListNode );
|
RecordAllocation( Matrix, Matrix->FirstFillinListNode );
|
||||||
if (Matrix->Error == spNO_MEMORY) return;
|
if (Matrix->Error == spNO_MEMORY) return;
|
||||||
Matrix->LastFillinListNode = Matrix->FirstFillinListNode;
|
Matrix->LastFillinListNode = Matrix->FirstFillinListNode;
|
||||||
|
|
||||||
|
|
@ -487,14 +487,14 @@ spcGetFillin(MatrixPtr Matrix)
|
||||||
} else {
|
} else {
|
||||||
/* Allocate block of fill-ins. */
|
/* Allocate block of fill-ins. */
|
||||||
pFillins = SP_MALLOC(struct MatrixElement, ELEMENTS_PER_ALLOCATION);
|
pFillins = SP_MALLOC(struct MatrixElement, ELEMENTS_PER_ALLOCATION);
|
||||||
RecordAllocation( Matrix, (void *)pFillins );
|
RecordAllocation( Matrix, pFillins );
|
||||||
if (Matrix->Error == spNO_MEMORY) return NULL;
|
if (Matrix->Error == spNO_MEMORY) return NULL;
|
||||||
Matrix->FillinsRemaining = ELEMENTS_PER_ALLOCATION;
|
Matrix->FillinsRemaining = ELEMENTS_PER_ALLOCATION;
|
||||||
Matrix->NextAvailFillin = pFillins;
|
Matrix->NextAvailFillin = pFillins;
|
||||||
|
|
||||||
/* Allocate a fill-in list structure. */
|
/* Allocate a fill-in list structure. */
|
||||||
pListNode->Next = SP_MALLOC(struct FillinListNodeStruct,1);
|
pListNode->Next = SP_MALLOC(struct FillinListNodeStruct,1);
|
||||||
RecordAllocation( Matrix, (void *)pListNode->Next );
|
RecordAllocation( Matrix, pListNode->Next );
|
||||||
if (Matrix->Error == spNO_MEMORY) return NULL;
|
if (Matrix->Error == spNO_MEMORY) return NULL;
|
||||||
Matrix->LastFillinListNode = pListNode = pListNode->Next;
|
Matrix->LastFillinListNode = pListNode = pListNode->Next;
|
||||||
|
|
||||||
|
|
@ -646,9 +646,8 @@ AllocateBlockOfAllocationList(MatrixPtr Matrix)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
spDestroy(MatrixPtr eMatrix)
|
spDestroy(MatrixPtr Matrix)
|
||||||
{
|
{
|
||||||
MatrixPtr Matrix = eMatrix;
|
|
||||||
AllocationListPtr ListPtr, NextListPtr;
|
AllocationListPtr ListPtr, NextListPtr;
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -701,16 +700,16 @@ spDestroy(MatrixPtr eMatrix)
|
||||||
* The error status of the given matrix.
|
* The error status of the given matrix.
|
||||||
*
|
*
|
||||||
* >>> Arguments:
|
* >>> Arguments:
|
||||||
* eMatrix <input> (void *)
|
* Matrix <input> (void *)
|
||||||
* The matrix for which the error status is desired. */
|
* The matrix for which the error status is desired. */
|
||||||
int
|
int
|
||||||
spError(MatrixPtr eMatrix )
|
spError(MatrixPtr Matrix )
|
||||||
{
|
{
|
||||||
/* Begin `spError'. */
|
/* Begin `spError'. */
|
||||||
|
|
||||||
if (eMatrix != NULL) {
|
if (Matrix != NULL) {
|
||||||
assert(eMatrix->ID == SPARSE_ID);
|
assert(Matrix->ID == SPARSE_ID);
|
||||||
return eMatrix->Error;
|
return Matrix->Error;
|
||||||
} else {
|
} else {
|
||||||
/* This error may actually be spPANIC, no way to tell. */
|
/* This error may actually be spPANIC, no way to tell. */
|
||||||
return spNO_MEMORY;
|
return spNO_MEMORY;
|
||||||
|
|
@ -732,7 +731,7 @@ spError(MatrixPtr eMatrix )
|
||||||
* detected as singular or where a zero was detected on the diagonal.
|
* detected as singular or where a zero was detected on the diagonal.
|
||||||
*
|
*
|
||||||
* >>> Arguments:
|
* >>> Arguments:
|
||||||
* eMatrix <input> (void *)
|
* Matrix <input> (void *)
|
||||||
* The matrix for which the error status is desired.
|
* The matrix for which the error status is desired.
|
||||||
* pRow <output> (int *)
|
* pRow <output> (int *)
|
||||||
* The row number.
|
* The row number.
|
||||||
|
|
@ -741,10 +740,8 @@ spError(MatrixPtr eMatrix )
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
spWhereSingular(MatrixPtr eMatrix, int *pRow, int *pCol)
|
spWhereSingular(MatrixPtr Matrix, int *pRow, int *pCol)
|
||||||
{
|
{
|
||||||
MatrixPtr Matrix = eMatrix;
|
|
||||||
|
|
||||||
/* Begin `spWhereSingular'. */
|
/* Begin `spWhereSingular'. */
|
||||||
assert( IS_SPARSE( Matrix ) );
|
assert( IS_SPARSE( Matrix ) );
|
||||||
|
|
||||||
|
|
@ -769,7 +766,7 @@ spWhereSingular(MatrixPtr eMatrix, int *pRow, int *pCol)
|
||||||
* the matrix is returned.
|
* the matrix is returned.
|
||||||
*
|
*
|
||||||
* >>> Arguments:
|
* >>> Arguments:
|
||||||
* eMatrix <input> (void *)
|
* Matrix <input> (void *)
|
||||||
* Pointer to matrix.
|
* Pointer to matrix.
|
||||||
* External <input> (int)
|
* External <input> (int)
|
||||||
* If External is set TRUE, the external size , i.e., the value of the
|
* If External is set TRUE, the external size , i.e., the value of the
|
||||||
|
|
@ -779,10 +776,8 @@ spWhereSingular(MatrixPtr eMatrix, int *pRow, int *pCol)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
spGetSize(MatrixPtr eMatrix, int External)
|
spGetSize(MatrixPtr Matrix, int External)
|
||||||
{
|
{
|
||||||
MatrixPtr Matrix = eMatrix;
|
|
||||||
|
|
||||||
/* Begin `spGetSize'. */
|
/* Begin `spGetSize'. */
|
||||||
assert( IS_SPARSE( Matrix ) );
|
assert( IS_SPARSE( Matrix ) );
|
||||||
|
|
||||||
|
|
@ -809,28 +804,28 @@ spGetSize(MatrixPtr eMatrix, int External)
|
||||||
* Forces matrix to be either real or complex.
|
* Forces matrix to be either real or complex.
|
||||||
*
|
*
|
||||||
* >>> Arguments:
|
* >>> Arguments:
|
||||||
* eMatrix <input> (void *)
|
* Matrix <input> (void *)
|
||||||
* Pointer to matrix.
|
* Pointer to matrix.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
spSetReal(MatrixPtr eMatrix)
|
spSetReal(MatrixPtr Matrix)
|
||||||
{
|
{
|
||||||
/* Begin `spSetReal'. */
|
/* Begin `spSetReal'. */
|
||||||
|
|
||||||
assert( IS_SPARSE( eMatrix ));
|
assert( IS_SPARSE( Matrix ));
|
||||||
eMatrix->Complex = NO;
|
Matrix->Complex = NO;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
spSetComplex(MatrixPtr eMatrix)
|
spSetComplex(MatrixPtr Matrix)
|
||||||
{
|
{
|
||||||
/* Begin `spSetComplex'. */
|
/* Begin `spSetComplex'. */
|
||||||
|
|
||||||
assert( IS_SPARSE( eMatrix ));
|
assert( IS_SPARSE( Matrix ));
|
||||||
eMatrix->Complex = YES;
|
Matrix->Complex = YES;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -850,34 +845,34 @@ spSetComplex(MatrixPtr eMatrix)
|
||||||
* of original elements can be returned.
|
* of original elements can be returned.
|
||||||
*
|
*
|
||||||
* >>> Arguments:
|
* >>> Arguments:
|
||||||
* eMatrix <input> (void *)
|
* Matrix <input> (void *)
|
||||||
* Pointer to matrix.
|
* Pointer to matrix.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
spFillinCount(MatrixPtr eMatrix)
|
spFillinCount(MatrixPtr Matrix)
|
||||||
{
|
{
|
||||||
/* Begin `spFillinCount'. */
|
/* Begin `spFillinCount'. */
|
||||||
|
|
||||||
assert( IS_SPARSE( eMatrix ) );
|
assert( IS_SPARSE( Matrix ) );
|
||||||
return eMatrix->Fillins;
|
return Matrix->Fillins;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
spElementCount(MatrixPtr eMatrix)
|
spElementCount(MatrixPtr Matrix)
|
||||||
{
|
{
|
||||||
/* Begin `spElementCount'. */
|
/* Begin `spElementCount'. */
|
||||||
|
|
||||||
assert( IS_SPARSE( eMatrix ) );
|
assert( IS_SPARSE( Matrix ) );
|
||||||
return eMatrix->Elements;
|
return Matrix->Elements;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
spOriginalCount(MatrixPtr eMatrix)
|
spOriginalCount(MatrixPtr Matrix)
|
||||||
{
|
{
|
||||||
/* Begin `spOriginalCount'. */
|
/* Begin `spOriginalCount'. */
|
||||||
|
|
||||||
assert( IS_SPARSE( eMatrix ) );
|
assert( IS_SPARSE( Matrix ) );
|
||||||
return eMatrix->Originals;
|
return Matrix->Originals;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -93,9 +93,8 @@ static void ExpandTranslationArrays( MatrixPtr, int );
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
spClear(MatrixPtr eMatrix)
|
spClear(MatrixPtr Matrix)
|
||||||
{
|
{
|
||||||
MatrixPtr Matrix = eMatrix;
|
|
||||||
ElementPtr pElement;
|
ElementPtr pElement;
|
||||||
int I;
|
int I;
|
||||||
|
|
||||||
|
|
@ -180,10 +179,9 @@ spClear(MatrixPtr eMatrix)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
RealNumber *
|
RealNumber *
|
||||||
spFindElement(MatrixPtr eMatrix, int Row, int Col)
|
spFindElement(MatrixPtr Matrix, int Row, int Col)
|
||||||
{
|
{
|
||||||
MatrixPtr Matrix = eMatrix;
|
ElementPtr pElement;
|
||||||
RealNumber *pElement;
|
|
||||||
|
|
||||||
/* Begin `spFindElement'. */
|
/* Begin `spFindElement'. */
|
||||||
assert( IS_SPARSE( Matrix ) && Row >= 0 && Col >= 0 );
|
assert( IS_SPARSE( Matrix ) && Row >= 0 && Col >= 0 );
|
||||||
|
|
@ -210,7 +208,7 @@ RealNumber *pElement;
|
||||||
* is the first record in the MatrixElement structure.
|
* is the first record in the MatrixElement structure.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ((Row != Col) || ((pElement = (RealNumber *)Matrix->Diag[Row]) == NULL))
|
if ((Row != Col) || ((pElement = Matrix->Diag[Row]) == NULL))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Element does not exist or does not reside along diagonal. Search
|
* Element does not exist or does not reside along diagonal. Search
|
||||||
|
|
@ -218,11 +216,11 @@ RealNumber *pElement;
|
||||||
* element which is returned by spcFindElementInCol is cast into a
|
* element which is returned by spcFindElementInCol is cast into a
|
||||||
* pointer to Real, a RealNumber.
|
* pointer to Real, a RealNumber.
|
||||||
*/
|
*/
|
||||||
pElement = (RealNumber*)spcFindElementInCol( Matrix,
|
pElement = spcFindElementInCol( Matrix,
|
||||||
&(Matrix->FirstInCol[Col]),
|
&(Matrix->FirstInCol[Col]),
|
||||||
Row, Col, NO );
|
Row, Col, NO );
|
||||||
}
|
}
|
||||||
return pElement;
|
return & pElement->Real;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -263,10 +261,9 @@ RealNumber *pElement;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
RealNumber *
|
RealNumber *
|
||||||
spGetElement(MatrixPtr eMatrix, int Row, int Col)
|
spGetElement(MatrixPtr Matrix, int Row, int Col)
|
||||||
{
|
{
|
||||||
MatrixPtr Matrix = eMatrix;
|
ElementPtr pElement;
|
||||||
RealNumber *pElement;
|
|
||||||
|
|
||||||
/* Begin `spGetElement'. */
|
/* Begin `spGetElement'. */
|
||||||
assert( IS_SPARSE( Matrix ) && Row >= 0 && Col >= 0 );
|
assert( IS_SPARSE( Matrix ) && Row >= 0 && Col >= 0 );
|
||||||
|
|
@ -305,18 +302,18 @@ spGetElement(MatrixPtr eMatrix, int Row, int Col)
|
||||||
* statement depends on the fact that Real is the first record in
|
* statement depends on the fact that Real is the first record in
|
||||||
* the MatrixElement structure. */
|
* the MatrixElement structure. */
|
||||||
|
|
||||||
if ((Row != Col) || ((pElement = (RealNumber *)Matrix->Diag[Row]) == NULL))
|
if ((Row != Col) || ((pElement = Matrix->Diag[Row]) == NULL))
|
||||||
{
|
{
|
||||||
/* Element does not exist or does not reside along diagonal.
|
/* Element does not exist or does not reside along diagonal.
|
||||||
* Search column for element. As in the if statement above,
|
* Search column for element. As in the if statement above,
|
||||||
* the pointer to the element which is returned by
|
* the pointer to the element which is returned by
|
||||||
* spcFindElementInCol is cast into a pointer to Real, a
|
* spcFindElementInCol is cast into a pointer to Real, a
|
||||||
* RealNumber. */
|
* RealNumber. */
|
||||||
pElement = (RealNumber*)spcFindElementInCol( Matrix,
|
pElement = spcFindElementInCol( Matrix,
|
||||||
&(Matrix->FirstInCol[Col]),
|
&(Matrix->FirstInCol[Col]),
|
||||||
Row, Col, YES );
|
Row, Col, YES );
|
||||||
}
|
}
|
||||||
return pElement;
|
return & pElement->Real;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -644,7 +641,7 @@ spGetQuad(MatrixPtr Matrix, int Row1, int Row2, int Col1, int Col2,
|
||||||
(Template->Element4Negated == NULL))
|
(Template->Element4Negated == NULL))
|
||||||
return spNO_MEMORY;
|
return spNO_MEMORY;
|
||||||
|
|
||||||
if (Template->Element1 == &((MatrixPtr)Matrix)->TrashCan.Real)
|
if (Template->Element1 == & Matrix->TrashCan.Real)
|
||||||
SWAP( RealNumber *, Template->Element1, Template->Element2 );
|
SWAP( RealNumber *, Template->Element1, Template->Element2 );
|
||||||
|
|
||||||
return spOKAY;
|
return spOKAY;
|
||||||
|
|
@ -1145,9 +1142,8 @@ spGetInitInfo(RealNumber *pElement)
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
spInitialize(MatrixPtr eMatrix, int (*pInit)(RealNumber*, void *InitInfo, int , int Col))
|
spInitialize(MatrixPtr Matrix, int (*pInit)(RealNumber*, void *InitInfo, int , int Col))
|
||||||
{
|
{
|
||||||
MatrixPtr Matrix = eMatrix;
|
|
||||||
ElementPtr pElement;
|
ElementPtr pElement;
|
||||||
int J, Error, Col;
|
int J, Error, Col;
|
||||||
|
|
||||||
|
|
@ -1182,7 +1178,7 @@ spInitialize(MatrixPtr eMatrix, int (*pInit)(RealNumber*, void *InitInfo, int ,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Error = pInit ((RealNumber *)pElement, pElement->pInitInfo,
|
Error = pInit (& pElement->Real, pElement->pInitInfo,
|
||||||
Matrix->IntToExtRowMap[pElement->Row], Col);
|
Matrix->IntToExtRowMap[pElement->Row], Col);
|
||||||
if (Error)
|
if (Error)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -189,10 +189,9 @@ static int ZeroPivot( MatrixPtr, int );
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
spOrderAndFactor(MatrixPtr eMatrix, RealNumber RHS[], RealNumber RelThreshold,
|
spOrderAndFactor(MatrixPtr Matrix, RealNumber RHS[], RealNumber RelThreshold,
|
||||||
RealNumber AbsThreshold, int DiagPivoting)
|
RealNumber AbsThreshold, int DiagPivoting)
|
||||||
{
|
{
|
||||||
MatrixPtr Matrix = eMatrix;
|
|
||||||
ElementPtr pPivot;
|
ElementPtr pPivot;
|
||||||
int Step, Size, ReorderingRequired;
|
int Step, Size, ReorderingRequired;
|
||||||
RealNumber LargestInCol;
|
RealNumber LargestInCol;
|
||||||
|
|
@ -321,9 +320,8 @@ Done:
|
||||||
* Error is cleared in this function. */
|
* Error is cleared in this function. */
|
||||||
|
|
||||||
int
|
int
|
||||||
spFactor(MatrixPtr eMatrix)
|
spFactor(MatrixPtr Matrix)
|
||||||
{
|
{
|
||||||
MatrixPtr Matrix = eMatrix;
|
|
||||||
ElementPtr pElement;
|
ElementPtr pElement;
|
||||||
ElementPtr pColumn;
|
ElementPtr pColumn;
|
||||||
int Step, Size;
|
int Step, Size;
|
||||||
|
|
@ -333,10 +331,10 @@ spFactor(MatrixPtr eMatrix)
|
||||||
assert( IS_VALID(Matrix) && !Matrix->Factored);
|
assert( IS_VALID(Matrix) && !Matrix->Factored);
|
||||||
|
|
||||||
if (Matrix->NeedsOrdering) {
|
if (Matrix->NeedsOrdering) {
|
||||||
return spOrderAndFactor( eMatrix, NULL,
|
return spOrderAndFactor( Matrix, NULL,
|
||||||
0.0, 0.0, DIAG_PIVOTING_AS_DEFAULT );
|
0.0, 0.0, DIAG_PIVOTING_AS_DEFAULT );
|
||||||
}
|
}
|
||||||
if (!Matrix->Partitioned) spPartition( eMatrix, spDEFAULT_PARTITION );
|
if (!Matrix->Partitioned) spPartition( Matrix, spDEFAULT_PARTITION );
|
||||||
if (Matrix->Complex)
|
if (Matrix->Complex)
|
||||||
return FactorComplexMatrix( Matrix );
|
return FactorComplexMatrix( Matrix );
|
||||||
|
|
||||||
|
|
@ -569,9 +567,8 @@ FactorComplexMatrix( MatrixPtr Matrix )
|
||||||
* spINDIRECT_PARTITION, or spAUTO_PARTITION. */
|
* spINDIRECT_PARTITION, or spAUTO_PARTITION. */
|
||||||
|
|
||||||
void
|
void
|
||||||
spPartition(MatrixPtr eMatrix, int Mode)
|
spPartition(MatrixPtr Matrix, int Mode)
|
||||||
{
|
{
|
||||||
MatrixPtr Matrix = eMatrix;
|
|
||||||
ElementPtr pElement, pColumn;
|
ElementPtr pElement, pColumn;
|
||||||
int Step, Size;
|
int Step, Size;
|
||||||
int *Nc, *No, *Nm;
|
int *Nc, *No, *Nm;
|
||||||
|
|
@ -603,8 +600,8 @@ spPartition(MatrixPtr eMatrix, int Mode)
|
||||||
assert( Mode == spAUTO_PARTITION );
|
assert( Mode == spAUTO_PARTITION );
|
||||||
|
|
||||||
/* Otherwise, count all operations needed in when factoring matrix. */
|
/* Otherwise, count all operations needed in when factoring matrix. */
|
||||||
Nc = (int *)Matrix->MarkowitzRow;
|
Nc = Matrix->MarkowitzRow;
|
||||||
No = (int *)Matrix->MarkowitzCol;
|
No = Matrix->MarkowitzCol;
|
||||||
Nm = (int *)Matrix->MarkowitzProd;
|
Nm = (int *)Matrix->MarkowitzProd;
|
||||||
|
|
||||||
/* Start mock-factorization. */
|
/* Start mock-factorization. */
|
||||||
|
|
|
||||||
|
|
@ -133,9 +133,8 @@ int Printer_Width = PRINTER_WIDTH;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
spPrint(MatrixPtr eMatrix, int PrintReordered, int Data, int Header)
|
spPrint(MatrixPtr Matrix, int PrintReordered, int Data, int Header)
|
||||||
{
|
{
|
||||||
MatrixPtr Matrix = eMatrix;
|
|
||||||
int J = 0;
|
int J = 0;
|
||||||
int I, Row, Col, Size, Top;
|
int I, Row, Col, Size, Top;
|
||||||
int StartCol = 1, StopCol, Columns, ElementCount = 0;
|
int StartCol = 1, StopCol, Columns, ElementCount = 0;
|
||||||
|
|
@ -295,7 +294,7 @@ spPrint(MatrixPtr eMatrix, int PrintReordered, int Data, int Header)
|
||||||
{
|
{
|
||||||
/* Case where element exists */
|
/* Case where element exists */
|
||||||
if (Data)
|
if (Data)
|
||||||
printf(" %9.3g", (double)pElement->Real);
|
printf(" %9.3g", pElement->Real);
|
||||||
else
|
else
|
||||||
putchar('x');
|
putchar('x');
|
||||||
|
|
||||||
|
|
@ -326,7 +325,7 @@ spPrint(MatrixPtr eMatrix, int PrintReordered, int Data, int Header)
|
||||||
if (pImagElements[J - StartCol] != NULL)
|
if (pImagElements[J - StartCol] != NULL)
|
||||||
{
|
{
|
||||||
printf(" %8.2gj",
|
printf(" %8.2gj",
|
||||||
(double)pImagElements[J-StartCol]->Imag);
|
pImagElements[J-StartCol]->Imag);
|
||||||
}
|
}
|
||||||
else printf(" ");
|
else printf(" ");
|
||||||
}
|
}
|
||||||
|
|
@ -436,10 +435,9 @@ spPrint(MatrixPtr eMatrix, int PrintReordered, int Data, int Header)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
spFileMatrix(MatrixPtr eMatrix, char *File, char *Label, int Reordered,
|
spFileMatrix(MatrixPtr Matrix, char *File, char *Label, int Reordered,
|
||||||
int Data, int Header)
|
int Data, int Header)
|
||||||
{
|
{
|
||||||
MatrixPtr Matrix = eMatrix;
|
|
||||||
int I, Size;
|
int I, Size;
|
||||||
ElementPtr pElement;
|
ElementPtr pElement;
|
||||||
int Row, Col, Err;
|
int Row, Col, Err;
|
||||||
|
|
@ -518,7 +516,7 @@ spFileMatrix(MatrixPtr eMatrix, char *File, char *Label, int Reordered,
|
||||||
}
|
}
|
||||||
Err = fprintf
|
Err = fprintf
|
||||||
( pMatrixFile,"%d\t%d\t%-.15g\t%-.15g\n",
|
( pMatrixFile,"%d\t%d\t%-.15g\t%-.15g\n",
|
||||||
Row, Col, (double)pElement->Real, (double)pElement->Imag
|
Row, Col, pElement->Real, pElement->Imag
|
||||||
);
|
);
|
||||||
if (Err < 0) return 0;
|
if (Err < 0) return 0;
|
||||||
pElement = pElement->NextInCol;
|
pElement = pElement->NextInCol;
|
||||||
|
|
@ -541,7 +539,7 @@ spFileMatrix(MatrixPtr eMatrix, char *File, char *Label, int Reordered,
|
||||||
Col = Matrix->IntToExtColMap[I];
|
Col = Matrix->IntToExtColMap[I];
|
||||||
Err = fprintf
|
Err = fprintf
|
||||||
( pMatrixFile,"%d\t%d\t%-.15g\n",
|
( pMatrixFile,"%d\t%d\t%-.15g\n",
|
||||||
Row, Col, (double)pElement->Real
|
Row, Col, pElement->Real
|
||||||
);
|
);
|
||||||
if (Err < 0) return 0;
|
if (Err < 0) return 0;
|
||||||
pElement = pElement->NextInCol;
|
pElement = pElement->NextInCol;
|
||||||
|
|
@ -595,9 +593,8 @@ spFileMatrix(MatrixPtr eMatrix, char *File, char *Label, int Reordered,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
spFileVector(MatrixPtr eMatrix, char *File, RealVector RHS, RealVector iRHS)
|
spFileVector(MatrixPtr Matrix, char *File, RealVector RHS, RealVector iRHS)
|
||||||
{
|
{
|
||||||
MatrixPtr Matrix = eMatrix;
|
|
||||||
int I, Size, Err;
|
int I, Size, Err;
|
||||||
FILE *pMatrixFile;
|
FILE *pMatrixFile;
|
||||||
|
|
||||||
|
|
@ -621,7 +618,7 @@ spFileVector(MatrixPtr eMatrix, char *File, RealVector RHS, RealVector iRHS)
|
||||||
{
|
{
|
||||||
Err = fprintf
|
Err = fprintf
|
||||||
( pMatrixFile, "%-.15g\t%-.15g\n",
|
( pMatrixFile, "%-.15g\t%-.15g\n",
|
||||||
(double)RHS[I], (double)iRHS[I]
|
RHS[I], iRHS[I]
|
||||||
);
|
);
|
||||||
if (Err < 0) return 0;
|
if (Err < 0) return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -630,7 +627,7 @@ spFileVector(MatrixPtr eMatrix, char *File, RealVector RHS, RealVector iRHS)
|
||||||
{
|
{
|
||||||
for (I = 1; I <= Size; I++)
|
for (I = 1; I <= Size; I++)
|
||||||
{
|
{
|
||||||
if (fprintf(pMatrixFile, "%-.15g\n", (double)RHS[I]) < 0)
|
if (fprintf(pMatrixFile, "%-.15g\n", RHS[I]) < 0)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -686,9 +683,8 @@ spFileVector(MatrixPtr eMatrix, char *File, RealVector RHS, RealVector iRHS)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
spFileStats(MatrixPtr eMatrix, char *File, char *Label)
|
spFileStats(MatrixPtr Matrix, char *File, char *Label)
|
||||||
{
|
{
|
||||||
MatrixPtr Matrix = eMatrix;
|
|
||||||
int Size, I;
|
int Size, I;
|
||||||
ElementPtr pElement;
|
ElementPtr pElement;
|
||||||
int NumberOfElements;
|
int NumberOfElements;
|
||||||
|
|
|
||||||
|
|
@ -106,7 +106,7 @@ extern double scalbn(double, int);
|
||||||
extern double logb(double);
|
extern double logb(double);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void LoadGmin(SMPmatrix *eMatrix, double Gmin);
|
static void LoadGmin(SMPmatrix *Matrix, double Gmin);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SMPaddElt()
|
* SMPaddElt()
|
||||||
|
|
@ -183,7 +183,7 @@ SMPcReorder(SMPmatrix *Matrix, double PivTol, double PivRel,
|
||||||
*NumSwaps = 1;
|
*NumSwaps = 1;
|
||||||
spSetComplex( Matrix->SPmatrix );
|
spSetComplex( Matrix->SPmatrix );
|
||||||
return spOrderAndFactor( Matrix->SPmatrix, NULL,
|
return spOrderAndFactor( Matrix->SPmatrix, NULL,
|
||||||
(spREAL)PivRel, (spREAL)PivTol, YES );
|
PivRel, PivTol, YES );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -195,7 +195,7 @@ SMPreorder(SMPmatrix *Matrix, double PivTol, double PivRel, double Gmin)
|
||||||
spSetReal( Matrix->SPmatrix );
|
spSetReal( Matrix->SPmatrix );
|
||||||
LoadGmin( Matrix, Gmin );
|
LoadGmin( Matrix, Gmin );
|
||||||
return spOrderAndFactor( Matrix->SPmatrix, NULL,
|
return spOrderAndFactor( Matrix->SPmatrix, NULL,
|
||||||
(spREAL)PivRel, (spREAL)PivTol, YES );
|
PivRel, PivTol, YES );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -504,7 +504,7 @@ SMPcAddCol(SMPmatrix *eMatrix, int Accum_Col, int Addend_Col)
|
||||||
|
|
||||||
Addend = Matrix->FirstInCol[Addend_Col];
|
Addend = Matrix->FirstInCol[Addend_Col];
|
||||||
Prev = &Matrix->FirstInCol[Accum_Col];
|
Prev = &Matrix->FirstInCol[Accum_Col];
|
||||||
Accum = *Prev;;
|
Accum = *Prev;
|
||||||
|
|
||||||
while (Addend != NULL) {
|
while (Addend != NULL) {
|
||||||
while (Accum && Accum->Row < Addend->Row) {
|
while (Accum && Accum->Row < Addend->Row) {
|
||||||
|
|
|
||||||
|
|
@ -124,10 +124,9 @@ static void SolveComplexTransposedMatrix( MatrixPtr,
|
||||||
/*VARARGS3*/
|
/*VARARGS3*/
|
||||||
|
|
||||||
void
|
void
|
||||||
spSolve(MatrixPtr eMatrix, RealVector RHS, RealVector Solution,
|
spSolve(MatrixPtr Matrix, RealVector RHS, RealVector Solution,
|
||||||
RealVector iRHS, RealVector iSolution)
|
RealVector iRHS, RealVector iSolution)
|
||||||
{
|
{
|
||||||
MatrixPtr Matrix = eMatrix;
|
|
||||||
ElementPtr pElement;
|
ElementPtr pElement;
|
||||||
RealVector Intermediate;
|
RealVector Intermediate;
|
||||||
RealNumber Temp;
|
RealNumber Temp;
|
||||||
|
|
@ -400,10 +399,9 @@ SolveComplexMatrix( MatrixPtr Matrix, RealVector RHS, RealVector Solution , Real
|
||||||
/*VARARGS3*/
|
/*VARARGS3*/
|
||||||
|
|
||||||
void
|
void
|
||||||
spSolveTransposed(MatrixPtr eMatrix, RealVector RHS, RealVector Solution,
|
spSolveTransposed(MatrixPtr Matrix, RealVector RHS, RealVector Solution,
|
||||||
RealVector iRHS, RealVector iSolution)
|
RealVector iRHS, RealVector iSolution)
|
||||||
{
|
{
|
||||||
MatrixPtr Matrix = eMatrix;
|
|
||||||
ElementPtr pElement;
|
ElementPtr pElement;
|
||||||
RealVector Intermediate;
|
RealVector Intermediate;
|
||||||
int I, *pExtOrder, Size;
|
int I, *pExtOrder, Size;
|
||||||
|
|
|
||||||
|
|
@ -151,7 +151,7 @@ static void ComplexTransposedMatrixMultiply( MatrixPtr, RealVector, RealVector,
|
||||||
* Tom Quarles.
|
* Tom Quarles.
|
||||||
*
|
*
|
||||||
* >>> Arguments:
|
* >>> Arguments:
|
||||||
* eMatrix <input> (char *)
|
* Matrix <input> (char *)
|
||||||
* Pointer to the matrix to be preordered.
|
* Pointer to the matrix to be preordered.
|
||||||
*
|
*
|
||||||
* >>> Local variables;
|
* >>> Local variables;
|
||||||
|
|
@ -174,9 +174,8 @@ static void ComplexTransposedMatrixMultiply( MatrixPtr, RealVector, RealVector,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
spMNA_Preorder(MatrixPtr eMatrix)
|
spMNA_Preorder(MatrixPtr Matrix)
|
||||||
{
|
{
|
||||||
MatrixPtr Matrix = eMatrix;
|
|
||||||
int J, Size;
|
int J, Size;
|
||||||
ElementPtr pTwin1, pTwin2;
|
ElementPtr pTwin1, pTwin2;
|
||||||
int Twins, StartAt = 1;
|
int Twins, StartAt = 1;
|
||||||
|
|
@ -346,7 +345,7 @@ SwapCols( MatrixPtr Matrix, ElementPtr pTwin1, ElementPtr pTwin2 )
|
||||||
* should not be executed before the function spMNA_Preorder.
|
* should not be executed before the function spMNA_Preorder.
|
||||||
*
|
*
|
||||||
* >>> Arguments:
|
* >>> Arguments:
|
||||||
* eMatrix <input> (char *)
|
* Matrix <input> (char *)
|
||||||
* Pointer to the matrix to be scaled.
|
* Pointer to the matrix to be scaled.
|
||||||
* SolutionScaleFactors <input> (RealVector)
|
* SolutionScaleFactors <input> (RealVector)
|
||||||
* The array of Solution scale factors. These factors scale the columns.
|
* The array of Solution scale factors. These factors scale the columns.
|
||||||
|
|
@ -368,9 +367,8 @@ SwapCols( MatrixPtr Matrix, ElementPtr pTwin1, ElementPtr pTwin2 )
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
spScale(MatrixPtr eMatrix, RealVector RHS_ScaleFactors, RealVector SolutionScaleFactors)
|
spScale(MatrixPtr Matrix, RealVector RHS_ScaleFactors, RealVector SolutionScaleFactors)
|
||||||
{
|
{
|
||||||
MatrixPtr Matrix = eMatrix;
|
|
||||||
ElementPtr pElement;
|
ElementPtr pElement;
|
||||||
int I, lSize, *pExtOrder;
|
int I, lSize, *pExtOrder;
|
||||||
RealNumber ScaleFactor;
|
RealNumber ScaleFactor;
|
||||||
|
|
@ -556,7 +554,7 @@ MatrixPtr Matrix;
|
||||||
* before spMNA_Preorder().
|
* before spMNA_Preorder().
|
||||||
*
|
*
|
||||||
* >>> Arguments:
|
* >>> Arguments:
|
||||||
* eMatrix <input> (char *)
|
* Matrix <input> (char *)
|
||||||
* Pointer to the matrix.
|
* Pointer to the matrix.
|
||||||
* RHS <output> (RealVector)
|
* RHS <output> (RealVector)
|
||||||
* RHS is the right hand side. This is what is being solved for.
|
* RHS is the right hand side. This is what is being solved for.
|
||||||
|
|
@ -571,14 +569,13 @@ MatrixPtr Matrix;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
spMultiply(MatrixPtr eMatrix, RealVector RHS, RealVector Solution,
|
spMultiply(MatrixPtr Matrix, RealVector RHS, RealVector Solution,
|
||||||
RealVector iRHS, RealVector iSolution)
|
RealVector iRHS, RealVector iSolution)
|
||||||
{
|
{
|
||||||
ElementPtr pElement;
|
ElementPtr pElement;
|
||||||
RealVector Vector;
|
RealVector Vector;
|
||||||
RealNumber Sum;
|
RealNumber Sum;
|
||||||
int I, *pExtOrder;
|
int I, *pExtOrder;
|
||||||
MatrixPtr Matrix = eMatrix;
|
|
||||||
|
|
||||||
/* Begin `spMultiply'. */
|
/* Begin `spMultiply'. */
|
||||||
assert( IS_SPARSE( Matrix ) && !Matrix->Factored );
|
assert( IS_SPARSE( Matrix ) && !Matrix->Factored );
|
||||||
|
|
@ -702,7 +699,7 @@ ComplexMatrixMultiply( MatrixPtr Matrix, RealVector RHS, RealVector Solution , R
|
||||||
* before spMNA_Preorder().
|
* before spMNA_Preorder().
|
||||||
*
|
*
|
||||||
* >>> Arguments:
|
* >>> Arguments:
|
||||||
* eMatrix <input> (char *)
|
* Matrix <input> (char *)
|
||||||
* Pointer to the matrix.
|
* Pointer to the matrix.
|
||||||
* RHS <output> (RealVector)
|
* RHS <output> (RealVector)
|
||||||
* RHS is the right hand side. This is what is being solved for.
|
* RHS is the right hand side. This is what is being solved for.
|
||||||
|
|
@ -717,14 +714,13 @@ ComplexMatrixMultiply( MatrixPtr Matrix, RealVector RHS, RealVector Solution , R
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
spMultTransposed(MatrixPtr eMatrix, RealVector RHS, RealVector Solution,
|
spMultTransposed(MatrixPtr Matrix, RealVector RHS, RealVector Solution,
|
||||||
RealVector iRHS, RealVector iSolution)
|
RealVector iRHS, RealVector iSolution)
|
||||||
{
|
{
|
||||||
ElementPtr pElement;
|
ElementPtr pElement;
|
||||||
RealVector Vector;
|
RealVector Vector;
|
||||||
RealNumber Sum;
|
RealNumber Sum;
|
||||||
int I, *pExtOrder;
|
int I, *pExtOrder;
|
||||||
MatrixPtr Matrix = eMatrix;
|
|
||||||
|
|
||||||
/* Begin `spMultTransposed'. */
|
/* Begin `spMultTransposed'. */
|
||||||
assert( IS_SPARSE( Matrix ) && !Matrix->Factored );
|
assert( IS_SPARSE( Matrix ) && !Matrix->Factored );
|
||||||
|
|
@ -854,7 +850,7 @@ ComplexTransposedMatrixMultiply( MatrixPtr Matrix, RealVector RHS, RealVector So
|
||||||
* reasonable value and the logarithm of the scale factor is returned.
|
* reasonable value and the logarithm of the scale factor is returned.
|
||||||
*
|
*
|
||||||
* >>> Arguments:
|
* >>> Arguments:
|
||||||
* eMatrix <input> (char *)
|
* Matrix <input> (char *)
|
||||||
* A pointer to the matrix for which the determinant is desired.
|
* A pointer to the matrix for which the determinant is desired.
|
||||||
* pExponent <output> (int *)
|
* pExponent <output> (int *)
|
||||||
* The logarithm base 10 of the scale factor for the determinant. To find
|
* The logarithm base 10 of the scale factor for the determinant. To find
|
||||||
|
|
@ -878,10 +874,9 @@ ComplexTransposedMatrixMultiply( MatrixPtr Matrix, RealVector RHS, RealVector So
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
spDeterminant(MatrixPtr eMatrix, int *pExponent, RealNumber *pDeterminant,
|
spDeterminant(MatrixPtr Matrix, int *pExponent, RealNumber *pDeterminant,
|
||||||
RealNumber *piDeterminant)
|
RealNumber *piDeterminant)
|
||||||
{
|
{
|
||||||
MatrixPtr Matrix = eMatrix;
|
|
||||||
int I, Size;
|
int I, Size;
|
||||||
RealNumber Norm, nr, ni;
|
RealNumber Norm, nr, ni;
|
||||||
ComplexNumber Pivot, cDeterminant;
|
ComplexNumber Pivot, cDeterminant;
|
||||||
|
|
@ -1037,9 +1032,8 @@ spDeterminant(MatrixPtr eMatrix, int *pExponent, RealNumber *pDeterminant,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
spStripFills(MatrixPtr eMatrix)
|
spStripFills(MatrixPtr Matrix)
|
||||||
{
|
{
|
||||||
MatrixPtr Matrix = eMatrix;
|
|
||||||
struct FillinListNodeStruct *pListNode;
|
struct FillinListNodeStruct *pListNode;
|
||||||
|
|
||||||
/* Begin `spStripFills'. */
|
/* Begin `spStripFills'. */
|
||||||
|
|
@ -1109,10 +1103,8 @@ spStripFills(MatrixPtr eMatrix)
|
||||||
* frame. This assumes that the matrix will be replaced with one of
|
* frame. This assumes that the matrix will be replaced with one of
|
||||||
* the same size. */
|
* the same size. */
|
||||||
void
|
void
|
||||||
spStripMatrix(MatrixPtr eMatrix)
|
spStripMatrix(MatrixPtr Matrix)
|
||||||
{
|
{
|
||||||
MatrixPtr Matrix = eMatrix;
|
|
||||||
|
|
||||||
/* Begin `spStripMatrix'. */
|
/* Begin `spStripMatrix'. */
|
||||||
assert( IS_SPARSE( Matrix ) );
|
assert( IS_SPARSE( Matrix ) );
|
||||||
if (Matrix->Elements == 0) return;
|
if (Matrix->Elements == 0) return;
|
||||||
|
|
@ -1124,7 +1116,6 @@ spStripMatrix(MatrixPtr eMatrix)
|
||||||
|
|
||||||
/* Reset the element lists. */
|
/* Reset the element lists. */
|
||||||
{
|
{
|
||||||
ElementPtr pElement;
|
|
||||||
struct ElementListNodeStruct *pListNode;
|
struct ElementListNodeStruct *pListNode;
|
||||||
|
|
||||||
pListNode = Matrix->LastElementListNode = Matrix->FirstElementListNode;
|
pListNode = Matrix->LastElementListNode = Matrix->FirstElementListNode;
|
||||||
|
|
@ -1134,7 +1125,6 @@ spStripMatrix(MatrixPtr eMatrix)
|
||||||
|
|
||||||
/* Reset the fill-in lists. */
|
/* Reset the fill-in lists. */
|
||||||
{
|
{
|
||||||
ElementPtr pFillin;
|
|
||||||
struct FillinListNodeStruct *pListNode;
|
struct FillinListNodeStruct *pListNode;
|
||||||
|
|
||||||
pListNode = Matrix->LastFillinListNode = Matrix->FirstFillinListNode;
|
pListNode = Matrix->LastFillinListNode = Matrix->FirstFillinListNode;
|
||||||
|
|
@ -1171,7 +1161,7 @@ spStripMatrix(MatrixPtr eMatrix)
|
||||||
* doesn't exist.
|
* doesn't exist.
|
||||||
*
|
*
|
||||||
* >>> Arguments:
|
* >>> Arguments:
|
||||||
* eMatrix <input> (char *)
|
* Matrix <input> (char *)
|
||||||
* Pointer to the matrix in which the row and column are to be deleted.
|
* Pointer to the matrix in which the row and column are to be deleted.
|
||||||
* Row <input> (int)
|
* Row <input> (int)
|
||||||
* Row to be deleted.
|
* Row to be deleted.
|
||||||
|
|
@ -1197,9 +1187,8 @@ spStripMatrix(MatrixPtr eMatrix)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
spDeleteRowAndCol(MatrixPtr eMatrix, int Row, int Col)
|
spDeleteRowAndCol(MatrixPtr Matrix, int Row, int Col)
|
||||||
{
|
{
|
||||||
MatrixPtr Matrix = eMatrix;
|
|
||||||
ElementPtr pElement, *ppElement, pLastElement;
|
ElementPtr pElement, *ppElement, pLastElement;
|
||||||
int Size, ExtRow, ExtCol;
|
int Size, ExtRow, ExtCol;
|
||||||
ElementPtr spcFindElementInCol();
|
ElementPtr spcFindElementInCol();
|
||||||
|
|
@ -1306,13 +1295,12 @@ spDeleteRowAndCol(MatrixPtr eMatrix, int Row, int Col)
|
||||||
* previous factorization. If the matrix was singular, zero is returned.
|
* previous factorization. If the matrix was singular, zero is returned.
|
||||||
*
|
*
|
||||||
* >>> Arguments:
|
* >>> Arguments:
|
||||||
* eMatrix <input> (char *)
|
* Matrix <input> (char *)
|
||||||
* Pointer to the matrix. */
|
* Pointer to the matrix. */
|
||||||
|
|
||||||
RealNumber
|
RealNumber
|
||||||
spPseudoCondition(MatrixPtr eMatrix)
|
spPseudoCondition(MatrixPtr Matrix)
|
||||||
{
|
{
|
||||||
MatrixPtr Matrix = eMatrix;
|
|
||||||
int I;
|
int I;
|
||||||
ArrayOfElementPtrs Diag;
|
ArrayOfElementPtrs Diag;
|
||||||
RealNumber MaxPivot, MinPivot, Mag;
|
RealNumber MaxPivot, MinPivot, Mag;
|
||||||
|
|
@ -1388,7 +1376,7 @@ spPseudoCondition(MatrixPtr eMatrix)
|
||||||
* zero is returned.
|
* zero is returned.
|
||||||
*
|
*
|
||||||
* >>> Arguments:
|
* >>> Arguments:
|
||||||
* eMatrix <input> (char *)
|
* Matrix <input> (char *)
|
||||||
* Pointer to the matrix.
|
* Pointer to the matrix.
|
||||||
* NormOfMatrix <input> (RealNumber)
|
* NormOfMatrix <input> (RealNumber)
|
||||||
* The L-infinity norm of the unfactored matrix as computed by
|
* The L-infinity norm of the unfactored matrix as computed by
|
||||||
|
|
@ -1401,9 +1389,8 @@ spPseudoCondition(MatrixPtr eMatrix)
|
||||||
* spNO_MEMORY */
|
* spNO_MEMORY */
|
||||||
|
|
||||||
RealNumber
|
RealNumber
|
||||||
spCondition(MatrixPtr eMatrix, RealNumber NormOfMatrix, int *pError)
|
spCondition(MatrixPtr Matrix, RealNumber NormOfMatrix, int *pError)
|
||||||
{
|
{
|
||||||
MatrixPtr Matrix = eMatrix;
|
|
||||||
ElementPtr pElement;
|
ElementPtr pElement;
|
||||||
RealVector T, Tm;
|
RealVector T, Tm;
|
||||||
int I, K, Row;
|
int I, K, Row;
|
||||||
|
|
@ -1824,14 +1811,13 @@ int *pError;
|
||||||
* The largest absolute row sum of matrix.
|
* The largest absolute row sum of matrix.
|
||||||
*
|
*
|
||||||
* >>> Arguments:
|
* >>> Arguments:
|
||||||
* eMatrix <input> (char *)
|
* Matrix <input> (char *)
|
||||||
* Pointer to the matrix.
|
* Pointer to the matrix.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
RealNumber
|
RealNumber
|
||||||
spNorm(MatrixPtr eMatrix)
|
spNorm(MatrixPtr Matrix)
|
||||||
{
|
{
|
||||||
MatrixPtr Matrix = eMatrix;
|
|
||||||
ElementPtr pElement;
|
ElementPtr pElement;
|
||||||
int I;
|
int I;
|
||||||
RealNumber Max = 0.0, AbsRowSum;
|
RealNumber Max = 0.0, AbsRowSum;
|
||||||
|
|
@ -1942,14 +1928,13 @@ spNorm(MatrixPtr eMatrix)
|
||||||
* largest element in any of the reduced submatrices is returned.
|
* largest element in any of the reduced submatrices is returned.
|
||||||
*
|
*
|
||||||
* >>> Arguments:
|
* >>> Arguments:
|
||||||
* eMatrix <input> (char *)
|
* Matrix <input> (char *)
|
||||||
* Pointer to the matrix.
|
* Pointer to the matrix.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
RealNumber
|
RealNumber
|
||||||
spLargestElement(MatrixPtr eMatrix)
|
spLargestElement(MatrixPtr Matrix)
|
||||||
{
|
{
|
||||||
MatrixPtr Matrix = eMatrix;
|
|
||||||
int I;
|
int I;
|
||||||
RealNumber Mag, AbsColSum, Max = 0.0, MaxRow = 0.0, MaxCol = 0.0;
|
RealNumber Mag, AbsColSum, Max = 0.0, MaxRow = 0.0, MaxCol = 0.0;
|
||||||
RealNumber Pivot;
|
RealNumber Pivot;
|
||||||
|
|
@ -2066,7 +2051,7 @@ spLargestElement(MatrixPtr eMatrix)
|
||||||
* Returns a bound on the magnitude of the largest element in E = A - LU.
|
* Returns a bound on the magnitude of the largest element in E = A - LU.
|
||||||
*
|
*
|
||||||
* >>> Arguments:
|
* >>> Arguments:
|
||||||
* eMatrix <input> (char *)
|
* Matrix <input> (char *)
|
||||||
* Pointer to the matrix.
|
* Pointer to the matrix.
|
||||||
* Rho <input> (RealNumber)
|
* Rho <input> (RealNumber)
|
||||||
* The bound on the magnitude of the largest element in any of the
|
* The bound on the magnitude of the largest element in any of the
|
||||||
|
|
@ -2076,9 +2061,8 @@ spLargestElement(MatrixPtr eMatrix)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
RealNumber
|
RealNumber
|
||||||
spRoundoff(MatrixPtr eMatrix, RealNumber Rho)
|
spRoundoff(MatrixPtr Matrix, RealNumber Rho)
|
||||||
{
|
{
|
||||||
MatrixPtr Matrix = eMatrix;
|
|
||||||
ElementPtr pElement;
|
ElementPtr pElement;
|
||||||
int Count, I, MaxCount = 0;
|
int Count, I, MaxCount = 0;
|
||||||
RealNumber Reid, Gear;
|
RealNumber Reid, Gear;
|
||||||
|
|
@ -2087,7 +2071,7 @@ spRoundoff(MatrixPtr eMatrix, RealNumber Rho)
|
||||||
assert( IS_SPARSE(Matrix) && IS_FACTORED(Matrix) );
|
assert( IS_SPARSE(Matrix) && IS_FACTORED(Matrix) );
|
||||||
|
|
||||||
/* Compute Barlow's bound if it is not given. */
|
/* Compute Barlow's bound if it is not given. */
|
||||||
if (Rho < 0.0) Rho = spLargestElement( eMatrix );
|
if (Rho < 0.0) Rho = spLargestElement( Matrix );
|
||||||
|
|
||||||
/* Find the maximum number of off-diagonals in L if not previously computed. */
|
/* Find the maximum number of off-diagonals in L if not previously computed. */
|
||||||
if (Matrix->MaxRowCountInLowerTri < 0)
|
if (Matrix->MaxRowCountInLowerTri < 0)
|
||||||
|
|
@ -2133,7 +2117,7 @@ spRoundoff(MatrixPtr eMatrix, RealNumber Rho)
|
||||||
* error state of sparse. No message is produced if there is no error.
|
* error state of sparse. No message is produced if there is no error.
|
||||||
*
|
*
|
||||||
* >>> Arguments:
|
* >>> Arguments:
|
||||||
* eMatrix <input> (char *)
|
* Matrix <input> (char *)
|
||||||
* Matrix for which the error message is to be printed.
|
* Matrix for which the error message is to be printed.
|
||||||
* Stream <input> (FILE *)
|
* Stream <input> (FILE *)
|
||||||
* Stream to which the error message is to be printed.
|
* Stream to which the error message is to be printed.
|
||||||
|
|
@ -2143,17 +2127,17 @@ spRoundoff(MatrixPtr eMatrix, RealNumber Rho)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
spErrorMessage(MatrixPtr eMatrix, FILE *Stream, char *Originator)
|
spErrorMessage(MatrixPtr Matrix, FILE *Stream, char *Originator)
|
||||||
{
|
{
|
||||||
int Row, Col, Error;
|
int Row, Col, Error;
|
||||||
|
|
||||||
/* Begin `spErrorMessage'. */
|
/* Begin `spErrorMessage'. */
|
||||||
if (eMatrix == NULL)
|
if (Matrix == NULL)
|
||||||
Error = spNO_MEMORY;
|
Error = spNO_MEMORY;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
assert(eMatrix->ID == SPARSE_ID);
|
assert(Matrix->ID == SPARSE_ID);
|
||||||
Error = eMatrix->Error;
|
Error = Matrix->Error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Error == spOKAY) return;
|
if (Error == spOKAY) return;
|
||||||
|
|
@ -2172,13 +2156,13 @@ spErrorMessage(MatrixPtr eMatrix, FILE *Stream, char *Originator)
|
||||||
fprintf( Stream, "insufficient memory available.\n");
|
fprintf( Stream, "insufficient memory available.\n");
|
||||||
else if (Error == spSINGULAR)
|
else if (Error == spSINGULAR)
|
||||||
{
|
{
|
||||||
spWhereSingular( eMatrix, &Row, &Col );
|
spWhereSingular( Matrix, &Row, &Col );
|
||||||
fprintf( Stream, "singular matrix detected at row %d and column %d.\n",
|
fprintf( Stream, "singular matrix detected at row %d and column %d.\n",
|
||||||
Row, Col);
|
Row, Col);
|
||||||
}
|
}
|
||||||
else if (Error == spZERO_DIAG)
|
else if (Error == spZERO_DIAG)
|
||||||
{
|
{
|
||||||
spWhereSingular( eMatrix, &Row, &Col );
|
spWhereSingular( Matrix, &Row, &Col );
|
||||||
fprintf( Stream, "zero diagonal detected at row %d and column %d.\n",
|
fprintf( Stream, "zero diagonal detected at row %d and column %d.\n",
|
||||||
Row, Col);
|
Row, Col);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,9 @@ Copyright 1990 Regents of the University of California. All rights reserved.
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_FTIME
|
||||||
|
# include <sys/timeb.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* Return the date. Return value is static data. */
|
/* Return the date. Return value is static data. */
|
||||||
|
|
@ -65,8 +68,6 @@ datestring(void)
|
||||||
|
|
||||||
/* return time interval in seconds and milliseconds */
|
/* return time interval in seconds and milliseconds */
|
||||||
|
|
||||||
#ifndef HAVE_GETRUSAGE
|
|
||||||
#ifndef HAVE_TIMES
|
|
||||||
#ifdef HAVE_FTIME
|
#ifdef HAVE_FTIME
|
||||||
|
|
||||||
struct timeb timebegin;
|
struct timeb timebegin;
|
||||||
|
|
@ -84,8 +85,6 @@ void timediff(struct timeb *now, struct timeb *begin, int *sec, int *msec)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -9,16 +9,12 @@
|
||||||
char * datestring(void);
|
char * datestring(void);
|
||||||
double seconds(void);
|
double seconds(void);
|
||||||
|
|
||||||
#ifndef HAVE_GETRUSAGE
|
|
||||||
#ifndef HAVE_TIMES
|
|
||||||
#ifdef HAVE_FTIME
|
#ifdef HAVE_FTIME
|
||||||
|
|
||||||
extern struct timeb timebegin;
|
extern struct timeb timebegin;
|
||||||
|
|
||||||
void timediff(struct timeb *, struct timeb *, int *, int *);
|
void timediff(struct timeb *, struct timeb *, int *, int *);
|
||||||
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,12 @@
|
||||||
#define STDERR_FILENO 2
|
#define STDERR_FILENO 2
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//#define low_latency
|
|
||||||
|
/* If a calling function has high latency times during printing,
|
||||||
|
causing memory access errors, you may undef the following line.
|
||||||
|
Printing messages are assembled in a wordlist, and sent to the caller
|
||||||
|
via a new thread. Delays may occur. */
|
||||||
|
#define low_latency
|
||||||
|
|
||||||
/**********************************************************************/
|
/**********************************************************************/
|
||||||
/* Header files for C functions */
|
/* Header files for C functions */
|
||||||
|
|
@ -131,11 +136,9 @@ typedef pthread_t threadId_t;
|
||||||
#include <frontend/com_measure2.h>
|
#include <frontend/com_measure2.h>
|
||||||
#include <frontend/misccoms.h>
|
#include <frontend/misccoms.h>
|
||||||
|
|
||||||
#ifndef HAVE_GETRUSAGE
|
|
||||||
#ifdef HAVE_FTIME
|
#ifdef HAVE_FTIME
|
||||||
#include <sys/timeb.h>
|
#include <sys/timeb.h>
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
/* To interupt a spice run */
|
/* To interupt a spice run */
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
@ -195,6 +198,7 @@ int sh_vfprintf(FILE *f, const char *fmt, va_list args);
|
||||||
int sh_fputsll(const char *input, FILE* outf);
|
int sh_fputsll(const char *input, FILE* outf);
|
||||||
|
|
||||||
int sh_ExecutePerLoop(void);
|
int sh_ExecutePerLoop(void);
|
||||||
|
double getvsrcval(double, char*);
|
||||||
int sh_vecinit(runDesc *run);
|
int sh_vecinit(runDesc *run);
|
||||||
|
|
||||||
void shared_exit(int status);
|
void shared_exit(int status);
|
||||||
|
|
@ -203,6 +207,8 @@ void sighandler_sharedspice(int num);
|
||||||
|
|
||||||
void wl_delete_first(wordlist **wlstart, wordlist **wlend);
|
void wl_delete_first(wordlist **wlstart, wordlist **wlend);
|
||||||
|
|
||||||
|
int add_bkpt(void);
|
||||||
|
|
||||||
#if !defined(low_latency)
|
#if !defined(low_latency)
|
||||||
static char* outstorage(char*, bool);
|
static char* outstorage(char*, bool);
|
||||||
static void printsend(void);
|
static void printsend(void);
|
||||||
|
|
@ -217,6 +223,7 @@ static ControlledExit* ngexit;
|
||||||
static SendData* datfcn;
|
static SendData* datfcn;
|
||||||
static SendInitData* datinitfcn;
|
static SendInitData* datinitfcn;
|
||||||
static BGThreadRunning* bgtr;
|
static BGThreadRunning* bgtr;
|
||||||
|
static GetVSRCData* getvdat;
|
||||||
static pvector_info myvec = NULL;
|
static pvector_info myvec = NULL;
|
||||||
char **allvecs = NULL;
|
char **allvecs = NULL;
|
||||||
char **allplots = NULL;
|
char **allplots = NULL;
|
||||||
|
|
@ -225,6 +232,7 @@ static bool nostatuswanted = FALSE;
|
||||||
static bool nodatawanted = FALSE;
|
static bool nodatawanted = FALSE;
|
||||||
static bool nodatainitwanted = FALSE;
|
static bool nodatainitwanted = FALSE;
|
||||||
static bool nobgtrwanted = FALSE;
|
static bool nobgtrwanted = FALSE;
|
||||||
|
static bool wantvdat = FALSE;
|
||||||
static bool immediate = FALSE;
|
static bool immediate = FALSE;
|
||||||
static bool coquit = FALSE;
|
static bool coquit = FALSE;
|
||||||
static jmp_buf errbufm, errbufc;
|
static jmp_buf errbufm, errbufc;
|
||||||
|
|
@ -244,7 +252,9 @@ mutexType fputsMutex;
|
||||||
static bool is_initialized = FALSE;
|
static bool is_initialized = FALSE;
|
||||||
static char* no_init = "Error: ngspice is not initialized!\n Run ngSpice_Init first";
|
static char* no_init = "Error: ngspice is not initialized!\n Run ngSpice_Init first";
|
||||||
|
|
||||||
static bool printstopp = FALSE;
|
/* identifier for this ngspice invocation */
|
||||||
|
static int ng_ident = 0;
|
||||||
|
|
||||||
|
|
||||||
/*helper function*//*
|
/*helper function*//*
|
||||||
static struct plot *
|
static struct plot *
|
||||||
|
|
@ -293,12 +303,16 @@ static threadId_t tid, printtid, bgtid = (threadId_t) 0;
|
||||||
static bool fl_running = FALSE;
|
static bool fl_running = FALSE;
|
||||||
static bool fl_exited = TRUE;
|
static bool fl_exited = TRUE;
|
||||||
|
|
||||||
|
static bool printstopp = FALSE;
|
||||||
|
static bool ps_exited = TRUE;
|
||||||
|
|
||||||
#if defined(__MINGW32__) || defined(_MSC_VER)
|
#if defined(__MINGW32__) || defined(_MSC_VER)
|
||||||
#define EXPORT_FLAVOR WINAPI
|
#define EXPORT_FLAVOR WINAPI
|
||||||
#else
|
#else
|
||||||
#define EXPORT_FLAVOR
|
#define EXPORT_FLAVOR
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* starts a background thread, e.g. from command bg_run */
|
||||||
static void * EXPORT_FLAVOR
|
static void * EXPORT_FLAVOR
|
||||||
_thread_run(void *string)
|
_thread_run(void *string)
|
||||||
{
|
{
|
||||||
|
|
@ -324,7 +338,7 @@ _thread_run(void *string)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*Stops a running thread, hopefully */
|
/*Stops a running background thread, hopefully */
|
||||||
static int EXPORT_FLAVOR
|
static int EXPORT_FLAVOR
|
||||||
_thread_stop(void)
|
_thread_stop(void)
|
||||||
{
|
{
|
||||||
|
|
@ -374,13 +388,16 @@ sighandler_sharedspice(int num)
|
||||||
|
|
||||||
#endif /*THREADS*/
|
#endif /*THREADS*/
|
||||||
|
|
||||||
|
/* run a ngspice command */
|
||||||
static int
|
static int
|
||||||
runc(char* command)
|
runc(char* command)
|
||||||
{
|
{
|
||||||
char buf[1024] = "";
|
char buf[1024] = "";
|
||||||
sighandler oldHandler;
|
sighandler oldHandler;
|
||||||
#ifdef THREADS
|
#ifdef THREADS
|
||||||
|
#ifndef low_latency
|
||||||
|
int timeout = 0;
|
||||||
|
#endif
|
||||||
char *string;
|
char *string;
|
||||||
bool fl_bg = FALSE;
|
bool fl_bg = FALSE;
|
||||||
command_id = threadid_self();
|
command_id = threadid_self();
|
||||||
|
|
@ -392,12 +409,24 @@ runc(char* command)
|
||||||
#ifndef low_latency
|
#ifndef low_latency
|
||||||
/* stop the printf thread 'printsend()' */
|
/* stop the printf thread 'printsend()' */
|
||||||
else if (cieq("bg_pstop", command)) {
|
else if (cieq("bg_pstop", command)) {
|
||||||
printstopp = TRUE;
|
while (!ps_exited && timeout < 100) {
|
||||||
|
printstopp = TRUE;
|
||||||
|
|
||||||
#if defined(__MINGW32__) || defined(_MSC_VER)
|
#if defined(__MINGW32__) || defined(_MSC_VER)
|
||||||
Sleep(100); // va: windows native
|
Sleep(100); // va: windows native
|
||||||
#else
|
#else
|
||||||
usleep(10000);
|
usleep(10000);
|
||||||
#endif
|
#endif
|
||||||
|
timeout++;
|
||||||
|
}
|
||||||
|
if (!ps_exited) {
|
||||||
|
fprintf(stderr, "Error: Couldn't stop printsend thread\n");
|
||||||
|
return EXIT_BAD;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
fprintf(stdout, "Printsend thread stopped with timeout = %d\n", timeout);
|
||||||
|
|
||||||
|
printstopp = FALSE;
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -408,7 +437,7 @@ runc(char* command)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Catch Ctrl-C to break simulations */
|
/* Catch Ctrl-C to break simulations */
|
||||||
#if !defined(_MSC_VER) /*&& !defined(__MINGW32__) */
|
#if 1 //!defined(_MSC_VER) /*&& !defined(__MINGW32__) */
|
||||||
oldHandler = signal(SIGINT, (SIGNAL_FUNCTION) ft_sigintr);
|
oldHandler = signal(SIGINT, (SIGNAL_FUNCTION) ft_sigintr);
|
||||||
if (SETJMP(jbuf, 1) != 0) {
|
if (SETJMP(jbuf, 1) != 0) {
|
||||||
signal(SIGINT, oldHandler);
|
signal(SIGINT, oldHandler);
|
||||||
|
|
@ -469,7 +498,7 @@ runc(char* command)
|
||||||
|
|
||||||
#ifdef THREADS
|
#ifdef THREADS
|
||||||
|
|
||||||
/* Checks if spice is running in the background */
|
/* Checks if ngspice is running in the background */
|
||||||
IMPEXP
|
IMPEXP
|
||||||
bool
|
bool
|
||||||
ngSpice_running (void)
|
ngSpice_running (void)
|
||||||
|
|
@ -478,8 +507,27 @@ ngSpice_running (void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Initialise external voltage source */
|
||||||
|
IMPEXP
|
||||||
|
int
|
||||||
|
ngSpice_Init_Sync(GetVSRCData* vsrcdat, int* ident, void* userData)
|
||||||
|
{
|
||||||
|
getvdat = vsrcdat;
|
||||||
|
/* set userdata, but don't overwrite with NULL */
|
||||||
|
if (userData)
|
||||||
|
userptr = userData;
|
||||||
|
/* set ngspice shared lib identification number */
|
||||||
|
ng_ident = *ident;
|
||||||
|
/* if caller sends NULL, don't try to retrieve voltage */
|
||||||
|
if (getvdat) {
|
||||||
|
wantvdat = TRUE;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Initialise spice and setup native methods */
|
|
||||||
|
/* Initialise ngspice and setup native methods */
|
||||||
IMPEXP
|
IMPEXP
|
||||||
int
|
int
|
||||||
ngSpice_Init(SendChar* printfcn, SendStat* statusfcn, ControlledExit* ngspiceexit,
|
ngSpice_Init(SendChar* printfcn, SendStat* statusfcn, ControlledExit* ngspiceexit,
|
||||||
|
|
@ -578,12 +626,9 @@ ngSpice_Init(SendChar* printfcn, SendStat* statusfcn, ControlledExit* ngspiceexi
|
||||||
struct passwd *pw;
|
struct passwd *pw;
|
||||||
pw = getpwuid(getuid());
|
pw = getpwuid(getuid());
|
||||||
|
|
||||||
#ifdef HAVE_ASPRINTF
|
|
||||||
asprintf(&s, "%s%s", pw->pw_dir, INITSTR);
|
|
||||||
#else
|
|
||||||
s = TMALLOC(char, 1 + strlen(pw->pw_dir) + strlen(INITSTR));
|
s = TMALLOC(char, 1 + strlen(pw->pw_dir) + strlen(INITSTR));
|
||||||
sprintf(s, "%s%s", pw->pw_dir, INITSTR);
|
sprintf(s, "%s%s", pw->pw_dir, INITSTR);
|
||||||
#endif
|
|
||||||
if (access(s, 0) == 0)
|
if (access(s, 0) == 0)
|
||||||
inp_source(s);
|
inp_source(s);
|
||||||
}
|
}
|
||||||
|
|
@ -627,7 +672,14 @@ bot:
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
com_version(NULL);
|
// com_version(NULL);
|
||||||
|
fprintf(cp_out,
|
||||||
|
"******\n"
|
||||||
|
"** %s-%s shared library\n",
|
||||||
|
ft_sim->simulator, ft_sim->version);
|
||||||
|
if (Spice_Build_Date != NULL && *Spice_Build_Date != 0)
|
||||||
|
fprintf(cp_out, "** Creation Date: %s\n", Spice_Build_Date);
|
||||||
|
fprintf(cp_out, "******\n");
|
||||||
|
|
||||||
is_initialized = TRUE;
|
is_initialized = TRUE;
|
||||||
|
|
||||||
|
|
@ -638,7 +690,7 @@ bot:
|
||||||
/* If caller has sent valid address for pfcn */
|
/* If caller has sent valid address for pfcn */
|
||||||
if (!noprintfwanted)
|
if (!noprintfwanted)
|
||||||
#ifdef HAVE_LIBPTHREAD
|
#ifdef HAVE_LIBPTHREAD
|
||||||
pthread_create(&tid, NULL, (void * (*)(void *))printsend, (void *)NULL);
|
pthread_create(&printtid, NULL, (void * (*)(void *))printsend, (void *)NULL);
|
||||||
#elif defined _MSC_VER || defined __MINGW32__
|
#elif defined _MSC_VER || defined __MINGW32__
|
||||||
printtid = (HANDLE)_beginthreadex(NULL, 0, (unsigned int (__stdcall *)(void *))printsend,
|
printtid = (HANDLE)_beginthreadex(NULL, 0, (unsigned int (__stdcall *)(void *))printsend,
|
||||||
(void*) NULL, 0, NULL);
|
(void*) NULL, 0, NULL);
|
||||||
|
|
@ -659,7 +711,6 @@ IMPEXP
|
||||||
int ngSpice_Command(char* comexec)
|
int ngSpice_Command(char* comexec)
|
||||||
{
|
{
|
||||||
if ( ! setjmp(errbufc) ) {
|
if ( ! setjmp(errbufc) ) {
|
||||||
// HANDLE tid2;
|
|
||||||
|
|
||||||
immediate = FALSE;
|
immediate = FALSE;
|
||||||
intermj = 1;
|
intermj = 1;
|
||||||
|
|
@ -668,12 +719,9 @@ int ngSpice_Command(char* comexec)
|
||||||
fprintf(stderr, no_init);
|
fprintf(stderr, no_init);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
// tid2 = (HANDLE)_beginthreadex(NULL, 0, (PTHREAD_START_ROUTINE)runc, (void*)comexec,
|
|
||||||
// 0, NULL);
|
|
||||||
runc(comexec);
|
runc(comexec);
|
||||||
/* main thread prepares immediate detaching of dll,
|
/* main thread prepares immediate detaching of dll */
|
||||||
in case of controlled_exit from tid2 thread, caller is asked
|
|
||||||
to detach dll via fcn ngexit() */
|
|
||||||
immediate = TRUE;
|
immediate = TRUE;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -722,6 +770,7 @@ int ngSpice_Circ(char** circa){
|
||||||
|
|
||||||
if ( ! setjmp(errbufm) ) {
|
if ( ! setjmp(errbufm) ) {
|
||||||
intermj = 0;
|
intermj = 0;
|
||||||
|
immediate = FALSE;
|
||||||
/* count the entries */
|
/* count the entries */
|
||||||
while (circa[entries]) {
|
while (circa[entries]) {
|
||||||
entries++;
|
entries++;
|
||||||
|
|
@ -747,7 +796,7 @@ char* ngSpice_CurPlot(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* return to the caller a pointer to an array of all plots created
|
/* return to the caller a pointer to an array of all plots created
|
||||||
by ngspice.dll */
|
by ngspice. Last entry in the array is NULL. */
|
||||||
IMPEXP
|
IMPEXP
|
||||||
char** ngSpice_AllPlots(void)
|
char** ngSpice_AllPlots(void)
|
||||||
{
|
{
|
||||||
|
|
@ -771,7 +820,7 @@ char** ngSpice_AllPlots(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* return to the caller a pointer to an array of vector names in the plot
|
/* return to the caller a pointer to an array of vector names in the plot
|
||||||
named by plotname */
|
named by plotname. Last entry in the array is NULL. */
|
||||||
IMPEXP
|
IMPEXP
|
||||||
char** ngSpice_AllVecs(char* plotname)
|
char** ngSpice_AllVecs(char* plotname)
|
||||||
{
|
{
|
||||||
|
|
@ -805,12 +854,71 @@ char** ngSpice_AllVecs(char* plotname)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static double *bkpttmp = NULL;
|
||||||
|
static int bkpttmpsize = 0;
|
||||||
|
|
||||||
|
/* set a breakpoint in ngspice */
|
||||||
|
IMPEXP
|
||||||
|
bool ngSpice_SetBkpt(double time)
|
||||||
|
{
|
||||||
|
int error;
|
||||||
|
CKTcircuit *ckt = NULL;
|
||||||
|
|
||||||
|
if (!ft_curckt || !ft_curckt->ci_ckt) {
|
||||||
|
fprintf(cp_err, "Error: no circuit loaded.\n");
|
||||||
|
return(FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
ckt = ft_curckt->ci_ckt;
|
||||||
|
if (ckt->CKTbreakSize == 0) {
|
||||||
|
/* breakpoints have not yet been set up, so store here preliminary
|
||||||
|
and add with fcn add_bkpt() called from DCTran()*/
|
||||||
|
if (bkpttmp == NULL) {
|
||||||
|
bkpttmp = TMALLOC(double, bkpttmpsize + 1);
|
||||||
|
if(bkpttmp == NULL)
|
||||||
|
return(FALSE);
|
||||||
|
bkpttmpsize++;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
bkpttmp = TREALLOC(double, bkpttmp, bkpttmpsize + 1);
|
||||||
|
bkpttmpsize++;
|
||||||
|
}
|
||||||
|
bkpttmp[bkpttmpsize-1] = time;
|
||||||
|
error = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
error = CKTsetBreak(ckt, time);
|
||||||
|
if(error)
|
||||||
|
return(FALSE);
|
||||||
|
return(TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* add the preliminary breakpoints to the list.
|
||||||
|
called from dctran.c */
|
||||||
|
int
|
||||||
|
add_bkpt(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int error = 0;
|
||||||
|
CKTcircuit *ckt = ft_curckt->ci_ckt;
|
||||||
|
|
||||||
|
if((bkpttmp) && (bkpttmpsize > 0)) {
|
||||||
|
for (i = 0; i < bkpttmpsize; i++)
|
||||||
|
error = CKTsetBreak(ckt, bkpttmp[i]);
|
||||||
|
FREE(bkpttmp);
|
||||||
|
bkpttmpsize = 0;
|
||||||
|
}
|
||||||
|
if(error)
|
||||||
|
return(error);
|
||||||
|
return(OK);
|
||||||
|
}
|
||||||
|
|
||||||
/*------------------------------------------------------*/
|
/*------------------------------------------------------*/
|
||||||
/* Redefine the vfprintf() functions for callback */
|
/* Redefine the vfprintf() functions for callback */
|
||||||
/*------------------------------------------------------*/
|
/*------------------------------------------------------*/
|
||||||
|
|
||||||
/* handling of escape characters (extra \ added) is removed, may be added by
|
/* handling of escape characters (extra \ added) only, if
|
||||||
un-commenting some lines */
|
'set addescape' is given in .spiceinit */
|
||||||
|
|
||||||
int
|
int
|
||||||
sh_vfprintf(FILE *f, const char *fmt, va_list args)
|
sh_vfprintf(FILE *f, const char *fmt, va_list args)
|
||||||
|
|
@ -889,7 +997,7 @@ sh_vfprintf(FILE *f, const char *fmt, va_list args)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* use sharedspice implementation of fputs (sh_fputs)
|
/* use sharedspice.c implementation of fputs (sh_fputs)
|
||||||
to assess callback function derived from address printfcn received via
|
to assess callback function derived from address printfcn received via
|
||||||
Spice_Init() from caller of ngspice.dll */
|
Spice_Init() from caller of ngspice.dll */
|
||||||
|
|
||||||
|
|
@ -903,9 +1011,10 @@ sh_vfprintf(FILE *f, const char *fmt, va_list args)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------
|
||||||
/* Reimplement fprintf() as a call to callback function pfcn */
|
Reimplement fprintf() as a call to callback function pfcn
|
||||||
/*----------------------------------------------------------------------*/
|
via sh_vfprintf, sh_fputs, and sh_fputsll
|
||||||
|
----------------------------------------------------------------------*/
|
||||||
|
|
||||||
int
|
int
|
||||||
sh_fprintf(FILE *f, const char *format, ...)
|
sh_fprintf(FILE *f, const char *format, ...)
|
||||||
|
|
@ -921,9 +1030,10 @@ sh_fprintf(FILE *f, const char *format, ...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------
|
||||||
/* Reimplement printf() as a call to callback function pfcn */
|
Reimplement printf() as a call to callback function pfcn
|
||||||
/*----------------------------------------------------------------------*/
|
via sh_vfprintf, sh_fputs, and sh_fputsll
|
||||||
|
----------------------------------------------------------------------*/
|
||||||
|
|
||||||
int
|
int
|
||||||
sh_printf(const char *format, ...)
|
sh_printf(const char *format, ...)
|
||||||
|
|
@ -975,9 +1085,9 @@ sh_fputc(const char inp, FILE* f)
|
||||||
static char* outstringerr = NULL;
|
static char* outstringerr = NULL;
|
||||||
static char* outstringout = NULL;
|
static char* outstringout = NULL;
|
||||||
|
|
||||||
#ifdef low_latency
|
#if defined (low_latency) || !defined(THREADS)
|
||||||
/* using the strings by the caller sent directly to the caller
|
/* The strings issued by printf etc. are sent directly to the caller.
|
||||||
has to fast enough (low latency) */
|
The callback has to be fast enough (low latency). */
|
||||||
int
|
int
|
||||||
sh_fputsll(const char *input, FILE* outf)
|
sh_fputsll(const char *input, FILE* outf)
|
||||||
{
|
{
|
||||||
|
|
@ -1065,7 +1175,8 @@ sh_fputsll(const char *input, FILE* outf)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* provide a lock around printing function */
|
/* provide a lock around printing function.
|
||||||
|
May become critical if latency of callback is too high.*/
|
||||||
int
|
int
|
||||||
sh_fputs(const char *input, FILE* outf)
|
sh_fputs(const char *input, FILE* outf)
|
||||||
{
|
{
|
||||||
|
|
@ -1187,6 +1298,8 @@ static char *outsend = NULL;
|
||||||
static void
|
static void
|
||||||
printsend(void)
|
printsend(void)
|
||||||
{
|
{
|
||||||
|
ps_exited = FALSE;
|
||||||
|
printstopp = FALSE;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
#if defined(__MINGW32__) || defined(_MSC_VER)
|
#if defined(__MINGW32__) || defined(_MSC_VER)
|
||||||
Sleep(50); // loop delay
|
Sleep(50); // loop delay
|
||||||
|
|
@ -1198,6 +1311,7 @@ printsend(void)
|
||||||
mutex_lock(&fputsMutex);
|
mutex_lock(&fputsMutex);
|
||||||
outsend = outstorage(NULL, FALSE);
|
outsend = outstorage(NULL, FALSE);
|
||||||
mutex_unlock(&fputsMutex);
|
mutex_unlock(&fputsMutex);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
mutex_lock(&fputsMutex);
|
mutex_lock(&fputsMutex);
|
||||||
|
|
@ -1210,6 +1324,7 @@ printsend(void)
|
||||||
tfree(outsend);
|
tfree(outsend);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ps_exited = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* remove the first entry of a wordlist, but keep wl->wl_word */
|
/* remove the first entry of a wordlist, but keep wl->wl_word */
|
||||||
|
|
@ -1251,13 +1366,14 @@ char* outstorage(char* wordin, bool write)
|
||||||
|
|
||||||
|
|
||||||
/* New progress report to statfcn().
|
/* New progress report to statfcn().
|
||||||
Update only every DELTATIME milliseconds */
|
An update occurs only every DELTATIME milliseconds. */
|
||||||
#define DELTATIME 150
|
#define DELTATIME 150
|
||||||
void SetAnalyse(
|
void SetAnalyse(
|
||||||
char * Analyse, /*in: analysis type */
|
char * Analyse, /*in: analysis type */
|
||||||
int DecaPercent /*in: 10 times the progress [%]*/
|
int DecaPercent /*in: 10 times the progress [%]*/
|
||||||
/*HWND hwAnalyse, in: global handle to analysis window */
|
/*HWND hwAnalyse, in: global handle to analysis window */
|
||||||
) {
|
) {
|
||||||
|
#ifdef HAVE_FTIME
|
||||||
static int OldPercent = -2; /* Previous progress value */
|
static int OldPercent = -2; /* Previous progress value */
|
||||||
static char OldAn[128]; /* Previous analysis type */
|
static char OldAn[128]; /* Previous analysis type */
|
||||||
char* s; /* outputs to callback function */
|
char* s; /* outputs to callback function */
|
||||||
|
|
@ -1321,10 +1437,21 @@ void SetAnalyse(
|
||||||
result = statfcn(s, userptr);
|
result = statfcn(s, userptr);
|
||||||
}
|
}
|
||||||
tfree(s);
|
tfree(s);
|
||||||
|
#else
|
||||||
|
char* s;
|
||||||
|
int result;
|
||||||
|
static bool havesent = FALSE;
|
||||||
|
if (!havesent) {
|
||||||
|
s = copy("No usage info available");
|
||||||
|
result = statfcn(s, userptr);
|
||||||
|
tfree(s);
|
||||||
|
havesent = TRUE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* a dll or shared library should never exit, but ask for graceful shutdown
|
/* a dll or shared library should never exit, if loaded dynamically,
|
||||||
(e.g. being detached) via a callback function*/
|
but ask for graceful shutdown (e.g. being detached) via a callback function*/
|
||||||
void shared_exit(int status)
|
void shared_exit(int status)
|
||||||
{
|
{
|
||||||
/* alert caller to detach dll (if we are in the main thread),
|
/* alert caller to detach dll (if we are in the main thread),
|
||||||
|
|
@ -1364,8 +1491,23 @@ void shared_exit(int status)
|
||||||
tfree(outsend);
|
tfree(outsend);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
// if we are in a worker thread, we exit it here
|
||||||
|
// detaching then has to be done explicitely by the caller
|
||||||
|
if (fl_running && !fl_exited) {
|
||||||
|
fl_exited = TRUE;
|
||||||
|
bgtr(fl_exited, userptr);
|
||||||
|
// set a flag that ngspice wants to be detached
|
||||||
|
ngexit(status, FALSE, coquit, userptr);
|
||||||
|
// finish and exit the worker thread
|
||||||
|
#ifdef HAVE_LIBPTHREAD
|
||||||
|
pthread_exit(1);
|
||||||
|
#elif defined _MSC_VER || defined __MINGW32__
|
||||||
|
_endthreadex(1);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
// set a flag in caller to detach ngspice.dll
|
// set a flag in caller to detach ngspice.dll
|
||||||
ngexit(status, immediate, coquit, userptr);
|
ngexit(status, immediate, coquit, userptr);
|
||||||
|
|
||||||
// jump back to finish the calling function
|
// jump back to finish the calling function
|
||||||
if (!intermj)
|
if (!intermj)
|
||||||
longjmp(errbufm,1); /* jump back to ngSpice_Circ() */
|
longjmp(errbufm,1); /* jump back to ngSpice_Circ() */
|
||||||
|
|
@ -1448,7 +1590,7 @@ int sh_ExecutePerLoop(void)
|
||||||
{
|
{
|
||||||
struct dvec *d;
|
struct dvec *d;
|
||||||
int i, veclen;
|
int i, veclen;
|
||||||
double testval;
|
// double testval;
|
||||||
struct plot *pl = plot_cur;
|
struct plot *pl = plot_cur;
|
||||||
/* return immediately if callback not wanted */
|
/* return immediately if callback not wanted */
|
||||||
if (nodatawanted)
|
if (nodatawanted)
|
||||||
|
|
@ -1456,11 +1598,12 @@ int sh_ExecutePerLoop(void)
|
||||||
|
|
||||||
/* get the data of the last entry to the plot vector */
|
/* get the data of the last entry to the plot vector */
|
||||||
veclen = pl->pl_dvecs->v_length - 1;
|
veclen = pl->pl_dvecs->v_length - 1;
|
||||||
|
curvecvalsall->vecindex = veclen;
|
||||||
for (d = pl->pl_dvecs, i = 0; d; d = d->v_next, i++) {
|
for (d = pl->pl_dvecs, i = 0; d; d = d->v_next, i++) {
|
||||||
/* test if real */
|
/* test if real */
|
||||||
if (d->v_flags & VF_REAL) {
|
if (d->v_flags & VF_REAL) {
|
||||||
curvecvalsall->vecsa[i]->is_complex = FALSE;
|
curvecvalsall->vecsa[i]->is_complex = FALSE;
|
||||||
testval = d->v_realdata[veclen];
|
// testval = d->v_realdata[veclen];
|
||||||
curvecvalsall->vecsa[i]->creal = d->v_realdata[veclen];
|
curvecvalsall->vecsa[i]->creal = d->v_realdata[veclen];
|
||||||
curvecvalsall->vecsa[i]->cimag = 0.;
|
curvecvalsall->vecsa[i]->cimag = 0.;
|
||||||
}
|
}
|
||||||
|
|
@ -1478,7 +1621,7 @@ int sh_ExecutePerLoop(void)
|
||||||
|
|
||||||
|
|
||||||
/* called once for a new plot from beginPlot() in outitf.c,
|
/* called once for a new plot from beginPlot() in outitf.c,
|
||||||
after the vectors in ngspice have been set.
|
after the vectors in ngspice for this plot have been set.
|
||||||
Transfers vector information to the caller via callback datinitfcn()
|
Transfers vector information to the caller via callback datinitfcn()
|
||||||
and sets transfer structure for use in sh_ExecutePerLoop() */
|
and sets transfer structure for use in sh_ExecutePerLoop() */
|
||||||
int sh_vecinit(runDesc *run)
|
int sh_vecinit(runDesc *run)
|
||||||
|
|
@ -1536,14 +1679,13 @@ int sh_vecinit(runDesc *run)
|
||||||
data will be sent from sh_ExecutePerLoop() via datfcn() */
|
data will be sent from sh_ExecutePerLoop() via datfcn() */
|
||||||
if (!curvecvalsall) {
|
if (!curvecvalsall) {
|
||||||
curvecvalsall = TMALLOC(vecvaluesall, 1);
|
curvecvalsall = TMALLOC(vecvaluesall, 1);
|
||||||
curvecvalsall->veccount = veccount;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for (i = 0; i < curvecvalsall->veccount; i++)
|
for (i = 0; i < curvecvalsall->veccount; i++)
|
||||||
tfree(curvecvalsall->vecsa[i]);
|
tfree(curvecvalsall->vecsa[i]);
|
||||||
tfree(curvecvalsall->vecsa);
|
tfree(curvecvalsall->vecsa);
|
||||||
}
|
}
|
||||||
|
curvecvalsall->veccount = veccount;
|
||||||
curvecvalsall->vecsa = TMALLOC(pvecvalues, veccount);
|
curvecvalsall->vecsa = TMALLOC(pvecvalues, veccount);
|
||||||
|
|
||||||
for (i = 0, d = cur_run->runPlot->pl_dvecs; i < veccount; i++, d = d->v_next) {
|
for (i = 0, d = cur_run->runPlot->pl_dvecs; i < veccount; i++, d = d->v_next) {
|
||||||
|
|
@ -1557,3 +1699,18 @@ int sh_vecinit(runDesc *run)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* issue callback to request external voltage data for source vname*/
|
||||||
|
double getvsrcval(double time, char* vname)
|
||||||
|
{
|
||||||
|
double vval;
|
||||||
|
if (!wantvdat) {
|
||||||
|
fprintf(stderr, "Error: No callback supplied for source %s\n", vname);
|
||||||
|
shared_exit(EXIT_BAD);
|
||||||
|
return(EXIT_BAD);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* callback fcn */
|
||||||
|
getvdat(&vval, time, vname, userptr);
|
||||||
|
return vval;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -107,6 +107,10 @@ libckt_la_SOURCES += \
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
if KIRCHHOFF_WANTED
|
||||||
|
libckt_la_SOURCES += cktmkcurKCL.c
|
||||||
|
endif
|
||||||
|
|
||||||
AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(top_srcdir)/src/include -I$(top_srcdir)/src/spicelib/devices
|
AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(top_srcdir)/src/include -I$(top_srcdir)/src/spicelib/devices
|
||||||
AM_CFLAGS = $(STATIC)
|
AM_CFLAGS = $(STATIC)
|
||||||
MAINTAINERCLEANFILES = Makefile.in
|
MAINTAINERCLEANFILES = Makefile.in
|
||||||
|
|
|
||||||
|
|
@ -149,11 +149,11 @@ ACan(CKTcircuit *ckt, int restart)
|
||||||
* Moreover the begin plot has not even been done yet at this
|
* Moreover the begin plot has not even been done yet at this
|
||||||
* point...
|
* point...
|
||||||
*/
|
*/
|
||||||
SPfrontEnd->OUTpBeginPlot (
|
SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
|
||||||
ckt, ckt->CKTcurJob,
|
ckt->CKTcurJob->JOBname,
|
||||||
ckt->CKTcurJob->JOBname,
|
NULL, IF_REAL,
|
||||||
NULL, IF_REAL,
|
numNames, nameList, IF_REAL,
|
||||||
numNames, nameList, IF_REAL, &acPlot);
|
&acPlot);
|
||||||
tfree(nameList);
|
tfree(nameList);
|
||||||
|
|
||||||
ipc_send_dcop_prefix();
|
ipc_send_dcop_prefix();
|
||||||
|
|
@ -174,30 +174,28 @@ ACan(CKTcircuit *ckt, int restart)
|
||||||
|
|
||||||
if (ckt->CKTkeepOpInfo) {
|
if (ckt->CKTkeepOpInfo) {
|
||||||
/* Dump operating point. */
|
/* Dump operating point. */
|
||||||
error = SPfrontEnd->OUTpBeginPlot (
|
error = SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
|
||||||
ckt, ckt->CKTcurJob,
|
"AC Operating Point",
|
||||||
"AC Operating Point",
|
NULL, IF_REAL,
|
||||||
NULL, IF_REAL,
|
numNames, nameList, IF_REAL,
|
||||||
numNames, nameList, IF_REAL, &plot);
|
&plot);
|
||||||
if(error) return(error);
|
if(error) return(error);
|
||||||
CKTdump(ckt, 0.0, plot);
|
CKTdump(ckt, 0.0, plot);
|
||||||
SPfrontEnd->OUTendPlot (plot);
|
SPfrontEnd->OUTendPlot (plot);
|
||||||
plot = NULL;
|
plot = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
SPfrontEnd->IFnewUid (ckt, &freqUid, NULL,
|
SPfrontEnd->IFnewUid (ckt, &freqUid, NULL, "frequency", UID_OTHER, NULL);
|
||||||
"frequency", UID_OTHER, NULL);
|
error = SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
|
||||||
error = SPfrontEnd->OUTpBeginPlot (
|
ckt->CKTcurJob->JOBname,
|
||||||
ckt, ckt->CKTcurJob,
|
freqUid, IF_REAL,
|
||||||
ckt->CKTcurJob->JOBname,
|
numNames, nameList, IF_COMPLEX,
|
||||||
freqUid, IF_REAL,
|
&acPlot);
|
||||||
numNames, nameList, IF_COMPLEX, &acPlot);
|
|
||||||
tfree(nameList);
|
tfree(nameList);
|
||||||
if(error) return(error);
|
if(error) return(error);
|
||||||
|
|
||||||
if (job->ACstepType != LINEAR) {
|
if (job->ACstepType != LINEAR) {
|
||||||
SPfrontEnd->OUTattributes (acPlot, NULL,
|
SPfrontEnd->OUTattributes (acPlot, NULL, OUT_SCALE_LOG, NULL);
|
||||||
OUT_SCALE_LOG, NULL);
|
|
||||||
}
|
}
|
||||||
freq = job->ACstartFreq;
|
freq = job->ACstartFreq;
|
||||||
|
|
||||||
|
|
@ -205,11 +203,11 @@ ACan(CKTcircuit *ckt, int restart)
|
||||||
freq = job->ACsaveFreq;
|
freq = job->ACsaveFreq;
|
||||||
job->ACsaveFreq = 0; /* clear the 'old' frequency */
|
job->ACsaveFreq = 0; /* clear the 'old' frequency */
|
||||||
/* fix resume? saj, indeed !*/
|
/* fix resume? saj, indeed !*/
|
||||||
error = SPfrontEnd->OUTpBeginPlot (
|
error = SPfrontEnd->OUTpBeginPlot (NULL, NULL,
|
||||||
NULL, NULL,
|
NULL,
|
||||||
NULL,
|
NULL, 0,
|
||||||
NULL, 0,
|
666, NULL, 666,
|
||||||
666, NULL, 666, &acPlot);
|
&acPlot);
|
||||||
/* saj*/
|
/* saj*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,10 @@ extern SPICEanalysis SENSinfo;
|
||||||
extern SPICEanalysis PSSinfo;
|
extern SPICEanalysis PSSinfo;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef WANT_SENSE2
|
||||||
|
extern SPICEanalysis SEN2info;
|
||||||
|
#endif
|
||||||
|
|
||||||
SPICEanalysis *analInfo[] = {
|
SPICEanalysis *analInfo[] = {
|
||||||
&OPTinfo,
|
&OPTinfo,
|
||||||
&ACinfo,
|
&ACinfo,
|
||||||
|
|
@ -34,6 +38,9 @@ SPICEanalysis *analInfo[] = {
|
||||||
#ifdef WITH_PSS
|
#ifdef WITH_PSS
|
||||||
&PSSinfo,
|
&PSSinfo,
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef WANT_SENSE2
|
||||||
|
&SEN2info,
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,11 @@ CKTload(CKTcircuit *ckt)
|
||||||
size = SMPmatSize(ckt->CKTmatrix);
|
size = SMPmatSize(ckt->CKTmatrix);
|
||||||
for (i = 0; i <= size; i++) {
|
for (i = 0; i <= size; i++) {
|
||||||
ckt->CKTrhs[i] = 0;
|
ckt->CKTrhs[i] = 0;
|
||||||
|
|
||||||
|
#ifdef KIRCHHOFF
|
||||||
|
ckt->CKTfvk[i] = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
SMPclear(ckt->CKTmatrix);
|
SMPclear(ckt->CKTmatrix);
|
||||||
#ifdef STEPDEBUG
|
#ifdef STEPDEBUG
|
||||||
|
|
|
||||||
|
|
@ -35,12 +35,8 @@ CKTmapNode(CKTcircuit *ckt, CKTnode **node, IFuid name)
|
||||||
/* not found, so must be a new one */
|
/* not found, so must be a new one */
|
||||||
error = CKTmkNode(ckt,&mynode); /*allocate the node*/
|
error = CKTmkNode(ckt,&mynode); /*allocate the node*/
|
||||||
if(error) return(error);
|
if(error) return(error);
|
||||||
error = SPfrontEnd->IFnewUid (ckt,
|
/* get a uid for it */
|
||||||
&uid,
|
error = SPfrontEnd->IFnewUid (ckt, &uid, NULL, name, UID_SIGNAL, &mynode);
|
||||||
NULL,
|
|
||||||
name,
|
|
||||||
UID_SIGNAL,
|
|
||||||
&mynode); /* get a uid for it */
|
|
||||||
if(error) return(error);
|
if(error) return(error);
|
||||||
mynode->name = uid; /* set the info we have */
|
mynode->name = uid; /* set the info we have */
|
||||||
mynode->type = SP_VOLTAGE;
|
mynode->type = SP_VOLTAGE;
|
||||||
|
|
|
||||||
|
|
@ -29,8 +29,7 @@ CKTmkCur(CKTcircuit *ckt, CKTnode **node, IFuid basename, char *suffix)
|
||||||
error = CKTmkNode(ckt,&mynode);
|
error = CKTmkNode(ckt,&mynode);
|
||||||
if(error) return(error);
|
if(error) return(error);
|
||||||
checknode = mynode;
|
checknode = mynode;
|
||||||
error = SPfrontEnd->IFnewUid (ckt, &uid, basename,
|
error = SPfrontEnd->IFnewUid (ckt, &uid, basename, suffix, UID_SIGNAL, &checknode);
|
||||||
suffix, UID_SIGNAL, &checknode);
|
|
||||||
if(error) {
|
if(error) {
|
||||||
FREE(mynode);
|
FREE(mynode);
|
||||||
if(node) *node = checknode;
|
if(node) *node = checknode;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
/**********
|
||||||
|
Author: 2013 Francesco Lannutti
|
||||||
|
**********/
|
||||||
|
|
||||||
|
#include "ngspice/ngspice.h"
|
||||||
|
#include "ngspice/sperror.h"
|
||||||
|
#include "ngspice/cktdefs.h"
|
||||||
|
|
||||||
|
int
|
||||||
|
CKTmkCurKCL (CKTcircuit *ckt, int i, double **node)
|
||||||
|
{
|
||||||
|
CKTmkCurKCLnode *tempNode ;
|
||||||
|
|
||||||
|
tempNode = TMALLOC (CKTmkCurKCLnode, 1) ;
|
||||||
|
tempNode->KCLcurrent = 0.0 ;
|
||||||
|
tempNode->next = ckt->CKTmkCurKCLarray [i] ;
|
||||||
|
ckt->CKTmkCurKCLarray [i] = tempNode ;
|
||||||
|
*node = &(tempNode->KCLcurrent) ;
|
||||||
|
|
||||||
|
return (OK) ;
|
||||||
|
}
|
||||||
|
|
@ -26,7 +26,7 @@ CKTmkNode(CKTcircuit *ckt, CKTnode **node)
|
||||||
mynode = TMALLOC(CKTnode, 1);
|
mynode = TMALLOC(CKTnode, 1);
|
||||||
if(mynode == NULL) return(E_NOMEM);
|
if(mynode == NULL) return(E_NOMEM);
|
||||||
mynode->next = NULL;
|
mynode->next = NULL;
|
||||||
mynode->name = (IFuid) 0;
|
mynode->name = NULL;
|
||||||
|
|
||||||
if(node) *node = mynode;
|
if(node) *node = mynode;
|
||||||
return(OK);
|
return(OK);
|
||||||
|
|
|
||||||
|
|
@ -27,8 +27,7 @@ CKTmkVolt(CKTcircuit *ckt, CKTnode **node, IFuid basename, char *suffix)
|
||||||
error = CKTmkNode(ckt,&mynode);
|
error = CKTmkNode(ckt,&mynode);
|
||||||
if(error) return(error);
|
if(error) return(error);
|
||||||
checknode = mynode;
|
checknode = mynode;
|
||||||
error = SPfrontEnd->IFnewUid (ckt, &uid, basename,
|
error = SPfrontEnd->IFnewUid (ckt, &uid, basename, suffix, UID_SIGNAL, &checknode);
|
||||||
suffix, UID_SIGNAL, &checknode);
|
|
||||||
if(error) {
|
if(error) {
|
||||||
FREE(mynode);
|
FREE(mynode);
|
||||||
if(node) *node = checknode;
|
if(node) *node = checknode;
|
||||||
|
|
|
||||||
|
|
@ -56,12 +56,12 @@ CKTnoise (CKTcircuit *ckt, int mode, int operation, Ndata *data)
|
||||||
data->namelist = TREALLOC(IFuid, data->namelist, data->numPlots + 1);
|
data->namelist = TREALLOC(IFuid, data->namelist, data->numPlots + 1);
|
||||||
|
|
||||||
SPfrontEnd->IFnewUid (ckt, &(data->namelist[data->numPlots++]),
|
SPfrontEnd->IFnewUid (ckt, &(data->namelist[data->numPlots++]),
|
||||||
NULL, "onoise_spectrum", UID_OTHER, NULL);
|
NULL, "onoise_spectrum", UID_OTHER, NULL);
|
||||||
|
|
||||||
data->namelist = TREALLOC(IFuid, data->namelist, data->numPlots + 1);
|
data->namelist = TREALLOC(IFuid, data->namelist, data->numPlots + 1);
|
||||||
|
|
||||||
SPfrontEnd->IFnewUid (ckt, &(data->namelist[data->numPlots++]),
|
SPfrontEnd->IFnewUid (ckt, &(data->namelist[data->numPlots++]),
|
||||||
NULL, "inoise_spectrum", UID_OTHER, NULL);
|
NULL, "inoise_spectrum", UID_OTHER, NULL);
|
||||||
|
|
||||||
/* we've added two more plots */
|
/* we've added two more plots */
|
||||||
|
|
||||||
|
|
@ -73,11 +73,11 @@ CKTnoise (CKTcircuit *ckt, int mode, int operation, Ndata *data)
|
||||||
|
|
||||||
data->namelist = TREALLOC(IFuid, data->namelist, data->numPlots + 1);
|
data->namelist = TREALLOC(IFuid, data->namelist, data->numPlots + 1);
|
||||||
SPfrontEnd->IFnewUid (ckt, &(data->namelist[data->numPlots++]),
|
SPfrontEnd->IFnewUid (ckt, &(data->namelist[data->numPlots++]),
|
||||||
NULL, "onoise_total", UID_OTHER, NULL);
|
NULL, "onoise_total", UID_OTHER, NULL);
|
||||||
|
|
||||||
data->namelist = TREALLOC(IFuid, data->namelist, data->numPlots + 1);
|
data->namelist = TREALLOC(IFuid, data->namelist, data->numPlots + 1);
|
||||||
SPfrontEnd->IFnewUid (ckt, &(data->namelist[data->numPlots++]),
|
SPfrontEnd->IFnewUid (ckt, &(data->namelist[data->numPlots++]),
|
||||||
NULL, "inoise_total", UID_OTHER, NULL);
|
NULL, "inoise_total", UID_OTHER, NULL);
|
||||||
/* we've added two more plots */
|
/* we've added two more plots */
|
||||||
|
|
||||||
data->outpVector =
|
data->outpVector =
|
||||||
|
|
|
||||||
|
|
@ -21,61 +21,60 @@ int
|
||||||
CKTop (CKTcircuit * ckt, long int firstmode, long int continuemode,
|
CKTop (CKTcircuit * ckt, long int firstmode, long int continuemode,
|
||||||
int iterlim)
|
int iterlim)
|
||||||
{
|
{
|
||||||
int converged;
|
int converged;
|
||||||
#ifdef HAS_PROGREP
|
#ifdef HAS_PROGREP
|
||||||
SetAnalyse("op", 0);
|
SetAnalyse("op", 0);
|
||||||
#endif
|
#endif
|
||||||
ckt->CKTmode = firstmode;
|
ckt->CKTmode = firstmode;
|
||||||
|
|
||||||
if (!ckt->CKTnoOpIter){
|
if (!ckt->CKTnoOpIter) {
|
||||||
#ifdef XSPICE
|
#ifdef XSPICE
|
||||||
/* gtri - begin - wbk - add convergence problem reporting flags */
|
/* gtri - begin - wbk - add convergence problem reporting flags */
|
||||||
if ((ckt->CKTnumGminSteps <= 0) && (ckt->CKTnumSrcSteps <= 0))
|
if ((ckt->CKTnumGminSteps <= 0) && (ckt->CKTnumSrcSteps <= 0))
|
||||||
ckt->enh->conv_debug.last_NIiter_call = MIF_TRUE;
|
ckt->enh->conv_debug.last_NIiter_call = MIF_TRUE;
|
||||||
else
|
else
|
||||||
ckt->enh->conv_debug.last_NIiter_call = MIF_FALSE;
|
ckt->enh->conv_debug.last_NIiter_call = MIF_FALSE;
|
||||||
/* gtri - end - wbk - add convergence problem reporting flags */
|
/* gtri - end - wbk - add convergence problem reporting flags */
|
||||||
#endif
|
#endif
|
||||||
converged = NIiter (ckt, iterlim);
|
converged = NIiter (ckt, iterlim);
|
||||||
} else {
|
} else {
|
||||||
converged = 1; /* the 'go directly to gmin stepping' option */
|
converged = 1; /* the 'go directly to gmin stepping' option */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (converged != 0)
|
if (converged != 0) {
|
||||||
{
|
/* no convergence on the first try, so we do something else */
|
||||||
/* no convergence on the first try, so we do something else */
|
/* first, check if we should try gmin stepping */
|
||||||
/* first, check if we should try gmin stepping */
|
|
||||||
|
|
||||||
if (ckt->CKTnumGminSteps >= 1){
|
if (ckt->CKTnumGminSteps >= 1) {
|
||||||
if (ckt->CKTnumGminSteps == 1)
|
if (ckt->CKTnumGminSteps == 1)
|
||||||
converged = dynamic_gmin(ckt, firstmode, continuemode, iterlim);
|
converged = dynamic_gmin(ckt, firstmode, continuemode, iterlim);
|
||||||
else
|
else
|
||||||
converged = spice3_gmin(ckt, firstmode, continuemode, iterlim);
|
converged = spice3_gmin(ckt, firstmode, continuemode, iterlim);
|
||||||
}
|
}
|
||||||
if (!converged) /* If gmin-stepping worked... move out */
|
if (!converged) /* If gmin-stepping worked... move out */
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
/* ... otherwise try stepping sources ...
|
/* ... otherwise try stepping sources ...
|
||||||
* now, we'll try source stepping - we scale the sources
|
* now, we'll try source stepping - we scale the sources
|
||||||
* to 0, converge, then start stepping them up until they
|
* to 0, converge, then start stepping them up until they
|
||||||
* are at their normal values
|
* are at their normal values
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (ckt->CKTnumSrcSteps >= 1){
|
if (ckt->CKTnumSrcSteps >= 1) {
|
||||||
if (ckt->CKTnumSrcSteps == 1)
|
if (ckt->CKTnumSrcSteps == 1)
|
||||||
converged = gillespie_src(ckt, firstmode, continuemode, iterlim);
|
converged = gillespie_src(ckt, firstmode, continuemode, iterlim);
|
||||||
else
|
else
|
||||||
converged = spice3_src(ckt, firstmode, continuemode, iterlim);
|
converged = spice3_src(ckt, firstmode, continuemode, iterlim);
|
||||||
}
|
}
|
||||||
#ifdef XSPICE
|
#ifdef XSPICE
|
||||||
/* gtri - begin - wbk - add convergence problem reporting flags */
|
/* gtri - begin - wbk - add convergence problem reporting flags */
|
||||||
ckt->enh->conv_debug.last_NIiter_call = MIF_FALSE;
|
ckt->enh->conv_debug.last_NIiter_call = MIF_FALSE;
|
||||||
/* gtri - end - wbk - add convergence problem reporting flags */
|
/* gtri - end - wbk - add convergence problem reporting flags */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
return (converged);
|
return (converged);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -93,18 +92,15 @@ CKTconvTest (CKTcircuit * ckt)
|
||||||
int i;
|
int i;
|
||||||
int error = OK;
|
int error = OK;
|
||||||
|
|
||||||
for (i = 0; i < DEVmaxnum; i++)
|
for (i = 0; i < DEVmaxnum; i++) {
|
||||||
{
|
if (DEVices[i] && DEVices[i]->DEVconvTest && ckt->CKThead[i]) {
|
||||||
if (DEVices[i] && DEVices[i]->DEVconvTest && ckt->CKThead[i])
|
|
||||||
{
|
|
||||||
error = DEVices[i]->DEVconvTest (ckt->CKThead[i], ckt);
|
error = DEVices[i]->DEVconvTest (ckt->CKThead[i], ckt);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error)
|
if (error)
|
||||||
return (error);
|
return (error);
|
||||||
|
|
||||||
if (ckt->CKTnoncon)
|
if (ckt->CKTnoncon) {
|
||||||
{
|
|
||||||
/* printf("convTest: device %s failed\n",
|
/* printf("convTest: device %s failed\n",
|
||||||
* DEVices[i]->DEVpublic.name); */
|
* DEVices[i]->DEVpublic.name); */
|
||||||
return (OK);
|
return (OK);
|
||||||
|
|
@ -129,140 +125,140 @@ CKTconvTest (CKTcircuit * ckt)
|
||||||
|
|
||||||
static int
|
static int
|
||||||
dynamic_gmin (CKTcircuit * ckt, long int firstmode,
|
dynamic_gmin (CKTcircuit * ckt, long int firstmode,
|
||||||
long int continuemode, int iterlim)
|
long int continuemode, int iterlim)
|
||||||
{
|
{
|
||||||
double OldGmin, gtarget, factor;
|
double OldGmin, gtarget, factor;
|
||||||
int success, failed, converged;
|
int success, failed, converged;
|
||||||
|
|
||||||
int NumNodes, iters, i;
|
int NumNodes, iters, i;
|
||||||
double *OldRhsOld, *OldCKTstate0;
|
double *OldRhsOld, *OldCKTstate0;
|
||||||
CKTnode *n;
|
CKTnode *n;
|
||||||
|
|
||||||
ckt->CKTmode = firstmode;
|
ckt->CKTmode = firstmode;
|
||||||
SPfrontEnd->IFerror (ERR_INFO,
|
SPfrontEnd->IFerror (ERR_INFO,
|
||||||
"Starting dynamic gmin stepping", NULL);
|
"Starting dynamic gmin stepping", NULL);
|
||||||
|
|
||||||
NumNodes = 0;
|
NumNodes = 0;
|
||||||
for (n = ckt->CKTnodes; n; n = n->next)
|
for (n = ckt->CKTnodes; n; n = n->next)
|
||||||
NumNodes++;
|
NumNodes++;
|
||||||
|
|
||||||
OldRhsOld = TMALLOC(double, NumNodes + 1);
|
OldRhsOld = TMALLOC(double, NumNodes + 1);
|
||||||
OldCKTstate0 =
|
OldCKTstate0 =
|
||||||
TMALLOC(double, ckt->CKTnumStates + 1);
|
TMALLOC(double, ckt->CKTnumStates + 1);
|
||||||
|
|
||||||
for (n = ckt->CKTnodes; n; n = n->next)
|
for (n = ckt->CKTnodes; n; n = n->next)
|
||||||
ckt->CKTrhsOld [n->number] = 0;
|
ckt->CKTrhsOld [n->number] = 0;
|
||||||
|
|
||||||
for (i = 0; i < ckt->CKTnumStates; i++)
|
for (i = 0; i < ckt->CKTnumStates; i++)
|
||||||
ckt->CKTstate0 [i] = 0;
|
ckt->CKTstate0 [i] = 0;
|
||||||
|
|
||||||
factor = ckt->CKTgminFactor;
|
factor = ckt->CKTgminFactor;
|
||||||
OldGmin = 1e-2;
|
OldGmin = 1e-2;
|
||||||
ckt->CKTdiagGmin = OldGmin / factor;
|
ckt->CKTdiagGmin = OldGmin / factor;
|
||||||
gtarget = MAX (ckt->CKTgmin, ckt->CKTgshunt);
|
gtarget = MAX (ckt->CKTgmin, ckt->CKTgshunt);
|
||||||
success = failed = 0;
|
success = failed = 0;
|
||||||
|
|
||||||
while ((!success) && (!failed)){
|
while ((!success) && (!failed)) {
|
||||||
fprintf (stderr, "Trying gmin = %12.4E ", ckt->CKTdiagGmin);
|
fprintf (stderr, "Trying gmin = %12.4E ", ckt->CKTdiagGmin);
|
||||||
ckt->CKTnoncon = 1;
|
ckt->CKTnoncon = 1;
|
||||||
iters = ckt->CKTstat->STATnumIter;
|
iters = ckt->CKTstat->STATnumIter;
|
||||||
|
|
||||||
converged = NIiter (ckt, ckt->CKTdcTrcvMaxIter);
|
converged = NIiter (ckt, ckt->CKTdcTrcvMaxIter);
|
||||||
iters = (ckt->CKTstat->STATnumIter) - iters;
|
iters = (ckt->CKTstat->STATnumIter) - iters;
|
||||||
|
|
||||||
if (converged == 0){
|
if (converged == 0) {
|
||||||
ckt->CKTmode = continuemode;
|
ckt->CKTmode = continuemode;
|
||||||
SPfrontEnd->IFerror (ERR_INFO,
|
SPfrontEnd->IFerror (ERR_INFO,
|
||||||
"One successful gmin step", NULL);
|
"One successful gmin step", NULL);
|
||||||
|
|
||||||
if (ckt->CKTdiagGmin <= gtarget){
|
if (ckt->CKTdiagGmin <= gtarget) {
|
||||||
success = 1;
|
success = 1;
|
||||||
} else {
|
} else {
|
||||||
i = 0;
|
i = 0;
|
||||||
for (n = ckt->CKTnodes; n; n = n->next){
|
for (n = ckt->CKTnodes; n; n = n->next) {
|
||||||
OldRhsOld[i] = ckt->CKTrhsOld[n->number];
|
OldRhsOld[i] = ckt->CKTrhsOld[n->number];
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < ckt->CKTnumStates; i++){
|
for (i = 0; i < ckt->CKTnumStates; i++) {
|
||||||
OldCKTstate0[i] = ckt->CKTstate0[i];
|
OldCKTstate0[i] = ckt->CKTstate0[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iters <= (ckt->CKTdcTrcvMaxIter / 4)){
|
if (iters <= (ckt->CKTdcTrcvMaxIter / 4)) {
|
||||||
factor *= sqrt (factor);
|
factor *= sqrt (factor);
|
||||||
if (factor > ckt->CKTgminFactor)
|
if (factor > ckt->CKTgminFactor)
|
||||||
factor = ckt->CKTgminFactor;
|
factor = ckt->CKTgminFactor;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iters > (3 * ckt->CKTdcTrcvMaxIter / 4))
|
if (iters > (3 * ckt->CKTdcTrcvMaxIter / 4))
|
||||||
factor = sqrt (factor);
|
factor = sqrt (factor);
|
||||||
|
|
||||||
OldGmin = ckt->CKTdiagGmin;
|
OldGmin = ckt->CKTdiagGmin;
|
||||||
|
|
||||||
if ((ckt->CKTdiagGmin) < (factor * gtarget)){
|
if ((ckt->CKTdiagGmin) < (factor * gtarget)) {
|
||||||
factor = ckt->CKTdiagGmin / gtarget;
|
factor = ckt->CKTdiagGmin / gtarget;
|
||||||
ckt->CKTdiagGmin = gtarget;
|
ckt->CKTdiagGmin = gtarget;
|
||||||
} else {
|
} else {
|
||||||
ckt->CKTdiagGmin /= factor;
|
ckt->CKTdiagGmin /= factor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (factor < 1.00005){
|
if (factor < 1.00005) {
|
||||||
failed = 1;
|
failed = 1;
|
||||||
SPfrontEnd->IFerror (ERR_WARNING,
|
SPfrontEnd->IFerror (ERR_WARNING,
|
||||||
"Last gmin step failed",
|
"Last gmin step failed",
|
||||||
NULL);
|
NULL);
|
||||||
} else {
|
} else {
|
||||||
SPfrontEnd->IFerror (ERR_WARNING,
|
SPfrontEnd->IFerror (ERR_WARNING,
|
||||||
"Further gmin increment",
|
"Further gmin increment",
|
||||||
NULL);
|
NULL);
|
||||||
factor = sqrt (sqrt (factor));
|
factor = sqrt (sqrt (factor));
|
||||||
ckt->CKTdiagGmin = OldGmin / factor;
|
ckt->CKTdiagGmin = OldGmin / factor;
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
for (n = ckt->CKTnodes; n; n = n->next){
|
for (n = ckt->CKTnodes; n; n = n->next) {
|
||||||
ckt->CKTrhsOld[n->number] = OldRhsOld[i];
|
ckt->CKTrhsOld[n->number] = OldRhsOld[i];
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < ckt->CKTnumStates; i++){
|
for (i = 0; i < ckt->CKTnumStates; i++) {
|
||||||
ckt->CKTstate0[i] = OldCKTstate0[i];
|
ckt->CKTstate0[i] = OldCKTstate0[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ckt->CKTdiagGmin = ckt->CKTgshunt;
|
ckt->CKTdiagGmin = ckt->CKTgshunt;
|
||||||
FREE (OldRhsOld);
|
FREE (OldRhsOld);
|
||||||
FREE (OldCKTstate0);
|
FREE (OldCKTstate0);
|
||||||
|
|
||||||
#ifdef XSPICE
|
#ifdef XSPICE
|
||||||
/* gtri - begin - wbk - add convergence problem reporting flags */
|
/* gtri - begin - wbk - add convergence problem reporting flags */
|
||||||
if (ckt->CKTnumSrcSteps <= 0)
|
if (ckt->CKTnumSrcSteps <= 0)
|
||||||
ckt->enh->conv_debug.last_NIiter_call = MIF_TRUE;
|
ckt->enh->conv_debug.last_NIiter_call = MIF_TRUE;
|
||||||
else
|
else
|
||||||
ckt->enh->conv_debug.last_NIiter_call = MIF_FALSE;
|
ckt->enh->conv_debug.last_NIiter_call = MIF_FALSE;
|
||||||
/* gtri - end - wbk - add convergence problem reporting flags */
|
/* gtri - end - wbk - add convergence problem reporting flags */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
converged = NIiter (ckt, iterlim);
|
converged = NIiter (ckt, iterlim);
|
||||||
|
|
||||||
if (converged != 0){
|
if (converged != 0) {
|
||||||
SPfrontEnd->IFerror (ERR_WARNING,
|
SPfrontEnd->IFerror (ERR_WARNING,
|
||||||
"Dynamic gmin stepping failed",
|
"Dynamic gmin stepping failed",
|
||||||
NULL);
|
NULL);
|
||||||
} else {
|
} else {
|
||||||
SPfrontEnd->IFerror (ERR_INFO,
|
SPfrontEnd->IFerror (ERR_INFO,
|
||||||
"Dynamic gmin stepping completed",
|
"Dynamic gmin stepping completed",
|
||||||
NULL);
|
NULL);
|
||||||
#ifdef XSPICE
|
#ifdef XSPICE
|
||||||
/* gtri - begin - wbk - add convergence problem reporting flags */
|
/* gtri - begin - wbk - add convergence problem reporting flags */
|
||||||
ckt->enh->conv_debug.last_NIiter_call = MIF_FALSE;
|
ckt->enh->conv_debug.last_NIiter_call = MIF_FALSE;
|
||||||
/* gtri - end - wbk - add convergence problem reporting flags */
|
/* gtri - end - wbk - add convergence problem reporting flags */
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
return (converged);
|
return (converged);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -280,72 +276,72 @@ dynamic_gmin (CKTcircuit * ckt, long int firstmode,
|
||||||
|
|
||||||
static int
|
static int
|
||||||
spice3_gmin (CKTcircuit * ckt, long int firstmode,
|
spice3_gmin (CKTcircuit * ckt, long int firstmode,
|
||||||
long int continuemode, int iterlim)
|
long int continuemode, int iterlim)
|
||||||
{
|
{
|
||||||
|
|
||||||
int converged, i;
|
int converged, i;
|
||||||
|
|
||||||
ckt->CKTmode = firstmode;
|
ckt->CKTmode = firstmode;
|
||||||
SPfrontEnd->IFerror (ERR_INFO,
|
SPfrontEnd->IFerror (ERR_INFO,
|
||||||
"Starting gmin stepping", NULL);
|
"Starting gmin stepping", NULL);
|
||||||
|
|
||||||
if (ckt->CKTgshunt == 0)
|
if (ckt->CKTgshunt == 0)
|
||||||
ckt->CKTdiagGmin = ckt->CKTgmin;
|
ckt->CKTdiagGmin = ckt->CKTgmin;
|
||||||
else
|
else
|
||||||
ckt->CKTdiagGmin = ckt->CKTgshunt;
|
ckt->CKTdiagGmin = ckt->CKTgshunt;
|
||||||
|
|
||||||
for (i = 0; i < ckt->CKTnumGminSteps; i++)
|
for (i = 0; i < ckt->CKTnumGminSteps; i++)
|
||||||
ckt->CKTdiagGmin *= ckt->CKTgminFactor;
|
ckt->CKTdiagGmin *= ckt->CKTgminFactor;
|
||||||
|
|
||||||
|
|
||||||
for (i = 0; i <= ckt->CKTnumGminSteps; i++){
|
for (i = 0; i <= ckt->CKTnumGminSteps; i++) {
|
||||||
fprintf (stderr, "Trying gmin = %12.4E ", ckt->CKTdiagGmin);
|
fprintf (stderr, "Trying gmin = %12.4E ", ckt->CKTdiagGmin);
|
||||||
ckt->CKTnoncon = 1;
|
ckt->CKTnoncon = 1;
|
||||||
converged = NIiter (ckt, ckt->CKTdcTrcvMaxIter);
|
converged = NIiter (ckt, ckt->CKTdcTrcvMaxIter);
|
||||||
|
|
||||||
if (converged != 0){
|
if (converged != 0) {
|
||||||
ckt->CKTdiagGmin = ckt->CKTgshunt;
|
ckt->CKTdiagGmin = ckt->CKTgshunt;
|
||||||
SPfrontEnd->IFerror (ERR_WARNING,
|
SPfrontEnd->IFerror (ERR_WARNING,
|
||||||
"gmin step failed", NULL);
|
"gmin step failed", NULL);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ckt->CKTdiagGmin /= ckt->CKTgminFactor;
|
ckt->CKTdiagGmin /= ckt->CKTgminFactor;
|
||||||
ckt->CKTmode = continuemode;
|
ckt->CKTmode = continuemode;
|
||||||
|
|
||||||
SPfrontEnd->IFerror (ERR_INFO,
|
SPfrontEnd->IFerror (ERR_INFO,
|
||||||
"One successful gmin step", NULL);
|
"One successful gmin step", NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
ckt->CKTdiagGmin = ckt->CKTgshunt;
|
ckt->CKTdiagGmin = ckt->CKTgshunt;
|
||||||
|
|
||||||
#ifdef XSPICE
|
#ifdef XSPICE
|
||||||
/* gtri - begin - wbk - add convergence problem reporting flags */
|
/* gtri - begin - wbk - add convergence problem reporting flags */
|
||||||
if (ckt->CKTnumSrcSteps <= 0)
|
if (ckt->CKTnumSrcSteps <= 0)
|
||||||
ckt->enh->conv_debug.last_NIiter_call = MIF_TRUE;
|
ckt->enh->conv_debug.last_NIiter_call = MIF_TRUE;
|
||||||
else
|
else
|
||||||
ckt->enh->conv_debug.last_NIiter_call = MIF_FALSE;
|
ckt->enh->conv_debug.last_NIiter_call = MIF_FALSE;
|
||||||
/* gtri - end - wbk - add convergence problem reporting flags */
|
/* gtri - end - wbk - add convergence problem reporting flags */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
converged = NIiter (ckt, iterlim);
|
converged = NIiter (ckt, iterlim);
|
||||||
|
|
||||||
if (converged == 0){
|
if (converged == 0) {
|
||||||
SPfrontEnd->IFerror (ERR_INFO,
|
SPfrontEnd->IFerror (ERR_INFO,
|
||||||
"gmin stepping completed", NULL);
|
"gmin stepping completed", NULL);
|
||||||
|
|
||||||
#ifdef XSPICE
|
#ifdef XSPICE
|
||||||
/* gtri - begin - wbk - add convergence problem reporting flags */
|
/* gtri - begin - wbk - add convergence problem reporting flags */
|
||||||
ckt->enh->conv_debug.last_NIiter_call = MIF_FALSE;
|
ckt->enh->conv_debug.last_NIiter_call = MIF_FALSE;
|
||||||
/* gtri - end - wbk - add convergence problem reporting flags */
|
/* gtri - end - wbk - add convergence problem reporting flags */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
SPfrontEnd->IFerror (ERR_WARNING,
|
SPfrontEnd->IFerror (ERR_WARNING,
|
||||||
"gmin stepping failed", NULL);
|
"gmin stepping failed", NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (converged);
|
return (converged);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -362,201 +358,197 @@ spice3_gmin (CKTcircuit * ckt, long int firstmode,
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
gillespie_src (CKTcircuit * ckt, long int firstmode,
|
gillespie_src (CKTcircuit * ckt, long int firstmode,
|
||||||
long int continuemode, int iterlim)
|
long int continuemode, int iterlim)
|
||||||
{
|
{
|
||||||
|
|
||||||
int converged, NumNodes, i, iters;
|
int converged, NumNodes, i, iters;
|
||||||
double raise, ConvFact;
|
double raise, ConvFact;
|
||||||
double *OldRhsOld, *OldCKTstate0;
|
double *OldRhsOld, *OldCKTstate0;
|
||||||
CKTnode *n;
|
CKTnode *n;
|
||||||
|
|
||||||
NG_IGNORE(iterlim);
|
NG_IGNORE(iterlim);
|
||||||
|
|
||||||
ckt->CKTmode = firstmode;
|
ckt->CKTmode = firstmode;
|
||||||
SPfrontEnd->IFerror (ERR_INFO,
|
SPfrontEnd->IFerror (ERR_INFO,
|
||||||
"Starting source stepping", NULL);
|
"Starting source stepping", NULL);
|
||||||
|
|
||||||
ckt->CKTsrcFact = 0;
|
ckt->CKTsrcFact = 0;
|
||||||
raise = 0.001;
|
raise = 0.001;
|
||||||
ConvFact = 0;
|
ConvFact = 0;
|
||||||
|
|
||||||
NumNodes = 0;
|
NumNodes = 0;
|
||||||
for (n = ckt->CKTnodes; n; n = n->next){
|
for (n = ckt->CKTnodes; n; n = n->next) {
|
||||||
NumNodes++;
|
NumNodes++;
|
||||||
}
|
|
||||||
|
|
||||||
OldRhsOld = TMALLOC(double, NumNodes + 1);
|
|
||||||
OldCKTstate0 =
|
|
||||||
TMALLOC(double, ckt->CKTnumStates + 1);
|
|
||||||
|
|
||||||
for (n = ckt->CKTnodes; n; n = n->next)
|
|
||||||
ckt->CKTrhsOld[n->number] = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < ckt->CKTnumStates; i++)
|
|
||||||
ckt->CKTstate0[i] = 0;
|
|
||||||
|
|
||||||
/* First, try a straight solution with all sources at zero */
|
|
||||||
|
|
||||||
fprintf (stderr, "Supplies reduced to %8.4f%% ", ckt->CKTsrcFact * 100);
|
|
||||||
converged = NIiter (ckt, ckt->CKTdcTrcvMaxIter);
|
|
||||||
|
|
||||||
/* If this doesn't work, try gmin stepping as well for the first solution */
|
|
||||||
|
|
||||||
if (converged != 0){
|
|
||||||
fprintf (stderr, "\n");
|
|
||||||
if (ckt->CKTgshunt <= 0){
|
|
||||||
ckt->CKTdiagGmin = ckt->CKTgmin;
|
|
||||||
} else {
|
|
||||||
ckt->CKTdiagGmin = ckt->CKTgshunt;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < 10; i++)
|
|
||||||
ckt->CKTdiagGmin *= 10;
|
|
||||||
|
|
||||||
for (i = 0; i <= 10; i++){
|
|
||||||
fprintf (stderr, "Trying gmin = %12.4E ", ckt->CKTdiagGmin);
|
|
||||||
ckt->CKTnoncon = 1;
|
|
||||||
|
|
||||||
#ifdef XSPICE
|
|
||||||
/* gtri - begin - wbk - add convergence problem reporting flags */
|
|
||||||
ckt->enh->conv_debug.last_NIiter_call = MIF_TRUE;
|
|
||||||
/* gtri - end - wbk - add convergence problem reporting flags */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
converged = NIiter (ckt, ckt->CKTdcTrcvMaxIter);
|
|
||||||
|
|
||||||
if (converged != 0){
|
|
||||||
ckt->CKTdiagGmin = ckt->CKTgshunt;
|
|
||||||
SPfrontEnd->IFerror (ERR_WARNING,
|
|
||||||
"gmin step failed", NULL);
|
|
||||||
#ifdef XSPICE
|
|
||||||
/* gtri - begin - wbk - add convergence problem reporting flags */
|
|
||||||
ckt->enh->conv_debug.last_NIiter_call = MIF_FALSE;
|
|
||||||
/* gtri - end - wbk - add convergence problem reporting flags */
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
ckt->CKTdiagGmin /= 10;
|
|
||||||
ckt->CKTmode = continuemode;
|
|
||||||
SPfrontEnd->IFerror (ERR_INFO,
|
|
||||||
"One successful gmin step",
|
|
||||||
NULL);
|
|
||||||
}
|
|
||||||
ckt->CKTdiagGmin = ckt->CKTgshunt;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If we've got convergence, then try stepping up the sources */
|
|
||||||
|
|
||||||
if (converged == 0){
|
|
||||||
i = 0;
|
|
||||||
for (n = ckt->CKTnodes; n; n = n->next){
|
|
||||||
OldRhsOld[i] = ckt->CKTrhsOld[n->number];
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < ckt->CKTnumStates; i++)
|
|
||||||
OldCKTstate0[i] = ckt->CKTstate0[i];
|
|
||||||
|
|
||||||
|
|
||||||
SPfrontEnd->IFerror (ERR_INFO,
|
|
||||||
"One successful source step", NULL);
|
|
||||||
ckt->CKTsrcFact = ConvFact + raise;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (converged == 0)
|
|
||||||
do {
|
|
||||||
fprintf (stderr,
|
|
||||||
"Supplies reduced to %8.4f%% ", ckt->CKTsrcFact * 100);
|
|
||||||
|
|
||||||
iters = ckt->CKTstat->STATnumIter;
|
|
||||||
|
|
||||||
#ifdef XSPICE
|
|
||||||
/* gtri - begin - wbk - add convergence problem reporting flags */
|
|
||||||
ckt->enh->conv_debug.last_NIiter_call = MIF_TRUE;
|
|
||||||
/* gtri - end - wbk - add convergence problem reporting flags */
|
|
||||||
#endif
|
|
||||||
converged = NIiter (ckt, ckt->CKTdcTrcvMaxIter);
|
|
||||||
|
|
||||||
iters = (ckt->CKTstat->STATnumIter) - iters;
|
|
||||||
|
|
||||||
ckt->CKTmode = continuemode;
|
|
||||||
|
|
||||||
if (converged == 0){
|
|
||||||
ConvFact = ckt->CKTsrcFact;
|
|
||||||
i = 0;
|
|
||||||
|
|
||||||
for (n = ckt->CKTnodes; n; n = n->next){
|
|
||||||
OldRhsOld[i] = ckt->CKTrhsOld[n->number];
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < ckt->CKTnumStates; i++)
|
|
||||||
OldCKTstate0[i] = ckt->CKTstate0[i];
|
|
||||||
|
|
||||||
SPfrontEnd->IFerror (ERR_INFO,
|
|
||||||
"One successful source step",
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
ckt->CKTsrcFact = ConvFact + raise;
|
|
||||||
|
|
||||||
if (iters <= (ckt->CKTdcTrcvMaxIter / 4)){
|
|
||||||
raise = raise * 1.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (iters > (3 * ckt->CKTdcTrcvMaxIter / 4)){
|
|
||||||
raise = raise * 0.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if (raise>0.01) raise=0.01; */
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
if ((ckt->CKTsrcFact - ConvFact) < 1e-8)
|
|
||||||
break;
|
|
||||||
|
|
||||||
raise = raise / 10;
|
|
||||||
|
|
||||||
if (raise > 0.01)
|
|
||||||
raise = 0.01;
|
|
||||||
|
|
||||||
ckt->CKTsrcFact = ConvFact;
|
|
||||||
i = 0;
|
|
||||||
|
|
||||||
for (n = ckt->CKTnodes; n; n = n->next){
|
|
||||||
ckt->CKTrhsOld[n->number] = OldRhsOld[i];
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < ckt->CKTnumStates; i++)
|
|
||||||
ckt->CKTstate0[i] = OldCKTstate0[i];
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((ckt->CKTsrcFact) > 1)
|
|
||||||
ckt->CKTsrcFact = 1;
|
|
||||||
|
|
||||||
}
|
|
||||||
while ((raise >= 1e-7) && (ConvFact < 1));
|
|
||||||
|
|
||||||
FREE (OldRhsOld);
|
|
||||||
FREE (OldCKTstate0);
|
|
||||||
ckt->CKTsrcFact = 1;
|
|
||||||
|
|
||||||
if (ConvFact != 1)
|
|
||||||
{
|
|
||||||
ckt->CKTsrcFact = 1;
|
|
||||||
ckt->CKTcurrentAnalysis = DOING_TRAN;
|
|
||||||
SPfrontEnd->IFerror (ERR_WARNING,
|
|
||||||
"source stepping failed", NULL);
|
|
||||||
return (E_ITERLIM);
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
OldRhsOld = TMALLOC(double, NumNodes + 1);
|
||||||
SPfrontEnd->IFerror (ERR_INFO,
|
OldCKTstate0 =
|
||||||
"Source stepping completed", NULL);
|
TMALLOC(double, ckt->CKTnumStates + 1);
|
||||||
return (0);
|
|
||||||
|
for (n = ckt->CKTnodes; n; n = n->next)
|
||||||
|
ckt->CKTrhsOld[n->number] = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < ckt->CKTnumStates; i++)
|
||||||
|
ckt->CKTstate0[i] = 0;
|
||||||
|
|
||||||
|
/* First, try a straight solution with all sources at zero */
|
||||||
|
|
||||||
|
fprintf (stderr, "Supplies reduced to %8.4f%% ", ckt->CKTsrcFact * 100);
|
||||||
|
converged = NIiter (ckt, ckt->CKTdcTrcvMaxIter);
|
||||||
|
|
||||||
|
/* If this doesn't work, try gmin stepping as well for the first solution */
|
||||||
|
|
||||||
|
if (converged != 0) {
|
||||||
|
fprintf (stderr, "\n");
|
||||||
|
if (ckt->CKTgshunt <= 0) {
|
||||||
|
ckt->CKTdiagGmin = ckt->CKTgmin;
|
||||||
|
} else {
|
||||||
|
ckt->CKTdiagGmin = ckt->CKTgshunt;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < 10; i++)
|
||||||
|
ckt->CKTdiagGmin *= 10;
|
||||||
|
|
||||||
|
for (i = 0; i <= 10; i++) {
|
||||||
|
fprintf (stderr, "Trying gmin = %12.4E ", ckt->CKTdiagGmin);
|
||||||
|
ckt->CKTnoncon = 1;
|
||||||
|
|
||||||
|
#ifdef XSPICE
|
||||||
|
/* gtri - begin - wbk - add convergence problem reporting flags */
|
||||||
|
ckt->enh->conv_debug.last_NIiter_call = MIF_TRUE;
|
||||||
|
/* gtri - end - wbk - add convergence problem reporting flags */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
converged = NIiter (ckt, ckt->CKTdcTrcvMaxIter);
|
||||||
|
|
||||||
|
if (converged != 0) {
|
||||||
|
ckt->CKTdiagGmin = ckt->CKTgshunt;
|
||||||
|
SPfrontEnd->IFerror (ERR_WARNING,
|
||||||
|
"gmin step failed", NULL);
|
||||||
|
#ifdef XSPICE
|
||||||
|
/* gtri - begin - wbk - add convergence problem reporting flags */
|
||||||
|
ckt->enh->conv_debug.last_NIiter_call = MIF_FALSE;
|
||||||
|
/* gtri - end - wbk - add convergence problem reporting flags */
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ckt->CKTdiagGmin /= 10;
|
||||||
|
ckt->CKTmode = continuemode;
|
||||||
|
SPfrontEnd->IFerror (ERR_INFO,
|
||||||
|
"One successful gmin step",
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
ckt->CKTdiagGmin = ckt->CKTgshunt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we've got convergence, then try stepping up the sources */
|
||||||
|
|
||||||
|
if (converged == 0) {
|
||||||
|
i = 0;
|
||||||
|
for (n = ckt->CKTnodes; n; n = n->next) {
|
||||||
|
OldRhsOld[i] = ckt->CKTrhsOld[n->number];
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < ckt->CKTnumStates; i++)
|
||||||
|
OldCKTstate0[i] = ckt->CKTstate0[i];
|
||||||
|
|
||||||
|
|
||||||
|
SPfrontEnd->IFerror (ERR_INFO,
|
||||||
|
"One successful source step", NULL);
|
||||||
|
ckt->CKTsrcFact = ConvFact + raise;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (converged == 0)
|
||||||
|
do {
|
||||||
|
fprintf (stderr,
|
||||||
|
"Supplies reduced to %8.4f%% ", ckt->CKTsrcFact * 100);
|
||||||
|
|
||||||
|
iters = ckt->CKTstat->STATnumIter;
|
||||||
|
|
||||||
|
#ifdef XSPICE
|
||||||
|
/* gtri - begin - wbk - add convergence problem reporting flags */
|
||||||
|
ckt->enh->conv_debug.last_NIiter_call = MIF_TRUE;
|
||||||
|
/* gtri - end - wbk - add convergence problem reporting flags */
|
||||||
|
#endif
|
||||||
|
converged = NIiter (ckt, ckt->CKTdcTrcvMaxIter);
|
||||||
|
|
||||||
|
iters = (ckt->CKTstat->STATnumIter) - iters;
|
||||||
|
|
||||||
|
ckt->CKTmode = continuemode;
|
||||||
|
|
||||||
|
if (converged == 0) {
|
||||||
|
ConvFact = ckt->CKTsrcFact;
|
||||||
|
i = 0;
|
||||||
|
|
||||||
|
for (n = ckt->CKTnodes; n; n = n->next) {
|
||||||
|
OldRhsOld[i] = ckt->CKTrhsOld[n->number];
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < ckt->CKTnumStates; i++)
|
||||||
|
OldCKTstate0[i] = ckt->CKTstate0[i];
|
||||||
|
|
||||||
|
SPfrontEnd->IFerror (ERR_INFO,
|
||||||
|
"One successful source step",
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
ckt->CKTsrcFact = ConvFact + raise;
|
||||||
|
|
||||||
|
if (iters <= (ckt->CKTdcTrcvMaxIter / 4)) {
|
||||||
|
raise = raise * 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iters > (3 * ckt->CKTdcTrcvMaxIter / 4)) {
|
||||||
|
raise = raise * 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if (raise>0.01) raise=0.01; */
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
if ((ckt->CKTsrcFact - ConvFact) < 1e-8)
|
||||||
|
break;
|
||||||
|
|
||||||
|
raise = raise / 10;
|
||||||
|
|
||||||
|
if (raise > 0.01)
|
||||||
|
raise = 0.01;
|
||||||
|
|
||||||
|
ckt->CKTsrcFact = ConvFact;
|
||||||
|
i = 0;
|
||||||
|
|
||||||
|
for (n = ckt->CKTnodes; n; n = n->next) {
|
||||||
|
ckt->CKTrhsOld[n->number] = OldRhsOld[i];
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < ckt->CKTnumStates; i++)
|
||||||
|
ckt->CKTstate0[i] = OldCKTstate0[i];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((ckt->CKTsrcFact) > 1)
|
||||||
|
ckt->CKTsrcFact = 1;
|
||||||
|
|
||||||
|
} while ((raise >= 1e-7) && (ConvFact < 1));
|
||||||
|
|
||||||
|
FREE (OldRhsOld);
|
||||||
|
FREE (OldCKTstate0);
|
||||||
|
ckt->CKTsrcFact = 1;
|
||||||
|
|
||||||
|
if (ConvFact != 1) {
|
||||||
|
ckt->CKTsrcFact = 1;
|
||||||
|
ckt->CKTcurrentAnalysis = DOING_TRAN;
|
||||||
|
SPfrontEnd->IFerror (ERR_WARNING,
|
||||||
|
"source stepping failed", NULL);
|
||||||
|
return (E_ITERLIM);
|
||||||
|
} else {
|
||||||
|
SPfrontEnd->IFerror (ERR_INFO,
|
||||||
|
"Source stepping completed", NULL);
|
||||||
|
return (0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -573,50 +565,48 @@ gillespie_src (CKTcircuit * ckt, long int firstmode,
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
spice3_src (CKTcircuit * ckt, long int firstmode,
|
spice3_src (CKTcircuit * ckt, long int firstmode,
|
||||||
long int continuemode, int iterlim)
|
long int continuemode, int iterlim)
|
||||||
{
|
{
|
||||||
|
|
||||||
int converged, i;
|
int converged, i;
|
||||||
|
|
||||||
NG_IGNORE(iterlim);
|
NG_IGNORE(iterlim);
|
||||||
|
|
||||||
ckt->CKTmode = firstmode;
|
ckt->CKTmode = firstmode;
|
||||||
SPfrontEnd->IFerror (ERR_INFO,
|
SPfrontEnd->IFerror (ERR_INFO,
|
||||||
"Starting source stepping", NULL);
|
"Starting source stepping", NULL);
|
||||||
|
|
||||||
for (i = 0; i <= ckt->CKTnumSrcSteps; i++)
|
for (i = 0; i <= ckt->CKTnumSrcSteps; i++) {
|
||||||
{
|
ckt->CKTsrcFact = ((double) i) / ((double) ckt->CKTnumSrcSteps);
|
||||||
ckt->CKTsrcFact = ((double) i) / ((double) ckt->CKTnumSrcSteps);
|
|
||||||
#ifdef XSPICE
|
#ifdef XSPICE
|
||||||
/* gtri - begin - wbk - add convergence problem reporting flags */
|
/* gtri - begin - wbk - add convergence problem reporting flags */
|
||||||
ckt->enh->conv_debug.last_NIiter_call = MIF_TRUE;
|
ckt->enh->conv_debug.last_NIiter_call = MIF_TRUE;
|
||||||
/* gtri - end - wbk - add convergence problem reporting flags */
|
/* gtri - end - wbk - add convergence problem reporting flags */
|
||||||
#endif
|
#endif
|
||||||
converged = NIiter (ckt, ckt->CKTdcTrcvMaxIter);
|
converged = NIiter (ckt, ckt->CKTdcTrcvMaxIter);
|
||||||
ckt->CKTmode = continuemode;
|
ckt->CKTmode = continuemode;
|
||||||
if (converged != 0)
|
if (converged != 0) {
|
||||||
{
|
ckt->CKTsrcFact = 1;
|
||||||
ckt->CKTsrcFact = 1;
|
ckt->CKTcurrentAnalysis = DOING_TRAN;
|
||||||
ckt->CKTcurrentAnalysis = DOING_TRAN;
|
SPfrontEnd->IFerror (ERR_WARNING,
|
||||||
SPfrontEnd->IFerror (ERR_WARNING,
|
"source stepping failed", NULL);
|
||||||
"source stepping failed", NULL);
|
|
||||||
#ifdef XSPICE
|
#ifdef XSPICE
|
||||||
/* gtri - begin - wbk - add convergence problem reporting flags */
|
/* gtri - begin - wbk - add convergence problem reporting flags */
|
||||||
ckt->enh->conv_debug.last_NIiter_call = MIF_FALSE;
|
ckt->enh->conv_debug.last_NIiter_call = MIF_FALSE;
|
||||||
/* gtri - end - wbk - add convergence problem reporting flags */
|
/* gtri - end - wbk - add convergence problem reporting flags */
|
||||||
#endif
|
#endif
|
||||||
return (converged);
|
return (converged);
|
||||||
}
|
}
|
||||||
SPfrontEnd->IFerror (ERR_INFO,
|
SPfrontEnd->IFerror (ERR_INFO,
|
||||||
"One successful source step", NULL);
|
"One successful source step", NULL);
|
||||||
}
|
}
|
||||||
SPfrontEnd->IFerror (ERR_INFO,
|
SPfrontEnd->IFerror (ERR_INFO,
|
||||||
"Source stepping completed", NULL);
|
"Source stepping completed", NULL);
|
||||||
ckt->CKTsrcFact = 1;
|
ckt->CKTsrcFact = 1;
|
||||||
#ifdef XSPICE
|
#ifdef XSPICE
|
||||||
/* gtri - begin - wbk - add convergence problem reporting flags */
|
/* gtri - begin - wbk - add convergence problem reporting flags */
|
||||||
ckt->enh->conv_debug.last_NIiter_call = MIF_FALSE;
|
ckt->enh->conv_debug.last_NIiter_call = MIF_FALSE;
|
||||||
/* gtri - end - wbk - add convergence problem reporting flags */
|
/* gtri - end - wbk - add convergence problem reporting flags */
|
||||||
#endif
|
#endif
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -635,12 +635,12 @@ CKTpzRunTrial(CKTcircuit *ckt, PZtrial **new_trialp, PZtrial **set)
|
||||||
if (!(p->flags & ISAROOT) && CKTpzTrapped == 3
|
if (!(p->flags & ISAROOT) && CKTpzTrapped == 3
|
||||||
&& NIpzK != 0.0 && NIpzK_mag > -10) {
|
&& NIpzK != 0.0 && NIpzK_mag > -10) {
|
||||||
#ifdef notdef
|
#ifdef notdef
|
||||||
if (p->flags & ISAROOT) {
|
// if (p->flags & ISAROOT) {
|
||||||
/* Ugh! muller doesn't work right */
|
// /* Ugh! muller doesn't work right */
|
||||||
new_trial->flags = ISAMINIMA;
|
// new_trial->flags = ISAMINIMA;
|
||||||
new_trial->s.imag = scalb(NIpzK, (int) (NIpzK_mag / 2));
|
// new_trial->s.imag = scalb(NIpzK, (int) (NIpzK_mag / 2));
|
||||||
pretest = 0;
|
// pretest = 0;
|
||||||
} else {
|
// } else {
|
||||||
#endif
|
#endif
|
||||||
p->flags |= ISAMINIMA;
|
p->flags |= ISAMINIMA;
|
||||||
tfree(new_trial);
|
tfree(new_trial);
|
||||||
|
|
|
||||||
|
|
@ -184,9 +184,7 @@ int sens_sens(CKTcircuit *ckt, int restart)
|
||||||
sg->ptable[sg->param].keyword);
|
sg->ptable[sg->param].keyword);
|
||||||
}
|
}
|
||||||
|
|
||||||
SPfrontEnd->IFnewUid (ckt,
|
SPfrontEnd->IFnewUid (ckt, output_names + k, NULL, namebuf, UID_OTHER, NULL);
|
||||||
output_names + k, NULL,
|
|
||||||
namebuf, UID_OTHER, NULL);
|
|
||||||
k += 1;
|
k += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -195,16 +193,14 @@ int sens_sens(CKTcircuit *ckt, int restart)
|
||||||
freq_name = NULL;
|
freq_name = NULL;
|
||||||
} else {
|
} else {
|
||||||
type = IF_COMPLEX;
|
type = IF_COMPLEX;
|
||||||
SPfrontEnd->IFnewUid (ckt,
|
SPfrontEnd->IFnewUid (ckt, &freq_name, NULL, "frequency", UID_OTHER, NULL);
|
||||||
&freq_name, NULL,
|
|
||||||
"frequency", UID_OTHER, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
error = SPfrontEnd->OUTpBeginPlot (
|
error = SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
|
||||||
ckt, ckt->CKTcurJob,
|
ckt->CKTcurJob->JOBname,
|
||||||
ckt->CKTcurJob->JOBname,
|
freq_name, IF_REAL,
|
||||||
freq_name, IF_REAL,
|
num_vars, output_names, type,
|
||||||
num_vars, output_names, type, &sen_data);
|
&sen_data);
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
|
|
@ -216,8 +212,7 @@ int sens_sens(CKTcircuit *ckt, int restart)
|
||||||
output_values = NULL;
|
output_values = NULL;
|
||||||
output_cvalues = NEWN(IFcomplex, num_vars);
|
output_cvalues = NEWN(IFcomplex, num_vars);
|
||||||
if (job->step_type != SENS_LINEAR)
|
if (job->step_type != SENS_LINEAR)
|
||||||
SPfrontEnd->OUTattributes (sen_data,
|
SPfrontEnd->OUTattributes (sen_data, NULL, OUT_SCALE_LOG, NULL);
|
||||||
NULL, OUT_SCALE_LOG, NULL);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,9 @@ CKTsetup(CKTcircuit *ckt)
|
||||||
|
|
||||||
#ifdef WANT_SENSE2
|
#ifdef WANT_SENSE2
|
||||||
if(ckt->CKTsenInfo){
|
if(ckt->CKTsenInfo){
|
||||||
if (error = CKTsenSetup(ckt)) return(error);
|
error = CKTsenSetup(ckt);
|
||||||
|
if (error)
|
||||||
|
return(error);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -269,6 +271,22 @@ CKTsetup(CKTcircuit *ckt)
|
||||||
|
|
||||||
/* gtri - end - Setup for adding rshunt option resistors */
|
/* gtri - end - Setup for adding rshunt option resistors */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef KIRCHHOFF
|
||||||
|
/** Marking node as Non-Linear when needed
|
||||||
|
* By default every node is Linear
|
||||||
|
*/
|
||||||
|
for (i = 0 ; i < DEVmaxnum ; i++)
|
||||||
|
{
|
||||||
|
if (DEVices[i] && DEVices[i]->DEVnodeIsNonLinear && ckt->CKThead[i])
|
||||||
|
{
|
||||||
|
error = DEVices[i]->DEVnodeIsNonLinear (ckt->CKThead[i], ckt) ;
|
||||||
|
if (error)
|
||||||
|
return (error) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return(OK);
|
return(OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -237,8 +237,8 @@ int set_param(sgen *sg)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef notdef
|
#ifdef notdef
|
||||||
sgen_suspend(sg)
|
void
|
||||||
sgen *sg;
|
sgen_suspend(sgen *sg)
|
||||||
{
|
{
|
||||||
sg->devlist[sg->dev] = sg->first_model;
|
sg->devlist[sg->dev] = sg->first_model;
|
||||||
sg->model->GENnextModel = sg->next_model;
|
sg->model->GENnextModel = sg->next_model;
|
||||||
|
|
@ -246,8 +246,8 @@ sgen_suspend(sg)
|
||||||
sg->model->GENinstances = sg->first_instance;
|
sg->model->GENinstances = sg->first_instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
sgen_restore(sg)
|
void
|
||||||
sgen *sg;
|
sgen_restore(sgen *sg)
|
||||||
{
|
{
|
||||||
sg->devlist[sg->dev] = sg->model;
|
sg->devlist[sg->dev] = sg->model;
|
||||||
sg->model->GENnextModel = NULL;
|
sg->model->GENnextModel = NULL;
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,11 @@ Modified: 2000 AlansFixes
|
||||||
int
|
int
|
||||||
DCop(CKTcircuit *ckt, int notused)
|
DCop(CKTcircuit *ckt, int notused)
|
||||||
{
|
{
|
||||||
|
#ifdef WANT_SENSE2
|
||||||
|
int i, senmode, size;
|
||||||
|
long save;
|
||||||
|
#endif
|
||||||
|
|
||||||
int converged;
|
int converged;
|
||||||
int error;
|
int error;
|
||||||
IFuid *nameList; /* va: tmalloc'ed list */
|
IFuid *nameList; /* va: tmalloc'ed list */
|
||||||
|
|
@ -45,11 +50,11 @@ DCop(CKTcircuit *ckt, int notused)
|
||||||
|
|
||||||
error = CKTnames(ckt,&numNames,&nameList);
|
error = CKTnames(ckt,&numNames,&nameList);
|
||||||
if(error) return(error);
|
if(error) return(error);
|
||||||
error = SPfrontEnd->OUTpBeginPlot (
|
error = SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
|
||||||
ckt, ckt->CKTcurJob,
|
ckt->CKTcurJob->JOBname,
|
||||||
ckt->CKTcurJob->JOBname,
|
NULL, IF_REAL,
|
||||||
NULL, IF_REAL,
|
numNames, nameList, IF_REAL,
|
||||||
numNames, nameList, IF_REAL, &plot);
|
&plot);
|
||||||
tfree(nameList); /* va: nameList not used any longer, it was a memory leak */
|
tfree(nameList); /* va: nameList not used any longer, it was a memory leak */
|
||||||
if(error) return(error);
|
if(error) return(error);
|
||||||
|
|
||||||
|
|
@ -133,7 +138,10 @@ DCop(CKTcircuit *ckt, int notused)
|
||||||
for(i = 1; i<=size ; i++){
|
for(i = 1; i<=size ; i++){
|
||||||
ckt->CKTrhsOp[i] = ckt->CKTrhsOld[i];
|
ckt->CKTrhsOp[i] = ckt->CKTrhsOld[i];
|
||||||
}
|
}
|
||||||
if(error = CKTsenDCtran(ckt)) return(error);
|
error = CKTsenDCtran(ckt);
|
||||||
|
if (error)
|
||||||
|
return(error);
|
||||||
|
|
||||||
ckt->CKTmode = save;
|
ckt->CKTmode = save;
|
||||||
ckt->CKTsenInfo->SENmode = senmode;
|
ckt->CKTsenInfo->SENmode = senmode;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -237,13 +237,12 @@ DCpss(CKTcircuit *ckt,
|
||||||
/* Time Domain plot start and prepared to be filled in later */
|
/* Time Domain plot start and prepared to be filled in later */
|
||||||
error = CKTnames(ckt,&numNames,&nameList);
|
error = CKTnames(ckt,&numNames,&nameList);
|
||||||
if(error) return(error);
|
if(error) return(error);
|
||||||
SPfrontEnd->IFnewUid (ckt, &timeUid, NULL,
|
SPfrontEnd->IFnewUid (ckt, &timeUid, NULL, "time", UID_OTHER, NULL);
|
||||||
"time", UID_OTHER, NULL);
|
error = SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
|
||||||
error = SPfrontEnd->OUTpBeginPlot (
|
"Time Domain Periodic Steady State Analysis",
|
||||||
ckt, ckt->CKTcurJob,
|
timeUid, IF_REAL,
|
||||||
"Time Domain Periodic Steady State Analysis",
|
numNames, nameList, IF_REAL,
|
||||||
timeUid, IF_REAL,
|
&(job->PSSplot_td));
|
||||||
numNames, nameList, IF_REAL, &(job->PSSplot_td));
|
|
||||||
tfree(nameList);
|
tfree(nameList);
|
||||||
if(error) return(error);
|
if(error) return(error);
|
||||||
|
|
||||||
|
|
@ -406,11 +405,11 @@ DCpss(CKTcircuit *ckt,
|
||||||
if(ckt->CKTminBreak==0) ckt->CKTminBreak=ckt->CKTmaxStep*5e-5;
|
if(ckt->CKTminBreak==0) ckt->CKTminBreak=ckt->CKTmaxStep*5e-5;
|
||||||
firsttime=0;
|
firsttime=0;
|
||||||
/* To get rawfile working saj*/
|
/* To get rawfile working saj*/
|
||||||
error = SPfrontEnd->OUTpBeginPlot (
|
error = SPfrontEnd->OUTpBeginPlot (NULL, NULL,
|
||||||
NULL, NULL,
|
NULL,
|
||||||
NULL,
|
NULL, 0,
|
||||||
NULL, 0,
|
666, NULL, 666,
|
||||||
666, NULL, 666, &(job->PSSplot_td));
|
&(job->PSSplot_td));
|
||||||
if(error) {
|
if(error) {
|
||||||
fprintf(stderr, "Couldn't relink rawfile\n");
|
fprintf(stderr, "Couldn't relink rawfile\n");
|
||||||
return error;
|
return error;
|
||||||
|
|
@ -1039,8 +1038,11 @@ DCpss(CKTcircuit *ckt,
|
||||||
if (error)
|
if (error)
|
||||||
return (error) ;
|
return (error) ;
|
||||||
SPfrontEnd->IFnewUid (ckt, &freqUid, NULL, "frequency", UID_OTHER, NULL) ;
|
SPfrontEnd->IFnewUid (ckt, &freqUid, NULL, "frequency", UID_OTHER, NULL) ;
|
||||||
error = SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob, "Frequency Domain Periodic Steady State Analysis",
|
error = SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
|
||||||
freqUid, IF_REAL, numNames, nameList, IF_REAL, &(job->PSSplot_fd)) ;
|
"Frequency Domain Periodic Steady State Analysis",
|
||||||
|
freqUid, IF_REAL,
|
||||||
|
numNames, nameList, IF_REAL,
|
||||||
|
&(job->PSSplot_fd)) ;
|
||||||
tfree (nameList) ;
|
tfree (nameList) ;
|
||||||
SPfrontEnd->OUTattributes (job->PSSplot_fd, NULL, PLOT_COMB, NULL) ;
|
SPfrontEnd->OUTattributes (job->PSSplot_fd, NULL, PLOT_COMB, NULL) ;
|
||||||
|
|
||||||
|
|
@ -1204,9 +1206,25 @@ resume:
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef XSPICE
|
#ifndef XSPICE
|
||||||
|
/* don't want to get below delmin for no reason */
|
||||||
|
ckt->CKTdelta = MAX(ckt->CKTdelta, ckt->CKTdelmin*2.0);
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef XSPICE
|
||||||
|
else if(ckt->CKTtime + ckt->CKTdelta >= ckt->CKTbreaks[0]) {
|
||||||
|
ckt->CKTsaveDelta = ckt->CKTdelta;
|
||||||
|
ckt->CKTdelta = ckt->CKTbreaks[0] - ckt->CKTtime;
|
||||||
|
/* fprintf (stderr, "delta cut to %g to hit breakpoint\n" ,ckt->CKTdelta) ; */
|
||||||
|
fflush(stdout);
|
||||||
|
ckt->CKTbreak = 1; /* why? the current pt. is not a bkpt. */
|
||||||
|
}
|
||||||
|
#endif /* !XSPICE */
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef XSPICE
|
||||||
/* gtri - begin - wbk - Add Breakpoint stuff */
|
/* gtri - begin - wbk - Add Breakpoint stuff */
|
||||||
|
|
||||||
if(ckt->CKTtime + ckt->CKTdelta >= g_mif_info.breakpoint.current) {
|
if(ckt->CKTtime + ckt->CKTdelta >= g_mif_info.breakpoint.current) {
|
||||||
|
|
@ -1247,28 +1265,7 @@ resume:
|
||||||
}
|
}
|
||||||
|
|
||||||
/* gtri - end - wbk - Modify Breakpoint stuff */
|
/* gtri - end - wbk - Modify Breakpoint stuff */
|
||||||
#else /* !XSPICE */
|
|
||||||
|
|
||||||
/* don't want to get below delmin for no reason */
|
|
||||||
ckt->CKTdelta = MAX(ckt->CKTdelta, ckt->CKTdelmin*2.0);
|
|
||||||
}
|
|
||||||
else if(ckt->CKTtime + ckt->CKTdelta >= ckt->CKTbreaks[0]) {
|
|
||||||
ckt->CKTsaveDelta = ckt->CKTdelta;
|
|
||||||
ckt->CKTdelta = ckt->CKTbreaks[0] - ckt->CKTtime;
|
|
||||||
/* fprintf (stderr, "delta cut to %g to hit breakpoint\n" ,ckt->CKTdelta) ; */
|
|
||||||
fflush(stdout);
|
|
||||||
ckt->CKTbreak = 1; /* why? the current pt. is not a bkpt. */
|
|
||||||
}
|
|
||||||
#ifdef CLUSTER
|
|
||||||
if(!CLUsync(ckt->CKTtime,&ckt->CKTdelta,0)) {
|
|
||||||
fprintf (stderr, "Sync error!\n");
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* XSPICE */
|
|
||||||
|
|
||||||
#ifdef XSPICE
|
|
||||||
/* gtri - begin - wbk - Do event solution */
|
/* gtri - begin - wbk - Do event solution */
|
||||||
|
|
||||||
if(ckt->evt->counts.num_insts > 0) {
|
if(ckt->evt->counts.num_insts > 0) {
|
||||||
|
|
@ -1311,6 +1308,15 @@ resume:
|
||||||
} /* end if there are event instances */
|
} /* end if there are event instances */
|
||||||
|
|
||||||
/* gtri - end - wbk - Do event solution */
|
/* gtri - end - wbk - Do event solution */
|
||||||
|
#else
|
||||||
|
|
||||||
|
#ifdef CLUSTER
|
||||||
|
if(!CLUsync(ckt->CKTtime,&ckt->CKTdelta,0)) {
|
||||||
|
fprintf (stderr, "Sync error!\n");
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
#endif /* CLUSTER */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* What is that??? */
|
/* What is that??? */
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,9 @@ extern struct dbcomm *dbs;
|
||||||
#include "ngspice/cluster.h"
|
#include "ngspice/cluster.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef SHARED_MODULE
|
||||||
|
extern int add_bkpt(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
#define INIT_STATS() \
|
#define INIT_STATS() \
|
||||||
do { \
|
do { \
|
||||||
|
|
@ -78,9 +81,8 @@ DCtran(CKTcircuit *ckt,
|
||||||
int firsttime;
|
int firsttime;
|
||||||
int error;
|
int error;
|
||||||
#ifdef WANT_SENSE2
|
#ifdef WANT_SENSE2
|
||||||
#ifdef SENSDEBUG
|
int save, save2, size;
|
||||||
FILE *outsen;
|
long save1;
|
||||||
#endif /* SENSDEBUG */
|
|
||||||
#endif
|
#endif
|
||||||
int save_order;
|
int save_order;
|
||||||
long save_mode;
|
long save_mode;
|
||||||
|
|
@ -132,7 +134,9 @@ DCtran(CKTcircuit *ckt,
|
||||||
ckt->CKTbreaks[0] = 0;
|
ckt->CKTbreaks[0] = 0;
|
||||||
ckt->CKTbreaks[1] = ckt->CKTfinalTime;
|
ckt->CKTbreaks[1] = ckt->CKTfinalTime;
|
||||||
ckt->CKTbreakSize = 2;
|
ckt->CKTbreakSize = 2;
|
||||||
|
#ifdef SHARED_MODULE
|
||||||
|
add_bkpt();
|
||||||
|
#endif
|
||||||
#ifdef XSPICE
|
#ifdef XSPICE
|
||||||
/* gtri - begin - wbk - 12/19/90 - Modify setting of CKTminBreak */
|
/* gtri - begin - wbk - 12/19/90 - Modify setting of CKTminBreak */
|
||||||
/* Set to 10 times delmin for ATESSE 1 compatibity */
|
/* Set to 10 times delmin for ATESSE 1 compatibity */
|
||||||
|
|
@ -155,13 +159,12 @@ DCtran(CKTcircuit *ckt,
|
||||||
#endif
|
#endif
|
||||||
error = CKTnames(ckt,&numNames,&nameList);
|
error = CKTnames(ckt,&numNames,&nameList);
|
||||||
if(error) return(error);
|
if(error) return(error);
|
||||||
SPfrontEnd->IFnewUid (ckt, &timeUid, NULL,
|
SPfrontEnd->IFnewUid (ckt, &timeUid, NULL, "time", UID_OTHER, NULL);
|
||||||
"time", UID_OTHER, NULL);
|
error = SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
|
||||||
error = SPfrontEnd->OUTpBeginPlot (
|
ckt->CKTcurJob->JOBname,
|
||||||
ckt, ckt->CKTcurJob,
|
timeUid, IF_REAL,
|
||||||
ckt->CKTcurJob->JOBname,
|
numNames, nameList, IF_REAL,
|
||||||
timeUid, IF_REAL,
|
&(job->TRANplot));
|
||||||
numNames, nameList, IF_REAL, &(job->TRANplot));
|
|
||||||
tfree(nameList);
|
tfree(nameList);
|
||||||
if(error) return(error);
|
if(error) return(error);
|
||||||
|
|
||||||
|
|
@ -316,7 +319,10 @@ DCtran(CKTcircuit *ckt,
|
||||||
save2 = ckt->CKTorder;
|
save2 = ckt->CKTorder;
|
||||||
ckt->CKTmode = save_mode;
|
ckt->CKTmode = save_mode;
|
||||||
ckt->CKTorder = save_order;
|
ckt->CKTorder = save_order;
|
||||||
if(error = CKTsenDCtran(ckt)) return(error);
|
error = CKTsenDCtran(ckt);
|
||||||
|
if (error)
|
||||||
|
return(error);
|
||||||
|
|
||||||
ckt->CKTmode = save1;
|
ckt->CKTmode = save1;
|
||||||
ckt->CKTorder = save2;
|
ckt->CKTorder = save2;
|
||||||
}
|
}
|
||||||
|
|
@ -348,11 +354,11 @@ DCtran(CKTcircuit *ckt,
|
||||||
if(ckt->CKTminBreak==0) ckt->CKTminBreak=ckt->CKTmaxStep*5e-5;
|
if(ckt->CKTminBreak==0) ckt->CKTminBreak=ckt->CKTmaxStep*5e-5;
|
||||||
firsttime=0;
|
firsttime=0;
|
||||||
/* To get rawfile working saj*/
|
/* To get rawfile working saj*/
|
||||||
error = SPfrontEnd->OUTpBeginPlot (
|
error = SPfrontEnd->OUTpBeginPlot (NULL, NULL,
|
||||||
NULL, NULL,
|
NULL,
|
||||||
NULL,
|
NULL, 0,
|
||||||
NULL, 0,
|
666, NULL, 666,
|
||||||
666, NULL, 666, &(job->TRANplot));
|
&(job->TRANplot));
|
||||||
if(error) {
|
if(error) {
|
||||||
fprintf(stderr, "Couldn't relink rawfile\n");
|
fprintf(stderr, "Couldn't relink rawfile\n");
|
||||||
return error;
|
return error;
|
||||||
|
|
@ -479,9 +485,6 @@ DCtran(CKTcircuit *ckt,
|
||||||
#ifdef WANT_SENSE2
|
#ifdef WANT_SENSE2
|
||||||
if(ckt->CKTsenInfo && (ckt->CKTsenInfo->SENmode & TRANSEN)){
|
if(ckt->CKTsenInfo && (ckt->CKTsenInfo->SENmode & TRANSEN)){
|
||||||
ckt->CKTsenInfo->SENmode = save;
|
ckt->CKTsenInfo->SENmode = save;
|
||||||
#ifdef SENSDEBUG
|
|
||||||
fclose(outsen);
|
|
||||||
#endif /* SENSDEBUG */
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return(OK);
|
return(OK);
|
||||||
|
|
@ -508,7 +511,7 @@ resume:
|
||||||
if (ckt->CKTtime == 0.)
|
if (ckt->CKTtime == 0.)
|
||||||
SetAnalyse( "tran init", 0);
|
SetAnalyse( "tran init", 0);
|
||||||
else
|
else
|
||||||
SetAnalyse( "tran", (int)((ckt->CKTtime * 1000.) / ckt->CKTfinalTime) + 0.5);
|
SetAnalyse( "tran", (int)((ckt->CKTtime * 1000.) / ckt->CKTfinalTime + 0.5));
|
||||||
#endif
|
#endif
|
||||||
ckt->CKTdelta =
|
ckt->CKTdelta =
|
||||||
MIN(ckt->CKTdelta,ckt->CKTmaxStep);
|
MIN(ckt->CKTdelta,ckt->CKTmaxStep);
|
||||||
|
|
@ -546,15 +549,37 @@ resume:
|
||||||
ckt->CKTbreaks[1] - ckt->CKTbreaks[0]));
|
ckt->CKTbreaks[1] - ckt->CKTbreaks[0]));
|
||||||
|
|
||||||
if(firsttime) {
|
if(firsttime) {
|
||||||
|
/* set a breakpoint to reduce ringing of current in devices */
|
||||||
|
if (ckt->CKTmode&MODEUIC)
|
||||||
|
CKTsetBreak(ckt,ckt->CKTstep);
|
||||||
|
|
||||||
ckt->CKTdelta /= 10;
|
ckt->CKTdelta /= 10;
|
||||||
#ifdef STEPDEBUG
|
#ifdef STEPDEBUG
|
||||||
(void)printf("delta cut for initial timepoint\n");
|
(void)printf("delta cut for initial timepoint\n");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef XSPICE
|
#ifndef XSPICE
|
||||||
|
/* don't want to get below delmin for no reason */
|
||||||
|
ckt->CKTdelta = MAX(ckt->CKTdelta, ckt->CKTdelmin*2.0);
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef XSPICE
|
||||||
|
else if(ckt->CKTtime + ckt->CKTdelta >= ckt->CKTbreaks[0]) {
|
||||||
|
ckt->CKTsaveDelta = ckt->CKTdelta;
|
||||||
|
ckt->CKTdelta = ckt->CKTbreaks[0] - ckt->CKTtime;
|
||||||
|
#ifdef STEPDEBUG
|
||||||
|
(void)printf("delta cut to %g to hit breakpoint\n",ckt->CKTdelta);
|
||||||
|
fflush(stdout);
|
||||||
|
#endif
|
||||||
|
ckt->CKTbreak = 1; /* why? the current pt. is not a bkpt. */
|
||||||
|
}
|
||||||
|
#endif /* !XSPICE */
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef XSPICE
|
||||||
/* gtri - begin - wbk - Add Breakpoint stuff */
|
/* gtri - begin - wbk - Add Breakpoint stuff */
|
||||||
|
|
||||||
if(ckt->CKTtime + ckt->CKTdelta >= g_mif_info.breakpoint.current) {
|
if(ckt->CKTtime + ckt->CKTdelta >= g_mif_info.breakpoint.current) {
|
||||||
|
|
@ -595,30 +620,7 @@ resume:
|
||||||
}
|
}
|
||||||
|
|
||||||
/* gtri - end - wbk - Modify Breakpoint stuff */
|
/* gtri - end - wbk - Modify Breakpoint stuff */
|
||||||
#else /* !XSPICE */
|
|
||||||
|
|
||||||
/* don't want to get below delmin for no reason */
|
|
||||||
ckt->CKTdelta = MAX(ckt->CKTdelta, ckt->CKTdelmin*2.0);
|
|
||||||
}
|
|
||||||
else if(ckt->CKTtime + ckt->CKTdelta >= ckt->CKTbreaks[0]) {
|
|
||||||
ckt->CKTsaveDelta = ckt->CKTdelta;
|
|
||||||
ckt->CKTdelta = ckt->CKTbreaks[0] - ckt->CKTtime;
|
|
||||||
#ifdef STEPDEBUG
|
|
||||||
(void)printf("delta cut to %g to hit breakpoint\n",ckt->CKTdelta);
|
|
||||||
fflush(stdout);
|
|
||||||
#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
|
|
||||||
|
|
||||||
#endif /* XSPICE */
|
|
||||||
|
|
||||||
#ifdef XSPICE
|
|
||||||
/* gtri - begin - wbk - Do event solution */
|
/* gtri - begin - wbk - Do event solution */
|
||||||
|
|
||||||
if(ckt->evt->counts.num_insts > 0) {
|
if(ckt->evt->counts.num_insts > 0) {
|
||||||
|
|
@ -661,6 +663,15 @@ resume:
|
||||||
} /* end if there are event instances */
|
} /* end if there are event instances */
|
||||||
|
|
||||||
/* gtri - end - wbk - Do event solution */
|
/* gtri - end - wbk - Do event solution */
|
||||||
|
#else
|
||||||
|
|
||||||
|
#ifdef CLUSTER
|
||||||
|
if(!CLUsync(ckt->CKTtime,&ckt->CKTdelta,0)) {
|
||||||
|
printf("Sync error!\n");
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
#endif /* CLUSTER */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
for(i=5; i>=0; i--)
|
for(i=5; i>=0; i--)
|
||||||
ckt->CKTdeltaOld[i+1] = ckt->CKTdeltaOld[i];
|
ckt->CKTdeltaOld[i+1] = ckt->CKTdeltaOld[i];
|
||||||
|
|
@ -792,7 +803,10 @@ resume:
|
||||||
save2 = ckt->CKTorder;
|
save2 = ckt->CKTorder;
|
||||||
ckt->CKTmode = save_mode;
|
ckt->CKTmode = save_mode;
|
||||||
ckt->CKTorder = save_order;
|
ckt->CKTorder = save_order;
|
||||||
if(error = CKTsenDCtran(ckt)) return(error);
|
error = CKTsenDCtran (ckt);
|
||||||
|
if (error)
|
||||||
|
return(error);
|
||||||
|
|
||||||
ckt->CKTmode = save1;
|
ckt->CKTmode = save1;
|
||||||
ckt->CKTorder = save2;
|
ckt->CKTorder = save2;
|
||||||
}
|
}
|
||||||
|
|
@ -852,7 +866,10 @@ resume:
|
||||||
save2 = ckt->CKTorder;
|
save2 = ckt->CKTorder;
|
||||||
ckt->CKTmode = save_mode;
|
ckt->CKTmode = save_mode;
|
||||||
ckt->CKTorder = save_order;
|
ckt->CKTorder = save_order;
|
||||||
if(error = CKTsenDCtran(ckt)) return(error);
|
error = CKTsenDCtran(ckt);
|
||||||
|
if (error)
|
||||||
|
return (error);
|
||||||
|
|
||||||
ckt->CKTmode = save1;
|
ckt->CKTmode = save1;
|
||||||
ckt->CKTorder = save2;
|
ckt->CKTorder = save2;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,7 @@ DCtrCurv(CKTcircuit *ckt, int restart)
|
||||||
static runDesc *plot = NULL;
|
static runDesc *plot = NULL;
|
||||||
|
|
||||||
#ifdef WANT_SENSE2
|
#ifdef WANT_SENSE2
|
||||||
|
long save;
|
||||||
#ifdef SENSDEBUG
|
#ifdef SENSDEBUG
|
||||||
if(ckt->CKTsenInfo && (ckt->CKTsenInfo->SENmode&DCSEN) ){
|
if(ckt->CKTsenInfo && (ckt->CKTsenInfo->SENmode&DCSEN) ){
|
||||||
printf("\nDC Sensitivity Results\n\n");
|
printf("\nDC Sensitivity Results\n\n");
|
||||||
|
|
@ -66,11 +67,11 @@ DCtrCurv(CKTcircuit *ckt, int restart)
|
||||||
/* continuing */
|
/* continuing */
|
||||||
i = job->TRCVnestState;
|
i = job->TRCVnestState;
|
||||||
/* resume to work? saj*/
|
/* resume to work? saj*/
|
||||||
error = SPfrontEnd->OUTpBeginPlot (
|
error = SPfrontEnd->OUTpBeginPlot (NULL, NULL,
|
||||||
NULL, NULL,
|
NULL,
|
||||||
NULL,
|
NULL, 0,
|
||||||
NULL, 0,
|
666, NULL, 666,
|
||||||
666, NULL, 666, &plot);
|
&plot);
|
||||||
goto resume;
|
goto resume;
|
||||||
}
|
}
|
||||||
ckt->CKTtime = 0;
|
ckt->CKTtime = 0;
|
||||||
|
|
@ -192,36 +193,31 @@ found:;
|
||||||
|
|
||||||
|
|
||||||
if (job->TRCVvType[i] == vcode)
|
if (job->TRCVvType[i] == vcode)
|
||||||
SPfrontEnd->IFnewUid (ckt, &varUid, NULL,
|
SPfrontEnd->IFnewUid (ckt, &varUid, NULL, "v-sweep", UID_OTHER, NULL);
|
||||||
"v-sweep", UID_OTHER, NULL);
|
|
||||||
|
|
||||||
else {
|
else {
|
||||||
if (job->TRCVvType[i] == icode)
|
if (job->TRCVvType[i] == icode)
|
||||||
SPfrontEnd->IFnewUid (ckt, &varUid, NULL,
|
SPfrontEnd->IFnewUid (ckt, &varUid, NULL, "i-sweep", UID_OTHER, NULL);
|
||||||
"i-sweep", UID_OTHER, NULL);
|
|
||||||
|
|
||||||
else {
|
else {
|
||||||
if (job->TRCVvType[i] == TEMP_CODE)
|
if (job->TRCVvType[i] == TEMP_CODE)
|
||||||
SPfrontEnd->IFnewUid (ckt, &varUid, NULL,
|
SPfrontEnd->IFnewUid (ckt, &varUid, NULL, "temp-sweep", UID_OTHER, NULL);
|
||||||
"temp-sweep", UID_OTHER, NULL);
|
|
||||||
|
|
||||||
else {
|
else {
|
||||||
if (job->TRCVvType[i] == rcode)
|
if (job->TRCVvType[i] == rcode)
|
||||||
SPfrontEnd->IFnewUid (ckt, &varUid, NULL,
|
SPfrontEnd->IFnewUid (ckt, &varUid, NULL, "res-sweep", UID_OTHER, NULL);
|
||||||
"res-sweep", UID_OTHER, NULL);
|
|
||||||
|
|
||||||
else
|
else
|
||||||
SPfrontEnd->IFnewUid (ckt, &varUid, NULL,
|
SPfrontEnd->IFnewUid (ckt, &varUid, NULL, "?-sweep", UID_OTHER, NULL);
|
||||||
"?-sweep", UID_OTHER, NULL);
|
|
||||||
} /* icode */
|
} /* icode */
|
||||||
} /* TEMP_CODE */
|
} /* TEMP_CODE */
|
||||||
} /* rcode*/
|
} /* rcode*/
|
||||||
|
|
||||||
error = SPfrontEnd->OUTpBeginPlot (
|
error = SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
|
||||||
ckt, ckt->CKTcurJob,
|
ckt->CKTcurJob->JOBname,
|
||||||
ckt->CKTcurJob->JOBname,
|
varUid, IF_REAL,
|
||||||
varUid, IF_REAL,
|
numNames, nameList, IF_REAL,
|
||||||
numNames, nameList, IF_REAL, &plot);
|
&plot);
|
||||||
tfree(nameList);
|
tfree(nameList);
|
||||||
|
|
||||||
if(error) return(error);
|
if(error) return(error);
|
||||||
|
|
@ -450,7 +446,7 @@ resume:
|
||||||
}
|
}
|
||||||
if (job->TRCVvType[i] == TEMP_CODE) { /* Temperature */
|
if (job->TRCVvType[i] == TEMP_CODE) { /* Temperature */
|
||||||
printf("Current Circuit Temperature : %.5e C\n",
|
printf("Current Circuit Temperature : %.5e C\n",
|
||||||
ckt-CKTtemp - CONSTCtoK);
|
ckt->CKTtemp - CONSTCtoK);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* SENSDEBUG */
|
#endif /* SENSDEBUG */
|
||||||
|
|
@ -458,7 +454,10 @@ resume:
|
||||||
senmode = ckt->CKTsenInfo->SENmode;
|
senmode = ckt->CKTsenInfo->SENmode;
|
||||||
save = ckt->CKTmode;
|
save = ckt->CKTmode;
|
||||||
ckt->CKTsenInfo->SENmode = DCSEN;
|
ckt->CKTsenInfo->SENmode = DCSEN;
|
||||||
if(error = CKTsenDCtran(ckt)) return (error);
|
error = CKTsenDCtran(ckt);
|
||||||
|
if (error)
|
||||||
|
return(error);
|
||||||
|
|
||||||
ckt->CKTmode = save;
|
ckt->CKTmode = save;
|
||||||
ckt->CKTsenInfo->SENmode = senmode;
|
ckt->CKTsenInfo->SENmode = senmode;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -107,11 +107,11 @@ time1 = SPfrontEnd->IFseconds();
|
||||||
|
|
||||||
if (ckt->CKTkeepOpInfo) {
|
if (ckt->CKTkeepOpInfo) {
|
||||||
/* Dump operating point. */
|
/* Dump operating point. */
|
||||||
error = SPfrontEnd->OUTpBeginPlot (
|
error = SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
|
||||||
ckt, ckt->CKTcurJob,
|
"Distortion Operating Point",
|
||||||
"Distortion Operating Point",
|
NULL, IF_REAL,
|
||||||
NULL, IF_REAL,
|
numNames, nameList, IF_REAL,
|
||||||
numNames, nameList, IF_REAL, &acPlot);
|
&acPlot);
|
||||||
if(error) return(error);
|
if(error) return(error);
|
||||||
CKTdump(ckt, 0.0, acPlot);
|
CKTdump(ckt, 0.0, acPlot);
|
||||||
SPfrontEnd->OUTendPlot (acPlot);
|
SPfrontEnd->OUTendPlot (acPlot);
|
||||||
|
|
@ -516,16 +516,14 @@ time1 = SPfrontEnd->IFseconds();
|
||||||
if (! job->Df2wanted) {
|
if (! job->Df2wanted) {
|
||||||
error = CKTnames(ckt,&numNames,&nameList);
|
error = CKTnames(ckt,&numNames,&nameList);
|
||||||
if(error) return(error);
|
if(error) return(error);
|
||||||
SPfrontEnd->IFnewUid (ckt, &freqUid, NULL,
|
SPfrontEnd->IFnewUid (ckt, &freqUid, NULL, "frequency", UID_OTHER, NULL);
|
||||||
"frequency", UID_OTHER, NULL);
|
SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
|
||||||
SPfrontEnd->OUTpBeginPlot (
|
"DISTORTION - 2nd harmonic",
|
||||||
ckt, ckt->CKTcurJob,
|
freqUid, IF_REAL,
|
||||||
"DISTORTION - 2nd harmonic",
|
numNames, nameList, IF_COMPLEX,
|
||||||
freqUid, IF_REAL,
|
&acPlot);
|
||||||
numNames, nameList, IF_COMPLEX, &acPlot);
|
|
||||||
if (job->DstepType != LINEAR) {
|
if (job->DstepType != LINEAR) {
|
||||||
SPfrontEnd->OUTattributes (acPlot, NULL,
|
SPfrontEnd->OUTattributes (acPlot, NULL, OUT_SCALE_LOG, NULL);
|
||||||
OUT_SCALE_LOG, NULL);
|
|
||||||
}
|
}
|
||||||
for (i=0; i< displacement ; i++)
|
for (i=0; i< displacement ; i++)
|
||||||
{
|
{
|
||||||
|
|
@ -542,13 +540,12 @@ time1 = SPfrontEnd->IFseconds();
|
||||||
|
|
||||||
error = CKTnames(ckt,&numNames,&nameList);
|
error = CKTnames(ckt,&numNames,&nameList);
|
||||||
if(error) return(error);
|
if(error) return(error);
|
||||||
SPfrontEnd->IFnewUid (ckt, &freqUid, NULL,
|
SPfrontEnd->IFnewUid (ckt, &freqUid, NULL, "frequency", UID_OTHER, NULL);
|
||||||
"frequency", UID_OTHER, NULL);
|
SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
|
||||||
SPfrontEnd->OUTpBeginPlot (
|
"DISTORTION - 3rd harmonic",
|
||||||
ckt, ckt->CKTcurJob,
|
freqUid, IF_REAL,
|
||||||
"DISTORTION - 3rd harmonic",
|
numNames, nameList, IF_COMPLEX,
|
||||||
freqUid, IF_REAL,
|
&acPlot);
|
||||||
numNames, nameList, IF_COMPLEX, &acPlot);
|
|
||||||
for (i=0; i< displacement ; i++)
|
for (i=0; i< displacement ; i++)
|
||||||
{
|
{
|
||||||
DkerProc(D_THRF1,job->r3H11stor[i],
|
DkerProc(D_THRF1,job->r3H11stor[i],
|
||||||
|
|
@ -566,13 +563,12 @@ time1 = SPfrontEnd->IFseconds();
|
||||||
|
|
||||||
error = CKTnames(ckt,&numNames,&nameList);
|
error = CKTnames(ckt,&numNames,&nameList);
|
||||||
if(error) return(error);
|
if(error) return(error);
|
||||||
SPfrontEnd->IFnewUid (ckt, &freqUid, NULL,
|
SPfrontEnd->IFnewUid (ckt, &freqUid, NULL, "frequency", UID_OTHER, NULL);
|
||||||
"frequency", UID_OTHER, NULL);
|
SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
|
||||||
SPfrontEnd->OUTpBeginPlot (
|
"DISTORTION - IM: f1+f2",
|
||||||
ckt, ckt->CKTcurJob,
|
freqUid, IF_REAL,
|
||||||
"DISTORTION - IM: f1+f2",
|
numNames, nameList, IF_COMPLEX,
|
||||||
freqUid, IF_REAL,
|
&acPlot);
|
||||||
numNames, nameList, IF_COMPLEX, &acPlot);
|
|
||||||
for (i=0; i< displacement ; i++)
|
for (i=0; i< displacement ; i++)
|
||||||
{
|
{
|
||||||
DkerProc(D_F1PF2,job->r2H12stor[i],
|
DkerProc(D_F1PF2,job->r2H12stor[i],
|
||||||
|
|
@ -588,13 +584,12 @@ time1 = SPfrontEnd->IFseconds();
|
||||||
|
|
||||||
error = CKTnames(ckt,&numNames,&nameList);
|
error = CKTnames(ckt,&numNames,&nameList);
|
||||||
if(error) return(error);
|
if(error) return(error);
|
||||||
SPfrontEnd->IFnewUid (ckt, &freqUid, NULL,
|
SPfrontEnd->IFnewUid (ckt, &freqUid, NULL, "frequency", UID_OTHER, NULL);
|
||||||
"frequency", UID_OTHER, NULL);
|
SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
|
||||||
SPfrontEnd->OUTpBeginPlot (
|
"DISTORTION - IM: f1-f2",
|
||||||
ckt, ckt->CKTcurJob,
|
freqUid, IF_REAL,
|
||||||
"DISTORTION - IM: f1-f2",
|
numNames, nameList, IF_COMPLEX,
|
||||||
freqUid, IF_REAL,
|
&acPlot);
|
||||||
numNames, nameList, IF_COMPLEX, &acPlot);
|
|
||||||
for (i=0; i< displacement ; i++)
|
for (i=0; i< displacement ; i++)
|
||||||
{
|
{
|
||||||
DkerProc(D_F1MF2,
|
DkerProc(D_F1MF2,
|
||||||
|
|
@ -611,13 +606,12 @@ time1 = SPfrontEnd->IFseconds();
|
||||||
|
|
||||||
error = CKTnames(ckt,&numNames,&nameList);
|
error = CKTnames(ckt,&numNames,&nameList);
|
||||||
if(error) return(error);
|
if(error) return(error);
|
||||||
SPfrontEnd->IFnewUid (ckt, &freqUid, NULL,
|
SPfrontEnd->IFnewUid (ckt, &freqUid, NULL, "frequency", UID_OTHER, NULL);
|
||||||
"frequency", UID_OTHER, NULL);
|
SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
|
||||||
SPfrontEnd->OUTpBeginPlot (
|
"DISTORTION - IM: 2f1-f2",
|
||||||
ckt, ckt->CKTcurJob,
|
freqUid, IF_REAL,
|
||||||
"DISTORTION - IM: 2f1-f2",
|
numNames, nameList, IF_COMPLEX,
|
||||||
freqUid, IF_REAL,
|
&acPlot);
|
||||||
numNames, nameList, IF_COMPLEX, &acPlot);
|
|
||||||
for (i=0; i< displacement ; i++)
|
for (i=0; i< displacement ; i++)
|
||||||
{
|
{
|
||||||
DkerProc(D_2F1MF2,
|
DkerProc(D_2F1MF2,
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,15 @@
|
||||||
/* Patch to noisean.c by Richard D. McRoberts.
|
|
||||||
* Patched with modifications from Weidong Liu (2000)
|
|
||||||
* Patched with modifications ftom Weidong Liu
|
|
||||||
* in bsim4.1.0 code
|
|
||||||
*/
|
|
||||||
/**********
|
/**********
|
||||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||||
Author: 1987 Gary W. Ng
|
Author: 1987 Gary W. Ng
|
||||||
Modified: 2001 AlansFixes
|
Modified: 2001 AlansFixes
|
||||||
**********/
|
**********/
|
||||||
|
|
||||||
|
/* Patch to noisean.c by Richard D. McRoberts.
|
||||||
|
* Patched with modifications from Weidong Liu (2000)
|
||||||
|
* Patched with modifications ftom Weidong Liu
|
||||||
|
* in bsim4.1.0 code
|
||||||
|
*/
|
||||||
|
|
||||||
#include "ngspice/ngspice.h"
|
#include "ngspice/ngspice.h"
|
||||||
#include "ngspice/acdefs.h"
|
#include "ngspice/acdefs.h"
|
||||||
#include "ngspice/cktdefs.h"
|
#include "ngspice/cktdefs.h"
|
||||||
|
|
@ -47,8 +48,7 @@ NOISEan (CKTcircuit *ckt, int restart)
|
||||||
inst = NULL;
|
inst = NULL;
|
||||||
code = CKTtypelook("Vsource");
|
code = CKTtypelook("Vsource");
|
||||||
if (code != -1) {
|
if (code != -1) {
|
||||||
error = CKTfndDev(ckt, &code, &inst,
|
error = CKTfndDev(ckt, &code, &inst, job->input, NULL);
|
||||||
job->input, NULL, NULL);
|
|
||||||
if (!error && !((VSRCinstance *)inst)->VSRCacGiven) {
|
if (!error && !((VSRCinstance *)inst)->VSRCacGiven) {
|
||||||
errMsg = TMALLOC(char, strlen(noacinput) + 1);
|
errMsg = TMALLOC(char, strlen(noacinput) + 1);
|
||||||
strcpy(errMsg,noacinput);
|
strcpy(errMsg,noacinput);
|
||||||
|
|
@ -58,8 +58,7 @@ NOISEan (CKTcircuit *ckt, int restart)
|
||||||
|
|
||||||
code = CKTtypelook("Isource");
|
code = CKTtypelook("Isource");
|
||||||
if (code != -1 && inst==NULL) {
|
if (code != -1 && inst==NULL) {
|
||||||
error = CKTfndDev(ckt, &code, &inst,
|
error = CKTfndDev(ckt, &code, &inst, job->input, NULL);
|
||||||
job->input, NULL, NULL);
|
|
||||||
if (error) {
|
if (error) {
|
||||||
/* XXX ??? */
|
/* XXX ??? */
|
||||||
SPfrontEnd->IFerror (ERR_WARNING,
|
SPfrontEnd->IFerror (ERR_WARNING,
|
||||||
|
|
@ -119,8 +118,7 @@ NOISEan (CKTcircuit *ckt, int restart)
|
||||||
/* the current front-end needs the namelist to be fully
|
/* the current front-end needs the namelist to be fully
|
||||||
declared before an OUTpBeginplot */
|
declared before an OUTpBeginplot */
|
||||||
|
|
||||||
SPfrontEnd->IFnewUid (ckt, &freqUid, NULL,
|
SPfrontEnd->IFnewUid (ckt, &freqUid, NULL, "frequency", UID_OTHER, NULL);
|
||||||
"frequency", UID_OTHER, NULL);
|
|
||||||
|
|
||||||
data->numPlots = 0; /* we don't have any plots yet */
|
data->numPlots = 0; /* we don't have any plots yet */
|
||||||
error = CKTnoise(ckt,N_DENS,N_OPEN,data);
|
error = CKTnoise(ckt,N_DENS,N_OPEN,data);
|
||||||
|
|
@ -131,16 +129,15 @@ NOISEan (CKTcircuit *ckt, int restart)
|
||||||
* plot
|
* plot
|
||||||
*/
|
*/
|
||||||
|
|
||||||
error = SPfrontEnd->OUTpBeginPlot (
|
error = SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
|
||||||
ckt, ckt->CKTcurJob,
|
"Noise Spectral Density Curves - (V^2 or A^2)/Hz",
|
||||||
"Noise Spectral Density Curves - (V^2 or A^2)/Hz",
|
freqUid, IF_REAL,
|
||||||
freqUid, IF_REAL,
|
data->numPlots, data->namelist, IF_REAL,
|
||||||
data->numPlots, data->namelist, IF_REAL, &(data->NplotPtr));
|
&(data->NplotPtr));
|
||||||
if (error) return(error);
|
if (error) return(error);
|
||||||
|
|
||||||
if (job->NstpType != LINEAR) {
|
if (job->NstpType != LINEAR) {
|
||||||
SPfrontEnd->OUTattributes (data->NplotPtr, NULL,
|
SPfrontEnd->OUTattributes (data->NplotPtr, NULL, OUT_SCALE_LOG, NULL);
|
||||||
OUT_SCALE_LOG, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else { /* we must have paused before. pick up where we left off */
|
} else { /* we must have paused before. pick up where we left off */
|
||||||
|
|
@ -166,11 +163,11 @@ NOISEan (CKTcircuit *ckt, int restart)
|
||||||
data->outNoiz = job->NsavOnoise;
|
data->outNoiz = job->NsavOnoise;
|
||||||
data->inNoise = job->NsavInoise;
|
data->inNoise = job->NsavInoise;
|
||||||
/* saj resume rawfile fix*/
|
/* saj resume rawfile fix*/
|
||||||
error = SPfrontEnd->OUTpBeginPlot (
|
error = SPfrontEnd->OUTpBeginPlot (NULL, NULL,
|
||||||
NULL, NULL,
|
NULL,
|
||||||
NULL,
|
NULL, 0,
|
||||||
NULL, 0,
|
666, NULL, 666,
|
||||||
666, NULL, 666, &(data->NplotPtr));
|
&(data->NplotPtr));
|
||||||
/*saj*/
|
/*saj*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -278,11 +275,11 @@ NOISEan (CKTcircuit *ckt, int restart)
|
||||||
|
|
||||||
if (error) return(error);
|
if (error) return(error);
|
||||||
|
|
||||||
SPfrontEnd->OUTpBeginPlot (
|
SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
|
||||||
ckt, ckt->CKTcurJob,
|
"Integrated Noise - V^2 or A^2",
|
||||||
"Integrated Noise - V^2 or A^2",
|
NULL, 0,
|
||||||
NULL, 0,
|
data->numPlots, data->namelist, IF_REAL,
|
||||||
data->numPlots, data->namelist, IF_REAL, &(data->NplotPtr));
|
&(data->NplotPtr));
|
||||||
|
|
||||||
error = CKTnoise(ckt,INT_NOIZ,N_CALC,data);
|
error = CKTnoise(ckt,INT_NOIZ,N_CALC,data);
|
||||||
if (error) return(error);
|
if (error) return(error);
|
||||||
|
|
|
||||||
|
|
@ -46,11 +46,11 @@ PZan(CKTcircuit *ckt, int reset)
|
||||||
/* Dump operating point. */
|
/* Dump operating point. */
|
||||||
error = CKTnames(ckt,&numNames,&nameList);
|
error = CKTnames(ckt,&numNames,&nameList);
|
||||||
if(error) return(error);
|
if(error) return(error);
|
||||||
error = SPfrontEnd->OUTpBeginPlot (
|
error = SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
|
||||||
ckt, ckt->CKTcurJob,
|
"Distortion Operating Point",
|
||||||
"Distortion Operating Point",
|
NULL, IF_REAL,
|
||||||
NULL, IF_REAL,
|
numNames, nameList, IF_REAL,
|
||||||
numNames, nameList, IF_REAL, &plot);
|
&plot);
|
||||||
if(error) return(error);
|
if(error) return(error);
|
||||||
CKTdump(ckt, 0.0, plot);
|
CKTdump(ckt, 0.0, plot);
|
||||||
SPfrontEnd->OUTendPlot (plot);
|
SPfrontEnd->OUTendPlot (plot);
|
||||||
|
|
@ -94,7 +94,7 @@ PZinit(CKTcircuit *ckt)
|
||||||
i = CKTtypelook("LTRA");
|
i = CKTtypelook("LTRA");
|
||||||
}
|
}
|
||||||
if (i != -1 && ckt->CKThead[i] != NULL)
|
if (i != -1 && ckt->CKThead[i] != NULL)
|
||||||
MERROR(E_XMISSIONLINE, "Transmission lines not supported")
|
MERROR(E_XMISSIONLINE, "Transmission lines not supported");
|
||||||
|
|
||||||
job->PZpoleList = NULL;
|
job->PZpoleList = NULL;
|
||||||
job->PZzeroList = NULL;
|
job->PZzeroList = NULL;
|
||||||
|
|
@ -102,19 +102,19 @@ PZinit(CKTcircuit *ckt)
|
||||||
job->PZnZeros = 0;
|
job->PZnZeros = 0;
|
||||||
|
|
||||||
if (job->PZin_pos == job->PZin_neg)
|
if (job->PZin_pos == job->PZin_neg)
|
||||||
MERROR(E_SHORT, "Input is shorted")
|
MERROR(E_SHORT, "Input is shorted");
|
||||||
|
|
||||||
if (job->PZout_pos == job->PZout_neg)
|
if (job->PZout_pos == job->PZout_neg)
|
||||||
MERROR(E_SHORT, "Output is shorted")
|
MERROR(E_SHORT, "Output is shorted");
|
||||||
|
|
||||||
if (job->PZin_pos == job->PZout_pos
|
if (job->PZin_pos == job->PZout_pos
|
||||||
&& job->PZin_neg == job->PZout_neg
|
&& job->PZin_neg == job->PZout_neg
|
||||||
&& job->PZinput_type == PZ_IN_VOL)
|
&& job->PZinput_type == PZ_IN_VOL)
|
||||||
MERROR(E_INISOUT, "Transfer function is unity")
|
MERROR(E_INISOUT, "Transfer function is unity");
|
||||||
else if (job->PZin_pos == job->PZout_neg
|
else if (job->PZin_pos == job->PZout_neg
|
||||||
&& job->PZin_neg == job->PZout_pos
|
&& job->PZin_neg == job->PZout_pos
|
||||||
&& job->PZinput_type == PZ_IN_VOL)
|
&& job->PZinput_type == PZ_IN_VOL)
|
||||||
MERROR(E_INISOUT, "Transfer function is -1")
|
MERROR(E_INISOUT, "Transfer function is -1");
|
||||||
|
|
||||||
return(OK);
|
return(OK);
|
||||||
}
|
}
|
||||||
|
|
@ -141,20 +141,18 @@ PZpost(CKTcircuit *ckt)
|
||||||
j = 0;
|
j = 0;
|
||||||
for (i = 0; i < job->PZnPoles; i++) {
|
for (i = 0; i < job->PZnPoles; i++) {
|
||||||
sprintf(name, "pole(%-u)", i+1);
|
sprintf(name, "pole(%-u)", i+1);
|
||||||
SPfrontEnd->IFnewUid (ckt, &(namelist[j++]), NULL,
|
SPfrontEnd->IFnewUid (ckt, &(namelist[j++]), NULL, name, UID_OTHER, NULL);
|
||||||
name, UID_OTHER, NULL);
|
|
||||||
}
|
}
|
||||||
for (i = 0; i < job->PZnZeros; i++) {
|
for (i = 0; i < job->PZnZeros; i++) {
|
||||||
sprintf(name, "zero(%-u)", i+1);
|
sprintf(name, "zero(%-u)", i+1);
|
||||||
SPfrontEnd->IFnewUid (ckt, &(namelist[j++]), NULL,
|
SPfrontEnd->IFnewUid (ckt, &(namelist[j++]), NULL, name, UID_OTHER, NULL);
|
||||||
name, UID_OTHER, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SPfrontEnd->OUTpBeginPlot (
|
SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
|
||||||
ckt, ckt->CKTcurJob,
|
ckt->CKTcurJob->JOBname,
|
||||||
ckt->CKTcurJob->JOBname,
|
NULL, 0,
|
||||||
NULL, 0,
|
job->PZnPoles + job->PZnZeros, namelist, IF_COMPLEX,
|
||||||
job->PZnPoles + job->PZnZeros, namelist, IF_COMPLEX, &pzPlotPtr);
|
&pzPlotPtr);
|
||||||
|
|
||||||
j = 0;
|
j = 0;
|
||||||
if (job->PZnPoles > 0) {
|
if (job->PZnPoles > 0) {
|
||||||
|
|
|
||||||
|
|
@ -51,8 +51,7 @@ TFanal(CKTcircuit *ckt, int restart)
|
||||||
Itype = CKTtypelook("Isource");
|
Itype = CKTtypelook("Isource");
|
||||||
Vtype = CKTtypelook("Vsource");
|
Vtype = CKTtypelook("Vsource");
|
||||||
if(Itype != -1) {
|
if(Itype != -1) {
|
||||||
error = CKTfndDev(ckt,&Itype,&ptr,
|
error = CKTfndDev(ckt, &Itype, &ptr, job->TFinSrc, NULL);
|
||||||
job->TFinSrc, NULL, NULL);
|
|
||||||
if(error ==0) {
|
if(error ==0) {
|
||||||
job->TFinIsI = 1;
|
job->TFinIsI = 1;
|
||||||
job->TFinIsV = 0;
|
job->TFinIsV = 0;
|
||||||
|
|
@ -62,9 +61,7 @@ TFanal(CKTcircuit *ckt, int restart)
|
||||||
}
|
}
|
||||||
|
|
||||||
if( (Vtype != -1) && (ptr==NULL) ) {
|
if( (Vtype != -1) && (ptr==NULL) ) {
|
||||||
error = CKTfndDev(ckt,&Vtype,&ptr,
|
error = CKTfndDev(ckt, &Vtype, &ptr, job->TFinSrc, NULL);
|
||||||
job->TFinSrc, NULL,
|
|
||||||
NULL);
|
|
||||||
job->TFinIsV = 1;
|
job->TFinIsV = 1;
|
||||||
job->TFinIsI = 0;
|
job->TFinIsI = 0;
|
||||||
if(error !=0) {
|
if(error !=0) {
|
||||||
|
|
@ -94,30 +91,26 @@ TFanal(CKTcircuit *ckt, int restart)
|
||||||
ckt->CKTrhs[0]=0;
|
ckt->CKTrhs[0]=0;
|
||||||
|
|
||||||
/* make a UID for the transfer function output */
|
/* make a UID for the transfer function output */
|
||||||
SPfrontEnd->IFnewUid (ckt, &tfuid, NULL, "Transfer_function",
|
SPfrontEnd->IFnewUid (ckt, &tfuid, NULL, "Transfer_function", UID_OTHER, NULL);
|
||||||
UID_OTHER, NULL);
|
|
||||||
|
|
||||||
/* make a UID for the input impedance */
|
/* make a UID for the input impedance */
|
||||||
SPfrontEnd->IFnewUid (ckt, &inuid, job->TFinSrc,
|
SPfrontEnd->IFnewUid (ckt, &inuid, job->TFinSrc, "Input_impedance", UID_OTHER, NULL);
|
||||||
"Input_impedance", UID_OTHER, NULL);
|
|
||||||
|
|
||||||
/* make a UID for the output impedance */
|
/* make a UID for the output impedance */
|
||||||
if (job->TFoutIsI) {
|
if (job->TFoutIsI) {
|
||||||
SPfrontEnd->IFnewUid (ckt, &outuid, job->TFoutSrc
|
SPfrontEnd->IFnewUid (ckt, &outuid, job->TFoutSrc ,"Output_impedance", UID_OTHER, NULL);
|
||||||
,"Output_impedance", UID_OTHER, NULL);
|
|
||||||
} else {
|
} else {
|
||||||
name = TMALLOC(char, strlen(job->TFoutName) + 22);
|
name = TMALLOC(char, strlen(job->TFoutName) + 22);
|
||||||
(void)sprintf(name,"output_impedance_at_%s",
|
(void)sprintf(name,"output_impedance_at_%s",
|
||||||
job->TFoutName);
|
job->TFoutName);
|
||||||
SPfrontEnd->IFnewUid (ckt, &outuid, NULL,
|
SPfrontEnd->IFnewUid (ckt, &outuid, NULL, name, UID_OTHER, NULL);
|
||||||
name, UID_OTHER, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
error = SPfrontEnd->OUTpBeginPlot (
|
error = SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
|
||||||
ckt, ckt->CKTcurJob,
|
job->JOBname,
|
||||||
job->JOBname,
|
NULL, 0,
|
||||||
NULL, 0,
|
3, uids, IF_REAL,
|
||||||
3, uids, IF_REAL, &plotptr);
|
&plotptr);
|
||||||
if(error) return(error);
|
if(error) return(error);
|
||||||
|
|
||||||
/*find transfer function */
|
/*find transfer function */
|
||||||
|
|
|
||||||
|
|
@ -22,23 +22,14 @@ int TRANinit(CKTcircuit *ckt, JOB *anal)
|
||||||
ckt->CKTinitTime = job->TRANinitTime;
|
ckt->CKTinitTime = job->TRANinitTime;
|
||||||
ckt->CKTmaxStep = job->TRANmaxStep;
|
ckt->CKTmaxStep = job->TRANmaxStep;
|
||||||
|
|
||||||
|
/* The following code has been taken from macspice 3f4 (A. Wilson)
|
||||||
|
in the file traninit.new.c - Seems interesting */
|
||||||
/* The following code has been taken from macspice 3f4 (A. Wilson)
|
if(ckt->CKTmaxStep == 0) {
|
||||||
in the file traninit.new.c - Seems interesting */
|
if (ckt->CKTstep < ( ckt->CKTfinalTime - ckt->CKTinitTime )/50.0)
|
||||||
if(ckt->CKTmaxStep == 0)
|
ckt->CKTmaxStep = ckt->CKTstep;
|
||||||
{
|
else
|
||||||
if (ckt->CKTstep < ( ckt->CKTfinalTime - ckt->CKTinitTime )/50.0)
|
ckt->CKTmaxStep = ( ckt->CKTfinalTime - ckt->CKTinitTime )/50.0;
|
||||||
{
|
}
|
||||||
ckt->CKTmaxStep = ckt->CKTstep;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ckt->CKTmaxStep = ( ckt->CKTfinalTime - ckt->CKTinitTime )/50.0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ckt->CKTdelmin = 1e-11*ckt->CKTmaxStep; /* XXX */
|
ckt->CKTdelmin = 1e-11*ckt->CKTmaxStep; /* XXX */
|
||||||
ckt->CKTmode = job->TRANmode;
|
ckt->CKTmode = job->TRANmode;
|
||||||
|
|
|
||||||
|
|
@ -19,10 +19,14 @@ libasrc_la_SOURCES = \
|
||||||
asrcmdel.c \
|
asrcmdel.c \
|
||||||
asrcpar.c \
|
asrcpar.c \
|
||||||
asrcpzld.c \
|
asrcpzld.c \
|
||||||
asrcset.c \
|
asrcset.c \
|
||||||
asrctemp.c
|
asrctemp.c
|
||||||
|
|
||||||
|
|
||||||
|
if KIRCHHOFF_WANTED
|
||||||
|
libasrc_la_SOURCES += asrcnode.c
|
||||||
|
endif
|
||||||
|
|
||||||
AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(top_srcdir)/src/include
|
AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(top_srcdir)/src/include
|
||||||
AM_CFLAGS = $(STATIC)
|
AM_CFLAGS = $(STATIC)
|
||||||
MAINTAINERCLEANFILES = Makefile.in
|
MAINTAINERCLEANFILES = Makefile.in
|
||||||
|
|
|
||||||
|
|
@ -16,3 +16,7 @@ extern int ASRCacLoad(GENmodel*,CKTcircuit*);
|
||||||
extern int ASRCsetup(SMPmatrix*,GENmodel*,CKTcircuit*,int*);
|
extern int ASRCsetup(SMPmatrix*,GENmodel*,CKTcircuit*,int*);
|
||||||
extern int ASRCunsetup(GENmodel*,CKTcircuit*);
|
extern int ASRCunsetup(GENmodel*,CKTcircuit*);
|
||||||
extern int ASRCtemp(GENmodel*,CKTcircuit*);
|
extern int ASRCtemp(GENmodel*,CKTcircuit*);
|
||||||
|
|
||||||
|
#ifdef KIRCHHOFF
|
||||||
|
extern int ASRCnodeIsNonLinear (GENmodel *, CKTcircuit *) ;
|
||||||
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -74,12 +74,17 @@ SPICEdev ASRCinfo = {
|
||||||
#endif
|
#endif
|
||||||
/* DEVinstSize */ &ASRCiSize,
|
/* DEVinstSize */ &ASRCiSize,
|
||||||
/* DEVmodSize */ &ASRCmSize,
|
/* DEVmodSize */ &ASRCmSize,
|
||||||
|
|
||||||
#if defined(KLU) || defined(SuperLU) || defined(UMFPACK)
|
#if defined(KLU) || defined(SuperLU) || defined(UMFPACK)
|
||||||
/* DEVbindCSC */ NULL,
|
/* DEVbindCSC */ NULL,
|
||||||
/* DEVbindCSCComplex */ NULL,
|
/* DEVbindCSCComplex */ NULL,
|
||||||
/* DEVbindCSCComplexToReal */ NULL,
|
/* DEVbindCSCComplexToReal */ NULL,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef KIRCHHOFF
|
||||||
|
/* DEVnodeIsNonLinear */ ASRCnodeIsNonLinear
|
||||||
|
#endif
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
/**********
|
||||||
|
Author: 2013 Francesco Lannutti
|
||||||
|
**********/
|
||||||
|
|
||||||
|
#include "ngspice/ngspice.h"
|
||||||
|
#include "ngspice/cktdefs.h"
|
||||||
|
#include "asrcdefs.h"
|
||||||
|
#include "ngspice/sperror.h"
|
||||||
|
|
||||||
|
int
|
||||||
|
ASRCnodeIsNonLinear (GENmodel *inModel, CKTcircuit *ckt)
|
||||||
|
{
|
||||||
|
ASRCmodel *model = (ASRCmodel *)inModel ;
|
||||||
|
ASRCinstance *here ;
|
||||||
|
|
||||||
|
/* loop through all the ASRC models */
|
||||||
|
for ( ; model != NULL ; model = model->ASRCnextModel)
|
||||||
|
{
|
||||||
|
/* loop through all the instances of the model */
|
||||||
|
for (here = model->ASRCinstances ; here != NULL ; here = here->ASRCnextInstance)
|
||||||
|
{
|
||||||
|
ckt->CKTnodeIsLinear [here->ASRCposNode] = 0 ;
|
||||||
|
ckt->CKTnodeIsLinear [here->ASRCnegNode] = 0 ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (OK) ;
|
||||||
|
}
|
||||||
|
|
@ -54,14 +54,14 @@ ASRCsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states)
|
||||||
|
|
||||||
/* macro to make elements with built in test for out of memory */
|
/* macro to make elements with built in test for out of memory */
|
||||||
#define TSTALLOC(ptr,first,second) \
|
#define TSTALLOC(ptr,first,second) \
|
||||||
if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\
|
do { if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\
|
||||||
return(E_NOMEM);\
|
return(E_NOMEM);\
|
||||||
}
|
} } while(0)
|
||||||
|
|
||||||
#define MY_TSTALLOC(ptr,first,second) \
|
#define MY_TSTALLOC(ptr,first,second) \
|
||||||
if((here->ptr = SMPmakeElt(matrix, here->first, (second)->number)) == NULL){\
|
do { if((here->ptr = SMPmakeElt(matrix, here->first, (second)->number)) == NULL){\
|
||||||
return(E_NOMEM);\
|
return(E_NOMEM);\
|
||||||
}
|
} } while(0)
|
||||||
|
|
||||||
/* For each controlling variable set the entries
|
/* For each controlling variable set the entries
|
||||||
in the vector of the positions of the SMP */
|
in the vector of the positions of the SMP */
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,10 @@ if UMFPACK_WANTED
|
||||||
libbjt_la_SOURCES += bjtbindCSC.c
|
libbjt_la_SOURCES += bjtbindCSC.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if KIRCHHOFF_WANTED
|
||||||
|
libbjt_la_SOURCES += bjtnode.c
|
||||||
|
endif
|
||||||
|
|
||||||
AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(top_srcdir)/src/include
|
AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(top_srcdir)/src/include
|
||||||
AM_CFLAGS = $(STATIC)
|
AM_CFLAGS = $(STATIC)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,9 @@ extern int BJTdisto(int,GENmodel*,CKTcircuit*);
|
||||||
extern int BJTnoise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*);
|
extern int BJTnoise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*);
|
||||||
extern int BJTdSetup(GENmodel*, register CKTcircuit*);
|
extern int BJTdSetup(GENmodel*, register CKTcircuit*);
|
||||||
|
|
||||||
|
#ifdef KIRCHHOFF
|
||||||
|
extern int BJTnodeIsNonLinear (GENmodel *, CKTcircuit *) ;
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(KLU) || defined(SuperLU) || defined(UMFPACK)
|
#if defined(KLU) || defined(SuperLU) || defined(UMFPACK)
|
||||||
|
|
|
||||||
|
|
@ -73,12 +73,17 @@ SPICEdev BJTinfo = { /* description from struct IFdevice */
|
||||||
#endif
|
#endif
|
||||||
/* DEVinstSize */ &BJTiSize,
|
/* DEVinstSize */ &BJTiSize,
|
||||||
/* DEVmodSize */ &BJTmSize,
|
/* DEVmodSize */ &BJTmSize,
|
||||||
|
|
||||||
#if defined(KLU) || defined(SuperLU) || defined(UMFPACK)
|
#if defined(KLU) || defined(SuperLU) || defined(UMFPACK)
|
||||||
/* DEVbindCSC */ BJTbindCSC,
|
/* DEVbindCSC */ BJTbindCSC,
|
||||||
/* DEVbindCSCComplex */ BJTbindCSCComplex,
|
/* DEVbindCSCComplex */ BJTbindCSCComplex,
|
||||||
/* DEVbindCSCComplexToReal */ BJTbindCSCComplexToReal,
|
/* DEVbindCSCComplexToReal */ BJTbindCSCComplexToReal,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef KIRCHHOFF
|
||||||
|
/* DEVnodeIsNonLinear */ BJTnodeIsNonLinear
|
||||||
|
#endif
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
/**********
|
||||||
|
Author: 2013 Francesco Lannutti
|
||||||
|
**********/
|
||||||
|
|
||||||
|
#include "ngspice/ngspice.h"
|
||||||
|
#include "ngspice/cktdefs.h"
|
||||||
|
#include "bjtdefs.h"
|
||||||
|
#include "ngspice/sperror.h"
|
||||||
|
|
||||||
|
int
|
||||||
|
BJTnodeIsNonLinear (GENmodel *inModel, CKTcircuit *ckt)
|
||||||
|
{
|
||||||
|
BJTmodel *model = (BJTmodel *)inModel ;
|
||||||
|
BJTinstance *here ;
|
||||||
|
|
||||||
|
/* loop through all the BJT models */
|
||||||
|
for ( ; model != NULL ; model = model->BJTnextModel)
|
||||||
|
{
|
||||||
|
/* loop through all the instances of the model */
|
||||||
|
for (here = model->BJTinstances ; here != NULL ; here = here->BJTnextInstance)
|
||||||
|
{
|
||||||
|
ckt->CKTnodeIsLinear [here->BJTcolPrimeNode] = 0 ;
|
||||||
|
ckt->CKTnodeIsLinear [here->BJTbasePrimeNode] = 0 ;
|
||||||
|
ckt->CKTnodeIsLinear [here->BJTemitPrimeNode] = 0 ;
|
||||||
|
ckt->CKTnodeIsLinear [here->BJTsubstNode] = 0 ;
|
||||||
|
ckt->CKTnodeIsLinear [here->BJTsubstConNode] = 0 ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (OK) ;
|
||||||
|
}
|
||||||
|
|
@ -540,11 +540,11 @@ load:
|
||||||
,cbe,icbe,cce,icce);
|
,cbe,icbe,cce,icce);
|
||||||
|
|
||||||
printf("cc = %.7e + j%.7e , ce = %.7e + j%.7e,",
|
printf("cc = %.7e + j%.7e , ce = %.7e + j%.7e,",
|
||||||
,cc,icc,ce,ice);
|
cc,icc,ce,ice);
|
||||||
printf("ccprm = %.7e + j%.7e , ceprm = %.7e + j%.7e",
|
printf("ccprm = %.7e + j%.7e , ceprm = %.7e + j%.7e",
|
||||||
ccprm,iccprm,ceprm,iceprm);
|
ccprm,iccprm,ceprm,iceprm);
|
||||||
printf("cb = %.7e + j%.7e , cbprm = %.7e + j%.7e , ",
|
printf("cb = %.7e + j%.7e , cbprm = %.7e + j%.7e , ",
|
||||||
cb,icb,cbprm,icbprm)
|
cb,icb,cbprm,icbprm);
|
||||||
printf("cs = %.7e + j%.7e\n",
|
printf("cs = %.7e + j%.7e\n",
|
||||||
cs,ics);
|
cs,ics);
|
||||||
#endif /* SENSDEBUG */
|
#endif /* SENSDEBUG */
|
||||||
|
|
|
||||||
|
|
@ -420,28 +420,28 @@ BJTsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states)
|
||||||
|
|
||||||
/* macro to make elements with built in test for out of memory */
|
/* macro to make elements with built in test for out of memory */
|
||||||
#define TSTALLOC(ptr,first,second) \
|
#define TSTALLOC(ptr,first,second) \
|
||||||
if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\
|
do { if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\
|
||||||
return(E_NOMEM);\
|
return(E_NOMEM);\
|
||||||
}
|
} } while(0)
|
||||||
TSTALLOC(BJTcolColPrimePtr,BJTcolNode,BJTcolPrimeNode)
|
TSTALLOC(BJTcolColPrimePtr,BJTcolNode,BJTcolPrimeNode);
|
||||||
TSTALLOC(BJTbaseBasePrimePtr,BJTbaseNode,BJTbasePrimeNode)
|
TSTALLOC(BJTbaseBasePrimePtr,BJTbaseNode,BJTbasePrimeNode);
|
||||||
TSTALLOC(BJTemitEmitPrimePtr,BJTemitNode,BJTemitPrimeNode)
|
TSTALLOC(BJTemitEmitPrimePtr,BJTemitNode,BJTemitPrimeNode);
|
||||||
TSTALLOC(BJTcolPrimeColPtr,BJTcolPrimeNode,BJTcolNode)
|
TSTALLOC(BJTcolPrimeColPtr,BJTcolPrimeNode,BJTcolNode);
|
||||||
TSTALLOC(BJTcolPrimeBasePrimePtr,BJTcolPrimeNode,BJTbasePrimeNode)
|
TSTALLOC(BJTcolPrimeBasePrimePtr,BJTcolPrimeNode,BJTbasePrimeNode);
|
||||||
TSTALLOC(BJTcolPrimeEmitPrimePtr,BJTcolPrimeNode,BJTemitPrimeNode)
|
TSTALLOC(BJTcolPrimeEmitPrimePtr,BJTcolPrimeNode,BJTemitPrimeNode);
|
||||||
TSTALLOC(BJTbasePrimeBasePtr,BJTbasePrimeNode,BJTbaseNode)
|
TSTALLOC(BJTbasePrimeBasePtr,BJTbasePrimeNode,BJTbaseNode);
|
||||||
TSTALLOC(BJTbasePrimeColPrimePtr,BJTbasePrimeNode,BJTcolPrimeNode)
|
TSTALLOC(BJTbasePrimeColPrimePtr,BJTbasePrimeNode,BJTcolPrimeNode);
|
||||||
TSTALLOC(BJTbasePrimeEmitPrimePtr,BJTbasePrimeNode,BJTemitPrimeNode)
|
TSTALLOC(BJTbasePrimeEmitPrimePtr,BJTbasePrimeNode,BJTemitPrimeNode);
|
||||||
TSTALLOC(BJTemitPrimeEmitPtr,BJTemitPrimeNode,BJTemitNode)
|
TSTALLOC(BJTemitPrimeEmitPtr,BJTemitPrimeNode,BJTemitNode);
|
||||||
TSTALLOC(BJTemitPrimeColPrimePtr,BJTemitPrimeNode,BJTcolPrimeNode)
|
TSTALLOC(BJTemitPrimeColPrimePtr,BJTemitPrimeNode,BJTcolPrimeNode);
|
||||||
TSTALLOC(BJTemitPrimeBasePrimePtr,BJTemitPrimeNode,BJTbasePrimeNode)
|
TSTALLOC(BJTemitPrimeBasePrimePtr,BJTemitPrimeNode,BJTbasePrimeNode);
|
||||||
TSTALLOC(BJTcolColPtr,BJTcolNode,BJTcolNode)
|
TSTALLOC(BJTcolColPtr,BJTcolNode,BJTcolNode);
|
||||||
TSTALLOC(BJTbaseBasePtr,BJTbaseNode,BJTbaseNode)
|
TSTALLOC(BJTbaseBasePtr,BJTbaseNode,BJTbaseNode);
|
||||||
TSTALLOC(BJTemitEmitPtr,BJTemitNode,BJTemitNode)
|
TSTALLOC(BJTemitEmitPtr,BJTemitNode,BJTemitNode);
|
||||||
TSTALLOC(BJTcolPrimeColPrimePtr,BJTcolPrimeNode,BJTcolPrimeNode)
|
TSTALLOC(BJTcolPrimeColPrimePtr,BJTcolPrimeNode,BJTcolPrimeNode);
|
||||||
TSTALLOC(BJTbasePrimeBasePrimePtr,BJTbasePrimeNode,BJTbasePrimeNode)
|
TSTALLOC(BJTbasePrimeBasePrimePtr,BJTbasePrimeNode,BJTbasePrimeNode);
|
||||||
TSTALLOC(BJTemitPrimeEmitPrimePtr,BJTemitPrimeNode,BJTemitPrimeNode)
|
TSTALLOC(BJTemitPrimeEmitPrimePtr,BJTemitPrimeNode,BJTemitPrimeNode);
|
||||||
TSTALLOC(BJTsubstSubstPtr,BJTsubstNode,BJTsubstNode)
|
TSTALLOC(BJTsubstSubstPtr,BJTsubstNode,BJTsubstNode);
|
||||||
if (model -> BJTsubs == LATERAL) {
|
if (model -> BJTsubs == LATERAL) {
|
||||||
here -> BJTsubstConNode = here -> BJTbasePrimeNode;
|
here -> BJTsubstConNode = here -> BJTbasePrimeNode;
|
||||||
here -> BJTsubstConSubstConPtr = here -> BJTbasePrimeBasePrimePtr;
|
here -> BJTsubstConSubstConPtr = here -> BJTbasePrimeBasePrimePtr;
|
||||||
|
|
@ -449,10 +449,10 @@ if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\
|
||||||
here -> BJTsubstConNode = here -> BJTcolPrimeNode;
|
here -> BJTsubstConNode = here -> BJTcolPrimeNode;
|
||||||
here -> BJTsubstConSubstConPtr = here -> BJTcolPrimeColPrimePtr;
|
here -> BJTsubstConSubstConPtr = here -> BJTcolPrimeColPrimePtr;
|
||||||
}
|
}
|
||||||
TSTALLOC(BJTsubstConSubstPtr,BJTsubstConNode,BJTsubstNode)
|
TSTALLOC(BJTsubstConSubstPtr,BJTsubstConNode,BJTsubstNode);
|
||||||
TSTALLOC(BJTsubstSubstConPtr,BJTsubstNode,BJTsubstConNode)
|
TSTALLOC(BJTsubstSubstConPtr,BJTsubstNode,BJTsubstConNode);
|
||||||
TSTALLOC(BJTbaseColPrimePtr,BJTbaseNode,BJTcolPrimeNode)
|
TSTALLOC(BJTbaseColPrimePtr,BJTbaseNode,BJTcolPrimeNode);
|
||||||
TSTALLOC(BJTcolPrimeBasePtr,BJTcolPrimeNode,BJTbaseNode)
|
TSTALLOC(BJTcolPrimeBasePtr,BJTcolPrimeNode,BJTbaseNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return(OK);
|
return(OK);
|
||||||
|
|
|
||||||
|
|
@ -55,9 +55,8 @@ BJTsUpdate(GENmodel *inModel, CKTcircuit *ckt)
|
||||||
sxpbx = 0;
|
sxpbx = 0;
|
||||||
#ifdef SENSDEBUG
|
#ifdef SENSDEBUG
|
||||||
printf("senupdate Instance name: %s\n",here->BJTname);
|
printf("senupdate Instance name: %s\n",here->BJTname);
|
||||||
printf("iparmno = %d,CKTag[0] = %.2e,CKTag[1] = %.2e\n",
|
printf("CKTag[0] = %.2e,CKTag[1] = %.2e\n",
|
||||||
iparmno,ckt->CKTag[0],ckt->CKTag[1]);
|
ckt->CKTag[0],ckt->CKTag[1]);
|
||||||
|
|
||||||
printf("capbe = %.7e\n",here->BJTcapbe);
|
printf("capbe = %.7e\n",here->BJTcapbe);
|
||||||
printf("capbc = %.7e\n",here->BJTcapbc);
|
printf("capbc = %.7e\n",here->BJTcapbc);
|
||||||
printf("capsub = %.7e\n",here->BJTcapsub);
|
printf("capsub = %.7e\n",here->BJTcapsub);
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,10 @@ if UMFPACK_WANTED
|
||||||
libbsim1_la_SOURCES += b1bindCSC.c
|
libbsim1_la_SOURCES += b1bindCSC.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if KIRCHHOFF_WANTED
|
||||||
|
libbsim1_la_SOURCES += b1node.c
|
||||||
|
endif
|
||||||
|
|
||||||
AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(top_srcdir)/src/include
|
AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(top_srcdir)/src/include
|
||||||
AM_CFLAGS = $(STATIC)
|
AM_CFLAGS = $(STATIC)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
/**********
|
||||||
|
Author: 2013 Francesco Lannutti
|
||||||
|
**********/
|
||||||
|
|
||||||
|
#include "ngspice/ngspice.h"
|
||||||
|
#include "ngspice/cktdefs.h"
|
||||||
|
#include "bsim1def.h"
|
||||||
|
#include "ngspice/sperror.h"
|
||||||
|
|
||||||
|
int
|
||||||
|
B1nodeIsNonLinear (GENmodel *inModel, CKTcircuit *ckt)
|
||||||
|
{
|
||||||
|
B1model *model = (B1model *)inModel ;
|
||||||
|
B1instance *here ;
|
||||||
|
|
||||||
|
/* loop through all the BSIM1 models */
|
||||||
|
for ( ; model != NULL ; model = model->B1nextModel)
|
||||||
|
{
|
||||||
|
/* loop through all the instances of the model */
|
||||||
|
for (here = model->B1instances ; here != NULL ; here = here->B1nextInstance)
|
||||||
|
{
|
||||||
|
ckt->CKTnodeIsLinear [here->B1dNodePrime] = 0 ;
|
||||||
|
ckt->CKTnodeIsLinear [here->B1sNodePrime] = 0 ;
|
||||||
|
ckt->CKTnodeIsLinear [here->B1gNode] = 0 ;
|
||||||
|
ckt->CKTnodeIsLinear [here->B1bNode] = 0 ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (OK) ;
|
||||||
|
}
|
||||||
|
|
@ -368,32 +368,32 @@ B1setup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt,
|
||||||
|
|
||||||
/* macro to make elements with built in test for out of memory */
|
/* macro to make elements with built in test for out of memory */
|
||||||
#define TSTALLOC(ptr,first,second) \
|
#define TSTALLOC(ptr,first,second) \
|
||||||
if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\
|
do { if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\
|
||||||
return(E_NOMEM);\
|
return(E_NOMEM);\
|
||||||
}
|
} } while(0)
|
||||||
|
|
||||||
TSTALLOC(B1DdPtr, B1dNode, B1dNode)
|
TSTALLOC(B1DdPtr, B1dNode, B1dNode);
|
||||||
TSTALLOC(B1GgPtr, B1gNode, B1gNode)
|
TSTALLOC(B1GgPtr, B1gNode, B1gNode);
|
||||||
TSTALLOC(B1SsPtr, B1sNode, B1sNode)
|
TSTALLOC(B1SsPtr, B1sNode, B1sNode);
|
||||||
TSTALLOC(B1BbPtr, B1bNode, B1bNode)
|
TSTALLOC(B1BbPtr, B1bNode, B1bNode);
|
||||||
TSTALLOC(B1DPdpPtr, B1dNodePrime, B1dNodePrime)
|
TSTALLOC(B1DPdpPtr, B1dNodePrime, B1dNodePrime);
|
||||||
TSTALLOC(B1SPspPtr, B1sNodePrime, B1sNodePrime)
|
TSTALLOC(B1SPspPtr, B1sNodePrime, B1sNodePrime);
|
||||||
TSTALLOC(B1DdpPtr, B1dNode, B1dNodePrime)
|
TSTALLOC(B1DdpPtr, B1dNode, B1dNodePrime);
|
||||||
TSTALLOC(B1GbPtr, B1gNode, B1bNode)
|
TSTALLOC(B1GbPtr, B1gNode, B1bNode);
|
||||||
TSTALLOC(B1GdpPtr, B1gNode, B1dNodePrime)
|
TSTALLOC(B1GdpPtr, B1gNode, B1dNodePrime);
|
||||||
TSTALLOC(B1GspPtr, B1gNode, B1sNodePrime)
|
TSTALLOC(B1GspPtr, B1gNode, B1sNodePrime);
|
||||||
TSTALLOC(B1SspPtr, B1sNode, B1sNodePrime)
|
TSTALLOC(B1SspPtr, B1sNode, B1sNodePrime);
|
||||||
TSTALLOC(B1BdpPtr, B1bNode, B1dNodePrime)
|
TSTALLOC(B1BdpPtr, B1bNode, B1dNodePrime);
|
||||||
TSTALLOC(B1BspPtr, B1bNode, B1sNodePrime)
|
TSTALLOC(B1BspPtr, B1bNode, B1sNodePrime);
|
||||||
TSTALLOC(B1DPspPtr, B1dNodePrime, B1sNodePrime)
|
TSTALLOC(B1DPspPtr, B1dNodePrime, B1sNodePrime);
|
||||||
TSTALLOC(B1DPdPtr, B1dNodePrime, B1dNode)
|
TSTALLOC(B1DPdPtr, B1dNodePrime, B1dNode);
|
||||||
TSTALLOC(B1BgPtr, B1bNode, B1gNode)
|
TSTALLOC(B1BgPtr, B1bNode, B1gNode);
|
||||||
TSTALLOC(B1DPgPtr, B1dNodePrime, B1gNode)
|
TSTALLOC(B1DPgPtr, B1dNodePrime, B1gNode);
|
||||||
TSTALLOC(B1SPgPtr, B1sNodePrime, B1gNode)
|
TSTALLOC(B1SPgPtr, B1sNodePrime, B1gNode);
|
||||||
TSTALLOC(B1SPsPtr, B1sNodePrime, B1sNode)
|
TSTALLOC(B1SPsPtr, B1sNodePrime, B1sNode);
|
||||||
TSTALLOC(B1DPbPtr, B1dNodePrime, B1bNode)
|
TSTALLOC(B1DPbPtr, B1dNodePrime, B1bNode);
|
||||||
TSTALLOC(B1SPbPtr, B1sNodePrime, B1bNode)
|
TSTALLOC(B1SPbPtr, B1sNodePrime, B1bNode);
|
||||||
TSTALLOC(B1SPdpPtr, B1sNodePrime, B1dNodePrime)
|
TSTALLOC(B1SPdpPtr, B1sNodePrime, B1dNodePrime);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,3 +35,7 @@ extern int B1bindCSC (GENmodel*, CKTcircuit*) ;
|
||||||
extern int B1bindCSCComplex (GENmodel*, CKTcircuit*) ;
|
extern int B1bindCSCComplex (GENmodel*, CKTcircuit*) ;
|
||||||
extern int B1bindCSCComplexToReal (GENmodel*, CKTcircuit*) ;
|
extern int B1bindCSCComplexToReal (GENmodel*, CKTcircuit*) ;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef KIRCHHOFF
|
||||||
|
extern int B1nodeIsNonLinear (GENmodel *, CKTcircuit *) ;
|
||||||
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -73,12 +73,17 @@ SPICEdev B1info = {
|
||||||
#endif
|
#endif
|
||||||
/* DEVinstSize */ &B1iSize,
|
/* DEVinstSize */ &B1iSize,
|
||||||
/* DEVmodSize */ &B1mSize,
|
/* DEVmodSize */ &B1mSize,
|
||||||
|
|
||||||
#if defined(KLU) || defined(SuperLU) || defined(UMFPACK)
|
#if defined(KLU) || defined(SuperLU) || defined(UMFPACK)
|
||||||
/* DEVbindCSC */ B1bindCSC,
|
/* DEVbindCSC */ B1bindCSC,
|
||||||
/* DEVbindCSCComplex */ B1bindCSCComplex,
|
/* DEVbindCSCComplex */ B1bindCSCComplex,
|
||||||
/* DEVbindCSCComplexToReal */ B1bindCSCComplexToReal,
|
/* DEVbindCSCComplexToReal */ B1bindCSCComplexToReal,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef KIRCHHOFF
|
||||||
|
/* DEVnodeIsNonLinear */ B1nodeIsNonLinear
|
||||||
|
#endif
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,10 @@ if UMFPACK_WANTED
|
||||||
libbsim2_la_SOURCES += b2bindCSC.c
|
libbsim2_la_SOURCES += b2bindCSC.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if KIRCHHOFF_WANTED
|
||||||
|
libbsim2_la_SOURCES += b2node.c
|
||||||
|
endif
|
||||||
|
|
||||||
AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(top_srcdir)/src/include
|
AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(top_srcdir)/src/include
|
||||||
AM_CFLAGS = $(STATIC)
|
AM_CFLAGS = $(STATIC)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -40,13 +40,13 @@ B2load(GENmodel *inModel, CKTcircuit *ckt)
|
||||||
double cd;
|
double cd;
|
||||||
double cdrain;
|
double cdrain;
|
||||||
double cdhat;
|
double cdhat;
|
||||||
double cdreq;
|
double cdreq, cdreq_fvk ;
|
||||||
double ceq;
|
double ceq;
|
||||||
double ceqbd;
|
double ceqbd, ceqbd_fvk ;
|
||||||
double ceqbs;
|
double ceqbs, ceqbs_fvk ;
|
||||||
double ceqqb;
|
double ceqqb, ceqqb_fvk ;
|
||||||
double ceqqd;
|
double ceqqd, ceqqd_fvk ;
|
||||||
double ceqqg;
|
double ceqqg, ceqqg_fvk ;
|
||||||
double czbd;
|
double czbd;
|
||||||
double czbdsw;
|
double czbdsw;
|
||||||
double czbs;
|
double czbs;
|
||||||
|
|
@ -628,7 +628,7 @@ line755:
|
||||||
|
|
||||||
line850:
|
line850:
|
||||||
/* initialize to zero charge conductance and current */
|
/* initialize to zero charge conductance and current */
|
||||||
ceqqg = ceqqb = ceqqd = 0.0;
|
ceqqg = ceqqg_fvk = ceqqb = ceqqb_fvk = ceqqd = ceqqd_fvk = 0.0;
|
||||||
gcdgb = gcddb = gcdsb = 0.0;
|
gcdgb = gcddb = gcdsb = 0.0;
|
||||||
gcsgb = gcsdb = gcssb = 0.0;
|
gcsgb = gcsdb = gcssb = 0.0;
|
||||||
gcggb = gcgdb = gcgsb = 0.0;
|
gcggb = gcgdb = gcgsb = 0.0;
|
||||||
|
|
@ -641,8 +641,11 @@ line860:
|
||||||
cqbulk = *(ckt->CKTstate0 + here->B2iqb);
|
cqbulk = *(ckt->CKTstate0 + here->B2iqb);
|
||||||
cqdrn = *(ckt->CKTstate0 + here->B2iqd);
|
cqdrn = *(ckt->CKTstate0 + here->B2iqd);
|
||||||
ceqqg = cqgate - gcggb * vgb + gcgdb * vbd + gcgsb * vbs;
|
ceqqg = cqgate - gcggb * vgb + gcgdb * vbd + gcgsb * vbs;
|
||||||
|
ceqqg_fvk = cqgate ;
|
||||||
ceqqb = cqbulk - gcbgb * vgb + gcbdb * vbd + gcbsb * vbs;
|
ceqqb = cqbulk - gcbgb * vgb + gcbdb * vbd + gcbsb * vbs;
|
||||||
|
ceqqb_fvk = cqbulk ;
|
||||||
ceqqd = cqdrn - gcdgb * vgb + gcddb * vbd + gcdsb * vbs;
|
ceqqd = cqdrn - gcdgb * vgb + gcddb * vbd + gcdsb * vbs;
|
||||||
|
ceqqd_fvk = cqdrn ;
|
||||||
|
|
||||||
if(ckt->CKTmode & MODEINITTRAN ) {
|
if(ckt->CKTmode & MODEINITTRAN ) {
|
||||||
*(ckt->CKTstate1 + here->B2iqb) =
|
*(ckt->CKTstate1 + here->B2iqb) =
|
||||||
|
|
@ -661,19 +664,25 @@ line900:
|
||||||
m = here->B2m;
|
m = here->B2m;
|
||||||
|
|
||||||
ceqbs = model->B2type * (cbs-(gbs-ckt->CKTgmin)*vbs);
|
ceqbs = model->B2type * (cbs-(gbs-ckt->CKTgmin)*vbs);
|
||||||
|
ceqbs_fvk = model->B2type * (cbs + ckt->CKTgmin * vbs) ;
|
||||||
ceqbd = model->B2type * (cbd-(gbd-ckt->CKTgmin)*vbd);
|
ceqbd = model->B2type * (cbd-(gbd-ckt->CKTgmin)*vbd);
|
||||||
|
ceqbd_fvk = model->B2type * (cbd + ckt->CKTgmin * vbd) ;
|
||||||
ceqqg = model->B2type * ceqqg;
|
ceqqg = model->B2type * ceqqg;
|
||||||
|
ceqqg_fvk = model->B2type * ceqqg_fvk ;
|
||||||
ceqqb = model->B2type * ceqqb;
|
ceqqb = model->B2type * ceqqb;
|
||||||
|
ceqqb_fvk = model->B2type * ceqqb_fvk ;
|
||||||
ceqqd = model->B2type * ceqqd;
|
ceqqd = model->B2type * ceqqd;
|
||||||
|
ceqqd_fvk = model->B2type * ceqqd_fvk ;
|
||||||
if (here->B2mode >= 0) {
|
if (here->B2mode >= 0) {
|
||||||
xnrm=1;
|
xnrm=1;
|
||||||
xrev=0;
|
xrev=0;
|
||||||
cdreq=model->B2type*(cdrain-gds*vds-gm*vgs-gmbs*vbs);
|
cdreq=model->B2type*(cdrain-gds*vds-gm*vgs-gmbs*vbs);
|
||||||
|
cdreq_fvk = model->B2type * cdrain ;
|
||||||
} else {
|
} else {
|
||||||
xnrm=0;
|
xnrm=0;
|
||||||
xrev=1;
|
xrev=1;
|
||||||
cdreq = -(model->B2type)*(cdrain+gds*vds-gm*vgd-gmbs*vbd);
|
cdreq = -(model->B2type)*(cdrain+gds*vds-gm*vgd-gmbs*vbd);
|
||||||
|
cdreq_fvk = - (model->B2type * cdrain) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
*(ckt->CKTrhs + here->B2gNode) -= m * (ceqqg);
|
*(ckt->CKTrhs + here->B2gNode) -= m * (ceqqg);
|
||||||
|
|
@ -712,6 +721,24 @@ line900:
|
||||||
*(here->B2SPbPtr) += m * (-gbs-(xnrm-xrev)*gmbs-gcsgb-gcsdb-gcssb);
|
*(here->B2SPbPtr) += m * (-gbs-(xnrm-xrev)*gmbs-gcsgb-gcsdb-gcssb);
|
||||||
*(here->B2SPdpPtr) += m * (-gds-xrev*(gm+gmbs)+gcsdb);
|
*(here->B2SPdpPtr) += m * (-gds-xrev*(gm+gmbs)+gcsdb);
|
||||||
|
|
||||||
|
#ifdef KIRCHHOFF
|
||||||
|
/* KCL verification - Dynamic Part */
|
||||||
|
*(ckt->CKTfvk + here->B2gNode) += m * ceqqg_fvk ;
|
||||||
|
*(ckt->CKTfvk + here->B2bNode) += m * (ceqbs_fvk + ceqbd_fvk + ceqqb_fvk) ;
|
||||||
|
*(ckt->CKTfvk + here->B2dNodePrime) -= m * (ceqbd_fvk - cdreq_fvk - ceqqd_fvk) ;
|
||||||
|
*(ckt->CKTfvk + here->B2sNodePrime) -= m * (cdreq_fvk + ceqbs_fvk + ceqqg_fvk + ceqqb_fvk + ceqqd_fvk) ;
|
||||||
|
|
||||||
|
|
||||||
|
/* KCL verification - Linear and Static Part */
|
||||||
|
*(ckt->CKTfvk + here->B2dNode) += m * (here->B2drainConductance) * *(ckt->CKTrhsOld + here->B2dNode) ;
|
||||||
|
*(ckt->CKTfvk + here->B2sNode) += m * (here->B2sourceConductance) * *(ckt->CKTrhsOld + here->B2sNode) ;
|
||||||
|
*(ckt->CKTfvk + here->B2dNodePrime) += m * (here->B2drainConductance) * *(ckt->CKTrhsOld + here->B2dNodePrime) ;
|
||||||
|
*(ckt->CKTfvk + here->B2sNodePrime) += m * (here->B2sourceConductance) * *(ckt->CKTrhsOld + here->B2sNodePrime) ;
|
||||||
|
*(ckt->CKTfvk + here->B2dNode) += m * (-here->B2drainConductance) * *(ckt->CKTrhsOld + here->B2dNodePrime) ;
|
||||||
|
*(ckt->CKTfvk + here->B2sNode) += m * (-here->B2sourceConductance) * *(ckt->CKTrhsOld + here->B2sNodePrime) ;
|
||||||
|
*(ckt->CKTfvk + here->B2dNodePrime) += m * (-here->B2drainConductance) * *(ckt->CKTrhsOld + here->B2dNode) ;
|
||||||
|
*(ckt->CKTfvk + here->B2sNodePrime) += m * (-here->B2sourceConductance) * *(ckt->CKTrhsOld + here->B2sNode) ;
|
||||||
|
#endif
|
||||||
|
|
||||||
line1000: ;
|
line1000: ;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
/**********
|
||||||
|
Author: 2013 Francesco Lannutti
|
||||||
|
**********/
|
||||||
|
|
||||||
|
#include "ngspice/ngspice.h"
|
||||||
|
#include "ngspice/cktdefs.h"
|
||||||
|
#include "bsim2def.h"
|
||||||
|
#include "ngspice/sperror.h"
|
||||||
|
|
||||||
|
int
|
||||||
|
B2nodeIsNonLinear (GENmodel *inModel, CKTcircuit *ckt)
|
||||||
|
{
|
||||||
|
B2model *model = (B2model *)inModel ;
|
||||||
|
B2instance *here ;
|
||||||
|
|
||||||
|
/* loop through all the BSIM2 models */
|
||||||
|
for ( ; model != NULL ; model = model->B2nextModel)
|
||||||
|
{
|
||||||
|
/* loop through all the instances of the model */
|
||||||
|
for (here = model->B2instances ; here != NULL ; here = here->B2nextInstance)
|
||||||
|
{
|
||||||
|
ckt->CKTnodeIsLinear [here->B2dNodePrime] = 0 ;
|
||||||
|
ckt->CKTnodeIsLinear [here->B2sNodePrime] = 0 ;
|
||||||
|
ckt->CKTnodeIsLinear [here->B2gNode] = 0 ;
|
||||||
|
ckt->CKTnodeIsLinear [here->B2bNode] = 0 ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (OK) ;
|
||||||
|
}
|
||||||
|
|
@ -535,32 +535,32 @@ B2setup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states)
|
||||||
|
|
||||||
/* macro to make elements with built in test for out of memory */
|
/* macro to make elements with built in test for out of memory */
|
||||||
#define TSTALLOC(ptr,first,second) \
|
#define TSTALLOC(ptr,first,second) \
|
||||||
if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\
|
do { if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\
|
||||||
return(E_NOMEM);\
|
return(E_NOMEM);\
|
||||||
}
|
} } while(0)
|
||||||
|
|
||||||
TSTALLOC(B2DdPtr, B2dNode, B2dNode)
|
TSTALLOC(B2DdPtr, B2dNode, B2dNode);
|
||||||
TSTALLOC(B2GgPtr, B2gNode, B2gNode)
|
TSTALLOC(B2GgPtr, B2gNode, B2gNode);
|
||||||
TSTALLOC(B2SsPtr, B2sNode, B2sNode)
|
TSTALLOC(B2SsPtr, B2sNode, B2sNode);
|
||||||
TSTALLOC(B2BbPtr, B2bNode, B2bNode)
|
TSTALLOC(B2BbPtr, B2bNode, B2bNode);
|
||||||
TSTALLOC(B2DPdpPtr, B2dNodePrime, B2dNodePrime)
|
TSTALLOC(B2DPdpPtr, B2dNodePrime, B2dNodePrime);
|
||||||
TSTALLOC(B2SPspPtr, B2sNodePrime, B2sNodePrime)
|
TSTALLOC(B2SPspPtr, B2sNodePrime, B2sNodePrime);
|
||||||
TSTALLOC(B2DdpPtr, B2dNode, B2dNodePrime)
|
TSTALLOC(B2DdpPtr, B2dNode, B2dNodePrime);
|
||||||
TSTALLOC(B2GbPtr, B2gNode, B2bNode)
|
TSTALLOC(B2GbPtr, B2gNode, B2bNode);
|
||||||
TSTALLOC(B2GdpPtr, B2gNode, B2dNodePrime)
|
TSTALLOC(B2GdpPtr, B2gNode, B2dNodePrime);
|
||||||
TSTALLOC(B2GspPtr, B2gNode, B2sNodePrime)
|
TSTALLOC(B2GspPtr, B2gNode, B2sNodePrime);
|
||||||
TSTALLOC(B2SspPtr, B2sNode, B2sNodePrime)
|
TSTALLOC(B2SspPtr, B2sNode, B2sNodePrime);
|
||||||
TSTALLOC(B2BdpPtr, B2bNode, B2dNodePrime)
|
TSTALLOC(B2BdpPtr, B2bNode, B2dNodePrime);
|
||||||
TSTALLOC(B2BspPtr, B2bNode, B2sNodePrime)
|
TSTALLOC(B2BspPtr, B2bNode, B2sNodePrime);
|
||||||
TSTALLOC(B2DPspPtr, B2dNodePrime, B2sNodePrime)
|
TSTALLOC(B2DPspPtr, B2dNodePrime, B2sNodePrime);
|
||||||
TSTALLOC(B2DPdPtr, B2dNodePrime, B2dNode)
|
TSTALLOC(B2DPdPtr, B2dNodePrime, B2dNode);
|
||||||
TSTALLOC(B2BgPtr, B2bNode, B2gNode)
|
TSTALLOC(B2BgPtr, B2bNode, B2gNode);
|
||||||
TSTALLOC(B2DPgPtr, B2dNodePrime, B2gNode)
|
TSTALLOC(B2DPgPtr, B2dNodePrime, B2gNode);
|
||||||
TSTALLOC(B2SPgPtr, B2sNodePrime, B2gNode)
|
TSTALLOC(B2SPgPtr, B2sNodePrime, B2gNode);
|
||||||
TSTALLOC(B2SPsPtr, B2sNodePrime, B2sNode)
|
TSTALLOC(B2SPsPtr, B2sNodePrime, B2sNode);
|
||||||
TSTALLOC(B2DPbPtr, B2dNodePrime, B2bNode)
|
TSTALLOC(B2DPbPtr, B2dNodePrime, B2bNode);
|
||||||
TSTALLOC(B2SPbPtr, B2sNodePrime, B2bNode)
|
TSTALLOC(B2SPbPtr, B2sNodePrime, B2bNode);
|
||||||
TSTALLOC(B2SPdpPtr, B2sNodePrime, B2dNodePrime)
|
TSTALLOC(B2SPdpPtr, B2sNodePrime, B2dNodePrime);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,3 +31,7 @@ extern int B2bindCSC (GENmodel*, CKTcircuit*) ;
|
||||||
extern int B2bindCSCComplex (GENmodel*, CKTcircuit*) ;
|
extern int B2bindCSCComplex (GENmodel*, CKTcircuit*) ;
|
||||||
extern int B2bindCSCComplexToReal (GENmodel*, CKTcircuit*) ;
|
extern int B2bindCSCComplexToReal (GENmodel*, CKTcircuit*) ;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef KIRCHHOFF
|
||||||
|
extern int B2nodeIsNonLinear (GENmodel *, CKTcircuit *) ;
|
||||||
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -73,12 +73,17 @@ SPICEdev B2info = {
|
||||||
#endif
|
#endif
|
||||||
/* DEVinstSize */ &B2iSize,
|
/* DEVinstSize */ &B2iSize,
|
||||||
/* DEVmodSize */ &B2mSize,
|
/* DEVmodSize */ &B2mSize,
|
||||||
|
|
||||||
#if defined(KLU) || defined(SuperLU) || defined(UMFPACK)
|
#if defined(KLU) || defined(SuperLU) || defined(UMFPACK)
|
||||||
/* DEVbindCSC */ B2bindCSC,
|
/* DEVbindCSC */ B2bindCSC,
|
||||||
/* DEVbindCSCComplex */ B2bindCSCComplex,
|
/* DEVbindCSCComplex */ B2bindCSCComplex,
|
||||||
/* DEVbindCSCComplexToReal */ B2bindCSCComplexToReal,
|
/* DEVbindCSCComplexToReal */ B2bindCSCComplexToReal,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef KIRCHHOFF
|
||||||
|
/* DEVnodeIsNonLinear */ B2nodeIsNonLinear
|
||||||
|
#endif
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,10 @@ if UMFPACK_WANTED
|
||||||
libbsim3_la_SOURCES += b3bindCSC.c
|
libbsim3_la_SOURCES += b3bindCSC.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if KIRCHHOFF_WANTED
|
||||||
|
libbsim3_la_SOURCES += b3node.c
|
||||||
|
endif
|
||||||
|
|
||||||
AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(top_srcdir)/src/include
|
AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(top_srcdir)/src/include
|
||||||
AM_CFLAGS = $(STATIC)
|
AM_CFLAGS = $(STATIC)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,44 +26,50 @@ IOP( "nrs", BSIM3_NRS, IF_REAL , "Number of squares in source"),
|
||||||
IOP( "off", BSIM3_OFF, IF_FLAG , "Device is initially off"),
|
IOP( "off", BSIM3_OFF, IF_FLAG , "Device is initially off"),
|
||||||
IOP( "nqsmod", BSIM3_NQSMOD, IF_INTEGER, "Non-quasi-static model selector"),
|
IOP( "nqsmod", BSIM3_NQSMOD, IF_INTEGER, "Non-quasi-static model selector"),
|
||||||
IOP( "acnqsmod", BSIM3_ACNQSMOD, IF_INTEGER, "AC NQS model selector"),
|
IOP( "acnqsmod", BSIM3_ACNQSMOD, IF_INTEGER, "AC NQS model selector"),
|
||||||
|
IOP( "geo", BSIM3_GEO, IF_INTEGER, "ACM model drain/source connection"),
|
||||||
|
IOP( "delvto", BSIM3_DELVTO, IF_REAL, "Zero bias threshold voltage variation"),
|
||||||
|
IOP( "mulu0", BSIM3_MULU0, IF_REAL, "Low field mobility multiplier"),
|
||||||
IP( "ic", BSIM3_IC, IF_REALVEC , "Vector of DS,GS,BS initial voltages"),
|
IP( "ic", BSIM3_IC, IF_REALVEC , "Vector of DS,GS,BS initial voltages"),
|
||||||
OP( "gmbs", BSIM3_GMBS, IF_REAL, "Gmb"),
|
OP( "gmbs", BSIM3_GMBS, IF_REAL, "Gmb"),
|
||||||
OP( "gm", BSIM3_GM, IF_REAL, "Gm"),
|
OP( "gm", BSIM3_GM, IF_REAL, "Gm"),
|
||||||
OP( "gds", BSIM3_GDS, IF_REAL, "Gds"),
|
OP( "gds", BSIM3_GDS, IF_REAL, "Gds"),
|
||||||
OP( "vdsat", BSIM3_VDSAT, IF_REAL, "Vdsat"),
|
OP( "vdsat", BSIM3_VDSAT, IF_REAL, "Vdsat"),
|
||||||
OP( "vth", BSIM3_VON, IF_REAL, "Vth"),
|
OP( "vth", BSIM3_VON, IF_REAL, "Vth"),
|
||||||
OP( "id", BSIM3_CD, IF_REAL, "Ids"),
|
OP( "id", BSIM3_CD, IF_REAL, "Ids"),
|
||||||
OP( "vbs", BSIM3_VBS, IF_REAL, "Vbs"),
|
OP( "vbs", BSIM3_VBS, IF_REAL, "Vbs"),
|
||||||
OP( "vgs", BSIM3_VGS, IF_REAL, "Vgs"),
|
OP( "vgs", BSIM3_VGS, IF_REAL, "Vgs"),
|
||||||
OP( "vds", BSIM3_VDS, IF_REAL, "Vds"),
|
OP( "vds", BSIM3_VDS, IF_REAL, "Vds"),
|
||||||
OP( "ibd", BSIM3_CBD, IF_REAL, "Ibd"), /* newly added from here */
|
OP( "ibd", BSIM3_CBD, IF_REAL, "Ibd"), /* newly added from here */
|
||||||
OP( "ibs", BSIM3_CBS, IF_REAL, "Ibs"),
|
OP( "ibs", BSIM3_CBS, IF_REAL, "Ibs"),
|
||||||
OP( "gbd", BSIM3_GBD, IF_REAL, "gbd"),
|
OP( "gbd", BSIM3_GBD, IF_REAL, "gbd"),
|
||||||
OP( "gbs", BSIM3_GBS, IF_REAL, "gbs"),
|
OP( "gbs", BSIM3_GBS, IF_REAL, "gbs"),
|
||||||
OP( "qb", BSIM3_QB, IF_REAL, "Qbulk"),
|
OP( "qb", BSIM3_QB, IF_REAL, "Qbulk"),
|
||||||
OP( "cqb", BSIM3_CQB, IF_REAL, "CQbulk"),
|
OP( "cqb", BSIM3_CQB, IF_REAL, "CQbulk"),
|
||||||
OP( "qg", BSIM3_QG, IF_REAL, "Qgate"),
|
OP( "qg", BSIM3_QG, IF_REAL, "Qgate"),
|
||||||
OP( "cqg", BSIM3_CQG, IF_REAL, "CQgate"),
|
OP( "cqg", BSIM3_CQG, IF_REAL, "CQgate"),
|
||||||
OP( "qd", BSIM3_QD, IF_REAL, "Qdrain"),
|
OP( "qd", BSIM3_QD, IF_REAL, "Qdrain"),
|
||||||
OP( "cqd", BSIM3_CQD, IF_REAL, "CQdrain"),
|
OP( "cqd", BSIM3_CQD, IF_REAL, "CQdrain"),
|
||||||
OP( "cgg", BSIM3_CGG, IF_REAL, "Cggb"),
|
OP( "cgg", BSIM3_CGG, IF_REAL, "Cggb"),
|
||||||
OP( "cgd", BSIM3_CGD, IF_REAL, "Cgdb"),
|
OP( "cgd", BSIM3_CGD, IF_REAL, "Cgdb"),
|
||||||
OP( "cgs", BSIM3_CGS, IF_REAL, "Cgsb"),
|
OP( "cgs", BSIM3_CGS, IF_REAL, "Cgsb"),
|
||||||
OP( "cdg", BSIM3_CDG, IF_REAL, "Cdgb"),
|
OP( "cdg", BSIM3_CDG, IF_REAL, "Cdgb"),
|
||||||
OP( "cdd", BSIM3_CDD, IF_REAL, "Cddb"),
|
OP( "cdd", BSIM3_CDD, IF_REAL, "Cddb"),
|
||||||
OP( "cds", BSIM3_CDS, IF_REAL, "Cdsb"),
|
OP( "cds", BSIM3_CDS, IF_REAL, "Cdsb"),
|
||||||
OP( "cbg", BSIM3_CBG, IF_REAL, "Cbgb"),
|
OP( "cbg", BSIM3_CBG, IF_REAL, "Cbgb"),
|
||||||
OP( "cbd", BSIM3_CBDB, IF_REAL, "Cbdb"),
|
OP( "cbd", BSIM3_CBDB, IF_REAL, "Cbdb"),
|
||||||
OP( "cbs", BSIM3_CBSB, IF_REAL, "Cbsb"),
|
OP( "cbs", BSIM3_CBSB, IF_REAL, "Cbsb"),
|
||||||
OP( "capbd", BSIM3_CAPBD, IF_REAL, "Capbd"),
|
OP( "capbd", BSIM3_CAPBD, IF_REAL, "Capbd"),
|
||||||
OP( "capbs", BSIM3_CAPBS, IF_REAL, "Capbs"),
|
OP( "capbs", BSIM3_CAPBS, IF_REAL, "Capbs"),
|
||||||
};
|
};
|
||||||
|
|
||||||
IFparm BSIM3mPTable[] = { /* model parameters */
|
IFparm BSIM3mPTable[] = { /* model parameters */
|
||||||
IOP( "capmod", BSIM3_MOD_CAPMOD, IF_INTEGER, "Capacitance model selector"),
|
IOP( "capmod", BSIM3_MOD_CAPMOD, IF_INTEGER, "Capacitance model selector"),
|
||||||
IOP( "mobmod", BSIM3_MOD_MOBMOD, IF_INTEGER, "Mobility model selector"),
|
IOP( "mobmod", BSIM3_MOD_MOBMOD, IF_INTEGER, "Mobility model selector"),
|
||||||
IOP( "noimod", BSIM3_MOD_NOIMOD, IF_INTEGER, "Noise model selector"),
|
IOP( "noimod", BSIM3_MOD_NOIMOD, IF_INTEGER, "Noise model selector"),
|
||||||
|
IOP( "nqsmod", BSIM3_MOD_NQSMOD, IF_INTEGER, "Non-quasi-static model selector"),
|
||||||
IOP( "acnqsmod", BSIM3_MOD_ACNQSMOD, IF_INTEGER, "AC NQS model selector"),
|
IOP( "acnqsmod", BSIM3_MOD_ACNQSMOD, IF_INTEGER, "AC NQS model selector"),
|
||||||
|
IOP( "acm", BSIM3_MOD_ACMMOD, IF_INTEGER, "Area calculation method selector"),
|
||||||
|
IOP( "calcacm", BSIM3_MOD_CALCACM, IF_INTEGER, "Area calculation method ACM=12"),
|
||||||
IOP( "paramchk", BSIM3_MOD_PARAMCHK, IF_INTEGER, "Model parameter checking selector"),
|
IOP( "paramchk", BSIM3_MOD_PARAMCHK, IF_INTEGER, "Model parameter checking selector"),
|
||||||
IOP( "binunit", BSIM3_MOD_BINUNIT, IF_INTEGER, "Bin unit selector"),
|
IOP( "binunit", BSIM3_MOD_BINUNIT, IF_INTEGER, "Bin unit selector"),
|
||||||
IOP( "version", BSIM3_MOD_VERSION, IF_STRING, " parameter for model version"),
|
IOP( "version", BSIM3_MOD_VERSION, IF_STRING, " parameter for model version"),
|
||||||
|
|
@ -180,6 +186,10 @@ IOP( "lwl", BSIM3_MOD_LWL, IF_REAL, "Length reduction parameter"),
|
||||||
IOP( "lwlc", BSIM3_MOD_LWLC, IF_REAL, "Length reduction parameter for CV"),
|
IOP( "lwlc", BSIM3_MOD_LWLC, IF_REAL, "Length reduction parameter for CV"),
|
||||||
IOP( "lmin", BSIM3_MOD_LMIN, IF_REAL, "Minimum length for the model"),
|
IOP( "lmin", BSIM3_MOD_LMIN, IF_REAL, "Minimum length for the model"),
|
||||||
IOP( "lmax", BSIM3_MOD_LMAX, IF_REAL, "Maximum length for the model"),
|
IOP( "lmax", BSIM3_MOD_LMAX, IF_REAL, "Maximum length for the model"),
|
||||||
|
|
||||||
|
IOP( "xl", BSIM3_MOD_XL, IF_REAL, "Length correction parameter"),
|
||||||
|
IOP( "xw", BSIM3_MOD_XW, IF_REAL, "Width correction parameter"),
|
||||||
|
|
||||||
IOP( "wr", BSIM3_MOD_WR, IF_REAL, "Width dependence of rds"),
|
IOP( "wr", BSIM3_MOD_WR, IF_REAL, "Width dependence of rds"),
|
||||||
IOP( "wint", BSIM3_MOD_WINT, IF_REAL, "Width reduction parameter"),
|
IOP( "wint", BSIM3_MOD_WINT, IF_REAL, "Width reduction parameter"),
|
||||||
IOP( "dwg", BSIM3_MOD_DWG, IF_REAL, "Width reduction parameter"),
|
IOP( "dwg", BSIM3_MOD_DWG, IF_REAL, "Width reduction parameter"),
|
||||||
|
|
@ -208,6 +218,15 @@ IOP( "cle", BSIM3_MOD_CLE, IF_REAL, "Vdsat parameter for C-V model"),
|
||||||
IOP( "dwc", BSIM3_MOD_DWC, IF_REAL, "Delta W for C-V model"),
|
IOP( "dwc", BSIM3_MOD_DWC, IF_REAL, "Delta W for C-V model"),
|
||||||
IOP( "dlc", BSIM3_MOD_DLC, IF_REAL, "Delta L for C-V model"),
|
IOP( "dlc", BSIM3_MOD_DLC, IF_REAL, "Delta L for C-V model"),
|
||||||
|
|
||||||
|
IOP( "hdif", BSIM3_MOD_HDIF, IF_REAL, "ACM Parameter: Distance Gate - contact"),
|
||||||
|
IOP( "ldif", BSIM3_MOD_LDIF, IF_REAL, "ACM Parameter: Length of LDD Gate-Source/Drain"),
|
||||||
|
IOP( "ld", BSIM3_MOD_LD, IF_REAL, "ACM Parameter: Length of LDD under Gate"),
|
||||||
|
IOP( "rd", BSIM3_MOD_RD, IF_REAL, "ACM Parameter: Resistance of LDD drain side"),
|
||||||
|
IOP( "rs", BSIM3_MOD_RS, IF_REAL, "ACM Parameter: Resistance of LDD source side"),
|
||||||
|
IOP( "rdc", BSIM3_MOD_RDC, IF_REAL, "ACM Parameter: Resistance contact drain side"),
|
||||||
|
IOP( "rsc", BSIM3_MOD_RSC, IF_REAL, "ACM Parameter: Resistance contact source side"),
|
||||||
|
IOP( "wmlt", BSIM3_MOD_WMLT, IF_REAL, "ACM Parameter: Width shrink factor"),
|
||||||
|
|
||||||
IOP( "alpha0", BSIM3_MOD_ALPHA0, IF_REAL, "substrate current model parameter"),
|
IOP( "alpha0", BSIM3_MOD_ALPHA0, IF_REAL, "substrate current model parameter"),
|
||||||
IOP( "alpha1", BSIM3_MOD_ALPHA1, IF_REAL, "substrate current model parameter"),
|
IOP( "alpha1", BSIM3_MOD_ALPHA1, IF_REAL, "substrate current model parameter"),
|
||||||
IOP( "beta0", BSIM3_MOD_BETA0, IF_REAL, "substrate current model parameter"),
|
IOP( "beta0", BSIM3_MOD_BETA0, IF_REAL, "substrate current model parameter"),
|
||||||
|
|
@ -493,11 +512,11 @@ char *BSIM3names[] = {
|
||||||
"Charge"
|
"Charge"
|
||||||
};
|
};
|
||||||
|
|
||||||
int BSIM3nSize = NUMELEMS(BSIM3names);
|
int BSIM3nSize = NUMELEMS(BSIM3names);
|
||||||
int BSIM3pTSize = NUMELEMS(BSIM3pTable);
|
int BSIM3pTSize = NUMELEMS(BSIM3pTable);
|
||||||
int BSIM3mPTSize = NUMELEMS(BSIM3mPTable);
|
int BSIM3mPTSize = NUMELEMS(BSIM3mPTable);
|
||||||
int BSIM3iSize = sizeof(BSIM3instance);
|
int BSIM3iSize = sizeof(BSIM3instance);
|
||||||
int BSIM3mSize = sizeof(BSIM3model);
|
int BSIM3mSize = sizeof(BSIM3model);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -65,6 +65,15 @@ BSIM3instance *here = (BSIM3instance*)inst;
|
||||||
case BSIM3_ACNQSMOD:
|
case BSIM3_ACNQSMOD:
|
||||||
value->iValue = here->BSIM3acnqsMod;
|
value->iValue = here->BSIM3acnqsMod;
|
||||||
return(OK);
|
return(OK);
|
||||||
|
case BSIM3_GEO:
|
||||||
|
value->iValue = here->BSIM3geo;
|
||||||
|
return(OK);
|
||||||
|
case BSIM3_DELVTO:
|
||||||
|
value->rValue = here->BSIM3delvto;
|
||||||
|
return(OK);
|
||||||
|
case BSIM3_MULU0:
|
||||||
|
value->rValue = here->BSIM3mulu0;
|
||||||
|
return(OK);
|
||||||
case BSIM3_IC_VBS:
|
case BSIM3_IC_VBS:
|
||||||
value->rValue = here->BSIM3icVBS;
|
value->rValue = here->BSIM3icVBS;
|
||||||
return(OK);
|
return(OK);
|
||||||
|
|
@ -94,11 +103,11 @@ BSIM3instance *here = (BSIM3instance*)inst;
|
||||||
return(OK);
|
return(OK);
|
||||||
case BSIM3_SOURCECONDUCT:
|
case BSIM3_SOURCECONDUCT:
|
||||||
value->rValue = here->BSIM3sourceConductance;
|
value->rValue = here->BSIM3sourceConductance;
|
||||||
value->rValue *= here->BSIM3m;
|
value->rValue *= here->BSIM3m;
|
||||||
return(OK);
|
return(OK);
|
||||||
case BSIM3_DRAINCONDUCT:
|
case BSIM3_DRAINCONDUCT:
|
||||||
value->rValue = here->BSIM3drainConductance;
|
value->rValue = here->BSIM3drainConductance;
|
||||||
value->rValue *= here->BSIM3m;
|
value->rValue *= here->BSIM3m;
|
||||||
return(OK);
|
return(OK);
|
||||||
case BSIM3_VBD:
|
case BSIM3_VBD:
|
||||||
value->rValue = *(ckt->CKTstate0 + here->BSIM3vbd);
|
value->rValue = *(ckt->CKTstate0 + here->BSIM3vbd);
|
||||||
|
|
@ -114,103 +123,103 @@ BSIM3instance *here = (BSIM3instance*)inst;
|
||||||
return(OK);
|
return(OK);
|
||||||
case BSIM3_CD:
|
case BSIM3_CD:
|
||||||
value->rValue = here->BSIM3cd;
|
value->rValue = here->BSIM3cd;
|
||||||
value->rValue *= here->BSIM3m;
|
value->rValue *= here->BSIM3m;
|
||||||
return(OK);
|
return(OK);
|
||||||
case BSIM3_CBS:
|
case BSIM3_CBS:
|
||||||
value->rValue = here->BSIM3cbs;
|
value->rValue = here->BSIM3cbs;
|
||||||
value->rValue *= here->BSIM3m;
|
value->rValue *= here->BSIM3m;
|
||||||
return(OK);
|
return(OK);
|
||||||
case BSIM3_CBD:
|
case BSIM3_CBD:
|
||||||
value->rValue = here->BSIM3cbd;
|
value->rValue = here->BSIM3cbd;
|
||||||
value->rValue *= here->BSIM3m;
|
value->rValue *= here->BSIM3m;
|
||||||
return(OK);
|
return(OK);
|
||||||
case BSIM3_GM:
|
case BSIM3_GM:
|
||||||
value->rValue = here->BSIM3gm;
|
value->rValue = here->BSIM3gm;
|
||||||
value->rValue *= here->BSIM3m;
|
value->rValue *= here->BSIM3m;
|
||||||
return(OK);
|
return(OK);
|
||||||
case BSIM3_GDS:
|
case BSIM3_GDS:
|
||||||
value->rValue = here->BSIM3gds;
|
value->rValue = here->BSIM3gds;
|
||||||
value->rValue *= here->BSIM3m;
|
value->rValue *= here->BSIM3m;
|
||||||
return(OK);
|
return(OK);
|
||||||
case BSIM3_GMBS:
|
case BSIM3_GMBS:
|
||||||
value->rValue = here->BSIM3gmbs;
|
value->rValue = here->BSIM3gmbs;
|
||||||
value->rValue *= here->BSIM3m;
|
value->rValue *= here->BSIM3m;
|
||||||
return(OK);
|
return(OK);
|
||||||
case BSIM3_GBD:
|
case BSIM3_GBD:
|
||||||
value->rValue = here->BSIM3gbd;
|
value->rValue = here->BSIM3gbd;
|
||||||
value->rValue *= here->BSIM3m;
|
value->rValue *= here->BSIM3m;
|
||||||
return(OK);
|
return(OK);
|
||||||
case BSIM3_GBS:
|
case BSIM3_GBS:
|
||||||
value->rValue = here->BSIM3gbs;
|
value->rValue = here->BSIM3gbs;
|
||||||
value->rValue *= here->BSIM3m;
|
value->rValue *= here->BSIM3m;
|
||||||
return(OK);
|
return(OK);
|
||||||
case BSIM3_QB:
|
case BSIM3_QB:
|
||||||
value->rValue = *(ckt->CKTstate0 + here->BSIM3qb);
|
value->rValue = *(ckt->CKTstate0 + here->BSIM3qb);
|
||||||
value->rValue *= here->BSIM3m;
|
value->rValue *= here->BSIM3m;
|
||||||
return(OK);
|
return(OK);
|
||||||
case BSIM3_CQB:
|
case BSIM3_CQB:
|
||||||
value->rValue = *(ckt->CKTstate0 + here->BSIM3cqb);
|
value->rValue = *(ckt->CKTstate0 + here->BSIM3cqb);
|
||||||
value->rValue *= here->BSIM3m;
|
value->rValue *= here->BSIM3m;
|
||||||
return(OK);
|
return(OK);
|
||||||
case BSIM3_QG:
|
case BSIM3_QG:
|
||||||
value->rValue = *(ckt->CKTstate0 + here->BSIM3qg);
|
value->rValue = *(ckt->CKTstate0 + here->BSIM3qg);
|
||||||
value->rValue *= here->BSIM3m;
|
value->rValue *= here->BSIM3m;
|
||||||
return(OK);
|
return(OK);
|
||||||
case BSIM3_CQG:
|
case BSIM3_CQG:
|
||||||
value->rValue = *(ckt->CKTstate0 + here->BSIM3cqg);
|
value->rValue = *(ckt->CKTstate0 + here->BSIM3cqg);
|
||||||
value->rValue *= here->BSIM3m;
|
value->rValue *= here->BSIM3m;
|
||||||
return(OK);
|
return(OK);
|
||||||
case BSIM3_QD:
|
case BSIM3_QD:
|
||||||
value->rValue = *(ckt->CKTstate0 + here->BSIM3qd);
|
value->rValue = *(ckt->CKTstate0 + here->BSIM3qd);
|
||||||
value->rValue *= here->BSIM3m;
|
value->rValue *= here->BSIM3m;
|
||||||
return(OK);
|
return(OK);
|
||||||
case BSIM3_CQD:
|
case BSIM3_CQD:
|
||||||
value->rValue = *(ckt->CKTstate0 + here->BSIM3cqd);
|
value->rValue = *(ckt->CKTstate0 + here->BSIM3cqd);
|
||||||
value->rValue *= here->BSIM3m;
|
value->rValue *= here->BSIM3m;
|
||||||
return(OK);
|
return(OK);
|
||||||
case BSIM3_CGG:
|
case BSIM3_CGG:
|
||||||
value->rValue = here->BSIM3cggb;
|
value->rValue = here->BSIM3cggb;
|
||||||
value->rValue *= here->BSIM3m;
|
value->rValue *= here->BSIM3m;
|
||||||
return(OK);
|
return(OK);
|
||||||
case BSIM3_CGD:
|
case BSIM3_CGD:
|
||||||
value->rValue = here->BSIM3cgdb;
|
value->rValue = here->BSIM3cgdb;
|
||||||
value->rValue *= here->BSIM3m;
|
value->rValue *= here->BSIM3m;
|
||||||
return(OK);
|
return(OK);
|
||||||
case BSIM3_CGS:
|
case BSIM3_CGS:
|
||||||
value->rValue = here->BSIM3cgsb;
|
value->rValue = here->BSIM3cgsb;
|
||||||
value->rValue *= here->BSIM3m;
|
value->rValue *= here->BSIM3m;
|
||||||
return(OK);
|
return(OK);
|
||||||
case BSIM3_CDG:
|
case BSIM3_CDG:
|
||||||
value->rValue = here->BSIM3cdgb;
|
value->rValue = here->BSIM3cdgb;
|
||||||
value->rValue *= here->BSIM3m;
|
value->rValue *= here->BSIM3m;
|
||||||
return(OK);
|
return(OK);
|
||||||
case BSIM3_CDD:
|
case BSIM3_CDD:
|
||||||
value->rValue = here->BSIM3cddb;
|
value->rValue = here->BSIM3cddb;
|
||||||
value->rValue *= here->BSIM3m;
|
value->rValue *= here->BSIM3m;
|
||||||
return(OK);
|
return(OK);
|
||||||
case BSIM3_CDS:
|
case BSIM3_CDS:
|
||||||
value->rValue = here->BSIM3cdsb;
|
value->rValue = here->BSIM3cdsb;
|
||||||
value->rValue *= here->BSIM3m;
|
value->rValue *= here->BSIM3m;
|
||||||
return(OK);
|
return(OK);
|
||||||
case BSIM3_CBG:
|
case BSIM3_CBG:
|
||||||
value->rValue = here->BSIM3cbgb;
|
value->rValue = here->BSIM3cbgb;
|
||||||
value->rValue *= here->BSIM3m;
|
value->rValue *= here->BSIM3m;
|
||||||
return(OK);
|
return(OK);
|
||||||
case BSIM3_CBDB:
|
case BSIM3_CBDB:
|
||||||
value->rValue = here->BSIM3cbdb;
|
value->rValue = here->BSIM3cbdb;
|
||||||
value->rValue *= here->BSIM3m;
|
value->rValue *= here->BSIM3m;
|
||||||
return(OK);
|
return(OK);
|
||||||
case BSIM3_CBSB:
|
case BSIM3_CBSB:
|
||||||
value->rValue = here->BSIM3cbsb;
|
value->rValue = here->BSIM3cbsb;
|
||||||
value->rValue *= here->BSIM3m;
|
value->rValue *= here->BSIM3m;
|
||||||
return(OK);
|
return(OK);
|
||||||
case BSIM3_CAPBD:
|
case BSIM3_CAPBD:
|
||||||
value->rValue = here->BSIM3capbd;
|
value->rValue = here->BSIM3capbd;
|
||||||
value->rValue *= here->BSIM3m;
|
value->rValue *= here->BSIM3m;
|
||||||
return(OK);
|
return(OK);
|
||||||
case BSIM3_CAPBS:
|
case BSIM3_CAPBS:
|
||||||
value->rValue = here->BSIM3capbs;
|
value->rValue = here->BSIM3capbs;
|
||||||
value->rValue *= here->BSIM3m;
|
value->rValue *= here->BSIM3m;
|
||||||
return(OK);
|
return(OK);
|
||||||
case BSIM3_VON:
|
case BSIM3_VON:
|
||||||
value->rValue = here->BSIM3von;
|
value->rValue = here->BSIM3von;
|
||||||
|
|
@ -220,11 +229,11 @@ BSIM3instance *here = (BSIM3instance*)inst;
|
||||||
return(OK);
|
return(OK);
|
||||||
case BSIM3_QBS:
|
case BSIM3_QBS:
|
||||||
value->rValue = *(ckt->CKTstate0 + here->BSIM3qbs);
|
value->rValue = *(ckt->CKTstate0 + here->BSIM3qbs);
|
||||||
value->rValue *= here->BSIM3m;
|
value->rValue *= here->BSIM3m;
|
||||||
return(OK);
|
return(OK);
|
||||||
case BSIM3_QBD:
|
case BSIM3_QBD:
|
||||||
value->rValue = *(ckt->CKTstate0 + here->BSIM3qbd);
|
value->rValue = *(ckt->CKTstate0 + here->BSIM3qbd);
|
||||||
value->rValue *= here->BSIM3m;
|
value->rValue *= here->BSIM3m;
|
||||||
return(OK);
|
return(OK);
|
||||||
default:
|
default:
|
||||||
return(E_BADPARM);
|
return(E_BADPARM);
|
||||||
|
|
|
||||||
|
|
@ -31,29 +31,29 @@ FILE *fplog;
|
||||||
|
|
||||||
NG_IGNORE(ckt);
|
NG_IGNORE(ckt);
|
||||||
|
|
||||||
if ((fplog = fopen("b3v3check.log", "w")) != NULL)
|
if ((fplog = fopen("b3v33check.log", "w")) != NULL)
|
||||||
{ pParam = here->pParam;
|
{ pParam = here->pParam;
|
||||||
fprintf(fplog, "BSIM3v3.3.0 Parameter Checking.\n");
|
fprintf(fplog, "BSIM3v3.3.0 Parameter Checking.\n");
|
||||||
if ((strcmp(model->BSIM3version, "3.3.0")) && (strcmp(model->BSIM3version, "3.30")) && (strcmp(model->BSIM3version, "3.3")))
|
if ((strncmp(model->BSIM3version, "3.3.0", 5)) && (strncmp(model->BSIM3version, "3.30", 4)) && (strncmp(model->BSIM3version, "3.3", 3)))
|
||||||
{ fprintf(fplog, "Warning: This model is BSIM3v3.3.0; you specified a wrong version number.\n");
|
{ fprintf(fplog, "Warning: This model is BSIM3v3.3.0; you specified a wrong version number.\n");
|
||||||
printf("Warning: This model is BSIM3v3.3.0; you specified a wrong version number.\n");
|
printf("Warning: This model is BSIM3v3.3.0; you specified a wrong version number.\n");
|
||||||
}
|
}
|
||||||
fprintf(fplog, "Model = %s\n", model->BSIM3modName);
|
fprintf(fplog, "Model = %s\n", model->BSIM3modName);
|
||||||
|
|
||||||
if (pParam->BSIM3nlx < -pParam->BSIM3leff)
|
if (pParam->BSIM3nlx < -pParam->BSIM3leff)
|
||||||
{ fprintf(fplog, "Fatal: Nlx = %g is less than -Leff.\n",
|
{ fprintf(fplog, "Fatal: Nlx = %g is less than -Leff.\n",
|
||||||
pParam->BSIM3nlx);
|
pParam->BSIM3nlx);
|
||||||
printf("Fatal: Nlx = %g is less than -Leff.\n",
|
printf("Fatal: Nlx = %g is less than -Leff.\n",
|
||||||
pParam->BSIM3nlx);
|
pParam->BSIM3nlx);
|
||||||
Fatal_Flag = 1;
|
Fatal_Flag = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (model->BSIM3tox <= 0.0)
|
if (model->BSIM3tox <= 0.0)
|
||||||
{ fprintf(fplog, "Fatal: Tox = %g is not positive.\n",
|
{ fprintf(fplog, "Fatal: Tox = %g is not positive.\n",
|
||||||
model->BSIM3tox);
|
model->BSIM3tox);
|
||||||
printf("Fatal: Tox = %g is not positive.\n", model->BSIM3tox);
|
printf("Fatal: Tox = %g is not positive.\n", model->BSIM3tox);
|
||||||
Fatal_Flag = 1;
|
Fatal_Flag = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (model->BSIM3toxm <= 0.0)
|
if (model->BSIM3toxm <= 0.0)
|
||||||
{ fprintf(fplog, "Fatal: Toxm = %g is not positive.\n",
|
{ fprintf(fplog, "Fatal: Toxm = %g is not positive.\n",
|
||||||
|
|
@ -70,104 +70,104 @@ FILE *fplog;
|
||||||
Fatal_Flag = 1;
|
Fatal_Flag = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pParam->BSIM3npeak <= 0.0)
|
if (pParam->BSIM3npeak <= 0.0)
|
||||||
{ fprintf(fplog, "Fatal: Nch = %g is not positive.\n",
|
{ fprintf(fplog, "Fatal: Nch = %g is not positive.\n",
|
||||||
pParam->BSIM3npeak);
|
pParam->BSIM3npeak);
|
||||||
printf("Fatal: Nch = %g is not positive.\n",
|
printf("Fatal: Nch = %g is not positive.\n",
|
||||||
pParam->BSIM3npeak);
|
pParam->BSIM3npeak);
|
||||||
Fatal_Flag = 1;
|
Fatal_Flag = 1;
|
||||||
}
|
}
|
||||||
if (pParam->BSIM3nsub <= 0.0)
|
if (pParam->BSIM3nsub <= 0.0)
|
||||||
{ fprintf(fplog, "Fatal: Nsub = %g is not positive.\n",
|
{ fprintf(fplog, "Fatal: Nsub = %g is not positive.\n",
|
||||||
pParam->BSIM3nsub);
|
pParam->BSIM3nsub);
|
||||||
printf("Fatal: Nsub = %g is not positive.\n",
|
printf("Fatal: Nsub = %g is not positive.\n",
|
||||||
pParam->BSIM3nsub);
|
pParam->BSIM3nsub);
|
||||||
Fatal_Flag = 1;
|
Fatal_Flag = 1;
|
||||||
}
|
}
|
||||||
if (pParam->BSIM3ngate < 0.0)
|
if (pParam->BSIM3ngate < 0.0)
|
||||||
{ fprintf(fplog, "Fatal: Ngate = %g is not positive.\n",
|
{ fprintf(fplog, "Fatal: Ngate = %g is not positive.\n",
|
||||||
pParam->BSIM3ngate);
|
pParam->BSIM3ngate);
|
||||||
printf("Fatal: Ngate = %g Ngate is not positive.\n",
|
printf("Fatal: Ngate = %g Ngate is not positive.\n",
|
||||||
pParam->BSIM3ngate);
|
pParam->BSIM3ngate);
|
||||||
Fatal_Flag = 1;
|
Fatal_Flag = 1;
|
||||||
}
|
}
|
||||||
if (pParam->BSIM3ngate > 1.e25)
|
if (pParam->BSIM3ngate > 1.e25)
|
||||||
{ fprintf(fplog, "Fatal: Ngate = %g is too high.\n",
|
{ fprintf(fplog, "Fatal: Ngate = %g is too high.\n",
|
||||||
pParam->BSIM3ngate);
|
pParam->BSIM3ngate);
|
||||||
printf("Fatal: Ngate = %g Ngate is too high\n",
|
printf("Fatal: Ngate = %g Ngate is too high\n",
|
||||||
pParam->BSIM3ngate);
|
pParam->BSIM3ngate);
|
||||||
Fatal_Flag = 1;
|
Fatal_Flag = 1;
|
||||||
}
|
}
|
||||||
if (pParam->BSIM3xj <= 0.0)
|
if (pParam->BSIM3xj <= 0.0)
|
||||||
{ fprintf(fplog, "Fatal: Xj = %g is not positive.\n",
|
{ fprintf(fplog, "Fatal: Xj = %g is not positive.\n",
|
||||||
pParam->BSIM3xj);
|
pParam->BSIM3xj);
|
||||||
printf("Fatal: Xj = %g is not positive.\n", pParam->BSIM3xj);
|
printf("Fatal: Xj = %g is not positive.\n", pParam->BSIM3xj);
|
||||||
Fatal_Flag = 1;
|
Fatal_Flag = 1;
|
||||||
}
|
|
||||||
|
|
||||||
if (pParam->BSIM3dvt1 < 0.0)
|
|
||||||
{ fprintf(fplog, "Fatal: Dvt1 = %g is negative.\n",
|
|
||||||
pParam->BSIM3dvt1);
|
|
||||||
printf("Fatal: Dvt1 = %g is negative.\n", pParam->BSIM3dvt1);
|
|
||||||
Fatal_Flag = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pParam->BSIM3dvt1w < 0.0)
|
|
||||||
{ fprintf(fplog, "Fatal: Dvt1w = %g is negative.\n",
|
|
||||||
pParam->BSIM3dvt1w);
|
|
||||||
printf("Fatal: Dvt1w = %g is negative.\n", pParam->BSIM3dvt1w);
|
|
||||||
Fatal_Flag = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pParam->BSIM3w0 == -pParam->BSIM3weff)
|
|
||||||
{ fprintf(fplog, "Fatal: (W0 + Weff) = 0 causing divided-by-zero.\n");
|
|
||||||
printf("Fatal: (W0 + Weff) = 0 causing divided-by-zero.\n");
|
|
||||||
Fatal_Flag = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pParam->BSIM3dsub < 0.0)
|
if (pParam->BSIM3dvt1 < 0.0)
|
||||||
{ fprintf(fplog, "Fatal: Dsub = %g is negative.\n", pParam->BSIM3dsub);
|
{ fprintf(fplog, "Fatal: Dvt1 = %g is negative.\n",
|
||||||
printf("Fatal: Dsub = %g is negative.\n", pParam->BSIM3dsub);
|
pParam->BSIM3dvt1);
|
||||||
Fatal_Flag = 1;
|
printf("Fatal: Dvt1 = %g is negative.\n", pParam->BSIM3dvt1);
|
||||||
}
|
Fatal_Flag = 1;
|
||||||
if (pParam->BSIM3b1 == -pParam->BSIM3weff)
|
}
|
||||||
{ fprintf(fplog, "Fatal: (B1 + Weff) = 0 causing divided-by-zero.\n");
|
|
||||||
printf("Fatal: (B1 + Weff) = 0 causing divided-by-zero.\n");
|
if (pParam->BSIM3dvt1w < 0.0)
|
||||||
Fatal_Flag = 1;
|
{ fprintf(fplog, "Fatal: Dvt1w = %g is negative.\n",
|
||||||
|
pParam->BSIM3dvt1w);
|
||||||
|
printf("Fatal: Dvt1w = %g is negative.\n", pParam->BSIM3dvt1w);
|
||||||
|
Fatal_Flag = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pParam->BSIM3w0 == -pParam->BSIM3weff)
|
||||||
|
{ fprintf(fplog, "Fatal: (W0 + Weff) = 0 causing divided-by-zero.\n");
|
||||||
|
printf("Fatal: (W0 + Weff) = 0 causing divided-by-zero.\n");
|
||||||
|
Fatal_Flag = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pParam->BSIM3dsub < 0.0)
|
||||||
|
{ fprintf(fplog, "Fatal: Dsub = %g is negative.\n", pParam->BSIM3dsub);
|
||||||
|
printf("Fatal: Dsub = %g is negative.\n", pParam->BSIM3dsub);
|
||||||
|
Fatal_Flag = 1;
|
||||||
|
}
|
||||||
|
if (pParam->BSIM3b1 == -pParam->BSIM3weff)
|
||||||
|
{ fprintf(fplog, "Fatal: (B1 + Weff) = 0 causing divided-by-zero.\n");
|
||||||
|
printf("Fatal: (B1 + Weff) = 0 causing divided-by-zero.\n");
|
||||||
|
Fatal_Flag = 1;
|
||||||
}
|
}
|
||||||
if (pParam->BSIM3u0temp <= 0.0)
|
if (pParam->BSIM3u0temp <= 0.0)
|
||||||
{ fprintf(fplog, "Fatal: u0 at current temperature = %g is not positive.\n", pParam->BSIM3u0temp);
|
{ fprintf(fplog, "Fatal: u0 at current temperature = %g is not positive.\n", pParam->BSIM3u0temp);
|
||||||
printf("Fatal: u0 at current temperature = %g is not positive.\n",
|
printf("Fatal: u0 at current temperature = %g is not positive.\n",
|
||||||
pParam->BSIM3u0temp);
|
pParam->BSIM3u0temp);
|
||||||
Fatal_Flag = 1;
|
Fatal_Flag = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check delta parameter */
|
/* Check delta parameter */
|
||||||
if (pParam->BSIM3delta < 0.0)
|
if (pParam->BSIM3delta < 0.0)
|
||||||
{ fprintf(fplog, "Fatal: Delta = %g is less than zero.\n",
|
{ fprintf(fplog, "Fatal: Delta = %g is less than zero.\n",
|
||||||
pParam->BSIM3delta);
|
pParam->BSIM3delta);
|
||||||
printf("Fatal: Delta = %g is less than zero.\n", pParam->BSIM3delta);
|
printf("Fatal: Delta = %g is less than zero.\n", pParam->BSIM3delta);
|
||||||
Fatal_Flag = 1;
|
Fatal_Flag = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pParam->BSIM3vsattemp <= 0.0)
|
if (pParam->BSIM3vsattemp <= 0.0)
|
||||||
{ fprintf(fplog, "Fatal: Vsat at current temperature = %g is not positive.\n", pParam->BSIM3vsattemp);
|
{ fprintf(fplog, "Fatal: Vsat at current temperature = %g is not positive.\n", pParam->BSIM3vsattemp);
|
||||||
printf("Fatal: Vsat at current temperature = %g is not positive.\n",
|
printf("Fatal: Vsat at current temperature = %g is not positive.\n",
|
||||||
pParam->BSIM3vsattemp);
|
pParam->BSIM3vsattemp);
|
||||||
Fatal_Flag = 1;
|
Fatal_Flag = 1;
|
||||||
}
|
}
|
||||||
/* Check Rout parameters */
|
/* Check Rout parameters */
|
||||||
if (pParam->BSIM3pclm <= 0.0)
|
if (pParam->BSIM3pclm <= 0.0)
|
||||||
{ fprintf(fplog, "Fatal: Pclm = %g is not positive.\n", pParam->BSIM3pclm);
|
{ fprintf(fplog, "Fatal: Pclm = %g is not positive.\n", pParam->BSIM3pclm);
|
||||||
printf("Fatal: Pclm = %g is not positive.\n", pParam->BSIM3pclm);
|
printf("Fatal: Pclm = %g is not positive.\n", pParam->BSIM3pclm);
|
||||||
Fatal_Flag = 1;
|
Fatal_Flag = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pParam->BSIM3drout < 0.0)
|
if (pParam->BSIM3drout < 0.0)
|
||||||
{ fprintf(fplog, "Fatal: Drout = %g is negative.\n", pParam->BSIM3drout);
|
{ fprintf(fplog, "Fatal: Drout = %g is negative.\n", pParam->BSIM3drout);
|
||||||
printf("Fatal: Drout = %g is negative.\n", pParam->BSIM3drout);
|
printf("Fatal: Drout = %g is negative.\n", pParam->BSIM3drout);
|
||||||
Fatal_Flag = 1;
|
Fatal_Flag = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pParam->BSIM3pscbe2 <= 0.0)
|
if (pParam->BSIM3pscbe2 <= 0.0)
|
||||||
{ fprintf(fplog, "Warning: Pscbe2 = %g is not positive.\n",
|
{ fprintf(fplog, "Warning: Pscbe2 = %g is not positive.\n",
|
||||||
|
|
@ -175,22 +175,31 @@ FILE *fplog;
|
||||||
printf("Warning: Pscbe2 = %g is not positive.\n", pParam->BSIM3pscbe2);
|
printf("Warning: Pscbe2 = %g is not positive.\n", pParam->BSIM3pscbe2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (model->BSIM3unitLengthSidewallJctCap > 0.0 ||
|
/* ACM model */
|
||||||
model->BSIM3unitLengthGateSidewallJctCap > 0.0)
|
if (model->BSIM3acmMod == 0) {
|
||||||
{
|
if (model->BSIM3unitLengthSidewallJctCap > 0.0 ||
|
||||||
if (here->BSIM3drainPerimeter < pParam->BSIM3weff)
|
model->BSIM3unitLengthGateSidewallJctCap > 0.0)
|
||||||
{ fprintf(fplog, "Warning: Pd = %g is less than W.\n",
|
{
|
||||||
here->BSIM3drainPerimeter);
|
if (here->BSIM3drainPerimeter < pParam->BSIM3weff)
|
||||||
printf("Warning: Pd = %g is less than W.\n",
|
{ fprintf(fplog, "Warning: Pd = %g is less than W.\n",
|
||||||
here->BSIM3drainPerimeter);
|
here->BSIM3drainPerimeter);
|
||||||
}
|
printf("Warning: Pd = %g is less than W.\n",
|
||||||
if (here->BSIM3sourcePerimeter < pParam->BSIM3weff)
|
here->BSIM3drainPerimeter);
|
||||||
{ fprintf(fplog, "Warning: Ps = %g is less than W.\n",
|
}
|
||||||
here->BSIM3sourcePerimeter);
|
if (here->BSIM3sourcePerimeter < pParam->BSIM3weff)
|
||||||
printf("Warning: Ps = %g is less than W.\n",
|
{ fprintf(fplog, "Warning: Ps = %g is less than W.\n",
|
||||||
here->BSIM3sourcePerimeter);
|
here->BSIM3sourcePerimeter);
|
||||||
}
|
printf("Warning: Ps = %g is less than W.\n",
|
||||||
}
|
here->BSIM3sourcePerimeter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((model->BSIM3calcacm > 0) && (model->BSIM3acmMod != 12))
|
||||||
|
{ fprintf(fplog, "Warning: CALCACM = %d is wrong. Set back to 0.\n",
|
||||||
|
model->BSIM3calcacm);
|
||||||
|
printf("Warning: CALCACM = %d is wrong. Set back to 0.\n", model->BSIM3calcacm);
|
||||||
|
model->BSIM3calcacm = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (pParam->BSIM3noff < 0.1)
|
if (pParam->BSIM3noff < 0.1)
|
||||||
{ fprintf(fplog, "Warning: Noff = %g is too small.\n",
|
{ fprintf(fplog, "Warning: Noff = %g is too small.\n",
|
||||||
|
|
@ -223,9 +232,9 @@ FILE *fplog;
|
||||||
|
|
||||||
/* Check capacitance parameters */
|
/* Check capacitance parameters */
|
||||||
if (pParam->BSIM3clc < 0.0)
|
if (pParam->BSIM3clc < 0.0)
|
||||||
{ fprintf(fplog, "Fatal: Clc = %g is negative.\n", pParam->BSIM3clc);
|
{ fprintf(fplog, "Fatal: Clc = %g is negative.\n", pParam->BSIM3clc);
|
||||||
printf("Fatal: Clc = %g is negative.\n", pParam->BSIM3clc);
|
printf("Fatal: Clc = %g is negative.\n", pParam->BSIM3clc);
|
||||||
Fatal_Flag = 1;
|
Fatal_Flag = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pParam->BSIM3moin < 5.0)
|
if (pParam->BSIM3moin < 5.0)
|
||||||
|
|
@ -239,160 +248,160 @@ FILE *fplog;
|
||||||
printf("Warning: Moin = %g is too large.\n", pParam->BSIM3moin);
|
printf("Warning: Moin = %g is too large.\n", pParam->BSIM3moin);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(model->BSIM3capMod ==3) {
|
if(model->BSIM3capMod ==3) {
|
||||||
if (pParam->BSIM3acde < 0.4)
|
if (pParam->BSIM3acde < 0.4)
|
||||||
{ fprintf(fplog, "Warning: Acde = %g is too small.\n",
|
{ fprintf(fplog, "Warning: Acde = %g is too small.\n",
|
||||||
pParam->BSIM3acde);
|
pParam->BSIM3acde);
|
||||||
printf("Warning: Acde = %g is too small.\n", pParam->BSIM3acde);
|
printf("Warning: Acde = %g is too small.\n", pParam->BSIM3acde);
|
||||||
}
|
}
|
||||||
if (pParam->BSIM3acde > 1.6)
|
if (pParam->BSIM3acde > 1.6)
|
||||||
{ fprintf(fplog, "Warning: Acde = %g is too large.\n",
|
{ fprintf(fplog, "Warning: Acde = %g is too large.\n",
|
||||||
pParam->BSIM3acde);
|
pParam->BSIM3acde);
|
||||||
printf("Warning: Acde = %g is too large.\n", pParam->BSIM3acde);
|
printf("Warning: Acde = %g is too large.\n", pParam->BSIM3acde);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (model->BSIM3paramChk ==1)
|
if (model->BSIM3paramChk ==1)
|
||||||
{
|
{
|
||||||
/* Check L and W parameters */
|
/* Check L and W parameters */
|
||||||
if (pParam->BSIM3leff <= 5.0e-8)
|
if (pParam->BSIM3leff <= 5.0e-8)
|
||||||
{ fprintf(fplog, "Warning: Leff = %g may be too small.\n",
|
{ fprintf(fplog, "Warning: Leff = %g may be too small.\n",
|
||||||
pParam->BSIM3leff);
|
pParam->BSIM3leff);
|
||||||
printf("Warning: Leff = %g may be too small.\n",
|
printf("Warning: Leff = %g may be too small.\n",
|
||||||
pParam->BSIM3leff);
|
pParam->BSIM3leff);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pParam->BSIM3leffCV <= 5.0e-8)
|
if (pParam->BSIM3leffCV <= 5.0e-8)
|
||||||
{ fprintf(fplog, "Warning: Leff for CV = %g may be too small.\n",
|
{ fprintf(fplog, "Warning: Leff for CV = %g may be too small.\n",
|
||||||
pParam->BSIM3leffCV);
|
pParam->BSIM3leffCV);
|
||||||
printf("Warning: Leff for CV = %g may be too small.\n",
|
printf("Warning: Leff for CV = %g may be too small.\n",
|
||||||
pParam->BSIM3leffCV);
|
pParam->BSIM3leffCV);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pParam->BSIM3weff <= 1.0e-7)
|
if (pParam->BSIM3weff <= 1.0e-7)
|
||||||
{ fprintf(fplog, "Warning: Weff = %g may be too small.\n",
|
{ fprintf(fplog, "Warning: Weff = %g may be too small.\n",
|
||||||
pParam->BSIM3weff);
|
pParam->BSIM3weff);
|
||||||
printf("Warning: Weff = %g may be too small.\n",
|
printf("Warning: Weff = %g may be too small.\n",
|
||||||
pParam->BSIM3weff);
|
pParam->BSIM3weff);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pParam->BSIM3weffCV <= 1.0e-7)
|
if (pParam->BSIM3weffCV <= 1.0e-7)
|
||||||
{ fprintf(fplog, "Warning: Weff for CV = %g may be too small.\n",
|
{ fprintf(fplog, "Warning: Weff for CV = %g may be too small.\n",
|
||||||
pParam->BSIM3weffCV);
|
pParam->BSIM3weffCV);
|
||||||
printf("Warning: Weff for CV = %g may be too small.\n",
|
printf("Warning: Weff for CV = %g may be too small.\n",
|
||||||
pParam->BSIM3weffCV);
|
pParam->BSIM3weffCV);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check threshold voltage parameters */
|
/* Check threshold voltage parameters */
|
||||||
if (pParam->BSIM3nlx < 0.0)
|
if (pParam->BSIM3nlx < 0.0)
|
||||||
{ fprintf(fplog, "Warning: Nlx = %g is negative.\n", pParam->BSIM3nlx);
|
{ fprintf(fplog, "Warning: Nlx = %g is negative.\n", pParam->BSIM3nlx);
|
||||||
printf("Warning: Nlx = %g is negative.\n", pParam->BSIM3nlx);
|
printf("Warning: Nlx = %g is negative.\n", pParam->BSIM3nlx);
|
||||||
}
|
}
|
||||||
if (model->BSIM3tox < 1.0e-9)
|
if (model->BSIM3tox < 1.0e-9)
|
||||||
{ fprintf(fplog, "Warning: Tox = %g is less than 10A.\n",
|
{ fprintf(fplog, "Warning: Tox = %g is less than 10A.\n",
|
||||||
model->BSIM3tox);
|
model->BSIM3tox);
|
||||||
printf("Warning: Tox = %g is less than 10A.\n", model->BSIM3tox);
|
printf("Warning: Tox = %g is less than 10A.\n", model->BSIM3tox);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pParam->BSIM3npeak <= 1.0e15)
|
if (pParam->BSIM3npeak <= 1.0e15)
|
||||||
{ fprintf(fplog, "Warning: Nch = %g may be too small.\n",
|
{ fprintf(fplog, "Warning: Nch = %g may be too small.\n",
|
||||||
pParam->BSIM3npeak);
|
pParam->BSIM3npeak);
|
||||||
printf("Warning: Nch = %g may be too small.\n",
|
printf("Warning: Nch = %g may be too small.\n",
|
||||||
pParam->BSIM3npeak);
|
pParam->BSIM3npeak);
|
||||||
}
|
}
|
||||||
else if (pParam->BSIM3npeak >= 1.0e21)
|
else if (pParam->BSIM3npeak >= 1.0e21)
|
||||||
{ fprintf(fplog, "Warning: Nch = %g may be too large.\n",
|
{ fprintf(fplog, "Warning: Nch = %g may be too large.\n",
|
||||||
pParam->BSIM3npeak);
|
pParam->BSIM3npeak);
|
||||||
printf("Warning: Nch = %g may be too large.\n",
|
printf("Warning: Nch = %g may be too large.\n",
|
||||||
pParam->BSIM3npeak);
|
pParam->BSIM3npeak);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pParam->BSIM3nsub <= 1.0e14)
|
if (pParam->BSIM3nsub <= 1.0e14)
|
||||||
{ fprintf(fplog, "Warning: Nsub = %g may be too small.\n",
|
{ fprintf(fplog, "Warning: Nsub = %g may be too small.\n",
|
||||||
pParam->BSIM3nsub);
|
pParam->BSIM3nsub);
|
||||||
printf("Warning: Nsub = %g may be too small.\n",
|
printf("Warning: Nsub = %g may be too small.\n",
|
||||||
pParam->BSIM3nsub);
|
pParam->BSIM3nsub);
|
||||||
}
|
}
|
||||||
else if (pParam->BSIM3nsub >= 1.0e21)
|
else if (pParam->BSIM3nsub >= 1.0e21)
|
||||||
{ fprintf(fplog, "Warning: Nsub = %g may be too large.\n",
|
{ fprintf(fplog, "Warning: Nsub = %g may be too large.\n",
|
||||||
pParam->BSIM3nsub);
|
pParam->BSIM3nsub);
|
||||||
printf("Warning: Nsub = %g may be too large.\n",
|
printf("Warning: Nsub = %g may be too large.\n",
|
||||||
pParam->BSIM3nsub);
|
pParam->BSIM3nsub);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((pParam->BSIM3ngate > 0.0) &&
|
if ((pParam->BSIM3ngate > 0.0) &&
|
||||||
(pParam->BSIM3ngate <= 1.e18))
|
(pParam->BSIM3ngate <= 1.e18))
|
||||||
{ fprintf(fplog, "Warning: Ngate = %g is less than 1.E18cm^-3.\n",
|
{ fprintf(fplog, "Warning: Ngate = %g is less than 1.E18cm^-3.\n",
|
||||||
pParam->BSIM3ngate);
|
pParam->BSIM3ngate);
|
||||||
printf("Warning: Ngate = %g is less than 1.E18cm^-3.\n",
|
printf("Warning: Ngate = %g is less than 1.E18cm^-3.\n",
|
||||||
pParam->BSIM3ngate);
|
pParam->BSIM3ngate);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pParam->BSIM3dvt0 < 0.0)
|
if (pParam->BSIM3dvt0 < 0.0)
|
||||||
{ fprintf(fplog, "Warning: Dvt0 = %g is negative.\n",
|
{ fprintf(fplog, "Warning: Dvt0 = %g is negative.\n",
|
||||||
pParam->BSIM3dvt0);
|
pParam->BSIM3dvt0);
|
||||||
printf("Warning: Dvt0 = %g is negative.\n", pParam->BSIM3dvt0);
|
printf("Warning: Dvt0 = %g is negative.\n", pParam->BSIM3dvt0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fabs(1.0e-6 / (pParam->BSIM3w0 + pParam->BSIM3weff)) > 10.0)
|
if (fabs(1.0e-6 / (pParam->BSIM3w0 + pParam->BSIM3weff)) > 10.0)
|
||||||
{ fprintf(fplog, "Warning: (W0 + Weff) may be too small.\n");
|
{ fprintf(fplog, "Warning: (W0 + Weff) may be too small.\n");
|
||||||
printf("Warning: (W0 + Weff) may be too small.\n");
|
printf("Warning: (W0 + Weff) may be too small.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check subthreshold parameters */
|
/* Check subthreshold parameters */
|
||||||
if (pParam->BSIM3nfactor < 0.0)
|
if (pParam->BSIM3nfactor < 0.0)
|
||||||
{ fprintf(fplog, "Warning: Nfactor = %g is negative.\n",
|
{ fprintf(fplog, "Warning: Nfactor = %g is negative.\n",
|
||||||
pParam->BSIM3nfactor);
|
pParam->BSIM3nfactor);
|
||||||
printf("Warning: Nfactor = %g is negative.\n", pParam->BSIM3nfactor);
|
printf("Warning: Nfactor = %g is negative.\n", pParam->BSIM3nfactor);
|
||||||
}
|
}
|
||||||
if (pParam->BSIM3cdsc < 0.0)
|
if (pParam->BSIM3cdsc < 0.0)
|
||||||
{ fprintf(fplog, "Warning: Cdsc = %g is negative.\n",
|
{ fprintf(fplog, "Warning: Cdsc = %g is negative.\n",
|
||||||
pParam->BSIM3cdsc);
|
pParam->BSIM3cdsc);
|
||||||
printf("Warning: Cdsc = %g is negative.\n", pParam->BSIM3cdsc);
|
printf("Warning: Cdsc = %g is negative.\n", pParam->BSIM3cdsc);
|
||||||
}
|
}
|
||||||
if (pParam->BSIM3cdscd < 0.0)
|
if (pParam->BSIM3cdscd < 0.0)
|
||||||
{ fprintf(fplog, "Warning: Cdscd = %g is negative.\n",
|
{ fprintf(fplog, "Warning: Cdscd = %g is negative.\n",
|
||||||
pParam->BSIM3cdscd);
|
pParam->BSIM3cdscd);
|
||||||
printf("Warning: Cdscd = %g is negative.\n", pParam->BSIM3cdscd);
|
printf("Warning: Cdscd = %g is negative.\n", pParam->BSIM3cdscd);
|
||||||
}
|
}
|
||||||
/* Check DIBL parameters */
|
/* Check DIBL parameters */
|
||||||
if (pParam->BSIM3eta0 < 0.0)
|
if (pParam->BSIM3eta0 < 0.0)
|
||||||
{ fprintf(fplog, "Warning: Eta0 = %g is negative.\n",
|
{ fprintf(fplog, "Warning: Eta0 = %g is negative.\n",
|
||||||
pParam->BSIM3eta0);
|
pParam->BSIM3eta0);
|
||||||
printf("Warning: Eta0 = %g is negative.\n", pParam->BSIM3eta0);
|
printf("Warning: Eta0 = %g is negative.\n", pParam->BSIM3eta0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check Abulk parameters */
|
/* Check Abulk parameters */
|
||||||
if (fabs(1.0e-6 / (pParam->BSIM3b1 + pParam->BSIM3weff)) > 10.0)
|
if (fabs(1.0e-6 / (pParam->BSIM3b1 + pParam->BSIM3weff)) > 10.0)
|
||||||
{ fprintf(fplog, "Warning: (B1 + Weff) may be too small.\n");
|
{ fprintf(fplog, "Warning: (B1 + Weff) may be too small.\n");
|
||||||
printf("Warning: (B1 + Weff) may be too small.\n");
|
printf("Warning: (B1 + Weff) may be too small.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Check Saturation parameters */
|
/* Check Saturation parameters */
|
||||||
if (pParam->BSIM3a2 < 0.01)
|
if (pParam->BSIM3a2 < 0.01)
|
||||||
{ fprintf(fplog, "Warning: A2 = %g is too small. Set to 0.01.\n", pParam->BSIM3a2);
|
{ fprintf(fplog, "Warning: A2 = %g is too small. Set to 0.01.\n", pParam->BSIM3a2);
|
||||||
printf("Warning: A2 = %g is too small. Set to 0.01.\n",
|
printf("Warning: A2 = %g is too small. Set to 0.01.\n",
|
||||||
pParam->BSIM3a2);
|
pParam->BSIM3a2);
|
||||||
pParam->BSIM3a2 = 0.01;
|
pParam->BSIM3a2 = 0.01;
|
||||||
}
|
}
|
||||||
else if (pParam->BSIM3a2 > 1.0)
|
else if (pParam->BSIM3a2 > 1.0)
|
||||||
{ fprintf(fplog, "Warning: A2 = %g is larger than 1. A2 is set to 1 and A1 is set to 0.\n",
|
{ fprintf(fplog, "Warning: A2 = %g is larger than 1. A2 is set to 1 and A1 is set to 0.\n",
|
||||||
pParam->BSIM3a2);
|
pParam->BSIM3a2);
|
||||||
printf("Warning: A2 = %g is larger than 1. A2 is set to 1 and A1 is set to 0.\n",
|
printf("Warning: A2 = %g is larger than 1. A2 is set to 1 and A1 is set to 0.\n",
|
||||||
pParam->BSIM3a2);
|
pParam->BSIM3a2);
|
||||||
pParam->BSIM3a2 = 1.0;
|
pParam->BSIM3a2 = 1.0;
|
||||||
pParam->BSIM3a1 = 0.0;
|
pParam->BSIM3a1 = 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pParam->BSIM3rdsw < 0.0)
|
if (pParam->BSIM3rdsw < 0.0)
|
||||||
{ fprintf(fplog, "Warning: Rdsw = %g is negative. Set to zero.\n",
|
{ fprintf(fplog, "Warning: Rdsw = %g is negative. Set to zero.\n",
|
||||||
pParam->BSIM3rdsw);
|
pParam->BSIM3rdsw);
|
||||||
printf("Warning: Rdsw = %g is negative. Set to zero.\n",
|
printf("Warning: Rdsw = %g is negative. Set to zero.\n",
|
||||||
pParam->BSIM3rdsw);
|
pParam->BSIM3rdsw);
|
||||||
pParam->BSIM3rdsw = 0.0;
|
pParam->BSIM3rdsw = 0.0;
|
||||||
pParam->BSIM3rds0 = 0.0;
|
pParam->BSIM3rds0 = 0.0;
|
||||||
}
|
}
|
||||||
if (pParam->BSIM3rds0 < 0.0)
|
if (pParam->BSIM3rds0 < 0.0)
|
||||||
{ fprintf(fplog, "Warning: Rds at current temperature = %g is negative. Set to zero.\n",
|
{ fprintf(fplog, "Warning: Rds at current temperature = %g is negative. Set to zero.\n",
|
||||||
pParam->BSIM3rds0);
|
pParam->BSIM3rds0);
|
||||||
|
|
@ -401,40 +410,40 @@ FILE *fplog;
|
||||||
pParam->BSIM3rds0 = 0.0;
|
pParam->BSIM3rds0 = 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pParam->BSIM3vsattemp < 1.0e3)
|
if (pParam->BSIM3vsattemp < 1.0e3)
|
||||||
{ fprintf(fplog, "Warning: Vsat at current temperature = %g may be too small.\n", pParam->BSIM3vsattemp);
|
{ fprintf(fplog, "Warning: Vsat at current temperature = %g may be too small.\n", pParam->BSIM3vsattemp);
|
||||||
printf("Warning: Vsat at current temperature = %g may be too small.\n", pParam->BSIM3vsattemp);
|
printf("Warning: Vsat at current temperature = %g may be too small.\n", pParam->BSIM3vsattemp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pParam->BSIM3pdibl1 < 0.0)
|
if (pParam->BSIM3pdibl1 < 0.0)
|
||||||
{ fprintf(fplog, "Warning: Pdibl1 = %g is negative.\n",
|
{ fprintf(fplog, "Warning: Pdibl1 = %g is negative.\n",
|
||||||
pParam->BSIM3pdibl1);
|
pParam->BSIM3pdibl1);
|
||||||
printf("Warning: Pdibl1 = %g is negative.\n", pParam->BSIM3pdibl1);
|
printf("Warning: Pdibl1 = %g is negative.\n", pParam->BSIM3pdibl1);
|
||||||
}
|
}
|
||||||
if (pParam->BSIM3pdibl2 < 0.0)
|
if (pParam->BSIM3pdibl2 < 0.0)
|
||||||
{ fprintf(fplog, "Warning: Pdibl2 = %g is negative.\n",
|
{ fprintf(fplog, "Warning: Pdibl2 = %g is negative.\n",
|
||||||
pParam->BSIM3pdibl2);
|
pParam->BSIM3pdibl2);
|
||||||
printf("Warning: Pdibl2 = %g is negative.\n", pParam->BSIM3pdibl2);
|
printf("Warning: Pdibl2 = %g is negative.\n", pParam->BSIM3pdibl2);
|
||||||
}
|
}
|
||||||
/* Check overlap capacitance parameters */
|
/* Check overlap capacitance parameters */
|
||||||
if (model->BSIM3cgdo < 0.0)
|
if (model->BSIM3cgdo < 0.0)
|
||||||
{ fprintf(fplog, "Warning: cgdo = %g is negative. Set to zero.\n", model->BSIM3cgdo);
|
{ fprintf(fplog, "Warning: cgdo = %g is negative. Set to zero.\n", model->BSIM3cgdo);
|
||||||
printf("Warning: cgdo = %g is negative. Set to zero.\n", model->BSIM3cgdo);
|
printf("Warning: cgdo = %g is negative. Set to zero.\n", model->BSIM3cgdo);
|
||||||
model->BSIM3cgdo = 0.0;
|
model->BSIM3cgdo = 0.0;
|
||||||
}
|
}
|
||||||
if (model->BSIM3cgso < 0.0)
|
if (model->BSIM3cgso < 0.0)
|
||||||
{ fprintf(fplog, "Warning: cgso = %g is negative. Set to zero.\n", model->BSIM3cgso);
|
{ fprintf(fplog, "Warning: cgso = %g is negative. Set to zero.\n", model->BSIM3cgso);
|
||||||
printf("Warning: cgso = %g is negative. Set to zero.\n", model->BSIM3cgso);
|
printf("Warning: cgso = %g is negative. Set to zero.\n", model->BSIM3cgso);
|
||||||
model->BSIM3cgso = 0.0;
|
model->BSIM3cgso = 0.0;
|
||||||
}
|
}
|
||||||
if (model->BSIM3cgbo < 0.0)
|
if (model->BSIM3cgbo < 0.0)
|
||||||
{ fprintf(fplog, "Warning: cgbo = %g is negative. Set to zero.\n", model->BSIM3cgbo);
|
{ fprintf(fplog, "Warning: cgbo = %g is negative. Set to zero.\n", model->BSIM3cgbo);
|
||||||
printf("Warning: cgbo = %g is negative. Set to zero.\n", model->BSIM3cgbo);
|
printf("Warning: cgbo = %g is negative. Set to zero.\n", model->BSIM3cgbo);
|
||||||
model->BSIM3cgbo = 0.0;
|
model->BSIM3cgbo = 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
}/* loop for the parameter check for warning messages */
|
}/* loop for the parameter check for warning messages */
|
||||||
fclose(fplog);
|
fclose(fplog);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ fprintf(stderr, "Warning: Can't open log file. Parameter checking skipped.\n");
|
{ fprintf(stderr, "Warning: Can't open log file. Parameter checking skipped.\n");
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -43,9 +43,18 @@ IFvalue *value)
|
||||||
case BSIM3_MOD_NOIMOD:
|
case BSIM3_MOD_NOIMOD:
|
||||||
value->iValue = model->BSIM3noiMod;
|
value->iValue = model->BSIM3noiMod;
|
||||||
return(OK);
|
return(OK);
|
||||||
|
case BSIM3_MOD_NQSMOD:
|
||||||
|
value->iValue = model->BSIM3nqsMod;
|
||||||
|
return(OK);
|
||||||
case BSIM3_MOD_ACNQSMOD:
|
case BSIM3_MOD_ACNQSMOD:
|
||||||
value->iValue = model->BSIM3acnqsMod;
|
value->iValue = model->BSIM3acnqsMod;
|
||||||
return(OK);
|
return(OK);
|
||||||
|
case BSIM3_MOD_ACMMOD:
|
||||||
|
value->iValue = model->BSIM3acmMod;
|
||||||
|
return(OK);
|
||||||
|
case BSIM3_MOD_CALCACM:
|
||||||
|
value->iValue = model->BSIM3calcacm;
|
||||||
|
return(OK);
|
||||||
case BSIM3_MOD_VERSION :
|
case BSIM3_MOD_VERSION :
|
||||||
value->sValue = model->BSIM3version;
|
value->sValue = model->BSIM3version;
|
||||||
return(OK);
|
return(OK);
|
||||||
|
|
@ -337,6 +346,32 @@ IFvalue *value)
|
||||||
value->rValue = model->BSIM3tpbswg;
|
value->rValue = model->BSIM3tpbswg;
|
||||||
return(OK);
|
return(OK);
|
||||||
|
|
||||||
|
/* ACM model */
|
||||||
|
case BSIM3_MOD_HDIF:
|
||||||
|
value->rValue = model->BSIM3hdif;
|
||||||
|
return(OK);
|
||||||
|
case BSIM3_MOD_LDIF:
|
||||||
|
value->rValue = model->BSIM3ldif;
|
||||||
|
return(OK);
|
||||||
|
case BSIM3_MOD_LD:
|
||||||
|
value->rValue = model->BSIM3ld;
|
||||||
|
return(OK);
|
||||||
|
case BSIM3_MOD_RD:
|
||||||
|
value->rValue = model->BSIM3rd;
|
||||||
|
return(OK);
|
||||||
|
case BSIM3_MOD_RS:
|
||||||
|
value->rValue = model->BSIM3rs;
|
||||||
|
return(OK);
|
||||||
|
case BSIM3_MOD_RDC:
|
||||||
|
value->rValue = model->BSIM3rdc;
|
||||||
|
return(OK);
|
||||||
|
case BSIM3_MOD_RSC:
|
||||||
|
value->rValue = model->BSIM3rsc;
|
||||||
|
return(OK);
|
||||||
|
case BSIM3_MOD_WMLT:
|
||||||
|
value->rValue = model->BSIM3wmlt;
|
||||||
|
return(OK);
|
||||||
|
|
||||||
/* Length dependence */
|
/* Length dependence */
|
||||||
case BSIM3_MOD_LCDSC :
|
case BSIM3_MOD_LCDSC :
|
||||||
value->rValue = model->BSIM3lcdsc;
|
value->rValue = model->BSIM3lcdsc;
|
||||||
|
|
@ -1219,6 +1254,14 @@ IFvalue *value)
|
||||||
case BSIM3_MOD_WMAX:
|
case BSIM3_MOD_WMAX:
|
||||||
value->rValue = model->BSIM3Wmax;
|
value->rValue = model->BSIM3Wmax;
|
||||||
return(OK);
|
return(OK);
|
||||||
|
|
||||||
|
case BSIM3_MOD_XL:
|
||||||
|
value->rValue = model->BSIM3xl;
|
||||||
|
return(OK);
|
||||||
|
case BSIM3_MOD_XW:
|
||||||
|
value->rValue = model->BSIM3xw;
|
||||||
|
return(OK);
|
||||||
|
|
||||||
case BSIM3_MOD_NOIA:
|
case BSIM3_MOD_NOIA:
|
||||||
value->rValue = model->BSIM3oxideTrapDensityA;
|
value->rValue = model->BSIM3oxideTrapDensityA;
|
||||||
return(OK);
|
return(OK);
|
||||||
|
|
|
||||||
|
|
@ -39,15 +39,27 @@ GENmodel *inMod)
|
||||||
mod->BSIM3capMod = value->iValue;
|
mod->BSIM3capMod = value->iValue;
|
||||||
mod->BSIM3capModGiven = TRUE;
|
mod->BSIM3capModGiven = TRUE;
|
||||||
break;
|
break;
|
||||||
|
case BSIM3_MOD_ACMMOD:
|
||||||
|
mod->BSIM3acmMod = value->iValue;
|
||||||
|
mod->BSIM3acmModGiven = TRUE;
|
||||||
|
break;
|
||||||
|
case BSIM3_MOD_CALCACM:
|
||||||
|
mod->BSIM3calcacm = value->iValue;
|
||||||
|
mod->BSIM3calcacmGiven = TRUE;
|
||||||
|
break;
|
||||||
case BSIM3_MOD_NOIMOD :
|
case BSIM3_MOD_NOIMOD :
|
||||||
mod->BSIM3noiMod = value->iValue;
|
mod->BSIM3noiMod = value->iValue;
|
||||||
mod->BSIM3noiModGiven = TRUE;
|
mod->BSIM3noiModGiven = TRUE;
|
||||||
break;
|
break;
|
||||||
|
case BSIM3_MOD_NQSMOD :
|
||||||
|
mod->BSIM3nqsMod = value->iValue;
|
||||||
|
mod->BSIM3nqsModGiven = TRUE;
|
||||||
|
break;
|
||||||
case BSIM3_MOD_ACNQSMOD :
|
case BSIM3_MOD_ACNQSMOD :
|
||||||
mod->BSIM3acnqsMod = value->iValue;
|
mod->BSIM3acnqsMod = value->iValue;
|
||||||
mod->BSIM3acnqsModGiven = TRUE;
|
mod->BSIM3acnqsModGiven = TRUE;
|
||||||
break;
|
break;
|
||||||
case BSIM3_MOD_VERSION :
|
case BSIM3_MOD_VERSION :
|
||||||
mod->BSIM3version = value->sValue;
|
mod->BSIM3version = value->sValue;
|
||||||
mod->BSIM3versionGiven = TRUE;
|
mod->BSIM3versionGiven = TRUE;
|
||||||
break;
|
break;
|
||||||
|
|
@ -123,14 +135,14 @@ GENmodel *inMod)
|
||||||
case BSIM3_MOD_NPEAK:
|
case BSIM3_MOD_NPEAK:
|
||||||
mod->BSIM3npeak = value->rValue;
|
mod->BSIM3npeak = value->rValue;
|
||||||
mod->BSIM3npeakGiven = TRUE;
|
mod->BSIM3npeakGiven = TRUE;
|
||||||
if (mod->BSIM3npeak > 1.0e20)
|
if (mod->BSIM3npeak > 1.0e20)
|
||||||
mod->BSIM3npeak *= 1.0e-6;
|
mod->BSIM3npeak *= 1.0e-6;
|
||||||
break;
|
break;
|
||||||
case BSIM3_MOD_NGATE:
|
case BSIM3_MOD_NGATE:
|
||||||
mod->BSIM3ngate = value->rValue;
|
mod->BSIM3ngate = value->rValue;
|
||||||
mod->BSIM3ngateGiven = TRUE;
|
mod->BSIM3ngateGiven = TRUE;
|
||||||
if (mod->BSIM3ngate > 1.0e23)
|
if (mod->BSIM3ngate > 1.0e23)
|
||||||
mod->BSIM3ngate *= 1.0e-6;
|
mod->BSIM3ngate *= 1.0e-6;
|
||||||
break;
|
break;
|
||||||
case BSIM3_MOD_GAMMA1:
|
case BSIM3_MOD_GAMMA1:
|
||||||
mod->BSIM3gamma1 = value->rValue;
|
mod->BSIM3gamma1 = value->rValue;
|
||||||
|
|
@ -438,7 +450,41 @@ GENmodel *inMod)
|
||||||
mod->BSIM3tpbswgGiven = TRUE;
|
mod->BSIM3tpbswgGiven = TRUE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Length dependence */
|
/* acm model */
|
||||||
|
case BSIM3_MOD_HDIF:
|
||||||
|
mod->BSIM3hdif = value->rValue;
|
||||||
|
mod->BSIM3hdifGiven = TRUE;
|
||||||
|
break;
|
||||||
|
case BSIM3_MOD_LDIF:
|
||||||
|
mod->BSIM3ldif = value->rValue;
|
||||||
|
mod->BSIM3ldifGiven = TRUE;
|
||||||
|
break;
|
||||||
|
case BSIM3_MOD_LD:
|
||||||
|
mod->BSIM3ld = value->rValue;
|
||||||
|
mod->BSIM3ldGiven = TRUE;
|
||||||
|
break;
|
||||||
|
case BSIM3_MOD_RD:
|
||||||
|
mod->BSIM3rd = value->rValue;
|
||||||
|
mod->BSIM3rdGiven = TRUE;
|
||||||
|
break;
|
||||||
|
case BSIM3_MOD_RS:
|
||||||
|
mod->BSIM3rs = value->rValue;
|
||||||
|
mod->BSIM3rsGiven = TRUE;
|
||||||
|
break;
|
||||||
|
case BSIM3_MOD_RDC:
|
||||||
|
mod->BSIM3rdc = value->rValue;
|
||||||
|
mod->BSIM3rdcGiven = TRUE;
|
||||||
|
break;
|
||||||
|
case BSIM3_MOD_RSC:
|
||||||
|
mod->BSIM3rsc = value->rValue;
|
||||||
|
mod->BSIM3rscGiven = TRUE;
|
||||||
|
break;
|
||||||
|
case BSIM3_MOD_WMLT:
|
||||||
|
mod->BSIM3wmlt = value->rValue;
|
||||||
|
mod->BSIM3wmltGiven = TRUE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Length dependence */
|
||||||
case BSIM3_MOD_LCDSC :
|
case BSIM3_MOD_LCDSC :
|
||||||
mod->BSIM3lcdsc = value->rValue;
|
mod->BSIM3lcdsc = value->rValue;
|
||||||
mod->BSIM3lcdscGiven = TRUE;
|
mod->BSIM3lcdscGiven = TRUE;
|
||||||
|
|
@ -502,14 +548,14 @@ GENmodel *inMod)
|
||||||
case BSIM3_MOD_LNPEAK:
|
case BSIM3_MOD_LNPEAK:
|
||||||
mod->BSIM3lnpeak = value->rValue;
|
mod->BSIM3lnpeak = value->rValue;
|
||||||
mod->BSIM3lnpeakGiven = TRUE;
|
mod->BSIM3lnpeakGiven = TRUE;
|
||||||
if (mod->BSIM3lnpeak > 1.0e20)
|
if (mod->BSIM3lnpeak > 1.0e20)
|
||||||
mod->BSIM3lnpeak *= 1.0e-6;
|
mod->BSIM3lnpeak *= 1.0e-6;
|
||||||
break;
|
break;
|
||||||
case BSIM3_MOD_LNGATE:
|
case BSIM3_MOD_LNGATE:
|
||||||
mod->BSIM3lngate = value->rValue;
|
mod->BSIM3lngate = value->rValue;
|
||||||
mod->BSIM3lngateGiven = TRUE;
|
mod->BSIM3lngateGiven = TRUE;
|
||||||
if (mod->BSIM3lngate > 1.0e23)
|
if (mod->BSIM3lngate > 1.0e23)
|
||||||
mod->BSIM3lngate *= 1.0e-6;
|
mod->BSIM3lngate *= 1.0e-6;
|
||||||
break;
|
break;
|
||||||
case BSIM3_MOD_LGAMMA1:
|
case BSIM3_MOD_LGAMMA1:
|
||||||
mod->BSIM3lgamma1 = value->rValue;
|
mod->BSIM3lgamma1 = value->rValue;
|
||||||
|
|
@ -781,7 +827,7 @@ GENmodel *inMod)
|
||||||
mod->BSIM3lvoffcvGiven = TRUE;
|
mod->BSIM3lvoffcvGiven = TRUE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Width dependence */
|
/* Width dependence */
|
||||||
case BSIM3_MOD_WCDSC :
|
case BSIM3_MOD_WCDSC :
|
||||||
mod->BSIM3wcdsc = value->rValue;
|
mod->BSIM3wcdsc = value->rValue;
|
||||||
mod->BSIM3wcdscGiven = TRUE;
|
mod->BSIM3wcdscGiven = TRUE;
|
||||||
|
|
@ -845,14 +891,14 @@ GENmodel *inMod)
|
||||||
case BSIM3_MOD_WNPEAK:
|
case BSIM3_MOD_WNPEAK:
|
||||||
mod->BSIM3wnpeak = value->rValue;
|
mod->BSIM3wnpeak = value->rValue;
|
||||||
mod->BSIM3wnpeakGiven = TRUE;
|
mod->BSIM3wnpeakGiven = TRUE;
|
||||||
if (mod->BSIM3wnpeak > 1.0e20)
|
if (mod->BSIM3wnpeak > 1.0e20)
|
||||||
mod->BSIM3wnpeak *= 1.0e-6;
|
mod->BSIM3wnpeak *= 1.0e-6;
|
||||||
break;
|
break;
|
||||||
case BSIM3_MOD_WNGATE:
|
case BSIM3_MOD_WNGATE:
|
||||||
mod->BSIM3wngate = value->rValue;
|
mod->BSIM3wngate = value->rValue;
|
||||||
mod->BSIM3wngateGiven = TRUE;
|
mod->BSIM3wngateGiven = TRUE;
|
||||||
if (mod->BSIM3wngate > 1.0e23)
|
if (mod->BSIM3wngate > 1.0e23)
|
||||||
mod->BSIM3wngate *= 1.0e-6;
|
mod->BSIM3wngate *= 1.0e-6;
|
||||||
break;
|
break;
|
||||||
case BSIM3_MOD_WGAMMA1:
|
case BSIM3_MOD_WGAMMA1:
|
||||||
mod->BSIM3wgamma1 = value->rValue;
|
mod->BSIM3wgamma1 = value->rValue;
|
||||||
|
|
@ -1124,7 +1170,7 @@ GENmodel *inMod)
|
||||||
mod->BSIM3wvoffcvGiven = TRUE;
|
mod->BSIM3wvoffcvGiven = TRUE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Cross-term dependence */
|
/* Cross-term dependence */
|
||||||
case BSIM3_MOD_PCDSC :
|
case BSIM3_MOD_PCDSC :
|
||||||
mod->BSIM3pcdsc = value->rValue;
|
mod->BSIM3pcdsc = value->rValue;
|
||||||
mod->BSIM3pcdscGiven = TRUE;
|
mod->BSIM3pcdscGiven = TRUE;
|
||||||
|
|
@ -1188,14 +1234,14 @@ GENmodel *inMod)
|
||||||
case BSIM3_MOD_PNPEAK:
|
case BSIM3_MOD_PNPEAK:
|
||||||
mod->BSIM3pnpeak = value->rValue;
|
mod->BSIM3pnpeak = value->rValue;
|
||||||
mod->BSIM3pnpeakGiven = TRUE;
|
mod->BSIM3pnpeakGiven = TRUE;
|
||||||
if (mod->BSIM3pnpeak > 1.0e20)
|
if (mod->BSIM3pnpeak > 1.0e20)
|
||||||
mod->BSIM3pnpeak *= 1.0e-6;
|
mod->BSIM3pnpeak *= 1.0e-6;
|
||||||
break;
|
break;
|
||||||
case BSIM3_MOD_PNGATE:
|
case BSIM3_MOD_PNGATE:
|
||||||
mod->BSIM3pngate = value->rValue;
|
mod->BSIM3pngate = value->rValue;
|
||||||
mod->BSIM3pngateGiven = TRUE;
|
mod->BSIM3pngateGiven = TRUE;
|
||||||
if (mod->BSIM3pngate > 1.0e23)
|
if (mod->BSIM3pngate > 1.0e23)
|
||||||
mod->BSIM3pngate *= 1.0e-6;
|
mod->BSIM3pngate *= 1.0e-6;
|
||||||
break;
|
break;
|
||||||
case BSIM3_MOD_PGAMMA1:
|
case BSIM3_MOD_PGAMMA1:
|
||||||
mod->BSIM3pgamma1 = value->rValue;
|
mod->BSIM3pgamma1 = value->rValue;
|
||||||
|
|
@ -1636,6 +1682,15 @@ GENmodel *inMod)
|
||||||
mod->BSIM3WmaxGiven = TRUE;
|
mod->BSIM3WmaxGiven = TRUE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case BSIM3_MOD_XL:
|
||||||
|
mod->BSIM3xl = value->rValue;
|
||||||
|
mod->BSIM3xlGiven = TRUE;
|
||||||
|
break;
|
||||||
|
case BSIM3_MOD_XW:
|
||||||
|
mod->BSIM3xw = value->rValue;
|
||||||
|
mod->BSIM3xwGiven = TRUE;
|
||||||
|
break;
|
||||||
|
|
||||||
case BSIM3_MOD_NOIA :
|
case BSIM3_MOD_NOIA :
|
||||||
mod->BSIM3oxideTrapDensityA = value->rValue;
|
mod->BSIM3oxideTrapDensityA = value->rValue;
|
||||||
mod->BSIM3oxideTrapDensityAGiven = TRUE;
|
mod->BSIM3oxideTrapDensityAGiven = TRUE;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
/**********
|
||||||
|
Author: 2013 Francesco Lannutti
|
||||||
|
**********/
|
||||||
|
|
||||||
|
#include "ngspice/ngspice.h"
|
||||||
|
#include "ngspice/cktdefs.h"
|
||||||
|
#include "bsim3def.h"
|
||||||
|
#include "ngspice/sperror.h"
|
||||||
|
|
||||||
|
int
|
||||||
|
BSIM3nodeIsNonLinear (GENmodel *inModel, CKTcircuit *ckt)
|
||||||
|
{
|
||||||
|
BSIM3model *model = (BSIM3model *)inModel ;
|
||||||
|
BSIM3instance *here ;
|
||||||
|
|
||||||
|
/* loop through all the BSIM3 models */
|
||||||
|
for ( ; model != NULL ; model = model->BSIM3nextModel)
|
||||||
|
{
|
||||||
|
/* loop through all the instances of the model */
|
||||||
|
for (here = model->BSIM3instances ; here != NULL ; here = here->BSIM3nextInstance)
|
||||||
|
{
|
||||||
|
ckt->CKTnodeIsLinear [here->BSIM3dNodePrime] = 0 ;
|
||||||
|
ckt->CKTnodeIsLinear [here->BSIM3sNodePrime] = 0 ;
|
||||||
|
ckt->CKTnodeIsLinear [here->BSIM3qNode] = 0 ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (OK) ;
|
||||||
|
}
|
||||||
|
|
@ -40,10 +40,10 @@ IFvalue *select)
|
||||||
here->BSIM3l = value->rValue*scale;
|
here->BSIM3l = value->rValue*scale;
|
||||||
here->BSIM3lGiven = TRUE;
|
here->BSIM3lGiven = TRUE;
|
||||||
break;
|
break;
|
||||||
case BSIM3_M:
|
case BSIM3_M:
|
||||||
here->BSIM3m = value->rValue;
|
here->BSIM3m = value->rValue;
|
||||||
here->BSIM3mGiven = TRUE;
|
here->BSIM3mGiven = TRUE;
|
||||||
break;
|
break;
|
||||||
case BSIM3_AS:
|
case BSIM3_AS:
|
||||||
here->BSIM3sourceArea = value->rValue*scale*scale;
|
here->BSIM3sourceArea = value->rValue*scale*scale;
|
||||||
here->BSIM3sourceAreaGiven = TRUE;
|
here->BSIM3sourceAreaGiven = TRUE;
|
||||||
|
|
@ -91,6 +91,18 @@ IFvalue *select)
|
||||||
here->BSIM3acnqsMod = value->iValue;
|
here->BSIM3acnqsMod = value->iValue;
|
||||||
here->BSIM3acnqsModGiven = TRUE;
|
here->BSIM3acnqsModGiven = TRUE;
|
||||||
break;
|
break;
|
||||||
|
case BSIM3_GEO:
|
||||||
|
here->BSIM3geo = value->iValue;
|
||||||
|
here->BSIM3geoGiven = TRUE;
|
||||||
|
break;
|
||||||
|
case BSIM3_DELVTO:
|
||||||
|
here->BSIM3delvto = value->rValue;
|
||||||
|
here->BSIM3delvtoGiven = TRUE;
|
||||||
|
break;
|
||||||
|
case BSIM3_MULU0:
|
||||||
|
here->BSIM3mulu0 = value->rValue;
|
||||||
|
here->BSIM3mulu0Given = TRUE;
|
||||||
|
break;
|
||||||
case BSIM3_IC:
|
case BSIM3_IC:
|
||||||
switch(value->v.numValue){
|
switch(value->v.numValue){
|
||||||
case 3:
|
case 3:
|
||||||
|
|
|
||||||
|
|
@ -61,8 +61,18 @@ BSIM3instance **InstArray;
|
||||||
model->BSIM3paramChk = 0;
|
model->BSIM3paramChk = 0;
|
||||||
if (!model->BSIM3capModGiven)
|
if (!model->BSIM3capModGiven)
|
||||||
model->BSIM3capMod = 3;
|
model->BSIM3capMod = 3;
|
||||||
|
if (!model->BSIM3acmModGiven)
|
||||||
|
model->BSIM3acmMod = 0;
|
||||||
|
if (!model->BSIM3calcacmGiven)
|
||||||
|
model->BSIM3calcacm = 0;
|
||||||
if (!model->BSIM3noiModGiven)
|
if (!model->BSIM3noiModGiven)
|
||||||
model->BSIM3noiMod = 1;
|
model->BSIM3noiMod = 1;
|
||||||
|
if (!model->BSIM3nqsModGiven)
|
||||||
|
model->BSIM3nqsMod = 0;
|
||||||
|
else if ((model->BSIM3nqsMod != 0) && (model->BSIM3nqsMod != 1))
|
||||||
|
{ model->BSIM3nqsMod = 0;
|
||||||
|
printf("Warning: nqsMod has been set to its default value: 0.\n");
|
||||||
|
}
|
||||||
if (!model->BSIM3acnqsModGiven)
|
if (!model->BSIM3acnqsModGiven)
|
||||||
model->BSIM3acnqsMod = 0;
|
model->BSIM3acnqsMod = 0;
|
||||||
else if ((model->BSIM3acnqsMod != 0) && (model->BSIM3acnqsMod != 1))
|
else if ((model->BSIM3acnqsMod != 0) && (model->BSIM3acnqsMod != 1))
|
||||||
|
|
@ -247,6 +257,24 @@ BSIM3instance **InstArray;
|
||||||
if (!model->BSIM3tpbswgGiven)
|
if (!model->BSIM3tpbswgGiven)
|
||||||
model->BSIM3tpbswg = 0.0;
|
model->BSIM3tpbswg = 0.0;
|
||||||
|
|
||||||
|
/* ACM model */
|
||||||
|
if (!model->BSIM3hdifGiven)
|
||||||
|
model->BSIM3hdif = 0.0;
|
||||||
|
if (!model->BSIM3ldifGiven)
|
||||||
|
model->BSIM3ldif = 0.0;
|
||||||
|
if (!model->BSIM3ldGiven)
|
||||||
|
model->BSIM3ld = 0.0;
|
||||||
|
if (!model->BSIM3rdGiven)
|
||||||
|
model->BSIM3rd = 0.0;
|
||||||
|
if (!model->BSIM3rsGiven)
|
||||||
|
model->BSIM3rs = 0.0;
|
||||||
|
if (!model->BSIM3rdcGiven)
|
||||||
|
model->BSIM3rdc = 0.0;
|
||||||
|
if (!model->BSIM3rscGiven)
|
||||||
|
model->BSIM3rsc = 0.0;
|
||||||
|
if (!model->BSIM3wmltGiven)
|
||||||
|
model->BSIM3wmlt = 1.0;
|
||||||
|
|
||||||
/* Length dependence */
|
/* Length dependence */
|
||||||
if (!model->BSIM3lcdscGiven)
|
if (!model->BSIM3lcdscGiven)
|
||||||
model->BSIM3lcdsc = 0.0;
|
model->BSIM3lcdsc = 0.0;
|
||||||
|
|
@ -780,6 +808,12 @@ BSIM3instance **InstArray;
|
||||||
model->BSIM3dwc = model->BSIM3Wint;
|
model->BSIM3dwc = model->BSIM3Wint;
|
||||||
if (!model->BSIM3dlcGiven)
|
if (!model->BSIM3dlcGiven)
|
||||||
model->BSIM3dlc = model->BSIM3Lint;
|
model->BSIM3dlc = model->BSIM3Lint;
|
||||||
|
|
||||||
|
if (!model->BSIM3xlGiven)
|
||||||
|
model->BSIM3xl = 0.0;
|
||||||
|
if (!model->BSIM3xwGiven)
|
||||||
|
model->BSIM3xw = 0.0;
|
||||||
|
|
||||||
if (!model->BSIM3cfGiven)
|
if (!model->BSIM3cfGiven)
|
||||||
model->BSIM3cf = 2.0 * EPSOX / PI
|
model->BSIM3cf = 2.0 * EPSOX / PI
|
||||||
* log(1.0 + 0.4e-6 / model->BSIM3tox);
|
* log(1.0 + 0.4e-6 / model->BSIM3tox);
|
||||||
|
|
@ -874,7 +908,16 @@ BSIM3instance **InstArray;
|
||||||
if (!here->BSIM3drainPerimeterGiven)
|
if (!here->BSIM3drainPerimeterGiven)
|
||||||
here->BSIM3drainPerimeter = 0.0;
|
here->BSIM3drainPerimeter = 0.0;
|
||||||
if (!here->BSIM3drainSquaresGiven)
|
if (!here->BSIM3drainSquaresGiven)
|
||||||
here->BSIM3drainSquares = 1.0;
|
{
|
||||||
|
if (model->BSIM3acmMod == 0)
|
||||||
|
here->BSIM3drainSquares = 1.0;
|
||||||
|
else
|
||||||
|
here->BSIM3drainSquares = 0.0;
|
||||||
|
}
|
||||||
|
if (!here->BSIM3delvtoGiven)
|
||||||
|
here->BSIM3delvto = 0.0;
|
||||||
|
if (!here->BSIM3mulu0Given)
|
||||||
|
here->BSIM3mulu0 = 1.0;
|
||||||
if (!here->BSIM3icVBSGiven)
|
if (!here->BSIM3icVBSGiven)
|
||||||
here->BSIM3icVBS = 0.0;
|
here->BSIM3icVBS = 0.0;
|
||||||
if (!here->BSIM3icVDSGiven)
|
if (!here->BSIM3icVDSGiven)
|
||||||
|
|
@ -888,11 +931,21 @@ BSIM3instance **InstArray;
|
||||||
if (!here->BSIM3sourcePerimeterGiven)
|
if (!here->BSIM3sourcePerimeterGiven)
|
||||||
here->BSIM3sourcePerimeter = 0.0;
|
here->BSIM3sourcePerimeter = 0.0;
|
||||||
if (!here->BSIM3sourceSquaresGiven)
|
if (!here->BSIM3sourceSquaresGiven)
|
||||||
here->BSIM3sourceSquares = 1.0;
|
{
|
||||||
|
if (model->BSIM3acmMod == 0)
|
||||||
|
here->BSIM3sourceSquares = 1.0;
|
||||||
|
else
|
||||||
|
here->BSIM3sourceSquares = 0.0;
|
||||||
|
}
|
||||||
if (!here->BSIM3wGiven)
|
if (!here->BSIM3wGiven)
|
||||||
here->BSIM3w = 5.0e-6;
|
here->BSIM3w = 5.0e-6;
|
||||||
if (!here->BSIM3nqsModGiven)
|
if (!here->BSIM3nqsModGiven)
|
||||||
here->BSIM3nqsMod = 0;
|
here->BSIM3nqsMod = model->BSIM3nqsMod;
|
||||||
|
else if ((here->BSIM3nqsMod != 0) && (here->BSIM3nqsMod != 1))
|
||||||
|
{ here->BSIM3nqsMod = model->BSIM3nqsMod;
|
||||||
|
printf("Warning: nqsMod has been set to its global value %d.\n",
|
||||||
|
model->BSIM3nqsMod);
|
||||||
|
}
|
||||||
if (!here->BSIM3acnqsModGiven)
|
if (!here->BSIM3acnqsModGiven)
|
||||||
here->BSIM3acnqsMod = model->BSIM3acnqsMod;
|
here->BSIM3acnqsMod = model->BSIM3acnqsMod;
|
||||||
else if ((here->BSIM3acnqsMod != 0) && (here->BSIM3acnqsMod != 1))
|
else if ((here->BSIM3acnqsMod != 0) && (here->BSIM3acnqsMod != 1))
|
||||||
|
|
@ -900,14 +953,19 @@ BSIM3instance **InstArray;
|
||||||
printf("Warning: acnqsMod has been set to its global value %d.\n",
|
printf("Warning: acnqsMod has been set to its global value %d.\n",
|
||||||
model->BSIM3acnqsMod);
|
model->BSIM3acnqsMod);
|
||||||
}
|
}
|
||||||
|
if (!here->BSIM3geoGiven)
|
||||||
|
here->BSIM3geo = 0;
|
||||||
|
|
||||||
if (!here->BSIM3mGiven)
|
if (!here->BSIM3mGiven)
|
||||||
here->BSIM3m = 1;
|
here->BSIM3m = 1;
|
||||||
|
|
||||||
/* process drain series resistance */
|
/* process drain series resistance */
|
||||||
if ((model->BSIM3sheetResistance > 0.0) &&
|
if ( ((model->BSIM3sheetResistance > 0.0) && (here->BSIM3drainSquares > 0.0))
|
||||||
(here->BSIM3drainSquares > 0.0 ))
|
||((model->BSIM3sheetResistance > 0.0) && (model->BSIM3hdif > 0.0))
|
||||||
|
||((model->BSIM3rd > 0.0) && (model->BSIM3ldif > 0.0))
|
||||||
|
||((model->BSIM3rd > 0.0) && (model->BSIM3ld > 0.0))
|
||||||
|
||((model->BSIM3rdc > 0.0))
|
||||||
|
)
|
||||||
{
|
{
|
||||||
if(here->BSIM3dNodePrime == 0) {
|
if(here->BSIM3dNodePrime == 0) {
|
||||||
error = CKTmkVolt(ckt,&tmp,here->BSIM3name,"drain");
|
error = CKTmkVolt(ckt,&tmp,here->BSIM3name,"drain");
|
||||||
|
|
@ -928,8 +986,12 @@ BSIM3instance **InstArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* process source series resistance */
|
/* process source series resistance */
|
||||||
if ((model->BSIM3sheetResistance > 0.0) &&
|
if ( ((model->BSIM3sheetResistance > 0.0) && (here->BSIM3sourceSquares > 0.0))
|
||||||
(here->BSIM3sourceSquares > 0.0 ))
|
||((model->BSIM3sheetResistance > 0.0) && (model->BSIM3hdif > 0.0))
|
||||||
|
||((model->BSIM3rs > 0.0) && (model->BSIM3ldif > 0.0))
|
||||||
|
||((model->BSIM3rs > 0.0) && (model->BSIM3ld > 0.0))
|
||||||
|
||((model->BSIM3rsc > 0.0))
|
||||||
|
)
|
||||||
{
|
{
|
||||||
if(here->BSIM3sNodePrime == 0) {
|
if(here->BSIM3sNodePrime == 0) {
|
||||||
error = CKTmkVolt(ckt,&tmp,here->BSIM3name,"source");
|
error = CKTmkVolt(ckt,&tmp,here->BSIM3name,"source");
|
||||||
|
|
@ -967,43 +1029,43 @@ BSIM3instance **InstArray;
|
||||||
|
|
||||||
/* macro to make elements with built in test for out of memory */
|
/* macro to make elements with built in test for out of memory */
|
||||||
#define TSTALLOC(ptr,first,second) \
|
#define TSTALLOC(ptr,first,second) \
|
||||||
if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\
|
do { if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\
|
||||||
return(E_NOMEM);\
|
return(E_NOMEM);\
|
||||||
}
|
} } while(0)
|
||||||
|
|
||||||
TSTALLOC(BSIM3DdPtr, BSIM3dNode, BSIM3dNode)
|
TSTALLOC(BSIM3DdPtr, BSIM3dNode, BSIM3dNode);
|
||||||
TSTALLOC(BSIM3GgPtr, BSIM3gNode, BSIM3gNode)
|
TSTALLOC(BSIM3GgPtr, BSIM3gNode, BSIM3gNode);
|
||||||
TSTALLOC(BSIM3SsPtr, BSIM3sNode, BSIM3sNode)
|
TSTALLOC(BSIM3SsPtr, BSIM3sNode, BSIM3sNode);
|
||||||
TSTALLOC(BSIM3BbPtr, BSIM3bNode, BSIM3bNode)
|
TSTALLOC(BSIM3BbPtr, BSIM3bNode, BSIM3bNode);
|
||||||
TSTALLOC(BSIM3DPdpPtr, BSIM3dNodePrime, BSIM3dNodePrime)
|
TSTALLOC(BSIM3DPdpPtr, BSIM3dNodePrime, BSIM3dNodePrime);
|
||||||
TSTALLOC(BSIM3SPspPtr, BSIM3sNodePrime, BSIM3sNodePrime)
|
TSTALLOC(BSIM3SPspPtr, BSIM3sNodePrime, BSIM3sNodePrime);
|
||||||
TSTALLOC(BSIM3DdpPtr, BSIM3dNode, BSIM3dNodePrime)
|
TSTALLOC(BSIM3DdpPtr, BSIM3dNode, BSIM3dNodePrime);
|
||||||
TSTALLOC(BSIM3GbPtr, BSIM3gNode, BSIM3bNode)
|
TSTALLOC(BSIM3GbPtr, BSIM3gNode, BSIM3bNode);
|
||||||
TSTALLOC(BSIM3GdpPtr, BSIM3gNode, BSIM3dNodePrime)
|
TSTALLOC(BSIM3GdpPtr, BSIM3gNode, BSIM3dNodePrime);
|
||||||
TSTALLOC(BSIM3GspPtr, BSIM3gNode, BSIM3sNodePrime)
|
TSTALLOC(BSIM3GspPtr, BSIM3gNode, BSIM3sNodePrime);
|
||||||
TSTALLOC(BSIM3SspPtr, BSIM3sNode, BSIM3sNodePrime)
|
TSTALLOC(BSIM3SspPtr, BSIM3sNode, BSIM3sNodePrime);
|
||||||
TSTALLOC(BSIM3BdpPtr, BSIM3bNode, BSIM3dNodePrime)
|
TSTALLOC(BSIM3BdpPtr, BSIM3bNode, BSIM3dNodePrime);
|
||||||
TSTALLOC(BSIM3BspPtr, BSIM3bNode, BSIM3sNodePrime)
|
TSTALLOC(BSIM3BspPtr, BSIM3bNode, BSIM3sNodePrime);
|
||||||
TSTALLOC(BSIM3DPspPtr, BSIM3dNodePrime, BSIM3sNodePrime)
|
TSTALLOC(BSIM3DPspPtr, BSIM3dNodePrime, BSIM3sNodePrime);
|
||||||
TSTALLOC(BSIM3DPdPtr, BSIM3dNodePrime, BSIM3dNode)
|
TSTALLOC(BSIM3DPdPtr, BSIM3dNodePrime, BSIM3dNode);
|
||||||
TSTALLOC(BSIM3BgPtr, BSIM3bNode, BSIM3gNode)
|
TSTALLOC(BSIM3BgPtr, BSIM3bNode, BSIM3gNode);
|
||||||
TSTALLOC(BSIM3DPgPtr, BSIM3dNodePrime, BSIM3gNode)
|
TSTALLOC(BSIM3DPgPtr, BSIM3dNodePrime, BSIM3gNode);
|
||||||
TSTALLOC(BSIM3SPgPtr, BSIM3sNodePrime, BSIM3gNode)
|
TSTALLOC(BSIM3SPgPtr, BSIM3sNodePrime, BSIM3gNode);
|
||||||
TSTALLOC(BSIM3SPsPtr, BSIM3sNodePrime, BSIM3sNode)
|
TSTALLOC(BSIM3SPsPtr, BSIM3sNodePrime, BSIM3sNode);
|
||||||
TSTALLOC(BSIM3DPbPtr, BSIM3dNodePrime, BSIM3bNode)
|
TSTALLOC(BSIM3DPbPtr, BSIM3dNodePrime, BSIM3bNode);
|
||||||
TSTALLOC(BSIM3SPbPtr, BSIM3sNodePrime, BSIM3bNode)
|
TSTALLOC(BSIM3SPbPtr, BSIM3sNodePrime, BSIM3bNode);
|
||||||
TSTALLOC(BSIM3SPdpPtr, BSIM3sNodePrime, BSIM3dNodePrime)
|
TSTALLOC(BSIM3SPdpPtr, BSIM3sNodePrime, BSIM3dNodePrime);
|
||||||
|
|
||||||
TSTALLOC(BSIM3QqPtr, BSIM3qNode, BSIM3qNode)
|
TSTALLOC(BSIM3QqPtr, BSIM3qNode, BSIM3qNode);
|
||||||
|
|
||||||
TSTALLOC(BSIM3QdpPtr, BSIM3qNode, BSIM3dNodePrime)
|
TSTALLOC(BSIM3QdpPtr, BSIM3qNode, BSIM3dNodePrime);
|
||||||
TSTALLOC(BSIM3QspPtr, BSIM3qNode, BSIM3sNodePrime)
|
TSTALLOC(BSIM3QspPtr, BSIM3qNode, BSIM3sNodePrime);
|
||||||
TSTALLOC(BSIM3QgPtr, BSIM3qNode, BSIM3gNode)
|
TSTALLOC(BSIM3QgPtr, BSIM3qNode, BSIM3gNode);
|
||||||
TSTALLOC(BSIM3QbPtr, BSIM3qNode, BSIM3bNode)
|
TSTALLOC(BSIM3QbPtr, BSIM3qNode, BSIM3bNode);
|
||||||
TSTALLOC(BSIM3DPqPtr, BSIM3dNodePrime, BSIM3qNode)
|
TSTALLOC(BSIM3DPqPtr, BSIM3dNodePrime, BSIM3qNode);
|
||||||
TSTALLOC(BSIM3SPqPtr, BSIM3sNodePrime, BSIM3qNode)
|
TSTALLOC(BSIM3SPqPtr, BSIM3sNodePrime, BSIM3qNode);
|
||||||
TSTALLOC(BSIM3GqPtr, BSIM3gNode, BSIM3qNode)
|
TSTALLOC(BSIM3GqPtr, BSIM3gNode, BSIM3qNode);
|
||||||
TSTALLOC(BSIM3BqPtr, BSIM3bNode, BSIM3qNode)
|
TSTALLOC(BSIM3BqPtr, BSIM3bNode, BSIM3qNode);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -53,6 +53,13 @@ typedef struct sBSIM3instance
|
||||||
double BSIM3sourcePerimeter;
|
double BSIM3sourcePerimeter;
|
||||||
double BSIM3sourceConductance;
|
double BSIM3sourceConductance;
|
||||||
double BSIM3drainConductance;
|
double BSIM3drainConductance;
|
||||||
|
double BSIM3delvto;
|
||||||
|
double BSIM3mulu0;
|
||||||
|
double BSIM3vth0;
|
||||||
|
double BSIM3vfb;
|
||||||
|
double BSIM3vfbzb;
|
||||||
|
double BSIM3u0temp;
|
||||||
|
double BSIM3tconst;
|
||||||
|
|
||||||
double BSIM3icVBS;
|
double BSIM3icVBS;
|
||||||
double BSIM3icVDS;
|
double BSIM3icVDS;
|
||||||
|
|
@ -61,6 +68,7 @@ typedef struct sBSIM3instance
|
||||||
int BSIM3mode;
|
int BSIM3mode;
|
||||||
int BSIM3nqsMod;
|
int BSIM3nqsMod;
|
||||||
int BSIM3acnqsMod;
|
int BSIM3acnqsMod;
|
||||||
|
int BSIM3geo;
|
||||||
|
|
||||||
/* OP point */
|
/* OP point */
|
||||||
double BSIM3qinv;
|
double BSIM3qinv;
|
||||||
|
|
@ -122,6 +130,8 @@ typedef struct sBSIM3instance
|
||||||
unsigned BSIM3sourceSquaresGiven :1;
|
unsigned BSIM3sourceSquaresGiven :1;
|
||||||
unsigned BSIM3drainPerimeterGiven :1;
|
unsigned BSIM3drainPerimeterGiven :1;
|
||||||
unsigned BSIM3sourcePerimeterGiven :1;
|
unsigned BSIM3sourcePerimeterGiven :1;
|
||||||
|
unsigned BSIM3delvtoGiven :1;
|
||||||
|
unsigned BSIM3mulu0Given :1;
|
||||||
unsigned BSIM3dNodePrimeSet :1;
|
unsigned BSIM3dNodePrimeSet :1;
|
||||||
unsigned BSIM3sNodePrimeSet :1;
|
unsigned BSIM3sNodePrimeSet :1;
|
||||||
unsigned BSIM3icVBSGiven :1;
|
unsigned BSIM3icVBSGiven :1;
|
||||||
|
|
@ -129,6 +139,7 @@ typedef struct sBSIM3instance
|
||||||
unsigned BSIM3icVGSGiven :1;
|
unsigned BSIM3icVGSGiven :1;
|
||||||
unsigned BSIM3nqsModGiven :1;
|
unsigned BSIM3nqsModGiven :1;
|
||||||
unsigned BSIM3acnqsModGiven :1;
|
unsigned BSIM3acnqsModGiven :1;
|
||||||
|
unsigned BSIM3geoGiven :1;
|
||||||
|
|
||||||
double *BSIM3DdPtr;
|
double *BSIM3DdPtr;
|
||||||
double *BSIM3GgPtr;
|
double *BSIM3GgPtr;
|
||||||
|
|
@ -430,7 +441,10 @@ typedef struct sBSIM3model
|
||||||
|
|
||||||
int BSIM3mobMod;
|
int BSIM3mobMod;
|
||||||
int BSIM3capMod;
|
int BSIM3capMod;
|
||||||
|
int BSIM3acmMod;
|
||||||
|
int BSIM3calcacm;
|
||||||
int BSIM3noiMod;
|
int BSIM3noiMod;
|
||||||
|
int BSIM3nqsMod;
|
||||||
int BSIM3acnqsMod;
|
int BSIM3acnqsMod;
|
||||||
int BSIM3binUnit;
|
int BSIM3binUnit;
|
||||||
int BSIM3paramChk;
|
int BSIM3paramChk;
|
||||||
|
|
@ -532,6 +546,18 @@ typedef struct sBSIM3model
|
||||||
double BSIM3tpbsw;
|
double BSIM3tpbsw;
|
||||||
double BSIM3tpbswg;
|
double BSIM3tpbswg;
|
||||||
|
|
||||||
|
/* ACM model */
|
||||||
|
double BSIM3xl;
|
||||||
|
double BSIM3xw;
|
||||||
|
double BSIM3hdif;
|
||||||
|
double BSIM3ldif;
|
||||||
|
double BSIM3ld;
|
||||||
|
double BSIM3rd;
|
||||||
|
double BSIM3rs;
|
||||||
|
double BSIM3rdc;
|
||||||
|
double BSIM3rsc;
|
||||||
|
double BSIM3wmlt;
|
||||||
|
|
||||||
/* Length Dependence */
|
/* Length Dependence */
|
||||||
double BSIM3lcdsc;
|
double BSIM3lcdsc;
|
||||||
double BSIM3lcdscb;
|
double BSIM3lcdscb;
|
||||||
|
|
@ -881,8 +907,11 @@ typedef struct sBSIM3model
|
||||||
unsigned BSIM3mobModGiven :1;
|
unsigned BSIM3mobModGiven :1;
|
||||||
unsigned BSIM3binUnitGiven :1;
|
unsigned BSIM3binUnitGiven :1;
|
||||||
unsigned BSIM3capModGiven :1;
|
unsigned BSIM3capModGiven :1;
|
||||||
|
unsigned BSIM3acmModGiven :1;
|
||||||
|
unsigned BSIM3calcacmGiven :1;
|
||||||
unsigned BSIM3paramChkGiven :1;
|
unsigned BSIM3paramChkGiven :1;
|
||||||
unsigned BSIM3noiModGiven :1;
|
unsigned BSIM3noiModGiven :1;
|
||||||
|
unsigned BSIM3nqsModGiven :1;
|
||||||
unsigned BSIM3acnqsModGiven :1;
|
unsigned BSIM3acnqsModGiven :1;
|
||||||
unsigned BSIM3typeGiven :1;
|
unsigned BSIM3typeGiven :1;
|
||||||
unsigned BSIM3toxGiven :1;
|
unsigned BSIM3toxGiven :1;
|
||||||
|
|
@ -983,6 +1012,17 @@ typedef struct sBSIM3model
|
||||||
unsigned BSIM3tpbswGiven :1;
|
unsigned BSIM3tpbswGiven :1;
|
||||||
unsigned BSIM3tpbswgGiven :1;
|
unsigned BSIM3tpbswgGiven :1;
|
||||||
|
|
||||||
|
/* ACM model */
|
||||||
|
unsigned BSIM3xlGiven :1;
|
||||||
|
unsigned BSIM3xwGiven :1;
|
||||||
|
unsigned BSIM3hdifGiven :1;
|
||||||
|
unsigned BSIM3ldifGiven :1;
|
||||||
|
unsigned BSIM3ldGiven :1;
|
||||||
|
unsigned BSIM3rdGiven :1;
|
||||||
|
unsigned BSIM3rsGiven :1;
|
||||||
|
unsigned BSIM3rdcGiven :1;
|
||||||
|
unsigned BSIM3rscGiven :1;
|
||||||
|
unsigned BSIM3wmltGiven :1;
|
||||||
|
|
||||||
/* Length dependence */
|
/* Length dependence */
|
||||||
unsigned BSIM3lcdscGiven :1;
|
unsigned BSIM3lcdscGiven :1;
|
||||||
|
|
@ -1265,7 +1305,7 @@ typedef struct sBSIM3model
|
||||||
unsigned BSIM3bulkJctGateSideGradingCoeffGiven :1;
|
unsigned BSIM3bulkJctGateSideGradingCoeffGiven :1;
|
||||||
unsigned BSIM3unitLengthGateSidewallJctCapGiven :1;
|
unsigned BSIM3unitLengthGateSidewallJctCapGiven :1;
|
||||||
unsigned BSIM3jctEmissionCoeffGiven :1;
|
unsigned BSIM3jctEmissionCoeffGiven :1;
|
||||||
unsigned BSIM3jctTempExponentGiven :1;
|
unsigned BSIM3jctTempExponentGiven :1;
|
||||||
|
|
||||||
unsigned BSIM3oxideTrapDensityAGiven :1;
|
unsigned BSIM3oxideTrapDensityAGiven :1;
|
||||||
unsigned BSIM3oxideTrapDensityBGiven :1;
|
unsigned BSIM3oxideTrapDensityBGiven :1;
|
||||||
|
|
@ -1312,7 +1352,6 @@ typedef struct sBSIM3model
|
||||||
/* device parameters */
|
/* device parameters */
|
||||||
#define BSIM3_W 1
|
#define BSIM3_W 1
|
||||||
#define BSIM3_L 2
|
#define BSIM3_L 2
|
||||||
#define BSIM3_M 16
|
|
||||||
#define BSIM3_AS 3
|
#define BSIM3_AS 3
|
||||||
#define BSIM3_AD 4
|
#define BSIM3_AD 4
|
||||||
#define BSIM3_PS 5
|
#define BSIM3_PS 5
|
||||||
|
|
@ -1326,9 +1365,15 @@ typedef struct sBSIM3model
|
||||||
#define BSIM3_IC 13
|
#define BSIM3_IC 13
|
||||||
#define BSIM3_NQSMOD 14
|
#define BSIM3_NQSMOD 14
|
||||||
#define BSIM3_ACNQSMOD 15
|
#define BSIM3_ACNQSMOD 15
|
||||||
|
#define BSIM3_M 16
|
||||||
|
#define BSIM3_DELVTO 17
|
||||||
|
#define BSIM3_MULU0 18
|
||||||
|
#define BSIM3_GEO 19
|
||||||
|
|
||||||
/* model parameters */
|
/* model parameters */
|
||||||
#define BSIM3_MOD_CAPMOD 101
|
#define BSIM3_MOD_CAPMOD 100
|
||||||
|
#define BSIM3_MOD_ACMMOD 101
|
||||||
|
#define BSIM3_MOD_CALCACM 102
|
||||||
#define BSIM3_MOD_MOBMOD 103
|
#define BSIM3_MOD_MOBMOD 103
|
||||||
#define BSIM3_MOD_NOIMOD 104
|
#define BSIM3_MOD_NOIMOD 104
|
||||||
|
|
||||||
|
|
@ -1440,7 +1485,8 @@ typedef struct sBSIM3model
|
||||||
#define BSIM3_MOD_TPBSWG 207
|
#define BSIM3_MOD_TPBSWG 207
|
||||||
#define BSIM3_MOD_VOFFCV 208
|
#define BSIM3_MOD_VOFFCV 208
|
||||||
#define BSIM3_MOD_LINTNOI 209
|
#define BSIM3_MOD_LINTNOI 209
|
||||||
#define BSIM3_MOD_ACNQSMOD 210
|
#define BSIM3_MOD_NQSMOD 210
|
||||||
|
#define BSIM3_MOD_ACNQSMOD 211
|
||||||
|
|
||||||
/* Length dependence */
|
/* Length dependence */
|
||||||
#define BSIM3_MOD_LCDSC 251
|
#define BSIM3_MOD_LCDSC 251
|
||||||
|
|
@ -1795,6 +1841,18 @@ typedef struct sBSIM3model
|
||||||
#define BSIM3_MOD_WWC 701
|
#define BSIM3_MOD_WWC 701
|
||||||
#define BSIM3_MOD_WWLC 702
|
#define BSIM3_MOD_WWLC 702
|
||||||
|
|
||||||
|
/* ACM parameters */
|
||||||
|
#define BSIM3_MOD_XL 703
|
||||||
|
#define BSIM3_MOD_XW 704
|
||||||
|
#define BSIM3_MOD_HDIF 711
|
||||||
|
#define BSIM3_MOD_LDIF 712
|
||||||
|
#define BSIM3_MOD_LD 713
|
||||||
|
#define BSIM3_MOD_RD 714
|
||||||
|
#define BSIM3_MOD_RS 715
|
||||||
|
#define BSIM3_MOD_RDC 716
|
||||||
|
#define BSIM3_MOD_RSC 717
|
||||||
|
#define BSIM3_MOD_WMLT 718
|
||||||
|
|
||||||
/* device questions */
|
/* device questions */
|
||||||
#define BSIM3_DNODE 751
|
#define BSIM3_DNODE 751
|
||||||
#define BSIM3_GNODE 752
|
#define BSIM3_GNODE 752
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue