Merge remote branch 'origin/new_kirchhoff-4' into KLU-kirchhoff-4
Conflicts: configure.ac src/include/ngspice/devdefs.h src/include/ngspice/smpdefs.h src/maths/sparse/spsmp.c src/spicelib/devices/asrc/asrcinit.c src/spicelib/devices/bjt/Makefile.am src/spicelib/devices/bjt/bjtinit.c src/spicelib/devices/bsim1/Makefile.am src/spicelib/devices/bsim1/bsim1ext.h src/spicelib/devices/bsim1/bsim1init.c src/spicelib/devices/bsim2/Makefile.am src/spicelib/devices/bsim2/bsim2ext.h src/spicelib/devices/bsim2/bsim2init.c src/spicelib/devices/bsim3/Makefile.am src/spicelib/devices/bsim3/bsim3ext.h src/spicelib/devices/bsim3/bsim3init.c src/spicelib/devices/bsim3soi_dd/Makefile.am src/spicelib/devices/bsim3soi_dd/b3soiddext.h src/spicelib/devices/bsim3soi_dd/b3soiddinit.c src/spicelib/devices/bsim3soi_dd/b3soiddset.c src/spicelib/devices/bsim3soi_fd/Makefile.am src/spicelib/devices/bsim3soi_fd/b3soifdext.h src/spicelib/devices/bsim3soi_fd/b3soifdinit.c src/spicelib/devices/bsim3soi_pd/Makefile.am src/spicelib/devices/bsim3soi_pd/b3soipdext.h src/spicelib/devices/bsim3soi_pd/b3soipdinit.c src/spicelib/devices/bsim3soi_pd/b3soipdset.c src/spicelib/devices/bsim3v0/Makefile.am src/spicelib/devices/bsim3v0/bsim3v0ext.h src/spicelib/devices/bsim3v0/bsim3v0init.c src/spicelib/devices/bsim3v1/Makefile.am src/spicelib/devices/bsim3v1/bsim3v1ext.h src/spicelib/devices/bsim3v1/bsim3v1init.c src/spicelib/devices/bsim3v32/Makefile.am src/spicelib/devices/bsim3v32/bsim3v32ext.h src/spicelib/devices/bsim3v32/bsim3v32init.c src/spicelib/devices/bsim4/Makefile.am src/spicelib/devices/bsim4/bsim4def.h src/spicelib/devices/bsim4/bsim4ext.h src/spicelib/devices/bsim4/bsim4init.c src/spicelib/devices/bsim4v4/Makefile.am src/spicelib/devices/bsim4v4/bsim4v4ext.h src/spicelib/devices/bsim4v4/bsim4v4init.c src/spicelib/devices/bsim4v5/Makefile.am src/spicelib/devices/bsim4v5/b4v5set.c src/spicelib/devices/bsim4v5/bsim4v5ext.h src/spicelib/devices/bsim4v5/bsim4v5init.c src/spicelib/devices/bsim4v6/Makefile.am src/spicelib/devices/bsim4v6/bsim4v6ext.h src/spicelib/devices/bsim4v6/bsim4v6init.c src/spicelib/devices/bsimsoi/Makefile.am src/spicelib/devices/bsimsoi/b4soiext.h src/spicelib/devices/bsimsoi/b4soiinit.c src/spicelib/devices/bsimsoi/b4soiset.c src/spicelib/devices/cap/Makefile.am src/spicelib/devices/cap/capdefs.h src/spicelib/devices/cap/capext.h src/spicelib/devices/cap/capinit.c src/spicelib/devices/cccs/cccsext.h src/spicelib/devices/cccs/cccsinit.c src/spicelib/devices/ccvs/ccvsinit.c src/spicelib/devices/cpl/cplinit.c src/spicelib/devices/csw/cswinit.c src/spicelib/devices/dio/Makefile.am src/spicelib/devices/dio/diodefs.h src/spicelib/devices/dio/dioext.h src/spicelib/devices/dio/dioinit.c src/spicelib/devices/hfet1/Makefile.am src/spicelib/devices/hfet1/hfetext.h src/spicelib/devices/hfet1/hfetinit.c src/spicelib/devices/hfet2/Makefile.am src/spicelib/devices/hfet2/hfet2ext.h src/spicelib/devices/hfet2/hfet2init.c src/spicelib/devices/hisim2/Makefile.am src/spicelib/devices/hisim2/hsm2ext.h src/spicelib/devices/hisim2/hsm2init.c src/spicelib/devices/hisimhv1/hsmhvext.h src/spicelib/devices/hisimhv1/hsmhvinit.c src/spicelib/devices/ind/Makefile.am src/spicelib/devices/ind/inddefs.h src/spicelib/devices/ind/indinit.c src/spicelib/devices/isrc/isrcinit.c src/spicelib/devices/jfet/Makefile.am src/spicelib/devices/jfet/jfetext.h src/spicelib/devices/jfet/jfetinit.c src/spicelib/devices/jfet/jfetset.c src/spicelib/devices/jfet2/Makefile.am src/spicelib/devices/jfet2/jfet2ext.h src/spicelib/devices/jfet2/jfet2init.c src/spicelib/devices/jfet2/jfet2set.c src/spicelib/devices/ltra/ltrainit.c src/spicelib/devices/mes/Makefile.am src/spicelib/devices/mes/mesext.h src/spicelib/devices/mes/mesinit.c src/spicelib/devices/mes/messetup.c src/spicelib/devices/mesa/Makefile.am src/spicelib/devices/mesa/mesaext.h src/spicelib/devices/mesa/mesainit.c src/spicelib/devices/mos1/Makefile.am src/spicelib/devices/mos1/mos1ext.h src/spicelib/devices/mos1/mos1init.c src/spicelib/devices/mos2/Makefile.am src/spicelib/devices/mos2/mos2ext.h src/spicelib/devices/mos2/mos2init.c src/spicelib/devices/mos3/Makefile.am src/spicelib/devices/mos3/mos3ext.h src/spicelib/devices/mos3/mos3init.c src/spicelib/devices/mos6/Makefile.am src/spicelib/devices/mos6/mos6ext.h src/spicelib/devices/mos6/mos6init.c src/spicelib/devices/mos9/Makefile.am src/spicelib/devices/mos9/mos9ext.h src/spicelib/devices/mos9/mos9init.c src/spicelib/devices/res/Makefile.am src/spicelib/devices/res/resdefs.h src/spicelib/devices/res/resext.h src/spicelib/devices/res/resinit.c src/spicelib/devices/soi3/Makefile.am src/spicelib/devices/soi3/soi3ext.h src/spicelib/devices/soi3/soi3init.c src/spicelib/devices/sw/swinit.c src/spicelib/devices/tra/trainit.c src/spicelib/devices/txl/txlinit.c src/spicelib/devices/txl/txlsetup.c src/spicelib/devices/urc/urcinit.c src/spicelib/devices/vbic/Makefile.am src/spicelib/devices/vbic/vbicinit.c src/spicelib/devices/vccs/vccsinit.c src/spicelib/devices/vcvs/vcvsext.h src/spicelib/devices/vcvs/vcvsinit.c src/spicelib/devices/vsrc/Makefile.am src/spicelib/devices/vsrc/vsrcdefs.h src/spicelib/devices/vsrc/vsrcext.h src/spicelib/devices/vsrc/vsrcinit.c
This commit is contained in:
commit
f5aefd7db8
10
INSTALL
10
INSTALL
|
|
@ -250,6 +250,14 @@ Most of the options now following are not well maintained, are not tested or eve
|
||||||
"tclspice" is compiled and installed instead of
|
"tclspice" is compiled and installed instead of
|
||||||
plain ngspice.
|
plain ngspice.
|
||||||
|
|
||||||
|
--with-ngshared
|
||||||
|
This option let you compile ngspice as a shared
|
||||||
|
library or dll, allowing an application controlling
|
||||||
|
ngspice. This option excludes using --with-x or
|
||||||
|
--with-wingui. Useful additional options are
|
||||||
|
--enable-xspice --enable-cider --enable-openmp.
|
||||||
|
No graphics inetrface is provided, this has to be
|
||||||
|
handled by the controlling application.
|
||||||
|
|
||||||
1.4.3 Options Useful for Debugging Ngspice
|
1.4.3 Options Useful for Debugging Ngspice
|
||||||
|
|
||||||
|
|
@ -538,7 +546,7 @@ Most of the options now following are not well maintained, are not tested or eve
|
||||||
|
|
||||||
9.2 make ngspice with MS Visual Studio 2008
|
9.2 make ngspice with MS Visual Studio 2008
|
||||||
|
|
||||||
ngspice may be compiled with MS Visual Studio 2008.
|
ngspice may be compiled with MS Visual Studio 2008 or 2010.
|
||||||
|
|
||||||
CIDER and XSPICE are included, but the code models for XSPICE
|
CIDER and XSPICE are included, but the code models for XSPICE
|
||||||
(*.cm) are not (yet) made. You may however use the code models
|
(*.cm) are not (yet) made. You may however use the code models
|
||||||
|
|
|
||||||
14
README.adms
14
README.adms
|
|
@ -22,6 +22,20 @@
|
||||||
* 02110-1301 USA *
|
* 02110-1301 USA *
|
||||||
***************************************************************************
|
***************************************************************************
|
||||||
|
|
||||||
|
WARNING!
|
||||||
|
|
||||||
|
The text in this document has been prepared in 2006 and is outdated. It is
|
||||||
|
provided here only for reference and may provide some (historical)
|
||||||
|
information.
|
||||||
|
|
||||||
|
Please refer to the ngspice adms web page at
|
||||||
|
http://ngspice.sourceforge.net/admshowto.html
|
||||||
|
for actual information on how to integrate Verilog A device models into
|
||||||
|
ngspice.
|
||||||
|
|
||||||
|
Holger Vogt, May 2013
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
INTRODUCTION
|
INTRODUCTION
|
||||||
|
|
||||||
|
|
|
||||||
16
configure.ac
16
configure.ac
|
|
@ -182,6 +182,10 @@ AC_ARG_WITH([tcl],
|
||||||
AC_ARG_WITH([ngshared],
|
AC_ARG_WITH([ngshared],
|
||||||
[AS_HELP_STRING([--with-ngshared], [Compiles ngspice as shared library (dll)])])
|
[AS_HELP_STRING([--with-ngshared], [Compiles ngspice as shared library (dll)])])
|
||||||
|
|
||||||
|
# --enable-kirchhoff: enable KCL
|
||||||
|
AC_ARG_ENABLE([kirchhoff],
|
||||||
|
[AS_HELP_STRING([--enable-kirchhoff], [Enables the Kirchhoff Current Law Verification])])
|
||||||
|
|
||||||
# readline and editline cannot both be enabled
|
# readline and editline cannot both be enabled
|
||||||
if test "x$with_editline" = xyes; then
|
if test "x$with_editline" = xyes; then
|
||||||
if test "x$with_readline" = xyes; then
|
if test "x$with_readline" = xyes; then
|
||||||
|
|
@ -801,6 +805,7 @@ AC_MSG_RESULT([Settings which were chosen:])
|
||||||
if test "x$enable_sense2" = xyes; then
|
if test "x$enable_sense2" = xyes; then
|
||||||
AC_DEFINE([WANT_SENSE2], [], [Define if we want spice2 sensitivity analysis])
|
AC_DEFINE([WANT_SENSE2], [], [Define if we want spice2 sensitivity analysis])
|
||||||
AC_MSG_RESULT([Spice2 sensitivity analysis enabled])
|
AC_MSG_RESULT([Spice2 sensitivity analysis enabled])
|
||||||
|
AC_MSG_WARN([This feature is UNSUPPORTED])
|
||||||
fi
|
fi
|
||||||
if test "x$enable_nobypass" = xyes; then
|
if test "x$enable_nobypass" = xyes; then
|
||||||
AC_DEFINE([NOBYPASS], [], [Define if we want NOBYPASS])
|
AC_DEFINE([NOBYPASS], [], [Define if we want NOBYPASS])
|
||||||
|
|
@ -856,7 +861,7 @@ if test "x$enable_pzdebug" = xyes; then
|
||||||
fi
|
fi
|
||||||
if test "x$enable_pss" = xyes; then
|
if test "x$enable_pss" = xyes; then
|
||||||
AC_DEFINE([WITH_PSS], [], [Define if you want PSS analysis])
|
AC_DEFINE([WITH_PSS], [], [Define if you want PSS analysis])
|
||||||
AC_MSG_RESULT(WARNING: PSS analysis enabled)
|
AC_MSG_RESULT([WARNING: PSS analysis enabled])
|
||||||
fi
|
fi
|
||||||
if test "x$enable_blktmsdebug" = xyes; then
|
if test "x$enable_blktmsdebug" = xyes; then
|
||||||
AC_DEFINE([D_DBG_BLOCKTIMES], [], [Define if we want debug distortion analysis (BLOCKTIMES)])
|
AC_DEFINE([D_DBG_BLOCKTIMES], [], [Define if we want debug distortion analysis (BLOCKTIMES)])
|
||||||
|
|
@ -879,6 +884,12 @@ fi
|
||||||
AC_SUBST([XGRAPHDIR])
|
AC_SUBST([XGRAPHDIR])
|
||||||
AC_SUBST([NOTXGRAPH])
|
AC_SUBST([NOTXGRAPH])
|
||||||
|
|
||||||
|
if test "x$enable_kirchhoff" = xyes; then
|
||||||
|
AC_DEFINE([KIRCHHOFF], [], [Define if we want to enable the Kirchhoff Current Law Verification])
|
||||||
|
AC_MSG_RESULT([WARNING: Kirchhoff Current Law Verification Enabled (experimental)])
|
||||||
|
fi
|
||||||
|
AM_CONDITIONAL([KIRCHHOFF_WANTED], [test "x$enable_kirchhoff" = xyes])
|
||||||
|
|
||||||
AC_CHECK_PROGS([YACC], ['bison -y' byacc yacc])
|
AC_CHECK_PROGS([YACC], ['bison -y' byacc yacc])
|
||||||
|
|
||||||
################# XSPICE ##################################################
|
################# XSPICE ##################################################
|
||||||
|
|
@ -945,6 +956,8 @@ AM_CONDITIONAL([NUMDEV_WANTED], [test "x$enable_cider" = xyes])
|
||||||
|
|
||||||
AM_CONDITIONAL([PSS_WANTED], [test "x$enable_pss" = xyes])
|
AM_CONDITIONAL([PSS_WANTED], [test "x$enable_pss" = xyes])
|
||||||
|
|
||||||
|
AM_CONDITIONAL([SENSE2_WANTED], [test "x$enable_sense2" = xyes])
|
||||||
|
|
||||||
# adms option
|
# adms option
|
||||||
if test "x$enable_adms" = xyes ; then
|
if test "x$enable_adms" = xyes ; then
|
||||||
AC_MSG_RESULT([**********************************
|
AC_MSG_RESULT([**********************************
|
||||||
|
|
@ -1216,6 +1229,7 @@ AC_CONFIG_FILES([Makefile
|
||||||
src/xspice/enh/Makefile
|
src/xspice/enh/Makefile
|
||||||
src/xspice/ipc/Makefile
|
src/xspice/ipc/Makefile
|
||||||
src/xspice/idn/Makefile
|
src/xspice/idn/Makefile
|
||||||
|
src/unsupported/Makefile
|
||||||
tests/Makefile
|
tests/Makefile
|
||||||
tests/bsim1/Makefile
|
tests/bsim1/Makefile
|
||||||
tests/bsim2/Makefile
|
tests/bsim2/Makefile
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
DBj_gidl_n
|
||||||
|
|
||||||
|
.INCLUDE 45nm_MGK_car2_gidlgisl.pm
|
||||||
|
.OPTIONS GMIN=1e-18 abstol=1e-19
|
||||||
|
|
||||||
|
*Definizione dei parametri
|
||||||
|
.PARAM Lmin=45n
|
||||||
|
.PARAM Wmin=45n
|
||||||
|
.PARAM Ldiff=90n
|
||||||
|
|
||||||
|
*Descrizione della cella
|
||||||
|
Mp drain gate source body nmos W={Wmin} L={Lmin} AS={Wmin*Ldiff} AD={Wmin*Ldiff} PS={2*(Ldiff+Wmin)} PD={2*(Ldiff+Wmin)}
|
||||||
|
Vd drain alim 0V
|
||||||
|
Vg gate 0 0V
|
||||||
|
Vs source alim 0V
|
||||||
|
Vb body 0 0V
|
||||||
|
Vdd alim 0 0.05V
|
||||||
|
|
||||||
|
*Definizione del tipo di analisi
|
||||||
|
.dc Vdd 0.0 1.2 0.1
|
||||||
|
.print all
|
||||||
|
.END
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
DBj_gidl_p
|
||||||
|
|
||||||
|
.INCLUDE 45nm_MGK_car2_gidlgisl.pm
|
||||||
|
.OPTIONS GMIN=1e-18 abstol=1e-24 vntol=1e-24
|
||||||
|
|
||||||
|
*Definizione dei parametri
|
||||||
|
.PARAM Lmin=45n
|
||||||
|
.PARAM Wmin=45n
|
||||||
|
.PARAM Ldiff=90n
|
||||||
|
|
||||||
|
*Descrizione della cella
|
||||||
|
Mp drain gate source body pmos W={Wmin} L={Lmin} AS={Wmin*Ldiff} AD={Wmin*Ldiff} PS={2*(Ldiff+Wmin)} PD={2*(Ldiff+Wmin)}
|
||||||
|
Vd drain 0 0V
|
||||||
|
Vg gate alim 0V
|
||||||
|
Vs source 0 0V
|
||||||
|
Vb body alim 0V
|
||||||
|
Vdd alim 0 0.05V
|
||||||
|
|
||||||
|
*Definizione del tipo di analisi
|
||||||
|
.dc Vdd 0.0 1.2 0.1
|
||||||
|
.print all
|
||||||
|
.END
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
DBj_gidl_p
|
||||||
|
|
||||||
|
.INCLUDE 45nm_MGK_car2_gidlgisl.pm
|
||||||
|
.OPTIONS GMIN=1e-18 abstol=1e-19
|
||||||
|
|
||||||
|
*Definizione dei parametri
|
||||||
|
.PARAM Lmin=45n
|
||||||
|
.PARAM Wmin=45n
|
||||||
|
.PARAM Ldiff=90n
|
||||||
|
|
||||||
|
*Descrizione della cella
|
||||||
|
Mp drain gate source body pmos W={Wmin} L={Lmin} AS={Wmin*Ldiff} AD={Wmin*Ldiff} PS={2*(Ldiff+Wmin)} PD={2*(Ldiff+Wmin)}
|
||||||
|
Vd drain 0 -1V
|
||||||
|
Vg gate alim 0V
|
||||||
|
Vs source 0 -1V
|
||||||
|
Vb body alim 0V
|
||||||
|
Vdd alim 0 -1.05V
|
||||||
|
|
||||||
|
*Definizione del tipo di analisi
|
||||||
|
.dc Vdd 0.0 1.2 0.1
|
||||||
|
.print all
|
||||||
|
.END
|
||||||
|
|
@ -0,0 +1,120 @@
|
||||||
|
.model nmos nmos level=54
|
||||||
|
+version = 4.7.0 binunit = 1 paramchk= 1 mobmod = 0
|
||||||
|
+capmod = 2 igcmod = 0 igbmod = 0 geomod = 1
|
||||||
|
+diomod = 1 rdsmod = 0 rbodymod= 1 rgatemod= 1
|
||||||
|
+permod = 1 acnqsmod= 0 trnqsmod= 0
|
||||||
|
+tnom = 27 toxe = 9e-010 toxp = 6.5e-010 toxm = 9e-010
|
||||||
|
+dtox = 2.5e-010 epsrox = 3.9 wint = 5e-009 lint = 2.7e-009
|
||||||
|
+ll = 0 wl = 0 lln = 1 wln = 1
|
||||||
|
+lw = 0 ww = 0 lwn = 1 wwn = 1
|
||||||
|
+lwl = 0 wwl = 0 xpart = 0 toxref = 9e-010 xl = -20e-9
|
||||||
|
+dlcig = 2.7e-009
|
||||||
|
+vth0 = 0.3423 k1 = 0.2 k2 = 0 k3 = 0
|
||||||
|
+k3b = 0 w0 = 2.5e-006 dvt0 = 1 dvt1 = 2
|
||||||
|
+dvt2 = 0 dvt0w = 0 dvt1w = 0 dvt2w = 0
|
||||||
|
+dsub = 0.078 minv = 0.05 voffl = 0 dvtp0 = 1e-010
|
||||||
|
+dvtp1 = 0.1 lpe0 = 0 lpeb = 0 xj = 1.4e-008
|
||||||
|
+ngate = 1e+023 ndep = 6.5e+018 nsd = 2e+020 phin = 0
|
||||||
|
+cdsc = 0 cdscb = 0 cdscd = 0 cit = 0
|
||||||
|
+voff = -0.13 nfactor = 1.9 eta0 = 0.0055 etab = 0
|
||||||
|
+vfb = -1.058 u0 = 0.02947 ua = -5e-010 ub = 1.7e-018
|
||||||
|
+uc = 0 vsat = 159550 a0 = 1 ags = 0
|
||||||
|
+a1 = 0 a2 = 1 b0 = 0 b1 = 0
|
||||||
|
+keta = 0.04 dwg = 0 dwb = 0 pclm = 0.06
|
||||||
|
+pdiblc1 = 0.001 pdiblc2 = 0.001 pdiblcb = -0.005 drout = 0.5
|
||||||
|
+pvag = 1e-020 delta = 0.01 pscbe1 = 2.0e+009 pscbe2 = 1e-007
|
||||||
|
+fprout = 0.2 pdits = 0.01 pditsd = 0.23 pditsl = 2300000
|
||||||
|
+rsh = 5 rdsw = 105 rsw = 52.5 rdw = 52.5
|
||||||
|
+rdswmin = 0 rdwmin = 0 rswmin = 0 prwg = 0
|
||||||
|
+prwb = 0 wr = 1 alpha0 = 0.0 alpha1 = 0.00
|
||||||
|
+beta0 = 30 agidl = 0.0002 bgidl = 2.1e+009 cgidl = 0.0002
|
||||||
|
+egidl = 0.8 aigbacc = 0.012 bigbacc = 0.0028 cigbacc = 0.002
|
||||||
|
+nigbacc = 1 aigbinv = 0.014 bigbinv = 0.004 cigbinv = 0.004
|
||||||
|
+eigbinv = 1.1 nigbinv = 3 aigc = 0.018029 bigc = 0.0029
|
||||||
|
+cigc = 0.002 aigsd = 0.018029 bigsd = 0.0029 cigsd = 0.002
|
||||||
|
+nigc = 1 poxedge = 1 pigcd = 1 ntox = 1
|
||||||
|
+xrcrg1 = 12 xrcrg2 = 5
|
||||||
|
+cgso = 1e-010 cgdo = 1e-010 cgbo = 0 cgdl = 7.5e-013
|
||||||
|
+cgsl = 7.5e-013 clc = 1e-007 cle = 0.6 cf = 1.1e-010
|
||||||
|
+ckappas = 0.6 ckappad = 0.6 vfbcv = -1 acde = 1
|
||||||
|
+moin = 15 noff = 1 voffcv = 0
|
||||||
|
+kt1 = -0.154 kt1l = 0 kt2 = 0.022 ute = -1.1
|
||||||
|
+ua1 = 1e-009 ub1 = -1e-018 uc1 = -5.6e-011 prt = 0
|
||||||
|
+at = 33000
|
||||||
|
+fnoimod = 1 tnoimod = 0 noia = 6.25e+041 noib = 3.125e+026
|
||||||
|
+noic = 8.75e+009 em = 41000000 af = 1 ef = 1
|
||||||
|
+kf = 0 tnoia = 1.5 tnoib = 3.5 ntnoi = 1
|
||||||
|
+jss = 0.0 jsws = 0.0 jswgs = 0.0 njs = 1
|
||||||
|
+ijthsfwd= 0.1 ijthsrev= 0.1 bvs = 10 xjbvs = 1
|
||||||
|
+jsd = 0.0 jswd = 0.0 jswgd = 0.0 xjbvd = 1
|
||||||
|
+pbs = 1 cjs = 0.0018 mjs = 0.5 pbsws = 1
|
||||||
|
+cjsws = 1.2e-010 mjsws = 0.33 cjswgs = 2.1e-010 cjd = 0.0018
|
||||||
|
+cjswd = 1.2e-010 mjswd = 0.33 pbswgd = 1 cjswgd = 2.1e-010
|
||||||
|
+mjswgd = 0.33 tpb = 0 tcj = 0 tpbsw = 0
|
||||||
|
+tcjsw = 0 tpbswg = 0 tcjswg = 0 xtis = 3
|
||||||
|
+dmcg = 0 dmci = 0 dmdg = 0 dmcgt = 0
|
||||||
|
+dwj = 0 xgw = 0 xgl = 0
|
||||||
|
+rshg = 0.4 gbmin = 1e-010 rbpb = 5 rbpd = 15
|
||||||
|
+rbps = 15 rbdb = 15 rbsb = 15 ngcon = 1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.model pmos pmos level = 54
|
||||||
|
+version = 4.7.0 binunit = 1 paramchk= 1 mobmod = 0
|
||||||
|
+capmod = 2 igcmod = 0 igbmod = 0 geomod = 1
|
||||||
|
+diomod = 1 rdsmod = 0 rbodymod= 1 rgatemod= 1
|
||||||
|
+permod = 1 acnqsmod= 0 trnqsmod= 0
|
||||||
|
+tnom = 27 toxe = 9.2e-010 toxp = 6.5e-010 toxm = 9.2e-010
|
||||||
|
+dtox = 2.7e-010 epsrox = 3.9 wint = 5e-009 lint = 2.7e-009
|
||||||
|
+ll = 0 wl = 0 lln = 1 wln = 1
|
||||||
|
+lw = 0 ww = 0 lwn = 1 wwn = 1
|
||||||
|
+lwl = 0 wwl = 0 xpart = 0 toxref = 9.2e-010 xl = -20e-9
|
||||||
|
+dlcig = 2.7e-009
|
||||||
|
+vth0 = -0.23122 k1 = 0.2 k2 = -0.01 k3 = 0
|
||||||
|
+k3b = 0 w0 = 2.5e-006 dvt0 = 1 dvt1 = 2
|
||||||
|
+dvt2 = -0.032 dvt0w = 0 dvt1w = 0 dvt2w = 0
|
||||||
|
+dsub = 0.1 minv = 0.05 voffl = 0 dvtp0 = 1e-011
|
||||||
|
+dvtp1 = 0.05 lpe0 = 0 lpeb = 0 xj = 1.4e-008
|
||||||
|
+ngate = 1e+023 ndep = 2.8e+018 nsd = 2e+020 phin = 0
|
||||||
|
+cdsc = 0 cdscb = 0 cdscd = 0 cit = 0
|
||||||
|
+voff = -0.13 nfactor = 1.9 eta0 = 0.0049 etab = 0
|
||||||
|
+vfb = -1.058 u0 = 0.00391 ua = -5e-010 ub = 1.6e-018
|
||||||
|
+uc = 0 vsat = 78000 a0 = 1 ags = 1e-020
|
||||||
|
+a1 = 0 a2 = 1 b0 = 0 b1 = 0
|
||||||
|
+keta = -0.047 dwg = 0 dwb = 0 pclm = 0.1
|
||||||
|
+pdiblc1 = 0.001 pdiblc2 = 0.001 pdiblcb = 3.4e-008 drout = 0.6
|
||||||
|
+pvag = 1e-020 delta = 0.01 pscbe1 = 2e+009 pscbe2 = 9.58e-007
|
||||||
|
+fprout = 0.2 pdits = 0.08 pditsd = 0.23 pditsl = 2300000
|
||||||
|
+rsh = 5 rdsw = 105 rsw = 52.5 rdw = 52.5
|
||||||
|
+rdswmin = 0 rdwmin = 0 rswmin = 0 prwg = 0
|
||||||
|
+prwb = 0 wr = 1 alpha0 = 0.0 alpha1 = 0.00
|
||||||
|
+beta0 = 30 agidl = 0.0002 bgidl = 2.1e+009 cgidl = 0.0002
|
||||||
|
+egidl = 0.8 aigbacc = 0.012 bigbacc = 0.0028 cigbacc = 0.002
|
||||||
|
+nigbacc = 1 aigbinv = 0.014 bigbinv = 0.004 cigbinv = 0.004
|
||||||
|
+eigbinv = 1.1 nigbinv = 3 aigc = 0.010687 bigc = 0.0012607
|
||||||
|
+cigc = 0.0008 aigsd = 0.010687 bigsd = 0.0012607 cigsd = 0.0008
|
||||||
|
+nigc = 1 poxedge = 1 pigcd = 1 ntox = 1
|
||||||
|
+xrcrg1 = 12 xrcrg2 = 5
|
||||||
|
+cgso = 1e-010 cgdo = 1e-010 cgbo = 0 cgdl = 3e-011
|
||||||
|
+cgsl = 3e-011 clc = 1e-007 cle = 0.6 cf = 1.1e-010
|
||||||
|
+ckappas = 0.6 ckappad = 0.6 vfbcv = -1 acde = 1
|
||||||
|
+moin = 15 noff = 1 voffcv = 0
|
||||||
|
+kt1 = -0.14 kt1l = 0 kt2 = 0.022 ute = -1.1
|
||||||
|
+ua1 = 1e-009 ub1 = -1e-018 uc1 = -5.6e-011 prt = 0
|
||||||
|
+at = 33000
|
||||||
|
+fnoimod = 1 tnoimod = 0 noia = 6.25e+041 noib = 3.125e+026
|
||||||
|
+noic = 8.75e+009 em = 41000000 af = 1 ef = 1
|
||||||
|
+kf = 0 tnoia = 1.5 tnoib = 3.5 ntnoi = 1
|
||||||
|
+jss = 0.0 jsws = 0.0 jswgs = 0.0 njs = 1
|
||||||
|
+ijthsfwd= 0.1 ijthsrev= 0.1 bvs = 10 xjbvs = 1
|
||||||
|
+jsd = 0.0 jswd = 0.0 jswgd = 0.0 xjbvd = 1
|
||||||
|
+pbs = 1 cjs = 0.0015 mjs = 0.5 pbsws = 1
|
||||||
|
+cjsws = 9.4e-011 mjsws = 0.33 cjswgs = 2e-010 cjd = 0.0015
|
||||||
|
+cjswd = 9.4e-011 mjswd = 0.33 pbswgd = 1 cjswgd = 2e-010
|
||||||
|
+mjswgd = 0.33 tpb = 0 tcj = 0 tpbsw = 0
|
||||||
|
+tcjsw = 0 tpbswg = 0 tcjswg = 0 xtis = 3
|
||||||
|
+dmcg = 0 dmdg = 0 dmcgt = 0 xgw = 0
|
||||||
|
+xgl = 0
|
||||||
|
+rshg = 0.1 gbmin = 1e-012 rbpb = 50 rbpd = 50
|
||||||
|
+rbps = 50 rbdb = 50 rbsb = 50 ngcon = 1
|
||||||
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
## Process this file with automake to produce Makefile.in
|
## Process this file with automake to produce Makefile.in
|
||||||
|
|
||||||
SUBDIRS = misc maths frontend spicelib include/ngspice
|
SUBDIRS = misc maths frontend spicelib include/ngspice
|
||||||
DIST_SUBDIRS = misc maths frontend spicelib include/ngspice xspice ciderlib
|
DIST_SUBDIRS = misc maths frontend spicelib include/ngspice xspice ciderlib unsupported
|
||||||
|
|
||||||
if XSPICE_WANTED
|
if XSPICE_WANTED
|
||||||
SUBDIRS += xspice
|
SUBDIRS += xspice
|
||||||
|
|
@ -11,6 +11,10 @@ if CIDER_WANTED
|
||||||
SUBDIRS += ciderlib
|
SUBDIRS += ciderlib
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if SENSE2_WANTED
|
||||||
|
SUBDIRS += unsupported
|
||||||
|
endif
|
||||||
|
|
||||||
if !TCL_MODULE
|
if !TCL_MODULE
|
||||||
if !SHARED_MODULE
|
if !SHARED_MODULE
|
||||||
bin_PROGRAMS = ngspice ngnutmeg
|
bin_PROGRAMS = ngspice ngnutmeg
|
||||||
|
|
@ -27,7 +31,7 @@ endif !SHARED_MODULE
|
||||||
endif !TCL_MODULE
|
endif !TCL_MODULE
|
||||||
|
|
||||||
EXTRA_DIST = ngspice.txt setplot spectrum \
|
EXTRA_DIST = ngspice.txt setplot spectrum \
|
||||||
devload devaxis ciderinit winmain.c winmain.h unsupported \
|
devload devaxis ciderinit winmain.c winmain.h \
|
||||||
tclspice.c tclspice.map pkgIndex.tcl.in spinit.in tclspinit.in \
|
tclspice.c tclspice.map pkgIndex.tcl.in spinit.in tclspinit.in \
|
||||||
main.c sharedspice.c
|
main.c sharedspice.c
|
||||||
|
|
||||||
|
|
@ -137,6 +141,10 @@ ngspice_LDADD += \
|
||||||
spicelib/analysis/libckt.la \
|
spicelib/analysis/libckt.la \
|
||||||
spicelib/devices/libdev.la
|
spicelib/devices/libdev.la
|
||||||
|
|
||||||
|
if SENSE2_WANTED
|
||||||
|
ngspice_LDADD += unsupported/libunsupported.la
|
||||||
|
endif
|
||||||
|
|
||||||
if XSPICE_WANTED
|
if XSPICE_WANTED
|
||||||
ngspice_LDADD += \
|
ngspice_LDADD += \
|
||||||
xspice/cm/libcmxsp.la \
|
xspice/cm/libcmxsp.la \
|
||||||
|
|
|
||||||
|
|
@ -50,9 +50,10 @@ static char *upper(register char *string);
|
||||||
static bool doedit(char *filename);
|
static bool doedit(char *filename);
|
||||||
static struct line *com_options = NULL;
|
static struct line *com_options = NULL;
|
||||||
static void cktislinear(CKTcircuit *ckt, struct line *deck);
|
static void cktislinear(CKTcircuit *ckt, struct line *deck);
|
||||||
|
static void dotifeval(struct line *deck);
|
||||||
|
|
||||||
void line_free_x(struct line *deck, bool recurse);
|
void line_free_x(struct line *deck, bool recurse);
|
||||||
|
void create_circbyline(char *line);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -547,6 +548,9 @@ inp_spsource(FILE *fp, bool comfile, char *filename, bool intfile)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* handle .if ... .elseif ... .else ... .endif statements. */
|
||||||
|
dotifeval(deck);
|
||||||
|
|
||||||
/*merge the two option line structs*/
|
/*merge the two option line structs*/
|
||||||
if (!options && com_options)
|
if (!options && com_options)
|
||||||
options = com_options;
|
options = com_options;
|
||||||
|
|
@ -1199,3 +1203,71 @@ com_circbyline(wordlist *wl)
|
||||||
char *newline = wl_flatten(wl);
|
char *newline = wl_flatten(wl);
|
||||||
create_circbyline(newline);
|
create_circbyline(newline);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* handle .if('expr') ... .elseif('expr') ... .else ... .endif statements.
|
||||||
|
numparam has evaluated .if('boolean expression') to
|
||||||
|
.if ( 1.000000000e+000 ) or .elseif ( 0.000000000e+000 ) */
|
||||||
|
static void
|
||||||
|
dotifeval(struct line *deck)
|
||||||
|
{
|
||||||
|
int iftrue = 0, elseiftrue = 0, elsetrue = 0, iffound = 0, elseiffound = 0, elsefound = 0;
|
||||||
|
struct line *dd;
|
||||||
|
char *dottoken;
|
||||||
|
char *s, *t;
|
||||||
|
|
||||||
|
/* skip the first line (title line) */
|
||||||
|
for (dd = deck->li_next; dd; dd = dd->li_next) {
|
||||||
|
|
||||||
|
s = t = dd->li_line;
|
||||||
|
|
||||||
|
if (*s == '*')
|
||||||
|
continue;
|
||||||
|
|
||||||
|
dottoken = gettok(&t);
|
||||||
|
/* find '.if' and read its parameter */
|
||||||
|
if (cieq(dottoken, ".if")) {
|
||||||
|
elsefound = 0;
|
||||||
|
elseiffound = 0;
|
||||||
|
iffound = 1;
|
||||||
|
*s = '*';
|
||||||
|
s = dd->li_line + 3;
|
||||||
|
iftrue = atoi(s);
|
||||||
|
}
|
||||||
|
else if (cieq(dottoken, ".elseif")) {
|
||||||
|
elsefound = 0;
|
||||||
|
elseiffound = 1;
|
||||||
|
iffound = 0;
|
||||||
|
*s = '*';
|
||||||
|
if (!iftrue) {
|
||||||
|
s = dd->li_line + 7;
|
||||||
|
elseiftrue = atoi(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (cieq(dottoken, ".else")) {
|
||||||
|
elsefound = 1;
|
||||||
|
elseiffound = 0;
|
||||||
|
iffound = 0;
|
||||||
|
if (!iftrue && !elseiftrue)
|
||||||
|
elsetrue = 1;
|
||||||
|
*s = '*';
|
||||||
|
}
|
||||||
|
else if (cieq(dottoken, ".endif")) {
|
||||||
|
elsefound = elseiffound = iffound = 0;
|
||||||
|
elsetrue = elseiftrue = iftrue = 0;
|
||||||
|
*s = '*';
|
||||||
|
// inp_subcktexpand(dd);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (iffound && !iftrue) {
|
||||||
|
*s = '*';
|
||||||
|
}
|
||||||
|
else if (elseiffound && !elseiftrue) {
|
||||||
|
*s = '*';
|
||||||
|
}
|
||||||
|
else if (elsefound && !elsetrue) {
|
||||||
|
*s = '*';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tfree(dottoken);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -239,6 +239,14 @@ do_measure(
|
||||||
return (measures_passed);
|
return (measures_passed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* don't allow autostop if no .meas commands are given in the input file */
|
||||||
|
if ((cp_getvar("autostop", CP_BOOL, NULL)) && (ft_curckt->ci_meas == NULL)) {
|
||||||
|
fprintf(cp_err, "\nWarning: No .meas commands found!\n");
|
||||||
|
fprintf(cp_err, " Option autostop is not available, ignored!\n\n");
|
||||||
|
cp_remvar("autostop");
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
/* Evaluating the linked list of .meas cards, assembled from the input deck
|
/* Evaluating the linked list of .meas cards, assembled from the input deck
|
||||||
by fcn inp_spsource() in inp.c:575.
|
by fcn inp_spsource() in inp.c:575.
|
||||||
A typical .meas card will contain:
|
A typical .meas card will contain:
|
||||||
|
|
|
||||||
|
|
@ -189,6 +189,11 @@ com_version(wordlist *wl)
|
||||||
fprintf(cp_out, "** %s\n", Spice_Notice);
|
fprintf(cp_out, "** %s\n", Spice_Notice);
|
||||||
if (Spice_Build_Date != NULL && *Spice_Build_Date != 0)
|
if (Spice_Build_Date != NULL && *Spice_Build_Date != 0)
|
||||||
fprintf(cp_out, "** Creation Date: %s\n", Spice_Build_Date);
|
fprintf(cp_out, "** Creation Date: %s\n", Spice_Build_Date);
|
||||||
|
|
||||||
|
#ifdef KIRCHHOFF
|
||||||
|
fprintf(cp_out, "** KCL Verification enabled.\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
fprintf(cp_out, "******\n");
|
fprintf(cp_out, "******\n");
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -279,6 +284,9 @@ com_version(wordlist *wl)
|
||||||
#endif
|
#endif
|
||||||
#ifdef EXP_DEV
|
#ifdef EXP_DEV
|
||||||
fprintf(cp_out, "** Experimental devices enabled.\n");
|
fprintf(cp_out, "** Experimental devices enabled.\n");
|
||||||
|
#endif
|
||||||
|
#ifdef KIRCHHOFF
|
||||||
|
fprintf(cp_out, "** KCL Verification enabled.\n");
|
||||||
#endif
|
#endif
|
||||||
fprintf(cp_out, "******\n");
|
fprintf(cp_out, "******\n");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ typedef enum {Nodekey = '#'} _nNodekey; /* Introduces node symbol */
|
||||||
typedef enum {Intro = '&'} _nIntro; /* Introduces preprocessor tokens */
|
typedef enum {Intro = '&'} _nIntro; /* Introduces preprocessor tokens */
|
||||||
typedef enum {Comment = '*'} _nComment; /* Spice Comment lines */
|
typedef enum {Comment = '*'} _nComment; /* Spice Comment lines */
|
||||||
typedef enum {Psp = '{'} _nPsp; /* Ps expression */
|
typedef enum {Psp = '{'} _nPsp; /* Ps expression */
|
||||||
typedef enum {Defd = 15} _nDefd; /* serial numb. of 'defined' keyword.
|
typedef enum {Defd = 6} _nDefd; /* serial numb. of 'defined' keyword.
|
||||||
The others are not used (yet) */
|
The others are not used (yet) */
|
||||||
|
|
||||||
typedef char *auxtable; /* dummy */
|
typedef char *auxtable; /* dummy */
|
||||||
|
|
|
||||||
|
|
@ -243,6 +243,11 @@ modernizeex(SPICE_DSTRINGPTR dstr_p)
|
||||||
state = 0;
|
state = 0;
|
||||||
ls = spice_dstring_length(dstr_p);
|
ls = spice_dstring_length(dstr_p);
|
||||||
s = spice_dstring_value(dstr_p);
|
s = spice_dstring_value(dstr_p);
|
||||||
|
|
||||||
|
/* check if string might need modernizing */
|
||||||
|
if (!memchr(s, Intro, (size_t) ls))
|
||||||
|
return;
|
||||||
|
|
||||||
spice_dstring_init(&t);
|
spice_dstring_init(&t);
|
||||||
|
|
||||||
while (i < ls) {
|
while (i < ls) {
|
||||||
|
|
|
||||||
|
|
@ -88,8 +88,7 @@ initkeys(void)
|
||||||
{
|
{
|
||||||
spice_dstring_init(&keyS);
|
spice_dstring_init(&keyS);
|
||||||
scopy_up(&keyS,
|
scopy_up(&keyS,
|
||||||
"and or not div mod if else end while macro funct defined"
|
"and or not div mod defined");
|
||||||
" include for to downto is var");
|
|
||||||
scopy_up(&fmathS,
|
scopy_up(&fmathS,
|
||||||
"sqr sqrt sin cos exp ln arctan abs pow pwr max min int log sinh cosh"
|
"sqr sqrt sin cos exp ln arctan abs pow pwr max min int log sinh cosh"
|
||||||
" tanh ternary_fcn v agauss sgn gauss unif aunif limit ceil floor");
|
" tanh ternary_fcn v agauss sgn gauss unif aunif limit ceil floor");
|
||||||
|
|
@ -935,7 +934,7 @@ opfunctkey(tdico *dico,
|
||||||
/*if kw operator keyword, c=token*/
|
/*if kw operator keyword, c=token*/
|
||||||
switch (kw)
|
switch (kw)
|
||||||
{
|
{
|
||||||
/* & | ~ DIV MOD Defined */
|
/* & | ~ DIV MOD Defined */
|
||||||
case 1:
|
case 1:
|
||||||
c = '&';
|
c = '&';
|
||||||
state = 2;
|
state = 2;
|
||||||
|
|
|
||||||
|
|
@ -81,10 +81,10 @@ static IFvalue *doask(CKTcircuit *ckt, int typecode, GENinstance *dev, GENmodel
|
||||||
IFparm *opt, int ind);
|
IFparm *opt, int ind);
|
||||||
static int doset(CKTcircuit *ckt, int typecode, GENinstance *dev, GENmodel *mod,
|
static int doset(CKTcircuit *ckt, int typecode, GENinstance *dev, GENmodel *mod,
|
||||||
IFparm *opt, struct dvec *val);
|
IFparm *opt, struct dvec *val);
|
||||||
static int finddev(CKTcircuit *ck, char *name, GENinstance **devptr, GENmodel **modptr);
|
static int finddev(CKTcircuit *ckt, char *name, GENinstance **devptr, GENmodel **modptr);
|
||||||
|
|
||||||
/* espice fix integration */
|
/* espice fix integration */
|
||||||
static int finddev_special(CKTcircuit *ck, char *name, GENinstance **devptr, GENmodel **modptr, int *device_or_model);
|
static int finddev_special(CKTcircuit *ckt, char *name, GENinstance **devptr, GENmodel **modptr, int *device_or_model);
|
||||||
|
|
||||||
|
|
||||||
/* Input a single deck, and return a pointer to the circuit. */
|
/* Input a single deck, and return a pointer to the circuit. */
|
||||||
|
|
@ -252,8 +252,7 @@ if_run(CKTcircuit *ckt, char *what, wordlist *args, INPtables *tab)
|
||||||
/*CDHW Create an interactive task AAA with a new UID.
|
/*CDHW Create an interactive task AAA with a new UID.
|
||||||
ci_specTask will point to it CDHW*/
|
ci_specTask will point to it CDHW*/
|
||||||
|
|
||||||
err = IFnewUid(ft_curckt->ci_ckt, &specUid, NULL, "special",
|
err = IFnewUid(ft_curckt->ci_ckt, &specUid, NULL, "special", UID_TASK, NULL);
|
||||||
UID_TASK, NULL);
|
|
||||||
if (err) {
|
if (err) {
|
||||||
ft_sperror(err, "newUid");
|
ft_sperror(err, "newUid");
|
||||||
return (2);
|
return (2);
|
||||||
|
|
@ -281,8 +280,7 @@ if_run(CKTcircuit *ckt, char *what, wordlist *args, INPtables *tab)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (which != -1) { /*CDHW options are available CDHW*/
|
if (which != -1) { /*CDHW options are available CDHW*/
|
||||||
err = IFnewUid(ft_curckt->ci_ckt, &optUid, NULL, "options",
|
err = IFnewUid(ft_curckt->ci_ckt, &optUid, NULL, "options", UID_ANALYSIS, NULL);
|
||||||
UID_ANALYSIS, NULL);
|
|
||||||
if (err) {
|
if (err) {
|
||||||
ft_sperror(err, "newUid");
|
ft_sperror(err, "newUid");
|
||||||
return (2);
|
return (2);
|
||||||
|
|
@ -616,7 +614,7 @@ finddev_special(
|
||||||
int err;
|
int err;
|
||||||
int type = -1;
|
int type = -1;
|
||||||
|
|
||||||
err = ft_sim->findInstance (ckt, &type, devptr, name, NULL, NULL);
|
err = ft_sim->findInstance (ckt, &type, devptr, name, NULL);
|
||||||
if (err == OK) {
|
if (err == OK) {
|
||||||
*device_or_model = 0;
|
*device_or_model = 0;
|
||||||
return (type);
|
return (type);
|
||||||
|
|
@ -1212,19 +1210,19 @@ doset(CKTcircuit *ckt, int typecode, GENinstance *dev, GENmodel *mod, IFparm *op
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int
|
static int
|
||||||
finddev(CKTcircuit *ck, char *name, GENinstance **devptr, GENmodel **modptr)
|
finddev(CKTcircuit *ckt, char *name, GENinstance **devptr, GENmodel **modptr)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
int type = -1;
|
int type = -1;
|
||||||
|
|
||||||
err = ft_sim->findInstance (ck, &type, devptr, name, NULL, NULL);
|
err = ft_sim->findInstance (ckt, &type, devptr, name, NULL);
|
||||||
if (err == OK)
|
if (err == OK)
|
||||||
return (type);
|
return (type);
|
||||||
|
|
||||||
type = -1;
|
type = -1;
|
||||||
*devptr = NULL;
|
*devptr = NULL;
|
||||||
|
|
||||||
err = ft_sim->findModel (ck, &type, modptr, name);
|
err = ft_sim->findModel (ckt, &type, modptr, name);
|
||||||
if (err == OK)
|
if (err == OK)
|
||||||
return (type);
|
return (type);
|
||||||
|
|
||||||
|
|
@ -1273,8 +1271,7 @@ if_tranparams(struct circ *ci, double *start, double *stop, double *step)
|
||||||
if (which == -1)
|
if (which == -1)
|
||||||
return (FALSE);
|
return (FALSE);
|
||||||
|
|
||||||
err = IFnewUid(ci->ci_ckt, &tranUid, NULL, "Transient Analysis",
|
err = IFnewUid(ci->ci_ckt, &tranUid, NULL, "Transient Analysis", UID_ANALYSIS, NULL);
|
||||||
UID_ANALYSIS, NULL);
|
|
||||||
if (err != OK)
|
if (err != OK)
|
||||||
return (FALSE);
|
return (FALSE);
|
||||||
|
|
||||||
|
|
@ -1616,11 +1613,11 @@ void com_snload(wordlist *wl)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SPfrontEnd->IFnewUid (ckt, &timeUid, NULL, "time", UID_OTHER, NULL);
|
SPfrontEnd->IFnewUid (ckt, &timeUid, NULL, "time", UID_OTHER, NULL);
|
||||||
error = SPfrontEnd->OUTpBeginPlot (
|
error = SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
|
||||||
ckt, ckt->CKTcurJob,
|
ckt->CKTcurJob->JOBname,
|
||||||
ckt->CKTcurJob->JOBname,
|
timeUid, IF_REAL,
|
||||||
timeUid, IF_REAL,
|
numNames, nameList, IF_REAL,
|
||||||
numNames, nameList, IF_REAL, &(((TRANan*)ckt->CKTcurJob)->TRANplot));
|
&(((TRANan*)ckt->CKTcurJob)->TRANplot));
|
||||||
if (error) {
|
if (error) {
|
||||||
fprintf(cp_err, "error in CKTnames\n");
|
fprintf(cp_err, "error in CKTnames\n");
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -1815,6 +1815,7 @@ devmodtranslate(struct line *deck, char *subname, wordlist * const submod)
|
||||||
|
|
||||||
case 'r':
|
case 'r':
|
||||||
case 'c':
|
case 'c':
|
||||||
|
case 'l':
|
||||||
name = gettok(&t); /* get refdes */
|
name = gettok(&t); /* get refdes */
|
||||||
(void) sprintf(buffer, "%s ", name);
|
(void) sprintf(buffer, "%s ", name);
|
||||||
tfree(name);
|
tfree(name);
|
||||||
|
|
@ -1967,7 +1968,7 @@ devmodtranslate(struct line *deck, char *subname, wordlist * const submod)
|
||||||
name = gettok(&t);
|
name = gettok(&t);
|
||||||
|
|
||||||
found = 0;
|
found = 0;
|
||||||
while (*t && !found) {
|
while (!found) {
|
||||||
/* Now, is this a subcircuit model? */
|
/* Now, is this a subcircuit model? */
|
||||||
for (wlsub = submod; wlsub; wlsub = wlsub->wl_next) {
|
for (wlsub = submod; wlsub; wlsub = wlsub->wl_next) {
|
||||||
/* FIXME, probably too unspecific */
|
/* FIXME, probably too unspecific */
|
||||||
|
|
@ -1994,6 +1995,10 @@ devmodtranslate(struct line *deck, char *subname, wordlist * const submod)
|
||||||
(void) sprintf(buffer + strlen(buffer), "%s ", name);
|
(void) sprintf(buffer + strlen(buffer), "%s ", name);
|
||||||
tfree(name);
|
tfree(name);
|
||||||
name = gettok(&t);
|
name = gettok(&t);
|
||||||
|
if (name == NULL) {
|
||||||
|
name = copy(""); /* allow 'tfree' */
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} /* while */
|
} /* while */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,12 @@ struct CKTnode {
|
||||||
#define PARM_IC 2
|
#define PARM_IC 2
|
||||||
#define PARM_NODETYPE 3
|
#define PARM_NODETYPE 3
|
||||||
|
|
||||||
|
#ifdef KIRCHHOFF
|
||||||
|
typedef struct sCKTmkCurKCLnode {
|
||||||
|
double KCLcurrent ;
|
||||||
|
struct sCKTmkCurKCLnode *next ;
|
||||||
|
} CKTmkCurKCLnode ;
|
||||||
|
#endif
|
||||||
|
|
||||||
struct CKTcircuit {
|
struct CKTcircuit {
|
||||||
|
|
||||||
|
|
@ -110,6 +116,13 @@ struct CKTcircuit {
|
||||||
double *CKTrhs; /* current rhs value - being loaded */
|
double *CKTrhs; /* current rhs value - being loaded */
|
||||||
double *CKTrhsOld; /* previous rhs value for convergence
|
double *CKTrhsOld; /* previous rhs value for convergence
|
||||||
testing */
|
testing */
|
||||||
|
|
||||||
|
#ifdef KIRCHHOFF
|
||||||
|
double *CKTfvk ; /* KCL Verification array */
|
||||||
|
int *CKTnodeIsLinear ; /* Flag to indicate if a node is linear or non-linear */
|
||||||
|
CKTmkCurKCLnode **CKTmkCurKCLarray ; /* Array of KCL Currents */
|
||||||
|
#endif
|
||||||
|
|
||||||
double *CKTrhsSpare; /* spare rhs value for reordering */
|
double *CKTrhsSpare; /* spare rhs value for reordering */
|
||||||
double *CKTirhs; /* current rhs value - being loaded
|
double *CKTirhs; /* current rhs value - being loaded
|
||||||
(imag) */
|
(imag) */
|
||||||
|
|
@ -289,7 +302,11 @@ struct CKTcircuit {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* Now function prottypes */
|
/* Now function prototypes */
|
||||||
|
|
||||||
|
#ifdef KIRCHHOFF
|
||||||
|
extern int CKTmkCurKCL (CKTcircuit *, int, double **) ;
|
||||||
|
#endif
|
||||||
|
|
||||||
extern int ACan(CKTcircuit *, int);
|
extern int ACan(CKTcircuit *, int);
|
||||||
extern int ACaskQuest(CKTcircuit *, JOB *, int , IFvalue *);
|
extern int ACaskQuest(CKTcircuit *, JOB *, int , IFvalue *);
|
||||||
|
|
@ -321,7 +338,7 @@ extern void NDEVacct(CKTcircuit *ckt, FILE *file);
|
||||||
extern void CKTncDump(CKTcircuit *);
|
extern void CKTncDump(CKTcircuit *);
|
||||||
extern int CKTfndAnal(CKTcircuit *, int *, JOB **, IFuid , TSKtask *, IFuid);
|
extern int CKTfndAnal(CKTcircuit *, int *, JOB **, IFuid , TSKtask *, IFuid);
|
||||||
extern int CKTfndBranch(CKTcircuit *, IFuid);
|
extern int CKTfndBranch(CKTcircuit *, IFuid);
|
||||||
extern int CKTfndDev(CKTcircuit *, int *, GENinstance **, IFuid , GENmodel *, IFuid);
|
extern int CKTfndDev(CKTcircuit *, int *, GENinstance **, IFuid , GENmodel *);
|
||||||
extern int CKTfndMod(CKTcircuit *, int *, GENmodel **, IFuid);
|
extern int CKTfndMod(CKTcircuit *, int *, GENmodel **, IFuid);
|
||||||
extern int CKTfndNode(CKTcircuit *, CKTnode **, IFuid);
|
extern int CKTfndNode(CKTcircuit *, CKTnode **, IFuid);
|
||||||
extern int CKTfndTask(CKTcircuit *, TSKtask **, IFuid );
|
extern int CKTfndTask(CKTcircuit *, TSKtask **, IFuid );
|
||||||
|
|
@ -387,10 +404,14 @@ extern int PZinit(CKTcircuit *);
|
||||||
extern int PZpost(CKTcircuit *);
|
extern int PZpost(CKTcircuit *);
|
||||||
extern int PZaskQuest(CKTcircuit *, JOB *, int , IFvalue *);
|
extern int PZaskQuest(CKTcircuit *, JOB *, int , IFvalue *);
|
||||||
extern int PZsetParm(CKTcircuit *, JOB *, int , IFvalue *);
|
extern int PZsetParm(CKTcircuit *, JOB *, int , IFvalue *);
|
||||||
|
|
||||||
|
#ifdef WANT_SENSE2
|
||||||
extern int SENaskQuest(CKTcircuit *, JOB *, int , IFvalue *);
|
extern int SENaskQuest(CKTcircuit *, JOB *, int , IFvalue *);
|
||||||
extern void SENdestroy(SENstruct *);
|
extern void SENdestroy(SENstruct *);
|
||||||
extern int SENsetParm(CKTcircuit *, JOB *, int , IFvalue *);
|
extern int SENsetParm(CKTcircuit *, JOB *, int , IFvalue *);
|
||||||
extern int SENstartup(CKTcircuit *);
|
extern int SENstartup(CKTcircuit *, int);
|
||||||
|
#endif
|
||||||
|
|
||||||
extern int SPIinit(IFfrontEnd *, IFsimulator **);
|
extern int SPIinit(IFfrontEnd *, IFsimulator **);
|
||||||
extern int TFanal(CKTcircuit *, int);
|
extern int TFanal(CKTcircuit *, int);
|
||||||
extern int TFaskQuest(CKTcircuit *, JOB *, int , IFvalue *);
|
extern int TFaskQuest(CKTcircuit *, JOB *, int , IFvalue *);
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,7 @@
|
||||||
/* Alternate initialisation file name */
|
/* Alternate initialisation file name */
|
||||||
#define ALT_INITSTR "spice.rc"
|
#define ALT_INITSTR "spice.rc"
|
||||||
|
|
||||||
#if defined(__MINGW32__) || defined(_MSC_VER)
|
#if defined(__MINGW32__) || defined(_MSC_VER) || defined (HAS_WINGUI)
|
||||||
#define DIR_PATHSEP "\\"
|
#define DIR_PATHSEP "\\"
|
||||||
#define DIR_TERM '\\'
|
#define DIR_TERM '\\'
|
||||||
#define DIR_PATHSEP_LINUX "/"
|
#define DIR_PATHSEP_LINUX "/"
|
||||||
|
|
|
||||||
|
|
@ -28,10 +28,21 @@ double limitJunctionVoltage( double, double, int * );
|
||||||
double limitVbe( double, double, int * );
|
double limitVbe( double, double, int * );
|
||||||
double limitVce( double, double, int * );
|
double limitVce( double, double, int * );
|
||||||
double limitVgb( double, double, int * );
|
double limitVgb( double, double, int * );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Area Calculation Method (ACM) for MOS models (devsup.c) */
|
||||||
|
int
|
||||||
|
ACM_SourceDrainResistances(int, double, double, double, double, double,
|
||||||
|
double, double, int, double, double, double,
|
||||||
|
int, double, double, double, double *, double *);
|
||||||
|
int
|
||||||
|
ACM_saturationCurrents(int, int, int, double, double, double, double, double,
|
||||||
|
double, int, double, int, double, int, double, int,
|
||||||
|
double, double *, double *);
|
||||||
|
int
|
||||||
|
ACM_junctionCapacitances(int, int, int, double, double, double, double, int,
|
||||||
|
double, int, double, int, double, int, double,
|
||||||
|
double, double, double, double *, double *,
|
||||||
|
double *, double *, double *, double *);
|
||||||
|
|
||||||
typedef struct SPICEdev {
|
typedef struct SPICEdev {
|
||||||
IFdevice DEVpublic;
|
IFdevice DEVpublic;
|
||||||
|
|
@ -110,6 +121,12 @@ typedef struct SPICEdev {
|
||||||
/* routine to convert Complex CSC array to Real CSC array */
|
/* routine to convert Complex CSC array to Real CSC array */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef KIRCHHOFF
|
||||||
|
/* Francesco Lannutti */
|
||||||
|
int (*DEVnodeIsNonLinear)(GENmodel *, CKTcircuit *) ;
|
||||||
|
/* Routine to declare a node as NonLinear */
|
||||||
|
#endif
|
||||||
|
|
||||||
} SPICEdev; /* instance of structure for each possible type of device */
|
} SPICEdev; /* instance of structure for each possible type of device */
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -370,7 +370,7 @@ struct IFsimulator {
|
||||||
/* set a parameter on an instance */
|
/* set a parameter on an instance */
|
||||||
int (*askInstanceQuest) (CKTcircuit *, GENinstance *, int, IFvalue *, IFvalue *);
|
int (*askInstanceQuest) (CKTcircuit *, GENinstance *, int, IFvalue *, IFvalue *);
|
||||||
/* ask a question about an instance */
|
/* ask a question about an instance */
|
||||||
int (*findInstance) (CKTcircuit *, int *, GENinstance **, IFuid, GENmodel *, IFuid);
|
int (*findInstance) (CKTcircuit *, int *, GENinstance **, IFuid, GENmodel *);
|
||||||
/* find a specific instance */
|
/* find a specific instance */
|
||||||
int (*deleteInstance) (CKTcircuit *, void *);
|
int (*deleteInstance) (CKTcircuit *, void *);
|
||||||
/* delete an instance from the circuit */
|
/* delete an instance from the circuit */
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
/**********
|
/**********
|
||||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||||
**********/
|
**********/
|
||||||
|
|
||||||
/* a couple of macros to make much of the input code
|
/* a couple of macros to make much of the input code
|
||||||
* much much shorter and easier to handle.
|
* much much shorter and easier to handle.
|
||||||
*
|
*
|
||||||
|
|
@ -9,25 +10,42 @@ Copyright 1990 Regents of the University of California. All rights reserved.
|
||||||
* If necessary, get the proper error message and tack it on the current
|
* If necessary, get the proper error message and tack it on the current
|
||||||
* error
|
* error
|
||||||
*/
|
*/
|
||||||
#define IFC(func,args)\
|
|
||||||
error=(*(ft_sim->func))args;\
|
#define IFC(func, args) \
|
||||||
if(error)current->error = INPerrCat(current->error,INPerror(error));
|
do { \
|
||||||
|
error = (*(ft_sim->func)) args; \
|
||||||
|
if (error) \
|
||||||
|
current->error = INPerrCat(current->error, INPerror(error)); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
/* and one for calling more General functions that still return an
|
/* and one for calling more General functions that still return an
|
||||||
* error code as above
|
* error code as above
|
||||||
*/
|
*/
|
||||||
#define GCA(func,args)\
|
|
||||||
error=func args;\
|
|
||||||
if(error)current->error = INPerrCat(current->error,INPerror(error));
|
|
||||||
|
|
||||||
/* and one for putting our own error messages onto the current
|
#define GCA(func, args) \
|
||||||
|
do { \
|
||||||
|
error = func args; \
|
||||||
|
if (error) \
|
||||||
|
current->error = INPerrCat(current->error, INPerror(error)); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
|
/* and one for putting our own error messages onto the current
|
||||||
* line's error string
|
* line's error string
|
||||||
*/
|
*/
|
||||||
#define LITERR(text) current->error=INPerrCat(current->error,INPmkTemp(text));
|
|
||||||
|
#define LITERR(text) \
|
||||||
|
do { \
|
||||||
|
current->error = INPerrCat(current->error, INPmkTemp(text)); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
/* and now a special one for calling INPdevParse which returns an
|
/* and now a special one for calling INPdevParse which returns an
|
||||||
* already concatenated list of error messages or NUL
|
* already concatenated list of error messages or NUL
|
||||||
*/
|
*/
|
||||||
#define PARSECALL(args)\
|
|
||||||
current->error = INPerrCat(current->error,INPdevParse args );
|
#define PARSECALL(args) \
|
||||||
|
do { \
|
||||||
|
current->error = INPerrCat(current->error, INPdevParse args); \
|
||||||
|
} while(0)
|
||||||
|
|
|
||||||
|
|
@ -123,10 +123,11 @@ void INPptPrint(char *str, IFparseTree * ptree);
|
||||||
#define PTF_GE0 28
|
#define PTF_GE0 28
|
||||||
#define PTF_LE0 29
|
#define PTF_LE0 29
|
||||||
#define PTF_POW 30
|
#define PTF_POW 30
|
||||||
#define PTF_MIN 31
|
#define PTF_PWR 31
|
||||||
#define PTF_MAX 32
|
#define PTF_MIN 32
|
||||||
#define PTF_CEIL 33
|
#define PTF_MAX 33
|
||||||
#define PTF_FLOOR 34
|
#define PTF_CEIL 34
|
||||||
|
#define PTF_FLOOR 35
|
||||||
|
|
||||||
/* The following things are used by the parser -- these are the token types the
|
/* The following things are used by the parser -- these are the token types the
|
||||||
* lexer returns.
|
* lexer returns.
|
||||||
|
|
|
||||||
|
|
@ -43,11 +43,12 @@
|
||||||
#define NIL(type) ((type *)0)
|
#define NIL(type) ((type *)0)
|
||||||
#define ABORT() fflush(stderr);fflush(stdout);abort();
|
#define ABORT() fflush(stderr);fflush(stdout);abort();
|
||||||
|
|
||||||
#define MERROR(CODE,MESSAGE) { \
|
#define MERROR(CODE, MESSAGE) \
|
||||||
errMsg = TMALLOC(char, strlen(MESSAGE) + 1); \
|
do { \
|
||||||
strcpy(errMsg, (MESSAGE)); \
|
errMsg = TMALLOC(char, strlen(MESSAGE) + 1); \
|
||||||
return (CODE); \
|
strcpy(errMsg, (MESSAGE)); \
|
||||||
}
|
return (CODE); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
#define NEW(TYPE) (TMALLOC(TYPE, 1))
|
#define NEW(TYPE) (TMALLOC(TYPE, 1))
|
||||||
#define NEWN(TYPE,COUNT) (TMALLOC(TYPE, COUNT))
|
#define NEWN(TYPE,COUNT) (TMALLOC(TYPE, COUNT))
|
||||||
|
|
|
||||||
|
|
@ -112,7 +112,9 @@ struct ngcomplex {
|
||||||
typedef struct ngcomplex ngcomplex_t;
|
typedef struct ngcomplex ngcomplex_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* vector info obtained from any vector in ngspice.dll */
|
/* vector info obtained from any vector in ngspice.dll.
|
||||||
|
Allows direct access to the ngspice internal vector structure,
|
||||||
|
as defined in include/ngspice/devc.h .*/
|
||||||
typedef struct vector_info {
|
typedef struct vector_info {
|
||||||
char *v_name; /* Same as so_vname. */
|
char *v_name; /* Same as so_vname. */
|
||||||
int v_type; /* Same as so_vtype. */
|
int v_type; /* Same as so_vtype. */
|
||||||
|
|
@ -123,16 +125,17 @@ typedef struct vector_info {
|
||||||
} vector_info, *pvector_info;
|
} vector_info, *pvector_info;
|
||||||
|
|
||||||
typedef struct vecvalues {
|
typedef struct vecvalues {
|
||||||
char* name;
|
char* name; /* name of a specific vector */
|
||||||
double creal;
|
double creal; /* actual data value */
|
||||||
double cimag;
|
double cimag; /* actual data value */
|
||||||
bool is_scale;
|
bool is_scale;/* if 'name' is the scale vector */
|
||||||
bool is_complex;
|
bool is_complex;/* if the data are complex numbers */
|
||||||
} vecvalues, *pvecvalues;
|
} vecvalues, *pvecvalues;
|
||||||
|
|
||||||
typedef struct vecvaluesall {
|
typedef struct vecvaluesall {
|
||||||
int veccount;
|
int veccount; /* number of vectors in plot */
|
||||||
pvecvalues *vecsa;
|
int vecindex; /* index of actual set of vectors. i.e. the number of accepted data points */
|
||||||
|
pvecvalues *vecsa; /* values of actual set of vectors, indexed from 0 to veccount - 1 */
|
||||||
} vecvaluesall, *pvecvaluesall;
|
} vecvaluesall, *pvecvaluesall;
|
||||||
|
|
||||||
/* info for a specific vector */
|
/* info for a specific vector */
|
||||||
|
|
@ -206,6 +209,18 @@ typedef int (BGThreadRunning)(bool, void*);
|
||||||
void* return pointer received from caller
|
void* return pointer received from caller
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* callback functions
|
||||||
|
addresses received from caller with ngSpice_Init_Sync() function
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* ask for VSRC EXTERNAL value */
|
||||||
|
typedef int (GetVSRCData)(double*, double, char*, void*);
|
||||||
|
/*
|
||||||
|
double* return voltage value
|
||||||
|
double actual time
|
||||||
|
char* node name
|
||||||
|
void* return pointer received from caller
|
||||||
|
*/
|
||||||
|
|
||||||
/* ngspice initialization,
|
/* ngspice initialization,
|
||||||
printfcn: pointer to callback function for reading printf, fprintf
|
printfcn: pointer to callback function for reading printf, fprintf
|
||||||
|
|
@ -220,6 +235,12 @@ IMPEXP
|
||||||
int ngSpice_Init(SendChar* printfcn, SendStat* statfcn, ControlledExit* ngexit,
|
int ngSpice_Init(SendChar* printfcn, SendStat* statfcn, ControlledExit* ngexit,
|
||||||
SendData* sdata, SendInitData* sinitdata, BGThreadRunning* bgtrun, void* userData);
|
SendData* sdata, SendInitData* sinitdata, BGThreadRunning* bgtrun, void* userData);
|
||||||
|
|
||||||
|
/* initialization of synchronizing functions
|
||||||
|
vsrcdat: pointer to callback function for retrieving a voltage source value
|
||||||
|
ident: pointer to integer unique to this shared library (defaults to 0)
|
||||||
|
*/
|
||||||
|
IMPEXP
|
||||||
|
int ngSpice_Init_Sync(GetVSRCData* vsrcdat, int* ident, void* userData);
|
||||||
|
|
||||||
/* Caller may send ngspice commands to ngspice.dll.
|
/* Caller may send ngspice commands to ngspice.dll.
|
||||||
Commands are executed immediately */
|
Commands are executed immediately */
|
||||||
|
|
@ -260,6 +281,10 @@ char** ngSpice_AllVecs(char* plotname);
|
||||||
IMPEXP
|
IMPEXP
|
||||||
bool ngSpice_running(void);
|
bool ngSpice_running(void);
|
||||||
|
|
||||||
|
/* set a breakpoint in ngspice */
|
||||||
|
IMPEXP
|
||||||
|
bool ngSpice_SetBkpt(double time);
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -122,8 +122,8 @@ void SMPgetError( SMPmatrix *, int *, int *);
|
||||||
int SMPcProdDiag( SMPmatrix *, SPcomplex *, int *);
|
int SMPcProdDiag( SMPmatrix *, SPcomplex *, int *);
|
||||||
int SMPcDProd(SMPmatrix *Matrix, SPcomplex *pMantissa, int *pExponent);
|
int SMPcDProd(SMPmatrix *Matrix, SPcomplex *pMantissa, int *pExponent);
|
||||||
SMPelement * SMPfindElt( SMPmatrix *, int , int , int );
|
SMPelement * SMPfindElt( SMPmatrix *, int , int , int );
|
||||||
int SMPcZeroCol(SMPmatrix *eMatrix, int Col);
|
int SMPcZeroCol(SMPmatrix *Matrix, int Col);
|
||||||
int SMPcAddCol(SMPmatrix *eMatrix, int Accum_Col, int Addend_Col);
|
int SMPcAddCol(SMPmatrix *Matrix, int Accum_Col, int Addend_Col);
|
||||||
int SMPzeroRow(SMPmatrix *eMatrix, int Row);
|
int SMPzeroRow(SMPmatrix *Matrix, int Row);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -263,7 +263,7 @@ extern int spFileMatrix( MatrixPtr, char *, char *, int, int, int );
|
||||||
extern int spFileStats( MatrixPtr, char *, char * );
|
extern int spFileStats( MatrixPtr, char *, char * );
|
||||||
extern int spFillinCount( MatrixPtr );
|
extern int spFillinCount( MatrixPtr );
|
||||||
extern int spGetAdmittance( MatrixPtr, int, int, struct spTemplate* );
|
extern int spGetAdmittance( MatrixPtr, int, int, struct spTemplate* );
|
||||||
extern spREAL *spFindElement(MatrixPtr eMatrix, int Row, int Col );
|
extern spREAL *spFindElement(MatrixPtr Matrix, int Row, int Col );
|
||||||
extern spREAL *spGetElement(MatrixPtr, int, int );
|
extern spREAL *spGetElement(MatrixPtr, int, int );
|
||||||
extern void *spGetInitInfo( spREAL* );
|
extern void *spGetInitInfo( spREAL* );
|
||||||
extern int spGetOnes( MatrixPtr, int, int, int, struct spTemplate* );
|
extern int spGetOnes( MatrixPtr, int, int, int, struct spTemplate* );
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,11 @@ bool AlmostEqualUlps(double A, double B, int maxUlps)
|
||||||
{
|
{
|
||||||
int64_t aInt, bInt, intDiff;
|
int64_t aInt, bInt, intDiff;
|
||||||
|
|
||||||
|
union {
|
||||||
|
double d;
|
||||||
|
int64_t i;
|
||||||
|
} uA, uB;
|
||||||
|
|
||||||
if (A == B)
|
if (A == B)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
|
@ -34,12 +39,14 @@ bool AlmostEqualUlps(double A, double B, int maxUlps)
|
||||||
/* default NAN won't compare as equal to anything. */
|
/* default NAN won't compare as equal to anything. */
|
||||||
assert(maxUlps > 0 && maxUlps < 4 * 1024 * 1024);
|
assert(maxUlps > 0 && maxUlps < 4 * 1024 * 1024);
|
||||||
|
|
||||||
aInt = *(int64_t*)&A;
|
uA.d = A;
|
||||||
|
aInt = uA.i;
|
||||||
/* Make aInt lexicographically ordered as a twos-complement int */
|
/* Make aInt lexicographically ordered as a twos-complement int */
|
||||||
if (aInt < 0)
|
if (aInt < 0)
|
||||||
aInt = int64_min - aInt;
|
aInt = int64_min - aInt;
|
||||||
|
|
||||||
bInt = *(int64_t*)&B;
|
uB.d = B;
|
||||||
|
bInt = uB.i;
|
||||||
/* Make bInt lexicographically ordered as a twos-complement int */
|
/* Make bInt lexicographically ordered as a twos-complement int */
|
||||||
if (bInt < 0)
|
if (bInt < 0)
|
||||||
bInt = int64_min - bInt;
|
bInt = int64_min - bInt;
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,9 @@ Author: 1985 Thomas L. Quarles
|
||||||
#include "ngspice/cktdefs.h"
|
#include "ngspice/cktdefs.h"
|
||||||
#include "ngspice/sperror.h"
|
#include "ngspice/sperror.h"
|
||||||
|
|
||||||
|
/* xmu=0: Backward Euler, xmu=0.5: trapezoidal (standard),
|
||||||
|
xmu=0.48: good damping of current ringing, e.g. in R.O.s. */
|
||||||
|
#define xmu 0.5
|
||||||
|
|
||||||
int
|
int
|
||||||
NIcomCof(CKTcircuit *ckt)
|
NIcomCof(CKTcircuit *ckt)
|
||||||
|
|
@ -17,6 +20,7 @@ NIcomCof(CKTcircuit *ckt)
|
||||||
double arg;
|
double arg;
|
||||||
double arg1;
|
double arg1;
|
||||||
|
|
||||||
|
|
||||||
/* this routine calculates the timestep-dependent terms used in the
|
/* this routine calculates the timestep-dependent terms used in the
|
||||||
* numerical integration.
|
* numerical integration.
|
||||||
*/
|
*/
|
||||||
|
|
@ -35,10 +39,8 @@ NIcomCof(CKTcircuit *ckt)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
ckt->CKTag[0]=1.0/ckt->CKTdelta/(1.0-0.5) ;
|
ckt->CKTag[0] = 1.0 / ckt->CKTdelta/(1.0 - xmu) ;
|
||||||
ckt->CKTag[1]=0.5/(1.0 - 0.5) ;
|
ckt->CKTag[1] = xmu / (1.0 - xmu) ;
|
||||||
/* above lines should have 'xmu' instead of .5 eventually */
|
|
||||||
/* (in all three places) */
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
||||||
|
|
@ -15,62 +15,124 @@ Author: 1985 Thomas L. Quarles
|
||||||
#include "ngspice/smpdefs.h"
|
#include "ngspice/smpdefs.h"
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
NIconvTest(CKTcircuit *ckt)
|
|
||||||
{
|
|
||||||
int i; /* generic loop variable */
|
|
||||||
int size; /* size of the matrix */
|
|
||||||
CKTnode *node; /* current matrix entry */
|
|
||||||
double old;
|
|
||||||
double new;
|
|
||||||
double tol;
|
|
||||||
|
|
||||||
node = ckt->CKTnodes;
|
int
|
||||||
size = SMPmatSize(ckt->CKTmatrix);
|
NIconvTest (CKTcircuit *ckt)
|
||||||
|
{
|
||||||
|
int i ; /* generic loop variable */
|
||||||
|
int size ; /* size of the matrix */
|
||||||
|
CKTnode *node ; /* current matrix entry */
|
||||||
|
|
||||||
|
#ifdef KIRCHHOFF
|
||||||
|
double maximum ;
|
||||||
|
CKTmkCurKCLnode *ptr ;
|
||||||
|
|
||||||
#ifdef STEPDEBUG
|
#ifdef STEPDEBUG
|
||||||
for (i=1;i<=size;i++) {
|
int j ;
|
||||||
new = ckt->CKTrhs [i] ;
|
#endif
|
||||||
old = ckt->CKTrhsOld [i] ;
|
#else
|
||||||
printf("chk for convergence: %s new: %g old: %g\n",CKTnodName(ckt,i),new,old);
|
double old, new, tol ;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
size = SMPmatSize (ckt->CKTmatrix) ;
|
||||||
|
node = ckt->CKTnodes ;
|
||||||
|
|
||||||
|
#ifndef KIRCHHOFF
|
||||||
|
#ifdef STEPDEBUG
|
||||||
|
for (i = 1 ; i <= size ; i++)
|
||||||
|
{
|
||||||
|
new = ckt->CKTrhs [i] ;
|
||||||
|
old = ckt->CKTrhsOld [i] ;
|
||||||
|
fprintf (err, "chk for convergence: %s new: %g old: %g\n", CKTnodName (ckt, i), new, old) ;
|
||||||
}
|
}
|
||||||
#endif /* STEPDEBUG */
|
#endif /* STEPDEBUG */
|
||||||
for (i=1;i<=size;i++) {
|
#endif
|
||||||
node = node->next;
|
|
||||||
new = ckt->CKTrhs [i] ;
|
for (i = 1 ; i <= size ; i++)
|
||||||
old = ckt->CKTrhsOld [i] ;
|
{
|
||||||
if(node->type == SP_VOLTAGE) {
|
node = node->next ;
|
||||||
tol = ckt->CKTreltol * (MAX(fabs(old),fabs(new))) +
|
|
||||||
ckt->CKTvoltTol;
|
#ifdef KIRCHHOFF
|
||||||
if (fabs(new-old) >tol ) {
|
/* KCL Verification */
|
||||||
|
if ((node->type == SP_VOLTAGE) && (!ckt->CKTnodeIsLinear [i]))
|
||||||
|
{
|
||||||
|
maximum = 0 ;
|
||||||
|
ptr = ckt->CKTmkCurKCLarray [i] ;
|
||||||
|
|
||||||
#ifdef STEPDEBUG
|
#ifdef STEPDEBUG
|
||||||
printf(" non-convergence at node (type=3) %s (fabs(new-old)>tol --> fabs(%g-%g)>%g)\n",CKTnodName(ckt,i),new,old,tol);
|
j = 0 ;
|
||||||
printf(" reltol: %g voltTol: %g (tol=reltol*(MAX(fabs(old),fabs(new))) + voltTol)\n",ckt->CKTreltol,ckt->CKTvoltTol);
|
#endif
|
||||||
|
|
||||||
|
while (ptr != NULL)
|
||||||
|
{
|
||||||
|
if (maximum < fabs (ptr->KCLcurrent))
|
||||||
|
maximum = fabs (ptr->KCLcurrent) ;
|
||||||
|
|
||||||
|
#ifdef STEPDEBUG
|
||||||
|
fprintf (stderr, "Index KCL Array: %d\tValue: %-.9g\tMaximum: %-.9g\n", j, fabs (ptr->KCLcurrent), maximum) ;
|
||||||
|
j++ ;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ptr = ptr->next ;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef STEPDEBUG
|
||||||
|
fprintf (stderr, "Index: %d\tValue: %-.9g\tThreshold: %-.9g\tMaximum: %-.9g\n", i, fabs (ckt->CKTfvk [i]),
|
||||||
|
ckt->CKTreltol * maximum + ckt->CKTabstol, maximum) ;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Check Convergence */
|
||||||
|
if (fabs (ckt->CKTfvk [i]) > (ckt->CKTreltol * maximum + ckt->CKTabstol))
|
||||||
|
return 1 ;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
new = ckt->CKTrhs [i] ;
|
||||||
|
old = ckt->CKTrhsOld [i] ;
|
||||||
|
if (node->type == SP_VOLTAGE)
|
||||||
|
{
|
||||||
|
tol = ckt->CKTreltol * (MAX (fabs (old), fabs (new))) + ckt->CKTvoltTol ;
|
||||||
|
if (fabs (new - old) > tol)
|
||||||
|
{
|
||||||
|
|
||||||
|
#ifdef STEPDEBUG
|
||||||
|
fprintf (err, " non-convergence at node (type=3) %s (fabs(new-old)>tol --> fabs(%g-%g)>%g)\n", CKTnodName (ckt, i), new, old, tol) ;
|
||||||
|
fprintf (err, " reltol: %g voltTol: %g (tol=reltol*(MAX(fabs(old),fabs(new))) + voltTol)\n", ckt->CKTreltol, ckt->CKTvoltTol) ;
|
||||||
#endif /* STEPDEBUG */
|
#endif /* STEPDEBUG */
|
||||||
ckt->CKTtroubleNode = i;
|
|
||||||
ckt->CKTtroubleElt = NULL;
|
ckt->CKTtroubleNode = i ;
|
||||||
return(1);
|
ckt->CKTtroubleElt = NULL ;
|
||||||
|
return 1 ;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
tol = ckt->CKTreltol * (MAX(fabs(old),fabs(new))) +
|
tol = ckt->CKTreltol * (MAX (fabs (old), fabs (new))) + ckt->CKTabstol ;
|
||||||
ckt->CKTabstol;
|
if (fabs (new - old) > tol)
|
||||||
if (fabs(new-old) >tol ) {
|
{
|
||||||
|
|
||||||
#ifdef STEPDEBUG
|
#ifdef STEPDEBUG
|
||||||
printf(" non-convergence at node (type=%d) %s (fabs(new-old)>tol --> fabs(%g-%g)>%g)\n",node->type,CKTnodName(ckt,i),new,old,tol);
|
fprintf (err, " non-convergence at node (type=%d) %s (fabs(new-old)>tol --> fabs(%g-%g)>%g)\n", node->type,
|
||||||
printf(" reltol: %g abstol: %g (tol=reltol*(MAX(fabs(old),fabs(new))) + abstol)\n",ckt->CKTreltol,ckt->CKTabstol);
|
CKTnodName (ckt, i), new, old, tol) ;
|
||||||
|
fprintf (err, " reltol: %g abstol: %g (tol=reltol*(MAX(fabs(old),fabs(new))) + abstol)\n", ckt->CKTreltol, ckt->CKTabstol) ;
|
||||||
#endif /* STEPDEBUG */
|
#endif /* STEPDEBUG */
|
||||||
ckt->CKTtroubleNode = i;
|
|
||||||
ckt->CKTtroubleElt = NULL;
|
ckt->CKTtroubleNode = i ;
|
||||||
return(1);
|
ckt->CKTtroubleElt = NULL ;
|
||||||
|
return 1 ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef KIRCHHOFF
|
||||||
|
return 0 ;
|
||||||
|
#else
|
||||||
#ifdef NEWCONV
|
#ifdef NEWCONV
|
||||||
i = CKTconvTest(ckt);
|
i = CKTconvTest (ckt) ;
|
||||||
if (i)
|
if (i)
|
||||||
ckt->CKTtroubleNode = 0;
|
ckt->CKTtroubleNode = 0 ;
|
||||||
return(i);
|
return i ;
|
||||||
#else /* NEWCONV */
|
#else /* NEWCONV */
|
||||||
return(0);
|
return 0 ;
|
||||||
#endif /* NEWCONV */
|
#endif /* NEWCONV */
|
||||||
|
#endif /* KIRCHHOFF */
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,9 +22,10 @@ int
|
||||||
NIreinit( CKTcircuit *ckt)
|
NIreinit( CKTcircuit *ckt)
|
||||||
{
|
{
|
||||||
int size;
|
int size;
|
||||||
#ifdef PREDICTOR
|
|
||||||
|
#if defined(PREDICTOR) || defined(KIRCHHOFF)
|
||||||
int i;
|
int i;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
size = SMPmatSize(ckt->CKTmatrix);
|
size = SMPmatSize(ckt->CKTmatrix);
|
||||||
CKALLOC(CKTrhs,size+1,double);
|
CKALLOC(CKTrhs,size+1,double);
|
||||||
|
|
@ -33,6 +34,17 @@ NIreinit( CKTcircuit *ckt)
|
||||||
CKALLOC(CKTirhs,size+1,double);
|
CKALLOC(CKTirhs,size+1,double);
|
||||||
CKALLOC(CKTirhsOld,size+1,double);
|
CKALLOC(CKTirhsOld,size+1,double);
|
||||||
CKALLOC(CKTirhsSpare,size+1,double);
|
CKALLOC(CKTirhsSpare,size+1,double);
|
||||||
|
|
||||||
|
#ifdef KIRCHHOFF
|
||||||
|
CKALLOC(CKTfvk,size+1,double);
|
||||||
|
CKALLOC(CKTnodeIsLinear,size+1,int);
|
||||||
|
for (i = 0 ; i <= size ; i++)
|
||||||
|
ckt->CKTnodeIsLinear [i] = 1 ;
|
||||||
|
CKALLOC(CKTmkCurKCLarray,size+1,CKTmkCurKCLnode*);
|
||||||
|
for (i = 0 ; i <= size ; i++)
|
||||||
|
ckt->CKTmkCurKCLarray [i] = NULL ;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef PREDICTOR
|
#ifdef PREDICTOR
|
||||||
CKALLOC(CKTpred,size+1,double);
|
CKALLOC(CKTpred,size+1,double);
|
||||||
for( i=0;i<8;i++) {
|
for( i=0;i<8;i++) {
|
||||||
|
|
|
||||||
|
|
@ -190,7 +190,7 @@ spCreate(int Size, int Complex, int *pError)
|
||||||
Matrix->ElementsRemaining = 0;
|
Matrix->ElementsRemaining = 0;
|
||||||
Matrix->FillinsRemaining = 0;
|
Matrix->FillinsRemaining = 0;
|
||||||
|
|
||||||
RecordAllocation( Matrix, (void *)Matrix );
|
RecordAllocation( Matrix, Matrix );
|
||||||
if (Matrix->Error == spNO_MEMORY) goto MemoryError;
|
if (Matrix->Error == spNO_MEMORY) goto MemoryError;
|
||||||
|
|
||||||
/* Take out the trash. */
|
/* Take out the trash. */
|
||||||
|
|
@ -311,7 +311,7 @@ spcGetElement(MatrixPtr Matrix)
|
||||||
/* Allocate block of MatrixElements if necessary. */
|
/* Allocate block of MatrixElements if necessary. */
|
||||||
if (Matrix->ElementsRemaining == 0) {
|
if (Matrix->ElementsRemaining == 0) {
|
||||||
pElements = SP_MALLOC(struct MatrixElement, ELEMENTS_PER_ALLOCATION);
|
pElements = SP_MALLOC(struct MatrixElement, ELEMENTS_PER_ALLOCATION);
|
||||||
RecordAllocation( Matrix, (void *)pElements );
|
RecordAllocation( Matrix, pElements );
|
||||||
if (Matrix->Error == spNO_MEMORY) return NULL;
|
if (Matrix->Error == spNO_MEMORY) return NULL;
|
||||||
Matrix->ElementsRemaining = ELEMENTS_PER_ALLOCATION;
|
Matrix->ElementsRemaining = ELEMENTS_PER_ALLOCATION;
|
||||||
Matrix->NextAvailElement = pElements;
|
Matrix->NextAvailElement = pElements;
|
||||||
|
|
@ -331,14 +331,14 @@ spcGetElement(MatrixPtr Matrix)
|
||||||
} else {
|
} else {
|
||||||
/* Allocate block of elements. */
|
/* Allocate block of elements. */
|
||||||
pElements = SP_MALLOC(struct MatrixElement, ELEMENTS_PER_ALLOCATION);
|
pElements = SP_MALLOC(struct MatrixElement, ELEMENTS_PER_ALLOCATION);
|
||||||
RecordAllocation( Matrix, (void *)pElements );
|
RecordAllocation( Matrix, pElements );
|
||||||
if (Matrix->Error == spNO_MEMORY) return NULL;
|
if (Matrix->Error == spNO_MEMORY) return NULL;
|
||||||
Matrix->ElementsRemaining = ELEMENTS_PER_ALLOCATION;
|
Matrix->ElementsRemaining = ELEMENTS_PER_ALLOCATION;
|
||||||
Matrix->NextAvailElement = pElements;
|
Matrix->NextAvailElement = pElements;
|
||||||
|
|
||||||
/* Allocate an element list structure. */
|
/* Allocate an element list structure. */
|
||||||
pListNode->Next = SP_MALLOC(struct ElementListNodeStruct,1);
|
pListNode->Next = SP_MALLOC(struct ElementListNodeStruct,1);
|
||||||
RecordAllocation( Matrix, (void *)pListNode->Next );
|
RecordAllocation( Matrix, pListNode->Next );
|
||||||
if (Matrix->Error == spNO_MEMORY)
|
if (Matrix->Error == spNO_MEMORY)
|
||||||
return NULL;
|
return NULL;
|
||||||
Matrix->LastElementListNode = pListNode = pListNode->Next;
|
Matrix->LastElementListNode = pListNode = pListNode->Next;
|
||||||
|
|
@ -402,14 +402,14 @@ InitializeElementBlocks(MatrixPtr Matrix, int InitialNumberOfElements,
|
||||||
|
|
||||||
/* Allocate block of MatrixElements for elements. */
|
/* Allocate block of MatrixElements for elements. */
|
||||||
pElement = SP_MALLOC(struct MatrixElement, InitialNumberOfElements);
|
pElement = SP_MALLOC(struct MatrixElement, InitialNumberOfElements);
|
||||||
RecordAllocation( Matrix, (void *)pElement );
|
RecordAllocation( Matrix, pElement );
|
||||||
if (Matrix->Error == spNO_MEMORY) return;
|
if (Matrix->Error == spNO_MEMORY) return;
|
||||||
Matrix->ElementsRemaining = InitialNumberOfElements;
|
Matrix->ElementsRemaining = InitialNumberOfElements;
|
||||||
Matrix->NextAvailElement = pElement;
|
Matrix->NextAvailElement = pElement;
|
||||||
|
|
||||||
/* Allocate an element list structure. */
|
/* Allocate an element list structure. */
|
||||||
Matrix->FirstElementListNode = SP_MALLOC(struct ElementListNodeStruct,1);
|
Matrix->FirstElementListNode = SP_MALLOC(struct ElementListNodeStruct,1);
|
||||||
RecordAllocation( Matrix, (void *)Matrix->FirstElementListNode );
|
RecordAllocation( Matrix, Matrix->FirstElementListNode );
|
||||||
if (Matrix->Error == spNO_MEMORY) return;
|
if (Matrix->Error == spNO_MEMORY) return;
|
||||||
Matrix->LastElementListNode = Matrix->FirstElementListNode;
|
Matrix->LastElementListNode = Matrix->FirstElementListNode;
|
||||||
|
|
||||||
|
|
@ -420,14 +420,14 @@ InitializeElementBlocks(MatrixPtr Matrix, int InitialNumberOfElements,
|
||||||
|
|
||||||
/* Allocate block of MatrixElements for fill-ins. */
|
/* Allocate block of MatrixElements for fill-ins. */
|
||||||
pElement = SP_MALLOC(struct MatrixElement, NumberOfFillinsExpected);
|
pElement = SP_MALLOC(struct MatrixElement, NumberOfFillinsExpected);
|
||||||
RecordAllocation( Matrix, (void *)pElement );
|
RecordAllocation( Matrix, pElement );
|
||||||
if (Matrix->Error == spNO_MEMORY) return;
|
if (Matrix->Error == spNO_MEMORY) return;
|
||||||
Matrix->FillinsRemaining = NumberOfFillinsExpected;
|
Matrix->FillinsRemaining = NumberOfFillinsExpected;
|
||||||
Matrix->NextAvailFillin = pElement;
|
Matrix->NextAvailFillin = pElement;
|
||||||
|
|
||||||
/* Allocate a fill-in list structure. */
|
/* Allocate a fill-in list structure. */
|
||||||
Matrix->FirstFillinListNode = SP_MALLOC(struct FillinListNodeStruct,1);
|
Matrix->FirstFillinListNode = SP_MALLOC(struct FillinListNodeStruct,1);
|
||||||
RecordAllocation( Matrix, (void *)Matrix->FirstFillinListNode );
|
RecordAllocation( Matrix, Matrix->FirstFillinListNode );
|
||||||
if (Matrix->Error == spNO_MEMORY) return;
|
if (Matrix->Error == spNO_MEMORY) return;
|
||||||
Matrix->LastFillinListNode = Matrix->FirstFillinListNode;
|
Matrix->LastFillinListNode = Matrix->FirstFillinListNode;
|
||||||
|
|
||||||
|
|
@ -487,14 +487,14 @@ spcGetFillin(MatrixPtr Matrix)
|
||||||
} else {
|
} else {
|
||||||
/* Allocate block of fill-ins. */
|
/* Allocate block of fill-ins. */
|
||||||
pFillins = SP_MALLOC(struct MatrixElement, ELEMENTS_PER_ALLOCATION);
|
pFillins = SP_MALLOC(struct MatrixElement, ELEMENTS_PER_ALLOCATION);
|
||||||
RecordAllocation( Matrix, (void *)pFillins );
|
RecordAllocation( Matrix, pFillins );
|
||||||
if (Matrix->Error == spNO_MEMORY) return NULL;
|
if (Matrix->Error == spNO_MEMORY) return NULL;
|
||||||
Matrix->FillinsRemaining = ELEMENTS_PER_ALLOCATION;
|
Matrix->FillinsRemaining = ELEMENTS_PER_ALLOCATION;
|
||||||
Matrix->NextAvailFillin = pFillins;
|
Matrix->NextAvailFillin = pFillins;
|
||||||
|
|
||||||
/* Allocate a fill-in list structure. */
|
/* Allocate a fill-in list structure. */
|
||||||
pListNode->Next = SP_MALLOC(struct FillinListNodeStruct,1);
|
pListNode->Next = SP_MALLOC(struct FillinListNodeStruct,1);
|
||||||
RecordAllocation( Matrix, (void *)pListNode->Next );
|
RecordAllocation( Matrix, pListNode->Next );
|
||||||
if (Matrix->Error == spNO_MEMORY) return NULL;
|
if (Matrix->Error == spNO_MEMORY) return NULL;
|
||||||
Matrix->LastFillinListNode = pListNode = pListNode->Next;
|
Matrix->LastFillinListNode = pListNode = pListNode->Next;
|
||||||
|
|
||||||
|
|
@ -646,9 +646,8 @@ AllocateBlockOfAllocationList(MatrixPtr Matrix)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
spDestroy(MatrixPtr eMatrix)
|
spDestroy(MatrixPtr Matrix)
|
||||||
{
|
{
|
||||||
MatrixPtr Matrix = eMatrix;
|
|
||||||
AllocationListPtr ListPtr, NextListPtr;
|
AllocationListPtr ListPtr, NextListPtr;
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -701,16 +700,16 @@ spDestroy(MatrixPtr eMatrix)
|
||||||
* The error status of the given matrix.
|
* The error status of the given matrix.
|
||||||
*
|
*
|
||||||
* >>> Arguments:
|
* >>> Arguments:
|
||||||
* eMatrix <input> (void *)
|
* Matrix <input> (void *)
|
||||||
* The matrix for which the error status is desired. */
|
* The matrix for which the error status is desired. */
|
||||||
int
|
int
|
||||||
spError(MatrixPtr eMatrix )
|
spError(MatrixPtr Matrix )
|
||||||
{
|
{
|
||||||
/* Begin `spError'. */
|
/* Begin `spError'. */
|
||||||
|
|
||||||
if (eMatrix != NULL) {
|
if (Matrix != NULL) {
|
||||||
assert(eMatrix->ID == SPARSE_ID);
|
assert(Matrix->ID == SPARSE_ID);
|
||||||
return eMatrix->Error;
|
return Matrix->Error;
|
||||||
} else {
|
} else {
|
||||||
/* This error may actually be spPANIC, no way to tell. */
|
/* This error may actually be spPANIC, no way to tell. */
|
||||||
return spNO_MEMORY;
|
return spNO_MEMORY;
|
||||||
|
|
@ -732,7 +731,7 @@ spError(MatrixPtr eMatrix )
|
||||||
* detected as singular or where a zero was detected on the diagonal.
|
* detected as singular or where a zero was detected on the diagonal.
|
||||||
*
|
*
|
||||||
* >>> Arguments:
|
* >>> Arguments:
|
||||||
* eMatrix <input> (void *)
|
* Matrix <input> (void *)
|
||||||
* The matrix for which the error status is desired.
|
* The matrix for which the error status is desired.
|
||||||
* pRow <output> (int *)
|
* pRow <output> (int *)
|
||||||
* The row number.
|
* The row number.
|
||||||
|
|
@ -741,10 +740,8 @@ spError(MatrixPtr eMatrix )
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
spWhereSingular(MatrixPtr eMatrix, int *pRow, int *pCol)
|
spWhereSingular(MatrixPtr Matrix, int *pRow, int *pCol)
|
||||||
{
|
{
|
||||||
MatrixPtr Matrix = eMatrix;
|
|
||||||
|
|
||||||
/* Begin `spWhereSingular'. */
|
/* Begin `spWhereSingular'. */
|
||||||
assert( IS_SPARSE( Matrix ) );
|
assert( IS_SPARSE( Matrix ) );
|
||||||
|
|
||||||
|
|
@ -769,7 +766,7 @@ spWhereSingular(MatrixPtr eMatrix, int *pRow, int *pCol)
|
||||||
* the matrix is returned.
|
* the matrix is returned.
|
||||||
*
|
*
|
||||||
* >>> Arguments:
|
* >>> Arguments:
|
||||||
* eMatrix <input> (void *)
|
* Matrix <input> (void *)
|
||||||
* Pointer to matrix.
|
* Pointer to matrix.
|
||||||
* External <input> (int)
|
* External <input> (int)
|
||||||
* If External is set TRUE, the external size , i.e., the value of the
|
* If External is set TRUE, the external size , i.e., the value of the
|
||||||
|
|
@ -779,10 +776,8 @@ spWhereSingular(MatrixPtr eMatrix, int *pRow, int *pCol)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
spGetSize(MatrixPtr eMatrix, int External)
|
spGetSize(MatrixPtr Matrix, int External)
|
||||||
{
|
{
|
||||||
MatrixPtr Matrix = eMatrix;
|
|
||||||
|
|
||||||
/* Begin `spGetSize'. */
|
/* Begin `spGetSize'. */
|
||||||
assert( IS_SPARSE( Matrix ) );
|
assert( IS_SPARSE( Matrix ) );
|
||||||
|
|
||||||
|
|
@ -809,28 +804,28 @@ spGetSize(MatrixPtr eMatrix, int External)
|
||||||
* Forces matrix to be either real or complex.
|
* Forces matrix to be either real or complex.
|
||||||
*
|
*
|
||||||
* >>> Arguments:
|
* >>> Arguments:
|
||||||
* eMatrix <input> (void *)
|
* Matrix <input> (void *)
|
||||||
* Pointer to matrix.
|
* Pointer to matrix.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
spSetReal(MatrixPtr eMatrix)
|
spSetReal(MatrixPtr Matrix)
|
||||||
{
|
{
|
||||||
/* Begin `spSetReal'. */
|
/* Begin `spSetReal'. */
|
||||||
|
|
||||||
assert( IS_SPARSE( eMatrix ));
|
assert( IS_SPARSE( Matrix ));
|
||||||
eMatrix->Complex = NO;
|
Matrix->Complex = NO;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
spSetComplex(MatrixPtr eMatrix)
|
spSetComplex(MatrixPtr Matrix)
|
||||||
{
|
{
|
||||||
/* Begin `spSetComplex'. */
|
/* Begin `spSetComplex'. */
|
||||||
|
|
||||||
assert( IS_SPARSE( eMatrix ));
|
assert( IS_SPARSE( Matrix ));
|
||||||
eMatrix->Complex = YES;
|
Matrix->Complex = YES;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -850,34 +845,34 @@ spSetComplex(MatrixPtr eMatrix)
|
||||||
* of original elements can be returned.
|
* of original elements can be returned.
|
||||||
*
|
*
|
||||||
* >>> Arguments:
|
* >>> Arguments:
|
||||||
* eMatrix <input> (void *)
|
* Matrix <input> (void *)
|
||||||
* Pointer to matrix.
|
* Pointer to matrix.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
spFillinCount(MatrixPtr eMatrix)
|
spFillinCount(MatrixPtr Matrix)
|
||||||
{
|
{
|
||||||
/* Begin `spFillinCount'. */
|
/* Begin `spFillinCount'. */
|
||||||
|
|
||||||
assert( IS_SPARSE( eMatrix ) );
|
assert( IS_SPARSE( Matrix ) );
|
||||||
return eMatrix->Fillins;
|
return Matrix->Fillins;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
spElementCount(MatrixPtr eMatrix)
|
spElementCount(MatrixPtr Matrix)
|
||||||
{
|
{
|
||||||
/* Begin `spElementCount'. */
|
/* Begin `spElementCount'. */
|
||||||
|
|
||||||
assert( IS_SPARSE( eMatrix ) );
|
assert( IS_SPARSE( Matrix ) );
|
||||||
return eMatrix->Elements;
|
return Matrix->Elements;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
spOriginalCount(MatrixPtr eMatrix)
|
spOriginalCount(MatrixPtr Matrix)
|
||||||
{
|
{
|
||||||
/* Begin `spOriginalCount'. */
|
/* Begin `spOriginalCount'. */
|
||||||
|
|
||||||
assert( IS_SPARSE( eMatrix ) );
|
assert( IS_SPARSE( Matrix ) );
|
||||||
return eMatrix->Originals;
|
return Matrix->Originals;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -93,9 +93,8 @@ static void ExpandTranslationArrays( MatrixPtr, int );
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
spClear(MatrixPtr eMatrix)
|
spClear(MatrixPtr Matrix)
|
||||||
{
|
{
|
||||||
MatrixPtr Matrix = eMatrix;
|
|
||||||
ElementPtr pElement;
|
ElementPtr pElement;
|
||||||
int I;
|
int I;
|
||||||
|
|
||||||
|
|
@ -180,10 +179,9 @@ spClear(MatrixPtr eMatrix)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
RealNumber *
|
RealNumber *
|
||||||
spFindElement(MatrixPtr eMatrix, int Row, int Col)
|
spFindElement(MatrixPtr Matrix, int Row, int Col)
|
||||||
{
|
{
|
||||||
MatrixPtr Matrix = eMatrix;
|
ElementPtr pElement;
|
||||||
RealNumber *pElement;
|
|
||||||
|
|
||||||
/* Begin `spFindElement'. */
|
/* Begin `spFindElement'. */
|
||||||
assert( IS_SPARSE( Matrix ) && Row >= 0 && Col >= 0 );
|
assert( IS_SPARSE( Matrix ) && Row >= 0 && Col >= 0 );
|
||||||
|
|
@ -210,7 +208,7 @@ RealNumber *pElement;
|
||||||
* is the first record in the MatrixElement structure.
|
* is the first record in the MatrixElement structure.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ((Row != Col) || ((pElement = (RealNumber *)Matrix->Diag[Row]) == NULL))
|
if ((Row != Col) || ((pElement = Matrix->Diag[Row]) == NULL))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Element does not exist or does not reside along diagonal. Search
|
* Element does not exist or does not reside along diagonal. Search
|
||||||
|
|
@ -218,11 +216,11 @@ RealNumber *pElement;
|
||||||
* element which is returned by spcFindElementInCol is cast into a
|
* element which is returned by spcFindElementInCol is cast into a
|
||||||
* pointer to Real, a RealNumber.
|
* pointer to Real, a RealNumber.
|
||||||
*/
|
*/
|
||||||
pElement = (RealNumber*)spcFindElementInCol( Matrix,
|
pElement = spcFindElementInCol( Matrix,
|
||||||
&(Matrix->FirstInCol[Col]),
|
&(Matrix->FirstInCol[Col]),
|
||||||
Row, Col, NO );
|
Row, Col, NO );
|
||||||
}
|
}
|
||||||
return pElement;
|
return & pElement->Real;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -263,10 +261,9 @@ RealNumber *pElement;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
RealNumber *
|
RealNumber *
|
||||||
spGetElement(MatrixPtr eMatrix, int Row, int Col)
|
spGetElement(MatrixPtr Matrix, int Row, int Col)
|
||||||
{
|
{
|
||||||
MatrixPtr Matrix = eMatrix;
|
ElementPtr pElement;
|
||||||
RealNumber *pElement;
|
|
||||||
|
|
||||||
/* Begin `spGetElement'. */
|
/* Begin `spGetElement'. */
|
||||||
assert( IS_SPARSE( Matrix ) && Row >= 0 && Col >= 0 );
|
assert( IS_SPARSE( Matrix ) && Row >= 0 && Col >= 0 );
|
||||||
|
|
@ -305,18 +302,18 @@ spGetElement(MatrixPtr eMatrix, int Row, int Col)
|
||||||
* statement depends on the fact that Real is the first record in
|
* statement depends on the fact that Real is the first record in
|
||||||
* the MatrixElement structure. */
|
* the MatrixElement structure. */
|
||||||
|
|
||||||
if ((Row != Col) || ((pElement = (RealNumber *)Matrix->Diag[Row]) == NULL))
|
if ((Row != Col) || ((pElement = Matrix->Diag[Row]) == NULL))
|
||||||
{
|
{
|
||||||
/* Element does not exist or does not reside along diagonal.
|
/* Element does not exist or does not reside along diagonal.
|
||||||
* Search column for element. As in the if statement above,
|
* Search column for element. As in the if statement above,
|
||||||
* the pointer to the element which is returned by
|
* the pointer to the element which is returned by
|
||||||
* spcFindElementInCol is cast into a pointer to Real, a
|
* spcFindElementInCol is cast into a pointer to Real, a
|
||||||
* RealNumber. */
|
* RealNumber. */
|
||||||
pElement = (RealNumber*)spcFindElementInCol( Matrix,
|
pElement = spcFindElementInCol( Matrix,
|
||||||
&(Matrix->FirstInCol[Col]),
|
&(Matrix->FirstInCol[Col]),
|
||||||
Row, Col, YES );
|
Row, Col, YES );
|
||||||
}
|
}
|
||||||
return pElement;
|
return & pElement->Real;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -644,7 +641,7 @@ spGetQuad(MatrixPtr Matrix, int Row1, int Row2, int Col1, int Col2,
|
||||||
(Template->Element4Negated == NULL))
|
(Template->Element4Negated == NULL))
|
||||||
return spNO_MEMORY;
|
return spNO_MEMORY;
|
||||||
|
|
||||||
if (Template->Element1 == &((MatrixPtr)Matrix)->TrashCan.Real)
|
if (Template->Element1 == & Matrix->TrashCan.Real)
|
||||||
SWAP( RealNumber *, Template->Element1, Template->Element2 );
|
SWAP( RealNumber *, Template->Element1, Template->Element2 );
|
||||||
|
|
||||||
return spOKAY;
|
return spOKAY;
|
||||||
|
|
@ -1145,9 +1142,8 @@ spGetInitInfo(RealNumber *pElement)
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
spInitialize(MatrixPtr eMatrix, int (*pInit)(RealNumber*, void *InitInfo, int , int Col))
|
spInitialize(MatrixPtr Matrix, int (*pInit)(RealNumber*, void *InitInfo, int , int Col))
|
||||||
{
|
{
|
||||||
MatrixPtr Matrix = eMatrix;
|
|
||||||
ElementPtr pElement;
|
ElementPtr pElement;
|
||||||
int J, Error, Col;
|
int J, Error, Col;
|
||||||
|
|
||||||
|
|
@ -1182,7 +1178,7 @@ spInitialize(MatrixPtr eMatrix, int (*pInit)(RealNumber*, void *InitInfo, int ,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Error = pInit ((RealNumber *)pElement, pElement->pInitInfo,
|
Error = pInit (& pElement->Real, pElement->pInitInfo,
|
||||||
Matrix->IntToExtRowMap[pElement->Row], Col);
|
Matrix->IntToExtRowMap[pElement->Row], Col);
|
||||||
if (Error)
|
if (Error)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -189,10 +189,9 @@ static int ZeroPivot( MatrixPtr, int );
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
spOrderAndFactor(MatrixPtr eMatrix, RealNumber RHS[], RealNumber RelThreshold,
|
spOrderAndFactor(MatrixPtr Matrix, RealNumber RHS[], RealNumber RelThreshold,
|
||||||
RealNumber AbsThreshold, int DiagPivoting)
|
RealNumber AbsThreshold, int DiagPivoting)
|
||||||
{
|
{
|
||||||
MatrixPtr Matrix = eMatrix;
|
|
||||||
ElementPtr pPivot;
|
ElementPtr pPivot;
|
||||||
int Step, Size, ReorderingRequired;
|
int Step, Size, ReorderingRequired;
|
||||||
RealNumber LargestInCol;
|
RealNumber LargestInCol;
|
||||||
|
|
@ -321,9 +320,8 @@ Done:
|
||||||
* Error is cleared in this function. */
|
* Error is cleared in this function. */
|
||||||
|
|
||||||
int
|
int
|
||||||
spFactor(MatrixPtr eMatrix)
|
spFactor(MatrixPtr Matrix)
|
||||||
{
|
{
|
||||||
MatrixPtr Matrix = eMatrix;
|
|
||||||
ElementPtr pElement;
|
ElementPtr pElement;
|
||||||
ElementPtr pColumn;
|
ElementPtr pColumn;
|
||||||
int Step, Size;
|
int Step, Size;
|
||||||
|
|
@ -333,10 +331,10 @@ spFactor(MatrixPtr eMatrix)
|
||||||
assert( IS_VALID(Matrix) && !Matrix->Factored);
|
assert( IS_VALID(Matrix) && !Matrix->Factored);
|
||||||
|
|
||||||
if (Matrix->NeedsOrdering) {
|
if (Matrix->NeedsOrdering) {
|
||||||
return spOrderAndFactor( eMatrix, NULL,
|
return spOrderAndFactor( Matrix, NULL,
|
||||||
0.0, 0.0, DIAG_PIVOTING_AS_DEFAULT );
|
0.0, 0.0, DIAG_PIVOTING_AS_DEFAULT );
|
||||||
}
|
}
|
||||||
if (!Matrix->Partitioned) spPartition( eMatrix, spDEFAULT_PARTITION );
|
if (!Matrix->Partitioned) spPartition( Matrix, spDEFAULT_PARTITION );
|
||||||
if (Matrix->Complex)
|
if (Matrix->Complex)
|
||||||
return FactorComplexMatrix( Matrix );
|
return FactorComplexMatrix( Matrix );
|
||||||
|
|
||||||
|
|
@ -569,9 +567,8 @@ FactorComplexMatrix( MatrixPtr Matrix )
|
||||||
* spINDIRECT_PARTITION, or spAUTO_PARTITION. */
|
* spINDIRECT_PARTITION, or spAUTO_PARTITION. */
|
||||||
|
|
||||||
void
|
void
|
||||||
spPartition(MatrixPtr eMatrix, int Mode)
|
spPartition(MatrixPtr Matrix, int Mode)
|
||||||
{
|
{
|
||||||
MatrixPtr Matrix = eMatrix;
|
|
||||||
ElementPtr pElement, pColumn;
|
ElementPtr pElement, pColumn;
|
||||||
int Step, Size;
|
int Step, Size;
|
||||||
int *Nc, *No, *Nm;
|
int *Nc, *No, *Nm;
|
||||||
|
|
@ -603,8 +600,8 @@ spPartition(MatrixPtr eMatrix, int Mode)
|
||||||
assert( Mode == spAUTO_PARTITION );
|
assert( Mode == spAUTO_PARTITION );
|
||||||
|
|
||||||
/* Otherwise, count all operations needed in when factoring matrix. */
|
/* Otherwise, count all operations needed in when factoring matrix. */
|
||||||
Nc = (int *)Matrix->MarkowitzRow;
|
Nc = Matrix->MarkowitzRow;
|
||||||
No = (int *)Matrix->MarkowitzCol;
|
No = Matrix->MarkowitzCol;
|
||||||
Nm = (int *)Matrix->MarkowitzProd;
|
Nm = (int *)Matrix->MarkowitzProd;
|
||||||
|
|
||||||
/* Start mock-factorization. */
|
/* Start mock-factorization. */
|
||||||
|
|
|
||||||
|
|
@ -133,9 +133,8 @@ int Printer_Width = PRINTER_WIDTH;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
spPrint(MatrixPtr eMatrix, int PrintReordered, int Data, int Header)
|
spPrint(MatrixPtr Matrix, int PrintReordered, int Data, int Header)
|
||||||
{
|
{
|
||||||
MatrixPtr Matrix = eMatrix;
|
|
||||||
int J = 0;
|
int J = 0;
|
||||||
int I, Row, Col, Size, Top;
|
int I, Row, Col, Size, Top;
|
||||||
int StartCol = 1, StopCol, Columns, ElementCount = 0;
|
int StartCol = 1, StopCol, Columns, ElementCount = 0;
|
||||||
|
|
@ -295,7 +294,7 @@ spPrint(MatrixPtr eMatrix, int PrintReordered, int Data, int Header)
|
||||||
{
|
{
|
||||||
/* Case where element exists */
|
/* Case where element exists */
|
||||||
if (Data)
|
if (Data)
|
||||||
printf(" %9.3g", (double)pElement->Real);
|
printf(" %9.3g", pElement->Real);
|
||||||
else
|
else
|
||||||
putchar('x');
|
putchar('x');
|
||||||
|
|
||||||
|
|
@ -326,7 +325,7 @@ spPrint(MatrixPtr eMatrix, int PrintReordered, int Data, int Header)
|
||||||
if (pImagElements[J - StartCol] != NULL)
|
if (pImagElements[J - StartCol] != NULL)
|
||||||
{
|
{
|
||||||
printf(" %8.2gj",
|
printf(" %8.2gj",
|
||||||
(double)pImagElements[J-StartCol]->Imag);
|
pImagElements[J-StartCol]->Imag);
|
||||||
}
|
}
|
||||||
else printf(" ");
|
else printf(" ");
|
||||||
}
|
}
|
||||||
|
|
@ -436,10 +435,9 @@ spPrint(MatrixPtr eMatrix, int PrintReordered, int Data, int Header)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
spFileMatrix(MatrixPtr eMatrix, char *File, char *Label, int Reordered,
|
spFileMatrix(MatrixPtr Matrix, char *File, char *Label, int Reordered,
|
||||||
int Data, int Header)
|
int Data, int Header)
|
||||||
{
|
{
|
||||||
MatrixPtr Matrix = eMatrix;
|
|
||||||
int I, Size;
|
int I, Size;
|
||||||
ElementPtr pElement;
|
ElementPtr pElement;
|
||||||
int Row, Col, Err;
|
int Row, Col, Err;
|
||||||
|
|
@ -518,7 +516,7 @@ spFileMatrix(MatrixPtr eMatrix, char *File, char *Label, int Reordered,
|
||||||
}
|
}
|
||||||
Err = fprintf
|
Err = fprintf
|
||||||
( pMatrixFile,"%d\t%d\t%-.15g\t%-.15g\n",
|
( pMatrixFile,"%d\t%d\t%-.15g\t%-.15g\n",
|
||||||
Row, Col, (double)pElement->Real, (double)pElement->Imag
|
Row, Col, pElement->Real, pElement->Imag
|
||||||
);
|
);
|
||||||
if (Err < 0) return 0;
|
if (Err < 0) return 0;
|
||||||
pElement = pElement->NextInCol;
|
pElement = pElement->NextInCol;
|
||||||
|
|
@ -541,7 +539,7 @@ spFileMatrix(MatrixPtr eMatrix, char *File, char *Label, int Reordered,
|
||||||
Col = Matrix->IntToExtColMap[I];
|
Col = Matrix->IntToExtColMap[I];
|
||||||
Err = fprintf
|
Err = fprintf
|
||||||
( pMatrixFile,"%d\t%d\t%-.15g\n",
|
( pMatrixFile,"%d\t%d\t%-.15g\n",
|
||||||
Row, Col, (double)pElement->Real
|
Row, Col, pElement->Real
|
||||||
);
|
);
|
||||||
if (Err < 0) return 0;
|
if (Err < 0) return 0;
|
||||||
pElement = pElement->NextInCol;
|
pElement = pElement->NextInCol;
|
||||||
|
|
@ -595,9 +593,8 @@ spFileMatrix(MatrixPtr eMatrix, char *File, char *Label, int Reordered,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
spFileVector(MatrixPtr eMatrix, char *File, RealVector RHS, RealVector iRHS)
|
spFileVector(MatrixPtr Matrix, char *File, RealVector RHS, RealVector iRHS)
|
||||||
{
|
{
|
||||||
MatrixPtr Matrix = eMatrix;
|
|
||||||
int I, Size, Err;
|
int I, Size, Err;
|
||||||
FILE *pMatrixFile;
|
FILE *pMatrixFile;
|
||||||
|
|
||||||
|
|
@ -621,7 +618,7 @@ spFileVector(MatrixPtr eMatrix, char *File, RealVector RHS, RealVector iRHS)
|
||||||
{
|
{
|
||||||
Err = fprintf
|
Err = fprintf
|
||||||
( pMatrixFile, "%-.15g\t%-.15g\n",
|
( pMatrixFile, "%-.15g\t%-.15g\n",
|
||||||
(double)RHS[I], (double)iRHS[I]
|
RHS[I], iRHS[I]
|
||||||
);
|
);
|
||||||
if (Err < 0) return 0;
|
if (Err < 0) return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -630,7 +627,7 @@ spFileVector(MatrixPtr eMatrix, char *File, RealVector RHS, RealVector iRHS)
|
||||||
{
|
{
|
||||||
for (I = 1; I <= Size; I++)
|
for (I = 1; I <= Size; I++)
|
||||||
{
|
{
|
||||||
if (fprintf(pMatrixFile, "%-.15g\n", (double)RHS[I]) < 0)
|
if (fprintf(pMatrixFile, "%-.15g\n", RHS[I]) < 0)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -686,9 +683,8 @@ spFileVector(MatrixPtr eMatrix, char *File, RealVector RHS, RealVector iRHS)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
spFileStats(MatrixPtr eMatrix, char *File, char *Label)
|
spFileStats(MatrixPtr Matrix, char *File, char *Label)
|
||||||
{
|
{
|
||||||
MatrixPtr Matrix = eMatrix;
|
|
||||||
int Size, I;
|
int Size, I;
|
||||||
ElementPtr pElement;
|
ElementPtr pElement;
|
||||||
int NumberOfElements;
|
int NumberOfElements;
|
||||||
|
|
|
||||||
|
|
@ -106,7 +106,7 @@ extern double scalbn(double, int);
|
||||||
extern double logb(double);
|
extern double logb(double);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void LoadGmin(SMPmatrix *eMatrix, double Gmin);
|
static void LoadGmin(SMPmatrix *Matrix, double Gmin);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SMPaddElt()
|
* SMPaddElt()
|
||||||
|
|
@ -183,7 +183,7 @@ SMPcReorder(SMPmatrix *Matrix, double PivTol, double PivRel,
|
||||||
*NumSwaps = 1;
|
*NumSwaps = 1;
|
||||||
spSetComplex( Matrix->SPmatrix );
|
spSetComplex( Matrix->SPmatrix );
|
||||||
return spOrderAndFactor( Matrix->SPmatrix, NULL,
|
return spOrderAndFactor( Matrix->SPmatrix, NULL,
|
||||||
(spREAL)PivRel, (spREAL)PivTol, YES );
|
PivRel, PivTol, YES );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -195,7 +195,7 @@ SMPreorder(SMPmatrix *Matrix, double PivTol, double PivRel, double Gmin)
|
||||||
spSetReal( Matrix->SPmatrix );
|
spSetReal( Matrix->SPmatrix );
|
||||||
LoadGmin( Matrix, Gmin );
|
LoadGmin( Matrix, Gmin );
|
||||||
return spOrderAndFactor( Matrix->SPmatrix, NULL,
|
return spOrderAndFactor( Matrix->SPmatrix, NULL,
|
||||||
(spREAL)PivRel, (spREAL)PivTol, YES );
|
PivRel, PivTol, YES );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -504,7 +504,7 @@ SMPcAddCol(SMPmatrix *eMatrix, int Accum_Col, int Addend_Col)
|
||||||
|
|
||||||
Addend = Matrix->FirstInCol[Addend_Col];
|
Addend = Matrix->FirstInCol[Addend_Col];
|
||||||
Prev = &Matrix->FirstInCol[Accum_Col];
|
Prev = &Matrix->FirstInCol[Accum_Col];
|
||||||
Accum = *Prev;;
|
Accum = *Prev;
|
||||||
|
|
||||||
while (Addend != NULL) {
|
while (Addend != NULL) {
|
||||||
while (Accum && Accum->Row < Addend->Row) {
|
while (Accum && Accum->Row < Addend->Row) {
|
||||||
|
|
|
||||||
|
|
@ -124,10 +124,9 @@ static void SolveComplexTransposedMatrix( MatrixPtr,
|
||||||
/*VARARGS3*/
|
/*VARARGS3*/
|
||||||
|
|
||||||
void
|
void
|
||||||
spSolve(MatrixPtr eMatrix, RealVector RHS, RealVector Solution,
|
spSolve(MatrixPtr Matrix, RealVector RHS, RealVector Solution,
|
||||||
RealVector iRHS, RealVector iSolution)
|
RealVector iRHS, RealVector iSolution)
|
||||||
{
|
{
|
||||||
MatrixPtr Matrix = eMatrix;
|
|
||||||
ElementPtr pElement;
|
ElementPtr pElement;
|
||||||
RealVector Intermediate;
|
RealVector Intermediate;
|
||||||
RealNumber Temp;
|
RealNumber Temp;
|
||||||
|
|
@ -400,10 +399,9 @@ SolveComplexMatrix( MatrixPtr Matrix, RealVector RHS, RealVector Solution , Real
|
||||||
/*VARARGS3*/
|
/*VARARGS3*/
|
||||||
|
|
||||||
void
|
void
|
||||||
spSolveTransposed(MatrixPtr eMatrix, RealVector RHS, RealVector Solution,
|
spSolveTransposed(MatrixPtr Matrix, RealVector RHS, RealVector Solution,
|
||||||
RealVector iRHS, RealVector iSolution)
|
RealVector iRHS, RealVector iSolution)
|
||||||
{
|
{
|
||||||
MatrixPtr Matrix = eMatrix;
|
|
||||||
ElementPtr pElement;
|
ElementPtr pElement;
|
||||||
RealVector Intermediate;
|
RealVector Intermediate;
|
||||||
int I, *pExtOrder, Size;
|
int I, *pExtOrder, Size;
|
||||||
|
|
|
||||||
|
|
@ -151,7 +151,7 @@ static void ComplexTransposedMatrixMultiply( MatrixPtr, RealVector, RealVector,
|
||||||
* Tom Quarles.
|
* Tom Quarles.
|
||||||
*
|
*
|
||||||
* >>> Arguments:
|
* >>> Arguments:
|
||||||
* eMatrix <input> (char *)
|
* Matrix <input> (char *)
|
||||||
* Pointer to the matrix to be preordered.
|
* Pointer to the matrix to be preordered.
|
||||||
*
|
*
|
||||||
* >>> Local variables;
|
* >>> Local variables;
|
||||||
|
|
@ -174,9 +174,8 @@ static void ComplexTransposedMatrixMultiply( MatrixPtr, RealVector, RealVector,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
spMNA_Preorder(MatrixPtr eMatrix)
|
spMNA_Preorder(MatrixPtr Matrix)
|
||||||
{
|
{
|
||||||
MatrixPtr Matrix = eMatrix;
|
|
||||||
int J, Size;
|
int J, Size;
|
||||||
ElementPtr pTwin1, pTwin2;
|
ElementPtr pTwin1, pTwin2;
|
||||||
int Twins, StartAt = 1;
|
int Twins, StartAt = 1;
|
||||||
|
|
@ -346,7 +345,7 @@ SwapCols( MatrixPtr Matrix, ElementPtr pTwin1, ElementPtr pTwin2 )
|
||||||
* should not be executed before the function spMNA_Preorder.
|
* should not be executed before the function spMNA_Preorder.
|
||||||
*
|
*
|
||||||
* >>> Arguments:
|
* >>> Arguments:
|
||||||
* eMatrix <input> (char *)
|
* Matrix <input> (char *)
|
||||||
* Pointer to the matrix to be scaled.
|
* Pointer to the matrix to be scaled.
|
||||||
* SolutionScaleFactors <input> (RealVector)
|
* SolutionScaleFactors <input> (RealVector)
|
||||||
* The array of Solution scale factors. These factors scale the columns.
|
* The array of Solution scale factors. These factors scale the columns.
|
||||||
|
|
@ -368,9 +367,8 @@ SwapCols( MatrixPtr Matrix, ElementPtr pTwin1, ElementPtr pTwin2 )
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
spScale(MatrixPtr eMatrix, RealVector RHS_ScaleFactors, RealVector SolutionScaleFactors)
|
spScale(MatrixPtr Matrix, RealVector RHS_ScaleFactors, RealVector SolutionScaleFactors)
|
||||||
{
|
{
|
||||||
MatrixPtr Matrix = eMatrix;
|
|
||||||
ElementPtr pElement;
|
ElementPtr pElement;
|
||||||
int I, lSize, *pExtOrder;
|
int I, lSize, *pExtOrder;
|
||||||
RealNumber ScaleFactor;
|
RealNumber ScaleFactor;
|
||||||
|
|
@ -556,7 +554,7 @@ MatrixPtr Matrix;
|
||||||
* before spMNA_Preorder().
|
* before spMNA_Preorder().
|
||||||
*
|
*
|
||||||
* >>> Arguments:
|
* >>> Arguments:
|
||||||
* eMatrix <input> (char *)
|
* Matrix <input> (char *)
|
||||||
* Pointer to the matrix.
|
* Pointer to the matrix.
|
||||||
* RHS <output> (RealVector)
|
* RHS <output> (RealVector)
|
||||||
* RHS is the right hand side. This is what is being solved for.
|
* RHS is the right hand side. This is what is being solved for.
|
||||||
|
|
@ -571,14 +569,13 @@ MatrixPtr Matrix;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
spMultiply(MatrixPtr eMatrix, RealVector RHS, RealVector Solution,
|
spMultiply(MatrixPtr Matrix, RealVector RHS, RealVector Solution,
|
||||||
RealVector iRHS, RealVector iSolution)
|
RealVector iRHS, RealVector iSolution)
|
||||||
{
|
{
|
||||||
ElementPtr pElement;
|
ElementPtr pElement;
|
||||||
RealVector Vector;
|
RealVector Vector;
|
||||||
RealNumber Sum;
|
RealNumber Sum;
|
||||||
int I, *pExtOrder;
|
int I, *pExtOrder;
|
||||||
MatrixPtr Matrix = eMatrix;
|
|
||||||
|
|
||||||
/* Begin `spMultiply'. */
|
/* Begin `spMultiply'. */
|
||||||
assert( IS_SPARSE( Matrix ) && !Matrix->Factored );
|
assert( IS_SPARSE( Matrix ) && !Matrix->Factored );
|
||||||
|
|
@ -702,7 +699,7 @@ ComplexMatrixMultiply( MatrixPtr Matrix, RealVector RHS, RealVector Solution , R
|
||||||
* before spMNA_Preorder().
|
* before spMNA_Preorder().
|
||||||
*
|
*
|
||||||
* >>> Arguments:
|
* >>> Arguments:
|
||||||
* eMatrix <input> (char *)
|
* Matrix <input> (char *)
|
||||||
* Pointer to the matrix.
|
* Pointer to the matrix.
|
||||||
* RHS <output> (RealVector)
|
* RHS <output> (RealVector)
|
||||||
* RHS is the right hand side. This is what is being solved for.
|
* RHS is the right hand side. This is what is being solved for.
|
||||||
|
|
@ -717,14 +714,13 @@ ComplexMatrixMultiply( MatrixPtr Matrix, RealVector RHS, RealVector Solution , R
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
spMultTransposed(MatrixPtr eMatrix, RealVector RHS, RealVector Solution,
|
spMultTransposed(MatrixPtr Matrix, RealVector RHS, RealVector Solution,
|
||||||
RealVector iRHS, RealVector iSolution)
|
RealVector iRHS, RealVector iSolution)
|
||||||
{
|
{
|
||||||
ElementPtr pElement;
|
ElementPtr pElement;
|
||||||
RealVector Vector;
|
RealVector Vector;
|
||||||
RealNumber Sum;
|
RealNumber Sum;
|
||||||
int I, *pExtOrder;
|
int I, *pExtOrder;
|
||||||
MatrixPtr Matrix = eMatrix;
|
|
||||||
|
|
||||||
/* Begin `spMultTransposed'. */
|
/* Begin `spMultTransposed'. */
|
||||||
assert( IS_SPARSE( Matrix ) && !Matrix->Factored );
|
assert( IS_SPARSE( Matrix ) && !Matrix->Factored );
|
||||||
|
|
@ -854,7 +850,7 @@ ComplexTransposedMatrixMultiply( MatrixPtr Matrix, RealVector RHS, RealVector So
|
||||||
* reasonable value and the logarithm of the scale factor is returned.
|
* reasonable value and the logarithm of the scale factor is returned.
|
||||||
*
|
*
|
||||||
* >>> Arguments:
|
* >>> Arguments:
|
||||||
* eMatrix <input> (char *)
|
* Matrix <input> (char *)
|
||||||
* A pointer to the matrix for which the determinant is desired.
|
* A pointer to the matrix for which the determinant is desired.
|
||||||
* pExponent <output> (int *)
|
* pExponent <output> (int *)
|
||||||
* The logarithm base 10 of the scale factor for the determinant. To find
|
* The logarithm base 10 of the scale factor for the determinant. To find
|
||||||
|
|
@ -878,10 +874,9 @@ ComplexTransposedMatrixMultiply( MatrixPtr Matrix, RealVector RHS, RealVector So
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
spDeterminant(MatrixPtr eMatrix, int *pExponent, RealNumber *pDeterminant,
|
spDeterminant(MatrixPtr Matrix, int *pExponent, RealNumber *pDeterminant,
|
||||||
RealNumber *piDeterminant)
|
RealNumber *piDeterminant)
|
||||||
{
|
{
|
||||||
MatrixPtr Matrix = eMatrix;
|
|
||||||
int I, Size;
|
int I, Size;
|
||||||
RealNumber Norm, nr, ni;
|
RealNumber Norm, nr, ni;
|
||||||
ComplexNumber Pivot, cDeterminant;
|
ComplexNumber Pivot, cDeterminant;
|
||||||
|
|
@ -1037,9 +1032,8 @@ spDeterminant(MatrixPtr eMatrix, int *pExponent, RealNumber *pDeterminant,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
spStripFills(MatrixPtr eMatrix)
|
spStripFills(MatrixPtr Matrix)
|
||||||
{
|
{
|
||||||
MatrixPtr Matrix = eMatrix;
|
|
||||||
struct FillinListNodeStruct *pListNode;
|
struct FillinListNodeStruct *pListNode;
|
||||||
|
|
||||||
/* Begin `spStripFills'. */
|
/* Begin `spStripFills'. */
|
||||||
|
|
@ -1109,10 +1103,8 @@ spStripFills(MatrixPtr eMatrix)
|
||||||
* frame. This assumes that the matrix will be replaced with one of
|
* frame. This assumes that the matrix will be replaced with one of
|
||||||
* the same size. */
|
* the same size. */
|
||||||
void
|
void
|
||||||
spStripMatrix(MatrixPtr eMatrix)
|
spStripMatrix(MatrixPtr Matrix)
|
||||||
{
|
{
|
||||||
MatrixPtr Matrix = eMatrix;
|
|
||||||
|
|
||||||
/* Begin `spStripMatrix'. */
|
/* Begin `spStripMatrix'. */
|
||||||
assert( IS_SPARSE( Matrix ) );
|
assert( IS_SPARSE( Matrix ) );
|
||||||
if (Matrix->Elements == 0) return;
|
if (Matrix->Elements == 0) return;
|
||||||
|
|
@ -1124,7 +1116,6 @@ spStripMatrix(MatrixPtr eMatrix)
|
||||||
|
|
||||||
/* Reset the element lists. */
|
/* Reset the element lists. */
|
||||||
{
|
{
|
||||||
ElementPtr pElement;
|
|
||||||
struct ElementListNodeStruct *pListNode;
|
struct ElementListNodeStruct *pListNode;
|
||||||
|
|
||||||
pListNode = Matrix->LastElementListNode = Matrix->FirstElementListNode;
|
pListNode = Matrix->LastElementListNode = Matrix->FirstElementListNode;
|
||||||
|
|
@ -1134,7 +1125,6 @@ spStripMatrix(MatrixPtr eMatrix)
|
||||||
|
|
||||||
/* Reset the fill-in lists. */
|
/* Reset the fill-in lists. */
|
||||||
{
|
{
|
||||||
ElementPtr pFillin;
|
|
||||||
struct FillinListNodeStruct *pListNode;
|
struct FillinListNodeStruct *pListNode;
|
||||||
|
|
||||||
pListNode = Matrix->LastFillinListNode = Matrix->FirstFillinListNode;
|
pListNode = Matrix->LastFillinListNode = Matrix->FirstFillinListNode;
|
||||||
|
|
@ -1171,7 +1161,7 @@ spStripMatrix(MatrixPtr eMatrix)
|
||||||
* doesn't exist.
|
* doesn't exist.
|
||||||
*
|
*
|
||||||
* >>> Arguments:
|
* >>> Arguments:
|
||||||
* eMatrix <input> (char *)
|
* Matrix <input> (char *)
|
||||||
* Pointer to the matrix in which the row and column are to be deleted.
|
* Pointer to the matrix in which the row and column are to be deleted.
|
||||||
* Row <input> (int)
|
* Row <input> (int)
|
||||||
* Row to be deleted.
|
* Row to be deleted.
|
||||||
|
|
@ -1197,9 +1187,8 @@ spStripMatrix(MatrixPtr eMatrix)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
spDeleteRowAndCol(MatrixPtr eMatrix, int Row, int Col)
|
spDeleteRowAndCol(MatrixPtr Matrix, int Row, int Col)
|
||||||
{
|
{
|
||||||
MatrixPtr Matrix = eMatrix;
|
|
||||||
ElementPtr pElement, *ppElement, pLastElement;
|
ElementPtr pElement, *ppElement, pLastElement;
|
||||||
int Size, ExtRow, ExtCol;
|
int Size, ExtRow, ExtCol;
|
||||||
ElementPtr spcFindElementInCol();
|
ElementPtr spcFindElementInCol();
|
||||||
|
|
@ -1306,13 +1295,12 @@ spDeleteRowAndCol(MatrixPtr eMatrix, int Row, int Col)
|
||||||
* previous factorization. If the matrix was singular, zero is returned.
|
* previous factorization. If the matrix was singular, zero is returned.
|
||||||
*
|
*
|
||||||
* >>> Arguments:
|
* >>> Arguments:
|
||||||
* eMatrix <input> (char *)
|
* Matrix <input> (char *)
|
||||||
* Pointer to the matrix. */
|
* Pointer to the matrix. */
|
||||||
|
|
||||||
RealNumber
|
RealNumber
|
||||||
spPseudoCondition(MatrixPtr eMatrix)
|
spPseudoCondition(MatrixPtr Matrix)
|
||||||
{
|
{
|
||||||
MatrixPtr Matrix = eMatrix;
|
|
||||||
int I;
|
int I;
|
||||||
ArrayOfElementPtrs Diag;
|
ArrayOfElementPtrs Diag;
|
||||||
RealNumber MaxPivot, MinPivot, Mag;
|
RealNumber MaxPivot, MinPivot, Mag;
|
||||||
|
|
@ -1388,7 +1376,7 @@ spPseudoCondition(MatrixPtr eMatrix)
|
||||||
* zero is returned.
|
* zero is returned.
|
||||||
*
|
*
|
||||||
* >>> Arguments:
|
* >>> Arguments:
|
||||||
* eMatrix <input> (char *)
|
* Matrix <input> (char *)
|
||||||
* Pointer to the matrix.
|
* Pointer to the matrix.
|
||||||
* NormOfMatrix <input> (RealNumber)
|
* NormOfMatrix <input> (RealNumber)
|
||||||
* The L-infinity norm of the unfactored matrix as computed by
|
* The L-infinity norm of the unfactored matrix as computed by
|
||||||
|
|
@ -1401,9 +1389,8 @@ spPseudoCondition(MatrixPtr eMatrix)
|
||||||
* spNO_MEMORY */
|
* spNO_MEMORY */
|
||||||
|
|
||||||
RealNumber
|
RealNumber
|
||||||
spCondition(MatrixPtr eMatrix, RealNumber NormOfMatrix, int *pError)
|
spCondition(MatrixPtr Matrix, RealNumber NormOfMatrix, int *pError)
|
||||||
{
|
{
|
||||||
MatrixPtr Matrix = eMatrix;
|
|
||||||
ElementPtr pElement;
|
ElementPtr pElement;
|
||||||
RealVector T, Tm;
|
RealVector T, Tm;
|
||||||
int I, K, Row;
|
int I, K, Row;
|
||||||
|
|
@ -1824,14 +1811,13 @@ int *pError;
|
||||||
* The largest absolute row sum of matrix.
|
* The largest absolute row sum of matrix.
|
||||||
*
|
*
|
||||||
* >>> Arguments:
|
* >>> Arguments:
|
||||||
* eMatrix <input> (char *)
|
* Matrix <input> (char *)
|
||||||
* Pointer to the matrix.
|
* Pointer to the matrix.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
RealNumber
|
RealNumber
|
||||||
spNorm(MatrixPtr eMatrix)
|
spNorm(MatrixPtr Matrix)
|
||||||
{
|
{
|
||||||
MatrixPtr Matrix = eMatrix;
|
|
||||||
ElementPtr pElement;
|
ElementPtr pElement;
|
||||||
int I;
|
int I;
|
||||||
RealNumber Max = 0.0, AbsRowSum;
|
RealNumber Max = 0.0, AbsRowSum;
|
||||||
|
|
@ -1942,14 +1928,13 @@ spNorm(MatrixPtr eMatrix)
|
||||||
* largest element in any of the reduced submatrices is returned.
|
* largest element in any of the reduced submatrices is returned.
|
||||||
*
|
*
|
||||||
* >>> Arguments:
|
* >>> Arguments:
|
||||||
* eMatrix <input> (char *)
|
* Matrix <input> (char *)
|
||||||
* Pointer to the matrix.
|
* Pointer to the matrix.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
RealNumber
|
RealNumber
|
||||||
spLargestElement(MatrixPtr eMatrix)
|
spLargestElement(MatrixPtr Matrix)
|
||||||
{
|
{
|
||||||
MatrixPtr Matrix = eMatrix;
|
|
||||||
int I;
|
int I;
|
||||||
RealNumber Mag, AbsColSum, Max = 0.0, MaxRow = 0.0, MaxCol = 0.0;
|
RealNumber Mag, AbsColSum, Max = 0.0, MaxRow = 0.0, MaxCol = 0.0;
|
||||||
RealNumber Pivot;
|
RealNumber Pivot;
|
||||||
|
|
@ -2066,7 +2051,7 @@ spLargestElement(MatrixPtr eMatrix)
|
||||||
* Returns a bound on the magnitude of the largest element in E = A - LU.
|
* Returns a bound on the magnitude of the largest element in E = A - LU.
|
||||||
*
|
*
|
||||||
* >>> Arguments:
|
* >>> Arguments:
|
||||||
* eMatrix <input> (char *)
|
* Matrix <input> (char *)
|
||||||
* Pointer to the matrix.
|
* Pointer to the matrix.
|
||||||
* Rho <input> (RealNumber)
|
* Rho <input> (RealNumber)
|
||||||
* The bound on the magnitude of the largest element in any of the
|
* The bound on the magnitude of the largest element in any of the
|
||||||
|
|
@ -2076,9 +2061,8 @@ spLargestElement(MatrixPtr eMatrix)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
RealNumber
|
RealNumber
|
||||||
spRoundoff(MatrixPtr eMatrix, RealNumber Rho)
|
spRoundoff(MatrixPtr Matrix, RealNumber Rho)
|
||||||
{
|
{
|
||||||
MatrixPtr Matrix = eMatrix;
|
|
||||||
ElementPtr pElement;
|
ElementPtr pElement;
|
||||||
int Count, I, MaxCount = 0;
|
int Count, I, MaxCount = 0;
|
||||||
RealNumber Reid, Gear;
|
RealNumber Reid, Gear;
|
||||||
|
|
@ -2087,7 +2071,7 @@ spRoundoff(MatrixPtr eMatrix, RealNumber Rho)
|
||||||
assert( IS_SPARSE(Matrix) && IS_FACTORED(Matrix) );
|
assert( IS_SPARSE(Matrix) && IS_FACTORED(Matrix) );
|
||||||
|
|
||||||
/* Compute Barlow's bound if it is not given. */
|
/* Compute Barlow's bound if it is not given. */
|
||||||
if (Rho < 0.0) Rho = spLargestElement( eMatrix );
|
if (Rho < 0.0) Rho = spLargestElement( Matrix );
|
||||||
|
|
||||||
/* Find the maximum number of off-diagonals in L if not previously computed. */
|
/* Find the maximum number of off-diagonals in L if not previously computed. */
|
||||||
if (Matrix->MaxRowCountInLowerTri < 0)
|
if (Matrix->MaxRowCountInLowerTri < 0)
|
||||||
|
|
@ -2133,7 +2117,7 @@ spRoundoff(MatrixPtr eMatrix, RealNumber Rho)
|
||||||
* error state of sparse. No message is produced if there is no error.
|
* error state of sparse. No message is produced if there is no error.
|
||||||
*
|
*
|
||||||
* >>> Arguments:
|
* >>> Arguments:
|
||||||
* eMatrix <input> (char *)
|
* Matrix <input> (char *)
|
||||||
* Matrix for which the error message is to be printed.
|
* Matrix for which the error message is to be printed.
|
||||||
* Stream <input> (FILE *)
|
* Stream <input> (FILE *)
|
||||||
* Stream to which the error message is to be printed.
|
* Stream to which the error message is to be printed.
|
||||||
|
|
@ -2143,17 +2127,17 @@ spRoundoff(MatrixPtr eMatrix, RealNumber Rho)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
spErrorMessage(MatrixPtr eMatrix, FILE *Stream, char *Originator)
|
spErrorMessage(MatrixPtr Matrix, FILE *Stream, char *Originator)
|
||||||
{
|
{
|
||||||
int Row, Col, Error;
|
int Row, Col, Error;
|
||||||
|
|
||||||
/* Begin `spErrorMessage'. */
|
/* Begin `spErrorMessage'. */
|
||||||
if (eMatrix == NULL)
|
if (Matrix == NULL)
|
||||||
Error = spNO_MEMORY;
|
Error = spNO_MEMORY;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
assert(eMatrix->ID == SPARSE_ID);
|
assert(Matrix->ID == SPARSE_ID);
|
||||||
Error = eMatrix->Error;
|
Error = Matrix->Error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Error == spOKAY) return;
|
if (Error == spOKAY) return;
|
||||||
|
|
@ -2172,13 +2156,13 @@ spErrorMessage(MatrixPtr eMatrix, FILE *Stream, char *Originator)
|
||||||
fprintf( Stream, "insufficient memory available.\n");
|
fprintf( Stream, "insufficient memory available.\n");
|
||||||
else if (Error == spSINGULAR)
|
else if (Error == spSINGULAR)
|
||||||
{
|
{
|
||||||
spWhereSingular( eMatrix, &Row, &Col );
|
spWhereSingular( Matrix, &Row, &Col );
|
||||||
fprintf( Stream, "singular matrix detected at row %d and column %d.\n",
|
fprintf( Stream, "singular matrix detected at row %d and column %d.\n",
|
||||||
Row, Col);
|
Row, Col);
|
||||||
}
|
}
|
||||||
else if (Error == spZERO_DIAG)
|
else if (Error == spZERO_DIAG)
|
||||||
{
|
{
|
||||||
spWhereSingular( eMatrix, &Row, &Col );
|
spWhereSingular( Matrix, &Row, &Col );
|
||||||
fprintf( Stream, "zero diagonal detected at row %d and column %d.\n",
|
fprintf( Stream, "zero diagonal detected at row %d and column %d.\n",
|
||||||
Row, Col);
|
Row, Col);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,9 @@ Copyright 1990 Regents of the University of California. All rights reserved.
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_FTIME
|
||||||
|
# include <sys/timeb.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* Return the date. Return value is static data. */
|
/* Return the date. Return value is static data. */
|
||||||
|
|
@ -65,8 +68,6 @@ datestring(void)
|
||||||
|
|
||||||
/* return time interval in seconds and milliseconds */
|
/* return time interval in seconds and milliseconds */
|
||||||
|
|
||||||
#ifndef HAVE_GETRUSAGE
|
|
||||||
#ifndef HAVE_TIMES
|
|
||||||
#ifdef HAVE_FTIME
|
#ifdef HAVE_FTIME
|
||||||
|
|
||||||
struct timeb timebegin;
|
struct timeb timebegin;
|
||||||
|
|
@ -84,8 +85,6 @@ void timediff(struct timeb *now, struct timeb *begin, int *sec, int *msec)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -9,16 +9,12 @@
|
||||||
char * datestring(void);
|
char * datestring(void);
|
||||||
double seconds(void);
|
double seconds(void);
|
||||||
|
|
||||||
#ifndef HAVE_GETRUSAGE
|
|
||||||
#ifndef HAVE_TIMES
|
|
||||||
#ifdef HAVE_FTIME
|
#ifdef HAVE_FTIME
|
||||||
|
|
||||||
extern struct timeb timebegin;
|
extern struct timeb timebegin;
|
||||||
|
|
||||||
void timediff(struct timeb *, struct timeb *, int *, int *);
|
void timediff(struct timeb *, struct timeb *, int *, int *);
|
||||||
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,12 @@
|
||||||
#define STDERR_FILENO 2
|
#define STDERR_FILENO 2
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//#define low_latency
|
|
||||||
|
/* If a calling function has high latency times during printing,
|
||||||
|
causing memory access errors, you may undef the following line.
|
||||||
|
Printing messages are assembled in a wordlist, and sent to the caller
|
||||||
|
via a new thread. Delays may occur. */
|
||||||
|
#define low_latency
|
||||||
|
|
||||||
/**********************************************************************/
|
/**********************************************************************/
|
||||||
/* Header files for C functions */
|
/* Header files for C functions */
|
||||||
|
|
@ -131,11 +136,9 @@ typedef pthread_t threadId_t;
|
||||||
#include <frontend/com_measure2.h>
|
#include <frontend/com_measure2.h>
|
||||||
#include <frontend/misccoms.h>
|
#include <frontend/misccoms.h>
|
||||||
|
|
||||||
#ifndef HAVE_GETRUSAGE
|
|
||||||
#ifdef HAVE_FTIME
|
#ifdef HAVE_FTIME
|
||||||
#include <sys/timeb.h>
|
#include <sys/timeb.h>
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
/* To interupt a spice run */
|
/* To interupt a spice run */
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
@ -195,6 +198,7 @@ int sh_vfprintf(FILE *f, const char *fmt, va_list args);
|
||||||
int sh_fputsll(const char *input, FILE* outf);
|
int sh_fputsll(const char *input, FILE* outf);
|
||||||
|
|
||||||
int sh_ExecutePerLoop(void);
|
int sh_ExecutePerLoop(void);
|
||||||
|
double getvsrcval(double, char*);
|
||||||
int sh_vecinit(runDesc *run);
|
int sh_vecinit(runDesc *run);
|
||||||
|
|
||||||
void shared_exit(int status);
|
void shared_exit(int status);
|
||||||
|
|
@ -203,6 +207,8 @@ void sighandler_sharedspice(int num);
|
||||||
|
|
||||||
void wl_delete_first(wordlist **wlstart, wordlist **wlend);
|
void wl_delete_first(wordlist **wlstart, wordlist **wlend);
|
||||||
|
|
||||||
|
int add_bkpt(void);
|
||||||
|
|
||||||
#if !defined(low_latency)
|
#if !defined(low_latency)
|
||||||
static char* outstorage(char*, bool);
|
static char* outstorage(char*, bool);
|
||||||
static void printsend(void);
|
static void printsend(void);
|
||||||
|
|
@ -217,6 +223,7 @@ static ControlledExit* ngexit;
|
||||||
static SendData* datfcn;
|
static SendData* datfcn;
|
||||||
static SendInitData* datinitfcn;
|
static SendInitData* datinitfcn;
|
||||||
static BGThreadRunning* bgtr;
|
static BGThreadRunning* bgtr;
|
||||||
|
static GetVSRCData* getvdat;
|
||||||
static pvector_info myvec = NULL;
|
static pvector_info myvec = NULL;
|
||||||
char **allvecs = NULL;
|
char **allvecs = NULL;
|
||||||
char **allplots = NULL;
|
char **allplots = NULL;
|
||||||
|
|
@ -225,6 +232,7 @@ static bool nostatuswanted = FALSE;
|
||||||
static bool nodatawanted = FALSE;
|
static bool nodatawanted = FALSE;
|
||||||
static bool nodatainitwanted = FALSE;
|
static bool nodatainitwanted = FALSE;
|
||||||
static bool nobgtrwanted = FALSE;
|
static bool nobgtrwanted = FALSE;
|
||||||
|
static bool wantvdat = FALSE;
|
||||||
static bool immediate = FALSE;
|
static bool immediate = FALSE;
|
||||||
static bool coquit = FALSE;
|
static bool coquit = FALSE;
|
||||||
static jmp_buf errbufm, errbufc;
|
static jmp_buf errbufm, errbufc;
|
||||||
|
|
@ -244,7 +252,9 @@ mutexType fputsMutex;
|
||||||
static bool is_initialized = FALSE;
|
static bool is_initialized = FALSE;
|
||||||
static char* no_init = "Error: ngspice is not initialized!\n Run ngSpice_Init first";
|
static char* no_init = "Error: ngspice is not initialized!\n Run ngSpice_Init first";
|
||||||
|
|
||||||
static bool printstopp = FALSE;
|
/* identifier for this ngspice invocation */
|
||||||
|
static int ng_ident = 0;
|
||||||
|
|
||||||
|
|
||||||
/*helper function*//*
|
/*helper function*//*
|
||||||
static struct plot *
|
static struct plot *
|
||||||
|
|
@ -293,12 +303,16 @@ static threadId_t tid, printtid, bgtid = (threadId_t) 0;
|
||||||
static bool fl_running = FALSE;
|
static bool fl_running = FALSE;
|
||||||
static bool fl_exited = TRUE;
|
static bool fl_exited = TRUE;
|
||||||
|
|
||||||
|
static bool printstopp = FALSE;
|
||||||
|
static bool ps_exited = TRUE;
|
||||||
|
|
||||||
#if defined(__MINGW32__) || defined(_MSC_VER)
|
#if defined(__MINGW32__) || defined(_MSC_VER)
|
||||||
#define EXPORT_FLAVOR WINAPI
|
#define EXPORT_FLAVOR WINAPI
|
||||||
#else
|
#else
|
||||||
#define EXPORT_FLAVOR
|
#define EXPORT_FLAVOR
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* starts a background thread, e.g. from command bg_run */
|
||||||
static void * EXPORT_FLAVOR
|
static void * EXPORT_FLAVOR
|
||||||
_thread_run(void *string)
|
_thread_run(void *string)
|
||||||
{
|
{
|
||||||
|
|
@ -324,7 +338,7 @@ _thread_run(void *string)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*Stops a running thread, hopefully */
|
/*Stops a running background thread, hopefully */
|
||||||
static int EXPORT_FLAVOR
|
static int EXPORT_FLAVOR
|
||||||
_thread_stop(void)
|
_thread_stop(void)
|
||||||
{
|
{
|
||||||
|
|
@ -374,13 +388,16 @@ sighandler_sharedspice(int num)
|
||||||
|
|
||||||
#endif /*THREADS*/
|
#endif /*THREADS*/
|
||||||
|
|
||||||
|
/* run a ngspice command */
|
||||||
static int
|
static int
|
||||||
runc(char* command)
|
runc(char* command)
|
||||||
{
|
{
|
||||||
char buf[1024] = "";
|
char buf[1024] = "";
|
||||||
sighandler oldHandler;
|
sighandler oldHandler;
|
||||||
#ifdef THREADS
|
#ifdef THREADS
|
||||||
|
#ifndef low_latency
|
||||||
|
int timeout = 0;
|
||||||
|
#endif
|
||||||
char *string;
|
char *string;
|
||||||
bool fl_bg = FALSE;
|
bool fl_bg = FALSE;
|
||||||
command_id = threadid_self();
|
command_id = threadid_self();
|
||||||
|
|
@ -392,12 +409,24 @@ runc(char* command)
|
||||||
#ifndef low_latency
|
#ifndef low_latency
|
||||||
/* stop the printf thread 'printsend()' */
|
/* stop the printf thread 'printsend()' */
|
||||||
else if (cieq("bg_pstop", command)) {
|
else if (cieq("bg_pstop", command)) {
|
||||||
printstopp = TRUE;
|
while (!ps_exited && timeout < 100) {
|
||||||
|
printstopp = TRUE;
|
||||||
|
|
||||||
#if defined(__MINGW32__) || defined(_MSC_VER)
|
#if defined(__MINGW32__) || defined(_MSC_VER)
|
||||||
Sleep(100); // va: windows native
|
Sleep(100); // va: windows native
|
||||||
#else
|
#else
|
||||||
usleep(10000);
|
usleep(10000);
|
||||||
#endif
|
#endif
|
||||||
|
timeout++;
|
||||||
|
}
|
||||||
|
if (!ps_exited) {
|
||||||
|
fprintf(stderr, "Error: Couldn't stop printsend thread\n");
|
||||||
|
return EXIT_BAD;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
fprintf(stdout, "Printsend thread stopped with timeout = %d\n", timeout);
|
||||||
|
|
||||||
|
printstopp = FALSE;
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -408,7 +437,7 @@ runc(char* command)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Catch Ctrl-C to break simulations */
|
/* Catch Ctrl-C to break simulations */
|
||||||
#if !defined(_MSC_VER) /*&& !defined(__MINGW32__) */
|
#if 1 //!defined(_MSC_VER) /*&& !defined(__MINGW32__) */
|
||||||
oldHandler = signal(SIGINT, (SIGNAL_FUNCTION) ft_sigintr);
|
oldHandler = signal(SIGINT, (SIGNAL_FUNCTION) ft_sigintr);
|
||||||
if (SETJMP(jbuf, 1) != 0) {
|
if (SETJMP(jbuf, 1) != 0) {
|
||||||
signal(SIGINT, oldHandler);
|
signal(SIGINT, oldHandler);
|
||||||
|
|
@ -469,7 +498,7 @@ runc(char* command)
|
||||||
|
|
||||||
#ifdef THREADS
|
#ifdef THREADS
|
||||||
|
|
||||||
/* Checks if spice is running in the background */
|
/* Checks if ngspice is running in the background */
|
||||||
IMPEXP
|
IMPEXP
|
||||||
bool
|
bool
|
||||||
ngSpice_running (void)
|
ngSpice_running (void)
|
||||||
|
|
@ -478,8 +507,27 @@ ngSpice_running (void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Initialise external voltage source */
|
||||||
|
IMPEXP
|
||||||
|
int
|
||||||
|
ngSpice_Init_Sync(GetVSRCData* vsrcdat, int* ident, void* userData)
|
||||||
|
{
|
||||||
|
getvdat = vsrcdat;
|
||||||
|
/* set userdata, but don't overwrite with NULL */
|
||||||
|
if (userData)
|
||||||
|
userptr = userData;
|
||||||
|
/* set ngspice shared lib identification number */
|
||||||
|
ng_ident = *ident;
|
||||||
|
/* if caller sends NULL, don't try to retrieve voltage */
|
||||||
|
if (getvdat) {
|
||||||
|
wantvdat = TRUE;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Initialise spice and setup native methods */
|
|
||||||
|
/* Initialise ngspice and setup native methods */
|
||||||
IMPEXP
|
IMPEXP
|
||||||
int
|
int
|
||||||
ngSpice_Init(SendChar* printfcn, SendStat* statusfcn, ControlledExit* ngspiceexit,
|
ngSpice_Init(SendChar* printfcn, SendStat* statusfcn, ControlledExit* ngspiceexit,
|
||||||
|
|
@ -578,12 +626,9 @@ ngSpice_Init(SendChar* printfcn, SendStat* statusfcn, ControlledExit* ngspiceexi
|
||||||
struct passwd *pw;
|
struct passwd *pw;
|
||||||
pw = getpwuid(getuid());
|
pw = getpwuid(getuid());
|
||||||
|
|
||||||
#ifdef HAVE_ASPRINTF
|
|
||||||
asprintf(&s, "%s%s", pw->pw_dir, INITSTR);
|
|
||||||
#else
|
|
||||||
s = TMALLOC(char, 1 + strlen(pw->pw_dir) + strlen(INITSTR));
|
s = TMALLOC(char, 1 + strlen(pw->pw_dir) + strlen(INITSTR));
|
||||||
sprintf(s, "%s%s", pw->pw_dir, INITSTR);
|
sprintf(s, "%s%s", pw->pw_dir, INITSTR);
|
||||||
#endif
|
|
||||||
if (access(s, 0) == 0)
|
if (access(s, 0) == 0)
|
||||||
inp_source(s);
|
inp_source(s);
|
||||||
}
|
}
|
||||||
|
|
@ -627,7 +672,14 @@ bot:
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
com_version(NULL);
|
// com_version(NULL);
|
||||||
|
fprintf(cp_out,
|
||||||
|
"******\n"
|
||||||
|
"** %s-%s shared library\n",
|
||||||
|
ft_sim->simulator, ft_sim->version);
|
||||||
|
if (Spice_Build_Date != NULL && *Spice_Build_Date != 0)
|
||||||
|
fprintf(cp_out, "** Creation Date: %s\n", Spice_Build_Date);
|
||||||
|
fprintf(cp_out, "******\n");
|
||||||
|
|
||||||
is_initialized = TRUE;
|
is_initialized = TRUE;
|
||||||
|
|
||||||
|
|
@ -638,7 +690,7 @@ bot:
|
||||||
/* If caller has sent valid address for pfcn */
|
/* If caller has sent valid address for pfcn */
|
||||||
if (!noprintfwanted)
|
if (!noprintfwanted)
|
||||||
#ifdef HAVE_LIBPTHREAD
|
#ifdef HAVE_LIBPTHREAD
|
||||||
pthread_create(&tid, NULL, (void * (*)(void *))printsend, (void *)NULL);
|
pthread_create(&printtid, NULL, (void * (*)(void *))printsend, (void *)NULL);
|
||||||
#elif defined _MSC_VER || defined __MINGW32__
|
#elif defined _MSC_VER || defined __MINGW32__
|
||||||
printtid = (HANDLE)_beginthreadex(NULL, 0, (unsigned int (__stdcall *)(void *))printsend,
|
printtid = (HANDLE)_beginthreadex(NULL, 0, (unsigned int (__stdcall *)(void *))printsend,
|
||||||
(void*) NULL, 0, NULL);
|
(void*) NULL, 0, NULL);
|
||||||
|
|
@ -659,7 +711,6 @@ IMPEXP
|
||||||
int ngSpice_Command(char* comexec)
|
int ngSpice_Command(char* comexec)
|
||||||
{
|
{
|
||||||
if ( ! setjmp(errbufc) ) {
|
if ( ! setjmp(errbufc) ) {
|
||||||
// HANDLE tid2;
|
|
||||||
|
|
||||||
immediate = FALSE;
|
immediate = FALSE;
|
||||||
intermj = 1;
|
intermj = 1;
|
||||||
|
|
@ -668,12 +719,9 @@ int ngSpice_Command(char* comexec)
|
||||||
fprintf(stderr, no_init);
|
fprintf(stderr, no_init);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
// tid2 = (HANDLE)_beginthreadex(NULL, 0, (PTHREAD_START_ROUTINE)runc, (void*)comexec,
|
|
||||||
// 0, NULL);
|
|
||||||
runc(comexec);
|
runc(comexec);
|
||||||
/* main thread prepares immediate detaching of dll,
|
/* main thread prepares immediate detaching of dll */
|
||||||
in case of controlled_exit from tid2 thread, caller is asked
|
|
||||||
to detach dll via fcn ngexit() */
|
|
||||||
immediate = TRUE;
|
immediate = TRUE;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -722,6 +770,7 @@ int ngSpice_Circ(char** circa){
|
||||||
|
|
||||||
if ( ! setjmp(errbufm) ) {
|
if ( ! setjmp(errbufm) ) {
|
||||||
intermj = 0;
|
intermj = 0;
|
||||||
|
immediate = FALSE;
|
||||||
/* count the entries */
|
/* count the entries */
|
||||||
while (circa[entries]) {
|
while (circa[entries]) {
|
||||||
entries++;
|
entries++;
|
||||||
|
|
@ -747,7 +796,7 @@ char* ngSpice_CurPlot(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* return to the caller a pointer to an array of all plots created
|
/* return to the caller a pointer to an array of all plots created
|
||||||
by ngspice.dll */
|
by ngspice. Last entry in the array is NULL. */
|
||||||
IMPEXP
|
IMPEXP
|
||||||
char** ngSpice_AllPlots(void)
|
char** ngSpice_AllPlots(void)
|
||||||
{
|
{
|
||||||
|
|
@ -771,7 +820,7 @@ char** ngSpice_AllPlots(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* return to the caller a pointer to an array of vector names in the plot
|
/* return to the caller a pointer to an array of vector names in the plot
|
||||||
named by plotname */
|
named by plotname. Last entry in the array is NULL. */
|
||||||
IMPEXP
|
IMPEXP
|
||||||
char** ngSpice_AllVecs(char* plotname)
|
char** ngSpice_AllVecs(char* plotname)
|
||||||
{
|
{
|
||||||
|
|
@ -805,12 +854,71 @@ char** ngSpice_AllVecs(char* plotname)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static double *bkpttmp = NULL;
|
||||||
|
static int bkpttmpsize = 0;
|
||||||
|
|
||||||
|
/* set a breakpoint in ngspice */
|
||||||
|
IMPEXP
|
||||||
|
bool ngSpice_SetBkpt(double time)
|
||||||
|
{
|
||||||
|
int error;
|
||||||
|
CKTcircuit *ckt = NULL;
|
||||||
|
|
||||||
|
if (!ft_curckt || !ft_curckt->ci_ckt) {
|
||||||
|
fprintf(cp_err, "Error: no circuit loaded.\n");
|
||||||
|
return(FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
ckt = ft_curckt->ci_ckt;
|
||||||
|
if (ckt->CKTbreakSize == 0) {
|
||||||
|
/* breakpoints have not yet been set up, so store here preliminary
|
||||||
|
and add with fcn add_bkpt() called from DCTran()*/
|
||||||
|
if (bkpttmp == NULL) {
|
||||||
|
bkpttmp = TMALLOC(double, bkpttmpsize + 1);
|
||||||
|
if(bkpttmp == NULL)
|
||||||
|
return(FALSE);
|
||||||
|
bkpttmpsize++;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
bkpttmp = TREALLOC(double, bkpttmp, bkpttmpsize + 1);
|
||||||
|
bkpttmpsize++;
|
||||||
|
}
|
||||||
|
bkpttmp[bkpttmpsize-1] = time;
|
||||||
|
error = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
error = CKTsetBreak(ckt, time);
|
||||||
|
if(error)
|
||||||
|
return(FALSE);
|
||||||
|
return(TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* add the preliminary breakpoints to the list.
|
||||||
|
called from dctran.c */
|
||||||
|
int
|
||||||
|
add_bkpt(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int error = 0;
|
||||||
|
CKTcircuit *ckt = ft_curckt->ci_ckt;
|
||||||
|
|
||||||
|
if((bkpttmp) && (bkpttmpsize > 0)) {
|
||||||
|
for (i = 0; i < bkpttmpsize; i++)
|
||||||
|
error = CKTsetBreak(ckt, bkpttmp[i]);
|
||||||
|
FREE(bkpttmp);
|
||||||
|
bkpttmpsize = 0;
|
||||||
|
}
|
||||||
|
if(error)
|
||||||
|
return(error);
|
||||||
|
return(OK);
|
||||||
|
}
|
||||||
|
|
||||||
/*------------------------------------------------------*/
|
/*------------------------------------------------------*/
|
||||||
/* Redefine the vfprintf() functions for callback */
|
/* Redefine the vfprintf() functions for callback */
|
||||||
/*------------------------------------------------------*/
|
/*------------------------------------------------------*/
|
||||||
|
|
||||||
/* handling of escape characters (extra \ added) is removed, may be added by
|
/* handling of escape characters (extra \ added) only, if
|
||||||
un-commenting some lines */
|
'set addescape' is given in .spiceinit */
|
||||||
|
|
||||||
int
|
int
|
||||||
sh_vfprintf(FILE *f, const char *fmt, va_list args)
|
sh_vfprintf(FILE *f, const char *fmt, va_list args)
|
||||||
|
|
@ -889,7 +997,7 @@ sh_vfprintf(FILE *f, const char *fmt, va_list args)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* use sharedspice implementation of fputs (sh_fputs)
|
/* use sharedspice.c implementation of fputs (sh_fputs)
|
||||||
to assess callback function derived from address printfcn received via
|
to assess callback function derived from address printfcn received via
|
||||||
Spice_Init() from caller of ngspice.dll */
|
Spice_Init() from caller of ngspice.dll */
|
||||||
|
|
||||||
|
|
@ -903,9 +1011,10 @@ sh_vfprintf(FILE *f, const char *fmt, va_list args)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------
|
||||||
/* Reimplement fprintf() as a call to callback function pfcn */
|
Reimplement fprintf() as a call to callback function pfcn
|
||||||
/*----------------------------------------------------------------------*/
|
via sh_vfprintf, sh_fputs, and sh_fputsll
|
||||||
|
----------------------------------------------------------------------*/
|
||||||
|
|
||||||
int
|
int
|
||||||
sh_fprintf(FILE *f, const char *format, ...)
|
sh_fprintf(FILE *f, const char *format, ...)
|
||||||
|
|
@ -921,9 +1030,10 @@ sh_fprintf(FILE *f, const char *format, ...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------
|
||||||
/* Reimplement printf() as a call to callback function pfcn */
|
Reimplement printf() as a call to callback function pfcn
|
||||||
/*----------------------------------------------------------------------*/
|
via sh_vfprintf, sh_fputs, and sh_fputsll
|
||||||
|
----------------------------------------------------------------------*/
|
||||||
|
|
||||||
int
|
int
|
||||||
sh_printf(const char *format, ...)
|
sh_printf(const char *format, ...)
|
||||||
|
|
@ -975,9 +1085,9 @@ sh_fputc(const char inp, FILE* f)
|
||||||
static char* outstringerr = NULL;
|
static char* outstringerr = NULL;
|
||||||
static char* outstringout = NULL;
|
static char* outstringout = NULL;
|
||||||
|
|
||||||
#ifdef low_latency
|
#if defined (low_latency) || !defined(THREADS)
|
||||||
/* using the strings by the caller sent directly to the caller
|
/* The strings issued by printf etc. are sent directly to the caller.
|
||||||
has to fast enough (low latency) */
|
The callback has to be fast enough (low latency). */
|
||||||
int
|
int
|
||||||
sh_fputsll(const char *input, FILE* outf)
|
sh_fputsll(const char *input, FILE* outf)
|
||||||
{
|
{
|
||||||
|
|
@ -1065,7 +1175,8 @@ sh_fputsll(const char *input, FILE* outf)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* provide a lock around printing function */
|
/* provide a lock around printing function.
|
||||||
|
May become critical if latency of callback is too high.*/
|
||||||
int
|
int
|
||||||
sh_fputs(const char *input, FILE* outf)
|
sh_fputs(const char *input, FILE* outf)
|
||||||
{
|
{
|
||||||
|
|
@ -1187,6 +1298,8 @@ static char *outsend = NULL;
|
||||||
static void
|
static void
|
||||||
printsend(void)
|
printsend(void)
|
||||||
{
|
{
|
||||||
|
ps_exited = FALSE;
|
||||||
|
printstopp = FALSE;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
#if defined(__MINGW32__) || defined(_MSC_VER)
|
#if defined(__MINGW32__) || defined(_MSC_VER)
|
||||||
Sleep(50); // loop delay
|
Sleep(50); // loop delay
|
||||||
|
|
@ -1198,6 +1311,7 @@ printsend(void)
|
||||||
mutex_lock(&fputsMutex);
|
mutex_lock(&fputsMutex);
|
||||||
outsend = outstorage(NULL, FALSE);
|
outsend = outstorage(NULL, FALSE);
|
||||||
mutex_unlock(&fputsMutex);
|
mutex_unlock(&fputsMutex);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
mutex_lock(&fputsMutex);
|
mutex_lock(&fputsMutex);
|
||||||
|
|
@ -1210,6 +1324,7 @@ printsend(void)
|
||||||
tfree(outsend);
|
tfree(outsend);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ps_exited = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* remove the first entry of a wordlist, but keep wl->wl_word */
|
/* remove the first entry of a wordlist, but keep wl->wl_word */
|
||||||
|
|
@ -1251,13 +1366,14 @@ char* outstorage(char* wordin, bool write)
|
||||||
|
|
||||||
|
|
||||||
/* New progress report to statfcn().
|
/* New progress report to statfcn().
|
||||||
Update only every DELTATIME milliseconds */
|
An update occurs only every DELTATIME milliseconds. */
|
||||||
#define DELTATIME 150
|
#define DELTATIME 150
|
||||||
void SetAnalyse(
|
void SetAnalyse(
|
||||||
char * Analyse, /*in: analysis type */
|
char * Analyse, /*in: analysis type */
|
||||||
int DecaPercent /*in: 10 times the progress [%]*/
|
int DecaPercent /*in: 10 times the progress [%]*/
|
||||||
/*HWND hwAnalyse, in: global handle to analysis window */
|
/*HWND hwAnalyse, in: global handle to analysis window */
|
||||||
) {
|
) {
|
||||||
|
#ifdef HAVE_FTIME
|
||||||
static int OldPercent = -2; /* Previous progress value */
|
static int OldPercent = -2; /* Previous progress value */
|
||||||
static char OldAn[128]; /* Previous analysis type */
|
static char OldAn[128]; /* Previous analysis type */
|
||||||
char* s; /* outputs to callback function */
|
char* s; /* outputs to callback function */
|
||||||
|
|
@ -1321,10 +1437,21 @@ void SetAnalyse(
|
||||||
result = statfcn(s, userptr);
|
result = statfcn(s, userptr);
|
||||||
}
|
}
|
||||||
tfree(s);
|
tfree(s);
|
||||||
|
#else
|
||||||
|
char* s;
|
||||||
|
int result;
|
||||||
|
static bool havesent = FALSE;
|
||||||
|
if (!havesent) {
|
||||||
|
s = copy("No usage info available");
|
||||||
|
result = statfcn(s, userptr);
|
||||||
|
tfree(s);
|
||||||
|
havesent = TRUE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* a dll or shared library should never exit, but ask for graceful shutdown
|
/* a dll or shared library should never exit, if loaded dynamically,
|
||||||
(e.g. being detached) via a callback function*/
|
but ask for graceful shutdown (e.g. being detached) via a callback function*/
|
||||||
void shared_exit(int status)
|
void shared_exit(int status)
|
||||||
{
|
{
|
||||||
/* alert caller to detach dll (if we are in the main thread),
|
/* alert caller to detach dll (if we are in the main thread),
|
||||||
|
|
@ -1364,8 +1491,23 @@ void shared_exit(int status)
|
||||||
tfree(outsend);
|
tfree(outsend);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
// if we are in a worker thread, we exit it here
|
||||||
|
// detaching then has to be done explicitely by the caller
|
||||||
|
if (fl_running && !fl_exited) {
|
||||||
|
fl_exited = TRUE;
|
||||||
|
bgtr(fl_exited, userptr);
|
||||||
|
// set a flag that ngspice wants to be detached
|
||||||
|
ngexit(status, FALSE, coquit, userptr);
|
||||||
|
// finish and exit the worker thread
|
||||||
|
#ifdef HAVE_LIBPTHREAD
|
||||||
|
pthread_exit(1);
|
||||||
|
#elif defined _MSC_VER || defined __MINGW32__
|
||||||
|
_endthreadex(1);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
// set a flag in caller to detach ngspice.dll
|
// set a flag in caller to detach ngspice.dll
|
||||||
ngexit(status, immediate, coquit, userptr);
|
ngexit(status, immediate, coquit, userptr);
|
||||||
|
|
||||||
// jump back to finish the calling function
|
// jump back to finish the calling function
|
||||||
if (!intermj)
|
if (!intermj)
|
||||||
longjmp(errbufm,1); /* jump back to ngSpice_Circ() */
|
longjmp(errbufm,1); /* jump back to ngSpice_Circ() */
|
||||||
|
|
@ -1448,7 +1590,7 @@ int sh_ExecutePerLoop(void)
|
||||||
{
|
{
|
||||||
struct dvec *d;
|
struct dvec *d;
|
||||||
int i, veclen;
|
int i, veclen;
|
||||||
double testval;
|
// double testval;
|
||||||
struct plot *pl = plot_cur;
|
struct plot *pl = plot_cur;
|
||||||
/* return immediately if callback not wanted */
|
/* return immediately if callback not wanted */
|
||||||
if (nodatawanted)
|
if (nodatawanted)
|
||||||
|
|
@ -1456,11 +1598,12 @@ int sh_ExecutePerLoop(void)
|
||||||
|
|
||||||
/* get the data of the last entry to the plot vector */
|
/* get the data of the last entry to the plot vector */
|
||||||
veclen = pl->pl_dvecs->v_length - 1;
|
veclen = pl->pl_dvecs->v_length - 1;
|
||||||
|
curvecvalsall->vecindex = veclen;
|
||||||
for (d = pl->pl_dvecs, i = 0; d; d = d->v_next, i++) {
|
for (d = pl->pl_dvecs, i = 0; d; d = d->v_next, i++) {
|
||||||
/* test if real */
|
/* test if real */
|
||||||
if (d->v_flags & VF_REAL) {
|
if (d->v_flags & VF_REAL) {
|
||||||
curvecvalsall->vecsa[i]->is_complex = FALSE;
|
curvecvalsall->vecsa[i]->is_complex = FALSE;
|
||||||
testval = d->v_realdata[veclen];
|
// testval = d->v_realdata[veclen];
|
||||||
curvecvalsall->vecsa[i]->creal = d->v_realdata[veclen];
|
curvecvalsall->vecsa[i]->creal = d->v_realdata[veclen];
|
||||||
curvecvalsall->vecsa[i]->cimag = 0.;
|
curvecvalsall->vecsa[i]->cimag = 0.;
|
||||||
}
|
}
|
||||||
|
|
@ -1478,7 +1621,7 @@ int sh_ExecutePerLoop(void)
|
||||||
|
|
||||||
|
|
||||||
/* called once for a new plot from beginPlot() in outitf.c,
|
/* called once for a new plot from beginPlot() in outitf.c,
|
||||||
after the vectors in ngspice have been set.
|
after the vectors in ngspice for this plot have been set.
|
||||||
Transfers vector information to the caller via callback datinitfcn()
|
Transfers vector information to the caller via callback datinitfcn()
|
||||||
and sets transfer structure for use in sh_ExecutePerLoop() */
|
and sets transfer structure for use in sh_ExecutePerLoop() */
|
||||||
int sh_vecinit(runDesc *run)
|
int sh_vecinit(runDesc *run)
|
||||||
|
|
@ -1536,14 +1679,13 @@ int sh_vecinit(runDesc *run)
|
||||||
data will be sent from sh_ExecutePerLoop() via datfcn() */
|
data will be sent from sh_ExecutePerLoop() via datfcn() */
|
||||||
if (!curvecvalsall) {
|
if (!curvecvalsall) {
|
||||||
curvecvalsall = TMALLOC(vecvaluesall, 1);
|
curvecvalsall = TMALLOC(vecvaluesall, 1);
|
||||||
curvecvalsall->veccount = veccount;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for (i = 0; i < curvecvalsall->veccount; i++)
|
for (i = 0; i < curvecvalsall->veccount; i++)
|
||||||
tfree(curvecvalsall->vecsa[i]);
|
tfree(curvecvalsall->vecsa[i]);
|
||||||
tfree(curvecvalsall->vecsa);
|
tfree(curvecvalsall->vecsa);
|
||||||
}
|
}
|
||||||
|
curvecvalsall->veccount = veccount;
|
||||||
curvecvalsall->vecsa = TMALLOC(pvecvalues, veccount);
|
curvecvalsall->vecsa = TMALLOC(pvecvalues, veccount);
|
||||||
|
|
||||||
for (i = 0, d = cur_run->runPlot->pl_dvecs; i < veccount; i++, d = d->v_next) {
|
for (i = 0, d = cur_run->runPlot->pl_dvecs; i < veccount; i++, d = d->v_next) {
|
||||||
|
|
@ -1557,3 +1699,18 @@ int sh_vecinit(runDesc *run)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* issue callback to request external voltage data for source vname*/
|
||||||
|
double getvsrcval(double time, char* vname)
|
||||||
|
{
|
||||||
|
double vval;
|
||||||
|
if (!wantvdat) {
|
||||||
|
fprintf(stderr, "Error: No callback supplied for source %s\n", vname);
|
||||||
|
shared_exit(EXIT_BAD);
|
||||||
|
return(EXIT_BAD);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* callback fcn */
|
||||||
|
getvdat(&vval, time, vname, userptr);
|
||||||
|
return vval;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -107,6 +107,10 @@ libckt_la_SOURCES += \
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
if KIRCHHOFF_WANTED
|
||||||
|
libckt_la_SOURCES += cktmkcurKCL.c
|
||||||
|
endif
|
||||||
|
|
||||||
AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(top_srcdir)/src/include -I$(top_srcdir)/src/spicelib/devices
|
AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(top_srcdir)/src/include -I$(top_srcdir)/src/spicelib/devices
|
||||||
AM_CFLAGS = $(STATIC)
|
AM_CFLAGS = $(STATIC)
|
||||||
MAINTAINERCLEANFILES = Makefile.in
|
MAINTAINERCLEANFILES = Makefile.in
|
||||||
|
|
|
||||||
|
|
@ -149,11 +149,11 @@ ACan(CKTcircuit *ckt, int restart)
|
||||||
* Moreover the begin plot has not even been done yet at this
|
* Moreover the begin plot has not even been done yet at this
|
||||||
* point...
|
* point...
|
||||||
*/
|
*/
|
||||||
SPfrontEnd->OUTpBeginPlot (
|
SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
|
||||||
ckt, ckt->CKTcurJob,
|
ckt->CKTcurJob->JOBname,
|
||||||
ckt->CKTcurJob->JOBname,
|
NULL, IF_REAL,
|
||||||
NULL, IF_REAL,
|
numNames, nameList, IF_REAL,
|
||||||
numNames, nameList, IF_REAL, &acPlot);
|
&acPlot);
|
||||||
tfree(nameList);
|
tfree(nameList);
|
||||||
|
|
||||||
ipc_send_dcop_prefix();
|
ipc_send_dcop_prefix();
|
||||||
|
|
@ -174,30 +174,28 @@ ACan(CKTcircuit *ckt, int restart)
|
||||||
|
|
||||||
if (ckt->CKTkeepOpInfo) {
|
if (ckt->CKTkeepOpInfo) {
|
||||||
/* Dump operating point. */
|
/* Dump operating point. */
|
||||||
error = SPfrontEnd->OUTpBeginPlot (
|
error = SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
|
||||||
ckt, ckt->CKTcurJob,
|
"AC Operating Point",
|
||||||
"AC Operating Point",
|
NULL, IF_REAL,
|
||||||
NULL, IF_REAL,
|
numNames, nameList, IF_REAL,
|
||||||
numNames, nameList, IF_REAL, &plot);
|
&plot);
|
||||||
if(error) return(error);
|
if(error) return(error);
|
||||||
CKTdump(ckt, 0.0, plot);
|
CKTdump(ckt, 0.0, plot);
|
||||||
SPfrontEnd->OUTendPlot (plot);
|
SPfrontEnd->OUTendPlot (plot);
|
||||||
plot = NULL;
|
plot = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
SPfrontEnd->IFnewUid (ckt, &freqUid, NULL,
|
SPfrontEnd->IFnewUid (ckt, &freqUid, NULL, "frequency", UID_OTHER, NULL);
|
||||||
"frequency", UID_OTHER, NULL);
|
error = SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
|
||||||
error = SPfrontEnd->OUTpBeginPlot (
|
ckt->CKTcurJob->JOBname,
|
||||||
ckt, ckt->CKTcurJob,
|
freqUid, IF_REAL,
|
||||||
ckt->CKTcurJob->JOBname,
|
numNames, nameList, IF_COMPLEX,
|
||||||
freqUid, IF_REAL,
|
&acPlot);
|
||||||
numNames, nameList, IF_COMPLEX, &acPlot);
|
|
||||||
tfree(nameList);
|
tfree(nameList);
|
||||||
if(error) return(error);
|
if(error) return(error);
|
||||||
|
|
||||||
if (job->ACstepType != LINEAR) {
|
if (job->ACstepType != LINEAR) {
|
||||||
SPfrontEnd->OUTattributes (acPlot, NULL,
|
SPfrontEnd->OUTattributes (acPlot, NULL, OUT_SCALE_LOG, NULL);
|
||||||
OUT_SCALE_LOG, NULL);
|
|
||||||
}
|
}
|
||||||
freq = job->ACstartFreq;
|
freq = job->ACstartFreq;
|
||||||
|
|
||||||
|
|
@ -205,11 +203,11 @@ ACan(CKTcircuit *ckt, int restart)
|
||||||
freq = job->ACsaveFreq;
|
freq = job->ACsaveFreq;
|
||||||
job->ACsaveFreq = 0; /* clear the 'old' frequency */
|
job->ACsaveFreq = 0; /* clear the 'old' frequency */
|
||||||
/* fix resume? saj, indeed !*/
|
/* fix resume? saj, indeed !*/
|
||||||
error = SPfrontEnd->OUTpBeginPlot (
|
error = SPfrontEnd->OUTpBeginPlot (NULL, NULL,
|
||||||
NULL, NULL,
|
NULL,
|
||||||
NULL,
|
NULL, 0,
|
||||||
NULL, 0,
|
666, NULL, 666,
|
||||||
666, NULL, 666, &acPlot);
|
&acPlot);
|
||||||
/* saj*/
|
/* saj*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,10 @@ extern SPICEanalysis SENSinfo;
|
||||||
extern SPICEanalysis PSSinfo;
|
extern SPICEanalysis PSSinfo;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef WANT_SENSE2
|
||||||
|
extern SPICEanalysis SEN2info;
|
||||||
|
#endif
|
||||||
|
|
||||||
SPICEanalysis *analInfo[] = {
|
SPICEanalysis *analInfo[] = {
|
||||||
&OPTinfo,
|
&OPTinfo,
|
||||||
&ACinfo,
|
&ACinfo,
|
||||||
|
|
@ -34,6 +38,9 @@ SPICEanalysis *analInfo[] = {
|
||||||
#ifdef WITH_PSS
|
#ifdef WITH_PSS
|
||||||
&PSSinfo,
|
&PSSinfo,
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef WANT_SENSE2
|
||||||
|
&SEN2info,
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,11 @@ CKTload(CKTcircuit *ckt)
|
||||||
size = SMPmatSize(ckt->CKTmatrix);
|
size = SMPmatSize(ckt->CKTmatrix);
|
||||||
for (i = 0; i <= size; i++) {
|
for (i = 0; i <= size; i++) {
|
||||||
ckt->CKTrhs[i] = 0;
|
ckt->CKTrhs[i] = 0;
|
||||||
|
|
||||||
|
#ifdef KIRCHHOFF
|
||||||
|
ckt->CKTfvk[i] = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
SMPclear(ckt->CKTmatrix);
|
SMPclear(ckt->CKTmatrix);
|
||||||
#ifdef STEPDEBUG
|
#ifdef STEPDEBUG
|
||||||
|
|
|
||||||
|
|
@ -35,12 +35,8 @@ CKTmapNode(CKTcircuit *ckt, CKTnode **node, IFuid name)
|
||||||
/* not found, so must be a new one */
|
/* not found, so must be a new one */
|
||||||
error = CKTmkNode(ckt,&mynode); /*allocate the node*/
|
error = CKTmkNode(ckt,&mynode); /*allocate the node*/
|
||||||
if(error) return(error);
|
if(error) return(error);
|
||||||
error = SPfrontEnd->IFnewUid (ckt,
|
/* get a uid for it */
|
||||||
&uid,
|
error = SPfrontEnd->IFnewUid (ckt, &uid, NULL, name, UID_SIGNAL, &mynode);
|
||||||
NULL,
|
|
||||||
name,
|
|
||||||
UID_SIGNAL,
|
|
||||||
&mynode); /* get a uid for it */
|
|
||||||
if(error) return(error);
|
if(error) return(error);
|
||||||
mynode->name = uid; /* set the info we have */
|
mynode->name = uid; /* set the info we have */
|
||||||
mynode->type = SP_VOLTAGE;
|
mynode->type = SP_VOLTAGE;
|
||||||
|
|
|
||||||
|
|
@ -29,8 +29,7 @@ CKTmkCur(CKTcircuit *ckt, CKTnode **node, IFuid basename, char *suffix)
|
||||||
error = CKTmkNode(ckt,&mynode);
|
error = CKTmkNode(ckt,&mynode);
|
||||||
if(error) return(error);
|
if(error) return(error);
|
||||||
checknode = mynode;
|
checknode = mynode;
|
||||||
error = SPfrontEnd->IFnewUid (ckt, &uid, basename,
|
error = SPfrontEnd->IFnewUid (ckt, &uid, basename, suffix, UID_SIGNAL, &checknode);
|
||||||
suffix, UID_SIGNAL, &checknode);
|
|
||||||
if(error) {
|
if(error) {
|
||||||
FREE(mynode);
|
FREE(mynode);
|
||||||
if(node) *node = checknode;
|
if(node) *node = checknode;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
/**********
|
||||||
|
Author: 2013 Francesco Lannutti
|
||||||
|
**********/
|
||||||
|
|
||||||
|
#include "ngspice/ngspice.h"
|
||||||
|
#include "ngspice/sperror.h"
|
||||||
|
#include "ngspice/cktdefs.h"
|
||||||
|
|
||||||
|
int
|
||||||
|
CKTmkCurKCL (CKTcircuit *ckt, int i, double **node)
|
||||||
|
{
|
||||||
|
CKTmkCurKCLnode *tempNode ;
|
||||||
|
|
||||||
|
tempNode = TMALLOC (CKTmkCurKCLnode, 1) ;
|
||||||
|
tempNode->KCLcurrent = 0.0 ;
|
||||||
|
tempNode->next = ckt->CKTmkCurKCLarray [i] ;
|
||||||
|
ckt->CKTmkCurKCLarray [i] = tempNode ;
|
||||||
|
*node = &(tempNode->KCLcurrent) ;
|
||||||
|
|
||||||
|
return (OK) ;
|
||||||
|
}
|
||||||
|
|
@ -26,7 +26,7 @@ CKTmkNode(CKTcircuit *ckt, CKTnode **node)
|
||||||
mynode = TMALLOC(CKTnode, 1);
|
mynode = TMALLOC(CKTnode, 1);
|
||||||
if(mynode == NULL) return(E_NOMEM);
|
if(mynode == NULL) return(E_NOMEM);
|
||||||
mynode->next = NULL;
|
mynode->next = NULL;
|
||||||
mynode->name = (IFuid) 0;
|
mynode->name = NULL;
|
||||||
|
|
||||||
if(node) *node = mynode;
|
if(node) *node = mynode;
|
||||||
return(OK);
|
return(OK);
|
||||||
|
|
|
||||||
|
|
@ -27,8 +27,7 @@ CKTmkVolt(CKTcircuit *ckt, CKTnode **node, IFuid basename, char *suffix)
|
||||||
error = CKTmkNode(ckt,&mynode);
|
error = CKTmkNode(ckt,&mynode);
|
||||||
if(error) return(error);
|
if(error) return(error);
|
||||||
checknode = mynode;
|
checknode = mynode;
|
||||||
error = SPfrontEnd->IFnewUid (ckt, &uid, basename,
|
error = SPfrontEnd->IFnewUid (ckt, &uid, basename, suffix, UID_SIGNAL, &checknode);
|
||||||
suffix, UID_SIGNAL, &checknode);
|
|
||||||
if(error) {
|
if(error) {
|
||||||
FREE(mynode);
|
FREE(mynode);
|
||||||
if(node) *node = checknode;
|
if(node) *node = checknode;
|
||||||
|
|
|
||||||
|
|
@ -56,12 +56,12 @@ CKTnoise (CKTcircuit *ckt, int mode, int operation, Ndata *data)
|
||||||
data->namelist = TREALLOC(IFuid, data->namelist, data->numPlots + 1);
|
data->namelist = TREALLOC(IFuid, data->namelist, data->numPlots + 1);
|
||||||
|
|
||||||
SPfrontEnd->IFnewUid (ckt, &(data->namelist[data->numPlots++]),
|
SPfrontEnd->IFnewUid (ckt, &(data->namelist[data->numPlots++]),
|
||||||
NULL, "onoise_spectrum", UID_OTHER, NULL);
|
NULL, "onoise_spectrum", UID_OTHER, NULL);
|
||||||
|
|
||||||
data->namelist = TREALLOC(IFuid, data->namelist, data->numPlots + 1);
|
data->namelist = TREALLOC(IFuid, data->namelist, data->numPlots + 1);
|
||||||
|
|
||||||
SPfrontEnd->IFnewUid (ckt, &(data->namelist[data->numPlots++]),
|
SPfrontEnd->IFnewUid (ckt, &(data->namelist[data->numPlots++]),
|
||||||
NULL, "inoise_spectrum", UID_OTHER, NULL);
|
NULL, "inoise_spectrum", UID_OTHER, NULL);
|
||||||
|
|
||||||
/* we've added two more plots */
|
/* we've added two more plots */
|
||||||
|
|
||||||
|
|
@ -73,11 +73,11 @@ CKTnoise (CKTcircuit *ckt, int mode, int operation, Ndata *data)
|
||||||
|
|
||||||
data->namelist = TREALLOC(IFuid, data->namelist, data->numPlots + 1);
|
data->namelist = TREALLOC(IFuid, data->namelist, data->numPlots + 1);
|
||||||
SPfrontEnd->IFnewUid (ckt, &(data->namelist[data->numPlots++]),
|
SPfrontEnd->IFnewUid (ckt, &(data->namelist[data->numPlots++]),
|
||||||
NULL, "onoise_total", UID_OTHER, NULL);
|
NULL, "onoise_total", UID_OTHER, NULL);
|
||||||
|
|
||||||
data->namelist = TREALLOC(IFuid, data->namelist, data->numPlots + 1);
|
data->namelist = TREALLOC(IFuid, data->namelist, data->numPlots + 1);
|
||||||
SPfrontEnd->IFnewUid (ckt, &(data->namelist[data->numPlots++]),
|
SPfrontEnd->IFnewUid (ckt, &(data->namelist[data->numPlots++]),
|
||||||
NULL, "inoise_total", UID_OTHER, NULL);
|
NULL, "inoise_total", UID_OTHER, NULL);
|
||||||
/* we've added two more plots */
|
/* we've added two more plots */
|
||||||
|
|
||||||
data->outpVector =
|
data->outpVector =
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -635,12 +635,12 @@ CKTpzRunTrial(CKTcircuit *ckt, PZtrial **new_trialp, PZtrial **set)
|
||||||
if (!(p->flags & ISAROOT) && CKTpzTrapped == 3
|
if (!(p->flags & ISAROOT) && CKTpzTrapped == 3
|
||||||
&& NIpzK != 0.0 && NIpzK_mag > -10) {
|
&& NIpzK != 0.0 && NIpzK_mag > -10) {
|
||||||
#ifdef notdef
|
#ifdef notdef
|
||||||
if (p->flags & ISAROOT) {
|
// if (p->flags & ISAROOT) {
|
||||||
/* Ugh! muller doesn't work right */
|
// /* Ugh! muller doesn't work right */
|
||||||
new_trial->flags = ISAMINIMA;
|
// new_trial->flags = ISAMINIMA;
|
||||||
new_trial->s.imag = scalb(NIpzK, (int) (NIpzK_mag / 2));
|
// new_trial->s.imag = scalb(NIpzK, (int) (NIpzK_mag / 2));
|
||||||
pretest = 0;
|
// pretest = 0;
|
||||||
} else {
|
// } else {
|
||||||
#endif
|
#endif
|
||||||
p->flags |= ISAMINIMA;
|
p->flags |= ISAMINIMA;
|
||||||
tfree(new_trial);
|
tfree(new_trial);
|
||||||
|
|
|
||||||
|
|
@ -184,9 +184,7 @@ int sens_sens(CKTcircuit *ckt, int restart)
|
||||||
sg->ptable[sg->param].keyword);
|
sg->ptable[sg->param].keyword);
|
||||||
}
|
}
|
||||||
|
|
||||||
SPfrontEnd->IFnewUid (ckt,
|
SPfrontEnd->IFnewUid (ckt, output_names + k, NULL, namebuf, UID_OTHER, NULL);
|
||||||
output_names + k, NULL,
|
|
||||||
namebuf, UID_OTHER, NULL);
|
|
||||||
k += 1;
|
k += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -195,16 +193,14 @@ int sens_sens(CKTcircuit *ckt, int restart)
|
||||||
freq_name = NULL;
|
freq_name = NULL;
|
||||||
} else {
|
} else {
|
||||||
type = IF_COMPLEX;
|
type = IF_COMPLEX;
|
||||||
SPfrontEnd->IFnewUid (ckt,
|
SPfrontEnd->IFnewUid (ckt, &freq_name, NULL, "frequency", UID_OTHER, NULL);
|
||||||
&freq_name, NULL,
|
|
||||||
"frequency", UID_OTHER, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
error = SPfrontEnd->OUTpBeginPlot (
|
error = SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
|
||||||
ckt, ckt->CKTcurJob,
|
ckt->CKTcurJob->JOBname,
|
||||||
ckt->CKTcurJob->JOBname,
|
freq_name, IF_REAL,
|
||||||
freq_name, IF_REAL,
|
num_vars, output_names, type,
|
||||||
num_vars, output_names, type, &sen_data);
|
&sen_data);
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
|
|
@ -216,8 +212,7 @@ int sens_sens(CKTcircuit *ckt, int restart)
|
||||||
output_values = NULL;
|
output_values = NULL;
|
||||||
output_cvalues = NEWN(IFcomplex, num_vars);
|
output_cvalues = NEWN(IFcomplex, num_vars);
|
||||||
if (job->step_type != SENS_LINEAR)
|
if (job->step_type != SENS_LINEAR)
|
||||||
SPfrontEnd->OUTattributes (sen_data,
|
SPfrontEnd->OUTattributes (sen_data, NULL, OUT_SCALE_LOG, NULL);
|
||||||
NULL, OUT_SCALE_LOG, NULL);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,9 @@ CKTsetup(CKTcircuit *ckt)
|
||||||
|
|
||||||
#ifdef WANT_SENSE2
|
#ifdef WANT_SENSE2
|
||||||
if(ckt->CKTsenInfo){
|
if(ckt->CKTsenInfo){
|
||||||
if (error = CKTsenSetup(ckt)) return(error);
|
error = CKTsenSetup(ckt);
|
||||||
|
if (error)
|
||||||
|
return(error);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -269,6 +271,22 @@ CKTsetup(CKTcircuit *ckt)
|
||||||
|
|
||||||
/* gtri - end - Setup for adding rshunt option resistors */
|
/* gtri - end - Setup for adding rshunt option resistors */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef KIRCHHOFF
|
||||||
|
/** Marking node as Non-Linear when needed
|
||||||
|
* By default every node is Linear
|
||||||
|
*/
|
||||||
|
for (i = 0 ; i < DEVmaxnum ; i++)
|
||||||
|
{
|
||||||
|
if (DEVices[i] && DEVices[i]->DEVnodeIsNonLinear && ckt->CKThead[i])
|
||||||
|
{
|
||||||
|
error = DEVices[i]->DEVnodeIsNonLinear (ckt->CKThead[i], ckt) ;
|
||||||
|
if (error)
|
||||||
|
return (error) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return(OK);
|
return(OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -237,8 +237,8 @@ int set_param(sgen *sg)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef notdef
|
#ifdef notdef
|
||||||
sgen_suspend(sg)
|
void
|
||||||
sgen *sg;
|
sgen_suspend(sgen *sg)
|
||||||
{
|
{
|
||||||
sg->devlist[sg->dev] = sg->first_model;
|
sg->devlist[sg->dev] = sg->first_model;
|
||||||
sg->model->GENnextModel = sg->next_model;
|
sg->model->GENnextModel = sg->next_model;
|
||||||
|
|
@ -246,8 +246,8 @@ sgen_suspend(sg)
|
||||||
sg->model->GENinstances = sg->first_instance;
|
sg->model->GENinstances = sg->first_instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
sgen_restore(sg)
|
void
|
||||||
sgen *sg;
|
sgen_restore(sgen *sg)
|
||||||
{
|
{
|
||||||
sg->devlist[sg->dev] = sg->model;
|
sg->devlist[sg->dev] = sg->model;
|
||||||
sg->model->GENnextModel = NULL;
|
sg->model->GENnextModel = NULL;
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,11 @@ Modified: 2000 AlansFixes
|
||||||
int
|
int
|
||||||
DCop(CKTcircuit *ckt, int notused)
|
DCop(CKTcircuit *ckt, int notused)
|
||||||
{
|
{
|
||||||
|
#ifdef WANT_SENSE2
|
||||||
|
int i, senmode, size;
|
||||||
|
long save;
|
||||||
|
#endif
|
||||||
|
|
||||||
int converged;
|
int converged;
|
||||||
int error;
|
int error;
|
||||||
IFuid *nameList; /* va: tmalloc'ed list */
|
IFuid *nameList; /* va: tmalloc'ed list */
|
||||||
|
|
@ -45,11 +50,11 @@ DCop(CKTcircuit *ckt, int notused)
|
||||||
|
|
||||||
error = CKTnames(ckt,&numNames,&nameList);
|
error = CKTnames(ckt,&numNames,&nameList);
|
||||||
if(error) return(error);
|
if(error) return(error);
|
||||||
error = SPfrontEnd->OUTpBeginPlot (
|
error = SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
|
||||||
ckt, ckt->CKTcurJob,
|
ckt->CKTcurJob->JOBname,
|
||||||
ckt->CKTcurJob->JOBname,
|
NULL, IF_REAL,
|
||||||
NULL, IF_REAL,
|
numNames, nameList, IF_REAL,
|
||||||
numNames, nameList, IF_REAL, &plot);
|
&plot);
|
||||||
tfree(nameList); /* va: nameList not used any longer, it was a memory leak */
|
tfree(nameList); /* va: nameList not used any longer, it was a memory leak */
|
||||||
if(error) return(error);
|
if(error) return(error);
|
||||||
|
|
||||||
|
|
@ -133,7 +138,10 @@ DCop(CKTcircuit *ckt, int notused)
|
||||||
for(i = 1; i<=size ; i++){
|
for(i = 1; i<=size ; i++){
|
||||||
ckt->CKTrhsOp[i] = ckt->CKTrhsOld[i];
|
ckt->CKTrhsOp[i] = ckt->CKTrhsOld[i];
|
||||||
}
|
}
|
||||||
if(error = CKTsenDCtran(ckt)) return(error);
|
error = CKTsenDCtran(ckt);
|
||||||
|
if (error)
|
||||||
|
return(error);
|
||||||
|
|
||||||
ckt->CKTmode = save;
|
ckt->CKTmode = save;
|
||||||
ckt->CKTsenInfo->SENmode = senmode;
|
ckt->CKTsenInfo->SENmode = senmode;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -237,13 +237,12 @@ DCpss(CKTcircuit *ckt,
|
||||||
/* Time Domain plot start and prepared to be filled in later */
|
/* Time Domain plot start and prepared to be filled in later */
|
||||||
error = CKTnames(ckt,&numNames,&nameList);
|
error = CKTnames(ckt,&numNames,&nameList);
|
||||||
if(error) return(error);
|
if(error) return(error);
|
||||||
SPfrontEnd->IFnewUid (ckt, &timeUid, NULL,
|
SPfrontEnd->IFnewUid (ckt, &timeUid, NULL, "time", UID_OTHER, NULL);
|
||||||
"time", UID_OTHER, NULL);
|
error = SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
|
||||||
error = SPfrontEnd->OUTpBeginPlot (
|
"Time Domain Periodic Steady State Analysis",
|
||||||
ckt, ckt->CKTcurJob,
|
timeUid, IF_REAL,
|
||||||
"Time Domain Periodic Steady State Analysis",
|
numNames, nameList, IF_REAL,
|
||||||
timeUid, IF_REAL,
|
&(job->PSSplot_td));
|
||||||
numNames, nameList, IF_REAL, &(job->PSSplot_td));
|
|
||||||
tfree(nameList);
|
tfree(nameList);
|
||||||
if(error) return(error);
|
if(error) return(error);
|
||||||
|
|
||||||
|
|
@ -406,11 +405,11 @@ DCpss(CKTcircuit *ckt,
|
||||||
if(ckt->CKTminBreak==0) ckt->CKTminBreak=ckt->CKTmaxStep*5e-5;
|
if(ckt->CKTminBreak==0) ckt->CKTminBreak=ckt->CKTmaxStep*5e-5;
|
||||||
firsttime=0;
|
firsttime=0;
|
||||||
/* To get rawfile working saj*/
|
/* To get rawfile working saj*/
|
||||||
error = SPfrontEnd->OUTpBeginPlot (
|
error = SPfrontEnd->OUTpBeginPlot (NULL, NULL,
|
||||||
NULL, NULL,
|
NULL,
|
||||||
NULL,
|
NULL, 0,
|
||||||
NULL, 0,
|
666, NULL, 666,
|
||||||
666, NULL, 666, &(job->PSSplot_td));
|
&(job->PSSplot_td));
|
||||||
if(error) {
|
if(error) {
|
||||||
fprintf(stderr, "Couldn't relink rawfile\n");
|
fprintf(stderr, "Couldn't relink rawfile\n");
|
||||||
return error;
|
return error;
|
||||||
|
|
@ -1039,8 +1038,11 @@ DCpss(CKTcircuit *ckt,
|
||||||
if (error)
|
if (error)
|
||||||
return (error) ;
|
return (error) ;
|
||||||
SPfrontEnd->IFnewUid (ckt, &freqUid, NULL, "frequency", UID_OTHER, NULL) ;
|
SPfrontEnd->IFnewUid (ckt, &freqUid, NULL, "frequency", UID_OTHER, NULL) ;
|
||||||
error = SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob, "Frequency Domain Periodic Steady State Analysis",
|
error = SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
|
||||||
freqUid, IF_REAL, numNames, nameList, IF_REAL, &(job->PSSplot_fd)) ;
|
"Frequency Domain Periodic Steady State Analysis",
|
||||||
|
freqUid, IF_REAL,
|
||||||
|
numNames, nameList, IF_REAL,
|
||||||
|
&(job->PSSplot_fd)) ;
|
||||||
tfree (nameList) ;
|
tfree (nameList) ;
|
||||||
SPfrontEnd->OUTattributes (job->PSSplot_fd, NULL, PLOT_COMB, NULL) ;
|
SPfrontEnd->OUTattributes (job->PSSplot_fd, NULL, PLOT_COMB, NULL) ;
|
||||||
|
|
||||||
|
|
@ -1204,9 +1206,25 @@ resume:
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef XSPICE
|
#ifndef XSPICE
|
||||||
|
/* don't want to get below delmin for no reason */
|
||||||
|
ckt->CKTdelta = MAX(ckt->CKTdelta, ckt->CKTdelmin*2.0);
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef XSPICE
|
||||||
|
else if(ckt->CKTtime + ckt->CKTdelta >= ckt->CKTbreaks[0]) {
|
||||||
|
ckt->CKTsaveDelta = ckt->CKTdelta;
|
||||||
|
ckt->CKTdelta = ckt->CKTbreaks[0] - ckt->CKTtime;
|
||||||
|
/* fprintf (stderr, "delta cut to %g to hit breakpoint\n" ,ckt->CKTdelta) ; */
|
||||||
|
fflush(stdout);
|
||||||
|
ckt->CKTbreak = 1; /* why? the current pt. is not a bkpt. */
|
||||||
|
}
|
||||||
|
#endif /* !XSPICE */
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef XSPICE
|
||||||
/* gtri - begin - wbk - Add Breakpoint stuff */
|
/* gtri - begin - wbk - Add Breakpoint stuff */
|
||||||
|
|
||||||
if(ckt->CKTtime + ckt->CKTdelta >= g_mif_info.breakpoint.current) {
|
if(ckt->CKTtime + ckt->CKTdelta >= g_mif_info.breakpoint.current) {
|
||||||
|
|
@ -1247,28 +1265,7 @@ resume:
|
||||||
}
|
}
|
||||||
|
|
||||||
/* gtri - end - wbk - Modify Breakpoint stuff */
|
/* gtri - end - wbk - Modify Breakpoint stuff */
|
||||||
#else /* !XSPICE */
|
|
||||||
|
|
||||||
/* don't want to get below delmin for no reason */
|
|
||||||
ckt->CKTdelta = MAX(ckt->CKTdelta, ckt->CKTdelmin*2.0);
|
|
||||||
}
|
|
||||||
else if(ckt->CKTtime + ckt->CKTdelta >= ckt->CKTbreaks[0]) {
|
|
||||||
ckt->CKTsaveDelta = ckt->CKTdelta;
|
|
||||||
ckt->CKTdelta = ckt->CKTbreaks[0] - ckt->CKTtime;
|
|
||||||
/* fprintf (stderr, "delta cut to %g to hit breakpoint\n" ,ckt->CKTdelta) ; */
|
|
||||||
fflush(stdout);
|
|
||||||
ckt->CKTbreak = 1; /* why? the current pt. is not a bkpt. */
|
|
||||||
}
|
|
||||||
#ifdef CLUSTER
|
|
||||||
if(!CLUsync(ckt->CKTtime,&ckt->CKTdelta,0)) {
|
|
||||||
fprintf (stderr, "Sync error!\n");
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* XSPICE */
|
|
||||||
|
|
||||||
#ifdef XSPICE
|
|
||||||
/* gtri - begin - wbk - Do event solution */
|
/* gtri - begin - wbk - Do event solution */
|
||||||
|
|
||||||
if(ckt->evt->counts.num_insts > 0) {
|
if(ckt->evt->counts.num_insts > 0) {
|
||||||
|
|
@ -1311,6 +1308,15 @@ resume:
|
||||||
} /* end if there are event instances */
|
} /* end if there are event instances */
|
||||||
|
|
||||||
/* gtri - end - wbk - Do event solution */
|
/* gtri - end - wbk - Do event solution */
|
||||||
|
#else
|
||||||
|
|
||||||
|
#ifdef CLUSTER
|
||||||
|
if(!CLUsync(ckt->CKTtime,&ckt->CKTdelta,0)) {
|
||||||
|
fprintf (stderr, "Sync error!\n");
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
#endif /* CLUSTER */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* What is that??? */
|
/* What is that??? */
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,9 @@ extern struct dbcomm *dbs;
|
||||||
#include "ngspice/cluster.h"
|
#include "ngspice/cluster.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef SHARED_MODULE
|
||||||
|
extern int add_bkpt(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
#define INIT_STATS() \
|
#define INIT_STATS() \
|
||||||
do { \
|
do { \
|
||||||
|
|
@ -78,9 +81,8 @@ DCtran(CKTcircuit *ckt,
|
||||||
int firsttime;
|
int firsttime;
|
||||||
int error;
|
int error;
|
||||||
#ifdef WANT_SENSE2
|
#ifdef WANT_SENSE2
|
||||||
#ifdef SENSDEBUG
|
int save, save2, size;
|
||||||
FILE *outsen;
|
long save1;
|
||||||
#endif /* SENSDEBUG */
|
|
||||||
#endif
|
#endif
|
||||||
int save_order;
|
int save_order;
|
||||||
long save_mode;
|
long save_mode;
|
||||||
|
|
@ -132,7 +134,9 @@ DCtran(CKTcircuit *ckt,
|
||||||
ckt->CKTbreaks[0] = 0;
|
ckt->CKTbreaks[0] = 0;
|
||||||
ckt->CKTbreaks[1] = ckt->CKTfinalTime;
|
ckt->CKTbreaks[1] = ckt->CKTfinalTime;
|
||||||
ckt->CKTbreakSize = 2;
|
ckt->CKTbreakSize = 2;
|
||||||
|
#ifdef SHARED_MODULE
|
||||||
|
add_bkpt();
|
||||||
|
#endif
|
||||||
#ifdef XSPICE
|
#ifdef XSPICE
|
||||||
/* gtri - begin - wbk - 12/19/90 - Modify setting of CKTminBreak */
|
/* gtri - begin - wbk - 12/19/90 - Modify setting of CKTminBreak */
|
||||||
/* Set to 10 times delmin for ATESSE 1 compatibity */
|
/* Set to 10 times delmin for ATESSE 1 compatibity */
|
||||||
|
|
@ -155,13 +159,12 @@ DCtran(CKTcircuit *ckt,
|
||||||
#endif
|
#endif
|
||||||
error = CKTnames(ckt,&numNames,&nameList);
|
error = CKTnames(ckt,&numNames,&nameList);
|
||||||
if(error) return(error);
|
if(error) return(error);
|
||||||
SPfrontEnd->IFnewUid (ckt, &timeUid, NULL,
|
SPfrontEnd->IFnewUid (ckt, &timeUid, NULL, "time", UID_OTHER, NULL);
|
||||||
"time", UID_OTHER, NULL);
|
error = SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
|
||||||
error = SPfrontEnd->OUTpBeginPlot (
|
ckt->CKTcurJob->JOBname,
|
||||||
ckt, ckt->CKTcurJob,
|
timeUid, IF_REAL,
|
||||||
ckt->CKTcurJob->JOBname,
|
numNames, nameList, IF_REAL,
|
||||||
timeUid, IF_REAL,
|
&(job->TRANplot));
|
||||||
numNames, nameList, IF_REAL, &(job->TRANplot));
|
|
||||||
tfree(nameList);
|
tfree(nameList);
|
||||||
if(error) return(error);
|
if(error) return(error);
|
||||||
|
|
||||||
|
|
@ -316,7 +319,10 @@ DCtran(CKTcircuit *ckt,
|
||||||
save2 = ckt->CKTorder;
|
save2 = ckt->CKTorder;
|
||||||
ckt->CKTmode = save_mode;
|
ckt->CKTmode = save_mode;
|
||||||
ckt->CKTorder = save_order;
|
ckt->CKTorder = save_order;
|
||||||
if(error = CKTsenDCtran(ckt)) return(error);
|
error = CKTsenDCtran(ckt);
|
||||||
|
if (error)
|
||||||
|
return(error);
|
||||||
|
|
||||||
ckt->CKTmode = save1;
|
ckt->CKTmode = save1;
|
||||||
ckt->CKTorder = save2;
|
ckt->CKTorder = save2;
|
||||||
}
|
}
|
||||||
|
|
@ -348,11 +354,11 @@ DCtran(CKTcircuit *ckt,
|
||||||
if(ckt->CKTminBreak==0) ckt->CKTminBreak=ckt->CKTmaxStep*5e-5;
|
if(ckt->CKTminBreak==0) ckt->CKTminBreak=ckt->CKTmaxStep*5e-5;
|
||||||
firsttime=0;
|
firsttime=0;
|
||||||
/* To get rawfile working saj*/
|
/* To get rawfile working saj*/
|
||||||
error = SPfrontEnd->OUTpBeginPlot (
|
error = SPfrontEnd->OUTpBeginPlot (NULL, NULL,
|
||||||
NULL, NULL,
|
NULL,
|
||||||
NULL,
|
NULL, 0,
|
||||||
NULL, 0,
|
666, NULL, 666,
|
||||||
666, NULL, 666, &(job->TRANplot));
|
&(job->TRANplot));
|
||||||
if(error) {
|
if(error) {
|
||||||
fprintf(stderr, "Couldn't relink rawfile\n");
|
fprintf(stderr, "Couldn't relink rawfile\n");
|
||||||
return error;
|
return error;
|
||||||
|
|
@ -479,9 +485,6 @@ DCtran(CKTcircuit *ckt,
|
||||||
#ifdef WANT_SENSE2
|
#ifdef WANT_SENSE2
|
||||||
if(ckt->CKTsenInfo && (ckt->CKTsenInfo->SENmode & TRANSEN)){
|
if(ckt->CKTsenInfo && (ckt->CKTsenInfo->SENmode & TRANSEN)){
|
||||||
ckt->CKTsenInfo->SENmode = save;
|
ckt->CKTsenInfo->SENmode = save;
|
||||||
#ifdef SENSDEBUG
|
|
||||||
fclose(outsen);
|
|
||||||
#endif /* SENSDEBUG */
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return(OK);
|
return(OK);
|
||||||
|
|
@ -508,7 +511,7 @@ resume:
|
||||||
if (ckt->CKTtime == 0.)
|
if (ckt->CKTtime == 0.)
|
||||||
SetAnalyse( "tran init", 0);
|
SetAnalyse( "tran init", 0);
|
||||||
else
|
else
|
||||||
SetAnalyse( "tran", (int)((ckt->CKTtime * 1000.) / ckt->CKTfinalTime) + 0.5);
|
SetAnalyse( "tran", (int)((ckt->CKTtime * 1000.) / ckt->CKTfinalTime + 0.5));
|
||||||
#endif
|
#endif
|
||||||
ckt->CKTdelta =
|
ckt->CKTdelta =
|
||||||
MIN(ckt->CKTdelta,ckt->CKTmaxStep);
|
MIN(ckt->CKTdelta,ckt->CKTmaxStep);
|
||||||
|
|
@ -546,15 +549,37 @@ resume:
|
||||||
ckt->CKTbreaks[1] - ckt->CKTbreaks[0]));
|
ckt->CKTbreaks[1] - ckt->CKTbreaks[0]));
|
||||||
|
|
||||||
if(firsttime) {
|
if(firsttime) {
|
||||||
|
/* set a breakpoint to reduce ringing of current in devices */
|
||||||
|
if (ckt->CKTmode&MODEUIC)
|
||||||
|
CKTsetBreak(ckt,ckt->CKTstep);
|
||||||
|
|
||||||
ckt->CKTdelta /= 10;
|
ckt->CKTdelta /= 10;
|
||||||
#ifdef STEPDEBUG
|
#ifdef STEPDEBUG
|
||||||
(void)printf("delta cut for initial timepoint\n");
|
(void)printf("delta cut for initial timepoint\n");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef XSPICE
|
#ifndef XSPICE
|
||||||
|
/* don't want to get below delmin for no reason */
|
||||||
|
ckt->CKTdelta = MAX(ckt->CKTdelta, ckt->CKTdelmin*2.0);
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef XSPICE
|
||||||
|
else if(ckt->CKTtime + ckt->CKTdelta >= ckt->CKTbreaks[0]) {
|
||||||
|
ckt->CKTsaveDelta = ckt->CKTdelta;
|
||||||
|
ckt->CKTdelta = ckt->CKTbreaks[0] - ckt->CKTtime;
|
||||||
|
#ifdef STEPDEBUG
|
||||||
|
(void)printf("delta cut to %g to hit breakpoint\n",ckt->CKTdelta);
|
||||||
|
fflush(stdout);
|
||||||
|
#endif
|
||||||
|
ckt->CKTbreak = 1; /* why? the current pt. is not a bkpt. */
|
||||||
|
}
|
||||||
|
#endif /* !XSPICE */
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef XSPICE
|
||||||
/* gtri - begin - wbk - Add Breakpoint stuff */
|
/* gtri - begin - wbk - Add Breakpoint stuff */
|
||||||
|
|
||||||
if(ckt->CKTtime + ckt->CKTdelta >= g_mif_info.breakpoint.current) {
|
if(ckt->CKTtime + ckt->CKTdelta >= g_mif_info.breakpoint.current) {
|
||||||
|
|
@ -595,30 +620,7 @@ resume:
|
||||||
}
|
}
|
||||||
|
|
||||||
/* gtri - end - wbk - Modify Breakpoint stuff */
|
/* gtri - end - wbk - Modify Breakpoint stuff */
|
||||||
#else /* !XSPICE */
|
|
||||||
|
|
||||||
/* don't want to get below delmin for no reason */
|
|
||||||
ckt->CKTdelta = MAX(ckt->CKTdelta, ckt->CKTdelmin*2.0);
|
|
||||||
}
|
|
||||||
else if(ckt->CKTtime + ckt->CKTdelta >= ckt->CKTbreaks[0]) {
|
|
||||||
ckt->CKTsaveDelta = ckt->CKTdelta;
|
|
||||||
ckt->CKTdelta = ckt->CKTbreaks[0] - ckt->CKTtime;
|
|
||||||
#ifdef STEPDEBUG
|
|
||||||
(void)printf("delta cut to %g to hit breakpoint\n",ckt->CKTdelta);
|
|
||||||
fflush(stdout);
|
|
||||||
#endif
|
|
||||||
ckt->CKTbreak = 1; /* why? the current pt. is not a bkpt. */
|
|
||||||
}
|
|
||||||
#ifdef CLUSTER
|
|
||||||
if(!CLUsync(ckt->CKTtime,&ckt->CKTdelta,0)) {
|
|
||||||
printf("Sync error!\n");
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* XSPICE */
|
|
||||||
|
|
||||||
#ifdef XSPICE
|
|
||||||
/* gtri - begin - wbk - Do event solution */
|
/* gtri - begin - wbk - Do event solution */
|
||||||
|
|
||||||
if(ckt->evt->counts.num_insts > 0) {
|
if(ckt->evt->counts.num_insts > 0) {
|
||||||
|
|
@ -661,6 +663,15 @@ resume:
|
||||||
} /* end if there are event instances */
|
} /* end if there are event instances */
|
||||||
|
|
||||||
/* gtri - end - wbk - Do event solution */
|
/* gtri - end - wbk - Do event solution */
|
||||||
|
#else
|
||||||
|
|
||||||
|
#ifdef CLUSTER
|
||||||
|
if(!CLUsync(ckt->CKTtime,&ckt->CKTdelta,0)) {
|
||||||
|
printf("Sync error!\n");
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
#endif /* CLUSTER */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
for(i=5; i>=0; i--)
|
for(i=5; i>=0; i--)
|
||||||
ckt->CKTdeltaOld[i+1] = ckt->CKTdeltaOld[i];
|
ckt->CKTdeltaOld[i+1] = ckt->CKTdeltaOld[i];
|
||||||
|
|
@ -792,7 +803,10 @@ resume:
|
||||||
save2 = ckt->CKTorder;
|
save2 = ckt->CKTorder;
|
||||||
ckt->CKTmode = save_mode;
|
ckt->CKTmode = save_mode;
|
||||||
ckt->CKTorder = save_order;
|
ckt->CKTorder = save_order;
|
||||||
if(error = CKTsenDCtran(ckt)) return(error);
|
error = CKTsenDCtran (ckt);
|
||||||
|
if (error)
|
||||||
|
return(error);
|
||||||
|
|
||||||
ckt->CKTmode = save1;
|
ckt->CKTmode = save1;
|
||||||
ckt->CKTorder = save2;
|
ckt->CKTorder = save2;
|
||||||
}
|
}
|
||||||
|
|
@ -852,7 +866,10 @@ resume:
|
||||||
save2 = ckt->CKTorder;
|
save2 = ckt->CKTorder;
|
||||||
ckt->CKTmode = save_mode;
|
ckt->CKTmode = save_mode;
|
||||||
ckt->CKTorder = save_order;
|
ckt->CKTorder = save_order;
|
||||||
if(error = CKTsenDCtran(ckt)) return(error);
|
error = CKTsenDCtran(ckt);
|
||||||
|
if (error)
|
||||||
|
return (error);
|
||||||
|
|
||||||
ckt->CKTmode = save1;
|
ckt->CKTmode = save1;
|
||||||
ckt->CKTorder = save2;
|
ckt->CKTorder = save2;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,7 @@ DCtrCurv(CKTcircuit *ckt, int restart)
|
||||||
static runDesc *plot = NULL;
|
static runDesc *plot = NULL;
|
||||||
|
|
||||||
#ifdef WANT_SENSE2
|
#ifdef WANT_SENSE2
|
||||||
|
long save;
|
||||||
#ifdef SENSDEBUG
|
#ifdef SENSDEBUG
|
||||||
if(ckt->CKTsenInfo && (ckt->CKTsenInfo->SENmode&DCSEN) ){
|
if(ckt->CKTsenInfo && (ckt->CKTsenInfo->SENmode&DCSEN) ){
|
||||||
printf("\nDC Sensitivity Results\n\n");
|
printf("\nDC Sensitivity Results\n\n");
|
||||||
|
|
@ -66,11 +67,11 @@ DCtrCurv(CKTcircuit *ckt, int restart)
|
||||||
/* continuing */
|
/* continuing */
|
||||||
i = job->TRCVnestState;
|
i = job->TRCVnestState;
|
||||||
/* resume to work? saj*/
|
/* resume to work? saj*/
|
||||||
error = SPfrontEnd->OUTpBeginPlot (
|
error = SPfrontEnd->OUTpBeginPlot (NULL, NULL,
|
||||||
NULL, NULL,
|
NULL,
|
||||||
NULL,
|
NULL, 0,
|
||||||
NULL, 0,
|
666, NULL, 666,
|
||||||
666, NULL, 666, &plot);
|
&plot);
|
||||||
goto resume;
|
goto resume;
|
||||||
}
|
}
|
||||||
ckt->CKTtime = 0;
|
ckt->CKTtime = 0;
|
||||||
|
|
@ -192,36 +193,31 @@ found:;
|
||||||
|
|
||||||
|
|
||||||
if (job->TRCVvType[i] == vcode)
|
if (job->TRCVvType[i] == vcode)
|
||||||
SPfrontEnd->IFnewUid (ckt, &varUid, NULL,
|
SPfrontEnd->IFnewUid (ckt, &varUid, NULL, "v-sweep", UID_OTHER, NULL);
|
||||||
"v-sweep", UID_OTHER, NULL);
|
|
||||||
|
|
||||||
else {
|
else {
|
||||||
if (job->TRCVvType[i] == icode)
|
if (job->TRCVvType[i] == icode)
|
||||||
SPfrontEnd->IFnewUid (ckt, &varUid, NULL,
|
SPfrontEnd->IFnewUid (ckt, &varUid, NULL, "i-sweep", UID_OTHER, NULL);
|
||||||
"i-sweep", UID_OTHER, NULL);
|
|
||||||
|
|
||||||
else {
|
else {
|
||||||
if (job->TRCVvType[i] == TEMP_CODE)
|
if (job->TRCVvType[i] == TEMP_CODE)
|
||||||
SPfrontEnd->IFnewUid (ckt, &varUid, NULL,
|
SPfrontEnd->IFnewUid (ckt, &varUid, NULL, "temp-sweep", UID_OTHER, NULL);
|
||||||
"temp-sweep", UID_OTHER, NULL);
|
|
||||||
|
|
||||||
else {
|
else {
|
||||||
if (job->TRCVvType[i] == rcode)
|
if (job->TRCVvType[i] == rcode)
|
||||||
SPfrontEnd->IFnewUid (ckt, &varUid, NULL,
|
SPfrontEnd->IFnewUid (ckt, &varUid, NULL, "res-sweep", UID_OTHER, NULL);
|
||||||
"res-sweep", UID_OTHER, NULL);
|
|
||||||
|
|
||||||
else
|
else
|
||||||
SPfrontEnd->IFnewUid (ckt, &varUid, NULL,
|
SPfrontEnd->IFnewUid (ckt, &varUid, NULL, "?-sweep", UID_OTHER, NULL);
|
||||||
"?-sweep", UID_OTHER, NULL);
|
|
||||||
} /* icode */
|
} /* icode */
|
||||||
} /* TEMP_CODE */
|
} /* TEMP_CODE */
|
||||||
} /* rcode*/
|
} /* rcode*/
|
||||||
|
|
||||||
error = SPfrontEnd->OUTpBeginPlot (
|
error = SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
|
||||||
ckt, ckt->CKTcurJob,
|
ckt->CKTcurJob->JOBname,
|
||||||
ckt->CKTcurJob->JOBname,
|
varUid, IF_REAL,
|
||||||
varUid, IF_REAL,
|
numNames, nameList, IF_REAL,
|
||||||
numNames, nameList, IF_REAL, &plot);
|
&plot);
|
||||||
tfree(nameList);
|
tfree(nameList);
|
||||||
|
|
||||||
if(error) return(error);
|
if(error) return(error);
|
||||||
|
|
@ -450,7 +446,7 @@ resume:
|
||||||
}
|
}
|
||||||
if (job->TRCVvType[i] == TEMP_CODE) { /* Temperature */
|
if (job->TRCVvType[i] == TEMP_CODE) { /* Temperature */
|
||||||
printf("Current Circuit Temperature : %.5e C\n",
|
printf("Current Circuit Temperature : %.5e C\n",
|
||||||
ckt-CKTtemp - CONSTCtoK);
|
ckt->CKTtemp - CONSTCtoK);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* SENSDEBUG */
|
#endif /* SENSDEBUG */
|
||||||
|
|
@ -458,7 +454,10 @@ resume:
|
||||||
senmode = ckt->CKTsenInfo->SENmode;
|
senmode = ckt->CKTsenInfo->SENmode;
|
||||||
save = ckt->CKTmode;
|
save = ckt->CKTmode;
|
||||||
ckt->CKTsenInfo->SENmode = DCSEN;
|
ckt->CKTsenInfo->SENmode = DCSEN;
|
||||||
if(error = CKTsenDCtran(ckt)) return (error);
|
error = CKTsenDCtran(ckt);
|
||||||
|
if (error)
|
||||||
|
return(error);
|
||||||
|
|
||||||
ckt->CKTmode = save;
|
ckt->CKTmode = save;
|
||||||
ckt->CKTsenInfo->SENmode = senmode;
|
ckt->CKTsenInfo->SENmode = senmode;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -107,11 +107,11 @@ time1 = SPfrontEnd->IFseconds();
|
||||||
|
|
||||||
if (ckt->CKTkeepOpInfo) {
|
if (ckt->CKTkeepOpInfo) {
|
||||||
/* Dump operating point. */
|
/* Dump operating point. */
|
||||||
error = SPfrontEnd->OUTpBeginPlot (
|
error = SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
|
||||||
ckt, ckt->CKTcurJob,
|
"Distortion Operating Point",
|
||||||
"Distortion Operating Point",
|
NULL, IF_REAL,
|
||||||
NULL, IF_REAL,
|
numNames, nameList, IF_REAL,
|
||||||
numNames, nameList, IF_REAL, &acPlot);
|
&acPlot);
|
||||||
if(error) return(error);
|
if(error) return(error);
|
||||||
CKTdump(ckt, 0.0, acPlot);
|
CKTdump(ckt, 0.0, acPlot);
|
||||||
SPfrontEnd->OUTendPlot (acPlot);
|
SPfrontEnd->OUTendPlot (acPlot);
|
||||||
|
|
@ -516,16 +516,14 @@ time1 = SPfrontEnd->IFseconds();
|
||||||
if (! job->Df2wanted) {
|
if (! job->Df2wanted) {
|
||||||
error = CKTnames(ckt,&numNames,&nameList);
|
error = CKTnames(ckt,&numNames,&nameList);
|
||||||
if(error) return(error);
|
if(error) return(error);
|
||||||
SPfrontEnd->IFnewUid (ckt, &freqUid, NULL,
|
SPfrontEnd->IFnewUid (ckt, &freqUid, NULL, "frequency", UID_OTHER, NULL);
|
||||||
"frequency", UID_OTHER, NULL);
|
SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
|
||||||
SPfrontEnd->OUTpBeginPlot (
|
"DISTORTION - 2nd harmonic",
|
||||||
ckt, ckt->CKTcurJob,
|
freqUid, IF_REAL,
|
||||||
"DISTORTION - 2nd harmonic",
|
numNames, nameList, IF_COMPLEX,
|
||||||
freqUid, IF_REAL,
|
&acPlot);
|
||||||
numNames, nameList, IF_COMPLEX, &acPlot);
|
|
||||||
if (job->DstepType != LINEAR) {
|
if (job->DstepType != LINEAR) {
|
||||||
SPfrontEnd->OUTattributes (acPlot, NULL,
|
SPfrontEnd->OUTattributes (acPlot, NULL, OUT_SCALE_LOG, NULL);
|
||||||
OUT_SCALE_LOG, NULL);
|
|
||||||
}
|
}
|
||||||
for (i=0; i< displacement ; i++)
|
for (i=0; i< displacement ; i++)
|
||||||
{
|
{
|
||||||
|
|
@ -542,13 +540,12 @@ time1 = SPfrontEnd->IFseconds();
|
||||||
|
|
||||||
error = CKTnames(ckt,&numNames,&nameList);
|
error = CKTnames(ckt,&numNames,&nameList);
|
||||||
if(error) return(error);
|
if(error) return(error);
|
||||||
SPfrontEnd->IFnewUid (ckt, &freqUid, NULL,
|
SPfrontEnd->IFnewUid (ckt, &freqUid, NULL, "frequency", UID_OTHER, NULL);
|
||||||
"frequency", UID_OTHER, NULL);
|
SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
|
||||||
SPfrontEnd->OUTpBeginPlot (
|
"DISTORTION - 3rd harmonic",
|
||||||
ckt, ckt->CKTcurJob,
|
freqUid, IF_REAL,
|
||||||
"DISTORTION - 3rd harmonic",
|
numNames, nameList, IF_COMPLEX,
|
||||||
freqUid, IF_REAL,
|
&acPlot);
|
||||||
numNames, nameList, IF_COMPLEX, &acPlot);
|
|
||||||
for (i=0; i< displacement ; i++)
|
for (i=0; i< displacement ; i++)
|
||||||
{
|
{
|
||||||
DkerProc(D_THRF1,job->r3H11stor[i],
|
DkerProc(D_THRF1,job->r3H11stor[i],
|
||||||
|
|
@ -566,13 +563,12 @@ time1 = SPfrontEnd->IFseconds();
|
||||||
|
|
||||||
error = CKTnames(ckt,&numNames,&nameList);
|
error = CKTnames(ckt,&numNames,&nameList);
|
||||||
if(error) return(error);
|
if(error) return(error);
|
||||||
SPfrontEnd->IFnewUid (ckt, &freqUid, NULL,
|
SPfrontEnd->IFnewUid (ckt, &freqUid, NULL, "frequency", UID_OTHER, NULL);
|
||||||
"frequency", UID_OTHER, NULL);
|
SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
|
||||||
SPfrontEnd->OUTpBeginPlot (
|
"DISTORTION - IM: f1+f2",
|
||||||
ckt, ckt->CKTcurJob,
|
freqUid, IF_REAL,
|
||||||
"DISTORTION - IM: f1+f2",
|
numNames, nameList, IF_COMPLEX,
|
||||||
freqUid, IF_REAL,
|
&acPlot);
|
||||||
numNames, nameList, IF_COMPLEX, &acPlot);
|
|
||||||
for (i=0; i< displacement ; i++)
|
for (i=0; i< displacement ; i++)
|
||||||
{
|
{
|
||||||
DkerProc(D_F1PF2,job->r2H12stor[i],
|
DkerProc(D_F1PF2,job->r2H12stor[i],
|
||||||
|
|
@ -588,13 +584,12 @@ time1 = SPfrontEnd->IFseconds();
|
||||||
|
|
||||||
error = CKTnames(ckt,&numNames,&nameList);
|
error = CKTnames(ckt,&numNames,&nameList);
|
||||||
if(error) return(error);
|
if(error) return(error);
|
||||||
SPfrontEnd->IFnewUid (ckt, &freqUid, NULL,
|
SPfrontEnd->IFnewUid (ckt, &freqUid, NULL, "frequency", UID_OTHER, NULL);
|
||||||
"frequency", UID_OTHER, NULL);
|
SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
|
||||||
SPfrontEnd->OUTpBeginPlot (
|
"DISTORTION - IM: f1-f2",
|
||||||
ckt, ckt->CKTcurJob,
|
freqUid, IF_REAL,
|
||||||
"DISTORTION - IM: f1-f2",
|
numNames, nameList, IF_COMPLEX,
|
||||||
freqUid, IF_REAL,
|
&acPlot);
|
||||||
numNames, nameList, IF_COMPLEX, &acPlot);
|
|
||||||
for (i=0; i< displacement ; i++)
|
for (i=0; i< displacement ; i++)
|
||||||
{
|
{
|
||||||
DkerProc(D_F1MF2,
|
DkerProc(D_F1MF2,
|
||||||
|
|
@ -611,13 +606,12 @@ time1 = SPfrontEnd->IFseconds();
|
||||||
|
|
||||||
error = CKTnames(ckt,&numNames,&nameList);
|
error = CKTnames(ckt,&numNames,&nameList);
|
||||||
if(error) return(error);
|
if(error) return(error);
|
||||||
SPfrontEnd->IFnewUid (ckt, &freqUid, NULL,
|
SPfrontEnd->IFnewUid (ckt, &freqUid, NULL, "frequency", UID_OTHER, NULL);
|
||||||
"frequency", UID_OTHER, NULL);
|
SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
|
||||||
SPfrontEnd->OUTpBeginPlot (
|
"DISTORTION - IM: 2f1-f2",
|
||||||
ckt, ckt->CKTcurJob,
|
freqUid, IF_REAL,
|
||||||
"DISTORTION - IM: 2f1-f2",
|
numNames, nameList, IF_COMPLEX,
|
||||||
freqUid, IF_REAL,
|
&acPlot);
|
||||||
numNames, nameList, IF_COMPLEX, &acPlot);
|
|
||||||
for (i=0; i< displacement ; i++)
|
for (i=0; i< displacement ; i++)
|
||||||
{
|
{
|
||||||
DkerProc(D_2F1MF2,
|
DkerProc(D_2F1MF2,
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,15 @@
|
||||||
/* Patch to noisean.c by Richard D. McRoberts.
|
|
||||||
* Patched with modifications from Weidong Liu (2000)
|
|
||||||
* Patched with modifications ftom Weidong Liu
|
|
||||||
* in bsim4.1.0 code
|
|
||||||
*/
|
|
||||||
/**********
|
/**********
|
||||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||||
Author: 1987 Gary W. Ng
|
Author: 1987 Gary W. Ng
|
||||||
Modified: 2001 AlansFixes
|
Modified: 2001 AlansFixes
|
||||||
**********/
|
**********/
|
||||||
|
|
||||||
|
/* Patch to noisean.c by Richard D. McRoberts.
|
||||||
|
* Patched with modifications from Weidong Liu (2000)
|
||||||
|
* Patched with modifications ftom Weidong Liu
|
||||||
|
* in bsim4.1.0 code
|
||||||
|
*/
|
||||||
|
|
||||||
#include "ngspice/ngspice.h"
|
#include "ngspice/ngspice.h"
|
||||||
#include "ngspice/acdefs.h"
|
#include "ngspice/acdefs.h"
|
||||||
#include "ngspice/cktdefs.h"
|
#include "ngspice/cktdefs.h"
|
||||||
|
|
@ -47,8 +48,7 @@ NOISEan (CKTcircuit *ckt, int restart)
|
||||||
inst = NULL;
|
inst = NULL;
|
||||||
code = CKTtypelook("Vsource");
|
code = CKTtypelook("Vsource");
|
||||||
if (code != -1) {
|
if (code != -1) {
|
||||||
error = CKTfndDev(ckt, &code, &inst,
|
error = CKTfndDev(ckt, &code, &inst, job->input, NULL);
|
||||||
job->input, NULL, NULL);
|
|
||||||
if (!error && !((VSRCinstance *)inst)->VSRCacGiven) {
|
if (!error && !((VSRCinstance *)inst)->VSRCacGiven) {
|
||||||
errMsg = TMALLOC(char, strlen(noacinput) + 1);
|
errMsg = TMALLOC(char, strlen(noacinput) + 1);
|
||||||
strcpy(errMsg,noacinput);
|
strcpy(errMsg,noacinput);
|
||||||
|
|
@ -58,8 +58,7 @@ NOISEan (CKTcircuit *ckt, int restart)
|
||||||
|
|
||||||
code = CKTtypelook("Isource");
|
code = CKTtypelook("Isource");
|
||||||
if (code != -1 && inst==NULL) {
|
if (code != -1 && inst==NULL) {
|
||||||
error = CKTfndDev(ckt, &code, &inst,
|
error = CKTfndDev(ckt, &code, &inst, job->input, NULL);
|
||||||
job->input, NULL, NULL);
|
|
||||||
if (error) {
|
if (error) {
|
||||||
/* XXX ??? */
|
/* XXX ??? */
|
||||||
SPfrontEnd->IFerror (ERR_WARNING,
|
SPfrontEnd->IFerror (ERR_WARNING,
|
||||||
|
|
@ -119,8 +118,7 @@ NOISEan (CKTcircuit *ckt, int restart)
|
||||||
/* the current front-end needs the namelist to be fully
|
/* the current front-end needs the namelist to be fully
|
||||||
declared before an OUTpBeginplot */
|
declared before an OUTpBeginplot */
|
||||||
|
|
||||||
SPfrontEnd->IFnewUid (ckt, &freqUid, NULL,
|
SPfrontEnd->IFnewUid (ckt, &freqUid, NULL, "frequency", UID_OTHER, NULL);
|
||||||
"frequency", UID_OTHER, NULL);
|
|
||||||
|
|
||||||
data->numPlots = 0; /* we don't have any plots yet */
|
data->numPlots = 0; /* we don't have any plots yet */
|
||||||
error = CKTnoise(ckt,N_DENS,N_OPEN,data);
|
error = CKTnoise(ckt,N_DENS,N_OPEN,data);
|
||||||
|
|
@ -131,16 +129,15 @@ NOISEan (CKTcircuit *ckt, int restart)
|
||||||
* plot
|
* plot
|
||||||
*/
|
*/
|
||||||
|
|
||||||
error = SPfrontEnd->OUTpBeginPlot (
|
error = SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
|
||||||
ckt, ckt->CKTcurJob,
|
"Noise Spectral Density Curves - (V^2 or A^2)/Hz",
|
||||||
"Noise Spectral Density Curves - (V^2 or A^2)/Hz",
|
freqUid, IF_REAL,
|
||||||
freqUid, IF_REAL,
|
data->numPlots, data->namelist, IF_REAL,
|
||||||
data->numPlots, data->namelist, IF_REAL, &(data->NplotPtr));
|
&(data->NplotPtr));
|
||||||
if (error) return(error);
|
if (error) return(error);
|
||||||
|
|
||||||
if (job->NstpType != LINEAR) {
|
if (job->NstpType != LINEAR) {
|
||||||
SPfrontEnd->OUTattributes (data->NplotPtr, NULL,
|
SPfrontEnd->OUTattributes (data->NplotPtr, NULL, OUT_SCALE_LOG, NULL);
|
||||||
OUT_SCALE_LOG, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else { /* we must have paused before. pick up where we left off */
|
} else { /* we must have paused before. pick up where we left off */
|
||||||
|
|
@ -166,11 +163,11 @@ NOISEan (CKTcircuit *ckt, int restart)
|
||||||
data->outNoiz = job->NsavOnoise;
|
data->outNoiz = job->NsavOnoise;
|
||||||
data->inNoise = job->NsavInoise;
|
data->inNoise = job->NsavInoise;
|
||||||
/* saj resume rawfile fix*/
|
/* saj resume rawfile fix*/
|
||||||
error = SPfrontEnd->OUTpBeginPlot (
|
error = SPfrontEnd->OUTpBeginPlot (NULL, NULL,
|
||||||
NULL, NULL,
|
NULL,
|
||||||
NULL,
|
NULL, 0,
|
||||||
NULL, 0,
|
666, NULL, 666,
|
||||||
666, NULL, 666, &(data->NplotPtr));
|
&(data->NplotPtr));
|
||||||
/*saj*/
|
/*saj*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -278,11 +275,11 @@ NOISEan (CKTcircuit *ckt, int restart)
|
||||||
|
|
||||||
if (error) return(error);
|
if (error) return(error);
|
||||||
|
|
||||||
SPfrontEnd->OUTpBeginPlot (
|
SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
|
||||||
ckt, ckt->CKTcurJob,
|
"Integrated Noise - V^2 or A^2",
|
||||||
"Integrated Noise - V^2 or A^2",
|
NULL, 0,
|
||||||
NULL, 0,
|
data->numPlots, data->namelist, IF_REAL,
|
||||||
data->numPlots, data->namelist, IF_REAL, &(data->NplotPtr));
|
&(data->NplotPtr));
|
||||||
|
|
||||||
error = CKTnoise(ckt,INT_NOIZ,N_CALC,data);
|
error = CKTnoise(ckt,INT_NOIZ,N_CALC,data);
|
||||||
if (error) return(error);
|
if (error) return(error);
|
||||||
|
|
|
||||||
|
|
@ -46,11 +46,11 @@ PZan(CKTcircuit *ckt, int reset)
|
||||||
/* Dump operating point. */
|
/* Dump operating point. */
|
||||||
error = CKTnames(ckt,&numNames,&nameList);
|
error = CKTnames(ckt,&numNames,&nameList);
|
||||||
if(error) return(error);
|
if(error) return(error);
|
||||||
error = SPfrontEnd->OUTpBeginPlot (
|
error = SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
|
||||||
ckt, ckt->CKTcurJob,
|
"Distortion Operating Point",
|
||||||
"Distortion Operating Point",
|
NULL, IF_REAL,
|
||||||
NULL, IF_REAL,
|
numNames, nameList, IF_REAL,
|
||||||
numNames, nameList, IF_REAL, &plot);
|
&plot);
|
||||||
if(error) return(error);
|
if(error) return(error);
|
||||||
CKTdump(ckt, 0.0, plot);
|
CKTdump(ckt, 0.0, plot);
|
||||||
SPfrontEnd->OUTendPlot (plot);
|
SPfrontEnd->OUTendPlot (plot);
|
||||||
|
|
@ -94,7 +94,7 @@ PZinit(CKTcircuit *ckt)
|
||||||
i = CKTtypelook("LTRA");
|
i = CKTtypelook("LTRA");
|
||||||
}
|
}
|
||||||
if (i != -1 && ckt->CKThead[i] != NULL)
|
if (i != -1 && ckt->CKThead[i] != NULL)
|
||||||
MERROR(E_XMISSIONLINE, "Transmission lines not supported")
|
MERROR(E_XMISSIONLINE, "Transmission lines not supported");
|
||||||
|
|
||||||
job->PZpoleList = NULL;
|
job->PZpoleList = NULL;
|
||||||
job->PZzeroList = NULL;
|
job->PZzeroList = NULL;
|
||||||
|
|
@ -102,19 +102,19 @@ PZinit(CKTcircuit *ckt)
|
||||||
job->PZnZeros = 0;
|
job->PZnZeros = 0;
|
||||||
|
|
||||||
if (job->PZin_pos == job->PZin_neg)
|
if (job->PZin_pos == job->PZin_neg)
|
||||||
MERROR(E_SHORT, "Input is shorted")
|
MERROR(E_SHORT, "Input is shorted");
|
||||||
|
|
||||||
if (job->PZout_pos == job->PZout_neg)
|
if (job->PZout_pos == job->PZout_neg)
|
||||||
MERROR(E_SHORT, "Output is shorted")
|
MERROR(E_SHORT, "Output is shorted");
|
||||||
|
|
||||||
if (job->PZin_pos == job->PZout_pos
|
if (job->PZin_pos == job->PZout_pos
|
||||||
&& job->PZin_neg == job->PZout_neg
|
&& job->PZin_neg == job->PZout_neg
|
||||||
&& job->PZinput_type == PZ_IN_VOL)
|
&& job->PZinput_type == PZ_IN_VOL)
|
||||||
MERROR(E_INISOUT, "Transfer function is unity")
|
MERROR(E_INISOUT, "Transfer function is unity");
|
||||||
else if (job->PZin_pos == job->PZout_neg
|
else if (job->PZin_pos == job->PZout_neg
|
||||||
&& job->PZin_neg == job->PZout_pos
|
&& job->PZin_neg == job->PZout_pos
|
||||||
&& job->PZinput_type == PZ_IN_VOL)
|
&& job->PZinput_type == PZ_IN_VOL)
|
||||||
MERROR(E_INISOUT, "Transfer function is -1")
|
MERROR(E_INISOUT, "Transfer function is -1");
|
||||||
|
|
||||||
return(OK);
|
return(OK);
|
||||||
}
|
}
|
||||||
|
|
@ -141,20 +141,18 @@ PZpost(CKTcircuit *ckt)
|
||||||
j = 0;
|
j = 0;
|
||||||
for (i = 0; i < job->PZnPoles; i++) {
|
for (i = 0; i < job->PZnPoles; i++) {
|
||||||
sprintf(name, "pole(%-u)", i+1);
|
sprintf(name, "pole(%-u)", i+1);
|
||||||
SPfrontEnd->IFnewUid (ckt, &(namelist[j++]), NULL,
|
SPfrontEnd->IFnewUid (ckt, &(namelist[j++]), NULL, name, UID_OTHER, NULL);
|
||||||
name, UID_OTHER, NULL);
|
|
||||||
}
|
}
|
||||||
for (i = 0; i < job->PZnZeros; i++) {
|
for (i = 0; i < job->PZnZeros; i++) {
|
||||||
sprintf(name, "zero(%-u)", i+1);
|
sprintf(name, "zero(%-u)", i+1);
|
||||||
SPfrontEnd->IFnewUid (ckt, &(namelist[j++]), NULL,
|
SPfrontEnd->IFnewUid (ckt, &(namelist[j++]), NULL, name, UID_OTHER, NULL);
|
||||||
name, UID_OTHER, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SPfrontEnd->OUTpBeginPlot (
|
SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
|
||||||
ckt, ckt->CKTcurJob,
|
ckt->CKTcurJob->JOBname,
|
||||||
ckt->CKTcurJob->JOBname,
|
NULL, 0,
|
||||||
NULL, 0,
|
job->PZnPoles + job->PZnZeros, namelist, IF_COMPLEX,
|
||||||
job->PZnPoles + job->PZnZeros, namelist, IF_COMPLEX, &pzPlotPtr);
|
&pzPlotPtr);
|
||||||
|
|
||||||
j = 0;
|
j = 0;
|
||||||
if (job->PZnPoles > 0) {
|
if (job->PZnPoles > 0) {
|
||||||
|
|
|
||||||
|
|
@ -51,8 +51,7 @@ TFanal(CKTcircuit *ckt, int restart)
|
||||||
Itype = CKTtypelook("Isource");
|
Itype = CKTtypelook("Isource");
|
||||||
Vtype = CKTtypelook("Vsource");
|
Vtype = CKTtypelook("Vsource");
|
||||||
if(Itype != -1) {
|
if(Itype != -1) {
|
||||||
error = CKTfndDev(ckt,&Itype,&ptr,
|
error = CKTfndDev(ckt, &Itype, &ptr, job->TFinSrc, NULL);
|
||||||
job->TFinSrc, NULL, NULL);
|
|
||||||
if(error ==0) {
|
if(error ==0) {
|
||||||
job->TFinIsI = 1;
|
job->TFinIsI = 1;
|
||||||
job->TFinIsV = 0;
|
job->TFinIsV = 0;
|
||||||
|
|
@ -62,9 +61,7 @@ TFanal(CKTcircuit *ckt, int restart)
|
||||||
}
|
}
|
||||||
|
|
||||||
if( (Vtype != -1) && (ptr==NULL) ) {
|
if( (Vtype != -1) && (ptr==NULL) ) {
|
||||||
error = CKTfndDev(ckt,&Vtype,&ptr,
|
error = CKTfndDev(ckt, &Vtype, &ptr, job->TFinSrc, NULL);
|
||||||
job->TFinSrc, NULL,
|
|
||||||
NULL);
|
|
||||||
job->TFinIsV = 1;
|
job->TFinIsV = 1;
|
||||||
job->TFinIsI = 0;
|
job->TFinIsI = 0;
|
||||||
if(error !=0) {
|
if(error !=0) {
|
||||||
|
|
@ -94,30 +91,26 @@ TFanal(CKTcircuit *ckt, int restart)
|
||||||
ckt->CKTrhs[0]=0;
|
ckt->CKTrhs[0]=0;
|
||||||
|
|
||||||
/* make a UID for the transfer function output */
|
/* make a UID for the transfer function output */
|
||||||
SPfrontEnd->IFnewUid (ckt, &tfuid, NULL, "Transfer_function",
|
SPfrontEnd->IFnewUid (ckt, &tfuid, NULL, "Transfer_function", UID_OTHER, NULL);
|
||||||
UID_OTHER, NULL);
|
|
||||||
|
|
||||||
/* make a UID for the input impedance */
|
/* make a UID for the input impedance */
|
||||||
SPfrontEnd->IFnewUid (ckt, &inuid, job->TFinSrc,
|
SPfrontEnd->IFnewUid (ckt, &inuid, job->TFinSrc, "Input_impedance", UID_OTHER, NULL);
|
||||||
"Input_impedance", UID_OTHER, NULL);
|
|
||||||
|
|
||||||
/* make a UID for the output impedance */
|
/* make a UID for the output impedance */
|
||||||
if (job->TFoutIsI) {
|
if (job->TFoutIsI) {
|
||||||
SPfrontEnd->IFnewUid (ckt, &outuid, job->TFoutSrc
|
SPfrontEnd->IFnewUid (ckt, &outuid, job->TFoutSrc ,"Output_impedance", UID_OTHER, NULL);
|
||||||
,"Output_impedance", UID_OTHER, NULL);
|
|
||||||
} else {
|
} else {
|
||||||
name = TMALLOC(char, strlen(job->TFoutName) + 22);
|
name = TMALLOC(char, strlen(job->TFoutName) + 22);
|
||||||
(void)sprintf(name,"output_impedance_at_%s",
|
(void)sprintf(name,"output_impedance_at_%s",
|
||||||
job->TFoutName);
|
job->TFoutName);
|
||||||
SPfrontEnd->IFnewUid (ckt, &outuid, NULL,
|
SPfrontEnd->IFnewUid (ckt, &outuid, NULL, name, UID_OTHER, NULL);
|
||||||
name, UID_OTHER, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
error = SPfrontEnd->OUTpBeginPlot (
|
error = SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
|
||||||
ckt, ckt->CKTcurJob,
|
job->JOBname,
|
||||||
job->JOBname,
|
NULL, 0,
|
||||||
NULL, 0,
|
3, uids, IF_REAL,
|
||||||
3, uids, IF_REAL, &plotptr);
|
&plotptr);
|
||||||
if(error) return(error);
|
if(error) return(error);
|
||||||
|
|
||||||
/*find transfer function */
|
/*find transfer function */
|
||||||
|
|
|
||||||
|
|
@ -21,25 +21,16 @@ int TRANinit(CKTcircuit *ckt, JOB *anal)
|
||||||
ckt->CKTstep = job->TRANstep;
|
ckt->CKTstep = job->TRANstep;
|
||||||
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 */
|
|
||||||
if(ckt->CKTmaxStep == 0)
|
|
||||||
{
|
|
||||||
if (ckt->CKTstep < ( ckt->CKTfinalTime - ckt->CKTinitTime )/50.0)
|
|
||||||
{
|
|
||||||
ckt->CKTmaxStep = ckt->CKTstep;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ckt->CKTmaxStep = ( ckt->CKTfinalTime - ckt->CKTinitTime )/50.0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/* The following code has been taken from macspice 3f4 (A. Wilson)
|
||||||
|
in the file traninit.new.c - Seems interesting */
|
||||||
|
if(ckt->CKTmaxStep == 0) {
|
||||||
|
if (ckt->CKTstep < ( ckt->CKTfinalTime - ckt->CKTinitTime )/50.0)
|
||||||
|
ckt->CKTmaxStep = ckt->CKTstep;
|
||||||
|
else
|
||||||
|
ckt->CKTmaxStep = ( ckt->CKTfinalTime - ckt->CKTinitTime )/50.0;
|
||||||
|
}
|
||||||
|
|
||||||
ckt->CKTdelmin = 1e-11*ckt->CKTmaxStep; /* XXX */
|
ckt->CKTdelmin = 1e-11*ckt->CKTmaxStep; /* XXX */
|
||||||
ckt->CKTmode = job->TRANmode;
|
ckt->CKTmode = job->TRANmode;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,10 +19,14 @@ libasrc_la_SOURCES = \
|
||||||
asrcmdel.c \
|
asrcmdel.c \
|
||||||
asrcpar.c \
|
asrcpar.c \
|
||||||
asrcpzld.c \
|
asrcpzld.c \
|
||||||
asrcset.c \
|
asrcset.c \
|
||||||
asrctemp.c
|
asrctemp.c
|
||||||
|
|
||||||
|
|
||||||
|
if KIRCHHOFF_WANTED
|
||||||
|
libasrc_la_SOURCES += asrcnode.c
|
||||||
|
endif
|
||||||
|
|
||||||
AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(top_srcdir)/src/include
|
AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(top_srcdir)/src/include
|
||||||
AM_CFLAGS = $(STATIC)
|
AM_CFLAGS = $(STATIC)
|
||||||
MAINTAINERCLEANFILES = Makefile.in
|
MAINTAINERCLEANFILES = Makefile.in
|
||||||
|
|
|
||||||
|
|
@ -16,3 +16,7 @@ extern int ASRCacLoad(GENmodel*,CKTcircuit*);
|
||||||
extern int ASRCsetup(SMPmatrix*,GENmodel*,CKTcircuit*,int*);
|
extern int ASRCsetup(SMPmatrix*,GENmodel*,CKTcircuit*,int*);
|
||||||
extern int ASRCunsetup(GENmodel*,CKTcircuit*);
|
extern int ASRCunsetup(GENmodel*,CKTcircuit*);
|
||||||
extern int ASRCtemp(GENmodel*,CKTcircuit*);
|
extern int ASRCtemp(GENmodel*,CKTcircuit*);
|
||||||
|
|
||||||
|
#ifdef KIRCHHOFF
|
||||||
|
extern int ASRCnodeIsNonLinear (GENmodel *, CKTcircuit *) ;
|
||||||
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -74,12 +74,17 @@ SPICEdev ASRCinfo = {
|
||||||
#endif
|
#endif
|
||||||
/* DEVinstSize */ &ASRCiSize,
|
/* DEVinstSize */ &ASRCiSize,
|
||||||
/* DEVmodSize */ &ASRCmSize,
|
/* DEVmodSize */ &ASRCmSize,
|
||||||
|
|
||||||
#if defined(KLU) || defined(SuperLU) || defined(UMFPACK)
|
#if defined(KLU) || defined(SuperLU) || defined(UMFPACK)
|
||||||
/* DEVbindCSC */ NULL,
|
/* DEVbindCSC */ NULL,
|
||||||
/* DEVbindCSCComplex */ NULL,
|
/* DEVbindCSCComplex */ NULL,
|
||||||
/* DEVbindCSCComplexToReal */ NULL,
|
/* DEVbindCSCComplexToReal */ NULL,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef KIRCHHOFF
|
||||||
|
/* DEVnodeIsNonLinear */ ASRCnodeIsNonLinear
|
||||||
|
#endif
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
/**********
|
||||||
|
Author: 2013 Francesco Lannutti
|
||||||
|
**********/
|
||||||
|
|
||||||
|
#include "ngspice/ngspice.h"
|
||||||
|
#include "ngspice/cktdefs.h"
|
||||||
|
#include "asrcdefs.h"
|
||||||
|
#include "ngspice/sperror.h"
|
||||||
|
|
||||||
|
int
|
||||||
|
ASRCnodeIsNonLinear (GENmodel *inModel, CKTcircuit *ckt)
|
||||||
|
{
|
||||||
|
ASRCmodel *model = (ASRCmodel *)inModel ;
|
||||||
|
ASRCinstance *here ;
|
||||||
|
|
||||||
|
/* loop through all the ASRC models */
|
||||||
|
for ( ; model != NULL ; model = model->ASRCnextModel)
|
||||||
|
{
|
||||||
|
/* loop through all the instances of the model */
|
||||||
|
for (here = model->ASRCinstances ; here != NULL ; here = here->ASRCnextInstance)
|
||||||
|
{
|
||||||
|
ckt->CKTnodeIsLinear [here->ASRCposNode] = 0 ;
|
||||||
|
ckt->CKTnodeIsLinear [here->ASRCnegNode] = 0 ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (OK) ;
|
||||||
|
}
|
||||||
|
|
@ -54,14 +54,14 @@ ASRCsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states)
|
||||||
|
|
||||||
/* macro to make elements with built in test for out of memory */
|
/* macro to make elements with built in test for out of memory */
|
||||||
#define TSTALLOC(ptr,first,second) \
|
#define TSTALLOC(ptr,first,second) \
|
||||||
if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\
|
do { if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\
|
||||||
return(E_NOMEM);\
|
return(E_NOMEM);\
|
||||||
}
|
} } while(0)
|
||||||
|
|
||||||
#define MY_TSTALLOC(ptr,first,second) \
|
#define MY_TSTALLOC(ptr,first,second) \
|
||||||
if((here->ptr = SMPmakeElt(matrix, here->first, (second)->number)) == NULL){\
|
do { if((here->ptr = SMPmakeElt(matrix, here->first, (second)->number)) == NULL){\
|
||||||
return(E_NOMEM);\
|
return(E_NOMEM);\
|
||||||
}
|
} } while(0)
|
||||||
|
|
||||||
/* For each controlling variable set the entries
|
/* For each controlling variable set the entries
|
||||||
in the vector of the positions of the SMP */
|
in the vector of the positions of the SMP */
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,10 @@ if UMFPACK_WANTED
|
||||||
libbjt_la_SOURCES += bjtbindCSC.c
|
libbjt_la_SOURCES += bjtbindCSC.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if KIRCHHOFF_WANTED
|
||||||
|
libbjt_la_SOURCES += bjtnode.c
|
||||||
|
endif
|
||||||
|
|
||||||
AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(top_srcdir)/src/include
|
AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(top_srcdir)/src/include
|
||||||
AM_CFLAGS = $(STATIC)
|
AM_CFLAGS = $(STATIC)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,9 @@ extern int BJTdisto(int,GENmodel*,CKTcircuit*);
|
||||||
extern int BJTnoise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*);
|
extern int BJTnoise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*);
|
||||||
extern int BJTdSetup(GENmodel*, register CKTcircuit*);
|
extern int BJTdSetup(GENmodel*, register CKTcircuit*);
|
||||||
|
|
||||||
|
#ifdef KIRCHHOFF
|
||||||
|
extern int BJTnodeIsNonLinear (GENmodel *, CKTcircuit *) ;
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(KLU) || defined(SuperLU) || defined(UMFPACK)
|
#if defined(KLU) || defined(SuperLU) || defined(UMFPACK)
|
||||||
|
|
|
||||||
|
|
@ -73,12 +73,17 @@ SPICEdev BJTinfo = { /* description from struct IFdevice */
|
||||||
#endif
|
#endif
|
||||||
/* DEVinstSize */ &BJTiSize,
|
/* DEVinstSize */ &BJTiSize,
|
||||||
/* DEVmodSize */ &BJTmSize,
|
/* DEVmodSize */ &BJTmSize,
|
||||||
|
|
||||||
#if defined(KLU) || defined(SuperLU) || defined(UMFPACK)
|
#if defined(KLU) || defined(SuperLU) || defined(UMFPACK)
|
||||||
/* DEVbindCSC */ BJTbindCSC,
|
/* DEVbindCSC */ BJTbindCSC,
|
||||||
/* DEVbindCSCComplex */ BJTbindCSCComplex,
|
/* DEVbindCSCComplex */ BJTbindCSCComplex,
|
||||||
/* DEVbindCSCComplexToReal */ BJTbindCSCComplexToReal,
|
/* DEVbindCSCComplexToReal */ BJTbindCSCComplexToReal,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef KIRCHHOFF
|
||||||
|
/* DEVnodeIsNonLinear */ BJTnodeIsNonLinear
|
||||||
|
#endif
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
/**********
|
||||||
|
Author: 2013 Francesco Lannutti
|
||||||
|
**********/
|
||||||
|
|
||||||
|
#include "ngspice/ngspice.h"
|
||||||
|
#include "ngspice/cktdefs.h"
|
||||||
|
#include "bjtdefs.h"
|
||||||
|
#include "ngspice/sperror.h"
|
||||||
|
|
||||||
|
int
|
||||||
|
BJTnodeIsNonLinear (GENmodel *inModel, CKTcircuit *ckt)
|
||||||
|
{
|
||||||
|
BJTmodel *model = (BJTmodel *)inModel ;
|
||||||
|
BJTinstance *here ;
|
||||||
|
|
||||||
|
/* loop through all the BJT models */
|
||||||
|
for ( ; model != NULL ; model = model->BJTnextModel)
|
||||||
|
{
|
||||||
|
/* loop through all the instances of the model */
|
||||||
|
for (here = model->BJTinstances ; here != NULL ; here = here->BJTnextInstance)
|
||||||
|
{
|
||||||
|
ckt->CKTnodeIsLinear [here->BJTcolPrimeNode] = 0 ;
|
||||||
|
ckt->CKTnodeIsLinear [here->BJTbasePrimeNode] = 0 ;
|
||||||
|
ckt->CKTnodeIsLinear [here->BJTemitPrimeNode] = 0 ;
|
||||||
|
ckt->CKTnodeIsLinear [here->BJTsubstNode] = 0 ;
|
||||||
|
ckt->CKTnodeIsLinear [here->BJTsubstConNode] = 0 ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (OK) ;
|
||||||
|
}
|
||||||
|
|
@ -540,11 +540,11 @@ load:
|
||||||
,cbe,icbe,cce,icce);
|
,cbe,icbe,cce,icce);
|
||||||
|
|
||||||
printf("cc = %.7e + j%.7e , ce = %.7e + j%.7e,",
|
printf("cc = %.7e + j%.7e , ce = %.7e + j%.7e,",
|
||||||
,cc,icc,ce,ice);
|
cc,icc,ce,ice);
|
||||||
printf("ccprm = %.7e + j%.7e , ceprm = %.7e + j%.7e",
|
printf("ccprm = %.7e + j%.7e , ceprm = %.7e + j%.7e",
|
||||||
ccprm,iccprm,ceprm,iceprm);
|
ccprm,iccprm,ceprm,iceprm);
|
||||||
printf("cb = %.7e + j%.7e , cbprm = %.7e + j%.7e , ",
|
printf("cb = %.7e + j%.7e , cbprm = %.7e + j%.7e , ",
|
||||||
cb,icb,cbprm,icbprm)
|
cb,icb,cbprm,icbprm);
|
||||||
printf("cs = %.7e + j%.7e\n",
|
printf("cs = %.7e + j%.7e\n",
|
||||||
cs,ics);
|
cs,ics);
|
||||||
#endif /* SENSDEBUG */
|
#endif /* SENSDEBUG */
|
||||||
|
|
|
||||||
|
|
@ -420,28 +420,28 @@ BJTsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states)
|
||||||
|
|
||||||
/* macro to make elements with built in test for out of memory */
|
/* macro to make elements with built in test for out of memory */
|
||||||
#define TSTALLOC(ptr,first,second) \
|
#define TSTALLOC(ptr,first,second) \
|
||||||
if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\
|
do { if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\
|
||||||
return(E_NOMEM);\
|
return(E_NOMEM);\
|
||||||
}
|
} } while(0)
|
||||||
TSTALLOC(BJTcolColPrimePtr,BJTcolNode,BJTcolPrimeNode)
|
TSTALLOC(BJTcolColPrimePtr,BJTcolNode,BJTcolPrimeNode);
|
||||||
TSTALLOC(BJTbaseBasePrimePtr,BJTbaseNode,BJTbasePrimeNode)
|
TSTALLOC(BJTbaseBasePrimePtr,BJTbaseNode,BJTbasePrimeNode);
|
||||||
TSTALLOC(BJTemitEmitPrimePtr,BJTemitNode,BJTemitPrimeNode)
|
TSTALLOC(BJTemitEmitPrimePtr,BJTemitNode,BJTemitPrimeNode);
|
||||||
TSTALLOC(BJTcolPrimeColPtr,BJTcolPrimeNode,BJTcolNode)
|
TSTALLOC(BJTcolPrimeColPtr,BJTcolPrimeNode,BJTcolNode);
|
||||||
TSTALLOC(BJTcolPrimeBasePrimePtr,BJTcolPrimeNode,BJTbasePrimeNode)
|
TSTALLOC(BJTcolPrimeBasePrimePtr,BJTcolPrimeNode,BJTbasePrimeNode);
|
||||||
TSTALLOC(BJTcolPrimeEmitPrimePtr,BJTcolPrimeNode,BJTemitPrimeNode)
|
TSTALLOC(BJTcolPrimeEmitPrimePtr,BJTcolPrimeNode,BJTemitPrimeNode);
|
||||||
TSTALLOC(BJTbasePrimeBasePtr,BJTbasePrimeNode,BJTbaseNode)
|
TSTALLOC(BJTbasePrimeBasePtr,BJTbasePrimeNode,BJTbaseNode);
|
||||||
TSTALLOC(BJTbasePrimeColPrimePtr,BJTbasePrimeNode,BJTcolPrimeNode)
|
TSTALLOC(BJTbasePrimeColPrimePtr,BJTbasePrimeNode,BJTcolPrimeNode);
|
||||||
TSTALLOC(BJTbasePrimeEmitPrimePtr,BJTbasePrimeNode,BJTemitPrimeNode)
|
TSTALLOC(BJTbasePrimeEmitPrimePtr,BJTbasePrimeNode,BJTemitPrimeNode);
|
||||||
TSTALLOC(BJTemitPrimeEmitPtr,BJTemitPrimeNode,BJTemitNode)
|
TSTALLOC(BJTemitPrimeEmitPtr,BJTemitPrimeNode,BJTemitNode);
|
||||||
TSTALLOC(BJTemitPrimeColPrimePtr,BJTemitPrimeNode,BJTcolPrimeNode)
|
TSTALLOC(BJTemitPrimeColPrimePtr,BJTemitPrimeNode,BJTcolPrimeNode);
|
||||||
TSTALLOC(BJTemitPrimeBasePrimePtr,BJTemitPrimeNode,BJTbasePrimeNode)
|
TSTALLOC(BJTemitPrimeBasePrimePtr,BJTemitPrimeNode,BJTbasePrimeNode);
|
||||||
TSTALLOC(BJTcolColPtr,BJTcolNode,BJTcolNode)
|
TSTALLOC(BJTcolColPtr,BJTcolNode,BJTcolNode);
|
||||||
TSTALLOC(BJTbaseBasePtr,BJTbaseNode,BJTbaseNode)
|
TSTALLOC(BJTbaseBasePtr,BJTbaseNode,BJTbaseNode);
|
||||||
TSTALLOC(BJTemitEmitPtr,BJTemitNode,BJTemitNode)
|
TSTALLOC(BJTemitEmitPtr,BJTemitNode,BJTemitNode);
|
||||||
TSTALLOC(BJTcolPrimeColPrimePtr,BJTcolPrimeNode,BJTcolPrimeNode)
|
TSTALLOC(BJTcolPrimeColPrimePtr,BJTcolPrimeNode,BJTcolPrimeNode);
|
||||||
TSTALLOC(BJTbasePrimeBasePrimePtr,BJTbasePrimeNode,BJTbasePrimeNode)
|
TSTALLOC(BJTbasePrimeBasePrimePtr,BJTbasePrimeNode,BJTbasePrimeNode);
|
||||||
TSTALLOC(BJTemitPrimeEmitPrimePtr,BJTemitPrimeNode,BJTemitPrimeNode)
|
TSTALLOC(BJTemitPrimeEmitPrimePtr,BJTemitPrimeNode,BJTemitPrimeNode);
|
||||||
TSTALLOC(BJTsubstSubstPtr,BJTsubstNode,BJTsubstNode)
|
TSTALLOC(BJTsubstSubstPtr,BJTsubstNode,BJTsubstNode);
|
||||||
if (model -> BJTsubs == LATERAL) {
|
if (model -> BJTsubs == LATERAL) {
|
||||||
here -> BJTsubstConNode = here -> BJTbasePrimeNode;
|
here -> BJTsubstConNode = here -> BJTbasePrimeNode;
|
||||||
here -> BJTsubstConSubstConPtr = here -> BJTbasePrimeBasePrimePtr;
|
here -> BJTsubstConSubstConPtr = here -> BJTbasePrimeBasePrimePtr;
|
||||||
|
|
@ -449,10 +449,10 @@ if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\
|
||||||
here -> BJTsubstConNode = here -> BJTcolPrimeNode;
|
here -> BJTsubstConNode = here -> BJTcolPrimeNode;
|
||||||
here -> BJTsubstConSubstConPtr = here -> BJTcolPrimeColPrimePtr;
|
here -> BJTsubstConSubstConPtr = here -> BJTcolPrimeColPrimePtr;
|
||||||
}
|
}
|
||||||
TSTALLOC(BJTsubstConSubstPtr,BJTsubstConNode,BJTsubstNode)
|
TSTALLOC(BJTsubstConSubstPtr,BJTsubstConNode,BJTsubstNode);
|
||||||
TSTALLOC(BJTsubstSubstConPtr,BJTsubstNode,BJTsubstConNode)
|
TSTALLOC(BJTsubstSubstConPtr,BJTsubstNode,BJTsubstConNode);
|
||||||
TSTALLOC(BJTbaseColPrimePtr,BJTbaseNode,BJTcolPrimeNode)
|
TSTALLOC(BJTbaseColPrimePtr,BJTbaseNode,BJTcolPrimeNode);
|
||||||
TSTALLOC(BJTcolPrimeBasePtr,BJTcolPrimeNode,BJTbaseNode)
|
TSTALLOC(BJTcolPrimeBasePtr,BJTcolPrimeNode,BJTbaseNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return(OK);
|
return(OK);
|
||||||
|
|
|
||||||
|
|
@ -55,9 +55,8 @@ BJTsUpdate(GENmodel *inModel, CKTcircuit *ckt)
|
||||||
sxpbx = 0;
|
sxpbx = 0;
|
||||||
#ifdef SENSDEBUG
|
#ifdef SENSDEBUG
|
||||||
printf("senupdate Instance name: %s\n",here->BJTname);
|
printf("senupdate Instance name: %s\n",here->BJTname);
|
||||||
printf("iparmno = %d,CKTag[0] = %.2e,CKTag[1] = %.2e\n",
|
printf("CKTag[0] = %.2e,CKTag[1] = %.2e\n",
|
||||||
iparmno,ckt->CKTag[0],ckt->CKTag[1]);
|
ckt->CKTag[0],ckt->CKTag[1]);
|
||||||
|
|
||||||
printf("capbe = %.7e\n",here->BJTcapbe);
|
printf("capbe = %.7e\n",here->BJTcapbe);
|
||||||
printf("capbc = %.7e\n",here->BJTcapbc);
|
printf("capbc = %.7e\n",here->BJTcapbc);
|
||||||
printf("capsub = %.7e\n",here->BJTcapsub);
|
printf("capsub = %.7e\n",here->BJTcapsub);
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,10 @@ if UMFPACK_WANTED
|
||||||
libbsim1_la_SOURCES += b1bindCSC.c
|
libbsim1_la_SOURCES += b1bindCSC.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if KIRCHHOFF_WANTED
|
||||||
|
libbsim1_la_SOURCES += b1node.c
|
||||||
|
endif
|
||||||
|
|
||||||
AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(top_srcdir)/src/include
|
AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(top_srcdir)/src/include
|
||||||
AM_CFLAGS = $(STATIC)
|
AM_CFLAGS = $(STATIC)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
/**********
|
||||||
|
Author: 2013 Francesco Lannutti
|
||||||
|
**********/
|
||||||
|
|
||||||
|
#include "ngspice/ngspice.h"
|
||||||
|
#include "ngspice/cktdefs.h"
|
||||||
|
#include "bsim1def.h"
|
||||||
|
#include "ngspice/sperror.h"
|
||||||
|
|
||||||
|
int
|
||||||
|
B1nodeIsNonLinear (GENmodel *inModel, CKTcircuit *ckt)
|
||||||
|
{
|
||||||
|
B1model *model = (B1model *)inModel ;
|
||||||
|
B1instance *here ;
|
||||||
|
|
||||||
|
/* loop through all the BSIM1 models */
|
||||||
|
for ( ; model != NULL ; model = model->B1nextModel)
|
||||||
|
{
|
||||||
|
/* loop through all the instances of the model */
|
||||||
|
for (here = model->B1instances ; here != NULL ; here = here->B1nextInstance)
|
||||||
|
{
|
||||||
|
ckt->CKTnodeIsLinear [here->B1dNodePrime] = 0 ;
|
||||||
|
ckt->CKTnodeIsLinear [here->B1sNodePrime] = 0 ;
|
||||||
|
ckt->CKTnodeIsLinear [here->B1gNode] = 0 ;
|
||||||
|
ckt->CKTnodeIsLinear [here->B1bNode] = 0 ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (OK) ;
|
||||||
|
}
|
||||||
|
|
@ -368,32 +368,32 @@ B1setup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt,
|
||||||
|
|
||||||
/* macro to make elements with built in test for out of memory */
|
/* macro to make elements with built in test for out of memory */
|
||||||
#define TSTALLOC(ptr,first,second) \
|
#define TSTALLOC(ptr,first,second) \
|
||||||
if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\
|
do { if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\
|
||||||
return(E_NOMEM);\
|
return(E_NOMEM);\
|
||||||
}
|
} } while(0)
|
||||||
|
|
||||||
TSTALLOC(B1DdPtr, B1dNode, B1dNode)
|
TSTALLOC(B1DdPtr, B1dNode, B1dNode);
|
||||||
TSTALLOC(B1GgPtr, B1gNode, B1gNode)
|
TSTALLOC(B1GgPtr, B1gNode, B1gNode);
|
||||||
TSTALLOC(B1SsPtr, B1sNode, B1sNode)
|
TSTALLOC(B1SsPtr, B1sNode, B1sNode);
|
||||||
TSTALLOC(B1BbPtr, B1bNode, B1bNode)
|
TSTALLOC(B1BbPtr, B1bNode, B1bNode);
|
||||||
TSTALLOC(B1DPdpPtr, B1dNodePrime, B1dNodePrime)
|
TSTALLOC(B1DPdpPtr, B1dNodePrime, B1dNodePrime);
|
||||||
TSTALLOC(B1SPspPtr, B1sNodePrime, B1sNodePrime)
|
TSTALLOC(B1SPspPtr, B1sNodePrime, B1sNodePrime);
|
||||||
TSTALLOC(B1DdpPtr, B1dNode, B1dNodePrime)
|
TSTALLOC(B1DdpPtr, B1dNode, B1dNodePrime);
|
||||||
TSTALLOC(B1GbPtr, B1gNode, B1bNode)
|
TSTALLOC(B1GbPtr, B1gNode, B1bNode);
|
||||||
TSTALLOC(B1GdpPtr, B1gNode, B1dNodePrime)
|
TSTALLOC(B1GdpPtr, B1gNode, B1dNodePrime);
|
||||||
TSTALLOC(B1GspPtr, B1gNode, B1sNodePrime)
|
TSTALLOC(B1GspPtr, B1gNode, B1sNodePrime);
|
||||||
TSTALLOC(B1SspPtr, B1sNode, B1sNodePrime)
|
TSTALLOC(B1SspPtr, B1sNode, B1sNodePrime);
|
||||||
TSTALLOC(B1BdpPtr, B1bNode, B1dNodePrime)
|
TSTALLOC(B1BdpPtr, B1bNode, B1dNodePrime);
|
||||||
TSTALLOC(B1BspPtr, B1bNode, B1sNodePrime)
|
TSTALLOC(B1BspPtr, B1bNode, B1sNodePrime);
|
||||||
TSTALLOC(B1DPspPtr, B1dNodePrime, B1sNodePrime)
|
TSTALLOC(B1DPspPtr, B1dNodePrime, B1sNodePrime);
|
||||||
TSTALLOC(B1DPdPtr, B1dNodePrime, B1dNode)
|
TSTALLOC(B1DPdPtr, B1dNodePrime, B1dNode);
|
||||||
TSTALLOC(B1BgPtr, B1bNode, B1gNode)
|
TSTALLOC(B1BgPtr, B1bNode, B1gNode);
|
||||||
TSTALLOC(B1DPgPtr, B1dNodePrime, B1gNode)
|
TSTALLOC(B1DPgPtr, B1dNodePrime, B1gNode);
|
||||||
TSTALLOC(B1SPgPtr, B1sNodePrime, B1gNode)
|
TSTALLOC(B1SPgPtr, B1sNodePrime, B1gNode);
|
||||||
TSTALLOC(B1SPsPtr, B1sNodePrime, B1sNode)
|
TSTALLOC(B1SPsPtr, B1sNodePrime, B1sNode);
|
||||||
TSTALLOC(B1DPbPtr, B1dNodePrime, B1bNode)
|
TSTALLOC(B1DPbPtr, B1dNodePrime, B1bNode);
|
||||||
TSTALLOC(B1SPbPtr, B1sNodePrime, B1bNode)
|
TSTALLOC(B1SPbPtr, B1sNodePrime, B1bNode);
|
||||||
TSTALLOC(B1SPdpPtr, B1sNodePrime, B1dNodePrime)
|
TSTALLOC(B1SPdpPtr, B1sNodePrime, B1dNodePrime);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,3 +35,7 @@ extern int B1bindCSC (GENmodel*, CKTcircuit*) ;
|
||||||
extern int B1bindCSCComplex (GENmodel*, CKTcircuit*) ;
|
extern int B1bindCSCComplex (GENmodel*, CKTcircuit*) ;
|
||||||
extern int B1bindCSCComplexToReal (GENmodel*, CKTcircuit*) ;
|
extern int B1bindCSCComplexToReal (GENmodel*, CKTcircuit*) ;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef KIRCHHOFF
|
||||||
|
extern int B1nodeIsNonLinear (GENmodel *, CKTcircuit *) ;
|
||||||
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -73,12 +73,17 @@ SPICEdev B1info = {
|
||||||
#endif
|
#endif
|
||||||
/* DEVinstSize */ &B1iSize,
|
/* DEVinstSize */ &B1iSize,
|
||||||
/* DEVmodSize */ &B1mSize,
|
/* DEVmodSize */ &B1mSize,
|
||||||
|
|
||||||
#if defined(KLU) || defined(SuperLU) || defined(UMFPACK)
|
#if defined(KLU) || defined(SuperLU) || defined(UMFPACK)
|
||||||
/* DEVbindCSC */ B1bindCSC,
|
/* DEVbindCSC */ B1bindCSC,
|
||||||
/* DEVbindCSCComplex */ B1bindCSCComplex,
|
/* DEVbindCSCComplex */ B1bindCSCComplex,
|
||||||
/* DEVbindCSCComplexToReal */ B1bindCSCComplexToReal,
|
/* DEVbindCSCComplexToReal */ B1bindCSCComplexToReal,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef KIRCHHOFF
|
||||||
|
/* DEVnodeIsNonLinear */ B1nodeIsNonLinear
|
||||||
|
#endif
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,10 @@ if UMFPACK_WANTED
|
||||||
libbsim2_la_SOURCES += b2bindCSC.c
|
libbsim2_la_SOURCES += b2bindCSC.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if KIRCHHOFF_WANTED
|
||||||
|
libbsim2_la_SOURCES += b2node.c
|
||||||
|
endif
|
||||||
|
|
||||||
AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(top_srcdir)/src/include
|
AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(top_srcdir)/src/include
|
||||||
AM_CFLAGS = $(STATIC)
|
AM_CFLAGS = $(STATIC)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -40,13 +40,13 @@ B2load(GENmodel *inModel, CKTcircuit *ckt)
|
||||||
double cd;
|
double cd;
|
||||||
double cdrain;
|
double cdrain;
|
||||||
double cdhat;
|
double cdhat;
|
||||||
double cdreq;
|
double cdreq, cdreq_fvk ;
|
||||||
double ceq;
|
double ceq;
|
||||||
double ceqbd;
|
double ceqbd, ceqbd_fvk ;
|
||||||
double ceqbs;
|
double ceqbs, ceqbs_fvk ;
|
||||||
double ceqqb;
|
double ceqqb, ceqqb_fvk ;
|
||||||
double ceqqd;
|
double ceqqd, ceqqd_fvk ;
|
||||||
double ceqqg;
|
double ceqqg, ceqqg_fvk ;
|
||||||
double czbd;
|
double czbd;
|
||||||
double czbdsw;
|
double czbdsw;
|
||||||
double czbs;
|
double czbs;
|
||||||
|
|
@ -628,7 +628,7 @@ line755:
|
||||||
|
|
||||||
line850:
|
line850:
|
||||||
/* initialize to zero charge conductance and current */
|
/* initialize to zero charge conductance and current */
|
||||||
ceqqg = ceqqb = ceqqd = 0.0;
|
ceqqg = ceqqg_fvk = ceqqb = ceqqb_fvk = ceqqd = ceqqd_fvk = 0.0;
|
||||||
gcdgb = gcddb = gcdsb = 0.0;
|
gcdgb = gcddb = gcdsb = 0.0;
|
||||||
gcsgb = gcsdb = gcssb = 0.0;
|
gcsgb = gcsdb = gcssb = 0.0;
|
||||||
gcggb = gcgdb = gcgsb = 0.0;
|
gcggb = gcgdb = gcgsb = 0.0;
|
||||||
|
|
@ -641,8 +641,11 @@ line860:
|
||||||
cqbulk = *(ckt->CKTstate0 + here->B2iqb);
|
cqbulk = *(ckt->CKTstate0 + here->B2iqb);
|
||||||
cqdrn = *(ckt->CKTstate0 + here->B2iqd);
|
cqdrn = *(ckt->CKTstate0 + here->B2iqd);
|
||||||
ceqqg = cqgate - gcggb * vgb + gcgdb * vbd + gcgsb * vbs;
|
ceqqg = cqgate - gcggb * vgb + gcgdb * vbd + gcgsb * vbs;
|
||||||
|
ceqqg_fvk = cqgate ;
|
||||||
ceqqb = cqbulk - gcbgb * vgb + gcbdb * vbd + gcbsb * vbs;
|
ceqqb = cqbulk - gcbgb * vgb + gcbdb * vbd + gcbsb * vbs;
|
||||||
|
ceqqb_fvk = cqbulk ;
|
||||||
ceqqd = cqdrn - gcdgb * vgb + gcddb * vbd + gcdsb * vbs;
|
ceqqd = cqdrn - gcdgb * vgb + gcddb * vbd + gcdsb * vbs;
|
||||||
|
ceqqd_fvk = cqdrn ;
|
||||||
|
|
||||||
if(ckt->CKTmode & MODEINITTRAN ) {
|
if(ckt->CKTmode & MODEINITTRAN ) {
|
||||||
*(ckt->CKTstate1 + here->B2iqb) =
|
*(ckt->CKTstate1 + here->B2iqb) =
|
||||||
|
|
@ -661,19 +664,25 @@ line900:
|
||||||
m = here->B2m;
|
m = here->B2m;
|
||||||
|
|
||||||
ceqbs = model->B2type * (cbs-(gbs-ckt->CKTgmin)*vbs);
|
ceqbs = model->B2type * (cbs-(gbs-ckt->CKTgmin)*vbs);
|
||||||
|
ceqbs_fvk = model->B2type * (cbs + ckt->CKTgmin * vbs) ;
|
||||||
ceqbd = model->B2type * (cbd-(gbd-ckt->CKTgmin)*vbd);
|
ceqbd = model->B2type * (cbd-(gbd-ckt->CKTgmin)*vbd);
|
||||||
|
ceqbd_fvk = model->B2type * (cbd + ckt->CKTgmin * vbd) ;
|
||||||
ceqqg = model->B2type * ceqqg;
|
ceqqg = model->B2type * ceqqg;
|
||||||
|
ceqqg_fvk = model->B2type * ceqqg_fvk ;
|
||||||
ceqqb = model->B2type * ceqqb;
|
ceqqb = model->B2type * ceqqb;
|
||||||
|
ceqqb_fvk = model->B2type * ceqqb_fvk ;
|
||||||
ceqqd = model->B2type * ceqqd;
|
ceqqd = model->B2type * ceqqd;
|
||||||
|
ceqqd_fvk = model->B2type * ceqqd_fvk ;
|
||||||
if (here->B2mode >= 0) {
|
if (here->B2mode >= 0) {
|
||||||
xnrm=1;
|
xnrm=1;
|
||||||
xrev=0;
|
xrev=0;
|
||||||
cdreq=model->B2type*(cdrain-gds*vds-gm*vgs-gmbs*vbs);
|
cdreq=model->B2type*(cdrain-gds*vds-gm*vgs-gmbs*vbs);
|
||||||
|
cdreq_fvk = model->B2type * cdrain ;
|
||||||
} else {
|
} else {
|
||||||
xnrm=0;
|
xnrm=0;
|
||||||
xrev=1;
|
xrev=1;
|
||||||
cdreq = -(model->B2type)*(cdrain+gds*vds-gm*vgd-gmbs*vbd);
|
cdreq = -(model->B2type)*(cdrain+gds*vds-gm*vgd-gmbs*vbd);
|
||||||
|
cdreq_fvk = - (model->B2type * cdrain) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
*(ckt->CKTrhs + here->B2gNode) -= m * (ceqqg);
|
*(ckt->CKTrhs + here->B2gNode) -= m * (ceqqg);
|
||||||
|
|
@ -712,6 +721,24 @@ line900:
|
||||||
*(here->B2SPbPtr) += m * (-gbs-(xnrm-xrev)*gmbs-gcsgb-gcsdb-gcssb);
|
*(here->B2SPbPtr) += m * (-gbs-(xnrm-xrev)*gmbs-gcsgb-gcsdb-gcssb);
|
||||||
*(here->B2SPdpPtr) += m * (-gds-xrev*(gm+gmbs)+gcsdb);
|
*(here->B2SPdpPtr) += m * (-gds-xrev*(gm+gmbs)+gcsdb);
|
||||||
|
|
||||||
|
#ifdef KIRCHHOFF
|
||||||
|
/* KCL verification - Dynamic Part */
|
||||||
|
*(ckt->CKTfvk + here->B2gNode) += m * ceqqg_fvk ;
|
||||||
|
*(ckt->CKTfvk + here->B2bNode) += m * (ceqbs_fvk + ceqbd_fvk + ceqqb_fvk) ;
|
||||||
|
*(ckt->CKTfvk + here->B2dNodePrime) -= m * (ceqbd_fvk - cdreq_fvk - ceqqd_fvk) ;
|
||||||
|
*(ckt->CKTfvk + here->B2sNodePrime) -= m * (cdreq_fvk + ceqbs_fvk + ceqqg_fvk + ceqqb_fvk + ceqqd_fvk) ;
|
||||||
|
|
||||||
|
|
||||||
|
/* KCL verification - Linear and Static Part */
|
||||||
|
*(ckt->CKTfvk + here->B2dNode) += m * (here->B2drainConductance) * *(ckt->CKTrhsOld + here->B2dNode) ;
|
||||||
|
*(ckt->CKTfvk + here->B2sNode) += m * (here->B2sourceConductance) * *(ckt->CKTrhsOld + here->B2sNode) ;
|
||||||
|
*(ckt->CKTfvk + here->B2dNodePrime) += m * (here->B2drainConductance) * *(ckt->CKTrhsOld + here->B2dNodePrime) ;
|
||||||
|
*(ckt->CKTfvk + here->B2sNodePrime) += m * (here->B2sourceConductance) * *(ckt->CKTrhsOld + here->B2sNodePrime) ;
|
||||||
|
*(ckt->CKTfvk + here->B2dNode) += m * (-here->B2drainConductance) * *(ckt->CKTrhsOld + here->B2dNodePrime) ;
|
||||||
|
*(ckt->CKTfvk + here->B2sNode) += m * (-here->B2sourceConductance) * *(ckt->CKTrhsOld + here->B2sNodePrime) ;
|
||||||
|
*(ckt->CKTfvk + here->B2dNodePrime) += m * (-here->B2drainConductance) * *(ckt->CKTrhsOld + here->B2dNode) ;
|
||||||
|
*(ckt->CKTfvk + here->B2sNodePrime) += m * (-here->B2sourceConductance) * *(ckt->CKTrhsOld + here->B2sNode) ;
|
||||||
|
#endif
|
||||||
|
|
||||||
line1000: ;
|
line1000: ;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
/**********
|
||||||
|
Author: 2013 Francesco Lannutti
|
||||||
|
**********/
|
||||||
|
|
||||||
|
#include "ngspice/ngspice.h"
|
||||||
|
#include "ngspice/cktdefs.h"
|
||||||
|
#include "bsim2def.h"
|
||||||
|
#include "ngspice/sperror.h"
|
||||||
|
|
||||||
|
int
|
||||||
|
B2nodeIsNonLinear (GENmodel *inModel, CKTcircuit *ckt)
|
||||||
|
{
|
||||||
|
B2model *model = (B2model *)inModel ;
|
||||||
|
B2instance *here ;
|
||||||
|
|
||||||
|
/* loop through all the BSIM2 models */
|
||||||
|
for ( ; model != NULL ; model = model->B2nextModel)
|
||||||
|
{
|
||||||
|
/* loop through all the instances of the model */
|
||||||
|
for (here = model->B2instances ; here != NULL ; here = here->B2nextInstance)
|
||||||
|
{
|
||||||
|
ckt->CKTnodeIsLinear [here->B2dNodePrime] = 0 ;
|
||||||
|
ckt->CKTnodeIsLinear [here->B2sNodePrime] = 0 ;
|
||||||
|
ckt->CKTnodeIsLinear [here->B2gNode] = 0 ;
|
||||||
|
ckt->CKTnodeIsLinear [here->B2bNode] = 0 ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (OK) ;
|
||||||
|
}
|
||||||
|
|
@ -535,32 +535,32 @@ B2setup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states)
|
||||||
|
|
||||||
/* macro to make elements with built in test for out of memory */
|
/* macro to make elements with built in test for out of memory */
|
||||||
#define TSTALLOC(ptr,first,second) \
|
#define TSTALLOC(ptr,first,second) \
|
||||||
if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\
|
do { if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\
|
||||||
return(E_NOMEM);\
|
return(E_NOMEM);\
|
||||||
}
|
} } while(0)
|
||||||
|
|
||||||
TSTALLOC(B2DdPtr, B2dNode, B2dNode)
|
TSTALLOC(B2DdPtr, B2dNode, B2dNode);
|
||||||
TSTALLOC(B2GgPtr, B2gNode, B2gNode)
|
TSTALLOC(B2GgPtr, B2gNode, B2gNode);
|
||||||
TSTALLOC(B2SsPtr, B2sNode, B2sNode)
|
TSTALLOC(B2SsPtr, B2sNode, B2sNode);
|
||||||
TSTALLOC(B2BbPtr, B2bNode, B2bNode)
|
TSTALLOC(B2BbPtr, B2bNode, B2bNode);
|
||||||
TSTALLOC(B2DPdpPtr, B2dNodePrime, B2dNodePrime)
|
TSTALLOC(B2DPdpPtr, B2dNodePrime, B2dNodePrime);
|
||||||
TSTALLOC(B2SPspPtr, B2sNodePrime, B2sNodePrime)
|
TSTALLOC(B2SPspPtr, B2sNodePrime, B2sNodePrime);
|
||||||
TSTALLOC(B2DdpPtr, B2dNode, B2dNodePrime)
|
TSTALLOC(B2DdpPtr, B2dNode, B2dNodePrime);
|
||||||
TSTALLOC(B2GbPtr, B2gNode, B2bNode)
|
TSTALLOC(B2GbPtr, B2gNode, B2bNode);
|
||||||
TSTALLOC(B2GdpPtr, B2gNode, B2dNodePrime)
|
TSTALLOC(B2GdpPtr, B2gNode, B2dNodePrime);
|
||||||
TSTALLOC(B2GspPtr, B2gNode, B2sNodePrime)
|
TSTALLOC(B2GspPtr, B2gNode, B2sNodePrime);
|
||||||
TSTALLOC(B2SspPtr, B2sNode, B2sNodePrime)
|
TSTALLOC(B2SspPtr, B2sNode, B2sNodePrime);
|
||||||
TSTALLOC(B2BdpPtr, B2bNode, B2dNodePrime)
|
TSTALLOC(B2BdpPtr, B2bNode, B2dNodePrime);
|
||||||
TSTALLOC(B2BspPtr, B2bNode, B2sNodePrime)
|
TSTALLOC(B2BspPtr, B2bNode, B2sNodePrime);
|
||||||
TSTALLOC(B2DPspPtr, B2dNodePrime, B2sNodePrime)
|
TSTALLOC(B2DPspPtr, B2dNodePrime, B2sNodePrime);
|
||||||
TSTALLOC(B2DPdPtr, B2dNodePrime, B2dNode)
|
TSTALLOC(B2DPdPtr, B2dNodePrime, B2dNode);
|
||||||
TSTALLOC(B2BgPtr, B2bNode, B2gNode)
|
TSTALLOC(B2BgPtr, B2bNode, B2gNode);
|
||||||
TSTALLOC(B2DPgPtr, B2dNodePrime, B2gNode)
|
TSTALLOC(B2DPgPtr, B2dNodePrime, B2gNode);
|
||||||
TSTALLOC(B2SPgPtr, B2sNodePrime, B2gNode)
|
TSTALLOC(B2SPgPtr, B2sNodePrime, B2gNode);
|
||||||
TSTALLOC(B2SPsPtr, B2sNodePrime, B2sNode)
|
TSTALLOC(B2SPsPtr, B2sNodePrime, B2sNode);
|
||||||
TSTALLOC(B2DPbPtr, B2dNodePrime, B2bNode)
|
TSTALLOC(B2DPbPtr, B2dNodePrime, B2bNode);
|
||||||
TSTALLOC(B2SPbPtr, B2sNodePrime, B2bNode)
|
TSTALLOC(B2SPbPtr, B2sNodePrime, B2bNode);
|
||||||
TSTALLOC(B2SPdpPtr, B2sNodePrime, B2dNodePrime)
|
TSTALLOC(B2SPdpPtr, B2sNodePrime, B2dNodePrime);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,3 +31,7 @@ extern int B2bindCSC (GENmodel*, CKTcircuit*) ;
|
||||||
extern int B2bindCSCComplex (GENmodel*, CKTcircuit*) ;
|
extern int B2bindCSCComplex (GENmodel*, CKTcircuit*) ;
|
||||||
extern int B2bindCSCComplexToReal (GENmodel*, CKTcircuit*) ;
|
extern int B2bindCSCComplexToReal (GENmodel*, CKTcircuit*) ;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef KIRCHHOFF
|
||||||
|
extern int B2nodeIsNonLinear (GENmodel *, CKTcircuit *) ;
|
||||||
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -73,12 +73,17 @@ SPICEdev B2info = {
|
||||||
#endif
|
#endif
|
||||||
/* DEVinstSize */ &B2iSize,
|
/* DEVinstSize */ &B2iSize,
|
||||||
/* DEVmodSize */ &B2mSize,
|
/* DEVmodSize */ &B2mSize,
|
||||||
|
|
||||||
#if defined(KLU) || defined(SuperLU) || defined(UMFPACK)
|
#if defined(KLU) || defined(SuperLU) || defined(UMFPACK)
|
||||||
/* DEVbindCSC */ B2bindCSC,
|
/* DEVbindCSC */ B2bindCSC,
|
||||||
/* DEVbindCSCComplex */ B2bindCSCComplex,
|
/* DEVbindCSCComplex */ B2bindCSCComplex,
|
||||||
/* DEVbindCSCComplexToReal */ B2bindCSCComplexToReal,
|
/* DEVbindCSCComplexToReal */ B2bindCSCComplexToReal,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef KIRCHHOFF
|
||||||
|
/* DEVnodeIsNonLinear */ B2nodeIsNonLinear
|
||||||
|
#endif
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,10 @@ if UMFPACK_WANTED
|
||||||
libbsim3_la_SOURCES += b3bindCSC.c
|
libbsim3_la_SOURCES += b3bindCSC.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if KIRCHHOFF_WANTED
|
||||||
|
libbsim3_la_SOURCES += b3node.c
|
||||||
|
endif
|
||||||
|
|
||||||
AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(top_srcdir)/src/include
|
AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(top_srcdir)/src/include
|
||||||
AM_CFLAGS = $(STATIC)
|
AM_CFLAGS = $(STATIC)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,44 +26,50 @@ IOP( "nrs", BSIM3_NRS, IF_REAL , "Number of squares in source"),
|
||||||
IOP( "off", BSIM3_OFF, IF_FLAG , "Device is initially off"),
|
IOP( "off", BSIM3_OFF, IF_FLAG , "Device is initially off"),
|
||||||
IOP( "nqsmod", BSIM3_NQSMOD, IF_INTEGER, "Non-quasi-static model selector"),
|
IOP( "nqsmod", BSIM3_NQSMOD, IF_INTEGER, "Non-quasi-static model selector"),
|
||||||
IOP( "acnqsmod", BSIM3_ACNQSMOD, IF_INTEGER, "AC NQS model selector"),
|
IOP( "acnqsmod", BSIM3_ACNQSMOD, IF_INTEGER, "AC NQS model selector"),
|
||||||
|
IOP( "geo", BSIM3_GEO, IF_INTEGER, "ACM model drain/source connection"),
|
||||||
|
IOP( "delvto", BSIM3_DELVTO, IF_REAL, "Zero bias threshold voltage variation"),
|
||||||
|
IOP( "mulu0", BSIM3_MULU0, IF_REAL, "Low field mobility multiplier"),
|
||||||
IP( "ic", BSIM3_IC, IF_REALVEC , "Vector of DS,GS,BS initial voltages"),
|
IP( "ic", BSIM3_IC, IF_REALVEC , "Vector of DS,GS,BS initial voltages"),
|
||||||
OP( "gmbs", BSIM3_GMBS, IF_REAL, "Gmb"),
|
OP( "gmbs", BSIM3_GMBS, IF_REAL, "Gmb"),
|
||||||
OP( "gm", BSIM3_GM, IF_REAL, "Gm"),
|
OP( "gm", BSIM3_GM, IF_REAL, "Gm"),
|
||||||
OP( "gds", BSIM3_GDS, IF_REAL, "Gds"),
|
OP( "gds", BSIM3_GDS, IF_REAL, "Gds"),
|
||||||
OP( "vdsat", BSIM3_VDSAT, IF_REAL, "Vdsat"),
|
OP( "vdsat", BSIM3_VDSAT, IF_REAL, "Vdsat"),
|
||||||
OP( "vth", BSIM3_VON, IF_REAL, "Vth"),
|
OP( "vth", BSIM3_VON, IF_REAL, "Vth"),
|
||||||
OP( "id", BSIM3_CD, IF_REAL, "Ids"),
|
OP( "id", BSIM3_CD, IF_REAL, "Ids"),
|
||||||
OP( "vbs", BSIM3_VBS, IF_REAL, "Vbs"),
|
OP( "vbs", BSIM3_VBS, IF_REAL, "Vbs"),
|
||||||
OP( "vgs", BSIM3_VGS, IF_REAL, "Vgs"),
|
OP( "vgs", BSIM3_VGS, IF_REAL, "Vgs"),
|
||||||
OP( "vds", BSIM3_VDS, IF_REAL, "Vds"),
|
OP( "vds", BSIM3_VDS, IF_REAL, "Vds"),
|
||||||
OP( "ibd", BSIM3_CBD, IF_REAL, "Ibd"), /* newly added from here */
|
OP( "ibd", BSIM3_CBD, IF_REAL, "Ibd"), /* newly added from here */
|
||||||
OP( "ibs", BSIM3_CBS, IF_REAL, "Ibs"),
|
OP( "ibs", BSIM3_CBS, IF_REAL, "Ibs"),
|
||||||
OP( "gbd", BSIM3_GBD, IF_REAL, "gbd"),
|
OP( "gbd", BSIM3_GBD, IF_REAL, "gbd"),
|
||||||
OP( "gbs", BSIM3_GBS, IF_REAL, "gbs"),
|
OP( "gbs", BSIM3_GBS, IF_REAL, "gbs"),
|
||||||
OP( "qb", BSIM3_QB, IF_REAL, "Qbulk"),
|
OP( "qb", BSIM3_QB, IF_REAL, "Qbulk"),
|
||||||
OP( "cqb", BSIM3_CQB, IF_REAL, "CQbulk"),
|
OP( "cqb", BSIM3_CQB, IF_REAL, "CQbulk"),
|
||||||
OP( "qg", BSIM3_QG, IF_REAL, "Qgate"),
|
OP( "qg", BSIM3_QG, IF_REAL, "Qgate"),
|
||||||
OP( "cqg", BSIM3_CQG, IF_REAL, "CQgate"),
|
OP( "cqg", BSIM3_CQG, IF_REAL, "CQgate"),
|
||||||
OP( "qd", BSIM3_QD, IF_REAL, "Qdrain"),
|
OP( "qd", BSIM3_QD, IF_REAL, "Qdrain"),
|
||||||
OP( "cqd", BSIM3_CQD, IF_REAL, "CQdrain"),
|
OP( "cqd", BSIM3_CQD, IF_REAL, "CQdrain"),
|
||||||
OP( "cgg", BSIM3_CGG, IF_REAL, "Cggb"),
|
OP( "cgg", BSIM3_CGG, IF_REAL, "Cggb"),
|
||||||
OP( "cgd", BSIM3_CGD, IF_REAL, "Cgdb"),
|
OP( "cgd", BSIM3_CGD, IF_REAL, "Cgdb"),
|
||||||
OP( "cgs", BSIM3_CGS, IF_REAL, "Cgsb"),
|
OP( "cgs", BSIM3_CGS, IF_REAL, "Cgsb"),
|
||||||
OP( "cdg", BSIM3_CDG, IF_REAL, "Cdgb"),
|
OP( "cdg", BSIM3_CDG, IF_REAL, "Cdgb"),
|
||||||
OP( "cdd", BSIM3_CDD, IF_REAL, "Cddb"),
|
OP( "cdd", BSIM3_CDD, IF_REAL, "Cddb"),
|
||||||
OP( "cds", BSIM3_CDS, IF_REAL, "Cdsb"),
|
OP( "cds", BSIM3_CDS, IF_REAL, "Cdsb"),
|
||||||
OP( "cbg", BSIM3_CBG, IF_REAL, "Cbgb"),
|
OP( "cbg", BSIM3_CBG, IF_REAL, "Cbgb"),
|
||||||
OP( "cbd", BSIM3_CBDB, IF_REAL, "Cbdb"),
|
OP( "cbd", BSIM3_CBDB, IF_REAL, "Cbdb"),
|
||||||
OP( "cbs", BSIM3_CBSB, IF_REAL, "Cbsb"),
|
OP( "cbs", BSIM3_CBSB, IF_REAL, "Cbsb"),
|
||||||
OP( "capbd", BSIM3_CAPBD, IF_REAL, "Capbd"),
|
OP( "capbd", BSIM3_CAPBD, IF_REAL, "Capbd"),
|
||||||
OP( "capbs", BSIM3_CAPBS, IF_REAL, "Capbs"),
|
OP( "capbs", BSIM3_CAPBS, IF_REAL, "Capbs"),
|
||||||
};
|
};
|
||||||
|
|
||||||
IFparm BSIM3mPTable[] = { /* model parameters */
|
IFparm BSIM3mPTable[] = { /* model parameters */
|
||||||
IOP( "capmod", BSIM3_MOD_CAPMOD, IF_INTEGER, "Capacitance model selector"),
|
IOP( "capmod", BSIM3_MOD_CAPMOD, IF_INTEGER, "Capacitance model selector"),
|
||||||
IOP( "mobmod", BSIM3_MOD_MOBMOD, IF_INTEGER, "Mobility model selector"),
|
IOP( "mobmod", BSIM3_MOD_MOBMOD, IF_INTEGER, "Mobility model selector"),
|
||||||
IOP( "noimod", BSIM3_MOD_NOIMOD, IF_INTEGER, "Noise model selector"),
|
IOP( "noimod", BSIM3_MOD_NOIMOD, IF_INTEGER, "Noise model selector"),
|
||||||
|
IOP( "nqsmod", BSIM3_MOD_NQSMOD, IF_INTEGER, "Non-quasi-static model selector"),
|
||||||
IOP( "acnqsmod", BSIM3_MOD_ACNQSMOD, IF_INTEGER, "AC NQS model selector"),
|
IOP( "acnqsmod", BSIM3_MOD_ACNQSMOD, IF_INTEGER, "AC NQS model selector"),
|
||||||
|
IOP( "acm", BSIM3_MOD_ACMMOD, IF_INTEGER, "Area calculation method selector"),
|
||||||
|
IOP( "calcacm", BSIM3_MOD_CALCACM, IF_INTEGER, "Area calculation method ACM=12"),
|
||||||
IOP( "paramchk", BSIM3_MOD_PARAMCHK, IF_INTEGER, "Model parameter checking selector"),
|
IOP( "paramchk", BSIM3_MOD_PARAMCHK, IF_INTEGER, "Model parameter checking selector"),
|
||||||
IOP( "binunit", BSIM3_MOD_BINUNIT, IF_INTEGER, "Bin unit selector"),
|
IOP( "binunit", BSIM3_MOD_BINUNIT, IF_INTEGER, "Bin unit selector"),
|
||||||
IOP( "version", BSIM3_MOD_VERSION, IF_STRING, " parameter for model version"),
|
IOP( "version", BSIM3_MOD_VERSION, IF_STRING, " parameter for model version"),
|
||||||
|
|
@ -71,15 +77,15 @@ IOP( "tox", BSIM3_MOD_TOX, IF_REAL, "Gate oxide thickness in meters"),
|
||||||
|
|
||||||
IOP( "toxm", BSIM3_MOD_TOXM, IF_REAL, "Gate oxide thickness used in extraction"),
|
IOP( "toxm", BSIM3_MOD_TOXM, IF_REAL, "Gate oxide thickness used in extraction"),
|
||||||
IOP( "cdsc", BSIM3_MOD_CDSC, IF_REAL, "Drain/Source and channel coupling capacitance"),
|
IOP( "cdsc", BSIM3_MOD_CDSC, IF_REAL, "Drain/Source and channel coupling capacitance"),
|
||||||
IOP( "cdscb", BSIM3_MOD_CDSCB, IF_REAL, "Body-bias dependence of cdsc"),
|
IOP( "cdscb", BSIM3_MOD_CDSCB, IF_REAL, "Body-bias dependence of cdsc"),
|
||||||
IOP( "cdscd", BSIM3_MOD_CDSCD, IF_REAL, "Drain-bias dependence of cdsc"),
|
IOP( "cdscd", BSIM3_MOD_CDSCD, IF_REAL, "Drain-bias dependence of cdsc"),
|
||||||
IOP( "cit", BSIM3_MOD_CIT, IF_REAL, "Interface state capacitance"),
|
IOP( "cit", BSIM3_MOD_CIT, IF_REAL, "Interface state capacitance"),
|
||||||
IOP( "nfactor", BSIM3_MOD_NFACTOR, IF_REAL, "Subthreshold swing Coefficient"),
|
IOP( "nfactor", BSIM3_MOD_NFACTOR, IF_REAL, "Subthreshold swing Coefficient"),
|
||||||
IOP( "xj", BSIM3_MOD_XJ, IF_REAL, "Junction depth in meters"),
|
IOP( "xj", BSIM3_MOD_XJ, IF_REAL, "Junction depth in meters"),
|
||||||
IOP( "vsat", BSIM3_MOD_VSAT, IF_REAL, "Saturation velocity at tnom"),
|
IOP( "vsat", BSIM3_MOD_VSAT, IF_REAL, "Saturation velocity at tnom"),
|
||||||
IOP( "at", BSIM3_MOD_AT, IF_REAL, "Temperature coefficient of vsat"),
|
IOP( "at", BSIM3_MOD_AT, IF_REAL, "Temperature coefficient of vsat"),
|
||||||
IOP( "a0", BSIM3_MOD_A0, IF_REAL, "Non-uniform depletion width effect coefficient."),
|
IOP( "a0", BSIM3_MOD_A0, IF_REAL, "Non-uniform depletion width effect coefficient."),
|
||||||
IOP( "ags", BSIM3_MOD_AGS, IF_REAL, "Gate bias coefficient of Abulk."),
|
IOP( "ags", BSIM3_MOD_AGS, IF_REAL, "Gate bias coefficient of Abulk."),
|
||||||
IOP( "a1", BSIM3_MOD_A1, IF_REAL, "Non-saturation effect coefficient"),
|
IOP( "a1", BSIM3_MOD_A1, IF_REAL, "Non-saturation effect coefficient"),
|
||||||
IOP( "a2", BSIM3_MOD_A2, IF_REAL, "Non-saturation effect coefficient"),
|
IOP( "a2", BSIM3_MOD_A2, IF_REAL, "Non-saturation effect coefficient"),
|
||||||
IOP( "keta", BSIM3_MOD_KETA, IF_REAL, "Body-bias coefficient of non-uniform depletion width effect."),
|
IOP( "keta", BSIM3_MOD_KETA, IF_REAL, "Body-bias coefficient of non-uniform depletion width effect."),
|
||||||
|
|
@ -128,21 +134,21 @@ IOP( "xpart", BSIM3_MOD_XPART, IF_REAL, "Channel charge partitioning"),
|
||||||
IOP( "elm", BSIM3_MOD_ELM, IF_REAL, "Non-quasi-static Elmore Constant Parameter"),
|
IOP( "elm", BSIM3_MOD_ELM, IF_REAL, "Non-quasi-static Elmore Constant Parameter"),
|
||||||
IOP( "delta", BSIM3_MOD_DELTA, IF_REAL, "Effective Vds parameter"),
|
IOP( "delta", BSIM3_MOD_DELTA, IF_REAL, "Effective Vds parameter"),
|
||||||
IOP( "rsh", BSIM3_MOD_RSH, IF_REAL, "Source-drain sheet resistance"),
|
IOP( "rsh", BSIM3_MOD_RSH, IF_REAL, "Source-drain sheet resistance"),
|
||||||
IOP( "rdsw", BSIM3_MOD_RDSW, IF_REAL, "Source-drain resistance per width"),
|
IOP( "rdsw", BSIM3_MOD_RDSW, IF_REAL, "Source-drain resistance per width"),
|
||||||
|
|
||||||
IOP( "prwg", BSIM3_MOD_PRWG, IF_REAL, "Gate-bias effect on parasitic resistance "),
|
IOP( "prwg", BSIM3_MOD_PRWG, IF_REAL, "Gate-bias effect on parasitic resistance "),
|
||||||
IOP( "prwb", BSIM3_MOD_PRWB, IF_REAL, "Body-effect on parasitic resistance "),
|
IOP( "prwb", BSIM3_MOD_PRWB, IF_REAL, "Body-effect on parasitic resistance "),
|
||||||
|
|
||||||
IOP( "prt", BSIM3_MOD_PRT, IF_REAL, "Temperature coefficient of parasitic resistance "),
|
IOP( "prt", BSIM3_MOD_PRT, IF_REAL, "Temperature coefficient of parasitic resistance "),
|
||||||
IOP( "eta0", BSIM3_MOD_ETA0, IF_REAL, "Subthreshold region DIBL coefficient"),
|
IOP( "eta0", BSIM3_MOD_ETA0, IF_REAL, "Subthreshold region DIBL coefficient"),
|
||||||
IOP( "etab", BSIM3_MOD_ETAB, IF_REAL, "Subthreshold region DIBL coefficient"),
|
IOP( "etab", BSIM3_MOD_ETAB, IF_REAL, "Subthreshold region DIBL coefficient"),
|
||||||
IOP( "pclm", BSIM3_MOD_PCLM, IF_REAL, "Channel length modulation Coefficient"),
|
IOP( "pclm", BSIM3_MOD_PCLM, IF_REAL, "Channel length modulation Coefficient"),
|
||||||
IOP( "pdiblc1", BSIM3_MOD_PDIBL1, IF_REAL, "Drain-induced barrier lowering coefficient"),
|
IOP( "pdiblc1", BSIM3_MOD_PDIBL1, IF_REAL, "Drain-induced barrier lowering coefficient"),
|
||||||
IOP( "pdiblc2", BSIM3_MOD_PDIBL2, IF_REAL, "Drain-induced barrier lowering coefficient"),
|
IOP( "pdiblc2", BSIM3_MOD_PDIBL2, IF_REAL, "Drain-induced barrier lowering coefficient"),
|
||||||
IOP( "pdiblcb", BSIM3_MOD_PDIBLB, IF_REAL, "Body-effect on drain-induced barrier lowering"),
|
IOP( "pdiblcb", BSIM3_MOD_PDIBLB, IF_REAL, "Body-effect on drain-induced barrier lowering"),
|
||||||
IOP( "pscbe1", BSIM3_MOD_PSCBE1, IF_REAL, "Substrate current body-effect coefficient"),
|
IOP( "pscbe1", BSIM3_MOD_PSCBE1, IF_REAL, "Substrate current body-effect coefficient"),
|
||||||
IOP( "pscbe2", BSIM3_MOD_PSCBE2, IF_REAL, "Substrate current body-effect coefficient"),
|
IOP( "pscbe2", BSIM3_MOD_PSCBE2, IF_REAL, "Substrate current body-effect coefficient"),
|
||||||
IOP( "pvag", BSIM3_MOD_PVAG, IF_REAL, "Gate dependence of output resistance parameter"),
|
IOP( "pvag", BSIM3_MOD_PVAG, IF_REAL, "Gate dependence of output resistance parameter"),
|
||||||
IOP( "js", BSIM3_MOD_JS, IF_REAL, "Source/drain junction reverse saturation current density"),
|
IOP( "js", BSIM3_MOD_JS, IF_REAL, "Source/drain junction reverse saturation current density"),
|
||||||
IOP( "jsw", BSIM3_MOD_JSW, IF_REAL, "Sidewall junction reverse saturation current density"),
|
IOP( "jsw", BSIM3_MOD_JSW, IF_REAL, "Sidewall junction reverse saturation current density"),
|
||||||
IOP( "pb", BSIM3_MOD_PB, IF_REAL, "Source/drain junction built-in potential"),
|
IOP( "pb", BSIM3_MOD_PB, IF_REAL, "Source/drain junction built-in potential"),
|
||||||
|
|
@ -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"),
|
||||||
|
|
@ -221,8 +240,8 @@ IOP( "lnfactor", BSIM3_MOD_LNFACTOR, IF_REAL, "Length dependence of nfactor"),
|
||||||
IOP( "lxj", BSIM3_MOD_LXJ, IF_REAL, "Length dependence of xj"),
|
IOP( "lxj", BSIM3_MOD_LXJ, IF_REAL, "Length dependence of xj"),
|
||||||
IOP( "lvsat", BSIM3_MOD_LVSAT, IF_REAL, "Length dependence of vsat"),
|
IOP( "lvsat", BSIM3_MOD_LVSAT, IF_REAL, "Length dependence of vsat"),
|
||||||
IOP( "lat", BSIM3_MOD_LAT, IF_REAL, "Length dependence of at"),
|
IOP( "lat", BSIM3_MOD_LAT, IF_REAL, "Length dependence of at"),
|
||||||
IOP( "la0", BSIM3_MOD_LA0, IF_REAL, "Length dependence of a0"),
|
IOP( "la0", BSIM3_MOD_LA0, IF_REAL, "Length dependence of a0"),
|
||||||
IOP( "lags", BSIM3_MOD_LAGS, IF_REAL, "Length dependence of ags"),
|
IOP( "lags", BSIM3_MOD_LAGS, IF_REAL, "Length dependence of ags"),
|
||||||
IOP( "la1", BSIM3_MOD_LA1, IF_REAL, "Length dependence of a1"),
|
IOP( "la1", BSIM3_MOD_LA1, IF_REAL, "Length dependence of a1"),
|
||||||
IOP( "la2", BSIM3_MOD_LA2, IF_REAL, "Length dependence of a2"),
|
IOP( "la2", BSIM3_MOD_LA2, IF_REAL, "Length dependence of a2"),
|
||||||
IOP( "lketa", BSIM3_MOD_LKETA, IF_REAL, "Length dependence of keta"),
|
IOP( "lketa", BSIM3_MOD_LKETA, IF_REAL, "Length dependence of keta"),
|
||||||
|
|
@ -264,21 +283,21 @@ IOP( "lute", BSIM3_MOD_LUTE, IF_REAL, "Length dependence of ute"),
|
||||||
IOP( "lvoff", BSIM3_MOD_LVOFF, IF_REAL, "Length dependence of voff"),
|
IOP( "lvoff", BSIM3_MOD_LVOFF, IF_REAL, "Length dependence of voff"),
|
||||||
IOP( "lelm", BSIM3_MOD_LELM, IF_REAL, "Length dependence of elm"),
|
IOP( "lelm", BSIM3_MOD_LELM, IF_REAL, "Length dependence of elm"),
|
||||||
IOP( "ldelta", BSIM3_MOD_LDELTA, IF_REAL, "Length dependence of delta"),
|
IOP( "ldelta", BSIM3_MOD_LDELTA, IF_REAL, "Length dependence of delta"),
|
||||||
IOP( "lrdsw", BSIM3_MOD_LRDSW, IF_REAL, "Length dependence of rdsw "),
|
IOP( "lrdsw", BSIM3_MOD_LRDSW, IF_REAL, "Length dependence of rdsw "),
|
||||||
|
|
||||||
IOP( "lprwg", BSIM3_MOD_LPRWG, IF_REAL, "Length dependence of prwg "),
|
IOP( "lprwg", BSIM3_MOD_LPRWG, IF_REAL, "Length dependence of prwg "),
|
||||||
IOP( "lprwb", BSIM3_MOD_LPRWB, IF_REAL, "Length dependence of prwb "),
|
IOP( "lprwb", BSIM3_MOD_LPRWB, IF_REAL, "Length dependence of prwb "),
|
||||||
|
|
||||||
IOP( "lprt", BSIM3_MOD_LPRT, IF_REAL, "Length dependence of prt "),
|
IOP( "lprt", BSIM3_MOD_LPRT, IF_REAL, "Length dependence of prt "),
|
||||||
IOP( "leta0", BSIM3_MOD_LETA0, IF_REAL, "Length dependence of eta0"),
|
IOP( "leta0", BSIM3_MOD_LETA0, IF_REAL, "Length dependence of eta0"),
|
||||||
IOP( "letab", BSIM3_MOD_LETAB, IF_REAL, "Length dependence of etab"),
|
IOP( "letab", BSIM3_MOD_LETAB, IF_REAL, "Length dependence of etab"),
|
||||||
IOP( "lpclm", BSIM3_MOD_LPCLM, IF_REAL, "Length dependence of pclm"),
|
IOP( "lpclm", BSIM3_MOD_LPCLM, IF_REAL, "Length dependence of pclm"),
|
||||||
IOP( "lpdiblc1", BSIM3_MOD_LPDIBL1, IF_REAL, "Length dependence of pdiblc1"),
|
IOP( "lpdiblc1", BSIM3_MOD_LPDIBL1, IF_REAL, "Length dependence of pdiblc1"),
|
||||||
IOP( "lpdiblc2", BSIM3_MOD_LPDIBL2, IF_REAL, "Length dependence of pdiblc2"),
|
IOP( "lpdiblc2", BSIM3_MOD_LPDIBL2, IF_REAL, "Length dependence of pdiblc2"),
|
||||||
IOP( "lpdiblcb", BSIM3_MOD_LPDIBLB, IF_REAL, "Length dependence of pdiblcb"),
|
IOP( "lpdiblcb", BSIM3_MOD_LPDIBLB, IF_REAL, "Length dependence of pdiblcb"),
|
||||||
IOP( "lpscbe1", BSIM3_MOD_LPSCBE1, IF_REAL, "Length dependence of pscbe1"),
|
IOP( "lpscbe1", BSIM3_MOD_LPSCBE1, IF_REAL, "Length dependence of pscbe1"),
|
||||||
IOP( "lpscbe2", BSIM3_MOD_LPSCBE2, IF_REAL, "Length dependence of pscbe2"),
|
IOP( "lpscbe2", BSIM3_MOD_LPSCBE2, IF_REAL, "Length dependence of pscbe2"),
|
||||||
IOP( "lpvag", BSIM3_MOD_LPVAG, IF_REAL, "Length dependence of pvag"),
|
IOP( "lpvag", BSIM3_MOD_LPVAG, IF_REAL, "Length dependence of pvag"),
|
||||||
IOP( "lwr", BSIM3_MOD_LWR, IF_REAL, "Length dependence of wr"),
|
IOP( "lwr", BSIM3_MOD_LWR, IF_REAL, "Length dependence of wr"),
|
||||||
IOP( "ldwg", BSIM3_MOD_LDWG, IF_REAL, "Length dependence of dwg"),
|
IOP( "ldwg", BSIM3_MOD_LDWG, IF_REAL, "Length dependence of dwg"),
|
||||||
IOP( "ldwb", BSIM3_MOD_LDWB, IF_REAL, "Length dependence of dwb"),
|
IOP( "ldwb", BSIM3_MOD_LDWB, IF_REAL, "Length dependence of dwb"),
|
||||||
|
|
@ -300,15 +319,15 @@ IOP( "lmoin", BSIM3_MOD_LMOIN, IF_REAL, "Length dependence of moin"),
|
||||||
IOP( "lnoff", BSIM3_MOD_LNOFF, IF_REAL, "Length dependence of noff"),
|
IOP( "lnoff", BSIM3_MOD_LNOFF, IF_REAL, "Length dependence of noff"),
|
||||||
IOP( "lvoffcv", BSIM3_MOD_LVOFFCV, IF_REAL, "Length dependence of voffcv"),
|
IOP( "lvoffcv", BSIM3_MOD_LVOFFCV, IF_REAL, "Length dependence of voffcv"),
|
||||||
IOP( "wcdsc", BSIM3_MOD_WCDSC, IF_REAL, "Width dependence of cdsc"),
|
IOP( "wcdsc", BSIM3_MOD_WCDSC, IF_REAL, "Width dependence of cdsc"),
|
||||||
IOP( "wcdscb", BSIM3_MOD_WCDSCB, IF_REAL, "Width dependence of cdscb"),
|
IOP( "wcdscb", BSIM3_MOD_WCDSCB, IF_REAL, "Width dependence of cdscb"),
|
||||||
IOP( "wcdscd", BSIM3_MOD_WCDSCD, IF_REAL, "Width dependence of cdscd"),
|
IOP( "wcdscd", BSIM3_MOD_WCDSCD, IF_REAL, "Width dependence of cdscd"),
|
||||||
IOP( "wcit", BSIM3_MOD_WCIT, IF_REAL, "Width dependence of cit"),
|
IOP( "wcit", BSIM3_MOD_WCIT, IF_REAL, "Width dependence of cit"),
|
||||||
IOP( "wnfactor", BSIM3_MOD_WNFACTOR, IF_REAL, "Width dependence of nfactor"),
|
IOP( "wnfactor", BSIM3_MOD_WNFACTOR, IF_REAL, "Width dependence of nfactor"),
|
||||||
IOP( "wxj", BSIM3_MOD_WXJ, IF_REAL, "Width dependence of xj"),
|
IOP( "wxj", BSIM3_MOD_WXJ, IF_REAL, "Width dependence of xj"),
|
||||||
IOP( "wvsat", BSIM3_MOD_WVSAT, IF_REAL, "Width dependence of vsat"),
|
IOP( "wvsat", BSIM3_MOD_WVSAT, IF_REAL, "Width dependence of vsat"),
|
||||||
IOP( "wat", BSIM3_MOD_WAT, IF_REAL, "Width dependence of at"),
|
IOP( "wat", BSIM3_MOD_WAT, IF_REAL, "Width dependence of at"),
|
||||||
IOP( "wa0", BSIM3_MOD_WA0, IF_REAL, "Width dependence of a0"),
|
IOP( "wa0", BSIM3_MOD_WA0, IF_REAL, "Width dependence of a0"),
|
||||||
IOP( "wags", BSIM3_MOD_WAGS, IF_REAL, "Width dependence of ags"),
|
IOP( "wags", BSIM3_MOD_WAGS, IF_REAL, "Width dependence of ags"),
|
||||||
IOP( "wa1", BSIM3_MOD_WA1, IF_REAL, "Width dependence of a1"),
|
IOP( "wa1", BSIM3_MOD_WA1, IF_REAL, "Width dependence of a1"),
|
||||||
IOP( "wa2", BSIM3_MOD_WA2, IF_REAL, "Width dependence of a2"),
|
IOP( "wa2", BSIM3_MOD_WA2, IF_REAL, "Width dependence of a2"),
|
||||||
IOP( "wketa", BSIM3_MOD_WKETA, IF_REAL, "Width dependence of keta"),
|
IOP( "wketa", BSIM3_MOD_WKETA, IF_REAL, "Width dependence of keta"),
|
||||||
|
|
@ -356,15 +375,15 @@ IOP( "wprwg", BSIM3_MOD_WPRWG, IF_REAL, "Width dependence of prwg "),
|
||||||
IOP( "wprwb", BSIM3_MOD_WPRWB, IF_REAL, "Width dependence of prwb "),
|
IOP( "wprwb", BSIM3_MOD_WPRWB, IF_REAL, "Width dependence of prwb "),
|
||||||
|
|
||||||
IOP( "wprt", BSIM3_MOD_WPRT, IF_REAL, "Width dependence of prt"),
|
IOP( "wprt", BSIM3_MOD_WPRT, IF_REAL, "Width dependence of prt"),
|
||||||
IOP( "weta0", BSIM3_MOD_WETA0, IF_REAL, "Width dependence of eta0"),
|
IOP( "weta0", BSIM3_MOD_WETA0, IF_REAL, "Width dependence of eta0"),
|
||||||
IOP( "wetab", BSIM3_MOD_WETAB, IF_REAL, "Width dependence of etab"),
|
IOP( "wetab", BSIM3_MOD_WETAB, IF_REAL, "Width dependence of etab"),
|
||||||
IOP( "wpclm", BSIM3_MOD_WPCLM, IF_REAL, "Width dependence of pclm"),
|
IOP( "wpclm", BSIM3_MOD_WPCLM, IF_REAL, "Width dependence of pclm"),
|
||||||
IOP( "wpdiblc1", BSIM3_MOD_WPDIBL1, IF_REAL, "Width dependence of pdiblc1"),
|
IOP( "wpdiblc1", BSIM3_MOD_WPDIBL1, IF_REAL, "Width dependence of pdiblc1"),
|
||||||
IOP( "wpdiblc2", BSIM3_MOD_WPDIBL2, IF_REAL, "Width dependence of pdiblc2"),
|
IOP( "wpdiblc2", BSIM3_MOD_WPDIBL2, IF_REAL, "Width dependence of pdiblc2"),
|
||||||
IOP( "wpdiblcb", BSIM3_MOD_WPDIBLB, IF_REAL, "Width dependence of pdiblcb"),
|
IOP( "wpdiblcb", BSIM3_MOD_WPDIBLB, IF_REAL, "Width dependence of pdiblcb"),
|
||||||
IOP( "wpscbe1", BSIM3_MOD_WPSCBE1, IF_REAL, "Width dependence of pscbe1"),
|
IOP( "wpscbe1", BSIM3_MOD_WPSCBE1, IF_REAL, "Width dependence of pscbe1"),
|
||||||
IOP( "wpscbe2", BSIM3_MOD_WPSCBE2, IF_REAL, "Width dependence of pscbe2"),
|
IOP( "wpscbe2", BSIM3_MOD_WPSCBE2, IF_REAL, "Width dependence of pscbe2"),
|
||||||
IOP( "wpvag", BSIM3_MOD_WPVAG, IF_REAL, "Width dependence of pvag"),
|
IOP( "wpvag", BSIM3_MOD_WPVAG, IF_REAL, "Width dependence of pvag"),
|
||||||
IOP( "wwr", BSIM3_MOD_WWR, IF_REAL, "Width dependence of wr"),
|
IOP( "wwr", BSIM3_MOD_WWR, IF_REAL, "Width dependence of wr"),
|
||||||
IOP( "wdwg", BSIM3_MOD_WDWG, IF_REAL, "Width dependence of dwg"),
|
IOP( "wdwg", BSIM3_MOD_WDWG, IF_REAL, "Width dependence of dwg"),
|
||||||
IOP( "wdwb", BSIM3_MOD_WDWB, IF_REAL, "Width dependence of dwb"),
|
IOP( "wdwb", BSIM3_MOD_WDWB, IF_REAL, "Width dependence of dwb"),
|
||||||
|
|
@ -387,14 +406,14 @@ IOP( "wnoff", BSIM3_MOD_WNOFF, IF_REAL, "Width dependence of noff"),
|
||||||
IOP( "wvoffcv", BSIM3_MOD_WVOFFCV, IF_REAL, "Width dependence of voffcv"),
|
IOP( "wvoffcv", BSIM3_MOD_WVOFFCV, IF_REAL, "Width dependence of voffcv"),
|
||||||
|
|
||||||
IOP( "pcdsc", BSIM3_MOD_PCDSC, IF_REAL, "Cross-term dependence of cdsc"),
|
IOP( "pcdsc", BSIM3_MOD_PCDSC, IF_REAL, "Cross-term dependence of cdsc"),
|
||||||
IOP( "pcdscb", BSIM3_MOD_PCDSCB, IF_REAL, "Cross-term dependence of cdscb"),
|
IOP( "pcdscb", BSIM3_MOD_PCDSCB, IF_REAL, "Cross-term dependence of cdscb"),
|
||||||
IOP( "pcdscd", BSIM3_MOD_PCDSCD, IF_REAL, "Cross-term dependence of cdscd"),
|
IOP( "pcdscd", BSIM3_MOD_PCDSCD, IF_REAL, "Cross-term dependence of cdscd"),
|
||||||
IOP( "pcit", BSIM3_MOD_PCIT, IF_REAL, "Cross-term dependence of cit"),
|
IOP( "pcit", BSIM3_MOD_PCIT, IF_REAL, "Cross-term dependence of cit"),
|
||||||
IOP( "pnfactor", BSIM3_MOD_PNFACTOR, IF_REAL, "Cross-term dependence of nfactor"),
|
IOP( "pnfactor", BSIM3_MOD_PNFACTOR, IF_REAL, "Cross-term dependence of nfactor"),
|
||||||
IOP( "pxj", BSIM3_MOD_PXJ, IF_REAL, "Cross-term dependence of xj"),
|
IOP( "pxj", BSIM3_MOD_PXJ, IF_REAL, "Cross-term dependence of xj"),
|
||||||
IOP( "pvsat", BSIM3_MOD_PVSAT, IF_REAL, "Cross-term dependence of vsat"),
|
IOP( "pvsat", BSIM3_MOD_PVSAT, IF_REAL, "Cross-term dependence of vsat"),
|
||||||
IOP( "pat", BSIM3_MOD_PAT, IF_REAL, "Cross-term dependence of at"),
|
IOP( "pat", BSIM3_MOD_PAT, IF_REAL, "Cross-term dependence of at"),
|
||||||
IOP( "pa0", BSIM3_MOD_PA0, IF_REAL, "Cross-term dependence of a0"),
|
IOP( "pa0", BSIM3_MOD_PA0, IF_REAL, "Cross-term dependence of a0"),
|
||||||
IOP( "pags", BSIM3_MOD_PAGS, IF_REAL, "Cross-term dependence of ags"),
|
IOP( "pags", BSIM3_MOD_PAGS, IF_REAL, "Cross-term dependence of ags"),
|
||||||
IOP( "pa1", BSIM3_MOD_PA1, IF_REAL, "Cross-term dependence of a1"),
|
IOP( "pa1", BSIM3_MOD_PA1, IF_REAL, "Cross-term dependence of a1"),
|
||||||
IOP( "pa2", BSIM3_MOD_PA2, IF_REAL, "Cross-term dependence of a2"),
|
IOP( "pa2", BSIM3_MOD_PA2, IF_REAL, "Cross-term dependence of a2"),
|
||||||
|
|
@ -437,10 +456,10 @@ IOP( "pute", BSIM3_MOD_PUTE, IF_REAL, "Cross-term dependence of ute"),
|
||||||
IOP( "pvoff", BSIM3_MOD_PVOFF, IF_REAL, "Cross-term dependence of voff"),
|
IOP( "pvoff", BSIM3_MOD_PVOFF, IF_REAL, "Cross-term dependence of voff"),
|
||||||
IOP( "pelm", BSIM3_MOD_PELM, IF_REAL, "Cross-term dependence of elm"),
|
IOP( "pelm", BSIM3_MOD_PELM, IF_REAL, "Cross-term dependence of elm"),
|
||||||
IOP( "pdelta", BSIM3_MOD_PDELTA, IF_REAL, "Cross-term dependence of delta"),
|
IOP( "pdelta", BSIM3_MOD_PDELTA, IF_REAL, "Cross-term dependence of delta"),
|
||||||
IOP( "prdsw", BSIM3_MOD_PRDSW, IF_REAL, "Cross-term dependence of rdsw "),
|
IOP( "prdsw", BSIM3_MOD_PRDSW, IF_REAL, "Cross-term dependence of rdsw "),
|
||||||
|
|
||||||
IOP( "pprwg", BSIM3_MOD_PPRWG, IF_REAL, "Cross-term dependence of prwg "),
|
IOP( "pprwg", BSIM3_MOD_PPRWG, IF_REAL, "Cross-term dependence of prwg "),
|
||||||
IOP( "pprwb", BSIM3_MOD_PPRWB, IF_REAL, "Cross-term dependence of prwb "),
|
IOP( "pprwb", BSIM3_MOD_PPRWB, IF_REAL, "Cross-term dependence of prwb "),
|
||||||
|
|
||||||
IOP( "pprt", BSIM3_MOD_PPRT, IF_REAL, "Cross-term dependence of prt "),
|
IOP( "pprt", BSIM3_MOD_PPRT, IF_REAL, "Cross-term dependence of prt "),
|
||||||
IOP( "peta0", BSIM3_MOD_PETA0, IF_REAL, "Cross-term dependence of eta0"),
|
IOP( "peta0", BSIM3_MOD_PETA0, IF_REAL, "Cross-term dependence of eta0"),
|
||||||
|
|
@ -451,7 +470,7 @@ IOP( "ppdiblc2", BSIM3_MOD_PPDIBL2, IF_REAL, "Cross-term dependence of pdiblc2")
|
||||||
IOP( "ppdiblcb", BSIM3_MOD_PPDIBLB, IF_REAL, "Cross-term dependence of pdiblcb"),
|
IOP( "ppdiblcb", BSIM3_MOD_PPDIBLB, IF_REAL, "Cross-term dependence of pdiblcb"),
|
||||||
IOP( "ppscbe1", BSIM3_MOD_PPSCBE1, IF_REAL, "Cross-term dependence of pscbe1"),
|
IOP( "ppscbe1", BSIM3_MOD_PPSCBE1, IF_REAL, "Cross-term dependence of pscbe1"),
|
||||||
IOP( "ppscbe2", BSIM3_MOD_PPSCBE2, IF_REAL, "Cross-term dependence of pscbe2"),
|
IOP( "ppscbe2", BSIM3_MOD_PPSCBE2, IF_REAL, "Cross-term dependence of pscbe2"),
|
||||||
IOP( "ppvag", BSIM3_MOD_PPVAG, IF_REAL, "Cross-term dependence of pvag"),
|
IOP( "ppvag", BSIM3_MOD_PPVAG, IF_REAL, "Cross-term dependence of pvag"),
|
||||||
IOP( "pwr", BSIM3_MOD_PWR, IF_REAL, "Cross-term dependence of wr"),
|
IOP( "pwr", BSIM3_MOD_PWR, IF_REAL, "Cross-term dependence of wr"),
|
||||||
IOP( "pdwg", BSIM3_MOD_PDWG, IF_REAL, "Cross-term dependence of dwg"),
|
IOP( "pdwg", BSIM3_MOD_PDWG, IF_REAL, "Cross-term dependence of dwg"),
|
||||||
IOP( "pdwb", BSIM3_MOD_PDWB, IF_REAL, "Cross-term dependence of dwb"),
|
IOP( "pdwb", BSIM3_MOD_PDWB, IF_REAL, "Cross-term dependence of dwb"),
|
||||||
|
|
@ -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);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ BSIM3instance *here = (BSIM3instance*)inst;
|
||||||
|
|
||||||
NG_IGNORE(select);
|
NG_IGNORE(select);
|
||||||
|
|
||||||
switch(which)
|
switch(which)
|
||||||
{ case BSIM3_L:
|
{ case BSIM3_L:
|
||||||
value->rValue = here->BSIM3l;
|
value->rValue = here->BSIM3l;
|
||||||
return(OK);
|
return(OK);
|
||||||
|
|
@ -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);
|
||||||
|
|
@ -113,118 +122,118 @@ BSIM3instance *here = (BSIM3instance*)inst;
|
||||||
value->rValue = *(ckt->CKTstate0 + here->BSIM3vds);
|
value->rValue = *(ckt->CKTstate0 + here->BSIM3vds);
|
||||||
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;
|
||||||
return(OK);
|
return(OK);
|
||||||
case BSIM3_VDSAT:
|
case BSIM3_VDSAT:
|
||||||
value->rValue = here->BSIM3vdsat;
|
value->rValue = here->BSIM3vdsat;
|
||||||
return(OK);
|
return(OK);
|
||||||
case BSIM3_QBS:
|
case BSIM3_QBS:
|
||||||
value->rValue = *(ckt->CKTstate0 + here->BSIM3qbs);
|
value->rValue = *(ckt->CKTstate0 + here->BSIM3qbs);
|
||||||
value->rValue *= here->BSIM3m;
|
value->rValue *= here->BSIM3m;
|
||||||
return(OK);
|
return(OK);
|
||||||
case BSIM3_QBD:
|
case BSIM3_QBD:
|
||||||
value->rValue = *(ckt->CKTstate0 + here->BSIM3qbd);
|
value->rValue = *(ckt->CKTstate0 + here->BSIM3qbd);
|
||||||
value->rValue *= here->BSIM3m;
|
value->rValue *= here->BSIM3m;
|
||||||
return(OK);
|
return(OK);
|
||||||
default:
|
default:
|
||||||
return(E_BADPARM);
|
return(E_BADPARM);
|
||||||
|
|
|
||||||
|
|
@ -31,29 +31,29 @@ FILE *fplog;
|
||||||
|
|
||||||
NG_IGNORE(ckt);
|
NG_IGNORE(ckt);
|
||||||
|
|
||||||
if ((fplog = fopen("b3v3check.log", "w")) != NULL)
|
if ((fplog = fopen("b3v33check.log", "w")) != NULL)
|
||||||
{ pParam = here->pParam;
|
{ pParam = here->pParam;
|
||||||
fprintf(fplog, "BSIM3v3.3.0 Parameter Checking.\n");
|
fprintf(fplog, "BSIM3v3.3.0 Parameter Checking.\n");
|
||||||
if ((strcmp(model->BSIM3version, "3.3.0")) && (strcmp(model->BSIM3version, "3.30")) && (strcmp(model->BSIM3version, "3.3")))
|
if ((strncmp(model->BSIM3version, "3.3.0", 5)) && (strncmp(model->BSIM3version, "3.30", 4)) && (strncmp(model->BSIM3version, "3.3", 3)))
|
||||||
{ fprintf(fplog, "Warning: This model is BSIM3v3.3.0; you specified a wrong version number.\n");
|
{ fprintf(fplog, "Warning: This model is BSIM3v3.3.0; you specified a wrong version number.\n");
|
||||||
printf("Warning: This model is BSIM3v3.3.0; you specified a wrong version number.\n");
|
printf("Warning: This model is BSIM3v3.3.0; you specified a wrong version number.\n");
|
||||||
}
|
}
|
||||||
fprintf(fplog, "Model = %s\n", model->BSIM3modName);
|
fprintf(fplog, "Model = %s\n", model->BSIM3modName);
|
||||||
|
|
||||||
if (pParam->BSIM3nlx < -pParam->BSIM3leff)
|
if (pParam->BSIM3nlx < -pParam->BSIM3leff)
|
||||||
{ fprintf(fplog, "Fatal: Nlx = %g is less than -Leff.\n",
|
{ fprintf(fplog, "Fatal: Nlx = %g is less than -Leff.\n",
|
||||||
pParam->BSIM3nlx);
|
pParam->BSIM3nlx);
|
||||||
printf("Fatal: Nlx = %g is less than -Leff.\n",
|
printf("Fatal: Nlx = %g is less than -Leff.\n",
|
||||||
pParam->BSIM3nlx);
|
pParam->BSIM3nlx);
|
||||||
Fatal_Flag = 1;
|
Fatal_Flag = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (model->BSIM3tox <= 0.0)
|
if (model->BSIM3tox <= 0.0)
|
||||||
{ fprintf(fplog, "Fatal: Tox = %g is not positive.\n",
|
{ fprintf(fplog, "Fatal: Tox = %g is not positive.\n",
|
||||||
model->BSIM3tox);
|
model->BSIM3tox);
|
||||||
printf("Fatal: Tox = %g is not positive.\n", model->BSIM3tox);
|
printf("Fatal: Tox = %g is not positive.\n", model->BSIM3tox);
|
||||||
Fatal_Flag = 1;
|
Fatal_Flag = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (model->BSIM3toxm <= 0.0)
|
if (model->BSIM3toxm <= 0.0)
|
||||||
{ fprintf(fplog, "Fatal: Toxm = %g is not positive.\n",
|
{ fprintf(fplog, "Fatal: Toxm = %g is not positive.\n",
|
||||||
|
|
@ -70,104 +70,104 @@ FILE *fplog;
|
||||||
Fatal_Flag = 1;
|
Fatal_Flag = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pParam->BSIM3npeak <= 0.0)
|
if (pParam->BSIM3npeak <= 0.0)
|
||||||
{ fprintf(fplog, "Fatal: Nch = %g is not positive.\n",
|
{ fprintf(fplog, "Fatal: Nch = %g is not positive.\n",
|
||||||
pParam->BSIM3npeak);
|
pParam->BSIM3npeak);
|
||||||
printf("Fatal: Nch = %g is not positive.\n",
|
printf("Fatal: Nch = %g is not positive.\n",
|
||||||
pParam->BSIM3npeak);
|
pParam->BSIM3npeak);
|
||||||
Fatal_Flag = 1;
|
Fatal_Flag = 1;
|
||||||
}
|
}
|
||||||
if (pParam->BSIM3nsub <= 0.0)
|
if (pParam->BSIM3nsub <= 0.0)
|
||||||
{ fprintf(fplog, "Fatal: Nsub = %g is not positive.\n",
|
{ fprintf(fplog, "Fatal: Nsub = %g is not positive.\n",
|
||||||
pParam->BSIM3nsub);
|
pParam->BSIM3nsub);
|
||||||
printf("Fatal: Nsub = %g is not positive.\n",
|
printf("Fatal: Nsub = %g is not positive.\n",
|
||||||
pParam->BSIM3nsub);
|
pParam->BSIM3nsub);
|
||||||
Fatal_Flag = 1;
|
Fatal_Flag = 1;
|
||||||
}
|
}
|
||||||
if (pParam->BSIM3ngate < 0.0)
|
if (pParam->BSIM3ngate < 0.0)
|
||||||
{ fprintf(fplog, "Fatal: Ngate = %g is not positive.\n",
|
{ fprintf(fplog, "Fatal: Ngate = %g is not positive.\n",
|
||||||
pParam->BSIM3ngate);
|
pParam->BSIM3ngate);
|
||||||
printf("Fatal: Ngate = %g Ngate is not positive.\n",
|
printf("Fatal: Ngate = %g Ngate is not positive.\n",
|
||||||
pParam->BSIM3ngate);
|
pParam->BSIM3ngate);
|
||||||
Fatal_Flag = 1;
|
Fatal_Flag = 1;
|
||||||
}
|
}
|
||||||
if (pParam->BSIM3ngate > 1.e25)
|
if (pParam->BSIM3ngate > 1.e25)
|
||||||
{ fprintf(fplog, "Fatal: Ngate = %g is too high.\n",
|
{ fprintf(fplog, "Fatal: Ngate = %g is too high.\n",
|
||||||
pParam->BSIM3ngate);
|
pParam->BSIM3ngate);
|
||||||
printf("Fatal: Ngate = %g Ngate is too high\n",
|
printf("Fatal: Ngate = %g Ngate is too high\n",
|
||||||
pParam->BSIM3ngate);
|
pParam->BSIM3ngate);
|
||||||
Fatal_Flag = 1;
|
Fatal_Flag = 1;
|
||||||
}
|
}
|
||||||
if (pParam->BSIM3xj <= 0.0)
|
if (pParam->BSIM3xj <= 0.0)
|
||||||
{ fprintf(fplog, "Fatal: Xj = %g is not positive.\n",
|
{ fprintf(fplog, "Fatal: Xj = %g is not positive.\n",
|
||||||
pParam->BSIM3xj);
|
pParam->BSIM3xj);
|
||||||
printf("Fatal: Xj = %g is not positive.\n", pParam->BSIM3xj);
|
printf("Fatal: Xj = %g is not positive.\n", pParam->BSIM3xj);
|
||||||
Fatal_Flag = 1;
|
Fatal_Flag = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pParam->BSIM3dvt1 < 0.0)
|
if (pParam->BSIM3dvt1 < 0.0)
|
||||||
{ fprintf(fplog, "Fatal: Dvt1 = %g is negative.\n",
|
{ fprintf(fplog, "Fatal: Dvt1 = %g is negative.\n",
|
||||||
pParam->BSIM3dvt1);
|
pParam->BSIM3dvt1);
|
||||||
printf("Fatal: Dvt1 = %g is negative.\n", pParam->BSIM3dvt1);
|
printf("Fatal: Dvt1 = %g is negative.\n", pParam->BSIM3dvt1);
|
||||||
Fatal_Flag = 1;
|
Fatal_Flag = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pParam->BSIM3dvt1w < 0.0)
|
if (pParam->BSIM3dvt1w < 0.0)
|
||||||
{ fprintf(fplog, "Fatal: Dvt1w = %g is negative.\n",
|
{ fprintf(fplog, "Fatal: Dvt1w = %g is negative.\n",
|
||||||
pParam->BSIM3dvt1w);
|
pParam->BSIM3dvt1w);
|
||||||
printf("Fatal: Dvt1w = %g is negative.\n", pParam->BSIM3dvt1w);
|
printf("Fatal: Dvt1w = %g is negative.\n", pParam->BSIM3dvt1w);
|
||||||
Fatal_Flag = 1;
|
Fatal_Flag = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pParam->BSIM3w0 == -pParam->BSIM3weff)
|
if (pParam->BSIM3w0 == -pParam->BSIM3weff)
|
||||||
{ 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->BSIM3dsub < 0.0)
|
if (pParam->BSIM3dsub < 0.0)
|
||||||
{ fprintf(fplog, "Fatal: Dsub = %g is negative.\n", pParam->BSIM3dsub);
|
{ fprintf(fplog, "Fatal: Dsub = %g is negative.\n", pParam->BSIM3dsub);
|
||||||
printf("Fatal: Dsub = %g is negative.\n", pParam->BSIM3dsub);
|
printf("Fatal: Dsub = %g is negative.\n", pParam->BSIM3dsub);
|
||||||
Fatal_Flag = 1;
|
Fatal_Flag = 1;
|
||||||
}
|
}
|
||||||
if (pParam->BSIM3b1 == -pParam->BSIM3weff)
|
if (pParam->BSIM3b1 == -pParam->BSIM3weff)
|
||||||
{ 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->BSIM3u0temp <= 0.0)
|
if (pParam->BSIM3u0temp <= 0.0)
|
||||||
{ fprintf(fplog, "Fatal: u0 at current temperature = %g is not positive.\n", pParam->BSIM3u0temp);
|
{ fprintf(fplog, "Fatal: u0 at current temperature = %g is not positive.\n", pParam->BSIM3u0temp);
|
||||||
printf("Fatal: u0 at current temperature = %g is not positive.\n",
|
printf("Fatal: u0 at current temperature = %g is not positive.\n",
|
||||||
pParam->BSIM3u0temp);
|
pParam->BSIM3u0temp);
|
||||||
Fatal_Flag = 1;
|
Fatal_Flag = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check delta parameter */
|
/* Check delta parameter */
|
||||||
if (pParam->BSIM3delta < 0.0)
|
if (pParam->BSIM3delta < 0.0)
|
||||||
{ fprintf(fplog, "Fatal: Delta = %g is less than zero.\n",
|
{ fprintf(fplog, "Fatal: Delta = %g is less than zero.\n",
|
||||||
pParam->BSIM3delta);
|
pParam->BSIM3delta);
|
||||||
printf("Fatal: Delta = %g is less than zero.\n", pParam->BSIM3delta);
|
printf("Fatal: Delta = %g is less than zero.\n", pParam->BSIM3delta);
|
||||||
Fatal_Flag = 1;
|
Fatal_Flag = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pParam->BSIM3vsattemp <= 0.0)
|
if (pParam->BSIM3vsattemp <= 0.0)
|
||||||
{ fprintf(fplog, "Fatal: Vsat at current temperature = %g is not positive.\n", pParam->BSIM3vsattemp);
|
{ fprintf(fplog, "Fatal: Vsat at current temperature = %g is not positive.\n", pParam->BSIM3vsattemp);
|
||||||
printf("Fatal: Vsat at current temperature = %g is not positive.\n",
|
printf("Fatal: Vsat at current temperature = %g is not positive.\n",
|
||||||
pParam->BSIM3vsattemp);
|
pParam->BSIM3vsattemp);
|
||||||
Fatal_Flag = 1;
|
Fatal_Flag = 1;
|
||||||
}
|
}
|
||||||
/* Check Rout parameters */
|
/* Check Rout parameters */
|
||||||
if (pParam->BSIM3pclm <= 0.0)
|
if (pParam->BSIM3pclm <= 0.0)
|
||||||
{ fprintf(fplog, "Fatal: Pclm = %g is not positive.\n", pParam->BSIM3pclm);
|
{ fprintf(fplog, "Fatal: Pclm = %g is not positive.\n", pParam->BSIM3pclm);
|
||||||
printf("Fatal: Pclm = %g is not positive.\n", pParam->BSIM3pclm);
|
printf("Fatal: Pclm = %g is not positive.\n", pParam->BSIM3pclm);
|
||||||
Fatal_Flag = 1;
|
Fatal_Flag = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pParam->BSIM3drout < 0.0)
|
if (pParam->BSIM3drout < 0.0)
|
||||||
{ fprintf(fplog, "Fatal: Drout = %g is negative.\n", pParam->BSIM3drout);
|
{ fprintf(fplog, "Fatal: Drout = %g is negative.\n", pParam->BSIM3drout);
|
||||||
printf("Fatal: Drout = %g is negative.\n", pParam->BSIM3drout);
|
printf("Fatal: Drout = %g is negative.\n", pParam->BSIM3drout);
|
||||||
Fatal_Flag = 1;
|
Fatal_Flag = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pParam->BSIM3pscbe2 <= 0.0)
|
if (pParam->BSIM3pscbe2 <= 0.0)
|
||||||
{ fprintf(fplog, "Warning: Pscbe2 = %g is not positive.\n",
|
{ fprintf(fplog, "Warning: Pscbe2 = %g is not positive.\n",
|
||||||
|
|
@ -175,22 +175,31 @@ FILE *fplog;
|
||||||
printf("Warning: Pscbe2 = %g is not positive.\n", pParam->BSIM3pscbe2);
|
printf("Warning: Pscbe2 = %g is not positive.\n", pParam->BSIM3pscbe2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (model->BSIM3unitLengthSidewallJctCap > 0.0 ||
|
/* ACM model */
|
||||||
model->BSIM3unitLengthGateSidewallJctCap > 0.0)
|
if (model->BSIM3acmMod == 0) {
|
||||||
{
|
if (model->BSIM3unitLengthSidewallJctCap > 0.0 ||
|
||||||
if (here->BSIM3drainPerimeter < pParam->BSIM3weff)
|
model->BSIM3unitLengthGateSidewallJctCap > 0.0)
|
||||||
{ fprintf(fplog, "Warning: Pd = %g is less than W.\n",
|
{
|
||||||
here->BSIM3drainPerimeter);
|
if (here->BSIM3drainPerimeter < pParam->BSIM3weff)
|
||||||
printf("Warning: Pd = %g is less than W.\n",
|
{ fprintf(fplog, "Warning: Pd = %g is less than W.\n",
|
||||||
here->BSIM3drainPerimeter);
|
here->BSIM3drainPerimeter);
|
||||||
}
|
printf("Warning: Pd = %g is less than W.\n",
|
||||||
if (here->BSIM3sourcePerimeter < pParam->BSIM3weff)
|
here->BSIM3drainPerimeter);
|
||||||
{ fprintf(fplog, "Warning: Ps = %g is less than W.\n",
|
}
|
||||||
here->BSIM3sourcePerimeter);
|
if (here->BSIM3sourcePerimeter < pParam->BSIM3weff)
|
||||||
printf("Warning: Ps = %g is less than W.\n",
|
{ fprintf(fplog, "Warning: Ps = %g is less than W.\n",
|
||||||
here->BSIM3sourcePerimeter);
|
here->BSIM3sourcePerimeter);
|
||||||
}
|
printf("Warning: Ps = %g is less than W.\n",
|
||||||
}
|
here->BSIM3sourcePerimeter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((model->BSIM3calcacm > 0) && (model->BSIM3acmMod != 12))
|
||||||
|
{ fprintf(fplog, "Warning: CALCACM = %d is wrong. Set back to 0.\n",
|
||||||
|
model->BSIM3calcacm);
|
||||||
|
printf("Warning: CALCACM = %d is wrong. Set back to 0.\n", model->BSIM3calcacm);
|
||||||
|
model->BSIM3calcacm = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (pParam->BSIM3noff < 0.1)
|
if (pParam->BSIM3noff < 0.1)
|
||||||
{ fprintf(fplog, "Warning: Noff = %g is too small.\n",
|
{ fprintf(fplog, "Warning: Noff = %g is too small.\n",
|
||||||
|
|
@ -223,9 +232,9 @@ FILE *fplog;
|
||||||
|
|
||||||
/* Check capacitance parameters */
|
/* Check capacitance parameters */
|
||||||
if (pParam->BSIM3clc < 0.0)
|
if (pParam->BSIM3clc < 0.0)
|
||||||
{ fprintf(fplog, "Fatal: Clc = %g is negative.\n", pParam->BSIM3clc);
|
{ fprintf(fplog, "Fatal: Clc = %g is negative.\n", pParam->BSIM3clc);
|
||||||
printf("Fatal: Clc = %g is negative.\n", pParam->BSIM3clc);
|
printf("Fatal: Clc = %g is negative.\n", pParam->BSIM3clc);
|
||||||
Fatal_Flag = 1;
|
Fatal_Flag = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pParam->BSIM3moin < 5.0)
|
if (pParam->BSIM3moin < 5.0)
|
||||||
|
|
@ -239,160 +248,160 @@ FILE *fplog;
|
||||||
printf("Warning: Moin = %g is too large.\n", pParam->BSIM3moin);
|
printf("Warning: Moin = %g is too large.\n", pParam->BSIM3moin);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(model->BSIM3capMod ==3) {
|
if(model->BSIM3capMod ==3) {
|
||||||
if (pParam->BSIM3acde < 0.4)
|
if (pParam->BSIM3acde < 0.4)
|
||||||
{ fprintf(fplog, "Warning: Acde = %g is too small.\n",
|
{ fprintf(fplog, "Warning: Acde = %g is too small.\n",
|
||||||
pParam->BSIM3acde);
|
pParam->BSIM3acde);
|
||||||
printf("Warning: Acde = %g is too small.\n", pParam->BSIM3acde);
|
printf("Warning: Acde = %g is too small.\n", pParam->BSIM3acde);
|
||||||
}
|
}
|
||||||
if (pParam->BSIM3acde > 1.6)
|
if (pParam->BSIM3acde > 1.6)
|
||||||
{ fprintf(fplog, "Warning: Acde = %g is too large.\n",
|
{ fprintf(fplog, "Warning: Acde = %g is too large.\n",
|
||||||
pParam->BSIM3acde);
|
pParam->BSIM3acde);
|
||||||
printf("Warning: Acde = %g is too large.\n", pParam->BSIM3acde);
|
printf("Warning: Acde = %g is too large.\n", pParam->BSIM3acde);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (model->BSIM3paramChk ==1)
|
if (model->BSIM3paramChk ==1)
|
||||||
{
|
{
|
||||||
/* Check L and W parameters */
|
/* Check L and W parameters */
|
||||||
if (pParam->BSIM3leff <= 5.0e-8)
|
if (pParam->BSIM3leff <= 5.0e-8)
|
||||||
{ fprintf(fplog, "Warning: Leff = %g may be too small.\n",
|
{ fprintf(fplog, "Warning: Leff = %g may be too small.\n",
|
||||||
pParam->BSIM3leff);
|
pParam->BSIM3leff);
|
||||||
printf("Warning: Leff = %g may be too small.\n",
|
printf("Warning: Leff = %g may be too small.\n",
|
||||||
pParam->BSIM3leff);
|
pParam->BSIM3leff);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pParam->BSIM3leffCV <= 5.0e-8)
|
if (pParam->BSIM3leffCV <= 5.0e-8)
|
||||||
{ fprintf(fplog, "Warning: Leff for CV = %g may be too small.\n",
|
{ fprintf(fplog, "Warning: Leff for CV = %g may be too small.\n",
|
||||||
pParam->BSIM3leffCV);
|
pParam->BSIM3leffCV);
|
||||||
printf("Warning: Leff for CV = %g may be too small.\n",
|
printf("Warning: Leff for CV = %g may be too small.\n",
|
||||||
pParam->BSIM3leffCV);
|
pParam->BSIM3leffCV);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pParam->BSIM3weff <= 1.0e-7)
|
if (pParam->BSIM3weff <= 1.0e-7)
|
||||||
{ fprintf(fplog, "Warning: Weff = %g may be too small.\n",
|
{ fprintf(fplog, "Warning: Weff = %g may be too small.\n",
|
||||||
pParam->BSIM3weff);
|
pParam->BSIM3weff);
|
||||||
printf("Warning: Weff = %g may be too small.\n",
|
printf("Warning: Weff = %g may be too small.\n",
|
||||||
pParam->BSIM3weff);
|
pParam->BSIM3weff);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pParam->BSIM3weffCV <= 1.0e-7)
|
if (pParam->BSIM3weffCV <= 1.0e-7)
|
||||||
{ fprintf(fplog, "Warning: Weff for CV = %g may be too small.\n",
|
{ fprintf(fplog, "Warning: Weff for CV = %g may be too small.\n",
|
||||||
pParam->BSIM3weffCV);
|
pParam->BSIM3weffCV);
|
||||||
printf("Warning: Weff for CV = %g may be too small.\n",
|
printf("Warning: Weff for CV = %g may be too small.\n",
|
||||||
pParam->BSIM3weffCV);
|
pParam->BSIM3weffCV);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check threshold voltage parameters */
|
/* Check threshold voltage parameters */
|
||||||
if (pParam->BSIM3nlx < 0.0)
|
if (pParam->BSIM3nlx < 0.0)
|
||||||
{ fprintf(fplog, "Warning: Nlx = %g is negative.\n", pParam->BSIM3nlx);
|
{ fprintf(fplog, "Warning: Nlx = %g is negative.\n", pParam->BSIM3nlx);
|
||||||
printf("Warning: Nlx = %g is negative.\n", pParam->BSIM3nlx);
|
printf("Warning: Nlx = %g is negative.\n", pParam->BSIM3nlx);
|
||||||
}
|
}
|
||||||
if (model->BSIM3tox < 1.0e-9)
|
if (model->BSIM3tox < 1.0e-9)
|
||||||
{ fprintf(fplog, "Warning: Tox = %g is less than 10A.\n",
|
{ fprintf(fplog, "Warning: Tox = %g is less than 10A.\n",
|
||||||
model->BSIM3tox);
|
model->BSIM3tox);
|
||||||
printf("Warning: Tox = %g is less than 10A.\n", model->BSIM3tox);
|
printf("Warning: Tox = %g is less than 10A.\n", model->BSIM3tox);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pParam->BSIM3npeak <= 1.0e15)
|
if (pParam->BSIM3npeak <= 1.0e15)
|
||||||
{ fprintf(fplog, "Warning: Nch = %g may be too small.\n",
|
{ fprintf(fplog, "Warning: Nch = %g may be too small.\n",
|
||||||
pParam->BSIM3npeak);
|
pParam->BSIM3npeak);
|
||||||
printf("Warning: Nch = %g may be too small.\n",
|
printf("Warning: Nch = %g may be too small.\n",
|
||||||
pParam->BSIM3npeak);
|
pParam->BSIM3npeak);
|
||||||
}
|
}
|
||||||
else if (pParam->BSIM3npeak >= 1.0e21)
|
else if (pParam->BSIM3npeak >= 1.0e21)
|
||||||
{ fprintf(fplog, "Warning: Nch = %g may be too large.\n",
|
{ fprintf(fplog, "Warning: Nch = %g may be too large.\n",
|
||||||
pParam->BSIM3npeak);
|
pParam->BSIM3npeak);
|
||||||
printf("Warning: Nch = %g may be too large.\n",
|
printf("Warning: Nch = %g may be too large.\n",
|
||||||
pParam->BSIM3npeak);
|
pParam->BSIM3npeak);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pParam->BSIM3nsub <= 1.0e14)
|
if (pParam->BSIM3nsub <= 1.0e14)
|
||||||
{ fprintf(fplog, "Warning: Nsub = %g may be too small.\n",
|
{ fprintf(fplog, "Warning: Nsub = %g may be too small.\n",
|
||||||
pParam->BSIM3nsub);
|
pParam->BSIM3nsub);
|
||||||
printf("Warning: Nsub = %g may be too small.\n",
|
printf("Warning: Nsub = %g may be too small.\n",
|
||||||
pParam->BSIM3nsub);
|
pParam->BSIM3nsub);
|
||||||
}
|
}
|
||||||
else if (pParam->BSIM3nsub >= 1.0e21)
|
else if (pParam->BSIM3nsub >= 1.0e21)
|
||||||
{ fprintf(fplog, "Warning: Nsub = %g may be too large.\n",
|
{ fprintf(fplog, "Warning: Nsub = %g may be too large.\n",
|
||||||
pParam->BSIM3nsub);
|
pParam->BSIM3nsub);
|
||||||
printf("Warning: Nsub = %g may be too large.\n",
|
printf("Warning: Nsub = %g may be too large.\n",
|
||||||
pParam->BSIM3nsub);
|
pParam->BSIM3nsub);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((pParam->BSIM3ngate > 0.0) &&
|
if ((pParam->BSIM3ngate > 0.0) &&
|
||||||
(pParam->BSIM3ngate <= 1.e18))
|
(pParam->BSIM3ngate <= 1.e18))
|
||||||
{ fprintf(fplog, "Warning: Ngate = %g is less than 1.E18cm^-3.\n",
|
{ fprintf(fplog, "Warning: Ngate = %g is less than 1.E18cm^-3.\n",
|
||||||
pParam->BSIM3ngate);
|
pParam->BSIM3ngate);
|
||||||
printf("Warning: Ngate = %g is less than 1.E18cm^-3.\n",
|
printf("Warning: Ngate = %g is less than 1.E18cm^-3.\n",
|
||||||
pParam->BSIM3ngate);
|
pParam->BSIM3ngate);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pParam->BSIM3dvt0 < 0.0)
|
if (pParam->BSIM3dvt0 < 0.0)
|
||||||
{ fprintf(fplog, "Warning: Dvt0 = %g is negative.\n",
|
{ fprintf(fplog, "Warning: Dvt0 = %g is negative.\n",
|
||||||
pParam->BSIM3dvt0);
|
pParam->BSIM3dvt0);
|
||||||
printf("Warning: Dvt0 = %g is negative.\n", pParam->BSIM3dvt0);
|
printf("Warning: Dvt0 = %g is negative.\n", pParam->BSIM3dvt0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fabs(1.0e-6 / (pParam->BSIM3w0 + pParam->BSIM3weff)) > 10.0)
|
if (fabs(1.0e-6 / (pParam->BSIM3w0 + pParam->BSIM3weff)) > 10.0)
|
||||||
{ fprintf(fplog, "Warning: (W0 + Weff) may be too small.\n");
|
{ fprintf(fplog, "Warning: (W0 + Weff) may be too small.\n");
|
||||||
printf("Warning: (W0 + Weff) may be too small.\n");
|
printf("Warning: (W0 + Weff) may be too small.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check subthreshold parameters */
|
/* Check subthreshold parameters */
|
||||||
if (pParam->BSIM3nfactor < 0.0)
|
if (pParam->BSIM3nfactor < 0.0)
|
||||||
{ fprintf(fplog, "Warning: Nfactor = %g is negative.\n",
|
{ fprintf(fplog, "Warning: Nfactor = %g is negative.\n",
|
||||||
pParam->BSIM3nfactor);
|
pParam->BSIM3nfactor);
|
||||||
printf("Warning: Nfactor = %g is negative.\n", pParam->BSIM3nfactor);
|
printf("Warning: Nfactor = %g is negative.\n", pParam->BSIM3nfactor);
|
||||||
}
|
}
|
||||||
if (pParam->BSIM3cdsc < 0.0)
|
if (pParam->BSIM3cdsc < 0.0)
|
||||||
{ fprintf(fplog, "Warning: Cdsc = %g is negative.\n",
|
{ fprintf(fplog, "Warning: Cdsc = %g is negative.\n",
|
||||||
pParam->BSIM3cdsc);
|
pParam->BSIM3cdsc);
|
||||||
printf("Warning: Cdsc = %g is negative.\n", pParam->BSIM3cdsc);
|
printf("Warning: Cdsc = %g is negative.\n", pParam->BSIM3cdsc);
|
||||||
}
|
}
|
||||||
if (pParam->BSIM3cdscd < 0.0)
|
if (pParam->BSIM3cdscd < 0.0)
|
||||||
{ fprintf(fplog, "Warning: Cdscd = %g is negative.\n",
|
{ fprintf(fplog, "Warning: Cdscd = %g is negative.\n",
|
||||||
pParam->BSIM3cdscd);
|
pParam->BSIM3cdscd);
|
||||||
printf("Warning: Cdscd = %g is negative.\n", pParam->BSIM3cdscd);
|
printf("Warning: Cdscd = %g is negative.\n", pParam->BSIM3cdscd);
|
||||||
}
|
}
|
||||||
/* Check DIBL parameters */
|
/* Check DIBL parameters */
|
||||||
if (pParam->BSIM3eta0 < 0.0)
|
if (pParam->BSIM3eta0 < 0.0)
|
||||||
{ fprintf(fplog, "Warning: Eta0 = %g is negative.\n",
|
{ fprintf(fplog, "Warning: Eta0 = %g is negative.\n",
|
||||||
pParam->BSIM3eta0);
|
pParam->BSIM3eta0);
|
||||||
printf("Warning: Eta0 = %g is negative.\n", pParam->BSIM3eta0);
|
printf("Warning: Eta0 = %g is negative.\n", pParam->BSIM3eta0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check Abulk parameters */
|
/* Check Abulk parameters */
|
||||||
if (fabs(1.0e-6 / (pParam->BSIM3b1 + pParam->BSIM3weff)) > 10.0)
|
if (fabs(1.0e-6 / (pParam->BSIM3b1 + pParam->BSIM3weff)) > 10.0)
|
||||||
{ fprintf(fplog, "Warning: (B1 + Weff) may be too small.\n");
|
{ fprintf(fplog, "Warning: (B1 + Weff) may be too small.\n");
|
||||||
printf("Warning: (B1 + Weff) may be too small.\n");
|
printf("Warning: (B1 + Weff) may be too small.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Check Saturation parameters */
|
/* Check Saturation parameters */
|
||||||
if (pParam->BSIM3a2 < 0.01)
|
if (pParam->BSIM3a2 < 0.01)
|
||||||
{ fprintf(fplog, "Warning: A2 = %g is too small. Set to 0.01.\n", pParam->BSIM3a2);
|
{ fprintf(fplog, "Warning: A2 = %g is too small. Set to 0.01.\n", pParam->BSIM3a2);
|
||||||
printf("Warning: A2 = %g is too small. Set to 0.01.\n",
|
printf("Warning: A2 = %g is too small. Set to 0.01.\n",
|
||||||
pParam->BSIM3a2);
|
pParam->BSIM3a2);
|
||||||
pParam->BSIM3a2 = 0.01;
|
pParam->BSIM3a2 = 0.01;
|
||||||
}
|
}
|
||||||
else if (pParam->BSIM3a2 > 1.0)
|
else if (pParam->BSIM3a2 > 1.0)
|
||||||
{ fprintf(fplog, "Warning: A2 = %g is larger than 1. A2 is set to 1 and A1 is set to 0.\n",
|
{ fprintf(fplog, "Warning: A2 = %g is larger than 1. A2 is set to 1 and A1 is set to 0.\n",
|
||||||
pParam->BSIM3a2);
|
pParam->BSIM3a2);
|
||||||
printf("Warning: A2 = %g is larger than 1. A2 is set to 1 and A1 is set to 0.\n",
|
printf("Warning: A2 = %g is larger than 1. A2 is set to 1 and A1 is set to 0.\n",
|
||||||
pParam->BSIM3a2);
|
pParam->BSIM3a2);
|
||||||
pParam->BSIM3a2 = 1.0;
|
pParam->BSIM3a2 = 1.0;
|
||||||
pParam->BSIM3a1 = 0.0;
|
pParam->BSIM3a1 = 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pParam->BSIM3rdsw < 0.0)
|
if (pParam->BSIM3rdsw < 0.0)
|
||||||
{ fprintf(fplog, "Warning: Rdsw = %g is negative. Set to zero.\n",
|
{ fprintf(fplog, "Warning: Rdsw = %g is negative. Set to zero.\n",
|
||||||
pParam->BSIM3rdsw);
|
pParam->BSIM3rdsw);
|
||||||
printf("Warning: Rdsw = %g is negative. Set to zero.\n",
|
printf("Warning: Rdsw = %g is negative. Set to zero.\n",
|
||||||
pParam->BSIM3rdsw);
|
pParam->BSIM3rdsw);
|
||||||
pParam->BSIM3rdsw = 0.0;
|
pParam->BSIM3rdsw = 0.0;
|
||||||
pParam->BSIM3rds0 = 0.0;
|
pParam->BSIM3rds0 = 0.0;
|
||||||
}
|
}
|
||||||
if (pParam->BSIM3rds0 < 0.0)
|
if (pParam->BSIM3rds0 < 0.0)
|
||||||
{ fprintf(fplog, "Warning: Rds at current temperature = %g is negative. Set to zero.\n",
|
{ fprintf(fplog, "Warning: Rds at current temperature = %g is negative. Set to zero.\n",
|
||||||
pParam->BSIM3rds0);
|
pParam->BSIM3rds0);
|
||||||
|
|
@ -401,40 +410,40 @@ FILE *fplog;
|
||||||
pParam->BSIM3rds0 = 0.0;
|
pParam->BSIM3rds0 = 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pParam->BSIM3vsattemp < 1.0e3)
|
if (pParam->BSIM3vsattemp < 1.0e3)
|
||||||
{ fprintf(fplog, "Warning: Vsat at current temperature = %g may be too small.\n", pParam->BSIM3vsattemp);
|
{ fprintf(fplog, "Warning: Vsat at current temperature = %g may be too small.\n", pParam->BSIM3vsattemp);
|
||||||
printf("Warning: Vsat at current temperature = %g may be too small.\n", pParam->BSIM3vsattemp);
|
printf("Warning: Vsat at current temperature = %g may be too small.\n", pParam->BSIM3vsattemp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pParam->BSIM3pdibl1 < 0.0)
|
if (pParam->BSIM3pdibl1 < 0.0)
|
||||||
{ fprintf(fplog, "Warning: Pdibl1 = %g is negative.\n",
|
{ fprintf(fplog, "Warning: Pdibl1 = %g is negative.\n",
|
||||||
pParam->BSIM3pdibl1);
|
pParam->BSIM3pdibl1);
|
||||||
printf("Warning: Pdibl1 = %g is negative.\n", pParam->BSIM3pdibl1);
|
printf("Warning: Pdibl1 = %g is negative.\n", pParam->BSIM3pdibl1);
|
||||||
}
|
}
|
||||||
if (pParam->BSIM3pdibl2 < 0.0)
|
if (pParam->BSIM3pdibl2 < 0.0)
|
||||||
{ fprintf(fplog, "Warning: Pdibl2 = %g is negative.\n",
|
{ fprintf(fplog, "Warning: Pdibl2 = %g is negative.\n",
|
||||||
pParam->BSIM3pdibl2);
|
pParam->BSIM3pdibl2);
|
||||||
printf("Warning: Pdibl2 = %g is negative.\n", pParam->BSIM3pdibl2);
|
printf("Warning: Pdibl2 = %g is negative.\n", pParam->BSIM3pdibl2);
|
||||||
}
|
}
|
||||||
/* Check overlap capacitance parameters */
|
/* Check overlap capacitance parameters */
|
||||||
if (model->BSIM3cgdo < 0.0)
|
if (model->BSIM3cgdo < 0.0)
|
||||||
{ fprintf(fplog, "Warning: cgdo = %g is negative. Set to zero.\n", model->BSIM3cgdo);
|
{ fprintf(fplog, "Warning: cgdo = %g is negative. Set to zero.\n", model->BSIM3cgdo);
|
||||||
printf("Warning: cgdo = %g is negative. Set to zero.\n", model->BSIM3cgdo);
|
printf("Warning: cgdo = %g is negative. Set to zero.\n", model->BSIM3cgdo);
|
||||||
model->BSIM3cgdo = 0.0;
|
model->BSIM3cgdo = 0.0;
|
||||||
}
|
}
|
||||||
if (model->BSIM3cgso < 0.0)
|
if (model->BSIM3cgso < 0.0)
|
||||||
{ fprintf(fplog, "Warning: cgso = %g is negative. Set to zero.\n", model->BSIM3cgso);
|
{ fprintf(fplog, "Warning: cgso = %g is negative. Set to zero.\n", model->BSIM3cgso);
|
||||||
printf("Warning: cgso = %g is negative. Set to zero.\n", model->BSIM3cgso);
|
printf("Warning: cgso = %g is negative. Set to zero.\n", model->BSIM3cgso);
|
||||||
model->BSIM3cgso = 0.0;
|
model->BSIM3cgso = 0.0;
|
||||||
}
|
}
|
||||||
if (model->BSIM3cgbo < 0.0)
|
if (model->BSIM3cgbo < 0.0)
|
||||||
{ fprintf(fplog, "Warning: cgbo = %g is negative. Set to zero.\n", model->BSIM3cgbo);
|
{ fprintf(fplog, "Warning: cgbo = %g is negative. Set to zero.\n", model->BSIM3cgbo);
|
||||||
printf("Warning: cgbo = %g is negative. Set to zero.\n", model->BSIM3cgbo);
|
printf("Warning: cgbo = %g is negative. Set to zero.\n", model->BSIM3cgbo);
|
||||||
model->BSIM3cgbo = 0.0;
|
model->BSIM3cgbo = 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
}/* loop for the parameter check for warning messages */
|
}/* loop for the parameter check for warning messages */
|
||||||
fclose(fplog);
|
fclose(fplog);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ fprintf(stderr, "Warning: Can't open log file. Parameter checking skipped.\n");
|
{ fprintf(stderr, "Warning: Can't open log file. Parameter checking skipped.\n");
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -43,9 +43,18 @@ IFvalue *value)
|
||||||
case BSIM3_MOD_NOIMOD:
|
case BSIM3_MOD_NOIMOD:
|
||||||
value->iValue = model->BSIM3noiMod;
|
value->iValue = model->BSIM3noiMod;
|
||||||
return(OK);
|
return(OK);
|
||||||
|
case BSIM3_MOD_NQSMOD:
|
||||||
|
value->iValue = model->BSIM3nqsMod;
|
||||||
|
return(OK);
|
||||||
case BSIM3_MOD_ACNQSMOD:
|
case BSIM3_MOD_ACNQSMOD:
|
||||||
value->iValue = model->BSIM3acnqsMod;
|
value->iValue = model->BSIM3acnqsMod;
|
||||||
return(OK);
|
return(OK);
|
||||||
|
case BSIM3_MOD_ACMMOD:
|
||||||
|
value->iValue = model->BSIM3acmMod;
|
||||||
|
return(OK);
|
||||||
|
case BSIM3_MOD_CALCACM:
|
||||||
|
value->iValue = model->BSIM3calcacm;
|
||||||
|
return(OK);
|
||||||
case BSIM3_MOD_VERSION :
|
case BSIM3_MOD_VERSION :
|
||||||
value->sValue = model->BSIM3version;
|
value->sValue = model->BSIM3version;
|
||||||
return(OK);
|
return(OK);
|
||||||
|
|
@ -337,6 +346,32 @@ IFvalue *value)
|
||||||
value->rValue = model->BSIM3tpbswg;
|
value->rValue = model->BSIM3tpbswg;
|
||||||
return(OK);
|
return(OK);
|
||||||
|
|
||||||
|
/* ACM model */
|
||||||
|
case BSIM3_MOD_HDIF:
|
||||||
|
value->rValue = model->BSIM3hdif;
|
||||||
|
return(OK);
|
||||||
|
case BSIM3_MOD_LDIF:
|
||||||
|
value->rValue = model->BSIM3ldif;
|
||||||
|
return(OK);
|
||||||
|
case BSIM3_MOD_LD:
|
||||||
|
value->rValue = model->BSIM3ld;
|
||||||
|
return(OK);
|
||||||
|
case BSIM3_MOD_RD:
|
||||||
|
value->rValue = model->BSIM3rd;
|
||||||
|
return(OK);
|
||||||
|
case BSIM3_MOD_RS:
|
||||||
|
value->rValue = model->BSIM3rs;
|
||||||
|
return(OK);
|
||||||
|
case BSIM3_MOD_RDC:
|
||||||
|
value->rValue = model->BSIM3rdc;
|
||||||
|
return(OK);
|
||||||
|
case BSIM3_MOD_RSC:
|
||||||
|
value->rValue = model->BSIM3rsc;
|
||||||
|
return(OK);
|
||||||
|
case BSIM3_MOD_WMLT:
|
||||||
|
value->rValue = model->BSIM3wmlt;
|
||||||
|
return(OK);
|
||||||
|
|
||||||
/* Length dependence */
|
/* Length dependence */
|
||||||
case BSIM3_MOD_LCDSC :
|
case BSIM3_MOD_LCDSC :
|
||||||
value->rValue = model->BSIM3lcdsc;
|
value->rValue = model->BSIM3lcdsc;
|
||||||
|
|
@ -1219,6 +1254,14 @@ IFvalue *value)
|
||||||
case BSIM3_MOD_WMAX:
|
case BSIM3_MOD_WMAX:
|
||||||
value->rValue = model->BSIM3Wmax;
|
value->rValue = model->BSIM3Wmax;
|
||||||
return(OK);
|
return(OK);
|
||||||
|
|
||||||
|
case BSIM3_MOD_XL:
|
||||||
|
value->rValue = model->BSIM3xl;
|
||||||
|
return(OK);
|
||||||
|
case BSIM3_MOD_XW:
|
||||||
|
value->rValue = model->BSIM3xw;
|
||||||
|
return(OK);
|
||||||
|
|
||||||
case BSIM3_MOD_NOIA:
|
case BSIM3_MOD_NOIA:
|
||||||
value->rValue = model->BSIM3oxideTrapDensityA;
|
value->rValue = model->BSIM3oxideTrapDensityA;
|
||||||
return(OK);
|
return(OK);
|
||||||
|
|
|
||||||
|
|
@ -39,15 +39,27 @@ GENmodel *inMod)
|
||||||
mod->BSIM3capMod = value->iValue;
|
mod->BSIM3capMod = value->iValue;
|
||||||
mod->BSIM3capModGiven = TRUE;
|
mod->BSIM3capModGiven = TRUE;
|
||||||
break;
|
break;
|
||||||
|
case BSIM3_MOD_ACMMOD:
|
||||||
|
mod->BSIM3acmMod = value->iValue;
|
||||||
|
mod->BSIM3acmModGiven = TRUE;
|
||||||
|
break;
|
||||||
|
case BSIM3_MOD_CALCACM:
|
||||||
|
mod->BSIM3calcacm = value->iValue;
|
||||||
|
mod->BSIM3calcacmGiven = TRUE;
|
||||||
|
break;
|
||||||
case BSIM3_MOD_NOIMOD :
|
case BSIM3_MOD_NOIMOD :
|
||||||
mod->BSIM3noiMod = value->iValue;
|
mod->BSIM3noiMod = value->iValue;
|
||||||
mod->BSIM3noiModGiven = TRUE;
|
mod->BSIM3noiModGiven = TRUE;
|
||||||
break;
|
break;
|
||||||
|
case BSIM3_MOD_NQSMOD :
|
||||||
|
mod->BSIM3nqsMod = value->iValue;
|
||||||
|
mod->BSIM3nqsModGiven = TRUE;
|
||||||
|
break;
|
||||||
case BSIM3_MOD_ACNQSMOD :
|
case BSIM3_MOD_ACNQSMOD :
|
||||||
mod->BSIM3acnqsMod = value->iValue;
|
mod->BSIM3acnqsMod = value->iValue;
|
||||||
mod->BSIM3acnqsModGiven = TRUE;
|
mod->BSIM3acnqsModGiven = TRUE;
|
||||||
break;
|
break;
|
||||||
case BSIM3_MOD_VERSION :
|
case BSIM3_MOD_VERSION :
|
||||||
mod->BSIM3version = value->sValue;
|
mod->BSIM3version = value->sValue;
|
||||||
mod->BSIM3versionGiven = TRUE;
|
mod->BSIM3versionGiven = TRUE;
|
||||||
break;
|
break;
|
||||||
|
|
@ -123,14 +135,14 @@ GENmodel *inMod)
|
||||||
case BSIM3_MOD_NPEAK:
|
case BSIM3_MOD_NPEAK:
|
||||||
mod->BSIM3npeak = value->rValue;
|
mod->BSIM3npeak = value->rValue;
|
||||||
mod->BSIM3npeakGiven = TRUE;
|
mod->BSIM3npeakGiven = TRUE;
|
||||||
if (mod->BSIM3npeak > 1.0e20)
|
if (mod->BSIM3npeak > 1.0e20)
|
||||||
mod->BSIM3npeak *= 1.0e-6;
|
mod->BSIM3npeak *= 1.0e-6;
|
||||||
break;
|
break;
|
||||||
case BSIM3_MOD_NGATE:
|
case BSIM3_MOD_NGATE:
|
||||||
mod->BSIM3ngate = value->rValue;
|
mod->BSIM3ngate = value->rValue;
|
||||||
mod->BSIM3ngateGiven = TRUE;
|
mod->BSIM3ngateGiven = TRUE;
|
||||||
if (mod->BSIM3ngate > 1.0e23)
|
if (mod->BSIM3ngate > 1.0e23)
|
||||||
mod->BSIM3ngate *= 1.0e-6;
|
mod->BSIM3ngate *= 1.0e-6;
|
||||||
break;
|
break;
|
||||||
case BSIM3_MOD_GAMMA1:
|
case BSIM3_MOD_GAMMA1:
|
||||||
mod->BSIM3gamma1 = value->rValue;
|
mod->BSIM3gamma1 = value->rValue;
|
||||||
|
|
@ -438,7 +450,41 @@ GENmodel *inMod)
|
||||||
mod->BSIM3tpbswgGiven = TRUE;
|
mod->BSIM3tpbswgGiven = TRUE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Length dependence */
|
/* acm model */
|
||||||
|
case BSIM3_MOD_HDIF:
|
||||||
|
mod->BSIM3hdif = value->rValue;
|
||||||
|
mod->BSIM3hdifGiven = TRUE;
|
||||||
|
break;
|
||||||
|
case BSIM3_MOD_LDIF:
|
||||||
|
mod->BSIM3ldif = value->rValue;
|
||||||
|
mod->BSIM3ldifGiven = TRUE;
|
||||||
|
break;
|
||||||
|
case BSIM3_MOD_LD:
|
||||||
|
mod->BSIM3ld = value->rValue;
|
||||||
|
mod->BSIM3ldGiven = TRUE;
|
||||||
|
break;
|
||||||
|
case BSIM3_MOD_RD:
|
||||||
|
mod->BSIM3rd = value->rValue;
|
||||||
|
mod->BSIM3rdGiven = TRUE;
|
||||||
|
break;
|
||||||
|
case BSIM3_MOD_RS:
|
||||||
|
mod->BSIM3rs = value->rValue;
|
||||||
|
mod->BSIM3rsGiven = TRUE;
|
||||||
|
break;
|
||||||
|
case BSIM3_MOD_RDC:
|
||||||
|
mod->BSIM3rdc = value->rValue;
|
||||||
|
mod->BSIM3rdcGiven = TRUE;
|
||||||
|
break;
|
||||||
|
case BSIM3_MOD_RSC:
|
||||||
|
mod->BSIM3rsc = value->rValue;
|
||||||
|
mod->BSIM3rscGiven = TRUE;
|
||||||
|
break;
|
||||||
|
case BSIM3_MOD_WMLT:
|
||||||
|
mod->BSIM3wmlt = value->rValue;
|
||||||
|
mod->BSIM3wmltGiven = TRUE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Length dependence */
|
||||||
case BSIM3_MOD_LCDSC :
|
case BSIM3_MOD_LCDSC :
|
||||||
mod->BSIM3lcdsc = value->rValue;
|
mod->BSIM3lcdsc = value->rValue;
|
||||||
mod->BSIM3lcdscGiven = TRUE;
|
mod->BSIM3lcdscGiven = TRUE;
|
||||||
|
|
@ -502,14 +548,14 @@ GENmodel *inMod)
|
||||||
case BSIM3_MOD_LNPEAK:
|
case BSIM3_MOD_LNPEAK:
|
||||||
mod->BSIM3lnpeak = value->rValue;
|
mod->BSIM3lnpeak = value->rValue;
|
||||||
mod->BSIM3lnpeakGiven = TRUE;
|
mod->BSIM3lnpeakGiven = TRUE;
|
||||||
if (mod->BSIM3lnpeak > 1.0e20)
|
if (mod->BSIM3lnpeak > 1.0e20)
|
||||||
mod->BSIM3lnpeak *= 1.0e-6;
|
mod->BSIM3lnpeak *= 1.0e-6;
|
||||||
break;
|
break;
|
||||||
case BSIM3_MOD_LNGATE:
|
case BSIM3_MOD_LNGATE:
|
||||||
mod->BSIM3lngate = value->rValue;
|
mod->BSIM3lngate = value->rValue;
|
||||||
mod->BSIM3lngateGiven = TRUE;
|
mod->BSIM3lngateGiven = TRUE;
|
||||||
if (mod->BSIM3lngate > 1.0e23)
|
if (mod->BSIM3lngate > 1.0e23)
|
||||||
mod->BSIM3lngate *= 1.0e-6;
|
mod->BSIM3lngate *= 1.0e-6;
|
||||||
break;
|
break;
|
||||||
case BSIM3_MOD_LGAMMA1:
|
case BSIM3_MOD_LGAMMA1:
|
||||||
mod->BSIM3lgamma1 = value->rValue;
|
mod->BSIM3lgamma1 = value->rValue;
|
||||||
|
|
@ -781,7 +827,7 @@ GENmodel *inMod)
|
||||||
mod->BSIM3lvoffcvGiven = TRUE;
|
mod->BSIM3lvoffcvGiven = TRUE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Width dependence */
|
/* Width dependence */
|
||||||
case BSIM3_MOD_WCDSC :
|
case BSIM3_MOD_WCDSC :
|
||||||
mod->BSIM3wcdsc = value->rValue;
|
mod->BSIM3wcdsc = value->rValue;
|
||||||
mod->BSIM3wcdscGiven = TRUE;
|
mod->BSIM3wcdscGiven = TRUE;
|
||||||
|
|
@ -845,14 +891,14 @@ GENmodel *inMod)
|
||||||
case BSIM3_MOD_WNPEAK:
|
case BSIM3_MOD_WNPEAK:
|
||||||
mod->BSIM3wnpeak = value->rValue;
|
mod->BSIM3wnpeak = value->rValue;
|
||||||
mod->BSIM3wnpeakGiven = TRUE;
|
mod->BSIM3wnpeakGiven = TRUE;
|
||||||
if (mod->BSIM3wnpeak > 1.0e20)
|
if (mod->BSIM3wnpeak > 1.0e20)
|
||||||
mod->BSIM3wnpeak *= 1.0e-6;
|
mod->BSIM3wnpeak *= 1.0e-6;
|
||||||
break;
|
break;
|
||||||
case BSIM3_MOD_WNGATE:
|
case BSIM3_MOD_WNGATE:
|
||||||
mod->BSIM3wngate = value->rValue;
|
mod->BSIM3wngate = value->rValue;
|
||||||
mod->BSIM3wngateGiven = TRUE;
|
mod->BSIM3wngateGiven = TRUE;
|
||||||
if (mod->BSIM3wngate > 1.0e23)
|
if (mod->BSIM3wngate > 1.0e23)
|
||||||
mod->BSIM3wngate *= 1.0e-6;
|
mod->BSIM3wngate *= 1.0e-6;
|
||||||
break;
|
break;
|
||||||
case BSIM3_MOD_WGAMMA1:
|
case BSIM3_MOD_WGAMMA1:
|
||||||
mod->BSIM3wgamma1 = value->rValue;
|
mod->BSIM3wgamma1 = value->rValue;
|
||||||
|
|
@ -1124,7 +1170,7 @@ GENmodel *inMod)
|
||||||
mod->BSIM3wvoffcvGiven = TRUE;
|
mod->BSIM3wvoffcvGiven = TRUE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Cross-term dependence */
|
/* Cross-term dependence */
|
||||||
case BSIM3_MOD_PCDSC :
|
case BSIM3_MOD_PCDSC :
|
||||||
mod->BSIM3pcdsc = value->rValue;
|
mod->BSIM3pcdsc = value->rValue;
|
||||||
mod->BSIM3pcdscGiven = TRUE;
|
mod->BSIM3pcdscGiven = TRUE;
|
||||||
|
|
@ -1188,14 +1234,14 @@ GENmodel *inMod)
|
||||||
case BSIM3_MOD_PNPEAK:
|
case BSIM3_MOD_PNPEAK:
|
||||||
mod->BSIM3pnpeak = value->rValue;
|
mod->BSIM3pnpeak = value->rValue;
|
||||||
mod->BSIM3pnpeakGiven = TRUE;
|
mod->BSIM3pnpeakGiven = TRUE;
|
||||||
if (mod->BSIM3pnpeak > 1.0e20)
|
if (mod->BSIM3pnpeak > 1.0e20)
|
||||||
mod->BSIM3pnpeak *= 1.0e-6;
|
mod->BSIM3pnpeak *= 1.0e-6;
|
||||||
break;
|
break;
|
||||||
case BSIM3_MOD_PNGATE:
|
case BSIM3_MOD_PNGATE:
|
||||||
mod->BSIM3pngate = value->rValue;
|
mod->BSIM3pngate = value->rValue;
|
||||||
mod->BSIM3pngateGiven = TRUE;
|
mod->BSIM3pngateGiven = TRUE;
|
||||||
if (mod->BSIM3pngate > 1.0e23)
|
if (mod->BSIM3pngate > 1.0e23)
|
||||||
mod->BSIM3pngate *= 1.0e-6;
|
mod->BSIM3pngate *= 1.0e-6;
|
||||||
break;
|
break;
|
||||||
case BSIM3_MOD_PGAMMA1:
|
case BSIM3_MOD_PGAMMA1:
|
||||||
mod->BSIM3pgamma1 = value->rValue;
|
mod->BSIM3pgamma1 = value->rValue;
|
||||||
|
|
@ -1636,6 +1682,15 @@ GENmodel *inMod)
|
||||||
mod->BSIM3WmaxGiven = TRUE;
|
mod->BSIM3WmaxGiven = TRUE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case BSIM3_MOD_XL:
|
||||||
|
mod->BSIM3xl = value->rValue;
|
||||||
|
mod->BSIM3xlGiven = TRUE;
|
||||||
|
break;
|
||||||
|
case BSIM3_MOD_XW:
|
||||||
|
mod->BSIM3xw = value->rValue;
|
||||||
|
mod->BSIM3xwGiven = TRUE;
|
||||||
|
break;
|
||||||
|
|
||||||
case BSIM3_MOD_NOIA :
|
case BSIM3_MOD_NOIA :
|
||||||
mod->BSIM3oxideTrapDensityA = value->rValue;
|
mod->BSIM3oxideTrapDensityA = value->rValue;
|
||||||
mod->BSIM3oxideTrapDensityAGiven = TRUE;
|
mod->BSIM3oxideTrapDensityAGiven = TRUE;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
/**********
|
||||||
|
Author: 2013 Francesco Lannutti
|
||||||
|
**********/
|
||||||
|
|
||||||
|
#include "ngspice/ngspice.h"
|
||||||
|
#include "ngspice/cktdefs.h"
|
||||||
|
#include "bsim3def.h"
|
||||||
|
#include "ngspice/sperror.h"
|
||||||
|
|
||||||
|
int
|
||||||
|
BSIM3nodeIsNonLinear (GENmodel *inModel, CKTcircuit *ckt)
|
||||||
|
{
|
||||||
|
BSIM3model *model = (BSIM3model *)inModel ;
|
||||||
|
BSIM3instance *here ;
|
||||||
|
|
||||||
|
/* loop through all the BSIM3 models */
|
||||||
|
for ( ; model != NULL ; model = model->BSIM3nextModel)
|
||||||
|
{
|
||||||
|
/* loop through all the instances of the model */
|
||||||
|
for (here = model->BSIM3instances ; here != NULL ; here = here->BSIM3nextInstance)
|
||||||
|
{
|
||||||
|
ckt->CKTnodeIsLinear [here->BSIM3dNodePrime] = 0 ;
|
||||||
|
ckt->CKTnodeIsLinear [here->BSIM3sNodePrime] = 0 ;
|
||||||
|
ckt->CKTnodeIsLinear [here->BSIM3qNode] = 0 ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (OK) ;
|
||||||
|
}
|
||||||
|
|
@ -31,7 +31,7 @@ IFvalue *select)
|
||||||
if (!cp_getvar("scale", CP_REAL, &scale))
|
if (!cp_getvar("scale", CP_REAL, &scale))
|
||||||
scale = 1;
|
scale = 1;
|
||||||
|
|
||||||
switch(param)
|
switch(param)
|
||||||
{ case BSIM3_W:
|
{ case BSIM3_W:
|
||||||
here->BSIM3w = value->rValue*scale;
|
here->BSIM3w = value->rValue*scale;
|
||||||
here->BSIM3wGiven = TRUE;
|
here->BSIM3wGiven = TRUE;
|
||||||
|
|
@ -40,10 +40,10 @@ IFvalue *select)
|
||||||
here->BSIM3l = value->rValue*scale;
|
here->BSIM3l = value->rValue*scale;
|
||||||
here->BSIM3lGiven = TRUE;
|
here->BSIM3lGiven = TRUE;
|
||||||
break;
|
break;
|
||||||
case BSIM3_M:
|
case BSIM3_M:
|
||||||
here->BSIM3m = value->rValue;
|
here->BSIM3m = value->rValue;
|
||||||
here->BSIM3mGiven = TRUE;
|
here->BSIM3mGiven = TRUE;
|
||||||
break;
|
break;
|
||||||
case BSIM3_AS:
|
case BSIM3_AS:
|
||||||
here->BSIM3sourceArea = value->rValue*scale*scale;
|
here->BSIM3sourceArea = value->rValue*scale*scale;
|
||||||
here->BSIM3sourceAreaGiven = TRUE;
|
here->BSIM3sourceAreaGiven = TRUE;
|
||||||
|
|
@ -91,6 +91,18 @@ IFvalue *select)
|
||||||
here->BSIM3acnqsMod = value->iValue;
|
here->BSIM3acnqsMod = value->iValue;
|
||||||
here->BSIM3acnqsModGiven = TRUE;
|
here->BSIM3acnqsModGiven = TRUE;
|
||||||
break;
|
break;
|
||||||
|
case BSIM3_GEO:
|
||||||
|
here->BSIM3geo = value->iValue;
|
||||||
|
here->BSIM3geoGiven = TRUE;
|
||||||
|
break;
|
||||||
|
case BSIM3_DELVTO:
|
||||||
|
here->BSIM3delvto = value->rValue;
|
||||||
|
here->BSIM3delvtoGiven = TRUE;
|
||||||
|
break;
|
||||||
|
case BSIM3_MULU0:
|
||||||
|
here->BSIM3mulu0 = value->rValue;
|
||||||
|
here->BSIM3mulu0Given = TRUE;
|
||||||
|
break;
|
||||||
case BSIM3_IC:
|
case BSIM3_IC:
|
||||||
switch(value->v.numValue){
|
switch(value->v.numValue){
|
||||||
case 3:
|
case 3:
|
||||||
|
|
|
||||||
|
|
@ -61,8 +61,18 @@ BSIM3instance **InstArray;
|
||||||
model->BSIM3paramChk = 0;
|
model->BSIM3paramChk = 0;
|
||||||
if (!model->BSIM3capModGiven)
|
if (!model->BSIM3capModGiven)
|
||||||
model->BSIM3capMod = 3;
|
model->BSIM3capMod = 3;
|
||||||
|
if (!model->BSIM3acmModGiven)
|
||||||
|
model->BSIM3acmMod = 0;
|
||||||
|
if (!model->BSIM3calcacmGiven)
|
||||||
|
model->BSIM3calcacm = 0;
|
||||||
if (!model->BSIM3noiModGiven)
|
if (!model->BSIM3noiModGiven)
|
||||||
model->BSIM3noiMod = 1;
|
model->BSIM3noiMod = 1;
|
||||||
|
if (!model->BSIM3nqsModGiven)
|
||||||
|
model->BSIM3nqsMod = 0;
|
||||||
|
else if ((model->BSIM3nqsMod != 0) && (model->BSIM3nqsMod != 1))
|
||||||
|
{ model->BSIM3nqsMod = 0;
|
||||||
|
printf("Warning: nqsMod has been set to its default value: 0.\n");
|
||||||
|
}
|
||||||
if (!model->BSIM3acnqsModGiven)
|
if (!model->BSIM3acnqsModGiven)
|
||||||
model->BSIM3acnqsMod = 0;
|
model->BSIM3acnqsMod = 0;
|
||||||
else if ((model->BSIM3acnqsMod != 0) && (model->BSIM3acnqsMod != 1))
|
else if ((model->BSIM3acnqsMod != 0) && (model->BSIM3acnqsMod != 1))
|
||||||
|
|
@ -247,6 +257,24 @@ BSIM3instance **InstArray;
|
||||||
if (!model->BSIM3tpbswgGiven)
|
if (!model->BSIM3tpbswgGiven)
|
||||||
model->BSIM3tpbswg = 0.0;
|
model->BSIM3tpbswg = 0.0;
|
||||||
|
|
||||||
|
/* ACM model */
|
||||||
|
if (!model->BSIM3hdifGiven)
|
||||||
|
model->BSIM3hdif = 0.0;
|
||||||
|
if (!model->BSIM3ldifGiven)
|
||||||
|
model->BSIM3ldif = 0.0;
|
||||||
|
if (!model->BSIM3ldGiven)
|
||||||
|
model->BSIM3ld = 0.0;
|
||||||
|
if (!model->BSIM3rdGiven)
|
||||||
|
model->BSIM3rd = 0.0;
|
||||||
|
if (!model->BSIM3rsGiven)
|
||||||
|
model->BSIM3rs = 0.0;
|
||||||
|
if (!model->BSIM3rdcGiven)
|
||||||
|
model->BSIM3rdc = 0.0;
|
||||||
|
if (!model->BSIM3rscGiven)
|
||||||
|
model->BSIM3rsc = 0.0;
|
||||||
|
if (!model->BSIM3wmltGiven)
|
||||||
|
model->BSIM3wmlt = 1.0;
|
||||||
|
|
||||||
/* Length dependence */
|
/* Length dependence */
|
||||||
if (!model->BSIM3lcdscGiven)
|
if (!model->BSIM3lcdscGiven)
|
||||||
model->BSIM3lcdsc = 0.0;
|
model->BSIM3lcdsc = 0.0;
|
||||||
|
|
@ -780,6 +808,12 @@ BSIM3instance **InstArray;
|
||||||
model->BSIM3dwc = model->BSIM3Wint;
|
model->BSIM3dwc = model->BSIM3Wint;
|
||||||
if (!model->BSIM3dlcGiven)
|
if (!model->BSIM3dlcGiven)
|
||||||
model->BSIM3dlc = model->BSIM3Lint;
|
model->BSIM3dlc = model->BSIM3Lint;
|
||||||
|
|
||||||
|
if (!model->BSIM3xlGiven)
|
||||||
|
model->BSIM3xl = 0.0;
|
||||||
|
if (!model->BSIM3xwGiven)
|
||||||
|
model->BSIM3xw = 0.0;
|
||||||
|
|
||||||
if (!model->BSIM3cfGiven)
|
if (!model->BSIM3cfGiven)
|
||||||
model->BSIM3cf = 2.0 * EPSOX / PI
|
model->BSIM3cf = 2.0 * EPSOX / PI
|
||||||
* log(1.0 + 0.4e-6 / model->BSIM3tox);
|
* log(1.0 + 0.4e-6 / model->BSIM3tox);
|
||||||
|
|
@ -874,7 +908,16 @@ BSIM3instance **InstArray;
|
||||||
if (!here->BSIM3drainPerimeterGiven)
|
if (!here->BSIM3drainPerimeterGiven)
|
||||||
here->BSIM3drainPerimeter = 0.0;
|
here->BSIM3drainPerimeter = 0.0;
|
||||||
if (!here->BSIM3drainSquaresGiven)
|
if (!here->BSIM3drainSquaresGiven)
|
||||||
here->BSIM3drainSquares = 1.0;
|
{
|
||||||
|
if (model->BSIM3acmMod == 0)
|
||||||
|
here->BSIM3drainSquares = 1.0;
|
||||||
|
else
|
||||||
|
here->BSIM3drainSquares = 0.0;
|
||||||
|
}
|
||||||
|
if (!here->BSIM3delvtoGiven)
|
||||||
|
here->BSIM3delvto = 0.0;
|
||||||
|
if (!here->BSIM3mulu0Given)
|
||||||
|
here->BSIM3mulu0 = 1.0;
|
||||||
if (!here->BSIM3icVBSGiven)
|
if (!here->BSIM3icVBSGiven)
|
||||||
here->BSIM3icVBS = 0.0;
|
here->BSIM3icVBS = 0.0;
|
||||||
if (!here->BSIM3icVDSGiven)
|
if (!here->BSIM3icVDSGiven)
|
||||||
|
|
@ -888,11 +931,21 @@ BSIM3instance **InstArray;
|
||||||
if (!here->BSIM3sourcePerimeterGiven)
|
if (!here->BSIM3sourcePerimeterGiven)
|
||||||
here->BSIM3sourcePerimeter = 0.0;
|
here->BSIM3sourcePerimeter = 0.0;
|
||||||
if (!here->BSIM3sourceSquaresGiven)
|
if (!here->BSIM3sourceSquaresGiven)
|
||||||
here->BSIM3sourceSquares = 1.0;
|
{
|
||||||
|
if (model->BSIM3acmMod == 0)
|
||||||
|
here->BSIM3sourceSquares = 1.0;
|
||||||
|
else
|
||||||
|
here->BSIM3sourceSquares = 0.0;
|
||||||
|
}
|
||||||
if (!here->BSIM3wGiven)
|
if (!here->BSIM3wGiven)
|
||||||
here->BSIM3w = 5.0e-6;
|
here->BSIM3w = 5.0e-6;
|
||||||
if (!here->BSIM3nqsModGiven)
|
if (!here->BSIM3nqsModGiven)
|
||||||
here->BSIM3nqsMod = 0;
|
here->BSIM3nqsMod = model->BSIM3nqsMod;
|
||||||
|
else if ((here->BSIM3nqsMod != 0) && (here->BSIM3nqsMod != 1))
|
||||||
|
{ here->BSIM3nqsMod = model->BSIM3nqsMod;
|
||||||
|
printf("Warning: nqsMod has been set to its global value %d.\n",
|
||||||
|
model->BSIM3nqsMod);
|
||||||
|
}
|
||||||
if (!here->BSIM3acnqsModGiven)
|
if (!here->BSIM3acnqsModGiven)
|
||||||
here->BSIM3acnqsMod = model->BSIM3acnqsMod;
|
here->BSIM3acnqsMod = model->BSIM3acnqsMod;
|
||||||
else if ((here->BSIM3acnqsMod != 0) && (here->BSIM3acnqsMod != 1))
|
else if ((here->BSIM3acnqsMod != 0) && (here->BSIM3acnqsMod != 1))
|
||||||
|
|
@ -900,14 +953,19 @@ BSIM3instance **InstArray;
|
||||||
printf("Warning: acnqsMod has been set to its global value %d.\n",
|
printf("Warning: acnqsMod has been set to its global value %d.\n",
|
||||||
model->BSIM3acnqsMod);
|
model->BSIM3acnqsMod);
|
||||||
}
|
}
|
||||||
|
if (!here->BSIM3geoGiven)
|
||||||
|
here->BSIM3geo = 0;
|
||||||
|
|
||||||
if (!here->BSIM3mGiven)
|
if (!here->BSIM3mGiven)
|
||||||
here->BSIM3m = 1;
|
here->BSIM3m = 1;
|
||||||
|
|
||||||
/* process drain series resistance */
|
/* process drain series resistance */
|
||||||
if ((model->BSIM3sheetResistance > 0.0) &&
|
if ( ((model->BSIM3sheetResistance > 0.0) && (here->BSIM3drainSquares > 0.0))
|
||||||
(here->BSIM3drainSquares > 0.0 ))
|
||((model->BSIM3sheetResistance > 0.0) && (model->BSIM3hdif > 0.0))
|
||||||
|
||((model->BSIM3rd > 0.0) && (model->BSIM3ldif > 0.0))
|
||||||
|
||((model->BSIM3rd > 0.0) && (model->BSIM3ld > 0.0))
|
||||||
|
||((model->BSIM3rdc > 0.0))
|
||||||
|
)
|
||||||
{
|
{
|
||||||
if(here->BSIM3dNodePrime == 0) {
|
if(here->BSIM3dNodePrime == 0) {
|
||||||
error = CKTmkVolt(ckt,&tmp,here->BSIM3name,"drain");
|
error = CKTmkVolt(ckt,&tmp,here->BSIM3name,"drain");
|
||||||
|
|
@ -928,8 +986,12 @@ BSIM3instance **InstArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* process source series resistance */
|
/* process source series resistance */
|
||||||
if ((model->BSIM3sheetResistance > 0.0) &&
|
if ( ((model->BSIM3sheetResistance > 0.0) && (here->BSIM3sourceSquares > 0.0))
|
||||||
(here->BSIM3sourceSquares > 0.0 ))
|
||((model->BSIM3sheetResistance > 0.0) && (model->BSIM3hdif > 0.0))
|
||||||
|
||((model->BSIM3rs > 0.0) && (model->BSIM3ldif > 0.0))
|
||||||
|
||((model->BSIM3rs > 0.0) && (model->BSIM3ld > 0.0))
|
||||||
|
||((model->BSIM3rsc > 0.0))
|
||||||
|
)
|
||||||
{
|
{
|
||||||
if(here->BSIM3sNodePrime == 0) {
|
if(here->BSIM3sNodePrime == 0) {
|
||||||
error = CKTmkVolt(ckt,&tmp,here->BSIM3name,"source");
|
error = CKTmkVolt(ckt,&tmp,here->BSIM3name,"source");
|
||||||
|
|
@ -967,43 +1029,43 @@ BSIM3instance **InstArray;
|
||||||
|
|
||||||
/* macro to make elements with built in test for out of memory */
|
/* macro to make elements with built in test for out of memory */
|
||||||
#define TSTALLOC(ptr,first,second) \
|
#define TSTALLOC(ptr,first,second) \
|
||||||
if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\
|
do { if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\
|
||||||
return(E_NOMEM);\
|
return(E_NOMEM);\
|
||||||
}
|
} } while(0)
|
||||||
|
|
||||||
TSTALLOC(BSIM3DdPtr, BSIM3dNode, BSIM3dNode)
|
TSTALLOC(BSIM3DdPtr, BSIM3dNode, BSIM3dNode);
|
||||||
TSTALLOC(BSIM3GgPtr, BSIM3gNode, BSIM3gNode)
|
TSTALLOC(BSIM3GgPtr, BSIM3gNode, BSIM3gNode);
|
||||||
TSTALLOC(BSIM3SsPtr, BSIM3sNode, BSIM3sNode)
|
TSTALLOC(BSIM3SsPtr, BSIM3sNode, BSIM3sNode);
|
||||||
TSTALLOC(BSIM3BbPtr, BSIM3bNode, BSIM3bNode)
|
TSTALLOC(BSIM3BbPtr, BSIM3bNode, BSIM3bNode);
|
||||||
TSTALLOC(BSIM3DPdpPtr, BSIM3dNodePrime, BSIM3dNodePrime)
|
TSTALLOC(BSIM3DPdpPtr, BSIM3dNodePrime, BSIM3dNodePrime);
|
||||||
TSTALLOC(BSIM3SPspPtr, BSIM3sNodePrime, BSIM3sNodePrime)
|
TSTALLOC(BSIM3SPspPtr, BSIM3sNodePrime, BSIM3sNodePrime);
|
||||||
TSTALLOC(BSIM3DdpPtr, BSIM3dNode, BSIM3dNodePrime)
|
TSTALLOC(BSIM3DdpPtr, BSIM3dNode, BSIM3dNodePrime);
|
||||||
TSTALLOC(BSIM3GbPtr, BSIM3gNode, BSIM3bNode)
|
TSTALLOC(BSIM3GbPtr, BSIM3gNode, BSIM3bNode);
|
||||||
TSTALLOC(BSIM3GdpPtr, BSIM3gNode, BSIM3dNodePrime)
|
TSTALLOC(BSIM3GdpPtr, BSIM3gNode, BSIM3dNodePrime);
|
||||||
TSTALLOC(BSIM3GspPtr, BSIM3gNode, BSIM3sNodePrime)
|
TSTALLOC(BSIM3GspPtr, BSIM3gNode, BSIM3sNodePrime);
|
||||||
TSTALLOC(BSIM3SspPtr, BSIM3sNode, BSIM3sNodePrime)
|
TSTALLOC(BSIM3SspPtr, BSIM3sNode, BSIM3sNodePrime);
|
||||||
TSTALLOC(BSIM3BdpPtr, BSIM3bNode, BSIM3dNodePrime)
|
TSTALLOC(BSIM3BdpPtr, BSIM3bNode, BSIM3dNodePrime);
|
||||||
TSTALLOC(BSIM3BspPtr, BSIM3bNode, BSIM3sNodePrime)
|
TSTALLOC(BSIM3BspPtr, BSIM3bNode, BSIM3sNodePrime);
|
||||||
TSTALLOC(BSIM3DPspPtr, BSIM3dNodePrime, BSIM3sNodePrime)
|
TSTALLOC(BSIM3DPspPtr, BSIM3dNodePrime, BSIM3sNodePrime);
|
||||||
TSTALLOC(BSIM3DPdPtr, BSIM3dNodePrime, BSIM3dNode)
|
TSTALLOC(BSIM3DPdPtr, BSIM3dNodePrime, BSIM3dNode);
|
||||||
TSTALLOC(BSIM3BgPtr, BSIM3bNode, BSIM3gNode)
|
TSTALLOC(BSIM3BgPtr, BSIM3bNode, BSIM3gNode);
|
||||||
TSTALLOC(BSIM3DPgPtr, BSIM3dNodePrime, BSIM3gNode)
|
TSTALLOC(BSIM3DPgPtr, BSIM3dNodePrime, BSIM3gNode);
|
||||||
TSTALLOC(BSIM3SPgPtr, BSIM3sNodePrime, BSIM3gNode)
|
TSTALLOC(BSIM3SPgPtr, BSIM3sNodePrime, BSIM3gNode);
|
||||||
TSTALLOC(BSIM3SPsPtr, BSIM3sNodePrime, BSIM3sNode)
|
TSTALLOC(BSIM3SPsPtr, BSIM3sNodePrime, BSIM3sNode);
|
||||||
TSTALLOC(BSIM3DPbPtr, BSIM3dNodePrime, BSIM3bNode)
|
TSTALLOC(BSIM3DPbPtr, BSIM3dNodePrime, BSIM3bNode);
|
||||||
TSTALLOC(BSIM3SPbPtr, BSIM3sNodePrime, BSIM3bNode)
|
TSTALLOC(BSIM3SPbPtr, BSIM3sNodePrime, BSIM3bNode);
|
||||||
TSTALLOC(BSIM3SPdpPtr, BSIM3sNodePrime, BSIM3dNodePrime)
|
TSTALLOC(BSIM3SPdpPtr, BSIM3sNodePrime, BSIM3dNodePrime);
|
||||||
|
|
||||||
TSTALLOC(BSIM3QqPtr, BSIM3qNode, BSIM3qNode)
|
TSTALLOC(BSIM3QqPtr, BSIM3qNode, BSIM3qNode);
|
||||||
|
|
||||||
TSTALLOC(BSIM3QdpPtr, BSIM3qNode, BSIM3dNodePrime)
|
TSTALLOC(BSIM3QdpPtr, BSIM3qNode, BSIM3dNodePrime);
|
||||||
TSTALLOC(BSIM3QspPtr, BSIM3qNode, BSIM3sNodePrime)
|
TSTALLOC(BSIM3QspPtr, BSIM3qNode, BSIM3sNodePrime);
|
||||||
TSTALLOC(BSIM3QgPtr, BSIM3qNode, BSIM3gNode)
|
TSTALLOC(BSIM3QgPtr, BSIM3qNode, BSIM3gNode);
|
||||||
TSTALLOC(BSIM3QbPtr, BSIM3qNode, BSIM3bNode)
|
TSTALLOC(BSIM3QbPtr, BSIM3qNode, BSIM3bNode);
|
||||||
TSTALLOC(BSIM3DPqPtr, BSIM3dNodePrime, BSIM3qNode)
|
TSTALLOC(BSIM3DPqPtr, BSIM3dNodePrime, BSIM3qNode);
|
||||||
TSTALLOC(BSIM3SPqPtr, BSIM3sNodePrime, BSIM3qNode)
|
TSTALLOC(BSIM3SPqPtr, BSIM3sNodePrime, BSIM3qNode);
|
||||||
TSTALLOC(BSIM3GqPtr, BSIM3gNode, BSIM3qNode)
|
TSTALLOC(BSIM3GqPtr, BSIM3gNode, BSIM3qNode);
|
||||||
TSTALLOC(BSIM3BqPtr, BSIM3bNode, BSIM3qNode)
|
TSTALLOC(BSIM3BqPtr, BSIM3bNode, BSIM3qNode);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue