simd version of BSIM3

This commit is contained in:
Florian Ballenegger 2020-08-06 23:18:07 +02:00
parent 0f6f1d1556
commit a15f9a1eba
44 changed files with 23026 additions and 31 deletions

View File

@ -1304,6 +1304,7 @@ fi
if test "x$enable_modsimd" = xyes; then
AC_DEFINE([BSIM3v32SIMD], [1], [simd acceleration for BSIM3V32 device])
AC_DEFINE([MODSIMD], [1], [simd acceleration for some device models])
if test "x$have_intrinsics" = xyes; then
AC_DEFINE([USEX86INTRINSICS], [1], [can use x86 simd intrinsics])
@ -1344,6 +1345,7 @@ AC_CONFIG_FILES([Makefile
src/spicelib/devices/bsim1/Makefile
src/spicelib/devices/bsim2/Makefile
src/spicelib/devices/bsim3/Makefile
src/spicelib/devices/bsim3simd/Makefile
src/spicelib/devices/bsim3v0/Makefile
src/spicelib/devices/bsim3v1/Makefile
src/spicelib/devices/bsim3v32/Makefile
@ -1415,6 +1417,7 @@ AC_CONFIG_FILES([Makefile
src/maths/fft/Makefile
src/maths/misc/Makefile
src/maths/ni/Makefile
src/maths/ni/SIMD/Makefile
src/maths/deriv/Makefile
src/maths/poly/Makefile
src/maths/sparse/Makefile

View File

@ -58,8 +58,8 @@ X1 1 2 3 4 5 6 7 8 9 10 11 12 0 13 99 FOURBIT
.save V(1) V(2) V(3) V(4) V(5) V(6) V(7) V(8)
* use BSIM3 model with default parameters
.model n1 nmos level=49 version=3.2.4simd
.model p1 pmos level=49 version=3.2.4simd
.model n1 nmos level=49 version=3.3.0
.model p1 pmos level=49 version=3.3.0
*.include ./Modelcards/modelcard32.nmos
*.include ./Modelcards/modelcard32.pmos

View File

@ -135,7 +135,8 @@ ngspice_LDADD += spicelib/devices/ndev/libndev.la
endif
if WANT_MODSIMD
ngspice_LDADD += spicelib/devices/bsim3v32simd/libbsim3v32simd.la
ngspice_LDADD += spicelib/devices/bsim3v32simd/libbsim3v32simd.la \
spicelib/devices/bsim3simd/libbsim3simd.la
endif
if NUMDEV_WANTED
@ -153,7 +154,8 @@ ngspice_LDADD += \
if WANT_MODSIMD
ngspice_LDADD += \
spicelib/analysis/SIMD/libcktsimd.la
spicelib/analysis/SIMD/libcktsimd.la \
maths/ni/SIMD/libnisimd.la
endif
if SENSE2_WANTED
@ -424,7 +426,8 @@ endif
if WANT_MODSIMD
libspice_la_LIBADD += \
spicelib/devices/bsim3v32simd/libbsim3v32simd.la
spicelib/devices/bsim3v32simd/libbsim3v32simd.la \
spicelib/devices/bsim3simd/libbsim3simd.la
endif
if NUMDEV_WANTED
@ -442,7 +445,8 @@ libspice_la_LIBADD += \
if WANT_MODSIMD
libspice_la_LIBADD += \
spicelib/analysis/SIMD/libcktsimd.la
spicelib/analysis/SIMD/libcktsimd.la \
maths/ni/SIMD/libnisimd.la
endif
if XSPICE_WANTED
@ -549,7 +553,8 @@ endif
if WANT_MODSIMD
libngspice_la_LIBADD += \
spicelib/devices/bsim3v32simd/libbsim3v32simd.la
spicelib/devices/bsim3v32simd/libbsim3v32simd.la \
spicelib/devices/bsim3simd/libbsim3simd.la
endif
if NUMDEV_WANTED
@ -567,7 +572,8 @@ libngspice_la_LIBADD += \
if WANT_MODSIMD
libngspice_la_LIBADD += \
spicelib/analysis/SIMD/libcktsimd.la
spicelib/analysis/SIMD/libcktsimd.la \
maths/ni/SIMD/libnisimd.la
endif
if XSPICE_WANTED

View File

@ -0,0 +1,9 @@
#ifndef NG_SIMD_NIINTEG_H
#define NG_SIMD_NIINTEG_H
#include "ngspice/SIMD/simdvector.h"
int
vecN_NIintegrate(CKTcircuit *ckt, double *geq, double *ceq, double cap, VecNm qcap);
#endif

View File

@ -33,9 +33,28 @@
#include "ngspice/SIMD/simdvector.h"
/* first include vector functions specialized for specific NSIMD */
#if NSIMD==4
#include "ngspice/SIMD/simdop4.h"
#endif /* NSIMD==4 */
#if NSIMD==8
#include "ngspice/SIMD/simdop8.h"
#endif /* NSIMD==8 */
#if NSIMD==2
#include "ngspice/SIMD/simdop2.h"
#endif /* NSIMD==2 */
/* now define missing vector functions in a generic manner */
inline VecNd vecN_broadcast(double x)
{
VecNd res;
#ifdef USE_OMPSIMD
#pragma omp simd simdlen(NSIMD)
#endif
for(int i=0;i<NSIMD;i++)
res[i]=x;
return res;
@ -44,61 +63,200 @@ inline VecNd vecN_broadcast(double x)
inline VecNd vecN_lu(double* array, VecNi indexes)
{
VecNd res;
#ifdef USE_OMPSIMD
#pragma omp simd simdlen(NSIMD)
#endif
for(int i=0;i<NSIMD;i++)
res[i]=array[indexes[i]];
return res;
}
#ifndef vecN_MAX
inline VecNd vecN_MAX(VecNd a, VecNd b)
{
VecNd res;
#ifdef USE_OMPSIMD
#pragma omp simd simdlen(NSIMD)
#endif
for(int i=0;i<NSIMD;i++)
res[i]=(a[i] > b[i]) ? a[i] : b[i];
return res;
}
#endif
#ifndef vecN_fabs
inline VecNd vecN_fabs(VecNd x)
{
VecNd res;
#ifdef USE_OMPSIMD
#pragma omp simd simdlen(NSIMD)
#endif
for(int i=0;i<NSIMD;i++)
res[i]=fabs(x[i]);
return res;
}
#endif
#ifndef vecN_sqrt
inline VecNd vecN_sqrt(VecNd x)
{
VecNd res;
#ifdef USE_OMPSIMD
#pragma omp simd simdlen(NSIMD)
#endif
for(int i=0;i<NSIMD;i++)
res[i]=sqrt(x[i]);
return res;
}
#endif
#ifndef vecN_pow
inline VecNd vecN_pow(VecNd x, double p)
{
VecNd res;
#ifdef USE_OMPSIMD
#pragma omp simd simdlen(NSIMD)
#endif
for(int i=0;i<NSIMD;i++)
res[i]=log(x[i]);
res = res*p;
#ifdef USE_OMPSIMD
#pragma omp simd simdlen(NSIMD)
#endif
for(int i=0;i<NSIMD;i++)
res[i]=exp(res[i]);
return res;
}
#endif
#ifndef vecN_exp
inline VecNd vecN_exp(VecNd x)
{
VecNd res;
#ifdef USE_OMPSIMD
#pragma omp simd simdlen(NSIMD)
#endif
for(int i=0;i<NSIMD;i++)
res[i]=exp(x[i]);
return res;
}
#endif
#ifndef vecN_log
inline VecNd vecN_log(VecNd x)
{
VecNd res;
#ifdef USE_OMPSIMD
#pragma omp simd simdlen(NSIMD)
#endif
for(int i=0;i<NSIMD;i++)
res[i]=log(x[i]);
return res;
}
#endif
#ifndef vecN_blend
static inline VecNd vecN_blend(VecNd fa, VecNd tr, VecNm mask)
{
VecNd r;
#ifdef USE_OMPSIMD
#pragma omp simd simdlen(NSIMD)
#endif
for(int i=0;i<NSIMD;i++)
r[i] = (mask[i]==0 ? fa[i] : tr[i]);
return r;
}
#endif
#ifndef vecN_SIMDTOVECTOR
static inline VecNd vecN_SIMDTOVECTOR(double val)
{
VecNd r;
#ifdef USE_OMPSIMD
#pragma omp simd simdlen(NSIMD)
#endif
for(int i=0;i<NSIMD;i++)
r[i] = val;
return r;
}
#endif
#ifndef vecN_SIMDTOVECTORMASK
static inline VecNm vecN_SIMDTOVECTORMASK(int val)
{
VecNm r;
#ifdef USE_OMPSIMD
#pragma omp simd simdlen(NSIMD)
#endif
for(int i=0;i<NSIMD;i++)
r[i] = val;
return r;
}
#endif
#ifndef vecN_StateAccess
static inline VecNd vecN_StateAccess(double* cktstate, VecNm stateindexes)
{
VecNd r;
#ifdef USE_OMPSIMD
#pragma omp simd simdlen(NSIMD)
#endif
for(int i=0;i<NSIMD;i++)
r[i] = cktstate[stateindexes[i]];
return r;
}
#endif
#ifndef vecN_SIMDCOUNT
static inline int vecN_SIMDCOUNT(VecNm mask) {
int count=0;
#ifdef USE_OMPSIMD
#pragma omp simd simdlen(NSIMD) reduction(+:count)
#endif
for(int i=0;i<NSIMD;i++)
if(mask[i])
count++;
return count;
}
#endif
#ifndef vecN_StateStore
static inline void vecN_StateStore(double* cktstate, VecNm stateindexes, VecNd values)
{
#ifdef USE_OMPSIMD
#pragma omp simd simdlen(NSIMD)
#endif
for(int idx=0;idx<NSIMD;idx++)
{
cktstate[stateindexes[idx]] = values[idx];
}
}
#endif
#ifndef vecN_StateAdd
static inline void vecN_StateAdd(double* cktstate, VecNm stateindexes, VecNd values)
{
#ifdef USE_OMPSIMD
#pragma omp simd simdlen(NSIMD)
#endif
for(int idx=0;idx<NSIMD;idx++)
{
cktstate[stateindexes[idx]] += values[idx];
}
}
#endif
#ifndef vecN_StateSub
static inline void vecN_StateSub(double* cktstate, VecNm stateindexes, VecNd values)
{
#ifdef USE_OMPSIMD
#pragma omp simd simdlen(NSIMD)
#endif
for(int idx=0;idx<NSIMD;idx++)
{
cktstate[stateindexes[idx]] -= values[idx];
}
}
#endif
#endif /* NG_SIMD_OP_H */

View File

@ -0,0 +1,120 @@
/*******************************************************************************
* Copyright 2020 Florian Ballenegger, Anamosic Ballenegger Design
*******************************************************************************
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
#if USEX86INTRINSICS==1
#include <x86intrin.h>
#define vec4_MAX(a,b) _mm256_max_pd(a,b)
#define vecN_MAX vec4_MAX
#define vec4_sqrt(a) _mm256_sqrt_pd(a)
#define vecN_sqrt vec4_sqrt
static inline Vec4d vec4_blend(Vec4d fa, Vec4d tr, Vec4m mask)
{
return _mm256_blendv_pd(fa,tr, (Vec4d) mask);
}
#define vecN_blend vec4_blend
#else
#define vec4_blend vecN_blend
#endif
#ifdef HAVE_LIBSLEEF
#include <sleef.h>
#define vec4_exp(a) Sleef_expd4_u10(a)
#define vecN_exp vec4_exp
#define vec4_log(a) Sleef_logd4_u35(a)
#define vecN_log vec4_log
#ifndef USEX86INTRINSICS
#define vec4_MAX(a,b) Sleef_fmaxd4(a,b)
#define vecN_MAX vec4_MAX
#define vec4_sqrt(a) Sleef_sqrtd4_u35(a)
#define vecN_sqrt vec4_sqrt
#endif
#define vec4_fabs(a) Sleef_fabsd4(a)
#define vecN_fabs vec4_fabs
#define vec4_pow(a,b) Sleef_powd4_u10(a,vec4_SIMDTOVECTOR(b))
#define vecN_pow vec4_pow
#else
#ifdef HAS_LIBMVEC
Vec4d _ZGVdN4v_exp(Vec4d);
Vec4d _ZGVdN4v_log(Vec4d);
Vec4d _ZGVdN4vv_pow(Vec4d, Vec4d);
#define vec4_exp(a) _ZGVdN4v_exp(a)
#define vecN_exp vec4_exp
#define vec4_log(a) _ZGVdN4v_log(a)
#define vecN_log vec4_log
#define vec4_pow(a,b) _ZGVdN4vv_pow(a,b)
#define vecN_pow vec4_pow
#define vec4_fabs vecN_fabs
#endif /* HAS_LIBMVEC */
#endif /* not HAVE_LIBSLEEF */
#ifdef USE_SERIAL_FORM
#define vec4_SIMDTOVECTOR vecN_SIMDTOVECTOR
#define vec4_SIMDTOVECTORMASK vecN_SIMDTOVECTORMASK
#define vec4_StateAccess vecN_StateAccess
#define vec4_SIMDCOUNT vecN_SIMDCOUNT
#else
static inline Vec4d vec4_SIMDTOVECTOR(double val)
{
return (Vec4d) {val,val,val,val};
}
static inline Vec4m vec4_SIMDTOVECTORMASK(int val)
{
return (Vec4m) {val,val,val,val};
}
static inline Vec4d vec4_StateAccess(double* cktstate, Vec4m stateindexes)
{
return (Vec4d) {
cktstate[stateindexes[0]],
cktstate[stateindexes[1]],
cktstate[stateindexes[2]],
cktstate[stateindexes[3]]
};
}
static inline int vec4_SIMDCOUNT(Vec4m mask) {
return (mask[0] ? 1 : 0) + (mask[1] ? 1 : 0) + (mask[2] ? 1 : 0) + (mask[3] ? 1 : 0);
}
#define vecN_SIMDTOVECTOR vec4_SIMDTOVECTOR
#define vecN_SIMDTOVECTORMASK vec4_SIMDTOVECTORMASK
#define vecN_StateAccess vec4_StateAccess
#define vecN_SIMDCOUNT vec4_SIMDCOUNT
#endif
#define vec4_StateStore vecN_StateStore
#define vec4_StateAdd vecN_StateAdd
#define vec4_StateSub vecN_StateSub

View File

@ -1,5 +1,10 @@
## Process this file with automake to produce Makefile.in
DIST_SUBDIRS = SIMD
if WANT_MODSIMD
SUBDIRS = SIMD
endif
noinst_LTLIBRARIES = libni.la
libni_la_SOURCES = \

View File

@ -0,0 +1,10 @@
## Process this file with automake to produce Makefile.in
noinst_LTLIBRARIES = libnisimd.la
libnisimd_la_SOURCES = \
simdniinteg.c
AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(top_srcdir)/src/include -I$(top_srcdir)/src/spicelib/devices
AM_CFLAGS = $(STATIC) $(SIMD_CFLAGS)
MAINTAINERCLEANFILES = Makefile.in

View File

@ -0,0 +1,88 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/**********
SIMD version:
Copyright 2020 Anamosic Ballenegger Design.
Author: 2020 Florian Ballenegger
**********/
#include "ngspice/ngspice.h"
#include "ngspice/cktdefs.h"
#include "ngspice/sperror.h"
#include "ngspice/SIMD/simdniinteg.h"
#include "ngspice/SIMD/simdop.h"
int
vecN_NIintegrate(CKTcircuit *ckt, double *geq, double *ceq, double cap, VecNm qcap)
{
static char *ordmsg = "Illegal integration order";
static char *methodmsg = "Unknown integration method";
VecNm ccap = qcap + 1;
switch(ckt->CKTintegrateMethod) {
case TRAPEZOIDAL:
switch(ckt->CKTorder) {
case 1:
vecN_StateStore(ckt->CKTstate0, ccap, ckt->CKTag[0] * vecN_StateAccess(ckt->CKTstate0,qcap)
+ ckt->CKTag[1] * vecN_StateAccess(ckt->CKTstate1,qcap));
break;
case 2:
vecN_StateStore(ckt->CKTstate0, ccap, - vecN_StateAccess(ckt->CKTstate1,ccap) * ckt->CKTag[1] +
ckt->CKTag[0] *
( vecN_StateAccess(ckt->CKTstate0,qcap) - vecN_StateAccess(ckt->CKTstate1,qcap) ) );
break;
default:
errMsg = TMALLOC(char, strlen(ordmsg) + 1);
strcpy(errMsg,ordmsg);
return(E_ORDER);
}
break;
case GEAR:
{
VecNd nstateccap = vecN_SIMDTOVECTOR(0);
switch(ckt->CKTorder) {
case 6:
nstateccap += ckt->CKTag[6]* vecN_StateAccess(ckt->CKTstate6,qcap);
/* fall through */
case 5:
nstateccap += ckt->CKTag[5]* vecN_StateAccess(ckt->CKTstate5,qcap);
/* fall through */
case 4:
nstateccap += ckt->CKTag[4]* vecN_StateAccess(ckt->CKTstate4,qcap);
/* fall through */
case 3:
nstateccap += ckt->CKTag[3]* vecN_StateAccess(ckt->CKTstate3,qcap);
/* fall through */
case 2:
nstateccap += ckt->CKTag[2]* vecN_StateAccess(ckt->CKTstate2,qcap);
/* fall through */
case 1:
nstateccap += ckt->CKTag[1]* vecN_StateAccess(ckt->CKTstate1,qcap);
nstateccap += ckt->CKTag[0]* vecN_StateAccess(ckt->CKTstate0,qcap);
break;
default:
return(E_ORDER);
}
vecN_StateStore(ckt->CKTstate0,ccap,nstateccap);
}
break;
default:
errMsg = TMALLOC(char, strlen(methodmsg) + 1);
strcpy(errMsg,methodmsg);
return(E_METHOD);
}
/* not used
*ceq = ckt->CKTstate0[ccap] - ckt->CKTag[0] * ckt->CKTstate0[qcap];
*geq = ckt->CKTag[0] * cap;
*/
return(OK);
}

View File

@ -62,7 +62,8 @@ SUBDIRS += nbjt nbjt2 numd numd2 numos
endif
if WANT_MODSIMD
SUBDIRS += bsim3v32simd
SUBDIRS += bsim3v32simd \
bsim3simd
endif
DIST_SUBDIRS = \
@ -71,6 +72,7 @@ DIST_SUBDIRS = \
bsim1 \
bsim2 \
bsim3 \
bsim3simd \
bsimsoi \
bsim4 \
bsim4v5 \

View File

@ -0,0 +1,30 @@
The terms under which the software is provided are as the following.
Software is distributed as is, completely without warranty or service
support. The University of California and its employees are not liable
for the condition or performance of the software.
The University owns the copyright but shall not be liable for any
infringement of copyright or other proprietary rights brought by third
parties against the users of the software.
The University of California hereby disclaims all implied warranties.
The University of California grants the users the right to modify, copy,
and redistribute the software and documentation, both within the user's
organization and externally, subject to the following restrictions:
1. The users agree not to charge for the University of California code
itself but may charge for additions, extensions, or support.
2. In any product based on the software, the users agree to acknowledge
the UC Berkeley BSIM Research Group that developed the software. This
acknowledgment shall appear in the product documentation.
3. The users agree to obey all U.S. Government restrictions governing
redistribution or export of the software.
4. The users agree to reproduce any copyright notice which appears on
the software on any copy or modification of such made available
to others.

View File

@ -0,0 +1,4 @@
1999-09-06 Arno Peters <A.W.Peters@ieee.org>
* b3ld.c: Removed unused variable.

View File

@ -0,0 +1,40 @@
## Process this file with automake to produce Makefile.in
noinst_LTLIBRARIES = libbsim3simd.la
libbsim3simd_la_SOURCES = \
b3.c \
b3acld.c \
b3ask.c \
b3check.c \
b3cvtest.c \
b3getic.c \
b3ld.c \
b3mask.c \
b3mdel.c \
b3mpar.c \
b3noi.c \
b3par.c \
b3pzld.c \
b3set.c \
b3soachk.c \
b3temp.c \
b3trunc.c \
bsim3def.h \
bsim3ext.h \
bsim3init.c \
bsim3init.h \
bsim3itf.h \
b3ldseq.c \
b3ldsel.c \
b3ldsimd.c
AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(top_srcdir)/src/include
AM_CFLAGS = $(STATIC) $(SIMD_CFLAGS)
MAINTAINERCLEANFILES = Makefile.in
EXTRA_DIST = B3TERMS_OF_USE

View File

@ -0,0 +1,531 @@
/**** BSIM3v3.3.0 beta, Released by Xuemei Xi 07/29/2005 ****/
/**********
* Copyright 2004 Regents of the University of California. All rights reserved.
* File: b3.c of BSIM3v3.3.0
* Author: 1995 Min-Chie Jeng and Mansun Chan
* Author: 1997-1999 Weidong Liu.
* Author: 2001 Xuemei Xi
**********/
#include "ngspice/ngspice.h"
#include "ngspice/devdefs.h"
#include "bsim3def.h"
#include "ngspice/suffix.h"
IFparm BSIM3SIMDpTable[] = { /* parameters */
IOP( "l", BSIM3_L, IF_REAL , "Length"),
IOP( "w", BSIM3_W, IF_REAL , "Width"),
IOP( "m", BSIM3_M, IF_REAL , "Parallel multiplier"),
IOP( "ad", BSIM3_AD, IF_REAL , "Drain area"),
IOP( "as", BSIM3_AS, IF_REAL , "Source area"),
IOP( "pd", BSIM3_PD, IF_REAL , "Drain perimeter"),
IOP( "ps", BSIM3_PS, IF_REAL , "Source perimeter"),
IOP( "nrd", BSIM3_NRD, IF_REAL , "Number of squares in drain"),
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"),
};
IFparm BSIM3SIMDmPTable[] = { /* 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"),
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( "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( "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."),
IOP( "nsub", BSIM3_MOD_NSUB, IF_REAL, "Substrate doping concentration"),
IOP( "nch", BSIM3_MOD_NPEAK, IF_REAL, "Channel doping concentration"),
IOP( "ngate", BSIM3_MOD_NGATE, IF_REAL, "Poly-gate doping concentration"),
IOP( "gamma1", BSIM3_MOD_GAMMA1, IF_REAL, "Vth body coefficient"),
IOP( "gamma2", BSIM3_MOD_GAMMA2, IF_REAL, "Vth body coefficient"),
IOP( "vbx", BSIM3_MOD_VBX, IF_REAL, "Vth transition body Voltage"),
IOP( "vbm", BSIM3_MOD_VBM, IF_REAL, "Maximum body voltage"),
IOP( "xt", BSIM3_MOD_XT, IF_REAL, "Doping depth"),
IOP( "k1", BSIM3_MOD_K1, IF_REAL, "Bulk effect coefficient 1"),
IOP( "kt1", BSIM3_MOD_KT1, IF_REAL, "Temperature coefficient of Vth"),
IOP( "kt1l", BSIM3_MOD_KT1L, IF_REAL, "Temperature coefficient of Vth"),
IOP( "kt2", BSIM3_MOD_KT2, IF_REAL, "Body-coefficient of kt1"),
IOP( "k2", BSIM3_MOD_K2, IF_REAL, "Bulk effect coefficient 2"),
IOP( "k3", BSIM3_MOD_K3, IF_REAL, "Narrow width effect coefficient"),
IOP( "k3b", BSIM3_MOD_K3B, IF_REAL, "Body effect coefficient of k3"),
IOP( "w0", BSIM3_MOD_W0, IF_REAL, "Narrow width effect parameter"),
IOP( "nlx", BSIM3_MOD_NLX, IF_REAL, "Lateral non-uniform doping effect"),
IOP( "dvt0", BSIM3_MOD_DVT0, IF_REAL, "Short channel effect coeff. 0"),
IOP( "dvt1", BSIM3_MOD_DVT1, IF_REAL, "Short channel effect coeff. 1"),
IOP( "dvt2", BSIM3_MOD_DVT2, IF_REAL, "Short channel effect coeff. 2"),
IOP( "dvt0w", BSIM3_MOD_DVT0W, IF_REAL, "Narrow Width coeff. 0"),
IOP( "dvt1w", BSIM3_MOD_DVT1W, IF_REAL, "Narrow Width effect coeff. 1"),
IOP( "dvt2w", BSIM3_MOD_DVT2W, IF_REAL, "Narrow Width effect coeff. 2"),
IOP( "drout", BSIM3_MOD_DROUT, IF_REAL, "DIBL coefficient of output resistance"),
IOP( "dsub", BSIM3_MOD_DSUB, IF_REAL, "DIBL coefficient in the subthreshold region"),
IOP( "vth0", BSIM3_MOD_VTH0, IF_REAL,"Threshold voltage"),
IOPR("vtho", BSIM3_MOD_VTH0, IF_REAL,"Threshold voltage"),
IOP( "ua", BSIM3_MOD_UA, IF_REAL, "Linear gate dependence of mobility"),
IOP( "ua1", BSIM3_MOD_UA1, IF_REAL, "Temperature coefficient of ua"),
IOP( "ub", BSIM3_MOD_UB, IF_REAL, "Quadratic gate dependence of mobility"),
IOP( "ub1", BSIM3_MOD_UB1, IF_REAL, "Temperature coefficient of ub"),
IOP( "uc", BSIM3_MOD_UC, IF_REAL, "Body-bias dependence of mobility"),
IOP( "uc1", BSIM3_MOD_UC1, IF_REAL, "Temperature coefficient of uc"),
IOP( "u0", BSIM3_MOD_U0, IF_REAL, "Low-field mobility at Tnom"),
IOP( "ute", BSIM3_MOD_UTE, IF_REAL, "Temperature coefficient of mobility"),
IOP( "voff", BSIM3_MOD_VOFF, IF_REAL, "Threshold voltage offset"),
IOP( "tnom", BSIM3_MOD_TNOM, IF_REAL, "Parameter measurement temperature"),
IOP( "cgso", BSIM3_MOD_CGSO, IF_REAL, "Gate-source overlap capacitance per width"),
IOP( "cgdo", BSIM3_MOD_CGDO, IF_REAL, "Gate-drain overlap capacitance per width"),
IOP( "cgbo", BSIM3_MOD_CGBO, IF_REAL, "Gate-bulk overlap capacitance per length"),
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( "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( "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( "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"),
IOP( "nj", BSIM3_MOD_NJ, IF_REAL, "Source/drain junction emission coefficient"),
IOP( "xti", BSIM3_MOD_XTI, IF_REAL, "Junction current temperature exponent"),
IOP( "mj", BSIM3_MOD_MJ, IF_REAL, "Source/drain bottom junction capacitance grading coefficient"),
IOP( "pbsw", BSIM3_MOD_PBSW, IF_REAL, "Source/drain sidewall junction capacitance built in potential"),
IOP( "mjsw", BSIM3_MOD_MJSW, IF_REAL, "Source/drain sidewall junction capacitance grading coefficient"),
IOP( "pbswg", BSIM3_MOD_PBSWG, IF_REAL, "Source/drain (gate side) sidewall junction capacitance built in potential"),
IOP( "mjswg", BSIM3_MOD_MJSWG, IF_REAL, "Source/drain (gate side) sidewall junction capacitance grading coefficient"),
IOP( "cj", BSIM3_MOD_CJ, IF_REAL, "Source/drain bottom junction capacitance per unit area"),
IOP( "vfbcv", BSIM3_MOD_VFBCV, IF_REAL, "Flat Band Voltage parameter for capmod=0 only"),
IOP( "vfb", BSIM3_MOD_VFB, IF_REAL, "Flat Band Voltage"),
IOP( "cjsw", BSIM3_MOD_CJSW, IF_REAL, "Source/drain sidewall junction capacitance per unit periphery"),
IOP( "cjswg", BSIM3_MOD_CJSWG, IF_REAL, "Source/drain (gate side) sidewall junction capacitance per unit width"),
IOP( "tpb", BSIM3_MOD_TPB, IF_REAL, "Temperature coefficient of pb"),
IOP( "tcj", BSIM3_MOD_TCJ, IF_REAL, "Temperature coefficient of cj"),
IOP( "tpbsw", BSIM3_MOD_TPBSW, IF_REAL, "Temperature coefficient of pbsw"),
IOP( "tcjsw", BSIM3_MOD_TCJSW, IF_REAL, "Temperature coefficient of cjsw"),
IOP( "tpbswg", BSIM3_MOD_TPBSWG, IF_REAL, "Temperature coefficient of pbswg"),
IOP( "tcjswg", BSIM3_MOD_TCJSWG, IF_REAL, "Temperature coefficient of cjswg"),
IOP( "acde", BSIM3_MOD_ACDE, IF_REAL, "Exponential coefficient for finite charge thickness"),
IOP( "moin", BSIM3_MOD_MOIN, IF_REAL, "Coefficient for gate-bias dependent surface potential"),
IOP( "noff", BSIM3_MOD_NOFF, IF_REAL, "C-V turn-on/off parameter"),
IOP( "voffcv", BSIM3_MOD_VOFFCV, IF_REAL, "C-V lateral-shift parameter"),
IOP( "lintnoi", BSIM3_MOD_LINTNOI, IF_REAL, "lint offset for noise calculation"),
IOP( "lint", BSIM3_MOD_LINT, IF_REAL, "Length reduction parameter"),
IOP( "ll", BSIM3_MOD_LL, IF_REAL, "Length reduction parameter"),
IOP( "llc", BSIM3_MOD_LLC, IF_REAL, "Length reduction parameter for CV"),
IOP( "lln", BSIM3_MOD_LLN, IF_REAL, "Length reduction parameter"),
IOP( "lw", BSIM3_MOD_LW, IF_REAL, "Length reduction parameter"),
IOP( "lwc", BSIM3_MOD_LWC, IF_REAL, "Length reduction parameter for CV"),
IOP( "lwn", BSIM3_MOD_LWN, IF_REAL, "Length reduction parameter"),
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"),
IOP( "dwb", BSIM3_MOD_DWB, IF_REAL, "Width reduction parameter"),
IOP( "wl", BSIM3_MOD_WL, IF_REAL, "Width reduction parameter"),
IOP( "wlc", BSIM3_MOD_WLC, IF_REAL, "Width reduction parameter for CV"),
IOP( "wln", BSIM3_MOD_WLN, IF_REAL, "Width reduction parameter"),
IOP( "ww", BSIM3_MOD_WW, IF_REAL, "Width reduction parameter"),
IOP( "wwc", BSIM3_MOD_WWC, IF_REAL, "Width reduction parameter for CV"),
IOP( "wwn", BSIM3_MOD_WWN, IF_REAL, "Width reduction parameter"),
IOP( "wwl", BSIM3_MOD_WWL, IF_REAL, "Width reduction parameter"),
IOP( "wwlc", BSIM3_MOD_WWLC, IF_REAL, "Width reduction parameter for CV"),
IOP( "wmin", BSIM3_MOD_WMIN, IF_REAL, "Minimum width for the model"),
IOP( "wmax", BSIM3_MOD_WMAX, IF_REAL, "Maximum width for the model"),
IOP( "b0", BSIM3_MOD_B0, IF_REAL, "Abulk narrow width parameter"),
IOP( "b1", BSIM3_MOD_B1, IF_REAL, "Abulk narrow width parameter"),
IOP( "cgsl", BSIM3_MOD_CGSL, IF_REAL, "New C-V model parameter"),
IOP( "cgdl", BSIM3_MOD_CGDL, IF_REAL, "New C-V model parameter"),
IOP( "ckappa", BSIM3_MOD_CKAPPA, IF_REAL, "New C-V model parameter"),
IOP( "cf", BSIM3_MOD_CF, IF_REAL, "Fringe capacitance parameter"),
IOP( "clc", BSIM3_MOD_CLC, IF_REAL, "Vdsat parameter for C-V model"),
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"),
IOP( "ijth", BSIM3_MOD_IJTH, IF_REAL, "Diode limiting current"),
IOP( "lcdsc", BSIM3_MOD_LCDSC, IF_REAL, "Length dependence of cdsc"),
IOP( "lcdscb", BSIM3_MOD_LCDSCB, IF_REAL, "Length dependence of cdscb"),
IOP( "lcdscd", BSIM3_MOD_LCDSCD, IF_REAL, "Length dependence of cdscd"),
IOP( "lcit", BSIM3_MOD_LCIT, IF_REAL, "Length dependence of cit"),
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( "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"),
IOP( "lnsub", BSIM3_MOD_LNSUB, IF_REAL, "Length dependence of nsub"),
IOP( "lnch", BSIM3_MOD_LNPEAK, IF_REAL, "Length dependence of nch"),
IOP( "lngate", BSIM3_MOD_LNGATE, IF_REAL, "Length dependence of ngate"),
IOP( "lgamma1", BSIM3_MOD_LGAMMA1, IF_REAL, "Length dependence of gamma1"),
IOP( "lgamma2", BSIM3_MOD_LGAMMA2, IF_REAL, "Length dependence of gamma2"),
IOP( "lvbx", BSIM3_MOD_LVBX, IF_REAL, "Length dependence of vbx"),
IOP( "lvbm", BSIM3_MOD_LVBM, IF_REAL, "Length dependence of vbm"),
IOP( "lxt", BSIM3_MOD_LXT, IF_REAL, "Length dependence of xt"),
IOP( "lk1", BSIM3_MOD_LK1, IF_REAL, "Length dependence of k1"),
IOP( "lkt1", BSIM3_MOD_LKT1, IF_REAL, "Length dependence of kt1"),
IOP( "lkt1l", BSIM3_MOD_LKT1L, IF_REAL, "Length dependence of kt1l"),
IOP( "lkt2", BSIM3_MOD_LKT2, IF_REAL, "Length dependence of kt2"),
IOP( "lk2", BSIM3_MOD_LK2, IF_REAL, "Length dependence of k2"),
IOP( "lk3", BSIM3_MOD_LK3, IF_REAL, "Length dependence of k3"),
IOP( "lk3b", BSIM3_MOD_LK3B, IF_REAL, "Length dependence of k3b"),
IOP( "lw0", BSIM3_MOD_LW0, IF_REAL, "Length dependence of w0"),
IOP( "lnlx", BSIM3_MOD_LNLX, IF_REAL, "Length dependence of nlx"),
IOP( "ldvt0", BSIM3_MOD_LDVT0, IF_REAL, "Length dependence of dvt0"),
IOP( "ldvt1", BSIM3_MOD_LDVT1, IF_REAL, "Length dependence of dvt1"),
IOP( "ldvt2", BSIM3_MOD_LDVT2, IF_REAL, "Length dependence of dvt2"),
IOP( "ldvt0w", BSIM3_MOD_LDVT0W, IF_REAL, "Length dependence of dvt0w"),
IOP( "ldvt1w", BSIM3_MOD_LDVT1W, IF_REAL, "Length dependence of dvt1w"),
IOP( "ldvt2w", BSIM3_MOD_LDVT2W, IF_REAL, "Length dependence of dvt2w"),
IOP( "ldrout", BSIM3_MOD_LDROUT, IF_REAL, "Length dependence of drout"),
IOP( "ldsub", BSIM3_MOD_LDSUB, IF_REAL, "Length dependence of dsub"),
IOP( "lvth0", BSIM3_MOD_LVTH0, IF_REAL,"Length dependence of vth0"),
IOPR("lvtho", BSIM3_MOD_LVTH0, IF_REAL,"Length dependence of vtho"),
IOP( "lua", BSIM3_MOD_LUA, IF_REAL, "Length dependence of ua"),
IOP( "lua1", BSIM3_MOD_LUA1, IF_REAL, "Length dependence of ua1"),
IOP( "lub", BSIM3_MOD_LUB, IF_REAL, "Length dependence of ub"),
IOP( "lub1", BSIM3_MOD_LUB1, IF_REAL, "Length dependence of ub1"),
IOP( "luc", BSIM3_MOD_LUC, IF_REAL, "Length dependence of uc"),
IOP( "luc1", BSIM3_MOD_LUC1, IF_REAL, "Length dependence of uc1"),
IOP( "lu0", BSIM3_MOD_LU0, IF_REAL, "Length dependence of u0"),
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( "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( "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"),
IOP( "lb0", BSIM3_MOD_LB0, IF_REAL, "Length dependence of b0"),
IOP( "lb1", BSIM3_MOD_LB1, IF_REAL, "Length dependence of b1"),
IOP( "lcgsl", BSIM3_MOD_LCGSL, IF_REAL, "Length dependence of cgsl"),
IOP( "lcgdl", BSIM3_MOD_LCGDL, IF_REAL, "Length dependence of cgdl"),
IOP( "lckappa", BSIM3_MOD_LCKAPPA, IF_REAL, "Length dependence of ckappa"),
IOP( "lcf", BSIM3_MOD_LCF, IF_REAL, "Length dependence of cf"),
IOP( "lclc", BSIM3_MOD_LCLC, IF_REAL, "Length dependence of clc"),
IOP( "lcle", BSIM3_MOD_LCLE, IF_REAL, "Length dependence of cle"),
IOP( "lalpha0", BSIM3_MOD_LALPHA0, IF_REAL, "Length dependence of alpha0"),
IOP( "lalpha1", BSIM3_MOD_LALPHA1, IF_REAL, "Length dependence of alpha1"),
IOP( "lbeta0", BSIM3_MOD_LBETA0, IF_REAL, "Length dependence of beta0"),
IOP( "lvfbcv", BSIM3_MOD_LVFBCV, IF_REAL, "Length dependence of vfbcv"),
IOP( "lvfb", BSIM3_MOD_LVFB, IF_REAL, "Length dependence of vfb"),
IOP( "lacde", BSIM3_MOD_LACDE, IF_REAL, "Length dependence of acde"),
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( "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( "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"),
IOP( "wnsub", BSIM3_MOD_WNSUB, IF_REAL, "Width dependence of nsub"),
IOP( "wnch", BSIM3_MOD_WNPEAK, IF_REAL, "Width dependence of nch"),
IOP( "wngate", BSIM3_MOD_WNGATE, IF_REAL, "Width dependence of ngate"),
IOP( "wgamma1", BSIM3_MOD_WGAMMA1, IF_REAL, "Width dependence of gamma1"),
IOP( "wgamma2", BSIM3_MOD_WGAMMA2, IF_REAL, "Width dependence of gamma2"),
IOP( "wvbx", BSIM3_MOD_WVBX, IF_REAL, "Width dependence of vbx"),
IOP( "wvbm", BSIM3_MOD_WVBM, IF_REAL, "Width dependence of vbm"),
IOP( "wxt", BSIM3_MOD_WXT, IF_REAL, "Width dependence of xt"),
IOP( "wk1", BSIM3_MOD_WK1, IF_REAL, "Width dependence of k1"),
IOP( "wkt1", BSIM3_MOD_WKT1, IF_REAL, "Width dependence of kt1"),
IOP( "wkt1l", BSIM3_MOD_WKT1L, IF_REAL, "Width dependence of kt1l"),
IOP( "wkt2", BSIM3_MOD_WKT2, IF_REAL, "Width dependence of kt2"),
IOP( "wk2", BSIM3_MOD_WK2, IF_REAL, "Width dependence of k2"),
IOP( "wk3", BSIM3_MOD_WK3, IF_REAL, "Width dependence of k3"),
IOP( "wk3b", BSIM3_MOD_WK3B, IF_REAL, "Width dependence of k3b"),
IOP( "ww0", BSIM3_MOD_WW0, IF_REAL, "Width dependence of w0"),
IOP( "wnlx", BSIM3_MOD_WNLX, IF_REAL, "Width dependence of nlx"),
IOP( "wdvt0", BSIM3_MOD_WDVT0, IF_REAL, "Width dependence of dvt0"),
IOP( "wdvt1", BSIM3_MOD_WDVT1, IF_REAL, "Width dependence of dvt1"),
IOP( "wdvt2", BSIM3_MOD_WDVT2, IF_REAL, "Width dependence of dvt2"),
IOP( "wdvt0w", BSIM3_MOD_WDVT0W, IF_REAL, "Width dependence of dvt0w"),
IOP( "wdvt1w", BSIM3_MOD_WDVT1W, IF_REAL, "Width dependence of dvt1w"),
IOP( "wdvt2w", BSIM3_MOD_WDVT2W, IF_REAL, "Width dependence of dvt2w"),
IOP( "wdrout", BSIM3_MOD_WDROUT, IF_REAL, "Width dependence of drout"),
IOP( "wdsub", BSIM3_MOD_WDSUB, IF_REAL, "Width dependence of dsub"),
IOP( "wvth0", BSIM3_MOD_WVTH0, IF_REAL,"Width dependence of vth0"),
IOPR("wvtho", BSIM3_MOD_WVTH0, IF_REAL,"Width dependence of vtho"),
IOP( "wua", BSIM3_MOD_WUA, IF_REAL, "Width dependence of ua"),
IOP( "wua1", BSIM3_MOD_WUA1, IF_REAL, "Width dependence of ua1"),
IOP( "wub", BSIM3_MOD_WUB, IF_REAL, "Width dependence of ub"),
IOP( "wub1", BSIM3_MOD_WUB1, IF_REAL, "Width dependence of ub1"),
IOP( "wuc", BSIM3_MOD_WUC, IF_REAL, "Width dependence of uc"),
IOP( "wuc1", BSIM3_MOD_WUC1, IF_REAL, "Width dependence of uc1"),
IOP( "wu0", BSIM3_MOD_WU0, IF_REAL, "Width dependence of u0"),
IOP( "wute", BSIM3_MOD_WUTE, IF_REAL, "Width dependence of ute"),
IOP( "wvoff", BSIM3_MOD_WVOFF, IF_REAL, "Width dependence of voff"),
IOP( "welm", BSIM3_MOD_WELM, IF_REAL, "Width dependence of elm"),
IOP( "wdelta", BSIM3_MOD_WDELTA, IF_REAL, "Width dependence of delta"),
IOP( "wrdsw", BSIM3_MOD_WRDSW, IF_REAL, "Width dependence of rdsw "),
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( "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"),
IOP( "wb0", BSIM3_MOD_WB0, IF_REAL, "Width dependence of b0"),
IOP( "wb1", BSIM3_MOD_WB1, IF_REAL, "Width dependence of b1"),
IOP( "wcgsl", BSIM3_MOD_WCGSL, IF_REAL, "Width dependence of cgsl"),
IOP( "wcgdl", BSIM3_MOD_WCGDL, IF_REAL, "Width dependence of cgdl"),
IOP( "wckappa", BSIM3_MOD_WCKAPPA, IF_REAL, "Width dependence of ckappa"),
IOP( "wcf", BSIM3_MOD_WCF, IF_REAL, "Width dependence of cf"),
IOP( "wclc", BSIM3_MOD_WCLC, IF_REAL, "Width dependence of clc"),
IOP( "wcle", BSIM3_MOD_WCLE, IF_REAL, "Width dependence of cle"),
IOP( "walpha0", BSIM3_MOD_WALPHA0, IF_REAL, "Width dependence of alpha0"),
IOP( "walpha1", BSIM3_MOD_WALPHA1, IF_REAL, "Width dependence of alpha1"),
IOP( "wbeta0", BSIM3_MOD_WBETA0, IF_REAL, "Width dependence of beta0"),
IOP( "wvfbcv", BSIM3_MOD_WVFBCV, IF_REAL, "Width dependence of vfbcv"),
IOP( "wvfb", BSIM3_MOD_WVFB, IF_REAL, "Width dependence of vfb"),
IOP( "wacde", BSIM3_MOD_WACDE, IF_REAL, "Width dependence of acde"),
IOP( "wmoin", BSIM3_MOD_WMOIN, IF_REAL, "Width dependence of moin"),
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( "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( "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"),
IOP( "pketa", BSIM3_MOD_PKETA, IF_REAL, "Cross-term dependence of keta"),
IOP( "pnsub", BSIM3_MOD_PNSUB, IF_REAL, "Cross-term dependence of nsub"),
IOP( "pnch", BSIM3_MOD_PNPEAK, IF_REAL, "Cross-term dependence of nch"),
IOP( "pngate", BSIM3_MOD_PNGATE, IF_REAL, "Cross-term dependence of ngate"),
IOP( "pgamma1", BSIM3_MOD_PGAMMA1, IF_REAL, "Cross-term dependence of gamma1"),
IOP( "pgamma2", BSIM3_MOD_PGAMMA2, IF_REAL, "Cross-term dependence of gamma2"),
IOP( "pvbx", BSIM3_MOD_PVBX, IF_REAL, "Cross-term dependence of vbx"),
IOP( "pvbm", BSIM3_MOD_PVBM, IF_REAL, "Cross-term dependence of vbm"),
IOP( "pxt", BSIM3_MOD_PXT, IF_REAL, "Cross-term dependence of xt"),
IOP( "pk1", BSIM3_MOD_PK1, IF_REAL, "Cross-term dependence of k1"),
IOP( "pkt1", BSIM3_MOD_PKT1, IF_REAL, "Cross-term dependence of kt1"),
IOP( "pkt1l", BSIM3_MOD_PKT1L, IF_REAL, "Cross-term dependence of kt1l"),
IOP( "pkt2", BSIM3_MOD_PKT2, IF_REAL, "Cross-term dependence of kt2"),
IOP( "pk2", BSIM3_MOD_PK2, IF_REAL, "Cross-term dependence of k2"),
IOP( "pk3", BSIM3_MOD_PK3, IF_REAL, "Cross-term dependence of k3"),
IOP( "pk3b", BSIM3_MOD_PK3B, IF_REAL, "Cross-term dependence of k3b"),
IOP( "pw0", BSIM3_MOD_PW0, IF_REAL, "Cross-term dependence of w0"),
IOP( "pnlx", BSIM3_MOD_PNLX, IF_REAL, "Cross-term dependence of nlx"),
IOP( "pdvt0", BSIM3_MOD_PDVT0, IF_REAL, "Cross-term dependence of dvt0"),
IOP( "pdvt1", BSIM3_MOD_PDVT1, IF_REAL, "Cross-term dependence of dvt1"),
IOP( "pdvt2", BSIM3_MOD_PDVT2, IF_REAL, "Cross-term dependence of dvt2"),
IOP( "pdvt0w", BSIM3_MOD_PDVT0W, IF_REAL, "Cross-term dependence of dvt0w"),
IOP( "pdvt1w", BSIM3_MOD_PDVT1W, IF_REAL, "Cross-term dependence of dvt1w"),
IOP( "pdvt2w", BSIM3_MOD_PDVT2W, IF_REAL, "Cross-term dependence of dvt2w"),
IOP( "pdrout", BSIM3_MOD_PDROUT, IF_REAL, "Cross-term dependence of drout"),
IOP( "pdsub", BSIM3_MOD_PDSUB, IF_REAL, "Cross-term dependence of dsub"),
IOP( "pvth0", BSIM3_MOD_PVTH0, IF_REAL,"Cross-term dependence of vth0"),
IOPR("pvtho", BSIM3_MOD_PVTH0, IF_REAL,"Cross-term dependence of vtho"),
IOP( "pua", BSIM3_MOD_PUA, IF_REAL, "Cross-term dependence of ua"),
IOP( "pua1", BSIM3_MOD_PUA1, IF_REAL, "Cross-term dependence of ua1"),
IOP( "pub", BSIM3_MOD_PUB, IF_REAL, "Cross-term dependence of ub"),
IOP( "pub1", BSIM3_MOD_PUB1, IF_REAL, "Cross-term dependence of ub1"),
IOP( "puc", BSIM3_MOD_PUC, IF_REAL, "Cross-term dependence of uc"),
IOP( "puc1", BSIM3_MOD_PUC1, IF_REAL, "Cross-term dependence of uc1"),
IOP( "pu0", BSIM3_MOD_PU0, IF_REAL, "Cross-term dependence of u0"),
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( "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"),
IOP( "petab", BSIM3_MOD_PETAB, IF_REAL, "Cross-term dependence of etab"),
IOP( "ppclm", BSIM3_MOD_PPCLM, IF_REAL, "Cross-term dependence of pclm"),
IOP( "ppdiblc1", BSIM3_MOD_PPDIBL1, IF_REAL, "Cross-term dependence of pdiblc1"),
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( "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"),
IOP( "pb0", BSIM3_MOD_PB0, IF_REAL, "Cross-term dependence of b0"),
IOP( "pb1", BSIM3_MOD_PB1, IF_REAL, "Cross-term dependence of b1"),
IOP( "pcgsl", BSIM3_MOD_PCGSL, IF_REAL, "Cross-term dependence of cgsl"),
IOP( "pcgdl", BSIM3_MOD_PCGDL, IF_REAL, "Cross-term dependence of cgdl"),
IOP( "pckappa", BSIM3_MOD_PCKAPPA, IF_REAL, "Cross-term dependence of ckappa"),
IOP( "pcf", BSIM3_MOD_PCF, IF_REAL, "Cross-term dependence of cf"),
IOP( "pclc", BSIM3_MOD_PCLC, IF_REAL, "Cross-term dependence of clc"),
IOP( "pcle", BSIM3_MOD_PCLE, IF_REAL, "Cross-term dependence of cle"),
IOP( "palpha0", BSIM3_MOD_PALPHA0, IF_REAL, "Cross-term dependence of alpha0"),
IOP( "palpha1", BSIM3_MOD_PALPHA1, IF_REAL, "Cross-term dependence of alpha1"),
IOP( "pbeta0", BSIM3_MOD_PBETA0, IF_REAL, "Cross-term dependence of beta0"),
IOP( "pvfbcv", BSIM3_MOD_PVFBCV, IF_REAL, "Cross-term dependence of vfbcv"),
IOP( "pvfb", BSIM3_MOD_PVFB, IF_REAL, "Cross-term dependence of vfb"),
IOP( "pacde", BSIM3_MOD_PACDE, IF_REAL, "Cross-term dependence of acde"),
IOP( "pmoin", BSIM3_MOD_PMOIN, IF_REAL, "Cross-term dependence of moin"),
IOP( "pnoff", BSIM3_MOD_PNOFF, IF_REAL, "Cross-term dependence of noff"),
IOP( "pvoffcv", BSIM3_MOD_PVOFFCV, IF_REAL, "Cross-term dependence of voffcv"),
IOP( "noia", BSIM3_MOD_NOIA, IF_REAL, "Flicker noise parameter"),
IOP( "noib", BSIM3_MOD_NOIB, IF_REAL, "Flicker noise parameter"),
IOP( "noic", BSIM3_MOD_NOIC, IF_REAL, "Flicker noise parameter"),
IOP( "em", BSIM3_MOD_EM, IF_REAL, "Flicker noise parameter"),
IOP( "ef", BSIM3_MOD_EF, IF_REAL, "Flicker noise frequency exponent"),
IOP( "af", BSIM3_MOD_AF, IF_REAL, "Flicker noise exponent"),
IOP( "kf", BSIM3_MOD_KF, IF_REAL, "Flicker noise coefficient"),
IOP("vgs_max", BSIM3_MOD_VGS_MAX, IF_REAL, "maximum voltage G-S branch"),
IOP("vgd_max", BSIM3_MOD_VGD_MAX, IF_REAL, "maximum voltage G-D branch"),
IOP("vgb_max", BSIM3_MOD_VGB_MAX, IF_REAL, "maximum voltage G-B branch"),
IOP("vds_max", BSIM3_MOD_VDS_MAX, IF_REAL, "maximum voltage D-S branch"),
IOP("vbs_max", BSIM3_MOD_VBS_MAX, IF_REAL, "maximum voltage B-S branch"),
IOP("vbd_max", BSIM3_MOD_VBD_MAX, IF_REAL, "maximum voltage B-D branch"),
IOP("vgsr_max", BSIM3_MOD_VGSR_MAX, IF_REAL, "maximum voltage G-S branch"),
IOP("vgdr_max", BSIM3_MOD_VGDR_MAX, IF_REAL, "maximum voltage G-D branch"),
IOP("vgbr_max", BSIM3_MOD_VGBR_MAX, IF_REAL, "maximum voltage G-B branch"),
IOP("vbsr_max", BSIM3_MOD_VBSR_MAX, IF_REAL, "maximum voltage B-S branch"),
IOP("vbdr_max", BSIM3_MOD_VBDR_MAX, IF_REAL, "maximum voltage B-D branch"),
IP( "nmos", BSIM3_MOD_NMOS, IF_FLAG, "Flag to indicate NMOS"),
IP( "pmos", BSIM3_MOD_PMOS, IF_FLAG, "Flag to indicate PMOS"),
};
char *BSIM3SIMDnames[] = {
"Drain",
"Gate",
"Source",
"Bulk",
"Charge"
};
int BSIM3SIMDnSize = NUMELEMS(BSIM3SIMDnames);
int BSIM3SIMDpTSize = NUMELEMS(BSIM3SIMDpTable);
int BSIM3SIMDmPTSize = NUMELEMS(BSIM3SIMDmPTable);
int BSIM3SIMDiSize = sizeof(BSIM3instance);
int BSIM3SIMDmSize = sizeof(BSIM3model);

View File

@ -0,0 +1,460 @@
/**** BSIM3v3.3.0 beta, Released by Xuemei Xi 07/29/2005 ****/
/**********
* Copyright 2004 Regents of the University of California. All rights reserved.
* File: b3acld.c of BSIM3v3.3.0
* Author: 1995 Min-Chie Jeng and Mansun Chan
* Author: 1997-1999 Weidong Liu.
* Author: 2001 Xuemei Xi
**********/
#include "ngspice/ngspice.h"
#include "ngspice/cktdefs.h"
#include "bsim3def.h"
#include "ngspice/sperror.h"
#include "ngspice/suffix.h"
int
BSIM3SIMDacLoad(
GENmodel *inModel,
CKTcircuit *ckt)
{
BSIM3model *model = (BSIM3model*)inModel;
BSIM3instance *here;
double xcggb, xcgdb, xcgsb, xcbgb, xcbdb, xcbsb, xcddb, xcssb, xcdgb;
double gdpr, gspr, gds, gbd, gbs, capbd, capbs, xcsgb, xcdsb, xcsdb;
double cggb, cgdb, cgsb, cbgb, cbdb, cbsb, cddb, cdgb, cdsb, omega;
double GSoverlapCap, GDoverlapCap, GBoverlapCap, FwdSum, RevSum, Gm, Gmbs;
double dxpart, sxpart, xgtg, xgtd, xgts, xgtb, xcqgb=0.0, xcqdb=0.0, xcqsb=0.0, xcqbb=0.0;
double gbspsp, gbbdp, gbbsp, gbspg, gbspb;
double gbspdp, gbdpdp, gbdpg, gbdpb, gbdpsp;
double ddxpart_dVd, ddxpart_dVg, ddxpart_dVb, ddxpart_dVs;
double dsxpart_dVd, dsxpart_dVg, dsxpart_dVb, dsxpart_dVs;
double T1, CoxWL, qcheq, Cdg, Cdd, Cds, Csg, Csd, Css;
double ScalingFactor = 1.0e-9;
/* For ACNQSMOD */
double T0, T2, T3, gmr, gmbsr, gmi, gmbsi, gdsi;
double Cddr, Cdgr, Cdsr, Csdr, Csgr, Cssr, Cgdr, Cggr, Cgsr;
double Cddi, Cdgi, Cdsi, Cdbi, Csdi, Csgi, Cssi, Csbi;
double Cgdi, Cggi, Cgsi, Cgbi, Gmi, Gmbsi, FwdSumi, RevSumi;
double xcdgbi, xcsgbi, xcddbi, xcdsbi, xcsdbi, xcssbi, xcdbbi;
double xcsbbi, xcggbi, xcgdbi, xcgsbi, xcgbbi;
double m;
omega = ckt->CKTomega;
for (; model != NULL; model = BSIM3SIMDnextModel(model))
{ for (here = BSIM3SIMDinstances(model); here!= NULL;
here = BSIM3SIMDnextInstance(here))
{
Csd = -(here->BSIM3cddb + here->BSIM3cgdb + here->BSIM3cbdb);
Csg = -(here->BSIM3cdgb + here->BSIM3cggb + here->BSIM3cbgb);
Css = -(here->BSIM3cdsb + here->BSIM3cgsb + here->BSIM3cbsb);
if (here->BSIM3acnqsMod)
{ T0 = omega * here->BSIM3taunet;
T1 = T0 * T0;
T2 = 1.0 / (1.0 + T1);
T3 = T0 * T2;
gmr = here->BSIM3gm * T2;
gmbsr = here->BSIM3gmbs * T2;
gds = here->BSIM3gds * T2;
gmi = -here->BSIM3gm * T3;
gmbsi = -here->BSIM3gmbs * T3;
gdsi = -here->BSIM3gds * T3;
Cddr = here->BSIM3cddb * T2;
Cdgr = here->BSIM3cdgb * T2;
Cdsr = here->BSIM3cdsb * T2;
Cddi = here->BSIM3cddb * T3 * omega;
Cdgi = here->BSIM3cdgb * T3 * omega;
Cdsi = here->BSIM3cdsb * T3 * omega;
Cdbi = -(Cddi + Cdgi + Cdsi);
Csdr = Csd * T2;
Csgr = Csg * T2;
Cssr = Css * T2;
Csdi = Csd * T3 * omega;
Csgi = Csg * T3 * omega;
Cssi = Css * T3 * omega;
Csbi = -(Csdi + Csgi + Cssi);
Cgdr = -(Cddr + Csdr + here->BSIM3cbdb);
Cggr = -(Cdgr + Csgr + here->BSIM3cbgb);
Cgsr = -(Cdsr + Cssr + here->BSIM3cbsb);
Cgdi = -(Cddi + Csdi);
Cggi = -(Cdgi + Csgi);
Cgsi = -(Cdsi + Cssi);
Cgbi = -(Cgdi + Cggi + Cgsi);
}
else /* QS */
{ gmr = here->BSIM3gm;
gmbsr = here->BSIM3gmbs;
gds = here->BSIM3gds;
gmi = gmbsi = gdsi = 0.0;
Cddr = here->BSIM3cddb;
Cdgr = here->BSIM3cdgb;
Cdsr = here->BSIM3cdsb;
Cddi = Cdgi = Cdsi = Cdbi = 0.0;
Csdr = Csd;
Csgr = Csg;
Cssr = Css;
Csdi = Csgi = Cssi = Csbi = 0.0;
Cgdr = here->BSIM3cgdb;
Cggr = here->BSIM3cggb;
Cgsr = here->BSIM3cgsb;
Cgdi = Cggi = Cgsi = Cgbi = 0.0;
}
if (here->BSIM3mode >= 0)
{ Gm = gmr;
Gmbs = gmbsr;
FwdSum = Gm + Gmbs;
RevSum = 0.0;
Gmi = gmi;
Gmbsi = gmbsi;
FwdSumi = Gmi + Gmbsi;
RevSumi = 0.0;
gbbdp = -here->BSIM3gbds;
gbbsp = here->BSIM3gbds + here->BSIM3gbgs + here->BSIM3gbbs;
gbdpg = here->BSIM3gbgs;
gbdpb = here->BSIM3gbbs;
gbdpdp = here->BSIM3gbds;
gbdpsp = -(gbdpg + gbdpb + gbdpdp);
gbspdp = 0.0;
gbspg = 0.0;
gbspb = 0.0;
gbspsp = 0.0;
if (here->BSIM3nqsMod == 0 || here->BSIM3acnqsMod == 1)
{ cggb = Cggr;
cgsb = Cgsr;
cgdb = Cgdr;
cbgb = here->BSIM3cbgb;
cbsb = here->BSIM3cbsb;
cbdb = here->BSIM3cbdb;
cdgb = Cdgr;
cdsb = Cdsr;
cddb = Cddr;
xgtg = xgtd = xgts = xgtb = 0.0;
sxpart = 0.6;
dxpart = 0.4;
ddxpart_dVd = ddxpart_dVg = ddxpart_dVb
= ddxpart_dVs = 0.0;
dsxpart_dVd = dsxpart_dVg = dsxpart_dVb
= dsxpart_dVs = 0.0;
}
else
{ cggb = cgdb = cgsb = 0.0;
cbgb = cbdb = cbsb = 0.0;
cdgb = cddb = cdsb = 0.0;
xgtg = here->BSIM3gtg;
xgtd = here->BSIM3gtd;
xgts = here->BSIM3gts;
xgtb = here->BSIM3gtb;
xcqgb = here->BSIM3cqgb * omega;
xcqdb = here->BSIM3cqdb * omega;
xcqsb = here->BSIM3cqsb * omega;
xcqbb = here->BSIM3cqbb * omega;
CoxWL = model->BSIM3cox * here->pParam->BSIM3weffCV
* here->pParam->BSIM3leffCV;
qcheq = -(here->BSIM3qgate + here->BSIM3qbulk);
if (fabs(qcheq) <= 1.0e-5 * CoxWL)
{ if (model->BSIM3xpart < 0.5)
{ dxpart = 0.4;
}
else if (model->BSIM3xpart > 0.5)
{ dxpart = 0.0;
}
else
{ dxpart = 0.5;
}
ddxpart_dVd = ddxpart_dVg = ddxpart_dVb
= ddxpart_dVs = 0.0;
}
else
{ dxpart = here->BSIM3qdrn / qcheq;
Cdd = here->BSIM3cddb;
Csd = -(here->BSIM3cgdb + here->BSIM3cddb
+ here->BSIM3cbdb);
ddxpart_dVd = (Cdd - dxpart * (Cdd + Csd)) / qcheq;
Cdg = here->BSIM3cdgb;
Csg = -(here->BSIM3cggb + here->BSIM3cdgb
+ here->BSIM3cbgb);
ddxpart_dVg = (Cdg - dxpart * (Cdg + Csg)) / qcheq;
Cds = here->BSIM3cdsb;
Css = -(here->BSIM3cgsb + here->BSIM3cdsb
+ here->BSIM3cbsb);
ddxpart_dVs = (Cds - dxpart * (Cds + Css)) / qcheq;
ddxpart_dVb = -(ddxpart_dVd + ddxpart_dVg
+ ddxpart_dVs);
}
sxpart = 1.0 - dxpart;
dsxpart_dVd = -ddxpart_dVd;
dsxpart_dVg = -ddxpart_dVg;
dsxpart_dVs = -ddxpart_dVs;
dsxpart_dVb = -(dsxpart_dVd + dsxpart_dVg + dsxpart_dVs);
}
xcdgbi = Cdgi;
xcsgbi = Csgi;
xcddbi = Cddi;
xcdsbi = Cdsi;
xcsdbi = Csdi;
xcssbi = Cssi;
xcdbbi = Cdbi;
xcsbbi = Csbi;
xcggbi = Cggi;
xcgdbi = Cgdi;
xcgsbi = Cgsi;
xcgbbi = Cgbi;
}
else
{ Gm = -gmr;
Gmbs = -gmbsr;
FwdSum = 0.0;
RevSum = -(Gm + Gmbs);
Gmi = -gmi;
Gmbsi = -gmbsi;
FwdSumi = 0.0;
RevSumi = -(Gmi + Gmbsi);
gbbsp = -here->BSIM3gbds;
gbbdp = here->BSIM3gbds + here->BSIM3gbgs + here->BSIM3gbbs;
gbdpg = 0.0;
gbdpsp = 0.0;
gbdpb = 0.0;
gbdpdp = 0.0;
gbspg = here->BSIM3gbgs;
gbspsp = here->BSIM3gbds;
gbspb = here->BSIM3gbbs;
gbspdp = -(gbspg + gbspsp + gbspb);
if (here->BSIM3nqsMod == 0 || here->BSIM3acnqsMod == 1)
{ cggb = Cggr;
cgsb = Cgdr;
cgdb = Cgsr;
cbgb = here->BSIM3cbgb;
cbsb = here->BSIM3cbdb;
cbdb = here->BSIM3cbsb;
cdgb = -(Cdgr + cggb + cbgb);
cdsb = -(Cddr + cgsb + cbsb);
cddb = -(Cdsr + cgdb + cbdb);
xgtg = xgtd = xgts = xgtb = 0.0;
sxpart = 0.4;
dxpart = 0.6;
ddxpart_dVd = ddxpart_dVg = ddxpart_dVb
= ddxpart_dVs = 0.0;
dsxpart_dVd = dsxpart_dVg = dsxpart_dVb
= dsxpart_dVs = 0.0;
}
else
{ cggb = cgdb = cgsb = 0.0;
cbgb = cbdb = cbsb = 0.0;
cdgb = cddb = cdsb = 0.0;
xgtg = here->BSIM3gtg;
xgtd = here->BSIM3gts;
xgts = here->BSIM3gtd;
xgtb = here->BSIM3gtb;
xcqgb = here->BSIM3cqgb * omega;
xcqdb = here->BSIM3cqsb * omega;
xcqsb = here->BSIM3cqdb * omega;
xcqbb = here->BSIM3cqbb * omega;
CoxWL = model->BSIM3cox * here->pParam->BSIM3weffCV
* here->pParam->BSIM3leffCV;
qcheq = -(here->BSIM3qgate + here->BSIM3qbulk);
if (fabs(qcheq) <= 1.0e-5 * CoxWL)
{ if (model->BSIM3xpart < 0.5)
{ sxpart = 0.4;
}
else if (model->BSIM3xpart > 0.5)
{ sxpart = 0.0;
}
else
{ sxpart = 0.5;
}
dsxpart_dVd = dsxpart_dVg = dsxpart_dVb
= dsxpart_dVs = 0.0;
}
else
{ sxpart = here->BSIM3qdrn / qcheq;
Css = here->BSIM3cddb;
Cds = -(here->BSIM3cgdb + here->BSIM3cddb
+ here->BSIM3cbdb);
dsxpart_dVs = (Css - sxpart * (Css + Cds)) / qcheq;
Csg = here->BSIM3cdgb;
Cdg = -(here->BSIM3cggb + here->BSIM3cdgb
+ here->BSIM3cbgb);
dsxpart_dVg = (Csg - sxpart * (Csg + Cdg)) / qcheq;
Csd = here->BSIM3cdsb;
Cdd = -(here->BSIM3cgsb + here->BSIM3cdsb
+ here->BSIM3cbsb);
dsxpart_dVd = (Csd - sxpart * (Csd + Cdd)) / qcheq;
dsxpart_dVb = -(dsxpart_dVd + dsxpart_dVg
+ dsxpart_dVs);
}
dxpart = 1.0 - sxpart;
ddxpart_dVd = -dsxpart_dVd;
ddxpart_dVg = -dsxpart_dVg;
ddxpart_dVs = -dsxpart_dVs;
ddxpart_dVb = -(ddxpart_dVd + ddxpart_dVg + ddxpart_dVs);
}
xcdgbi = Csgi;
xcsgbi = Cdgi;
xcddbi = Cssi;
xcdsbi = Csdi;
xcsdbi = Cdsi;
xcssbi = Cddi;
xcdbbi = Csbi;
xcsbbi = Cdbi;
xcggbi = Cggi;
xcgdbi = Cgsi;
xcgsbi = Cgdi;
xcgbbi = Cgbi;
}
T1 = *(ckt->CKTstate0 + here->BSIM3qdef) * here->BSIM3gtau;
gdpr = here->BSIM3drainConductance;
gspr = here->BSIM3sourceConductance;
gbd = here->BSIM3gbd;
gbs = here->BSIM3gbs;
capbd = here->BSIM3capbd;
capbs = here->BSIM3capbs;
GSoverlapCap = here->BSIM3cgso;
GDoverlapCap = here->BSIM3cgdo;
GBoverlapCap = here->pParam->BSIM3cgbo;
xcdgb = (cdgb - GDoverlapCap) * omega;
xcddb = (cddb + capbd + GDoverlapCap) * omega;
xcdsb = cdsb * omega;
xcsgb = -(cggb + cbgb + cdgb + GSoverlapCap) * omega;
xcsdb = -(cgdb + cbdb + cddb) * omega;
xcssb = (capbs + GSoverlapCap - (cgsb + cbsb + cdsb)) * omega;
xcggb = (cggb + GDoverlapCap + GSoverlapCap + GBoverlapCap)
* omega;
xcgdb = (cgdb - GDoverlapCap ) * omega;
xcgsb = (cgsb - GSoverlapCap) * omega;
xcbgb = (cbgb - GBoverlapCap) * omega;
xcbdb = (cbdb - capbd ) * omega;
xcbsb = (cbsb - capbs ) * omega;
m = here->BSIM3m;
*(here->BSIM3GgPtr +1) += m * xcggb;
*(here->BSIM3BbPtr +1) -= m * (xcbgb + xcbdb + xcbsb);
*(here->BSIM3DPdpPtr +1) += m * (xcddb + gdsi + RevSumi);
*(here->BSIM3SPspPtr +1) += m * (xcssb + gdsi + FwdSumi);
*(here->BSIM3GbPtr +1) -= m * (xcggb + xcgdb + xcgsb);
*(here->BSIM3GdpPtr +1) += m * xcgdb;
*(here->BSIM3GspPtr +1) += m * xcgsb;
*(here->BSIM3BgPtr +1) += m * xcbgb;
*(here->BSIM3BdpPtr +1) += m * xcbdb;
*(here->BSIM3BspPtr +1) += m * xcbsb;
*(here->BSIM3DPgPtr +1) += m * (xcdgb + Gmi);
*(here->BSIM3DPbPtr +1) -= m * (xcdgb + xcddb + xcdsb + Gmbsi);
*(here->BSIM3DPspPtr +1) += m * (xcdsb - gdsi - FwdSumi);
*(here->BSIM3SPgPtr +1) += m * (xcsgb - Gmi);
*(here->BSIM3SPbPtr +1) -= m * (xcsgb + xcsdb + xcssb - Gmbsi);
*(here->BSIM3SPdpPtr +1) += m * (xcsdb - gdsi - RevSumi);
*(here->BSIM3DdPtr) += m * gdpr;
*(here->BSIM3SsPtr) += m * gspr;
*(here->BSIM3BbPtr) += m * (gbd + gbs - here->BSIM3gbbs);
*(here->BSIM3DPdpPtr) += m * (gdpr + gds + gbd + RevSum + xcddbi
+ dxpart * xgtd + T1 * ddxpart_dVd + gbdpdp);
*(here->BSIM3SPspPtr) += m * (gspr + gds + gbs + FwdSum + xcssbi
+ sxpart * xgts + T1 * dsxpart_dVs + gbspsp);
*(here->BSIM3DdpPtr) -= m * gdpr;
*(here->BSIM3SspPtr) -= m * gspr;
*(here->BSIM3BgPtr) -= m * here->BSIM3gbgs;
*(here->BSIM3BdpPtr) -= m * (gbd - gbbdp);
*(here->BSIM3BspPtr) -= m * (gbs - gbbsp);
*(here->BSIM3DPdPtr) -= m * gdpr;
*(here->BSIM3DPgPtr) += m * (Gm + dxpart * xgtg + T1 * ddxpart_dVg
+ gbdpg + xcdgbi);
*(here->BSIM3DPbPtr) -= m * (gbd - Gmbs - dxpart * xgtb
- T1 * ddxpart_dVb - gbdpb - xcdbbi);
*(here->BSIM3DPspPtr) -= m * (gds + FwdSum - dxpart * xgts
- T1 * ddxpart_dVs - gbdpsp - xcdsbi);
*(here->BSIM3SPgPtr) -= m * (Gm - sxpart * xgtg - T1 * dsxpart_dVg
- gbspg - xcsgbi);
*(here->BSIM3SPsPtr) -= m * gspr;
*(here->BSIM3SPbPtr) -= m * (gbs + Gmbs - sxpart * xgtb
- T1 * dsxpart_dVb - gbspb - xcsbbi);
*(here->BSIM3SPdpPtr) -= m * (gds + RevSum - sxpart * xgtd
- T1 * dsxpart_dVd - gbspdp - xcsdbi);
*(here->BSIM3GgPtr) -= m * (xgtg - xcggbi);
*(here->BSIM3GbPtr) -= m * (xgtb - xcgbbi);
*(here->BSIM3GdpPtr) -= m * (xgtd - xcgdbi);
*(here->BSIM3GspPtr) -= m * (xgts - xcgsbi);
if (here->BSIM3nqsMod)
{ if (here->BSIM3acnqsMod)
{ (*(here->BSIM3QqPtr) += m * 1.0);
(*(here->BSIM3QgPtr) += 0.0);
(*(here->BSIM3QdpPtr) += 0.0);
(*(here->BSIM3QspPtr) += 0.0);
(*(here->BSIM3QbPtr) += 0.0);
(*(here->BSIM3DPqPtr) += 0.0);
(*(here->BSIM3SPqPtr) += 0.0);
(*(here->BSIM3GqPtr) += 0.0);
} else {
*(here->BSIM3QqPtr +1) += m * omega * ScalingFactor;
*(here->BSIM3QgPtr +1) -= m * xcqgb;
*(here->BSIM3QdpPtr +1) -= m * xcqdb;
*(here->BSIM3QspPtr +1) -= m * xcqsb;
*(here->BSIM3QbPtr +1) -= m * xcqbb;
*(here->BSIM3QqPtr) += m * here->BSIM3gtau;
*(here->BSIM3DPqPtr) += m * dxpart * here->BSIM3gtau;
*(here->BSIM3SPqPtr) += m * sxpart * here->BSIM3gtau;
*(here->BSIM3GqPtr) -= m * here->BSIM3gtau;
*(here->BSIM3QgPtr) += m * xgtg;
*(here->BSIM3QdpPtr) += m * xgtd;
*(here->BSIM3QspPtr) += m * xgts;
*(here->BSIM3QbPtr) += m * xgtb;
}
}
}
}
return(OK);
}

View File

@ -0,0 +1,243 @@
/**** BSIM3v3.3.0, Released by Xuemei Xi 07/29/2005 ****/
/**********
* Copyright 2004 Regents of the University of California. All rights reserved.
* File: b3ask.c of BSIM3v3.3.0
* Author: 1995 Min-Chie Jeng and Mansun Chan
* Author: 1997-1999 Weidong Liu.
* Author: 2001 Xuemei Xi
**********/
#include "ngspice/ngspice.h"
#include "ngspice/ifsim.h"
#include "ngspice/cktdefs.h"
#include "ngspice/devdefs.h"
#include "bsim3def.h"
#include "ngspice/sperror.h"
#include "ngspice/suffix.h"
int
BSIM3SIMDask(
CKTcircuit *ckt,
GENinstance *inst,
int which,
IFvalue *value,
IFvalue *select)
{
BSIM3instance *here = (BSIM3instance*)inst;
NG_IGNORE(select);
switch(which)
{ case BSIM3_L:
value->rValue = here->BSIM3l;
return(OK);
case BSIM3_W:
value->rValue = here->BSIM3w;
return(OK);
case BSIM3_M:
value->rValue = here->BSIM3m;
return(OK);
case BSIM3_AS:
value->rValue = here->BSIM3sourceArea;
return(OK);
case BSIM3_AD:
value->rValue = here->BSIM3drainArea;
return(OK);
case BSIM3_PS:
value->rValue = here->BSIM3sourcePerimeter;
return(OK);
case BSIM3_PD:
value->rValue = here->BSIM3drainPerimeter;
return(OK);
case BSIM3_NRS:
value->rValue = here->BSIM3sourceSquares;
return(OK);
case BSIM3_NRD:
value->rValue = here->BSIM3drainSquares;
return(OK);
case BSIM3_OFF:
value->rValue = here->BSIM3off;
return(OK);
case BSIM3_NQSMOD:
value->iValue = here->BSIM3nqsMod;
return(OK);
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);
case BSIM3_IC_VDS:
value->rValue = here->BSIM3icVDS;
return(OK);
case BSIM3_IC_VGS:
value->rValue = here->BSIM3icVGS;
return(OK);
case BSIM3_DNODE:
value->iValue = here->BSIM3dNode;
return(OK);
case BSIM3_GNODE:
value->iValue = here->BSIM3gNode;
return(OK);
case BSIM3_SNODE:
value->iValue = here->BSIM3sNode;
return(OK);
case BSIM3_BNODE:
value->iValue = here->BSIM3bNode;
return(OK);
case BSIM3_DNODEPRIME:
value->iValue = here->BSIM3dNodePrime;
return(OK);
case BSIM3_SNODEPRIME:
value->iValue = here->BSIM3sNodePrime;
return(OK);
case BSIM3_SOURCECONDUCT:
value->rValue = here->BSIM3sourceConductance;
value->rValue *= here->BSIM3m;
return(OK);
case BSIM3_DRAINCONDUCT:
value->rValue = here->BSIM3drainConductance;
value->rValue *= here->BSIM3m;
return(OK);
case BSIM3_VBD:
value->rValue = *(ckt->CKTstate0 + here->BSIM3vbd);
return(OK);
case BSIM3_VBS:
value->rValue = *(ckt->CKTstate0 + here->BSIM3vbs);
return(OK);
case BSIM3_VGS:
value->rValue = *(ckt->CKTstate0 + here->BSIM3vgs);
return(OK);
case BSIM3_VDS:
value->rValue = *(ckt->CKTstate0 + here->BSIM3vds);
return(OK);
case BSIM3_CD:
value->rValue = here->BSIM3cd;
value->rValue *= here->BSIM3m;
return(OK);
case BSIM3_CBS:
value->rValue = here->BSIM3cbs;
value->rValue *= here->BSIM3m;
return(OK);
case BSIM3_CBD:
value->rValue = here->BSIM3cbd;
value->rValue *= here->BSIM3m;
return(OK);
case BSIM3_GM:
value->rValue = here->BSIM3gm;
value->rValue *= here->BSIM3m;
return(OK);
case BSIM3_GDS:
value->rValue = here->BSIM3gds;
value->rValue *= here->BSIM3m;
return(OK);
case BSIM3_GMBS:
value->rValue = here->BSIM3gmbs;
value->rValue *= here->BSIM3m;
return(OK);
case BSIM3_GBD:
value->rValue = here->BSIM3gbd;
value->rValue *= here->BSIM3m;
return(OK);
case BSIM3_GBS:
value->rValue = here->BSIM3gbs;
value->rValue *= here->BSIM3m;
return(OK);
case BSIM3_QB:
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;
return(OK);
case BSIM3_QG:
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;
return(OK);
case BSIM3_QD:
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;
return(OK);
case BSIM3_CGG:
value->rValue = here->BSIM3cggb;
value->rValue *= here->BSIM3m;
return(OK);
case BSIM3_CGD:
value->rValue = here->BSIM3cgdb;
value->rValue *= here->BSIM3m;
return(OK);
case BSIM3_CGS:
value->rValue = here->BSIM3cgsb;
value->rValue *= here->BSIM3m;
return(OK);
case BSIM3_CDG:
value->rValue = here->BSIM3cdgb;
value->rValue *= here->BSIM3m;
return(OK);
case BSIM3_CDD:
value->rValue = here->BSIM3cddb;
value->rValue *= here->BSIM3m;
return(OK);
case BSIM3_CDS:
value->rValue = here->BSIM3cdsb;
value->rValue *= here->BSIM3m;
return(OK);
case BSIM3_CBG:
value->rValue = here->BSIM3cbgb;
value->rValue *= here->BSIM3m;
return(OK);
case BSIM3_CBDB:
value->rValue = here->BSIM3cbdb;
value->rValue *= here->BSIM3m;
return(OK);
case BSIM3_CBSB:
value->rValue = here->BSIM3cbsb;
value->rValue *= here->BSIM3m;
return(OK);
case BSIM3_CAPBD:
value->rValue = here->BSIM3capbd;
value->rValue *= here->BSIM3m;
return(OK);
case BSIM3_CAPBS:
value->rValue = here->BSIM3capbs;
value->rValue *= here->BSIM3m;
return(OK);
case BSIM3_VON:
value->rValue = here->BSIM3von;
return(OK);
case BSIM3_VDSAT:
value->rValue = here->BSIM3vdsat;
return(OK);
case BSIM3_QBS:
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;
return(OK);
default:
return(E_BADPARM);
}
/* NOTREACHED */
}

View File

@ -0,0 +1,455 @@
/**** BSIM3v3.3.0, Released by Xuemei Xi 07/29/2005 ****/
/**********
* Copyright 2004 Regents of the University of California. All rights reserved.
* File: b3check.c of BSIM3v3.3.0
* Author: 1995 Min-Chie Jeng
* Author: 1997-1999 Weidong Liu.
* Author: 2001 Xuemei Xi.
* Modified by Xuemei Xi, 10/05, 12/14, 2001.
* Modified by Xuemei Xi, 07/29/2005.
**********/
#include "ngspice/ngspice.h"
#include "ngspice/cktdefs.h"
#include "bsim3def.h"
#include "ngspice/trandefs.h"
#include "ngspice/const.h"
#include "ngspice/sperror.h"
#include "ngspice/devdefs.h"
#include "ngspice/suffix.h"
int
BSIM3SIMDcheckModel(
BSIM3model *model,
BSIM3instance *here,
CKTcircuit *ckt)
{
struct bsim3SizeDependParam *pParam;
int Fatal_Flag = 0;
FILE *fplog;
NG_IGNORE(ckt);
if ((fplog = fopen("b3v33check.log", "w")) != NULL)
{ pParam = here->pParam;
fprintf(fplog, "BSIM3v3.3.0 Parameter Checking.\n");
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;
}
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",
model->BSIM3toxm);
printf("Fatal: Toxm = %g is not positive.\n", model->BSIM3toxm);
Fatal_Flag = 1;
}
if (model->BSIM3lintnoi > pParam->BSIM3leff/2)
{ fprintf(fplog, "Fatal: Lintnoi = %g is too large - Leff for noise is negative.\n",
model->BSIM3lintnoi);
printf("Fatal: Lintnoi = %g is too large - Leff for noise is negative.\n",
model->BSIM3lintnoi);
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->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;
}
/* 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;
}
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->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",
pParam->BSIM3pscbe2);
printf("Warning: Pscbe2 = %g is not positive.\n", pParam->BSIM3pscbe2);
}
/* 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",
pParam->BSIM3noff);
printf("Warning: Noff = %g is too small.\n", pParam->BSIM3noff);
}
if (pParam->BSIM3noff > 4.0)
{ fprintf(fplog, "Warning: Noff = %g is too large.\n",
pParam->BSIM3noff);
printf("Warning: Noff = %g is too large.\n", pParam->BSIM3noff);
}
if (pParam->BSIM3voffcv < -0.5)
{ fprintf(fplog, "Warning: Voffcv = %g is too small.\n",
pParam->BSIM3voffcv);
printf("Warning: Voffcv = %g is too small.\n", pParam->BSIM3voffcv);
}
if (pParam->BSIM3voffcv > 0.5)
{ fprintf(fplog, "Warning: Voffcv = %g is too large.\n",
pParam->BSIM3voffcv);
printf("Warning: Voffcv = %g is too large.\n", pParam->BSIM3voffcv);
}
if (model->BSIM3ijth < 0.0)
{ fprintf(fplog, "Fatal: Ijth = %g cannot be negative.\n",
model->BSIM3ijth);
printf("Fatal: Ijth = %g cannot be negative.\n", model->BSIM3ijth);
Fatal_Flag = 1;
}
/* 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;
}
if (pParam->BSIM3moin < 5.0)
{ fprintf(fplog, "Warning: Moin = %g is too small.\n",
pParam->BSIM3moin);
printf("Warning: Moin = %g is too small.\n", pParam->BSIM3moin);
}
if (pParam->BSIM3moin > 25.0)
{ fprintf(fplog, "Warning: Moin = %g is too large.\n",
pParam->BSIM3moin);
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->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->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);
}
/* 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 (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);
}
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->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");
}
/* 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);
}
/* 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");
}
/* 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->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);
printf("Warning: Rds at current temperature = %g is negative. Set to zero.\n",
pParam->BSIM3rds0);
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->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;
}
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;
}
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;
}
}/* loop for the parameter check for warning messages */
fclose(fplog);
}
else
{ fprintf(stderr, "Warning: Can't open log file. Parameter checking skipped.\n");
}
return(Fatal_Flag);
}

View File

@ -0,0 +1,107 @@
/**** BSIM3v3.3.0, Released by Xuemei Xi 07/29/2005 ****/
/**********
* Copyright 2004 Regents of the University of California. All rights reserved.
* File: b3cvtest.c of BSIM3v3.3.0
* Author: 1995 Min-Chie Jeng and Mansun Chan
* Author: 1997-1999 Weidong Liu.
* Author: 2001 Xuemei Xi
**********/
#include "ngspice/ngspice.h"
#include "ngspice/cktdefs.h"
#include "bsim3def.h"
#include "ngspice/trandefs.h"
#include "ngspice/const.h"
#include "ngspice/devdefs.h"
#include "ngspice/sperror.h"
#include "ngspice/suffix.h"
int
BSIM3SIMDconvTest(
GENmodel *inModel,
CKTcircuit *ckt)
{
BSIM3model *model = (BSIM3model*)inModel;
BSIM3instance *here;
double delvbd, delvbs, delvds, delvgd, delvgs, vbd, vbs, vds;
double cbd, cbhat, cbs, cd, cdhat, tol, vgd, vgdo, vgs;
/* loop through all the BSIM3 device models */
for (; model != NULL; model = BSIM3SIMDnextModel(model))
{ /* loop through all the instances of the model */
for (here = BSIM3SIMDinstances(model); here != NULL ;
here=BSIM3SIMDnextInstance(here))
{
vbs = model->BSIM3type
* (*(ckt->CKTrhsOld+here->BSIM3bNode)
- *(ckt->CKTrhsOld+here->BSIM3sNodePrime));
vgs = model->BSIM3type
* (*(ckt->CKTrhsOld+here->BSIM3gNode)
- *(ckt->CKTrhsOld+here->BSIM3sNodePrime));
vds = model->BSIM3type
* (*(ckt->CKTrhsOld+here->BSIM3dNodePrime)
- *(ckt->CKTrhsOld+here->BSIM3sNodePrime));
vbd = vbs - vds;
vgd = vgs - vds;
vgdo = *(ckt->CKTstate0 + here->BSIM3vgs)
- *(ckt->CKTstate0 + here->BSIM3vds);
delvbs = vbs - *(ckt->CKTstate0 + here->BSIM3vbs);
delvbd = vbd - *(ckt->CKTstate0 + here->BSIM3vbd);
delvgs = vgs - *(ckt->CKTstate0 + here->BSIM3vgs);
delvds = vds - *(ckt->CKTstate0 + here->BSIM3vds);
delvgd = vgd-vgdo;
cd = here->BSIM3cd - here->BSIM3cbd;
if (here->BSIM3mode >= 0)
{ cd += here->BSIM3csub;
cdhat = cd - here->BSIM3gbd * delvbd
+ (here->BSIM3gmbs + here->BSIM3gbbs) * delvbs
+ (here->BSIM3gm + here->BSIM3gbgs) * delvgs
+ (here->BSIM3gds + here->BSIM3gbds) * delvds;
}
else
{ cdhat = cd + (here->BSIM3gmbs - here->BSIM3gbd) * delvbd
+ here->BSIM3gm * delvgd - here->BSIM3gds * delvds;
}
/*
* check convergence
*/
if ((here->BSIM3off == 0) || (!(ckt->CKTmode & MODEINITFIX)))
{ tol = ckt->CKTreltol * MAX(fabs(cdhat), fabs(cd))
+ ckt->CKTabstol;
if (fabs(cdhat - cd) >= tol)
{ ckt->CKTnoncon++;
return(OK);
}
cbs = here->BSIM3cbs;
cbd = here->BSIM3cbd;
if (here->BSIM3mode >= 0)
{ cbhat = cbs + cbd - here->BSIM3csub
+ here->BSIM3gbd * delvbd
+ (here->BSIM3gbs - here->BSIM3gbbs) * delvbs
- here->BSIM3gbgs * delvgs
- here->BSIM3gbds * delvds;
}
else
{ cbhat = cbs + cbd - here->BSIM3csub
+ here->BSIM3gbs * delvbs
+ (here->BSIM3gbd - here->BSIM3gbbs) * delvbd
- here->BSIM3gbgs * delvgd
+ here->BSIM3gbds * delvds;
}
tol = ckt->CKTreltol * MAX(fabs(cbhat),
fabs(cbs + cbd - here->BSIM3csub)) + ckt->CKTabstol;
if (fabs(cbhat - (cbs + cbd - here->BSIM3csub)) > tol)
{ ckt->CKTnoncon++;
return(OK);
}
}
}
}
return(OK);
}

View File

@ -0,0 +1,44 @@
/**** BSIM3v3.3.0, Released by Xuemei Xi 07/29/2005 ****/
/**********
* Copyright 2004 Regents of the University of California. All rights reserved.
* File: b3getic.c of BSIM3v3.3.0
* Author: 1995 Min-Chie Jeng and Mansun Chan.
* Author: 1997-1999 Weidong Liu.
* Author: 2001 Xuemei Xi
**********/
#include "ngspice/ngspice.h"
#include "ngspice/cktdefs.h"
#include "bsim3def.h"
#include "ngspice/sperror.h"
#include "ngspice/suffix.h"
int
BSIM3SIMDgetic(
GENmodel *inModel,
CKTcircuit *ckt)
{
BSIM3model *model = (BSIM3model*)inModel;
BSIM3instance *here;
for (; model ; model = BSIM3SIMDnextModel(model))
{ for (here = BSIM3SIMDinstances(model); here; here = BSIM3SIMDnextInstance(here))
{
if (!here->BSIM3icVBSGiven)
{ here->BSIM3icVBS = *(ckt->CKTrhs + here->BSIM3bNode)
- *(ckt->CKTrhs + here->BSIM3sNode);
}
if (!here->BSIM3icVDSGiven)
{ here->BSIM3icVDS = *(ckt->CKTrhs + here->BSIM3dNode)
- *(ckt->CKTrhs + here->BSIM3sNode);
}
if (!here->BSIM3icVGSGiven)
{ here->BSIM3icVGS = *(ckt->CKTrhs + here->BSIM3gNode)
- *(ckt->CKTrhs + here->BSIM3sNode);
}
}
}
return(OK);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,153 @@
/*******************************************************************************
* Copyright 2020 Florian Ballenegger, Anamosic Ballenegger Design
*******************************************************************************
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
#include "ngspice/ngspice.h"
#include "bsim3def.h"
#define NDATASIMD 7
#ifndef USE_OMP
extern int BSIM3SIMDLoadSeq(BSIM3instance *here, CKTcircuit *ckt, double* data, int stride);
extern int BSIM3LoadSIMD(BSIM3instance **heres, CKTcircuit *ckt, double data[7][NSIMD]);
#else
extern void BSIM3SIMDLoadRhsMat(GENmodel *inModel, CKTcircuit *ckt);
extern int BSIM3SIMDLoadSeq(BSIM3instance *here, CKTcircuit *ckt, int);
extern int BSIM3LoadSIMD(BSIM3instance **heres, CKTcircuit *ckt);
#endif
#ifndef USE_OMP
int
BSIM3SIMDloadSel (GENmodel *inModel, CKTcircuit *ckt)
{
#ifndef USE_OMP
double data[NDATASIMD][NSIMD];
#endif
BSIM3group *group; /* a group of instance of same model, same pParam, same nqsMode, same geo and same off */
BSIM3model *model = (BSIM3model*)inModel;
BSIM3instance* heres[NSIMD];
for (; model != NULL; model = BSIM3SIMDnextModel(model))
for (group=model->groupHead; group!=NULL; group=group->next)
{
int idx=0;
while(idx+NSIMD <= group->InstCount)
{
int count=0;
while((count<NSIMD) && (idx<group->InstCount))
{
data[0][count]=NAN;
heres[count] = group->InstArray[idx];
int local_error = BSIM3SIMDLoadSeq(group->InstArray[idx++],ckt,
&data[0][count],NSIMD
);
if (local_error) return local_error;
if(!isnan(data[0][count]))
{
count++;
}
}
if(count==NSIMD)
{
int local_error;
/* process NSIMD instances at once */
local_error = BSIM3LoadSIMD(heres, ckt, data);
if (local_error) return local_error;
}
else for(int i=0;i<count;i++)
{
int local_error = BSIM3SIMDLoadSeq(heres[i], ckt, NULL,0);
if (local_error) return local_error;
}
}
/* remaining instances are evaluated sequencially */
for (; idx < group->InstCount; idx++) {
int local_error = BSIM3SIMDLoadSeq(group->InstArray[idx], ckt,
NULL, 0);
if (local_error) return local_error;
}
}
return 0; /* no error */
}
#endif
#ifdef USE_OMP
int
BSIM3SIMDloadSel (GENmodel *inModel, CKTcircuit *ckt)
{
/*
This version do omp parallel only inside groups
*/
BSIM3group *group;
BSIM3model *model = (BSIM3model*)inModel;
int error=0;
int idx=0;
for (; model != NULL; model = BSIM3SIMDnextModel(model))
for (group=model->groupHead; group!=NULL; group=group->next)
{
#pragma omp parallel for
for (idx=0; idx <= group->InstCount-NSIMD; idx+=NSIMD)
{
int local_error;
int i;
int needeval=0;
for(i=0;i<NSIMD;i++)
{
group->InstArray[idx+i]->BSIM3SIMDCheck=-1;
local_error = BSIM3SIMDLoadSeq(group->InstArray[idx+i], ckt, 1);
if (local_error) error = local_error;
if(group->InstArray[idx+i]->BSIM3SIMDCheck!=-1)
needeval=1;
}
if(!needeval)
continue; /* all NSIMD instances are bypassed */
local_error = BSIM3LoadSIMD(&group->InstArray[idx], ckt);
if (local_error) error = local_error;
}
/* omp mess with idx val after the for loop above, so we recalc it */
idx = NSIMD*(group->InstCount/NSIMD);
for (; idx < group->InstCount; idx++) {
int local_error = BSIM3SIMDLoadSeq(group->InstArray[idx], ckt, 2);
if (local_error) error = local_error;
}
}
BSIM3SIMDLoadRhsMat(inModel, ckt);
return error;
}
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,193 @@
/*******************************************************************************
* Copyright 2020 Florian Ballenegger, Anamosic Ballenegger Design
*******************************************************************************
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
#include <math.h>
#include "ngspice/ngspice.h"
#include "ngspice/cktdefs.h"
#include "bsim3def.h"
#include "ngspice/trandefs.h"
#include "ngspice/const.h"
#include "ngspice/sperror.h"
#include "ngspice/devdefs.h"
#include "ngspice/suffix.h"
#include "ngspice/SIMD/simdvector.h"
#include "ngspice/SIMD/simdop.h"
#include "ngspice/SIMD/simdniinteg.h"
#define MAX_EXP 5.834617425e14
#define MIN_EXP 1.713908431e-15
#define EXP_THRESHOLD 34.0
#define EPSOX 3.453133e-11
#define EPSSI 1.03594e-10
#define Charge_q 1.60219e-19
#define DELTA_1 0.02
#define DELTA_2 0.02
#define DELTA_3 0.02
#define DELTA_4 0.02
#define SIMDANY(err) (err!=0)
#define SIMDIFYCMD(cmd) /* empty */
#define SIMDifySaveScope(sc) /* empty */
int BSIM3_ACM_saturationCurrents(BSIM3model*, BSIM3instance*,
double*, double*);
int BSIM3_ACM_junctionCapacitances(BSIM3model*, BSIM3instance*,
double*, double*,double*, double*,double*, double*);
static inline VecNd vecN_SIMDLOADDATA(int idx, double data[7][NSIMD])
{
VecNd r;
for(int i=0;i<NSIMD;i++)
r[i] = data[idx][i];
return r;
}
static inline int vecN_BSIM3_ACM_saturationCurrents
(
BSIM3model *model,
BSIM3instance **heres,
VecNd *DrainSatCurrent,
VecNd *SourceSatCurrent
)
{
int error;
double dsat,ssat;
for(int idx=0;idx<NSIMD;idx++)
{
error = BSIM3_ACM_saturationCurrents(
model, heres[idx],
&dsat,
&ssat
);
(*DrainSatCurrent)[idx] = dsat;
(*SourceSatCurrent)[idx] = ssat;
if(error) return error;
}
return error;
}
static inline int vecN_BSIM3_ACM_junctionCapacitances(
BSIM3model *model,
BSIM3instance **heres,
VecNd *areaDrainBulkCapacitance,
VecNd *periDrainBulkCapacitance,
VecNd *gateDrainBulkCapacitance,
VecNd *areaSourceBulkCapacitance,
VecNd *periSourceBulkCapacitance,
VecNd *gateSourceBulkCapacitance
)
{
int error;
double areaDB,periDB,gateDB,areaSB,periSB,gateSB;
for(int idx=0;idx<NSIMD;idx++)
{
error = BSIM3_ACM_junctionCapacitances(
model, heres[idx],
&areaDB,
&periDB,
&gateDB,
&areaSB,
&periSB,
&gateSB
);
(*areaDrainBulkCapacitance)[idx]=areaDB;
(*periDrainBulkCapacitance)[idx]=periDB;
(*gateDrainBulkCapacitance)[idx]=gateDB;
(*areaSourceBulkCapacitance)[idx]=areaSB;
(*periSourceBulkCapacitance)[idx]=periSB;
(*gateSourceBulkCapacitance)[idx]=gateSB;
if(error) return error;
}
return error;
}
#if NSIMD==4
#define vec4_SIMDLOADDATA vecN_SIMDLOADDATA
#define vec4_BSIM3_ACM_saturationCurrents vecN_BSIM3_ACM_saturationCurrents
#define vec4_BSIM3_ACM_junctionCapacitances vecN_BSIM3_ACM_junctionCapacitances
#define vec4_NIintegrate vecN_NIintegrate
#endif
#if NSIMD==8
#define vec8_SIMDLOADDATA vecN_SIMDLOADDATA
#define vec8_BSIM3_ACM_saturationCurrents vecN_BSIM3_ACM_saturationCurrents
#define vec8_BSIM3_ACM_junctionCapacitances vecN_BSIM3_ACM_junctionCapacitances
#define vec8_NIintegrate vecN_NIintegrate
#endif
#if NSIMD==2
#define vec2_SIMDLOADDATA vecN_SIMDLOADDATA
#define vec2_BSIM3_ACM_saturationCurrents vecN_BSIM3_ACM_saturationCurrents
#define vec2_BSIM3_ACM_junctionCapacitances vecN_BSIM3_ACM_junctionCapacitances
#define vec2_NIintegrate vecN_NIintegrate
#endif
int BSIM3LoadSIMD(BSIM3instance **heres, CKTcircuit *ckt
#ifndef USE_OMP
, double data[7][NSIMD]
#endif
)
{
BSIM3model *model = BSIM3SIMDmodPtr(heres[0]);
#if NSIMD==4
#ifdef USE_OMP
#include "b3ldseq_simd4d_omp.c"
#else
#include "b3ldseq_simd4d.c"
#endif
#elif NSIMD==8
#ifdef USE_OMP
#include "b3ldseq_simd8d_omp.c"
#else
#include "b3ldseq_simd8d.c"
#endif
#elif NSIMD==2
#ifdef USE_OMP
#include "b3ldseq_simd2d_omp.c"
#else
#include "b3ldseq_simd2d.c"
#endif
#else
#error Unsupported value for NSIMD
#endif
return(OK);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,37 @@
/**** BSIM3v3.3.0, Released by Xuemei Xi 07/29/2005 ****/
/**********
* Copyright 2004 Regents of the University of California. All rights reserved.
* File: b3mdel.c of BSIM3v3.3.0
* Author: 1995 Min-Chie Jeng and Mansun Chan.
* Author: 1997-1999 Weidong Liu.
* Author: 2001 Xuemei Xi
**********/
#include "ngspice/ngspice.h"
#include "bsim3def.h"
#include "ngspice/sperror.h"
#include "ngspice/suffix.h"
int
BSIM3SIMDmDelete(GENmodel *gen_model)
{
BSIM3model *model = (BSIM3model*) gen_model;
#ifdef USE_OMP
FREE(model->BSIM3InstanceArray);
#endif
struct bsim3SizeDependParam *p = model->pSizeDependParamKnot;
while (p) {
struct bsim3SizeDependParam *next_p = p->pNext;
FREE(p);
p = next_p;
}
/* model->BSIM3modName to be freed in INPtabEnd() */
FREE(model->BSIM3version);
return OK;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,360 @@
/**** BSIM3v3.3.0, Released by Xuemei Xi 07/29/2005 ****/
/**********
* Copyright 2004 Regents of the University of California. All rights reserved.
* File: b3noi.c of BSIM3v3.3.0
* Author: 1995 Gary W. Ng and Min-Chie Jeng.
* Author: 1997-1999 Weidong Liu.
* Author: 2001 Xuemei Xi
* Modified by Xuemei Xi, 10/05/2001.
**********/
#include "ngspice/ngspice.h"
#include "bsim3def.h"
#include "ngspice/cktdefs.h"
#include "ngspice/iferrmsg.h"
#include "ngspice/noisedef.h"
#include "ngspice/suffix.h"
#include "ngspice/const.h" /* jwan */
/*
* BSIM3SIMDnoise (mode, operation, firstModel, ckt, data, OnDens)
* This routine names and evaluates all of the noise sources
* associated with MOSFET's. It starts with the model *firstModel and
* traverses all of its insts. It then proceeds to any other models
* on the linked list. The total output noise density generated by
* all of the MOSFET's is summed with the variable "OnDens".
*/
/*
Channel thermal and flicker noises are calculated based on the value
of model->BSIM3noiMod.
If model->BSIM3noiMod = 1,
Channel thermal noise = SPICE2 model
Flicker noise = SPICE2 model
If model->BSIM3noiMod = 2,
Channel thermal noise = BSIM3 model
Flicker noise = BSIM3 model
If model->BSIM3noiMod = 3,
Channel thermal noise = SPICE2 model
Flicker noise = BSIM3 model
If model->BSIM3noiMod = 4,
Channel thermal noise = BSIM3 model
Flicker noise = SPICE2 model
If model->BSIM3noiMod = 5,
Channel thermal noise = SPICE2 model with linear/sat fix
Flicker noise = SPICE2 model
If model->BSIM3noiMod = 6,
Channel thermal noise = SPICE2 model with linear/sat fix
Flicker noise = BSIM3 model
*/
/*
* JX: 1/f noise model is smoothed out 12/18/01.
*/
static double
StrongInversionNoiseEval(
double Vds,
BSIM3model *model,
BSIM3instance *here,
double freq, double temp)
{
struct bsim3SizeDependParam *pParam;
double cd, esat, DelClm, EffFreq, N0, Nl, Leff, Leffsq;
double T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, Ssi;
pParam = here->pParam;
cd = fabs(here->BSIM3cd);
Leff = pParam->BSIM3leff - 2.0 * model->BSIM3lintnoi;
Leffsq = Leff * Leff;
esat = 2.0 * pParam->BSIM3vsattemp / here->BSIM3ueff;
if(model->BSIM3em<=0.0) DelClm = 0.0;
else {
T0 = ((((Vds - here->BSIM3Vdseff) / pParam->BSIM3litl)
+ model->BSIM3em) / esat);
DelClm = pParam->BSIM3litl * log (MAX(T0, N_MINLOG));
if (DelClm < 0.0) DelClm = 0.0; /* bugfix */
}
EffFreq = pow(freq, model->BSIM3ef);
T1 = CHARGE * CHARGE * 8.62e-5 * cd * temp * here->BSIM3ueff;
T2 = 1.0e8 * EffFreq * here->BSIM3Abulk * model->BSIM3cox * Leffsq;
N0 = model->BSIM3cox * here->BSIM3Vgsteff / CHARGE;
Nl = model->BSIM3cox * here->BSIM3Vgsteff
* (1.0 - here->BSIM3AbovVgst2Vtm * here->BSIM3Vdseff) / CHARGE;
T3 = model->BSIM3oxideTrapDensityA
* log(MAX(((N0 + 2.0e14) / (Nl + 2.0e14)), N_MINLOG));
T4 = model->BSIM3oxideTrapDensityB * (N0 - Nl);
T5 = model->BSIM3oxideTrapDensityC * 0.5 * (N0 * N0 - Nl * Nl);
T6 = 8.62e-5 * temp * cd * cd;
T7 = 1.0e8 * EffFreq * Leffsq * pParam->BSIM3weff;
T8 = model->BSIM3oxideTrapDensityA + model->BSIM3oxideTrapDensityB * Nl
+ model->BSIM3oxideTrapDensityC * Nl * Nl;
T9 = (Nl + 2.0e14) * (Nl + 2.0e14);
Ssi = T1 / T2 * (T3 + T4 + T5) + T6 / T7 * DelClm * T8 / T9;
return Ssi;
}
int
BSIM3SIMDnoise (
int mode, int operation,
GENmodel *inModel,
CKTcircuit *ckt,
Ndata *data,
double *OnDens)
{
NOISEAN *job = (NOISEAN *) ckt->CKTcurJob;
BSIM3model *model = (BSIM3model *)inModel;
BSIM3instance *here;
struct bsim3SizeDependParam *pParam;
double tempOnoise;
double tempInoise;
double noizDens[BSIM3NSRCS];
double lnNdens[BSIM3NSRCS];
double vds;
double T1, T10, T11;
double Ssi, Swi;
double m;
int i;
/* define the names of the noise sources */
static char *BSIM3nNames[BSIM3NSRCS] =
{ /* Note that we have to keep the order */
".rd", /* noise due to rd */
/* consistent with the index definitions */
".rs", /* noise due to rs */
/* in BSIM3defs.h */
".id", /* noise due to id */
".1overf", /* flicker (1/f) noise */
"" /* total transistor noise */
};
for (; model != NULL; model = BSIM3SIMDnextModel(model))
{ for (here = BSIM3SIMDinstances(model); here != NULL;
here = BSIM3SIMDnextInstance(here))
{ pParam = here->pParam;
switch (operation)
{ case N_OPEN:
/* see if we have to to produce a summary report */
/* if so, name all the noise generators */
if (job->NStpsSm != 0)
{ switch (mode)
{ case N_DENS:
for (i = 0; i < BSIM3NSRCS; i++)
{ NOISE_ADD_OUTVAR(ckt, data, "onoise.%s%s", here->BSIM3name, BSIM3nNames[i]);
}
break;
case INT_NOIZ:
for (i = 0; i < BSIM3NSRCS; i++)
{ NOISE_ADD_OUTVAR(ckt, data, "onoise_total.%s%s", here->BSIM3name, BSIM3nNames[i]);
NOISE_ADD_OUTVAR(ckt, data, "inoise_total.%s%s", here->BSIM3name, BSIM3nNames[i]);
}
break;
}
}
break;
case N_CALC:
m = here->BSIM3m;
switch (mode)
{ case N_DENS:
NevalSrc(&noizDens[BSIM3RDNOIZ],
&lnNdens[BSIM3RDNOIZ], ckt, THERMNOISE,
here->BSIM3dNodePrime, here->BSIM3dNode,
here->BSIM3drainConductance * m);
NevalSrc(&noizDens[BSIM3RSNOIZ],
&lnNdens[BSIM3RSNOIZ], ckt, THERMNOISE,
here->BSIM3sNodePrime, here->BSIM3sNode,
here->BSIM3sourceConductance * m);
switch( model->BSIM3noiMod )
{ case 1:
case 3:
NevalSrc(&noizDens[BSIM3IDNOIZ],
&lnNdens[BSIM3IDNOIZ], ckt,
THERMNOISE, here->BSIM3dNodePrime,
here->BSIM3sNodePrime,
2.0 * fabs(here->BSIM3gm
+ here->BSIM3gds
+ here->BSIM3gmbs) / 3.0 * m);
break;
case 5:
case 6:
vds = MIN(*(ckt->CKTstates[0] + here->BSIM3vds), here->BSIM3vdsat);
NevalSrc(&noizDens[BSIM3IDNOIZ],
&lnNdens[BSIM3IDNOIZ], ckt,
THERMNOISE, here->BSIM3dNodePrime,
here->BSIM3sNodePrime,
(3.0 - vds / here->BSIM3vdsat)
* fabs(here->BSIM3gm
+ here->BSIM3gds
+ here->BSIM3gmbs) / 3.0 * m);
break;
case 2:
case 4:
NevalSrc(&noizDens[BSIM3IDNOIZ],
&lnNdens[BSIM3IDNOIZ], ckt,
THERMNOISE, here->BSIM3dNodePrime,
here->BSIM3sNodePrime,
(m * here->BSIM3ueff
* fabs(here->BSIM3qinv)
/ (pParam->BSIM3leff * pParam->BSIM3leff
+ here->BSIM3ueff *fabs(here->BSIM3qinv)
* here->BSIM3rds))); /* bugfix */
break;
}
NevalSrc(&noizDens[BSIM3FLNOIZ], NULL,
ckt, N_GAIN, here->BSIM3dNodePrime,
here->BSIM3sNodePrime, (double) 0.0);
switch( model->BSIM3noiMod )
{ case 1:
case 4:
case 5:
noizDens[BSIM3FLNOIZ] *= m * model->BSIM3kf
* exp(model->BSIM3af
* log(MAX(fabs(here->BSIM3cd),
N_MINLOG)))
/ (pow(data->freq, model->BSIM3ef)
* pParam->BSIM3leff
* pParam->BSIM3leff
* model->BSIM3cox);
break;
case 2:
case 3:
case 6:
vds = *(ckt->CKTstates[0] + here->BSIM3vds);
if (vds < 0.0)
{ vds = -vds;
}
Ssi = StrongInversionNoiseEval(vds, model,
here, data->freq, ckt->CKTtemp);
T10 = model->BSIM3oxideTrapDensityA
* 8.62e-5 * ckt->CKTtemp;
T11 = pParam->BSIM3weff
* pParam->BSIM3leff
* pow(data->freq, model->BSIM3ef)
* 4.0e36;
Swi = T10 / T11 * here->BSIM3cd
* here->BSIM3cd;
T1 = Swi + Ssi;
if (T1 > 0.0)
noizDens[BSIM3FLNOIZ] *= m * (Ssi * Swi) / T1;
else
noizDens[BSIM3FLNOIZ] *= 0.0;
break;
}
lnNdens[BSIM3FLNOIZ] =
log(MAX(noizDens[BSIM3FLNOIZ], N_MINLOG));
noizDens[BSIM3TOTNOIZ] = noizDens[BSIM3RDNOIZ]
+ noizDens[BSIM3RSNOIZ]
+ noizDens[BSIM3IDNOIZ]
+ noizDens[BSIM3FLNOIZ];
lnNdens[BSIM3TOTNOIZ] =
log(MAX(noizDens[BSIM3TOTNOIZ], N_MINLOG));
*OnDens += noizDens[BSIM3TOTNOIZ];
if (data->delFreq == 0.0)
{ /* if we haven't done any previous
integration, we need to initialize our
"history" variables.
*/
for (i = 0; i < BSIM3NSRCS; i++)
{ here->BSIM3nVar[LNLSTDENS][i] =
lnNdens[i];
}
/* clear out our integration variables
if it's the first pass
*/
if (data->freq ==
job->NstartFreq)
{ for (i = 0; i < BSIM3NSRCS; i++)
{ here->BSIM3nVar[OUTNOIZ][i] = 0.0;
here->BSIM3nVar[INNOIZ][i] = 0.0;
}
}
}
else
{ /* data->delFreq != 0.0,
we have to integrate.
*/
for (i = 0; i < BSIM3NSRCS; i++)
{ if (i != BSIM3TOTNOIZ)
{ tempOnoise = Nintegrate(noizDens[i],
lnNdens[i],
here->BSIM3nVar[LNLSTDENS][i],
data);
tempInoise = Nintegrate(noizDens[i]
* data->GainSqInv, lnNdens[i]
+ data->lnGainInv,
here->BSIM3nVar[LNLSTDENS][i]
+ data->lnGainInv, data);
here->BSIM3nVar[LNLSTDENS][i] =
lnNdens[i];
data->outNoiz += tempOnoise;
data->inNoise += tempInoise;
if (job->NStpsSm != 0)
{ here->BSIM3nVar[OUTNOIZ][i]
+= tempOnoise;
here->BSIM3nVar[OUTNOIZ][BSIM3TOTNOIZ]
+= tempOnoise;
here->BSIM3nVar[INNOIZ][i]
+= tempInoise;
here->BSIM3nVar[INNOIZ][BSIM3TOTNOIZ]
+= tempInoise;
}
}
}
}
if (data->prtSummary)
{ for (i = 0; i < BSIM3NSRCS; i++)
{ /* print a summary report */
data->outpVector[data->outNumber++]
= noizDens[i];
}
}
break;
case INT_NOIZ:
/* already calculated, just output */
if (job->NStpsSm != 0)
{ for (i = 0; i < BSIM3NSRCS; i++)
{ data->outpVector[data->outNumber++]
= here->BSIM3nVar[OUTNOIZ][i];
data->outpVector[data->outNumber++]
= here->BSIM3nVar[INNOIZ][i];
}
}
break;
}
break;
case N_CLOSE:
/* do nothing, the main calling routine will close */
return (OK);
break; /* the plots */
} /* switch (operation) */
} /* for here */
} /* for model */
return(OK);
}

View File

@ -0,0 +1,133 @@
/**** BSIM3v3.3.0, Released by Xuemei Xi 07/29/2005 ****/
/**********
* Copyright 2004 Regents of the University of California. All rights reserved.
* File: b3par.c of BSIM3v3.3.0
* Author: 1995 Min-Chie Jeng and Mansun Chan
* Author: 1997-1999 Weidong Liu.
* Author: 2001 Xuemei Xi
**********/
#include "ngspice/ngspice.h"
#include "ngspice/ifsim.h"
#include "bsim3def.h"
#include "ngspice/sperror.h"
#include "ngspice/suffix.h"
#include "ngspice/fteext.h"
int
BSIM3SIMDparam (
int param,
IFvalue *value,
GENinstance *inst,
IFvalue *select)
{
double scale;
BSIM3instance *here = (BSIM3instance*)inst;
NG_IGNORE(select);
if (!cp_getvar("scale", CP_REAL, &scale, 0))
scale = 1;
switch (param) {
case BSIM3_W:
here->BSIM3w = value->rValue*scale;
here->BSIM3wGiven = TRUE;
break;
case BSIM3_L:
here->BSIM3l = value->rValue*scale;
here->BSIM3lGiven = 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;
break;
case BSIM3_AD:
here->BSIM3drainArea = value->rValue*scale*scale;
here->BSIM3drainAreaGiven = TRUE;
break;
case BSIM3_PS:
here->BSIM3sourcePerimeter = value->rValue*scale;
here->BSIM3sourcePerimeterGiven = TRUE;
break;
case BSIM3_PD:
here->BSIM3drainPerimeter = value->rValue*scale;
here->BSIM3drainPerimeterGiven = TRUE;
break;
case BSIM3_NRS:
here->BSIM3sourceSquares = value->rValue;
here->BSIM3sourceSquaresGiven = TRUE;
break;
case BSIM3_NRD:
here->BSIM3drainSquares = value->rValue;
here->BSIM3drainSquaresGiven = TRUE;
break;
case BSIM3_OFF:
here->BSIM3off = value->iValue;
break;
case BSIM3_IC_VBS:
here->BSIM3icVBS = value->rValue;
here->BSIM3icVBSGiven = TRUE;
break;
case BSIM3_IC_VDS:
here->BSIM3icVDS = value->rValue;
here->BSIM3icVDSGiven = TRUE;
break;
case BSIM3_IC_VGS:
here->BSIM3icVGS = value->rValue;
here->BSIM3icVGSGiven = TRUE;
break;
case BSIM3_NQSMOD:
here->BSIM3nqsMod = value->iValue;
here->BSIM3nqsModGiven = TRUE;
break;
case BSIM3_ACNQSMOD:
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:
/* FALLTHROUGH added to suppress GCC warning due to
* -Wimplicit-fallthrough flag */
switch (value->v.numValue) {
case 3:
here->BSIM3icVBS = *(value->v.vec.rVec+2);
here->BSIM3icVBSGiven = TRUE;
/* FALLTHROUGH */
case 2:
here->BSIM3icVGS = *(value->v.vec.rVec+1);
here->BSIM3icVGSGiven = TRUE;
/* FALLTHROUGH */
case 1:
here->BSIM3icVDS = *(value->v.vec.rVec);
here->BSIM3icVDSGiven = TRUE;
break;
default:
return(E_BADPARM);
}
break;
default:
return(E_BADPARM);
}
return(OK);
}

View File

@ -0,0 +1,371 @@
/**** BSIM3v3.3.0, Released by Xuemei Xi 07/29/2005 ****/
/**********
* Copyright 2004 Regents of the University of California. All rights reserved.
* File: b3pzld.c of BSIM3v3.3.0
* Author: 1995 Min-Chie Jeng and Mansun Chan.
* Author: 1997-1999 Weidong Liu.
* Author: 2001 Xuemei Xi
**********/
#include "ngspice/ngspice.h"
#include "ngspice/cktdefs.h"
#include "ngspice/complex.h"
#include "ngspice/sperror.h"
#include "bsim3def.h"
#include "ngspice/suffix.h"
int
BSIM3SIMDpzLoad(
GENmodel *inModel,
CKTcircuit *ckt,
SPcomplex *s)
{
BSIM3model *model = (BSIM3model*)inModel;
BSIM3instance *here;
double xcggb, xcgdb, xcgsb, xcgbb, xcbgb, xcbdb, xcbsb, xcbbb;
double xcdgb, xcddb, xcdsb, xcdbb, xcsgb, xcsdb, xcssb, xcsbb;
double gdpr, gspr, gds, gbd, gbs, capbd, capbs, FwdSum, RevSum, Gm, Gmbs;
double cggb, cgdb, cgsb, cbgb, cbdb, cbsb, cddb, cdgb, cdsb;
double GSoverlapCap, GDoverlapCap, GBoverlapCap;
double dxpart, sxpart, xgtg, xgtd, xgts, xgtb, xcqgb=0.0, xcqdb=0.0, xcqsb=0.0, xcqbb=0.0;
double gbspsp, gbbdp, gbbsp, gbspg, gbspb;
double gbspdp, gbdpdp, gbdpg, gbdpb, gbdpsp;
double ddxpart_dVd, ddxpart_dVg, ddxpart_dVb, ddxpart_dVs;
double dsxpart_dVd, dsxpart_dVg, dsxpart_dVb, dsxpart_dVs;
double T1, CoxWL, qcheq, Cdg, Cdd, Cds, Csg, Csd, Css;
double ScalingFactor = 1.0e-9;
double m;
for (; model != NULL; model = BSIM3SIMDnextModel(model))
{ for (here = BSIM3SIMDinstances(model); here!= NULL;
here = BSIM3SIMDnextInstance(here))
{
if (here->BSIM3mode >= 0)
{ Gm = here->BSIM3gm;
Gmbs = here->BSIM3gmbs;
FwdSum = Gm + Gmbs;
RevSum = 0.0;
gbbdp = -here->BSIM3gbds;
gbbsp = here->BSIM3gbds + here->BSIM3gbgs + here->BSIM3gbbs;
gbdpg = here->BSIM3gbgs;
gbdpdp = here->BSIM3gbds;
gbdpb = here->BSIM3gbbs;
gbdpsp = -(gbdpg + gbdpdp + gbdpb);
gbspg = 0.0;
gbspdp = 0.0;
gbspb = 0.0;
gbspsp = 0.0;
if (here->BSIM3nqsMod == 0 && here->BSIM3acnqsMod == 0)
{ cggb = here->BSIM3cggb;
cgsb = here->BSIM3cgsb;
cgdb = here->BSIM3cgdb;
cbgb = here->BSIM3cbgb;
cbsb = here->BSIM3cbsb;
cbdb = here->BSIM3cbdb;
cdgb = here->BSIM3cdgb;
cdsb = here->BSIM3cdsb;
cddb = here->BSIM3cddb;
xgtg = xgtd = xgts = xgtb = 0.0;
sxpart = 0.6;
dxpart = 0.4;
ddxpart_dVd = ddxpart_dVg = ddxpart_dVb
= ddxpart_dVs = 0.0;
dsxpart_dVd = dsxpart_dVg = dsxpart_dVb
= dsxpart_dVs = 0.0;
}
else
{ cggb = cgdb = cgsb = 0.0;
cbgb = cbdb = cbsb = 0.0;
cdgb = cddb = cdsb = 0.0;
xgtg = here->BSIM3gtg;
xgtd = here->BSIM3gtd;
xgts = here->BSIM3gts;
xgtb = here->BSIM3gtb;
xcqgb = here->BSIM3cqgb;
xcqdb = here->BSIM3cqdb;
xcqsb = here->BSIM3cqsb;
xcqbb = here->BSIM3cqbb;
CoxWL = model->BSIM3cox * here->pParam->BSIM3weffCV
* here->pParam->BSIM3leffCV;
qcheq = -(here->BSIM3qgate + here->BSIM3qbulk);
if (fabs(qcheq) <= 1.0e-5 * CoxWL)
{ if (model->BSIM3xpart < 0.5)
{ dxpart = 0.4;
}
else if (model->BSIM3xpart > 0.5)
{ dxpart = 0.0;
}
else
{ dxpart = 0.5;
}
ddxpart_dVd = ddxpart_dVg = ddxpart_dVb
= ddxpart_dVs = 0.0;
}
else
{ dxpart = here->BSIM3qdrn / qcheq;
Cdd = here->BSIM3cddb;
Csd = -(here->BSIM3cgdb + here->BSIM3cddb
+ here->BSIM3cbdb);
ddxpart_dVd = (Cdd - dxpart * (Cdd + Csd)) / qcheq;
Cdg = here->BSIM3cdgb;
Csg = -(here->BSIM3cggb + here->BSIM3cdgb
+ here->BSIM3cbgb);
ddxpart_dVg = (Cdg - dxpart * (Cdg + Csg)) / qcheq;
Cds = here->BSIM3cdsb;
Css = -(here->BSIM3cgsb + here->BSIM3cdsb
+ here->BSIM3cbsb);
ddxpart_dVs = (Cds - dxpart * (Cds + Css)) / qcheq;
ddxpart_dVb = -(ddxpart_dVd + ddxpart_dVg
+ ddxpart_dVs);
}
sxpart = 1.0 - dxpart;
dsxpart_dVd = -ddxpart_dVd;
dsxpart_dVg = -ddxpart_dVg;
dsxpart_dVs = -ddxpart_dVs;
dsxpart_dVb = -(dsxpart_dVd + dsxpart_dVg + dsxpart_dVs);
}
}
else
{ Gm = -here->BSIM3gm;
Gmbs = -here->BSIM3gmbs;
FwdSum = 0.0;
RevSum = -(Gm + Gmbs);
gbbsp = -here->BSIM3gbds;
gbbdp = here->BSIM3gbds + here->BSIM3gbgs + here->BSIM3gbbs;
gbdpg = 0.0;
gbdpsp = 0.0;
gbdpb = 0.0;
gbdpdp = 0.0;
gbspg = here->BSIM3gbgs;
gbspsp = here->BSIM3gbds;
gbspb = here->BSIM3gbbs;
gbspdp = -(gbspg + gbspsp + gbspb);
if (here->BSIM3nqsMod == 0 && here->BSIM3acnqsMod == 0)
{ cggb = here->BSIM3cggb;
cgsb = here->BSIM3cgdb;
cgdb = here->BSIM3cgsb;
cbgb = here->BSIM3cbgb;
cbsb = here->BSIM3cbdb;
cbdb = here->BSIM3cbsb;
cdgb = -(here->BSIM3cdgb + cggb + cbgb);
cdsb = -(here->BSIM3cddb + cgsb + cbsb);
cddb = -(here->BSIM3cdsb + cgdb + cbdb);
xgtg = xgtd = xgts = xgtb = 0.0;
sxpart = 0.4;
dxpart = 0.6;
ddxpart_dVd = ddxpart_dVg = ddxpart_dVb
= ddxpart_dVs = 0.0;
dsxpart_dVd = dsxpart_dVg = dsxpart_dVb
= dsxpart_dVs = 0.0;
}
else
{ cggb = cgdb = cgsb = 0.0;
cbgb = cbdb = cbsb = 0.0;
cdgb = cddb = cdsb = 0.0;
xgtg = here->BSIM3gtg;
xgtd = here->BSIM3gts;
xgts = here->BSIM3gtd;
xgtb = here->BSIM3gtb;
xcqgb = here->BSIM3cqgb;
xcqdb = here->BSIM3cqsb;
xcqsb = here->BSIM3cqdb;
xcqbb = here->BSIM3cqbb;
CoxWL = model->BSIM3cox * here->pParam->BSIM3weffCV
* here->pParam->BSIM3leffCV;
qcheq = -(here->BSIM3qgate + here->BSIM3qbulk);
if (fabs(qcheq) <= 1.0e-5 * CoxWL)
{ if (model->BSIM3xpart < 0.5)
{ sxpart = 0.4;
}
else if (model->BSIM3xpart > 0.5)
{ sxpart = 0.0;
}
else
{ sxpart = 0.5;
}
dsxpart_dVd = dsxpart_dVg = dsxpart_dVb
= dsxpart_dVs = 0.0;
}
else
{ sxpart = here->BSIM3qdrn / qcheq;
Css = here->BSIM3cddb;
Cds = -(here->BSIM3cgdb + here->BSIM3cddb
+ here->BSIM3cbdb);
dsxpart_dVs = (Css - sxpart * (Css + Cds)) / qcheq;
Csg = here->BSIM3cdgb;
Cdg = -(here->BSIM3cggb + here->BSIM3cdgb
+ here->BSIM3cbgb);
dsxpart_dVg = (Csg - sxpart * (Csg + Cdg)) / qcheq;
Csd = here->BSIM3cdsb;
Cdd = -(here->BSIM3cgsb + here->BSIM3cdsb
+ here->BSIM3cbsb);
dsxpart_dVd = (Csd - sxpart * (Csd + Cdd)) / qcheq;
dsxpart_dVb = -(dsxpart_dVd + dsxpart_dVg
+ dsxpart_dVs);
}
dxpart = 1.0 - sxpart;
ddxpart_dVd = -dsxpart_dVd;
ddxpart_dVg = -dsxpart_dVg;
ddxpart_dVs = -dsxpart_dVs;
ddxpart_dVb = -(ddxpart_dVd + ddxpart_dVg + ddxpart_dVs);
}
}
T1 = *(ckt->CKTstate0 + here->BSIM3qdef) * here->BSIM3gtau;
gdpr = here->BSIM3drainConductance;
gspr = here->BSIM3sourceConductance;
gds = here->BSIM3gds;
gbd = here->BSIM3gbd;
gbs = here->BSIM3gbs;
capbd = here->BSIM3capbd;
capbs = here->BSIM3capbs;
GSoverlapCap = here->BSIM3cgso;
GDoverlapCap = here->BSIM3cgdo;
GBoverlapCap = here->pParam->BSIM3cgbo;
xcdgb = (cdgb - GDoverlapCap);
xcddb = (cddb + capbd + GDoverlapCap);
xcdsb = cdsb;
xcdbb = -(xcdgb + xcddb + xcdsb);
xcsgb = -(cggb + cbgb + cdgb + GSoverlapCap);
xcsdb = -(cgdb + cbdb + cddb);
xcssb = (capbs + GSoverlapCap - (cgsb + cbsb + cdsb));
xcsbb = -(xcsgb + xcsdb + xcssb);
xcggb = (cggb + GDoverlapCap + GSoverlapCap + GBoverlapCap);
xcgdb = (cgdb - GDoverlapCap);
xcgsb = (cgsb - GSoverlapCap);
xcgbb = -(xcggb + xcgdb + xcgsb);
xcbgb = (cbgb - GBoverlapCap);
xcbdb = (cbdb - capbd);
xcbsb = (cbsb - capbs);
xcbbb = -(xcbgb + xcbdb + xcbsb);
m = here->BSIM3m;
*(here->BSIM3GgPtr ) += m * (xcggb * s->real);
*(here->BSIM3GgPtr +1) += m * (xcggb * s->imag);
*(here->BSIM3BbPtr ) += m * (xcbbb * s->real);
*(here->BSIM3BbPtr +1) += m * (xcbbb * s->imag);
*(here->BSIM3DPdpPtr ) += m * (xcddb * s->real);
*(here->BSIM3DPdpPtr +1) += m * (xcddb * s->imag);
*(here->BSIM3SPspPtr ) += m * (xcssb * s->real);
*(here->BSIM3SPspPtr +1) += m * (xcssb * s->imag);
*(here->BSIM3GbPtr ) += m * (xcgbb * s->real);
*(here->BSIM3GbPtr +1) += m * (xcgbb * s->imag);
*(here->BSIM3GdpPtr ) += m * (xcgdb * s->real);
*(here->BSIM3GdpPtr +1) += m * (xcgdb * s->imag);
*(here->BSIM3GspPtr ) += m * (xcgsb * s->real);
*(here->BSIM3GspPtr +1) += m * (xcgsb * s->imag);
*(here->BSIM3BgPtr ) += m * (xcbgb * s->real);
*(here->BSIM3BgPtr +1) += m * (xcbgb * s->imag);
*(here->BSIM3BdpPtr ) += m * (xcbdb * s->real);
*(here->BSIM3BdpPtr +1) += m * (xcbdb * s->imag);
*(here->BSIM3BspPtr ) += m * (xcbsb * s->real);
*(here->BSIM3BspPtr +1) += m * (xcbsb * s->imag);
*(here->BSIM3DPgPtr ) += m * (xcdgb * s->real);
*(here->BSIM3DPgPtr +1) += m * (xcdgb * s->imag);
*(here->BSIM3DPbPtr ) += m * (xcdbb * s->real);
*(here->BSIM3DPbPtr +1) += m * (xcdbb * s->imag);
*(here->BSIM3DPspPtr ) += m * (xcdsb * s->real);
*(here->BSIM3DPspPtr +1) += m * (xcdsb * s->imag);
*(here->BSIM3SPgPtr ) += m * (xcsgb * s->real);
*(here->BSIM3SPgPtr +1) += m * (xcsgb * s->imag);
*(here->BSIM3SPbPtr ) += m * (xcsbb * s->real);
*(here->BSIM3SPbPtr +1) += m * (xcsbb * s->imag);
*(here->BSIM3SPdpPtr ) += m * (xcsdb * s->real);
*(here->BSIM3SPdpPtr +1) += m * (xcsdb * s->imag);
*(here->BSIM3DdPtr) += m * gdpr;
*(here->BSIM3DdpPtr) -= m * gdpr;
*(here->BSIM3DPdPtr) -= m * gdpr;
*(here->BSIM3SsPtr) += m * gspr;
*(here->BSIM3SspPtr) -= m * gspr;
*(here->BSIM3SPsPtr) -= m * gspr;
*(here->BSIM3BgPtr) -= m * here->BSIM3gbgs;
*(here->BSIM3BbPtr) += m * (gbd + gbs - here->BSIM3gbbs);
*(here->BSIM3BdpPtr) -= m * (gbd - gbbdp);
*(here->BSIM3BspPtr) -= m * (gbs - gbbsp);
*(here->BSIM3DPgPtr) += m * (Gm + dxpart * xgtg
+ T1 * ddxpart_dVg + gbdpg);
*(here->BSIM3DPdpPtr) += m * (gdpr + gds + gbd + RevSum
+ dxpart * xgtd + T1 * ddxpart_dVd + gbdpdp);
*(here->BSIM3DPspPtr) -= m * (gds + FwdSum - dxpart * xgts
- T1 * ddxpart_dVs - gbdpsp);
*(here->BSIM3DPbPtr) -= m * (gbd - Gmbs - dxpart * xgtb
- T1 * ddxpart_dVb - gbdpb);
*(here->BSIM3SPgPtr) -= m * (Gm - sxpart * xgtg
- T1 * dsxpart_dVg - gbspg);
*(here->BSIM3SPspPtr) += m * (gspr + gds + gbs + FwdSum
+ sxpart * xgts + T1 * dsxpart_dVs + gbspsp);
*(here->BSIM3SPbPtr) -= m * (gbs + Gmbs - sxpart * xgtb
- T1 * dsxpart_dVb - gbspb);
*(here->BSIM3SPdpPtr) -= m * (gds + RevSum - sxpart * xgtd
- T1 * dsxpart_dVd - gbspdp);
*(here->BSIM3GgPtr) -= m * xgtg;
*(here->BSIM3GbPtr) -= m * xgtb;
*(here->BSIM3GdpPtr) -= m * xgtd;
*(here->BSIM3GspPtr) -= m * xgts;
if (here->BSIM3nqsMod || here->BSIM3acnqsMod)
{ *(here->BSIM3QqPtr ) += m * (s->real * ScalingFactor);
*(here->BSIM3QqPtr +1) += m * (s->imag * ScalingFactor);
*(here->BSIM3QgPtr ) -= m * (xcqgb * s->real);
*(here->BSIM3QgPtr +1) -= m * (xcqgb * s->imag);
*(here->BSIM3QdpPtr ) -= m * (xcqdb * s->real);
*(here->BSIM3QdpPtr +1) -= m * (xcqdb * s->imag);
*(here->BSIM3QbPtr ) -= m * (xcqbb * s->real);
*(here->BSIM3QbPtr +1) -= m * (xcqbb * s->imag);
*(here->BSIM3QspPtr ) -= m * (xcqsb * s->real);
*(here->BSIM3QspPtr +1) -= m * (xcqsb * s->imag);
*(here->BSIM3GqPtr) -= m * (here->BSIM3gtau);
*(here->BSIM3DPqPtr) += m * (dxpart * here->BSIM3gtau);
*(here->BSIM3SPqPtr) += m * (sxpart * here->BSIM3gtau);
*(here->BSIM3QqPtr) += m * (here->BSIM3gtau);
*(here->BSIM3QgPtr) += m * xgtg;
*(here->BSIM3QdpPtr) += m * xgtd;
*(here->BSIM3QbPtr) += m * xgtb;
*(here->BSIM3QspPtr) += m * xgts;
}
}
}
return(OK);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,341 @@
/**********
Copyright 2013 Dietmar Warning. All rights reserved.
Author: 2013 Dietmar Warning
**********/
#include "ngspice/ngspice.h"
#include "ngspice/cktdefs.h"
#include "bsim3def.h"
#include "ngspice/trandefs.h"
#include "ngspice/sperror.h"
#include "ngspice/suffix.h"
#include "ngspice/cpdefs.h"
int
BSIM3SIMDsoaCheck(CKTcircuit *ckt, GENmodel *inModel)
{
BSIM3model *model = (BSIM3model *) inModel;
BSIM3instance *here;
double vgs, vgd, vgb, vds, vbs, vbd; /* actual mos voltages */
int maxwarns;
static int warns_vgs = 0, warns_vgd = 0, warns_vgb = 0, warns_vds = 0, warns_vbs = 0, warns_vbd = 0;
if (!ckt) {
warns_vgs = 0;
warns_vgd = 0;
warns_vgb = 0;
warns_vds = 0;
warns_vbs = 0;
warns_vbd = 0;
return OK;
}
maxwarns = ckt->CKTsoaMaxWarns;
for (; model; model = BSIM3SIMDnextModel(model)) {
for (here = BSIM3SIMDinstances(model); here; here = BSIM3SIMDnextInstance(here)) {
vgs = ckt->CKTrhsOld [here->BSIM3gNode] -
ckt->CKTrhsOld [here->BSIM3sNodePrime];
vgd = ckt->CKTrhsOld [here->BSIM3gNode] -
ckt->CKTrhsOld [here->BSIM3dNodePrime];
vgb = ckt->CKTrhsOld [here->BSIM3gNode] -
ckt->CKTrhsOld [here->BSIM3bNode];
vds = ckt->CKTrhsOld [here->BSIM3dNodePrime] -
ckt->CKTrhsOld [here->BSIM3sNodePrime];
vbs = ckt->CKTrhsOld [here->BSIM3bNode] -
ckt->CKTrhsOld [here->BSIM3sNodePrime];
vbd = ckt->CKTrhsOld [here->BSIM3bNode] -
ckt->CKTrhsOld [here->BSIM3dNodePrime];
if (!model->BSIM3vgsrMaxGiven) {
if (fabs(vgs) > model->BSIM3vgsMax)
if (warns_vgs < maxwarns) {
soa_printf(ckt, (GENinstance*) here,
"Vgs=%g has exceeded Vgs_max=%g\n",
vgs, model->BSIM3vgsMax);
warns_vgs++;
}
if (!model->BSIM3vgbMaxGiven) {
if (fabs(vgb) > model->BSIM3vgsMax)
if (warns_vgb < maxwarns) {
soa_printf(ckt, (GENinstance*) here,
"Vgb=%g has exceeded Vgs_max=%g\n",
vgb, model->BSIM3vgsMax);
warns_vgb++;
}
} else {
if (fabs(vgb) > model->BSIM3vgbMax)
if (warns_vgb < maxwarns) {
soa_printf(ckt, (GENinstance*) here,
"Vgb=%g has exceeded Vgb_max=%g\n",
vgb, model->BSIM3vgbMax);
warns_vgb++;
}
}
} else {
if (model->BSIM3type > 0) {
if (vgs > model->BSIM3vgsMax)
if (warns_vgs < maxwarns) {
soa_printf(ckt, (GENinstance*) here,
"Vgs=%g has exceeded Vgs_max=%g\n",
vgs, model->BSIM3vgsMax);
warns_vgs++;
}
if (-1*vgs > model->BSIM3vgsrMax)
if (warns_vgs < maxwarns) {
soa_printf(ckt, (GENinstance*) here,
"Vgs=%g has exceeded Vgsr_max=%g\n",
vgs, model->BSIM3vgsrMax);
warns_vgs++;
}
} else {
if (vgs > model->BSIM3vgsrMax)
if (warns_vgs < maxwarns) {
soa_printf(ckt, (GENinstance*) here,
"Vgs=%g has exceeded Vgsr_max=%g\n",
vgs, model->BSIM3vgsrMax);
warns_vgs++;
}
if (-1*vgs > model->BSIM3vgsMax)
if (warns_vgs < maxwarns) {
soa_printf(ckt, (GENinstance*) here,
"Vgs=%g has exceeded Vgs_max=%g\n",
vgs, model->BSIM3vgsMax);
warns_vgs++;
}
}
}
if (!model->BSIM3vgdrMaxGiven) {
if (fabs(vgd) > model->BSIM3vgdMax)
if (warns_vgd < maxwarns) {
soa_printf(ckt, (GENinstance*) here,
"Vgd=%g has exceeded Vgd_max=%g\n",
vgd, model->BSIM3vgdMax);
warns_vgd++;
}
} else {
if (model->BSIM3type > 0) {
if (vgd > model->BSIM3vgdMax)
if (warns_vgd < maxwarns) {
soa_printf(ckt, (GENinstance*) here,
"Vgd=%g has exceeded Vgd_max=%g\n",
vgd, model->BSIM3vgdMax);
warns_vgd++;
}
if (-1*vgd > model->BSIM3vgdrMax)
if (warns_vgd < maxwarns) {
soa_printf(ckt, (GENinstance*) here,
"Vgd=%g has exceeded Vgdr_max=%g\n",
vgd, model->BSIM3vgdrMax);
warns_vgd++;
}
} else {
if (vgd > model->BSIM3vgdrMax)
if (warns_vgd < maxwarns) {
soa_printf(ckt, (GENinstance*) here,
"Vgd=%g has exceeded Vgdr_max=%g\n",
vgd, model->BSIM3vgdrMax);
warns_vgd++;
}
if (-1*vgd > model->BSIM3vgdMax)
if (warns_vgd < maxwarns) {
soa_printf(ckt, (GENinstance*) here,
"Vgd=%g has exceeded Vgd_max=%g\n",
vgd, model->BSIM3vgdMax);
warns_vgd++;
}
}
}
if (fabs(vds) > model->BSIM3vdsMax)
if (warns_vds < maxwarns) {
soa_printf(ckt, (GENinstance*) here,
"Vds=%g has exceeded Vds_max=%g\n",
vds, model->BSIM3vdsMax);
warns_vds++;
}
if (!model->BSIM3vgbrMaxGiven) {
if (fabs(vgb) > model->BSIM3vgbMax)
if (warns_vgb < maxwarns) {
soa_printf(ckt, (GENinstance*) here,
"Vgb=%g has exceeded Vgb_max=%g\n",
vgb, model->BSIM3vgbMax);
warns_vgb++;
}
} else {
if (model->BSIM3type > 0) {
if (vgb > model->BSIM3vgbMax)
if (warns_vgb < maxwarns) {
soa_printf(ckt, (GENinstance*) here,
"Vgb=%g has exceeded Vgb_max=%g\n",
vgb, model->BSIM3vgbMax);
warns_vgb++;
}
if (-1*vgb > model->BSIM3vgbrMax)
if (warns_vgb < maxwarns) {
soa_printf(ckt, (GENinstance*) here,
"Vgb=%g has exceeded Vgbr_max=%g\n",
vgb, model->BSIM3vgbrMax);
warns_vgb++;
}
} else {
if (vgb > model->BSIM3vgbrMax)
if (warns_vgb < maxwarns) {
soa_printf(ckt, (GENinstance*) here,
"Vgb=%g has exceeded Vgbr_max=%g\n",
vgb, model->BSIM3vgbrMax);
warns_vgb++;
}
if (-1*vgb > model->BSIM3vgbMax)
if (warns_vgb < maxwarns) {
soa_printf(ckt, (GENinstance*) here,
"Vgb=%g has exceeded Vgb_max=%g\n",
vgb, model->BSIM3vgbMax);
warns_vgb++;
}
}
}
if (!model->BSIM3vbsrMaxGiven) {
if (!model->BSIM3vbsMaxGiven) {
if (fabs(vbs) > model->BSIM3vbdMax)
if (warns_vbs < maxwarns) {
soa_printf(ckt, (GENinstance*) here,
"Vbs=%g has exceeded Vbd_max=%g\n",
vbs, model->BSIM3vbdMax);
warns_vbs++;
}
} else {
if (fabs(vbs) > model->BSIM3vbsMax)
if (warns_vbs < maxwarns) {
soa_printf(ckt, (GENinstance*) here,
"Vbs=%g has exceeded Vbs_max=%g\n",
vbs, model->BSIM3vbsMax);
warns_vbs++;
}
}
} else {
if (!model->BSIM3vbsMaxGiven) {
if (model->BSIM3type > 0) {
if (vbs > model->BSIM3vbdMax)
if (warns_vbs < maxwarns) {
soa_printf(ckt, (GENinstance*) here,
"Vbs=%g has exceeded Vbd_max=%g\n",
vbs, model->BSIM3vbdMax);
warns_vbs++;
}
if (-1*vbs > model->BSIM3vbsrMax)
if (warns_vbs < maxwarns) {
soa_printf(ckt, (GENinstance*) here,
"Vbs=%g has exceeded Vbsr_max=%g\n",
vbs, model->BSIM3vbsrMax);
warns_vbs++;
}
} else {
if (vbs > model->BSIM3vbsrMax)
if (warns_vbs < maxwarns) {
soa_printf(ckt, (GENinstance*) here,
"Vbs=%g has exceeded Vbsr_max=%g\n",
vbs, model->BSIM3vbsrMax);
warns_vbs++;
}
if (-1*vbs > model->BSIM3vbdMax)
if (warns_vbs < maxwarns) {
soa_printf(ckt, (GENinstance*) here,
"Vbs=%g has exceeded Vbd_max=%g\n",
vbs, model->BSIM3vbdMax);
warns_vbs++;
}
}
} else {
if (model->BSIM3type > 0) {
if (vbs > model->BSIM3vbsMax)
if (warns_vbs < maxwarns) {
soa_printf(ckt, (GENinstance*) here,
"Vbs=%g has exceeded Vbs_max=%g\n",
vbs, model->BSIM3vbsMax);
warns_vbs++;
}
if (-1*vbs > model->BSIM3vbsrMax)
if (warns_vbs < maxwarns) {
soa_printf(ckt, (GENinstance*) here,
"Vbs=%g has exceeded Vbsr_max=%g\n",
vbs, model->BSIM3vbsrMax);
warns_vbs++;
}
} else {
if (vbs > model->BSIM3vbsrMax)
if (warns_vbs < maxwarns) {
soa_printf(ckt, (GENinstance*) here,
"Vbs=%g has exceeded Vbsr_max=%g\n",
vbs, model->BSIM3vbsrMax);
warns_vbs++;
}
if (-1*vbs > model->BSIM3vbsMax)
if (warns_vbs < maxwarns) {
soa_printf(ckt, (GENinstance*) here,
"Vbs=%g has exceeded Vbs_max=%g\n",
vbs, model->BSIM3vbsMax);
warns_vbs++;
}
}
}
}
if (!model->BSIM3vbdrMaxGiven) {
if (fabs(vbd) > model->BSIM3vbdMax)
if (warns_vbd < maxwarns) {
soa_printf(ckt, (GENinstance*) here,
"Vbd=%g has exceeded Vbd_max=%g\n",
vbd, model->BSIM3vbdMax);
warns_vbd++;
}
} else {
if (model->BSIM3type > 0) {
if (vbd > model->BSIM3vbdMax)
if (warns_vbd < maxwarns) {
soa_printf(ckt, (GENinstance*) here,
"Vbd=%g has exceeded Vbd_max=%g\n",
vbd, model->BSIM3vbdMax);
warns_vbd++;
}
if (-1*vbd > model->BSIM3vbdrMax)
if (warns_vbd < maxwarns) {
soa_printf(ckt, (GENinstance*) here,
"Vbd=%g has exceeded Vbdr_max=%g\n",
vbd, model->BSIM3vbdrMax);
warns_vbd++;
}
} else {
if (vbd > model->BSIM3vbdrMax)
if (warns_vbd < maxwarns) {
soa_printf(ckt, (GENinstance*) here,
"Vbd=%g has exceeded Vbdr_max=%g\n",
vbd, model->BSIM3vbdrMax);
warns_vbd++;
}
if (-1*vbd > model->BSIM3vbdMax)
if (warns_vbd < maxwarns) {
soa_printf(ckt, (GENinstance*) here,
"Vbd=%g has exceeded Vbd_max=%g\n",
vbd, model->BSIM3vbdMax);
warns_vbd++;
}
}
}
}
}
return OK;
}

View File

@ -0,0 +1,894 @@
/**** BSIM3v3.3.0, Released by Xuemei Xi 07/29/2005 ****/
/**********
* Copyright 2004 Regents of the University of California. All rights reserved.
* File: b3temp.c of BSIM3v3.3.0
* Author: 1995 Min-Chie Jeng and Mansun Chan.
* Author: 1997-1999 Weidong Liu.
* Author: 2001 Xuemei Xi
**********/
/* Lmin, Lmax, Wmin, Wmax */
#include "ngspice/ngspice.h"
#include "ngspice/smpdefs.h"
#include "ngspice/cktdefs.h"
#include "bsim3def.h"
#include "ngspice/const.h"
#include "ngspice/sperror.h"
#include "ngspice/devdefs.h"
#include "ngspice/suffix.h"
#define Kb 1.3806226e-23
#define KboQ 8.617087e-5 /* Kb / q where q = 1.60219e-19 */
#define EPSOX 3.453133e-11
#define EPSSI 1.03594e-10
#define PI 3.141592654
#define MAX_EXP 5.834617425e14
#define MIN_EXP 1.713908431e-15
#define EXP_THRESHOLD 34.0
#define Charge_q 1.60219e-19
/* ARGSUSED */
int
BSIM3SIMDtemp(
GENmodel *inModel,
CKTcircuit *ckt)
{
BSIM3model *model = (BSIM3model*) inModel;
BSIM3instance *here;
struct bsim3SizeDependParam *pSizeDependParamKnot, *pLastKnot, *pParam=NULL;
double tmp, tmp1, tmp2, tmp3, Eg, Eg0, ni, T0, T1, T2, T3, T4, T5, Ldrn, Wdrn;
double delTemp, Temp, TRatio, Inv_L, Inv_W, Inv_LW, Vtm0, Tnom;
double Nvtm, SourceSatCurrent, DrainSatCurrent;
int Size_Not_Found, error;
/* loop through all the BSIM3 device models */
for (; model != NULL; model = BSIM3SIMDnextModel(model))
{ Temp = ckt->CKTtemp;
if (model->BSIM3bulkJctPotential < 0.1)
{ model->BSIM3bulkJctPotential = 0.1;
fprintf(stderr, "Given pb is less than 0.1. Pb is set to 0.1.\n");
}
if (model->BSIM3sidewallJctPotential < 0.1)
{ model->BSIM3sidewallJctPotential = 0.1;
fprintf(stderr, "Given pbsw is less than 0.1. Pbsw is set to 0.1.\n");
}
if (model->BSIM3GatesidewallJctPotential < 0.1)
{ model->BSIM3GatesidewallJctPotential = 0.1;
fprintf(stderr, "Given pbswg is less than 0.1. Pbswg is set to 0.1.\n");
}
struct bsim3SizeDependParam *p = model->pSizeDependParamKnot;
while (p) {
struct bsim3SizeDependParam *next_p = p->pNext;
FREE(p);
p = next_p;
}
model->pSizeDependParamKnot = NULL;
pLastKnot = NULL;
Tnom = model->BSIM3tnom;
TRatio = Temp / Tnom;
model->BSIM3vcrit = CONSTvt0 * log(CONSTvt0 / (CONSTroot2 * 1.0e-14));
model->BSIM3factor1 = sqrt(EPSSI / EPSOX * model->BSIM3tox);
Vtm0 = KboQ * Tnom;
Eg0 = 1.16 - 7.02e-4 * Tnom * Tnom / (Tnom + 1108.0);
ni = 1.45e10 * (Tnom / 300.15) * sqrt(Tnom / 300.15)
* exp(21.5565981 - Eg0 / (2.0 * Vtm0));
model->BSIM3vtm = KboQ * Temp;
Eg = 1.16 - 7.02e-4 * Temp * Temp / (Temp + 1108.0);
if (Temp != Tnom)
{ T0 = Eg0 / Vtm0 - Eg / model->BSIM3vtm + model->BSIM3jctTempExponent
* log(Temp / Tnom);
T1 = exp(T0 / model->BSIM3jctEmissionCoeff);
model->BSIM3jctTempSatCurDensity = model->BSIM3jctSatCurDensity
* T1;
model->BSIM3jctSidewallTempSatCurDensity
= model->BSIM3jctSidewallSatCurDensity * T1;
}
else
{ model->BSIM3jctTempSatCurDensity = model->BSIM3jctSatCurDensity;
model->BSIM3jctSidewallTempSatCurDensity
= model->BSIM3jctSidewallSatCurDensity;
}
if (model->BSIM3jctTempSatCurDensity < 0.0)
model->BSIM3jctTempSatCurDensity = 0.0;
if (model->BSIM3jctSidewallTempSatCurDensity < 0.0)
model->BSIM3jctSidewallTempSatCurDensity = 0.0;
/* Temperature dependence of D/B and S/B diode capacitance begins */
delTemp = ckt->CKTtemp - model->BSIM3tnom;
T0 = model->BSIM3tcj * delTemp;
if (T0 >= -1.0)
{ model->BSIM3unitAreaTempJctCap = model->BSIM3unitAreaJctCap * (1.0 + T0);
}
else if (model->BSIM3unitAreaJctCap > 0.0)
{ model->BSIM3unitAreaTempJctCap = 0.0;
fprintf(stderr, "Temperature effect has caused cj to be negative. Cj is clamped to zero.\n");
}
T0 = model->BSIM3tcjsw * delTemp;
if (T0 >= -1.0)
{ model->BSIM3unitLengthSidewallTempJctCap = model->BSIM3unitLengthSidewallJctCap * (1.0 + T0);
}
else if (model->BSIM3unitLengthSidewallJctCap > 0.0)
{ model->BSIM3unitLengthSidewallTempJctCap = 0.0;
fprintf(stderr, "Temperature effect has caused cjsw to be negative. Cjsw is clamped to zero.\n");
}
T0 = model->BSIM3tcjswg * delTemp;
if (T0 >= -1.0)
{ model->BSIM3unitLengthGateSidewallTempJctCap = model->BSIM3unitLengthGateSidewallJctCap * (1.0 + T0);
}
else if (model->BSIM3unitLengthGateSidewallJctCap > 0.0)
{ model->BSIM3unitLengthGateSidewallTempJctCap = 0.0;
fprintf(stderr, "Temperature effect has caused cjswg to be negative. Cjswg is clamped to zero.\n");
}
model->BSIM3PhiB = model->BSIM3bulkJctPotential
- model->BSIM3tpb * delTemp;
if (model->BSIM3PhiB < 0.01)
{ model->BSIM3PhiB = 0.01;
fprintf(stderr, "Temperature effect has caused pb to be less than 0.01. Pb is clamped to 0.01.\n");
}
model->BSIM3PhiBSW = model->BSIM3sidewallJctPotential
- model->BSIM3tpbsw * delTemp;
if (model->BSIM3PhiBSW <= 0.01)
{ model->BSIM3PhiBSW = 0.01;
fprintf(stderr, "Temperature effect has caused pbsw to be less than 0.01. Pbsw is clamped to 0.01.\n");
}
model->BSIM3PhiBSWG = model->BSIM3GatesidewallJctPotential
- model->BSIM3tpbswg * delTemp;
if (model->BSIM3PhiBSWG <= 0.01)
{ model->BSIM3PhiBSWG = 0.01;
fprintf(stderr, "Temperature effect has caused pbswg to be less than 0.01. Pbswg is clamped to 0.01.\n");
}
/* End of junction capacitance */
/* loop through all the instances of the model */
/* MCJ: Length and Width not initialized */
for (here = BSIM3SIMDinstances(model); here != NULL;
here = BSIM3SIMDnextInstance(here))
{
pSizeDependParamKnot = model->pSizeDependParamKnot;
Size_Not_Found = 1;
while ((pSizeDependParamKnot != NULL) && Size_Not_Found)
{ if ((here->BSIM3l == pSizeDependParamKnot->Length)
&& (here->BSIM3w == pSizeDependParamKnot->Width))
{ Size_Not_Found = 0;
here->pParam = pSizeDependParamKnot;
pParam = here->pParam; /*bug-fix */
}
else
{ pLastKnot = pSizeDependParamKnot;
pSizeDependParamKnot = pSizeDependParamKnot->pNext;
}
}
if (Size_Not_Found)
{ pParam = TMALLOC(struct bsim3SizeDependParam, 1);
if (pLastKnot == NULL)
model->pSizeDependParamKnot = pParam;
else
pLastKnot->pNext = pParam;
pParam->pNext = NULL;
here->pParam = pParam;
Ldrn = here->BSIM3l;
Wdrn = here->BSIM3w;
pParam->Length = Ldrn;
pParam->Width = Wdrn;
T0 = pow(Ldrn, model->BSIM3Lln);
T1 = pow(Wdrn, model->BSIM3Lwn);
tmp1 = model->BSIM3Ll / T0 + model->BSIM3Lw / T1
+ model->BSIM3Lwl / (T0 * T1);
pParam->BSIM3dl = model->BSIM3Lint + tmp1;
tmp2 = model->BSIM3Llc / T0 + model->BSIM3Lwc / T1
+ model->BSIM3Lwlc / (T0 * T1);
pParam->BSIM3dlc = model->BSIM3dlc + tmp2;
T2 = pow(Ldrn, model->BSIM3Wln);
T3 = pow(Wdrn, model->BSIM3Wwn);
tmp1 = model->BSIM3Wl / T2 + model->BSIM3Ww / T3
+ model->BSIM3Wwl / (T2 * T3);
pParam->BSIM3dw = model->BSIM3Wint + tmp1;
tmp2 = model->BSIM3Wlc / T2 + model->BSIM3Wwc / T3
+ model->BSIM3Wwlc / (T2 * T3);
pParam->BSIM3dwc = model->BSIM3dwc + tmp2;
pParam->BSIM3leff = here->BSIM3l + model->BSIM3xl - 2.0 * pParam->BSIM3dl;
if (pParam->BSIM3leff <= 0.0)
{
SPfrontEnd->IFerrorf (ERR_FATAL,
"BSIM3: mosfet %s, model %s: Effective channel length <= 0",
model->BSIM3modName, here->BSIM3name);
return(E_BADPARM);
}
pParam->BSIM3weff = here->BSIM3w + model->BSIM3xw - 2.0 * pParam->BSIM3dw;
if (pParam->BSIM3weff <= 0.0)
{
SPfrontEnd->IFerrorf (ERR_FATAL,
"BSIM3: mosfet %s, model %s: Effective channel width <= 0",
model->BSIM3modName, here->BSIM3name);
return(E_BADPARM);
}
pParam->BSIM3leffCV = here->BSIM3l + model->BSIM3xl - 2.0 * pParam->BSIM3dlc;
if (pParam->BSIM3leffCV <= 0.0)
{
SPfrontEnd->IFerrorf (ERR_FATAL,
"BSIM3: mosfet %s, model %s: Effective channel length for C-V <= 0",
model->BSIM3modName, here->BSIM3name);
return(E_BADPARM);
}
pParam->BSIM3weffCV = here->BSIM3w + model->BSIM3xw - 2.0 * pParam->BSIM3dwc;
if (pParam->BSIM3weffCV <= 0.0)
{
SPfrontEnd->IFerrorf (ERR_FATAL,
"BSIM3: mosfet %s, model %s: Effective channel width for C-V <= 0",
model->BSIM3modName, here->BSIM3name);
return(E_BADPARM);
}
if (model->BSIM3binUnit == 1)
{ Inv_L = 1.0e-6 / pParam->BSIM3leff;
Inv_W = 1.0e-6 / pParam->BSIM3weff;
Inv_LW = 1.0e-12 / (pParam->BSIM3leff
* pParam->BSIM3weff);
}
else
{ Inv_L = 1.0 / pParam->BSIM3leff;
Inv_W = 1.0 / pParam->BSIM3weff;
Inv_LW = 1.0 / (pParam->BSIM3leff
* pParam->BSIM3weff);
}
pParam->BSIM3cdsc = model->BSIM3cdsc
+ model->BSIM3lcdsc * Inv_L
+ model->BSIM3wcdsc * Inv_W
+ model->BSIM3pcdsc * Inv_LW;
pParam->BSIM3cdscb = model->BSIM3cdscb
+ model->BSIM3lcdscb * Inv_L
+ model->BSIM3wcdscb * Inv_W
+ model->BSIM3pcdscb * Inv_LW;
pParam->BSIM3cdscd = model->BSIM3cdscd
+ model->BSIM3lcdscd * Inv_L
+ model->BSIM3wcdscd * Inv_W
+ model->BSIM3pcdscd * Inv_LW;
pParam->BSIM3cit = model->BSIM3cit
+ model->BSIM3lcit * Inv_L
+ model->BSIM3wcit * Inv_W
+ model->BSIM3pcit * Inv_LW;
pParam->BSIM3nfactor = model->BSIM3nfactor
+ model->BSIM3lnfactor * Inv_L
+ model->BSIM3wnfactor * Inv_W
+ model->BSIM3pnfactor * Inv_LW;
pParam->BSIM3xj = model->BSIM3xj
+ model->BSIM3lxj * Inv_L
+ model->BSIM3wxj * Inv_W
+ model->BSIM3pxj * Inv_LW;
pParam->BSIM3vsat = model->BSIM3vsat
+ model->BSIM3lvsat * Inv_L
+ model->BSIM3wvsat * Inv_W
+ model->BSIM3pvsat * Inv_LW;
pParam->BSIM3at = model->BSIM3at
+ model->BSIM3lat * Inv_L
+ model->BSIM3wat * Inv_W
+ model->BSIM3pat * Inv_LW;
pParam->BSIM3a0 = model->BSIM3a0
+ model->BSIM3la0 * Inv_L
+ model->BSIM3wa0 * Inv_W
+ model->BSIM3pa0 * Inv_LW;
pParam->BSIM3ags = model->BSIM3ags
+ model->BSIM3lags * Inv_L
+ model->BSIM3wags * Inv_W
+ model->BSIM3pags * Inv_LW;
pParam->BSIM3a1 = model->BSIM3a1
+ model->BSIM3la1 * Inv_L
+ model->BSIM3wa1 * Inv_W
+ model->BSIM3pa1 * Inv_LW;
pParam->BSIM3a2 = model->BSIM3a2
+ model->BSIM3la2 * Inv_L
+ model->BSIM3wa2 * Inv_W
+ model->BSIM3pa2 * Inv_LW;
pParam->BSIM3keta = model->BSIM3keta
+ model->BSIM3lketa * Inv_L
+ model->BSIM3wketa * Inv_W
+ model->BSIM3pketa * Inv_LW;
pParam->BSIM3nsub = model->BSIM3nsub
+ model->BSIM3lnsub * Inv_L
+ model->BSIM3wnsub * Inv_W
+ model->BSIM3pnsub * Inv_LW;
pParam->BSIM3npeak = model->BSIM3npeak
+ model->BSIM3lnpeak * Inv_L
+ model->BSIM3wnpeak * Inv_W
+ model->BSIM3pnpeak * Inv_LW;
pParam->BSIM3ngate = model->BSIM3ngate
+ model->BSIM3lngate * Inv_L
+ model->BSIM3wngate * Inv_W
+ model->BSIM3pngate * Inv_LW;
pParam->BSIM3gamma1 = model->BSIM3gamma1
+ model->BSIM3lgamma1 * Inv_L
+ model->BSIM3wgamma1 * Inv_W
+ model->BSIM3pgamma1 * Inv_LW;
pParam->BSIM3gamma2 = model->BSIM3gamma2
+ model->BSIM3lgamma2 * Inv_L
+ model->BSIM3wgamma2 * Inv_W
+ model->BSIM3pgamma2 * Inv_LW;
pParam->BSIM3vbx = model->BSIM3vbx
+ model->BSIM3lvbx * Inv_L
+ model->BSIM3wvbx * Inv_W
+ model->BSIM3pvbx * Inv_LW;
pParam->BSIM3vbm = model->BSIM3vbm
+ model->BSIM3lvbm * Inv_L
+ model->BSIM3wvbm * Inv_W
+ model->BSIM3pvbm * Inv_LW;
pParam->BSIM3xt = model->BSIM3xt
+ model->BSIM3lxt * Inv_L
+ model->BSIM3wxt * Inv_W
+ model->BSIM3pxt * Inv_LW;
pParam->BSIM3vfb = model->BSIM3vfb
+ model->BSIM3lvfb * Inv_L
+ model->BSIM3wvfb * Inv_W
+ model->BSIM3pvfb * Inv_LW;
pParam->BSIM3k1 = model->BSIM3k1
+ model->BSIM3lk1 * Inv_L
+ model->BSIM3wk1 * Inv_W
+ model->BSIM3pk1 * Inv_LW;
pParam->BSIM3kt1 = model->BSIM3kt1
+ model->BSIM3lkt1 * Inv_L
+ model->BSIM3wkt1 * Inv_W
+ model->BSIM3pkt1 * Inv_LW;
pParam->BSIM3kt1l = model->BSIM3kt1l
+ model->BSIM3lkt1l * Inv_L
+ model->BSIM3wkt1l * Inv_W
+ model->BSIM3pkt1l * Inv_LW;
pParam->BSIM3k2 = model->BSIM3k2
+ model->BSIM3lk2 * Inv_L
+ model->BSIM3wk2 * Inv_W
+ model->BSIM3pk2 * Inv_LW;
pParam->BSIM3kt2 = model->BSIM3kt2
+ model->BSIM3lkt2 * Inv_L
+ model->BSIM3wkt2 * Inv_W
+ model->BSIM3pkt2 * Inv_LW;
pParam->BSIM3k3 = model->BSIM3k3
+ model->BSIM3lk3 * Inv_L
+ model->BSIM3wk3 * Inv_W
+ model->BSIM3pk3 * Inv_LW;
pParam->BSIM3k3b = model->BSIM3k3b
+ model->BSIM3lk3b * Inv_L
+ model->BSIM3wk3b * Inv_W
+ model->BSIM3pk3b * Inv_LW;
pParam->BSIM3w0 = model->BSIM3w0
+ model->BSIM3lw0 * Inv_L
+ model->BSIM3ww0 * Inv_W
+ model->BSIM3pw0 * Inv_LW;
pParam->BSIM3nlx = model->BSIM3nlx
+ model->BSIM3lnlx * Inv_L
+ model->BSIM3wnlx * Inv_W
+ model->BSIM3pnlx * Inv_LW;
pParam->BSIM3dvt0 = model->BSIM3dvt0
+ model->BSIM3ldvt0 * Inv_L
+ model->BSIM3wdvt0 * Inv_W
+ model->BSIM3pdvt0 * Inv_LW;
pParam->BSIM3dvt1 = model->BSIM3dvt1
+ model->BSIM3ldvt1 * Inv_L
+ model->BSIM3wdvt1 * Inv_W
+ model->BSIM3pdvt1 * Inv_LW;
pParam->BSIM3dvt2 = model->BSIM3dvt2
+ model->BSIM3ldvt2 * Inv_L
+ model->BSIM3wdvt2 * Inv_W
+ model->BSIM3pdvt2 * Inv_LW;
pParam->BSIM3dvt0w = model->BSIM3dvt0w
+ model->BSIM3ldvt0w * Inv_L
+ model->BSIM3wdvt0w * Inv_W
+ model->BSIM3pdvt0w * Inv_LW;
pParam->BSIM3dvt1w = model->BSIM3dvt1w
+ model->BSIM3ldvt1w * Inv_L
+ model->BSIM3wdvt1w * Inv_W
+ model->BSIM3pdvt1w * Inv_LW;
pParam->BSIM3dvt2w = model->BSIM3dvt2w
+ model->BSIM3ldvt2w * Inv_L
+ model->BSIM3wdvt2w * Inv_W
+ model->BSIM3pdvt2w * Inv_LW;
pParam->BSIM3drout = model->BSIM3drout
+ model->BSIM3ldrout * Inv_L
+ model->BSIM3wdrout * Inv_W
+ model->BSIM3pdrout * Inv_LW;
pParam->BSIM3dsub = model->BSIM3dsub
+ model->BSIM3ldsub * Inv_L
+ model->BSIM3wdsub * Inv_W
+ model->BSIM3pdsub * Inv_LW;
pParam->BSIM3vth0 = model->BSIM3vth0
+ model->BSIM3lvth0 * Inv_L
+ model->BSIM3wvth0 * Inv_W
+ model->BSIM3pvth0 * Inv_LW;
pParam->BSIM3ua = model->BSIM3ua
+ model->BSIM3lua * Inv_L
+ model->BSIM3wua * Inv_W
+ model->BSIM3pua * Inv_LW;
pParam->BSIM3ua1 = model->BSIM3ua1
+ model->BSIM3lua1 * Inv_L
+ model->BSIM3wua1 * Inv_W
+ model->BSIM3pua1 * Inv_LW;
pParam->BSIM3ub = model->BSIM3ub
+ model->BSIM3lub * Inv_L
+ model->BSIM3wub * Inv_W
+ model->BSIM3pub * Inv_LW;
pParam->BSIM3ub1 = model->BSIM3ub1
+ model->BSIM3lub1 * Inv_L
+ model->BSIM3wub1 * Inv_W
+ model->BSIM3pub1 * Inv_LW;
pParam->BSIM3uc = model->BSIM3uc
+ model->BSIM3luc * Inv_L
+ model->BSIM3wuc * Inv_W
+ model->BSIM3puc * Inv_LW;
pParam->BSIM3uc1 = model->BSIM3uc1
+ model->BSIM3luc1 * Inv_L
+ model->BSIM3wuc1 * Inv_W
+ model->BSIM3puc1 * Inv_LW;
pParam->BSIM3u0 = model->BSIM3u0
+ model->BSIM3lu0 * Inv_L
+ model->BSIM3wu0 * Inv_W
+ model->BSIM3pu0 * Inv_LW;
pParam->BSIM3ute = model->BSIM3ute
+ model->BSIM3lute * Inv_L
+ model->BSIM3wute * Inv_W
+ model->BSIM3pute * Inv_LW;
pParam->BSIM3voff = model->BSIM3voff
+ model->BSIM3lvoff * Inv_L
+ model->BSIM3wvoff * Inv_W
+ model->BSIM3pvoff * Inv_LW;
pParam->BSIM3delta = model->BSIM3delta
+ model->BSIM3ldelta * Inv_L
+ model->BSIM3wdelta * Inv_W
+ model->BSIM3pdelta * Inv_LW;
pParam->BSIM3rdsw = model->BSIM3rdsw
+ model->BSIM3lrdsw * Inv_L
+ model->BSIM3wrdsw * Inv_W
+ model->BSIM3prdsw * Inv_LW;
pParam->BSIM3prwg = model->BSIM3prwg
+ model->BSIM3lprwg * Inv_L
+ model->BSIM3wprwg * Inv_W
+ model->BSIM3pprwg * Inv_LW;
pParam->BSIM3prwb = model->BSIM3prwb
+ model->BSIM3lprwb * Inv_L
+ model->BSIM3wprwb * Inv_W
+ model->BSIM3pprwb * Inv_LW;
pParam->BSIM3prt = model->BSIM3prt
+ model->BSIM3lprt * Inv_L
+ model->BSIM3wprt * Inv_W
+ model->BSIM3pprt * Inv_LW;
pParam->BSIM3eta0 = model->BSIM3eta0
+ model->BSIM3leta0 * Inv_L
+ model->BSIM3weta0 * Inv_W
+ model->BSIM3peta0 * Inv_LW;
pParam->BSIM3etab = model->BSIM3etab
+ model->BSIM3letab * Inv_L
+ model->BSIM3wetab * Inv_W
+ model->BSIM3petab * Inv_LW;
pParam->BSIM3pclm = model->BSIM3pclm
+ model->BSIM3lpclm * Inv_L
+ model->BSIM3wpclm * Inv_W
+ model->BSIM3ppclm * Inv_LW;
pParam->BSIM3pdibl1 = model->BSIM3pdibl1
+ model->BSIM3lpdibl1 * Inv_L
+ model->BSIM3wpdibl1 * Inv_W
+ model->BSIM3ppdibl1 * Inv_LW;
pParam->BSIM3pdibl2 = model->BSIM3pdibl2
+ model->BSIM3lpdibl2 * Inv_L
+ model->BSIM3wpdibl2 * Inv_W
+ model->BSIM3ppdibl2 * Inv_LW;
pParam->BSIM3pdiblb = model->BSIM3pdiblb
+ model->BSIM3lpdiblb * Inv_L
+ model->BSIM3wpdiblb * Inv_W
+ model->BSIM3ppdiblb * Inv_LW;
pParam->BSIM3pscbe1 = model->BSIM3pscbe1
+ model->BSIM3lpscbe1 * Inv_L
+ model->BSIM3wpscbe1 * Inv_W
+ model->BSIM3ppscbe1 * Inv_LW;
pParam->BSIM3pscbe2 = model->BSIM3pscbe2
+ model->BSIM3lpscbe2 * Inv_L
+ model->BSIM3wpscbe2 * Inv_W
+ model->BSIM3ppscbe2 * Inv_LW;
pParam->BSIM3pvag = model->BSIM3pvag
+ model->BSIM3lpvag * Inv_L
+ model->BSIM3wpvag * Inv_W
+ model->BSIM3ppvag * Inv_LW;
pParam->BSIM3wr = model->BSIM3wr
+ model->BSIM3lwr * Inv_L
+ model->BSIM3wwr * Inv_W
+ model->BSIM3pwr * Inv_LW;
pParam->BSIM3dwg = model->BSIM3dwg
+ model->BSIM3ldwg * Inv_L
+ model->BSIM3wdwg * Inv_W
+ model->BSIM3pdwg * Inv_LW;
pParam->BSIM3dwb = model->BSIM3dwb
+ model->BSIM3ldwb * Inv_L
+ model->BSIM3wdwb * Inv_W
+ model->BSIM3pdwb * Inv_LW;
pParam->BSIM3b0 = model->BSIM3b0
+ model->BSIM3lb0 * Inv_L
+ model->BSIM3wb0 * Inv_W
+ model->BSIM3pb0 * Inv_LW;
pParam->BSIM3b1 = model->BSIM3b1
+ model->BSIM3lb1 * Inv_L
+ model->BSIM3wb1 * Inv_W
+ model->BSIM3pb1 * Inv_LW;
pParam->BSIM3alpha0 = model->BSIM3alpha0
+ model->BSIM3lalpha0 * Inv_L
+ model->BSIM3walpha0 * Inv_W
+ model->BSIM3palpha0 * Inv_LW;
pParam->BSIM3alpha1 = model->BSIM3alpha1
+ model->BSIM3lalpha1 * Inv_L
+ model->BSIM3walpha1 * Inv_W
+ model->BSIM3palpha1 * Inv_LW;
pParam->BSIM3beta0 = model->BSIM3beta0
+ model->BSIM3lbeta0 * Inv_L
+ model->BSIM3wbeta0 * Inv_W
+ model->BSIM3pbeta0 * Inv_LW;
/* CV model */
pParam->BSIM3elm = model->BSIM3elm
+ model->BSIM3lelm * Inv_L
+ model->BSIM3welm * Inv_W
+ model->BSIM3pelm * Inv_LW;
pParam->BSIM3cgsl = model->BSIM3cgsl
+ model->BSIM3lcgsl * Inv_L
+ model->BSIM3wcgsl * Inv_W
+ model->BSIM3pcgsl * Inv_LW;
pParam->BSIM3cgdl = model->BSIM3cgdl
+ model->BSIM3lcgdl * Inv_L
+ model->BSIM3wcgdl * Inv_W
+ model->BSIM3pcgdl * Inv_LW;
pParam->BSIM3ckappa = model->BSIM3ckappa
+ model->BSIM3lckappa * Inv_L
+ model->BSIM3wckappa * Inv_W
+ model->BSIM3pckappa * Inv_LW;
pParam->BSIM3cf = model->BSIM3cf
+ model->BSIM3lcf * Inv_L
+ model->BSIM3wcf * Inv_W
+ model->BSIM3pcf * Inv_LW;
pParam->BSIM3clc = model->BSIM3clc
+ model->BSIM3lclc * Inv_L
+ model->BSIM3wclc * Inv_W
+ model->BSIM3pclc * Inv_LW;
pParam->BSIM3cle = model->BSIM3cle
+ model->BSIM3lcle * Inv_L
+ model->BSIM3wcle * Inv_W
+ model->BSIM3pcle * Inv_LW;
pParam->BSIM3vfbcv = model->BSIM3vfbcv
+ model->BSIM3lvfbcv * Inv_L
+ model->BSIM3wvfbcv * Inv_W
+ model->BSIM3pvfbcv * Inv_LW;
pParam->BSIM3acde = model->BSIM3acde
+ model->BSIM3lacde * Inv_L
+ model->BSIM3wacde * Inv_W
+ model->BSIM3pacde * Inv_LW;
pParam->BSIM3moin = model->BSIM3moin
+ model->BSIM3lmoin * Inv_L
+ model->BSIM3wmoin * Inv_W
+ model->BSIM3pmoin * Inv_LW;
pParam->BSIM3noff = model->BSIM3noff
+ model->BSIM3lnoff * Inv_L
+ model->BSIM3wnoff * Inv_W
+ model->BSIM3pnoff * Inv_LW;
pParam->BSIM3voffcv = model->BSIM3voffcv
+ model->BSIM3lvoffcv * Inv_L
+ model->BSIM3wvoffcv * Inv_W
+ model->BSIM3pvoffcv * Inv_LW;
pParam->BSIM3abulkCVfactor = 1.0 + pow((pParam->BSIM3clc
/ pParam->BSIM3leffCV),
pParam->BSIM3cle);
T0 = (TRatio - 1.0);
pParam->BSIM3ua = pParam->BSIM3ua + pParam->BSIM3ua1 * T0;
pParam->BSIM3ub = pParam->BSIM3ub + pParam->BSIM3ub1 * T0;
pParam->BSIM3uc = pParam->BSIM3uc + pParam->BSIM3uc1 * T0;
if (pParam->BSIM3u0 > 1.0)
pParam->BSIM3u0 = pParam->BSIM3u0 / 1.0e4;
pParam->BSIM3u0temp = pParam->BSIM3u0
* pow(TRatio, pParam->BSIM3ute);
pParam->BSIM3vsattemp = pParam->BSIM3vsat - pParam->BSIM3at
* T0;
pParam->BSIM3rds0 = (pParam->BSIM3rdsw + pParam->BSIM3prt * T0)
/ pow(pParam->BSIM3weff * 1E6, pParam->BSIM3wr);
if (BSIM3SIMDcheckModel(model, here, ckt))
{
SPfrontEnd->IFerrorf (ERR_FATAL, "Fatal error(s) detected during BSIM3V3.3 parameter checking for %s in model %s", model->BSIM3modName, here->BSIM3name);
return(E_BADPARM);
}
pParam->BSIM3cgdo = (model->BSIM3cgdo + pParam->BSIM3cf)
* pParam->BSIM3weffCV;
pParam->BSIM3cgso = (model->BSIM3cgso + pParam->BSIM3cf)
* pParam->BSIM3weffCV;
pParam->BSIM3cgbo = model->BSIM3cgbo * pParam->BSIM3leffCV;
T0 = pParam->BSIM3leffCV * pParam->BSIM3leffCV;
pParam->BSIM3tconst = pParam->BSIM3u0temp * pParam->BSIM3elm / (model->BSIM3cox
* pParam->BSIM3weffCV * pParam->BSIM3leffCV * T0);
if (!model->BSIM3npeakGiven && model->BSIM3gamma1Given)
{ T0 = pParam->BSIM3gamma1 * model->BSIM3cox;
pParam->BSIM3npeak = 3.021E22 * T0 * T0;
}
pParam->BSIM3phi = 2.0 * Vtm0
* log(pParam->BSIM3npeak / ni);
pParam->BSIM3sqrtPhi = sqrt(pParam->BSIM3phi);
pParam->BSIM3phis3 = pParam->BSIM3sqrtPhi * pParam->BSIM3phi;
pParam->BSIM3Xdep0 = sqrt(2.0 * EPSSI / (Charge_q
* pParam->BSIM3npeak * 1.0e6))
* pParam->BSIM3sqrtPhi;
pParam->BSIM3sqrtXdep0 = sqrt(pParam->BSIM3Xdep0);
pParam->BSIM3litl = sqrt(3.0 * pParam->BSIM3xj
* model->BSIM3tox);
pParam->BSIM3vbi = Vtm0 * log(1.0e20
* pParam->BSIM3npeak / (ni * ni));
pParam->BSIM3cdep0 = sqrt(Charge_q * EPSSI
* pParam->BSIM3npeak * 1.0e6 / 2.0
/ pParam->BSIM3phi);
pParam->BSIM3ldeb = sqrt(EPSSI * Vtm0 / (Charge_q
* pParam->BSIM3npeak * 1.0e6)) / 3.0;
pParam->BSIM3acde *= pow((pParam->BSIM3npeak / 2.0e16), -0.25);
if (model->BSIM3k1Given || model->BSIM3k2Given)
{ if (!model->BSIM3k1Given)
{
if ((!ckt->CKTcurJob) || (ckt->CKTcurJob->JOBtype < 9)) /* don't print in sensitivity */
fprintf(stdout, "Warning: k1 should be specified with k2.\n");
pParam->BSIM3k1 = 0.53;
}
if (!model->BSIM3k2Given)
{
if ((!ckt->CKTcurJob) || (ckt->CKTcurJob->JOBtype < 9)) /* don't print in sensitivity */
fprintf(stdout, "Warning: k2 should be specified with k1.\n");
pParam->BSIM3k2 = -0.0186;
}
if ((!ckt->CKTcurJob) || (ckt->CKTcurJob->JOBtype < 9)) { /* don't print in sensitivity */
if (model->BSIM3nsubGiven)
fprintf(stdout, "Warning: nsub is ignored because k1 or k2 is given.\n");
if (model->BSIM3xtGiven)
fprintf(stdout, "Warning: xt is ignored because k1 or k2 is given.\n");
if (model->BSIM3vbxGiven)
fprintf(stdout, "Warning: vbx is ignored because k1 or k2 is given.\n");
if (model->BSIM3gamma1Given)
fprintf(stdout, "Warning: gamma1 is ignored because k1 or k2 is given.\n");
if (model->BSIM3gamma2Given)
fprintf(stdout, "Warning: gamma2 is ignored because k1 or k2 is given.\n");
}
}
else
{ if (!model->BSIM3vbxGiven)
pParam->BSIM3vbx = pParam->BSIM3phi - 7.7348e-4
* pParam->BSIM3npeak
* pParam->BSIM3xt * pParam->BSIM3xt;
if (pParam->BSIM3vbx > 0.0)
pParam->BSIM3vbx = -pParam->BSIM3vbx;
if (pParam->BSIM3vbm > 0.0)
pParam->BSIM3vbm = -pParam->BSIM3vbm;
if (!model->BSIM3gamma1Given)
pParam->BSIM3gamma1 = 5.753e-12
* sqrt(pParam->BSIM3npeak)
/ model->BSIM3cox;
if (!model->BSIM3gamma2Given)
pParam->BSIM3gamma2 = 5.753e-12
* sqrt(pParam->BSIM3nsub)
/ model->BSIM3cox;
T0 = pParam->BSIM3gamma1 - pParam->BSIM3gamma2;
T1 = sqrt(pParam->BSIM3phi - pParam->BSIM3vbx)
- pParam->BSIM3sqrtPhi;
T2 = sqrt(pParam->BSIM3phi * (pParam->BSIM3phi
- pParam->BSIM3vbm)) - pParam->BSIM3phi;
pParam->BSIM3k2 = T0 * T1 / (2.0 * T2 + pParam->BSIM3vbm);
pParam->BSIM3k1 = pParam->BSIM3gamma2 - 2.0
* pParam->BSIM3k2 * sqrt(pParam->BSIM3phi
- pParam->BSIM3vbm);
}
if (pParam->BSIM3k2 < 0.0)
{ T0 = 0.5 * pParam->BSIM3k1 / pParam->BSIM3k2;
pParam->BSIM3vbsc = 0.9 * (pParam->BSIM3phi - T0 * T0);
if (pParam->BSIM3vbsc > -3.0)
pParam->BSIM3vbsc = -3.0;
else if (pParam->BSIM3vbsc < -30.0)
pParam->BSIM3vbsc = -30.0;
}
else
{ pParam->BSIM3vbsc = -30.0;
}
if (pParam->BSIM3vbsc > pParam->BSIM3vbm)
pParam->BSIM3vbsc = pParam->BSIM3vbm;
if (!model->BSIM3vfbGiven)
{ if (model->BSIM3vth0Given)
{ pParam->BSIM3vfb = model->BSIM3type * pParam->BSIM3vth0
- pParam->BSIM3phi - pParam->BSIM3k1
* pParam->BSIM3sqrtPhi;
}
else
{ pParam->BSIM3vfb = -1.0;
}
}
if (!model->BSIM3vth0Given)
{ pParam->BSIM3vth0 = model->BSIM3type * (pParam->BSIM3vfb
+ pParam->BSIM3phi + pParam->BSIM3k1
* pParam->BSIM3sqrtPhi);
}
pParam->BSIM3k1ox = pParam->BSIM3k1 * model->BSIM3tox
/ model->BSIM3toxm;
pParam->BSIM3k2ox = pParam->BSIM3k2 * model->BSIM3tox
/ model->BSIM3toxm;
T1 = sqrt(EPSSI / EPSOX * model->BSIM3tox
* pParam->BSIM3Xdep0);
T0 = exp(-0.5 * pParam->BSIM3dsub * pParam->BSIM3leff / T1);
pParam->BSIM3theta0vb0 = (T0 + 2.0 * T0 * T0);
T0 = exp(-0.5 * pParam->BSIM3drout * pParam->BSIM3leff / T1);
T2 = (T0 + 2.0 * T0 * T0);
pParam->BSIM3thetaRout = pParam->BSIM3pdibl1 * T2
+ pParam->BSIM3pdibl2;
tmp = sqrt(pParam->BSIM3Xdep0);
tmp1 = pParam->BSIM3vbi - pParam->BSIM3phi;
tmp2 = model->BSIM3factor1 * tmp;
T0 = -0.5 * pParam->BSIM3dvt1w * pParam->BSIM3weff
* pParam->BSIM3leff / tmp2;
if (T0 > -EXP_THRESHOLD)
{ T1 = exp(T0);
T2 = T1 * (1.0 + 2.0 * T1);
}
else
{ T1 = MIN_EXP;
T2 = T1 * (1.0 + 2.0 * T1);
}
T0 = pParam->BSIM3dvt0w * T2;
T2 = T0 * tmp1;
T0 = -0.5 * pParam->BSIM3dvt1 * pParam->BSIM3leff / tmp2;
if (T0 > -EXP_THRESHOLD)
{ T1 = exp(T0);
T3 = T1 * (1.0 + 2.0 * T1);
}
else
{ T1 = MIN_EXP;
T3 = T1 * (1.0 + 2.0 * T1);
}
T3 = pParam->BSIM3dvt0 * T3 * tmp1;
T4 = model->BSIM3tox * pParam->BSIM3phi
/ (pParam->BSIM3weff + pParam->BSIM3w0);
T0 = sqrt(1.0 + pParam->BSIM3nlx / pParam->BSIM3leff);
T5 = pParam->BSIM3k1ox * (T0 - 1.0) * pParam->BSIM3sqrtPhi
+ (pParam->BSIM3kt1 + pParam->BSIM3kt1l / pParam->BSIM3leff)
* (TRatio - 1.0);
tmp3 = model->BSIM3type * pParam->BSIM3vth0
- T2 - T3 + pParam->BSIM3k3 * T4 + T5;
pParam->BSIM3vfbzb = tmp3 - pParam->BSIM3phi - pParam->BSIM3k1
* pParam->BSIM3sqrtPhi;
/* End of vfbzb */
}
/* adding delvto */
here->BSIM3vth0 = pParam->BSIM3vth0 + here->BSIM3delvto;
here->BSIM3vfb = pParam->BSIM3vfb + model->BSIM3type * here->BSIM3delvto;
here->BSIM3vfbzb = pParam->BSIM3vfbzb + model->BSIM3type * here->BSIM3delvto;
/* low field mobility multiplier */
here->BSIM3u0temp = pParam->BSIM3u0temp * here->BSIM3mulu0;
here->BSIM3tconst = here->BSIM3u0temp * pParam->BSIM3elm / (model->BSIM3cox
* pParam->BSIM3weffCV * pParam->BSIM3leffCV * T0);
/* process source/drain series resistance */
/* ACM model */
double drainResistance, sourceResistance;
if (model->BSIM3acmMod == 0)
{
drainResistance = model->BSIM3sheetResistance
* here->BSIM3drainSquares;
sourceResistance = model->BSIM3sheetResistance
* here->BSIM3sourceSquares;
}
else /* ACM > 0 */
{
error = ACM_SourceDrainResistances(
model->BSIM3acmMod,
model->BSIM3ld,
model->BSIM3ldif,
model->BSIM3hdif,
model->BSIM3wmlt,
here->BSIM3w,
model->BSIM3xw,
model->BSIM3sheetResistance,
here->BSIM3drainSquaresGiven,
model->BSIM3rd,
model->BSIM3rdc,
here->BSIM3drainSquares,
here->BSIM3sourceSquaresGiven,
model->BSIM3rs,
model->BSIM3rsc,
here->BSIM3sourceSquares,
&drainResistance,
&sourceResistance
);
if (error)
return(error);
}
if (drainResistance > 0.0)
here->BSIM3drainConductance = 1.0 / drainResistance;
else
here->BSIM3drainConductance = 0.0;
if (sourceResistance > 0.0)
here->BSIM3sourceConductance = 1.0 / sourceResistance;
else
here->BSIM3sourceConductance = 0.0;
here->BSIM3cgso = pParam->BSIM3cgso;
here->BSIM3cgdo = pParam->BSIM3cgdo;
Nvtm = model->BSIM3vtm * model->BSIM3jctEmissionCoeff;
if ((here->BSIM3sourceArea <= 0.0) &&
(here->BSIM3sourcePerimeter <= 0.0))
{ SourceSatCurrent = 1.0e-14;
}
else
{ SourceSatCurrent = here->BSIM3sourceArea
* model->BSIM3jctTempSatCurDensity
+ here->BSIM3sourcePerimeter
* model->BSIM3jctSidewallTempSatCurDensity;
}
if ((SourceSatCurrent > 0.0) && (model->BSIM3ijth > 0.0))
{ here->BSIM3vjsm = Nvtm * log(model->BSIM3ijth
/ SourceSatCurrent + 1.0);
here->BSIM3IsEvjsm = SourceSatCurrent * exp(here->BSIM3vjsm
/ Nvtm);
}
if ((here->BSIM3drainArea <= 0.0) &&
(here->BSIM3drainPerimeter <= 0.0))
{ DrainSatCurrent = 1.0e-14;
}
else
{ DrainSatCurrent = here->BSIM3drainArea
* model->BSIM3jctTempSatCurDensity
+ here->BSIM3drainPerimeter
* model->BSIM3jctSidewallTempSatCurDensity;
}
if ((DrainSatCurrent > 0.0) && (model->BSIM3ijth > 0.0))
{ here->BSIM3vjdm = Nvtm * log(model->BSIM3ijth
/ DrainSatCurrent + 1.0);
here->BSIM3IsEvjdm = DrainSatCurrent * exp(here->BSIM3vjdm
/ Nvtm);
}
}
}
return(OK);
}

View File

@ -0,0 +1,50 @@
/**** BSIM3v3.3.0, Released by Xuemei Xi 07/29/2005 ****/
/**********
* Copyright 2004 Regents of the University of California. All rights reserved.
* File: b3trunc.c of BSIM3v3.3.0
* Author: 1995 Min-Chie Jeng and Mansun Chan.
* Author: 1997-1999 Weidong Liu.
* Author: 2001 Xuemei Xi
**********/
#include "ngspice/ngspice.h"
#include "ngspice/cktdefs.h"
#include "bsim3def.h"
#include "ngspice/sperror.h"
#include "ngspice/suffix.h"
int
BSIM3SIMDtrunc(
GENmodel *inModel,
CKTcircuit *ckt,
double *timeStep)
{
BSIM3model *model = (BSIM3model*)inModel;
BSIM3instance *here;
#ifdef STEPDEBUG
double debugtemp;
#endif /* STEPDEBUG */
for (; model != NULL; model = BSIM3SIMDnextModel(model))
{ for (here = BSIM3SIMDinstances(model); here != NULL;
here = BSIM3SIMDnextInstance(here))
{
#ifdef STEPDEBUG
debugtemp = *timeStep;
#endif /* STEPDEBUG */
CKTterr(here->BSIM3qb,ckt,timeStep);
CKTterr(here->BSIM3qg,ckt,timeStep);
CKTterr(here->BSIM3qd,ckt,timeStep);
#ifdef STEPDEBUG
if(debugtemp != *timeStep)
{ printf("device %s reduces step from %g to %g\n",
here->BSIM3name,debugtemp,*timeStep);
}
#endif /* STEPDEBUG */
}
}
return(OK);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,30 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1991 JianHui Huang and Min-Chie Jeng.
Modified by Yuhua Cheng to use BSIM3v3 in Spice3f5 (Jan. 1997)
File: bsim3ext.h
**********/
extern int BSIM3SIMDacLoad(GENmodel *,CKTcircuit*);
extern int BSIM3SIMDask(CKTcircuit *,GENinstance*,int,IFvalue*,IFvalue*);
extern int BSIM3SIMDconvTest(GENmodel *,CKTcircuit*);
extern int BSIM3SIMDgetic(GENmodel*,CKTcircuit*);
extern int BSIM3SIMDload(GENmodel*,CKTcircuit*);
extern int BSIM3SIMDloadSel(GENmodel*,CKTcircuit*);
extern int BSIM3SIMDmAsk(CKTcircuit*,GENmodel *,int, IFvalue*);
extern int BSIM3SIMDmDelete(GENmodel*);
extern int BSIM3SIMDmParam(int,IFvalue*,GENmodel*);
extern void BSIM3SIMDmosCap(CKTcircuit*, double, double, double, double,
double, double, double, double, double, double, double,
double, double, double, double, double, double, double*,
double*, double*, double*, double*, double*, double*, double*,
double*, double*, double*, double*, double*, double*, double*,
double*);
extern int BSIM3SIMDparam(int,IFvalue*,GENinstance*,IFvalue*);
extern int BSIM3SIMDpzLoad(GENmodel*,CKTcircuit*,SPcomplex*);
extern int BSIM3SIMDsetup(SMPmatrix*,GENmodel*,CKTcircuit*,int*);
extern int BSIM3SIMDtemp(GENmodel*,CKTcircuit*);
extern int BSIM3SIMDtrunc(GENmodel*,CKTcircuit*,double*);
extern int BSIM3SIMDnoise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*);
extern int BSIM3SIMDunsetup(GENmodel*,CKTcircuit*);
extern int BSIM3SIMDsoaCheck(CKTcircuit *, GENmodel *);

View File

@ -0,0 +1,78 @@
#include "ngspice/config.h"
#include "ngspice/devdefs.h"
#include "bsim3itf.h"
#include "bsim3ext.h"
#include "bsim3init.h"
SPICEdev BSIM3SIMDinfo = {
.DEVpublic = {
.name = "BSIM3simd",
.description = "Berkeley Short Channel IGFET Model Version-3",
.terms = &BSIM3SIMDnSize,
.numNames = &BSIM3SIMDnSize,
.termNames = BSIM3SIMDnames,
.numInstanceParms = &BSIM3SIMDpTSize,
.instanceParms = BSIM3SIMDpTable,
.numModelParms = &BSIM3SIMDmPTSize,
.modelParms = BSIM3SIMDmPTable,
.flags = DEV_DEFAULT,
#ifdef XSPICE
.cm_func = NULL,
.num_conn = 0,
.conn = NULL,
.num_param = 0,
.param = NULL,
.num_inst_var = 0,
.inst_var = NULL,
#endif
},
.DEVparam = BSIM3SIMDparam,
.DEVmodParam = BSIM3SIMDmParam,
.DEVload = BSIM3SIMDloadSel,
.DEVsetup = BSIM3SIMDsetup,
.DEVunsetup = BSIM3SIMDunsetup,
.DEVpzSetup = BSIM3SIMDsetup,
.DEVtemperature = BSIM3SIMDtemp,
.DEVtrunc = BSIM3SIMDtrunc,
.DEVfindBranch = NULL,
.DEVacLoad = BSIM3SIMDacLoad,
.DEVaccept = NULL,
.DEVdestroy = NULL,
.DEVmodDelete = BSIM3SIMDmDelete,
.DEVdelete = NULL,
.DEVsetic = BSIM3SIMDgetic,
.DEVask = BSIM3SIMDask,
.DEVmodAsk = BSIM3SIMDmAsk,
.DEVpzLoad = BSIM3SIMDpzLoad,
.DEVconvTest = BSIM3SIMDconvTest,
.DEVsenSetup = NULL,
.DEVsenLoad = NULL,
.DEVsenUpdate = NULL,
.DEVsenAcLoad = NULL,
.DEVsenPrint = NULL,
.DEVsenTrunc = NULL,
.DEVdisto = NULL,
.DEVnoise = BSIM3SIMDnoise,
.DEVsoaCheck = BSIM3SIMDsoaCheck,
.DEVinstSize = &BSIM3SIMDiSize,
.DEVmodSize = &BSIM3SIMDmSize,
#ifdef CIDER
.DEVdump = NULL,
.DEVacct = NULL,
#endif
};
SPICEdev *
get_bsim3simd_info(void)
{
return &BSIM3SIMDinfo;
}

View File

@ -0,0 +1,13 @@
#ifndef _BSIM3SIMDINIT_H
#define _BSIM3SIMDINIT_H
extern IFparm BSIM3SIMDpTable[ ];
extern IFparm BSIM3SIMDmPTable[ ];
extern char *BSIM3SIMDnames[ ];
extern int BSIM3SIMDpTSize;
extern int BSIM3SIMDmPTSize;
extern int BSIM3SIMDnSize;
extern int BSIM3SIMDiSize;
extern int BSIM3SIMDmSize;
#endif

View File

@ -0,0 +1,12 @@
/**********
Copyright 1999 Regents of the University of California. All rights reserved.
Author: 1991 JianHui Huang and Min-Chie Jeng.
File: bsim3itf.h
**********/
#ifndef DEV_BSIM3SIMD
#define DEV_BSIM3SIMD
SPICEdev *get_bsim3simd_info(void);
#endif

View File

@ -39,7 +39,7 @@
#define vec4_powMJSWG(x,p) vec4_pow(x,p)
#ifdef USE_SLEEF
#ifdef HAVE_LIBSLEEF
#include <sleef.h>
#define vec4_exp(a) Sleef_expd4_u10(a)
#define vec4_log(a) Sleef_logd4_u35(a)
@ -50,7 +50,7 @@
#endif
/* HAS_LIBMVEC defined from configure.ac */
/* HAS_LIBMVEC and/or HAVE_LIBSLEEF defined from configure.ac */
/* USE_SERIAL_FORM can be defined but has no performance influence */
@ -73,7 +73,7 @@ static inline Vec4d vec4_blend(Vec4d fa, Vec4d tr, Vec4m mask)
}
#endif
#ifndef USE_SLEEF
#ifndef HAVE_LIBSLEEF
/******* vec4_exp, vec4_log *******/
#ifdef HAS_LIBMVEC
Vec4d _ZGVdN4v_exp(Vec4d x);
@ -161,7 +161,7 @@ static inline Vec4d vec4_pow(Vec4d x, double p)
return vec4_exp(vec4_log(x)*p);
}
#endif /* USE_SLEEF */
#endif /* HAVE_LIBSLEEF */
/******* vec4_SIMDTOVECTOR, vec4_SIMDTOVECTORMASK *******/
#ifdef USE_SERIAL_FORM

View File

@ -79,6 +79,7 @@ extern struct coreInfo_t coreInfo; /* cmexport.c */
#include "bsim1/bsim1itf.h"
#include "bsim2/bsim2itf.h"
#include "bsim3/bsim3itf.h"
#include "bsim3simd/bsim3itf.h"
#include "bsim3v0/bsim3v0itf.h"
#include "bsim3v1/bsim3v1itf.h"
#include "bsim3v32/bsim3v32itf.h"
@ -218,8 +219,9 @@ static SPICEdev *(*static_devices[])(void) = {
get_ndev_info,
#endif
#ifdef BSIM3v32SIMD
#ifdef MODSIMD
get_bsim3v32simd_info,
get_bsim3simd_info,
#endif
};
@ -299,12 +301,12 @@ SPICEdev ** devices(void)
/*not yet usable*/
#ifdef ADMS
#define DEVICES_USED {"asrc", "bjt", "vbic", "bsim1", "bsim2", "bsim3", "bsim3v32", "bsim3v32simd", "bsim3v2", "bsim3v1", "bsim4", "bsim4v5", "bsim4v6", "bsim4v7", \
#define DEVICES_USED {"asrc", "bjt", "vbic", "bsim1", "bsim2", "bsim3", "bsim3simd", "bsim3v32", "bsim3v32simd", "bsim3v2", "bsim3v1", "bsim4", "bsim4v5", "bsim4v6", "bsim4v7", \
"bsim4soi", "bsim3soipd", "bsim3soifd", "bsim3soidd", "hisim2", "hisimhv1", "hisimhv2", \
"cap", "cccs", "ccvs", "csw", "dio", "hfet", "hfet2", "ind", "isrc", "jfet", "ltra", "mes", "mesa" ,"mos1", "mos2", "mos3", \
"mos6", "mos9", "res", "soi3", "sw", "tra", "urc", "vccs", "vcvs", "vsrc", "hicum0", "hicum2", "bjt504t", "ekv", "psp102"}
#else
#define DEVICES_USED {"asrc", "bjt", "vbic", "bsim1", "bsim2", "bsim3", "bsim3v32", "bsim3v32simd", "bsim3v2", "bsim3v1", "bsim4", "bsim4v5", "bsim4v6", "bsim4v7", \
#define DEVICES_USED {"asrc", "bjt", "vbic", "bsim1", "bsim2", "bsim3", "bsim3simd", "bsim3v32", "bsim3v32simd", "bsim3v2", "bsim3v1", "bsim4", "bsim4v5", "bsim4v6", "bsim4v7", \
"bsim4soi", "bsim3soipd", "bsim3soifd", "bsim3soidd", "hisim2", "hisimhv1", "hisimhv2", \
"cap", "cccs", "ccvs", "csw", "dio", "hfet", "hfet2", "ind", "isrc", "jfet", "ltra", "mes", "mesa" ,"mos1", "mos2", "mos3", \
"mos6", "mos9", "res", "soi3", "sw", "tra", "urc", "vccs", "vcvs", "vsrc"}

View File

@ -120,7 +120,6 @@ INP2M(CKTcircuit *ckt, INPtables *tab, struct card *current)
thismodel->INPmodType != INPtypelook("BSIM2") &&
thismodel->INPmodType != INPtypelook("BSIM3") &&
thismodel->INPmodType != INPtypelook("BSIM3v32") &&
thismodel->INPmodType != INPtypelook("BSIM3v32simd") &&
thismodel->INPmodType != INPtypelook("B4SOI") &&
thismodel->INPmodType != INPtypelook("B3SOIPD") &&
thismodel->INPmodType != INPtypelook("B3SOIFD") &&
@ -138,6 +137,10 @@ INP2M(CKTcircuit *ckt, INPtables *tab, struct card *current)
#ifdef ADMS
thismodel->INPmodType != INPtypelook("ekv") &&
thismodel->INPmodType != INPtypelook("psp102") &&
#endif
#ifdef MODSIMD
thismodel->INPmodType != INPtypelook("BSIM3v32simd") &&
thismodel->INPmodType != INPtypelook("BSIM3simd") &&
#endif
thismodel->INPmodType != INPtypelook("HiSIM2") &&
thismodel->INPmodType != INPtypelook("HiSIMHV1") &&

View File

@ -7,9 +7,34 @@ Author: 1985 Thomas L. Quarles
#include "ngspice/iferrmsg.h"
#include "ngspice/inpdefs.h"
#include "inpxx.h"
#ifdef BSIM3v32SIMD
#ifdef MODSIMD
#include "ngspice/cpextern.h"
#endif
#ifdef MODSIMD
int SIMDselect(const char* ver)
{
const char* ev;
ev = getenv("NGSPICE_MODSIMD");
if(ev && strcmp(ev,"never")==0)
return 0;
if(ev && strcmp(ev,"always")==0)
return 1;
if(((strlen(ver)>5) && (strcmp(&ver[strlen(ver)-4],"simd")==0))
|| cp_getvar("modsimd", CP_BOOL, NULL, 0)
#if defined(MODSIMD_ALWAYS)
|| 1
#endif
)
return 1;
else
return 0;
}
#else
#define SIMDselect 0
#endif
/*--------------------------------------------------------------
* This fcn takes the model card & examines it. Depending upon
* model type, it parses the model line, and then calls
@ -301,30 +326,28 @@ char *INPdomodel(CKTcircuit *ckt, struct card *image, INPtables * tab)
type = INPtypelook("BSIM3v1");
}
if (prefix("3.2", ver)) { /* version string ver has to start with 3.2 */
#ifdef BSIM3v32SIMD
if(((strlen(ver)>5) && (strcmp(&ver[strlen(ver)-4],"simd")==0))
|| cp_getvar("modsimd", CP_BOOL, NULL, 0)
#if defined(MODSIMD_ALWAYS)
|| 1
#endif
)
if(SIMDselect(ver))
type = INPtypelook("BSIM3v32simd");
else
#endif /* BSIM3v32SIMD */
type = INPtypelook("BSIM3v32");
}
if ( (strstr(ver, "default")) || (prefix("3.3", ver)) ) {
type = INPtypelook("BSIM3");
if(SIMDselect(ver))
type = INPtypelook("BSIM3simd");
else
type = INPtypelook("BSIM3");
}
if (type < 0) {
err = tprintf("Device type BSIM3 version %s not available in this binary\n", ver);
}
break;
case 88:
case 88: /* level 88 select simd version of BSIM3 - not so useful and should be removed */
err = INPfindVer(line, ver);
if (prefix("3.2", ver)) { /* version string ver has to start with 3.2 */
type = INPtypelook("BSIM3v32simd");
}
if ( (strstr(ver, "default")) || (prefix("3.3", ver)) )
type = INPtypelook("BSIM3simd");
if (type < 0) {
err = tprintf("Device type BSIM3(simd) version %s not available in this binary\n", ver);
}

View File

@ -244,7 +244,8 @@ INPgetModBin(CKTcircuit *ckt, char *name, INPmodel **model, INPtables *tab, char
/* skip if not binnable */
if (modtmp->INPmodType != INPtypelook("BSIM3") &&
modtmp->INPmodType != INPtypelook("BSIM3v32") &&
modtmp->INPmodType != INPtypelook("BSIM3simd") &&
modtmp->INPmodType != INPtypelook("BSIM3v32") &&
modtmp->INPmodType != INPtypelook("BSIM3v32simd") &&
modtmp->INPmodType != INPtypelook("BSIM3v0") &&
modtmp->INPmodType != INPtypelook("BSIM3v1") &&