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
|
||||
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
|
||||
|
||||
|
|
@ -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
|
||||
|
||||
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
|
||||
(*.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 *
|
||||
***************************************************************************
|
||||
|
||||
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
|
||||
|
||||
|
|
|
|||
16
configure.ac
16
configure.ac
|
|
@ -182,6 +182,10 @@ AC_ARG_WITH([tcl],
|
|||
AC_ARG_WITH([ngshared],
|
||||
[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
|
||||
if test "x$with_editline" = 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
|
||||
AC_DEFINE([WANT_SENSE2], [], [Define if we want spice2 sensitivity analysis])
|
||||
AC_MSG_RESULT([Spice2 sensitivity analysis enabled])
|
||||
AC_MSG_WARN([This feature is UNSUPPORTED])
|
||||
fi
|
||||
if test "x$enable_nobypass" = xyes; then
|
||||
AC_DEFINE([NOBYPASS], [], [Define if we want NOBYPASS])
|
||||
|
|
@ -856,7 +861,7 @@ if test "x$enable_pzdebug" = xyes; then
|
|||
fi
|
||||
if test "x$enable_pss" = xyes; then
|
||||
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
|
||||
if test "x$enable_blktmsdebug" = xyes; then
|
||||
AC_DEFINE([D_DBG_BLOCKTIMES], [], [Define if we want debug distortion analysis (BLOCKTIMES)])
|
||||
|
|
@ -879,6 +884,12 @@ fi
|
|||
AC_SUBST([XGRAPHDIR])
|
||||
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])
|
||||
|
||||
################# 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([SENSE2_WANTED], [test "x$enable_sense2" = xyes])
|
||||
|
||||
# adms option
|
||||
if test "x$enable_adms" = xyes ; then
|
||||
AC_MSG_RESULT([**********************************
|
||||
|
|
@ -1216,6 +1229,7 @@ AC_CONFIG_FILES([Makefile
|
|||
src/xspice/enh/Makefile
|
||||
src/xspice/ipc/Makefile
|
||||
src/xspice/idn/Makefile
|
||||
src/unsupported/Makefile
|
||||
tests/Makefile
|
||||
tests/bsim1/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
|
||||
|
||||
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
|
||||
SUBDIRS += xspice
|
||||
|
|
@ -11,6 +11,10 @@ if CIDER_WANTED
|
|||
SUBDIRS += ciderlib
|
||||
endif
|
||||
|
||||
if SENSE2_WANTED
|
||||
SUBDIRS += unsupported
|
||||
endif
|
||||
|
||||
if !TCL_MODULE
|
||||
if !SHARED_MODULE
|
||||
bin_PROGRAMS = ngspice ngnutmeg
|
||||
|
|
@ -27,7 +31,7 @@ endif !SHARED_MODULE
|
|||
endif !TCL_MODULE
|
||||
|
||||
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 \
|
||||
main.c sharedspice.c
|
||||
|
||||
|
|
@ -137,6 +141,10 @@ ngspice_LDADD += \
|
|||
spicelib/analysis/libckt.la \
|
||||
spicelib/devices/libdev.la
|
||||
|
||||
if SENSE2_WANTED
|
||||
ngspice_LDADD += unsupported/libunsupported.la
|
||||
endif
|
||||
|
||||
if XSPICE_WANTED
|
||||
ngspice_LDADD += \
|
||||
xspice/cm/libcmxsp.la \
|
||||
|
|
|
|||
|
|
@ -50,9 +50,10 @@ static char *upper(register char *string);
|
|||
static bool doedit(char *filename);
|
||||
static struct line *com_options = NULL;
|
||||
static void cktislinear(CKTcircuit *ckt, struct line *deck);
|
||||
static void dotifeval(struct line *deck);
|
||||
|
||||
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*/
|
||||
if (!options && com_options)
|
||||
options = com_options;
|
||||
|
|
@ -1199,3 +1203,71 @@ com_circbyline(wordlist *wl)
|
|||
char *newline = wl_flatten(wl);
|
||||
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);
|
||||
}
|
||||
|
||||
/* 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
|
||||
by fcn inp_spsource() in inp.c:575.
|
||||
A typical .meas card will contain:
|
||||
|
|
|
|||
|
|
@ -189,6 +189,11 @@ com_version(wordlist *wl)
|
|||
fprintf(cp_out, "** %s\n", Spice_Notice);
|
||||
if (Spice_Build_Date != NULL && *Spice_Build_Date != 0)
|
||||
fprintf(cp_out, "** Creation Date: %s\n", Spice_Build_Date);
|
||||
|
||||
#ifdef KIRCHHOFF
|
||||
fprintf(cp_out, "** KCL Verification enabled.\n");
|
||||
#endif
|
||||
|
||||
fprintf(cp_out, "******\n");
|
||||
|
||||
} else {
|
||||
|
|
@ -279,6 +284,9 @@ com_version(wordlist *wl)
|
|||
#endif
|
||||
#ifdef EXP_DEV
|
||||
fprintf(cp_out, "** Experimental devices enabled.\n");
|
||||
#endif
|
||||
#ifdef KIRCHHOFF
|
||||
fprintf(cp_out, "** KCL Verification enabled.\n");
|
||||
#endif
|
||||
fprintf(cp_out, "******\n");
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ typedef enum {Nodekey = '#'} _nNodekey; /* Introduces node symbol */
|
|||
typedef enum {Intro = '&'} _nIntro; /* Introduces preprocessor tokens */
|
||||
typedef enum {Comment = '*'} _nComment; /* Spice Comment lines */
|
||||
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) */
|
||||
|
||||
typedef char *auxtable; /* dummy */
|
||||
|
|
|
|||
|
|
@ -243,6 +243,11 @@ modernizeex(SPICE_DSTRINGPTR dstr_p)
|
|||
state = 0;
|
||||
ls = spice_dstring_length(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);
|
||||
|
||||
while (i < ls) {
|
||||
|
|
|
|||
|
|
@ -88,8 +88,7 @@ initkeys(void)
|
|||
{
|
||||
spice_dstring_init(&keyS);
|
||||
scopy_up(&keyS,
|
||||
"and or not div mod if else end while macro funct defined"
|
||||
" include for to downto is var");
|
||||
"and or not div mod defined");
|
||||
scopy_up(&fmathS,
|
||||
"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");
|
||||
|
|
@ -935,7 +934,7 @@ opfunctkey(tdico *dico,
|
|||
/*if kw operator keyword, c=token*/
|
||||
switch (kw)
|
||||
{
|
||||
/* & | ~ DIV MOD Defined */
|
||||
/* & | ~ DIV MOD Defined */
|
||||
case 1:
|
||||
c = '&';
|
||||
state = 2;
|
||||
|
|
|
|||
|
|
@ -81,10 +81,10 @@ static IFvalue *doask(CKTcircuit *ckt, int typecode, GENinstance *dev, GENmodel
|
|||
IFparm *opt, int ind);
|
||||
static int doset(CKTcircuit *ckt, int typecode, GENinstance *dev, GENmodel *mod,
|
||||
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 */
|
||||
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. */
|
||||
|
|
@ -252,8 +252,7 @@ if_run(CKTcircuit *ckt, char *what, wordlist *args, INPtables *tab)
|
|||
/*CDHW Create an interactive task AAA with a new UID.
|
||||
ci_specTask will point to it CDHW*/
|
||||
|
||||
err = IFnewUid(ft_curckt->ci_ckt, &specUid, NULL, "special",
|
||||
UID_TASK, NULL);
|
||||
err = IFnewUid(ft_curckt->ci_ckt, &specUid, NULL, "special", UID_TASK, NULL);
|
||||
if (err) {
|
||||
ft_sperror(err, "newUid");
|
||||
return (2);
|
||||
|
|
@ -281,8 +280,7 @@ if_run(CKTcircuit *ckt, char *what, wordlist *args, INPtables *tab)
|
|||
}
|
||||
|
||||
if (which != -1) { /*CDHW options are available CDHW*/
|
||||
err = IFnewUid(ft_curckt->ci_ckt, &optUid, NULL, "options",
|
||||
UID_ANALYSIS, NULL);
|
||||
err = IFnewUid(ft_curckt->ci_ckt, &optUid, NULL, "options", UID_ANALYSIS, NULL);
|
||||
if (err) {
|
||||
ft_sperror(err, "newUid");
|
||||
return (2);
|
||||
|
|
@ -616,7 +614,7 @@ finddev_special(
|
|||
int err;
|
||||
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) {
|
||||
*device_or_model = 0;
|
||||
return (type);
|
||||
|
|
@ -1212,19 +1210,19 @@ doset(CKTcircuit *ckt, int typecode, GENinstance *dev, GENmodel *mod, IFparm *op
|
|||
*/
|
||||
|
||||
static int
|
||||
finddev(CKTcircuit *ck, char *name, GENinstance **devptr, GENmodel **modptr)
|
||||
finddev(CKTcircuit *ckt, char *name, GENinstance **devptr, GENmodel **modptr)
|
||||
{
|
||||
int err;
|
||||
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)
|
||||
return (type);
|
||||
|
||||
type = -1;
|
||||
*devptr = NULL;
|
||||
|
||||
err = ft_sim->findModel (ck, &type, modptr, name);
|
||||
err = ft_sim->findModel (ckt, &type, modptr, name);
|
||||
if (err == OK)
|
||||
return (type);
|
||||
|
||||
|
|
@ -1273,8 +1271,7 @@ if_tranparams(struct circ *ci, double *start, double *stop, double *step)
|
|||
if (which == -1)
|
||||
return (FALSE);
|
||||
|
||||
err = IFnewUid(ci->ci_ckt, &tranUid, NULL, "Transient Analysis",
|
||||
UID_ANALYSIS, NULL);
|
||||
err = IFnewUid(ci->ci_ckt, &tranUid, NULL, "Transient Analysis", UID_ANALYSIS, NULL);
|
||||
if (err != OK)
|
||||
return (FALSE);
|
||||
|
||||
|
|
@ -1616,11 +1613,11 @@ void com_snload(wordlist *wl)
|
|||
return;
|
||||
}
|
||||
SPfrontEnd->IFnewUid (ckt, &timeUid, NULL, "time", UID_OTHER, NULL);
|
||||
error = SPfrontEnd->OUTpBeginPlot (
|
||||
ckt, ckt->CKTcurJob,
|
||||
ckt->CKTcurJob->JOBname,
|
||||
timeUid, IF_REAL,
|
||||
numNames, nameList, IF_REAL, &(((TRANan*)ckt->CKTcurJob)->TRANplot));
|
||||
error = SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
|
||||
ckt->CKTcurJob->JOBname,
|
||||
timeUid, IF_REAL,
|
||||
numNames, nameList, IF_REAL,
|
||||
&(((TRANan*)ckt->CKTcurJob)->TRANplot));
|
||||
if (error) {
|
||||
fprintf(cp_err, "error in CKTnames\n");
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -1815,6 +1815,7 @@ devmodtranslate(struct line *deck, char *subname, wordlist * const submod)
|
|||
|
||||
case 'r':
|
||||
case 'c':
|
||||
case 'l':
|
||||
name = gettok(&t); /* get refdes */
|
||||
(void) sprintf(buffer, "%s ", name);
|
||||
tfree(name);
|
||||
|
|
@ -1967,7 +1968,7 @@ devmodtranslate(struct line *deck, char *subname, wordlist * const submod)
|
|||
name = gettok(&t);
|
||||
|
||||
found = 0;
|
||||
while (*t && !found) {
|
||||
while (!found) {
|
||||
/* Now, is this a subcircuit model? */
|
||||
for (wlsub = submod; wlsub; wlsub = wlsub->wl_next) {
|
||||
/* FIXME, probably too unspecific */
|
||||
|
|
@ -1994,6 +1995,10 @@ devmodtranslate(struct line *deck, char *subname, wordlist * const submod)
|
|||
(void) sprintf(buffer + strlen(buffer), "%s ", name);
|
||||
tfree(name);
|
||||
name = gettok(&t);
|
||||
if (name == NULL) {
|
||||
name = copy(""); /* allow 'tfree' */
|
||||
break;
|
||||
}
|
||||
}
|
||||
} /* while */
|
||||
|
||||
|
|
|
|||
|
|
@ -56,6 +56,12 @@ struct CKTnode {
|
|||
#define PARM_IC 2
|
||||
#define PARM_NODETYPE 3
|
||||
|
||||
#ifdef KIRCHHOFF
|
||||
typedef struct sCKTmkCurKCLnode {
|
||||
double KCLcurrent ;
|
||||
struct sCKTmkCurKCLnode *next ;
|
||||
} CKTmkCurKCLnode ;
|
||||
#endif
|
||||
|
||||
struct CKTcircuit {
|
||||
|
||||
|
|
@ -110,6 +116,13 @@ struct CKTcircuit {
|
|||
double *CKTrhs; /* current rhs value - being loaded */
|
||||
double *CKTrhsOld; /* previous rhs value for convergence
|
||||
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 *CKTirhs; /* current rhs value - being loaded
|
||||
(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 ACaskQuest(CKTcircuit *, JOB *, int , IFvalue *);
|
||||
|
|
@ -321,7 +338,7 @@ extern void NDEVacct(CKTcircuit *ckt, FILE *file);
|
|||
extern void CKTncDump(CKTcircuit *);
|
||||
extern int CKTfndAnal(CKTcircuit *, int *, JOB **, IFuid , TSKtask *, 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 CKTfndNode(CKTcircuit *, CKTnode **, IFuid);
|
||||
extern int CKTfndTask(CKTcircuit *, TSKtask **, IFuid );
|
||||
|
|
@ -387,10 +404,14 @@ extern int PZinit(CKTcircuit *);
|
|||
extern int PZpost(CKTcircuit *);
|
||||
extern int PZaskQuest(CKTcircuit *, JOB *, int , IFvalue *);
|
||||
extern int PZsetParm(CKTcircuit *, JOB *, int , IFvalue *);
|
||||
|
||||
#ifdef WANT_SENSE2
|
||||
extern int SENaskQuest(CKTcircuit *, JOB *, int , IFvalue *);
|
||||
extern void SENdestroy(SENstruct *);
|
||||
extern int SENsetParm(CKTcircuit *, JOB *, int , IFvalue *);
|
||||
extern int SENstartup(CKTcircuit *);
|
||||
extern int SENstartup(CKTcircuit *, int);
|
||||
#endif
|
||||
|
||||
extern int SPIinit(IFfrontEnd *, IFsimulator **);
|
||||
extern int TFanal(CKTcircuit *, int);
|
||||
extern int TFaskQuest(CKTcircuit *, JOB *, int , IFvalue *);
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@
|
|||
/* Alternate initialisation file name */
|
||||
#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_TERM '\\'
|
||||
#define DIR_PATHSEP_LINUX "/"
|
||||
|
|
|
|||
|
|
@ -28,10 +28,21 @@ double limitJunctionVoltage( double, double, int * );
|
|||
double limitVbe( double, double, int * );
|
||||
double limitVce( 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 {
|
||||
IFdevice DEVpublic;
|
||||
|
|
@ -110,6 +121,12 @@ typedef struct SPICEdev {
|
|||
/* routine to convert Complex CSC array to Real CSC array */
|
||||
#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 */
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -370,7 +370,7 @@ struct IFsimulator {
|
|||
/* set a parameter on an instance */
|
||||
int (*askInstanceQuest) (CKTcircuit *, GENinstance *, int, IFvalue *, IFvalue *);
|
||||
/* 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 */
|
||||
int (*deleteInstance) (CKTcircuit *, void *);
|
||||
/* delete an instance from the circuit */
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
**********/
|
||||
|
||||
/* a couple of macros to make much of the input code
|
||||
* 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
|
||||
* error
|
||||
*/
|
||||
#define IFC(func,args)\
|
||||
error=(*(ft_sim->func))args;\
|
||||
if(error)current->error = INPerrCat(current->error,INPerror(error));
|
||||
|
||||
#define IFC(func, args) \
|
||||
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
|
||||
* 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
|
||||
*/
|
||||
#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
|
||||
* 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_LE0 29
|
||||
#define PTF_POW 30
|
||||
#define PTF_MIN 31
|
||||
#define PTF_MAX 32
|
||||
#define PTF_CEIL 33
|
||||
#define PTF_FLOOR 34
|
||||
#define PTF_PWR 31
|
||||
#define PTF_MIN 32
|
||||
#define PTF_MAX 33
|
||||
#define PTF_CEIL 34
|
||||
#define PTF_FLOOR 35
|
||||
|
||||
/* The following things are used by the parser -- these are the token types the
|
||||
* lexer returns.
|
||||
|
|
|
|||
|
|
@ -43,11 +43,12 @@
|
|||
#define NIL(type) ((type *)0)
|
||||
#define ABORT() fflush(stderr);fflush(stdout);abort();
|
||||
|
||||
#define MERROR(CODE,MESSAGE) { \
|
||||
errMsg = TMALLOC(char, strlen(MESSAGE) + 1); \
|
||||
strcpy(errMsg, (MESSAGE)); \
|
||||
return (CODE); \
|
||||
}
|
||||
#define MERROR(CODE, MESSAGE) \
|
||||
do { \
|
||||
errMsg = TMALLOC(char, strlen(MESSAGE) + 1); \
|
||||
strcpy(errMsg, (MESSAGE)); \
|
||||
return (CODE); \
|
||||
} while(0)
|
||||
|
||||
#define NEW(TYPE) (TMALLOC(TYPE, 1))
|
||||
#define NEWN(TYPE,COUNT) (TMALLOC(TYPE, COUNT))
|
||||
|
|
|
|||
|
|
@ -112,7 +112,9 @@ struct ngcomplex {
|
|||
typedef struct ngcomplex ngcomplex_t;
|
||||
#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 {
|
||||
char *v_name; /* Same as so_vname. */
|
||||
int v_type; /* Same as so_vtype. */
|
||||
|
|
@ -123,16 +125,17 @@ typedef struct vector_info {
|
|||
} vector_info, *pvector_info;
|
||||
|
||||
typedef struct vecvalues {
|
||||
char* name;
|
||||
double creal;
|
||||
double cimag;
|
||||
bool is_scale;
|
||||
bool is_complex;
|
||||
char* name; /* name of a specific vector */
|
||||
double creal; /* actual data value */
|
||||
double cimag; /* actual data value */
|
||||
bool is_scale;/* if 'name' is the scale vector */
|
||||
bool is_complex;/* if the data are complex numbers */
|
||||
} vecvalues, *pvecvalues;
|
||||
|
||||
typedef struct vecvaluesall {
|
||||
int veccount;
|
||||
pvecvalues *vecsa;
|
||||
int veccount; /* number of vectors in plot */
|
||||
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;
|
||||
|
||||
/* info for a specific vector */
|
||||
|
|
@ -206,6 +209,18 @@ typedef int (BGThreadRunning)(bool, void*);
|
|||
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,
|
||||
printfcn: pointer to callback function for reading printf, fprintf
|
||||
|
|
@ -220,6 +235,12 @@ IMPEXP
|
|||
int ngSpice_Init(SendChar* printfcn, SendStat* statfcn, ControlledExit* ngexit,
|
||||
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.
|
||||
Commands are executed immediately */
|
||||
|
|
@ -260,6 +281,10 @@ char** ngSpice_AllVecs(char* plotname);
|
|||
IMPEXP
|
||||
bool ngSpice_running(void);
|
||||
|
||||
/* set a breakpoint in ngspice */
|
||||
IMPEXP
|
||||
bool ngSpice_SetBkpt(double time);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
|||
|
|
@ -122,8 +122,8 @@ void SMPgetError( SMPmatrix *, int *, int *);
|
|||
int SMPcProdDiag( SMPmatrix *, SPcomplex *, int *);
|
||||
int SMPcDProd(SMPmatrix *Matrix, SPcomplex *pMantissa, int *pExponent);
|
||||
SMPelement * SMPfindElt( SMPmatrix *, int , int , int );
|
||||
int SMPcZeroCol(SMPmatrix *eMatrix, int Col);
|
||||
int SMPcAddCol(SMPmatrix *eMatrix, int Accum_Col, int Addend_Col);
|
||||
int SMPzeroRow(SMPmatrix *eMatrix, int Row);
|
||||
int SMPcZeroCol(SMPmatrix *Matrix, int Col);
|
||||
int SMPcAddCol(SMPmatrix *Matrix, int Accum_Col, int Addend_Col);
|
||||
int SMPzeroRow(SMPmatrix *Matrix, int Row);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -263,7 +263,7 @@ extern int spFileMatrix( MatrixPtr, char *, char *, int, int, int );
|
|||
extern int spFileStats( MatrixPtr, char *, char * );
|
||||
extern int spFillinCount( MatrixPtr );
|
||||
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 void *spGetInitInfo( spREAL* );
|
||||
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;
|
||||
|
||||
union {
|
||||
double d;
|
||||
int64_t i;
|
||||
} uA, uB;
|
||||
|
||||
if (A == B)
|
||||
return TRUE;
|
||||
|
||||
|
|
@ -34,12 +39,14 @@ bool AlmostEqualUlps(double A, double B, int maxUlps)
|
|||
/* default NAN won't compare as equal to anything. */
|
||||
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 */
|
||||
if (aInt < 0)
|
||||
aInt = int64_min - aInt;
|
||||
|
||||
bInt = *(int64_t*)&B;
|
||||
uB.d = B;
|
||||
bInt = uB.i;
|
||||
/* Make bInt lexicographically ordered as a twos-complement int */
|
||||
if (bInt < 0)
|
||||
bInt = int64_min - bInt;
|
||||
|
|
|
|||
|
|
@ -7,6 +7,9 @@ Author: 1985 Thomas L. Quarles
|
|||
#include "ngspice/cktdefs.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
|
||||
NIcomCof(CKTcircuit *ckt)
|
||||
|
|
@ -17,6 +20,7 @@ NIcomCof(CKTcircuit *ckt)
|
|||
double arg;
|
||||
double arg1;
|
||||
|
||||
|
||||
/* this routine calculates the timestep-dependent terms used in the
|
||||
* numerical integration.
|
||||
*/
|
||||
|
|
@ -35,10 +39,8 @@ NIcomCof(CKTcircuit *ckt)
|
|||
break;
|
||||
|
||||
case 2:
|
||||
ckt->CKTag[0]=1.0/ckt->CKTdelta/(1.0-0.5) ;
|
||||
ckt->CKTag[1]=0.5/(1.0 - 0.5) ;
|
||||
/* above lines should have 'xmu' instead of .5 eventually */
|
||||
/* (in all three places) */
|
||||
ckt->CKTag[0] = 1.0 / ckt->CKTdelta/(1.0 - xmu) ;
|
||||
ckt->CKTag[1] = xmu / (1.0 - xmu) ;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -15,62 +15,124 @@ Author: 1985 Thomas L. Quarles
|
|||
#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;
|
||||
size = SMPmatSize(ckt->CKTmatrix);
|
||||
int
|
||||
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
|
||||
for (i=1;i<=size;i++) {
|
||||
new = ckt->CKTrhs [i] ;
|
||||
old = ckt->CKTrhsOld [i] ;
|
||||
printf("chk for convergence: %s new: %g old: %g\n",CKTnodName(ckt,i),new,old);
|
||||
int j ;
|
||||
#endif
|
||||
#else
|
||||
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 */
|
||||
for (i=1;i<=size;i++) {
|
||||
node = node->next;
|
||||
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 ) {
|
||||
#endif
|
||||
|
||||
for (i = 1 ; i <= size ; i++)
|
||||
{
|
||||
node = node->next ;
|
||||
|
||||
#ifdef KIRCHHOFF
|
||||
/* KCL Verification */
|
||||
if ((node->type == SP_VOLTAGE) && (!ckt->CKTnodeIsLinear [i]))
|
||||
{
|
||||
maximum = 0 ;
|
||||
ptr = ckt->CKTmkCurKCLarray [i] ;
|
||||
|
||||
#ifdef STEPDEBUG
|
||||
printf(" non-convergence at node (type=3) %s (fabs(new-old)>tol --> fabs(%g-%g)>%g)\n",CKTnodName(ckt,i),new,old,tol);
|
||||
printf(" reltol: %g voltTol: %g (tol=reltol*(MAX(fabs(old),fabs(new))) + voltTol)\n",ckt->CKTreltol,ckt->CKTvoltTol);
|
||||
j = 0 ;
|
||||
#endif
|
||||
|
||||
while (ptr != NULL)
|
||||
{
|
||||
if (maximum < fabs (ptr->KCLcurrent))
|
||||
maximum = fabs (ptr->KCLcurrent) ;
|
||||
|
||||
#ifdef STEPDEBUG
|
||||
fprintf (stderr, "Index KCL Array: %d\tValue: %-.9g\tMaximum: %-.9g\n", j, fabs (ptr->KCLcurrent), maximum) ;
|
||||
j++ ;
|
||||
#endif
|
||||
|
||||
ptr = ptr->next ;
|
||||
}
|
||||
|
||||
#ifdef STEPDEBUG
|
||||
fprintf (stderr, "Index: %d\tValue: %-.9g\tThreshold: %-.9g\tMaximum: %-.9g\n", i, fabs (ckt->CKTfvk [i]),
|
||||
ckt->CKTreltol * maximum + ckt->CKTabstol, maximum) ;
|
||||
#endif
|
||||
|
||||
/* 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 */
|
||||
ckt->CKTtroubleNode = i;
|
||||
ckt->CKTtroubleElt = NULL;
|
||||
return(1);
|
||||
|
||||
ckt->CKTtroubleNode = i ;
|
||||
ckt->CKTtroubleElt = NULL ;
|
||||
return 1 ;
|
||||
}
|
||||
} else {
|
||||
tol = ckt->CKTreltol * (MAX(fabs(old),fabs(new))) +
|
||||
ckt->CKTabstol;
|
||||
if (fabs(new-old) >tol ) {
|
||||
tol = ckt->CKTreltol * (MAX (fabs (old), fabs (new))) + ckt->CKTabstol ;
|
||||
if (fabs (new - old) > tol)
|
||||
{
|
||||
|
||||
#ifdef STEPDEBUG
|
||||
printf(" non-convergence at node (type=%d) %s (fabs(new-old)>tol --> fabs(%g-%g)>%g)\n",node->type,CKTnodName(ckt,i),new,old,tol);
|
||||
printf(" reltol: %g abstol: %g (tol=reltol*(MAX(fabs(old),fabs(new))) + abstol)\n",ckt->CKTreltol,ckt->CKTabstol);
|
||||
fprintf (err, " 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, " reltol: %g abstol: %g (tol=reltol*(MAX(fabs(old),fabs(new))) + abstol)\n", ckt->CKTreltol, ckt->CKTabstol) ;
|
||||
#endif /* STEPDEBUG */
|
||||
ckt->CKTtroubleNode = i;
|
||||
ckt->CKTtroubleElt = NULL;
|
||||
return(1);
|
||||
|
||||
ckt->CKTtroubleNode = i ;
|
||||
ckt->CKTtroubleElt = NULL ;
|
||||
return 1 ;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#ifdef KIRCHHOFF
|
||||
return 0 ;
|
||||
#else
|
||||
#ifdef NEWCONV
|
||||
i = CKTconvTest(ckt);
|
||||
i = CKTconvTest (ckt) ;
|
||||
if (i)
|
||||
ckt->CKTtroubleNode = 0;
|
||||
return(i);
|
||||
ckt->CKTtroubleNode = 0 ;
|
||||
return i ;
|
||||
#else /* NEWCONV */
|
||||
return(0);
|
||||
return 0 ;
|
||||
#endif /* NEWCONV */
|
||||
#endif /* KIRCHHOFF */
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,9 +22,10 @@ int
|
|||
NIreinit( CKTcircuit *ckt)
|
||||
{
|
||||
int size;
|
||||
#ifdef PREDICTOR
|
||||
|
||||
#if defined(PREDICTOR) || defined(KIRCHHOFF)
|
||||
int i;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
size = SMPmatSize(ckt->CKTmatrix);
|
||||
CKALLOC(CKTrhs,size+1,double);
|
||||
|
|
@ -33,6 +34,17 @@ NIreinit( CKTcircuit *ckt)
|
|||
CKALLOC(CKTirhs,size+1,double);
|
||||
CKALLOC(CKTirhsOld,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
|
||||
CKALLOC(CKTpred,size+1,double);
|
||||
for( i=0;i<8;i++) {
|
||||
|
|
|
|||
|
|
@ -190,7 +190,7 @@ spCreate(int Size, int Complex, int *pError)
|
|||
Matrix->ElementsRemaining = 0;
|
||||
Matrix->FillinsRemaining = 0;
|
||||
|
||||
RecordAllocation( Matrix, (void *)Matrix );
|
||||
RecordAllocation( Matrix, Matrix );
|
||||
if (Matrix->Error == spNO_MEMORY) goto MemoryError;
|
||||
|
||||
/* Take out the trash. */
|
||||
|
|
@ -311,7 +311,7 @@ spcGetElement(MatrixPtr Matrix)
|
|||
/* Allocate block of MatrixElements if necessary. */
|
||||
if (Matrix->ElementsRemaining == 0) {
|
||||
pElements = SP_MALLOC(struct MatrixElement, ELEMENTS_PER_ALLOCATION);
|
||||
RecordAllocation( Matrix, (void *)pElements );
|
||||
RecordAllocation( Matrix, pElements );
|
||||
if (Matrix->Error == spNO_MEMORY) return NULL;
|
||||
Matrix->ElementsRemaining = ELEMENTS_PER_ALLOCATION;
|
||||
Matrix->NextAvailElement = pElements;
|
||||
|
|
@ -331,14 +331,14 @@ spcGetElement(MatrixPtr Matrix)
|
|||
} else {
|
||||
/* Allocate block of elements. */
|
||||
pElements = SP_MALLOC(struct MatrixElement, ELEMENTS_PER_ALLOCATION);
|
||||
RecordAllocation( Matrix, (void *)pElements );
|
||||
RecordAllocation( Matrix, pElements );
|
||||
if (Matrix->Error == spNO_MEMORY) return NULL;
|
||||
Matrix->ElementsRemaining = ELEMENTS_PER_ALLOCATION;
|
||||
Matrix->NextAvailElement = pElements;
|
||||
|
||||
/* Allocate an element list structure. */
|
||||
pListNode->Next = SP_MALLOC(struct ElementListNodeStruct,1);
|
||||
RecordAllocation( Matrix, (void *)pListNode->Next );
|
||||
RecordAllocation( Matrix, pListNode->Next );
|
||||
if (Matrix->Error == spNO_MEMORY)
|
||||
return NULL;
|
||||
Matrix->LastElementListNode = pListNode = pListNode->Next;
|
||||
|
|
@ -402,14 +402,14 @@ InitializeElementBlocks(MatrixPtr Matrix, int InitialNumberOfElements,
|
|||
|
||||
/* Allocate block of MatrixElements for elements. */
|
||||
pElement = SP_MALLOC(struct MatrixElement, InitialNumberOfElements);
|
||||
RecordAllocation( Matrix, (void *)pElement );
|
||||
RecordAllocation( Matrix, pElement );
|
||||
if (Matrix->Error == spNO_MEMORY) return;
|
||||
Matrix->ElementsRemaining = InitialNumberOfElements;
|
||||
Matrix->NextAvailElement = pElement;
|
||||
|
||||
/* Allocate an element list structure. */
|
||||
Matrix->FirstElementListNode = SP_MALLOC(struct ElementListNodeStruct,1);
|
||||
RecordAllocation( Matrix, (void *)Matrix->FirstElementListNode );
|
||||
RecordAllocation( Matrix, Matrix->FirstElementListNode );
|
||||
if (Matrix->Error == spNO_MEMORY) return;
|
||||
Matrix->LastElementListNode = Matrix->FirstElementListNode;
|
||||
|
||||
|
|
@ -420,14 +420,14 @@ InitializeElementBlocks(MatrixPtr Matrix, int InitialNumberOfElements,
|
|||
|
||||
/* Allocate block of MatrixElements for fill-ins. */
|
||||
pElement = SP_MALLOC(struct MatrixElement, NumberOfFillinsExpected);
|
||||
RecordAllocation( Matrix, (void *)pElement );
|
||||
RecordAllocation( Matrix, pElement );
|
||||
if (Matrix->Error == spNO_MEMORY) return;
|
||||
Matrix->FillinsRemaining = NumberOfFillinsExpected;
|
||||
Matrix->NextAvailFillin = pElement;
|
||||
|
||||
/* Allocate a fill-in list structure. */
|
||||
Matrix->FirstFillinListNode = SP_MALLOC(struct FillinListNodeStruct,1);
|
||||
RecordAllocation( Matrix, (void *)Matrix->FirstFillinListNode );
|
||||
RecordAllocation( Matrix, Matrix->FirstFillinListNode );
|
||||
if (Matrix->Error == spNO_MEMORY) return;
|
||||
Matrix->LastFillinListNode = Matrix->FirstFillinListNode;
|
||||
|
||||
|
|
@ -487,14 +487,14 @@ spcGetFillin(MatrixPtr Matrix)
|
|||
} else {
|
||||
/* Allocate block of fill-ins. */
|
||||
pFillins = SP_MALLOC(struct MatrixElement, ELEMENTS_PER_ALLOCATION);
|
||||
RecordAllocation( Matrix, (void *)pFillins );
|
||||
RecordAllocation( Matrix, pFillins );
|
||||
if (Matrix->Error == spNO_MEMORY) return NULL;
|
||||
Matrix->FillinsRemaining = ELEMENTS_PER_ALLOCATION;
|
||||
Matrix->NextAvailFillin = pFillins;
|
||||
|
||||
/* Allocate a fill-in list structure. */
|
||||
pListNode->Next = SP_MALLOC(struct FillinListNodeStruct,1);
|
||||
RecordAllocation( Matrix, (void *)pListNode->Next );
|
||||
RecordAllocation( Matrix, pListNode->Next );
|
||||
if (Matrix->Error == spNO_MEMORY) return NULL;
|
||||
Matrix->LastFillinListNode = pListNode = pListNode->Next;
|
||||
|
||||
|
|
@ -646,9 +646,8 @@ AllocateBlockOfAllocationList(MatrixPtr Matrix)
|
|||
*/
|
||||
|
||||
void
|
||||
spDestroy(MatrixPtr eMatrix)
|
||||
spDestroy(MatrixPtr Matrix)
|
||||
{
|
||||
MatrixPtr Matrix = eMatrix;
|
||||
AllocationListPtr ListPtr, NextListPtr;
|
||||
|
||||
|
||||
|
|
@ -701,16 +700,16 @@ spDestroy(MatrixPtr eMatrix)
|
|||
* The error status of the given matrix.
|
||||
*
|
||||
* >>> Arguments:
|
||||
* eMatrix <input> (void *)
|
||||
* Matrix <input> (void *)
|
||||
* The matrix for which the error status is desired. */
|
||||
int
|
||||
spError(MatrixPtr eMatrix )
|
||||
spError(MatrixPtr Matrix )
|
||||
{
|
||||
/* Begin `spError'. */
|
||||
|
||||
if (eMatrix != NULL) {
|
||||
assert(eMatrix->ID == SPARSE_ID);
|
||||
return eMatrix->Error;
|
||||
if (Matrix != NULL) {
|
||||
assert(Matrix->ID == SPARSE_ID);
|
||||
return Matrix->Error;
|
||||
} else {
|
||||
/* This error may actually be spPANIC, no way to tell. */
|
||||
return spNO_MEMORY;
|
||||
|
|
@ -732,7 +731,7 @@ spError(MatrixPtr eMatrix )
|
|||
* detected as singular or where a zero was detected on the diagonal.
|
||||
*
|
||||
* >>> Arguments:
|
||||
* eMatrix <input> (void *)
|
||||
* Matrix <input> (void *)
|
||||
* The matrix for which the error status is desired.
|
||||
* pRow <output> (int *)
|
||||
* The row number.
|
||||
|
|
@ -741,10 +740,8 @@ spError(MatrixPtr eMatrix )
|
|||
*/
|
||||
|
||||
void
|
||||
spWhereSingular(MatrixPtr eMatrix, int *pRow, int *pCol)
|
||||
spWhereSingular(MatrixPtr Matrix, int *pRow, int *pCol)
|
||||
{
|
||||
MatrixPtr Matrix = eMatrix;
|
||||
|
||||
/* Begin `spWhereSingular'. */
|
||||
assert( IS_SPARSE( Matrix ) );
|
||||
|
||||
|
|
@ -769,7 +766,7 @@ spWhereSingular(MatrixPtr eMatrix, int *pRow, int *pCol)
|
|||
* the matrix is returned.
|
||||
*
|
||||
* >>> Arguments:
|
||||
* eMatrix <input> (void *)
|
||||
* Matrix <input> (void *)
|
||||
* Pointer to matrix.
|
||||
* External <input> (int)
|
||||
* 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
|
||||
spGetSize(MatrixPtr eMatrix, int External)
|
||||
spGetSize(MatrixPtr Matrix, int External)
|
||||
{
|
||||
MatrixPtr Matrix = eMatrix;
|
||||
|
||||
/* Begin `spGetSize'. */
|
||||
assert( IS_SPARSE( Matrix ) );
|
||||
|
||||
|
|
@ -809,28 +804,28 @@ spGetSize(MatrixPtr eMatrix, int External)
|
|||
* Forces matrix to be either real or complex.
|
||||
*
|
||||
* >>> Arguments:
|
||||
* eMatrix <input> (void *)
|
||||
* Matrix <input> (void *)
|
||||
* Pointer to matrix.
|
||||
*/
|
||||
|
||||
void
|
||||
spSetReal(MatrixPtr eMatrix)
|
||||
spSetReal(MatrixPtr Matrix)
|
||||
{
|
||||
/* Begin `spSetReal'. */
|
||||
|
||||
assert( IS_SPARSE( eMatrix ));
|
||||
eMatrix->Complex = NO;
|
||||
assert( IS_SPARSE( Matrix ));
|
||||
Matrix->Complex = NO;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
spSetComplex(MatrixPtr eMatrix)
|
||||
spSetComplex(MatrixPtr Matrix)
|
||||
{
|
||||
/* Begin `spSetComplex'. */
|
||||
|
||||
assert( IS_SPARSE( eMatrix ));
|
||||
eMatrix->Complex = YES;
|
||||
assert( IS_SPARSE( Matrix ));
|
||||
Matrix->Complex = YES;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -850,34 +845,34 @@ spSetComplex(MatrixPtr eMatrix)
|
|||
* of original elements can be returned.
|
||||
*
|
||||
* >>> Arguments:
|
||||
* eMatrix <input> (void *)
|
||||
* Matrix <input> (void *)
|
||||
* Pointer to matrix.
|
||||
*/
|
||||
|
||||
int
|
||||
spFillinCount(MatrixPtr eMatrix)
|
||||
spFillinCount(MatrixPtr Matrix)
|
||||
{
|
||||
/* Begin `spFillinCount'. */
|
||||
|
||||
assert( IS_SPARSE( eMatrix ) );
|
||||
return eMatrix->Fillins;
|
||||
assert( IS_SPARSE( Matrix ) );
|
||||
return Matrix->Fillins;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
spElementCount(MatrixPtr eMatrix)
|
||||
spElementCount(MatrixPtr Matrix)
|
||||
{
|
||||
/* Begin `spElementCount'. */
|
||||
|
||||
assert( IS_SPARSE( eMatrix ) );
|
||||
return eMatrix->Elements;
|
||||
assert( IS_SPARSE( Matrix ) );
|
||||
return Matrix->Elements;
|
||||
}
|
||||
|
||||
int
|
||||
spOriginalCount(MatrixPtr eMatrix)
|
||||
spOriginalCount(MatrixPtr Matrix)
|
||||
{
|
||||
/* Begin `spOriginalCount'. */
|
||||
|
||||
assert( IS_SPARSE( eMatrix ) );
|
||||
return eMatrix->Originals;
|
||||
assert( IS_SPARSE( Matrix ) );
|
||||
return Matrix->Originals;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -93,9 +93,8 @@ static void ExpandTranslationArrays( MatrixPtr, int );
|
|||
*/
|
||||
|
||||
void
|
||||
spClear(MatrixPtr eMatrix)
|
||||
spClear(MatrixPtr Matrix)
|
||||
{
|
||||
MatrixPtr Matrix = eMatrix;
|
||||
ElementPtr pElement;
|
||||
int I;
|
||||
|
||||
|
|
@ -180,10 +179,9 @@ spClear(MatrixPtr eMatrix)
|
|||
*/
|
||||
|
||||
RealNumber *
|
||||
spFindElement(MatrixPtr eMatrix, int Row, int Col)
|
||||
spFindElement(MatrixPtr Matrix, int Row, int Col)
|
||||
{
|
||||
MatrixPtr Matrix = eMatrix;
|
||||
RealNumber *pElement;
|
||||
ElementPtr pElement;
|
||||
|
||||
/* Begin `spFindElement'. */
|
||||
assert( IS_SPARSE( Matrix ) && Row >= 0 && Col >= 0 );
|
||||
|
|
@ -210,7 +208,7 @@ RealNumber *pElement;
|
|||
* 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
|
||||
|
|
@ -218,11 +216,11 @@ RealNumber *pElement;
|
|||
* element which is returned by spcFindElementInCol is cast into a
|
||||
* pointer to Real, a RealNumber.
|
||||
*/
|
||||
pElement = (RealNumber*)spcFindElementInCol( Matrix,
|
||||
pElement = spcFindElementInCol( Matrix,
|
||||
&(Matrix->FirstInCol[Col]),
|
||||
Row, Col, NO );
|
||||
}
|
||||
return pElement;
|
||||
return & pElement->Real;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -263,10 +261,9 @@ RealNumber *pElement;
|
|||
*/
|
||||
|
||||
RealNumber *
|
||||
spGetElement(MatrixPtr eMatrix, int Row, int Col)
|
||||
spGetElement(MatrixPtr Matrix, int Row, int Col)
|
||||
{
|
||||
MatrixPtr Matrix = eMatrix;
|
||||
RealNumber *pElement;
|
||||
ElementPtr pElement;
|
||||
|
||||
/* Begin `spGetElement'. */
|
||||
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
|
||||
* 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 column for element. As in the if statement above,
|
||||
* the pointer to the element which is returned by
|
||||
* spcFindElementInCol is cast into a pointer to Real, a
|
||||
* RealNumber. */
|
||||
pElement = (RealNumber*)spcFindElementInCol( Matrix,
|
||||
pElement = spcFindElementInCol( Matrix,
|
||||
&(Matrix->FirstInCol[Col]),
|
||||
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))
|
||||
return spNO_MEMORY;
|
||||
|
||||
if (Template->Element1 == &((MatrixPtr)Matrix)->TrashCan.Real)
|
||||
if (Template->Element1 == & Matrix->TrashCan.Real)
|
||||
SWAP( RealNumber *, Template->Element1, Template->Element2 );
|
||||
|
||||
return spOKAY;
|
||||
|
|
@ -1145,9 +1142,8 @@ spGetInitInfo(RealNumber *pElement)
|
|||
|
||||
|
||||
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;
|
||||
int J, Error, Col;
|
||||
|
||||
|
|
@ -1182,7 +1178,7 @@ spInitialize(MatrixPtr eMatrix, int (*pInit)(RealNumber*, void *InitInfo, int ,
|
|||
}
|
||||
else
|
||||
{
|
||||
Error = pInit ((RealNumber *)pElement, pElement->pInitInfo,
|
||||
Error = pInit (& pElement->Real, pElement->pInitInfo,
|
||||
Matrix->IntToExtRowMap[pElement->Row], Col);
|
||||
if (Error)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -189,10 +189,9 @@ static int ZeroPivot( MatrixPtr, int );
|
|||
*/
|
||||
|
||||
int
|
||||
spOrderAndFactor(MatrixPtr eMatrix, RealNumber RHS[], RealNumber RelThreshold,
|
||||
spOrderAndFactor(MatrixPtr Matrix, RealNumber RHS[], RealNumber RelThreshold,
|
||||
RealNumber AbsThreshold, int DiagPivoting)
|
||||
{
|
||||
MatrixPtr Matrix = eMatrix;
|
||||
ElementPtr pPivot;
|
||||
int Step, Size, ReorderingRequired;
|
||||
RealNumber LargestInCol;
|
||||
|
|
@ -321,9 +320,8 @@ Done:
|
|||
* Error is cleared in this function. */
|
||||
|
||||
int
|
||||
spFactor(MatrixPtr eMatrix)
|
||||
spFactor(MatrixPtr Matrix)
|
||||
{
|
||||
MatrixPtr Matrix = eMatrix;
|
||||
ElementPtr pElement;
|
||||
ElementPtr pColumn;
|
||||
int Step, Size;
|
||||
|
|
@ -333,10 +331,10 @@ spFactor(MatrixPtr eMatrix)
|
|||
assert( IS_VALID(Matrix) && !Matrix->Factored);
|
||||
|
||||
if (Matrix->NeedsOrdering) {
|
||||
return spOrderAndFactor( eMatrix, NULL,
|
||||
return spOrderAndFactor( Matrix, NULL,
|
||||
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)
|
||||
return FactorComplexMatrix( Matrix );
|
||||
|
||||
|
|
@ -569,9 +567,8 @@ FactorComplexMatrix( MatrixPtr Matrix )
|
|||
* spINDIRECT_PARTITION, or spAUTO_PARTITION. */
|
||||
|
||||
void
|
||||
spPartition(MatrixPtr eMatrix, int Mode)
|
||||
spPartition(MatrixPtr Matrix, int Mode)
|
||||
{
|
||||
MatrixPtr Matrix = eMatrix;
|
||||
ElementPtr pElement, pColumn;
|
||||
int Step, Size;
|
||||
int *Nc, *No, *Nm;
|
||||
|
|
@ -603,8 +600,8 @@ spPartition(MatrixPtr eMatrix, int Mode)
|
|||
assert( Mode == spAUTO_PARTITION );
|
||||
|
||||
/* Otherwise, count all operations needed in when factoring matrix. */
|
||||
Nc = (int *)Matrix->MarkowitzRow;
|
||||
No = (int *)Matrix->MarkowitzCol;
|
||||
Nc = Matrix->MarkowitzRow;
|
||||
No = Matrix->MarkowitzCol;
|
||||
Nm = (int *)Matrix->MarkowitzProd;
|
||||
|
||||
/* Start mock-factorization. */
|
||||
|
|
|
|||
|
|
@ -133,9 +133,8 @@ int Printer_Width = PRINTER_WIDTH;
|
|||
*/
|
||||
|
||||
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 I, Row, Col, Size, Top;
|
||||
int StartCol = 1, StopCol, Columns, ElementCount = 0;
|
||||
|
|
@ -295,7 +294,7 @@ spPrint(MatrixPtr eMatrix, int PrintReordered, int Data, int Header)
|
|||
{
|
||||
/* Case where element exists */
|
||||
if (Data)
|
||||
printf(" %9.3g", (double)pElement->Real);
|
||||
printf(" %9.3g", pElement->Real);
|
||||
else
|
||||
putchar('x');
|
||||
|
||||
|
|
@ -326,7 +325,7 @@ spPrint(MatrixPtr eMatrix, int PrintReordered, int Data, int Header)
|
|||
if (pImagElements[J - StartCol] != NULL)
|
||||
{
|
||||
printf(" %8.2gj",
|
||||
(double)pImagElements[J-StartCol]->Imag);
|
||||
pImagElements[J-StartCol]->Imag);
|
||||
}
|
||||
else printf(" ");
|
||||
}
|
||||
|
|
@ -436,10 +435,9 @@ spPrint(MatrixPtr eMatrix, int PrintReordered, int Data, int Header)
|
|||
*/
|
||||
|
||||
int
|
||||
spFileMatrix(MatrixPtr eMatrix, char *File, char *Label, int Reordered,
|
||||
spFileMatrix(MatrixPtr Matrix, char *File, char *Label, int Reordered,
|
||||
int Data, int Header)
|
||||
{
|
||||
MatrixPtr Matrix = eMatrix;
|
||||
int I, Size;
|
||||
ElementPtr pElement;
|
||||
int Row, Col, Err;
|
||||
|
|
@ -518,7 +516,7 @@ spFileMatrix(MatrixPtr eMatrix, char *File, char *Label, int Reordered,
|
|||
}
|
||||
Err = fprintf
|
||||
( 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;
|
||||
pElement = pElement->NextInCol;
|
||||
|
|
@ -541,7 +539,7 @@ spFileMatrix(MatrixPtr eMatrix, char *File, char *Label, int Reordered,
|
|||
Col = Matrix->IntToExtColMap[I];
|
||||
Err = fprintf
|
||||
( pMatrixFile,"%d\t%d\t%-.15g\n",
|
||||
Row, Col, (double)pElement->Real
|
||||
Row, Col, pElement->Real
|
||||
);
|
||||
if (Err < 0) return 0;
|
||||
pElement = pElement->NextInCol;
|
||||
|
|
@ -595,9 +593,8 @@ spFileMatrix(MatrixPtr eMatrix, char *File, char *Label, int Reordered,
|
|||
*/
|
||||
|
||||
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;
|
||||
FILE *pMatrixFile;
|
||||
|
||||
|
|
@ -621,7 +618,7 @@ spFileVector(MatrixPtr eMatrix, char *File, RealVector RHS, RealVector iRHS)
|
|||
{
|
||||
Err = fprintf
|
||||
( pMatrixFile, "%-.15g\t%-.15g\n",
|
||||
(double)RHS[I], (double)iRHS[I]
|
||||
RHS[I], iRHS[I]
|
||||
);
|
||||
if (Err < 0) return 0;
|
||||
}
|
||||
|
|
@ -630,7 +627,7 @@ spFileVector(MatrixPtr eMatrix, char *File, RealVector RHS, RealVector iRHS)
|
|||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
@ -686,9 +683,8 @@ spFileVector(MatrixPtr eMatrix, char *File, RealVector RHS, RealVector iRHS)
|
|||
*/
|
||||
|
||||
int
|
||||
spFileStats(MatrixPtr eMatrix, char *File, char *Label)
|
||||
spFileStats(MatrixPtr Matrix, char *File, char *Label)
|
||||
{
|
||||
MatrixPtr Matrix = eMatrix;
|
||||
int Size, I;
|
||||
ElementPtr pElement;
|
||||
int NumberOfElements;
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@ extern double scalbn(double, int);
|
|||
extern double logb(double);
|
||||
#endif
|
||||
|
||||
static void LoadGmin(SMPmatrix *eMatrix, double Gmin);
|
||||
static void LoadGmin(SMPmatrix *Matrix, double Gmin);
|
||||
|
||||
/*
|
||||
* SMPaddElt()
|
||||
|
|
@ -183,7 +183,7 @@ SMPcReorder(SMPmatrix *Matrix, double PivTol, double PivRel,
|
|||
*NumSwaps = 1;
|
||||
spSetComplex( Matrix->SPmatrix );
|
||||
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 );
|
||||
LoadGmin( Matrix, Gmin );
|
||||
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];
|
||||
Prev = &Matrix->FirstInCol[Accum_Col];
|
||||
Accum = *Prev;;
|
||||
Accum = *Prev;
|
||||
|
||||
while (Addend != NULL) {
|
||||
while (Accum && Accum->Row < Addend->Row) {
|
||||
|
|
|
|||
|
|
@ -124,10 +124,9 @@ static void SolveComplexTransposedMatrix( MatrixPtr,
|
|||
/*VARARGS3*/
|
||||
|
||||
void
|
||||
spSolve(MatrixPtr eMatrix, RealVector RHS, RealVector Solution,
|
||||
spSolve(MatrixPtr Matrix, RealVector RHS, RealVector Solution,
|
||||
RealVector iRHS, RealVector iSolution)
|
||||
{
|
||||
MatrixPtr Matrix = eMatrix;
|
||||
ElementPtr pElement;
|
||||
RealVector Intermediate;
|
||||
RealNumber Temp;
|
||||
|
|
@ -400,10 +399,9 @@ SolveComplexMatrix( MatrixPtr Matrix, RealVector RHS, RealVector Solution , Real
|
|||
/*VARARGS3*/
|
||||
|
||||
void
|
||||
spSolveTransposed(MatrixPtr eMatrix, RealVector RHS, RealVector Solution,
|
||||
spSolveTransposed(MatrixPtr Matrix, RealVector RHS, RealVector Solution,
|
||||
RealVector iRHS, RealVector iSolution)
|
||||
{
|
||||
MatrixPtr Matrix = eMatrix;
|
||||
ElementPtr pElement;
|
||||
RealVector Intermediate;
|
||||
int I, *pExtOrder, Size;
|
||||
|
|
|
|||
|
|
@ -151,7 +151,7 @@ static void ComplexTransposedMatrixMultiply( MatrixPtr, RealVector, RealVector,
|
|||
* Tom Quarles.
|
||||
*
|
||||
* >>> Arguments:
|
||||
* eMatrix <input> (char *)
|
||||
* Matrix <input> (char *)
|
||||
* Pointer to the matrix to be preordered.
|
||||
*
|
||||
* >>> Local variables;
|
||||
|
|
@ -174,9 +174,8 @@ static void ComplexTransposedMatrixMultiply( MatrixPtr, RealVector, RealVector,
|
|||
*/
|
||||
|
||||
void
|
||||
spMNA_Preorder(MatrixPtr eMatrix)
|
||||
spMNA_Preorder(MatrixPtr Matrix)
|
||||
{
|
||||
MatrixPtr Matrix = eMatrix;
|
||||
int J, Size;
|
||||
ElementPtr pTwin1, pTwin2;
|
||||
int Twins, StartAt = 1;
|
||||
|
|
@ -346,7 +345,7 @@ SwapCols( MatrixPtr Matrix, ElementPtr pTwin1, ElementPtr pTwin2 )
|
|||
* should not be executed before the function spMNA_Preorder.
|
||||
*
|
||||
* >>> Arguments:
|
||||
* eMatrix <input> (char *)
|
||||
* Matrix <input> (char *)
|
||||
* Pointer to the matrix to be scaled.
|
||||
* SolutionScaleFactors <input> (RealVector)
|
||||
* The array of Solution scale factors. These factors scale the columns.
|
||||
|
|
@ -368,9 +367,8 @@ SwapCols( MatrixPtr Matrix, ElementPtr pTwin1, ElementPtr pTwin2 )
|
|||
*/
|
||||
|
||||
void
|
||||
spScale(MatrixPtr eMatrix, RealVector RHS_ScaleFactors, RealVector SolutionScaleFactors)
|
||||
spScale(MatrixPtr Matrix, RealVector RHS_ScaleFactors, RealVector SolutionScaleFactors)
|
||||
{
|
||||
MatrixPtr Matrix = eMatrix;
|
||||
ElementPtr pElement;
|
||||
int I, lSize, *pExtOrder;
|
||||
RealNumber ScaleFactor;
|
||||
|
|
@ -556,7 +554,7 @@ MatrixPtr Matrix;
|
|||
* before spMNA_Preorder().
|
||||
*
|
||||
* >>> Arguments:
|
||||
* eMatrix <input> (char *)
|
||||
* Matrix <input> (char *)
|
||||
* Pointer to the matrix.
|
||||
* RHS <output> (RealVector)
|
||||
* RHS is the right hand side. This is what is being solved for.
|
||||
|
|
@ -571,14 +569,13 @@ MatrixPtr Matrix;
|
|||
*/
|
||||
|
||||
void
|
||||
spMultiply(MatrixPtr eMatrix, RealVector RHS, RealVector Solution,
|
||||
spMultiply(MatrixPtr Matrix, RealVector RHS, RealVector Solution,
|
||||
RealVector iRHS, RealVector iSolution)
|
||||
{
|
||||
ElementPtr pElement;
|
||||
RealVector Vector;
|
||||
RealNumber Sum;
|
||||
int I, *pExtOrder;
|
||||
MatrixPtr Matrix = eMatrix;
|
||||
|
||||
/* Begin `spMultiply'. */
|
||||
assert( IS_SPARSE( Matrix ) && !Matrix->Factored );
|
||||
|
|
@ -702,7 +699,7 @@ ComplexMatrixMultiply( MatrixPtr Matrix, RealVector RHS, RealVector Solution , R
|
|||
* before spMNA_Preorder().
|
||||
*
|
||||
* >>> Arguments:
|
||||
* eMatrix <input> (char *)
|
||||
* Matrix <input> (char *)
|
||||
* Pointer to the matrix.
|
||||
* RHS <output> (RealVector)
|
||||
* 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
|
||||
spMultTransposed(MatrixPtr eMatrix, RealVector RHS, RealVector Solution,
|
||||
spMultTransposed(MatrixPtr Matrix, RealVector RHS, RealVector Solution,
|
||||
RealVector iRHS, RealVector iSolution)
|
||||
{
|
||||
ElementPtr pElement;
|
||||
RealVector Vector;
|
||||
RealNumber Sum;
|
||||
int I, *pExtOrder;
|
||||
MatrixPtr Matrix = eMatrix;
|
||||
|
||||
/* Begin `spMultTransposed'. */
|
||||
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.
|
||||
*
|
||||
* >>> Arguments:
|
||||
* eMatrix <input> (char *)
|
||||
* Matrix <input> (char *)
|
||||
* A pointer to the matrix for which the determinant is desired.
|
||||
* pExponent <output> (int *)
|
||||
* 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
|
||||
spDeterminant(MatrixPtr eMatrix, int *pExponent, RealNumber *pDeterminant,
|
||||
spDeterminant(MatrixPtr Matrix, int *pExponent, RealNumber *pDeterminant,
|
||||
RealNumber *piDeterminant)
|
||||
{
|
||||
MatrixPtr Matrix = eMatrix;
|
||||
int I, Size;
|
||||
RealNumber Norm, nr, ni;
|
||||
ComplexNumber Pivot, cDeterminant;
|
||||
|
|
@ -1037,9 +1032,8 @@ spDeterminant(MatrixPtr eMatrix, int *pExponent, RealNumber *pDeterminant,
|
|||
*/
|
||||
|
||||
void
|
||||
spStripFills(MatrixPtr eMatrix)
|
||||
spStripFills(MatrixPtr Matrix)
|
||||
{
|
||||
MatrixPtr Matrix = eMatrix;
|
||||
struct FillinListNodeStruct *pListNode;
|
||||
|
||||
/* Begin `spStripFills'. */
|
||||
|
|
@ -1109,10 +1103,8 @@ spStripFills(MatrixPtr eMatrix)
|
|||
* frame. This assumes that the matrix will be replaced with one of
|
||||
* the same size. */
|
||||
void
|
||||
spStripMatrix(MatrixPtr eMatrix)
|
||||
spStripMatrix(MatrixPtr Matrix)
|
||||
{
|
||||
MatrixPtr Matrix = eMatrix;
|
||||
|
||||
/* Begin `spStripMatrix'. */
|
||||
assert( IS_SPARSE( Matrix ) );
|
||||
if (Matrix->Elements == 0) return;
|
||||
|
|
@ -1124,7 +1116,6 @@ spStripMatrix(MatrixPtr eMatrix)
|
|||
|
||||
/* Reset the element lists. */
|
||||
{
|
||||
ElementPtr pElement;
|
||||
struct ElementListNodeStruct *pListNode;
|
||||
|
||||
pListNode = Matrix->LastElementListNode = Matrix->FirstElementListNode;
|
||||
|
|
@ -1134,7 +1125,6 @@ spStripMatrix(MatrixPtr eMatrix)
|
|||
|
||||
/* Reset the fill-in lists. */
|
||||
{
|
||||
ElementPtr pFillin;
|
||||
struct FillinListNodeStruct *pListNode;
|
||||
|
||||
pListNode = Matrix->LastFillinListNode = Matrix->FirstFillinListNode;
|
||||
|
|
@ -1171,7 +1161,7 @@ spStripMatrix(MatrixPtr eMatrix)
|
|||
* doesn't exist.
|
||||
*
|
||||
* >>> Arguments:
|
||||
* eMatrix <input> (char *)
|
||||
* Matrix <input> (char *)
|
||||
* Pointer to the matrix in which the row and column are to be deleted.
|
||||
* Row <input> (int)
|
||||
* Row to be deleted.
|
||||
|
|
@ -1197,9 +1187,8 @@ spStripMatrix(MatrixPtr eMatrix)
|
|||
*/
|
||||
|
||||
void
|
||||
spDeleteRowAndCol(MatrixPtr eMatrix, int Row, int Col)
|
||||
spDeleteRowAndCol(MatrixPtr Matrix, int Row, int Col)
|
||||
{
|
||||
MatrixPtr Matrix = eMatrix;
|
||||
ElementPtr pElement, *ppElement, pLastElement;
|
||||
int Size, ExtRow, ExtCol;
|
||||
ElementPtr spcFindElementInCol();
|
||||
|
|
@ -1306,13 +1295,12 @@ spDeleteRowAndCol(MatrixPtr eMatrix, int Row, int Col)
|
|||
* previous factorization. If the matrix was singular, zero is returned.
|
||||
*
|
||||
* >>> Arguments:
|
||||
* eMatrix <input> (char *)
|
||||
* Matrix <input> (char *)
|
||||
* Pointer to the matrix. */
|
||||
|
||||
RealNumber
|
||||
spPseudoCondition(MatrixPtr eMatrix)
|
||||
spPseudoCondition(MatrixPtr Matrix)
|
||||
{
|
||||
MatrixPtr Matrix = eMatrix;
|
||||
int I;
|
||||
ArrayOfElementPtrs Diag;
|
||||
RealNumber MaxPivot, MinPivot, Mag;
|
||||
|
|
@ -1388,7 +1376,7 @@ spPseudoCondition(MatrixPtr eMatrix)
|
|||
* zero is returned.
|
||||
*
|
||||
* >>> Arguments:
|
||||
* eMatrix <input> (char *)
|
||||
* Matrix <input> (char *)
|
||||
* Pointer to the matrix.
|
||||
* NormOfMatrix <input> (RealNumber)
|
||||
* The L-infinity norm of the unfactored matrix as computed by
|
||||
|
|
@ -1401,9 +1389,8 @@ spPseudoCondition(MatrixPtr eMatrix)
|
|||
* spNO_MEMORY */
|
||||
|
||||
RealNumber
|
||||
spCondition(MatrixPtr eMatrix, RealNumber NormOfMatrix, int *pError)
|
||||
spCondition(MatrixPtr Matrix, RealNumber NormOfMatrix, int *pError)
|
||||
{
|
||||
MatrixPtr Matrix = eMatrix;
|
||||
ElementPtr pElement;
|
||||
RealVector T, Tm;
|
||||
int I, K, Row;
|
||||
|
|
@ -1824,14 +1811,13 @@ int *pError;
|
|||
* The largest absolute row sum of matrix.
|
||||
*
|
||||
* >>> Arguments:
|
||||
* eMatrix <input> (char *)
|
||||
* Matrix <input> (char *)
|
||||
* Pointer to the matrix.
|
||||
*/
|
||||
|
||||
RealNumber
|
||||
spNorm(MatrixPtr eMatrix)
|
||||
spNorm(MatrixPtr Matrix)
|
||||
{
|
||||
MatrixPtr Matrix = eMatrix;
|
||||
ElementPtr pElement;
|
||||
int I;
|
||||
RealNumber Max = 0.0, AbsRowSum;
|
||||
|
|
@ -1942,14 +1928,13 @@ spNorm(MatrixPtr eMatrix)
|
|||
* largest element in any of the reduced submatrices is returned.
|
||||
*
|
||||
* >>> Arguments:
|
||||
* eMatrix <input> (char *)
|
||||
* Matrix <input> (char *)
|
||||
* Pointer to the matrix.
|
||||
*/
|
||||
|
||||
RealNumber
|
||||
spLargestElement(MatrixPtr eMatrix)
|
||||
spLargestElement(MatrixPtr Matrix)
|
||||
{
|
||||
MatrixPtr Matrix = eMatrix;
|
||||
int I;
|
||||
RealNumber Mag, AbsColSum, Max = 0.0, MaxRow = 0.0, MaxCol = 0.0;
|
||||
RealNumber Pivot;
|
||||
|
|
@ -2066,7 +2051,7 @@ spLargestElement(MatrixPtr eMatrix)
|
|||
* Returns a bound on the magnitude of the largest element in E = A - LU.
|
||||
*
|
||||
* >>> Arguments:
|
||||
* eMatrix <input> (char *)
|
||||
* Matrix <input> (char *)
|
||||
* Pointer to the matrix.
|
||||
* Rho <input> (RealNumber)
|
||||
* The bound on the magnitude of the largest element in any of the
|
||||
|
|
@ -2076,9 +2061,8 @@ spLargestElement(MatrixPtr eMatrix)
|
|||
*/
|
||||
|
||||
RealNumber
|
||||
spRoundoff(MatrixPtr eMatrix, RealNumber Rho)
|
||||
spRoundoff(MatrixPtr Matrix, RealNumber Rho)
|
||||
{
|
||||
MatrixPtr Matrix = eMatrix;
|
||||
ElementPtr pElement;
|
||||
int Count, I, MaxCount = 0;
|
||||
RealNumber Reid, Gear;
|
||||
|
|
@ -2087,7 +2071,7 @@ spRoundoff(MatrixPtr eMatrix, RealNumber Rho)
|
|||
assert( IS_SPARSE(Matrix) && IS_FACTORED(Matrix) );
|
||||
|
||||
/* 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. */
|
||||
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.
|
||||
*
|
||||
* >>> Arguments:
|
||||
* eMatrix <input> (char *)
|
||||
* Matrix <input> (char *)
|
||||
* Matrix for which the error message is to be printed.
|
||||
* Stream <input> (FILE *)
|
||||
* Stream to which the error message is to be printed.
|
||||
|
|
@ -2143,17 +2127,17 @@ spRoundoff(MatrixPtr eMatrix, RealNumber Rho)
|
|||
*/
|
||||
|
||||
void
|
||||
spErrorMessage(MatrixPtr eMatrix, FILE *Stream, char *Originator)
|
||||
spErrorMessage(MatrixPtr Matrix, FILE *Stream, char *Originator)
|
||||
{
|
||||
int Row, Col, Error;
|
||||
|
||||
/* Begin `spErrorMessage'. */
|
||||
if (eMatrix == NULL)
|
||||
if (Matrix == NULL)
|
||||
Error = spNO_MEMORY;
|
||||
else
|
||||
{
|
||||
assert(eMatrix->ID == SPARSE_ID);
|
||||
Error = eMatrix->Error;
|
||||
assert(Matrix->ID == SPARSE_ID);
|
||||
Error = Matrix->Error;
|
||||
}
|
||||
|
||||
if (Error == spOKAY) return;
|
||||
|
|
@ -2172,13 +2156,13 @@ spErrorMessage(MatrixPtr eMatrix, FILE *Stream, char *Originator)
|
|||
fprintf( Stream, "insufficient memory available.\n");
|
||||
else if (Error == spSINGULAR)
|
||||
{
|
||||
spWhereSingular( eMatrix, &Row, &Col );
|
||||
spWhereSingular( Matrix, &Row, &Col );
|
||||
fprintf( Stream, "singular matrix detected at row %d and column %d.\n",
|
||||
Row, Col);
|
||||
}
|
||||
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",
|
||||
Row, Col);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,9 @@ Copyright 1990 Regents of the University of California. All rights reserved.
|
|||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_FTIME
|
||||
# include <sys/timeb.h>
|
||||
#endif
|
||||
|
||||
|
||||
/* Return the date. Return value is static data. */
|
||||
|
|
@ -65,8 +68,6 @@ datestring(void)
|
|||
|
||||
/* return time interval in seconds and milliseconds */
|
||||
|
||||
#ifndef HAVE_GETRUSAGE
|
||||
#ifndef HAVE_TIMES
|
||||
#ifdef HAVE_FTIME
|
||||
|
||||
struct timeb timebegin;
|
||||
|
|
@ -84,8 +85,6 @@ void timediff(struct timeb *now, struct timeb *begin, int *sec, int *msec)
|
|||
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -9,16 +9,12 @@
|
|||
char * datestring(void);
|
||||
double seconds(void);
|
||||
|
||||
#ifndef HAVE_GETRUSAGE
|
||||
#ifndef HAVE_TIMES
|
||||
#ifdef HAVE_FTIME
|
||||
|
||||
extern struct timeb timebegin;
|
||||
|
||||
void timediff(struct timeb *, struct timeb *, int *, int *);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -16,7 +16,12 @@
|
|||
#define STDERR_FILENO 2
|
||||
#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 */
|
||||
|
|
@ -131,11 +136,9 @@ typedef pthread_t threadId_t;
|
|||
#include <frontend/com_measure2.h>
|
||||
#include <frontend/misccoms.h>
|
||||
|
||||
#ifndef HAVE_GETRUSAGE
|
||||
#ifdef HAVE_FTIME
|
||||
#include <sys/timeb.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* To interupt a spice run */
|
||||
#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_ExecutePerLoop(void);
|
||||
double getvsrcval(double, char*);
|
||||
int sh_vecinit(runDesc *run);
|
||||
|
||||
void shared_exit(int status);
|
||||
|
|
@ -203,6 +207,8 @@ void sighandler_sharedspice(int num);
|
|||
|
||||
void wl_delete_first(wordlist **wlstart, wordlist **wlend);
|
||||
|
||||
int add_bkpt(void);
|
||||
|
||||
#if !defined(low_latency)
|
||||
static char* outstorage(char*, bool);
|
||||
static void printsend(void);
|
||||
|
|
@ -217,6 +223,7 @@ static ControlledExit* ngexit;
|
|||
static SendData* datfcn;
|
||||
static SendInitData* datinitfcn;
|
||||
static BGThreadRunning* bgtr;
|
||||
static GetVSRCData* getvdat;
|
||||
static pvector_info myvec = NULL;
|
||||
char **allvecs = NULL;
|
||||
char **allplots = NULL;
|
||||
|
|
@ -225,6 +232,7 @@ static bool nostatuswanted = FALSE;
|
|||
static bool nodatawanted = FALSE;
|
||||
static bool nodatainitwanted = FALSE;
|
||||
static bool nobgtrwanted = FALSE;
|
||||
static bool wantvdat = FALSE;
|
||||
static bool immediate = FALSE;
|
||||
static bool coquit = FALSE;
|
||||
static jmp_buf errbufm, errbufc;
|
||||
|
|
@ -244,7 +252,9 @@ mutexType fputsMutex;
|
|||
static bool is_initialized = FALSE;
|
||||
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*//*
|
||||
static struct plot *
|
||||
|
|
@ -293,12 +303,16 @@ static threadId_t tid, printtid, bgtid = (threadId_t) 0;
|
|||
static bool fl_running = FALSE;
|
||||
static bool fl_exited = TRUE;
|
||||
|
||||
static bool printstopp = FALSE;
|
||||
static bool ps_exited = TRUE;
|
||||
|
||||
#if defined(__MINGW32__) || defined(_MSC_VER)
|
||||
#define EXPORT_FLAVOR WINAPI
|
||||
#else
|
||||
#define EXPORT_FLAVOR
|
||||
#endif
|
||||
|
||||
/* starts a background thread, e.g. from command bg_run */
|
||||
static void * EXPORT_FLAVOR
|
||||
_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
|
||||
_thread_stop(void)
|
||||
{
|
||||
|
|
@ -374,13 +388,16 @@ sighandler_sharedspice(int num)
|
|||
|
||||
#endif /*THREADS*/
|
||||
|
||||
|
||||
/* run a ngspice command */
|
||||
static int
|
||||
runc(char* command)
|
||||
{
|
||||
char buf[1024] = "";
|
||||
sighandler oldHandler;
|
||||
#ifdef THREADS
|
||||
#ifndef low_latency
|
||||
int timeout = 0;
|
||||
#endif
|
||||
char *string;
|
||||
bool fl_bg = FALSE;
|
||||
command_id = threadid_self();
|
||||
|
|
@ -392,12 +409,24 @@ runc(char* command)
|
|||
#ifndef low_latency
|
||||
/* stop the printf thread 'printsend()' */
|
||||
else if (cieq("bg_pstop", command)) {
|
||||
printstopp = TRUE;
|
||||
while (!ps_exited && timeout < 100) {
|
||||
printstopp = TRUE;
|
||||
|
||||
#if defined(__MINGW32__) || defined(_MSC_VER)
|
||||
Sleep(100); // va: windows native
|
||||
Sleep(100); // va: windows native
|
||||
#else
|
||||
usleep(10000);
|
||||
usleep(10000);
|
||||
#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;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -408,7 +437,7 @@ runc(char* command)
|
|||
#endif
|
||||
|
||||
/* 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);
|
||||
if (SETJMP(jbuf, 1) != 0) {
|
||||
signal(SIGINT, oldHandler);
|
||||
|
|
@ -469,7 +498,7 @@ runc(char* command)
|
|||
|
||||
#ifdef THREADS
|
||||
|
||||
/* Checks if spice is running in the background */
|
||||
/* Checks if ngspice is running in the background */
|
||||
IMPEXP
|
||||
bool
|
||||
ngSpice_running (void)
|
||||
|
|
@ -478,8 +507,27 @@ ngSpice_running (void)
|
|||
}
|
||||
#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
|
||||
int
|
||||
ngSpice_Init(SendChar* printfcn, SendStat* statusfcn, ControlledExit* ngspiceexit,
|
||||
|
|
@ -578,12 +626,9 @@ ngSpice_Init(SendChar* printfcn, SendStat* statusfcn, ControlledExit* ngspiceexi
|
|||
struct passwd *pw;
|
||||
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));
|
||||
sprintf(s, "%s%s", pw->pw_dir, INITSTR);
|
||||
#endif
|
||||
|
||||
if (access(s, 0) == 0)
|
||||
inp_source(s);
|
||||
}
|
||||
|
|
@ -627,7 +672,14 @@ bot:
|
|||
}
|
||||
#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;
|
||||
|
||||
|
|
@ -638,7 +690,7 @@ bot:
|
|||
/* If caller has sent valid address for pfcn */
|
||||
if (!noprintfwanted)
|
||||
#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__
|
||||
printtid = (HANDLE)_beginthreadex(NULL, 0, (unsigned int (__stdcall *)(void *))printsend,
|
||||
(void*) NULL, 0, NULL);
|
||||
|
|
@ -659,7 +711,6 @@ IMPEXP
|
|||
int ngSpice_Command(char* comexec)
|
||||
{
|
||||
if ( ! setjmp(errbufc) ) {
|
||||
// HANDLE tid2;
|
||||
|
||||
immediate = FALSE;
|
||||
intermj = 1;
|
||||
|
|
@ -668,12 +719,9 @@ int ngSpice_Command(char* comexec)
|
|||
fprintf(stderr, no_init);
|
||||
return 1;
|
||||
}
|
||||
// tid2 = (HANDLE)_beginthreadex(NULL, 0, (PTHREAD_START_ROUTINE)runc, (void*)comexec,
|
||||
// 0, NULL);
|
||||
|
||||
runc(comexec);
|
||||
/* main thread prepares immediate detaching of dll,
|
||||
in case of controlled_exit from tid2 thread, caller is asked
|
||||
to detach dll via fcn ngexit() */
|
||||
/* main thread prepares immediate detaching of dll */
|
||||
immediate = TRUE;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -722,6 +770,7 @@ int ngSpice_Circ(char** circa){
|
|||
|
||||
if ( ! setjmp(errbufm) ) {
|
||||
intermj = 0;
|
||||
immediate = FALSE;
|
||||
/* count the entries */
|
||||
while (circa[entries]) {
|
||||
entries++;
|
||||
|
|
@ -747,7 +796,7 @@ char* ngSpice_CurPlot(void)
|
|||
}
|
||||
|
||||
/* 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
|
||||
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
|
||||
named by plotname */
|
||||
named by plotname. Last entry in the array is NULL. */
|
||||
IMPEXP
|
||||
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 */
|
||||
/*------------------------------------------------------*/
|
||||
|
||||
/* handling of escape characters (extra \ added) is removed, may be added by
|
||||
un-commenting some lines */
|
||||
/* handling of escape characters (extra \ added) only, if
|
||||
'set addescape' is given in .spiceinit */
|
||||
|
||||
int
|
||||
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
|
||||
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
|
||||
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
|
||||
sh_printf(const char *format, ...)
|
||||
|
|
@ -975,9 +1085,9 @@ sh_fputc(const char inp, FILE* f)
|
|||
static char* outstringerr = NULL;
|
||||
static char* outstringout = NULL;
|
||||
|
||||
#ifdef low_latency
|
||||
/* using the strings by the caller sent directly to the caller
|
||||
has to fast enough (low latency) */
|
||||
#if defined (low_latency) || !defined(THREADS)
|
||||
/* The strings issued by printf etc. are sent directly to the caller.
|
||||
The callback has to be fast enough (low latency). */
|
||||
int
|
||||
sh_fputsll(const char *input, FILE* outf)
|
||||
{
|
||||
|
|
@ -1065,7 +1175,8 @@ sh_fputsll(const char *input, FILE* outf)
|
|||
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
|
||||
sh_fputs(const char *input, FILE* outf)
|
||||
{
|
||||
|
|
@ -1187,6 +1298,8 @@ static char *outsend = NULL;
|
|||
static void
|
||||
printsend(void)
|
||||
{
|
||||
ps_exited = FALSE;
|
||||
printstopp = FALSE;
|
||||
for (;;) {
|
||||
#if defined(__MINGW32__) || defined(_MSC_VER)
|
||||
Sleep(50); // loop delay
|
||||
|
|
@ -1198,6 +1311,7 @@ printsend(void)
|
|||
mutex_lock(&fputsMutex);
|
||||
outsend = outstorage(NULL, FALSE);
|
||||
mutex_unlock(&fputsMutex);
|
||||
|
||||
break;
|
||||
}
|
||||
mutex_lock(&fputsMutex);
|
||||
|
|
@ -1210,6 +1324,7 @@ printsend(void)
|
|||
tfree(outsend);
|
||||
}
|
||||
}
|
||||
ps_exited = TRUE;
|
||||
}
|
||||
|
||||
/* 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().
|
||||
Update only every DELTATIME milliseconds */
|
||||
An update occurs only every DELTATIME milliseconds. */
|
||||
#define DELTATIME 150
|
||||
void SetAnalyse(
|
||||
char * Analyse, /*in: analysis type */
|
||||
int DecaPercent /*in: 10 times the progress [%]*/
|
||||
/*HWND hwAnalyse, in: global handle to analysis window */
|
||||
) {
|
||||
#ifdef HAVE_FTIME
|
||||
static int OldPercent = -2; /* Previous progress value */
|
||||
static char OldAn[128]; /* Previous analysis type */
|
||||
char* s; /* outputs to callback function */
|
||||
|
|
@ -1321,10 +1437,21 @@ void SetAnalyse(
|
|||
result = statfcn(s, userptr);
|
||||
}
|
||||
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
|
||||
(e.g. being detached) via a callback function*/
|
||||
/* a dll or shared library should never exit, if loaded dynamically,
|
||||
but ask for graceful shutdown (e.g. being detached) via a callback function*/
|
||||
void shared_exit(int status)
|
||||
{
|
||||
/* alert caller to detach dll (if we are in the main thread),
|
||||
|
|
@ -1364,8 +1491,23 @@ void shared_exit(int status)
|
|||
tfree(outsend);
|
||||
}
|
||||
#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
|
||||
ngexit(status, immediate, coquit, userptr);
|
||||
|
||||
// jump back to finish the calling function
|
||||
if (!intermj)
|
||||
longjmp(errbufm,1); /* jump back to ngSpice_Circ() */
|
||||
|
|
@ -1448,7 +1590,7 @@ int sh_ExecutePerLoop(void)
|
|||
{
|
||||
struct dvec *d;
|
||||
int i, veclen;
|
||||
double testval;
|
||||
// double testval;
|
||||
struct plot *pl = plot_cur;
|
||||
/* return immediately if callback not wanted */
|
||||
if (nodatawanted)
|
||||
|
|
@ -1456,11 +1598,12 @@ int sh_ExecutePerLoop(void)
|
|||
|
||||
/* get the data of the last entry to the plot vector */
|
||||
veclen = pl->pl_dvecs->v_length - 1;
|
||||
curvecvalsall->vecindex = veclen;
|
||||
for (d = pl->pl_dvecs, i = 0; d; d = d->v_next, i++) {
|
||||
/* test if real */
|
||||
if (d->v_flags & VF_REAL) {
|
||||
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]->cimag = 0.;
|
||||
}
|
||||
|
|
@ -1478,7 +1621,7 @@ int sh_ExecutePerLoop(void)
|
|||
|
||||
|
||||
/* 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()
|
||||
and sets transfer structure for use in sh_ExecutePerLoop() */
|
||||
int sh_vecinit(runDesc *run)
|
||||
|
|
@ -1536,14 +1679,13 @@ int sh_vecinit(runDesc *run)
|
|||
data will be sent from sh_ExecutePerLoop() via datfcn() */
|
||||
if (!curvecvalsall) {
|
||||
curvecvalsall = TMALLOC(vecvaluesall, 1);
|
||||
curvecvalsall->veccount = veccount;
|
||||
}
|
||||
else {
|
||||
for (i = 0; i < curvecvalsall->veccount; i++)
|
||||
tfree(curvecvalsall->vecsa[i]);
|
||||
tfree(curvecvalsall->vecsa);
|
||||
}
|
||||
|
||||
curvecvalsall->veccount = veccount;
|
||||
curvecvalsall->vecsa = TMALLOC(pvecvalues, veccount);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/* 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
|
||||
|
||||
|
||||
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_CFLAGS = $(STATIC)
|
||||
MAINTAINERCLEANFILES = Makefile.in
|
||||
|
|
|
|||
|
|
@ -149,11 +149,11 @@ ACan(CKTcircuit *ckt, int restart)
|
|||
* Moreover the begin plot has not even been done yet at this
|
||||
* point...
|
||||
*/
|
||||
SPfrontEnd->OUTpBeginPlot (
|
||||
ckt, ckt->CKTcurJob,
|
||||
ckt->CKTcurJob->JOBname,
|
||||
NULL, IF_REAL,
|
||||
numNames, nameList, IF_REAL, &acPlot);
|
||||
SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
|
||||
ckt->CKTcurJob->JOBname,
|
||||
NULL, IF_REAL,
|
||||
numNames, nameList, IF_REAL,
|
||||
&acPlot);
|
||||
tfree(nameList);
|
||||
|
||||
ipc_send_dcop_prefix();
|
||||
|
|
@ -174,30 +174,28 @@ ACan(CKTcircuit *ckt, int restart)
|
|||
|
||||
if (ckt->CKTkeepOpInfo) {
|
||||
/* Dump operating point. */
|
||||
error = SPfrontEnd->OUTpBeginPlot (
|
||||
ckt, ckt->CKTcurJob,
|
||||
"AC Operating Point",
|
||||
NULL, IF_REAL,
|
||||
numNames, nameList, IF_REAL, &plot);
|
||||
error = SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
|
||||
"AC Operating Point",
|
||||
NULL, IF_REAL,
|
||||
numNames, nameList, IF_REAL,
|
||||
&plot);
|
||||
if(error) return(error);
|
||||
CKTdump(ckt, 0.0, plot);
|
||||
SPfrontEnd->OUTendPlot (plot);
|
||||
plot = NULL;
|
||||
}
|
||||
|
||||
SPfrontEnd->IFnewUid (ckt, &freqUid, NULL,
|
||||
"frequency", UID_OTHER, NULL);
|
||||
error = SPfrontEnd->OUTpBeginPlot (
|
||||
ckt, ckt->CKTcurJob,
|
||||
ckt->CKTcurJob->JOBname,
|
||||
freqUid, IF_REAL,
|
||||
numNames, nameList, IF_COMPLEX, &acPlot);
|
||||
SPfrontEnd->IFnewUid (ckt, &freqUid, NULL, "frequency", UID_OTHER, NULL);
|
||||
error = SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
|
||||
ckt->CKTcurJob->JOBname,
|
||||
freqUid, IF_REAL,
|
||||
numNames, nameList, IF_COMPLEX,
|
||||
&acPlot);
|
||||
tfree(nameList);
|
||||
if(error) return(error);
|
||||
|
||||
if (job->ACstepType != LINEAR) {
|
||||
SPfrontEnd->OUTattributes (acPlot, NULL,
|
||||
OUT_SCALE_LOG, NULL);
|
||||
SPfrontEnd->OUTattributes (acPlot, NULL, OUT_SCALE_LOG, NULL);
|
||||
}
|
||||
freq = job->ACstartFreq;
|
||||
|
||||
|
|
@ -205,11 +203,11 @@ ACan(CKTcircuit *ckt, int restart)
|
|||
freq = job->ACsaveFreq;
|
||||
job->ACsaveFreq = 0; /* clear the 'old' frequency */
|
||||
/* fix resume? saj, indeed !*/
|
||||
error = SPfrontEnd->OUTpBeginPlot (
|
||||
NULL, NULL,
|
||||
NULL,
|
||||
NULL, 0,
|
||||
666, NULL, 666, &acPlot);
|
||||
error = SPfrontEnd->OUTpBeginPlot (NULL, NULL,
|
||||
NULL,
|
||||
NULL, 0,
|
||||
666, NULL, 666,
|
||||
&acPlot);
|
||||
/* saj*/
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,6 +20,10 @@ extern SPICEanalysis SENSinfo;
|
|||
extern SPICEanalysis PSSinfo;
|
||||
#endif
|
||||
|
||||
#ifdef WANT_SENSE2
|
||||
extern SPICEanalysis SEN2info;
|
||||
#endif
|
||||
|
||||
SPICEanalysis *analInfo[] = {
|
||||
&OPTinfo,
|
||||
&ACinfo,
|
||||
|
|
@ -34,6 +38,9 @@ SPICEanalysis *analInfo[] = {
|
|||
#ifdef WITH_PSS
|
||||
&PSSinfo,
|
||||
#endif
|
||||
#ifdef WANT_SENSE2
|
||||
&SEN2info,
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -52,6 +52,11 @@ CKTload(CKTcircuit *ckt)
|
|||
size = SMPmatSize(ckt->CKTmatrix);
|
||||
for (i = 0; i <= size; i++) {
|
||||
ckt->CKTrhs[i] = 0;
|
||||
|
||||
#ifdef KIRCHHOFF
|
||||
ckt->CKTfvk[i] = 0;
|
||||
#endif
|
||||
|
||||
}
|
||||
SMPclear(ckt->CKTmatrix);
|
||||
#ifdef STEPDEBUG
|
||||
|
|
|
|||
|
|
@ -35,12 +35,8 @@ CKTmapNode(CKTcircuit *ckt, CKTnode **node, IFuid name)
|
|||
/* not found, so must be a new one */
|
||||
error = CKTmkNode(ckt,&mynode); /*allocate the node*/
|
||||
if(error) return(error);
|
||||
error = SPfrontEnd->IFnewUid (ckt,
|
||||
&uid,
|
||||
NULL,
|
||||
name,
|
||||
UID_SIGNAL,
|
||||
&mynode); /* get a uid for it */
|
||||
/* get a uid for it */
|
||||
error = SPfrontEnd->IFnewUid (ckt, &uid, NULL, name, UID_SIGNAL, &mynode);
|
||||
if(error) return(error);
|
||||
mynode->name = uid; /* set the info we have */
|
||||
mynode->type = SP_VOLTAGE;
|
||||
|
|
|
|||
|
|
@ -29,8 +29,7 @@ CKTmkCur(CKTcircuit *ckt, CKTnode **node, IFuid basename, char *suffix)
|
|||
error = CKTmkNode(ckt,&mynode);
|
||||
if(error) return(error);
|
||||
checknode = mynode;
|
||||
error = SPfrontEnd->IFnewUid (ckt, &uid, basename,
|
||||
suffix, UID_SIGNAL, &checknode);
|
||||
error = SPfrontEnd->IFnewUid (ckt, &uid, basename, suffix, UID_SIGNAL, &checknode);
|
||||
if(error) {
|
||||
FREE(mynode);
|
||||
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);
|
||||
if(mynode == NULL) return(E_NOMEM);
|
||||
mynode->next = NULL;
|
||||
mynode->name = (IFuid) 0;
|
||||
mynode->name = NULL;
|
||||
|
||||
if(node) *node = mynode;
|
||||
return(OK);
|
||||
|
|
|
|||
|
|
@ -27,8 +27,7 @@ CKTmkVolt(CKTcircuit *ckt, CKTnode **node, IFuid basename, char *suffix)
|
|||
error = CKTmkNode(ckt,&mynode);
|
||||
if(error) return(error);
|
||||
checknode = mynode;
|
||||
error = SPfrontEnd->IFnewUid (ckt, &uid, basename,
|
||||
suffix, UID_SIGNAL, &checknode);
|
||||
error = SPfrontEnd->IFnewUid (ckt, &uid, basename, suffix, UID_SIGNAL, &checknode);
|
||||
if(error) {
|
||||
FREE(mynode);
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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 */
|
||||
|
||||
|
|
@ -73,11 +73,11 @@ CKTnoise (CKTcircuit *ckt, int mode, int operation, Ndata *data)
|
|||
|
||||
data->namelist = TREALLOC(IFuid, data->namelist, data->numPlots + 1);
|
||||
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);
|
||||
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 */
|
||||
|
||||
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
|
||||
&& NIpzK != 0.0 && NIpzK_mag > -10) {
|
||||
#ifdef notdef
|
||||
if (p->flags & ISAROOT) {
|
||||
/* Ugh! muller doesn't work right */
|
||||
new_trial->flags = ISAMINIMA;
|
||||
new_trial->s.imag = scalb(NIpzK, (int) (NIpzK_mag / 2));
|
||||
pretest = 0;
|
||||
} else {
|
||||
// if (p->flags & ISAROOT) {
|
||||
// /* Ugh! muller doesn't work right */
|
||||
// new_trial->flags = ISAMINIMA;
|
||||
// new_trial->s.imag = scalb(NIpzK, (int) (NIpzK_mag / 2));
|
||||
// pretest = 0;
|
||||
// } else {
|
||||
#endif
|
||||
p->flags |= ISAMINIMA;
|
||||
tfree(new_trial);
|
||||
|
|
|
|||
|
|
@ -184,9 +184,7 @@ int sens_sens(CKTcircuit *ckt, int restart)
|
|||
sg->ptable[sg->param].keyword);
|
||||
}
|
||||
|
||||
SPfrontEnd->IFnewUid (ckt,
|
||||
output_names + k, NULL,
|
||||
namebuf, UID_OTHER, NULL);
|
||||
SPfrontEnd->IFnewUid (ckt, output_names + k, NULL, namebuf, UID_OTHER, NULL);
|
||||
k += 1;
|
||||
}
|
||||
|
||||
|
|
@ -195,16 +193,14 @@ int sens_sens(CKTcircuit *ckt, int restart)
|
|||
freq_name = NULL;
|
||||
} else {
|
||||
type = IF_COMPLEX;
|
||||
SPfrontEnd->IFnewUid (ckt,
|
||||
&freq_name, NULL,
|
||||
"frequency", UID_OTHER, NULL);
|
||||
SPfrontEnd->IFnewUid (ckt, &freq_name, NULL, "frequency", UID_OTHER, NULL);
|
||||
}
|
||||
|
||||
error = SPfrontEnd->OUTpBeginPlot (
|
||||
ckt, ckt->CKTcurJob,
|
||||
ckt->CKTcurJob->JOBname,
|
||||
freq_name, IF_REAL,
|
||||
num_vars, output_names, type, &sen_data);
|
||||
error = SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
|
||||
ckt->CKTcurJob->JOBname,
|
||||
freq_name, IF_REAL,
|
||||
num_vars, output_names, type,
|
||||
&sen_data);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
|
|
@ -216,8 +212,7 @@ int sens_sens(CKTcircuit *ckt, int restart)
|
|||
output_values = NULL;
|
||||
output_cvalues = NEWN(IFcomplex, num_vars);
|
||||
if (job->step_type != SENS_LINEAR)
|
||||
SPfrontEnd->OUTattributes (sen_data,
|
||||
NULL, OUT_SCALE_LOG, NULL);
|
||||
SPfrontEnd->OUTattributes (sen_data, NULL, OUT_SCALE_LOG, NULL);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -61,7 +61,9 @@ CKTsetup(CKTcircuit *ckt)
|
|||
|
||||
#ifdef WANT_SENSE2
|
||||
if(ckt->CKTsenInfo){
|
||||
if (error = CKTsenSetup(ckt)) return(error);
|
||||
error = CKTsenSetup(ckt);
|
||||
if (error)
|
||||
return(error);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -269,6 +271,22 @@ CKTsetup(CKTcircuit *ckt)
|
|||
|
||||
/* gtri - end - Setup for adding rshunt option resistors */
|
||||
#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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -237,8 +237,8 @@ int set_param(sgen *sg)
|
|||
}
|
||||
|
||||
#ifdef notdef
|
||||
sgen_suspend(sg)
|
||||
sgen *sg;
|
||||
void
|
||||
sgen_suspend(sgen *sg)
|
||||
{
|
||||
sg->devlist[sg->dev] = sg->first_model;
|
||||
sg->model->GENnextModel = sg->next_model;
|
||||
|
|
@ -246,8 +246,8 @@ sgen_suspend(sg)
|
|||
sg->model->GENinstances = sg->first_instance;
|
||||
}
|
||||
|
||||
sgen_restore(sg)
|
||||
sgen *sg;
|
||||
void
|
||||
sgen_restore(sgen *sg)
|
||||
{
|
||||
sg->devlist[sg->dev] = sg->model;
|
||||
sg->model->GENnextModel = NULL;
|
||||
|
|
|
|||
|
|
@ -21,6 +21,11 @@ Modified: 2000 AlansFixes
|
|||
int
|
||||
DCop(CKTcircuit *ckt, int notused)
|
||||
{
|
||||
#ifdef WANT_SENSE2
|
||||
int i, senmode, size;
|
||||
long save;
|
||||
#endif
|
||||
|
||||
int converged;
|
||||
int error;
|
||||
IFuid *nameList; /* va: tmalloc'ed list */
|
||||
|
|
@ -45,11 +50,11 @@ DCop(CKTcircuit *ckt, int notused)
|
|||
|
||||
error = CKTnames(ckt,&numNames,&nameList);
|
||||
if(error) return(error);
|
||||
error = SPfrontEnd->OUTpBeginPlot (
|
||||
ckt, ckt->CKTcurJob,
|
||||
ckt->CKTcurJob->JOBname,
|
||||
NULL, IF_REAL,
|
||||
numNames, nameList, IF_REAL, &plot);
|
||||
error = SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
|
||||
ckt->CKTcurJob->JOBname,
|
||||
NULL, IF_REAL,
|
||||
numNames, nameList, IF_REAL,
|
||||
&plot);
|
||||
tfree(nameList); /* va: nameList not used any longer, it was a memory leak */
|
||||
if(error) return(error);
|
||||
|
||||
|
|
@ -133,7 +138,10 @@ DCop(CKTcircuit *ckt, int notused)
|
|||
for(i = 1; i<=size ; i++){
|
||||
ckt->CKTrhsOp[i] = ckt->CKTrhsOld[i];
|
||||
}
|
||||
if(error = CKTsenDCtran(ckt)) return(error);
|
||||
error = CKTsenDCtran(ckt);
|
||||
if (error)
|
||||
return(error);
|
||||
|
||||
ckt->CKTmode = save;
|
||||
ckt->CKTsenInfo->SENmode = senmode;
|
||||
|
||||
|
|
|
|||
|
|
@ -237,13 +237,12 @@ DCpss(CKTcircuit *ckt,
|
|||
/* Time Domain plot start and prepared to be filled in later */
|
||||
error = CKTnames(ckt,&numNames,&nameList);
|
||||
if(error) return(error);
|
||||
SPfrontEnd->IFnewUid (ckt, &timeUid, NULL,
|
||||
"time", UID_OTHER, NULL);
|
||||
error = SPfrontEnd->OUTpBeginPlot (
|
||||
ckt, ckt->CKTcurJob,
|
||||
"Time Domain Periodic Steady State Analysis",
|
||||
timeUid, IF_REAL,
|
||||
numNames, nameList, IF_REAL, &(job->PSSplot_td));
|
||||
SPfrontEnd->IFnewUid (ckt, &timeUid, NULL, "time", UID_OTHER, NULL);
|
||||
error = SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
|
||||
"Time Domain Periodic Steady State Analysis",
|
||||
timeUid, IF_REAL,
|
||||
numNames, nameList, IF_REAL,
|
||||
&(job->PSSplot_td));
|
||||
tfree(nameList);
|
||||
if(error) return(error);
|
||||
|
||||
|
|
@ -406,11 +405,11 @@ DCpss(CKTcircuit *ckt,
|
|||
if(ckt->CKTminBreak==0) ckt->CKTminBreak=ckt->CKTmaxStep*5e-5;
|
||||
firsttime=0;
|
||||
/* To get rawfile working saj*/
|
||||
error = SPfrontEnd->OUTpBeginPlot (
|
||||
NULL, NULL,
|
||||
NULL,
|
||||
NULL, 0,
|
||||
666, NULL, 666, &(job->PSSplot_td));
|
||||
error = SPfrontEnd->OUTpBeginPlot (NULL, NULL,
|
||||
NULL,
|
||||
NULL, 0,
|
||||
666, NULL, 666,
|
||||
&(job->PSSplot_td));
|
||||
if(error) {
|
||||
fprintf(stderr, "Couldn't relink rawfile\n");
|
||||
return error;
|
||||
|
|
@ -1039,8 +1038,11 @@ DCpss(CKTcircuit *ckt,
|
|||
if (error)
|
||||
return (error) ;
|
||||
SPfrontEnd->IFnewUid (ckt, &freqUid, NULL, "frequency", UID_OTHER, NULL) ;
|
||||
error = SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob, "Frequency Domain Periodic Steady State Analysis",
|
||||
freqUid, IF_REAL, numNames, nameList, IF_REAL, &(job->PSSplot_fd)) ;
|
||||
error = SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
|
||||
"Frequency Domain Periodic Steady State Analysis",
|
||||
freqUid, IF_REAL,
|
||||
numNames, nameList, IF_REAL,
|
||||
&(job->PSSplot_fd)) ;
|
||||
tfree (nameList) ;
|
||||
SPfrontEnd->OUTattributes (job->PSSplot_fd, NULL, PLOT_COMB, NULL) ;
|
||||
|
||||
|
|
@ -1204,9 +1206,25 @@ resume:
|
|||
#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 */
|
||||
|
||||
if(ckt->CKTtime + ckt->CKTdelta >= g_mif_info.breakpoint.current) {
|
||||
|
|
@ -1247,28 +1265,7 @@ resume:
|
|||
}
|
||||
|
||||
/* 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 */
|
||||
|
||||
if(ckt->evt->counts.num_insts > 0) {
|
||||
|
|
@ -1311,6 +1308,15 @@ resume:
|
|||
} /* end if there are event instances */
|
||||
|
||||
/* 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
|
||||
|
||||
/* What is that??? */
|
||||
|
|
|
|||
|
|
@ -34,6 +34,9 @@ extern struct dbcomm *dbs;
|
|||
#include "ngspice/cluster.h"
|
||||
#endif
|
||||
|
||||
#ifdef SHARED_MODULE
|
||||
extern int add_bkpt(void);
|
||||
#endif
|
||||
|
||||
#define INIT_STATS() \
|
||||
do { \
|
||||
|
|
@ -78,9 +81,8 @@ DCtran(CKTcircuit *ckt,
|
|||
int firsttime;
|
||||
int error;
|
||||
#ifdef WANT_SENSE2
|
||||
#ifdef SENSDEBUG
|
||||
FILE *outsen;
|
||||
#endif /* SENSDEBUG */
|
||||
int save, save2, size;
|
||||
long save1;
|
||||
#endif
|
||||
int save_order;
|
||||
long save_mode;
|
||||
|
|
@ -132,7 +134,9 @@ DCtran(CKTcircuit *ckt,
|
|||
ckt->CKTbreaks[0] = 0;
|
||||
ckt->CKTbreaks[1] = ckt->CKTfinalTime;
|
||||
ckt->CKTbreakSize = 2;
|
||||
|
||||
#ifdef SHARED_MODULE
|
||||
add_bkpt();
|
||||
#endif
|
||||
#ifdef XSPICE
|
||||
/* gtri - begin - wbk - 12/19/90 - Modify setting of CKTminBreak */
|
||||
/* Set to 10 times delmin for ATESSE 1 compatibity */
|
||||
|
|
@ -155,13 +159,12 @@ DCtran(CKTcircuit *ckt,
|
|||
#endif
|
||||
error = CKTnames(ckt,&numNames,&nameList);
|
||||
if(error) return(error);
|
||||
SPfrontEnd->IFnewUid (ckt, &timeUid, NULL,
|
||||
"time", UID_OTHER, NULL);
|
||||
error = SPfrontEnd->OUTpBeginPlot (
|
||||
ckt, ckt->CKTcurJob,
|
||||
ckt->CKTcurJob->JOBname,
|
||||
timeUid, IF_REAL,
|
||||
numNames, nameList, IF_REAL, &(job->TRANplot));
|
||||
SPfrontEnd->IFnewUid (ckt, &timeUid, NULL, "time", UID_OTHER, NULL);
|
||||
error = SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
|
||||
ckt->CKTcurJob->JOBname,
|
||||
timeUid, IF_REAL,
|
||||
numNames, nameList, IF_REAL,
|
||||
&(job->TRANplot));
|
||||
tfree(nameList);
|
||||
if(error) return(error);
|
||||
|
||||
|
|
@ -316,7 +319,10 @@ DCtran(CKTcircuit *ckt,
|
|||
save2 = ckt->CKTorder;
|
||||
ckt->CKTmode = save_mode;
|
||||
ckt->CKTorder = save_order;
|
||||
if(error = CKTsenDCtran(ckt)) return(error);
|
||||
error = CKTsenDCtran(ckt);
|
||||
if (error)
|
||||
return(error);
|
||||
|
||||
ckt->CKTmode = save1;
|
||||
ckt->CKTorder = save2;
|
||||
}
|
||||
|
|
@ -348,11 +354,11 @@ DCtran(CKTcircuit *ckt,
|
|||
if(ckt->CKTminBreak==0) ckt->CKTminBreak=ckt->CKTmaxStep*5e-5;
|
||||
firsttime=0;
|
||||
/* To get rawfile working saj*/
|
||||
error = SPfrontEnd->OUTpBeginPlot (
|
||||
NULL, NULL,
|
||||
NULL,
|
||||
NULL, 0,
|
||||
666, NULL, 666, &(job->TRANplot));
|
||||
error = SPfrontEnd->OUTpBeginPlot (NULL, NULL,
|
||||
NULL,
|
||||
NULL, 0,
|
||||
666, NULL, 666,
|
||||
&(job->TRANplot));
|
||||
if(error) {
|
||||
fprintf(stderr, "Couldn't relink rawfile\n");
|
||||
return error;
|
||||
|
|
@ -479,9 +485,6 @@ DCtran(CKTcircuit *ckt,
|
|||
#ifdef WANT_SENSE2
|
||||
if(ckt->CKTsenInfo && (ckt->CKTsenInfo->SENmode & TRANSEN)){
|
||||
ckt->CKTsenInfo->SENmode = save;
|
||||
#ifdef SENSDEBUG
|
||||
fclose(outsen);
|
||||
#endif /* SENSDEBUG */
|
||||
}
|
||||
#endif
|
||||
return(OK);
|
||||
|
|
@ -508,7 +511,7 @@ resume:
|
|||
if (ckt->CKTtime == 0.)
|
||||
SetAnalyse( "tran init", 0);
|
||||
else
|
||||
SetAnalyse( "tran", (int)((ckt->CKTtime * 1000.) / ckt->CKTfinalTime) + 0.5);
|
||||
SetAnalyse( "tran", (int)((ckt->CKTtime * 1000.) / ckt->CKTfinalTime + 0.5));
|
||||
#endif
|
||||
ckt->CKTdelta =
|
||||
MIN(ckt->CKTdelta,ckt->CKTmaxStep);
|
||||
|
|
@ -546,15 +549,37 @@ resume:
|
|||
ckt->CKTbreaks[1] - ckt->CKTbreaks[0]));
|
||||
|
||||
if(firsttime) {
|
||||
/* set a breakpoint to reduce ringing of current in devices */
|
||||
if (ckt->CKTmode&MODEUIC)
|
||||
CKTsetBreak(ckt,ckt->CKTstep);
|
||||
|
||||
ckt->CKTdelta /= 10;
|
||||
#ifdef STEPDEBUG
|
||||
(void)printf("delta cut for initial timepoint\n");
|
||||
#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 */
|
||||
|
||||
if(ckt->CKTtime + ckt->CKTdelta >= g_mif_info.breakpoint.current) {
|
||||
|
|
@ -595,30 +620,7 @@ resume:
|
|||
}
|
||||
|
||||
/* 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 */
|
||||
|
||||
if(ckt->evt->counts.num_insts > 0) {
|
||||
|
|
@ -661,6 +663,15 @@ resume:
|
|||
} /* end if there are event instances */
|
||||
|
||||
/* 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
|
||||
for(i=5; i>=0; i--)
|
||||
ckt->CKTdeltaOld[i+1] = ckt->CKTdeltaOld[i];
|
||||
|
|
@ -792,7 +803,10 @@ resume:
|
|||
save2 = ckt->CKTorder;
|
||||
ckt->CKTmode = save_mode;
|
||||
ckt->CKTorder = save_order;
|
||||
if(error = CKTsenDCtran(ckt)) return(error);
|
||||
error = CKTsenDCtran (ckt);
|
||||
if (error)
|
||||
return(error);
|
||||
|
||||
ckt->CKTmode = save1;
|
||||
ckt->CKTorder = save2;
|
||||
}
|
||||
|
|
@ -852,7 +866,10 @@ resume:
|
|||
save2 = ckt->CKTorder;
|
||||
ckt->CKTmode = save_mode;
|
||||
ckt->CKTorder = save_order;
|
||||
if(error = CKTsenDCtran(ckt)) return(error);
|
||||
error = CKTsenDCtran(ckt);
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
ckt->CKTmode = save1;
|
||||
ckt->CKTorder = save2;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ DCtrCurv(CKTcircuit *ckt, int restart)
|
|||
static runDesc *plot = NULL;
|
||||
|
||||
#ifdef WANT_SENSE2
|
||||
long save;
|
||||
#ifdef SENSDEBUG
|
||||
if(ckt->CKTsenInfo && (ckt->CKTsenInfo->SENmode&DCSEN) ){
|
||||
printf("\nDC Sensitivity Results\n\n");
|
||||
|
|
@ -66,11 +67,11 @@ DCtrCurv(CKTcircuit *ckt, int restart)
|
|||
/* continuing */
|
||||
i = job->TRCVnestState;
|
||||
/* resume to work? saj*/
|
||||
error = SPfrontEnd->OUTpBeginPlot (
|
||||
NULL, NULL,
|
||||
NULL,
|
||||
NULL, 0,
|
||||
666, NULL, 666, &plot);
|
||||
error = SPfrontEnd->OUTpBeginPlot (NULL, NULL,
|
||||
NULL,
|
||||
NULL, 0,
|
||||
666, NULL, 666,
|
||||
&plot);
|
||||
goto resume;
|
||||
}
|
||||
ckt->CKTtime = 0;
|
||||
|
|
@ -192,36 +193,31 @@ found:;
|
|||
|
||||
|
||||
if (job->TRCVvType[i] == vcode)
|
||||
SPfrontEnd->IFnewUid (ckt, &varUid, NULL,
|
||||
"v-sweep", UID_OTHER, NULL);
|
||||
SPfrontEnd->IFnewUid (ckt, &varUid, NULL, "v-sweep", UID_OTHER, NULL);
|
||||
|
||||
else {
|
||||
if (job->TRCVvType[i] == icode)
|
||||
SPfrontEnd->IFnewUid (ckt, &varUid, NULL,
|
||||
"i-sweep", UID_OTHER, NULL);
|
||||
SPfrontEnd->IFnewUid (ckt, &varUid, NULL, "i-sweep", UID_OTHER, NULL);
|
||||
|
||||
else {
|
||||
if (job->TRCVvType[i] == TEMP_CODE)
|
||||
SPfrontEnd->IFnewUid (ckt, &varUid, NULL,
|
||||
"temp-sweep", UID_OTHER, NULL);
|
||||
SPfrontEnd->IFnewUid (ckt, &varUid, NULL, "temp-sweep", UID_OTHER, NULL);
|
||||
|
||||
else {
|
||||
if (job->TRCVvType[i] == rcode)
|
||||
SPfrontEnd->IFnewUid (ckt, &varUid, NULL,
|
||||
"res-sweep", UID_OTHER, NULL);
|
||||
SPfrontEnd->IFnewUid (ckt, &varUid, NULL, "res-sweep", UID_OTHER, NULL);
|
||||
|
||||
else
|
||||
SPfrontEnd->IFnewUid (ckt, &varUid, NULL,
|
||||
"?-sweep", UID_OTHER, NULL);
|
||||
SPfrontEnd->IFnewUid (ckt, &varUid, NULL, "?-sweep", UID_OTHER, NULL);
|
||||
} /* icode */
|
||||
} /* TEMP_CODE */
|
||||
} /* rcode*/
|
||||
|
||||
error = SPfrontEnd->OUTpBeginPlot (
|
||||
ckt, ckt->CKTcurJob,
|
||||
ckt->CKTcurJob->JOBname,
|
||||
varUid, IF_REAL,
|
||||
numNames, nameList, IF_REAL, &plot);
|
||||
error = SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
|
||||
ckt->CKTcurJob->JOBname,
|
||||
varUid, IF_REAL,
|
||||
numNames, nameList, IF_REAL,
|
||||
&plot);
|
||||
tfree(nameList);
|
||||
|
||||
if(error) return(error);
|
||||
|
|
@ -450,7 +446,7 @@ resume:
|
|||
}
|
||||
if (job->TRCVvType[i] == TEMP_CODE) { /* Temperature */
|
||||
printf("Current Circuit Temperature : %.5e C\n",
|
||||
ckt-CKTtemp - CONSTCtoK);
|
||||
ckt->CKTtemp - CONSTCtoK);
|
||||
}
|
||||
|
||||
#endif /* SENSDEBUG */
|
||||
|
|
@ -458,7 +454,10 @@ resume:
|
|||
senmode = ckt->CKTsenInfo->SENmode;
|
||||
save = ckt->CKTmode;
|
||||
ckt->CKTsenInfo->SENmode = DCSEN;
|
||||
if(error = CKTsenDCtran(ckt)) return (error);
|
||||
error = CKTsenDCtran(ckt);
|
||||
if (error)
|
||||
return(error);
|
||||
|
||||
ckt->CKTmode = save;
|
||||
ckt->CKTsenInfo->SENmode = senmode;
|
||||
|
||||
|
|
|
|||
|
|
@ -107,11 +107,11 @@ time1 = SPfrontEnd->IFseconds();
|
|||
|
||||
if (ckt->CKTkeepOpInfo) {
|
||||
/* Dump operating point. */
|
||||
error = SPfrontEnd->OUTpBeginPlot (
|
||||
ckt, ckt->CKTcurJob,
|
||||
"Distortion Operating Point",
|
||||
NULL, IF_REAL,
|
||||
numNames, nameList, IF_REAL, &acPlot);
|
||||
error = SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
|
||||
"Distortion Operating Point",
|
||||
NULL, IF_REAL,
|
||||
numNames, nameList, IF_REAL,
|
||||
&acPlot);
|
||||
if(error) return(error);
|
||||
CKTdump(ckt, 0.0, acPlot);
|
||||
SPfrontEnd->OUTendPlot (acPlot);
|
||||
|
|
@ -516,16 +516,14 @@ time1 = SPfrontEnd->IFseconds();
|
|||
if (! job->Df2wanted) {
|
||||
error = CKTnames(ckt,&numNames,&nameList);
|
||||
if(error) return(error);
|
||||
SPfrontEnd->IFnewUid (ckt, &freqUid, NULL,
|
||||
"frequency", UID_OTHER, NULL);
|
||||
SPfrontEnd->OUTpBeginPlot (
|
||||
ckt, ckt->CKTcurJob,
|
||||
"DISTORTION - 2nd harmonic",
|
||||
freqUid, IF_REAL,
|
||||
numNames, nameList, IF_COMPLEX, &acPlot);
|
||||
SPfrontEnd->IFnewUid (ckt, &freqUid, NULL, "frequency", UID_OTHER, NULL);
|
||||
SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
|
||||
"DISTORTION - 2nd harmonic",
|
||||
freqUid, IF_REAL,
|
||||
numNames, nameList, IF_COMPLEX,
|
||||
&acPlot);
|
||||
if (job->DstepType != LINEAR) {
|
||||
SPfrontEnd->OUTattributes (acPlot, NULL,
|
||||
OUT_SCALE_LOG, NULL);
|
||||
SPfrontEnd->OUTattributes (acPlot, NULL, OUT_SCALE_LOG, NULL);
|
||||
}
|
||||
for (i=0; i< displacement ; i++)
|
||||
{
|
||||
|
|
@ -542,13 +540,12 @@ time1 = SPfrontEnd->IFseconds();
|
|||
|
||||
error = CKTnames(ckt,&numNames,&nameList);
|
||||
if(error) return(error);
|
||||
SPfrontEnd->IFnewUid (ckt, &freqUid, NULL,
|
||||
"frequency", UID_OTHER, NULL);
|
||||
SPfrontEnd->OUTpBeginPlot (
|
||||
ckt, ckt->CKTcurJob,
|
||||
"DISTORTION - 3rd harmonic",
|
||||
freqUid, IF_REAL,
|
||||
numNames, nameList, IF_COMPLEX, &acPlot);
|
||||
SPfrontEnd->IFnewUid (ckt, &freqUid, NULL, "frequency", UID_OTHER, NULL);
|
||||
SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
|
||||
"DISTORTION - 3rd harmonic",
|
||||
freqUid, IF_REAL,
|
||||
numNames, nameList, IF_COMPLEX,
|
||||
&acPlot);
|
||||
for (i=0; i< displacement ; i++)
|
||||
{
|
||||
DkerProc(D_THRF1,job->r3H11stor[i],
|
||||
|
|
@ -566,13 +563,12 @@ time1 = SPfrontEnd->IFseconds();
|
|||
|
||||
error = CKTnames(ckt,&numNames,&nameList);
|
||||
if(error) return(error);
|
||||
SPfrontEnd->IFnewUid (ckt, &freqUid, NULL,
|
||||
"frequency", UID_OTHER, NULL);
|
||||
SPfrontEnd->OUTpBeginPlot (
|
||||
ckt, ckt->CKTcurJob,
|
||||
"DISTORTION - IM: f1+f2",
|
||||
freqUid, IF_REAL,
|
||||
numNames, nameList, IF_COMPLEX, &acPlot);
|
||||
SPfrontEnd->IFnewUid (ckt, &freqUid, NULL, "frequency", UID_OTHER, NULL);
|
||||
SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
|
||||
"DISTORTION - IM: f1+f2",
|
||||
freqUid, IF_REAL,
|
||||
numNames, nameList, IF_COMPLEX,
|
||||
&acPlot);
|
||||
for (i=0; i< displacement ; i++)
|
||||
{
|
||||
DkerProc(D_F1PF2,job->r2H12stor[i],
|
||||
|
|
@ -588,13 +584,12 @@ time1 = SPfrontEnd->IFseconds();
|
|||
|
||||
error = CKTnames(ckt,&numNames,&nameList);
|
||||
if(error) return(error);
|
||||
SPfrontEnd->IFnewUid (ckt, &freqUid, NULL,
|
||||
"frequency", UID_OTHER, NULL);
|
||||
SPfrontEnd->OUTpBeginPlot (
|
||||
ckt, ckt->CKTcurJob,
|
||||
"DISTORTION - IM: f1-f2",
|
||||
freqUid, IF_REAL,
|
||||
numNames, nameList, IF_COMPLEX, &acPlot);
|
||||
SPfrontEnd->IFnewUid (ckt, &freqUid, NULL, "frequency", UID_OTHER, NULL);
|
||||
SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
|
||||
"DISTORTION - IM: f1-f2",
|
||||
freqUid, IF_REAL,
|
||||
numNames, nameList, IF_COMPLEX,
|
||||
&acPlot);
|
||||
for (i=0; i< displacement ; i++)
|
||||
{
|
||||
DkerProc(D_F1MF2,
|
||||
|
|
@ -611,13 +606,12 @@ time1 = SPfrontEnd->IFseconds();
|
|||
|
||||
error = CKTnames(ckt,&numNames,&nameList);
|
||||
if(error) return(error);
|
||||
SPfrontEnd->IFnewUid (ckt, &freqUid, NULL,
|
||||
"frequency", UID_OTHER, NULL);
|
||||
SPfrontEnd->OUTpBeginPlot (
|
||||
ckt, ckt->CKTcurJob,
|
||||
"DISTORTION - IM: 2f1-f2",
|
||||
freqUid, IF_REAL,
|
||||
numNames, nameList, IF_COMPLEX, &acPlot);
|
||||
SPfrontEnd->IFnewUid (ckt, &freqUid, NULL, "frequency", UID_OTHER, NULL);
|
||||
SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
|
||||
"DISTORTION - IM: 2f1-f2",
|
||||
freqUid, IF_REAL,
|
||||
numNames, nameList, IF_COMPLEX,
|
||||
&acPlot);
|
||||
for (i=0; i< displacement ; i++)
|
||||
{
|
||||
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.
|
||||
Author: 1987 Gary W. Ng
|
||||
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/acdefs.h"
|
||||
#include "ngspice/cktdefs.h"
|
||||
|
|
@ -47,8 +48,7 @@ NOISEan (CKTcircuit *ckt, int restart)
|
|||
inst = NULL;
|
||||
code = CKTtypelook("Vsource");
|
||||
if (code != -1) {
|
||||
error = CKTfndDev(ckt, &code, &inst,
|
||||
job->input, NULL, NULL);
|
||||
error = CKTfndDev(ckt, &code, &inst, job->input, NULL);
|
||||
if (!error && !((VSRCinstance *)inst)->VSRCacGiven) {
|
||||
errMsg = TMALLOC(char, strlen(noacinput) + 1);
|
||||
strcpy(errMsg,noacinput);
|
||||
|
|
@ -58,8 +58,7 @@ NOISEan (CKTcircuit *ckt, int restart)
|
|||
|
||||
code = CKTtypelook("Isource");
|
||||
if (code != -1 && inst==NULL) {
|
||||
error = CKTfndDev(ckt, &code, &inst,
|
||||
job->input, NULL, NULL);
|
||||
error = CKTfndDev(ckt, &code, &inst, job->input, NULL);
|
||||
if (error) {
|
||||
/* XXX ??? */
|
||||
SPfrontEnd->IFerror (ERR_WARNING,
|
||||
|
|
@ -119,8 +118,7 @@ NOISEan (CKTcircuit *ckt, int restart)
|
|||
/* the current front-end needs the namelist to be fully
|
||||
declared before an OUTpBeginplot */
|
||||
|
||||
SPfrontEnd->IFnewUid (ckt, &freqUid, NULL,
|
||||
"frequency", UID_OTHER, NULL);
|
||||
SPfrontEnd->IFnewUid (ckt, &freqUid, NULL, "frequency", UID_OTHER, NULL);
|
||||
|
||||
data->numPlots = 0; /* we don't have any plots yet */
|
||||
error = CKTnoise(ckt,N_DENS,N_OPEN,data);
|
||||
|
|
@ -131,16 +129,15 @@ NOISEan (CKTcircuit *ckt, int restart)
|
|||
* plot
|
||||
*/
|
||||
|
||||
error = SPfrontEnd->OUTpBeginPlot (
|
||||
ckt, ckt->CKTcurJob,
|
||||
"Noise Spectral Density Curves - (V^2 or A^2)/Hz",
|
||||
freqUid, IF_REAL,
|
||||
data->numPlots, data->namelist, IF_REAL, &(data->NplotPtr));
|
||||
error = SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
|
||||
"Noise Spectral Density Curves - (V^2 or A^2)/Hz",
|
||||
freqUid, IF_REAL,
|
||||
data->numPlots, data->namelist, IF_REAL,
|
||||
&(data->NplotPtr));
|
||||
if (error) return(error);
|
||||
|
||||
if (job->NstpType != LINEAR) {
|
||||
SPfrontEnd->OUTattributes (data->NplotPtr, NULL,
|
||||
OUT_SCALE_LOG, NULL);
|
||||
SPfrontEnd->OUTattributes (data->NplotPtr, NULL, OUT_SCALE_LOG, NULL);
|
||||
}
|
||||
|
||||
} 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->inNoise = job->NsavInoise;
|
||||
/* saj resume rawfile fix*/
|
||||
error = SPfrontEnd->OUTpBeginPlot (
|
||||
NULL, NULL,
|
||||
NULL,
|
||||
NULL, 0,
|
||||
666, NULL, 666, &(data->NplotPtr));
|
||||
error = SPfrontEnd->OUTpBeginPlot (NULL, NULL,
|
||||
NULL,
|
||||
NULL, 0,
|
||||
666, NULL, 666,
|
||||
&(data->NplotPtr));
|
||||
/*saj*/
|
||||
}
|
||||
|
||||
|
|
@ -278,11 +275,11 @@ NOISEan (CKTcircuit *ckt, int restart)
|
|||
|
||||
if (error) return(error);
|
||||
|
||||
SPfrontEnd->OUTpBeginPlot (
|
||||
ckt, ckt->CKTcurJob,
|
||||
"Integrated Noise - V^2 or A^2",
|
||||
NULL, 0,
|
||||
data->numPlots, data->namelist, IF_REAL, &(data->NplotPtr));
|
||||
SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
|
||||
"Integrated Noise - V^2 or A^2",
|
||||
NULL, 0,
|
||||
data->numPlots, data->namelist, IF_REAL,
|
||||
&(data->NplotPtr));
|
||||
|
||||
error = CKTnoise(ckt,INT_NOIZ,N_CALC,data);
|
||||
if (error) return(error);
|
||||
|
|
|
|||
|
|
@ -46,11 +46,11 @@ PZan(CKTcircuit *ckt, int reset)
|
|||
/* Dump operating point. */
|
||||
error = CKTnames(ckt,&numNames,&nameList);
|
||||
if(error) return(error);
|
||||
error = SPfrontEnd->OUTpBeginPlot (
|
||||
ckt, ckt->CKTcurJob,
|
||||
"Distortion Operating Point",
|
||||
NULL, IF_REAL,
|
||||
numNames, nameList, IF_REAL, &plot);
|
||||
error = SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
|
||||
"Distortion Operating Point",
|
||||
NULL, IF_REAL,
|
||||
numNames, nameList, IF_REAL,
|
||||
&plot);
|
||||
if(error) return(error);
|
||||
CKTdump(ckt, 0.0, plot);
|
||||
SPfrontEnd->OUTendPlot (plot);
|
||||
|
|
@ -94,7 +94,7 @@ PZinit(CKTcircuit *ckt)
|
|||
i = CKTtypelook("LTRA");
|
||||
}
|
||||
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->PZzeroList = NULL;
|
||||
|
|
@ -102,19 +102,19 @@ PZinit(CKTcircuit *ckt)
|
|||
job->PZnZeros = 0;
|
||||
|
||||
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)
|
||||
MERROR(E_SHORT, "Output is shorted")
|
||||
MERROR(E_SHORT, "Output is shorted");
|
||||
|
||||
if (job->PZin_pos == job->PZout_pos
|
||||
&& job->PZin_neg == job->PZout_neg
|
||||
&& 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
|
||||
&& job->PZin_neg == job->PZout_pos
|
||||
&& job->PZinput_type == PZ_IN_VOL)
|
||||
MERROR(E_INISOUT, "Transfer function is -1")
|
||||
MERROR(E_INISOUT, "Transfer function is -1");
|
||||
|
||||
return(OK);
|
||||
}
|
||||
|
|
@ -141,20 +141,18 @@ PZpost(CKTcircuit *ckt)
|
|||
j = 0;
|
||||
for (i = 0; i < job->PZnPoles; i++) {
|
||||
sprintf(name, "pole(%-u)", i+1);
|
||||
SPfrontEnd->IFnewUid (ckt, &(namelist[j++]), NULL,
|
||||
name, UID_OTHER, NULL);
|
||||
SPfrontEnd->IFnewUid (ckt, &(namelist[j++]), NULL, name, UID_OTHER, NULL);
|
||||
}
|
||||
for (i = 0; i < job->PZnZeros; i++) {
|
||||
sprintf(name, "zero(%-u)", i+1);
|
||||
SPfrontEnd->IFnewUid (ckt, &(namelist[j++]), NULL,
|
||||
name, UID_OTHER, NULL);
|
||||
SPfrontEnd->IFnewUid (ckt, &(namelist[j++]), NULL, name, UID_OTHER, NULL);
|
||||
}
|
||||
|
||||
SPfrontEnd->OUTpBeginPlot (
|
||||
ckt, ckt->CKTcurJob,
|
||||
ckt->CKTcurJob->JOBname,
|
||||
NULL, 0,
|
||||
job->PZnPoles + job->PZnZeros, namelist, IF_COMPLEX, &pzPlotPtr);
|
||||
SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
|
||||
ckt->CKTcurJob->JOBname,
|
||||
NULL, 0,
|
||||
job->PZnPoles + job->PZnZeros, namelist, IF_COMPLEX,
|
||||
&pzPlotPtr);
|
||||
|
||||
j = 0;
|
||||
if (job->PZnPoles > 0) {
|
||||
|
|
|
|||
|
|
@ -51,8 +51,7 @@ TFanal(CKTcircuit *ckt, int restart)
|
|||
Itype = CKTtypelook("Isource");
|
||||
Vtype = CKTtypelook("Vsource");
|
||||
if(Itype != -1) {
|
||||
error = CKTfndDev(ckt,&Itype,&ptr,
|
||||
job->TFinSrc, NULL, NULL);
|
||||
error = CKTfndDev(ckt, &Itype, &ptr, job->TFinSrc, NULL);
|
||||
if(error ==0) {
|
||||
job->TFinIsI = 1;
|
||||
job->TFinIsV = 0;
|
||||
|
|
@ -62,9 +61,7 @@ TFanal(CKTcircuit *ckt, int restart)
|
|||
}
|
||||
|
||||
if( (Vtype != -1) && (ptr==NULL) ) {
|
||||
error = CKTfndDev(ckt,&Vtype,&ptr,
|
||||
job->TFinSrc, NULL,
|
||||
NULL);
|
||||
error = CKTfndDev(ckt, &Vtype, &ptr, job->TFinSrc, NULL);
|
||||
job->TFinIsV = 1;
|
||||
job->TFinIsI = 0;
|
||||
if(error !=0) {
|
||||
|
|
@ -94,30 +91,26 @@ TFanal(CKTcircuit *ckt, int restart)
|
|||
ckt->CKTrhs[0]=0;
|
||||
|
||||
/* make a UID for the transfer function output */
|
||||
SPfrontEnd->IFnewUid (ckt, &tfuid, NULL, "Transfer_function",
|
||||
UID_OTHER, NULL);
|
||||
SPfrontEnd->IFnewUid (ckt, &tfuid, NULL, "Transfer_function", UID_OTHER, NULL);
|
||||
|
||||
/* make a UID for the input impedance */
|
||||
SPfrontEnd->IFnewUid (ckt, &inuid, job->TFinSrc,
|
||||
"Input_impedance", UID_OTHER, NULL);
|
||||
SPfrontEnd->IFnewUid (ckt, &inuid, job->TFinSrc, "Input_impedance", UID_OTHER, NULL);
|
||||
|
||||
/* make a UID for the output impedance */
|
||||
if (job->TFoutIsI) {
|
||||
SPfrontEnd->IFnewUid (ckt, &outuid, job->TFoutSrc
|
||||
,"Output_impedance", UID_OTHER, NULL);
|
||||
SPfrontEnd->IFnewUid (ckt, &outuid, job->TFoutSrc ,"Output_impedance", UID_OTHER, NULL);
|
||||
} else {
|
||||
name = TMALLOC(char, strlen(job->TFoutName) + 22);
|
||||
(void)sprintf(name,"output_impedance_at_%s",
|
||||
job->TFoutName);
|
||||
SPfrontEnd->IFnewUid (ckt, &outuid, NULL,
|
||||
name, UID_OTHER, NULL);
|
||||
SPfrontEnd->IFnewUid (ckt, &outuid, NULL, name, UID_OTHER, NULL);
|
||||
}
|
||||
|
||||
error = SPfrontEnd->OUTpBeginPlot (
|
||||
ckt, ckt->CKTcurJob,
|
||||
job->JOBname,
|
||||
NULL, 0,
|
||||
3, uids, IF_REAL, &plotptr);
|
||||
error = SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
|
||||
job->JOBname,
|
||||
NULL, 0,
|
||||
3, uids, IF_REAL,
|
||||
&plotptr);
|
||||
if(error) return(error);
|
||||
|
||||
/*find transfer function */
|
||||
|
|
|
|||
|
|
@ -21,25 +21,16 @@ int TRANinit(CKTcircuit *ckt, JOB *anal)
|
|||
ckt->CKTstep = job->TRANstep;
|
||||
ckt->CKTinitTime = job->TRANinitTime;
|
||||
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->CKTmode = job->TRANmode;
|
||||
|
||||
|
|
|
|||
|
|
@ -19,10 +19,14 @@ libasrc_la_SOURCES = \
|
|||
asrcmdel.c \
|
||||
asrcpar.c \
|
||||
asrcpzld.c \
|
||||
asrcset.c \
|
||||
asrcset.c \
|
||||
asrctemp.c
|
||||
|
||||
|
||||
if KIRCHHOFF_WANTED
|
||||
libasrc_la_SOURCES += asrcnode.c
|
||||
endif
|
||||
|
||||
AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(top_srcdir)/src/include
|
||||
AM_CFLAGS = $(STATIC)
|
||||
MAINTAINERCLEANFILES = Makefile.in
|
||||
|
|
|
|||
|
|
@ -16,3 +16,7 @@ extern int ASRCacLoad(GENmodel*,CKTcircuit*);
|
|||
extern int ASRCsetup(SMPmatrix*,GENmodel*,CKTcircuit*,int*);
|
||||
extern int ASRCunsetup(GENmodel*,CKTcircuit*);
|
||||
extern int ASRCtemp(GENmodel*,CKTcircuit*);
|
||||
|
||||
#ifdef KIRCHHOFF
|
||||
extern int ASRCnodeIsNonLinear (GENmodel *, CKTcircuit *) ;
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -74,12 +74,17 @@ SPICEdev ASRCinfo = {
|
|||
#endif
|
||||
/* DEVinstSize */ &ASRCiSize,
|
||||
/* DEVmodSize */ &ASRCmSize,
|
||||
|
||||
#if defined(KLU) || defined(SuperLU) || defined(UMFPACK)
|
||||
/* DEVbindCSC */ NULL,
|
||||
/* DEVbindCSCComplex */ NULL,
|
||||
/* DEVbindCSCComplexToReal */ NULL,
|
||||
#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 */
|
||||
#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);\
|
||||
}
|
||||
} } while(0)
|
||||
|
||||
#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);\
|
||||
}
|
||||
} } while(0)
|
||||
|
||||
/* For each controlling variable set the entries
|
||||
in the vector of the positions of the SMP */
|
||||
|
|
|
|||
|
|
@ -47,6 +47,10 @@ if UMFPACK_WANTED
|
|||
libbjt_la_SOURCES += bjtbindCSC.c
|
||||
endif
|
||||
|
||||
if KIRCHHOFF_WANTED
|
||||
libbjt_la_SOURCES += bjtnode.c
|
||||
endif
|
||||
|
||||
AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(top_srcdir)/src/include
|
||||
AM_CFLAGS = $(STATIC)
|
||||
|
||||
|
|
|
|||
|
|
@ -32,6 +32,9 @@ extern int BJTdisto(int,GENmodel*,CKTcircuit*);
|
|||
extern int BJTnoise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*);
|
||||
extern int BJTdSetup(GENmodel*, register CKTcircuit*);
|
||||
|
||||
#ifdef KIRCHHOFF
|
||||
extern int BJTnodeIsNonLinear (GENmodel *, CKTcircuit *) ;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(KLU) || defined(SuperLU) || defined(UMFPACK)
|
||||
|
|
|
|||
|
|
@ -73,12 +73,17 @@ SPICEdev BJTinfo = { /* description from struct IFdevice */
|
|||
#endif
|
||||
/* DEVinstSize */ &BJTiSize,
|
||||
/* DEVmodSize */ &BJTmSize,
|
||||
|
||||
#if defined(KLU) || defined(SuperLU) || defined(UMFPACK)
|
||||
/* DEVbindCSC */ BJTbindCSC,
|
||||
/* DEVbindCSCComplex */ BJTbindCSCComplex,
|
||||
/* DEVbindCSCComplexToReal */ BJTbindCSCComplexToReal,
|
||||
#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);
|
||||
|
||||
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",
|
||||
ccprm,iccprm,ceprm,iceprm);
|
||||
printf("cb = %.7e + j%.7e , cbprm = %.7e + j%.7e , ",
|
||||
cb,icb,cbprm,icbprm)
|
||||
cb,icb,cbprm,icbprm);
|
||||
printf("cs = %.7e + j%.7e\n",
|
||||
cs,ics);
|
||||
#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 */
|
||||
#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);\
|
||||
}
|
||||
TSTALLOC(BJTcolColPrimePtr,BJTcolNode,BJTcolPrimeNode)
|
||||
TSTALLOC(BJTbaseBasePrimePtr,BJTbaseNode,BJTbasePrimeNode)
|
||||
TSTALLOC(BJTemitEmitPrimePtr,BJTemitNode,BJTemitPrimeNode)
|
||||
TSTALLOC(BJTcolPrimeColPtr,BJTcolPrimeNode,BJTcolNode)
|
||||
TSTALLOC(BJTcolPrimeBasePrimePtr,BJTcolPrimeNode,BJTbasePrimeNode)
|
||||
TSTALLOC(BJTcolPrimeEmitPrimePtr,BJTcolPrimeNode,BJTemitPrimeNode)
|
||||
TSTALLOC(BJTbasePrimeBasePtr,BJTbasePrimeNode,BJTbaseNode)
|
||||
TSTALLOC(BJTbasePrimeColPrimePtr,BJTbasePrimeNode,BJTcolPrimeNode)
|
||||
TSTALLOC(BJTbasePrimeEmitPrimePtr,BJTbasePrimeNode,BJTemitPrimeNode)
|
||||
TSTALLOC(BJTemitPrimeEmitPtr,BJTemitPrimeNode,BJTemitNode)
|
||||
TSTALLOC(BJTemitPrimeColPrimePtr,BJTemitPrimeNode,BJTcolPrimeNode)
|
||||
TSTALLOC(BJTemitPrimeBasePrimePtr,BJTemitPrimeNode,BJTbasePrimeNode)
|
||||
TSTALLOC(BJTcolColPtr,BJTcolNode,BJTcolNode)
|
||||
TSTALLOC(BJTbaseBasePtr,BJTbaseNode,BJTbaseNode)
|
||||
TSTALLOC(BJTemitEmitPtr,BJTemitNode,BJTemitNode)
|
||||
TSTALLOC(BJTcolPrimeColPrimePtr,BJTcolPrimeNode,BJTcolPrimeNode)
|
||||
TSTALLOC(BJTbasePrimeBasePrimePtr,BJTbasePrimeNode,BJTbasePrimeNode)
|
||||
TSTALLOC(BJTemitPrimeEmitPrimePtr,BJTemitPrimeNode,BJTemitPrimeNode)
|
||||
TSTALLOC(BJTsubstSubstPtr,BJTsubstNode,BJTsubstNode)
|
||||
} } while(0)
|
||||
TSTALLOC(BJTcolColPrimePtr,BJTcolNode,BJTcolPrimeNode);
|
||||
TSTALLOC(BJTbaseBasePrimePtr,BJTbaseNode,BJTbasePrimeNode);
|
||||
TSTALLOC(BJTemitEmitPrimePtr,BJTemitNode,BJTemitPrimeNode);
|
||||
TSTALLOC(BJTcolPrimeColPtr,BJTcolPrimeNode,BJTcolNode);
|
||||
TSTALLOC(BJTcolPrimeBasePrimePtr,BJTcolPrimeNode,BJTbasePrimeNode);
|
||||
TSTALLOC(BJTcolPrimeEmitPrimePtr,BJTcolPrimeNode,BJTemitPrimeNode);
|
||||
TSTALLOC(BJTbasePrimeBasePtr,BJTbasePrimeNode,BJTbaseNode);
|
||||
TSTALLOC(BJTbasePrimeColPrimePtr,BJTbasePrimeNode,BJTcolPrimeNode);
|
||||
TSTALLOC(BJTbasePrimeEmitPrimePtr,BJTbasePrimeNode,BJTemitPrimeNode);
|
||||
TSTALLOC(BJTemitPrimeEmitPtr,BJTemitPrimeNode,BJTemitNode);
|
||||
TSTALLOC(BJTemitPrimeColPrimePtr,BJTemitPrimeNode,BJTcolPrimeNode);
|
||||
TSTALLOC(BJTemitPrimeBasePrimePtr,BJTemitPrimeNode,BJTbasePrimeNode);
|
||||
TSTALLOC(BJTcolColPtr,BJTcolNode,BJTcolNode);
|
||||
TSTALLOC(BJTbaseBasePtr,BJTbaseNode,BJTbaseNode);
|
||||
TSTALLOC(BJTemitEmitPtr,BJTemitNode,BJTemitNode);
|
||||
TSTALLOC(BJTcolPrimeColPrimePtr,BJTcolPrimeNode,BJTcolPrimeNode);
|
||||
TSTALLOC(BJTbasePrimeBasePrimePtr,BJTbasePrimeNode,BJTbasePrimeNode);
|
||||
TSTALLOC(BJTemitPrimeEmitPrimePtr,BJTemitPrimeNode,BJTemitPrimeNode);
|
||||
TSTALLOC(BJTsubstSubstPtr,BJTsubstNode,BJTsubstNode);
|
||||
if (model -> BJTsubs == LATERAL) {
|
||||
here -> BJTsubstConNode = here -> BJTbasePrimeNode;
|
||||
here -> BJTsubstConSubstConPtr = here -> BJTbasePrimeBasePrimePtr;
|
||||
|
|
@ -449,10 +449,10 @@ if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\
|
|||
here -> BJTsubstConNode = here -> BJTcolPrimeNode;
|
||||
here -> BJTsubstConSubstConPtr = here -> BJTcolPrimeColPrimePtr;
|
||||
}
|
||||
TSTALLOC(BJTsubstConSubstPtr,BJTsubstConNode,BJTsubstNode)
|
||||
TSTALLOC(BJTsubstSubstConPtr,BJTsubstNode,BJTsubstConNode)
|
||||
TSTALLOC(BJTbaseColPrimePtr,BJTbaseNode,BJTcolPrimeNode)
|
||||
TSTALLOC(BJTcolPrimeBasePtr,BJTcolPrimeNode,BJTbaseNode)
|
||||
TSTALLOC(BJTsubstConSubstPtr,BJTsubstConNode,BJTsubstNode);
|
||||
TSTALLOC(BJTsubstSubstConPtr,BJTsubstNode,BJTsubstConNode);
|
||||
TSTALLOC(BJTbaseColPrimePtr,BJTbaseNode,BJTcolPrimeNode);
|
||||
TSTALLOC(BJTcolPrimeBasePtr,BJTcolPrimeNode,BJTbaseNode);
|
||||
}
|
||||
}
|
||||
return(OK);
|
||||
|
|
|
|||
|
|
@ -55,9 +55,8 @@ BJTsUpdate(GENmodel *inModel, CKTcircuit *ckt)
|
|||
sxpbx = 0;
|
||||
#ifdef SENSDEBUG
|
||||
printf("senupdate Instance name: %s\n",here->BJTname);
|
||||
printf("iparmno = %d,CKTag[0] = %.2e,CKTag[1] = %.2e\n",
|
||||
iparmno,ckt->CKTag[0],ckt->CKTag[1]);
|
||||
|
||||
printf("CKTag[0] = %.2e,CKTag[1] = %.2e\n",
|
||||
ckt->CKTag[0],ckt->CKTag[1]);
|
||||
printf("capbe = %.7e\n",here->BJTcapbe);
|
||||
printf("capbc = %.7e\n",here->BJTcapbc);
|
||||
printf("capsub = %.7e\n",here->BJTcapsub);
|
||||
|
|
|
|||
|
|
@ -43,6 +43,10 @@ if UMFPACK_WANTED
|
|||
libbsim1_la_SOURCES += b1bindCSC.c
|
||||
endif
|
||||
|
||||
if KIRCHHOFF_WANTED
|
||||
libbsim1_la_SOURCES += b1node.c
|
||||
endif
|
||||
|
||||
AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(top_srcdir)/src/include
|
||||
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 */
|
||||
#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);\
|
||||
}
|
||||
} } while(0)
|
||||
|
||||
TSTALLOC(B1DdPtr, B1dNode, B1dNode)
|
||||
TSTALLOC(B1GgPtr, B1gNode, B1gNode)
|
||||
TSTALLOC(B1SsPtr, B1sNode, B1sNode)
|
||||
TSTALLOC(B1BbPtr, B1bNode, B1bNode)
|
||||
TSTALLOC(B1DPdpPtr, B1dNodePrime, B1dNodePrime)
|
||||
TSTALLOC(B1SPspPtr, B1sNodePrime, B1sNodePrime)
|
||||
TSTALLOC(B1DdpPtr, B1dNode, B1dNodePrime)
|
||||
TSTALLOC(B1GbPtr, B1gNode, B1bNode)
|
||||
TSTALLOC(B1GdpPtr, B1gNode, B1dNodePrime)
|
||||
TSTALLOC(B1GspPtr, B1gNode, B1sNodePrime)
|
||||
TSTALLOC(B1SspPtr, B1sNode, B1sNodePrime)
|
||||
TSTALLOC(B1BdpPtr, B1bNode, B1dNodePrime)
|
||||
TSTALLOC(B1BspPtr, B1bNode, B1sNodePrime)
|
||||
TSTALLOC(B1DPspPtr, B1dNodePrime, B1sNodePrime)
|
||||
TSTALLOC(B1DPdPtr, B1dNodePrime, B1dNode)
|
||||
TSTALLOC(B1BgPtr, B1bNode, B1gNode)
|
||||
TSTALLOC(B1DPgPtr, B1dNodePrime, B1gNode)
|
||||
TSTALLOC(B1SPgPtr, B1sNodePrime, B1gNode)
|
||||
TSTALLOC(B1SPsPtr, B1sNodePrime, B1sNode)
|
||||
TSTALLOC(B1DPbPtr, B1dNodePrime, B1bNode)
|
||||
TSTALLOC(B1SPbPtr, B1sNodePrime, B1bNode)
|
||||
TSTALLOC(B1SPdpPtr, B1sNodePrime, B1dNodePrime)
|
||||
TSTALLOC(B1DdPtr, B1dNode, B1dNode);
|
||||
TSTALLOC(B1GgPtr, B1gNode, B1gNode);
|
||||
TSTALLOC(B1SsPtr, B1sNode, B1sNode);
|
||||
TSTALLOC(B1BbPtr, B1bNode, B1bNode);
|
||||
TSTALLOC(B1DPdpPtr, B1dNodePrime, B1dNodePrime);
|
||||
TSTALLOC(B1SPspPtr, B1sNodePrime, B1sNodePrime);
|
||||
TSTALLOC(B1DdpPtr, B1dNode, B1dNodePrime);
|
||||
TSTALLOC(B1GbPtr, B1gNode, B1bNode);
|
||||
TSTALLOC(B1GdpPtr, B1gNode, B1dNodePrime);
|
||||
TSTALLOC(B1GspPtr, B1gNode, B1sNodePrime);
|
||||
TSTALLOC(B1SspPtr, B1sNode, B1sNodePrime);
|
||||
TSTALLOC(B1BdpPtr, B1bNode, B1dNodePrime);
|
||||
TSTALLOC(B1BspPtr, B1bNode, B1sNodePrime);
|
||||
TSTALLOC(B1DPspPtr, B1dNodePrime, B1sNodePrime);
|
||||
TSTALLOC(B1DPdPtr, B1dNodePrime, B1dNode);
|
||||
TSTALLOC(B1BgPtr, B1bNode, B1gNode);
|
||||
TSTALLOC(B1DPgPtr, B1dNodePrime, B1gNode);
|
||||
TSTALLOC(B1SPgPtr, B1sNodePrime, B1gNode);
|
||||
TSTALLOC(B1SPsPtr, B1sNodePrime, B1sNode);
|
||||
TSTALLOC(B1DPbPtr, B1dNodePrime, B1bNode);
|
||||
TSTALLOC(B1SPbPtr, B1sNodePrime, B1bNode);
|
||||
TSTALLOC(B1SPdpPtr, B1sNodePrime, B1dNodePrime);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,3 +35,7 @@ extern int B1bindCSC (GENmodel*, CKTcircuit*) ;
|
|||
extern int B1bindCSCComplex (GENmodel*, CKTcircuit*) ;
|
||||
extern int B1bindCSCComplexToReal (GENmodel*, CKTcircuit*) ;
|
||||
#endif
|
||||
|
||||
#ifdef KIRCHHOFF
|
||||
extern int B1nodeIsNonLinear (GENmodel *, CKTcircuit *) ;
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -73,12 +73,17 @@ SPICEdev B1info = {
|
|||
#endif
|
||||
/* DEVinstSize */ &B1iSize,
|
||||
/* DEVmodSize */ &B1mSize,
|
||||
|
||||
#if defined(KLU) || defined(SuperLU) || defined(UMFPACK)
|
||||
/* DEVbindCSC */ B1bindCSC,
|
||||
/* DEVbindCSCComplex */ B1bindCSCComplex,
|
||||
/* DEVbindCSCComplexToReal */ B1bindCSCComplexToReal,
|
||||
#endif
|
||||
|
||||
#ifdef KIRCHHOFF
|
||||
/* DEVnodeIsNonLinear */ B1nodeIsNonLinear
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -41,6 +41,10 @@ if UMFPACK_WANTED
|
|||
libbsim2_la_SOURCES += b2bindCSC.c
|
||||
endif
|
||||
|
||||
if KIRCHHOFF_WANTED
|
||||
libbsim2_la_SOURCES += b2node.c
|
||||
endif
|
||||
|
||||
AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(top_srcdir)/src/include
|
||||
AM_CFLAGS = $(STATIC)
|
||||
|
||||
|
|
|
|||
|
|
@ -40,13 +40,13 @@ B2load(GENmodel *inModel, CKTcircuit *ckt)
|
|||
double cd;
|
||||
double cdrain;
|
||||
double cdhat;
|
||||
double cdreq;
|
||||
double cdreq, cdreq_fvk ;
|
||||
double ceq;
|
||||
double ceqbd;
|
||||
double ceqbs;
|
||||
double ceqqb;
|
||||
double ceqqd;
|
||||
double ceqqg;
|
||||
double ceqbd, ceqbd_fvk ;
|
||||
double ceqbs, ceqbs_fvk ;
|
||||
double ceqqb, ceqqb_fvk ;
|
||||
double ceqqd, ceqqd_fvk ;
|
||||
double ceqqg, ceqqg_fvk ;
|
||||
double czbd;
|
||||
double czbdsw;
|
||||
double czbs;
|
||||
|
|
@ -628,7 +628,7 @@ line755:
|
|||
|
||||
line850:
|
||||
/* 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;
|
||||
gcsgb = gcsdb = gcssb = 0.0;
|
||||
gcggb = gcgdb = gcgsb = 0.0;
|
||||
|
|
@ -641,8 +641,11 @@ line860:
|
|||
cqbulk = *(ckt->CKTstate0 + here->B2iqb);
|
||||
cqdrn = *(ckt->CKTstate0 + here->B2iqd);
|
||||
ceqqg = cqgate - gcggb * vgb + gcgdb * vbd + gcgsb * vbs;
|
||||
ceqqg_fvk = cqgate ;
|
||||
ceqqb = cqbulk - gcbgb * vgb + gcbdb * vbd + gcbsb * vbs;
|
||||
ceqqb_fvk = cqbulk ;
|
||||
ceqqd = cqdrn - gcdgb * vgb + gcddb * vbd + gcdsb * vbs;
|
||||
ceqqd_fvk = cqdrn ;
|
||||
|
||||
if(ckt->CKTmode & MODEINITTRAN ) {
|
||||
*(ckt->CKTstate1 + here->B2iqb) =
|
||||
|
|
@ -661,19 +664,25 @@ line900:
|
|||
m = here->B2m;
|
||||
|
||||
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_fvk = model->B2type * (cbd + ckt->CKTgmin * vbd) ;
|
||||
ceqqg = model->B2type * ceqqg;
|
||||
ceqqg_fvk = model->B2type * ceqqg_fvk ;
|
||||
ceqqb = model->B2type * ceqqb;
|
||||
ceqqb_fvk = model->B2type * ceqqb_fvk ;
|
||||
ceqqd = model->B2type * ceqqd;
|
||||
ceqqd_fvk = model->B2type * ceqqd_fvk ;
|
||||
if (here->B2mode >= 0) {
|
||||
xnrm=1;
|
||||
xrev=0;
|
||||
cdreq=model->B2type*(cdrain-gds*vds-gm*vgs-gmbs*vbs);
|
||||
cdreq_fvk = model->B2type * cdrain ;
|
||||
} else {
|
||||
xnrm=0;
|
||||
xrev=1;
|
||||
cdreq = -(model->B2type)*(cdrain+gds*vds-gm*vgd-gmbs*vbd);
|
||||
cdreq_fvk = - (model->B2type * cdrain) ;
|
||||
}
|
||||
|
||||
*(ckt->CKTrhs + here->B2gNode) -= m * (ceqqg);
|
||||
|
|
@ -712,6 +721,24 @@ line900:
|
|||
*(here->B2SPbPtr) += m * (-gbs-(xnrm-xrev)*gmbs-gcsgb-gcsdb-gcssb);
|
||||
*(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: ;
|
||||
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
#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);\
|
||||
}
|
||||
} } while(0)
|
||||
|
||||
TSTALLOC(B2DdPtr, B2dNode, B2dNode)
|
||||
TSTALLOC(B2GgPtr, B2gNode, B2gNode)
|
||||
TSTALLOC(B2SsPtr, B2sNode, B2sNode)
|
||||
TSTALLOC(B2BbPtr, B2bNode, B2bNode)
|
||||
TSTALLOC(B2DPdpPtr, B2dNodePrime, B2dNodePrime)
|
||||
TSTALLOC(B2SPspPtr, B2sNodePrime, B2sNodePrime)
|
||||
TSTALLOC(B2DdpPtr, B2dNode, B2dNodePrime)
|
||||
TSTALLOC(B2GbPtr, B2gNode, B2bNode)
|
||||
TSTALLOC(B2GdpPtr, B2gNode, B2dNodePrime)
|
||||
TSTALLOC(B2GspPtr, B2gNode, B2sNodePrime)
|
||||
TSTALLOC(B2SspPtr, B2sNode, B2sNodePrime)
|
||||
TSTALLOC(B2BdpPtr, B2bNode, B2dNodePrime)
|
||||
TSTALLOC(B2BspPtr, B2bNode, B2sNodePrime)
|
||||
TSTALLOC(B2DPspPtr, B2dNodePrime, B2sNodePrime)
|
||||
TSTALLOC(B2DPdPtr, B2dNodePrime, B2dNode)
|
||||
TSTALLOC(B2BgPtr, B2bNode, B2gNode)
|
||||
TSTALLOC(B2DPgPtr, B2dNodePrime, B2gNode)
|
||||
TSTALLOC(B2SPgPtr, B2sNodePrime, B2gNode)
|
||||
TSTALLOC(B2SPsPtr, B2sNodePrime, B2sNode)
|
||||
TSTALLOC(B2DPbPtr, B2dNodePrime, B2bNode)
|
||||
TSTALLOC(B2SPbPtr, B2sNodePrime, B2bNode)
|
||||
TSTALLOC(B2SPdpPtr, B2sNodePrime, B2dNodePrime)
|
||||
TSTALLOC(B2DdPtr, B2dNode, B2dNode);
|
||||
TSTALLOC(B2GgPtr, B2gNode, B2gNode);
|
||||
TSTALLOC(B2SsPtr, B2sNode, B2sNode);
|
||||
TSTALLOC(B2BbPtr, B2bNode, B2bNode);
|
||||
TSTALLOC(B2DPdpPtr, B2dNodePrime, B2dNodePrime);
|
||||
TSTALLOC(B2SPspPtr, B2sNodePrime, B2sNodePrime);
|
||||
TSTALLOC(B2DdpPtr, B2dNode, B2dNodePrime);
|
||||
TSTALLOC(B2GbPtr, B2gNode, B2bNode);
|
||||
TSTALLOC(B2GdpPtr, B2gNode, B2dNodePrime);
|
||||
TSTALLOC(B2GspPtr, B2gNode, B2sNodePrime);
|
||||
TSTALLOC(B2SspPtr, B2sNode, B2sNodePrime);
|
||||
TSTALLOC(B2BdpPtr, B2bNode, B2dNodePrime);
|
||||
TSTALLOC(B2BspPtr, B2bNode, B2sNodePrime);
|
||||
TSTALLOC(B2DPspPtr, B2dNodePrime, B2sNodePrime);
|
||||
TSTALLOC(B2DPdPtr, B2dNodePrime, B2dNode);
|
||||
TSTALLOC(B2BgPtr, B2bNode, B2gNode);
|
||||
TSTALLOC(B2DPgPtr, B2dNodePrime, B2gNode);
|
||||
TSTALLOC(B2SPgPtr, B2sNodePrime, B2gNode);
|
||||
TSTALLOC(B2SPsPtr, B2sNodePrime, B2sNode);
|
||||
TSTALLOC(B2DPbPtr, B2dNodePrime, B2bNode);
|
||||
TSTALLOC(B2SPbPtr, B2sNodePrime, B2bNode);
|
||||
TSTALLOC(B2SPdpPtr, B2sNodePrime, B2dNodePrime);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,3 +31,7 @@ extern int B2bindCSC (GENmodel*, CKTcircuit*) ;
|
|||
extern int B2bindCSCComplex (GENmodel*, CKTcircuit*) ;
|
||||
extern int B2bindCSCComplexToReal (GENmodel*, CKTcircuit*) ;
|
||||
#endif
|
||||
|
||||
#ifdef KIRCHHOFF
|
||||
extern int B2nodeIsNonLinear (GENmodel *, CKTcircuit *) ;
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -73,12 +73,17 @@ SPICEdev B2info = {
|
|||
#endif
|
||||
/* DEVinstSize */ &B2iSize,
|
||||
/* DEVmodSize */ &B2mSize,
|
||||
|
||||
#if defined(KLU) || defined(SuperLU) || defined(UMFPACK)
|
||||
/* DEVbindCSC */ B2bindCSC,
|
||||
/* DEVbindCSCComplex */ B2bindCSCComplex,
|
||||
/* DEVbindCSCComplexToReal */ B2bindCSCComplexToReal,
|
||||
#endif
|
||||
|
||||
#ifdef KIRCHHOFF
|
||||
/* DEVnodeIsNonLinear */ B2nodeIsNonLinear
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -40,6 +40,10 @@ if UMFPACK_WANTED
|
|||
libbsim3_la_SOURCES += b3bindCSC.c
|
||||
endif
|
||||
|
||||
if KIRCHHOFF_WANTED
|
||||
libbsim3_la_SOURCES += b3node.c
|
||||
endif
|
||||
|
||||
AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(top_srcdir)/src/include
|
||||
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( "nqsmod", BSIM3_NQSMOD, IF_INTEGER, "Non-quasi-static 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"),
|
||||
OP( "gmbs", BSIM3_GMBS, IF_REAL, "Gmb"),
|
||||
OP( "gm", BSIM3_GM, IF_REAL, "Gm"),
|
||||
OP( "gds", BSIM3_GDS, IF_REAL, "Gds"),
|
||||
OP( "vdsat", BSIM3_VDSAT, IF_REAL, "Vdsat"),
|
||||
OP( "vth", BSIM3_VON, IF_REAL, "Vth"),
|
||||
OP( "id", BSIM3_CD, IF_REAL, "Ids"),
|
||||
OP( "vbs", BSIM3_VBS, IF_REAL, "Vbs"),
|
||||
OP( "vgs", BSIM3_VGS, IF_REAL, "Vgs"),
|
||||
OP( "vds", BSIM3_VDS, IF_REAL, "Vds"),
|
||||
OP( "ibd", BSIM3_CBD, IF_REAL, "Ibd"), /* newly added from here */
|
||||
OP( "ibs", BSIM3_CBS, IF_REAL, "Ibs"),
|
||||
OP( "gbd", BSIM3_GBD, IF_REAL, "gbd"),
|
||||
OP( "gbs", BSIM3_GBS, IF_REAL, "gbs"),
|
||||
OP( "qb", BSIM3_QB, IF_REAL, "Qbulk"),
|
||||
OP( "cqb", BSIM3_CQB, IF_REAL, "CQbulk"),
|
||||
OP( "qg", BSIM3_QG, IF_REAL, "Qgate"),
|
||||
OP( "cqg", BSIM3_CQG, IF_REAL, "CQgate"),
|
||||
OP( "qd", BSIM3_QD, IF_REAL, "Qdrain"),
|
||||
OP( "cqd", BSIM3_CQD, IF_REAL, "CQdrain"),
|
||||
OP( "cgg", BSIM3_CGG, IF_REAL, "Cggb"),
|
||||
OP( "cgd", BSIM3_CGD, IF_REAL, "Cgdb"),
|
||||
OP( "cgs", BSIM3_CGS, IF_REAL, "Cgsb"),
|
||||
OP( "cdg", BSIM3_CDG, IF_REAL, "Cdgb"),
|
||||
OP( "cdd", BSIM3_CDD, IF_REAL, "Cddb"),
|
||||
OP( "cds", BSIM3_CDS, IF_REAL, "Cdsb"),
|
||||
OP( "cbg", BSIM3_CBG, IF_REAL, "Cbgb"),
|
||||
OP( "cbd", BSIM3_CBDB, IF_REAL, "Cbdb"),
|
||||
OP( "cbs", BSIM3_CBSB, IF_REAL, "Cbsb"),
|
||||
OP( "capbd", BSIM3_CAPBD, IF_REAL, "Capbd"),
|
||||
OP( "capbs", BSIM3_CAPBS, IF_REAL, "Capbs"),
|
||||
OP( "gmbs", BSIM3_GMBS, IF_REAL, "Gmb"),
|
||||
OP( "gm", BSIM3_GM, IF_REAL, "Gm"),
|
||||
OP( "gds", BSIM3_GDS, IF_REAL, "Gds"),
|
||||
OP( "vdsat", BSIM3_VDSAT, IF_REAL, "Vdsat"),
|
||||
OP( "vth", BSIM3_VON, IF_REAL, "Vth"),
|
||||
OP( "id", BSIM3_CD, IF_REAL, "Ids"),
|
||||
OP( "vbs", BSIM3_VBS, IF_REAL, "Vbs"),
|
||||
OP( "vgs", BSIM3_VGS, IF_REAL, "Vgs"),
|
||||
OP( "vds", BSIM3_VDS, IF_REAL, "Vds"),
|
||||
OP( "ibd", BSIM3_CBD, IF_REAL, "Ibd"), /* newly added from here */
|
||||
OP( "ibs", BSIM3_CBS, IF_REAL, "Ibs"),
|
||||
OP( "gbd", BSIM3_GBD, IF_REAL, "gbd"),
|
||||
OP( "gbs", BSIM3_GBS, IF_REAL, "gbs"),
|
||||
OP( "qb", BSIM3_QB, IF_REAL, "Qbulk"),
|
||||
OP( "cqb", BSIM3_CQB, IF_REAL, "CQbulk"),
|
||||
OP( "qg", BSIM3_QG, IF_REAL, "Qgate"),
|
||||
OP( "cqg", BSIM3_CQG, IF_REAL, "CQgate"),
|
||||
OP( "qd", BSIM3_QD, IF_REAL, "Qdrain"),
|
||||
OP( "cqd", BSIM3_CQD, IF_REAL, "CQdrain"),
|
||||
OP( "cgg", BSIM3_CGG, IF_REAL, "Cggb"),
|
||||
OP( "cgd", BSIM3_CGD, IF_REAL, "Cgdb"),
|
||||
OP( "cgs", BSIM3_CGS, IF_REAL, "Cgsb"),
|
||||
OP( "cdg", BSIM3_CDG, IF_REAL, "Cdgb"),
|
||||
OP( "cdd", BSIM3_CDD, IF_REAL, "Cddb"),
|
||||
OP( "cds", BSIM3_CDS, IF_REAL, "Cdsb"),
|
||||
OP( "cbg", BSIM3_CBG, IF_REAL, "Cbgb"),
|
||||
OP( "cbd", BSIM3_CBDB, IF_REAL, "Cbdb"),
|
||||
OP( "cbs", BSIM3_CBSB, IF_REAL, "Cbsb"),
|
||||
OP( "capbd", BSIM3_CAPBD, IF_REAL, "Capbd"),
|
||||
OP( "capbs", BSIM3_CAPBS, IF_REAL, "Capbs"),
|
||||
};
|
||||
|
||||
IFparm BSIM3mPTable[] = { /* model parameters */
|
||||
IOP( "capmod", BSIM3_MOD_CAPMOD, IF_INTEGER, "Capacitance model selector"),
|
||||
IOP( "mobmod", BSIM3_MOD_MOBMOD, IF_INTEGER, "Mobility 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( "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( "binunit", BSIM3_MOD_BINUNIT, IF_INTEGER, "Bin unit selector"),
|
||||
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( "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( "cdscd", BSIM3_MOD_CDSCD, IF_REAL, "Drain-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( "cit", BSIM3_MOD_CIT, IF_REAL, "Interface state capacitance"),
|
||||
IOP( "nfactor", BSIM3_MOD_NFACTOR, IF_REAL, "Subthreshold swing Coefficient"),
|
||||
IOP( "xj", BSIM3_MOD_XJ, IF_REAL, "Junction depth in meters"),
|
||||
IOP( "vsat", BSIM3_MOD_VSAT, IF_REAL, "Saturation velocity at tnom"),
|
||||
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( "ags", BSIM3_MOD_AGS, IF_REAL, "Gate bias coefficient of Abulk."),
|
||||
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( "a1", BSIM3_MOD_A1, 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."),
|
||||
|
|
@ -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( "delta", BSIM3_MOD_DELTA, IF_REAL, "Effective Vds parameter"),
|
||||
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( "prwb", BSIM3_MOD_PRWB, IF_REAL, "Body-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( "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( "etab", BSIM3_MOD_ETAB, IF_REAL, "Subthreshold region DIBL 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( "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( "pscbe1", BSIM3_MOD_PSCBE1, 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( "pdiblc1", BSIM3_MOD_PDIBL1, 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( "pscbe1", BSIM3_MOD_PSCBE1, 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( "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( "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( "lmin", BSIM3_MOD_LMIN, IF_REAL, "Minimum 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( "wint", BSIM3_MOD_WINT, 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( "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( "alpha1", BSIM3_MOD_ALPHA1, 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( "lvsat", BSIM3_MOD_LVSAT, IF_REAL, "Length dependence of vsat"),
|
||||
IOP( "lat", BSIM3_MOD_LAT, IF_REAL, "Length dependence of at"),
|
||||
IOP( "la0", BSIM3_MOD_LA0, IF_REAL, "Length dependence of a0"),
|
||||
IOP( "lags", BSIM3_MOD_LAGS, IF_REAL, "Length dependence of ags"),
|
||||
IOP( "la0", BSIM3_MOD_LA0, IF_REAL, "Length dependence of a0"),
|
||||
IOP( "lags", BSIM3_MOD_LAGS, IF_REAL, "Length dependence of ags"),
|
||||
IOP( "la1", BSIM3_MOD_LA1, IF_REAL, "Length dependence of a1"),
|
||||
IOP( "la2", BSIM3_MOD_LA2, IF_REAL, "Length dependence of a2"),
|
||||
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( "lelm", BSIM3_MOD_LELM, IF_REAL, "Length dependence of elm"),
|
||||
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( "lprwb", BSIM3_MOD_LPRWB, IF_REAL, "Length dependence of prwb "),
|
||||
IOP( "lprwg", BSIM3_MOD_LPRWG, IF_REAL, "Length dependence of prwg "),
|
||||
IOP( "lprwb", BSIM3_MOD_LPRWB, IF_REAL, "Length dependence of prwb "),
|
||||
|
||||
IOP( "lprt", BSIM3_MOD_LPRT, IF_REAL, "Length dependence of prt "),
|
||||
IOP( "leta0", BSIM3_MOD_LETA0, IF_REAL, "Length dependence of eta0"),
|
||||
IOP( "letab", BSIM3_MOD_LETAB, IF_REAL, "Length dependence of etab"),
|
||||
IOP( "lpclm", BSIM3_MOD_LPCLM, IF_REAL, "Length dependence of pclm"),
|
||||
IOP( "lpdiblc1", BSIM3_MOD_LPDIBL1, IF_REAL, "Length dependence of pdiblc1"),
|
||||
IOP( "lpdiblc2", BSIM3_MOD_LPDIBL2, IF_REAL, "Length dependence of pdiblc2"),
|
||||
IOP( "lpdiblcb", BSIM3_MOD_LPDIBLB, IF_REAL, "Length dependence of pdiblcb"),
|
||||
IOP( "lpscbe1", BSIM3_MOD_LPSCBE1, IF_REAL, "Length dependence of pscbe1"),
|
||||
IOP( "lpscbe2", BSIM3_MOD_LPSCBE2, IF_REAL, "Length dependence of pscbe2"),
|
||||
IOP( "lpvag", BSIM3_MOD_LPVAG, IF_REAL, "Length dependence of pvag"),
|
||||
IOP( "lprt", BSIM3_MOD_LPRT, IF_REAL, "Length dependence of prt "),
|
||||
IOP( "leta0", BSIM3_MOD_LETA0, IF_REAL, "Length dependence of eta0"),
|
||||
IOP( "letab", BSIM3_MOD_LETAB, IF_REAL, "Length dependence of etab"),
|
||||
IOP( "lpclm", BSIM3_MOD_LPCLM, IF_REAL, "Length dependence of pclm"),
|
||||
IOP( "lpdiblc1", BSIM3_MOD_LPDIBL1, IF_REAL, "Length dependence of pdiblc1"),
|
||||
IOP( "lpdiblc2", BSIM3_MOD_LPDIBL2, IF_REAL, "Length dependence of pdiblc2"),
|
||||
IOP( "lpdiblcb", BSIM3_MOD_LPDIBLB, IF_REAL, "Length dependence of pdiblcb"),
|
||||
IOP( "lpscbe1", BSIM3_MOD_LPSCBE1, IF_REAL, "Length dependence of pscbe1"),
|
||||
IOP( "lpscbe2", BSIM3_MOD_LPSCBE2, IF_REAL, "Length dependence of pscbe2"),
|
||||
IOP( "lpvag", BSIM3_MOD_LPVAG, IF_REAL, "Length dependence of pvag"),
|
||||
IOP( "lwr", BSIM3_MOD_LWR, IF_REAL, "Length dependence of wr"),
|
||||
IOP( "ldwg", BSIM3_MOD_LDWG, IF_REAL, "Length dependence of dwg"),
|
||||
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( "lvoffcv", BSIM3_MOD_LVOFFCV, IF_REAL, "Length dependence of voffcv"),
|
||||
IOP( "wcdsc", BSIM3_MOD_WCDSC, IF_REAL, "Width dependence of cdsc"),
|
||||
IOP( "wcdscb", BSIM3_MOD_WCDSCB, IF_REAL, "Width dependence of cdscb"),
|
||||
IOP( "wcdscd", BSIM3_MOD_WCDSCD, IF_REAL, "Width dependence of cdscd"),
|
||||
IOP( "wcdscb", BSIM3_MOD_WCDSCB, IF_REAL, "Width dependence of cdscb"),
|
||||
IOP( "wcdscd", BSIM3_MOD_WCDSCD, IF_REAL, "Width dependence of cdscd"),
|
||||
IOP( "wcit", BSIM3_MOD_WCIT, IF_REAL, "Width dependence of cit"),
|
||||
IOP( "wnfactor", BSIM3_MOD_WNFACTOR, IF_REAL, "Width dependence of nfactor"),
|
||||
IOP( "wxj", BSIM3_MOD_WXJ, IF_REAL, "Width dependence of xj"),
|
||||
IOP( "wvsat", BSIM3_MOD_WVSAT, IF_REAL, "Width dependence of vsat"),
|
||||
IOP( "wat", BSIM3_MOD_WAT, IF_REAL, "Width dependence of at"),
|
||||
IOP( "wa0", BSIM3_MOD_WA0, IF_REAL, "Width dependence of a0"),
|
||||
IOP( "wags", BSIM3_MOD_WAGS, IF_REAL, "Width dependence of ags"),
|
||||
IOP( "wa0", BSIM3_MOD_WA0, IF_REAL, "Width dependence of a0"),
|
||||
IOP( "wags", BSIM3_MOD_WAGS, IF_REAL, "Width dependence of ags"),
|
||||
IOP( "wa1", BSIM3_MOD_WA1, IF_REAL, "Width dependence of a1"),
|
||||
IOP( "wa2", BSIM3_MOD_WA2, IF_REAL, "Width dependence of a2"),
|
||||
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( "wprt", BSIM3_MOD_WPRT, IF_REAL, "Width dependence of prt"),
|
||||
IOP( "weta0", BSIM3_MOD_WETA0, IF_REAL, "Width dependence of eta0"),
|
||||
IOP( "wetab", BSIM3_MOD_WETAB, IF_REAL, "Width dependence of etab"),
|
||||
IOP( "wpclm", BSIM3_MOD_WPCLM, IF_REAL, "Width dependence of pclm"),
|
||||
IOP( "wpdiblc1", BSIM3_MOD_WPDIBL1, IF_REAL, "Width dependence of pdiblc1"),
|
||||
IOP( "wpdiblc2", BSIM3_MOD_WPDIBL2, IF_REAL, "Width dependence of pdiblc2"),
|
||||
IOP( "wpdiblcb", BSIM3_MOD_WPDIBLB, IF_REAL, "Width dependence of pdiblcb"),
|
||||
IOP( "wpscbe1", BSIM3_MOD_WPSCBE1, IF_REAL, "Width dependence of pscbe1"),
|
||||
IOP( "wpscbe2", BSIM3_MOD_WPSCBE2, IF_REAL, "Width dependence of pscbe2"),
|
||||
IOP( "wpvag", BSIM3_MOD_WPVAG, IF_REAL, "Width dependence of pvag"),
|
||||
IOP( "weta0", BSIM3_MOD_WETA0, IF_REAL, "Width dependence of eta0"),
|
||||
IOP( "wetab", BSIM3_MOD_WETAB, IF_REAL, "Width dependence of etab"),
|
||||
IOP( "wpclm", BSIM3_MOD_WPCLM, IF_REAL, "Width dependence of pclm"),
|
||||
IOP( "wpdiblc1", BSIM3_MOD_WPDIBL1, IF_REAL, "Width dependence of pdiblc1"),
|
||||
IOP( "wpdiblc2", BSIM3_MOD_WPDIBL2, IF_REAL, "Width dependence of pdiblc2"),
|
||||
IOP( "wpdiblcb", BSIM3_MOD_WPDIBLB, IF_REAL, "Width dependence of pdiblcb"),
|
||||
IOP( "wpscbe1", BSIM3_MOD_WPSCBE1, IF_REAL, "Width dependence of pscbe1"),
|
||||
IOP( "wpscbe2", BSIM3_MOD_WPSCBE2, IF_REAL, "Width dependence of pscbe2"),
|
||||
IOP( "wpvag", BSIM3_MOD_WPVAG, IF_REAL, "Width dependence of pvag"),
|
||||
IOP( "wwr", BSIM3_MOD_WWR, IF_REAL, "Width dependence of wr"),
|
||||
IOP( "wdwg", BSIM3_MOD_WDWG, IF_REAL, "Width dependence of dwg"),
|
||||
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( "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( "pcit", BSIM3_MOD_PCIT, IF_REAL, "Cross-term dependence of cit"),
|
||||
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( "pvsat", BSIM3_MOD_PVSAT, IF_REAL, "Cross-term dependence of vsat"),
|
||||
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( "pa1", BSIM3_MOD_PA1, IF_REAL, "Cross-term dependence of a1"),
|
||||
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( "pelm", BSIM3_MOD_PELM, IF_REAL, "Cross-term dependence of elm"),
|
||||
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( "pprwb", BSIM3_MOD_PPRWB, IF_REAL, "Cross-term dependence of prwb "),
|
||||
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( "pprt", BSIM3_MOD_PPRT, IF_REAL, "Cross-term dependence of prt "),
|
||||
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( "ppscbe1", BSIM3_MOD_PPSCBE1, IF_REAL, "Cross-term dependence of pscbe1"),
|
||||
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( "pdwg", BSIM3_MOD_PDWG, IF_REAL, "Cross-term dependence of dwg"),
|
||||
IOP( "pdwb", BSIM3_MOD_PDWB, IF_REAL, "Cross-term dependence of dwb"),
|
||||
|
|
@ -493,11 +512,11 @@ char *BSIM3names[] = {
|
|||
"Charge"
|
||||
};
|
||||
|
||||
int BSIM3nSize = NUMELEMS(BSIM3names);
|
||||
int BSIM3pTSize = NUMELEMS(BSIM3pTable);
|
||||
int BSIM3mPTSize = NUMELEMS(BSIM3mPTable);
|
||||
int BSIM3iSize = sizeof(BSIM3instance);
|
||||
int BSIM3mSize = sizeof(BSIM3model);
|
||||
int BSIM3nSize = NUMELEMS(BSIM3names);
|
||||
int BSIM3pTSize = NUMELEMS(BSIM3pTable);
|
||||
int BSIM3mPTSize = NUMELEMS(BSIM3mPTable);
|
||||
int BSIM3iSize = sizeof(BSIM3instance);
|
||||
int BSIM3mSize = sizeof(BSIM3model);
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ BSIM3instance *here = (BSIM3instance*)inst;
|
|||
|
||||
NG_IGNORE(select);
|
||||
|
||||
switch(which)
|
||||
switch(which)
|
||||
{ case BSIM3_L:
|
||||
value->rValue = here->BSIM3l;
|
||||
return(OK);
|
||||
|
|
@ -65,6 +65,15 @@ BSIM3instance *here = (BSIM3instance*)inst;
|
|||
case BSIM3_ACNQSMOD:
|
||||
value->iValue = here->BSIM3acnqsMod;
|
||||
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:
|
||||
value->rValue = here->BSIM3icVBS;
|
||||
return(OK);
|
||||
|
|
@ -94,11 +103,11 @@ BSIM3instance *here = (BSIM3instance*)inst;
|
|||
return(OK);
|
||||
case BSIM3_SOURCECONDUCT:
|
||||
value->rValue = here->BSIM3sourceConductance;
|
||||
value->rValue *= here->BSIM3m;
|
||||
value->rValue *= here->BSIM3m;
|
||||
return(OK);
|
||||
case BSIM3_DRAINCONDUCT:
|
||||
value->rValue = here->BSIM3drainConductance;
|
||||
value->rValue *= here->BSIM3m;
|
||||
value->rValue *= here->BSIM3m;
|
||||
return(OK);
|
||||
case BSIM3_VBD:
|
||||
value->rValue = *(ckt->CKTstate0 + here->BSIM3vbd);
|
||||
|
|
@ -113,118 +122,118 @@ BSIM3instance *here = (BSIM3instance*)inst;
|
|||
value->rValue = *(ckt->CKTstate0 + here->BSIM3vds);
|
||||
return(OK);
|
||||
case BSIM3_CD:
|
||||
value->rValue = here->BSIM3cd;
|
||||
value->rValue *= here->BSIM3m;
|
||||
value->rValue = here->BSIM3cd;
|
||||
value->rValue *= here->BSIM3m;
|
||||
return(OK);
|
||||
case BSIM3_CBS:
|
||||
value->rValue = here->BSIM3cbs;
|
||||
value->rValue *= here->BSIM3m;
|
||||
value->rValue = here->BSIM3cbs;
|
||||
value->rValue *= here->BSIM3m;
|
||||
return(OK);
|
||||
case BSIM3_CBD:
|
||||
value->rValue = here->BSIM3cbd;
|
||||
value->rValue *= here->BSIM3m;
|
||||
value->rValue = here->BSIM3cbd;
|
||||
value->rValue *= here->BSIM3m;
|
||||
return(OK);
|
||||
case BSIM3_GM:
|
||||
value->rValue = here->BSIM3gm;
|
||||
value->rValue *= here->BSIM3m;
|
||||
value->rValue = here->BSIM3gm;
|
||||
value->rValue *= here->BSIM3m;
|
||||
return(OK);
|
||||
case BSIM3_GDS:
|
||||
value->rValue = here->BSIM3gds;
|
||||
value->rValue *= here->BSIM3m;
|
||||
value->rValue = here->BSIM3gds;
|
||||
value->rValue *= here->BSIM3m;
|
||||
return(OK);
|
||||
case BSIM3_GMBS:
|
||||
value->rValue = here->BSIM3gmbs;
|
||||
value->rValue *= here->BSIM3m;
|
||||
value->rValue = here->BSIM3gmbs;
|
||||
value->rValue *= here->BSIM3m;
|
||||
return(OK);
|
||||
case BSIM3_GBD:
|
||||
value->rValue = here->BSIM3gbd;
|
||||
value->rValue *= here->BSIM3m;
|
||||
value->rValue = here->BSIM3gbd;
|
||||
value->rValue *= here->BSIM3m;
|
||||
return(OK);
|
||||
case BSIM3_GBS:
|
||||
value->rValue = here->BSIM3gbs;
|
||||
value->rValue *= here->BSIM3m;
|
||||
value->rValue = here->BSIM3gbs;
|
||||
value->rValue *= here->BSIM3m;
|
||||
return(OK);
|
||||
case BSIM3_QB:
|
||||
value->rValue = *(ckt->CKTstate0 + here->BSIM3qb);
|
||||
value->rValue *= here->BSIM3m;
|
||||
value->rValue = *(ckt->CKTstate0 + here->BSIM3qb);
|
||||
value->rValue *= here->BSIM3m;
|
||||
return(OK);
|
||||
case BSIM3_CQB:
|
||||
value->rValue = *(ckt->CKTstate0 + here->BSIM3cqb);
|
||||
value->rValue *= here->BSIM3m;
|
||||
value->rValue = *(ckt->CKTstate0 + here->BSIM3cqb);
|
||||
value->rValue *= here->BSIM3m;
|
||||
return(OK);
|
||||
case BSIM3_QG:
|
||||
value->rValue = *(ckt->CKTstate0 + here->BSIM3qg);
|
||||
value->rValue *= here->BSIM3m;
|
||||
value->rValue = *(ckt->CKTstate0 + here->BSIM3qg);
|
||||
value->rValue *= here->BSIM3m;
|
||||
return(OK);
|
||||
case BSIM3_CQG:
|
||||
value->rValue = *(ckt->CKTstate0 + here->BSIM3cqg);
|
||||
value->rValue *= here->BSIM3m;
|
||||
value->rValue = *(ckt->CKTstate0 + here->BSIM3cqg);
|
||||
value->rValue *= here->BSIM3m;
|
||||
return(OK);
|
||||
case BSIM3_QD:
|
||||
value->rValue = *(ckt->CKTstate0 + here->BSIM3qd);
|
||||
value->rValue *= here->BSIM3m;
|
||||
value->rValue = *(ckt->CKTstate0 + here->BSIM3qd);
|
||||
value->rValue *= here->BSIM3m;
|
||||
return(OK);
|
||||
case BSIM3_CQD:
|
||||
value->rValue = *(ckt->CKTstate0 + here->BSIM3cqd);
|
||||
value->rValue *= here->BSIM3m;
|
||||
value->rValue = *(ckt->CKTstate0 + here->BSIM3cqd);
|
||||
value->rValue *= here->BSIM3m;
|
||||
return(OK);
|
||||
case BSIM3_CGG:
|
||||
value->rValue = here->BSIM3cggb;
|
||||
value->rValue *= here->BSIM3m;
|
||||
value->rValue = here->BSIM3cggb;
|
||||
value->rValue *= here->BSIM3m;
|
||||
return(OK);
|
||||
case BSIM3_CGD:
|
||||
value->rValue = here->BSIM3cgdb;
|
||||
value->rValue *= here->BSIM3m;
|
||||
value->rValue *= here->BSIM3m;
|
||||
return(OK);
|
||||
case BSIM3_CGS:
|
||||
value->rValue = here->BSIM3cgsb;
|
||||
value->rValue *= here->BSIM3m;
|
||||
value->rValue *= here->BSIM3m;
|
||||
return(OK);
|
||||
case BSIM3_CDG:
|
||||
value->rValue = here->BSIM3cdgb;
|
||||
value->rValue *= here->BSIM3m;
|
||||
value->rValue = here->BSIM3cdgb;
|
||||
value->rValue *= here->BSIM3m;
|
||||
return(OK);
|
||||
case BSIM3_CDD:
|
||||
value->rValue = here->BSIM3cddb;
|
||||
value->rValue *= here->BSIM3m;
|
||||
value->rValue = here->BSIM3cddb;
|
||||
value->rValue *= here->BSIM3m;
|
||||
return(OK);
|
||||
case BSIM3_CDS:
|
||||
value->rValue = here->BSIM3cdsb;
|
||||
value->rValue *= here->BSIM3m;
|
||||
value->rValue = here->BSIM3cdsb;
|
||||
value->rValue *= here->BSIM3m;
|
||||
return(OK);
|
||||
case BSIM3_CBG:
|
||||
value->rValue = here->BSIM3cbgb;
|
||||
value->rValue *= here->BSIM3m;
|
||||
value->rValue *= here->BSIM3m;
|
||||
return(OK);
|
||||
case BSIM3_CBDB:
|
||||
value->rValue = here->BSIM3cbdb;
|
||||
value->rValue *= here->BSIM3m;
|
||||
value->rValue *= here->BSIM3m;
|
||||
return(OK);
|
||||
case BSIM3_CBSB:
|
||||
value->rValue = here->BSIM3cbsb;
|
||||
value->rValue *= here->BSIM3m;
|
||||
value->rValue *= here->BSIM3m;
|
||||
return(OK);
|
||||
case BSIM3_CAPBD:
|
||||
value->rValue = here->BSIM3capbd;
|
||||
value->rValue *= here->BSIM3m;
|
||||
value->rValue = here->BSIM3capbd;
|
||||
value->rValue *= here->BSIM3m;
|
||||
return(OK);
|
||||
case BSIM3_CAPBS:
|
||||
value->rValue = here->BSIM3capbs;
|
||||
value->rValue *= here->BSIM3m;
|
||||
value->rValue *= here->BSIM3m;
|
||||
return(OK);
|
||||
case BSIM3_VON:
|
||||
value->rValue = here->BSIM3von;
|
||||
value->rValue = here->BSIM3von;
|
||||
return(OK);
|
||||
case BSIM3_VDSAT:
|
||||
value->rValue = here->BSIM3vdsat;
|
||||
value->rValue = here->BSIM3vdsat;
|
||||
return(OK);
|
||||
case BSIM3_QBS:
|
||||
value->rValue = *(ckt->CKTstate0 + here->BSIM3qbs);
|
||||
value->rValue *= here->BSIM3m;
|
||||
value->rValue = *(ckt->CKTstate0 + here->BSIM3qbs);
|
||||
value->rValue *= here->BSIM3m;
|
||||
return(OK);
|
||||
case BSIM3_QBD:
|
||||
value->rValue = *(ckt->CKTstate0 + here->BSIM3qbd);
|
||||
value->rValue *= here->BSIM3m;
|
||||
value->rValue = *(ckt->CKTstate0 + here->BSIM3qbd);
|
||||
value->rValue *= here->BSIM3m;
|
||||
return(OK);
|
||||
default:
|
||||
return(E_BADPARM);
|
||||
|
|
|
|||
|
|
@ -31,29 +31,29 @@ FILE *fplog;
|
|||
|
||||
NG_IGNORE(ckt);
|
||||
|
||||
if ((fplog = fopen("b3v3check.log", "w")) != NULL)
|
||||
if ((fplog = fopen("b3v33check.log", "w")) != NULL)
|
||||
{ pParam = here->pParam;
|
||||
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");
|
||||
printf("Warning: This model is BSIM3v3.3.0; you specified a wrong version number.\n");
|
||||
}
|
||||
fprintf(fplog, "Model = %s\n", model->BSIM3modName);
|
||||
|
||||
if (pParam->BSIM3nlx < -pParam->BSIM3leff)
|
||||
{ fprintf(fplog, "Fatal: Nlx = %g is less than -Leff.\n",
|
||||
pParam->BSIM3nlx);
|
||||
printf("Fatal: Nlx = %g is less than -Leff.\n",
|
||||
pParam->BSIM3nlx);
|
||||
Fatal_Flag = 1;
|
||||
{ fprintf(fplog, "Fatal: Nlx = %g is less than -Leff.\n",
|
||||
pParam->BSIM3nlx);
|
||||
printf("Fatal: Nlx = %g is less than -Leff.\n",
|
||||
pParam->BSIM3nlx);
|
||||
Fatal_Flag = 1;
|
||||
}
|
||||
|
||||
if (model->BSIM3tox <= 0.0)
|
||||
{ fprintf(fplog, "Fatal: Tox = %g is not positive.\n",
|
||||
model->BSIM3tox);
|
||||
printf("Fatal: Tox = %g is not positive.\n", model->BSIM3tox);
|
||||
Fatal_Flag = 1;
|
||||
}
|
||||
if (model->BSIM3tox <= 0.0)
|
||||
{ fprintf(fplog, "Fatal: Tox = %g is not positive.\n",
|
||||
model->BSIM3tox);
|
||||
printf("Fatal: Tox = %g is not positive.\n", model->BSIM3tox);
|
||||
Fatal_Flag = 1;
|
||||
}
|
||||
|
||||
if (model->BSIM3toxm <= 0.0)
|
||||
{ fprintf(fplog, "Fatal: Toxm = %g is not positive.\n",
|
||||
|
|
@ -70,104 +70,104 @@ FILE *fplog;
|
|||
Fatal_Flag = 1;
|
||||
}
|
||||
|
||||
if (pParam->BSIM3npeak <= 0.0)
|
||||
{ fprintf(fplog, "Fatal: Nch = %g is not positive.\n",
|
||||
pParam->BSIM3npeak);
|
||||
printf("Fatal: Nch = %g is not positive.\n",
|
||||
pParam->BSIM3npeak);
|
||||
Fatal_Flag = 1;
|
||||
}
|
||||
if (pParam->BSIM3nsub <= 0.0)
|
||||
{ fprintf(fplog, "Fatal: Nsub = %g is not positive.\n",
|
||||
pParam->BSIM3nsub);
|
||||
printf("Fatal: Nsub = %g is not positive.\n",
|
||||
pParam->BSIM3nsub);
|
||||
Fatal_Flag = 1;
|
||||
}
|
||||
if (pParam->BSIM3ngate < 0.0)
|
||||
{ fprintf(fplog, "Fatal: Ngate = %g is not positive.\n",
|
||||
pParam->BSIM3ngate);
|
||||
printf("Fatal: Ngate = %g Ngate is not positive.\n",
|
||||
pParam->BSIM3ngate);
|
||||
Fatal_Flag = 1;
|
||||
}
|
||||
if (pParam->BSIM3ngate > 1.e25)
|
||||
{ fprintf(fplog, "Fatal: Ngate = %g is too high.\n",
|
||||
pParam->BSIM3ngate);
|
||||
printf("Fatal: Ngate = %g Ngate is too high\n",
|
||||
pParam->BSIM3ngate);
|
||||
Fatal_Flag = 1;
|
||||
}
|
||||
if (pParam->BSIM3xj <= 0.0)
|
||||
{ fprintf(fplog, "Fatal: Xj = %g is not positive.\n",
|
||||
pParam->BSIM3xj);
|
||||
printf("Fatal: Xj = %g is not positive.\n", pParam->BSIM3xj);
|
||||
Fatal_Flag = 1;
|
||||
}
|
||||
if (pParam->BSIM3npeak <= 0.0)
|
||||
{ fprintf(fplog, "Fatal: Nch = %g is not positive.\n",
|
||||
pParam->BSIM3npeak);
|
||||
printf("Fatal: Nch = %g is not positive.\n",
|
||||
pParam->BSIM3npeak);
|
||||
Fatal_Flag = 1;
|
||||
}
|
||||
if (pParam->BSIM3nsub <= 0.0)
|
||||
{ fprintf(fplog, "Fatal: Nsub = %g is not positive.\n",
|
||||
pParam->BSIM3nsub);
|
||||
printf("Fatal: Nsub = %g is not positive.\n",
|
||||
pParam->BSIM3nsub);
|
||||
Fatal_Flag = 1;
|
||||
}
|
||||
if (pParam->BSIM3ngate < 0.0)
|
||||
{ fprintf(fplog, "Fatal: Ngate = %g is not positive.\n",
|
||||
pParam->BSIM3ngate);
|
||||
printf("Fatal: Ngate = %g Ngate is not positive.\n",
|
||||
pParam->BSIM3ngate);
|
||||
Fatal_Flag = 1;
|
||||
}
|
||||
if (pParam->BSIM3ngate > 1.e25)
|
||||
{ fprintf(fplog, "Fatal: Ngate = %g is too high.\n",
|
||||
pParam->BSIM3ngate);
|
||||
printf("Fatal: Ngate = %g Ngate is too high\n",
|
||||
pParam->BSIM3ngate);
|
||||
Fatal_Flag = 1;
|
||||
}
|
||||
if (pParam->BSIM3xj <= 0.0)
|
||||
{ fprintf(fplog, "Fatal: Xj = %g is not positive.\n",
|
||||
pParam->BSIM3xj);
|
||||
printf("Fatal: Xj = %g is not positive.\n", pParam->BSIM3xj);
|
||||
Fatal_Flag = 1;
|
||||
}
|
||||
|
||||
if (pParam->BSIM3dvt1 < 0.0)
|
||||
{ fprintf(fplog, "Fatal: Dvt1 = %g is negative.\n",
|
||||
pParam->BSIM3dvt1);
|
||||
printf("Fatal: Dvt1 = %g is negative.\n", pParam->BSIM3dvt1);
|
||||
Fatal_Flag = 1;
|
||||
}
|
||||
|
||||
if (pParam->BSIM3dvt1w < 0.0)
|
||||
{ fprintf(fplog, "Fatal: Dvt1w = %g is negative.\n",
|
||||
pParam->BSIM3dvt1w);
|
||||
printf("Fatal: Dvt1w = %g is negative.\n", pParam->BSIM3dvt1w);
|
||||
Fatal_Flag = 1;
|
||||
}
|
||||
|
||||
if (pParam->BSIM3w0 == -pParam->BSIM3weff)
|
||||
{ fprintf(fplog, "Fatal: (W0 + Weff) = 0 causing divided-by-zero.\n");
|
||||
printf("Fatal: (W0 + Weff) = 0 causing divided-by-zero.\n");
|
||||
Fatal_Flag = 1;
|
||||
if (pParam->BSIM3dvt1 < 0.0)
|
||||
{ fprintf(fplog, "Fatal: Dvt1 = %g is negative.\n",
|
||||
pParam->BSIM3dvt1);
|
||||
printf("Fatal: Dvt1 = %g is negative.\n", pParam->BSIM3dvt1);
|
||||
Fatal_Flag = 1;
|
||||
}
|
||||
|
||||
if (pParam->BSIM3dvt1w < 0.0)
|
||||
{ fprintf(fplog, "Fatal: Dvt1w = %g is negative.\n",
|
||||
pParam->BSIM3dvt1w);
|
||||
printf("Fatal: Dvt1w = %g is negative.\n", pParam->BSIM3dvt1w);
|
||||
Fatal_Flag = 1;
|
||||
}
|
||||
|
||||
if (pParam->BSIM3w0 == -pParam->BSIM3weff)
|
||||
{ fprintf(fplog, "Fatal: (W0 + Weff) = 0 causing divided-by-zero.\n");
|
||||
printf("Fatal: (W0 + Weff) = 0 causing divided-by-zero.\n");
|
||||
Fatal_Flag = 1;
|
||||
}
|
||||
|
||||
if (pParam->BSIM3dsub < 0.0)
|
||||
{ fprintf(fplog, "Fatal: Dsub = %g is negative.\n", pParam->BSIM3dsub);
|
||||
printf("Fatal: Dsub = %g is negative.\n", pParam->BSIM3dsub);
|
||||
Fatal_Flag = 1;
|
||||
}
|
||||
if (pParam->BSIM3b1 == -pParam->BSIM3weff)
|
||||
{ fprintf(fplog, "Fatal: (B1 + Weff) = 0 causing divided-by-zero.\n");
|
||||
printf("Fatal: (B1 + Weff) = 0 causing divided-by-zero.\n");
|
||||
Fatal_Flag = 1;
|
||||
if (pParam->BSIM3dsub < 0.0)
|
||||
{ fprintf(fplog, "Fatal: Dsub = %g is negative.\n", pParam->BSIM3dsub);
|
||||
printf("Fatal: Dsub = %g is negative.\n", pParam->BSIM3dsub);
|
||||
Fatal_Flag = 1;
|
||||
}
|
||||
if (pParam->BSIM3b1 == -pParam->BSIM3weff)
|
||||
{ fprintf(fplog, "Fatal: (B1 + Weff) = 0 causing divided-by-zero.\n");
|
||||
printf("Fatal: (B1 + Weff) = 0 causing divided-by-zero.\n");
|
||||
Fatal_Flag = 1;
|
||||
}
|
||||
if (pParam->BSIM3u0temp <= 0.0)
|
||||
{ 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",
|
||||
pParam->BSIM3u0temp);
|
||||
Fatal_Flag = 1;
|
||||
{ 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",
|
||||
pParam->BSIM3u0temp);
|
||||
Fatal_Flag = 1;
|
||||
}
|
||||
|
||||
/* Check delta parameter */
|
||||
if (pParam->BSIM3delta < 0.0)
|
||||
{ fprintf(fplog, "Fatal: Delta = %g is less than zero.\n",
|
||||
pParam->BSIM3delta);
|
||||
printf("Fatal: Delta = %g is less than zero.\n", pParam->BSIM3delta);
|
||||
Fatal_Flag = 1;
|
||||
{ fprintf(fplog, "Fatal: Delta = %g is less than zero.\n",
|
||||
pParam->BSIM3delta);
|
||||
printf("Fatal: Delta = %g is less than zero.\n", pParam->BSIM3delta);
|
||||
Fatal_Flag = 1;
|
||||
}
|
||||
|
||||
if (pParam->BSIM3vsattemp <= 0.0)
|
||||
{ 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",
|
||||
pParam->BSIM3vsattemp);
|
||||
Fatal_Flag = 1;
|
||||
}
|
||||
if (pParam->BSIM3vsattemp <= 0.0)
|
||||
{ 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",
|
||||
pParam->BSIM3vsattemp);
|
||||
Fatal_Flag = 1;
|
||||
}
|
||||
/* Check Rout parameters */
|
||||
if (pParam->BSIM3pclm <= 0.0)
|
||||
{ fprintf(fplog, "Fatal: Pclm = %g is not positive.\n", pParam->BSIM3pclm);
|
||||
printf("Fatal: Pclm = %g is not positive.\n", pParam->BSIM3pclm);
|
||||
Fatal_Flag = 1;
|
||||
}
|
||||
if (pParam->BSIM3pclm <= 0.0)
|
||||
{ fprintf(fplog, "Fatal: Pclm = %g is not positive.\n", pParam->BSIM3pclm);
|
||||
printf("Fatal: Pclm = %g is not positive.\n", pParam->BSIM3pclm);
|
||||
Fatal_Flag = 1;
|
||||
}
|
||||
|
||||
if (pParam->BSIM3drout < 0.0)
|
||||
{ fprintf(fplog, "Fatal: Drout = %g is negative.\n", pParam->BSIM3drout);
|
||||
printf("Fatal: Drout = %g is negative.\n", pParam->BSIM3drout);
|
||||
Fatal_Flag = 1;
|
||||
}
|
||||
if (pParam->BSIM3drout < 0.0)
|
||||
{ fprintf(fplog, "Fatal: Drout = %g is negative.\n", pParam->BSIM3drout);
|
||||
printf("Fatal: Drout = %g is negative.\n", pParam->BSIM3drout);
|
||||
Fatal_Flag = 1;
|
||||
}
|
||||
|
||||
if (pParam->BSIM3pscbe2 <= 0.0)
|
||||
{ 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);
|
||||
}
|
||||
|
||||
if (model->BSIM3unitLengthSidewallJctCap > 0.0 ||
|
||||
model->BSIM3unitLengthGateSidewallJctCap > 0.0)
|
||||
{
|
||||
if (here->BSIM3drainPerimeter < pParam->BSIM3weff)
|
||||
{ fprintf(fplog, "Warning: Pd = %g is less than W.\n",
|
||||
here->BSIM3drainPerimeter);
|
||||
printf("Warning: Pd = %g is less than W.\n",
|
||||
here->BSIM3drainPerimeter);
|
||||
}
|
||||
if (here->BSIM3sourcePerimeter < pParam->BSIM3weff)
|
||||
{ fprintf(fplog, "Warning: Ps = %g is less than W.\n",
|
||||
here->BSIM3sourcePerimeter);
|
||||
printf("Warning: Ps = %g is less than W.\n",
|
||||
here->BSIM3sourcePerimeter);
|
||||
}
|
||||
}
|
||||
/* ACM model */
|
||||
if (model->BSIM3acmMod == 0) {
|
||||
if (model->BSIM3unitLengthSidewallJctCap > 0.0 ||
|
||||
model->BSIM3unitLengthGateSidewallJctCap > 0.0)
|
||||
{
|
||||
if (here->BSIM3drainPerimeter < pParam->BSIM3weff)
|
||||
{ fprintf(fplog, "Warning: Pd = %g is less than W.\n",
|
||||
here->BSIM3drainPerimeter);
|
||||
printf("Warning: Pd = %g is less than W.\n",
|
||||
here->BSIM3drainPerimeter);
|
||||
}
|
||||
if (here->BSIM3sourcePerimeter < pParam->BSIM3weff)
|
||||
{ fprintf(fplog, "Warning: Ps = %g is less than W.\n",
|
||||
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)
|
||||
{ fprintf(fplog, "Warning: Noff = %g is too small.\n",
|
||||
|
|
@ -223,9 +232,9 @@ FILE *fplog;
|
|||
|
||||
/* Check capacitance parameters */
|
||||
if (pParam->BSIM3clc < 0.0)
|
||||
{ fprintf(fplog, "Fatal: Clc = %g is negative.\n", pParam->BSIM3clc);
|
||||
printf("Fatal: Clc = %g is negative.\n", pParam->BSIM3clc);
|
||||
Fatal_Flag = 1;
|
||||
{ fprintf(fplog, "Fatal: Clc = %g is negative.\n", pParam->BSIM3clc);
|
||||
printf("Fatal: Clc = %g is negative.\n", pParam->BSIM3clc);
|
||||
Fatal_Flag = 1;
|
||||
}
|
||||
|
||||
if (pParam->BSIM3moin < 5.0)
|
||||
|
|
@ -239,160 +248,160 @@ FILE *fplog;
|
|||
printf("Warning: Moin = %g is too large.\n", pParam->BSIM3moin);
|
||||
}
|
||||
|
||||
if(model->BSIM3capMod ==3) {
|
||||
if (pParam->BSIM3acde < 0.4)
|
||||
{ fprintf(fplog, "Warning: Acde = %g is too small.\n",
|
||||
pParam->BSIM3acde);
|
||||
printf("Warning: Acde = %g is too small.\n", pParam->BSIM3acde);
|
||||
}
|
||||
if (pParam->BSIM3acde > 1.6)
|
||||
{ fprintf(fplog, "Warning: Acde = %g is too large.\n",
|
||||
pParam->BSIM3acde);
|
||||
printf("Warning: Acde = %g is too large.\n", pParam->BSIM3acde);
|
||||
}
|
||||
}
|
||||
if(model->BSIM3capMod ==3) {
|
||||
if (pParam->BSIM3acde < 0.4)
|
||||
{ fprintf(fplog, "Warning: Acde = %g is too small.\n",
|
||||
pParam->BSIM3acde);
|
||||
printf("Warning: Acde = %g is too small.\n", pParam->BSIM3acde);
|
||||
}
|
||||
if (pParam->BSIM3acde > 1.6)
|
||||
{ fprintf(fplog, "Warning: Acde = %g is too large.\n",
|
||||
pParam->BSIM3acde);
|
||||
printf("Warning: Acde = %g is too large.\n", pParam->BSIM3acde);
|
||||
}
|
||||
}
|
||||
|
||||
if (model->BSIM3paramChk ==1)
|
||||
{
|
||||
/* Check L and W parameters */
|
||||
if (pParam->BSIM3leff <= 5.0e-8)
|
||||
{ fprintf(fplog, "Warning: Leff = %g may be too small.\n",
|
||||
pParam->BSIM3leff);
|
||||
printf("Warning: Leff = %g may be too small.\n",
|
||||
pParam->BSIM3leff);
|
||||
}
|
||||
|
||||
if (pParam->BSIM3leffCV <= 5.0e-8)
|
||||
{ fprintf(fplog, "Warning: Leff for CV = %g may be too small.\n",
|
||||
pParam->BSIM3leffCV);
|
||||
printf("Warning: Leff for CV = %g may be too small.\n",
|
||||
pParam->BSIM3leffCV);
|
||||
}
|
||||
|
||||
if (pParam->BSIM3leff <= 5.0e-8)
|
||||
{ fprintf(fplog, "Warning: Leff = %g may be too small.\n",
|
||||
pParam->BSIM3leff);
|
||||
printf("Warning: Leff = %g may be too small.\n",
|
||||
pParam->BSIM3leff);
|
||||
}
|
||||
|
||||
if (pParam->BSIM3leffCV <= 5.0e-8)
|
||||
{ fprintf(fplog, "Warning: Leff for CV = %g may be too small.\n",
|
||||
pParam->BSIM3leffCV);
|
||||
printf("Warning: Leff for CV = %g may be too small.\n",
|
||||
pParam->BSIM3leffCV);
|
||||
}
|
||||
|
||||
if (pParam->BSIM3weff <= 1.0e-7)
|
||||
{ fprintf(fplog, "Warning: Weff = %g may be too small.\n",
|
||||
pParam->BSIM3weff);
|
||||
printf("Warning: Weff = %g may be too small.\n",
|
||||
pParam->BSIM3weff);
|
||||
}
|
||||
|
||||
if (pParam->BSIM3weffCV <= 1.0e-7)
|
||||
{ fprintf(fplog, "Warning: Weff for CV = %g may be too small.\n",
|
||||
pParam->BSIM3weffCV);
|
||||
printf("Warning: Weff for CV = %g may be too small.\n",
|
||||
pParam->BSIM3weffCV);
|
||||
}
|
||||
|
||||
{ fprintf(fplog, "Warning: Weff = %g may be too small.\n",
|
||||
pParam->BSIM3weff);
|
||||
printf("Warning: Weff = %g may be too small.\n",
|
||||
pParam->BSIM3weff);
|
||||
}
|
||||
|
||||
if (pParam->BSIM3weffCV <= 1.0e-7)
|
||||
{ fprintf(fplog, "Warning: Weff for CV = %g may be too small.\n",
|
||||
pParam->BSIM3weffCV);
|
||||
printf("Warning: Weff for CV = %g may be too small.\n",
|
||||
pParam->BSIM3weffCV);
|
||||
}
|
||||
|
||||
/* Check threshold voltage parameters */
|
||||
if (pParam->BSIM3nlx < 0.0)
|
||||
{ fprintf(fplog, "Warning: Nlx = %g is negative.\n", pParam->BSIM3nlx);
|
||||
printf("Warning: Nlx = %g is negative.\n", pParam->BSIM3nlx);
|
||||
if (pParam->BSIM3nlx < 0.0)
|
||||
{ fprintf(fplog, "Warning: Nlx = %g is negative.\n", pParam->BSIM3nlx);
|
||||
printf("Warning: Nlx = %g is negative.\n", pParam->BSIM3nlx);
|
||||
}
|
||||
if (model->BSIM3tox < 1.0e-9)
|
||||
{ fprintf(fplog, "Warning: Tox = %g is less than 10A.\n",
|
||||
model->BSIM3tox);
|
||||
printf("Warning: Tox = %g is less than 10A.\n", model->BSIM3tox);
|
||||
if (model->BSIM3tox < 1.0e-9)
|
||||
{ fprintf(fplog, "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)
|
||||
{ fprintf(fplog, "Warning: Nch = %g may be too small.\n",
|
||||
pParam->BSIM3npeak);
|
||||
printf("Warning: Nch = %g may be too small.\n",
|
||||
pParam->BSIM3npeak);
|
||||
}
|
||||
else if (pParam->BSIM3npeak >= 1.0e21)
|
||||
{ fprintf(fplog, "Warning: Nch = %g may be too large.\n",
|
||||
pParam->BSIM3npeak);
|
||||
printf("Warning: Nch = %g may be too large.\n",
|
||||
pParam->BSIM3npeak);
|
||||
}
|
||||
{ fprintf(fplog, "Warning: Nch = %g may be too small.\n",
|
||||
pParam->BSIM3npeak);
|
||||
printf("Warning: Nch = %g may be too small.\n",
|
||||
pParam->BSIM3npeak);
|
||||
}
|
||||
else if (pParam->BSIM3npeak >= 1.0e21)
|
||||
{ fprintf(fplog, "Warning: Nch = %g may be too large.\n",
|
||||
pParam->BSIM3npeak);
|
||||
printf("Warning: Nch = %g may be too large.\n",
|
||||
pParam->BSIM3npeak);
|
||||
}
|
||||
|
||||
if (pParam->BSIM3nsub <= 1.0e14)
|
||||
{ fprintf(fplog, "Warning: Nsub = %g may be too small.\n",
|
||||
pParam->BSIM3nsub);
|
||||
printf("Warning: Nsub = %g may be too small.\n",
|
||||
pParam->BSIM3nsub);
|
||||
}
|
||||
else if (pParam->BSIM3nsub >= 1.0e21)
|
||||
{ fprintf(fplog, "Warning: Nsub = %g may be too large.\n",
|
||||
pParam->BSIM3nsub);
|
||||
printf("Warning: Nsub = %g may be too large.\n",
|
||||
pParam->BSIM3nsub);
|
||||
}
|
||||
if (pParam->BSIM3nsub <= 1.0e14)
|
||||
{ fprintf(fplog, "Warning: Nsub = %g may be too small.\n",
|
||||
pParam->BSIM3nsub);
|
||||
printf("Warning: Nsub = %g may be too small.\n",
|
||||
pParam->BSIM3nsub);
|
||||
}
|
||||
else if (pParam->BSIM3nsub >= 1.0e21)
|
||||
{ fprintf(fplog, "Warning: Nsub = %g may be too large.\n",
|
||||
pParam->BSIM3nsub);
|
||||
printf("Warning: Nsub = %g may be too large.\n",
|
||||
pParam->BSIM3nsub);
|
||||
}
|
||||
|
||||
if ((pParam->BSIM3ngate > 0.0) &&
|
||||
(pParam->BSIM3ngate <= 1.e18))
|
||||
{ fprintf(fplog, "Warning: Ngate = %g is less than 1.E18cm^-3.\n",
|
||||
pParam->BSIM3ngate);
|
||||
printf("Warning: Ngate = %g is less than 1.E18cm^-3.\n",
|
||||
pParam->BSIM3ngate);
|
||||
}
|
||||
if ((pParam->BSIM3ngate > 0.0) &&
|
||||
(pParam->BSIM3ngate <= 1.e18))
|
||||
{ fprintf(fplog, "Warning: Ngate = %g is less than 1.E18cm^-3.\n",
|
||||
pParam->BSIM3ngate);
|
||||
printf("Warning: Ngate = %g is less than 1.E18cm^-3.\n",
|
||||
pParam->BSIM3ngate);
|
||||
}
|
||||
|
||||
if (pParam->BSIM3dvt0 < 0.0)
|
||||
{ fprintf(fplog, "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)
|
||||
{ fprintf(fplog, "Warning: (W0 + Weff) may be too small.\n");
|
||||
printf("Warning: (W0 + Weff) may be too small.\n");
|
||||
{ fprintf(fplog, "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)
|
||||
{ fprintf(fplog, "Warning: (W0 + Weff) may be too small.\n");
|
||||
printf("Warning: (W0 + Weff) may be too small.\n");
|
||||
}
|
||||
|
||||
/* Check subthreshold parameters */
|
||||
if (pParam->BSIM3nfactor < 0.0)
|
||||
{ fprintf(fplog, "Warning: Nfactor = %g is negative.\n",
|
||||
pParam->BSIM3nfactor);
|
||||
printf("Warning: Nfactor = %g is negative.\n", pParam->BSIM3nfactor);
|
||||
}
|
||||
if (pParam->BSIM3cdsc < 0.0)
|
||||
{ fprintf(fplog, "Warning: Cdsc = %g is negative.\n",
|
||||
pParam->BSIM3cdsc);
|
||||
printf("Warning: Cdsc = %g is negative.\n", pParam->BSIM3cdsc);
|
||||
}
|
||||
if (pParam->BSIM3cdscd < 0.0)
|
||||
{ fprintf(fplog, "Warning: Cdscd = %g is negative.\n",
|
||||
pParam->BSIM3cdscd);
|
||||
printf("Warning: Cdscd = %g is negative.\n", pParam->BSIM3cdscd);
|
||||
}
|
||||
if (pParam->BSIM3nfactor < 0.0)
|
||||
{ fprintf(fplog, "Warning: Nfactor = %g is negative.\n",
|
||||
pParam->BSIM3nfactor);
|
||||
printf("Warning: Nfactor = %g is negative.\n", pParam->BSIM3nfactor);
|
||||
}
|
||||
if (pParam->BSIM3cdsc < 0.0)
|
||||
{ fprintf(fplog, "Warning: Cdsc = %g is negative.\n",
|
||||
pParam->BSIM3cdsc);
|
||||
printf("Warning: Cdsc = %g is negative.\n", pParam->BSIM3cdsc);
|
||||
}
|
||||
if (pParam->BSIM3cdscd < 0.0)
|
||||
{ fprintf(fplog, "Warning: Cdscd = %g is negative.\n",
|
||||
pParam->BSIM3cdscd);
|
||||
printf("Warning: Cdscd = %g is negative.\n", pParam->BSIM3cdscd);
|
||||
}
|
||||
/* Check DIBL parameters */
|
||||
if (pParam->BSIM3eta0 < 0.0)
|
||||
{ fprintf(fplog, "Warning: Eta0 = %g is negative.\n",
|
||||
pParam->BSIM3eta0);
|
||||
printf("Warning: Eta0 = %g is negative.\n", pParam->BSIM3eta0);
|
||||
}
|
||||
|
||||
/* Check Abulk parameters */
|
||||
if (fabs(1.0e-6 / (pParam->BSIM3b1 + pParam->BSIM3weff)) > 10.0)
|
||||
{ fprintf(fplog, "Warning: (B1 + Weff) may be too small.\n");
|
||||
printf("Warning: (B1 + Weff) may be too small.\n");
|
||||
if (pParam->BSIM3eta0 < 0.0)
|
||||
{ fprintf(fplog, "Warning: Eta0 = %g is negative.\n",
|
||||
pParam->BSIM3eta0);
|
||||
printf("Warning: Eta0 = %g is negative.\n", pParam->BSIM3eta0);
|
||||
}
|
||||
|
||||
/* Check Abulk parameters */
|
||||
if (fabs(1.0e-6 / (pParam->BSIM3b1 + pParam->BSIM3weff)) > 10.0)
|
||||
{ fprintf(fplog, "Warning: (B1 + Weff) may be too small.\n");
|
||||
printf("Warning: (B1 + Weff) may be too small.\n");
|
||||
}
|
||||
|
||||
|
||||
/* Check Saturation parameters */
|
||||
if (pParam->BSIM3a2 < 0.01)
|
||||
{ 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",
|
||||
pParam->BSIM3a2);
|
||||
pParam->BSIM3a2 = 0.01;
|
||||
}
|
||||
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",
|
||||
pParam->BSIM3a2);
|
||||
printf("Warning: A2 = %g is larger than 1. A2 is set to 1 and A1 is set to 0.\n",
|
||||
pParam->BSIM3a2);
|
||||
pParam->BSIM3a2 = 1.0;
|
||||
pParam->BSIM3a1 = 0.0;
|
||||
}
|
||||
if (pParam->BSIM3a2 < 0.01)
|
||||
{ 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",
|
||||
pParam->BSIM3a2);
|
||||
pParam->BSIM3a2 = 0.01;
|
||||
}
|
||||
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",
|
||||
pParam->BSIM3a2);
|
||||
printf("Warning: A2 = %g is larger than 1. A2 is set to 1 and A1 is set to 0.\n",
|
||||
pParam->BSIM3a2);
|
||||
pParam->BSIM3a2 = 1.0;
|
||||
pParam->BSIM3a1 = 0.0;
|
||||
}
|
||||
|
||||
if (pParam->BSIM3rdsw < 0.0)
|
||||
{ fprintf(fplog, "Warning: Rdsw = %g is negative. Set to zero.\n",
|
||||
pParam->BSIM3rdsw);
|
||||
printf("Warning: Rdsw = %g is negative. Set to zero.\n",
|
||||
pParam->BSIM3rdsw);
|
||||
pParam->BSIM3rdsw = 0.0;
|
||||
pParam->BSIM3rds0 = 0.0;
|
||||
}
|
||||
if (pParam->BSIM3rdsw < 0.0)
|
||||
{ fprintf(fplog, "Warning: Rdsw = %g is negative. Set to zero.\n",
|
||||
pParam->BSIM3rdsw);
|
||||
printf("Warning: Rdsw = %g is negative. Set to zero.\n",
|
||||
pParam->BSIM3rdsw);
|
||||
pParam->BSIM3rdsw = 0.0;
|
||||
pParam->BSIM3rds0 = 0.0;
|
||||
}
|
||||
if (pParam->BSIM3rds0 < 0.0)
|
||||
{ fprintf(fplog, "Warning: Rds at current temperature = %g is negative. Set to zero.\n",
|
||||
pParam->BSIM3rds0);
|
||||
|
|
@ -401,40 +410,40 @@ FILE *fplog;
|
|||
pParam->BSIM3rds0 = 0.0;
|
||||
}
|
||||
|
||||
if (pParam->BSIM3vsattemp < 1.0e3)
|
||||
{ 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);
|
||||
}
|
||||
if (pParam->BSIM3vsattemp < 1.0e3)
|
||||
{ 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);
|
||||
}
|
||||
|
||||
if (pParam->BSIM3pdibl1 < 0.0)
|
||||
{ fprintf(fplog, "Warning: Pdibl1 = %g is negative.\n",
|
||||
pParam->BSIM3pdibl1);
|
||||
printf("Warning: Pdibl1 = %g is negative.\n", pParam->BSIM3pdibl1);
|
||||
}
|
||||
if (pParam->BSIM3pdibl2 < 0.0)
|
||||
{ fprintf(fplog, "Warning: Pdibl2 = %g is negative.\n",
|
||||
pParam->BSIM3pdibl2);
|
||||
printf("Warning: Pdibl2 = %g is negative.\n", pParam->BSIM3pdibl2);
|
||||
}
|
||||
if (pParam->BSIM3pdibl1 < 0.0)
|
||||
{ fprintf(fplog, "Warning: Pdibl1 = %g is negative.\n",
|
||||
pParam->BSIM3pdibl1);
|
||||
printf("Warning: Pdibl1 = %g is negative.\n", pParam->BSIM3pdibl1);
|
||||
}
|
||||
if (pParam->BSIM3pdibl2 < 0.0)
|
||||
{ fprintf(fplog, "Warning: Pdibl2 = %g is negative.\n",
|
||||
pParam->BSIM3pdibl2);
|
||||
printf("Warning: Pdibl2 = %g is negative.\n", pParam->BSIM3pdibl2);
|
||||
}
|
||||
/* Check overlap capacitance parameters */
|
||||
if (model->BSIM3cgdo < 0.0)
|
||||
{ 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);
|
||||
model->BSIM3cgdo = 0.0;
|
||||
{ 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);
|
||||
model->BSIM3cgdo = 0.0;
|
||||
}
|
||||
if (model->BSIM3cgso < 0.0)
|
||||
{ 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);
|
||||
model->BSIM3cgso = 0.0;
|
||||
{ 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);
|
||||
model->BSIM3cgso = 0.0;
|
||||
}
|
||||
if (model->BSIM3cgbo < 0.0)
|
||||
{ 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);
|
||||
model->BSIM3cgbo = 0.0;
|
||||
{ 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);
|
||||
model->BSIM3cgbo = 0.0;
|
||||
}
|
||||
|
||||
}/* loop for the parameter check for warning messages */
|
||||
fclose(fplog);
|
||||
fclose(fplog);
|
||||
}
|
||||
else
|
||||
{ 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:
|
||||
value->iValue = model->BSIM3noiMod;
|
||||
return(OK);
|
||||
case BSIM3_MOD_NQSMOD:
|
||||
value->iValue = model->BSIM3nqsMod;
|
||||
return(OK);
|
||||
case BSIM3_MOD_ACNQSMOD:
|
||||
value->iValue = model->BSIM3acnqsMod;
|
||||
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 :
|
||||
value->sValue = model->BSIM3version;
|
||||
return(OK);
|
||||
|
|
@ -337,6 +346,32 @@ IFvalue *value)
|
|||
value->rValue = model->BSIM3tpbswg;
|
||||
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 */
|
||||
case BSIM3_MOD_LCDSC :
|
||||
value->rValue = model->BSIM3lcdsc;
|
||||
|
|
@ -1219,6 +1254,14 @@ IFvalue *value)
|
|||
case BSIM3_MOD_WMAX:
|
||||
value->rValue = model->BSIM3Wmax;
|
||||
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:
|
||||
value->rValue = model->BSIM3oxideTrapDensityA;
|
||||
return(OK);
|
||||
|
|
|
|||
|
|
@ -39,15 +39,27 @@ GENmodel *inMod)
|
|||
mod->BSIM3capMod = value->iValue;
|
||||
mod->BSIM3capModGiven = TRUE;
|
||||
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 :
|
||||
mod->BSIM3noiMod = value->iValue;
|
||||
mod->BSIM3noiModGiven = TRUE;
|
||||
break;
|
||||
case BSIM3_MOD_NQSMOD :
|
||||
mod->BSIM3nqsMod = value->iValue;
|
||||
mod->BSIM3nqsModGiven = TRUE;
|
||||
break;
|
||||
case BSIM3_MOD_ACNQSMOD :
|
||||
mod->BSIM3acnqsMod = value->iValue;
|
||||
mod->BSIM3acnqsModGiven = TRUE;
|
||||
break;
|
||||
case BSIM3_MOD_VERSION :
|
||||
case BSIM3_MOD_VERSION :
|
||||
mod->BSIM3version = value->sValue;
|
||||
mod->BSIM3versionGiven = TRUE;
|
||||
break;
|
||||
|
|
@ -123,14 +135,14 @@ GENmodel *inMod)
|
|||
case BSIM3_MOD_NPEAK:
|
||||
mod->BSIM3npeak = value->rValue;
|
||||
mod->BSIM3npeakGiven = TRUE;
|
||||
if (mod->BSIM3npeak > 1.0e20)
|
||||
mod->BSIM3npeak *= 1.0e-6;
|
||||
if (mod->BSIM3npeak > 1.0e20)
|
||||
mod->BSIM3npeak *= 1.0e-6;
|
||||
break;
|
||||
case BSIM3_MOD_NGATE:
|
||||
mod->BSIM3ngate = value->rValue;
|
||||
mod->BSIM3ngateGiven = TRUE;
|
||||
if (mod->BSIM3ngate > 1.0e23)
|
||||
mod->BSIM3ngate *= 1.0e-6;
|
||||
if (mod->BSIM3ngate > 1.0e23)
|
||||
mod->BSIM3ngate *= 1.0e-6;
|
||||
break;
|
||||
case BSIM3_MOD_GAMMA1:
|
||||
mod->BSIM3gamma1 = value->rValue;
|
||||
|
|
@ -438,7 +450,41 @@ GENmodel *inMod)
|
|||
mod->BSIM3tpbswgGiven = TRUE;
|
||||
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 :
|
||||
mod->BSIM3lcdsc = value->rValue;
|
||||
mod->BSIM3lcdscGiven = TRUE;
|
||||
|
|
@ -502,14 +548,14 @@ GENmodel *inMod)
|
|||
case BSIM3_MOD_LNPEAK:
|
||||
mod->BSIM3lnpeak = value->rValue;
|
||||
mod->BSIM3lnpeakGiven = TRUE;
|
||||
if (mod->BSIM3lnpeak > 1.0e20)
|
||||
mod->BSIM3lnpeak *= 1.0e-6;
|
||||
if (mod->BSIM3lnpeak > 1.0e20)
|
||||
mod->BSIM3lnpeak *= 1.0e-6;
|
||||
break;
|
||||
case BSIM3_MOD_LNGATE:
|
||||
mod->BSIM3lngate = value->rValue;
|
||||
mod->BSIM3lngateGiven = TRUE;
|
||||
if (mod->BSIM3lngate > 1.0e23)
|
||||
mod->BSIM3lngate *= 1.0e-6;
|
||||
if (mod->BSIM3lngate > 1.0e23)
|
||||
mod->BSIM3lngate *= 1.0e-6;
|
||||
break;
|
||||
case BSIM3_MOD_LGAMMA1:
|
||||
mod->BSIM3lgamma1 = value->rValue;
|
||||
|
|
@ -781,7 +827,7 @@ GENmodel *inMod)
|
|||
mod->BSIM3lvoffcvGiven = TRUE;
|
||||
break;
|
||||
|
||||
/* Width dependence */
|
||||
/* Width dependence */
|
||||
case BSIM3_MOD_WCDSC :
|
||||
mod->BSIM3wcdsc = value->rValue;
|
||||
mod->BSIM3wcdscGiven = TRUE;
|
||||
|
|
@ -845,14 +891,14 @@ GENmodel *inMod)
|
|||
case BSIM3_MOD_WNPEAK:
|
||||
mod->BSIM3wnpeak = value->rValue;
|
||||
mod->BSIM3wnpeakGiven = TRUE;
|
||||
if (mod->BSIM3wnpeak > 1.0e20)
|
||||
mod->BSIM3wnpeak *= 1.0e-6;
|
||||
if (mod->BSIM3wnpeak > 1.0e20)
|
||||
mod->BSIM3wnpeak *= 1.0e-6;
|
||||
break;
|
||||
case BSIM3_MOD_WNGATE:
|
||||
mod->BSIM3wngate = value->rValue;
|
||||
mod->BSIM3wngateGiven = TRUE;
|
||||
if (mod->BSIM3wngate > 1.0e23)
|
||||
mod->BSIM3wngate *= 1.0e-6;
|
||||
if (mod->BSIM3wngate > 1.0e23)
|
||||
mod->BSIM3wngate *= 1.0e-6;
|
||||
break;
|
||||
case BSIM3_MOD_WGAMMA1:
|
||||
mod->BSIM3wgamma1 = value->rValue;
|
||||
|
|
@ -1124,7 +1170,7 @@ GENmodel *inMod)
|
|||
mod->BSIM3wvoffcvGiven = TRUE;
|
||||
break;
|
||||
|
||||
/* Cross-term dependence */
|
||||
/* Cross-term dependence */
|
||||
case BSIM3_MOD_PCDSC :
|
||||
mod->BSIM3pcdsc = value->rValue;
|
||||
mod->BSIM3pcdscGiven = TRUE;
|
||||
|
|
@ -1188,14 +1234,14 @@ GENmodel *inMod)
|
|||
case BSIM3_MOD_PNPEAK:
|
||||
mod->BSIM3pnpeak = value->rValue;
|
||||
mod->BSIM3pnpeakGiven = TRUE;
|
||||
if (mod->BSIM3pnpeak > 1.0e20)
|
||||
mod->BSIM3pnpeak *= 1.0e-6;
|
||||
if (mod->BSIM3pnpeak > 1.0e20)
|
||||
mod->BSIM3pnpeak *= 1.0e-6;
|
||||
break;
|
||||
case BSIM3_MOD_PNGATE:
|
||||
mod->BSIM3pngate = value->rValue;
|
||||
mod->BSIM3pngateGiven = TRUE;
|
||||
if (mod->BSIM3pngate > 1.0e23)
|
||||
mod->BSIM3pngate *= 1.0e-6;
|
||||
if (mod->BSIM3pngate > 1.0e23)
|
||||
mod->BSIM3pngate *= 1.0e-6;
|
||||
break;
|
||||
case BSIM3_MOD_PGAMMA1:
|
||||
mod->BSIM3pgamma1 = value->rValue;
|
||||
|
|
@ -1636,6 +1682,15 @@ GENmodel *inMod)
|
|||
mod->BSIM3WmaxGiven = TRUE;
|
||||
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 :
|
||||
mod->BSIM3oxideTrapDensityA = value->rValue;
|
||||
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))
|
||||
scale = 1;
|
||||
|
||||
switch(param)
|
||||
switch(param)
|
||||
{ case BSIM3_W:
|
||||
here->BSIM3w = value->rValue*scale;
|
||||
here->BSIM3wGiven = TRUE;
|
||||
|
|
@ -40,10 +40,10 @@ IFvalue *select)
|
|||
here->BSIM3l = value->rValue*scale;
|
||||
here->BSIM3lGiven = TRUE;
|
||||
break;
|
||||
case BSIM3_M:
|
||||
here->BSIM3m = value->rValue;
|
||||
here->BSIM3mGiven = TRUE;
|
||||
break;
|
||||
case BSIM3_M:
|
||||
here->BSIM3m = value->rValue;
|
||||
here->BSIM3mGiven = TRUE;
|
||||
break;
|
||||
case BSIM3_AS:
|
||||
here->BSIM3sourceArea = value->rValue*scale*scale;
|
||||
here->BSIM3sourceAreaGiven = TRUE;
|
||||
|
|
@ -91,6 +91,18 @@ IFvalue *select)
|
|||
here->BSIM3acnqsMod = value->iValue;
|
||||
here->BSIM3acnqsModGiven = TRUE;
|
||||
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:
|
||||
switch(value->v.numValue){
|
||||
case 3:
|
||||
|
|
|
|||
|
|
@ -61,8 +61,18 @@ BSIM3instance **InstArray;
|
|||
model->BSIM3paramChk = 0;
|
||||
if (!model->BSIM3capModGiven)
|
||||
model->BSIM3capMod = 3;
|
||||
if (!model->BSIM3acmModGiven)
|
||||
model->BSIM3acmMod = 0;
|
||||
if (!model->BSIM3calcacmGiven)
|
||||
model->BSIM3calcacm = 0;
|
||||
if (!model->BSIM3noiModGiven)
|
||||
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)
|
||||
model->BSIM3acnqsMod = 0;
|
||||
else if ((model->BSIM3acnqsMod != 0) && (model->BSIM3acnqsMod != 1))
|
||||
|
|
@ -247,6 +257,24 @@ BSIM3instance **InstArray;
|
|||
if (!model->BSIM3tpbswgGiven)
|
||||
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 */
|
||||
if (!model->BSIM3lcdscGiven)
|
||||
model->BSIM3lcdsc = 0.0;
|
||||
|
|
@ -780,6 +808,12 @@ BSIM3instance **InstArray;
|
|||
model->BSIM3dwc = model->BSIM3Wint;
|
||||
if (!model->BSIM3dlcGiven)
|
||||
model->BSIM3dlc = model->BSIM3Lint;
|
||||
|
||||
if (!model->BSIM3xlGiven)
|
||||
model->BSIM3xl = 0.0;
|
||||
if (!model->BSIM3xwGiven)
|
||||
model->BSIM3xw = 0.0;
|
||||
|
||||
if (!model->BSIM3cfGiven)
|
||||
model->BSIM3cf = 2.0 * EPSOX / PI
|
||||
* log(1.0 + 0.4e-6 / model->BSIM3tox);
|
||||
|
|
@ -874,7 +908,16 @@ BSIM3instance **InstArray;
|
|||
if (!here->BSIM3drainPerimeterGiven)
|
||||
here->BSIM3drainPerimeter = 0.0;
|
||||
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)
|
||||
here->BSIM3icVBS = 0.0;
|
||||
if (!here->BSIM3icVDSGiven)
|
||||
|
|
@ -888,11 +931,21 @@ BSIM3instance **InstArray;
|
|||
if (!here->BSIM3sourcePerimeterGiven)
|
||||
here->BSIM3sourcePerimeter = 0.0;
|
||||
if (!here->BSIM3sourceSquaresGiven)
|
||||
here->BSIM3sourceSquares = 1.0;
|
||||
{
|
||||
if (model->BSIM3acmMod == 0)
|
||||
here->BSIM3sourceSquares = 1.0;
|
||||
else
|
||||
here->BSIM3sourceSquares = 0.0;
|
||||
}
|
||||
if (!here->BSIM3wGiven)
|
||||
here->BSIM3w = 5.0e-6;
|
||||
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)
|
||||
here->BSIM3acnqsMod = model->BSIM3acnqsMod;
|
||||
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",
|
||||
model->BSIM3acnqsMod);
|
||||
}
|
||||
|
||||
if (!here->BSIM3geoGiven)
|
||||
here->BSIM3geo = 0;
|
||||
|
||||
if (!here->BSIM3mGiven)
|
||||
here->BSIM3m = 1;
|
||||
|
||||
/* process drain series resistance */
|
||||
if ((model->BSIM3sheetResistance > 0.0) &&
|
||||
(here->BSIM3drainSquares > 0.0 ))
|
||||
if ( ((model->BSIM3sheetResistance > 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) {
|
||||
error = CKTmkVolt(ckt,&tmp,here->BSIM3name,"drain");
|
||||
|
|
@ -928,8 +986,12 @@ BSIM3instance **InstArray;
|
|||
}
|
||||
|
||||
/* process source series resistance */
|
||||
if ((model->BSIM3sheetResistance > 0.0) &&
|
||||
(here->BSIM3sourceSquares > 0.0 ))
|
||||
if ( ((model->BSIM3sheetResistance > 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) {
|
||||
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 */
|
||||
#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);\
|
||||
}
|
||||
} } while(0)
|
||||
|
||||
TSTALLOC(BSIM3DdPtr, BSIM3dNode, BSIM3dNode)
|
||||
TSTALLOC(BSIM3GgPtr, BSIM3gNode, BSIM3gNode)
|
||||
TSTALLOC(BSIM3SsPtr, BSIM3sNode, BSIM3sNode)
|
||||
TSTALLOC(BSIM3BbPtr, BSIM3bNode, BSIM3bNode)
|
||||
TSTALLOC(BSIM3DPdpPtr, BSIM3dNodePrime, BSIM3dNodePrime)
|
||||
TSTALLOC(BSIM3SPspPtr, BSIM3sNodePrime, BSIM3sNodePrime)
|
||||
TSTALLOC(BSIM3DdpPtr, BSIM3dNode, BSIM3dNodePrime)
|
||||
TSTALLOC(BSIM3GbPtr, BSIM3gNode, BSIM3bNode)
|
||||
TSTALLOC(BSIM3GdpPtr, BSIM3gNode, BSIM3dNodePrime)
|
||||
TSTALLOC(BSIM3GspPtr, BSIM3gNode, BSIM3sNodePrime)
|
||||
TSTALLOC(BSIM3SspPtr, BSIM3sNode, BSIM3sNodePrime)
|
||||
TSTALLOC(BSIM3BdpPtr, BSIM3bNode, BSIM3dNodePrime)
|
||||
TSTALLOC(BSIM3BspPtr, BSIM3bNode, BSIM3sNodePrime)
|
||||
TSTALLOC(BSIM3DPspPtr, BSIM3dNodePrime, BSIM3sNodePrime)
|
||||
TSTALLOC(BSIM3DPdPtr, BSIM3dNodePrime, BSIM3dNode)
|
||||
TSTALLOC(BSIM3BgPtr, BSIM3bNode, BSIM3gNode)
|
||||
TSTALLOC(BSIM3DPgPtr, BSIM3dNodePrime, BSIM3gNode)
|
||||
TSTALLOC(BSIM3SPgPtr, BSIM3sNodePrime, BSIM3gNode)
|
||||
TSTALLOC(BSIM3SPsPtr, BSIM3sNodePrime, BSIM3sNode)
|
||||
TSTALLOC(BSIM3DPbPtr, BSIM3dNodePrime, BSIM3bNode)
|
||||
TSTALLOC(BSIM3SPbPtr, BSIM3sNodePrime, BSIM3bNode)
|
||||
TSTALLOC(BSIM3SPdpPtr, BSIM3sNodePrime, BSIM3dNodePrime)
|
||||
TSTALLOC(BSIM3DdPtr, BSIM3dNode, BSIM3dNode);
|
||||
TSTALLOC(BSIM3GgPtr, BSIM3gNode, BSIM3gNode);
|
||||
TSTALLOC(BSIM3SsPtr, BSIM3sNode, BSIM3sNode);
|
||||
TSTALLOC(BSIM3BbPtr, BSIM3bNode, BSIM3bNode);
|
||||
TSTALLOC(BSIM3DPdpPtr, BSIM3dNodePrime, BSIM3dNodePrime);
|
||||
TSTALLOC(BSIM3SPspPtr, BSIM3sNodePrime, BSIM3sNodePrime);
|
||||
TSTALLOC(BSIM3DdpPtr, BSIM3dNode, BSIM3dNodePrime);
|
||||
TSTALLOC(BSIM3GbPtr, BSIM3gNode, BSIM3bNode);
|
||||
TSTALLOC(BSIM3GdpPtr, BSIM3gNode, BSIM3dNodePrime);
|
||||
TSTALLOC(BSIM3GspPtr, BSIM3gNode, BSIM3sNodePrime);
|
||||
TSTALLOC(BSIM3SspPtr, BSIM3sNode, BSIM3sNodePrime);
|
||||
TSTALLOC(BSIM3BdpPtr, BSIM3bNode, BSIM3dNodePrime);
|
||||
TSTALLOC(BSIM3BspPtr, BSIM3bNode, BSIM3sNodePrime);
|
||||
TSTALLOC(BSIM3DPspPtr, BSIM3dNodePrime, BSIM3sNodePrime);
|
||||
TSTALLOC(BSIM3DPdPtr, BSIM3dNodePrime, BSIM3dNode);
|
||||
TSTALLOC(BSIM3BgPtr, BSIM3bNode, BSIM3gNode);
|
||||
TSTALLOC(BSIM3DPgPtr, BSIM3dNodePrime, BSIM3gNode);
|
||||
TSTALLOC(BSIM3SPgPtr, BSIM3sNodePrime, BSIM3gNode);
|
||||
TSTALLOC(BSIM3SPsPtr, BSIM3sNodePrime, BSIM3sNode);
|
||||
TSTALLOC(BSIM3DPbPtr, BSIM3dNodePrime, BSIM3bNode);
|
||||
TSTALLOC(BSIM3SPbPtr, BSIM3sNodePrime, BSIM3bNode);
|
||||
TSTALLOC(BSIM3SPdpPtr, BSIM3sNodePrime, BSIM3dNodePrime);
|
||||
|
||||
TSTALLOC(BSIM3QqPtr, BSIM3qNode, BSIM3qNode)
|
||||
TSTALLOC(BSIM3QqPtr, BSIM3qNode, BSIM3qNode);
|
||||
|
||||
TSTALLOC(BSIM3QdpPtr, BSIM3qNode, BSIM3dNodePrime)
|
||||
TSTALLOC(BSIM3QspPtr, BSIM3qNode, BSIM3sNodePrime)
|
||||
TSTALLOC(BSIM3QgPtr, BSIM3qNode, BSIM3gNode)
|
||||
TSTALLOC(BSIM3QbPtr, BSIM3qNode, BSIM3bNode)
|
||||
TSTALLOC(BSIM3DPqPtr, BSIM3dNodePrime, BSIM3qNode)
|
||||
TSTALLOC(BSIM3SPqPtr, BSIM3sNodePrime, BSIM3qNode)
|
||||
TSTALLOC(BSIM3GqPtr, BSIM3gNode, BSIM3qNode)
|
||||
TSTALLOC(BSIM3BqPtr, BSIM3bNode, BSIM3qNode)
|
||||
TSTALLOC(BSIM3QdpPtr, BSIM3qNode, BSIM3dNodePrime);
|
||||
TSTALLOC(BSIM3QspPtr, BSIM3qNode, BSIM3sNodePrime);
|
||||
TSTALLOC(BSIM3QgPtr, BSIM3qNode, BSIM3gNode);
|
||||
TSTALLOC(BSIM3QbPtr, BSIM3qNode, BSIM3bNode);
|
||||
TSTALLOC(BSIM3DPqPtr, BSIM3dNodePrime, BSIM3qNode);
|
||||
TSTALLOC(BSIM3SPqPtr, BSIM3sNodePrime, BSIM3qNode);
|
||||
TSTALLOC(BSIM3GqPtr, BSIM3gNode, 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