simd version of BSIM3
This commit is contained in:
parent
0f6f1d1556
commit
a15f9a1eba
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
@ -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 = \
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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 \
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
1999-09-06 Arno Peters <A.W.Peters@ieee.org>
|
||||
|
||||
* b3ld.c: Removed unused variable.
|
||||
|
||||
|
|
@ -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
|
||||
|
|
@ -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);
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
@ -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 */
|
||||
}
|
||||
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
@ -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
|
|
@ -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 *);
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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"}
|
||||
|
|
|
|||
|
|
@ -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") &&
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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") &&
|
||||
|
|
|
|||
Loading…
Reference in New Issue