Merge remote branch 'origin/new_kirchhoff-3' into KLU-kirchhoff

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_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/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/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/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/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/jfet2/Makefile.am
	src/spicelib/devices/jfet2/jfet2ext.h
	src/spicelib/devices/jfet2/jfet2init.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/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/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/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:
Francesco Lannutti 2013-09-15 15:14:29 +02:00
commit 85e3b90d26
306 changed files with 13309 additions and 9335 deletions

10
INSTALL
View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 \

View File

@ -52,7 +52,7 @@ static struct line *com_options = NULL;
static void cktislinear(CKTcircuit *ckt, struct line *deck); static void cktislinear(CKTcircuit *ckt, 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);
/* /*

File diff suppressed because it is too large Load Diff

View File

@ -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:

View File

@ -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 */

View File

@ -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;

View File

@ -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);

View File

@ -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,14 @@ 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 */
int *CKTvoltCurNode ; /* Flag to indicate if a node contains some direct unknown currents */
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 +303,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 *);
@ -387,10 +405,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 *);

View File

@ -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 "/"

View File

@ -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 */

View File

@ -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 */

View File

@ -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

View File

@ -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* );

View File

@ -15,6 +15,7 @@ Author: 1985 Thomas L. Quarles
#include "ngspice/smpdefs.h" #include "ngspice/smpdefs.h"
int int
NIconvTest(CKTcircuit *ckt) NIconvTest(CKTcircuit *ckt)
{ {
@ -25,8 +26,19 @@ NIconvTest(CKTcircuit *ckt)
double new; double new;
double tol; double tol;
node = ckt->CKTnodes; #ifdef KIRCHHOFF
#ifdef STEPDEBUG
int j ;
#endif
double maximum ;
CKTmkCurKCLnode *ptr ;
#endif
size = SMPmatSize(ckt->CKTmatrix); size = SMPmatSize(ckt->CKTmatrix);
node = ckt->CKTnodes;
#ifdef STEPDEBUG #ifdef STEPDEBUG
for (i=1;i<=size;i++) { for (i=1;i<=size;i++) {
new = ckt->CKTrhs [i] ; new = ckt->CKTrhs [i] ;
@ -34,6 +46,7 @@ NIconvTest(CKTcircuit *ckt)
printf("chk for convergence: %s new: %g old: %g\n",CKTnodName(ckt,i),new,old); printf("chk for convergence: %s new: %g old: %g\n",CKTnodName(ckt,i),new,old);
} }
#endif /* STEPDEBUG */ #endif /* STEPDEBUG */
for (i=1;i<=size;i++) { for (i=1;i<=size;i++) {
node = node->next; node = node->next;
new = ckt->CKTrhs [i] ; new = ckt->CKTrhs [i] ;
@ -42,26 +55,66 @@ NIconvTest(CKTcircuit *ckt)
tol = ckt->CKTreltol * (MAX(fabs(old),fabs(new))) + tol = ckt->CKTreltol * (MAX(fabs(old),fabs(new))) +
ckt->CKTvoltTol; ckt->CKTvoltTol;
if (fabs(new-old) >tol ) { if (fabs(new-old) >tol ) {
#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); printf(" non-convergence at node (type=3) %s (fabs(new-old)>tol --> fabs(%g-%g)>%g)\n",CKTnodName(ckt,i),new,old,tol);
printf(" reltol: %g voltTol: %g (tol=reltol*(MAX(fabs(old),fabs(new))) + voltTol)\n",ckt->CKTreltol,ckt->CKTvoltTol); printf(" 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->CKTtroubleNode = i;
ckt->CKTtroubleElt = NULL; ckt->CKTtroubleElt = NULL;
return(1); return(1);
} }
#ifndef KIRCHHOFF
} 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); 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);
printf(" reltol: %g abstol: %g (tol=reltol*(MAX(fabs(old),fabs(new))) + abstol)\n",ckt->CKTreltol,ckt->CKTabstol); printf(" 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->CKTtroubleNode = i;
ckt->CKTtroubleElt = NULL; ckt->CKTtroubleElt = NULL;
return(1); return(1);
} }
#else
/* KCL Verification */
}
if ((node->type == SP_VOLTAGE) && (!ckt->CKTnodeIsLinear [i]) && (ckt->CKTvoltCurNode [i]))
{
maximum = 0 ;
ptr = ckt->CKTmkCurKCLarray [i] ;
#ifdef STEPDEBUG
j = 0 ;
#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
if (fabs (ckt->CKTfvk [i]) > (ckt->CKTreltol * maximum + ckt->CKTabstol))
return 1 ;
#endif
} }
} }

View File

@ -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,20 @@ 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(CKTvoltCurNode,size+1,int);
for (i = 0 ; i <= size ; i++)
ckt->CKTvoltCurNode [i] = 0 ;
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++) {

View File

@ -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;
} }

View File

@ -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)
{ {

View File

@ -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. */

View File

@ -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;

View File

@ -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 );
} }
/* /*

View File

@ -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;

View File

@ -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);
} }

View File

@ -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 */
@ -244,7 +249,6 @@ 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;
/*helper function*//* /*helper function*//*
static struct plot * static struct plot *
@ -293,12 +297,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 +332,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 +382,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 +403,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 +431,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 +492,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)
@ -479,7 +502,7 @@ ngSpice_running (void)
#endif #endif
/* 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 +601,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 +647,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 +665,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 +686,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 +694,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 +745,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 +771,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 +795,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)
{ {
@ -809,8 +833,8 @@ char** ngSpice_AllVecs(char* plotname)
/* 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 +913,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 +927,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 +946,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 +1001,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 +1091,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 +1214,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 +1227,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 +1240,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,7 +1282,7 @@ 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 */
@ -1323,8 +1354,8 @@ void SetAnalyse(
tfree(s); tfree(s);
} }
/* 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),
@ -1448,7 +1479,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 +1487,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 +1510,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 +1568,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) {

View File

@ -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

View File

@ -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
}; };

View File

@ -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

View File

@ -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) ;
}

View File

@ -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);
} }

View File

@ -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 */
@ -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;

View File

@ -78,9 +78,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;
@ -316,7 +315,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;
} }
@ -479,9 +481,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 +507,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,6 +545,10 @@ 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");
@ -792,7 +795,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 +858,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;
} }

View File

@ -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");
@ -450,7 +451,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 +459,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;

View File

@ -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;

View File

@ -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

View File

@ -16,3 +16,4 @@ 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*);
extern int ASRCnodeIsNonLinear (GENmodel *, CKTcircuit *) ;

View File

@ -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
}; };

View File

@ -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) ;
}

View File

@ -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)

View File

@ -31,6 +31,7 @@ extern int BJTtrunc(GENmodel*,CKTcircuit*,double*);
extern int BJTdisto(int,GENmodel*,CKTcircuit*); 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*);
extern int BJTnodeIsNonLinear (GENmodel *, CKTcircuit *) ;
#endif #endif

View File

@ -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
}; };

View File

@ -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) ;
}

View File

@ -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 */

View File

@ -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);

View File

@ -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)

View File

@ -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) ;
}

View File

@ -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

View File

@ -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
}; };

View File

@ -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)

View File

@ -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: ;

View File

@ -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) ;
}

View File

@ -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

View File

@ -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
}; };

View File

@ -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)

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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) ;
}

View File

@ -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:

View File

@ -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");

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -34,3 +34,7 @@ extern int BSIM3bindCSC (GENmodel*, CKTcircuit*) ;
extern int BSIM3bindCSCComplex (GENmodel*, CKTcircuit*) ; extern int BSIM3bindCSCComplex (GENmodel*, CKTcircuit*) ;
extern int BSIM3bindCSCComplexToReal (GENmodel*, CKTcircuit*) ; extern int BSIM3bindCSCComplexToReal (GENmodel*, CKTcircuit*) ;
#endif #endif
#ifdef KIRCHHOFF
extern int BSIM3nodeIsNonLinear (GENmodel *, CKTcircuit *) ;
#endif

View File

@ -72,12 +72,17 @@ SPICEdev BSIM3info = {
#endif #endif
/* DEVinstSize */ &BSIM3iSize, /* DEVinstSize */ &BSIM3iSize,
/* DEVmodSize */ &BSIM3mSize, /* DEVmodSize */ &BSIM3mSize,
#if defined(KLU) || defined(SuperLU) || defined(UMFPACK) #if defined(KLU) || defined(SuperLU) || defined(UMFPACK)
/* DEVbindCSC */ BSIM3bindCSC, /* DEVbindCSC */ BSIM3bindCSC,
/* DEVbindCSCComplex */ BSIM3bindCSCComplex, /* DEVbindCSCComplex */ BSIM3bindCSCComplex,
/* DEVbindCSCComplexToReal */ BSIM3bindCSCComplexToReal, /* DEVbindCSCComplexToReal */ BSIM3bindCSCComplexToReal,
#endif #endif
#ifdef KIRCHHOFF
/* DEVnodeIsNonLinear */ BSIM3nodeIsNonLinear
#endif
}; };

View File

@ -2,29 +2,29 @@
noinst_LTLIBRARIES = libbsim3soidd.la noinst_LTLIBRARIES = libbsim3soidd.la
libbsim3soidd_la_SOURCES = \ libbsim3soidd_la_SOURCES = \
b3soidd.c \ b3soidd.c \
b3soiddacld.c \ b3soiddacld.c \
b3soiddask.c \ b3soiddask.c \
b3soiddcheck.c \ b3soiddcheck.c \
b3soiddcvtest.c \ b3soiddcvtest.c \
b3soidddel.c \ b3soidddel.c \
b3soidddest.c \ b3soidddest.c \
b3soiddgetic.c \ b3soiddgetic.c \
b3soiddld.c \ b3soiddld.c \
b3soiddmask.c \ b3soiddmask.c \
b3soiddmdel.c \ b3soiddmdel.c \
b3soiddmpar.c \ b3soiddmpar.c \
b3soiddnoi.c \ b3soiddnoi.c \
b3soiddpar.c \ b3soiddpar.c \
b3soiddpzld.c \ b3soiddpzld.c \
b3soiddset.c \ b3soiddset.c \
b3soiddtemp.c \ b3soiddtemp.c \
b3soiddtrunc.c \ b3soiddtrunc.c \
b3soidddef.h \ b3soidddef.h \
b3soiddext.h \ b3soiddext.h \
b3soiddinit.c \ b3soiddinit.c \
b3soiddinit.h \ b3soiddinit.h \
b3soidditf.h b3soidditf.h
@ -40,6 +40,10 @@ if UMFPACK_WANTED
libbsim3soidd_la_SOURCES += b3soiddbindCSC.c libbsim3soidd_la_SOURCES += b3soiddbindCSC.c
endif endif
if KIRCHHOFF_WANTED
libbsim3soidd_la_SOURCES += b3soiddnode.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)

View File

@ -34,3 +34,7 @@ extern int B3SOIDDbindCSC (GENmodel*, CKTcircuit*) ;
extern int B3SOIDDbindCSCComplex (GENmodel*, CKTcircuit*) ; extern int B3SOIDDbindCSCComplex (GENmodel*, CKTcircuit*) ;
extern int B3SOIDDbindCSCComplexToReal (GENmodel*, CKTcircuit*) ; extern int B3SOIDDbindCSCComplexToReal (GENmodel*, CKTcircuit*) ;
#endif #endif
#ifdef KIRCHHOFF
extern int B3SOIDDnodeIsNonLinear (GENmodel *, CKTcircuit *) ;
#endif

View File

@ -70,12 +70,17 @@ SPICEdev B3SOIDDinfo = {
#endif #endif
/* DEVinstSize */ &B3SOIDDiSize, /* DEVinstSize */ &B3SOIDDiSize,
/* DEVmodSize */ &B3SOIDDmSize, /* DEVmodSize */ &B3SOIDDmSize,
#if defined(KLU) || defined(SuperLU) || defined(UMFPACK) #if defined(KLU) || defined(SuperLU) || defined(UMFPACK)
/* DEVbindCSC */ B3SOIDDbindCSC, /* DEVbindCSC */ B3SOIDDbindCSC,
/* DEVbindCSCComplex */ B3SOIDDbindCSCComplex, /* DEVbindCSCComplex */ B3SOIDDbindCSCComplex,
/* DEVbindCSCComplexToReal */ B3SOIDDbindCSCComplexToReal, /* DEVbindCSCComplexToReal */ B3SOIDDbindCSCComplexToReal,
#endif #endif
#ifdef KIRCHHOFF
/* DEVnodeIsNonLinear */ B3SOIDDnodeIsNonLinear
#endif
}; };
SPICEdev * SPICEdev *

View File

@ -0,0 +1,79 @@
/**********
Author: 2013 Francesco Lannutti
**********/
#include "ngspice/ngspice.h"
#include "ngspice/cktdefs.h"
#include "b3soidddef.h"
#include "ngspice/sperror.h"
int
B3SOIDDnodeIsNonLinear (GENmodel *inModel, CKTcircuit *ckt)
{
B3SOIDDmodel *model = (B3SOIDDmodel *)inModel ;
B3SOIDDinstance *here ;
/* loop through all the B3SOIDD models */
for ( ; model != NULL ; model = model->B3SOIDDnextModel)
{
/* loop through all the instances of the model */
for (here = model->B3SOIDDinstances ; here != NULL ; here = here->B3SOIDDnextInstance)
{
ckt->CKTnodeIsLinear [here->B3SOIDDdNodePrime] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIDDsNodePrime] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIDDbNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIDDtempNode] = 0 ;
if ((here->B3SOIDDdebugMod > 1) || (here->B3SOIDDdebugMod == -1))
{
ckt->CKTnodeIsLinear [here->B3SOIDDvbsNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIDDidsNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIDDicNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIDDibsNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIDDibdNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIDDiiiNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIDDigidlNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIDDitunNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIDDibpNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIDDabeffNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIDDvbs0effNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIDDvbseffNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIDDxcNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIDDcbbNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIDDcbdNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIDDcbgNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIDDqbNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIDDqbfNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIDDqjsNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIDDqjdNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIDDgmNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIDDgmbsNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIDDgdsNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIDDgmeNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIDDvbs0teffNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIDDvthNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIDDvgsteffNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIDDxcsatNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIDDqaccNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIDDqsub0Node] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIDDqsubs1Node] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIDDqsubs2Node] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIDDqeNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIDDqdNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIDDqgNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIDDvdscvNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIDDvcscvNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIDDcbeNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIDDdum1Node] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIDDdum2Node] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIDDdum3Node] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIDDdum4Node] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIDDdum5Node] = 0 ;
}
ckt->CKTnodeIsLinear [here->B3SOIDDgNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIDDeNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIDDpNode] = 0 ;
}
}
return (OK) ;
}

View File

@ -2,29 +2,29 @@
noinst_LTLIBRARIES = libbsim3soifd.la noinst_LTLIBRARIES = libbsim3soifd.la
libbsim3soifd_la_SOURCES = \ libbsim3soifd_la_SOURCES = \
b3soifd.c \ b3soifd.c \
b3soifdacld.c \ b3soifdacld.c \
b3soifdask.c \ b3soifdask.c \
b3soifdcheck.c \ b3soifdcheck.c \
b3soifdcvtest.c \ b3soifdcvtest.c \
b3soifddel.c \ b3soifddel.c \
b3soifddest.c \ b3soifddest.c \
b3soifdgetic.c \ b3soifdgetic.c \
b3soifdld.c \ b3soifdld.c \
b3soifdmask.c \ b3soifdmask.c \
b3soifdmdel.c \ b3soifdmdel.c \
b3soifdmpar.c \ b3soifdmpar.c \
b3soifdnoi.c \ b3soifdnoi.c \
b3soifdpar.c \ b3soifdpar.c \
b3soifdpzld.c \ b3soifdpzld.c \
b3soifdset.c \ b3soifdset.c \
b3soifdtemp.c \ b3soifdtemp.c \
b3soifdtrunc.c \ b3soifdtrunc.c \
b3soifddef.h \ b3soifddef.h \
b3soifdext.h \ b3soifdext.h \
b3soifdinit.c \ b3soifdinit.c \
b3soifdinit.h \ b3soifdinit.h \
b3soifditf.h b3soifditf.h
@ -40,6 +40,10 @@ if UMFPACK_WANTED
libbsim3soifd_la_SOURCES += b3soifdbindCSC.c libbsim3soifd_la_SOURCES += b3soifdbindCSC.c
endif endif
if KIRCHHOFF_WANTED
libbsim3soifd_la_SOURCES += b3soifdnode.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)

View File

@ -29,9 +29,12 @@ extern int B3SOIFDtrunc(GENmodel*,CKTcircuit*,double*);
extern int B3SOIFDnoise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*); extern int B3SOIFDnoise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*);
extern int B3SOIFDunsetup(GENmodel*,CKTcircuit*); extern int B3SOIFDunsetup(GENmodel*,CKTcircuit*);
#if defined(KLU) || defined(SuperLU) || defined(UMFPACK) #if defined(KLU) || defined(SuperLU) || defined(UMFPACK)
extern int B3SOIFDbindCSC (GENmodel*, CKTcircuit*) ; extern int B3SOIFDbindCSC (GENmodel*, CKTcircuit*) ;
extern int B3SOIFDbindCSCComplex (GENmodel*, CKTcircuit*) ; extern int B3SOIFDbindCSCComplex (GENmodel*, CKTcircuit*) ;
extern int B3SOIFDbindCSCComplexToReal (GENmodel*, CKTcircuit*) ; extern int B3SOIFDbindCSCComplexToReal (GENmodel*, CKTcircuit*) ;
#endif #endif
#ifdef KIRCHHOFF
extern int B3SOIFDnodeIsNonLinear (GENmodel *, CKTcircuit *) ;
#endif

View File

@ -71,12 +71,17 @@ SPICEdev B3SOIFDinfo = {
#endif #endif
/* DEVinstSize*/ &B3SOIFDiSize, /* DEVinstSize*/ &B3SOIFDiSize,
/* DEVmodSize*/ &B3SOIFDmSize, /* DEVmodSize*/ &B3SOIFDmSize,
#if defined(KLU) || defined(SuperLU) || defined(UMFPACK) #if defined(KLU) || defined(SuperLU) || defined(UMFPACK)
/* DEVbindCSC */ B3SOIFDbindCSC, /* DEVbindCSC */ B3SOIFDbindCSC,
/* DEVbindCSCComplex */ B3SOIFDbindCSCComplex, /* DEVbindCSCComplex */ B3SOIFDbindCSCComplex,
/* DEVbindCSCComplexToReal */ B3SOIFDbindCSCComplexToReal, /* DEVbindCSCComplexToReal */ B3SOIFDbindCSCComplexToReal,
#endif #endif
#ifdef KIRCHHOFF
/* DEVnodeIsNonLinear */ B3SOIFDnodeIsNonLinear
#endif
}; };

View File

@ -0,0 +1,79 @@
/**********
Author: 2013 Francesco Lannutti
**********/
#include "ngspice/ngspice.h"
#include "ngspice/cktdefs.h"
#include "b3soifddef.h"
#include "ngspice/sperror.h"
int
B3SOIFDnodeIsNonLinear (GENmodel *inModel, CKTcircuit *ckt)
{
B3SOIFDmodel *model = (B3SOIFDmodel *)inModel ;
B3SOIFDinstance *here ;
/* loop through all the B3SOIFD models */
for ( ; model != NULL ; model = model->B3SOIFDnextModel)
{
/* loop through all the instances of the model */
for (here = model->B3SOIFDinstances ; here != NULL ; here = here->B3SOIFDnextInstance)
{
ckt->CKTnodeIsLinear [here->B3SOIFDdNodePrime] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIFDsNodePrime] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIFDbNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIFDtempNode] = 0 ;
if ((here->B3SOIFDdebugMod > 1) || (here->B3SOIFDdebugMod == -1))
{
ckt->CKTnodeIsLinear [here->B3SOIFDvbsNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIFDidsNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIFDicNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIFDibsNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIFDibdNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIFDiiiNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIFDigidlNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIFDitunNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIFDibpNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIFDabeffNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIFDvbs0effNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIFDvbseffNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIFDxcNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIFDcbbNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIFDcbdNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIFDcbgNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIFDqbNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIFDqbfNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIFDqjsNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIFDqjdNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIFDgmNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIFDgmbsNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIFDgdsNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIFDgmeNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIFDvbs0teffNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIFDvthNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIFDvgsteffNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIFDxcsatNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIFDqaccNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIFDqsub0Node] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIFDqsubs1Node] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIFDqsubs2Node] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIFDqeNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIFDqdNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIFDqgNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIFDvdscvNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIFDvcscvNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIFDcbeNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIFDdum1Node] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIFDdum2Node] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIFDdum3Node] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIFDdum4Node] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIFDdum5Node] = 0 ;
}
ckt->CKTnodeIsLinear [here->B3SOIFDgNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIFDeNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIFDpNode] = 0 ;
}
}
return (OK) ;
}

View File

@ -2,29 +2,29 @@
noinst_LTLIBRARIES = libbsim3soipd.la noinst_LTLIBRARIES = libbsim3soipd.la
libbsim3soipd_la_SOURCES = \ libbsim3soipd_la_SOURCES = \
b3soipd.c \ b3soipd.c \
b3soipdacld.c \ b3soipdacld.c \
b3soipdask.c \ b3soipdask.c \
b3soipdcheck.c \ b3soipdcheck.c \
b3soipdcvtest.c \ b3soipdcvtest.c \
b3soipddel.c \ b3soipddel.c \
b3soipddest.c \ b3soipddest.c \
b3soipdgetic.c \ b3soipdgetic.c \
b3soipdld.c \ b3soipdld.c \
b3soipdmask.c \ b3soipdmask.c \
b3soipdmdel.c \ b3soipdmdel.c \
b3soipdmpar.c \ b3soipdmpar.c \
b3soipdnoi.c \ b3soipdnoi.c \
b3soipdpar.c \ b3soipdpar.c \
b3soipdpzld.c \ b3soipdpzld.c \
b3soipdset.c \ b3soipdset.c \
b3soipdtemp.c \ b3soipdtemp.c \
b3soipdtrunc.c \ b3soipdtrunc.c \
b3soipddef.h \ b3soipddef.h \
b3soipdext.h \ b3soipdext.h \
b3soipdinit.c \ b3soipdinit.c \
b3soipdinit.h \ b3soipdinit.h \
b3soipditf.h b3soipditf.h
@ -40,6 +40,10 @@ if UMFPACK_WANTED
libbsim3soipd_la_SOURCES += b3soipdbindCSC.c libbsim3soipd_la_SOURCES += b3soipdbindCSC.c
endif endif
if KIRCHHOFF_WANTED
libbsim3soipd_la_SOURCES += b3soipdnode.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)

View File

@ -34,3 +34,7 @@ extern int B3SOIPDbindCSC (GENmodel*, CKTcircuit*) ;
extern int B3SOIPDbindCSCComplex (GENmodel*, CKTcircuit*) ; extern int B3SOIPDbindCSCComplex (GENmodel*, CKTcircuit*) ;
extern int B3SOIPDbindCSCComplexToReal (GENmodel*, CKTcircuit*) ; extern int B3SOIPDbindCSCComplexToReal (GENmodel*, CKTcircuit*) ;
#endif #endif
#ifdef KIRCHHOFF
extern int B3SOIPDnodeIsNonLinear (GENmodel *, CKTcircuit *) ;
#endif

View File

@ -72,12 +72,17 @@ SPICEdev B3SOIPDinfo = {
#endif #endif
/* DEVinstSize*/ &B3SOIPDiSize, /* DEVinstSize*/ &B3SOIPDiSize,
/* DEVmodSize*/ &B3SOIPDmSize, /* DEVmodSize*/ &B3SOIPDmSize,
#if defined(KLU) || defined(SuperLU) || defined(UMFPACK) #if defined(KLU) || defined(SuperLU) || defined(UMFPACK)
/* DEVbindCSC */ B3SOIPDbindCSC, /* DEVbindCSC */ B3SOIPDbindCSC,
/* DEVbindCSCComplex */ B3SOIPDbindCSCComplex, /* DEVbindCSCComplex */ B3SOIPDbindCSCComplex,
/* DEVbindCSCComplexToReal */ B3SOIPDbindCSCComplexToReal, /* DEVbindCSCComplexToReal */ B3SOIPDbindCSCComplexToReal,
#endif #endif
#ifdef KIRCHHOFF
/* DEVnodeIsNonLinear */ B3SOIPDnodeIsNonLinear
#endif
}; };
SPICEdev * SPICEdev *

View File

@ -0,0 +1,55 @@
/**********
Author: 2013 Francesco Lannutti
**********/
#include "ngspice/ngspice.h"
#include "ngspice/cktdefs.h"
#include "b3soipddef.h"
#include "ngspice/sperror.h"
int
B3SOIPDnodeIsNonLinear (GENmodel *inModel, CKTcircuit *ckt)
{
B3SOIPDmodel *model = (B3SOIPDmodel *)inModel ;
B3SOIPDinstance *here ;
/* loop through all the B3SOIPD models */
for ( ; model != NULL ; model = model->B3SOIPDnextModel)
{
/* loop through all the instances of the model */
for (here = model->B3SOIPDinstances ; here != NULL ; here = here->B3SOIPDnextInstance)
{
ckt->CKTnodeIsLinear [here->B3SOIPDdNodePrime] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIPDsNodePrime] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIPDbNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIPDtempNode] = 0 ;
if (here->B3SOIPDdebugMod != 0)
{
ckt->CKTnodeIsLinear [here->B3SOIPDvbsNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIPDidsNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIPDicNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIPDibsNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIPDibdNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIPDiiiNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIPDigNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIPDgiggNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIPDgigdNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIPDgigbNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIPDigidlNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIPDitunNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIPDibpNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIPDcbbNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIPDcbdNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIPDcbgNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIPDqbfNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIPDqjsNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIPDqjdNode] = 0 ;
}
ckt->CKTnodeIsLinear [here->B3SOIPDgNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIPDeNode] = 0 ;
ckt->CKTnodeIsLinear [here->B3SOIPDpNode] = 0 ;
}
}
return (OK) ;
}

View File

@ -39,6 +39,10 @@ if UMFPACK_WANTED
libbsim3v0_la_SOURCES += b3v0bindCSC.c libbsim3v0_la_SOURCES += b3v0bindCSC.c
endif endif
if KIRCHHOFF_WANTED
libbsim3v0_la_SOURCES += b3v0node.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)

View File

@ -0,0 +1,31 @@
/**********
Author: 2013 Francesco Lannutti
**********/
#include "ngspice/ngspice.h"
#include "ngspice/cktdefs.h"
#include "bsim3v0def.h"
#include "ngspice/sperror.h"
int
BSIM3v0nodeIsNonLinear (GENmodel *inModel, CKTcircuit *ckt)
{
BSIM3v0model *model = (BSIM3v0model *)inModel ;
BSIM3v0instance *here ;
/* loop through all the BSIM3v0 models */
for ( ; model != NULL ; model = model->BSIM3v0nextModel)
{
/* loop through all the instances of the model */
for (here = model->BSIM3v0instances ; here != NULL ; here = here->BSIM3v0nextInstance)
{
ckt->CKTnodeIsLinear [here->BSIM3v0dNodePrime] = 0 ;
ckt->CKTnodeIsLinear [here->BSIM3v0sNodePrime] = 0 ;
ckt->CKTnodeIsLinear [here->BSIM3v0qNode] = 0 ;
ckt->CKTnodeIsLinear [here->BSIM3v0gNode] = 0 ;
ckt->CKTnodeIsLinear [here->BSIM3v0bNode] = 0 ;
}
}
return (OK) ;
}

View File

@ -26,11 +26,14 @@ extern int BSIM3v0setup(SMPmatrix*,GENmodel*,CKTcircuit*,int*);
extern int BSIM3v0temp(GENmodel*,CKTcircuit*); extern int BSIM3v0temp(GENmodel*,CKTcircuit*);
extern int BSIM3v0trunc(GENmodel*,CKTcircuit*,double*); extern int BSIM3v0trunc(GENmodel*,CKTcircuit*,double*);
extern int BSIM3v0noise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*); extern int BSIM3v0noise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*);
extern int BSIM3v0unsetup(GENmodel *, CKTcircuit *); extern int BSIM3v0unsetup(GENmodel *, CKTcircuit *);
#if defined(KLU) || defined(SuperLU) || defined(UMFPACK) #if defined(KLU) || defined(SuperLU) || defined(UMFPACK)
extern int BSIM3v0bindCSC (GENmodel*, CKTcircuit*) ; extern int BSIM3v0bindCSC (GENmodel*, CKTcircuit*) ;
extern int BSIM3v0bindCSCComplex (GENmodel*, CKTcircuit*) ; extern int BSIM3v0bindCSCComplex (GENmodel*, CKTcircuit*) ;
extern int BSIM3v0bindCSCComplexToReal (GENmodel*, CKTcircuit*) ; extern int BSIM3v0bindCSCComplexToReal (GENmodel*, CKTcircuit*) ;
#endif #endif
#ifdef KIRCHHOFF
extern int BSIM3v0nodeIsNonLinear (GENmodel *, CKTcircuit *) ;
#endif

View File

@ -71,12 +71,17 @@ SPICEdev B3v0info = {
#endif #endif
/* DEVinstSize */ &BSIM3v0iSize, /* DEVinstSize */ &BSIM3v0iSize,
/* DEVmodSize */ &BSIM3v0mSize, /* DEVmodSize */ &BSIM3v0mSize,
#if defined(KLU) || defined(SuperLU) || defined(UMFPACK) #if defined(KLU) || defined(SuperLU) || defined(UMFPACK)
/* DEVbindCSC */ BSIM3v0bindCSC, /* DEVbindCSC */ BSIM3v0bindCSC,
/* DEVbindCSCComplex */ BSIM3v0bindCSCComplex, /* DEVbindCSCComplex */ BSIM3v0bindCSCComplex,
/* DEVbindCSCComplexToReal */ BSIM3v0bindCSCComplexToReal, /* DEVbindCSCComplexToReal */ BSIM3v0bindCSCComplexToReal,
#endif #endif
#ifdef KIRCHHOFF
/* DEVnodeIsNonLinear */ BSIM3v0nodeIsNonLinear
#endif
}; };

View File

@ -40,6 +40,10 @@ if UMFPACK_WANTED
libbsim3v1_la_SOURCES += b3v1bindCSC.c libbsim3v1_la_SOURCES += b3v1bindCSC.c
endif endif
if KIRCHHOFF_WANTED
libbsim3v1_la_SOURCES += b3v1node.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)

View File

@ -0,0 +1,31 @@
/**********
Author: 2013 Francesco Lannutti
**********/
#include "ngspice/ngspice.h"
#include "ngspice/cktdefs.h"
#include "bsim3v1def.h"
#include "ngspice/sperror.h"
int
BSIM3v1nodeIsNonLinear (GENmodel *inModel, CKTcircuit *ckt)
{
BSIM3v1model *model = (BSIM3v1model *)inModel ;
BSIM3v1instance *here ;
/* loop through all the BSIM3v1 models */
for ( ; model != NULL ; model = model->BSIM3v1nextModel)
{
/* loop through all the instances of the model */
for (here = model->BSIM3v1instances ; here != NULL ; here = here->BSIM3v1nextInstance)
{
ckt->CKTnodeIsLinear [here->BSIM3v1dNodePrime] = 0 ;
ckt->CKTnodeIsLinear [here->BSIM3v1sNodePrime] = 0 ;
ckt->CKTnodeIsLinear [here->BSIM3v1qNode] = 0 ;
ckt->CKTnodeIsLinear [here->BSIM3v1gNode] = 0 ;
ckt->CKTnodeIsLinear [here->BSIM3v1bNode] = 0 ;
}
}
return (OK) ;
}

View File

@ -29,9 +29,12 @@ extern int BSIM3v1trunc(GENmodel *, CKTcircuit *, double *);
extern int BSIM3v1noise(int, int, GENmodel *, CKTcircuit *, Ndata *, double *); extern int BSIM3v1noise(int, int, GENmodel *, CKTcircuit *, Ndata *, double *);
extern int BSIM3v1unsetup(GENmodel *, CKTcircuit *); extern int BSIM3v1unsetup(GENmodel *, CKTcircuit *);
#if defined(KLU) || defined(SuperLU) || defined(UMFPACK) #if defined(KLU) || defined(SuperLU) || defined(UMFPACK)
extern int BSIM3v1bindCSC (GENmodel*, CKTcircuit*) ; extern int BSIM3v1bindCSC (GENmodel*, CKTcircuit*) ;
extern int BSIM3v1bindCSCComplex (GENmodel*, CKTcircuit*) ; extern int BSIM3v1bindCSCComplex (GENmodel*, CKTcircuit*) ;
extern int BSIM3v1bindCSCComplexToReal (GENmodel*, CKTcircuit*) ; extern int BSIM3v1bindCSCComplexToReal (GENmodel*, CKTcircuit*) ;
#endif #endif
#ifdef KIRCHHOFF
extern int BSIM3v1nodeIsNonLinear (GENmodel *, CKTcircuit *) ;
#endif

View File

@ -71,12 +71,17 @@ SPICEdev BSIM3v1info = {
#endif #endif
/* DEVinstSize */ &BSIM3v1iSize, /* DEVinstSize */ &BSIM3v1iSize,
/* DEVmodSize */ &BSIM3v1mSize, /* DEVmodSize */ &BSIM3v1mSize,
#if defined(KLU) || defined(SuperLU) || defined(UMFPACK) #if defined(KLU) || defined(SuperLU) || defined(UMFPACK)
/* DEVbindCSC */ BSIM3v1bindCSC, /* DEVbindCSC */ BSIM3v1bindCSC,
/* DEVbindCSCComplex */ BSIM3v1bindCSCComplex, /* DEVbindCSCComplex */ BSIM3v1bindCSCComplex,
/* DEVbindCSCComplexToReal */ BSIM3v1bindCSCComplexToReal, /* DEVbindCSCComplexToReal */ BSIM3v1bindCSCComplexToReal,
#endif #endif
#ifdef KIRCHHOFF
/* DEVnodeIsNonLinear */ BSIM3v1nodeIsNonLinear
#endif
}; };

View File

@ -40,6 +40,10 @@ if UMFPACK_WANTED
libbsim3v32_la_SOURCES += b3v32bindCSC.c libbsim3v32_la_SOURCES += b3v32bindCSC.c
endif endif
if KIRCHHOFF_WANTED
libbsim3v32_la_SOURCES += b3v32node.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)

View File

@ -26,6 +26,7 @@ IOP( "nrd", BSIM3v32_NRD, IF_REAL , "Number of squares in drain"),
IOP( "nrs", BSIM3v32_NRS, IF_REAL , "Number of squares in source"), IOP( "nrs", BSIM3v32_NRS, IF_REAL , "Number of squares in source"),
IOP( "off", BSIM3v32_OFF, IF_FLAG , "Device is initially off"), IOP( "off", BSIM3v32_OFF, IF_FLAG , "Device is initially off"),
IOP( "nqsmod", BSIM3v32_NQSMOD, IF_INTEGER, "Non-quasi-static model selector"), IOP( "nqsmod", BSIM3v32_NQSMOD, IF_INTEGER, "Non-quasi-static model selector"),
IOP( "geo", BSIM3v32_GEO, IF_INTEGER, "ACM model drain/source connection"),
IOP( "delvto", BSIM3v32_DELVTO, IF_REAL , "Zero bias threshold voltage variation"), IOP( "delvto", BSIM3v32_DELVTO, IF_REAL , "Zero bias threshold voltage variation"),
IOP( "mulu0", BSIM3v32_MULU0, IF_REAL , "Low field mobility multiplier"), IOP( "mulu0", BSIM3v32_MULU0, IF_REAL , "Low field mobility multiplier"),
IP( "ic", BSIM3v32_IC, IF_REALVEC , "Vector of DS,GS,BS initial voltages"), IP( "ic", BSIM3v32_IC, IF_REALVEC , "Vector of DS,GS,BS initial voltages"),
@ -65,7 +66,9 @@ IFparm BSIM3v32mPTable[] = { /* model parameters */
IOP( "capmod", BSIM3v32_MOD_CAPMOD, IF_INTEGER, "Capacitance model selector"), IOP( "capmod", BSIM3v32_MOD_CAPMOD, IF_INTEGER, "Capacitance model selector"),
IOP( "mobmod", BSIM3v32_MOD_MOBMOD, IF_INTEGER, "Mobility model selector"), IOP( "mobmod", BSIM3v32_MOD_MOBMOD, IF_INTEGER, "Mobility model selector"),
IOP( "noimod", BSIM3v32_MOD_NOIMOD, IF_INTEGER, "Noise model selector"), IOP( "noimod", BSIM3v32_MOD_NOIMOD, IF_INTEGER, "Noise model selector"),
IOP( "nqsmod", BSIM3v32_MOD_NQSMOD, IF_INTEGER, "Non-quasi-static model selector"),
IOP( "acm", BSIM3v32_MOD_ACMMOD, IF_INTEGER, "Area calculation method selector"), IOP( "acm", BSIM3v32_MOD_ACMMOD, IF_INTEGER, "Area calculation method selector"),
IOP( "calcacm", BSIM3v32_MOD_CALCACM, IF_INTEGER, "Area calculation method ACM=12"),
IOP( "paramchk", BSIM3v32_MOD_PARAMCHK, IF_INTEGER, "Model parameter checking selector"), IOP( "paramchk", BSIM3v32_MOD_PARAMCHK, IF_INTEGER, "Model parameter checking selector"),
IOP( "binunit", BSIM3v32_MOD_BINUNIT, IF_INTEGER, "Bin unit selector"), IOP( "binunit", BSIM3v32_MOD_BINUNIT, IF_INTEGER, "Bin unit selector"),
IOP( "version", BSIM3v32_MOD_VERSION, IF_STRING, " parameter for model version"), IOP( "version", BSIM3v32_MOD_VERSION, IF_STRING, " parameter for model version"),
@ -218,8 +221,9 @@ IOP( "ldif", BSIM3v32_MOD_LDIF, IF_REAL, "ACM Parameter: Length of LDD Gate-Sour
IOP( "ld", BSIM3v32_MOD_LD, IF_REAL, "ACM Parameter: Length of LDD under Gate"), IOP( "ld", BSIM3v32_MOD_LD, IF_REAL, "ACM Parameter: Length of LDD under Gate"),
IOP( "rd", BSIM3v32_MOD_RD, IF_REAL, "ACM Parameter: Resistance of LDD drain side"), IOP( "rd", BSIM3v32_MOD_RD, IF_REAL, "ACM Parameter: Resistance of LDD drain side"),
IOP( "rs", BSIM3v32_MOD_RS, IF_REAL, "ACM Parameter: Resistance of LDD source side"), IOP( "rs", BSIM3v32_MOD_RS, IF_REAL, "ACM Parameter: Resistance of LDD source side"),
IOP( "rdc", BSIM3v32_MOD_RS, IF_REAL, "ACM Parameter: Resistance contact drain side"), IOP( "rdc", BSIM3v32_MOD_RDC, IF_REAL, "ACM Parameter: Resistance contact drain side"),
IOP( "rsc", BSIM3v32_MOD_RS, IF_REAL, "ACM Parameter: Resistance contact source side"), IOP( "rsc", BSIM3v32_MOD_RSC, IF_REAL, "ACM Parameter: Resistance contact source side"),
IOP( "wmlt", BSIM3v32_MOD_WMLT, IF_REAL, "ACM Parameter: Width shrink factor"),
IOP( "alpha0", BSIM3v32_MOD_ALPHA0, IF_REAL, "substrate current model parameter"), IOP( "alpha0", BSIM3v32_MOD_ALPHA0, IF_REAL, "substrate current model parameter"),
IOP( "alpha1", BSIM3v32_MOD_ALPHA1, IF_REAL, "substrate current model parameter"), IOP( "alpha1", BSIM3v32_MOD_ALPHA1, IF_REAL, "substrate current model parameter"),
@ -506,11 +510,11 @@ char *BSIM3v32names[] = {
"Charge" "Charge"
}; };
int BSIM3v32nSize = NUMELEMS(BSIM3v32names); int BSIM3v32nSize = NUMELEMS(BSIM3v32names);
int BSIM3v32pTSize = NUMELEMS(BSIM3v32pTable); int BSIM3v32pTSize = NUMELEMS(BSIM3v32pTable);
int BSIM3v32mPTSize = NUMELEMS(BSIM3v32mPTable); int BSIM3v32mPTSize = NUMELEMS(BSIM3v32mPTable);
int BSIM3v32iSize = sizeof(BSIM3v32instance); int BSIM3v32iSize = sizeof(BSIM3v32instance);
int BSIM3v32mSize = sizeof(BSIM3v32model); int BSIM3v32mSize = sizeof(BSIM3v32model);

View File

@ -39,9 +39,9 @@ double m;
for (; model != NULL; model = model->BSIM3v32nextModel) for (; model != NULL; model = model->BSIM3v32nextModel)
{ for (here = model->BSIM3v32instances; here!= NULL; { for (here = model->BSIM3v32instances; here!= NULL;
here = here->BSIM3v32nextInstance) here = here->BSIM3v32nextInstance)
{ {
if (here->BSIM3v32mode >= 0) if (here->BSIM3v32mode >= 0)
{ Gm = here->BSIM3v32gm; { Gm = here->BSIM3v32gm;
Gmbs = here->BSIM3v32gmbs; Gmbs = here->BSIM3v32gmbs;
FwdSum = Gm + Gmbs; FwdSum = Gm + Gmbs;
RevSum = 0.0; RevSum = 0.0;
@ -59,7 +59,7 @@ double m;
gbspb = 0.0; gbspb = 0.0;
gbspsp = 0.0; gbspsp = 0.0;
if (here->BSIM3v32nqsMod == 0) if (here->BSIM3v32nqsMod == 0)
{ cggb = here->BSIM3v32cggb; { cggb = here->BSIM3v32cggb;
cgsb = here->BSIM3v32cgsb; cgsb = here->BSIM3v32cgsb;
cgdb = here->BSIM3v32cgdb; cgdb = here->BSIM3v32cgdb;
@ -73,19 +73,19 @@ double m;
cddb = here->BSIM3v32cddb; cddb = here->BSIM3v32cddb;
xgtg = xgtd = xgts = xgtb = 0.0; xgtg = xgtd = xgts = xgtb = 0.0;
sxpart = 0.6; sxpart = 0.6;
dxpart = 0.4; dxpart = 0.4;
ddxpart_dVd = ddxpart_dVg = ddxpart_dVb ddxpart_dVd = ddxpart_dVg = ddxpart_dVb
= ddxpart_dVs = 0.0; = ddxpart_dVs = 0.0;
dsxpart_dVd = dsxpart_dVg = dsxpart_dVb dsxpart_dVd = dsxpart_dVg = dsxpart_dVb
= dsxpart_dVs = 0.0; = dsxpart_dVs = 0.0;
} }
else else
{ cggb = cgdb = cgsb = 0.0; { cggb = cgdb = cgsb = 0.0;
cbgb = cbdb = cbsb = 0.0; cbgb = cbdb = cbsb = 0.0;
cdgb = cddb = cdsb = 0.0; cdgb = cddb = cdsb = 0.0;
xgtg = here->BSIM3v32gtg; xgtg = here->BSIM3v32gtg;
xgtd = here->BSIM3v32gtd; xgtd = here->BSIM3v32gtd;
xgts = here->BSIM3v32gts; xgts = here->BSIM3v32gts;
xgtb = here->BSIM3v32gtb; xgtb = here->BSIM3v32gtb;
@ -95,46 +95,46 @@ double m;
xcqsb = here->BSIM3v32cqsb * omega; xcqsb = here->BSIM3v32cqsb * omega;
xcqbb = here->BSIM3v32cqbb * omega; xcqbb = here->BSIM3v32cqbb * omega;
CoxWL = model->BSIM3v32cox * here->pParam->BSIM3v32weffCV CoxWL = model->BSIM3v32cox * here->pParam->BSIM3v32weffCV
* here->pParam->BSIM3v32leffCV; * here->pParam->BSIM3v32leffCV;
qcheq = -(here->BSIM3v32qgate + here->BSIM3v32qbulk); qcheq = -(here->BSIM3v32qgate + here->BSIM3v32qbulk);
if (fabs(qcheq) <= 1.0e-5 * CoxWL) if (fabs(qcheq) <= 1.0e-5 * CoxWL)
{ if (model->BSIM3v32xpart < 0.5) { if (model->BSIM3v32xpart < 0.5)
{ dxpart = 0.4; { dxpart = 0.4;
} }
else if (model->BSIM3v32xpart > 0.5) else if (model->BSIM3v32xpart > 0.5)
{ dxpart = 0.0; { dxpart = 0.0;
} }
else else
{ dxpart = 0.5; { dxpart = 0.5;
} }
ddxpart_dVd = ddxpart_dVg = ddxpart_dVb ddxpart_dVd = ddxpart_dVg = ddxpart_dVb
= ddxpart_dVs = 0.0; = ddxpart_dVs = 0.0;
} }
else else
{ dxpart = here->BSIM3v32qdrn / qcheq; { dxpart = here->BSIM3v32qdrn / qcheq;
Cdd = here->BSIM3v32cddb; Cdd = here->BSIM3v32cddb;
Csd = -(here->BSIM3v32cgdb + here->BSIM3v32cddb Csd = -(here->BSIM3v32cgdb + here->BSIM3v32cddb
+ here->BSIM3v32cbdb); + here->BSIM3v32cbdb);
ddxpart_dVd = (Cdd - dxpart * (Cdd + Csd)) / qcheq; ddxpart_dVd = (Cdd - dxpart * (Cdd + Csd)) / qcheq;
Cdg = here->BSIM3v32cdgb; Cdg = here->BSIM3v32cdgb;
Csg = -(here->BSIM3v32cggb + here->BSIM3v32cdgb Csg = -(here->BSIM3v32cggb + here->BSIM3v32cdgb
+ here->BSIM3v32cbgb); + here->BSIM3v32cbgb);
ddxpart_dVg = (Cdg - dxpart * (Cdg + Csg)) / qcheq; ddxpart_dVg = (Cdg - dxpart * (Cdg + Csg)) / qcheq;
Cds = here->BSIM3v32cdsb; Cds = here->BSIM3v32cdsb;
Css = -(here->BSIM3v32cgsb + here->BSIM3v32cdsb Css = -(here->BSIM3v32cgsb + here->BSIM3v32cdsb
+ here->BSIM3v32cbsb); + here->BSIM3v32cbsb);
ddxpart_dVs = (Cds - dxpart * (Cds + Css)) / qcheq; ddxpart_dVs = (Cds - dxpart * (Cds + Css)) / qcheq;
ddxpart_dVb = -(ddxpart_dVd + ddxpart_dVg ddxpart_dVb = -(ddxpart_dVd + ddxpart_dVg
+ ddxpart_dVs); + ddxpart_dVs);
} }
sxpart = 1.0 - dxpart; sxpart = 1.0 - dxpart;
dsxpart_dVd = -ddxpart_dVd; dsxpart_dVd = -ddxpart_dVd;
dsxpart_dVg = -ddxpart_dVg; dsxpart_dVg = -ddxpart_dVg;
dsxpart_dVs = -ddxpart_dVs; dsxpart_dVs = -ddxpart_dVs;
dsxpart_dVb = -(dsxpart_dVd + dsxpart_dVg + dsxpart_dVs); dsxpart_dVb = -(dsxpart_dVd + dsxpart_dVg + dsxpart_dVs);
} }
} }
else else
@ -156,7 +156,7 @@ double m;
gbspb = here->BSIM3v32gbbs; gbspb = here->BSIM3v32gbbs;
gbspdp = -(gbspg + gbspsp + gbspb); gbspdp = -(gbspg + gbspsp + gbspb);
if (here->BSIM3v32nqsMod == 0) if (here->BSIM3v32nqsMod == 0)
{ cggb = here->BSIM3v32cggb; { cggb = here->BSIM3v32cggb;
cgsb = here->BSIM3v32cgdb; cgsb = here->BSIM3v32cgdb;
cgdb = here->BSIM3v32cgsb; cgdb = here->BSIM3v32cgsb;
@ -170,19 +170,19 @@ double m;
cddb = -(here->BSIM3v32cdsb + cgdb + cbdb); cddb = -(here->BSIM3v32cdsb + cgdb + cbdb);
xgtg = xgtd = xgts = xgtb = 0.0; xgtg = xgtd = xgts = xgtb = 0.0;
sxpart = 0.4; sxpart = 0.4;
dxpart = 0.6; dxpart = 0.6;
ddxpart_dVd = ddxpart_dVg = ddxpart_dVb ddxpart_dVd = ddxpart_dVg = ddxpart_dVb
= ddxpart_dVs = 0.0; = ddxpart_dVs = 0.0;
dsxpart_dVd = dsxpart_dVg = dsxpart_dVb dsxpart_dVd = dsxpart_dVg = dsxpart_dVb
= dsxpart_dVs = 0.0; = dsxpart_dVs = 0.0;
} }
else else
{ cggb = cgdb = cgsb = 0.0; { cggb = cgdb = cgsb = 0.0;
cbgb = cbdb = cbsb = 0.0; cbgb = cbdb = cbsb = 0.0;
cdgb = cddb = cdsb = 0.0; cdgb = cddb = cdsb = 0.0;
xgtg = here->BSIM3v32gtg; xgtg = here->BSIM3v32gtg;
xgtd = here->BSIM3v32gts; xgtd = here->BSIM3v32gts;
xgts = here->BSIM3v32gtd; xgts = here->BSIM3v32gtd;
xgtb = here->BSIM3v32gtb; xgtb = here->BSIM3v32gtb;
@ -192,50 +192,50 @@ double m;
xcqsb = here->BSIM3v32cqdb * omega; xcqsb = here->BSIM3v32cqdb * omega;
xcqbb = here->BSIM3v32cqbb * omega; xcqbb = here->BSIM3v32cqbb * omega;
CoxWL = model->BSIM3v32cox * here->pParam->BSIM3v32weffCV CoxWL = model->BSIM3v32cox * here->pParam->BSIM3v32weffCV
* here->pParam->BSIM3v32leffCV; * here->pParam->BSIM3v32leffCV;
qcheq = -(here->BSIM3v32qgate + here->BSIM3v32qbulk); qcheq = -(here->BSIM3v32qgate + here->BSIM3v32qbulk);
if (fabs(qcheq) <= 1.0e-5 * CoxWL) if (fabs(qcheq) <= 1.0e-5 * CoxWL)
{ if (model->BSIM3v32xpart < 0.5) { if (model->BSIM3v32xpart < 0.5)
{ sxpart = 0.4; { sxpart = 0.4;
} }
else if (model->BSIM3v32xpart > 0.5) else if (model->BSIM3v32xpart > 0.5)
{ sxpart = 0.0; { sxpart = 0.0;
} }
else else
{ sxpart = 0.5; { sxpart = 0.5;
} }
dsxpart_dVd = dsxpart_dVg = dsxpart_dVb dsxpart_dVd = dsxpart_dVg = dsxpart_dVb
= dsxpart_dVs = 0.0; = dsxpart_dVs = 0.0;
} }
else else
{ sxpart = here->BSIM3v32qdrn / qcheq; { sxpart = here->BSIM3v32qdrn / qcheq;
Css = here->BSIM3v32cddb; Css = here->BSIM3v32cddb;
Cds = -(here->BSIM3v32cgdb + here->BSIM3v32cddb Cds = -(here->BSIM3v32cgdb + here->BSIM3v32cddb
+ here->BSIM3v32cbdb); + here->BSIM3v32cbdb);
dsxpart_dVs = (Css - sxpart * (Css + Cds)) / qcheq; dsxpart_dVs = (Css - sxpart * (Css + Cds)) / qcheq;
Csg = here->BSIM3v32cdgb; Csg = here->BSIM3v32cdgb;
Cdg = -(here->BSIM3v32cggb + here->BSIM3v32cdgb Cdg = -(here->BSIM3v32cggb + here->BSIM3v32cdgb
+ here->BSIM3v32cbgb); + here->BSIM3v32cbgb);
dsxpart_dVg = (Csg - sxpart * (Csg + Cdg)) / qcheq; dsxpart_dVg = (Csg - sxpart * (Csg + Cdg)) / qcheq;
Csd = here->BSIM3v32cdsb; Csd = here->BSIM3v32cdsb;
Cdd = -(here->BSIM3v32cgsb + here->BSIM3v32cdsb Cdd = -(here->BSIM3v32cgsb + here->BSIM3v32cdsb
+ here->BSIM3v32cbsb); + here->BSIM3v32cbsb);
dsxpart_dVd = (Csd - sxpart * (Csd + Cdd)) / qcheq; dsxpart_dVd = (Csd - sxpart * (Csd + Cdd)) / qcheq;
dsxpart_dVb = -(dsxpart_dVd + dsxpart_dVg dsxpart_dVb = -(dsxpart_dVd + dsxpart_dVg
+ dsxpart_dVs); + dsxpart_dVs);
} }
dxpart = 1.0 - sxpart; dxpart = 1.0 - sxpart;
ddxpart_dVd = -dsxpart_dVd; ddxpart_dVd = -dsxpart_dVd;
ddxpart_dVg = -dsxpart_dVg; ddxpart_dVg = -dsxpart_dVg;
ddxpart_dVs = -dsxpart_dVs; ddxpart_dVs = -dsxpart_dVs;
ddxpart_dVb = -(ddxpart_dVd + ddxpart_dVg + ddxpart_dVs); ddxpart_dVb = -(ddxpart_dVd + ddxpart_dVg + ddxpart_dVs);
} }
} }
T1 = *(ckt->CKTstate0 + here->BSIM3v32qdef) * here->BSIM3v32gtau; T1 = *(ckt->CKTstate0 + here->BSIM3v32qdef) * here->BSIM3v32gtau;
gdpr = here->BSIM3v32drainConductance; gdpr = here->BSIM3v32drainConductance;
gspr = here->BSIM3v32sourceConductance; gspr = here->BSIM3v32sourceConductance;
gds = here->BSIM3v32gds; gds = here->BSIM3v32gds;
@ -244,9 +244,9 @@ double m;
capbd = here->BSIM3v32capbd; capbd = here->BSIM3v32capbd;
capbs = here->BSIM3v32capbs; capbs = here->BSIM3v32capbs;
GSoverlapCap = here->BSIM3v32cgso; GSoverlapCap = here->BSIM3v32cgso;
GDoverlapCap = here->BSIM3v32cgdo; GDoverlapCap = here->BSIM3v32cgdo;
GBoverlapCap = here->pParam->BSIM3v32cgbo; GBoverlapCap = here->pParam->BSIM3v32cgbo;
xcdgb = (cdgb - GDoverlapCap) * omega; xcdgb = (cdgb - GDoverlapCap) * omega;
xcddb = (cddb + capbd + GDoverlapCap) * omega; xcddb = (cddb + capbd + GDoverlapCap) * omega;
@ -255,106 +255,106 @@ double m;
xcsdb = -(cgdb + cbdb + cddb) * omega; xcsdb = -(cgdb + cbdb + cddb) * omega;
xcssb = (capbs + GSoverlapCap - (cgsb + cbsb + cdsb)) * omega; xcssb = (capbs + GSoverlapCap - (cgsb + cbsb + cdsb)) * omega;
xcggb = (cggb + GDoverlapCap + GSoverlapCap + GBoverlapCap) xcggb = (cggb + GDoverlapCap + GSoverlapCap + GBoverlapCap)
* omega; * omega;
xcgdb = (cgdb - GDoverlapCap ) * omega; xcgdb = (cgdb - GDoverlapCap ) * omega;
xcgsb = (cgsb - GSoverlapCap) * omega; xcgsb = (cgsb - GSoverlapCap) * omega;
xcbgb = (cbgb - GBoverlapCap) * omega; xcbgb = (cbgb - GBoverlapCap) * omega;
xcbdb = (cbdb - capbd ) * omega; xcbdb = (cbdb - capbd ) * omega;
xcbsb = (cbsb - capbs ) * omega; xcbsb = (cbsb - capbs ) * omega;
m = here->BSIM3v32m; m = here->BSIM3v32m;
*(here->BSIM3v32GgPtr + 1) += m * xcggb; *(here->BSIM3v32GgPtr + 1) += m * xcggb;
*(here->BSIM3v32BbPtr + 1) -= *(here->BSIM3v32BbPtr + 1) -=
m * (xcbgb + xcbdb + xcbsb); m * (xcbgb + xcbdb + xcbsb);
*(here->BSIM3v32DPdpPtr + 1) += m * xcddb; *(here->BSIM3v32DPdpPtr + 1) += m * xcddb;
*(here->BSIM3v32SPspPtr + 1) += m * xcssb; *(here->BSIM3v32SPspPtr + 1) += m * xcssb;
*(here->BSIM3v32GbPtr + 1) -= *(here->BSIM3v32GbPtr + 1) -=
m * (xcggb + xcgdb + xcgsb); m * (xcggb + xcgdb + xcgsb);
*(here->BSIM3v32GdpPtr + 1) += m * xcgdb; *(here->BSIM3v32GdpPtr + 1) += m * xcgdb;
*(here->BSIM3v32GspPtr + 1) += m * xcgsb; *(here->BSIM3v32GspPtr + 1) += m * xcgsb;
*(here->BSIM3v32BgPtr + 1) += m * xcbgb; *(here->BSIM3v32BgPtr + 1) += m * xcbgb;
*(here->BSIM3v32BdpPtr + 1) += m * xcbdb; *(here->BSIM3v32BdpPtr + 1) += m * xcbdb;
*(here->BSIM3v32BspPtr + 1) += m * xcbsb; *(here->BSIM3v32BspPtr + 1) += m * xcbsb;
*(here->BSIM3v32DPgPtr + 1) += m * xcdgb; *(here->BSIM3v32DPgPtr + 1) += m * xcdgb;
*(here->BSIM3v32DPbPtr + 1) -= *(here->BSIM3v32DPbPtr + 1) -=
m * (xcdgb + xcddb + xcdsb); m * (xcdgb + xcddb + xcdsb);
*(here->BSIM3v32DPspPtr + 1) += m * xcdsb; *(here->BSIM3v32DPspPtr + 1) += m * xcdsb;
*(here->BSIM3v32SPgPtr + 1) += m * xcsgb; *(here->BSIM3v32SPgPtr + 1) += m * xcsgb;
*(here->BSIM3v32SPbPtr + 1) -= *(here->BSIM3v32SPbPtr + 1) -=
m * (xcsgb + xcsdb + xcssb); m * (xcsgb + xcsdb + xcssb);
*(here->BSIM3v32SPdpPtr + 1) += m * xcsdb; *(here->BSIM3v32SPdpPtr + 1) += m * xcsdb;
*(here->BSIM3v32DdPtr) += m * gdpr; *(here->BSIM3v32DdPtr) += m * gdpr;
*(here->BSIM3v32SsPtr) += m * gspr; *(here->BSIM3v32SsPtr) += m * gspr;
*(here->BSIM3v32BbPtr) += *(here->BSIM3v32BbPtr) +=
m * (gbd + gbs - here->BSIM3v32gbbs); m * (gbd + gbs - here->BSIM3v32gbbs);
*(here->BSIM3v32DPdpPtr) += *(here->BSIM3v32DPdpPtr) +=
m * (gdpr + gds + gbd + RevSum + m * (gdpr + gds + gbd + RevSum +
dxpart * xgtd + T1 * ddxpart_dVd + dxpart * xgtd + T1 * ddxpart_dVd +
gbdpdp); gbdpdp);
*(here->BSIM3v32SPspPtr) += *(here->BSIM3v32SPspPtr) +=
m * (gspr + gds + gbs + FwdSum + m * (gspr + gds + gbs + FwdSum +
sxpart * xgts + T1 * dsxpart_dVs + sxpart * xgts + T1 * dsxpart_dVs +
gbspsp); gbspsp);
*(here->BSIM3v32DdpPtr) -= m * gdpr; *(here->BSIM3v32DdpPtr) -= m * gdpr;
*(here->BSIM3v32SspPtr) -= m * gspr; *(here->BSIM3v32SspPtr) -= m * gspr;
*(here->BSIM3v32BgPtr) -= m * here->BSIM3v32gbgs; *(here->BSIM3v32BgPtr) -= m * here->BSIM3v32gbgs;
*(here->BSIM3v32BdpPtr) -= m * (gbd - gbbdp); *(here->BSIM3v32BdpPtr) -= m * (gbd - gbbdp);
*(here->BSIM3v32BspPtr) -= m * (gbs - gbbsp); *(here->BSIM3v32BspPtr) -= m * (gbs - gbbsp);
*(here->BSIM3v32DPdPtr) -= m * gdpr; *(here->BSIM3v32DPdPtr) -= m * gdpr;
*(here->BSIM3v32DPgPtr) += *(here->BSIM3v32DPgPtr) +=
m * (Gm + dxpart * xgtg + T1 * ddxpart_dVg + m * (Gm + dxpart * xgtg + T1 * ddxpart_dVg +
gbdpg); gbdpg);
*(here->BSIM3v32DPbPtr) -= *(here->BSIM3v32DPbPtr) -=
m * (gbd - Gmbs - dxpart * xgtb - m * (gbd - Gmbs - dxpart * xgtb -
T1 * ddxpart_dVb - gbdpb); T1 * ddxpart_dVb - gbdpb);
*(here->BSIM3v32DPspPtr) -= *(here->BSIM3v32DPspPtr) -=
m * (gds + FwdSum - dxpart * xgts - m * (gds + FwdSum - dxpart * xgts -
T1 * ddxpart_dVs - gbdpsp); T1 * ddxpart_dVs - gbdpsp);
*(here->BSIM3v32SPgPtr) -= *(here->BSIM3v32SPgPtr) -=
m * (Gm - sxpart * xgtg - T1 * dsxpart_dVg - m * (Gm - sxpart * xgtg - T1 * dsxpart_dVg -
gbspg); gbspg);
*(here->BSIM3v32SPsPtr) -= m * gspr; *(here->BSIM3v32SPsPtr) -= m * gspr;
*(here->BSIM3v32SPbPtr) -= *(here->BSIM3v32SPbPtr) -=
m * (gbs + Gmbs - sxpart * xgtb - m * (gbs + Gmbs - sxpart * xgtb -
T1 * dsxpart_dVb - gbspb); T1 * dsxpart_dVb - gbspb);
*(here->BSIM3v32SPdpPtr) -= *(here->BSIM3v32SPdpPtr) -=
m * (gds + RevSum - sxpart * xgtd - m * (gds + RevSum - sxpart * xgtd -
T1 * dsxpart_dVd - gbspdp); T1 * dsxpart_dVd - gbspdp);
*(here->BSIM3v32GgPtr) -= m * xgtg; *(here->BSIM3v32GgPtr) -= m * xgtg;
*(here->BSIM3v32GbPtr) -= m * xgtb; *(here->BSIM3v32GbPtr) -= m * xgtb;
*(here->BSIM3v32GdpPtr) -= m * xgtd; *(here->BSIM3v32GdpPtr) -= m * xgtd;
*(here->BSIM3v32GspPtr) -= m * xgts; *(here->BSIM3v32GspPtr) -= m * xgts;
if (here->BSIM3v32nqsMod) if (here->BSIM3v32nqsMod)
{ {
*(here->BSIM3v32QqPtr + 1) += *(here->BSIM3v32QqPtr + 1) +=
m * omega * ScalingFactor; m * omega * ScalingFactor;
*(here->BSIM3v32QgPtr + 1) -= m * xcqgb; *(here->BSIM3v32QgPtr + 1) -= m * xcqgb;
*(here->BSIM3v32QdpPtr + 1) -= m * xcqdb; *(here->BSIM3v32QdpPtr + 1) -= m * xcqdb;
*(here->BSIM3v32QspPtr + 1) -= m * xcqsb; *(here->BSIM3v32QspPtr + 1) -= m * xcqsb;
*(here->BSIM3v32QbPtr + 1) -= m * xcqbb; *(here->BSIM3v32QbPtr + 1) -= m * xcqbb;
*(here->BSIM3v32QqPtr) += m * here->BSIM3v32gtau; *(here->BSIM3v32QqPtr) += m * here->BSIM3v32gtau;
*(here->BSIM3v32DPqPtr) += *(here->BSIM3v32DPqPtr) +=
m * (dxpart * here->BSIM3v32gtau); m * (dxpart * here->BSIM3v32gtau);
*(here->BSIM3v32SPqPtr) += *(here->BSIM3v32SPqPtr) +=
m * (sxpart * here->BSIM3v32gtau); m * (sxpart * here->BSIM3v32gtau);
*(here->BSIM3v32GqPtr) -= m * here->BSIM3v32gtau; *(here->BSIM3v32GqPtr) -= m * here->BSIM3v32gtau;
*(here->BSIM3v32QgPtr) += m * xgtg; *(here->BSIM3v32QgPtr) += m * xgtg;
*(here->BSIM3v32QdpPtr) += m * xgtd; *(here->BSIM3v32QdpPtr) += m * xgtd;
*(here->BSIM3v32QspPtr) += m * xgts; *(here->BSIM3v32QspPtr) += m * xgts;
*(here->BSIM3v32QbPtr) += m * xgtb; *(here->BSIM3v32QbPtr) += m * xgtb;
} }
} }
} }
return(OK); return(OK);
} }

View File

@ -19,7 +19,7 @@
int int
BSIM3v32ask (CKTcircuit *ckt, GENinstance *inst, int which, IFvalue *value, BSIM3v32ask (CKTcircuit *ckt, GENinstance *inst, int which, IFvalue *value,
IFvalue *select) IFvalue *select)
{ {
BSIM3v32instance *here = (BSIM3v32instance*)inst; BSIM3v32instance *here = (BSIM3v32instance*)inst;
@ -32,9 +32,9 @@ BSIM3v32instance *here = (BSIM3v32instance*)inst;
case BSIM3v32_W: case BSIM3v32_W:
value->rValue = here->BSIM3v32w; value->rValue = here->BSIM3v32w;
return(OK); return(OK);
case BSIM3v32_M: case BSIM3v32_M:
value->rValue = here->BSIM3v32m; value->rValue = here->BSIM3v32m;
return (OK); return (OK);
case BSIM3v32_AS: case BSIM3v32_AS:
value->rValue = here->BSIM3v32sourceArea; value->rValue = here->BSIM3v32sourceArea;
return(OK); return(OK);
@ -59,6 +59,9 @@ BSIM3v32instance *here = (BSIM3v32instance*)inst;
case BSIM3v32_NQSMOD: case BSIM3v32_NQSMOD:
value->iValue = here->BSIM3v32nqsMod; value->iValue = here->BSIM3v32nqsMod;
return(OK); return(OK);
case BSIM3v32_GEO:
value->iValue = here->BSIM3v32geo;
return(OK);
case BSIM3v32_DELVTO: case BSIM3v32_DELVTO:
value->rValue = here->BSIM3v32delvto; value->rValue = here->BSIM3v32delvto;
return(OK); return(OK);
@ -94,11 +97,11 @@ BSIM3v32instance *here = (BSIM3v32instance*)inst;
return(OK); return(OK);
case BSIM3v32_SOURCECONDUCT: case BSIM3v32_SOURCECONDUCT:
value->rValue = here->BSIM3v32sourceConductance; value->rValue = here->BSIM3v32sourceConductance;
value->rValue *= here->BSIM3v32m; value->rValue *= here->BSIM3v32m;
return(OK); return(OK);
case BSIM3v32_DRAINCONDUCT: case BSIM3v32_DRAINCONDUCT:
value->rValue = here->BSIM3v32drainConductance; value->rValue = here->BSIM3v32drainConductance;
value->rValue *= here->BSIM3v32m; value->rValue *= here->BSIM3v32m;
return(OK); return(OK);
case BSIM3v32_VBD: case BSIM3v32_VBD:
value->rValue = *(ckt->CKTstate0 + here->BSIM3v32vbd); value->rValue = *(ckt->CKTstate0 + here->BSIM3v32vbd);
@ -114,103 +117,103 @@ BSIM3v32instance *here = (BSIM3v32instance*)inst;
return(OK); return(OK);
case BSIM3v32_CD: case BSIM3v32_CD:
value->rValue = here->BSIM3v32cd; value->rValue = here->BSIM3v32cd;
value->rValue *= here->BSIM3v32m; value->rValue *= here->BSIM3v32m;
return(OK); return(OK);
case BSIM3v32_CBS: case BSIM3v32_CBS:
value->rValue = here->BSIM3v32cbs; value->rValue = here->BSIM3v32cbs;
value->rValue *= here->BSIM3v32m; value->rValue *= here->BSIM3v32m;
return(OK); return(OK);
case BSIM3v32_CBD: case BSIM3v32_CBD:
value->rValue = here->BSIM3v32cbd; value->rValue = here->BSIM3v32cbd;
value->rValue *= here->BSIM3v32m; value->rValue *= here->BSIM3v32m;
return(OK); return(OK);
case BSIM3v32_GM: case BSIM3v32_GM:
value->rValue = here->BSIM3v32gm; value->rValue = here->BSIM3v32gm;
value->rValue *= here->BSIM3v32m; value->rValue *= here->BSIM3v32m;
return(OK); return(OK);
case BSIM3v32_GDS: case BSIM3v32_GDS:
value->rValue = here->BSIM3v32gds; value->rValue = here->BSIM3v32gds;
value->rValue *= here->BSIM3v32m; value->rValue *= here->BSIM3v32m;
return(OK); return(OK);
case BSIM3v32_GMBS: case BSIM3v32_GMBS:
value->rValue = here->BSIM3v32gmbs; value->rValue = here->BSIM3v32gmbs;
value->rValue *= here->BSIM3v32m; value->rValue *= here->BSIM3v32m;
return(OK); return(OK);
case BSIM3v32_GBD: case BSIM3v32_GBD:
value->rValue = here->BSIM3v32gbd; value->rValue = here->BSIM3v32gbd;
value->rValue *= here->BSIM3v32m; value->rValue *= here->BSIM3v32m;
return(OK); return(OK);
case BSIM3v32_GBS: case BSIM3v32_GBS:
value->rValue = here->BSIM3v32gbs; value->rValue = here->BSIM3v32gbs;
value->rValue *= here->BSIM3v32m; value->rValue *= here->BSIM3v32m;
return(OK); return(OK);
case BSIM3v32_QB: case BSIM3v32_QB:
value->rValue = *(ckt->CKTstate0 + here->BSIM3v32qb); value->rValue = *(ckt->CKTstate0 + here->BSIM3v32qb);
value->rValue *= here->BSIM3v32m; value->rValue *= here->BSIM3v32m;
return(OK); return(OK);
case BSIM3v32_CQB: case BSIM3v32_CQB:
value->rValue = *(ckt->CKTstate0 + here->BSIM3v32cqb); value->rValue = *(ckt->CKTstate0 + here->BSIM3v32cqb);
value->rValue *= here->BSIM3v32m; value->rValue *= here->BSIM3v32m;
return(OK); return(OK);
case BSIM3v32_QG: case BSIM3v32_QG:
value->rValue = *(ckt->CKTstate0 + here->BSIM3v32qg); value->rValue = *(ckt->CKTstate0 + here->BSIM3v32qg);
value->rValue *= here->BSIM3v32m; value->rValue *= here->BSIM3v32m;
return(OK); return(OK);
case BSIM3v32_CQG: case BSIM3v32_CQG:
value->rValue = *(ckt->CKTstate0 + here->BSIM3v32cqg); value->rValue = *(ckt->CKTstate0 + here->BSIM3v32cqg);
value->rValue *= here->BSIM3v32m; value->rValue *= here->BSIM3v32m;
return(OK); return(OK);
case BSIM3v32_QD: case BSIM3v32_QD:
value->rValue = *(ckt->CKTstate0 + here->BSIM3v32qd); value->rValue = *(ckt->CKTstate0 + here->BSIM3v32qd);
value->rValue *= here->BSIM3v32m; value->rValue *= here->BSIM3v32m;
return(OK); return(OK);
case BSIM3v32_CQD: case BSIM3v32_CQD:
value->rValue = *(ckt->CKTstate0 + here->BSIM3v32cqd); value->rValue = *(ckt->CKTstate0 + here->BSIM3v32cqd);
value->rValue *= here->BSIM3v32m; value->rValue *= here->BSIM3v32m;
return(OK); return(OK);
case BSIM3v32_CGG: case BSIM3v32_CGG:
value->rValue = here->BSIM3v32cggb; value->rValue = here->BSIM3v32cggb;
value->rValue *= here->BSIM3v32m; value->rValue *= here->BSIM3v32m;
return(OK); return(OK);
case BSIM3v32_CGD: case BSIM3v32_CGD:
value->rValue = here->BSIM3v32cgdb; value->rValue = here->BSIM3v32cgdb;
value->rValue *= here->BSIM3v32m; value->rValue *= here->BSIM3v32m;
return(OK); return(OK);
case BSIM3v32_CGS: case BSIM3v32_CGS:
value->rValue = here->BSIM3v32cgsb; value->rValue = here->BSIM3v32cgsb;
value->rValue *= here->BSIM3v32m; value->rValue *= here->BSIM3v32m;
return(OK); return(OK);
case BSIM3v32_CDG: case BSIM3v32_CDG:
value->rValue = here->BSIM3v32cdgb; value->rValue = here->BSIM3v32cdgb;
value->rValue *= here->BSIM3v32m; value->rValue *= here->BSIM3v32m;
return(OK); return(OK);
case BSIM3v32_CDD: case BSIM3v32_CDD:
value->rValue = here->BSIM3v32cddb; value->rValue = here->BSIM3v32cddb;
value->rValue *= here->BSIM3v32m; value->rValue *= here->BSIM3v32m;
return(OK); return(OK);
case BSIM3v32_CDS: case BSIM3v32_CDS:
value->rValue = here->BSIM3v32cdsb; value->rValue = here->BSIM3v32cdsb;
value->rValue *= here->BSIM3v32m; value->rValue *= here->BSIM3v32m;
return(OK); return(OK);
case BSIM3v32_CBG: case BSIM3v32_CBG:
value->rValue = here->BSIM3v32cbgb; value->rValue = here->BSIM3v32cbgb;
value->rValue *= here->BSIM3v32m; value->rValue *= here->BSIM3v32m;
return(OK); return(OK);
case BSIM3v32_CBDB: case BSIM3v32_CBDB:
value->rValue = here->BSIM3v32cbdb; value->rValue = here->BSIM3v32cbdb;
value->rValue *= here->BSIM3v32m; value->rValue *= here->BSIM3v32m;
return(OK); return(OK);
case BSIM3v32_CBSB: case BSIM3v32_CBSB:
value->rValue = here->BSIM3v32cbsb; value->rValue = here->BSIM3v32cbsb;
value->rValue *= here->BSIM3v32m; value->rValue *= here->BSIM3v32m;
return(OK); return(OK);
case BSIM3v32_CAPBD: case BSIM3v32_CAPBD:
value->rValue = here->BSIM3v32capbd; value->rValue = here->BSIM3v32capbd;
value->rValue *= here->BSIM3v32m; value->rValue *= here->BSIM3v32m;
return(OK); return(OK);
case BSIM3v32_CAPBS: case BSIM3v32_CAPBS:
value->rValue = here->BSIM3v32capbs; value->rValue = here->BSIM3v32capbs;
value->rValue *= here->BSIM3v32m; value->rValue *= here->BSIM3v32m;
return(OK); return(OK);
case BSIM3v32_VON: case BSIM3v32_VON:
value->rValue = here->BSIM3v32von; value->rValue = here->BSIM3v32von;
@ -220,11 +223,11 @@ BSIM3v32instance *here = (BSIM3v32instance*)inst;
return(OK); return(OK);
case BSIM3v32_QBS: case BSIM3v32_QBS:
value->rValue = *(ckt->CKTstate0 + here->BSIM3v32qbs); value->rValue = *(ckt->CKTstate0 + here->BSIM3v32qbs);
value->rValue *= here->BSIM3v32m; value->rValue *= here->BSIM3v32m;
return(OK); return(OK);
case BSIM3v32_QBD: case BSIM3v32_QBD:
value->rValue = *(ckt->CKTstate0 + here->BSIM3v32qbd); value->rValue = *(ckt->CKTstate0 + here->BSIM3v32qbd);
value->rValue *= here->BSIM3v32m; value->rValue *= here->BSIM3v32m;
return(OK); return(OK);
default: default:
return(E_BADPARM); return(E_BADPARM);

View File

@ -28,419 +28,425 @@ FILE *fplog;
NG_IGNORE(ckt); NG_IGNORE(ckt);
if ((fplog = fopen("b3v3check.log", "w")) != NULL) if ((fplog = fopen("b3v32check.log", "w")) != NULL)
{ pParam = here->pParam; { pParam = here->pParam;
fprintf (fplog, fprintf (fplog,
"BSIM3 Model (Supports: v3.2, v3.2.2, v3.2.3, v3.2.4)\n"); "BSIM3 Model (Supports: v3.2, v3.2.2, v3.2.3, v3.2.4)\n");
fprintf (fplog, "Parameter Checking.\n"); fprintf (fplog, "Parameter Checking.\n");
fprintf (fplog, "Model = %s\n", model->BSIM3v32modName); fprintf (fplog, "Model = %s\n", model->BSIM3v32modName);
fprintf (fplog, "W = %g, L = %g, M = %g\n", here->BSIM3v32w, fprintf (fplog, "W = %g, L = %g, M = %g\n", here->BSIM3v32w,
here->BSIM3v32l, here->BSIM3v32m); here->BSIM3v32l, here->BSIM3v32m);
if ((strcmp(model->BSIM3v32version, "3.2.4")) && (strcmp(model->BSIM3v32version, "3.24")) if ((strcmp(model->BSIM3v32version, "3.2.4")) && (strcmp(model->BSIM3v32version, "3.24"))
&& (strcmp(model->BSIM3v32version, "3.2.3")) && (strcmp(model->BSIM3v32version, "3.23")) && (strcmp(model->BSIM3v32version, "3.2.3")) && (strcmp(model->BSIM3v32version, "3.23"))
&& (strcmp(model->BSIM3v32version, "3.2.2")) && (strcmp(model->BSIM3v32version, "3.22")) && (strcmp(model->BSIM3v32version, "3.2.2")) && (strcmp(model->BSIM3v32version, "3.22"))
&& (strcmp(model->BSIM3v32version, "3.2")) && (strcmp(model->BSIM3v32version, "3.20"))) && (strcmp(model->BSIM3v32version, "3.2")) && (strcmp(model->BSIM3v32version, "3.20")))
{ {
fprintf (fplog, fprintf (fplog,
"Warning: This model supports BSIM3v3.2, BSIM3v3.2.2, BSIM3v3.2.3, BSIM3v3.2.4\n"); "Warning: This model supports BSIM3v3.2, BSIM3v3.2.2, BSIM3v3.2.3, BSIM3v3.2.4\n");
fprintf (fplog, fprintf (fplog,
"You specified a wrong version number. Working now with BSIM3v3.2.4.\n"); "You specified a wrong version number. Working now with BSIM3v3.2.4.\n");
printf ("Warning: This model supports BSIM3v3.2, BSIM3v3.2.2, BSIM3v3.2.3, BSIM3v3.2.4\n"); printf ("Warning: This model supports BSIM3v3.2, BSIM3v3.2.2, BSIM3v3.2.3, BSIM3v3.2.4\n");
printf ("You specified a wrong version number. Working now with BSIM3v3.2.4.\n"); printf ("You specified a wrong version number. Working now with BSIM3v3.2.4.\n");
} }
if (pParam->BSIM3v32nlx < -pParam->BSIM3v32leff) if (pParam->BSIM3v32nlx < -pParam->BSIM3v32leff)
{ fprintf(fplog, "Fatal: Nlx = %g is less than -Leff.\n", { fprintf(fplog, "Fatal: Nlx = %g is less than -Leff.\n",
pParam->BSIM3v32nlx); pParam->BSIM3v32nlx);
printf("Fatal: Nlx = %g is less than -Leff.\n", printf("Fatal: Nlx = %g is less than -Leff.\n",
pParam->BSIM3v32nlx); pParam->BSIM3v32nlx);
Fatal_Flag = 1; Fatal_Flag = 1;
} }
if (model->BSIM3v32tox <= 0.0) if (model->BSIM3v32tox <= 0.0)
{ fprintf(fplog, "Fatal: Tox = %g is not positive.\n", { fprintf(fplog, "Fatal: Tox = %g is not positive.\n",
model->BSIM3v32tox); model->BSIM3v32tox);
printf("Fatal: Tox = %g is not positive.\n", model->BSIM3v32tox); printf("Fatal: Tox = %g is not positive.\n", model->BSIM3v32tox);
Fatal_Flag = 1; Fatal_Flag = 1;
} }
if (model->BSIM3v32toxm <= 0.0) if (model->BSIM3v32toxm <= 0.0)
{ fprintf(fplog, "Fatal: Toxm = %g is not positive.\n", { fprintf(fplog, "Fatal: Toxm = %g is not positive.\n",
model->BSIM3v32toxm); model->BSIM3v32toxm);
printf("Fatal: Toxm = %g is not positive.\n", model->BSIM3v32toxm); printf("Fatal: Toxm = %g is not positive.\n", model->BSIM3v32toxm);
Fatal_Flag = 1; Fatal_Flag = 1;
} }
if (pParam->BSIM3v32npeak <= 0.0) if (pParam->BSIM3v32npeak <= 0.0)
{ fprintf(fplog, "Fatal: Nch = %g is not positive.\n", { fprintf(fplog, "Fatal: Nch = %g is not positive.\n",
pParam->BSIM3v32npeak); pParam->BSIM3v32npeak);
printf("Fatal: Nch = %g is not positive.\n", printf("Fatal: Nch = %g is not positive.\n",
pParam->BSIM3v32npeak); pParam->BSIM3v32npeak);
Fatal_Flag = 1; Fatal_Flag = 1;
} }
if (pParam->BSIM3v32nsub <= 0.0) if (pParam->BSIM3v32nsub <= 0.0)
{ fprintf(fplog, "Fatal: Nsub = %g is not positive.\n", { fprintf(fplog, "Fatal: Nsub = %g is not positive.\n",
pParam->BSIM3v32nsub); pParam->BSIM3v32nsub);
printf("Fatal: Nsub = %g is not positive.\n", printf("Fatal: Nsub = %g is not positive.\n",
pParam->BSIM3v32nsub); pParam->BSIM3v32nsub);
Fatal_Flag = 1; Fatal_Flag = 1;
} }
if (pParam->BSIM3v32ngate < 0.0) if (pParam->BSIM3v32ngate < 0.0)
{ fprintf(fplog, "Fatal: Ngate = %g is not positive.\n", { fprintf(fplog, "Fatal: Ngate = %g is not positive.\n",
pParam->BSIM3v32ngate); pParam->BSIM3v32ngate);
printf("Fatal: Ngate = %g Ngate is not positive.\n", printf("Fatal: Ngate = %g Ngate is not positive.\n",
pParam->BSIM3v32ngate); pParam->BSIM3v32ngate);
Fatal_Flag = 1; Fatal_Flag = 1;
} }
if (pParam->BSIM3v32ngate > 1.e25) if (pParam->BSIM3v32ngate > 1.e25)
{ fprintf(fplog, "Fatal: Ngate = %g is too high.\n", { fprintf(fplog, "Fatal: Ngate = %g is too high.\n",
pParam->BSIM3v32ngate); pParam->BSIM3v32ngate);
printf("Fatal: Ngate = %g Ngate is too high\n", printf("Fatal: Ngate = %g Ngate is too high\n",
pParam->BSIM3v32ngate); pParam->BSIM3v32ngate);
Fatal_Flag = 1; Fatal_Flag = 1;
} }
if (pParam->BSIM3v32xj <= 0.0) if (pParam->BSIM3v32xj <= 0.0)
{ fprintf(fplog, "Fatal: Xj = %g is not positive.\n", { fprintf(fplog, "Fatal: Xj = %g is not positive.\n",
pParam->BSIM3v32xj); pParam->BSIM3v32xj);
printf("Fatal: Xj = %g is not positive.\n", pParam->BSIM3v32xj); printf("Fatal: Xj = %g is not positive.\n", pParam->BSIM3v32xj);
Fatal_Flag = 1; Fatal_Flag = 1;
} }
if (pParam->BSIM3v32dvt1 < 0.0) if (pParam->BSIM3v32dvt1 < 0.0)
{ fprintf(fplog, "Fatal: Dvt1 = %g is negative.\n", { fprintf(fplog, "Fatal: Dvt1 = %g is negative.\n",
pParam->BSIM3v32dvt1); pParam->BSIM3v32dvt1);
printf("Fatal: Dvt1 = %g is negative.\n", pParam->BSIM3v32dvt1); printf("Fatal: Dvt1 = %g is negative.\n", pParam->BSIM3v32dvt1);
Fatal_Flag = 1; Fatal_Flag = 1;
} }
if (pParam->BSIM3v32dvt1w < 0.0) if (pParam->BSIM3v32dvt1w < 0.0)
{ fprintf(fplog, "Fatal: Dvt1w = %g is negative.\n", { fprintf(fplog, "Fatal: Dvt1w = %g is negative.\n",
pParam->BSIM3v32dvt1w); pParam->BSIM3v32dvt1w);
printf("Fatal: Dvt1w = %g is negative.\n", pParam->BSIM3v32dvt1w); printf("Fatal: Dvt1w = %g is negative.\n", pParam->BSIM3v32dvt1w);
Fatal_Flag = 1; Fatal_Flag = 1;
} }
if (pParam->BSIM3v32w0 == -pParam->BSIM3v32weff) if (pParam->BSIM3v32w0 == -pParam->BSIM3v32weff)
{ fprintf(fplog, "Fatal: (W0 + Weff) = 0 causing divided-by-zero.\n"); { fprintf(fplog, "Fatal: (W0 + Weff) = 0 causing divided-by-zero.\n");
printf("Fatal: (W0 + Weff) = 0 causing divided-by-zero.\n"); printf("Fatal: (W0 + Weff) = 0 causing divided-by-zero.\n");
Fatal_Flag = 1; Fatal_Flag = 1;
} }
if (pParam->BSIM3v32dsub < 0.0) if (pParam->BSIM3v32dsub < 0.0)
{ fprintf(fplog, "Fatal: Dsub = %g is negative.\n", pParam->BSIM3v32dsub); { fprintf(fplog, "Fatal: Dsub = %g is negative.\n", pParam->BSIM3v32dsub);
printf("Fatal: Dsub = %g is negative.\n", pParam->BSIM3v32dsub); printf("Fatal: Dsub = %g is negative.\n", pParam->BSIM3v32dsub);
Fatal_Flag = 1; Fatal_Flag = 1;
} }
if (pParam->BSIM3v32b1 == -pParam->BSIM3v32weff) if (pParam->BSIM3v32b1 == -pParam->BSIM3v32weff)
{ fprintf(fplog, "Fatal: (B1 + Weff) = 0 causing divided-by-zero.\n"); { fprintf(fplog, "Fatal: (B1 + Weff) = 0 causing divided-by-zero.\n");
printf("Fatal: (B1 + Weff) = 0 causing divided-by-zero.\n"); printf("Fatal: (B1 + Weff) = 0 causing divided-by-zero.\n");
Fatal_Flag = 1; Fatal_Flag = 1;
} }
if (pParam->BSIM3v32u0temp <= 0.0) if (pParam->BSIM3v32u0temp <= 0.0)
{ fprintf(fplog, "Fatal: u0 at current temperature = %g is not positive.\n", pParam->BSIM3v32u0temp); { fprintf(fplog, "Fatal: u0 at current temperature = %g is not positive.\n", pParam->BSIM3v32u0temp);
printf("Fatal: u0 at current temperature = %g is not positive.\n", printf("Fatal: u0 at current temperature = %g is not positive.\n",
pParam->BSIM3v32u0temp); pParam->BSIM3v32u0temp);
Fatal_Flag = 1; Fatal_Flag = 1;
} }
/* Check delta parameter */ /* Check delta parameter */
if (pParam->BSIM3v32delta < 0.0) if (pParam->BSIM3v32delta < 0.0)
{ fprintf(fplog, "Fatal: Delta = %g is less than zero.\n", { fprintf(fplog, "Fatal: Delta = %g is less than zero.\n",
pParam->BSIM3v32delta); pParam->BSIM3v32delta);
printf("Fatal: Delta = %g is less than zero.\n", pParam->BSIM3v32delta); printf("Fatal: Delta = %g is less than zero.\n", pParam->BSIM3v32delta);
Fatal_Flag = 1; Fatal_Flag = 1;
} }
if (pParam->BSIM3v32vsattemp <= 0.0) if (pParam->BSIM3v32vsattemp <= 0.0)
{ fprintf(fplog, "Fatal: Vsat at current temperature = %g is not positive.\n", pParam->BSIM3v32vsattemp); { fprintf(fplog, "Fatal: Vsat at current temperature = %g is not positive.\n", pParam->BSIM3v32vsattemp);
printf("Fatal: Vsat at current temperature = %g is not positive.\n", printf("Fatal: Vsat at current temperature = %g is not positive.\n",
pParam->BSIM3v32vsattemp); pParam->BSIM3v32vsattemp);
Fatal_Flag = 1; Fatal_Flag = 1;
} }
/* Check Rout parameters */ /* Check Rout parameters */
if (pParam->BSIM3v32pclm <= 0.0) if (pParam->BSIM3v32pclm <= 0.0)
{ fprintf(fplog, "Fatal: Pclm = %g is not positive.\n", pParam->BSIM3v32pclm); { fprintf(fplog, "Fatal: Pclm = %g is not positive.\n", pParam->BSIM3v32pclm);
printf("Fatal: Pclm = %g is not positive.\n", pParam->BSIM3v32pclm); printf("Fatal: Pclm = %g is not positive.\n", pParam->BSIM3v32pclm);
Fatal_Flag = 1; Fatal_Flag = 1;
} }
if (pParam->BSIM3v32drout < 0.0) if (pParam->BSIM3v32drout < 0.0)
{ fprintf(fplog, "Fatal: Drout = %g is negative.\n", pParam->BSIM3v32drout); { fprintf(fplog, "Fatal: Drout = %g is negative.\n", pParam->BSIM3v32drout);
printf("Fatal: Drout = %g is negative.\n", pParam->BSIM3v32drout); printf("Fatal: Drout = %g is negative.\n", pParam->BSIM3v32drout);
Fatal_Flag = 1; Fatal_Flag = 1;
} }
if (pParam->BSIM3v32pscbe2 <= 0.0) if (pParam->BSIM3v32pscbe2 <= 0.0)
{ fprintf(fplog, "Warning: Pscbe2 = %g is not positive.\n", { fprintf(fplog, "Warning: Pscbe2 = %g is not positive.\n",
pParam->BSIM3v32pscbe2); pParam->BSIM3v32pscbe2);
printf("Warning: Pscbe2 = %g is not positive.\n", pParam->BSIM3v32pscbe2); printf("Warning: Pscbe2 = %g is not positive.\n", pParam->BSIM3v32pscbe2);
} }
/* acm model */ /* ACM model */
if (model->BSIM3v32acmMod == 0) { if (model->BSIM3v32acmMod == 0) {
if (model->BSIM3v32unitLengthSidewallJctCap > 0.0 || if (model->BSIM3v32unitLengthSidewallJctCap > 0.0 ||
model->BSIM3v32unitLengthGateSidewallJctCap > 0.0) model->BSIM3v32unitLengthGateSidewallJctCap > 0.0)
{ {
if (here->BSIM3v32drainPerimeter < pParam->BSIM3v32weff) if (here->BSIM3v32drainPerimeter < pParam->BSIM3v32weff)
{ fprintf(fplog, "Warning: Pd = %g is less than W.\n", { fprintf(fplog, "Warning: Pd = %g is less than W.\n",
here->BSIM3v32drainPerimeter); here->BSIM3v32drainPerimeter);
printf("Warning: Pd = %g is less than W.\n", printf("Warning: Pd = %g is less than W.\n",
here->BSIM3v32drainPerimeter); here->BSIM3v32drainPerimeter);
} }
if (here->BSIM3v32sourcePerimeter < pParam->BSIM3v32weff) if (here->BSIM3v32sourcePerimeter < pParam->BSIM3v32weff)
{ fprintf(fplog, "Warning: Ps = %g is less than W.\n", { fprintf(fplog, "Warning: Ps = %g is less than W.\n",
here->BSIM3v32sourcePerimeter); here->BSIM3v32sourcePerimeter);
printf("Warning: Ps = %g is less than W.\n", printf("Warning: Ps = %g is less than W.\n",
here->BSIM3v32sourcePerimeter); here->BSIM3v32sourcePerimeter);
} }
} }
} }
if ((model->BSIM3v32calcacm > 0) && (model->BSIM3v32acmMod != 12))
{ fprintf(fplog, "Warning: CALCACM = %d is wrong. Set back to 0.\n",
model->BSIM3v32calcacm);
printf("Warning: CALCACM = %d is wrong. Set back to 0.\n", model->BSIM3v32calcacm);
model->BSIM3v32calcacm = 0;
}
if (pParam->BSIM3v32noff < 0.1) if (pParam->BSIM3v32noff < 0.1)
{ fprintf(fplog, "Warning: Noff = %g is too small.\n", { fprintf(fplog, "Warning: Noff = %g is too small.\n",
pParam->BSIM3v32noff); pParam->BSIM3v32noff);
printf("Warning: Noff = %g is too small.\n", pParam->BSIM3v32noff); printf("Warning: Noff = %g is too small.\n", pParam->BSIM3v32noff);
} }
if (pParam->BSIM3v32noff > 4.0) if (pParam->BSIM3v32noff > 4.0)
{ fprintf(fplog, "Warning: Noff = %g is too large.\n", { fprintf(fplog, "Warning: Noff = %g is too large.\n",
pParam->BSIM3v32noff); pParam->BSIM3v32noff);
printf("Warning: Noff = %g is too large.\n", pParam->BSIM3v32noff); printf("Warning: Noff = %g is too large.\n", pParam->BSIM3v32noff);
} }
if (pParam->BSIM3v32voffcv < -0.5) if (pParam->BSIM3v32voffcv < -0.5)
{ fprintf(fplog, "Warning: Voffcv = %g is too small.\n", { fprintf(fplog, "Warning: Voffcv = %g is too small.\n",
pParam->BSIM3v32voffcv); pParam->BSIM3v32voffcv);
printf("Warning: Voffcv = %g is too small.\n", pParam->BSIM3v32voffcv); printf("Warning: Voffcv = %g is too small.\n", pParam->BSIM3v32voffcv);
} }
if (pParam->BSIM3v32voffcv > 0.5) if (pParam->BSIM3v32voffcv > 0.5)
{ fprintf(fplog, "Warning: Voffcv = %g is too large.\n", { fprintf(fplog, "Warning: Voffcv = %g is too large.\n",
pParam->BSIM3v32voffcv); pParam->BSIM3v32voffcv);
printf("Warning: Voffcv = %g is too large.\n", pParam->BSIM3v32voffcv); printf("Warning: Voffcv = %g is too large.\n", pParam->BSIM3v32voffcv);
} }
if (model->BSIM3v32ijth < 0.0) if (model->BSIM3v32ijth < 0.0)
{ fprintf(fplog, "Fatal: Ijth = %g cannot be negative.\n", { fprintf(fplog, "Fatal: Ijth = %g cannot be negative.\n",
model->BSIM3v32ijth); model->BSIM3v32ijth);
printf("Fatal: Ijth = %g cannot be negative.\n", model->BSIM3v32ijth); printf("Fatal: Ijth = %g cannot be negative.\n", model->BSIM3v32ijth);
Fatal_Flag = 1; Fatal_Flag = 1;
} }
/* Check capacitance parameters */ /* Check capacitance parameters */
if (pParam->BSIM3v32clc < 0.0) if (pParam->BSIM3v32clc < 0.0)
{ fprintf(fplog, "Fatal: Clc = %g is negative.\n", pParam->BSIM3v32clc); { fprintf(fplog, "Fatal: Clc = %g is negative.\n", pParam->BSIM3v32clc);
printf("Fatal: Clc = %g is negative.\n", pParam->BSIM3v32clc); printf("Fatal: Clc = %g is negative.\n", pParam->BSIM3v32clc);
Fatal_Flag = 1; Fatal_Flag = 1;
} }
if (pParam->BSIM3v32moin < 5.0) if (pParam->BSIM3v32moin < 5.0)
{ fprintf(fplog, "Warning: Moin = %g is too small.\n", { fprintf(fplog, "Warning: Moin = %g is too small.\n",
pParam->BSIM3v32moin); pParam->BSIM3v32moin);
printf("Warning: Moin = %g is too small.\n", pParam->BSIM3v32moin); printf("Warning: Moin = %g is too small.\n", pParam->BSIM3v32moin);
} }
if (pParam->BSIM3v32moin > 25.0) if (pParam->BSIM3v32moin > 25.0)
{ fprintf(fplog, "Warning: Moin = %g is too large.\n", { fprintf(fplog, "Warning: Moin = %g is too large.\n",
pParam->BSIM3v32moin); pParam->BSIM3v32moin);
printf("Warning: Moin = %g is too large.\n", pParam->BSIM3v32moin); printf("Warning: Moin = %g is too large.\n", pParam->BSIM3v32moin);
} }
if(model->BSIM3v32capMod ==3) { if(model->BSIM3v32capMod ==3) {
if (pParam->BSIM3v32acde < 0.4) if (pParam->BSIM3v32acde < 0.4)
{ fprintf(fplog, "Warning: Acde = %g is too small.\n", { fprintf(fplog, "Warning: Acde = %g is too small.\n",
pParam->BSIM3v32acde); pParam->BSIM3v32acde);
printf("Warning: Acde = %g is too small.\n", pParam->BSIM3v32acde); printf("Warning: Acde = %g is too small.\n", pParam->BSIM3v32acde);
} }
if (pParam->BSIM3v32acde > 1.6) if (pParam->BSIM3v32acde > 1.6)
{ fprintf(fplog, "Warning: Acde = %g is too large.\n", { fprintf(fplog, "Warning: Acde = %g is too large.\n",
pParam->BSIM3v32acde); pParam->BSIM3v32acde);
printf("Warning: Acde = %g is too large.\n", pParam->BSIM3v32acde); printf("Warning: Acde = %g is too large.\n", pParam->BSIM3v32acde);
} }
} }
if (model->BSIM3v32paramChk ==1) if (model->BSIM3v32paramChk ==1)
{ {
/* Check L and W parameters */ /* Check L and W parameters */
if (pParam->BSIM3v32leff <= 5.0e-8) if (pParam->BSIM3v32leff <= 5.0e-8)
{ fprintf(fplog, "Warning: Leff = %g may be too small.\n", { fprintf(fplog, "Warning: Leff = %g may be too small.\n",
pParam->BSIM3v32leff); pParam->BSIM3v32leff);
printf("Warning: Leff = %g may be too small.\n", printf("Warning: Leff = %g may be too small.\n",
pParam->BSIM3v32leff); pParam->BSIM3v32leff);
} }
if (pParam->BSIM3v32leffCV <= 5.0e-8) if (pParam->BSIM3v32leffCV <= 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->BSIM3v32leffCV); pParam->BSIM3v32leffCV);
printf("Warning: Leff for CV = %g may be too small.\n", printf("Warning: Leff for CV = %g may be too small.\n",
pParam->BSIM3v32leffCV); pParam->BSIM3v32leffCV);
} }
if (pParam->BSIM3v32weff <= 1.0e-7) if (pParam->BSIM3v32weff <= 1.0e-7)
{ fprintf(fplog, "Warning: Weff = %g may be too small.\n", { fprintf(fplog, "Warning: Weff = %g may be too small.\n",
pParam->BSIM3v32weff); pParam->BSIM3v32weff);
printf("Warning: Weff = %g may be too small.\n", printf("Warning: Weff = %g may be too small.\n",
pParam->BSIM3v32weff); pParam->BSIM3v32weff);
} }
if (pParam->BSIM3v32weffCV <= 1.0e-7) if (pParam->BSIM3v32weffCV <= 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->BSIM3v32weffCV); pParam->BSIM3v32weffCV);
printf("Warning: Weff for CV = %g may be too small.\n", printf("Warning: Weff for CV = %g may be too small.\n",
pParam->BSIM3v32weffCV); pParam->BSIM3v32weffCV);
} }
/* Check threshold voltage parameters */ /* Check threshold voltage parameters */
if (pParam->BSIM3v32nlx < 0.0) if (pParam->BSIM3v32nlx < 0.0)
{ fprintf(fplog, "Warning: Nlx = %g is negative.\n", pParam->BSIM3v32nlx); { fprintf(fplog, "Warning: Nlx = %g is negative.\n", pParam->BSIM3v32nlx);
printf("Warning: Nlx = %g is negative.\n", pParam->BSIM3v32nlx); printf("Warning: Nlx = %g is negative.\n", pParam->BSIM3v32nlx);
} }
if (model->BSIM3v32tox < 1.0e-9) if (model->BSIM3v32tox < 1.0e-9)
{ fprintf(fplog, "Warning: Tox = %g is less than 10A.\n", { fprintf(fplog, "Warning: Tox = %g is less than 10A.\n",
model->BSIM3v32tox); model->BSIM3v32tox);
printf("Warning: Tox = %g is less than 10A.\n", model->BSIM3v32tox); printf("Warning: Tox = %g is less than 10A.\n", model->BSIM3v32tox);
} }
if (pParam->BSIM3v32npeak <= 1.0e15) if (pParam->BSIM3v32npeak <= 1.0e15)
{ fprintf(fplog, "Warning: Nch = %g may be too small.\n", { fprintf(fplog, "Warning: Nch = %g may be too small.\n",
pParam->BSIM3v32npeak); pParam->BSIM3v32npeak);
printf("Warning: Nch = %g may be too small.\n", printf("Warning: Nch = %g may be too small.\n",
pParam->BSIM3v32npeak); pParam->BSIM3v32npeak);
} }
else if (pParam->BSIM3v32npeak >= 1.0e21) else if (pParam->BSIM3v32npeak >= 1.0e21)
{ fprintf(fplog, "Warning: Nch = %g may be too large.\n", { fprintf(fplog, "Warning: Nch = %g may be too large.\n",
pParam->BSIM3v32npeak); pParam->BSIM3v32npeak);
printf("Warning: Nch = %g may be too large.\n", printf("Warning: Nch = %g may be too large.\n",
pParam->BSIM3v32npeak); pParam->BSIM3v32npeak);
} }
if (pParam->BSIM3v32nsub <= 1.0e14) if (pParam->BSIM3v32nsub <= 1.0e14)
{ fprintf(fplog, "Warning: Nsub = %g may be too small.\n", { fprintf(fplog, "Warning: Nsub = %g may be too small.\n",
pParam->BSIM3v32nsub); pParam->BSIM3v32nsub);
printf("Warning: Nsub = %g may be too small.\n", printf("Warning: Nsub = %g may be too small.\n",
pParam->BSIM3v32nsub); pParam->BSIM3v32nsub);
} }
else if (pParam->BSIM3v32nsub >= 1.0e21) else if (pParam->BSIM3v32nsub >= 1.0e21)
{ fprintf(fplog, "Warning: Nsub = %g may be too large.\n", { fprintf(fplog, "Warning: Nsub = %g may be too large.\n",
pParam->BSIM3v32nsub); pParam->BSIM3v32nsub);
printf("Warning: Nsub = %g may be too large.\n", printf("Warning: Nsub = %g may be too large.\n",
pParam->BSIM3v32nsub); pParam->BSIM3v32nsub);
} }
if ((pParam->BSIM3v32ngate > 0.0) && if ((pParam->BSIM3v32ngate > 0.0) &&
(pParam->BSIM3v32ngate <= 1.e18)) (pParam->BSIM3v32ngate <= 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->BSIM3v32ngate); pParam->BSIM3v32ngate);
printf("Warning: Ngate = %g is less than 1.E18cm^-3.\n", printf("Warning: Ngate = %g is less than 1.E18cm^-3.\n",
pParam->BSIM3v32ngate); pParam->BSIM3v32ngate);
} }
if (pParam->BSIM3v32dvt0 < 0.0) if (pParam->BSIM3v32dvt0 < 0.0)
{ fprintf(fplog, "Warning: Dvt0 = %g is negative.\n", { fprintf(fplog, "Warning: Dvt0 = %g is negative.\n",
pParam->BSIM3v32dvt0); pParam->BSIM3v32dvt0);
printf("Warning: Dvt0 = %g is negative.\n", pParam->BSIM3v32dvt0); printf("Warning: Dvt0 = %g is negative.\n", pParam->BSIM3v32dvt0);
} }
if (fabs(1.0e-6 / (pParam->BSIM3v32w0 + pParam->BSIM3v32weff)) > 10.0) if (fabs(1.0e-6 / (pParam->BSIM3v32w0 + pParam->BSIM3v32weff)) > 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->BSIM3v32nfactor < 0.0) if (pParam->BSIM3v32nfactor < 0.0)
{ fprintf(fplog, "Warning: Nfactor = %g is negative.\n", { fprintf(fplog, "Warning: Nfactor = %g is negative.\n",
pParam->BSIM3v32nfactor); pParam->BSIM3v32nfactor);
printf("Warning: Nfactor = %g is negative.\n", pParam->BSIM3v32nfactor); printf("Warning: Nfactor = %g is negative.\n", pParam->BSIM3v32nfactor);
} }
if (pParam->BSIM3v32cdsc < 0.0) if (pParam->BSIM3v32cdsc < 0.0)
{ fprintf(fplog, "Warning: Cdsc = %g is negative.\n", { fprintf(fplog, "Warning: Cdsc = %g is negative.\n",
pParam->BSIM3v32cdsc); pParam->BSIM3v32cdsc);
printf("Warning: Cdsc = %g is negative.\n", pParam->BSIM3v32cdsc); printf("Warning: Cdsc = %g is negative.\n", pParam->BSIM3v32cdsc);
} }
if (pParam->BSIM3v32cdscd < 0.0) if (pParam->BSIM3v32cdscd < 0.0)
{ fprintf(fplog, "Warning: Cdscd = %g is negative.\n", { fprintf(fplog, "Warning: Cdscd = %g is negative.\n",
pParam->BSIM3v32cdscd); pParam->BSIM3v32cdscd);
printf("Warning: Cdscd = %g is negative.\n", pParam->BSIM3v32cdscd); printf("Warning: Cdscd = %g is negative.\n", pParam->BSIM3v32cdscd);
} }
/* Check DIBL parameters */ /* Check DIBL parameters */
if (pParam->BSIM3v32eta0 < 0.0) if (pParam->BSIM3v32eta0 < 0.0)
{ fprintf(fplog, "Warning: Eta0 = %g is negative.\n", { fprintf(fplog, "Warning: Eta0 = %g is negative.\n",
pParam->BSIM3v32eta0); pParam->BSIM3v32eta0);
printf("Warning: Eta0 = %g is negative.\n", pParam->BSIM3v32eta0); printf("Warning: Eta0 = %g is negative.\n", pParam->BSIM3v32eta0);
} }
/* Check Abulk parameters */ /* Check Abulk parameters */
if (fabs(1.0e-6 / (pParam->BSIM3v32b1 + pParam->BSIM3v32weff)) > 10.0) if (fabs(1.0e-6 / (pParam->BSIM3v32b1 + pParam->BSIM3v32weff)) > 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->BSIM3v32a2 < 0.01) if (pParam->BSIM3v32a2 < 0.01)
{ fprintf(fplog, "Warning: A2 = %g is too small. Set to 0.01.\n", pParam->BSIM3v32a2); { fprintf(fplog, "Warning: A2 = %g is too small. Set to 0.01.\n", pParam->BSIM3v32a2);
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->BSIM3v32a2); pParam->BSIM3v32a2);
pParam->BSIM3v32a2 = 0.01; pParam->BSIM3v32a2 = 0.01;
} }
else if (pParam->BSIM3v32a2 > 1.0) else if (pParam->BSIM3v32a2 > 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->BSIM3v32a2); pParam->BSIM3v32a2);
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->BSIM3v32a2); pParam->BSIM3v32a2);
pParam->BSIM3v32a2 = 1.0; pParam->BSIM3v32a2 = 1.0;
pParam->BSIM3v32a1 = 0.0; pParam->BSIM3v32a1 = 0.0;
} }
if (pParam->BSIM3v32rdsw < 0.0) if (pParam->BSIM3v32rdsw < 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->BSIM3v32rdsw); pParam->BSIM3v32rdsw);
printf("Warning: Rdsw = %g is negative. Set to zero.\n", printf("Warning: Rdsw = %g is negative. Set to zero.\n",
pParam->BSIM3v32rdsw); pParam->BSIM3v32rdsw);
pParam->BSIM3v32rdsw = 0.0; pParam->BSIM3v32rdsw = 0.0;
pParam->BSIM3v32rds0 = 0.0; pParam->BSIM3v32rds0 = 0.0;
} }
else if ((pParam->BSIM3v32rds0 > 0.0) && (pParam->BSIM3v32rds0 < 0.001)) else if ((pParam->BSIM3v32rds0 > 0.0) && (pParam->BSIM3v32rds0 < 0.001))
{ fprintf(fplog, "Warning: Rds at current temperature = %g is less than 0.001 ohm. Set to zero.\n", { fprintf(fplog, "Warning: Rds at current temperature = %g is less than 0.001 ohm. Set to zero.\n",
pParam->BSIM3v32rds0); pParam->BSIM3v32rds0);
printf("Warning: Rds at current temperature = %g is less than 0.001 ohm. Set to zero.\n", printf("Warning: Rds at current temperature = %g is less than 0.001 ohm. Set to zero.\n",
pParam->BSIM3v32rds0); pParam->BSIM3v32rds0);
pParam->BSIM3v32rds0 = 0.0; pParam->BSIM3v32rds0 = 0.0;
} }
if (pParam->BSIM3v32vsattemp < 1.0e3) if (pParam->BSIM3v32vsattemp < 1.0e3)
{ fprintf(fplog, "Warning: Vsat at current temperature = %g may be too small.\n", pParam->BSIM3v32vsattemp); { fprintf(fplog, "Warning: Vsat at current temperature = %g may be too small.\n", pParam->BSIM3v32vsattemp);
printf("Warning: Vsat at current temperature = %g may be too small.\n", pParam->BSIM3v32vsattemp); printf("Warning: Vsat at current temperature = %g may be too small.\n", pParam->BSIM3v32vsattemp);
} }
if (pParam->BSIM3v32pdibl1 < 0.0) if (pParam->BSIM3v32pdibl1 < 0.0)
{ fprintf(fplog, "Warning: Pdibl1 = %g is negative.\n", { fprintf(fplog, "Warning: Pdibl1 = %g is negative.\n",
pParam->BSIM3v32pdibl1); pParam->BSIM3v32pdibl1);
printf("Warning: Pdibl1 = %g is negative.\n", pParam->BSIM3v32pdibl1); printf("Warning: Pdibl1 = %g is negative.\n", pParam->BSIM3v32pdibl1);
} }
if (pParam->BSIM3v32pdibl2 < 0.0) if (pParam->BSIM3v32pdibl2 < 0.0)
{ fprintf(fplog, "Warning: Pdibl2 = %g is negative.\n", { fprintf(fplog, "Warning: Pdibl2 = %g is negative.\n",
pParam->BSIM3v32pdibl2); pParam->BSIM3v32pdibl2);
printf("Warning: Pdibl2 = %g is negative.\n", pParam->BSIM3v32pdibl2); printf("Warning: Pdibl2 = %g is negative.\n", pParam->BSIM3v32pdibl2);
} }
/* Check overlap capacitance parameters */ /* Check overlap capacitance parameters */
if (model->BSIM3v32cgdo < 0.0) if (model->BSIM3v32cgdo < 0.0)
{ fprintf(fplog, "Warning: cgdo = %g is negative. Set to zero.\n", model->BSIM3v32cgdo); { fprintf(fplog, "Warning: cgdo = %g is negative. Set to zero.\n", model->BSIM3v32cgdo);
printf("Warning: cgdo = %g is negative. Set to zero.\n", model->BSIM3v32cgdo); printf("Warning: cgdo = %g is negative. Set to zero.\n", model->BSIM3v32cgdo);
model->BSIM3v32cgdo = 0.0; model->BSIM3v32cgdo = 0.0;
} }
if (model->BSIM3v32cgso < 0.0) if (model->BSIM3v32cgso < 0.0)
{ fprintf(fplog, "Warning: cgso = %g is negative. Set to zero.\n", model->BSIM3v32cgso); { fprintf(fplog, "Warning: cgso = %g is negative. Set to zero.\n", model->BSIM3v32cgso);
printf("Warning: cgso = %g is negative. Set to zero.\n", model->BSIM3v32cgso); printf("Warning: cgso = %g is negative. Set to zero.\n", model->BSIM3v32cgso);
model->BSIM3v32cgso = 0.0; model->BSIM3v32cgso = 0.0;
} }
if (model->BSIM3v32cgbo < 0.0) if (model->BSIM3v32cgbo < 0.0)
{ fprintf(fplog, "Warning: cgbo = %g is negative. Set to zero.\n", model->BSIM3v32cgbo); { fprintf(fplog, "Warning: cgbo = %g is negative. Set to zero.\n", model->BSIM3v32cgbo);
printf("Warning: cgbo = %g is negative. Set to zero.\n", model->BSIM3v32cgbo); printf("Warning: cgbo = %g is negative. Set to zero.\n", model->BSIM3v32cgbo);
model->BSIM3v32cgbo = 0.0; model->BSIM3v32cgbo = 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");

View File

@ -32,20 +32,20 @@ double cbd, cbhat, cbs, cd, cdhat, tol, vgd, vgdo, vgs;
{ /* loop through all the instances of the model */ { /* loop through all the instances of the model */
for (here = model->BSIM3v32instances; here != NULL ; for (here = model->BSIM3v32instances; here != NULL ;
here=here->BSIM3v32nextInstance) here=here->BSIM3v32nextInstance)
{ {
vbs = model->BSIM3v32type vbs = model->BSIM3v32type
* (*(ckt->CKTrhsOld+here->BSIM3v32bNode) * (*(ckt->CKTrhsOld+here->BSIM3v32bNode)
- *(ckt->CKTrhsOld+here->BSIM3v32sNodePrime)); - *(ckt->CKTrhsOld+here->BSIM3v32sNodePrime));
vgs = model->BSIM3v32type vgs = model->BSIM3v32type
* (*(ckt->CKTrhsOld+here->BSIM3v32gNode) * (*(ckt->CKTrhsOld+here->BSIM3v32gNode)
- *(ckt->CKTrhsOld+here->BSIM3v32sNodePrime)); - *(ckt->CKTrhsOld+here->BSIM3v32sNodePrime));
vds = model->BSIM3v32type vds = model->BSIM3v32type
* (*(ckt->CKTrhsOld+here->BSIM3v32dNodePrime) * (*(ckt->CKTrhsOld+here->BSIM3v32dNodePrime)
- *(ckt->CKTrhsOld+here->BSIM3v32sNodePrime)); - *(ckt->CKTrhsOld+here->BSIM3v32sNodePrime));
vbd = vbs - vds; vbd = vbs - vds;
vgd = vgs - vds; vgd = vgs - vds;
vgdo = *(ckt->CKTstate0 + here->BSIM3v32vgs) vgdo = *(ckt->CKTstate0 + here->BSIM3v32vgs)
- *(ckt->CKTstate0 + here->BSIM3v32vds); - *(ckt->CKTstate0 + here->BSIM3v32vds);
delvbs = vbs - *(ckt->CKTstate0 + here->BSIM3v32vbs); delvbs = vbs - *(ckt->CKTstate0 + here->BSIM3v32vbs);
delvbd = vbd - *(ckt->CKTstate0 + here->BSIM3v32vbd); delvbd = vbd - *(ckt->CKTstate0 + here->BSIM3v32vbd);
delvgs = vgs - *(ckt->CKTstate0 + here->BSIM3v32vgs); delvgs = vgs - *(ckt->CKTstate0 + here->BSIM3v32vgs);
@ -54,47 +54,47 @@ double cbd, cbhat, cbs, cd, cdhat, tol, vgd, vgdo, vgs;
cd = here->BSIM3v32cd - here->BSIM3v32cbd; cd = here->BSIM3v32cd - here->BSIM3v32cbd;
if (here->BSIM3v32mode >= 0) if (here->BSIM3v32mode >= 0)
{ cd += here->BSIM3v32csub; { cd += here->BSIM3v32csub;
cdhat = cd - here->BSIM3v32gbd * delvbd cdhat = cd - here->BSIM3v32gbd * delvbd
+ (here->BSIM3v32gmbs + here->BSIM3v32gbbs) * delvbs + (here->BSIM3v32gmbs + here->BSIM3v32gbbs) * delvbs
+ (here->BSIM3v32gm + here->BSIM3v32gbgs) * delvgs + (here->BSIM3v32gm + here->BSIM3v32gbgs) * delvgs
+ (here->BSIM3v32gds + here->BSIM3v32gbds) * delvds; + (here->BSIM3v32gds + here->BSIM3v32gbds) * delvds;
} }
else else
{ cdhat = cd + (here->BSIM3v32gmbs - here->BSIM3v32gbd) * delvbd { cdhat = cd + (here->BSIM3v32gmbs - here->BSIM3v32gbd) * delvbd
+ here->BSIM3v32gm * delvgd - here->BSIM3v32gds * delvds; + here->BSIM3v32gm * delvgd - here->BSIM3v32gds * delvds;
} }
/* /*
* check convergence * check convergence
*/ */
if ((here->BSIM3v32off == 0) || (!(ckt->CKTmode & MODEINITFIX))) if ((here->BSIM3v32off == 0) || (!(ckt->CKTmode & MODEINITFIX)))
{ tol = ckt->CKTreltol * MAX(fabs(cdhat), fabs(cd)) { tol = ckt->CKTreltol * MAX(fabs(cdhat), fabs(cd))
+ ckt->CKTabstol; + ckt->CKTabstol;
if (fabs(cdhat - cd) >= tol) if (fabs(cdhat - cd) >= tol)
{ ckt->CKTnoncon++; { ckt->CKTnoncon++;
return(OK); return(OK);
} }
cbs = here->BSIM3v32cbs; cbs = here->BSIM3v32cbs;
cbd = here->BSIM3v32cbd; cbd = here->BSIM3v32cbd;
if (here->BSIM3v32mode >= 0) if (here->BSIM3v32mode >= 0)
{ cbhat = cbs + cbd - here->BSIM3v32csub { cbhat = cbs + cbd - here->BSIM3v32csub
+ here->BSIM3v32gbd * delvbd + here->BSIM3v32gbd * delvbd
+ (here->BSIM3v32gbs - here->BSIM3v32gbbs) * delvbs + (here->BSIM3v32gbs - here->BSIM3v32gbbs) * delvbs
- here->BSIM3v32gbgs * delvgs - here->BSIM3v32gbgs * delvgs
- here->BSIM3v32gbds * delvds; - here->BSIM3v32gbds * delvds;
} }
else else
{ cbhat = cbs + cbd - here->BSIM3v32csub { cbhat = cbs + cbd - here->BSIM3v32csub
+ here->BSIM3v32gbs * delvbs + here->BSIM3v32gbs * delvbs
+ (here->BSIM3v32gbd - here->BSIM3v32gbbs) * delvbd + (here->BSIM3v32gbd - here->BSIM3v32gbbs) * delvbd
- here->BSIM3v32gbgs * delvgd - here->BSIM3v32gbgs * delvgd
+ here->BSIM3v32gbds * delvds; + here->BSIM3v32gbds * delvds;
} }
tol = ckt->CKTreltol * MAX(fabs(cbhat), tol = ckt->CKTreltol * MAX(fabs(cbhat),
fabs(cbs + cbd - here->BSIM3v32csub)) + ckt->CKTabstol; fabs(cbs + cbd - here->BSIM3v32csub)) + ckt->CKTabstol;
if (fabs(cbhat - (cbs + cbd - here->BSIM3v32csub)) > tol) if (fabs(cbhat - (cbs + cbd - here->BSIM3v32csub)) > tol)
{ ckt->CKTnoncon++; { ckt->CKTnoncon++;
return(OK); return(OK);
} }
} }

View File

@ -28,8 +28,8 @@ BSIM3v32instance *here;
for (; model ; model = model->BSIM3v32nextModel) for (; model ; model = model->BSIM3v32nextModel)
{ prev = &(model->BSIM3v32instances); { prev = &(model->BSIM3v32instances);
for (here = *prev; here ; here = *prev) for (here = *prev; here ; here = *prev)
{ if (here->BSIM3v32name == name || (fast && here==*fast)) { if (here->BSIM3v32name == name || (fast && here==*fast))
{ *prev= here->BSIM3v32nextInstance; { *prev= here->BSIM3v32nextInstance;
FREE(here); FREE(here);
return(OK); return(OK);
} }

View File

@ -23,18 +23,18 @@ BSIM3v32instance *here;
for (; model ; model = model->BSIM3v32nextModel) for (; model ; model = model->BSIM3v32nextModel)
{ for (here = model->BSIM3v32instances; here; here = here->BSIM3v32nextInstance) { for (here = model->BSIM3v32instances; here; here = here->BSIM3v32nextInstance)
{ {
if (!here->BSIM3v32icVBSGiven) if (!here->BSIM3v32icVBSGiven)
{ here->BSIM3v32icVBS = *(ckt->CKTrhs + here->BSIM3v32bNode) { here->BSIM3v32icVBS = *(ckt->CKTrhs + here->BSIM3v32bNode)
- *(ckt->CKTrhs + here->BSIM3v32sNode); - *(ckt->CKTrhs + here->BSIM3v32sNode);
} }
if (!here->BSIM3v32icVDSGiven) if (!here->BSIM3v32icVDSGiven)
{ here->BSIM3v32icVDS = *(ckt->CKTrhs + here->BSIM3v32dNode) { here->BSIM3v32icVDS = *(ckt->CKTrhs + here->BSIM3v32dNode)
- *(ckt->CKTrhs + here->BSIM3v32sNode); - *(ckt->CKTrhs + here->BSIM3v32sNode);
} }
if (!here->BSIM3v32icVGSGiven) if (!here->BSIM3v32icVGSGiven)
{ here->BSIM3v32icVGS = *(ckt->CKTrhs + here->BSIM3v32gNode) { here->BSIM3v32icVGS = *(ckt->CKTrhs + here->BSIM3v32gNode)
- *(ckt->CKTrhs + here->BSIM3v32sNode); - *(ckt->CKTrhs + here->BSIM3v32sNode);
} }
} }
} }

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